@@ -25,6 +25,7 @@ open import Function.Inverse using (_↔_; inverse)
25
25
open import Relation.Binary hiding (Decidable)
26
26
open import Relation.Binary.PropositionalEquality as P
27
27
using (_≡_; _≢_; refl; _≗_)
28
+ open import Relation.Binary.HeterogeneousEquality as H using (_≅_; refl)
28
29
open import Relation.Unary using (Pred; Decidable)
29
30
open import Relation.Nullary using (yes; no)
30
31
@@ -67,7 +68,7 @@ module _ {a} {A : Set a} where
67
68
lookup⇒[]= : ∀ {n} (i : Fin n) {x : A} xs →
68
69
lookup i xs ≡ x → xs [ i ]= x
69
70
lookup⇒[]= zero (_ ∷ _) refl = here
70
- lookup⇒[]= (suc i) (_ ∷ xs) p = there (lookup⇒[]= i xs p)
71
+ lookup⇒[]= (suc i) (_ ∷ xs) p = there (lookup⇒[]= i xs p)
71
72
72
73
[]=↔lookup : ∀ {n i} {x} {xs : Vec A n} →
73
74
xs [ i ]= x ↔ lookup i xs ≡ x
@@ -89,59 +90,171 @@ module _ {a} {A : Set a} where
89
90
[]=⇒lookup∘lookup⇒[]= (suc i) (x ∷ xs) p =
90
91
[]=⇒lookup∘lookup⇒[]= i xs p
91
92
93
+ ------------------------------------------------------------------------
94
+ -- updateAt (_[_]%=_)
95
+
96
+ module _ {a} {A : Set a} where
97
+
98
+ -- Defining properties of updateAt:
99
+
100
+ -- (+) updateAt i actually updates the element at index i.
101
+
102
+ updateAt-updates : ∀ {n} (i : Fin n) {f : A → A} (xs : Vec A n) {x : A}
103
+ → xs [ i ]= x
104
+ → updateAt i f xs [ i ]= f x
105
+ updateAt-updates zero (x ∷ xs) here = here
106
+ updateAt-updates (suc i) (x ∷ xs) (there loc) = there (updateAt-updates i xs loc)
107
+
108
+ -- (-) updateAt i does not touch the elements at other indices.
109
+
110
+ updateAt-minimal : ∀ {n} (i j : Fin n) {f : A → A} {x : A} (xs : Vec A n)
111
+ → i ≢ j
112
+ → xs [ i ]= x
113
+ → updateAt j f xs [ i ]= x
114
+ updateAt-minimal zero zero (x ∷ xs) 0≢0 here = ⊥-elim (0≢0 refl)
115
+ updateAt-minimal zero (suc j) (x ∷ xs) _ here = here
116
+ updateAt-minimal (suc i) zero (x ∷ xs) _ (there loc) = there loc
117
+ updateAt-minimal (suc i) (suc j) (x ∷ xs) i≢j (there loc) =
118
+ there (updateAt-minimal i j xs (i≢j ∘ P.cong suc) loc)
119
+
120
+ -- The other properties are consequences of (+) and (-).
121
+ -- We spell the most natural properties out.
122
+ -- Direct inductive proofs are in most cases easier than just using
123
+ -- the defining properties.
124
+
125
+ -- In the explanations, we make use of shorthand f = g ↾ x
126
+ -- meaning that f and g agree at point x, i.e. f x ≡ g x.
127
+
128
+ -- updateAt i is a morphism from the monoid of endofunctions A → A
129
+ -- to the monoid of endofunctions Vec A n → Vec A n
130
+
131
+ -- 1a. relative identity: f = id ↾ (lookup i xs)
132
+ -- implies updateAt i f = id ↾ xs
133
+
134
+ updateAt-id-relative : ∀ {n} (i : Fin n) (xs : Vec A n) {f : A → A}
135
+ → f (lookup i xs) ≡ lookup i xs
136
+ → updateAt i f xs ≡ xs
137
+ updateAt-id-relative zero (x ∷ xs) eq = P.cong (_∷ xs) eq
138
+ updateAt-id-relative (suc i) (x ∷ xs) eq = P.cong (x ∷_) (updateAt-id-relative i xs eq)
139
+
140
+ -- 1b. identity: updateAt i id ≗ id
141
+
142
+ updateAt-id : ∀ {n} (i : Fin n) (xs : Vec A n) →
143
+ updateAt i id xs ≡ xs
144
+ updateAt-id i xs = updateAt-id-relative i xs refl
145
+
146
+ -- 2a. relative composition: f ∘ g = h ↾ (lookup i xs)
147
+ -- implies updateAt i f ∘ updateAt i g ≗ updateAt i h
148
+
149
+ updateAt-compose-relative : ∀ {n} (i : Fin n) {f g h : A → A} (xs : Vec A n)
150
+ → f (g (lookup i xs)) ≡ h (lookup i xs)
151
+ → updateAt i f (updateAt i g xs) ≡ updateAt i h xs
152
+ updateAt-compose-relative zero (x ∷ xs) fg=h = P.cong (_∷ xs) fg=h
153
+ updateAt-compose-relative (suc i) (x ∷ xs) fg=h =
154
+ P.cong (x ∷_) (updateAt-compose-relative i xs fg=h)
155
+
156
+ -- 2b. composition: updateAt i f ∘ updateAt i g ≗ updateAt i (f ∘ g)
157
+
158
+ updateAt-compose : ∀ {n} (i : Fin n) {f g : A → A} →
159
+ updateAt i f ∘ updateAt i g ≗ updateAt i (f ∘ g)
160
+ updateAt-compose i xs = updateAt-compose-relative i xs refl
161
+
162
+ -- 3. congruence: updateAt i is a congruence wrt. extensional equality.
163
+
164
+ -- 3a. If f = g ↾ (lookup i xs)
165
+ -- then updateAt i f = updateAt i g ↾ xs
166
+
167
+ updateAt-cong-relative : ∀ {n} (i : Fin n) {f g : A → A} (xs : Vec A n)
168
+ → f (lookup i xs) ≡ g (lookup i xs)
169
+ → updateAt i f xs ≡ updateAt i g xs
170
+ updateAt-cong-relative zero (x ∷ xs) f=g = P.cong (_∷ xs) f=g
171
+ updateAt-cong-relative (suc i) (x ∷ xs) f=g = P.cong (x ∷_) (updateAt-cong-relative i xs f=g)
172
+
173
+ -- 3b. congruence: f ≗ g → updateAt i f ≗ updateAt i g
174
+
175
+ updateAt-cong : ∀ {n} (i : Fin n) {f g : A → A}
176
+ → f ≗ g
177
+ → updateAt i f ≗ updateAt i g
178
+ updateAt-cong i f≗g xs = updateAt-cong-relative i xs (f≗g (lookup i xs))
179
+
180
+ -- The order of updates at different indices i ≢ j does not matter.
181
+
182
+ -- This a consequence of updateAt-updates and updateAt-minimal
183
+ -- but easier to prove inductively.
184
+
185
+ updateAt-commutes : ∀ {n} (i j : Fin n) {f g : A → A}
186
+ → i ≢ j
187
+ → updateAt i f ∘ updateAt j g ≗ updateAt j g ∘ updateAt i f
188
+ updateAt-commutes zero zero 0≢0 (x ∷ xs) = ⊥-elim (0≢0 refl)
189
+ updateAt-commutes zero (suc j) i≢j (x ∷ xs) = refl
190
+ updateAt-commutes (suc i) zero i≢j (x ∷ xs) = refl
191
+ updateAt-commutes (suc i) (suc j) i≢j (x ∷ xs) =
192
+ P.cong (x ∷_) (updateAt-commutes i j (i≢j ∘ P.cong suc) xs)
193
+
194
+ -- lookup after updateAt reduces.
195
+
196
+ -- For same index this is an easy consequence of updateAt-updates
197
+ -- using []=↔lookup.
198
+
199
+ lookup∘updateAt : ∀ {n} (i : Fin n) {f : A → A} →
200
+ lookup i ∘ updateAt i f ≗ f ∘ lookup i
201
+ lookup∘updateAt i xs =
202
+ []=⇒lookup (updateAt-updates i xs (lookup⇒[]= i _ refl))
203
+
204
+ -- For different indices it easily follows from updateAt-minimal.
205
+
206
+ lookup∘updateAt′ : ∀ {n} (i j : Fin n) {f : A → A}
207
+ → i ≢ j
208
+ → lookup i ∘ updateAt j f ≗ lookup i
209
+ lookup∘updateAt′ i j xs i≢j =
210
+ []=⇒lookup (updateAt-minimal i j i≢j xs (lookup⇒[]= i _ refl))
211
+
212
+ -- Aliases for notation _[_]%=_
213
+
214
+ []%=-id : ∀ {n} (xs : Vec A n) (i : Fin n) → xs [ i ]%= id ≡ xs
215
+ []%=-id xs i = updateAt-id i xs
216
+
217
+ []%=-compose : ∀ {n} (xs : Vec A n) (i : Fin n) {f g : A → A} →
218
+ xs [ i ]%= f
219
+ [ i ]%= g
220
+ ≡ xs [ i ]%= g ∘ f
221
+ []%=-compose xs i = updateAt-compose i xs
222
+
92
223
------------------------------------------------------------------------
93
224
-- _[_]≔_ (update)
225
+ --
226
+ -- _[_]≔_ is defined in terms of updateAt, and all of its properties
227
+ -- are special cases of the ones for updateAt.
94
228
95
229
module _ {a} {A : Set a} where
96
230
97
231
[]≔-idempotent : ∀ {n} (xs : Vec A n) (i : Fin n) {x₁ x₂ : A} →
98
232
(xs [ i ]≔ x₁) [ i ]≔ x₂ ≡ xs [ i ]≔ x₂
99
- []≔-idempotent [] ()
100
- []≔-idempotent (x ∷ xs) zero = refl
101
- []≔-idempotent (x ∷ xs) (suc i) = P.cong (x ∷_) ([]≔-idempotent xs i)
233
+ []≔-idempotent xs i = updateAt-compose i xs
102
234
103
235
[]≔-commutes : ∀ {n} (xs : Vec A n) (i j : Fin n) {x y : A} → i ≢ j →
104
236
(xs [ i ]≔ x) [ j ]≔ y ≡ (xs [ j ]≔ y) [ i ]≔ x
105
- []≔-commutes [] () () _
106
- []≔-commutes (x ∷ xs) zero zero 0≢0 = ⊥-elim $ 0≢0 refl
107
- []≔-commutes (x ∷ xs) zero (suc i) _ = refl
108
- []≔-commutes (x ∷ xs) (suc i) zero _ = refl
109
- []≔-commutes (x ∷ xs) (suc i) (suc j) i≢j =
110
- P.cong (x ∷_) $ []≔-commutes xs i j (i≢j ∘ P.cong suc)
237
+ []≔-commutes xs i j i≢j = updateAt-commutes j i (i≢j ∘ P.sym) xs
111
238
112
239
[]≔-updates : ∀ {n} (xs : Vec A n) (i : Fin n) {x : A} →
113
240
(xs [ i ]≔ x) [ i ]= x
114
- []≔-updates [] ()
115
- []≔-updates (x ∷ xs) zero = here
116
- []≔-updates (x ∷ xs) (suc i) = there ([]≔-updates xs i)
241
+ []≔-updates xs i = updateAt-updates i xs (lookup⇒[]= i xs refl)
117
242
118
243
[]≔-minimal : ∀ {n} (xs : Vec A n) (i j : Fin n) {x y : A} → i ≢ j →
119
244
xs [ i ]= x → (xs [ j ]≔ y) [ i ]= x
120
- []≔-minimal [] () () _ _
121
- []≔-minimal (x ∷ xs) .zero zero 0≢0 here = ⊥-elim (0≢0 refl)
122
- []≔-minimal (x ∷ xs) .zero (suc j) _ here = here
123
- []≔-minimal (x ∷ xs) (suc i) zero _ (there loc) = there loc
124
- []≔-minimal (x ∷ xs) (suc i) (suc j) i≢j (there loc) =
125
- there ([]≔-minimal xs i j (i≢j ∘ P.cong suc) loc)
245
+ []≔-minimal xs i j i≢j loc = updateAt-minimal i j xs i≢j loc
126
246
127
247
[]≔-lookup : ∀ {n} (xs : Vec A n) (i : Fin n) →
128
248
xs [ i ]≔ lookup i xs ≡ xs
129
- []≔-lookup [] ()
130
- []≔-lookup (x ∷ xs) zero = refl
131
- []≔-lookup (x ∷ xs) (suc i) = P.cong (_∷_ x) $ []≔-lookup xs i
249
+ []≔-lookup xs i = updateAt-id-relative i xs refl
132
250
133
251
lookup∘update : ∀ {n} (i : Fin n) (xs : Vec A n) x →
134
252
lookup i (xs [ i ]≔ x) ≡ x
135
- lookup∘update zero (_ ∷ xs) x = refl
136
- lookup∘update (suc i) (_ ∷ xs) x = lookup∘update i xs x
253
+ lookup∘update i xs x = lookup∘updateAt i xs
137
254
138
255
lookup∘update′ : ∀ {n} {i j : Fin n} → i ≢ j → ∀ (xs : Vec A n) y →
139
256
lookup i (xs [ j ]≔ y) ≡ lookup i xs
140
- lookup∘update′ {i = zero} {zero} i≢j xs y = ⊥-elim (i≢j refl)
141
- lookup∘update′ {i = zero} {suc j} i≢j (x ∷ xs) y = refl
142
- lookup∘update′ {i = suc i} {zero} i≢j (x ∷ xs) y = refl
143
- lookup∘update′ {i = suc i} {suc j} i≢j (x ∷ xs) y =
144
- lookup∘update′ (i≢j ∘ P.cong suc) xs y
257
+ lookup∘update′ {n} {i} {j} i≢j xs y = lookup∘updateAt′ i j i≢j xs
145
258
146
259
------------------------------------------------------------------------
147
260
-- map
@@ -167,12 +280,17 @@ lookup-map : ∀ {a b n} {A : Set a} {B : Set b}
167
280
lookup-map zero f (x ∷ xs) = refl
168
281
lookup-map (suc i) f (x ∷ xs) = lookup-map i f xs
169
282
283
+ map-updateAt : ∀ {n a b} {A : Set a} {B : Set b} →
284
+ ∀ {f : A → B} {g : A → A} {h : B → B} (xs : Vec A n) (i : Fin n)
285
+ → f (g (lookup i xs)) ≡ h (f (lookup i xs))
286
+ → map f (updateAt i g xs) ≡ updateAt i h (map f xs)
287
+ map-updateAt (x ∷ xs) zero eq = P.cong (_∷ _) eq
288
+ map-updateAt (x ∷ xs) (suc i) eq = P.cong (_ ∷_) (map-updateAt xs i eq)
289
+
170
290
map-[]≔ : ∀ {n a b} {A : Set a} {B : Set b}
171
291
(f : A → B) (xs : Vec A n) (i : Fin n) {x : A} →
172
292
map f (xs [ i ]≔ x) ≡ map f xs [ i ]≔ f x
173
- map-[]≔ f [] ()
174
- map-[]≔ f (x ∷ xs) zero = refl
175
- map-[]≔ f (x ∷ xs) (suc i) = P.cong (_ ∷_) $ map-[]≔ f xs i
293
+ map-[]≔ f xs i = map-updateAt xs i refl
176
294
177
295
------------------------------------------------------------------------
178
296
-- _++_
@@ -621,3 +739,6 @@ module _ {a} {A : Set a} where
621
739
toList∘fromList : (xs : List A) → toList (fromList xs) ≡ xs
622
740
toList∘fromList List.[] = refl
623
741
toList∘fromList (x List.∷ xs) = P.cong (x List.∷_) (toList∘fromList xs)
742
+
743
+ -- -}
744
+ -- -}
0 commit comments