35 | module Data.Array.Index
37 | import Control.Order
39 | import Decidable.Equality
40 | import public Data.DPair
41 | import public Data.Fin
42 | import public Data.Maybe0
43 | import public Data.Nat
48 | 0 ltLemma : (0 k,m,n : Nat) -> k + S m === n -> LT k n
49 | ltLemma 0 m (S m) Refl = %search
50 | ltLemma (S k) m (S n) prf = LTESucc $
ltLemma k m n (injective prf)
51 | ltLemma (S k) m 0 prf = absurd prf
54 | 0 lteLemma : (0 k,m,n : Nat) -> k + m === n -> LTE k n
55 | lteLemma 0 m m Refl = %search
56 | lteLemma (S k) m (S n) prf = LTESucc $
lteLemma k m n (injective prf)
57 | lteLemma (S k) m 0 prf = absurd prf
60 | 0 lteSuccPlus : (k : Nat) -> LTE (S k) (k + S m)
61 | lteSuccPlus 0 = LTESucc LTEZero
62 | lteSuccPlus (S k) = LTESucc $
lteSuccPlus k
69 | allFinsFast : (n : Nat) -> List (Fin n)
71 | allFinsFast (S n) = go [] last
73 | go : List (Fin $
S n) -> Fin (S n) -> List (Fin $
S n)
75 | go xs (FS x) = go (FS x :: xs) (assert_smaller (FS x) $
weaken x)
82 | data Suffix : (xs,ys : List a) -> Type where
84 | Uncons : Suffix (x::xs) ys -> Suffix xs ys
87 | suffixToNat : Suffix xs ys -> Nat
88 | suffixToNat Same = 0
89 | suffixToNat (Uncons x) = S $
suffixToNat x
92 | 0 suffixLemma : (s : Suffix xs ys) -> suffixToNat s + length xs === length ys
93 | suffixLemma Same = Refl
94 | suffixLemma (Uncons x) = trans (plusSuccRightSucc _ _) $
suffixLemma x
97 | 0 suffixLT : (s : Suffix (x::xs) ys) -> LT (suffixToNat s) (length ys)
98 | suffixLT s = ltLemma _ _ _ $
suffixLemma s
101 | suffixToFin : Suffix (x::xs) ys -> Fin (length ys)
102 | suffixToFin x = natToFinLT (suffixToNat x) @{suffixLT x}
113 | data Ix : (m,n : Nat) -> Type where
115 | IS : Ix (S m) n -> Ix m n
119 | ixToNat : Ix m n -> Nat
121 | ixToNat (IS n) = S $
ixToNat n
125 | succIx : Ix m n -> Ix (S m) (S n)
127 | succIx (IS x) = IS (succIx x)
131 | plusIx : Ix m n -> Ix (o + m) (o + n)
133 | plusIx (IS x) = IS $
rewrite plusSuccRightSucc o m in plusIx x
137 | symPlusIx : Ix m n -> Ix (m+o) (n+o)
139 | rewrite plusCommutative m o in
140 | rewrite plusCommutative n o in plusIx x
146 | natToIx : (n : Nat) -> Ix 0 n
148 | natToIx (S k) = IS $
succIx (natToIx k)
151 | offset : (0 n : Nat) -> (o : Nat) -> Ix n (o+n)
152 | offset n o = symPlusIx {o = n} $
natToIx o
159 | natToIx1 : (n : Nat) -> Ix 1 (S n)
160 | natToIx1 n = case natToIx (S n) of
165 | 0 ixLemma : (x : Ix m n) -> ixToNat x + m === n
167 | ixLemma (IS v) = trans (plusSuccRightSucc _ _) $
ixLemma v
173 | 0 ixLT : (x : Ix (S m) n) -> LT (ixToNat x) n
174 | ixLT s = ltLemma _ _ _ $
ixLemma s
179 | 0 ixLTE : (x : Ix m n) -> LTE (ixToNat x) n
180 | ixLTE s = lteLemma _ _ _ $
ixLemma s
187 | ixToFin : Ix (S m) n -> Fin n
188 | ixToFin x = natToFinLT (ixToNat x) @{ixLT x}
195 | 0 finToNatLT : (x : Fin n) -> LT (finToNat x) n
196 | finToNatLT FZ = %search
197 | finToNatLT (FS x) = LTESucc $
finToNatLT x
203 | 0 SubLength : Nat -> Type
204 | SubLength n = Subset Nat (`LTE` n)
207 | sublength : (k : Nat) -> (0 lte : LTE k n) => SubLength n
208 | sublength k = Element k lte
211 | fromFin : Fin n -> SubLength n
212 | fromFin x = Element (finToNat x) (lteSuccLeft $
finToNatLT x)
215 | fromIx : Ix m n -> SubLength n
216 | fromIx x = Element (ixToNat x) (ixLTE x)
227 | 0 lsl : (p : LTE (S m) n) => LTE m n
228 | lsl = lteSuccLeft p
235 | 0 lteOpReflectsLTE : (m,n : Nat) -> (m <= n) === True -> LTE m n
236 | lteOpReflectsLTE 0 (S k) prf = LTEZero
237 | lteOpReflectsLTE (S k) (S j) prf = LTESucc (lteOpReflectsLTE k j prf)
238 | lteOpReflectsLTE 0 0 prf = LTEZero
239 | lteOpReflectsLTE (S k) Z prf impossible
242 | 0 ltOpReflectsLT : (m,n : Nat) -> (m < n) === True -> LT m n
243 | ltOpReflectsLT 0 (S k) prf = LTESucc LTEZero
244 | ltOpReflectsLT (S k) (S j) prf = LTESucc (ltOpReflectsLT k j prf)
245 | ltOpReflectsLT Z Z prf impossible
246 | ltOpReflectsLT (S k) Z prf impossible
249 | 0 eqOpReflectsEquals : (m,n : Nat) -> (m == n) === True -> m === n
250 | eqOpReflectsEquals 0 0 prf = Refl
251 | eqOpReflectsEquals (S k) (S j) prf = cong S $
eqOpReflectsEquals k j prf
252 | eqOpReflectsEquals Z (S k) prf impossible
253 | eqOpReflectsEquals (S k) Z prf impossible
260 | tryLT : {n : _} -> (k : Nat) -> Maybe0 (LT k n)
261 | tryLT k with (k < n) proof eq
262 | _ | True = Just0 $
ltOpReflectsLT k n eq
263 | _ | False = Nothing0
266 | tryLTE : {n : _} -> (k : Nat) -> Maybe0 (LTE k n)
267 | tryLTE 0 = Just0 %search
268 | tryLTE (S k) = tryLT k
272 | tryNatToFin : {k : _} -> Nat -> Maybe (Fin k)
273 | tryNatToFin n with (n < k) proof eq
274 | _ | True = Just $
natToFinLT n @{ltOpReflectsLT n k eq}
275 | _ | False = Nothing
279 | tryFinToFin : {k : _} -> Fin n -> Maybe (Fin k)
280 | tryFinToFin = tryNatToFin . finToNat
283 | 0 minusLTE : (k,m : Nat) -> LTE (k `minus` m) k
284 | minusLTE 0 m = LTEZero
285 | minusLTE (S k) 0 = reflexive
286 | minusLTE (S k) (S j) = lteSuccRight $
minusLTE k j
289 | 0 minusFinLT : (n : Nat) -> (x : Fin n) -> LT (n `minus` S (finToNat x)) n
290 | minusFinLT (S k) FZ = LTESucc (minusLTE k 0)
291 | minusFinLT (S k) (FS x) = LTESucc (minusLTE k _)
294 | 0 minusLT : (x,m,n : Nat) -> LT x (n `minus` m) -> LT (x+m) n
295 | minusLT x _ 0 y = absurd y
296 | minusLT x 0 (S k) y = rewrite plusZeroRightNeutral x in y
297 | minusLT x (S k) (S j) y =
298 | let p1 := minusLT x k j y
299 | in LTESucc (rewrite sym (plusSuccRightSucc x k) in p1)
302 | inc : {m : _} -> Fin (n `minus` m) -> Fin n
304 | let 0 p1 := finToNatLT x
305 | in natToFinLT (finToNat x + m) @{minusLT _ _ _ p1}
308 | 0 ltAddLeft : LT k n -> LT k (m+n)
309 | ltAddLeft {m = 0} lt = lt
310 | ltAddLeft {m = S x} lt = lteSuccRight $
ltAddLeft lt
313 | 0 lteAddLeft : (n : Nat) -> LTE n (m+n)
314 | lteAddLeft n = rewrite plusCommutative m n in lteAddRight n
321 | 0 plusMinus : (m,n : Nat) -> LTE m n -> m + (n `minus` m) === n
322 | plusMinus 0 0 _ = Refl
323 | plusMinus 0 (S k) x = Refl
324 | plusMinus (S k) (S j) (LTESucc p) = cong S $
plusMinus k j p
325 | plusMinus (S k) Z x impossible
328 | 0 eqLTE : (m,n : Nat) -> m === n -> LTE m n
329 | eqLTE 0 0 Refl = LTEZero
330 | eqLTE (S k) (S k) Refl = LTESucc $
eqLTE k k Refl
333 | 0 dropLemma : (k,n : Nat) -> LTE (plus (minus n (minus n k)) (minus n k)) n
335 | let p1 := minusLTE n k
336 | p2 := plusMinus _ _ p1
337 | p3 := trans (plusCommutative _ _) p2
341 | 0 plusMinusLTE : (m,n : Nat) -> LTE m n -> LTE (m + (n `minus` m)) n
342 | plusMinusLTE m n lte = eqLTE _ _ $
plusMinus m n lte
345 | 0 plusMinus0 : (m,n,x : Nat) -> n === 0 -> LTE m x -> LTE (m + n) x
346 | plusMinus0 m 0 x Refl lte = rewrite plusZeroRightNeutral m in lte
349 | 0 minusGTE : (m,n : Nat) -> GTE m n -> (n `minus` m) === 0
350 | minusGTE m 0 x = Refl
351 | minusGTE 0 (S k) x = absurd x
352 | minusGTE (S j) (S k) (LTESucc x) = minusGTE j k x
355 | 0 plusMinusBothLTE : (m,n : Nat) -> LTE m x -> LTE n x -> LTE (m + (n `minus` m)) x
356 | plusMinusBothLTE m n ltm ltn =
358 | Yes prf => plusMinus0 m _ x (minusGTE m n $
rewrite prf in refl) ltm
359 | No contra => case connex {rel = LTE} contra of
360 | Left y => transitive (plusMinusLTE m n y) ltn
361 | Right y => plusMinus0 m _ x (minusGTE m n y) ltm
371 | trans : Ix k m -> Ix m n -> Ix k n
373 | trans (IS x) t = IS $
trans x t
376 | transp : Ix k m -> Ix m n -> Ix k n
377 | transp x y = believe_me (ixToNat x + ixToNat y)
379 | %transform "ixTransPlus"
Index.trans = Index.transp
382 | public export %inline
383 | Reflexive Nat Ix where
387 | public export %inline
388 | Transitive Nat Ix where
396 | 0 castBits8LT : (x : Bits8) -> LT (cast x) 256
398 | case choose (cast {to = Nat} x < 256) of
399 | Left oh => Data.Nat.ltOpReflectsLT _ _ oh
400 | _ => assert_total $
idris_crash "Bits8 value >= 256"
404 | bits8ToFin : Bits8 -> Fin 256
405 | bits8ToFin x = natToFinLT (cast x) @{castBits8LT x}