Section Code_Substitute_Formula.
Variable L : Language.
Variable codeF : Functions L -> nat.
Variable codeR : Relations L -> nat.
Notation Formula := (Formula L) (only parsing).
Notation Formulas := (Formulas L) (only parsing).
Notation System := (System L) (only parsing).
Notation Term := (Term L) (only parsing).
Notation Terms := (Terms L) (only parsing).
Let var := var L.
Let apply := apply L.
Let codeFormula := codeFormula L codeF codeR.
Let codeTerm := codeTerm L codeF.
Definition cTriple (a b c : nat) : nat := cPair a (cPair b c).
Definition cTriplePi1 (n : nat) : nat := cPairPi1 n.
Definition cTriplePi2 (n : nat) : nat := cPairPi1 (cPairPi2 n).
Definition cTriplePi3 (n : nat) : nat := cPairPi2 (cPairPi2 n).
unfold cTriplePi1, cTriple in |- *.
intros.
apply cPairProjections1.
Qed.
unfold cTriplePi2, cTriple in |- *.
intros.
rewrite cPairProjections2.
apply cPairProjections1.
Qed.
unfold cTriplePi3, cTriple in |- *.
intros.
rewrite cPairProjections2.
apply cPairProjections2.
Qed.
(*Trace has form ((v,s, formula_input), formula_output, [subTrace1], [subTrace2])*)
Definition codeNewVar (l : nat) : nat :=
evalStrongRec 0
(fun n Hrecs : nat =>
switchPR n
(max (S (cPairPi1 (pred n)))
(codeNth (n - S (cPairPi2 (pred n))) Hrecs)) 0) l.

Lemma codeNewVarCorrect :
forall l : list nat, codeNewVar (codeList l) = newVar l.