1 | module Data.Nat.Order.Properties
3 | import Syntax.PreorderReasoning.Generic
5 | import Data.Bool.Decidable
10 | LTESuccInjectiveMonotone : (m, n : Nat) -> Reflects (m `LTE` n) b -> Reflects (S m `LTE` S n) b
11 | LTESuccInjectiveMonotone m n (RTrue m_lte_n) = RTrue $
LTESucc m_lte_n
12 | LTESuccInjectiveMonotone m n (RFalse not_m_lte_n) = RFalse $
\case
13 | LTESucc m_lte_n => not_m_lte_n m_lte_n
16 | lteReflection : (a, b : Nat) -> Reflects (a `LTE` b) (a `lte` b)
17 | lteReflection 0 b = RTrue LTEZero
18 | lteReflection (S k) 0 = RFalse $
\sk_lte_z => absurd sk_lte_z
19 | lteReflection (S a) (S b) = LTESuccInjectiveMonotone a b (lteReflection a b)
22 | ltReflection : (a, b : Nat) -> Reflects (a `LT` b) (a `lt` b)
23 | ltReflection a = lteReflection (S a)
27 | lteIsLTE : (a, b : Nat) -> a `lte` b = True -> a `LTE` b
28 | lteIsLTE a b prf = invert (replace {p = Reflects (a `LTE` b)} prf (lteReflection a b))
31 | ltIsLT : (a, b : Nat) -> a `lt` b = True -> a `LT` b
32 | ltIsLT a = lteIsLTE (S a)
35 | notlteIsNotLTE : (a, b : Nat) -> a `lte` b = False -> Not (a `LTE` b)
36 | notlteIsNotLTE a b prf = invert (replace {p = Reflects (a `LTE` b)} prf (lteReflection a b))
39 | notltIsNotLT : (a, b : Nat) -> a `lt` b = False -> Not (a `LT` b)
40 | notltIsNotLT a = notlteIsNotLTE (S a)
44 | notlteIsLT : (a, b : Nat) -> a `lte` b = False -> b `LT` a
45 | notlteIsLT a b prf = notLTImpliesGTE $
47 | (invert $
replace {p = Reflects (S a `LTE` S b)} prf
48 | $
lteReflection (S a) (S b)) prf'
51 | notltIsGTE : (a, b : Nat) -> (a `lt` b) === False -> a `GTE` b
52 | notltIsGTE a b p = notLTImpliesGTE (notlteIsNotLTE (S a) b p)
57 | LteIslte : (a, b : Nat) -> a `LTE` b -> a `lte` b = True
58 | LteIslte a b a_lt_b = reflect (lteReflection a b) a_lt_b
62 | notLteIsnotlte : (a, b : Nat) -> Not (a `LTE` b) -> a `lte` b = False
63 | notLteIsnotlte a b not_a_lte_b = reflect (lteReflection a b) not_a_lte_b
67 | GTIsnotlte : (a, b : Nat) -> b `LT` a -> a `lte` b = False
68 | GTIsnotlte a b prf =
69 | notLteIsnotlte a b $
\contra =>
70 | succNotLTEpred $
transitive prf contra
74 | minusLTE : (a,b : Nat) -> (b `minus` a) `LTE` b
75 | minusLTE a 0 = LTEZero
76 | minusLTE 0 (S _) = reflexive
77 | minusLTE (S a) (S b) =
80 | (lteSuccRight reflexive)
84 | minusPosLT : (a,b : Nat) -> 0 `LT` a -> a `LTE` b -> (b `minus` a) `LT` b
85 | minusPosLT 0 b z_lt_z a_lte_b impossible
86 | minusPosLT (S a) 0 z_lt_sa a_lte_b impossible
87 | minusPosLT (S a) (S b) z_lt_sa a_lte_b = LTESucc (minusLTE a b)
91 | multLteMonotoneRight : (l, a, b : Nat) -> a `LTE` b -> l*a `LTE` l*b
92 | multLteMonotoneRight 0 a b _ = LTEZero
93 | multLteMonotoneRight (S k) a b a_lte_b = CalcWith {leq = LTE} $
95 | ~~ a + k*a ...(Refl)
96 | <~ b + k*a ...(plusLteMonotoneRight (k*a) a b a_lte_b)
97 | <~ b + k*b ...(plusLteMonotoneLeft b (k*a) (k*b) $
98 | multLteMonotoneRight k a b a_lte_b)
99 | ~~ (1 + k) * b ...(Refl)
102 | multLteMonotoneLeft : (a, b, r : Nat) -> a `LTE` b -> a*r `LTE` b*r
103 | multLteMonotoneLeft a b r a_lt_b =
104 | rewrite multCommutative a r in
105 | rewrite multCommutative b r in
106 | multLteMonotoneRight r a b a_lt_b
109 | lteNotLtEq : (a, b : Nat) -> LTE a b -> Not (LT a b) -> a = b
110 | lteNotLtEq a b a_lte_b not_n_lte_n =
111 | let b_lte_a = notLTImpliesGTE not_n_lte_n
112 | in antisymmetric a_lte_b b_lte_a
116 | decomposeLte : (a, b : Nat) -> LTE a b -> Either (LT a b) (a = b)
117 | decomposeLte a b a_lte_b with (isLT a b)
118 | decomposeLte a b a_lte_b | Yes a_lt_b = Left a_lt_b
119 | decomposeLte a b a_lte_b | No not_a_lt_b = Right $
lteNotLtEq a b a_lte_b not_a_lt_b