module Implicit.Algo.Properties.Id where

open import Implicit.Language.All
open import Implicit.Algo.Base
open import Implicit.Algo.Properties.Subst

data Id : Context n m  Type m  Set where
  id-□ : Id (Context n m ∋⦂ ) A
  id-τ : Id (Context n m ∋⦂ τ A) A
  id-e : Id Σ B
        Id ([ e ]↝ Σ) (A `→ B)

id-st' : Id Σ A
         k / T ⟧ᶜ Σ  Σ*
         k / T  A  A*
        Id Σ* A*
id-st' id-□ empty stA = id-□
id-st' id-τ (fulltype st) stA with reflst-unique st stA = id-τ
id-st' (id-e id₁) (term stc ste) (st-arr stA stA₁) = id-e (id-st' id₁ stc stA₁)

id-↑tm : Id Σ' A
        Σ ↑tmᶜ k  Σ'
        Id Σ A
id-↑tm id-□ ↑tmᶜ-□ = id-□
id-↑tm id-τ ↑tmᶜ-τ = id-τ
id-↑tm (id-e id₁) (↑tmᶜ-e up-e upΣ) = id-e (id-↑tm id₁ upΣ)

⊢id' : Γ  Σ  e  A
      Id Σ A

s-id' : Γ  A ≤⁺ Σ  Δ  B
       Id Σ B

infs-id' : Γ  Σ  A
          Id Σ A

⊢id' (⊢lit regΓ) = id-□
⊢id' (⊢var regΓ x∈Γ) = id-□
⊢id' (⊢ann ⊢e) = id-□
⊢id' (⊢app ⊢e) with ⊢id' ⊢e
... | id-e r = r
⊢id' (⊢lam₁ ⊢e) with ⊢id' ⊢e
... | id-τ = id-τ
⊢id' (⊢lam₂ ⊢e up-c ⊢e₁) with ⊢id' ⊢e₁
... | r = id-e (id-↑tm r up-c)
⊢id' (⊢sub ⊢e ne gc s) = s-id' s
⊢id' (⊢tabs ⊢e) = id-□
⊢id' (⊢tabs-τ ⊢e) with ⊢id' ⊢e
... | id-τ = id-τ
⊢id' (⊢tapp ⊢e regA st s) = s-id' s

s-id' (s-empty regΓ cloA grd) = id-□
s-id' (s-type ss) = id-τ
s-id' (s-term-c cloA ap ⊢e s) = id-e (s-id' s)
s-id' (s-term-o opnA ⊢e ss s) = id-e (s-id' s)
s-id' (s-∀l s upᶜ upᵉ upC upD) with s-id' s
... | id-e r = id-e (id-st' {T = Int} r (↑tyᶜ-st upᶜ) (↑ty-st upD))
s-id' (s-∀l-no s upᶜ upᵉ upC upD) with s-id' s
... | id-e r = id-e (id-st' {T = Int} r (↑tyᶜ-st upᶜ) (↑ty-st upD))
s-id' (s-svar-term inΓ s) = s-id' s
s-id' (s-evar-infers infs inst) = infs-id' infs

infs-id' (infs-z regΓ regA) = id-τ
infs-id' (infs-s x infs) = id-e (infs-id' infs)


⊢id0 : Γ  τ B  e  A
      B  A
⊢id0 ⊢e with ⊢id' ⊢e
... | id-τ = refl

s-id0 : Γ  A ≤⁺ τ B  Γ'  C
       B  C
s-id0 (s-type ss) = refl