module A201801.S4TTTerms where

open import A201801.Prelude
open import A201801.Category
open import A201801.Fin
open import A201801.FinLemmas
open import A201801.Vec


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


data Term : Nat  Nat  Set
  where
    VAR    :  {d g}  Fin g  Term d g
    LAM    :  {d g}  Term d (suc g)  Term d g
    APP    :  {d g}  Term d g  Term d g  Term d g
    MVAR   :  {d g}  Fin d  Term d g
    BOX    :  {d g}  Term d zero  Term d g
    LETBOX :  {d g}  Term d g  Term (suc d) g  Term d g


Terms : Nat  Nat  Nat  Set
Terms d g n = Vec (Term d g) n


Terms* : Nat  Nat  Set
Terms* d n = Vec (Term d zero) n


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


REN :  {d g g′}  g′  g  Term d g
                  Term d g′
REN e (VAR i)      = VAR (REN∋ e i)
REN e (LAM M)      = LAM (REN (keep e) M)
REN e (APP M N)    = APP (REN e M) (REN e N)
REN e (MVAR i)     = MVAR i
REN e (BOX M)      = BOX M
REN e (LETBOX M N) = LETBOX (REN e M) (REN e N)


RENS :  {d g g′ n}  g′  g  Terms d g n
                     Terms d g′ n
RENS e τ = MAPS (REN e) τ


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


MREN :  {d d′ g}  d′  d  Term d g
                   Term d′ g
MREN e (VAR i)      = VAR i
MREN e (LAM M)      = LAM (MREN e M)
MREN e (APP M N)    = APP (MREN e M) (MREN e N)
MREN e (MVAR i)     = MVAR (REN∋ e i)
MREN e (BOX M)      = BOX (MREN e M)
MREN e (LETBOX M N) = LETBOX (MREN e M) (MREN (keep e) N)


MRENS :  {d d′ g n}  d′  d  Terms d g n
                      Terms d′ g n
MRENS e τ = MAPS (MREN e) τ


MRENS* :  {d d′ n}  d′  d  Terms* d n
                     Terms* d′ n
MRENS* e τ = MRENS e τ


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


WK :  {d g}  Term d g
              Term d (suc g)
WK M = REN (drop id) M


WKS :  {d g n}  Terms d g n
                 Terms d (suc g) n
WKS τ = RENS (drop id) τ


VZ :  {d g}  Term d (suc g)
VZ = VAR zero


LIFTS :  {d g n}  Terms d g n
                   Terms d (suc g) (suc n)
LIFTS τ = WKS τ , VZ


VARS :  {d g g′}  g′  g
                   Terms d g′ g
VARS done     = 
VARS (drop e) = WKS (VARS e)
VARS (keep e) = LIFTS (VARS e)


IDS :  {d g}  Terms d g g
IDS = VARS id


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


MWK :  {d g}  Term d g
               Term (suc d) g
MWK M = MREN (drop id) M


MWKS :  {d g n}  Terms d g n
                  Terms (suc d) g n
MWKS τ = MRENS (drop id) τ


MWKS* :  {d n}  Terms* d n
                 Terms* (suc d) n
MWKS* τ = MWKS τ


MVZ :  {d g}  Term (suc d) g
MVZ = MVAR zero


MLIFTS* :  {d n}  Terms* d n
                   Terms* (suc d) (suc n)
MLIFTS* τ = MWKS* τ , MVZ


MVARS* :  {d d′}  d′  d
                   Terms* d′ d
MVARS* done     = 
MVARS* (drop e) = MWKS* (MVARS* e)
MVARS* (keep e) = MLIFTS* (MVARS* e)


MIDS* :  {d}  Terms* d d
MIDS* = MVARS* id


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


SUB :  {d g n}  Terms d g n  Term d n
                 Term d g
SUB τ (VAR i)      = GET τ i
SUB τ (LAM M)      = LAM (SUB (LIFTS τ) M)
SUB τ (APP M N)    = APP (SUB τ M) (SUB τ N)
SUB τ (MVAR i)     = MVAR i
SUB τ (BOX M)      = BOX M
SUB τ (LETBOX M N) = LETBOX (SUB τ M) (SUB (MWKS τ) N)


SUBS :  {d g n m}  Terms d g n  Terms d n m
                    Terms d g m
SUBS τ υ = MAPS (SUB τ) υ


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


MSUB :  {d g n}  Terms* d n  Term n g
                  Term d g
MSUB τ (VAR i)      = VAR i
MSUB τ (LAM M)      = LAM (MSUB τ M)
MSUB τ (APP M N)    = APP (MSUB τ M) (MSUB τ N)
MSUB τ (MVAR i)     = SUB  (GET τ i)
MSUB τ (BOX M)      = BOX (MSUB τ M)
MSUB τ (LETBOX M N) = LETBOX (MSUB τ M) (MSUB (MLIFTS* τ) N)


MSUBS :  {d g n m}  Terms* d n  Terms n g m
                     Terms d g m
MSUBS τ υ = MAPS (MSUB τ) υ


MSUBS* :  {d n m}  Terms* d n  Terms* n m
                    Terms* d m
MSUBS* τ υ = MSUBS τ υ


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


UNLAM :  {d g}  Term d g
                 Term d (suc g)
UNLAM M = APP (WK M) VZ


CUT :  {d g}  Term d g  Term d (suc g)
               Term d g
CUT M N = SUB (IDS , M) N


PSEUDOCUT :  {d g}  Term d g  Term d (suc g)
                     Term d g
PSEUDOCUT M N = APP (LAM N) M


PSEUDOSUB :  {d g n}  Terms d g n  Term d n
                       Term d g
PSEUDOSUB        M = REN bot≥ M
PSEUDOSUB (τ , L) M = APP (PSEUDOSUB τ (LAM M)) L


EXCH :  {d g}  Term d (suc (suc g))
                Term d (suc (suc g))
EXCH M = APP (APP (WK (WK (LAM (LAM M)))) VZ) (WK VZ)


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


VAU :  {d g}  Term (suc d) g
               Term d (suc g)
VAU M = LETBOX VZ (WK M)


UNVAU :  {d g}  Term d (suc g)
                 Term (suc d) g
UNVAU M = APP (LAM (MWK M)) (BOX MVZ)


BOXAPP :  {d g}  Term d g  Term d g
                  Term d g
BOXAPP M N = LETBOX M (LETBOX (MWK N) (BOX (APP (MWK MVZ) MVZ)))


UNBOX :  {d g}  Term d g
                 Term d g
UNBOX M = LETBOX M MVZ


REBOX :  {d g}  Term d g
                 Term d g
REBOX M = LETBOX M (BOX MVZ)


DUPBOX :  {d g}  Term d g
                  Term d g
DUPBOX M = LETBOX M (BOX (BOX MVZ))


MCUT :  {d g}  Term d zero  Term (suc d) g
                Term d g
MCUT M N = MSUB (MIDS* , M) N


PSEUDOMCUT :  {d g}  Term d zero  Term (suc d) g
                      Term d g
PSEUDOMCUT M N = LETBOX (BOX M) N


PSEUDOMSUB :  {d g n}  Terms* d n  Term n g
                        Term d g
PSEUDOMSUB        M = MREN bot≥ M
PSEUDOMSUB (τ , L) M = APP (PSEUDOMSUB τ (LAM (VAU M))) (BOX L)


MEXCH :  {d g}  Term (suc (suc d)) g
                 Term (suc (suc d)) g
MEXCH M = UNVAU (UNVAU (EXCH (VAU (VAU M))))


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