\import Paths
\import Paths.Meta
\class TermSig
| \coerce Sort : \Set
| Symb : Sort -> \Set
| domain {s : Sort} : Symb s -> Array Sort
\data Term {S : TermSig} (V : S -> \Set) (s : S)
| var (V s)
| apply (f : Symb s) (DArray \lam j => Term V (domain f j))
\func subst {S : TermSig} {U V : S -> \Set} {s : S} (t : Term U s) (rho : \Pi {s : S} -> U s -> Term V s) : Term V s \elim t
| var v => rho v
| apply f ts => apply f \lam j => subst (ts j) rho
\lemma subst-assoc {S : TermSig} {U V W : S -> \Set} {s : S} (t : Term U s) {rho : \Pi {s : S} -> U s -> Term V s} {tau : \Pi {s : S} -> V s -> Term W s}
: subst (subst t rho) tau = subst t (\lam u => subst (rho u) tau) \elim t
| var u => idp
| apply f d => pmap (apply f) (exts \lam j => subst-assoc (d j))
\lemma subst_var {S : TermSig} {V : S -> \Set} {s : S} (t : Term V s) : subst t var = t \elim t
| var v => idp
| apply f d => pmap (apply f) (exts \lam j => subst_var (d j))