Int.order
import Natural (+, *, plusComm, zeroPlusId, zeroMult)
import Natural.order (β€, leTotal, sumZeroL)
import Int (Int, intZero, intNeg)
import Int.add (+, intAddComm, intAddAssoc)
import Int.mul (*, intMulComm, intMulDistribL, intAddNegL, intAddNegR, intNegNeg, classPairEta)
import Rat.frac (intAddZeroL, intAddZeroR)
import Int.eq (intCanon, intCanonClass)
import Int.effective (intEffective)
import Core.equality (trans, sym, cong, transport)
import Core.id (Id, idToEq, eqToId)
intOfNat : β β Int using (Int.Int.unfold)
intOfNat = Ξ»n. class (n, Z)
infixl 4 β€
β€ : Int β Int β π
(β€) = Ξ»x y. (k : β) Γ Id _ (x + intOfNat k) y
intOfNatZero : intOfNat Z β‘ intZero using (Int.order.intOfNat.eq, Int.Int.unfold, Int.intZero.eq)
intOfNatZero = β
intOfNatPlus : (a b : β) β intOfNat a + intOfNat b β‘ intOfNat (a + b)
using (Int.order.intOfNat.eq, Int.Int.unfold, Int.add.+.eq, Natural.+.eq)
intOfNatPlus = Ξ»a b. β
intOfNatInjZ : {k : β} β (intOfNat k β‘ intZero) β k β‘ Z
using (hyp.rw,
Int.order.intOfNat.eq,
Int.IntR.unfold,
Int.intZero.eq,
Natural.plusZeroId,
Natural.plusZeroId.rw)
intOfNatInjZ = Ξ»k h. let r = intEffective h in β
intOfNatSplit : {x : Int} {a b : β} β x + intOfNat (a + b) β‘ x + intOfNat a + intOfNat b
using (Int.Int.unfold)
intOfNatSplit =
Ξ»x a b. x + intOfNat (a + b)
β‘β¨ cong (Ξ»u. Int) (Ξ»u. x + u) (sym _ _ (intOfNatPlus a b)) β© x + (intOfNat a + intOfNat b)
β‘β¨ sym _ _ (intAddAssoc x (intOfNat a) (intOfNat b)) β© x + intOfNat a + intOfNat b
intNegAdd : (z w : Int) β intNeg (z + w) β‘ intNeg z + intNeg w
using (Int.Int.unfold, Int.intNeg.eq, Int.add.+.eq)
intNegAdd = Ξ»z w. quot-elim (p. quot-elim (q. β) w) z
intNegPlusCancel : (x a : Int) β intNeg x + (x + a) β‘ a using (Int.Int.unfold)
intNegPlusCancel =
Ξ»x a. intNeg x + (x + a)
β‘β¨ sym _ _ (intAddAssoc (intNeg x) x a) β© intNeg x + x + a
β‘β¨ cong (Ξ»u. Int) (Ξ»u. u + a) (intAddNegL x) β© intZero + a
β‘β¨ intAddZeroL a β© a
intCancelL : (x a b : Int) β (x + a β‘ x + b) β a β‘ b
intCancelL =
Ξ»x a b h. trans
_
_
_
sym _ _ (intNegPlusCancel x a)
trans _ _ _ (cong (Ξ»u. Int) (Ξ»u. intNeg x + u) h) (intNegPlusCancel x b)
intPlusDiff : (x y : Int) β x + (y + intNeg x) β‘ y using (Int.Int.unfold)
intPlusDiff =
Ξ»x y. x + (y + intNeg x)
β‘β¨ cong (Ξ»u. Int) (Ξ»u. x + u) (intAddComm y (intNeg x)) β© x + (intNeg x + y)
β‘β¨ sym _ _ (intAddAssoc x (intNeg x) y) β© x + intNeg x + y
β‘β¨ cong (Ξ»u. Int) (Ξ»u. u + y) (intAddNegR x) β© intZero + y
β‘β¨ intAddZeroL y β© y
intPlusNegDiff : (x y : Int) β y + intNeg (y + intNeg x) β‘ x using (Int.Int.unfold)
intPlusNegDiff =
Ξ»x y. y + intNeg (y + intNeg x)
β‘β¨ cong (Ξ»u. Int) (Ξ»u. y + u) (intNegAdd y (intNeg x)) β© y + (intNeg y + intNeg (intNeg x))
β‘β¨ cong (Ξ»u. Int) (Ξ»u. y + (intNeg y + u)) (intNegNeg x) β© y + (intNeg y + x)
β‘β¨ sym _ _ (intAddAssoc y (intNeg y) x) β© y + intNeg y + x
β‘β¨ cong (Ξ»u. Int) (Ξ»u. u + x) (intAddNegR y) β© intZero + x
β‘β¨ intAddZeroL x β© x
leZRefl : (x : Int) β x β€ x using (Int.order.β€.unfold, Int.order.intOfNatZero, Int.Int.unfold)
leZRefl = Ξ»x. Z, eqToId _ _ (intAddZeroR x)
leZOfEq : {x y : Int} β (x β‘ y) β x β€ y
using (Int.order.β€.unfold, Int.order.intOfNatZero, Int.Int.unfold)
leZOfEq = Ξ»x y h. Z, eqToId _ _ (trans (x + intOfNat Z) _ _ (intAddZeroR x) h)
leZTrans : {x : Int} (y : Int) {z : Int} β x β€ y β y β€ z β x β€ z using (Int.order.β€.unfold)
leZTrans =
Ξ»x y z l1 l2. (,)
l1 .Οβ + l2 .Οβ
eqToId
_
_
trans
x + intOfNat (l1 .Οβ + l2 .Οβ)
_
_
intOfNatSplit
trans
_
_
_
cong (Ξ»u. Int) (Ξ»u. u + intOfNat (l2 .Οβ)) (idToEq _ _ _ (l1 .Οβ))
idToEq _ _ _ (l2 .Οβ)
leZAntisym : (x y : Int) β x β€ y β y β€ x β x β‘ y using (Int.order.β€.unfold)
leZAntisym =
Ξ»x y l1 l2. let h1 = idToEq _ _ _ (l1 .Οβ)
h2 = idToEq _ _ _ (l2 .Οβ)
loop : x + intOfNat (l1 .Οβ + l2 .Οβ) β‘ x
= trans
_
_
_
intOfNatSplit
trans _ _ _ (cong (Ξ»u. Int) (Ξ»u. u + intOfNat (l2 .Οβ)) h1) h2
sumz : intOfNat (l1 .Οβ + l2 .Οβ) β‘ intZero
= intCancelL _ _ _ (trans _ _ _ loop (sym _ _ (intAddZeroR x)))
k1z = sumZeroL _ _ (intOfNatInjZ sumz)
trans
_
_
_
trans
_
_
_
sym _ _ (intAddZeroR x)
cong
Ξ»u. Int
Ξ»u. x + u
sym _ _ (trans _ _ _ (cong (Ξ»u. Int) (Ξ»u. intOfNat u) k1z) intOfNatZero)
h1
intAddShiftR : {x w v : Int} β x + w + v β‘ x + v + w using (Int.Int.unfold)
intAddShiftR =
Ξ»x w v. x + w + v
β‘β¨ intAddAssoc x w v β© x + (w + v)
β‘β¨ cong (Ξ»u. Int) (Ξ»u. x + u) (intAddComm w v) β© x + (v + w)
β‘β¨ sym _ _ (intAddAssoc x v w) β© x + v + w
leZPlusMonoR : {x y : Int} (w : Int) β x β€ y β x + w β€ y + w using (Int.order.β€.unfold)
leZPlusMonoR =
Ξ»x y w le. (,)
le .Οβ
eqToId
_
_
trans
x + w + intOfNat (le .Οβ)
_
_
intAddShiftR
cong (Ξ»u. Int) (Ξ»u. u + w) (idToEq _ _ _ (le .Οβ))
leZPlusMonoL : (x y w : Int) β x β€ y β w + x β€ w + y using (Int.order.β€.unfold)
leZPlusMonoL =
Ξ»x y w le. leZTrans
_
leZOfEq (intAddComm w x)
leZTrans _ (leZPlusMonoR w le) (leZOfEq (intAddComm y w))
intNegAddCancel : {x v : Int} β intNeg (x + v) + v β‘ intNeg x using (Int.Int.unfold)
intNegAddCancel =
Ξ»x v. intNeg (x + v) + v
β‘β¨ cong (Ξ»u. Int) (Ξ»u. u + v) (intNegAdd x v) β© intNeg x + intNeg v + v
β‘β¨ intAddAssoc (intNeg x) (intNeg v) v β© intNeg x + (intNeg v + v)
β‘β¨ cong (Ξ»u. Int) (Ξ»u. intNeg x + u) (intAddNegL v) β© intNeg x + intZero
β‘β¨ intAddZeroR (intNeg x) β© intNeg x
leZNegFlip : (x y : Int) β x β€ y β intNeg y β€ intNeg x using (Int.order.β€.unfold)
leZNegFlip =
Ξ»x y le. (,)
le .Οβ
eqToId
_
_
trans
_
_
intNeg x
cong (Ξ»u. Int) (Ξ»u. intNeg u + intOfNat (le .Οβ)) (sym _ _ (idToEq _ _ _ (le .Οβ)))
intNegAddCancel
leZOfNat : (a b : β) β a β€ b β intOfNat a β€ intOfNat b
using (Int.order.β€.unfold, Natural.order.β€.unfold)
leZOfNat =
Ξ»a b le. (,)
le .Οβ
eqToId
_
_
trans
_
_
_
intOfNatPlus a (le .Οβ)
cong (Ξ»u. Int) (Ξ»u. intOfNat u) (idToEq _ _ _ (le .Οβ))
sumSwapZL : (a b k : β) β (b + k β‘ a) β k + b β‘ Z + a
sumSwapZL = Ξ»a b k h. k + b β‘β¨ plusComm b k β© b + k β‘β¨ h β© a β‘β¨ zeroPlusId a β© Z + a
clsOfRelGe : (a b k : β) β (b + k β‘ a) β class (k, Z) β‘ class (a, b) β Int
using (Int.Int.unfold, plusComm, sumSwapZL, zeroPlusId)
clsOfRelGe = Ξ»a b k h. β
clsOfRelLe : (a b k : β) β (a + k β‘ b) β class (k, Z) β‘ class (b, a) β Int
using (Int.order.clsOfRelGe, Int.Int.unfold, plusComm, zeroPlusId)
clsOfRelLe = Ξ»a b k h. β
intNegClass : (p : β Γ β) β intNeg (class p) β‘ class (p .Οβ, p .Οβ)
using (Int.Int.unfold, Int.intNeg.eq)
intNegClass = Ξ»p. β
leZTotal : (x y : Int) β x β€ y β y β€ x
using (Core.id.Id.unfold,
Int.order.β€.unfold,
Int.order.intOfNat.eq,
Int.Int.unfold,
Int.mul.intAddCong2,
Natural.order.β€.unfold)
leZTotal =
Ξ»x y. let d = y + intNeg x
hd = intCanonClass d
β-elim
nn. let hb = idToEq _ _ _ (nn .Οβ)
e1 : intOfNat (nn .Οβ) β‘ class (intCanon d)
= intOfNat (nn .Οβ)
β‘β¨ clsOfRelGe _ _ _ hb β© class (intCanon d .Οβ, intCanon d .Οβ)
β‘β¨ classPairEta (intCanon d) β© class (intCanon d)
injβ
(,)
nn .Οβ
eqToId
_
_
trans
_
_
y
cong (Ξ»u. Int) (Ξ»u. x + u) (trans _ _ _ e1 hd)
intPlusDiff x y
nn. let ha = idToEq _ _ _ (nn .Οβ)
e2 : intOfNat (nn .Οβ) β‘ intNeg (class (intCanon d))
= intOfNat (nn .Οβ)
β‘β¨ clsOfRelLe _ _ _ ha β© class (intCanon d .Οβ, intCanon d .Οβ)
β‘β¨ sym _ _ (intNegClass (intCanon d)) β© intNeg (class (intCanon d))
injβ
(,)
nn .Οβ
eqToId
_
_
trans
_
_
x
cong
Ξ»u. Int
Ξ»u. y + u
trans _ _ _ e2 (cong (Ξ»u. Int) (Ξ»u. intNeg u) hd)
intPlusNegDiff x y
leTotal (intCanon d .Οβ) (intCanon d .Οβ)
intOfNatMul : (a b : β) β intOfNat a * intOfNat b β‘ intOfNat (a * b)
using (Int.order.intOfNat.eq,
Int.mul.*.eq,
Int.Int.eq,
zeroMult,
zeroMult.rw,
Natural.multZeroId,
Natural.multZeroId.rw,
Natural.plusZeroId,
Natural.plusZeroId.rw,
zeroPlusId,
zeroPlusId.rw)
intOfNatMul = Ξ»a b. β
intMulDistribR : (a b c : Int) β (a + b) * c β‘ a * c + b * c using (Int.Int.unfold)
intMulDistribR =
Ξ»a b c. (a + b) * c
β‘β¨ intMulComm (a + b) c β© c * (a + b)
β‘β¨ intMulDistribL c a b β© c * a + c * b
β‘β¨ cong (Ξ»v. Int) (Ξ»v. v + c * b) (intMulComm c a) β© a * c + c * b
β‘β¨ cong (Ξ»v. Int) (Ξ»v. a * c + v) (intMulComm c b) β© a * c + b * c
leZMultMonoNat : {x y : Int} {m : β} β x β€ y β x * intOfNat m β€ y * intOfNat m
using (Int.order.β€.unfold)
leZMultMonoNat =
Ξ»x y m le. (,)
le .Οβ * m
eqToId
_
_
trans
_
_
_
cong (Ξ»v. Int) (Ξ»v. x * intOfNat m + v) (sym _ _ (intOfNatMul (le .Οβ) m))
trans
_
_
_
sym _ _ (intMulDistribR x (intOfNat (le .Οβ)) (intOfNat m))
cong (Ξ»v. Int) (Ξ»v. v * intOfNat m) (idToEq _ _ _ (le .Οβ))
leZNonNegView : (c : Int) β intZero β€ c β (m : β) Γ intOfNat m β‘ c using (Int.order.β€.unfold)
leZNonNegView =
Ξ»c le. le .Οβ, trans _ _ _ (sym _ _ (intAddZeroL (intOfNat (le .Οβ)))) (idToEq _ _ _ (le .Οβ))
leZMultMono : (x y c : Int) β x β€ y β intZero β€ c β x * c β€ y * c using (Int.order.β€.unfold)
leZMultMono =
Ξ»x y c le lc. transport
{Int}
Ξ»u. x * u β€ y * u
{intOfNat (leZNonNegView _ lc .Οβ)}
leZNonNegView _ lc .Οβ
leZMultMonoNat le