module A201801.S4TTStandardDerivations where

open import A201801.Prelude
open import A201801.Category
open import A201801.Fin
open import A201801.Vec
open import A201801.AllVec
open import A201801.S4TTTypes
open import A201801.S4TTTerms
import A201801.S4TTDerivations as S4TT


--------------------------------------------------------------------------------


infix 3 _⨾_⊢_⦂_true
data _⨾_⊢_⦂_true :  {d g}  Asserts d  Types g  Term d g  Type  Set
  where
    var :  {A d g i}  {Δ : Asserts d} {Γ : Types g}
                       Γ ∋⟨ i  A
                       Δ  Γ  VAR i  A true

    lam :  {A B d g M}  {Δ : Asserts d} {Γ : Types g}
                         Δ  Γ , A  M  B true
                         Δ  Γ  LAM M  A  B true

    app :  {A B d g M N}  {Δ : Asserts d} {Γ : Types g}
                           Δ  Γ  M  A  B true  Δ  Γ  N  A true
                           Δ  Γ  APP M N  B true

    mvar :  {A d g i}  {Δ : Asserts d} {Γ : Types g}
                        Δ ∋⟨ i  ⟪⊫ A 
                        Δ  Γ  MVAR i  A true

    box :  {A d g M}  {Δ : Asserts d} {Γ : Types g}
                       Δ    M  A true
                       Δ  Γ  BOX M   A true

    letbox :  {A B d g M N}  {Δ : Asserts d} {Γ : Types g}
                              Δ  Γ  M   A true  Δ , ⟪⊫ A   Γ  N  B true
                              Δ  Γ  LETBOX M N  B true


--------------------------------------------------------------------------------


 :  {d g M A}  {Δ : Asserts d} {Γ : Types g}
                 Δ  Γ  M  A true
                 Δ S4TT.⊢ M  A valid[ Γ ]
 (var i)      = S4TT.var i
 (lam 𝒟)      = S4TT.lam ( 𝒟)
 (app 𝒟 )    = S4TT.app ( 𝒟) ( )
 (mvar i)     = S4TT.mvar i
 (box 𝒟)      = S4TT.box ( 𝒟)
 (letbox 𝒟 ) = S4TT.letbox ( 𝒟) ( )


 :  {d g M A}  {Δ : Asserts d} {Γ : Types g}
                 Δ S4TT.⊢ M  A valid[ Γ ]
                 Δ  Γ  M  A true
 (S4TT.var i)      = var i
 (S4TT.lam 𝒟)      = lam ( 𝒟)
 (S4TT.app 𝒟 )    = app ( 𝒟) ( )
 (S4TT.mvar i)     = mvar i
 (S4TT.box 𝒟)      = box ( 𝒟)
 (S4TT.letbox 𝒟 ) = letbox ( 𝒟) ( )


id↓↑ :  {d g M A}  {Δ : Asserts d} {Γ : Types g}
                    (𝒟 : Δ S4TT.⊢ M  A valid[ Γ ])
                    (  ) 𝒟  𝒟
id↓↑ (S4TT.var i)      = refl
id↓↑ (S4TT.lam 𝒟)      = S4TT.lam & id↓↑ 𝒟
id↓↑ (S4TT.app 𝒟 )    = S4TT.app & id↓↑ 𝒟  id↓↑ 
id↓↑ (S4TT.mvar i)     = refl
id↓↑ (S4TT.box 𝒟)      = S4TT.box & id↓↑ 𝒟
id↓↑ (S4TT.letbox 𝒟 ) = S4TT.letbox & id↓↑ 𝒟  id↓↑ 


id↑↓ :  {d g M A}  {Δ : Asserts d} {Γ : Types g}
                    (𝒟 : Δ  Γ  M  A true)
                    (  ) 𝒟  𝒟
id↑↓ (var i)      = refl
id↑↓ (lam 𝒟)      = lam & id↑↓ 𝒟
id↑↓ (app 𝒟 )    = app & id↑↓ 𝒟  id↑↓ 
id↑↓ (mvar i)     = refl
id↑↓ (box 𝒟)      = box & id↑↓ 𝒟
id↑↓ (letbox 𝒟 ) = letbox & id↑↓ 𝒟  id↑↓ 


--------------------------------------------------------------------------------