~ubuntu-branches/ubuntu/lucid/agda-stdlib/lucid

« back to all changes in this revision

Viewing changes to src/Relation/Binary/List/StrictLex.agda

  • Committer: Bazaar Package Importer
  • Author(s): Iain Lane
  • Date: 2010-01-08 23:35:09 UTC
  • Revision ID: james.westby@ubuntu.com-20100108233509-l6ejt9xji64xysfb
Import upstream version 0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
------------------------------------------------------------------------
 
2
-- Lexicographic ordering of lists
 
3
------------------------------------------------------------------------
 
4
 
 
5
-- The definition of lexicographic ordering used here is suitable if
 
6
-- the argument order is a strict partial order. The lexicographic
 
7
-- ordering itself can be either strict or non-strict, depending on
 
8
-- the value of a parameter.
 
9
 
 
10
module Relation.Binary.List.StrictLex where
 
11
 
 
12
open import Data.Empty
 
13
open import Data.Unit using (⊤; tt)
 
14
open import Data.Function
 
15
open import Data.Product
 
16
open import Data.Sum
 
17
open import Data.List
 
18
open import Level
 
19
open import Relation.Nullary
 
20
open import Relation.Binary
 
21
open import Relation.Binary.Consequences
 
22
open import Relation.Binary.List.Pointwise as Pointwise
 
23
   using ([]; _∷_; head; tail)
 
24
 
 
25
private
 
26
 module Dummy {A : Set} where
 
27
 
 
28
  data Lex (P : Set) (≈ < : Rel A zero) : Rel (List A) zero where
 
29
    base : P                           → Lex P ≈ < []       []
 
30
    halt : ∀ {y ys}                    → Lex P ≈ < []       (y ∷ ys)
 
31
    this : ∀ {x xs y ys} (x<y : < x y) → Lex P ≈ < (x ∷ xs) (y ∷ ys)
 
32
    next : ∀ {x xs y ys} (x≈y : ≈ x y)
 
33
           (xs⊴ys : Lex P ≈ < xs ys)   → Lex P ≈ < (x ∷ xs) (y ∷ ys)
 
34
 
 
35
  -- Strict lexicographic ordering.
 
36
 
 
37
  Lex-< : (≈ < : Rel A zero) → Rel (List A) zero
 
38
  Lex-< = Lex ⊥
 
39
 
 
40
  ¬[]<[] : ∀ {≈ <} → ¬ Lex-< ≈ < [] []
 
41
  ¬[]<[] (base ())
 
42
 
 
43
  -- Non-strict lexicographic ordering.
 
44
 
 
45
  Lex-≤ : (≈ < : Rel A zero) → Rel (List A) zero
 
46
  Lex-≤ = Lex ⊤
 
47
 
 
48
  -- Utilities.
 
49
 
 
50
  ¬≤-this : ∀ {P ≈ < x y xs ys} → ¬ ≈ x y → ¬ < x y →
 
51
            ¬ Lex P ≈ < (x ∷ xs) (y ∷ ys)
 
52
  ¬≤-this ¬x≈y ¬x<y (this x<y)       = ¬x<y x<y
 
53
  ¬≤-this ¬x≈y ¬x<y (next x≈y xs⊴ys) = ¬x≈y x≈y
 
54
 
 
55
  ¬≤-next : ∀ {P ≈ < x y xs ys} → ¬ < x y → ¬ Lex P ≈ < xs ys →
 
56
            ¬ Lex P ≈ < (x ∷ xs) (y ∷ ys)
 
57
  ¬≤-next ¬x<y ¬xs⊴ys (this x<y)       = ¬x<y x<y
 
58
  ¬≤-next ¬x<y ¬xs⊴ys (next x≈y xs⊴ys) = ¬xs⊴ys xs⊴ys
 
59
 
 
60
  ----------------------------------------------------------------------
 
61
  -- Properties
 
62
 
 
63
  ≤-reflexive : ∀ ≈ < → Pointwise.Rel ≈ ⇒ Lex-≤ ≈ <
 
64
  ≤-reflexive ≈ < []            = base tt
 
65
  ≤-reflexive ≈ < (x≈y ∷ xs≈ys) = next x≈y (≤-reflexive ≈ < xs≈ys)
 
66
 
 
67
  <-irreflexive : ∀ {≈ <} → Irreflexive ≈ < →
 
68
                  Irreflexive (Pointwise.Rel ≈) (Lex-< ≈ <)
 
69
  <-irreflexive irr []            (base ())
 
70
  <-irreflexive irr (x≈y ∷ xs≈ys) (this x<y)       = irr x≈y x<y
 
71
  <-irreflexive irr (x≈y ∷ xs≈ys) (next x≊y xs⊴ys) =
 
72
    <-irreflexive irr xs≈ys xs⊴ys
 
73
 
 
74
  transitive : ∀ {P ≈ <} →
 
75
               IsEquivalence ≈ → < Respects₂ ≈ → Transitive < →
 
76
               Transitive (Lex P ≈ <)
 
77
  transitive {P} {≈} {<} eq resp tr = trans
 
78
    where
 
79
    trans : Transitive (Lex P ≈ <)
 
80
    trans (base p)         (base _)         = base p
 
81
    trans (base y)         halt             = halt
 
82
    trans halt             (this y<z)       = halt
 
83
    trans halt             (next y≈z ys⊴zs) = halt
 
84
    trans (this x<y)       (this y<z)       = this (tr x<y y<z)
 
85
    trans (this x<y)       (next y≈z ys⊴zs) = this (proj₁ resp y≈z x<y)
 
86
    trans (next x≈y xs⊴ys) (this y<z)       =
 
87
       this (proj₂ resp (IsEquivalence.sym eq x≈y) y<z)
 
88
    trans (next x≈y xs⊴ys) (next y≈z ys⊴zs) =
 
89
       next (IsEquivalence.trans eq x≈y y≈z) (trans xs⊴ys ys⊴zs)
 
90
 
 
91
  antisymmetric : ∀ {P ≈ <} →
 
92
                  Symmetric ≈ → Irreflexive ≈ < →  Asymmetric < →
 
93
                  Antisymmetric (Pointwise.Rel ≈) (Lex P ≈ <)
 
94
  antisymmetric {P} {≈} {<} sym ir asym = as
 
95
    where
 
96
    as : Antisymmetric (Pointwise.Rel ≈) (Lex P ≈ <)
 
97
    as (base _)         (base _)         = []
 
98
    as halt             ()
 
99
    as (this x<y)       (this y<x)       = ⊥-elim (asym x<y y<x)
 
100
    as (this x<y)       (next y≈x ys⊴xs) = ⊥-elim (ir (sym y≈x) x<y)
 
101
    as (next x≈y xs⊴ys) (this y<x)       = ⊥-elim (ir (sym x≈y) y<x)
 
102
    as (next x≈y xs⊴ys) (next y≈x ys⊴xs) = x≈y ∷ as xs⊴ys ys⊴xs
 
103
 
 
104
  <-asymmetric : ∀ {≈ <} →
 
105
                 Symmetric ≈ → < Respects₂ ≈ → Asymmetric < →
 
106
                 Asymmetric (Lex-< ≈ <)
 
107
  <-asymmetric {≈} {<} sym resp as = asym
 
108
    where
 
109
    irrefl : Irreflexive ≈ <
 
110
    irrefl = asym⟶irr resp sym as
 
111
 
 
112
    asym : Asymmetric (Lex-< ≈ <)
 
113
    asym (base bot)       _                = bot
 
114
    asym halt             ()
 
115
    asym (this x<y)       (this y<x)       = as x<y y<x
 
116
    asym (this x<y)       (next y≈x ys⊴xs) = irrefl (sym y≈x) x<y
 
117
    asym (next x≈y xs⊴ys) (this y<x)       = irrefl (sym x≈y) y<x
 
118
    asym (next x≈y xs⊴ys) (next y≈x ys⊴xs) = asym xs⊴ys ys⊴xs
 
119
 
 
120
  respects₂ : ∀ {P ≈ <} →
 
121
              IsEquivalence ≈ → < Respects₂ ≈ →
 
122
              Lex P ≈ < Respects₂ Pointwise.Rel ≈
 
123
  respects₂ {P} {≈} {<} eq resp =
 
124
    (λ {xs} {ys} {zs} → resp¹ {xs} {ys} {zs}) ,
 
125
    (λ {xs} {ys} {zs} → resp² {xs} {ys} {zs})
 
126
    where
 
127
    resp¹ : ∀ {xs} → Lex P ≈ < xs Respects Pointwise.Rel ≈
 
128
    resp¹ []            xs⊴[]            = xs⊴[]
 
129
    resp¹ (x≈y ∷ xs≈ys) halt             = halt
 
130
    resp¹ (x≈y ∷ xs≈ys) (this z<x)       = this (proj₁ resp x≈y z<x)
 
131
    resp¹ (x≈y ∷ xs≈ys) (next z≈x zs⊴xs) =
 
132
      next (Eq.trans z≈x x≈y) (resp¹ xs≈ys zs⊴xs)
 
133
      where module Eq = IsEquivalence eq
 
134
 
 
135
    resp² : ∀ {ys} → flip (Lex P ≈ <) ys Respects Pointwise.Rel ≈
 
136
    resp² []            []⊴ys            = []⊴ys
 
137
    resp² (x≈z ∷ xs≈zs) (this x<y)       = this (proj₂ resp x≈z x<y)
 
138
    resp² (x≈z ∷ xs≈zs) (next x≈y xs⊴ys) =
 
139
      next (Eq.trans (Eq.sym x≈z) x≈y) (resp² xs≈zs xs⊴ys)
 
140
      where module Eq = IsEquivalence eq
 
141
 
 
142
  decidable : ∀ {P ≈ <} →
 
143
              Dec P → Decidable ≈ → Decidable < →
 
144
              Decidable (Lex P ≈ <)
 
145
  decidable {P} {≈} {<} dec-P dec-≈ dec-< = dec
 
146
    where
 
147
    dec : Decidable (Lex P ≈ <)
 
148
    dec []       []       with dec-P
 
149
    ...                   | yes p = yes (base p)
 
150
    ...                   | no ¬p = no helper
 
151
      where
 
152
      helper : ¬ Lex P ≈ < [] []
 
153
      helper (base p) = ¬p p
 
154
    dec []       (y ∷ ys) = yes halt
 
155
    dec (x ∷ xs) []       = no (λ ())
 
156
    dec (x ∷ xs) (y ∷ ys) with dec-< x y
 
157
    ... | yes x<y = yes (this x<y)
 
158
    ... | no ¬x<y with dec-≈ x y
 
159
    ...           | no ¬x≈y = no (¬≤-this ¬x≈y ¬x<y)
 
160
    ...           | yes x≈y with dec xs ys
 
161
    ...                     | yes xs⊴ys = yes (next x≈y xs⊴ys)
 
162
    ...                     | no ¬xs⊴ys = no (¬≤-next ¬x<y ¬xs⊴ys)
 
163
 
 
164
  <-decidable : ∀ {≈ <} →
 
165
                Decidable ≈ → Decidable < → Decidable (Lex-< ≈ <)
 
166
  <-decidable = decidable (no id)
 
167
 
 
168
  ≤-decidable : ∀ {≈ <} →
 
169
                Decidable ≈ → Decidable < → Decidable (Lex-≤ ≈ <)
 
170
  ≤-decidable = decidable (yes tt)
 
171
 
 
172
  -- Note that trichotomy is an unnecessarily strong precondition for
 
173
  -- the following lemma.
 
174
 
 
175
  ≤-total : ∀ {≈ <} →
 
176
            Symmetric ≈ → Trichotomous ≈ < → Total (Lex-≤ ≈ <)
 
177
  ≤-total {≈} {<} sym tri = total
 
178
    where
 
179
    total : Total (Lex-≤ ≈ <)
 
180
    total []       []       = inj₁ (base tt)
 
181
    total []       (x ∷ xs) = inj₁ halt
 
182
    total (x ∷ xs) []       = inj₂ halt
 
183
    total (x ∷ xs) (y ∷ ys) with tri x y
 
184
    ... | tri< x<y _ _ = inj₁ (this x<y)
 
185
    ... | tri> _ _ y<x = inj₂ (this y<x)
 
186
    ... | tri≈ _ x≈y _ with total xs ys
 
187
    ...                | inj₁ xs≲ys = inj₁ (next      x≈y  xs≲ys)
 
188
    ...                | inj₂ ys≲xs = inj₂ (next (sym x≈y) ys≲xs)
 
189
 
 
190
  <-compare : ∀ {≈ <} →
 
191
              Symmetric ≈ → Trichotomous ≈ < →
 
192
              Trichotomous (Pointwise.Rel ≈) (Lex-< ≈ <)
 
193
  <-compare {≈} {<} sym tri = cmp
 
194
   where
 
195
   cmp : Trichotomous (Pointwise.Rel ≈) (Lex-< ≈ <)
 
196
   cmp []       []       = tri≈ ¬[]<[] [] ¬[]<[]
 
197
   cmp []       (y ∷ ys) = tri< halt (λ ()) (λ ())
 
198
   cmp (x ∷ xs) []       = tri> (λ ()) (λ ()) halt
 
199
   cmp (x ∷ xs) (y ∷ ys) with tri x y
 
200
   ... | tri< x<y ¬x≈y ¬y<x =
 
201
         tri< (this x<y) (¬x≈y ∘ head) (¬≤-this (¬x≈y ∘ sym) ¬y<x)
 
202
   ... | tri> ¬x<y ¬x≈y y<x =
 
203
         tri> (¬≤-this ¬x≈y ¬x<y) (¬x≈y ∘ head) (this y<x)
 
204
   ... | tri≈ ¬x<y x≈y ¬y<x with cmp xs ys
 
205
   ...    | tri< xs<ys ¬xs≈ys ¬ys<xs =
 
206
            tri< (next x≈y xs<ys) (¬xs≈ys ∘ tail) (¬≤-next ¬y<x ¬ys<xs)
 
207
   ...    | tri≈ ¬xs<ys xs≈ys ¬ys<xs =
 
208
            tri≈ (¬≤-next ¬x<y ¬xs<ys) (x≈y ∷ xs≈ys) (¬≤-next ¬y<x ¬ys<xs)
 
209
   ...    | tri> ¬xs<ys ¬xs≈ys ys<xs =
 
210
            tri> (¬≤-next ¬x<y ¬xs<ys) (¬xs≈ys ∘ tail) (next (sym x≈y) ys<xs)
 
211
 
 
212
  -- Some collections of properties which are preserved by Lex-≤ or
 
213
  -- Lex-<.
 
214
 
 
215
  ≤-isPreorder : ∀ {≈ <} →
 
216
                 IsEquivalence ≈ → Transitive < → < Respects₂ ≈ →
 
217
                 IsPreorder (Pointwise.Rel ≈) (Lex-≤ ≈ <)
 
218
  ≤-isPreorder {≈} {<} eq tr resp = record
 
219
    { isEquivalence = Pointwise.isEquivalence eq
 
220
    ; reflexive     = ≤-reflexive ≈ <
 
221
    ; trans         = transitive eq resp tr
 
222
    ; ∼-resp-≈      = respects₂ eq resp
 
223
    }
 
224
 
 
225
  ≤-isPartialOrder : ∀ {≈ <} →
 
226
                     IsStrictPartialOrder ≈ < →
 
227
                     IsPartialOrder (Pointwise.Rel ≈) (Lex-≤ ≈ <)
 
228
  ≤-isPartialOrder {≈} {<} spo = record
 
229
    { isPreorder = ≤-isPreorder isEquivalence trans <-resp-≈
 
230
    ; antisym    = antisymmetric Eq.sym irrefl
 
231
                     (trans∧irr⟶asym {≈ = ≈} {<} Eq.refl trans irrefl)
 
232
    } where open IsStrictPartialOrder spo
 
233
 
 
234
  ≤-isTotalOrder : ∀ {≈ <} →
 
235
                   IsStrictTotalOrder ≈ < →
 
236
                   IsTotalOrder (Pointwise.Rel ≈) (Lex-≤ ≈ <)
 
237
  ≤-isTotalOrder sto = record
 
238
    { isPartialOrder =
 
239
        ≤-isPartialOrder (record
 
240
          { isEquivalence = isEquivalence
 
241
          ; irrefl        = tri⟶irr <-resp-≈ Eq.sym compare
 
242
          ; trans         = trans
 
243
          ; <-resp-≈      = <-resp-≈
 
244
          })
 
245
    ; total          = ≤-total Eq.sym compare
 
246
    } where open IsStrictTotalOrder sto
 
247
 
 
248
  ≤-isDecTotalOrder : ∀ {≈ <} →
 
249
                      IsStrictTotalOrder ≈ < →
 
250
                      IsDecTotalOrder (Pointwise.Rel ≈) (Lex-≤ ≈ <)
 
251
  ≤-isDecTotalOrder sto = record
 
252
    { isTotalOrder = ≤-isTotalOrder sto
 
253
    ; _≟_          = Pointwise.decidable _≟_
 
254
    ; _≤?_         = ≤-decidable _≟_ (tri⟶dec< compare)
 
255
    } where open IsStrictTotalOrder sto
 
256
 
 
257
  <-isStrictPartialOrder
 
258
    : ∀ {≈ <} → IsStrictPartialOrder ≈ < →
 
259
      IsStrictPartialOrder (Pointwise.Rel ≈) (Lex-< ≈ <)
 
260
  <-isStrictPartialOrder spo = record
 
261
    { isEquivalence = Pointwise.isEquivalence isEquivalence
 
262
    ; irrefl        = <-irreflexive irrefl
 
263
    ; trans         = transitive isEquivalence <-resp-≈ trans
 
264
    ; <-resp-≈      = respects₂ isEquivalence <-resp-≈
 
265
    } where open IsStrictPartialOrder spo
 
266
 
 
267
  <-isStrictTotalOrder
 
268
    : ∀ {≈ <} → IsStrictTotalOrder ≈ < →
 
269
      IsStrictTotalOrder (Pointwise.Rel ≈) (Lex-< ≈ <)
 
270
  <-isStrictTotalOrder sto = record
 
271
    { isEquivalence = Pointwise.isEquivalence isEquivalence
 
272
    ; trans         = transitive isEquivalence <-resp-≈ trans
 
273
    ; compare       = <-compare Eq.sym compare
 
274
    ; <-resp-≈      = respects₂ isEquivalence <-resp-≈
 
275
    } where open IsStrictTotalOrder sto
 
276
 
 
277
open Dummy public
 
278
 
 
279
-- "Packages" (e.g. preorders) can also be handled.
 
280
 
 
281
≤-preorder : Preorder _ _ _ → Preorder _ _ _
 
282
≤-preorder pre = record
 
283
  { isPreorder = ≤-isPreorder isEquivalence trans ∼-resp-≈
 
284
  } where open Preorder pre
 
285
 
 
286
≤-partialOrder : StrictPartialOrder _ _ _ → Poset _ _ _
 
287
≤-partialOrder spo = record
 
288
  { isPartialOrder = ≤-isPartialOrder isStrictPartialOrder
 
289
  } where open StrictPartialOrder spo
 
290
 
 
291
≤-decTotalOrder : StrictTotalOrder _ _ _ → DecTotalOrder _ _ _
 
292
≤-decTotalOrder sto = record
 
293
  { isDecTotalOrder = ≤-isDecTotalOrder isStrictTotalOrder
 
294
  } where open StrictTotalOrder sto
 
295
 
 
296
<-strictPartialOrder :
 
297
  StrictPartialOrder _ _ _ → StrictPartialOrder _ _ _
 
298
<-strictPartialOrder spo = record
 
299
  { isStrictPartialOrder = <-isStrictPartialOrder isStrictPartialOrder
 
300
  } where open StrictPartialOrder spo
 
301
 
 
302
<-strictTotalOrder : StrictTotalOrder _ _ _ → StrictTotalOrder _ _ _
 
303
<-strictTotalOrder sto = record
 
304
  { isStrictTotalOrder = <-isStrictTotalOrder isStrictTotalOrder
 
305
  } where open StrictTotalOrder sto