@@ -17,6 +17,14 @@ data Fin : (n : Nat) -> Type where
17
17
FZ : Fin (S k)
18
18
FS : Fin k -> Fin (S k)
19
19
20
+ ||| Cast between Fins with equal indices
21
+ public export
22
+ cast : {n : Nat } -> (0 eq : m = n) -> Fin m -> Fin n
23
+ cast {n = S _ } eq FZ = FZ
24
+ cast {n = Z } eq FZ impossible
25
+ cast {n = S _ } eq (FS k) = FS (cast (succInjective _ _ eq) k)
26
+ cast {n = Z } eq (FS k) impossible
27
+
20
28
export
21
29
Uninhabited (Fin Z ) where
22
30
uninhabited FZ impossible
@@ -176,3 +184,99 @@ DecEq (Fin n) where
176
184
= case decEq f f' of
177
185
Yes p => Yes $ cong FS p
178
186
No p => No $ p . fsInjective
187
+
188
+ namespace Equality
189
+
190
+ ||| Pointwise equality of Fins
191
+ ||| It is sometimes complicated to prove equalities on type-changing
192
+ ||| operations on Fins.
193
+ ||| This inductive definition can be used to simplify proof. We can
194
+ ||| recover proofs of equalities by using `homoPointwiseIsEqual`.
195
+ public export
196
+ data Pointwise : Fin m -> Fin n -> Type where
197
+ FZ : Pointwise FZ FZ
198
+ FS : Pointwise k l -> Pointwise (FS k) (FS l)
199
+
200
+ infix 6 ~~~
201
+ ||| Convenient infix notation for the notion of pointwise equality of Fins
202
+ public export
203
+ (~~~ ) : Fin m -> Fin n -> Type
204
+ (~~~ ) = Pointwise
205
+
206
+ ||| Pointwise equality is reflexive
207
+ export
208
+ reflexive : {k : Fin m} -> k ~~~ k
209
+ reflexive {k = FZ } = FZ
210
+ reflexive {k = FS k} = FS reflexive
211
+
212
+ ||| Pointwise equality is symmetric
213
+ export
214
+ symmetric : k ~~~ l -> l ~~~ k
215
+ symmetric FZ = FZ
216
+ symmetric (FS prf) = FS (symmetric prf)
217
+
218
+ ||| Pointwise equality is transitive
219
+ export
220
+ transitive : j ~~~ k -> k ~~~ l -> j ~~~ l
221
+ transitive FZ FZ = FZ
222
+ transitive (FS prf) (FS prg) = FS (transitive prf prg)
223
+
224
+ ||| Pointwise equality is compatible with cast
225
+ export
226
+ castEq : {k : Fin m} -> (0 eq : m = n) -> cast eq k ~~~ k
227
+ castEq {k = FZ } Refl = FZ
228
+ castEq {k = FS k} Refl = FS (castEq _ )
229
+
230
+ ||| The actual proof used by cast is irrelevant
231
+ export
232
+ congCast : {n, q : Nat } -> {k : Fin m} -> {l : Fin p} ->
233
+ {0 eq1 : m = n} -> {0 eq2 : p = q} ->
234
+ k ~~~ l ->
235
+ cast eq1 k ~~~ cast eq2 l
236
+ congCast eq = transitive (castEq _ ) (transitive eq $ symmetric $ castEq _ )
237
+
238
+ ||| Last is congruent wrt index equality
239
+ export
240
+ congLast : {m, n : Nat } -> (0 _ : m = n) -> last {n=m} ~~~ last {n}
241
+ congLast {m = Z } {n = Z } eq = reflexive
242
+ congLast {m = S _ } {n = S _ } eq = FS (congLast (succInjective _ _ eq))
243
+
244
+ export
245
+ congShift : (m : Nat ) -> k ~~~ l -> shift m k ~~~ shift m l
246
+ congShift Z prf = prf
247
+ congShift (S m) prf = FS (congShift m prf)
248
+
249
+ ||| WeakenN is congruent wrt pointwise equality
250
+ export
251
+ congWeakenN : k ~~~ l -> weakenN n k ~~~ weakenN n l
252
+ congWeakenN FZ = FZ
253
+ congWeakenN (FS prf) = FS (congWeakenN prf)
254
+
255
+ ||| Pointwise equality is propositional equality on Fins that have the same type
256
+ export
257
+ homoPointwiseIsEqual : {0 k, l : Fin m} -> k ~~~ l -> k === l
258
+ homoPointwiseIsEqual FZ = Refl
259
+ homoPointwiseIsEqual (FS prf) = cong FS (homoPointwiseIsEqual prf)
260
+
261
+ ||| Pointwise equality is propositional equality modulo transport on Fins that
262
+ ||| have provably equal types
263
+ export
264
+ hetPointwiseIsTransport :
265
+ {0 k : Fin m} -> {0 l : Fin n} ->
266
+ (eq : m === n) -> k ~~~ l -> k === rewrite eq in l
267
+ hetPointwiseIsTransport Refl = homoPointwiseIsEqual
268
+
269
+ export
270
+ finToNatQuotient : k ~~~ l -> finToNat k === finToNat l
271
+ finToNatQuotient FZ = Refl
272
+ finToNatQuotient (FS prf) = cong S (finToNatQuotient prf)
273
+
274
+ export
275
+ weakenNeutral : (k : Fin n) -> weaken k ~~~ k
276
+ weakenNeutral FZ = FZ
277
+ weakenNeutral (FS k) = FS (weakenNeutral k)
278
+
279
+ export
280
+ weakenNNeutral : (0 m : Nat ) -> (k : Fin n) -> weakenN m k ~~~ k
281
+ weakenNNeutral m FZ = FZ
282
+ weakenNNeutral m (FS k) = FS (weakenNNeutral m k)
0 commit comments