35 | module Data.Array.Index
38 | import public Data.DPair
39 | import public Data.Fin
40 | import public Data.Maybe0
41 | import public Data.Nat
46 | 0 ltLemma : (0 k,m,n : Nat) -> k + S m === n -> LT k n
47 | ltLemma 0 m (S m) Refl = %search
48 | ltLemma (S k) m (S n) prf = LTESucc $
ltLemma k m n (injective prf)
49 | ltLemma (S k) m 0 prf = absurd prf
52 | 0 lteLemma : (0 k,m,n : Nat) -> k + m === n -> LTE k n
53 | lteLemma 0 m m Refl = %search
54 | lteLemma (S k) m (S n) prf = LTESucc $
lteLemma k m n (injective prf)
55 | lteLemma (S k) m 0 prf = absurd prf
58 | 0 lteSuccPlus : (k : Nat) -> LTE (S k) (k + S m)
59 | lteSuccPlus 0 = LTESucc LTEZero
60 | lteSuccPlus (S k) = LTESucc $
lteSuccPlus k
67 | data Suffix : (xs,ys : List a) -> Type where
69 | Uncons : Suffix (x::xs) ys -> Suffix xs ys
72 | suffixToNat : Suffix xs ys -> Nat
73 | suffixToNat Same = 0
74 | suffixToNat (Uncons x) = S $
suffixToNat x
77 | 0 suffixLemma : (s : Suffix xs ys) -> suffixToNat s + length xs === length ys
78 | suffixLemma Same = Refl
79 | suffixLemma (Uncons x) = trans (plusSuccRightSucc _ _) $
suffixLemma x
82 | 0 suffixLT : (s : Suffix (x::xs) ys) -> LT (suffixToNat s) (length ys)
83 | suffixLT s = ltLemma _ _ _ $
suffixLemma s
86 | suffixToFin : Suffix (x::xs) ys -> Fin (length ys)
87 | suffixToFin x = natToFinLT (suffixToNat x) @{suffixLT x}
98 | data Ix : (m,n : Nat) -> Type where
100 | IS : Ix (S m) n -> Ix m n
104 | ixToNat : Ix m n -> Nat
106 | ixToNat (IS n) = S $
ixToNat n
110 | succIx : Ix m n -> Ix (S m) (S n)
112 | succIx (IS x) = IS (succIx x)
118 | natToIx : (n : Nat) -> Ix 0 n
120 | natToIx (S k) = IS $
succIx (natToIx k)
127 | natToIx1 : (n : Nat) -> Ix 1 (S n)
128 | natToIx1 n = case natToIx (S n) of
133 | 0 ixLemma : (x : Ix m n) -> ixToNat x + m === n
135 | ixLemma (IS v) = trans (plusSuccRightSucc _ _) $
ixLemma v
141 | 0 ixLT : (x : Ix (S m) n) -> LT (ixToNat x) n
142 | ixLT s = ltLemma _ _ _ $
ixLemma s
147 | 0 ixLTE : (x : Ix m n) -> LTE (ixToNat x) n
148 | ixLTE s = lteLemma _ _ _ $
ixLemma s
155 | ixToFin : Ix (S m) n -> Fin n
156 | ixToFin x = natToFinLT (ixToNat x) @{ixLT x}
163 | 0 finToNatLT : (x : Fin n) -> LT (finToNat x) n
164 | finToNatLT FZ = %search
165 | finToNatLT (FS x) = LTESucc $
finToNatLT x
171 | 0 SubLength : Nat -> Type
172 | SubLength n = Subset Nat (`LTE` n)
175 | sublength : (k : Nat) -> (0 lte : LTE k n) => SubLength n
176 | sublength k = Element k lte
179 | fromFin : Fin n -> SubLength n
180 | fromFin x = Element (finToNat x) (lteSuccLeft $
finToNatLT x)
183 | fromIx : Ix m n -> SubLength n
184 | fromIx x = Element (ixToNat x) (ixLTE x)
195 | 0 lsl : (p : LTE (S m) n) => LTE m n
196 | lsl = lteSuccLeft p
203 | 0 lteOpReflectsLTE : (m,n : Nat) -> (m <= n) === True -> LTE m n
204 | lteOpReflectsLTE 0 (S k) prf = LTEZero
205 | lteOpReflectsLTE (S k) (S j) prf = LTESucc (lteOpReflectsLTE k j prf)
206 | lteOpReflectsLTE 0 0 prf = LTEZero
207 | lteOpReflectsLTE (S k) Z prf impossible
210 | 0 ltOpReflectsLT : (m,n : Nat) -> (m < n) === True -> LT m n
211 | ltOpReflectsLT 0 (S k) prf = LTESucc LTEZero
212 | ltOpReflectsLT (S k) (S j) prf = LTESucc (ltOpReflectsLT k j prf)
213 | ltOpReflectsLT Z Z prf impossible
214 | ltOpReflectsLT (S k) Z prf impossible
217 | 0 eqOpReflectsEquals : (m,n : Nat) -> (m == n) === True -> m === n
218 | eqOpReflectsEquals 0 0 prf = Refl
219 | eqOpReflectsEquals (S k) (S j) prf = cong S $
eqOpReflectsEquals k j prf
220 | eqOpReflectsEquals Z (S k) prf impossible
221 | eqOpReflectsEquals (S k) Z prf impossible
228 | tryLT : {n : _} -> (k : Nat) -> Maybe0 (LT k n)
229 | tryLT k with (k < n) proof eq
230 | _ | True = Just0 $
ltOpReflectsLT k n eq
231 | _ | False = Nothing0
234 | tryLTE : {n : _} -> (k : Nat) -> Maybe0 (LTE k n)
235 | tryLTE 0 = Just0 %search
236 | tryLTE (S k) = tryLT k
240 | tryNatToFin : {k : _} -> Nat -> Maybe (Fin k)
241 | tryNatToFin n with (n < k) proof eq
242 | _ | True = Just $
natToFinLT n @{ltOpReflectsLT n k eq}
243 | _ | False = Nothing
247 | tryFinToFin : {k : _} -> Fin n -> Maybe (Fin k)
248 | tryFinToFin = tryNatToFin . finToNat
251 | 0 minusLTE : (k,m : Nat) -> LTE (k `minus` m) k
252 | minusLTE 0 m = LTEZero
253 | minusLTE (S k) 0 = reflexive
254 | minusLTE (S k) (S j) = lteSuccRight $
minusLTE k j
257 | 0 minusFinLT : (n : Nat) -> (x : Fin n) -> LT (n `minus` S (finToNat x)) n
258 | minusFinLT (S k) FZ = LTESucc (minusLTE k 0)
259 | minusFinLT (S k) (FS x) = LTESucc (minusLTE k _)
262 | 0 minusLT : (x,m,n : Nat) -> LT x (n `minus` m) -> LT (x+m) n
263 | minusLT x _ 0 y = absurd y
264 | minusLT x 0 (S k) y = rewrite plusZeroRightNeutral x in y
265 | minusLT x (S k) (S j) y =
266 | let p1 := minusLT x k j y
267 | in LTESucc (rewrite sym (plusSuccRightSucc x k) in p1)
270 | inc : {m : _} -> Fin (n `minus` m) -> Fin n
272 | let 0 p1 := finToNatLT x
273 | in natToFinLT (finToNat x + m) @{minusLT _ _ _ p1}
276 | 0 ltAddLeft : LT k n -> LT k (m+n)
277 | ltAddLeft {m = 0} lt = lt
278 | ltAddLeft {m = S x} lt = lteSuccRight $
ltAddLeft lt
281 | 0 lteAddLeft : (n : Nat) -> LTE n (m+n)
282 | lteAddLeft n = rewrite plusCommutative m n in lteAddRight n
289 | 0 plusMinus : (m,n : Nat) -> LTE m n -> m + (n `minus` m) === n
290 | plusMinus 0 0 _ = Refl
291 | plusMinus 0 (S k) x = Refl
292 | plusMinus (S k) (S j) (LTESucc p) = cong S $
plusMinus k j p
293 | plusMinus (S k) Z x impossible
296 | 0 eqLTE : (m,n : Nat) -> m === n -> LTE m n
297 | eqLTE 0 0 Refl = LTEZero
298 | eqLTE (S k) (S k) Refl = LTESucc $
eqLTE k k Refl
301 | 0 dropLemma : (k,n : Nat) -> LTE (plus (minus n (minus n k)) (minus n k)) n
303 | let p1 := minusLTE n k
304 | p2 := plusMinus _ _ p1
305 | p3 := trans (plusCommutative _ _) p2
309 | 0 plusMinusLTE : (m,n : Nat) -> LTE m n -> LTE (m + (n `minus` m)) n
310 | plusMinusLTE m n lte = eqLTE _ _ $
plusMinus m n lte
320 | trans : Ix k m -> Ix m n -> Ix k n
322 | trans (IS x) t = IS $
trans x t
325 | transp : Ix k m -> Ix m n -> Ix k n
326 | transp x y = believe_me (ixToNat x + ixToNat y)
328 | %transform "ixTransPlus"
Index.trans = Index.transp
331 | public export %inline
332 | Reflexive Nat Ix where
336 | public export %inline
337 | Transitive Nat Ix where
345 | 0 castBits8LT : (x : Bits8) -> LT (cast x) 256
347 | case choose (cast {to = Nat} x < 256) of
348 | Left oh => Data.Nat.ltOpReflectsLT _ _ oh
349 | _ => assert_total $
idris_crash "Bits8 value >= 256"
353 | bits8ToFin : Bits8 -> Fin 256
354 | bits8ToFin x = natToFinLT (cast x) @{castBits8LT x}