Int.eq
import Natural (+, zeroPlusId, sucPlus)
import Int (Int, IntR, intZero, intOne, toInt)
import Int.normalize (normPair, normSound, intNormalize)
import Core.equality (sym, trans, cong, pairext)
import Core.prop (↔, iffIntro, ∧, ¬, ⊥, andIntro, andFst, andSnd, impIntro, impApply)
import Natural.eq (EqN, eqNRefl, eqNSound, eqNComplete, predEq)
classEqOfRel : {p q : ℕ × ℕ} → IntR p q → class p ≡ class q ∈ Int
using (Int.Int.unfold, Int.IntR.unfold)
classEqOfRel = λp q h. ⋆
classNormPairEq : {p : ℕ × ℕ} → class (normPair (p .π₁) (p .π₂)) ≡ class p ∈ Int
using (Int.Int.unfold, Int.IntR.eq, Int.normalize.normClass, Int.normalize.normPair.eq, normSound)
classNormPairEq = λp. classEqOfRel (normSound (p .π₁) (p .π₂))
intNormalizeId : (z : Int) → intNormalize z ≡ z
using (classNormPairEq,
Int.Int.unfold,
Int.normalize.intNormalize.eq,
Int.normalize.normClass,
Int.normalize.normPair.eq)
intNormalizeId = λz. quot-elim (p. classNormPairEq) z
EqI : Int → Int → Ω
EqI = λz1 z2. intNormalize z1 ≡ intNormalize z2
eqIRefl : (z : Int) → EqI z z using (Int.eq.EqI.unfold, intNormalizeId)
eqIRefl = λz. ⋆
eqISound : {z1 z2 : Int} → EqI z1 z2 → z1 ≡ z2
using (Int.eq.EqI.eq,
Int.eq.EqI.unfold,
intNormalizeId,
Int.Int.eq,
Int.Int.unfold,
Int.normalize.intNormalize.eq)
eqISound =
λz1 z2 h. trans
_
_
_
sym _ _ (intNormalizeId z1)
trans (intNormalize z1) _ _ h (intNormalizeId z2)
eqIComplete : {z1 z2 : Int} → (z1 ≡ z2) → EqI z1 z2
using (Int.eq.EqI.unfold, intNormalizeId, Int.Int.unfold)
eqIComplete = λz1 z2 h. ⋆
eqISoundP : {z1 z2 : Int} → EqI z1 z2 → z1 ≡ z2 using (intNormalizeId)
eqISoundP = λz1 z2 h. eqISound h
eqICompleteP : {z1 z2 : Int} → (z1 ≡ z2) → EqI z1 z2 using (Int.eq.EqI.unfold, intNormalizeId)
eqICompleteP = λz1 z2 h. eqIComplete h
eqIIff : {z1 z2 : Int} → EqI z1 z2 ↔ (z1 ≡ z2)
using (intNormalizeId, Core.prop.↔.unfold, Core.prop.∧.unfold)
eqIIff = λz1 z2. iffIntro eqISoundP eqICompleteP
normPairZR : {n : ℕ} → normPair n Z ≡ (n, Z) using (Int.normalize.normPair.eq)
normPairZR = λn. ℕ-elim ⋆ (k ih. ⋆) n
normPairLeftZ : (b c : ℕ) → normPair c (b + c) ≡ (Z, b)
using (Int.normalize.normPair.eq, Natural.+.eq, Natural.plusZeroId)
normPairLeftZ = λb c. ℕ-elim ⋆ (k ih. ⋆) c
normPairRightZ : (n d : ℕ) → normPair (n + d) d ≡ (n, Z)
using (Int.normalize.normPair.eq, Natural.+.eq, normPairZR)
normPairRightZ = λn d. ℕ-elim normPairZR (k ih. ⋆) d
normPairWD : (a b c d : ℕ) (h : a + d ≡ b + c) → normPair a b ≡ normPair c d
using (Int.eq.normPairZR,
Int.normalize.normPair.eq,
normPairLeftZ,
normPairRightZ,
sucPlus,
zeroPlusId)
normPairWD =
λa. ℕ-elim
λb c d h. trans
_
_
_
⋆
trans
_
_
_
sym _ _ (normPairLeftZ b c)
cong (λu. ℕ × ℕ) (λx. normPair c x) (sym _ _ (trans _ _ _ (sym _ _ (zeroPlusId d)) h))
a' ih. λb. ℕ-elim
λc d h. trans
_
_
_
⋆
trans
_
_
_
sym _ _ (normPairRightZ (S a') d)
cong (λu. ℕ × ℕ) (λx. normPair x d) (trans _ _ _ h (zeroPlusId c))
b' ihb. λc d h. ih
b'
c
d
predEq (trans _ _ _ (sym _ _ (sucPlus a' d)) (trans _ _ _ h (sucPlus b' c)))
b
a
intCanon : Int → ℕ × ℕ using (Int.Int.unfold, normPairWD)
intCanon = λz. quot-elim (p. normPair (p .π₁) (p .π₂)) z
intCanonToInt : (z : Int) → toInt (intCanon z) ≡ z
using (classNormPairEq,
Int.eq.intCanon.eq,
Int.Int.eq,
Int.Int.unfold,
Int.toInt.unfold,
Int.toInt.eq,
Int.normalize.normClass,
Int.normalize.normPair.eq)
intCanonToInt = λz. quot-elim (p. classNormPairEq) z
intCanonClass : (z : Int) → class (intCanon z) ≡ z
using (classNormPairEq,
Int.eq.intCanon.eq,
Int.Int.eq,
Int.Int.unfold,
Int.normalize.normClass,
Int.normalize.normPair.eq)
intCanonClass = λz. quot-elim (p. classNormPairEq) z
intCanonOne : intCanon intOne ≡ (S Z, Z)
using (Int.eq.intCanon.eq, Int.intOne.eq, Int.normalize.normPair.eq)
intCanonOne = ⋆
intCanonZero : intCanon intZero ≡ (Z, Z)
using (Int.eq.intCanon.eq, Int.intZero.eq, Int.normalize.normPair.eq)
intCanonZero = ⋆
EqZ : Int → Int → Ω
EqZ = λz1 z2. EqN (intCanon z1 .π₁) (intCanon z2 .π₁) ∧ EqN (intCanon z1 .π₂) (intCanon z2 .π₂)
eqZRefl : (z : Int) → EqZ z z
using (Int.eq.EqZ.eq,
Int.eq.EqZ.unfold,
Int.eq.intCanon.eq,
Natural.eq.EqN.eq,
Int.Int.unfold,
Core.prop.∧.unfold)
eqZRefl = λz. andIntro (eqNRefl (intCanon z .π₁)) (eqNRefl (intCanon z .π₂))
eqZSound : {z1 z2 : Int} → EqZ z1 z2 → z1 ≡ z2 using (Int.eq.EqZ.eq)
eqZSound =
λz1 z2 h. trans
_
_
_
sym _ _ (intCanonToInt z1)
trans
_
_
_
cong _ toInt (pairext (eqNSound (andFst h)) (eqNSound (andSnd h)))
intCanonToInt z2
eqZComplete : {z1 z2 : Int} → (z1 ≡ z2) → EqZ z1 z2
using (Int.eq.EqZ.eq,
Int.eq.EqZ.unfold,
Int.eq.intCanon.eq,
Natural.eq.EqN.eq,
Int.Int.unfold,
Core.prop.∧.unfold)
eqZComplete =
λz1 z2 h. andIntro
eqNComplete (cong (λu. ℕ) (λz. intCanon z .π₁) h)
eqNComplete (cong (λu. ℕ) (λz. intCanon z .π₂) h)
eqZSoundP : {z1 z2 : Int} → EqZ z1 z2 → z1 ≡ z2
eqZSoundP = λz1 z2 h. eqZSound h
eqZCompleteP : {z1 z2 : Int} → (z1 ≡ z2) → EqZ z1 z2 using (Int.eq.EqZ.unfold, Core.prop.∧.unfold)
eqZCompleteP = λz1 z2 h. eqZComplete h
eqZIff : (z1 z2 : Int) → EqZ z1 z2 ↔ (z1 ≡ z2) using (Core.prop.↔.unfold, Core.prop.∧.unfold)
eqZIff = λz1 z2. iffIntro eqZSoundP eqZCompleteP
NeqZ : Int → Int → Ω
NeqZ = λz1 z2. ¬ (EqZ z1 z2)
neqZSound : {z1 z2 : Int} → NeqZ z1 z2 → ¬ (z1 ≡ z2)
using (Int.eq.EqZ.eq,
Int.eq.NeqZ.eq,
Int.eq.NeqZ.unfold,
Int.eq.intCanon.eq,
Natural.eq.EqN.eq,
Int.Int.eq,
Int.Int.unfold,
Natural.+.eq,
Core.prop.¬.eq,
Core.prop.¬.unfold,
Core.prop.∧.eq,
Core.prop.⊃.eq,
Core.prop.⊃.unfold,
Core.prop.⊥.eq)
neqZSound = λz1 z2 h. impIntro {z1 ≡ z2} {∥𝟘∥} (λe. impApply h (eqZCompleteP e))
neqZComplete : {z1 z2 : Int} → ¬ (z1 ≡ z2) → NeqZ z1 z2
using (Int.eq.EqZ.eq,
Int.eq.EqZ.unfold,
Int.eq.NeqZ.eq,
Int.eq.NeqZ.unfold,
Int.eq.intCanon.eq,
Natural.eq.EqN.eq,
Int.Int.eq,
Int.Int.unfold,
Int.normalize.normPair.eq,
Core.prop.¬.eq,
Core.prop.¬.unfold,
Core.prop.∧.eq,
Core.prop.∧.unfold,
Core.prop.⊃.eq,
Core.prop.⊃.unfold,
Core.prop.⊤.eq,
Core.prop.⊥.eq)
neqZComplete = λz1 z2 h. impIntro {EqZ z1 z2} {∥𝟘∥} (λe. impApply h (eqZSoundP e))
neqZIff : (z1 z2 : Int) → NeqZ z1 z2 ↔ ¬ (z1 ≡ z2) using (Core.prop.↔.unfold, Core.prop.∧.unfold)
neqZIff = λz1 z2. iffIntro neqZSound neqZComplete
eqZOneZero : NeqZ intOne intZero
using (Int.eq.EqZ.eq,
Int.eq.EqZ.unfold,
Int.eq.NeqZ.eq,
Int.eq.NeqZ.unfold,
Int.eq.intCanon.eq,
Natural.eq.EqN.eq,
Int.intOne.eq,
Int.intZero.eq,
Int.normalize.normPair.eq,
Core.prop.¬.eq,
Core.prop.¬.unfold,
Core.prop.∧.eq,
Core.prop.∧.unfold,
Core.prop.⊃.eq,
Core.prop.⊃.unfold,
Core.prop.⊥.eq)
eqZOneZero =
impIntro
{EqZ intOne intZero}
{⊥}
λh. andFst {⊥} {EqN (intCanon intOne .π₂) (intCanon intZero .π₂)} h
intOneNotZero : ¬ (intOne ≡ intZero) using (Core.prop.¬.unfold, Core.prop.⊃.unfold)
intOneNotZero = neqZSound eqZOneZero
eqZTwo : EqZ (class (2, Z)) (class (3, S Z))
using (Int.eq.EqZ.eq,
Int.eq.EqZ.unfold,
Int.eq.intCanon.eq,
Natural.eq.EqN.eq,
Int.Int.unfold,
Int.normalize.normPair.eq,
Core.prop.∧.eq,
Core.prop.∧.unfold,
Core.prop.⊤.eq,
Core.prop.⊥.eq)
eqZTwo = andIntro {∥𝟙∥} {∥𝟙∥} ⋆ ⋆