-- The identity FAMILY: structural equality as a small QIIT
-- (docs/NovaFoundation.txt, Ω block — the prf-code construction).
-- Equality the PROPOSITION lives at Ω and carries no data; Id is its
-- structural counterpart IN 𝕌: a code, storable inside small types,
-- usable as an eliminator motive, indexwise-injective through the
-- qidx selector. The two are logically equivalent (the bridge lemmas
-- below), and that iff is all a proposition can soundly give.
import prop (↔, iffIntro)
data [a : 𝕌] ( Id : El a → El a → U
; refl : (x : El a) → El (Id x x) )
-- reflection, by prop-motive induction (J into a proposition): the
-- refl method's equation is evident, and ElimP asks no coherences
def idToEq : (a : 𝕌) (x : El a) (y : El a) → El (Id x y) → x ≡ y ∈ ≔
λa. λx. λy. λp. IdElimP (λu. λv. λw. (u ≡ v ∈ )) (λu. ⋆) p
-- introduction: with x ≐ y reflected from the hypothesis, refl a x
-- already inhabits Id a x y (index congruence)
def eqToId : (a : 𝕌) (x : El a) (y : El a) → (x ≡ y ∈ El a) → El (Id x y) ≔
λa. λx. λy. λh. refl x
-- the bridge, packaged: Id and ≡ are the same proposition up to iff
def idIffEq : (a : 𝕌) (x : El a) (y : El a) →
Prf (∥ El (Id x y) ∥ ↔ (x ≡ y ∈ )) ≔
λa. λx. λy. iffIntro ∥ El (Id x y) ∥ (x ≡ y ∈ )
(λh. squash-elim h (p. idToEq p))
(λh. ⋆ (eqToId h))
-- round trips compute: β at refl on one side, index congruence on the
-- other
def idToEqBeta : (a : 𝕌) (x : El a) →
idToEq (refl x) ≡ ⋆ ∈ Prf (x ≡ x ∈ ) ≔
λa. λx. ⋆
def eqToIdBeta : (a : 𝕌) (x : El a) →
eqToId x x ⋆ ≡ refl x ∈ El (Id x x) ≔
λa. λx. ⋆
-- equality as DATA in a small type — what the Ω-valued ≡ cannot do
-- (no 𝕌-code) and Id restores: a subset code by an equation
def OnlyZ : 𝕌 ≔ (n : ℕ) ⨯ Id n Z
def onlyZ : El OnlyZ ≔ Z , refl Z
def onlyZIsZ : (v : El OnlyZ) → v .π₁ ≡ Z ∈ ≔
λv. idToEq (v .π₂)