@@ -18,14 +18,22 @@ open import Data.Sum.Base
18
18
open import Data.Sum.Properties
19
19
open import Data.Sum.Function.Propositional using (_⊎-cong_)
20
20
open import Function.Base
21
- open import Function.Equality using (_⟨$⟩_)
22
- open import Function.Inverse as Inv using (_↔_; Inverse; inverse )
23
- import Function.Related as Related
21
+ open import Function.Bundles
22
+ open import Function.Properties. Inverse using (↔-refl; ↔-sym; ↔⇒↣ )
23
+ import Function.Related.Propositional as Related
24
24
open import Function.Related.TypeIsomorphisms
25
+ open import Level
26
+ open import Relation.Unary using (Pred)
25
27
import Induction.WellFounded as WF
26
28
open import Relation.Binary.PropositionalEquality.Core as P using (_≡_)
27
29
import Relation.Binary.Construct.On as On
28
30
31
+ private
32
+ variable
33
+ a p : Level
34
+ A : Set a
35
+ P : Pred A p
36
+
29
37
------------------------------------------------------------------------
30
38
-- Some code that is used to work around Agda's syntactic guardedness
31
39
-- checker.
@@ -34,74 +42,70 @@ private
34
42
35
43
infixr 5 _∷_ _⋎_
36
44
37
- data ColistP {a} (A : Set a) : Set a where
45
+ data ColistP (A : Set a) : Set a where
38
46
[] : ColistP A
39
47
_∷_ : A → ∞ (ColistP A) → ColistP A
40
48
_⋎_ : ColistP A → ColistP A → ColistP A
41
49
42
- data ColistW {a} (A : Set a) : Set a where
50
+ data ColistW (A : Set a) : Set a where
43
51
[] : ColistW A
44
52
_∷_ : A → ColistP A → ColistW A
45
53
46
- program : ∀ {a} {A : Set a} → Colist A → ColistP A
54
+ program : Colist A → ColistP A
47
55
program [] = []
48
56
program (x ∷ xs) = x ∷ ♯ program (♭ xs)
49
57
50
58
mutual
51
59
52
- _⋎W_ : ∀ {a} {A : Set a} → ColistW A → ColistP A → ColistW A
60
+ _⋎W_ : ColistW A → ColistP A → ColistW A
53
61
[] ⋎W ys = whnf ys
54
62
(x ∷ xs) ⋎W ys = x ∷ (ys ⋎ xs)
55
63
56
- whnf : ∀ {a} {A : Set a} → ColistP A → ColistW A
64
+ whnf : ColistP A → ColistW A
57
65
whnf [] = []
58
66
whnf (x ∷ xs) = x ∷ ♭ xs
59
67
whnf (xs ⋎ ys) = whnf xs ⋎W ys
60
68
61
69
mutual
62
70
63
- ⟦_⟧P : ∀ {a} {A : Set a} → ColistP A → Colist A
71
+ ⟦_⟧P : ColistP A → Colist A
64
72
⟦ xs ⟧P = ⟦ whnf xs ⟧W
65
73
66
- ⟦_⟧W : ∀ {a} {A : Set a} → ColistW A → Colist A
74
+ ⟦_⟧W : ColistW A → Colist A
67
75
⟦ [] ⟧W = []
68
76
⟦ x ∷ xs ⟧W = x ∷ ♯ ⟦ xs ⟧P
69
77
70
78
mutual
71
79
72
- ⋎-homP : ∀ {a} {A : Set a} (xs : ColistP A) {ys} →
73
- ⟦ xs ⋎ ys ⟧P ≈ ⟦ xs ⟧P Colist.⋎ ⟦ ys ⟧P
80
+ ⋎-homP : ∀ (xs : ColistP A) {ys} → ⟦ xs ⋎ ys ⟧P ≈ ⟦ xs ⟧P Colist.⋎ ⟦ ys ⟧P
74
81
⋎-homP xs = ⋎-homW (whnf xs) _
75
82
76
- ⋎-homW : ∀ {a} {A : Set a} (xs : ColistW A) ys →
77
- ⟦ xs ⋎W ys ⟧W ≈ ⟦ xs ⟧W Colist.⋎ ⟦ ys ⟧P
83
+ ⋎-homW : ∀ (xs : ColistW A) ys → ⟦ xs ⋎W ys ⟧W ≈ ⟦ xs ⟧W Colist.⋎ ⟦ ys ⟧P
78
84
⋎-homW (x ∷ xs) ys = x ∷ ♯ ⋎-homP ys
79
85
⋎-homW [] ys = begin ⟦ ys ⟧P ∎
80
86
where open ≈-Reasoning
81
87
82
- ⟦program⟧P : ∀ {a} {A : Set a} (xs : Colist A) →
83
- ⟦ program xs ⟧P ≈ xs
88
+ ⟦program⟧P : ∀ (xs : Colist A) → ⟦ program xs ⟧P ≈ xs
84
89
⟦program⟧P [] = []
85
90
⟦program⟧P (x ∷ xs) = x ∷ ♯ ⟦program⟧P (♭ xs)
86
91
87
- Any-⋎P : ∀ {a p} {A : Set a} {P : A → Set p} xs {ys} →
92
+ Any-⋎P : ∀ xs {ys} →
88
93
Any P ⟦ program xs ⋎ ys ⟧P ↔ (Any P xs ⊎ Any P ⟦ ys ⟧P)
89
94
Any-⋎P {P = P} xs {ys} =
90
- Any P ⟦ program xs ⋎ ys ⟧P ↔⟨ Any-cong Inv.id (⋎-homP (program xs)) ⟩
95
+ Any P ⟦ program xs ⋎ ys ⟧P ↔⟨ Any-cong ↔-refl (⋎-homP (program xs)) ⟩
91
96
Any P (⟦ program xs ⟧P Colist.⋎ ⟦ ys ⟧P) ↔⟨ Any-⋎ _ ⟩
92
- (Any P ⟦ program xs ⟧P ⊎ Any P ⟦ ys ⟧P) ↔⟨ Any-cong Inv.id (⟦program⟧P _) ⊎-cong (_ ∎) ⟩
97
+ (Any P ⟦ program xs ⟧P ⊎ Any P ⟦ ys ⟧P) ↔⟨ Any-cong ↔-refl (⟦program⟧P _) ⊎-cong (_ ∎) ⟩
93
98
(Any P xs ⊎ Any P ⟦ ys ⟧P) ∎
94
99
where open Related.EquationalReasoning
95
100
96
101
index-Any-⋎P :
97
- ∀ {a p} {A : Set a} {P : A → Set p} xs {ys}
98
- (p : Any P ⟦ program xs ⋎ ys ⟧P) →
99
- index p ≥′ [ index , index ]′ (Inverse.to (Any-⋎P xs) ⟨$⟩ p)
102
+ ∀ xs {ys} (p : Any P ⟦ program xs ⋎ ys ⟧P) →
103
+ index p ≥′ [ index , index ]′ (Inverse.to (Any-⋎P xs) p)
100
104
index-Any-⋎P xs p
101
105
with Any-resp id (⋎-homW (whnf (program xs)) _) p
102
106
| index-Any-resp {f = id} (⋎-homW (whnf (program xs)) _) p
103
107
index-Any-⋎P xs p | q | q≡p
104
- with Inverse.to (Any-⋎ ⟦ program xs ⟧P) ⟨$⟩ q
108
+ with Inverse.to (Any-⋎ ⟦ program xs ⟧P) q
105
109
| index-Any-⋎ ⟦ program xs ⟧P q
106
110
index-Any-⋎P xs p | q | q≡p | inj₂ r | r≤q rewrite q≡p = r≤q
107
111
index-Any-⋎P xs p | q | q≡p | inj₁ r | r≤q
@@ -115,95 +119,90 @@ private
115
119
116
120
private
117
121
118
- merge′ : ∀ {a} {A : Set a} → Colist (A × Colist A) → ColistP A
122
+ merge′ : Colist (A × Colist A) → ColistP A
119
123
merge′ [] = []
120
124
merge′ ((x , xs) ∷ xss) = x ∷ ♯ (program xs ⋎ merge′ (♭ xss))
121
125
122
- merge : ∀ {a} {A : Set a} → Colist (A × Colist A) → Colist A
126
+ merge : Colist (A × Colist A) → Colist A
123
127
merge xss = ⟦ merge′ xss ⟧P
124
128
125
129
------------------------------------------------------------------------
126
130
-- Any lemma for merge.
127
131
128
- module _ {a p} {A : Set a} {P : A → Set p} where
129
-
130
- Any-merge : ∀ xss → Any P (merge xss) ↔ Any (λ { (x , xs) → P x ⊎ Any P xs }) xss
131
- Any-merge xss = inverse (proj₁ ∘ to xss) from (proj₂ ∘ to xss) to∘from
132
+ Any-merge : ∀ xss → Any P (merge xss) ↔ Any (λ { (x , xs) → P x ⊎ Any P xs }) xss
133
+ Any-merge {P = P} xss = mk↔ₛ′ (proj₁ ∘ to xss) from to∘from (proj₂ ∘ to xss)
134
+ where
135
+ open P.≡-Reasoning
136
+
137
+ -- The from function.
138
+
139
+ Q = λ { (x , xs) → P x ⊎ Any P xs }
140
+
141
+ from : ∀ {xss} → Any Q xss → Any P (merge xss)
142
+ from (here (inj₁ p)) = here p
143
+ from (here (inj₂ p)) = there (Inverse.from (Any-⋎P _) (inj₁ p))
144
+ from (there {x = _ , xs} p) = there (Inverse.from (Any-⋎P xs) (inj₂ (from p)))
145
+
146
+ -- The from function is injective.
147
+
148
+ from-injective : ∀ {xss} (p₁ p₂ : Any Q xss) →
149
+ from p₁ ≡ from p₂ → p₁ ≡ p₂
150
+ from-injective (here (inj₁ p)) (here (inj₁ .p)) P.refl = P.refl
151
+ from-injective (here (inj₂ p₁)) (here (inj₂ p₂)) eq =
152
+ P.cong (here ∘ inj₂) $
153
+ inj₁-injective $
154
+ Injection.injective (↔⇒↣ (↔-sym (Any-⋎P _))) $
155
+ there-injective eq
156
+ from-injective (here (inj₂ p₁)) (there p₂) eq with
157
+ Injection.injective (↔⇒↣ (↔-sym (Any-⋎P _)))
158
+ {x = inj₁ p₁} {y = inj₂ (from p₂)}
159
+ (there-injective eq)
160
+ ... | ()
161
+ from-injective (there p₁) (here (inj₂ p₂)) eq with
162
+ Injection.injective (↔⇒↣ (↔-sym (Any-⋎P _)))
163
+ {x = inj₂ (from p₁)} {y = inj₁ p₂}
164
+ (there-injective eq)
165
+ ... | ()
166
+ from-injective (there {x = _ , xs} p₁) (there p₂) eq =
167
+ P.cong there $
168
+ from-injective p₁ p₂ $
169
+ inj₂-injective $
170
+ Injection.injective (↔⇒↣ (↔-sym (Any-⋎P xs))) $
171
+ there-injective eq
172
+ -- The to function (defined as a right inverse of from).
173
+
174
+ Input = ∃ λ xss → Any P (merge xss)
175
+
176
+ InputPred : Input → Set _
177
+ InputPred (xss , p) = ∃ λ (q : Any Q xss) → from q ≡ p
178
+
179
+ to : ∀ xss p → InputPred (xss , p)
180
+ to xss p =
181
+ WF.All.wfRec (On.wellFounded size <′-wellFounded) _
182
+ InputPred step (xss , p)
132
183
where
133
- open P.≡-Reasoning
134
-
135
- -- The from function.
136
-
137
- Q = λ { (x , xs) → P x ⊎ Any P xs }
138
-
139
- from : ∀ {xss} → Any Q xss → Any P (merge xss)
140
- from (here (inj₁ p)) = here p
141
- from (here (inj₂ p)) = there (Inverse.from (Any-⋎P _) ⟨$⟩ inj₁ p)
142
- from (there {x = _ , xs} p) = there (Inverse.from (Any-⋎P xs) ⟨$⟩ inj₂ (from p))
143
-
144
- -- The from function is injective.
145
-
146
- from-injective : ∀ {xss} (p₁ p₂ : Any Q xss) →
147
- from p₁ ≡ from p₂ → p₁ ≡ p₂
148
- from-injective (here (inj₁ p)) (here (inj₁ .p)) P.refl = P.refl
149
- from-injective (here (inj₂ p₁)) (here (inj₂ p₂)) eq =
150
- P.cong (here ∘ inj₂) $
151
- inj₁-injective $
152
- Inverse.injective (Inv.sym (Any-⋎P _)) {x = inj₁ p₁} {y = inj₁ p₂} $
153
- there-injective eq
154
- from-injective (here (inj₂ p₁)) (there p₂) eq
155
- with Inverse.injective (Inv.sym (Any-⋎P _))
156
- {x = inj₁ p₁} {y = inj₂ (from p₂)}
157
- (there-injective eq)
158
- ... | ()
159
- from-injective (there p₁) (here (inj₂ p₂)) eq
160
- with Inverse.injective (Inv.sym (Any-⋎P _))
161
- {x = inj₂ (from p₁)} {y = inj₁ p₂}
162
- (there-injective eq)
163
- ... | ()
164
- from-injective (there {x = _ , xs} p₁) (there p₂) eq =
165
- P.cong there $
166
- from-injective p₁ p₂ $
167
- inj₂-injective $
168
- Inverse.injective (Inv.sym (Any-⋎P xs))
169
- {x = inj₂ (from p₁)} {y = inj₂ (from p₂)} $
170
- there-injective eq
171
-
172
- -- The to function (defined as a right inverse of from).
173
-
174
- Input = ∃ λ xss → Any P (merge xss)
175
-
176
- Pred : Input → Set _
177
- Pred (xss , p) = ∃ λ (q : Any Q xss) → from q ≡ p
178
-
179
- to : ∀ xss p → Pred (xss , p)
180
- to = λ xss p →
181
- WF.All.wfRec (On.wellFounded size <′-wellFounded) _
182
- Pred step (xss , p)
183
- where
184
- size : Input → ℕ
185
- size (_ , p) = index p
186
-
187
- step : ∀ p → WF.WfRec (_<′_ on size) Pred p → Pred p
188
- step ([] , ()) rec
189
- step ((x , xs) ∷ xss , here p) rec = here (inj₁ p) , P.refl
190
- step ((x , xs) ∷ xss , there p) rec
191
- with Inverse.to (Any-⋎P xs) ⟨$⟩ p
192
- | Inverse.left-inverse-of (Any-⋎P xs) p
193
- | index-Any-⋎P xs p
194
- ... | inj₁ q | P.refl | _ = here (inj₂ q) , P.refl
195
- ... | inj₂ q | P.refl | q≤p =
196
- Prod.map there
197
- (P.cong (there ∘ _⟨$⟩_ (Inverse.from (Any-⋎P xs)) ∘ inj₂))
198
- (rec (♭ xss , q) (s≤′s q≤p))
199
-
200
- to∘from = λ p → from-injective _ _ (proj₂ (to xss (from p)))
184
+ size : Input → ℕ
185
+ size (_ , p) = index p
186
+
187
+ step : ∀ p → WF.WfRec (_<′_ on size) InputPred p → InputPred p
188
+ step ([] , ()) rec
189
+ step ((x , xs) ∷ xss , here p) rec = here (inj₁ p) , P.refl
190
+ step ((x , xs) ∷ xss , there p) rec
191
+ with Inverse.to (Any-⋎P xs) p
192
+ | Inverse.strictlyInverseʳ (Any-⋎P xs) p
193
+ | index-Any-⋎P xs p
194
+ ... | inj₁ q | P.refl | _ = here (inj₂ q) , P.refl
195
+ ... | inj₂ q | P.refl | q≤p =
196
+ Prod.map there
197
+ (P.cong (there ∘ (Inverse.from (Any-⋎P xs)) ∘ inj₂))
198
+ (rec (♭ xss , q) (s≤′s q≤p))
199
+
200
+ to∘from = λ p → from-injective _ _ (proj₂ (to xss (from p)))
201
201
202
202
-- Every member of xss is a member of merge xss, and vice versa (with
203
203
-- equal multiplicities).
204
204
205
- ∈-merge : ∀ {a} {A : Set a} {y : A} xss →
206
- y ∈ merge xss ↔ ∃₂ λ x xs → (x , xs) ∈ xss × (y ≡ x ⊎ y ∈ xs)
205
+ ∈-merge : ∀ {y : A} xss → y ∈ merge xss ↔ ∃₂ λ x xs → (x , xs) ∈ xss × (y ≡ x ⊎ y ∈ xs)
207
206
∈-merge {y = y} xss =
208
207
y ∈ merge xss ↔⟨ Any-merge _ ⟩
209
208
Any (λ { (x , xs) → y ≡ x ⊎ y ∈ xs }) xss ↔⟨ Any-∈ ⟩
0 commit comments