{-
This second-order equational theory was created from the following second-order syntax description:

syntax TLC | Ξ›

type
  N   : 0-ary
  _↣_ : 2-ary | r30
  πŸ™   : 0-ary
  _βŠ—_ : 2-ary | l40
  𝟘   : 0-ary
  _βŠ•_ : 2-ary | l30

term
  app   : Ξ± ↣ Ξ²  Ξ±  ->  Ξ² | _$_ l20
  lam   : Ξ±.Ξ²  ->  Ξ± ↣ Ξ² | Ζ›_ r10
  unit  : πŸ™
  pair  : Ξ±  Ξ²  ->  Ξ± βŠ— Ξ² | ⟨_,_⟩
  fst   : Ξ± βŠ— Ξ²  ->  Ξ±
  snd   : Ξ± βŠ— Ξ²  ->  Ξ²
  abort : 𝟘  ->  α
  inl   : Ξ±  ->  Ξ± βŠ• Ξ²
  inr   : Ξ²  ->  Ξ± βŠ• Ξ²
  case  : Ξ± βŠ• Ξ²  Ξ±.Ξ³  Ξ².Ξ³  ->  Ξ³
  ze    : N
  su    : N  ->  N
  nrec  : N  Ξ±  (Ξ±,N).Ξ±  ->  Ξ±

theory
  (Ζ›Ξ²) b : Ξ±.Ξ²  a : Ξ± |> app (lam(x.b[x]), a) = b[a]
  (Ζ›Ξ·) f : Ξ± ↣ Ξ²      |> lam (x. app(f, x))   = f
  (πŸ™Ξ·) u : πŸ™ |> u = unit
  (fΞ²) a : Ξ±  b : Ξ² |> fst (pair(a, b))      = a
  (sΞ²) a : Ξ±  b : Ξ² |> snd (pair(a, b))      = b
  (pΞ·) p : Ξ± βŠ— Ξ²    |> pair (fst(p), snd(p)) = p
  (𝟘η) e : 𝟘  c : α |> abort(e) = c
  (lΞ²) a : Ξ±   f : Ξ±.Ξ³  g : Ξ².Ξ³ |> case (inl(a), x.f[x], y.g[y])      = f[a]
  (rΞ²) b : Ξ²   f : Ξ±.Ξ³  g : Ξ².Ξ³ |> case (inr(b), x.f[x], y.g[y])      = g[b]
  (cΞ·) s : Ξ± βŠ• Ξ²  c : (Ξ± βŠ• Ξ²).Ξ³ |> case (s, x.c[inl(x)], y.c[inr(y)]) = c[s]
  (zeΞ²) z : Ξ±   s : (Ξ±,N).Ξ±        |> nrec (ze,       z, r m. s[r,m]) = z
  (suΞ²) z : Ξ±   s : (Ξ±,N).Ξ±  n : N |> nrec (su (n), z, r m. s[r,m]) = s[nrec (n, z, r m. s[r,m]), n]
  (ift) t f : Ξ± |> if (true,  t, f) = t
  (iff) t f : Ξ± |> if (false, t, f) = f
-}

module TLC.Equality where

open import SOAS.Common
open import SOAS.Context
open import SOAS.Variable
open import SOAS.Families.Core
open import SOAS.Families.Build
open import SOAS.ContextMaps.Inductive

open import TLC.Signature
open import TLC.Syntax

open import SOAS.Metatheory.SecondOrder.Metasubstitution Ξ›:Syn
open import SOAS.Metatheory.SecondOrder.Equality Ξ›:Syn

private
  variable
    Ξ± Ξ² Ξ³ Ο„ : Ξ›T
    Ξ“ Ξ” Ξ  : Ctx

infix 1 _β–Ή_⊒_≋ₐ_

-- Axioms of equality
data _β–Ή_⊒_≋ₐ_ : βˆ€ 𝔐 Ξ“ {Ξ±} β†’ (𝔐 β–· Ξ›) Ξ± Ξ“ β†’ (𝔐 β–· Ξ›) Ξ± Ξ“ β†’ Set where
  Ζ›Ξ²  : ⁅ Ξ± ⊩ Ξ² ⁆ ⁅ Ξ± ⁆̣           β–Ή βˆ… ⊒                    (Ζ› π”žβŸ¨ xβ‚€ ⟩) $ π”Ÿ ≋ₐ π”žβŸ¨ π”Ÿ ⟩
  Ζ›Ξ·  : ⁅ Ξ± ↣ Ξ² ⁆̣                 β–Ή βˆ… ⊒                         Ζ› (π”ž $ xβ‚€) ≋ₐ π”ž
  πŸ™Ξ·  : ⁅ πŸ™ ⁆̣                     β–Ή βˆ… ⊒                                  π”ž ≋ₐ unit
  fΞ²  : ⁅ Ξ± ⁆ ⁅ Ξ² ⁆̣               β–Ή βˆ… ⊒                    fst (⟨ π”ž , π”Ÿ ⟩) ≋ₐ π”ž
  sΞ²  : ⁅ Ξ± ⁆ ⁅ Ξ² ⁆̣               β–Ή βˆ… ⊒                    snd (⟨ π”ž , π”Ÿ ⟩) ≋ₐ π”Ÿ
  pΞ·  : ⁅ Ξ± βŠ— Ξ² ⁆̣                 β–Ή βˆ… ⊒              ⟨ (fst π”ž) , (snd π”ž) ⟩ ≋ₐ π”ž
  𝟘η  : ⁅ 𝟘 ⁆ ⁅ Ξ± ⁆̣               β–Ή βˆ… ⊒                            abort π”ž ≋ₐ π”Ÿ
  lΞ²  : ⁅ Ξ± ⁆ ⁅ Ξ± ⊩ Ξ³ ⁆ ⁅ Ξ² ⊩ Ξ³ ⁆̣ β–Ή βˆ… ⊒   case (inl π”ž) (π”ŸβŸ¨ xβ‚€ ⟩) (π” βŸ¨ xβ‚€ ⟩) ≋ₐ π”ŸβŸ¨ π”ž ⟩
  rΞ²  : ⁅ Ξ² ⁆ ⁅ Ξ± ⊩ Ξ³ ⁆ ⁅ Ξ² ⊩ Ξ³ ⁆̣ β–Ή βˆ… ⊒   case (inr π”ž) (π”ŸβŸ¨ xβ‚€ ⟩) (π” βŸ¨ xβ‚€ ⟩) ≋ₐ π” βŸ¨ π”ž ⟩
  cΞ·  : ⁅ Ξ± βŠ• Ξ² ⁆ ⁅ (Ξ± βŠ• Ξ²) ⊩ Ξ³ ⁆̣ β–Ή βˆ… ⊒ case π”ž (π”ŸβŸ¨ inl xβ‚€ ⟩) (π”ŸβŸ¨ inr xβ‚€ ⟩) ≋ₐ π”ŸβŸ¨ π”ž ⟩
  zeΞ² : ⁅ Ξ± ⁆ ⁅ Ξ± Β· N ⊩ Ξ± ⁆̣       β–Ή βˆ… ⊒           nrec ze π”ž (π”ŸβŸ¨ xβ‚€ β—‚ x₁ ⟩) ≋ₐ π”ž
  suΞ² : ⁅ Ξ± ⁆ ⁅ Ξ± Β· N ⊩ Ξ± ⁆ ⁅ N ⁆̣ β–Ή βˆ… ⊒       nrec (su 𝔠) π”ž (π”ŸβŸ¨ xβ‚€ β—‚ x₁ ⟩) ≋ₐ π”ŸβŸ¨ (nrec 𝔠 π”ž (π”ŸβŸ¨ xβ‚€ β—‚ x₁ ⟩)) β—‚ 𝔠 ⟩

open EqLogic _β–Ή_⊒_≋ₐ_
open ≋-Reasoning

-- Derived equations
ift : ⁅ Ξ± ⁆ ⁅ Ξ± ⁆̣ β–Ή βˆ… ⊒ if true π”ž π”Ÿ ≋ π”ž
ift = ax lΞ² withγ€Š unit β—ƒ π”ž β—ƒ π”Ÿ 》
iff : ⁅ Ξ± ⁆ ⁅ Ξ± ⁆̣ β–Ή βˆ… ⊒ if false π”ž π”Ÿ ≋ π”Ÿ
iff = ax rΞ² withγ€Š unit β—ƒ π”ž β—ƒ π”Ÿ 》

-- Double beta reduction
Ζ›Ξ²Β² : ⁅ Ξ² Β· Ξ± ⊩ Ξ³ ⁆ ⁅ Ξ± ⁆ ⁅ Ξ² ⁆̣ β–Ή βˆ… ⊒ (Ζ› (Ζ› π”žβŸ¨ xβ‚€ β—‚ x₁ ⟩)) $ π”Ÿ $ 𝔠 ≋ π”žβŸ¨ 𝔠 β—‚ π”Ÿ ⟩
Ζ›Ξ²Β² = begin
      (Ζ› (Ζ› π”žβŸ¨ xβ‚€ β—‚ x₁ ⟩)) $ π”Ÿ $ 𝔠
  β‰‹βŸ¨ cong[ ax Ζ›Ξ² withγ€Š (Ζ› π”žβŸ¨ xβ‚€ β—‚ x₁ ⟩) β—ƒ π”Ÿ 》 ]inside β—Œα΅ˆ $ 𝔠 ⟩
      (Ζ› π”žβŸ¨ xβ‚€ β—‚ π”Ÿ ⟩) $ 𝔠
  β‰‹βŸ¨ ax Ζ›Ξ² withγ€Š (π”žβŸ¨ xβ‚€ β—‚ π”Ÿ ⟩) β—ƒ 𝔠 》 ⟩
      π”žβŸ¨ 𝔠 β—‚ π”Ÿ ⟩
  ∎

-- Uncurrying and arithmetic
1+2 : ⁅⁆ β–Ή βˆ… ⊒ uncurry $ plus $ ⟨ su ze , su (su ze) ⟩ ≋ su (su (su ze))
1+2 = begin
      uncurry $ plus $ ⟨ su ze , su (su ze) ⟩
  β‰‹βŸ¨ thm Ζ›Ξ²Β² withγ€Š x₁ $ fst xβ‚€ $ snd xβ‚€ β—ƒ plus β—ƒ ⟨ su ze , su (su ze) ⟩ 》 ⟩
      plus $ fst ⟨ su ze , su (su ze) ⟩ $ snd ⟨ su ze , su (su ze) ⟩
  β‰‹βŸ¨ congβ‚‚[ ax fΞ² withγ€Š su ze β—ƒ su (su ze) 》 ][
            ax sΞ² withγ€Š su ze β—ƒ su (su ze) 》 ]inside plus $ β—Œα΅ƒ $ β—Œα΅‡ ⟩
      plus $ su ze $  su (su ze)
  β‰‹βŸ¨ thm Ζ›Ξ²Β² withγ€Š nrec x₁ xβ‚€ (su xβ‚€) β—ƒ su ze β—ƒ su (su ze) 》 ⟩
      nrec (su ze) (su (su ze)) (su xβ‚€)
  β‰‹βŸ¨ ax suΞ² withγ€Š su (su ze) β—ƒ su xβ‚€ β—ƒ ze 》 ⟩
      su (nrec ze (su (su ze)) (su xβ‚€))
  β‰‹βŸ¨ cong[ ax zeΞ² withγ€Š su (su ze) β—ƒ su xβ‚€ 》 ]inside su β—Œα΅ƒ ⟩
      su (su (su ze))
  ∎