Core.equality

-- The equality combinators. In an extensional theory each is one
-- โ‹† (or the coerced term itself): reflecting the hypotheses makes
-- the sides โ€” and, for coercion and transport, the types โ€” equal, so
-- what other theories build from J is judgemental here.

refl : {A : ๐•Œ} (a : A) โ†’ a โ‰ก a
refl = ฮปA a. โ‹†

sym : {A : ๐•Œ} (a b : A) โ†’ (a โ‰ก b) โ†’ b โ‰ก a
sym = ฮปA a b h. โ‹†

trans : {A : ๐•Œ} (a b c : A) โ†’ (a โ‰ก b) โ†’ (b โ‰ก c) โ†’ a โ‰ก c
trans = ฮปA a b c ab bc. a โ‰กโŸจ ab โŸฉ b โ‰กโŸจ bc โŸฉ c

-- coercion along a universe equation: the element itself, at the
-- other type (A โ‰ B by reflection)
coe : {A B : ๐•Œ} โ†’ (A โ‰ก B) โ†’ A โ†’ B
coe = ฮปA B h a. a

-- transport along an equation in the base: again the element itself
-- (P a โ‰ P b by congruence over the reflected hypothesis)
transport : {A : ๐•Œ} (P : A โ†’ ๐•Œ) {a b : A} โ†’ (a โ‰ก b) โ†’ P a โ†’ P b
transport = ฮปA P a b h p. p

-- transport at a PROP motive: equality is ฮฉ-valued, so prop-indexed
-- facts move along an equation the same way elements do โ€” the proof
-- itself, at the other instance ((P a) โ‰ (P b) by congruence
-- over the reflected hypothesis)
transportP : {A : ๐•Œ} (P : A โ†’ ฮฉ) {a b : A} โ†’ (a โ‰ก b) โ†’ P a โ†’ P b
transportP = ฮปA P a b h p. p

-- dependent congruence: in an extensional theory it is one โ‹†, since
-- reflecting the hypothesis makes the sides and their types equal
cong : {A : ๐•Œ} (B : A โ†’ ๐•Œ) (f : (v : A) โ†’ B v) {v w : A} โ†’ (v โ‰ก w) โ†’ f v โ‰ก f w
cong = ฮปA B f v w h. โ‹†

appCong : {A : ๐•Œ}
  (B : A โ†’ ๐•Œ)
  {f0 f1 : (x : A) โ†’ B x}
  {a0 a1 : A}
  โ†’ (f0 โ‰ก f1) โ†’ (a0 โ‰ก a1) โ†’ f0 a0 โ‰ก f1 a1 โˆˆ B a1
appCong = ฮปA B f0 f1 a0 a1 f a. f0 a0 โ‰กโŸจ a โŸฉ f0 a1 โ‰กโŸจ cong (ฮป_. B a1) (ฮปg. g a1) f โŸฉ f1 a1

irr : {A : ๐•Œ} {v u : A} (p : v โ‰ก u) โ†’ p โ‰ก (โ‹†)
irr = ฮปA v u p. โ‹†

-- ฮฃ-ฮท and componentwise equality at a DEPENDENT pair. Both are the
-- non-dependent versions (Int/eq.nova's pairEtaG/pairEq2) with the
-- second component's type allowed to mention the first: reflecting h1
-- makes x .ฯ€โ‚ โ‰ y .ฯ€โ‚, which is exactly what h2's type needs. Stated
-- type-generically, as every shape-generic lemma must be (B-3).
paireta : {A : ๐•Œ} {B : A โ†’ ๐•Œ} (p : (a : A) ร— B a) โ†’ (p .ฯ€โ‚, p .ฯ€โ‚‚) โ‰ก p using (sigma.eta)
paireta = ฮปA B p. โ‹†

pairext : {A : ๐•Œ} {B : A โ†’ ๐•Œ} {x y : (a : A) ร— B a} โ†’ (x .ฯ€โ‚ โ‰ก y .ฯ€โ‚) โ†’ (x .ฯ€โ‚‚ โ‰ก y .ฯ€โ‚‚) โ†’ x โ‰ก y
  using (sigma.eta, hyp.rw)
pairext = ฮปA B x y h1 h2. trans _ _ _ (trans _ _ (y .ฯ€โ‚, y .ฯ€โ‚‚) (sym _ _ (paireta x)) โ‹†) (paireta y)