~ubuntu-branches/ubuntu/saucy/agda-stdlib/saucy

« back to all changes in this revision

Viewing changes to src/Function/Related.agda

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2011-11-29 17:00:35 UTC
  • mfrom: (2.1.4 sid)
  • Revision ID: package-import@ubuntu.com-20111129170035-be8cbok8ojft5tjl
Tags: 0.6~darcs20111129t1640-1
* [ef445ab] Imported Upstream version 0.6~darcs20111129t1640
  + Darcs snapshot required for Agda 2.3.0 compatibility
* [f801f83] Update BDs and deps to require Agda 2.3.0
* [c52be90] Use 3.0 (quilt) for bz2 orig

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
------------------------------------------------------------------------
 
2
-- The Agda standard library
 
3
--
 
4
-- A universe which includes several kinds of "relatedness" for sets,
 
5
-- such as equivalences, surjections and bijections
 
6
------------------------------------------------------------------------
 
7
 
 
8
module Function.Related where
 
9
 
 
10
open import Level
 
11
open import Function
 
12
open import Function.Equality using (_⟨$⟩_)
 
13
open import Function.Equivalence as Eq      using (Equivalence)
 
14
open import Function.Injection   as Inj     using (Injection; _↣_)
 
15
open import Function.Inverse     as Inv     using (Inverse; _↔_)
 
16
open import Function.LeftInverse as LeftInv using (LeftInverse)
 
17
open import Function.Surjection  as Surj    using (Surjection)
 
18
open import Relation.Binary
 
19
open import Relation.Binary.PropositionalEquality as P using (_≡_)
 
20
 
 
21
------------------------------------------------------------------------
 
22
-- Wrapper types
 
23
 
 
24
-- Synonyms which are used to make _∼[_]_ below "constructor-headed"
 
25
-- (which implies that Agda can deduce the universe code from an
 
26
-- expression matching any of the right-hand sides).
 
27
 
 
28
record _←_ {a b} (A : Set a) (B : Set b) : Set (a ⊔ b) where
 
29
  constructor lam
 
30
  field app-← : B → A
 
31
 
 
32
open _←_ public
 
33
 
 
34
record _↢_ {a b} (A : Set a) (B : Set b) : Set (a ⊔ b) where
 
35
  constructor lam
 
36
  field app-↢ : B ↣ A
 
37
 
 
38
open _↢_ public
 
39
 
 
40
------------------------------------------------------------------------
 
41
-- Relatedness
 
42
 
 
43
-- There are several kinds of "relatedness".
 
44
 
 
45
-- The idea to include kinds other than equivalence and bijection came
 
46
-- from Simon Thompson and Bengt Nordström. /NAD
 
47
 
 
48
data Kind : Set where
 
49
  implication reverse-implication
 
50
    equivalence
 
51
    injection reverse-injection
 
52
    left-inverse surjection
 
53
    bijection
 
54
    : Kind
 
55
 
 
56
-- Interpretation of the codes above. The code "bijection" is
 
57
-- interpreted as Inverse rather than Bijection; the two types are
 
58
-- equivalent.
 
59
 
 
60
infix 4 _∼[_]_
 
61
 
 
62
_∼[_]_ : ∀ {ℓ₁ ℓ₂} → Set ℓ₁ → Kind → Set ℓ₂ → Set _
 
63
A ∼[ implication         ] B = A → B
 
64
A ∼[ reverse-implication ] B = A ← B
 
65
A ∼[ equivalence         ] B = Equivalence (P.setoid A) (P.setoid B)
 
66
A ∼[ injection           ] B = Injection   (P.setoid A) (P.setoid B)
 
67
A ∼[ reverse-injection   ] B = A ↢ B
 
68
A ∼[ left-inverse        ] B = LeftInverse (P.setoid A) (P.setoid B)
 
69
A ∼[ surjection          ] B = Surjection  (P.setoid A) (P.setoid B)
 
70
A ∼[ bijection           ] B = Inverse     (P.setoid A) (P.setoid B)
 
71
 
 
72
-- A non-infix synonym.
 
73
 
 
74
Related : Kind → ∀ {ℓ₁ ℓ₂} → Set ℓ₁ → Set ℓ₂ → Set _
 
75
Related k A B = A ∼[ k ] B
 
76
 
 
77
-- The bijective equality implies any kind of relatedness.
 
78
 
 
79
↔⇒ : ∀ {k x y} {X : Set x} {Y : Set y} →
 
80
     X ∼[ bijection ] Y → X ∼[ k ] Y
 
81
↔⇒ {implication}         = _⟨$⟩_ ∘ Inverse.to
 
82
↔⇒ {reverse-implication} = lam ∘′ _⟨$⟩_ ∘ Inverse.from
 
83
↔⇒ {equivalence}         = Inverse.equivalence
 
84
↔⇒ {injection}           = Inverse.injection
 
85
↔⇒ {reverse-injection}   = lam ∘′ Inverse.injection ∘ Inv.sym
 
86
↔⇒ {left-inverse}        = Inverse.left-inverse
 
87
↔⇒ {surjection}          = Inverse.surjection
 
88
↔⇒ {bijection}           = id
 
89
 
 
90
-- Actual equality also implies any kind of relatedness.
 
91
 
 
92
≡⇒ : ∀ {k ℓ} {X Y : Set ℓ} → X ≡ Y → X ∼[ k ] Y
 
93
≡⇒ P.refl = ↔⇒ Inv.id
 
94
 
 
95
------------------------------------------------------------------------
 
96
-- Special kinds of kinds
 
97
 
 
98
-- Kinds whose interpretation is symmetric.
 
99
 
 
100
data Symmetric-kind : Set where
 
101
  equivalence bijection : Symmetric-kind
 
102
 
 
103
-- Forgetful map.
 
104
 
 
105
⌊_⌋ : Symmetric-kind → Kind
 
106
⌊ equivalence ⌋ = equivalence
 
107
⌊ bijection   ⌋ = bijection
 
108
 
 
109
-- The proof of symmetry can be found below.
 
110
 
 
111
-- Kinds whose interpretation include a function which "goes in the
 
112
-- forward direction".
 
113
 
 
114
data Forward-kind : Set where
 
115
  implication equivalence injection
 
116
    left-inverse surjection bijection : Forward-kind
 
117
 
 
118
-- Forgetful map.
 
119
 
 
120
⌊_⌋→ : Forward-kind → Kind
 
121
⌊ implication  ⌋→ = implication
 
122
⌊ equivalence  ⌋→ = equivalence
 
123
⌊ injection    ⌋→ = injection
 
124
⌊ left-inverse ⌋→ = left-inverse
 
125
⌊ surjection   ⌋→ = surjection
 
126
⌊ bijection    ⌋→ = bijection
 
127
 
 
128
-- The function.
 
129
 
 
130
⇒→ : ∀ {k x y} {X : Set x} {Y : Set y} → X ∼[ ⌊ k ⌋→ ] Y → X → Y
 
131
⇒→ {implication}  = id
 
132
⇒→ {equivalence}  = _⟨$⟩_ ∘ Equivalence.to
 
133
⇒→ {injection}    = _⟨$⟩_ ∘ Injection.to
 
134
⇒→ {left-inverse} = _⟨$⟩_ ∘ LeftInverse.to
 
135
⇒→ {surjection}   = _⟨$⟩_ ∘ Surjection.to
 
136
⇒→ {bijection}    = _⟨$⟩_ ∘ Inverse.to
 
137
 
 
138
-- Kinds whose interpretation include a function which "goes backwards".
 
139
 
 
140
data Backward-kind : Set where
 
141
  reverse-implication equivalence reverse-injection
 
142
    left-inverse surjection bijection : Backward-kind
 
143
 
 
144
-- Forgetful map.
 
145
 
 
146
⌊_⌋← : Backward-kind → Kind
 
147
⌊ reverse-implication ⌋← = reverse-implication
 
148
⌊ equivalence         ⌋← = equivalence
 
149
⌊ reverse-injection   ⌋← = reverse-injection
 
150
⌊ left-inverse        ⌋← = left-inverse
 
151
⌊ surjection          ⌋← = surjection
 
152
⌊ bijection           ⌋← = bijection
 
153
 
 
154
-- The function.
 
155
 
 
156
⇒← : ∀ {k x y} {X : Set x} {Y : Set y} → X ∼[ ⌊ k ⌋← ] Y → Y → X
 
157
⇒← {reverse-implication} = app-←
 
158
⇒← {equivalence}         = _⟨$⟩_ ∘ Equivalence.from
 
159
⇒← {reverse-injection}   = _⟨$⟩_ ∘ Injection.to ∘ app-↢
 
160
⇒← {left-inverse}        = _⟨$⟩_ ∘ LeftInverse.from
 
161
⇒← {surjection}          = _⟨$⟩_ ∘ Surjection.from
 
162
⇒← {bijection}           = _⟨$⟩_ ∘ Inverse.from
 
163
 
 
164
-- Kinds whose interpretation include functions going in both
 
165
-- directions.
 
166
 
 
167
data Equivalence-kind : Set where
 
168
    equivalence left-inverse surjection bijection : Equivalence-kind
 
169
 
 
170
-- Forgetful map.
 
171
 
 
172
⌊_⌋⇔ : Equivalence-kind → Kind
 
173
⌊ equivalence  ⌋⇔ = equivalence
 
174
⌊ left-inverse ⌋⇔ = left-inverse
 
175
⌊ surjection   ⌋⇔ = surjection
 
176
⌊ bijection    ⌋⇔ = bijection
 
177
 
 
178
-- The functions.
 
179
 
 
180
⇒⇔ : ∀ {k x y} {X : Set x} {Y : Set y} →
 
181
     X ∼[ ⌊ k ⌋⇔ ] Y → X ∼[ equivalence ] Y
 
182
⇒⇔ {equivalence}  = id
 
183
⇒⇔ {left-inverse} = LeftInverse.equivalence
 
184
⇒⇔ {surjection}   = Surjection.equivalence
 
185
⇒⇔ {bijection}    = Inverse.equivalence
 
186
 
 
187
-- Conversions between special kinds.
 
188
 
 
189
⇔⌊_⌋ : Symmetric-kind → Equivalence-kind
 
190
⇔⌊ equivalence ⌋ = equivalence
 
191
⇔⌊ bijection   ⌋ = bijection
 
192
 
 
193
→⌊_⌋ : Equivalence-kind → Forward-kind
 
194
→⌊ equivalence  ⌋ = equivalence
 
195
→⌊ left-inverse ⌋ = left-inverse
 
196
→⌊ surjection   ⌋ = surjection
 
197
→⌊ bijection    ⌋ = bijection
 
198
 
 
199
←⌊_⌋ : Equivalence-kind → Backward-kind
 
200
←⌊ equivalence  ⌋ = equivalence
 
201
←⌊ left-inverse ⌋ = left-inverse
 
202
←⌊ surjection   ⌋ = surjection
 
203
←⌊ bijection    ⌋ = bijection
 
204
 
 
205
------------------------------------------------------------------------
 
206
-- Opposites
 
207
 
 
208
-- For every kind there is an opposite kind.
 
209
 
 
210
_op : Kind → Kind
 
211
implication         op = reverse-implication
 
212
reverse-implication op = implication
 
213
equivalence         op = equivalence
 
214
injection           op = reverse-injection
 
215
reverse-injection   op = injection
 
216
left-inverse        op = surjection
 
217
surjection          op = left-inverse
 
218
bijection           op = bijection
 
219
 
 
220
-- For every morphism there is a corresponding reverse morphism of the
 
221
-- opposite kind.
 
222
 
 
223
reverse : ∀ {k a b} {A : Set a} {B : Set b} →
 
224
          A ∼[ k ] B → B ∼[ k op ] A
 
225
reverse {implication}         = lam
 
226
reverse {reverse-implication} = app-←
 
227
reverse {equivalence}         = Eq.sym
 
228
reverse {injection}           = lam
 
229
reverse {reverse-injection}   = app-↢
 
230
reverse {left-inverse}        = Surj.fromRightInverse
 
231
reverse {surjection}          = Surjection.right-inverse
 
232
reverse {bijection}           = Inv.sym
 
233
 
 
234
------------------------------------------------------------------------
 
235
-- Equational reasoning
 
236
 
 
237
-- Equational reasoning for related things.
 
238
 
 
239
module EquationalReasoning where
 
240
 
 
241
  private
 
242
 
 
243
    refl : ∀ {k ℓ} → Reflexive (Related k {ℓ})
 
244
    refl {implication}         = id
 
245
    refl {reverse-implication} = lam id
 
246
    refl {equivalence}         = Eq.id
 
247
    refl {injection}           = Inj.id
 
248
    refl {reverse-injection}   = lam Inj.id
 
249
    refl {left-inverse}        = LeftInv.id
 
250
    refl {surjection}          = Surj.id
 
251
    refl {bijection}           = Inv.id
 
252
 
 
253
    trans : ∀ {k ℓ₁ ℓ₂ ℓ₃} →
 
254
            Trans (Related k {ℓ₁} {ℓ₂})
 
255
                  (Related k {ℓ₂} {ℓ₃})
 
256
                  (Related k {ℓ₁} {ℓ₃})
 
257
    trans {implication}         = flip _∘′_
 
258
    trans {reverse-implication} = λ f g → lam (app-← f ∘ app-← g)
 
259
    trans {equivalence}         = flip Eq._∘_
 
260
    trans {injection}           = flip Inj._∘_
 
261
    trans {reverse-injection}   = λ f g → lam (Inj._∘_ (app-↢ f) (app-↢ g))
 
262
    trans {left-inverse}        = flip LeftInv._∘_
 
263
    trans {surjection}          = flip Surj._∘_
 
264
    trans {bijection}           = flip Inv._∘_
 
265
 
 
266
  sym : ∀ {k ℓ₁ ℓ₂} →
 
267
        Sym (Related ⌊ k ⌋ {ℓ₁} {ℓ₂})
 
268
            (Related ⌊ k ⌋ {ℓ₂} {ℓ₁})
 
269
  sym {equivalence} = Eq.sym
 
270
  sym {bijection}   = Inv.sym
 
271
 
 
272
  infix  2 _∎
 
273
  infixr 2 _∼⟨_⟩_ _↔⟨_⟩_ _≡⟨_⟩_
 
274
 
 
275
  _∼⟨_⟩_ : ∀ {k x y z} (X : Set x) {Y : Set y} {Z : Set z} →
 
276
           X ∼[ k ] Y → Y ∼[ k ] Z → X ∼[ k ] Z
 
277
  _ ∼⟨ X↝Y ⟩ Y↝Z = trans X↝Y Y↝Z
 
278
 
 
279
  -- Isomorphisms can be combined with any other kind of relatedness.
 
280
 
 
281
  _↔⟨_⟩_ : ∀ {k x y z} (X : Set x) {Y : Set y} {Z : Set z} →
 
282
           X ↔ Y → Y ∼[ k ] Z → X ∼[ k ] Z
 
283
  X ↔⟨ X↔Y ⟩ Y⇔Z = X ∼⟨ ↔⇒ X↔Y ⟩ Y⇔Z
 
284
 
 
285
  _≡⟨_⟩_ : ∀ {k ℓ z} (X : Set ℓ) {Y : Set ℓ} {Z : Set z} →
 
286
           X ≡ Y → Y ∼[ k ] Z → X ∼[ k ] Z
 
287
  X ≡⟨ X≡Y ⟩ Y⇔Z = X ∼⟨ ≡⇒ X≡Y ⟩ Y⇔Z
 
288
 
 
289
  _∎ : ∀ {k x} (X : Set x) → X ∼[ k ] X
 
290
  X ∎ = refl
 
291
 
 
292
-- For a symmetric kind and a fixed universe level we can construct a
 
293
-- setoid.
 
294
 
 
295
setoid : Symmetric-kind → (ℓ : Level) → Setoid _ _
 
296
setoid k ℓ = record
 
297
  { Carrier       = Set ℓ
 
298
  ; _≈_           = Related ⌊ k ⌋
 
299
  ; isEquivalence =
 
300
      record {refl = _ ∎; sym = sym; trans = _∼⟨_⟩_ _}
 
301
  } where open EquationalReasoning
 
302
 
 
303
-- For an arbitrary kind and a fixed universe level we can construct a
 
304
-- preorder.
 
305
 
 
306
preorder : Kind → (ℓ : Level) → Preorder _ _ _
 
307
preorder k ℓ = record
 
308
  { Carrier    = Set ℓ
 
309
  ; _≈_        = _↔_
 
310
  ; _∼_        = Related k
 
311
  ; isPreorder = record
 
312
    { isEquivalence = Setoid.isEquivalence (setoid bijection ℓ)
 
313
    ; reflexive     = ↔⇒
 
314
    ; trans         = _∼⟨_⟩_ _
 
315
    }
 
316
  } where open EquationalReasoning
 
317
 
 
318
------------------------------------------------------------------------
 
319
-- Some induced relations
 
320
 
 
321
-- Every unary relation induces a preorder and, for symmetric kinds,
 
322
-- an equivalence. (No claim is made that these relations are unique.)
 
323
 
 
324
InducedRelation₁ : Kind → ∀ {a s} {A : Set a} →
 
325
                   (A → Set s) → A → A → Set _
 
326
InducedRelation₁ k S = λ x y → S x ∼[ k ] S y
 
327
 
 
328
InducedPreorder₁ : Kind → ∀ {a s} {A : Set a} →
 
329
                   (A → Set s) → Preorder _ _ _
 
330
InducedPreorder₁ k S = record
 
331
  { _≈_        = P._≡_
 
332
  ; _∼_        = InducedRelation₁ k S
 
333
  ; isPreorder = record
 
334
    { isEquivalence = P.isEquivalence
 
335
    ; reflexive     = reflexive ∘
 
336
                      Setoid.reflexive (setoid bijection _) ∘
 
337
                      P.cong S
 
338
    ; trans         = trans
 
339
    }
 
340
  } where open Preorder (preorder _ _)
 
341
 
 
342
InducedEquivalence₁ : Symmetric-kind → ∀ {a s} {A : Set a} →
 
343
                      (A → Set s) → Setoid _ _
 
344
InducedEquivalence₁ k S = record
 
345
  { _≈_           = InducedRelation₁ ⌊ k ⌋ S
 
346
  ; isEquivalence = record {refl = refl; sym = sym; trans = trans}
 
347
  } where open Setoid (setoid _ _)
 
348
 
 
349
-- Every binary relation induces a preorder and, for symmetric kinds,
 
350
-- an equivalence. (No claim is made that these relations are unique.)
 
351
 
 
352
InducedRelation₂ : Kind → ∀ {a b s} {A : Set a} {B : Set b} →
 
353
                   (A → B → Set s) → B → B → Set _
 
354
InducedRelation₂ k _S_ = λ x y → ∀ {z} → (z S x) ∼[ k ] (z S y)
 
355
 
 
356
InducedPreorder₂ : Kind → ∀ {a b s} {A : Set a} {B : Set b} →
 
357
                   (A → B → Set s) → Preorder _ _ _
 
358
InducedPreorder₂ k _S_ = record
 
359
  { _≈_        = P._≡_
 
360
  ; _∼_        = InducedRelation₂ k _S_
 
361
  ; isPreorder = record
 
362
    { isEquivalence = P.isEquivalence
 
363
    ; reflexive     = λ x≡y {z} →
 
364
                        reflexive $
 
365
                        Setoid.reflexive (setoid bijection _) $
 
366
                        P.cong (_S_ z) x≡y
 
367
 
 
368
    ; trans         = λ i↝j j↝k → trans i↝j j↝k
 
369
    }
 
370
  } where open Preorder (preorder _ _)
 
371
 
 
372
InducedEquivalence₂ : Symmetric-kind →
 
373
                      ∀ {a b s} {A : Set a} {B : Set b} →
 
374
                      (A → B → Set s) → Setoid _ _
 
375
InducedEquivalence₂ k _S_ = record
 
376
  { _≈_           = InducedRelation₂ ⌊ k ⌋ _S_
 
377
  ; isEquivalence = record
 
378
    { refl  = refl
 
379
    ; sym   = λ i↝j → sym i↝j
 
380
    ; trans = λ i↝j j↝k → trans i↝j j↝k
 
381
    }
 
382
  } where open Setoid (setoid _ _)