module Implicit.Language.EnvOps.Replace where
open import Implicit.Language.Base
open import Implicit.Language.Shift.All
open import Implicit.Language.Lookup.All
open import Implicit.Language.EnvOps.Base
open import Implicit.Language.Regular.Base
open import Implicit.Language.OpenClose.Base
infix 3 _◆_⇘_
data _◆_⇘_ : Env n m → Fin m → Env n m → Set where
◆Z : Γ ,= A ◆ #0 ⇘ Γ ,∙
◆S, : Γ ◆ k ⇘ Γ'
→ Γ , A ◆ k ⇘ Γ' , A
◆S∙ : Γ ◆ k ⇘ Γ'
→ Γ ,∙ ◆ #S k ⇘ Γ' ,∙
◆S= : Γ ◆ k ⇘ Γ'
→ Γ ,= A ◆ #S k ⇘ Γ' ,= A
◆S^ : Γ ◆ k ⇘ Γ'
→ Γ ,^ ◆ #S k ⇘ Γ' ,^
◆-unique : Γ ◆ k ⇘ Γ₁
→ Γ ◆ k ⇘ Γ₂
→ Γ₁ ≡ Γ₂
◆-unique ◆Z ◆Z = refl
◆-unique (◆S, new1) (◆S, new2) rewrite ◆-unique new1 new2 = refl
◆-unique (◆S∙ new1) (◆S∙ new2) rewrite ◆-unique new1 new2 = refl
◆-unique (◆S= new1) (◆S= new2) rewrite ◆-unique new1 new2 = refl
◆-unique (◆S^ new1) (◆S^ new2) rewrite ◆-unique new1 new2 = refl
◆-total : Γ ∋= k
→ ∃[ Γ' ](Γ ◆ k ⇘ Γ')
◆-total {Γ = Γ ,= _} Z = ⟨ Γ ,∙ , ◆Z ⟩
◆-total (S∙ inΓ) = ⟨ (◆-total inΓ .proj₁ ,∙) , ◆S∙ (◆-total inΓ .proj₂) ⟩
◆-total (S^ inΓ) = ⟨ ◆-total inΓ .proj₁ ,^ , ◆S^ (◆-total inΓ .proj₂) ⟩
◆-total (S= {B = B} inΓ) = ⟨ (◆-total inΓ .proj₁ ,= B) , ◆S= (◆-total inΓ .proj₂) ⟩
◆-total {Γ = Γ , A} (S, inΓ) = ⟨ ((◆-total inΓ .proj₁) , A) , ◆S, (◆-total inΓ .proj₂) ⟩
◇-total : Γ ∋^ k
→ ∃[ Γ' ](Γ ◇ k ⇘ Γ')
◇-total {Γ = Γ ,^ } Z = ⟨ Γ ,∙ , ◇Z ⟩
◇-total (S, {A = A} inΓ) = ⟨ (◇-total inΓ .proj₁ , A) , ◇S, (◇-total inΓ .proj₂) ⟩
◇-total (S∙ inΓ) = ⟨ ◇-total inΓ .proj₁ ,∙ , ◇S∙ (◇-total inΓ .proj₂) ⟩
◇-total (S= {B = B} inΓ) = ⟨ ◇-total inΓ .proj₁ ,= B , ◇S= (◇-total inΓ .proj₂) ⟩
◇-total (S^ inΓ) = ⟨ ◇-total inΓ .proj₁ ,^ , ◇S^ (◇-total inΓ .proj₂) ⟩
◇-unique : Γ ◇ k ⇘ Γ₁
→ Γ ◇ k ⇘ Γ₂
→ Γ₁ ≡ Γ₂
◇-unique ◇Z ◇Z = refl
◇-unique (◇S, in1) (◇S, in2) rewrite ◇-unique in1 in2 = refl
◇-unique (◇S∙ in1) (◇S∙ in2) rewrite ◇-unique in1 in2 = refl
◇-unique (◇S= in1) (◇S= in2) rewrite ◇-unique in1 in2 = refl
◇-unique (◇S^ in1) (◇S^ in2) rewrite ◇-unique in1 in2 = refl
◆-∙∈ : Γ ∋∙ X
→ Γ ◆ k ⇘ Γ'
→ Γ' ∋∙ X
◆-∙∈ (S= inΓ) ◆Z = S∙ inΓ
◆-∙∈ (S, inΓ) (◆S, ◆Γ) = S, (◆-∙∈ inΓ ◆Γ)
◆-∙∈ Z (◆S∙ ◆Γ) = Z
◆-∙∈ (S∙ inΓ) (◆S∙ ◆Γ) = S∙ (◆-∙∈ inΓ ◆Γ)
◆-∙∈ (S= inΓ) (◆S= ◆Γ) = S= (◆-∙∈ inΓ ◆Γ)
◆-∙∈ (S^ inΓ) (◆S^ ◆Γ) = S^ (◆-∙∈ inΓ ◆Γ)
◇-∙∈ : Γ ∋∙ X
→ Γ ◇ k ⇘ Γ'
→ Γ' ∋∙ X
◇-∙∈ Z (◇S∙ newΓ) = Z
◇-∙∈ (S, inΓ) (◇S, newΓ) = S, (◇-∙∈ inΓ newΓ)
◇-∙∈ (S∙ inΓ) (◇S∙ newΓ) = S∙ (◇-∙∈ inΓ newΓ)
◇-∙∈ (S= inΓ) (◇S= newΓ) = S= (◇-∙∈ inΓ newΓ)
◇-∙∈ (S^ inΓ) ◇Z = S∙ inΓ
◇-∙∈ (S^ inΓ) (◇S^ newΓ) = S^ (◇-∙∈ inΓ newΓ)
◇-=∈ : Γ ∋= X
→ Γ ◇ k ⇘ Γ'
→ Γ' ∋= X
◇-=∈ Z (◇S= newΓ) = Z
◇-=∈ (S, inΓ) (◇S, newΓ) = S, (◇-=∈ inΓ newΓ)
◇-=∈ (S∙ inΓ) (◇S∙ newΓ) = S∙ (◇-=∈ inΓ newΓ)
◇-=∈ (S= inΓ) (◇S= newΓ) = S= (◇-=∈ inΓ newΓ)
◇-=∈ (S^ inΓ) ◇Z = S∙ inΓ
◇-=∈ (S^ inΓ) (◇S^ newΓ) = S^ (◇-=∈ inΓ newΓ)
◆-=∈-≢ : Γ ∋= X
→ Γ ◆ k ⇘ Γ'
→ k ≢ X
→ Γ' ∋= X
◆-=∈-≢ Z ◆Z neq = ⊥-elim (neq refl)
◆-=∈-≢ Z (◆S= ◆Γ) neq = Z
◆-=∈-≢ (S, inΓ) (◆S, ◆Γ) neq = S, (◆-=∈-≢ inΓ ◆Γ neq)
◆-=∈-≢ (S^ inΓ) (◆S^ ◆Γ) neq = S^ (◆-=∈-≢ inΓ ◆Γ (≢-pred neq))
◆-=∈-≢ (S∙ inΓ) (◆S∙ ◆Γ) neq = S∙ (◆-=∈-≢ inΓ ◆Γ (≢-pred neq))
◆-=∈-≢ (S= inΓ) ◆Z neq = S∙ inΓ
◆-=∈-≢ (S= inΓ) (◆S= ◆Γ) neq = S= (◆-=∈-≢ inΓ ◆Γ (≢-pred neq))
◆-=∈-≡ : Γ ∋= k
→ Γ ◆ k ⇘ Γ'
→ Γ' ∋∙ k
◆-=∈-≡ Z ◆Z = Z
◆-=∈-≡ (S, inΓ) (◆S, ◆Γ) = S, (◆-=∈-≡ inΓ ◆Γ)
◆-=∈-≡ (S^ inΓ) (◆S^ ◆Γ) = S^ (◆-=∈-≡ inΓ ◆Γ)
◆-=∈-≡ (S∙ inΓ) (◆S∙ ◆Γ) = S∙ (◆-=∈-≡ inΓ ◆Γ)
◆-=∈-≡ (S= inΓ) (◆S= ◆Γ) = S= (◆-=∈-≡ inΓ ◆Γ)
env-◆◇-false : Γ ◇ k ⇘ Γ₁
→ Γ ◆ k ⇘ Γ₂
→ ⊥
env-◆◇-false (◇S, newΓ1) (◆S, newΓ2) = env-◆◇-false newΓ1 newΓ2
env-◆◇-false (◇S∙ newΓ1) (◆S∙ newΓ2) = env-◆◇-false newΓ1 newΓ2
env-◆◇-false (◇S= newΓ1) (◆S= newΓ2) = env-◆◇-false newΓ1 newΓ2
env-◆◇-false (◇S^ newΓ1) (◆S^ newΓ2) = env-◆◇-false newΓ1 newΓ2
◇-∋^ : Γ ◇ k ⇘ Γ'
→ Γ ∋^ k
◇-∋^ ◇Z = Z
◇-∋^ (◇S, newΓ) = S, (◇-∋^ newΓ)
◇-∋^ (◇S∙ newΓ) = S∙ (◇-∋^ newΓ)
◇-∋^ (◇S= newΓ) = S= (◇-∋^ newΓ)
◇-∋^ (◇S^ newΓ) = S^ (◇-∋^ newΓ)
◆-∋= : Γ ◆ k ⇘ Γ'
→ Γ ∋= k
◆-∋= ◆Z = Z
◆-∋= (◆S, newΓ) = S, (◆-∋= newΓ)
◆-∋= (◆S∙ newΓ) = S∙ (◆-∋= newΓ)
◆-∋= (◆S= newΓ) = S= (◆-∋= newΓ)
◆-∋= (◆S^ newΓ) = S^ (◆-∋= newΓ)
◈-∋:=-neq : Γ ◈ k ⇘ Γ'
→ Γ ∋ X := A
→ X ≢ k
◈-∋:=-neq ◈Z (S∙ inΓ up) = λ ()
◈-∋:=-neq (◈S, new) (S, inΓ) = ◈-∋:=-neq new inΓ
◈-∋:=-neq (◈S∙ new) (S∙ inΓ up) = ≢-suc (◈-∋:=-neq new inΓ)
◈-∋:=-neq (◈S= new) (Z up) = λ ()
◈-∋:=-neq (◈S= new) (S= inΓ up) = ≢-suc (◈-∋:=-neq new inΓ)
◈-∋:=-neq (◈S^ new) (S^ inΓ up) = ≢-suc (◈-∋:=-neq new inΓ)
∋∙-∋:=-≢ : Γ ∋ X := A
→ Γ ∋∙ k
→ k ≢ X
∋∙-∋:=-≢ in1 in2 refl = ∋∙-∋:=-false in2 in1
⊢r-◆ : Γ ⊢r A
→ Γ ◆ k ⇘ Γ'
→ Γ' ⊢r A
⊢r-◆ ⊢r-int new = ⊢r-int
⊢r-◆ (⊢r-var-∙ inΓ) new = ⊢r-var-∙ (◆-∙∈ inΓ new)
⊢r-◆ (⊢r-arr regA regA₁) new = ⊢r-arr (⊢r-◆ regA new) (⊢r-◆ regA₁ new)
⊢r-◆ (⊢r-∀ regA) new = ⊢r-∀ (⊢r-◆ regA (◆S∙ new))
⊢r-◆0 : Γ ,= T ⊢r A
→ Γ ,∙ ⊢r A
⊢r-◆0 regA = ⊢r-◆ regA ◆Z
⊢c-◆ : Γ ⊢c A
→ Γ ◆ k ⇘ Γ'
→ Γ' ⊢c A
⊢c-◆ ⊢c-int new = ⊢c-int
⊢c-◆ (⊢c-var-∙ inΔ) new = ⊢c-var-∙ (◆-∙∈ inΔ new)
⊢c-◆ {k = k} (⊢c-var-= {X = X} inΔ) new with k #≟ X
... | yes refl = ⊢c-var-∙ (◆-=∈-≡ inΔ new)
... | no ¬p = ⊢c-var-= (◆-=∈-≢ inΔ new ¬p)
⊢c-◆ (⊢c-arr cloA cloA₁) new = ⊢c-arr (⊢c-◆ cloA new) (⊢c-◆ cloA₁ new)
⊢c-◆ (⊢c-∀ cloA) new = ⊢c-∀ (⊢c-◆ cloA (◆S∙ new))
⊢c-◆0 : Γ ,= T ⊢c A
→ Γ ,∙ ⊢c A
⊢c-◆0 cloA = ⊢c-◆ cloA ◆Z
⊢c-◇ : Γ ⊢c A
→ Γ ◇ k ⇘ Γ'
→ Γ' ⊢c A
⊢c-◇ ⊢c-int new = ⊢c-int
⊢c-◇ (⊢c-var-∙ inΔ) new = ⊢c-var-∙ (◇-∙∈ inΔ new)
⊢c-◇ (⊢c-var-= inΔ) new = ⊢c-var-= (◇-=∈ inΔ new)
⊢c-◇ (⊢c-arr cloA cloA₁) new = ⊢c-arr (⊢c-◇ cloA new) (⊢c-◇ cloA₁ new)
⊢c-◇ (⊢c-∀ cloA) new = ⊢c-∀ (⊢c-◇ cloA (◇S∙ new))
⊢c-◇0 : Γ ,^ ⊢c A
→ Γ ,∙ ⊢c A
⊢c-◇0 cloA = ⊢c-◇ cloA ◇Z
◈-∋:=-neq-unique : Γ ◈ k ⇘ Γ'
→ X ≢ k
→ Γ ∋ X := A₁
→ Γ' ∋ X := A₂
→ A₁ ≡ A₂
◈-∋:=-neq-unique ◈Z neq (S∙ in1 up) (S^ in2 up₁)
with refl ← ∋:=-unique in1 in2 = ↑ty-unique up up₁
◈-∋:=-neq-unique (◈S, new) neq (S, in1) (S, in2) = ◈-∋:=-neq-unique new neq in1 in2
◈-∋:=-neq-unique (◈S∙ new) neq (S∙ in1 up) (S∙ in2 up₁)
with refl ← ◈-∋:=-neq-unique new (≢-pred neq) in1 in2 = ↑ty-unique up up₁
◈-∋:=-neq-unique (◈S= new) neq (Z up) (Z up₁) = ↑ty-unique up up₁
◈-∋:=-neq-unique (◈S= new) neq (S= in1 up) (S= in2 up₁)
with refl ← ◈-∋:=-neq-unique new (≢-pred neq) in1 in2 = ↑ty-unique up up₁
◈-∋:=-neq-unique (◈S^ new) neq (S^ in1 up) (S^ in2 up₁)
with refl ← ◈-∋:=-neq-unique new (≢-pred neq) in1 in2 = ↑ty-unique up up₁
◈-neq-∋:= : Γ ∋ X := A
→ Γ ◈ k ⇘ Γ'
→ X ≢ k
→ Γ' ∋ X := A
◈-neq-∋:= (Z up) (◈S= new) neq = Z up
◈-neq-∋:= (S∙ inΓ up) ◈Z neq = S^ inΓ up
◈-neq-∋:= (S∙ inΓ up) (◈S∙ new) neq = S∙ (◈-neq-∋:= inΓ new (≢-pred neq)) up
◈-neq-∋:= (S^ inΓ up) (◈S^ new) neq = S^ (◈-neq-∋:= inΓ new (≢-pred neq)) up
◈-neq-∋:= (S= inΓ up) (◈S= new) neq = S= (◈-neq-∋:= inΓ new (≢-pred neq)) up
◈-neq-∋:= (S, inΓ) (◈S, new) neq = S, (◈-neq-∋:= inΓ new neq)
◈-neq-∋∙ : Γ ∋∙ X
→ Γ ◈ k ⇘ Γ'
→ X ≢ k
→ Γ' ∋∙ X
◈-neq-∋∙ Z ◈Z neq = ⊥-elim (neq refl)
◈-neq-∋∙ Z (◈S∙ new) neq = Z
◈-neq-∋∙ (S, in1) (◈S, new) neq = S, (◈-neq-∋∙ in1 new neq)
◈-neq-∋∙ (S∙ in1) ◈Z neq = S^ in1
◈-neq-∋∙ (S∙ in1) (◈S∙ new) neq = S∙ (◈-neq-∋∙ in1 new (≢-pred neq))
◈-neq-∋∙ (S= in1) (◈S= new) neq = S= (◈-neq-∋∙ in1 new (≢-pred neq))
◈-neq-∋∙ (S^ in1) (◈S^ new) neq = S^ (◈-neq-∋∙ in1 new (≢-pred neq))
infix 3 [_/_]_∙⟹_
data [_/_]_∙⟹_ : Type m → Fin m → Env n m → Env n m → Set where
∙⟹^0 : (up : ↑ty0 A ⇘ A')
→ (regA : Γ ⊢r A)
→ [ A' / #0 ] (Γ ,∙) ∙⟹ (Γ ,= A)
∙⟹^S : [ A / k ] Γ ∙⟹ Γ'
→ (up1 : ↑ty0 A ⇘ A')
→ [ A' / #S k ] (Γ ,^) ∙⟹ Γ' ,^
∙⟹∙S : [ A / k ] Γ ∙⟹ Γ'
→ (up1 : ↑ty0 A ⇘ A')
→ [ A' / #S k ] (Γ ,∙) ∙⟹ (Γ' ,∙)
∙⟹,S : [ A / k ] Γ ∙⟹ Γ'
→ [ A / k ] (Γ , B) ∙⟹ (Γ' , B)
∙⟹=S : [ A / k ] Γ ∙⟹ Γ'
→ (up1 : ↑ty0 A ⇘ A')
→ [ A' / #S k ] (Γ ,= B) ∙⟹ (Γ' ,= B)
∙⟹-∋∙ : Γ ∋∙ X
→ X ≢ k
→ [ T / k ] Γ ∙⟹ Γ'
→ Γ' ∋∙ X
∙⟹-∋∙ Z neq (∙⟹^0 up regA) = ⊥-elim (neq refl)
∙⟹-∋∙ Z neq (∙⟹∙S new up1) = Z
∙⟹-∋∙ (S, inΓ) neq (∙⟹,S new) = S, (∙⟹-∋∙ inΓ neq new)
∙⟹-∋∙ (S∙ inΓ) neq (∙⟹^0 up regA) = S= inΓ
∙⟹-∋∙ (S∙ inΓ) neq (∙⟹∙S new up1) = S∙ (∙⟹-∋∙ inΓ (≢-pred neq) new)
∙⟹-∋∙ (S= inΓ) neq (∙⟹=S new up1) = S= (∙⟹-∋∙ inΓ (≢-pred neq) new)
∙⟹-∋∙ (S^ inΓ) neq (∙⟹^S new up1) = S^ (∙⟹-∋∙ inΓ (≢-pred neq) new)
∙⟹-⊢r : Γ ⊢r A
→ [ T / k ] Γ ∙⟹ Γ'
→ k ¬ε A
→ Γ' ⊢r A
∙⟹-⊢r ⊢r-int new ¬ε-int = ⊢r-int
∙⟹-⊢r (⊢r-var-∙ inΓ) new (¬ε-var x) = ⊢r-var-∙ (∙⟹-∋∙ inΓ x new)
∙⟹-⊢r (⊢r-arr regA regA₁) new (¬ε-arr ninA ninA₁) = ⊢r-arr (∙⟹-⊢r regA new ninA) (∙⟹-⊢r regA₁ new ninA₁)
∙⟹-⊢r {T = T} (⊢r-∀ regA) new (¬ε-∀ ninA)
with ⟨ T' , upT ⟩ ← ↑ty0-total T = ⊢r-∀ (∙⟹-⊢r regA (∙⟹∙S new upT) ninA)
∙⟹-∋:=-prv : Γ ∋ X := A
→ [ T / k ] Γ ∙⟹ Γ'
→ Γ' ∋ X := A
∙⟹-∋:=-prv (Z up) (∙⟹=S new up1) = Z up
∙⟹-∋:=-prv (S∙ inΓ up) (∙⟹^0 up₁ regA) = S= inΓ up
∙⟹-∋:=-prv (S∙ inΓ up) (∙⟹∙S new up1) = S∙ (∙⟹-∋:=-prv inΓ new) up
∙⟹-∋:=-prv (S^ inΓ up) (∙⟹^S new up1) = S^ (∙⟹-∋:=-prv inΓ new) up
∙⟹-∋:=-prv (S= inΓ up) (∙⟹=S new up1) = S= (∙⟹-∋:=-prv inΓ new) up
∙⟹-∋:=-prv (S, inΓ) (∙⟹,S new) = S, (∙⟹-∋:=-prv inΓ new)
∙⟹-∋:= : [ T / k ] Γ ∙⟹ Γ'
→ Γ' ∋ k := T
∙⟹-∋:= (∙⟹^0 up regA) = Z up
∙⟹-∋:= (∙⟹^S new up1) = S^ (∙⟹-∋:= new) up1
∙⟹-∋:= (∙⟹∙S new up1) = S∙ (∙⟹-∋:= new) up1
∙⟹-∋:= (∙⟹,S new) = S, (∙⟹-∋:= new)
∙⟹-∋:= (∙⟹=S new up1) = S= (∙⟹-∋:= new) up1
∙⟹-∋∙-neq : Γ ∋∙ X
→ [ T' / k ] Γ ∙⟹ Γ'
→ Γ' ∋∙ X
→ k ≢ X
∙⟹-∋∙-neq Z (∙⟹∙S new up1) Z = λ ()
∙⟹-∋∙-neq (S, inΓ) (∙⟹,S new) (S, inΓ') = ∙⟹-∋∙-neq inΓ new inΓ'
∙⟹-∋∙-neq (S∙ inΓ) (∙⟹^0 up regA) (S= inΓ') = λ ()
∙⟹-∋∙-neq (S∙ inΓ) (∙⟹∙S new up1) (S∙ inΓ') = ≢-suc (∙⟹-∋∙-neq inΓ new inΓ')
∙⟹-∋∙-neq (S= inΓ) (∙⟹=S new up1) (S= inΓ') = ≢-suc (∙⟹-∋∙-neq inΓ new inΓ')
∙⟹-∋∙-neq (S^ inΓ) (∙⟹^S new up1) (S^ inΓ') = ≢-suc (∙⟹-∋∙-neq inΓ new inΓ')
∙⟹-:=-eq : Γ ∋ X := A₁
→ [ B / k ] Γ ∙⟹ Γ'
→ Γ' ∋ X := A₂
→ A₁ ≡ A₂
∙⟹-:=-eq (Z up) (∙⟹=S newΓ up1) (Z up₁) = ↑ty-unique up up₁
∙⟹-:=-eq (S, in1) (∙⟹,S newΓ) (S, in2) = ∙⟹-:=-eq in1 newΓ in2
∙⟹-:=-eq (S∙ in1 up) (∙⟹^0 reg up₁) (S= in2 up₂) with ∋:=-unique in1 in2
... | refl = ↑ty-unique up up₂
∙⟹-:=-eq (S∙ in1 up) (∙⟹∙S newΓ up1) (S∙ in2 up₁) with ∙⟹-:=-eq in1 newΓ in2
... | refl = ↑ty-unique up up₁
∙⟹-:=-eq (S^ in1 up) (∙⟹^S newΓ up1) (S^ in2 up₁) with ∙⟹-:=-eq in1 newΓ in2
... | refl = ↑ty-unique up up₁
∙⟹-:=-eq (S= in1 up) (∙⟹=S newΓ up1) (S= in2 up₁) with ∙⟹-:=-eq in1 newΓ in2
... | refl = ↑ty-unique up up₁
∙⟹-:=-∙-false : Γ ∋ X := A
→ [ B / k ] Γ ∙⟹ Γ'
→ Γ' ∋∙ X
→ ⊥
∙⟹-:=-∙-false (Z up) (∙⟹=S newΓ' up1) ()
∙⟹-:=-∙-false (S, inΓ) (∙⟹,S newΓ') (S, inΓ') = ∙⟹-:=-∙-false inΓ newΓ' inΓ'
∙⟹-:=-∙-false (S∙ inΓ up) (∙⟹^0 reg up₁) (S= inΓ') = ∋∙-∋:=-false inΓ' inΓ
∙⟹-:=-∙-false (S∙ inΓ up) (∙⟹∙S newΓ' up1) (S∙ inΓ') = ∙⟹-:=-∙-false inΓ newΓ' inΓ'
∙⟹-:=-∙-false (S^ inΓ up) (∙⟹^S newΓ' up1) (S^ inΓ') = ∙⟹-:=-∙-false inΓ newΓ' inΓ'
∙⟹-:=-∙-false (S= inΓ up) (∙⟹=S newΓ' up1) (S= inΓ') = ∙⟹-:=-∙-false inΓ newΓ' inΓ'
∙⟹-∙-:=-eq : Γ ∋∙ k
→ [ B / k ] Γ ∙⟹ Γ'
→ Γ' ∋ k := A
→ A ≡ B
∙⟹-∙-:=-eq Z (∙⟹^0 reg up) (Z up₁) = ↑ty-unique up₁ reg
∙⟹-∙-:=-eq (S, inΓ) (∙⟹,S newΓ) (S, inΓ') = ∙⟹-∙-:=-eq inΓ newΓ inΓ'
∙⟹-∙-:=-eq (S∙ inΓ) (∙⟹∙S newΓ up1) (S∙ inΓ' up) with ∙⟹-∙-:=-eq inΓ newΓ inΓ'
... | refl = ↑ty-unique up up1
∙⟹-∙-:=-eq (S= inΓ) (∙⟹=S newΓ up1) (S= inΓ' up) with ∙⟹-∙-:=-eq inΓ newΓ inΓ'
... | refl = ↑ty-unique up up1
∙⟹-∙-:=-eq (S^ inΓ) (∙⟹^S newΓ up1) (S^ inΓ' up) with ∙⟹-∙-:=-eq inΓ newΓ inΓ'
... | refl = ↑ty-unique up up1
∙⟹-∙-:=-neq-false : Γ ∋∙ X
→ [ B / k ] Γ ∙⟹ Γ'
→ Γ' ∋ X := A
→ k ≢ X
→ ⊥
∙⟹-∙-:=-neq-false Z (∙⟹^0 up reg) inΓ' neq = neq refl
∙⟹-∙-:=-neq-false (S, inΓ) (∙⟹,S newΓ) (S, inΓ') neq = ∙⟹-∙-:=-neq-false inΓ newΓ inΓ' neq
∙⟹-∙-:=-neq-false (S∙ inΓ) (∙⟹^0 up reg) (S= inΓ' up₁) neq = ∋∙-∋:=-false inΓ inΓ'
∙⟹-∙-:=-neq-false (S∙ inΓ) (∙⟹∙S newΓ up1) (S∙ inΓ' up) neq = ∙⟹-∙-:=-neq-false inΓ newΓ inΓ' (≢-pred neq)
∙⟹-∙-:=-neq-false (S= inΓ) (∙⟹=S newΓ up1) (S= inΓ' up) neq = ∙⟹-∙-:=-neq-false inΓ newΓ inΓ' (≢-pred neq)
∙⟹-∙-:=-neq-false (S^ inΓ) (∙⟹^S newΓ up1) (S^ inΓ' up) neq = ∙⟹-∙-:=-neq-false inΓ newΓ inΓ' (≢-pred neq)
∙⟹-∙-eq-false : Γ ∋∙ k
→ [ A / k ] Γ ∙⟹ Γ'
→ Γ' ∋∙ k
→ ⊥
∙⟹-∙-eq-false Z (∙⟹^0 up reg) ()
∙⟹-∙-eq-false (S, inΓ) (∙⟹,S newΓ) (S, inΓ') = ∙⟹-∙-eq-false inΓ newΓ inΓ'
∙⟹-∙-eq-false (S∙ inΓ) (∙⟹∙S newΓ up1) (S∙ inΓ') = ∙⟹-∙-eq-false inΓ newΓ inΓ'
∙⟹-∙-eq-false (S= inΓ) (∙⟹=S newΓ up1) (S= inΓ') = ∙⟹-∙-eq-false inΓ newΓ inΓ'
∙⟹-∙-eq-false (S^ inΓ) (∙⟹^S newΓ up1) (S^ inΓ') = ∙⟹-∙-eq-false inΓ newΓ inΓ'
⊢r-◇ : Γ ⊢r A
→ Γ ◇ k ⇘ Γ'
→ Γ' ⊢r A
⊢r-◇ ⊢r-int new = ⊢r-int
⊢r-◇ (⊢r-var-∙ inΓ) new = ⊢r-var-∙ (◇-∙∈ inΓ new)
⊢r-◇ (⊢r-arr regA regA₁) new = ⊢r-arr (⊢r-◇ regA new) (⊢r-◇ regA₁ new)
⊢r-◇ (⊢r-∀ regA) new = ⊢r-∀ (⊢r-◇ regA (◇S∙ new))
◆-sregular : SRegular Γ
→ Γ ◆ k ⇘ Γ'
→ SRegular Γ'
◆-sregular (reg-S∙ regΓ) (◆S∙ new) = reg-S∙ (◆-sregular regΓ new)
◆-sregular (reg-S^ regΓ) (◆S^ new) = reg-S^ (◆-sregular regΓ new)
◆-sregular (reg-S= regΓ regA) ◆Z = reg-S∙ regΓ
◆-sregular (reg-S= regΓ regA) (◆S= new) = reg-S= (◆-sregular regΓ new) (⊢r-◆ regA new)
◇-sregular : SRegular Γ
→ Γ ◇ k ⇘ Γ'
→ SRegular Γ'
◇-sregular (reg-S∙ regΓ) (◇S∙ new) = reg-S∙ (◇-sregular regΓ new)
◇-sregular (reg-S^ regΓ) ◇Z = reg-S∙ regΓ
◇-sregular (reg-S^ regΓ) (◇S^ new) = reg-S^ (◇-sregular regΓ new)
◇-sregular (reg-S= regΓ regA) (◇S= new) = reg-S= (◇-sregular regΓ new) (⊢r-◇ regA new)