0 | module Data.Fin.Extra
3 | import public Data.Fin.Arith as Data.Fin.Extra
4 | import public Data.Fin.Properties as Data.Fin.Extra
5 | import public Data.Fin.Split as Data.Fin.Extra
7 | import Data.Nat.Division
9 | import Syntax.WithProof
10 | import Syntax.PreorderReasoning
21 | public export %inline
22 | invFin : {n : Nat} -> Fin n -> Fin n
27 | invFinSpec : {n : _} -> (i : Fin n) -> 1 + finToNat i + finToNat (complement i) = n
28 | invFinSpec = complementSpec
32 | invFinWeakenIsFS : {n : Nat} -> (m : Fin n) -> complement (weaken m) = FS (complement m)
33 | invFinWeakenIsFS = complementWeakenIsFS
37 | invFinLastIsFZ : {n : Nat} -> complement (last {n}) = FZ
38 | invFinLastIsFZ = complementLastIsFZ
42 | invFinInvolutive : {n : Nat} -> (m : Fin n) -> complement (complement m) = m
43 | invFinInvolutive = complementInvolutive
51 | data FractionView : (n : Nat) -> (d : Nat) -> Type where
52 | Fraction : (n : Nat) -> (d : Nat) -> {auto ok: GT d Z} ->
53 | (q : Nat) -> (r : Fin d) ->
54 | q * d + finToNat r = n -> FractionView n d
58 | divMod : (n, d : Nat) -> {auto ok: GT d Z} -> FractionView n d
59 | divMod Z (S d) = Fraction Z (S d) Z FZ Refl
60 | divMod {ok=_} (S n) (S d) =
61 | let Fraction {ok=ok} n (S d) q r eq = divMod n (S d) in
62 | case strengthen' r of
63 | Left eq' => Fraction {ok=ok} (S n) (S d) (S q) FZ $
65 | rewrite trans (cong finToNat eq') finToNatLastIsBound in
67 | (plusZeroRightNeutral (d + q * S d))
68 | (plusCommutative d (q * S d))
69 | Right (
r' ** eq')
=> Fraction {ok=ok} (S n) (S d) q (FS r') $
70 | rewrite sym $
plusSuccRightSucc (q * S d) (finToNat r') in
71 | cong S $
trans (sym $
cong (plus (q * S d)) eq') eq
80 | -> {auto mNZ : NonZero m}
82 | modFin n 0 impossible
84 | modFin (S j) (S k) =
86 | n' = modNatNZ (S j) (S k) mNZ in
87 | let ok = boundModNatNZ (S j) (S k) mNZ
88 | in natToFinLT n' @{ok}
93 | strengthenMod : {n : _}
96 | -> {auto mNZ : NonZero m}
98 | strengthenMod _ Z impossible
99 | strengthenMod {n = 0} f m@(S k) = weakenN m f
100 | strengthenMod {n = (S j)} f m@(S k) =
102 | n' = modNatNZ (S j) (S k) %search in
103 | let ok = boundModNatNZ (S j) (S k) %search
104 | in natToFinLT n' @{ok}
113 | natToFinLTE : (n : Nat) -> (0 _ : LT n m) -> Fin m
114 | natToFinLTE Z (LTESucc _) = FZ
115 | natToFinLTE (S k) (LTESucc l) = FS $
natToFinLTE k l
122 | -> finToNat (natToFinLTE n lte) = n
123 | natToFinToNat 0 (LTESucc lte) = Refl
124 | natToFinToNat (S k) (LTESucc lte) = cong S (natToFinToNat k lte)