4 | module Data.Int.Order
52 | strictRefl : a === b -> Lazy c -> c
53 | strictRefl Refl p = p
56 | unsafeRefl : {0 a, b : t} -> a === b
57 | unsafeRefl = believe_me (the (a === a) Refl)
74 | data LT : Int -> Int -> Type where
75 | MkLT : (a < b) === True -> LT a b
79 | mkLT : (a < b) === True -> LT a b
84 | runLT : LT a b -> (a < b) === True
85 | runLT (MkLT eq) = eq
90 | strictLT : LT a b -> Lazy c -> c
91 | strictLT (MkLT p) c = strictRefl p c
95 | decide : (a, b : Int) -> Dec (LT a b)
96 | decide a b with (the (test : Bool ** (a < b) === test) (
a < b ** Refl)
)
97 | decide a b | (
True ** p)
= Yes (MkLT p)
98 | decide a b | (
False ** p)
= No (\ (MkLT q) => absurd (trans (sym p) q))
102 | trans : LT a b -> LT b c -> LT a (the Int c)
103 | trans p q = strictLT p $
strictLT q $
MkLT unsafeRefl
109 | irrefl : Not (LT a a)
110 | irrefl p = strictLT p
111 | $
assert_total $
idris_crash "IMPOSSIBLE: LT is irreflexive"
118 | GT : Int -> Int -> Type
122 | LT_not_GT : LT a b -> Not (GT a b)
123 | LT_not_GT p q = irrefl (trans p q)
126 | GT_not_LT : GT a b -> Not (LT a b)
127 | GT_not_LT = flip LT_not_GT
129 | ------------------------------------------------------------------------
134 | ||| `EQ a b` is a proof that `a` is equal to `b` which is to say that
135 | ||| the function call `a == b` returns `True`.
137 | ||| NB: we do not re-export the constructor so that users cannot force
138 | ||| our magic functions to blow up in absurd contexts by bypassing the
139 | ||| safety measures introduced by the `strictX` functions.
140 | ||| We do provide functions corresponding to the wrapping and unwrapping
141 | ||| of `EQ` but, crucially, they do not let people force `EQ` proofs to
142 | ||| be in canonical form.
144 | data EQ : Int -> Int -> Type where
145 | MkEQ : (a == b) === True -> EQ a b
147 | ||| We may prove `EQ a b` by using a proof that `a == b` returns `True`.
149 | mkEQ : (a ==
b) === True -> EQ a b
154 | runEQ : EQ a b -> (a == b) === True
155 | runEQ (MkEQ eq) = eq
160 | strictEQ : EQ a b -> Lazy c -> c
161 | strictEQ (MkEQ p) c = strictRefl p c
165 | decide : (a, b : Int) -> Dec (EQ a b)
166 | decide a b with (the (test : Bool ** (a == b) === test) (
a == b ** Refl)
)
167 | decide a b | (
True ** p)
= Yes (MkEQ p)
168 | decide a b | (
False ** p)
= No (\ (MkEQ q) => absurd (trans (sym p) q))
173 | refl = MkEQ unsafeRefl
177 | elimEQ : (0 p : Int -> Type) -> EQ a b -> p a -> p b
178 | elimEQ _ p v = strictEQ p $
believe_me v
182 | reflect : EQ a b -> a === b
183 | reflect p = elimEQ (\ b => a === b) p Refl
187 | sym : EQ a b -> EQ b a
188 | sym p = elimEQ (\ b => EQ b a) p refl
192 | trans : EQ a b -> EQ b c -> EQ a c
193 | trans p q = elimEQ (\ b => EQ b c) (sym p) q
196 | trans_LT_EQ : LT a b -> EQ b c -> LT a c
197 | trans_LT_EQ p q = elimEQ (LT a) q p
200 | trans_EQ_LT : EQ a b -> LT b c -> LT a c
201 | trans_EQ_LT p q = elimEQ (\ b => LT b c) (sym p) q
204 | LT_not_EQ : LT a b -> Not (EQ a b)
205 | LT_not_EQ p q = irrefl (trans_LT_EQ p (sym q))
208 | EQ_not_LT : EQ a b -> Not (LT a b)
209 | EQ_not_LT = flip LT_not_EQ
212 | EQ_not_GT : EQ a b -> Not (GT a b)
213 | EQ_not_GT = EQ_not_LT . sym
216 | GT_not_EQ : GT a b -> Not (EQ a b)
217 | GT_not_EQ = flip EQ_not_GT
231 | data LTE : Int -> Int -> Type where
232 | MkLT : (a < b) === True -> LTE a b
233 | MkEQ : (a == b) === True -> LTE a b
237 | runLTE : LTE a b -> Either (LT a b) (EQ a b)
238 | runLTE (MkLT p) = Left (mkLT p)
239 | runLTE (MkEQ p) = Right (mkEQ p)
244 | strictLTE : LTE a b -> Lazy c -> c
245 | strictLTE (MkLT p) q = strictRefl p q
246 | strictLTE (MkEQ p) q = strictRefl p q
250 | decide : (a, b : Int) -> Dec (LTE a b)
251 | decide a b with (LT.decide a b)
252 | decide a b | Yes p = Yes (MkLT (runLT p))
253 | decide a b | No notLT with (EQ.decide a b)
254 | decide a b | No notLT | Yes p = Yes (MkEQ (runEQ p))
255 | decide a b | No notLT | No notEQ = No $
\ case
256 | MkLT p => notLT (mkLT p)
257 | MkEQ p => notEQ (mkEQ p)
262 | refl = MkEQ unsafeRefl
265 | trans_LT_LTE : LT a b -> LTE b c -> LT a c
266 | trans_LT_LTE p (MkLT q) = trans p (mkLT q)
267 | trans_LT_LTE p (MkEQ q) = trans_LT_EQ p (mkEQ q)
270 | trans_LTE_LT : LTE a b -> LT b c -> LT a c
271 | trans_LTE_LT (MkLT p) q = trans (mkLT p) q
272 | trans_LTE_LT (MkEQ p) q = trans_EQ_LT (mkEQ p) q
275 | inject_LT_LTE : LT a b -> LTE a b
276 | inject_LT_LTE = MkLT . runLT
279 | inject_EQ_LTE : EQ a b -> LTE a b
280 | inject_EQ_LTE p = MkEQ (runEQ p)
284 | trans : LTE a b -> LTE b c -> LTE a c
285 | trans (MkLT p) q = inject_LT_LTE (trans_LT_LTE (mkLT p) q)
286 | trans p (MkLT q) = inject_LT_LTE (trans_LTE_LT p (mkLT q))
287 | trans (MkEQ p) (MkEQ q) = inject_EQ_LTE (trans (mkEQ p) (mkEQ q))
291 | antisym : LTE a b -> LTE b a -> EQ a b
292 | antisym (MkEQ p) _ = mkEQ p
293 | antisym _ (MkEQ p) = EQ.sym (mkEQ p)
294 | antisym (MkLT p) (MkLT q) = absurd $
LT.irrefl (LT.trans (mkLT p) (mkLT q))
301 | GTE : Int -> Int -> Type
309 | trichotomous : (a, b : Int) -> Trichotomous LT EQ GT a b
310 | trichotomous a b with (LTE.decide a b)
311 | trichotomous a b | Yes lte = case runLTE lte of
312 | Left lt => MkLT lt (LT_not_EQ lt) (LT_not_GT lt)
313 | Right eq => MkEQ (EQ_not_LT eq) eq (EQ_not_GT eq)
314 | trichotomous a b | No notLTE = let gt = mkLT unsafeRefl in MkGT (GT_not_LT gt) (GT_not_EQ gt) gt
318 | decide_LT_GTE : (a, b : Int) -> Either (LT a b) (GTE a b)
319 | decide_LT_GTE a b with (trichotomous a b)
320 | decide_LT_GTE a b | MkLT lt _ _ = Left lt
321 | decide_LT_GTE a b | MkEQ _ eq _ = Right (inject_EQ_LTE (sym eq))
322 | decide_LT_GTE a b | MkGT _ _ gt = Right (inject_LT_LTE gt)
326 | decide_LTE_GT : (a, b : Int) -> Either (LTE a b) (GT a b)
327 | decide_LTE_GT a b with (trichotomous a b)
328 | decide_LTE_GT a b | MkLT lt _ _ = Left (inject_LT_LTE lt)
329 | decide_LTE_GT a b | MkEQ _ eq _ = Left (inject_EQ_LTE eq)
330 | decide_LTE_GT a b | MkGT _ _ gt = Right gt
337 | suc_LT_LTE : {a, b : Int} -> LT a b -> LTE (a + 1) b
338 | suc_LT_LTE p with (the (test : Bool ** (a + 1 == b) === test) (
a + 1 == b ** Refl)
)
339 | suc_LT_LTE p | (
True ** q)
= inject_EQ_LTE $
mkEQ q
340 | suc_LT_LTE p | (
False ** q)
= strictLT p $
inject_LT_LTE $
mkLT unsafeRefl
344 | pred_LT_LTE : {a, b : Int} -> LT a b -> LTE a (b - 1)
345 | pred_LT_LTE p with (the (test : Bool ** (a == b - 1) === test) (
a == b - 1 ** Refl)
)
346 | pred_LT_LTE p | (
True ** q)
= inject_EQ_LTE $
mkEQ q
347 | pred_LT_LTE p | (
False ** q)
= strictLT p $
inject_LT_LTE $
mkLT unsafeRefl
352 | sucBounded : LT a b -> LT a (a + 1)
353 | sucBounded p = strictLT p $
mkLT unsafeRefl