~ubuntu-branches/ubuntu/precise/agda-stdlib/precise

« back to all changes in this revision

Viewing changes to src/Function/Inverse/TypeIsomorphisms.agda

  • Committer: Bazaar Package Importer
  • Author(s): Iain Lane
  • Date: 2011-02-25 22:28:40 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110225222840-jt16gl302kca7h0g
Tags: 0.5-1~ubuntu1

* Upload to Ubuntu from Debian's VCS due to delays in unstable caused by
  the GHC 7 transition (LP: #725364)
* [ba20206] Make package architecture independent (Closes: #573807, #598708,
  #599958)
* [0fb0600] Standards-Version → 3.9.1, no changes required
* [d3f13b8] Update required Agda version to 2.2.8
* [cc1f5c8] Imported Upstream version 0.4
* [2c82171] Add watch file
* [9251e0b] Imported Upstream version 0.5
* [0518fa6] No longer need procps | hurd BD as we no longer have the ticker
* [daf2445] Don't use upstream's make install — handled ourselves by
  dh_install
* [1b86533] Update watchfile to point at new location
* [637f47d] Remove debian/gbp.conf as we are no longer building for exp
* [cc88671] Require Agda 2.2.10
* [e99dab5] Set maximum stack size to 1G to prevent overflows in the build
* [251cd1d] Run the test suite manually
* [a7db697] Set the variable in the emacs loading script properly

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
------------------------------------------------------------------------
 
2
-- Various basic type isomorphisms
 
3
------------------------------------------------------------------------
 
4
 
 
5
{-# OPTIONS --universe-polymorphism #-}
 
6
 
 
7
module Function.Inverse.TypeIsomorphisms where
 
8
 
 
9
open import Algebra
 
10
import Algebra.FunctionProperties as FP
 
11
open import Data.Empty
 
12
open import Data.Product as Prod hiding (swap)
 
13
open import Data.Sum as Sum
 
14
open import Data.Unit
 
15
open import Level
 
16
open import Function
 
17
open import Function.Equality using (_⟨$⟩_)
 
18
open import Function.Equivalence
 
19
  using (_⇔_; equivalent; module Equivalent)
 
20
open import Function.Inverse as Inv
 
21
  using (Kind; Isomorphism; _⇿_; module Inverse)
 
22
open import Relation.Binary
 
23
open import Relation.Binary.Product.Pointwise
 
24
open import Relation.Binary.PropositionalEquality as P using (_≡_; _≗_)
 
25
open import Relation.Binary.Sum
 
26
open import Relation.Nullary
 
27
 
 
28
------------------------------------------------------------------------
 
29
-- ⊥, ⊤, _×_ and _⊎_ form a commutative semiring
 
30
 
 
31
×-CommutativeMonoid : Kind → (ℓ : Level) → CommutativeMonoid _ _
 
32
×-CommutativeMonoid k ℓ = record
 
33
  { Carrier             = Set ℓ
 
34
  ; _≈_                 = Isomorphism k
 
35
  ; _∙_                 = _×_
 
36
  ; ε                   = Lift ⊤
 
37
  ; isCommutativeMonoid = record
 
38
    { isSemigroup   = record
 
39
      { isEquivalence = Setoid.isEquivalence $
 
40
                          Inv.Isomorphism-setoid k ℓ
 
41
      ; assoc         = λ A B C → Inv.⇿⇒ $ assoc A B C
 
42
      ; ∙-cong        = ×-cong k
 
43
      }
 
44
    ; identityˡ = λ A → Inv.⇿⇒ $ left-identity A
 
45
    ; comm      = λ A B → Inv.⇿⇒ $ comm A B
 
46
    }
 
47
  }
 
48
  where
 
49
  open FP _⇿_
 
50
 
 
51
  ×-cong : ∀ k {A B C D : Set ℓ} →
 
52
           Isomorphism k A B → Isomorphism k C D →
 
53
           Isomorphism k (A × C) (B × D)
 
54
  ×-cong Inv.equivalent = _×-⇔_
 
55
  ×-cong Inv.inverse    = _×-⇿_
 
56
 
 
57
  left-identity : LeftIdentity (Lift {ℓ = ℓ} ⊤) _×_
 
58
  left-identity _ = record
 
59
    { to         = P.→-to-⟶ $ proj₂ {a = ℓ} {b = ℓ}
 
60
    ; from       = P.→-to-⟶ {b₁ = ℓ} λ y → _ , y
 
61
    ; inverse-of = record
 
62
      { left-inverse-of  = λ _ → P.refl
 
63
      ; right-inverse-of = λ _ → P.refl
 
64
      }
 
65
    }
 
66
 
 
67
  assoc : Associative _×_
 
68
  assoc _ _ _ = record
 
69
    { to         = P.→-to-⟶ {a = ℓ} {b₁ = ℓ} λ t → (proj₁ (proj₁ t) , (proj₂ (proj₁ t) , proj₂ t))
 
70
    ; from       = P.→-to-⟶ {a = ℓ} {b₁ = ℓ} λ t → ((proj₁ t , proj₁ (proj₂ t)) , proj₂ (proj₂ t))
 
71
    ; inverse-of = record
 
72
      { left-inverse-of  = λ _ → P.refl
 
73
      ; right-inverse-of = λ _ → P.refl
 
74
      }
 
75
    }
 
76
 
 
77
  comm : Commutative _×_
 
78
  comm _ _ = record
 
79
    { to         = P.→-to-⟶ $ Prod.swap {a = ℓ} {b = ℓ}
 
80
    ; from       = P.→-to-⟶ $ Prod.swap {a = ℓ} {b = ℓ}
 
81
    ; inverse-of = record
 
82
      { left-inverse-of  = λ _ → P.refl
 
83
      ; right-inverse-of = λ _ → P.refl
 
84
      }
 
85
    }
 
86
 
 
87
⊎-CommutativeMonoid : Kind → (ℓ : Level) → CommutativeMonoid _ _
 
88
⊎-CommutativeMonoid k ℓ = record
 
89
  { Carrier             = Set ℓ
 
90
  ; _≈_                 = Isomorphism k
 
91
  ; _∙_                 = _⊎_
 
92
  ; ε                   = Lift ⊥
 
93
  ; isCommutativeMonoid = record
 
94
    { isSemigroup   = record
 
95
      { isEquivalence = Setoid.isEquivalence $
 
96
                          Inv.Isomorphism-setoid k ℓ
 
97
      ; assoc         = λ A B C → Inv.⇿⇒ $ assoc A B C
 
98
      ; ∙-cong        = ⊎-cong k
 
99
      }
 
100
    ; identityˡ = λ A → Inv.⇿⇒ $ left-identity A
 
101
    ; comm      = λ A B → Inv.⇿⇒ $ comm A B
 
102
    }
 
103
  }
 
104
  where
 
105
  open FP _⇿_
 
106
 
 
107
  ⊎-cong : ∀ k {A B C D : Set ℓ} →
 
108
           Isomorphism k A B → Isomorphism k C D →
 
109
           Isomorphism k (A ⊎ C) (B ⊎ D)
 
110
  ⊎-cong Inv.equivalent = _⊎-⇔_
 
111
  ⊎-cong Inv.inverse    = _⊎-⇿_
 
112
 
 
113
  left-identity : LeftIdentity (Lift ⊥) (_⊎_ {a = ℓ} {b = ℓ})
 
114
  left-identity A = record
 
115
    { to         = P.→-to-⟶ to
 
116
    ; from       = P.→-to-⟶ from
 
117
    ; inverse-of = record
 
118
      { right-inverse-of = λ _ → P.refl
 
119
      ; left-inverse-of  =
 
120
          [ ⊥-elim {Whatever = _ ≡ _} ∘ lower , (λ _ → P.refl) ]
 
121
      }
 
122
    }
 
123
    where
 
124
    to : Lift {ℓ = ℓ} ⊥ ⊎ A → A
 
125
    to = [ (λ ()) ∘′ lower , id ]
 
126
 
 
127
    from : A → Lift {ℓ = ℓ} ⊥ ⊎ A
 
128
    from = inj₂
 
129
 
 
130
  assoc : Associative _⊎_
 
131
  assoc A B C = record
 
132
    { to         = P.→-to-⟶ to
 
133
    ; from       = P.→-to-⟶ from
 
134
    ; inverse-of = record
 
135
      { left-inverse-of  = [ [ (λ _ → P.refl) , (λ _ → P.refl) ] , (λ _ → P.refl) ]
 
136
      ; right-inverse-of = [ (λ _ → P.refl) , [ (λ _ → P.refl) , (λ _ → P.refl) ] ]
 
137
      }
 
138
    }
 
139
    where
 
140
    to : (A ⊎ B) ⊎ C → A ⊎ (B ⊎ C)
 
141
    to = [ [ inj₁ , inj₂ ∘ inj₁ ] , inj₂ ∘ inj₂ ]
 
142
 
 
143
    from : A ⊎ (B ⊎ C) → (A ⊎ B) ⊎ C
 
144
    from = [ inj₁ ∘ inj₁ , [ inj₁ ∘ inj₂ , inj₂ ] ]
 
145
 
 
146
  comm : Commutative _⊎_
 
147
  comm _ _ = record
 
148
    { to         = P.→-to-⟶ swap
 
149
    ; from       = P.→-to-⟶ swap
 
150
    ; inverse-of = record
 
151
      { left-inverse-of  = inv
 
152
      ; right-inverse-of = inv
 
153
      }
 
154
    }
 
155
    where
 
156
    swap : {A B : Set ℓ} → A ⊎ B → B ⊎ A
 
157
    swap = [ inj₂ , inj₁ ]
 
158
 
 
159
    inv : ∀ {A B} → swap ∘ swap {A} {B} ≗ id
 
160
    inv = [ (λ _ → P.refl) , (λ _ → P.refl) ]
 
161
 
 
162
×⊎-CommutativeSemiring : Kind → (ℓ : Level) → CommutativeSemiring _ _
 
163
×⊎-CommutativeSemiring k ℓ = record
 
164
  { Carrier               = Set ℓ
 
165
  ; _≈_                   = Isomorphism k
 
166
  ; _+_                   = _⊎_
 
167
  ; _*_                   = _×_
 
168
  ; 0#                    = Lift ⊥
 
169
  ; 1#                    = Lift ⊤
 
170
  ; isCommutativeSemiring = record
 
171
    { +-isCommutativeMonoid = isCommutativeMonoid $
 
172
                                ⊎-CommutativeMonoid k ℓ
 
173
    ; *-isCommutativeMonoid = isCommutativeMonoid $
 
174
                                ×-CommutativeMonoid k ℓ
 
175
    ; distribʳ              = λ A B C → Inv.⇿⇒ $ right-distrib A B C
 
176
    ; zeroˡ                 = λ A → Inv.⇿⇒ $ left-zero A
 
177
    }
 
178
  }
 
179
  where
 
180
  open CommutativeMonoid
 
181
  open FP _⇿_
 
182
 
 
183
  left-zero : LeftZero (Lift ⊥) (_×_ {a = ℓ} {b = ℓ})
 
184
  left-zero A = record
 
185
    { to         = P.→-to-⟶ $ proj₁ {a = ℓ} {b = ℓ}
 
186
    ; from       = P.→-to-⟶ (⊥-elim ∘′ lower)
 
187
    ; inverse-of = record
 
188
      { left-inverse-of  = λ p → ⊥-elim (lower $ proj₁ p)
 
189
      ; right-inverse-of = λ x → ⊥-elim (lower x)
 
190
      }
 
191
    }
 
192
 
 
193
  right-distrib : _×_ DistributesOverʳ _⊎_
 
194
  right-distrib A B C = record
 
195
    { to         = P.→-to-⟶ to
 
196
    ; from       = P.→-to-⟶ from
 
197
    ; inverse-of = record
 
198
      { right-inverse-of = [ (λ _ → P.refl) , (λ _ → P.refl) ]
 
199
      ; left-inverse-of  =
 
200
          uncurry [ (λ _ _ → P.refl) , (λ _ _ → P.refl) ]
 
201
      }
 
202
    }
 
203
    where
 
204
    to : (B ⊎ C) × A → B × A ⊎ C × A
 
205
    to = uncurry [ curry inj₁ , curry inj₂ ]
 
206
 
 
207
    from : B × A ⊎ C × A → (B ⊎ C) × A
 
208
    from = [ Prod.map inj₁ id , Prod.map inj₂ id ]
 
209
 
 
210
------------------------------------------------------------------------
 
211
-- Some reordering lemmas
 
212
 
 
213
ΠΠ⇿ΠΠ : ∀ {a b p} {A : Set a} {B : Set b} (P : A → B → Set p) →
 
214
        ((x : A) (y : B) → P x y) ⇿ ((y : B) (x : A) → P x y)
 
215
ΠΠ⇿ΠΠ _ = record
 
216
  { to         = P.→-to-⟶ λ f x y → f y x
 
217
  ; from       = P.→-to-⟶ λ f y x → f x y
 
218
  ; inverse-of = record
 
219
    { left-inverse-of  = λ _ → P.refl
 
220
    ; right-inverse-of = λ _ → P.refl
 
221
    }
 
222
  }
 
223
 
 
224
∃∃⇿∃∃ : ∀ {a b p} {A : Set a} {B : Set b} (P : A → B → Set p) →
 
225
        (∃₂ λ x y → P x y) ⇿ (∃₂ λ y x → P x y)
 
226
∃∃⇿∃∃ {a} {b} {p} _ = record
 
227
  { to         = P.→-to-⟶ {a = ℓ} λ p → (proj₁ (proj₂ p) , proj₁ p , proj₂ (proj₂ p))
 
228
  ; from       = P.→-to-⟶ {a = ℓ} λ p → (proj₁ (proj₂ p) , proj₁ p , proj₂ (proj₂ p))
 
229
  ; inverse-of = record
 
230
    { left-inverse-of  = λ _ → P.refl
 
231
    ; right-inverse-of = λ _ → P.refl
 
232
    }
 
233
  } where ℓ = p ⊔ (b ⊔ a)
 
234
 
 
235
------------------------------------------------------------------------
 
236
-- Implicit and explicit function spaces are isomorphic
 
237
 
 
238
Π⇿Π : ∀ {a b} {A : Set a} {B : A → Set b} →
 
239
      ((x : A) → B x) ⇿ ({x : A} → B x)
 
240
Π⇿Π = record
 
241
  { to         = P.→-to-⟶ λ f {x} → f x
 
242
  ; from       = P.→-to-⟶ λ f x → f {x}
 
243
  ; inverse-of = record
 
244
    { left-inverse-of  = λ _ → P.refl
 
245
    ; right-inverse-of = λ _ → P.refl
 
246
    }
 
247
  }
 
248
 
 
249
------------------------------------------------------------------------
 
250
-- _→_ preserves isomorphisms
 
251
 
 
252
_→-cong-⇔_ :
 
253
  ∀ {a b c d} {A : Set a} {B : Set b} {C : Set c} {D : Set d} →
 
254
  A ⇔ B → C ⇔ D → (A → C) ⇔ (B → D)
 
255
A⇔B →-cong-⇔ C⇔D = record
 
256
  { to   = P.→-to-⟶ λ f x →
 
257
             Equivalent.to   C⇔D ⟨$⟩ f (Equivalent.from A⇔B ⟨$⟩ x)
 
258
  ; from = P.→-to-⟶ λ f x →
 
259
             Equivalent.from C⇔D ⟨$⟩ f (Equivalent.to   A⇔B ⟨$⟩ x)
 
260
  }
 
261
 
 
262
→-cong :
 
263
  ∀ {a b c d} →
 
264
  P.Extensionality a c → P.Extensionality b d →
 
265
  ∀ {k} {A : Set a} {B : Set b} {C : Set c} {D : Set d} →
 
266
  Isomorphism k A B → Isomorphism k C D → Isomorphism k (A → C) (B → D)
 
267
→-cong extAC extBD {Inv.equivalent} A⇔B C⇔D = A⇔B →-cong-⇔ C⇔D
 
268
→-cong extAC extBD {Inv.inverse}    A⇿B C⇿D = record
 
269
  { to         = Equivalent.to   A→C⇔B→D
 
270
  ; from       = Equivalent.from A→C⇔B→D
 
271
  ; inverse-of = record
 
272
    { left-inverse-of  = λ f → extAC λ x → begin
 
273
        Inverse.from C⇿D ⟨$⟩ (Inverse.to C⇿D ⟨$⟩
 
274
          f (Inverse.from A⇿B ⟨$⟩ (Inverse.to A⇿B ⟨$⟩ x)))  ≡⟨ Inverse.left-inverse-of C⇿D _ ⟩
 
275
        f (Inverse.from A⇿B ⟨$⟩ (Inverse.to A⇿B ⟨$⟩ x))     ≡⟨ P.cong f $ Inverse.left-inverse-of A⇿B x ⟩
 
276
        f x                                                 ∎
 
277
    ; right-inverse-of = λ f → extBD λ x → begin
 
278
        Inverse.to C⇿D ⟨$⟩ (Inverse.from C⇿D ⟨$⟩
 
279
          f (Inverse.to A⇿B ⟨$⟩ (Inverse.from A⇿B ⟨$⟩ x)))  ≡⟨ Inverse.right-inverse-of C⇿D _ ⟩
 
280
        f (Inverse.to A⇿B ⟨$⟩ (Inverse.from A⇿B ⟨$⟩ x))     ≡⟨ P.cong f $ Inverse.right-inverse-of A⇿B x ⟩
 
281
        f x                                                 ∎
 
282
    }
 
283
  }
 
284
  where
 
285
  open P.≡-Reasoning
 
286
  A→C⇔B→D = Inv.⇿⇒ A⇿B →-cong-⇔ Inv.⇿⇒ C⇿D
 
287
 
 
288
------------------------------------------------------------------------
 
289
-- ¬_ preserves isomorphisms
 
290
 
 
291
¬-cong-⇔ : ∀ {a b} {A : Set a} {B : Set b} →
 
292
           A ⇔ B → (¬ A) ⇔ (¬ B)
 
293
¬-cong-⇔ A⇔B = A⇔B →-cong-⇔ (⊥ ∎)
 
294
  where open Inv.EquationalReasoning
 
295
 
 
296
¬-cong : ∀ {a b} →
 
297
         P.Extensionality a zero → P.Extensionality b zero →
 
298
         ∀ {k} {A : Set a} {B : Set b} →
 
299
         Isomorphism k A B → Isomorphism k (¬ A) (¬ B)
 
300
¬-cong extA extB A≈B = →-cong extA extB A≈B (⊥ ∎)
 
301
  where open Inv.EquationalReasoning
 
302
 
 
303
------------------------------------------------------------------------
 
304
-- _⇔_ preserves _⇔_
 
305
 
 
306
-- The type of the following proof is a bit more general.
 
307
 
 
308
Isomorphism-cong :
 
309
  ∀ {k a b c d} {A : Set a} {B : Set b} {C : Set c} {D : Set d} →
 
310
  Isomorphism k A B → Isomorphism k C D →
 
311
  Isomorphism k A C ⇔ Isomorphism k B D
 
312
Isomorphism-cong {A = A} {B} {C} {D} A≈B C≈D =
 
313
  equivalent (λ A≈C → B  ≈⟨ sym A≈B ⟩
 
314
                      A  ≈⟨ A≈C ⟩
 
315
                      C  ≈⟨ C≈D ⟩
 
316
                      D  ∎)
 
317
             (λ B≈D → A  ≈⟨ A≈B ⟩
 
318
                      B  ≈⟨ B≈D ⟩
 
319
                      D  ≈⟨ sym C≈D ⟩
 
320
                      C  ∎)
 
321
  where open Inv.EquationalReasoning