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 | allFinsFast : (n : Nat) -> List (Fin n)
69 | allFinsFast (S n) = go [] last
71 | go : List (Fin $
S n) -> Fin (S n) -> List (Fin $
S n)
73 | go xs (FS x) = go (FS x :: xs) (assert_smaller (FS x) $
weaken x)
80 | data Suffix : (xs,ys : List a) -> Type where
82 | Uncons : Suffix (x::xs) ys -> Suffix xs ys
85 | suffixToNat : Suffix xs ys -> Nat
86 | suffixToNat Same = 0
87 | suffixToNat (Uncons x) = S $
suffixToNat x
90 | 0 suffixLemma : (s : Suffix xs ys) -> suffixToNat s + length xs === length ys
91 | suffixLemma Same = Refl
92 | suffixLemma (Uncons x) = trans (plusSuccRightSucc _ _) $
suffixLemma x
95 | 0 suffixLT : (s : Suffix (x::xs) ys) -> LT (suffixToNat s) (length ys)
96 | suffixLT s = ltLemma _ _ _ $
suffixLemma s
99 | suffixToFin : Suffix (x::xs) ys -> Fin (length ys)
100 | suffixToFin x = natToFinLT (suffixToNat x) @{suffixLT x}
111 | data Ix : (m,n : Nat) -> Type where
113 | IS : Ix (S m) n -> Ix m n
117 | ixToNat : Ix m n -> Nat
119 | ixToNat (IS n) = S $
ixToNat n
123 | succIx : Ix m n -> Ix (S m) (S n)
125 | succIx (IS x) = IS (succIx x)
131 | natToIx : (n : Nat) -> Ix 0 n
133 | natToIx (S k) = IS $
succIx (natToIx k)
140 | natToIx1 : (n : Nat) -> Ix 1 (S n)
141 | natToIx1 n = case natToIx (S n) of
146 | 0 ixLemma : (x : Ix m n) -> ixToNat x + m === n
148 | ixLemma (IS v) = trans (plusSuccRightSucc _ _) $
ixLemma v
154 | 0 ixLT : (x : Ix (S m) n) -> LT (ixToNat x) n
155 | ixLT s = ltLemma _ _ _ $
ixLemma s
160 | 0 ixLTE : (x : Ix m n) -> LTE (ixToNat x) n
161 | ixLTE s = lteLemma _ _ _ $
ixLemma s
168 | ixToFin : Ix (S m) n -> Fin n
169 | ixToFin x = natToFinLT (ixToNat x) @{ixLT x}
176 | 0 finToNatLT : (x : Fin n) -> LT (finToNat x) n
177 | finToNatLT FZ = %search
178 | finToNatLT (FS x) = LTESucc $
finToNatLT x
184 | 0 SubLength : Nat -> Type
185 | SubLength n = Subset Nat (`LTE` n)
188 | sublength : (k : Nat) -> (0 lte : LTE k n) => SubLength n
189 | sublength k = Element k lte
192 | fromFin : Fin n -> SubLength n
193 | fromFin x = Element (finToNat x) (lteSuccLeft $
finToNatLT x)
196 | fromIx : Ix m n -> SubLength n
197 | fromIx x = Element (ixToNat x) (ixLTE x)
208 | 0 lsl : (p : LTE (S m) n) => LTE m n
209 | lsl = lteSuccLeft p
216 | 0 lteOpReflectsLTE : (m,n : Nat) -> (m <= n) === True -> LTE m n
217 | lteOpReflectsLTE 0 (S k) prf = LTEZero
218 | lteOpReflectsLTE (S k) (S j) prf = LTESucc (lteOpReflectsLTE k j prf)
219 | lteOpReflectsLTE 0 0 prf = LTEZero
220 | lteOpReflectsLTE (S k) Z prf impossible
223 | 0 ltOpReflectsLT : (m,n : Nat) -> (m < n) === True -> LT m n
224 | ltOpReflectsLT 0 (S k) prf = LTESucc LTEZero
225 | ltOpReflectsLT (S k) (S j) prf = LTESucc (ltOpReflectsLT k j prf)
226 | ltOpReflectsLT Z Z prf impossible
227 | ltOpReflectsLT (S k) Z prf impossible
230 | 0 eqOpReflectsEquals : (m,n : Nat) -> (m == n) === True -> m === n
231 | eqOpReflectsEquals 0 0 prf = Refl
232 | eqOpReflectsEquals (S k) (S j) prf = cong S $
eqOpReflectsEquals k j prf
233 | eqOpReflectsEquals Z (S k) prf impossible
234 | eqOpReflectsEquals (S k) Z prf impossible
241 | tryLT : {n : _} -> (k : Nat) -> Maybe0 (LT k n)
242 | tryLT k with (k < n) proof eq
243 | _ | True = Just0 $
ltOpReflectsLT k n eq
244 | _ | False = Nothing0
247 | tryLTE : {n : _} -> (k : Nat) -> Maybe0 (LTE k n)
248 | tryLTE 0 = Just0 %search
249 | tryLTE (S k) = tryLT k
253 | tryNatToFin : {k : _} -> Nat -> Maybe (Fin k)
254 | tryNatToFin n with (n < k) proof eq
255 | _ | True = Just $
natToFinLT n @{ltOpReflectsLT n k eq}
256 | _ | False = Nothing
260 | tryFinToFin : {k : _} -> Fin n -> Maybe (Fin k)
261 | tryFinToFin = tryNatToFin . finToNat
264 | 0 minusLTE : (k,m : Nat) -> LTE (k `minus` m) k
265 | minusLTE 0 m = LTEZero
266 | minusLTE (S k) 0 = reflexive
267 | minusLTE (S k) (S j) = lteSuccRight $
minusLTE k j
270 | 0 minusFinLT : (n : Nat) -> (x : Fin n) -> LT (n `minus` S (finToNat x)) n
271 | minusFinLT (S k) FZ = LTESucc (minusLTE k 0)
272 | minusFinLT (S k) (FS x) = LTESucc (minusLTE k _)
275 | 0 minusLT : (x,m,n : Nat) -> LT x (n `minus` m) -> LT (x+m) n
276 | minusLT x _ 0 y = absurd y
277 | minusLT x 0 (S k) y = rewrite plusZeroRightNeutral x in y
278 | minusLT x (S k) (S j) y =
279 | let p1 := minusLT x k j y
280 | in LTESucc (rewrite sym (plusSuccRightSucc x k) in p1)
283 | inc : {m : _} -> Fin (n `minus` m) -> Fin n
285 | let 0 p1 := finToNatLT x
286 | in natToFinLT (finToNat x + m) @{minusLT _ _ _ p1}
289 | 0 ltAddLeft : LT k n -> LT k (m+n)
290 | ltAddLeft {m = 0} lt = lt
291 | ltAddLeft {m = S x} lt = lteSuccRight $
ltAddLeft lt
294 | 0 lteAddLeft : (n : Nat) -> LTE n (m+n)
295 | lteAddLeft n = rewrite plusCommutative m n in lteAddRight n
302 | 0 plusMinus : (m,n : Nat) -> LTE m n -> m + (n `minus` m) === n
303 | plusMinus 0 0 _ = Refl
304 | plusMinus 0 (S k) x = Refl
305 | plusMinus (S k) (S j) (LTESucc p) = cong S $
plusMinus k j p
306 | plusMinus (S k) Z x impossible
309 | 0 eqLTE : (m,n : Nat) -> m === n -> LTE m n
310 | eqLTE 0 0 Refl = LTEZero
311 | eqLTE (S k) (S k) Refl = LTESucc $
eqLTE k k Refl
314 | 0 dropLemma : (k,n : Nat) -> LTE (plus (minus n (minus n k)) (minus n k)) n
316 | let p1 := minusLTE n k
317 | p2 := plusMinus _ _ p1
318 | p3 := trans (plusCommutative _ _) p2
322 | 0 plusMinusLTE : (m,n : Nat) -> LTE m n -> LTE (m + (n `minus` m)) n
323 | plusMinusLTE m n lte = eqLTE _ _ $
plusMinus m n lte
333 | trans : Ix k m -> Ix m n -> Ix k n
335 | trans (IS x) t = IS $
trans x t
338 | transp : Ix k m -> Ix m n -> Ix k n
339 | transp x y = believe_me (ixToNat x + ixToNat y)
341 | %transform "ixTransPlus"
Index.trans = Index.transp
344 | public export %inline
345 | Reflexive Nat Ix where
349 | public export %inline
350 | Transitive Nat Ix where
358 | 0 castBits8LT : (x : Bits8) -> LT (cast x) 256
360 | case choose (cast {to = Nat} x < 256) of
361 | Left oh => Data.Nat.ltOpReflectsLT _ _ oh
362 | _ => assert_total $
idris_crash "Bits8 value >= 256"
366 | bits8ToFin : Bits8 -> Fin 256
367 | bits8ToFin x = natToFinLT (cast x) @{castBits8LT x}