3 | import public Control.Relation
4 | import public Control.Ord
5 | import public Control.Order
6 | import public Control.Function
7 | import Syntax.PreorderReasoning
8 | import Syntax.PreorderReasoning.Generic
13 | Uninhabited (Z = S n) where
14 | uninhabited Refl
impossible
17 | Uninhabited (S n = Z) where
18 | uninhabited Refl
impossible
21 | Uninhabited (a = b) => Uninhabited (S a = S b) where
22 | uninhabited Refl @{ab} = uninhabited @{ab} Refl
25 | isZero : Nat -> Bool
27 | isZero (S n) = False
30 | isSucc : Nat -> Bool
38 | data IsSucc : (n : Nat) -> Type where
39 | ItIsSucc : IsSucc (S n)
42 | Uninhabited (IsSucc Z) where
43 | uninhabited ItIsSucc
impossible
46 | isItSucc : (n : Nat) -> Dec (IsSucc n)
47 | isItSucc Z = No absurd
48 | isItSucc (S n) = Yes ItIsSucc
52 | 0 NonZero : Nat -> Type
57 | public export %inline
59 | SIsNonZero : NonZero (S n)
60 | SIsNonZero = ItIsSucc
63 | power : Nat -> Nat -> Nat
65 | power base (S exp) = base * (power base exp)
68 | hyper : Nat -> Nat -> Nat -> Nat
71 | hyper (S(S Z)) a Z = Z
73 | hyper (S pn) a (S pb) = hyper pn a (hyper (S pn) a pb)
83 | compareNatDiag : (k : Nat) -> compareNat k k === EQ
84 | compareNatDiag Z = Refl
85 | compareNatDiag (S k) = compareNatDiag k
88 | compareNatFlip : (m, n : Nat) ->
89 | flip Prelude.compareNat m n === contra (compareNat m n)
90 | compareNatFlip 0 0 = Refl
91 | compareNatFlip 0 (S n) = Refl
92 | compareNatFlip (S m) 0 = Refl
93 | compareNatFlip (S m) (S n) = compareNatFlip m n
96 | data NotBothZero : (n, m : Nat) -> Type where
97 | LeftIsNotZero : NotBothZero (S n) m
98 | RightIsNotZero : NotBothZero n (S m)
101 | Uninhabited (NotBothZero 0 0) where
102 | uninhabited LeftIsNotZero
impossible
103 | uninhabited RightIsNotZero
impossible
106 | data LTE : (n, m : Nat) -> Type where
107 | LTEZero : LTE Z right
108 | LTESucc : LTE left right -> LTE (S left) (S right)
111 | Uninhabited (LTE (S n) Z) where
112 | uninhabited LTEZero
impossible
115 | Uninhabited (LTE m n) => Uninhabited (LTE (S m) (S n)) where
116 | uninhabited (LTESucc lte) = uninhabited lte
119 | Reflexive Nat LTE where
120 | reflexive {x = Z} = LTEZero
121 | reflexive {x = S _} = LTESucc $
reflexive
124 | Transitive Nat LTE where
125 | transitive LTEZero _ = LTEZero
126 | transitive (LTESucc xy) (LTESucc yz) =
127 | LTESucc $
transitive xy yz
130 | Antisymmetric Nat LTE where
131 | antisymmetric LTEZero LTEZero = Refl
132 | antisymmetric (LTESucc xy) (LTESucc yx) =
133 | cong S $
antisymmetric xy yx
136 | Connex Nat LTE where
137 | connex {x = Z} _ = Left LTEZero
138 | connex {y = Z} _ = Right LTEZero
139 | connex {x = S _} {y = S _} prf =
140 | case connex $
\xy => prf $
cong S xy of
141 | Left jk => Left $
LTESucc jk
142 | Right kj => Right $
LTESucc kj
145 | Preorder Nat LTE where
148 | PartialOrder Nat LTE where
151 | LinearOrder Nat LTE where
154 | GTE : Nat -> Nat -> Type
155 | GTE left right = LTE right left
158 | LT : Nat -> Nat -> Type
159 | LT left right = LTE (S left) right
168 | data View : LT m n -> Type where
169 | LTZero : View (LTESucc LTEZero)
170 | LTSucc : (lt : m `LT` n) -> View (LTESucc lt)
174 | view : (lt : LT m n) -> View lt
175 | view (LTESucc LTEZero) = LTZero
176 | view (LTESucc lt@(LTESucc _)) = LTSucc lt
180 | ltZero : Z `LT` S m
181 | ltZero = LTESucc LTEZero
184 | GT : Nat -> Nat -> Type
185 | GT left right = LT right left
188 | succNotLTEzero : Not (LTE (S m) Z)
189 | succNotLTEzero LTEZero
impossible
192 | fromLteSucc : LTE (S m) (S n) -> LTE m n
193 | fromLteSucc (LTESucc x) = x
196 | succNotLTEpred : Not $
LTE (S x) x
197 | succNotLTEpred {x = (S right)} (LTESucc y) = succNotLTEpred y
200 | isLTE : (m, n : Nat) -> Dec (LTE m n)
201 | isLTE Z n = Yes LTEZero
202 | isLTE (S k) Z = No succNotLTEzero
204 | = case isLTE k j of
205 | No contra => No (contra . fromLteSucc)
206 | Yes prf => Yes (LTESucc prf)
209 | isGTE : (m, n : Nat) -> Dec (GTE m n)
210 | isGTE m n = isLTE n m
213 | isLT : (m, n : Nat) -> Dec (LT m n)
214 | isLT m n = isLTE (S m) n
217 | isGT : (m, n : Nat) -> Dec (GT m n)
218 | isGT m n = isLT n m
220 | lteRecallLeft : LTE m n -> (m' : Nat ** m = m')
221 | lteRecallLeft LTEZero = (
0 ** Refl)
222 | lteRecallLeft (LTESucc x) with (lteRecallLeft x)
223 | lteRecallLeft (LTESucc x) | (
left ** Refl)
= (
S left ** Refl)
225 | irrelevantLte : {m : Nat} -> (0 prf : LTE m n) -> LTE m n
226 | irrelevantLte {m = 0} LTEZero = LTEZero
227 | irrelevantLte {m = (S k)} (LTESucc x) = LTESucc (irrelevantLte x)
229 | lteRecall : LTE m n -> {p : Nat -> Nat} -> (0 prf : LTE (p m) q) -> LTE (p m) q
230 | lteRecall {m} x prf with (lteRecallLeft x)
231 | lteRecall {m = m} x prf | (
m ** Refl)
= irrelevantLte prf
233 | ltRecall : LT m n -> {p : Nat -> Nat} -> (0 prf : LT (p m) q) -> LT (p m) q
234 | ltRecall {m} x prf with (lteRecallLeft x)
235 | ltRecall {m = m} x prf | (
S m ** Refl)
= irrelevantLte prf
238 | lteSuccRight : LTE n m -> LTE n (S m)
239 | lteSuccRight LTEZero = LTEZero
240 | lteSuccRight (LTESucc x) = LTESucc (lteSuccRight x)
243 | lteSuccLeft : LTE (S n) m -> LTE n m
244 | lteSuccLeft (LTESucc x) = lteSuccRight x
247 | lteAddRight : (n : Nat) -> LTE n (n + m)
248 | lteAddRight Z = LTEZero
249 | lteAddRight (S k) {m} = LTESucc (lteAddRight {m} k)
252 | notLTEImpliesGT : {a, b : Nat} -> Not (a `LTE` b) -> a `GT` b
253 | notLTEImpliesGT {a = 0 } not_z_lte_b = absurd $
not_z_lte_b LTEZero
254 | notLTEImpliesGT {a = S a} {b = 0 } notLTE = LTESucc LTEZero
255 | notLTEImpliesGT {a = S a} {b = S k} notLTE = LTESucc (notLTEImpliesGT (notLTE . LTESucc))
258 | LTEImpliesNotGT : a `LTE` b -> Not (a `GT` b)
259 | LTEImpliesNotGT LTEZero q = absurd q
260 | LTEImpliesNotGT (LTESucc p) (LTESucc q) = LTEImpliesNotGT p q
263 | notLTImpliesGTE : {a, b : _} -> Not (LT a b) -> GTE a b
264 | notLTImpliesGTE notLT = fromLteSucc $
notLTEImpliesGT notLT
267 | LTImpliesNotGTE : a `LT` b -> Not (a `GTE` b)
268 | LTImpliesNotGTE p q = LTEImpliesNotGT q p
271 | lte : Nat -> Nat -> Bool
274 | lte (S left) (S right) = lte left right
277 | gte : Nat -> Nat -> Bool
278 | gte left right = lte right left
281 | lt : Nat -> Nat -> Bool
282 | lt left right = lte (S left) right
285 | gt : Nat -> Nat -> Bool
286 | gt left right = lt right left
289 | lteReflectsLTE : (k : Nat) -> (n : Nat) -> lte k n === True -> k `LTE` n
290 | lteReflectsLTE (S k) 0 _ impossible
291 | lteReflectsLTE 0 0 _ = LTEZero
292 | lteReflectsLTE 0 (S k) _ = LTEZero
293 | lteReflectsLTE (S k) (S j) prf = LTESucc (lteReflectsLTE k j prf)
296 | gteReflectsGTE : (k : Nat) -> (n : Nat) -> gte k n === True -> k `GTE` n
297 | gteReflectsGTE k n prf = lteReflectsLTE n k prf
300 | ltReflectsLT : (k : Nat) -> (n : Nat) -> lt k n === True -> k `LT` n
301 | ltReflectsLT k n prf = lteReflectsLTE (S k) n prf
304 | ltOpReflectsLT : (m,n : Nat) -> So (m < n) -> LT m n
305 | ltOpReflectsLT 0 (S k) prf = LTESucc LTEZero
306 | ltOpReflectsLT (S k) (S j) prf = LTESucc (ltOpReflectsLT k j prf)
307 | ltOpReflectsLT (S k) 0 prf impossible
308 | ltOpReflectsLT 0 0 prf impossible
311 | gtReflectsGT : (k : Nat) -> (n : Nat) -> gt k n === True -> k `GT` n
312 | gtReflectsGT k n prf = ltReflectsLT n k prf
315 | minimum : Nat -> Nat -> Nat
317 | minimum (S n) Z = Z
318 | minimum (S n) (S m) = S (minimum n m)
321 | maximum : Nat -> Nat -> Nat
323 | maximum (S n) Z = S n
324 | maximum (S n) (S m) = S (maximum n m)
329 | eqSucc : (0 left, right : Nat) -> left = right -> S left = S right
330 | eqSucc _ _ Refl = Refl
334 | injective Refl = Refl
337 | SIsNotZ : Not (S x = Z)
344 | mod' : Nat -> Nat -> Nat -> Nat
345 | mod' Z centre right = centre
346 | mod' (S fuel) centre right =
347 | if lte centre right then
350 | mod' fuel (minus centre (S right)) right
353 | modNatNZ : Nat -> (y: Nat) -> (0 _ : NonZero y) -> Nat
354 | modNatNZ left Z p = void (absurd p)
355 | modNatNZ left (S right) _ = mod' left left right
358 | modNat : Nat -> Nat -> Nat
359 | modNat left (S right) = modNatNZ left (S right) ItIsSucc
365 | div' : Nat -> Nat -> Nat -> Nat
366 | div' Z centre right = Z
367 | div' (S fuel) centre right =
368 | if lte centre right then
371 | S (div' fuel (minus centre (S right)) right)
375 | divNatNZ : Nat -> (y: Nat) -> (0 _ : NonZero y) -> Nat
376 | divNatNZ left (S right) _ = div' left left right
379 | divNat : Nat -> Nat -> Nat
380 | divNat left (S right) = divNatNZ left (S right) ItIsSucc
384 | divCeilNZ : Nat -> (y: Nat) -> (0 _ : NonZero y) -> Nat
385 | divCeilNZ x y p = case (modNatNZ x y p) of
386 | Z => divNatNZ x y p
387 | S _ => S (divNatNZ x y p)
390 | divCeil : Nat -> Nat -> Nat
391 | divCeil x (S y) = divCeilNZ x (S y) ItIsSucc
395 | divmod' : Nat -> Nat -> Nat -> (Nat, Nat)
396 | divmod' Z centre right = (Z, centre)
397 | divmod' (S fuel) centre right =
398 | if lte centre right then
401 | let qr = divmod' fuel (minus centre (S right)) right
402 | in (S (fst qr), snd qr)
405 | divmodNatNZ : Nat -> (y: Nat) -> (0 _ : NonZero y) -> (Nat, Nat)
406 | divmodNatNZ left (S right) _ = divmod' left left right
416 | gcd : (a: Nat) -> (b: Nat) -> {auto 0 ok: NotBothZero a b} -> Nat
419 | gcd a (S b) = gcd (S b) (modNatNZ a (S b) ItIsSucc)
422 | lcm : Nat -> Nat -> Nat
425 | lcm a (S b) = divNat (a * (S b)) (gcd a (S b))
431 | data CmpNat : Nat -> Nat -> Type where
432 | CmpLT : (y : _) -> CmpNat x (x + S y)
434 | CmpGT : (x : _) -> CmpNat (y + S x) y
437 | cmp : (x, y : Nat) -> CmpNat x y
439 | cmp Z (S k) = CmpLT _
440 | cmp (S k) Z = CmpGT _
441 | cmp (S x) (S y) with (cmp x y)
442 | cmp (S x) (S (x + (S k))) | CmpLT k = CmpLT k
443 | cmp (S x) (S x) | CmpEQ = CmpEQ
444 | cmp (S (y + (S k))) (S y) | CmpGT k = CmpGT k
449 | plusZeroLeftNeutral : (right : Nat) -> 0 + right = right
450 | plusZeroLeftNeutral _ = Refl
453 | plusZeroRightNeutral : (left : Nat) -> left + 0 = left
454 | plusZeroRightNeutral Z = Refl
455 | plusZeroRightNeutral (S n) = Calc $
457 | ~~ 1 + n ...(cong (1+) $
plusZeroRightNeutral n)
460 | plusSuccRightSucc : (left, right : Nat) -> S (left + right) = left + (S right)
461 | plusSuccRightSucc Z _ = Refl
462 | plusSuccRightSucc (S left) right = Calc $
463 | |~ 1 + (1 + (left + right))
464 | ~~ 1 + (left + (1 + right)) ...(cong (1+) $
plusSuccRightSucc left right)
467 | plusCommutative : (left, right : Nat) -> left + right = right + left
468 | plusCommutative Z right = Calc $
470 | ~~ right + 0 ..<(plusZeroRightNeutral right)
471 | plusCommutative (S left) right = Calc $
472 | |~ 1 + (left + right)
473 | ~~ 1 + (right + left) ...(cong (1+) $
plusCommutative left right)
474 | ~~ right + (1 + left) ...(plusSuccRightSucc right left)
477 | plusAssociative : (left, centre, right : Nat) ->
478 | left + (centre + right) = (left + centre) + right
479 | plusAssociative Z _ _ = Refl
480 | plusAssociative (S left) centre right = Calc $
481 | |~ 1 + (left + (centre + right))
482 | ~~ 1 + ((left + centre) + right) ...(cong (1+) $
plusAssociative left centre right)
485 | plusConstantRight : (left, right, c : Nat) -> left = right ->
486 | left + c = right + c
487 | plusConstantRight _ _ _ Refl = Refl
490 | plusConstantLeft : (left, right, c : Nat) -> left = right ->
491 | c + left = c + right
492 | plusConstantLeft _ _ _ Refl = Refl
495 | plusOneSucc : (right : Nat) -> 1 + right = S right
496 | plusOneSucc _ = Refl
499 | plusLeftCancel : (left, right, right' : Nat) ->
500 | left + right = left + right' -> right = right'
501 | plusLeftCancel Z _ _ p = p
502 | plusLeftCancel (S left) right right' p =
503 | plusLeftCancel left right right' $
injective p
506 | plusRightCancel : (left, left', right : Nat) ->
507 | left + right = left' + right -> left = left'
508 | plusRightCancel left left' right p =
509 | plusLeftCancel right left left' $
Calc $
511 | ~~ left + right ...(plusCommutative right left)
512 | ~~ left' + right ...(p)
513 | ~~ right + left' ...(plusCommutative left' right)
516 | plusLeftLeftRightZero : (left, right : Nat) ->
517 | left + right = left -> right = Z
518 | plusLeftLeftRightZero left right p =
519 | plusLeftCancel left right Z $
Calc $
522 | ~~ left + 0 ..<(plusZeroRightNeutral left)
525 | plusLteMonotoneRight : (p, q, r : Nat) -> q `LTE` r -> (q+p) `LTE` (r+p)
526 | plusLteMonotoneRight p Z r LTEZero = CalcSmart {leq = LTE} $
528 | <~ p + r ...(lteAddRight p)
529 | <~ r + p .=.(plusCommutative p r)
530 | plusLteMonotoneRight p (S q) (S r) (LTESucc q_lte_r) =
531 | LTESucc $
CalcSmart {leq = LTE} $
533 | <~ r + p ...(plusLteMonotoneRight p q r q_lte_r)
536 | plusLteMonotoneLeft : (p, q, r : Nat) -> q `LTE` r -> (p + q) `LTE` (p + r)
537 | plusLteMonotoneLeft p q r q_lt_r = CalcSmart {leq = LTE} $
539 | <~ q + p .=.(plusCommutative p q)
540 | <~ r + p ...(plusLteMonotoneRight p q r q_lt_r)
541 | <~ p + r .=.(plusCommutative r p)
545 | plusLteMonotone : {m, n, p, q : Nat} -> m `LTE` n -> p `LTE` q ->
546 | (m + p) `LTE` (n + q)
547 | plusLteMonotone left right = CalcSmart {leq = LTE} $
549 | <~ m + q ...(plusLteMonotoneLeft m p q right)
550 | <~ n + q ...(plusLteMonotoneRight q m n left)
552 | zeroPlusLeftZero : (a,b : Nat) -> (0 = a + b) -> a = 0
553 | zeroPlusLeftZero 0 0 Refl = Refl
554 | zeroPlusLeftZero (S k) b _ impossible
556 | zeroPlusRightZero : (a,b : Nat) -> (0 = a + b) -> b = 0
557 | zeroPlusRightZero 0 0 Refl = Refl
558 | zeroPlusRightZero (S k) b _ impossible
563 | multZeroLeftZero : (right : Nat) -> Z * right = Z
564 | multZeroLeftZero _ = Refl
567 | multZeroRightZero : (left : Nat) -> left * Z = Z
568 | multZeroRightZero Z = Refl
569 | multZeroRightZero (S left) = multZeroRightZero left
572 | multRightSuccPlus : (left, right : Nat) ->
573 | left * (S right) = left + (left * right)
574 | multRightSuccPlus Z _ = Refl
575 | multRightSuccPlus (S left) right = cong (1+) $
Calc $
576 | |~ right + (left * (1 + right))
577 | ~~ right + (left + (left * right))
578 | ...(cong (right +) $
multRightSuccPlus left right)
579 | ~~ (right + left) + (left * right)
580 | ...(plusAssociative right left (left*right))
581 | ~~ (left + right) + (left * right)
582 | ...(cong (+ (left * right)) $
plusCommutative right left)
583 | ~~ left + (right + (left * right))
584 | ..<(plusAssociative left right (left * right))
585 | ~~ left + ((1 + left) * right)
589 | multLeftSuccPlus : (left, right : Nat) ->
590 | (S left) * right = right + (left * right)
591 | multLeftSuccPlus _ _ = Refl
594 | multCommutative : (left, right : Nat) -> left * right = right * left
595 | multCommutative Z right = Calc $
597 | ~~ right * 0 ..<(multZeroRightZero right)
598 | multCommutative (S left) right = Calc $
599 | |~ right + (left * right)
600 | ~~ right + (right * left)
601 | ...(cong (right +) $
multCommutative left right)
602 | ~~ right * (1 + left)
603 | ..<(multRightSuccPlus right left)
606 | multDistributesOverPlusLeft : (left, centre, right : Nat) ->
607 | (left + centre) * right = (left * right) + (centre * right)
608 | multDistributesOverPlusLeft Z _ _ = Refl
609 | multDistributesOverPlusLeft (S left) centre right = Calc $
610 | |~ right + ((left + centre) * right)
611 | ~~ right + ((left * right) + (centre * right))
612 | ...(cong (right +) $
613 | multDistributesOverPlusLeft left centre right)
614 | ~~ (right + (left * right)) + (centre * right)
615 | ...(plusAssociative right (left*right) (centre*right))
617 | multDistributesOverPlusRight : (left, centre, right : Nat) ->
618 | left * (centre + right) = (left * centre) + (left * right)
619 | multDistributesOverPlusRight left centre right = Calc $
620 | |~ left * (centre + right)
621 | ~~ (centre + right) * left ...(multCommutative left (centre + right))
622 | ~~ (centre * left) + (right * left)
623 | ...(multDistributesOverPlusLeft centre right left)
624 | ~~ (left * centre) + (left * right)
626 | (multCommutative centre left)
627 | (multCommutative right left))
630 | multAssociative : (left, centre, right : Nat) ->
631 | left * (centre * right) = (left * centre) * right
632 | multAssociative Z _ _ = Refl
633 | multAssociative (S left) centre right = Calc $
634 | |~ (centre * right) + (left * (centre * right))
635 | ~~ (centre * right) + ((left * centre) * right)
636 | ...(cong ((centre * right) +) $
637 | multAssociative left centre right)
638 | ~~ ((1 + left) * centre) * right ..<(multDistributesOverPlusLeft centre (left * centre) right)
641 | multOneLeftNeutral : (right : Nat) -> 1 * right = right
642 | multOneLeftNeutral right = plusZeroRightNeutral right
645 | multOneRightNeutral : (left : Nat) -> left * 1 = left
646 | multOneRightNeutral left = Calc $
648 | ~~ 1 * left ...(multCommutative left 1)
649 | ~~ left ...(multOneLeftNeutral left)
654 | minusSuccSucc : (left, right : Nat) ->
655 | minus (S left) (S right) = minus left right
656 | minusSuccSucc _ _ = Refl
659 | minusZeroLeft : (right : Nat) -> minus 0 right = Z
660 | minusZeroLeft _ = Refl
663 | minusZeroRight : (left : Nat) -> minus left 0 = left
664 | minusZeroRight Z = Refl
665 | minusZeroRight (S _) = Refl
668 | minusZeroN : (n : Nat) -> Z = minus n n
669 | minusZeroN Z = Refl
670 | minusZeroN (S n) = minusZeroN n
673 | minusOneSuccN : (n : Nat) -> S Z = minus (S n) n
674 | minusOneSuccN Z = Refl
675 | minusOneSuccN (S n) = minusOneSuccN n
678 | minusSuccOne : (n : Nat) -> minus (S n) 1 = n
679 | minusSuccOne Z = Refl
680 | minusSuccOne (S _) = Refl
683 | minusPlusZero : (n, m : Nat) -> minus n (n + m) = Z
684 | minusPlusZero Z _ = Refl
685 | minusPlusZero (S n) m = minusPlusZero n m
688 | minusPos : m `LT` n -> Z `LT` minus n m
689 | minusPos lt = case view lt of
691 | LTSucc lt => minusPos lt
694 | minusLteMonotone : {p : Nat} -> m `LTE` n -> minus m p `LTE` minus n p
695 | minusLteMonotone LTEZero = LTEZero
696 | minusLteMonotone {p = Z} prf@(LTESucc _) = prf
697 | minusLteMonotone {p = S p} (LTESucc lte) = minusLteMonotone lte
700 | minusLtMonotone : m `LT` n -> p `LT` n -> minus m p `LT` minus n p
701 | minusLtMonotone {m} {p} mltn pltn = case view pltn of
702 | LTZero => ltRecall {p = (`minus` 0)} mltn $
CalcSmart {leq = LT} $
704 | ~~ m ...(minusZeroRight m)
705 | <~ minus n Z ...(mltn)
706 | LTSucc pltn => case view mltn of
707 | LTZero => minusPos pltn
708 | LTSucc mltn => minusLtMonotone mltn pltn
711 | minusPlus : (m : Nat) -> minus (plus m n) m === n
712 | minusPlus Z = irrelevantEq (minusZeroRight n)
713 | minusPlus (S m) = minusPlus m
716 | plusMinusLte : (n, m : Nat) -> LTE n m -> (m `minus` n) + n = m
717 | plusMinusLte Z m _ = Calc $
718 | |~ (m `minus` 0) + 0
719 | ~~ m + 0 ...(cong (+0) $
minusZeroRight m)
720 | ~~ m ...(plusZeroRightNeutral m)
721 | plusMinusLte (S _) Z lte = absurd lte
722 | plusMinusLte (S n) (S m) lte = Calc $
723 | |~ ((1+m) `minus` (1+n)) + (1+n)
724 | ~~ (m `minus` n) + (1 + n) ...(Refl)
725 | ~~ 1+((m `minus` n) + n) ..<(plusSuccRightSucc (m `minus` n) n)
726 | ~~ 1+m ...(cong (1+) $
plusMinusLte n m
730 | minusMinusMinusPlus : (left, centre, right : Nat) ->
731 | minus (minus left centre) right = minus left (centre + right)
732 | minusMinusMinusPlus Z Z _ = Refl
733 | minusMinusMinusPlus (S _) Z _ = Refl
734 | minusMinusMinusPlus Z (S _) _ = Refl
735 | minusMinusMinusPlus (S left) (S centre) right = Calc $
736 | |~ (((1+left) `minus` (1+centre)) `minus` right)
737 | ~~ ((left `minus` centre) `minus` right) ...(Refl)
738 | ~~ (left `minus` (centre + right)) ...(minusMinusMinusPlus left centre right)
741 | plusMinusLeftCancel : (left, right : Nat) -> (right' : Nat) ->
742 | minus (left + right) (left + right') = minus right right'
743 | plusMinusLeftCancel Z _ _ = Refl
744 | plusMinusLeftCancel (S left) right right' = Calc $
745 | |~ ((left + right) `minus` (left + right'))
746 | ~~ (right `minus` right') ...(plusMinusLeftCancel left right right')
749 | multDistributesOverMinusLeft : (left, centre, right : Nat) ->
750 | (minus left centre) * right = minus (left * right) (centre * right)
751 | multDistributesOverMinusLeft Z Z _ = Refl
752 | multDistributesOverMinusLeft (S left) Z right = Calc $
753 | |~ right + (left * right)
754 | ~~ ((right + (left * right)) `minus` 0)
755 | ..<(minusZeroRight (right + (left*right)))
756 | ~~ (((1+left) * right) `minus` (0 * right))
758 | multDistributesOverMinusLeft Z (S _) _ = Refl
759 | multDistributesOverMinusLeft (S left) (S centre) right = Calc $
760 | |~ ((1 + left) `minus` (1 + centre)) * right
761 | ~~ (left `minus` centre) * right
763 | ~~ ((left*right) `minus` (centre*right))
764 | ...(multDistributesOverMinusLeft left centre right)
765 | ~~ ((right + (left * right)) `minus` (right + (centre * right)))
766 | ..<(plusMinusLeftCancel right (left*right) (centre*right))
767 | ~~ (((1+ left) * right) `minus` ((1+centre) * right))
770 | multDistributesOverMinusRight : (left, centre, right : Nat) ->
771 | left * (minus centre right) = minus (left * centre) (left * right)
772 | multDistributesOverMinusRight left centre right = Calc $
773 | |~ left * (centre `minus` right)
774 | ~~ (centre `minus` right) * left
775 | ...(multCommutative left (centre `minus` right))
776 | ~~ ((centre*left) `minus` (right*left))
777 | ...(multDistributesOverMinusLeft centre right left)
778 | ~~ ((left * centre) `minus` (left * right))
780 | (multCommutative centre left)
781 | (multCommutative right left))
783 | zeroMultEitherZero : (a,b : Nat) -> a*b = 0 -> Either (a = 0) (b = 0)
784 | zeroMultEitherZero 0 b prf = Left Refl
785 | zeroMultEitherZero (S a) b prf = Right $
zeroPlusLeftZero b (a * b) (sym prf)
817 | maximumAssociative : (l, c, r : Nat) ->
818 | maximum l (maximum c r) = maximum (maximum l c) r
819 | maximumAssociative Z _ _ = Refl
820 | maximumAssociative (S _) Z _ = Refl
821 | maximumAssociative (S _) (S _) Z = Refl
822 | maximumAssociative (S k) (S j) (S i) = cong S $
Calc $
823 | |~ maximum k (maximum j i)
824 | ~~ maximum (maximum k j) i ...(maximumAssociative k j i)
827 | maximumCommutative : (l, r : Nat) -> maximum l r = maximum r l
828 | maximumCommutative Z Z = Refl
829 | maximumCommutative Z (S _) = Refl
830 | maximumCommutative (S _) Z = Refl
831 | maximumCommutative (S k) (S j) = cong S $
maximumCommutative k j
834 | maximumIdempotent : (n : Nat) -> maximum n n = n
835 | maximumIdempotent Z = Refl
836 | maximumIdempotent (S k) = cong S $
maximumIdempotent k
839 | maximumLeftUpperBound : (m, n : Nat) -> m `LTE` maximum m n
840 | maximumLeftUpperBound 0 n = LTEZero
841 | maximumLeftUpperBound (S m) 0 = reflexive
842 | maximumLeftUpperBound (S m) (S n) = LTESucc (maximumLeftUpperBound m n)
845 | maximumRightUpperBound : (m, n : Nat) -> n `LTE` maximum m n
846 | maximumRightUpperBound 0 n = reflexive
847 | maximumRightUpperBound (S m) 0 = LTEZero
848 | maximumRightUpperBound (S m) (S n) = LTESucc (maximumRightUpperBound m n)
851 | minimumAssociative : (l, c, r : Nat) ->
852 | minimum l (minimum c r) = minimum (minimum l c) r
853 | minimumAssociative Z _ _ = Refl
854 | minimumAssociative (S _) Z _ = Refl
855 | minimumAssociative (S _) (S _) Z = Refl
856 | minimumAssociative (S k) (S j) (S i) = cong S $
minimumAssociative k j i
859 | minimumCommutative : (l, r : Nat) -> minimum l r = minimum r l
860 | minimumCommutative Z Z = Refl
861 | minimumCommutative Z (S _) = Refl
862 | minimumCommutative (S _) Z = Refl
863 | minimumCommutative (S k) (S j) = cong S $
minimumCommutative k j
866 | minimumIdempotent : (n : Nat) -> minimum n n = n
867 | minimumIdempotent Z = Refl
868 | minimumIdempotent (S k) = cong S $
minimumIdempotent k
871 | minimumZeroZeroLeft : (left : Nat) -> minimum left 0 = Z
872 | minimumZeroZeroLeft left = Calc $
874 | ~~ minimum 0 left ...(minimumCommutative left 0)
878 | minimumSuccSucc : (left, right : Nat) ->
879 | minimum (S left) (S right) = S (minimum left right)
880 | minimumSuccSucc _ _ = Refl
883 | maximumZeroNLeft : (left : Nat) -> maximum left Z = left
884 | maximumZeroNLeft left = Calc $
886 | ~~ maximum 0 left ...(maximumCommutative left Z)
890 | maximumSuccSucc : (left, right : Nat) ->
891 | S (maximum left right) = maximum (S left) (S right)
892 | maximumSuccSucc _ _ = Refl
895 | sucMaxL : (l : Nat) -> maximum (S l) l = (S l)
897 | sucMaxL (S l) = cong S $
sucMaxL l
900 | sucMaxR : (l : Nat) -> maximum l (S l) = (S l)
902 | sucMaxR (S l) = cong S $
sucMaxR l
905 | sucMinL : (l : Nat) -> minimum (S l) l = l
907 | sucMinL (S l) = cong S $
sucMinL l
910 | sucMinR : (l : Nat) -> minimum l (S l) = l
912 | sucMinR (S l) = cong S $
sucMinR l
919 | [Maximum] Monoid Nat using Semigroup.Maximum where