module Implicit.Algo2Interm.Context2Counter where
open import Implicit.Language.All
open import Implicit.Interm.All
open import Implicit.Algo.All
open import Implicit.Algo2Interm.AlgoCounter.All
infix 3 _⊢_~t_
data _⊢_~t_ : Env n m → Mask × Type m → Context n m → Set where
~tZ : ∀ {Γ : Env n m} {A}
→ Γ ⊢ ⟨ `■ , A ⟩ ~t □
~t∞ : ∀ {Γ : Env n m} {A }
→ Γ ⊢ ⟨ `□ , A ⟩ ~t τ A
~tI : ∀ {Γ : Env n m} {j A B Σ e}
→ (⊢e : Γ ⊢ `■ # e ⦂ A)
→ Γ ⊢ ⟨ j , B ⟩ ~t Σ
→ Γ ⊢ ⟨ □ · j , A `→ B ⟩ ~t ([ e ]↝ Σ)
~tC : ∀ {Γ : Env n m} {j A B Σ e}
(⊢e : Γ ⊢ `□ # e ⦂ A)
→ Γ ⊢ ⟨ j , B ⟩ ~t Σ
→ Γ ⊢ ⟨ ■ · j , A `→ B ⟩ ~t ([ e ]↝ Σ)
infix 3 _⊢_~inf_
data _⊢_~inf_ : Env n m → Mask × Type m → Context n m → Set where
~i∞ : ∀ {Γ : Env n m} {A }
→ Γ ⊢ ⟨ `□ , A ⟩ ~inf τ A
~iI : ∀ {Γ : Env n m} {j A B Σ e}
→ (⊢e : Γ ⊢ `■ # e ⦂ A)
→ Γ ⊢ ⟨ j , B ⟩ ~inf Σ
→ Γ ⊢ ⟨ □ · j , A `→ B ⟩ ~inf ([ e ]↝ Σ)
infix 3 _⊢_~s_
data _⊢_~s_ : Env n m → Mask × Type m → Context n m → Set where
~sZ : ∀ {Γ : Env n m} {A}
→ Γ ⊢ ⟨ `■ , A ⟩ ~s □
~s∞ : ∀ {Γ : Env n m} {A }
→ Γ ⊢ ⟨ `□ , A ⟩ ~s τ A
~sI : ∀ {Γ : Env n m} {j A B Σ e}
→ (⊢e : 𝕣 Γ ⊢ `■ # e ⦂ A)
→ Γ ⊢ ⟨ j , B ⟩ ~s Σ
→ Γ ⊢ ⟨ □ · j , A `→ B ⟩ ~s ([ e ]↝ Σ)
~sC : ∀ {Γ : Env n m} {j A B Σ e}
(⊢e : 𝕣 Γ ⊢ `□ # e ⦂ A)
→ Γ ⊢ ⟨ j , B ⟩ ~s Σ
→ Γ ⊢ ⟨ ■ · j , A `→ B ⟩ ~s ([ e ]↝ Σ)
~s-~t : Γ ⊢ ⟨ j , A ⟩ ~s Σ
→ 𝕣 Γ ⊢ ⟨ j , A ⟩ ~t Σ
~s-~t ~sZ = ~tZ
~s-~t ~s∞ = ~t∞
~s-~t (~sI ⊢e ~s) = ~tI ⊢e (~s-~t ~s)
~s-~t (~sC ⊢e ~s) = ~tC ⊢e (~s-~t ~s)
~t-~s : 𝕣 Γ ⊢ ⟨ j , A ⟩ ~t Σ
→ Γ ⊢ ⟨ j , A ⟩ ~s Σ
~t-~s ~tZ = ~sZ
~t-~s ~t∞ = ~s∞
~t-~s (~tI ⊢e ~t) = ~sI ⊢e (~t-~s ~t )
~t-~s (~tC ⊢e ~t) = ~sC ⊢e (~t-~s ~t )
~infs-~t : Γ ⊢ ⟨ j , A ⟩ ~inf Σ
→ Γ ⊢ ⟨ j , A ⟩ ~t Σ
~infs-~t ~i∞ = ~t∞
~infs-~t (~iI ⊢e ~inf) = ~tI ⊢e (~infs-~t ~inf)
~s-irrev-⊆ : Γ ⊢ ⟨ j , A ⟩ ~s Σ
→ Γ ⊆ Δ
→ Δ ⊢ ⟨ j , A ⟩ ~s Σ
~s-irrev-⊆ ~sZ ext = ~sZ
~s-irrev-⊆ ~s∞ ext = ~s∞
~s-irrev-⊆ (~sI ⊢e ~s) ext = ~sI (t-⊆-prv ⊢e ext) (~s-irrev-⊆ ~s ext)
~s-irrev-⊆ (~sC ⊢e ~s) ext = ~sC (t-⊆-prv ⊢e ext) (~s-irrev-⊆ ~s ext)
NonEmpty-NonZ : NonEmpty Σ
→ Γ ⊢ ⟨ j , A ⟩ ~t Σ
→ NonZ j
NonEmpty-NonZ ne-τ ~t∞ = nz-□
NonEmpty-NonZ ne-app (~tI ⊢e newj) = nz-app
NonEmpty-NonZ ne-app (~tC ⊢e newj) = nz-app
~s-strengthen^0 : Γ ,^ ⊢ ⟨ j , A' ⟩ ~s Σ'
→ ↑ty0 A ⇘ A'
→ ↑tyᶜ0 Σ ⇘ Σ'
→ Γ ⊢ ⟨ j , A ⟩ ~s Σ
~s-strengthen^0 ~sZ upA ↑tyᶜ-□ = ~sZ
~s-strengthen^0 ~s∞ upA (↑tyᶜ-τ up-t) with refl ← ↑ty-unique-inver upA up-t = ~s∞
~s-strengthen^0 (~sI ⊢e ~s) (↑ty-arr upA upA₁) (↑tyᶜ-e up-e upΣ) = ~sI (t-strengthen^ ⊢e ◀Z up-e upA) (~s-strengthen^0 ~s upA₁ upΣ)
~s-strengthen^0 (~sC ⊢e ~s) (↑ty-arr upA upA₁) (↑tyᶜ-e up-e upΣ) = ~sC (t-strengthen^ ⊢e ◀Z up-e upA) (~s-strengthen^0 ~s upA₁ upΣ)
~s-strengthen=0 : Γ ,= T ⊢ ⟨ j , A' ⟩ ~s Σ'
→ ↑ty0 A ⇘ A'
→ ↑tyᶜ0 Σ ⇘ Σ'
→ Γ ⊢ ⟨ j , A ⟩ ~s Σ
~s-strengthen=0 ~sZ upA ↑tyᶜ-□ = ~sZ
~s-strengthen=0 ~s∞ upA (↑tyᶜ-τ up-t) with refl ← ↑ty-unique-inver upA up-t = ~s∞
~s-strengthen=0 (~sI ⊢e ~s) (↑ty-arr upA upA₁) (↑tyᶜ-e up-e upΣ) = ~sI (t-strengthen= ⊢e ◀Z up-e upA) (~s-strengthen=0 ~s upA₁ upΣ)
~s-strengthen=0 (~sC ⊢e ~s) (↑ty-arr upA upA₁) (↑tyᶜ-e up-e upΣ) = ~sC (t-strengthen= ⊢e ◀Z up-e upA) (~s-strengthen=0 ~s upA₁ upΣ)
~t-strengthen,0 : Γ , A ⊢ ⟨ j , B ⟩ ~t Σ'
→ ↑tmᶜ0 Σ ⇘ Σ'
→ Γ ⊢ ⟨ j , B ⟩ ~t Σ
~t-strengthen,0 ~tZ ↑tmᶜ-□ = ~tZ
~t-strengthen,0 ~t∞ ↑tmᶜ-τ = ~t∞
~t-strengthen,0 (~tI ⊢e ~t) (↑tmᶜ-e up-e upΣ) = ~tI (t-strengthen,0 ⊢e up-e) (~t-strengthen,0 ~t upΣ)
~t-strengthen,0 (~tC ⊢e ~t) (↑tmᶜ-e up-e upΣ) = ~tC (t-strengthen,0 ⊢e up-e) (~t-strengthen,0 ~t upΣ)