Natural.eq
import Core.prelude (constP)
import Core.prop (⊤, ⊥, ↔, iffIntro, reflectSquash, isZeroCode)
import Core.equality (cong, sym, transport)
EqN : ℕ → ℕ → Ω
EqN = λn. ℕ-elim (λm. ℕ-elim ⊤ (k ih. ⊥) m) (n ih. λm. ℕ-elim ⊥ (k ih2. ih k) m) n
eqNRefl : (n : ℕ) → EqN n n using (Natural.eq.EqN.eq, Natural.eq.EqN.unfold, Core.prop.⊤.unfold)
eqNRefl = λn. ℕ-elim ⋆ (k ih. ih) n
eqNSound : {n m : ℕ} → EqN n m → n ≡ m
using (Natural.eq.EqN.eq, Natural.eq.EqN.unfold, Core.prop.propext, Core.prop.⊥.unfold)
eqNSound =
λn. ℕ-elim
λm. ℕ-elim (constP ⋆) (j ih2. λh. reflectSquash (squash-elim h (x. 𝟘-elim x))) m
n ih. λm. ℕ-elim (λh. reflectSquash (squash-elim h (x. 𝟘-elim x))) (j ih2. λh. ih j h) m
n
zNotS : {j : ℕ} → (Z ≡ S j) → 𝟘 using (Core.prop.isZeroCode.unfold)
zNotS = λj h. transport isZeroCode h ()
pred : ℕ → ℕ
pred = λn. ℕ-elim Z (n ih. n) n
predEq : {n j : ℕ} → (S n ≡ S j) → n ≡ j
predEq = λn j h. cong (λ_. ℕ) pred h
eqNComplete : {n m : ℕ} → (n ≡ m) → EqN n m
using (Natural.eq.EqN.eq, Natural.eq.EqN.unfold, Core.prop.⊤.unfold)
eqNComplete =
λn. ℕ-elim
λm. ℕ-elim (λh. ⋆) (j ih2. λh. 𝟘-elim (zNotS h)) m
n ih. λm. ℕ-elim (λh. 𝟘-elim (zNotS (sym _ _ h))) (j ih2. λh. ih j (predEq {j} {n} h)) m
n
eqNSoundP : {n m : ℕ} → EqN n m → n ≡ m
eqNSoundP = λn m h. ⋆ (eqNSound h)
eqNCompleteP : {n m : ℕ} → (n ≡ m) → EqN n m using (Natural.eq.EqN.unfold)
eqNCompleteP = λn m h. eqNComplete h
eqNIff : (n m : ℕ) → EqN n m ↔ (n ≡ m) using (Core.prop.↔.unfold, Core.prop.∧.unfold)
eqNIff = λn m. iffIntro eqNSoundP eqNCompleteP