module STLC.Algo where
open import STLC.Prelude
open import STLC.Common
infixr 8 [_]↝_
data Context : Set where
□ : Context
τ_ : Type → Context
[_]↝_ : Term → Context → Context
data ¬□ : Context → Set where
¬□-τ : ∀ {A} → ¬□ (τ A)
¬□-term : ∀ {e Σ} → ¬□ ([ e ]↝ Σ)
infixl 7 _⇧_
_⇧_ : Context → ℕ → Context
τ A ⇧ n = τ A
□ ⇧ n = □
([ e ]↝ Σ) ⇧ n = [ e ↑ n ]↝ (Σ ⇧ n)
infixl 7 _⇩_
_⇩_ : Context → ℕ → Context
τ A ⇩ n = τ A
□ ⇩ n = □
([ e ]↝ Σ) ⇩ n = [ e ↓ n ]↝ (Σ ⇩ n)
data GenericConsumer : Term → Set where
gc-lit : ∀ {i} → GenericConsumer (lit i)
gc-var : ∀ {x} → GenericConsumer (` x)
gc-ann : ∀ {e A} → GenericConsumer (e ⦂ A)
infix 4 _⊢_≈_
infix 4 _⊢_⇒_⇒_
data _⊢_≈_ : Env → Type → Context → Set
data _⊢_⇒_⇒_ : Env → Context → Term → Type → Set
data _⊢_≈_ where
≈□ : ∀ {Γ A}
→ Γ ⊢ A ≈ □
≈τ : ∀ {Γ A}
→ Γ ⊢ A ≈ τ A
≈term : ∀ {Γ Σ e A B C}
→ Γ ⊢ τ A ⇒ e ⇒ C
→ Γ ⊢ B ≈ Σ
→ Γ ⊢ (A `→ B) ≈ [ e ]↝ Σ
data _⊢_⇒_⇒_ where
⊢lit : ∀ {Γ n}
→ Γ ⊢ □ ⇒ lit n ⇒ Int
⊢var : ∀ {Γ A x}
→ Γ ∋ x ⦂ A
→ Γ ⊢ □ ⇒ ` x ⇒ A
⊢ann : ∀ {Γ e A B}
→ Γ ⊢ τ A ⇒ e ⇒ B
→ Γ ⊢ □ ⇒ e ⦂ A ⇒ A
⊢app : ∀ {Γ e₁ e₂ Σ A B}
→ Γ ⊢ [ e₂ ]↝ Σ ⇒ e₁ ⇒ A `→ B
→ Γ ⊢ Σ ⇒ e₁ · e₂ ⇒ B
⊢lam₁ : ∀ {Γ e A B C}
→ Γ , A ⊢ τ B ⇒ e ⇒ C
→ Γ ⊢ τ (A `→ B) ⇒ ƛ e ⇒ A `→ C
⊢lam₂ : ∀ {Γ e₁ e A B Σ}
→ Γ ⊢ □ ⇒ e₁ ⇒ A
→ Γ , A ⊢ (Σ ⇧ 0) ⇒ e ⇒ B
→ Γ ⊢ [ e₁ ]↝ Σ ⇒ ƛ e ⇒ A `→ B
⊢sub : ∀ {Γ e A Σ}
→ Γ ⊢ □ ⇒ e ⇒ A
→ Γ ⊢ A ≈ Σ
→ GenericConsumer e
→ ¬□ Σ
→ Γ ⊢ Σ ⇒ e ⇒ A
infix 4 ⟦_,_⟧→⟦_,_,_,_⟧
data ⟦_,_⟧→⟦_,_,_,_⟧ : Context → Type → List Term → Context → List Type → Type → Set where
none-□ : ∀ {A}
→ ⟦ □ , A ⟧→⟦ [] , □ , [] , A ⟧
none-τ : ∀ {A B}
→ ⟦ τ A , B ⟧→⟦ [] , τ A , [] , B ⟧
have : ∀ {e Σ A B e̅ Σ' A' A̅}
→ ⟦ Σ , B ⟧→⟦ e̅ , Σ' , A̅ , A' ⟧
→ ⟦ [ e ]↝ Σ , A `→ B ⟧→⟦ e ∷ e̅ , Σ' , A ∷ A̅ , A' ⟧