module A201801.STLCStandardTerms where

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


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


data Term : Nat  Set
  where
    VAR :  {g}  Fin g  Term g
    LAM :  {g}  Term (suc g)  Term g
    APP :  {g}  Term g  Term g  Term g


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


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


REN :  {g g′}  g′  g  Term g
                Term 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)


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


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


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


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


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


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


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


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


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


SUB :  {g n}  Terms g n  Term n
               Term g
SUB τ (VAR I)    = GET τ I
SUB τ (LAM M)    = LAM (SUB (LIFTS τ) M)
SUB τ (APP M N)  = APP (SUB τ M) (SUB τ N)


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


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


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


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


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


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


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


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