module A201802.WIP.CoquandStyle where

open import A201801.Prelude
open import A201801.Category
open import A201801.FullIPLPropositions

open import A201802.WIP.Bool
open import A201802.WIP.Name
open import A201802.WIP.CoquandList


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


infix 3 _⊢_true
data _⊢_true : List Form  Form  Set
  where
    var :  {A Γ} x  Γ  x  A
                     Γ  A true

    lam :  {A B Γ} x  {{_ : T (fresh x Γ)}}
                       Γ , x  A  B true
                       Γ  A  B true

    app :  {A B Γ}  Γ  A  B true  Γ  A true
                     Γ  B true

    pair :  {A B Γ}  Γ  A true  Γ  B true
                      Γ  A  B true

    fst :  {A B Γ}  Γ  A  B true
                     Γ  A true

    snd :  {A B Γ}  Γ  A  B true
                     Γ  B true

    unit :  {Γ}  Γ  𝟏 true

    abort :  {A Γ}  Γ  𝟎 true
                     Γ  A true

    inl :  {A B Γ}  Γ  A true
                     Γ  A  B true

    inr :  {A B Γ}  Γ  B true
                     Γ  A  B true

    case :  {A B C Γ} x y  {{_ : T (fresh x Γ)}} {{_ : T (fresh y Γ)}}
                            Γ  A  B true
                            Γ , x  A  C true
                            Γ , y  B  C true
                            Γ  C true

infix 3 _⊢_alltrue
_⊢_alltrue : List Form  List Form  Set
Γ  Ξ alltrue = All (Γ ⊢_true) Ξ


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


-- TODO: unfinished
postulate
  oopsᵣ :  {𝔄 x}  {Γ Γ′ : List 𝔄} {{_ : T (fresh x Γ)}}
                   Γ′  Γ
                   T (fresh x Γ′)


ren :  {Γ′ Γ A}  Γ′  Γ  Γ  A true
                  Γ′  A true
ren η (var x i)        = var x (get⊇ η i)
ren η (lam x 𝒟)        = lam x {{oopsᵣ η}} (ren (keep⊇ {{oopsᵣ η}} η) 𝒟)
ren η (app 𝒟 )        = app (ren η 𝒟) (ren η )
ren η (pair 𝒟 )       = pair (ren η 𝒟) (ren η )
ren η (fst 𝒟)          = fst (ren η 𝒟)
ren η (snd 𝒟)          = snd (ren η 𝒟)
ren η unit             = unit
ren η (abort 𝒟)        = abort (ren η 𝒟)
ren η (inl 𝒟)          = inl (ren η 𝒟)
ren η (inr 𝒟)          = inr (ren η 𝒟)
ren η (case x y 𝒟  ) = case x y {{oopsᵣ η}} {{oopsᵣ η}}
                              (ren η 𝒟)
                              (ren (keep⊇ {{oopsᵣ η}} η) )
                              (ren (keep⊇ {{oopsᵣ η}} η) )


rens :  {Γ Γ′ Ξ}  Γ′  Γ  Γ  Ξ alltrue
                   Γ′  Ξ alltrue
rens η ξ = maps (ren η) ξ


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


wk :  {A x C Γ}  {{_ : T (fresh x Γ)}}
                  Γ  C true
                  Γ , x  A  C true
wk 𝒟 = ren (drop⊇ id) 𝒟


wks :  {A x Γ Ξ}  {{_ : T (fresh x Γ)}}
                   Γ  Ξ alltrue
                   Γ , x  A  Ξ alltrue
wks ξ = rens (drop⊇ id) ξ


vz :  {Γ A} x  {{_ : T (fresh x Γ)}}
                Γ , x  A  A true
vz x = var x zero


lifts :  {A x Γ Ξ}  {{_ : T (fresh x Γ)}} {{_ : T (fresh x Ξ)}}
                     Γ  Ξ alltrue
                     Γ , x  A  Ξ , x  A alltrue
lifts {x = x} ξ = wks ξ , vz x


vars :  {Γ Γ′}  Γ′  Γ
                 Γ′  Γ alltrue
vars done               = 
vars (step {x = x} η i) = vars η , var x i


ids :  {Γ}  Γ  Γ alltrue
ids = vars id


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


-- TODO: unfinished
postulate
  oopsₛ :  {Γ Ξ x}  {{_ : T (fresh x Ξ)}}
                     Γ  Ξ alltrue
                     T (fresh x Γ)


sub :  {Γ Ξ A}  Γ  Ξ alltrue  Ξ  A true
                 Γ  A true
sub ξ (var x i)        = get ξ i
sub ξ (lam x 𝒟)        = lam x {{oopsₛ ξ}} (sub (lifts {{oopsₛ ξ}} ξ) 𝒟)
sub ξ (app 𝒟 )        = app (sub ξ 𝒟) (sub ξ )
sub ξ (pair 𝒟 )       = pair (sub ξ 𝒟) (sub ξ )
sub ξ (fst 𝒟)          = fst (sub ξ 𝒟)
sub ξ (snd 𝒟)          = snd (sub ξ 𝒟)
sub ξ unit             = unit
sub ξ (abort 𝒟)        = abort (sub ξ 𝒟)
sub ξ (inl 𝒟)          = inl (sub ξ 𝒟)
sub ξ (inr 𝒟)          = inr (sub ξ 𝒟)
sub ξ (case x y 𝒟  ) = case x y {{oopsₛ ξ}} {{oopsₛ ξ}}
                              (sub ξ 𝒟)
                              (sub (lifts {{oopsₛ ξ}} ξ) )
                              (sub (lifts {{oopsₛ ξ}} ξ) )


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