Rat.half
import Natural (+, *, sucPlus, plusSucId)
import Int (Int, intOne)
import Int.add (+)
import Int.mul (*, intMulOneL, intMulDistribL, intMulDistribR)
import Int.order (intOfNat, intOfNatPlus)
import Rat.frac (NZ, nzPos, nzMul, nzToInt, Rat, mkRat, num, den, ratAdd, intScale, intScaleToInt)
import Rat (Q, qcls, +, qZero, qAddCls, RatR, dInt, clsEqOfRel, nzToIntMul)
import Rat.order (≤)
import Rat.bound (leQSelfAdd, leQZeroOfPos)
import Real (qInvNat, qInvNatPos)
import Core.equality (trans, sym, cong, transport)
dbl : ℕ → ℕ
dbl = λn. S (n + n)
intDblSquare : (g : Int) → (g + g + (g + g)) * g ≡ (g + g) * (g + g) using (Int.Int.unfold)
intDblSquare =
λg. (g + g + (g + g)) * g
≡⟨ intMulDistribR (g + g) (g + g) g ⟩ (g + g) * g + (g + g) * g
≡⟨ sym _ _ (intMulDistribL (g + g) g g) ⟩ (g + g) * (g + g)
nzPosInt : (k : ℕ) → nzToInt (nzPos k) ≡ intOfNat (S k)
using (Int.order.intOfNat.eq, Int.Int.unfold, Rat.frac.nzPos.eq, Rat.frac.nzToInt.eq)
nzPosInt = λk. ⋆
sucDbl : (n : ℕ) → S (dbl n) ≡ S n + S n using (sucPlus.rw, plusSucId.rw, Rat.half.dbl.eq)
sucDbl = λn. ⋆
nzPosDbl : (n : ℕ) → nzToInt (nzPos (dbl n)) ≡ nzToInt (nzPos n) + nzToInt (nzPos n)
using (Int.Int.unfold)
nzPosDbl =
λn. nzToInt (nzPos (dbl n))
≡⟨ nzPosInt (dbl n) ⟩ intOfNat (S (dbl n))
≡⟨ cong (λw. Int) (λw. intOfNat w) (sucDbl n) ⟩ intOfNat (S n + S n)
≡⟨ sym _ _ (intOfNatPlus (S n) (S n)) ⟩ intOfNat (S n) + intOfNat (S n)
≡⟨ sym _ _ (cong (λw. Int) (λw. w + w) (nzPosInt n)) ⟩ nzToInt (nzPos n) + nzToInt (nzPos n)
unitRat : ℕ → Rat using (Rat.frac.Rat.unfold)
unitRat = λk. mkRat intOne (nzPos k)
scaleOne : {d : NZ} → intScale d intOne ≡ nzToInt d using (Int.intOne.eq, Rat.frac.NZ.unfold)
scaleOne = λd. intScaleToInt
unitAddNum : {d : NZ} → num (ratAdd (mkRat intOne d) (mkRat intOne d)) ≡ nzToInt d + nzToInt d
using (Int.intNeg.eq,
Int.intOne.eq,
Int.add.+.eq,
Rat.frac.NZ.unfold,
Rat.frac.den.eq,
Rat.frac.intScale.eq,
Rat.frac.intScaleN.eq,
Rat.frac.mkRat.eq,
Rat.frac.num.eq,
Rat.frac.ratAdd.eq)
unitAddNum = λd. cong (λw. Int) (λw. w + w) {intScale d intOne} {nzToInt d} scaleOne
unitAddDen : {d : NZ} → dInt (ratAdd (mkRat intOne d) (mkRat intOne d)) ≡ nzToInt d * nzToInt d
using (Int.intOne.eq,
Int.add.+.eq,
Rat.frac.NZ.unfold,
Rat.frac.den.eq,
Rat.frac.intScale.eq,
Rat.frac.mkRat.eq,
Rat.frac.num.eq,
Rat.frac.nzMul.eq,
Rat.frac.nzNeg.eq,
Rat.frac.nzPos.eq,
Rat.frac.nzToInt.eq,
Rat.frac.ratAdd.eq,
Rat.dInt.eq)
unitAddDen = λd. nzToIntMul d d
unitNum : (k : ℕ) → num (unitRat k) ≡ intOne
using (Int.Int.unfold, Rat.half.unitRat.eq, Rat.frac.mkRat.eq, Rat.frac.num.eq)
unitNum = λk. ⋆
unitDen : (k : ℕ) → dInt (unitRat k) ≡ nzToInt (nzPos k)
using (Int.Int.unfold, Rat.half.unitRat.eq, Rat.frac.den.eq, Rat.frac.mkRat.eq, Rat.dInt.eq)
unitDen = λk. ⋆
unitAddNumU : (k : ℕ) → num (ratAdd (unitRat k) (unitRat k)) ≡ nzToInt (nzPos k) + nzToInt (nzPos k)
using (Rat.half.unitRat.eq)
unitAddNumU = λk. unitAddNum
unitAddDenU : (k : ℕ)
→ dInt (ratAdd (unitRat k) (unitRat k)) ≡ nzToInt (nzPos k) * nzToInt (nzPos k)
using (Rat.half.unitRat.eq)
unitAddDenU = λk. unitAddDen
halfCross : {n : ℕ}
→ num (ratAdd (unitRat (dbl n)) (unitRat (dbl n))) * dInt (unitRat n)
≡ num (unitRat n) * dInt (ratAdd (unitRat (dbl n)) (unitRat (dbl n)))
using (Int.Int.unfold)
halfCross =
λn. num (ratAdd (unitRat (dbl n)) (unitRat (dbl n))) * dInt (unitRat n)
≡⟨ cong (λw. Int) (λw. num (ratAdd (unitRat (dbl n)) (unitRat (dbl n))) * w) (unitDen n) ⟩
num (ratAdd (unitRat (dbl n)) (unitRat (dbl n))) * nzToInt (nzPos n)
≡⟨ cong (λw. Int) (λw. w * nzToInt (nzPos n)) (unitAddNumU (dbl n)) ⟩
(nzToInt (nzPos (dbl n)) + nzToInt (nzPos (dbl n))) * nzToInt (nzPos n)
≡⟨ cong (λw. Int) (λw. (w + w) * nzToInt (nzPos n)) (nzPosDbl n) ⟩
(nzToInt (nzPos n) + nzToInt (nzPos n) + (nzToInt (nzPos n) + nzToInt (nzPos n)))
* nzToInt (nzPos n)
≡⟨ intDblSquare (nzToInt (nzPos n)) ⟩
(nzToInt (nzPos n) + nzToInt (nzPos n)) * (nzToInt (nzPos n) + nzToInt (nzPos n))
≡⟨ sym _ _ (cong (λw. Int) (λw. w * w) (nzPosDbl n)) ⟩
nzToInt (nzPos (dbl n)) * nzToInt (nzPos (dbl n))
≡⟨ sym _ _ (unitAddDenU (dbl n)) ⟩ dInt (ratAdd (unitRat (dbl n)) (unitRat (dbl n)))
≡⟨ sym _ _ (intMulOneL (dInt (ratAdd (unitRat (dbl n)) (unitRat (dbl n))))) ⟩
intOne * dInt (ratAdd (unitRat (dbl n)) (unitRat (dbl n)))
≡⟨ cong (λw. Int) (λw. w * dInt (ratAdd (unitRat (dbl n)) (unitRat (dbl n)))) (unitNum n) ⟩
num (unitRat n) * dInt (ratAdd (unitRat (dbl n)) (unitRat (dbl n)))
halfRel : (n : ℕ) → RatR (ratAdd (unitRat (dbl n)) (unitRat (dbl n))) (unitRat n)
using (Rat.RatR.eq, Rat.RatR.unfold)
halfRel = λn. halfCross
qInvHalf : (n : ℕ) → qInvNat (dbl n) + qInvNat (dbl n) ≡ qInvNat n
using (Int.intOne.eq,
Rat.half.dbl.eq,
Rat.half.unitRat.eq,
Rat.frac.mkRat.eq,
Rat.frac.nzPos.eq,
Rat.frac.ratAdd.eq,
Rat.+.eq,
Rat.qcls.eq,
Real.qInvNat.eq)
qInvHalf =
λn. trans
_
qcls (ratAdd (unitRat (dbl n)) (unitRat (dbl n)))
_
qAddCls (unitRat (dbl n)) (unitRat (dbl n))
clsEqOfRel _ _ (halfRel n)
leQZeroInvNat : (n : ℕ) → qZero ≤ qInvNat n using (Rat.order.≤.unfold, Rat.order.NonNegS.unfold)
leQZeroInvNat = λn. leQZeroOfPos _ (qInvNatPos n)
leQInvDbl : (n : ℕ) → qInvNat (dbl n) ≤ qInvNat n
using (Rat.order.≤.unfold, Rat.order.NonNegS.unfold)
leQInvDbl =
λn. transport
λw. qInvNat (dbl n) ≤ w
qInvHalf n
leQSelfAdd (qInvNat (dbl n)) (leQZeroInvNat (dbl n))