2 | import Control.Function
3 | import public Control.Ord
5 | import public Data.Maybe
6 | import public Data.Nat
7 | import public Data.So
8 | import Decidable.Equality.Core
18 | data Fin : (n : Nat) -> Type where
20 | FS : Fin k -> Fin (S k)
24 | coerce : {n : Nat} -> (0 eq : m = n) -> Fin m -> Fin n
25 | coerce {n = S _} eq FZ = FZ
26 | coerce {n = Z} eq FZ impossible
27 | coerce {n = S _} eq (FS k) = FS (coerce (injective eq) k)
28 | coerce {n = Z} eq (FS k) impossible
30 | %transform "coerce-identity"
coerce eq k = replace {p = Fin} eq k
33 | Uninhabited (Fin Z) where
34 | uninhabited FZ
impossible
35 | uninhabited (FS f
) impossible
38 | Uninhabited (FZ = FS k) where
39 | uninhabited Refl
impossible
42 | Uninhabited (FS k = FZ) where
43 | uninhabited Refl
impossible
46 | Uninhabited (n = m) => Uninhabited (FS n = FS m) where
47 | uninhabited Refl @{nm} = uninhabited Refl @{nm}
51 | injective Refl = Refl
55 | finToNat : Fin n -> Nat
57 | finToNat (FS k) = S $
finToNat k
61 | x == y = finToNat x == finToNat y
63 | finToNatInjective : (fm : Fin k) -> (fn : Fin k) -> (finToNat fm) = (finToNat fn) -> fm = fn
64 | finToNatInjective FZ FZ _ = Refl
65 | finToNatInjective (FS _) FZ Refl impossible
66 | finToNatInjective FZ (FS _) Refl impossible
67 | finToNatInjective (FS m) (FS n) prf =
68 | cong FS $
finToNatInjective m n $
injective prf
72 | Injective Fin.finToNat where
73 | injective = (finToNatInjective _ _)
76 | Cast (Fin n) Nat where
81 | finToInteger : Fin n -> Integer
83 | finToInteger (FS k) = 1 + finToInteger k
89 | show = show . finToInteger
92 | Cast (Fin n) Integer where
97 | weaken : Fin n -> Fin (S n)
99 | weaken (FS k) = FS $
weaken k
103 | weakenN : (0 n : Nat) -> Fin m -> Fin (m + n)
105 | weakenN n (FS f) = FS $
weakenN n f
109 | weakenLTE : Fin n -> LTE n m -> Fin m
110 | weakenLTE FZ LTEZero
impossible
111 | weakenLTE (FS
_) LTEZero
impossible
112 | weakenLTE FZ (LTESucc _) = FZ
113 | weakenLTE (FS x) (LTESucc y) = FS $
weakenLTE x y
118 | strengthen : {n : _} -> Fin (S n) -> Maybe (Fin n)
119 | strengthen {n = S _} FZ = Just FZ
120 | strengthen {n = S _} (FS p) with (strengthen p)
121 | strengthen (FS _) | Nothing = Nothing
122 | strengthen (FS _) | Just q = Just $
FS q
123 | strengthen _ = Nothing
129 | shift : (m : Nat) -> Fin n -> Fin (m + n)
131 | shift (S m) f = FS $
shift m f
135 | finS : {n : Nat} -> Fin n -> Fin n
136 | finS {n = S _} x = case strengthen x of
142 | last : {n : _} -> Fin (S n)
144 | last {n=S _} = FS last
149 | complement : {n : Nat} -> Fin n -> Fin n
150 | complement {n = S _} FZ = last
151 | complement {n = S _} (FS x) = weaken $
complement x
157 | allFins : (n : Nat) -> List (Fin n)
159 | allFins (S n) = FZ :: map FS (allFins n)
165 | allFins : (n : Nat) -> List1 (Fin (S n))
166 | allFins Z = FZ ::: []
167 | allFins (S n) = FZ ::: map FS (forget (allFins n))
172 | compare x y = compare (finToNat x) (finToNat y)
177 | [Minimum] {n : Nat} -> Monoid (Fin $
S n) using Semigroup.Minimum where
181 | [Maximum] Monoid (Fin $
S n) using Semigroup.Maximum where
185 | natToFinLT : (x : Nat) -> {0 n : Nat} ->
186 | {auto 0 prf : x `LT` n} ->
188 | natToFinLT Z {prf = LTESucc _} = FZ
189 | natToFinLT (S k) {prf = LTESucc _} = FS $
natToFinLT k
192 | natToFinLt : (x : Nat) -> {0 n : Nat} ->
193 | {auto 0 prf : So (x < n)} ->
195 | natToFinLt x = let 0 p := ltOpReflectsLT x n prf in natToFinLT x
198 | natToFin : Nat -> (n : Nat) -> Maybe (Fin n)
199 | natToFin x n = case isLT x n of
200 | Yes prf => Just $
natToFinLT x
201 | No contra => Nothing
206 | integerToFin : Integer -> (n : Nat) -> Maybe (Fin n)
207 | integerToFin x Z = Nothing
208 | integerToFin x n = if x >= 0 then natToFin (fromInteger x) n else Nothing
211 | maybeLTE : (x : Nat) -> (y : Nat) -> Maybe (x `LTE` y)
212 | maybeLTE Z _ = Just LTEZero
213 | maybeLTE (S x) (S y) = LTESucc <$> maybeLTE x y
214 | maybeLTE _ _ = Nothing
217 | maybeLT : (x : Nat) -> (y : Nat) -> Maybe (x `LT` y)
218 | maybeLT x y = maybeLTE (S x) y
221 | finFromInteger : (x : Integer) ->
222 | {auto 0 prf : So (fromInteger x < n)} ->
224 | finFromInteger x = natToFinLt (fromInteger x)
231 | integerLessThanNat : Integer -> Nat -> Bool
232 | integerLessThanNat 0 (S m) = True
233 | integerLessThanNat x n with (x < the Integer 0)
234 | integerLessThanNat _ _ | True = False
235 | integerLessThanNat x (S m) | False = integerLessThanNat (x-1) m
236 | integerLessThanNat x Z | False = False
242 | fromInteger : (x : Integer) ->
243 | {auto 0 prf : So (integerLessThanNat x n)} ->
245 | fromInteger x = finFromInteger x {prf = lemma prf} where
248 | 0 lemma : {x : Integer} -> So (integerLessThanNat x n) -> So (fromInteger {ty=Nat} x < n)
249 | lemma oh = believe_me oh
256 | restrict : (n : Nat) -> Integer -> Fin (S n)
257 | restrict n val = let val' = assert_total (abs (mod val (cast (S n)))) in
261 | fromInteger {n = S n} val'
262 | {prf = believe_me {a=IsJust (Just val')} ItIsJust}
269 | {n : Nat} -> Num (Fin (S n)) where
271 | (+) {n = S _} (FS x) y = finS $
assert_smaller x (weaken x) + y
274 | (FS x) * y = y + (assert_smaller x $
weaken x) * y
276 | fromInteger = restrict n
279 | {n : Nat} -> Neg (Fin (S n)) where
280 | negate = finS . complement
282 | x - y = x + (negate y)
289 | DecEq (Fin n) where
290 | decEq FZ FZ = Yes Refl
291 | decEq (FS f) (FS f') = decEqCong $
decEq f f'
292 | decEq FZ (FS f) = No absurd
293 | decEq (FS f) FZ = No absurd
303 | data Pointwise : Fin m -> Fin n -> Type where
304 | FZ : Pointwise FZ FZ
305 | FS : Pointwise k l -> Pointwise (FS k) (FS l)
310 | (~~~) : Fin m -> Fin n -> Type
314 | Uninhabited (FS k ~~~ FZ) where
315 | uninhabited FZ
impossible
316 | uninhabited (FS
_) impossible
319 | Uninhabited (FZ ~~~ FS k) where
320 | uninhabited FZ
impossible
321 | uninhabited (FS
_) impossible
325 | reflexive : {k : Fin m} -> k ~~~ k
326 | reflexive {k = FZ} = FZ
327 | reflexive {k = FS k} = FS reflexive
331 | symmetric : k ~~~ l -> l ~~~ k
333 | symmetric (FS prf) = FS (symmetric prf)
337 | transitive : j ~~~ k -> k ~~~ l -> j ~~~ l
338 | transitive FZ FZ = FZ
339 | transitive (FS prf) (FS prg) = FS (transitive prf prg)
343 | coerceEq : {k : Fin m} -> (0 eq : m = n) -> coerce eq k ~~~ k
344 | coerceEq {k = FZ} Refl = FZ
345 | coerceEq {k = FS k} Refl = FS (coerceEq _)
349 | congCoerce : {0 n, q : Nat} -> {k : Fin m} -> {l : Fin p} ->
350 | {0 eq1 : m = n} -> {0 eq2 : p = q} ->
352 | coerce eq1 k ~~~ coerce eq2 l
354 | = transitive (coerceEq _)
355 | $
transitive eq $
symmetric $
coerceEq _
359 | congLast : {m : Nat} -> (0 _ : m = n) -> last {n=m} ~~~ last {n}
360 | congLast Refl = reflexive
363 | congShift : (m : Nat) -> k ~~~ l -> shift m k ~~~ shift m l
364 | congShift Z prf = prf
365 | congShift (S m) prf = FS (congShift m prf)
369 | congWeakenN : k ~~~ l -> weakenN n k ~~~ weakenN n l
370 | congWeakenN FZ = FZ
371 | congWeakenN (FS prf) = FS (congWeakenN prf)
375 | homoPointwiseIsEqual : {0 k, l : Fin m} -> k ~~~ l -> k === l
376 | homoPointwiseIsEqual FZ = Refl
377 | homoPointwiseIsEqual (FS prf) = cong FS (homoPointwiseIsEqual prf)
382 | hetPointwiseIsTransport :
383 | {0 k : Fin m} -> {0 l : Fin n} ->
384 | (0 eq : m === n) -> k ~~~ l -> k === rewrite eq in l
385 | hetPointwiseIsTransport Refl = homoPointwiseIsEqual
388 | finToNatQuotient : k ~~~ l -> finToNat k === finToNat l
389 | finToNatQuotient FZ = Refl
390 | finToNatQuotient (FS prf) = cong S (finToNatQuotient prf)
394 | finToNatEqualityAsPointwise : (k : Fin m) ->
396 | finToNat k = finToNat l ->
398 | finToNatEqualityAsPointwise FZ FZ _ = FZ
399 | finToNatEqualityAsPointwise FZ (FS _) prf = absurd prf
400 | finToNatEqualityAsPointwise (FS _) FZ prf = absurd prf
401 | finToNatEqualityAsPointwise (FS k) (FS l) prf = FS $
finToNatEqualityAsPointwise k l (injective prf)
404 | weakenNeutral : (k : Fin n) -> weaken k ~~~ k
405 | weakenNeutral FZ = FZ
406 | weakenNeutral (FS k) = FS (weakenNeutral k)
409 | weakenNNeutral : (0 m : Nat) -> (k : Fin n) -> weakenN m k ~~~ k
410 | weakenNNeutral m FZ = FZ
411 | weakenNNeutral m (FS k) = FS (weakenNNeutral m k)