module A201607.BasicT.Syntax.GentzenNormalForm where
open import A201607.BasicT.Syntax.Gentzen public
mutual
infix 3 _⊢ⁿᶠ_
data _⊢ⁿᶠ_ (Γ : Cx Ty) : Ty → Set where
neⁿᶠ : ∀ {A} → Γ ⊢ⁿᵉ A → Γ ⊢ⁿᶠ A
lamⁿᶠ : ∀ {A B} → Γ , A ⊢ⁿᶠ B → Γ ⊢ⁿᶠ A ▻ B
pairⁿᶠ : ∀ {A B} → Γ ⊢ⁿᶠ A → Γ ⊢ⁿᶠ B → Γ ⊢ⁿᶠ A ∧ B
unitⁿᶠ : Γ ⊢ⁿᶠ ⊤
trueⁿᶠ : Γ ⊢ⁿᶠ BOOL
falseⁿᶠ : Γ ⊢ⁿᶠ BOOL
zeroⁿᶠ : Γ ⊢ⁿᶠ NAT
sucⁿᶠ : Γ ⊢ⁿᶠ NAT → Γ ⊢ⁿᶠ NAT
infix 3 _⊢ⁿᵉ_
data _⊢ⁿᵉ_ (Γ : Cx Ty) : Ty → Set where
varⁿᵉ : ∀ {A} → A ∈ Γ → Γ ⊢ⁿᵉ A
appⁿᵉ : ∀ {A B} → Γ ⊢ⁿᵉ A ▻ B → Γ ⊢ⁿᶠ A → Γ ⊢ⁿᵉ B
fstⁿᵉ : ∀ {A B} → Γ ⊢ⁿᵉ A ∧ B → Γ ⊢ⁿᵉ A
sndⁿᵉ : ∀ {A B} → Γ ⊢ⁿᵉ A ∧ B → Γ ⊢ⁿᵉ B
ifⁿᵉ : ∀ {C} → Γ ⊢ⁿᵉ BOOL → Γ ⊢ⁿᶠ C → Γ ⊢ⁿᶠ C → Γ ⊢ⁿᵉ C
itⁿᵉ : ∀ {C} → Γ ⊢ⁿᵉ NAT → Γ ⊢ⁿᶠ C ▻ C → Γ ⊢ⁿᶠ C → Γ ⊢ⁿᵉ C
recⁿᵉ : ∀ {C} → Γ ⊢ⁿᵉ NAT → Γ ⊢ⁿᶠ NAT ▻ C ▻ C → Γ ⊢ⁿᶠ C → Γ ⊢ⁿᵉ C
infix 3 _⊢⋆ⁿᶠ_
_⊢⋆ⁿᶠ_ : Cx Ty → Cx Ty → Set
Γ ⊢⋆ⁿᶠ ∅ = 𝟙
Γ ⊢⋆ⁿᶠ Ξ , A = Γ ⊢⋆ⁿᶠ Ξ × Γ ⊢ⁿᶠ A
infix 3 _⊢⋆ⁿᵉ_
_⊢⋆ⁿᵉ_ : Cx Ty → Cx Ty → Set
Γ ⊢⋆ⁿᵉ ∅ = 𝟙
Γ ⊢⋆ⁿᵉ Ξ , A = Γ ⊢⋆ⁿᵉ Ξ × Γ ⊢ⁿᵉ A
mutual
nf→tm : ∀ {A Γ} → Γ ⊢ⁿᶠ A → Γ ⊢ A
nf→tm (neⁿᶠ t) = ne→tm t
nf→tm (lamⁿᶠ t) = lam (nf→tm t)
nf→tm (pairⁿᶠ t u) = pair (nf→tm t) (nf→tm u)
nf→tm unitⁿᶠ = unit
nf→tm trueⁿᶠ = true
nf→tm falseⁿᶠ = true
nf→tm zeroⁿᶠ = zero
nf→tm (sucⁿᶠ t) = suc (nf→tm t)
ne→tm : ∀ {A Γ} → Γ ⊢ⁿᵉ A → Γ ⊢ A
ne→tm (varⁿᵉ i) = var i
ne→tm (appⁿᵉ t u) = app (ne→tm t) (nf→tm u)
ne→tm (fstⁿᵉ t) = fst (ne→tm t)
ne→tm (sndⁿᵉ t) = snd (ne→tm t)
ne→tm (ifⁿᵉ t u v) = if (ne→tm t) (nf→tm u) (nf→tm v)
ne→tm (itⁿᵉ t u v) = it (ne→tm t) (nf→tm u) (nf→tm v)
ne→tm (recⁿᵉ t u v) = rec (ne→tm t) (nf→tm u) (nf→tm v)
nf→tm⋆ : ∀ {Ξ Γ} → Γ ⊢⋆ⁿᶠ Ξ → Γ ⊢⋆ Ξ
nf→tm⋆ {∅} ∙ = ∙
nf→tm⋆ {Ξ , A} (ts , t) = nf→tm⋆ ts , nf→tm t
ne→tm⋆ : ∀ {Ξ Γ} → Γ ⊢⋆ⁿᵉ Ξ → Γ ⊢⋆ Ξ
ne→tm⋆ {∅} ∙ = ∙
ne→tm⋆ {Ξ , A} (ts , t) = ne→tm⋆ ts , ne→tm t
mutual
mono⊢ⁿᶠ : ∀ {A Γ Γ′} → Γ ⊆ Γ′ → Γ ⊢ⁿᶠ A → Γ′ ⊢ⁿᶠ A
mono⊢ⁿᶠ η (neⁿᶠ t) = neⁿᶠ (mono⊢ⁿᵉ η t)
mono⊢ⁿᶠ η (lamⁿᶠ t) = lamⁿᶠ (mono⊢ⁿᶠ (keep η) t)
mono⊢ⁿᶠ η (pairⁿᶠ t u) = pairⁿᶠ (mono⊢ⁿᶠ η t) (mono⊢ⁿᶠ η u)
mono⊢ⁿᶠ η unitⁿᶠ = unitⁿᶠ
mono⊢ⁿᶠ η trueⁿᶠ = trueⁿᶠ
mono⊢ⁿᶠ η falseⁿᶠ = trueⁿᶠ
mono⊢ⁿᶠ η zeroⁿᶠ = zeroⁿᶠ
mono⊢ⁿᶠ η (sucⁿᶠ t) = sucⁿᶠ (mono⊢ⁿᶠ η t)
mono⊢ⁿᵉ : ∀ {A Γ Γ′} → Γ ⊆ Γ′ → Γ ⊢ⁿᵉ A → Γ′ ⊢ⁿᵉ A
mono⊢ⁿᵉ η (varⁿᵉ i) = varⁿᵉ (mono∈ η i)
mono⊢ⁿᵉ η (appⁿᵉ t u) = appⁿᵉ (mono⊢ⁿᵉ η t) (mono⊢ⁿᶠ η u)
mono⊢ⁿᵉ η (fstⁿᵉ t) = fstⁿᵉ (mono⊢ⁿᵉ η t)
mono⊢ⁿᵉ η (sndⁿᵉ t) = sndⁿᵉ (mono⊢ⁿᵉ η t)
mono⊢ⁿᵉ η (ifⁿᵉ t u v) = ifⁿᵉ (mono⊢ⁿᵉ η t) (mono⊢ⁿᶠ η u) (mono⊢ⁿᶠ η v)
mono⊢ⁿᵉ η (itⁿᵉ t u v) = itⁿᵉ (mono⊢ⁿᵉ η t) (mono⊢ⁿᶠ η u) (mono⊢ⁿᶠ η v)
mono⊢ⁿᵉ η (recⁿᵉ t u v) = recⁿᵉ (mono⊢ⁿᵉ η t) (mono⊢ⁿᶠ η u) (mono⊢ⁿᶠ η v)
mono⊢⋆ⁿᶠ : ∀ {Ξ Γ Γ′} → Γ ⊆ Γ′ → Γ ⊢⋆ⁿᶠ Ξ → Γ′ ⊢⋆ⁿᶠ Ξ
mono⊢⋆ⁿᶠ {∅} η ∙ = ∙
mono⊢⋆ⁿᶠ {Ξ , A} η (ts , t) = mono⊢⋆ⁿᶠ η ts , mono⊢ⁿᶠ η t
mono⊢⋆ⁿᵉ : ∀ {Ξ Γ Γ′} → Γ ⊆ Γ′ → Γ ⊢⋆ⁿᵉ Ξ → Γ′ ⊢⋆ⁿᵉ Ξ
mono⊢⋆ⁿᵉ {∅} η ∙ = ∙
mono⊢⋆ⁿᵉ {Ξ , A} η (ts , t) = mono⊢⋆ⁿᵉ η ts , mono⊢ⁿᵉ η t
refl⊢⋆ⁿᵉ : ∀ {Γ} → Γ ⊢⋆ⁿᵉ Γ
refl⊢⋆ⁿᵉ {∅} = ∙
refl⊢⋆ⁿᵉ {Γ , A} = mono⊢⋆ⁿᵉ weak⊆ refl⊢⋆ⁿᵉ , varⁿᵉ top