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 0 0 _ = LTEZero
291 | lteReflectsLTE 0 (S k) _ = LTEZero
292 | lteReflectsLTE (S k) (S j) prf = LTESucc (lteReflectsLTE k j prf)
295 | gteReflectsGTE : (k : Nat) -> (n : Nat) -> gte k n === True -> k `GTE` n
296 | gteReflectsGTE k n prf = lteReflectsLTE n k prf
299 | ltReflectsLT : (k : Nat) -> (n : Nat) -> lt k n === True -> k `LT` n
300 | ltReflectsLT k n prf = lteReflectsLTE (S k) n prf
303 | ltOpReflectsLT : (m,n : Nat) -> So (m < n) -> LT m n
304 | ltOpReflectsLT 0 (S k) prf = LTESucc LTEZero
305 | ltOpReflectsLT (S k) (S j) prf = LTESucc (ltOpReflectsLT k j prf)
308 | gtReflectsGT : (k : Nat) -> (n : Nat) -> gt k n === True -> k `GT` n
309 | gtReflectsGT k n prf = ltReflectsLT n k prf
312 | minimum : Nat -> Nat -> Nat
314 | minimum (S n) Z = Z
315 | minimum (S n) (S m) = S (minimum n m)
318 | maximum : Nat -> Nat -> Nat
320 | maximum (S n) Z = S n
321 | maximum (S n) (S m) = S (maximum n m)
326 | eqSucc : (0 left, right : Nat) -> left = right -> S left = S right
327 | eqSucc _ _ Refl = Refl
331 | injective Refl = Refl
334 | SIsNotZ : Not (S x = Z)
341 | mod' : Nat -> Nat -> Nat -> Nat
342 | mod' Z centre right = centre
343 | mod' (S fuel) centre right =
344 | if lte centre right then
347 | mod' fuel (minus centre (S right)) right
350 | modNatNZ : Nat -> (y: Nat) -> (0 _ : NonZero y) -> Nat
351 | modNatNZ left Z p = void (absurd p)
352 | modNatNZ left (S right) _ = mod' left left right
355 | modNat : Nat -> Nat -> Nat
356 | modNat left (S right) = modNatNZ left (S right) ItIsSucc
362 | div' : Nat -> Nat -> Nat -> Nat
363 | div' Z centre right = Z
364 | div' (S fuel) centre right =
365 | if lte centre right then
368 | S (div' fuel (minus centre (S right)) right)
372 | divNatNZ : Nat -> (y: Nat) -> (0 _ : NonZero y) -> Nat
373 | divNatNZ left (S right) _ = div' left left right
376 | divNat : Nat -> Nat -> Nat
377 | divNat left (S right) = divNatNZ left (S right) ItIsSucc
381 | divCeilNZ : Nat -> (y: Nat) -> (0 _ : NonZero y) -> Nat
382 | divCeilNZ x y p = case (modNatNZ x y p) of
383 | Z => divNatNZ x y p
384 | S _ => S (divNatNZ x y p)
387 | divCeil : Nat -> Nat -> Nat
388 | divCeil x (S y) = divCeilNZ x (S y) ItIsSucc
392 | divmod' : Nat -> Nat -> Nat -> (Nat, Nat)
393 | divmod' Z centre right = (Z, centre)
394 | divmod' (S fuel) centre right =
395 | if lte centre right then
398 | let qr = divmod' fuel (minus centre (S right)) right
399 | in (S (fst qr), snd qr)
402 | divmodNatNZ : Nat -> (y: Nat) -> (0 _ : NonZero y) -> (Nat, Nat)
403 | divmodNatNZ left (S right) _ = divmod' left left right
413 | gcd : (a: Nat) -> (b: Nat) -> {auto 0 ok: NotBothZero a b} -> Nat
416 | gcd a (S b) = gcd (S b) (modNatNZ a (S b) ItIsSucc)
419 | lcm : Nat -> Nat -> Nat
422 | lcm a (S b) = divNat (a * (S b)) (gcd a (S b))
428 | data CmpNat : Nat -> Nat -> Type where
429 | CmpLT : (y : _) -> CmpNat x (x + S y)
431 | CmpGT : (x : _) -> CmpNat (y + S x) y
434 | cmp : (x, y : Nat) -> CmpNat x y
436 | cmp Z (S k) = CmpLT _
437 | cmp (S k) Z = CmpGT _
438 | cmp (S x) (S y) with (cmp x y)
439 | cmp (S x) (S (x + (S k))) | CmpLT k = CmpLT k
440 | cmp (S x) (S x) | CmpEQ = CmpEQ
441 | cmp (S (y + (S k))) (S y) | CmpGT k = CmpGT k
446 | plusZeroLeftNeutral : (right : Nat) -> 0 + right = right
447 | plusZeroLeftNeutral _ = Refl
450 | plusZeroRightNeutral : (left : Nat) -> left + 0 = left
451 | plusZeroRightNeutral Z = Refl
452 | plusZeroRightNeutral (S n) = Calc $
454 | ~~ 1 + n ...(cong (1+) $
plusZeroRightNeutral n)
457 | plusSuccRightSucc : (left, right : Nat) -> S (left + right) = left + (S right)
458 | plusSuccRightSucc Z _ = Refl
459 | plusSuccRightSucc (S left) right = Calc $
460 | |~ 1 + (1 + (left + right))
461 | ~~ 1 + (left + (1 + right)) ...(cong (1+) $
plusSuccRightSucc left right)
464 | plusCommutative : (left, right : Nat) -> left + right = right + left
465 | plusCommutative Z right = Calc $
467 | ~~ right + 0 ..<(plusZeroRightNeutral right)
468 | plusCommutative (S left) right = Calc $
469 | |~ 1 + (left + right)
470 | ~~ 1 + (right + left) ...(cong (1+) $
plusCommutative left right)
471 | ~~ right + (1 + left) ...(plusSuccRightSucc right left)
474 | plusAssociative : (left, centre, right : Nat) ->
475 | left + (centre + right) = (left + centre) + right
476 | plusAssociative Z _ _ = Refl
477 | plusAssociative (S left) centre right = Calc $
478 | |~ 1 + (left + (centre + right))
479 | ~~ 1 + ((left + centre) + right) ...(cong (1+) $
plusAssociative left centre right)
482 | plusConstantRight : (left, right, c : Nat) -> left = right ->
483 | left + c = right + c
484 | plusConstantRight _ _ _ Refl = Refl
487 | plusConstantLeft : (left, right, c : Nat) -> left = right ->
488 | c + left = c + right
489 | plusConstantLeft _ _ _ Refl = Refl
492 | plusOneSucc : (right : Nat) -> 1 + right = S right
493 | plusOneSucc _ = Refl
496 | plusLeftCancel : (left, right, right' : Nat) ->
497 | left + right = left + right' -> right = right'
498 | plusLeftCancel Z _ _ p = p
499 | plusLeftCancel (S left) right right' p =
500 | plusLeftCancel left right right' $
injective p
503 | plusRightCancel : (left, left', right : Nat) ->
504 | left + right = left' + right -> left = left'
505 | plusRightCancel left left' right p =
506 | plusLeftCancel right left left' $
Calc $
508 | ~~ left + right ...(plusCommutative right left)
509 | ~~ left' + right ...(p)
510 | ~~ right + left' ...(plusCommutative left' right)
513 | plusLeftLeftRightZero : (left, right : Nat) ->
514 | left + right = left -> right = Z
515 | plusLeftLeftRightZero left right p =
516 | plusLeftCancel left right Z $
Calc $
519 | ~~ left + 0 ..<(plusZeroRightNeutral left)
522 | plusLteMonotoneRight : (p, q, r : Nat) -> q `LTE` r -> (q+p) `LTE` (r+p)
523 | plusLteMonotoneRight p Z r LTEZero = CalcSmart {leq = LTE} $
525 | <~ p + r ...(lteAddRight p)
526 | <~ r + p .=.(plusCommutative p r)
527 | plusLteMonotoneRight p (S q) (S r) (LTESucc q_lte_r) =
528 | LTESucc $
CalcSmart {leq = LTE} $
530 | <~ r + p ...(plusLteMonotoneRight p q r q_lte_r)
533 | plusLteMonotoneLeft : (p, q, r : Nat) -> q `LTE` r -> (p + q) `LTE` (p + r)
534 | plusLteMonotoneLeft p q r q_lt_r = CalcSmart {leq = LTE} $
536 | <~ q + p .=.(plusCommutative p q)
537 | <~ r + p ...(plusLteMonotoneRight p q r q_lt_r)
538 | <~ p + r .=.(plusCommutative r p)
542 | plusLteMonotone : {m, n, p, q : Nat} -> m `LTE` n -> p `LTE` q ->
543 | (m + p) `LTE` (n + q)
544 | plusLteMonotone left right = CalcSmart {leq = LTE} $
546 | <~ m + q ...(plusLteMonotoneLeft m p q right)
547 | <~ n + q ...(plusLteMonotoneRight q m n left)
549 | zeroPlusLeftZero : (a,b : Nat) -> (0 = a + b) -> a = 0
550 | zeroPlusLeftZero 0 0 Refl = Refl
551 | zeroPlusLeftZero (S k) b _ impossible
553 | zeroPlusRightZero : (a,b : Nat) -> (0 = a + b) -> b = 0
554 | zeroPlusRightZero 0 0 Refl = Refl
555 | zeroPlusRightZero (S k) b _ impossible
560 | multZeroLeftZero : (right : Nat) -> Z * right = Z
561 | multZeroLeftZero _ = Refl
564 | multZeroRightZero : (left : Nat) -> left * Z = Z
565 | multZeroRightZero Z = Refl
566 | multZeroRightZero (S left) = multZeroRightZero left
569 | multRightSuccPlus : (left, right : Nat) ->
570 | left * (S right) = left + (left * right)
571 | multRightSuccPlus Z _ = Refl
572 | multRightSuccPlus (S left) right = cong (1+) $
Calc $
573 | |~ right + (left * (1 + right))
574 | ~~ right + (left + (left * right))
575 | ...(cong (right +) $
multRightSuccPlus left right)
576 | ~~ (right + left) + (left * right)
577 | ...(plusAssociative right left (left*right))
578 | ~~ (left + right) + (left * right)
579 | ...(cong (+ (left * right)) $
plusCommutative right left)
580 | ~~ left + (right + (left * right))
581 | ..<(plusAssociative left right (left * right))
582 | ~~ left + ((1 + left) * right)
586 | multLeftSuccPlus : (left, right : Nat) ->
587 | (S left) * right = right + (left * right)
588 | multLeftSuccPlus _ _ = Refl
591 | multCommutative : (left, right : Nat) -> left * right = right * left
592 | multCommutative Z right = Calc $
594 | ~~ right * 0 ..<(multZeroRightZero right)
595 | multCommutative (S left) right = Calc $
596 | |~ right + (left * right)
597 | ~~ right + (right * left)
598 | ...(cong (right +) $
multCommutative left right)
599 | ~~ right * (1 + left)
600 | ..<(multRightSuccPlus right left)
603 | multDistributesOverPlusLeft : (left, centre, right : Nat) ->
604 | (left + centre) * right = (left * right) + (centre * right)
605 | multDistributesOverPlusLeft Z _ _ = Refl
606 | multDistributesOverPlusLeft (S left) centre right = Calc $
607 | |~ right + ((left + centre) * right)
608 | ~~ right + ((left * right) + (centre * right))
609 | ...(cong (right +) $
610 | multDistributesOverPlusLeft left centre right)
611 | ~~ (right + (left * right)) + (centre * right)
612 | ...(plusAssociative right (left*right) (centre*right))
614 | multDistributesOverPlusRight : (left, centre, right : Nat) ->
615 | left * (centre + right) = (left * centre) + (left * right)
616 | multDistributesOverPlusRight left centre right = Calc $
617 | |~ left * (centre + right)
618 | ~~ (centre + right) * left ...(multCommutative left (centre + right))
619 | ~~ (centre * left) + (right * left)
620 | ...(multDistributesOverPlusLeft centre right left)
621 | ~~ (left * centre) + (left * right)
623 | (multCommutative centre left)
624 | (multCommutative right left))
627 | multAssociative : (left, centre, right : Nat) ->
628 | left * (centre * right) = (left * centre) * right
629 | multAssociative Z _ _ = Refl
630 | multAssociative (S left) centre right = Calc $
631 | |~ (centre * right) + (left * (centre * right))
632 | ~~ (centre * right) + ((left * centre) * right)
633 | ...(cong ((centre * right) +) $
634 | multAssociative left centre right)
635 | ~~ ((1 + left) * centre) * right ..<(multDistributesOverPlusLeft centre (left * centre) right)
638 | multOneLeftNeutral : (right : Nat) -> 1 * right = right
639 | multOneLeftNeutral right = plusZeroRightNeutral right
642 | multOneRightNeutral : (left : Nat) -> left * 1 = left
643 | multOneRightNeutral left = Calc $
645 | ~~ 1 * left ...(multCommutative left 1)
646 | ~~ left ...(multOneLeftNeutral left)
651 | minusSuccSucc : (left, right : Nat) ->
652 | minus (S left) (S right) = minus left right
653 | minusSuccSucc _ _ = Refl
656 | minusZeroLeft : (right : Nat) -> minus 0 right = Z
657 | minusZeroLeft _ = Refl
660 | minusZeroRight : (left : Nat) -> minus left 0 = left
661 | minusZeroRight Z = Refl
662 | minusZeroRight (S _) = Refl
665 | minusZeroN : (n : Nat) -> Z = minus n n
666 | minusZeroN Z = Refl
667 | minusZeroN (S n) = minusZeroN n
670 | minusOneSuccN : (n : Nat) -> S Z = minus (S n) n
671 | minusOneSuccN Z = Refl
672 | minusOneSuccN (S n) = minusOneSuccN n
675 | minusSuccOne : (n : Nat) -> minus (S n) 1 = n
676 | minusSuccOne Z = Refl
677 | minusSuccOne (S _) = Refl
680 | minusPlusZero : (n, m : Nat) -> minus n (n + m) = Z
681 | minusPlusZero Z _ = Refl
682 | minusPlusZero (S n) m = minusPlusZero n m
685 | minusPos : m `LT` n -> Z `LT` minus n m
686 | minusPos lt = case view lt of
688 | LTSucc lt => minusPos lt
691 | minusLteMonotone : {p : Nat} -> m `LTE` n -> minus m p `LTE` minus n p
692 | minusLteMonotone LTEZero = LTEZero
693 | minusLteMonotone {p = Z} prf@(LTESucc _) = prf
694 | minusLteMonotone {p = S p} (LTESucc lte) = minusLteMonotone lte
697 | minusLtMonotone : m `LT` n -> p `LT` n -> minus m p `LT` minus n p
698 | minusLtMonotone {m} {p} mltn pltn = case view pltn of
699 | LTZero => ltRecall {p = (`minus` 0)} mltn $
CalcSmart {leq = LT} $
701 | ~~ m ...(minusZeroRight m)
702 | <~ minus n Z ...(mltn)
703 | LTSucc pltn => case view mltn of
704 | LTZero => minusPos pltn
705 | LTSucc mltn => minusLtMonotone mltn pltn
708 | minusPlus : (m : Nat) -> minus (plus m n) m === n
709 | minusPlus Z = irrelevantEq (minusZeroRight n)
710 | minusPlus (S m) = minusPlus m
713 | plusMinusLte : (n, m : Nat) -> LTE n m -> (m `minus` n) + n = m
714 | plusMinusLte Z m _ = Calc $
715 | |~ (m `minus` 0) + 0
716 | ~~ m + 0 ...(cong (+0) $
minusZeroRight m)
717 | ~~ m ...(plusZeroRightNeutral m)
718 | plusMinusLte (S _) Z lte = absurd lte
719 | plusMinusLte (S n) (S m) lte = Calc $
720 | |~ ((1+m) `minus` (1+n)) + (1+n)
721 | ~~ (m `minus` n) + (1 + n) ...(Refl)
722 | ~~ 1+((m `minus` n) + n) ..<(plusSuccRightSucc (m `minus` n) n)
723 | ~~ 1+m ...(cong (1+) $
plusMinusLte n m
727 | minusMinusMinusPlus : (left, centre, right : Nat) ->
728 | minus (minus left centre) right = minus left (centre + right)
729 | minusMinusMinusPlus Z Z _ = Refl
730 | minusMinusMinusPlus (S _) Z _ = Refl
731 | minusMinusMinusPlus Z (S _) _ = Refl
732 | minusMinusMinusPlus (S left) (S centre) right = Calc $
733 | |~ (((1+left) `minus` (1+centre)) `minus` right)
734 | ~~ ((left `minus` centre) `minus` right) ...(Refl)
735 | ~~ (left `minus` (centre + right)) ...(minusMinusMinusPlus left centre right)
738 | plusMinusLeftCancel : (left, right : Nat) -> (right' : Nat) ->
739 | minus (left + right) (left + right') = minus right right'
740 | plusMinusLeftCancel Z _ _ = Refl
741 | plusMinusLeftCancel (S left) right right' = Calc $
742 | |~ ((left + right) `minus` (left + right'))
743 | ~~ (right `minus` right') ...(plusMinusLeftCancel left right right')
746 | multDistributesOverMinusLeft : (left, centre, right : Nat) ->
747 | (minus left centre) * right = minus (left * right) (centre * right)
748 | multDistributesOverMinusLeft Z Z _ = Refl
749 | multDistributesOverMinusLeft (S left) Z right = Calc $
750 | |~ right + (left * right)
751 | ~~ ((right + (left * right)) `minus` 0)
752 | ..<(minusZeroRight (right + (left*right)))
753 | ~~ (((1+left) * right) `minus` (0 * right))
755 | multDistributesOverMinusLeft Z (S _) _ = Refl
756 | multDistributesOverMinusLeft (S left) (S centre) right = Calc $
757 | |~ ((1 + left) `minus` (1 + centre)) * right
758 | ~~ (left `minus` centre) * right
760 | ~~ ((left*right) `minus` (centre*right))
761 | ...(multDistributesOverMinusLeft left centre right)
762 | ~~ ((right + (left * right)) `minus` (right + (centre * right)))
763 | ..<(plusMinusLeftCancel right (left*right) (centre*right))
764 | ~~ (((1+ left) * right) `minus` ((1+centre) * right))
767 | multDistributesOverMinusRight : (left, centre, right : Nat) ->
768 | left * (minus centre right) = minus (left * centre) (left * right)
769 | multDistributesOverMinusRight left centre right = Calc $
770 | |~ left * (centre `minus` right)
771 | ~~ (centre `minus` right) * left
772 | ...(multCommutative left (centre `minus` right))
773 | ~~ ((centre*left) `minus` (right*left))
774 | ...(multDistributesOverMinusLeft centre right left)
775 | ~~ ((left * centre) `minus` (left * right))
777 | (multCommutative centre left)
778 | (multCommutative right left))
780 | zeroMultEitherZero : (a,b : Nat) -> a*b = 0 -> Either (a = 0) (b = 0)
781 | zeroMultEitherZero 0 b prf = Left Refl
782 | zeroMultEitherZero (S a) b prf = Right $
zeroPlusLeftZero b (a * b) (sym prf)
814 | maximumAssociative : (l, c, r : Nat) ->
815 | maximum l (maximum c r) = maximum (maximum l c) r
816 | maximumAssociative Z _ _ = Refl
817 | maximumAssociative (S _) Z _ = Refl
818 | maximumAssociative (S _) (S _) Z = Refl
819 | maximumAssociative (S k) (S j) (S i) = cong S $
Calc $
820 | |~ maximum k (maximum j i)
821 | ~~ maximum (maximum k j) i ...(maximumAssociative k j i)
824 | maximumCommutative : (l, r : Nat) -> maximum l r = maximum r l
825 | maximumCommutative Z Z = Refl
826 | maximumCommutative Z (S _) = Refl
827 | maximumCommutative (S _) Z = Refl
828 | maximumCommutative (S k) (S j) = cong S $
maximumCommutative k j
831 | maximumIdempotent : (n : Nat) -> maximum n n = n
832 | maximumIdempotent Z = Refl
833 | maximumIdempotent (S k) = cong S $
maximumIdempotent k
836 | maximumLeftUpperBound : (m, n : Nat) -> m `LTE` maximum m n
837 | maximumLeftUpperBound 0 n = LTEZero
838 | maximumLeftUpperBound (S m) 0 = reflexive
839 | maximumLeftUpperBound (S m) (S n) = LTESucc (maximumLeftUpperBound m n)
842 | maximumRightUpperBound : (m, n : Nat) -> n `LTE` maximum m n
843 | maximumRightUpperBound 0 n = reflexive
844 | maximumRightUpperBound (S m) 0 = LTEZero
845 | maximumRightUpperBound (S m) (S n) = LTESucc (maximumRightUpperBound m n)
848 | minimumAssociative : (l, c, r : Nat) ->
849 | minimum l (minimum c r) = minimum (minimum l c) r
850 | minimumAssociative Z _ _ = Refl
851 | minimumAssociative (S _) Z _ = Refl
852 | minimumAssociative (S _) (S _) Z = Refl
853 | minimumAssociative (S k) (S j) (S i) = cong S $
minimumAssociative k j i
856 | minimumCommutative : (l, r : Nat) -> minimum l r = minimum r l
857 | minimumCommutative Z Z = Refl
858 | minimumCommutative Z (S _) = Refl
859 | minimumCommutative (S _) Z = Refl
860 | minimumCommutative (S k) (S j) = cong S $
minimumCommutative k j
863 | minimumIdempotent : (n : Nat) -> minimum n n = n
864 | minimumIdempotent Z = Refl
865 | minimumIdempotent (S k) = cong S $
minimumIdempotent k
868 | minimumZeroZeroLeft : (left : Nat) -> minimum left 0 = Z
869 | minimumZeroZeroLeft left = Calc $
871 | ~~ minimum 0 left ...(minimumCommutative left 0)
875 | minimumSuccSucc : (left, right : Nat) ->
876 | minimum (S left) (S right) = S (minimum left right)
877 | minimumSuccSucc _ _ = Refl
880 | maximumZeroNLeft : (left : Nat) -> maximum left Z = left
881 | maximumZeroNLeft left = Calc $
883 | ~~ maximum 0 left ...(maximumCommutative left Z)
887 | maximumSuccSucc : (left, right : Nat) ->
888 | S (maximum left right) = maximum (S left) (S right)
889 | maximumSuccSucc _ _ = Refl
892 | sucMaxL : (l : Nat) -> maximum (S l) l = (S l)
894 | sucMaxL (S l) = cong S $
sucMaxL l
897 | sucMaxR : (l : Nat) -> maximum l (S l) = (S l)
899 | sucMaxR (S l) = cong S $
sucMaxR l
902 | sucMinL : (l : Nat) -> minimum (S l) l = l
904 | sucMinL (S l) = cong S $
sucMinL l
907 | sucMinR : (l : Nat) -> minimum l (S l) = l
909 | sucMinR (S l) = cong S $
sucMinR l
916 | [Maximum] Monoid Nat using Semigroup.Maximum where