Definition makeTraceImp (f1 : fol.Formula L)
(f1rec : nat * fol.Term L -> nat) (f2 : fol.Formula L)
(f2rec : nat * fol.Term L -> nat) (p : nat * fol.Term L) : nat :=
let v := fst p in
let s := snd p in
cTriple (cTriple v (codeTerm s) (codeFormula (impH L f1 f2)))
(codeFormula (substituteFormula L (impH L f1 f2) v s))
(cPair (f1rec p) (f2rec p)).
Definition makeTraceNot (f : fol.Formula L) (frec : nat * fol.Term L -> nat)
(p : nat * fol.Term L) : nat :=
let v := fst p in
let s := snd p in
cTriple (cTriple v (codeTerm s) (codeFormula (notH L f)))
(codeFormula (substituteFormula L (notH L f) v s))
(frec p).
Definition makeTraceForall (n : nat) (f : fol.Formula L)
(rec : forall b : fol.Formula L,
lt_depth L b (forallH L n f) -> nat * fol.Term L -> nat)
(p : nat * fol.Term L) : nat.
intros.
set (v := fst p) in *.
set (s := snd p) in *.
induction (eq_nat_dec n v).
exact
(cTriple (cTriple v (codeTerm s) (codeFormula (forallH L n f)))
(codeFormula (substituteFormula L (forallH L n f) v s)) 0).
assert (lt_depth L f (forallH L v f)).
apply depthForall.
induction (In_dec eq_nat_dec n (freeVarTerm L s)).
set (nv := newVar (v :: freeVarTerm L s ++ freeVarFormula L f)) in *.
assert (lt_depth L (substituteFormula L f n (var nv)) (forallH L v f)).
apply eqDepth with f.
symmetry  in |- *.
apply subFormulaDepth.
apply H.
exact
(cTriple (cTriple v (codeTerm s) (codeFormula (forallH L n f)))
(codeFormula (substituteFormula L (forallH L n f) v s))
(cPair (rec f H (n, var nv))
(rec (substituteFormula L f n (var nv)) H0 p))).
exact
(cTriple (cTriple v (codeTerm s) (codeFormula (forallH L n f)))
(codeFormula (substituteFormula L (forallH L n f) v s))
(rec f H p)).
Defined.
Definition makeTrace : fol.Formula L -> nat * fol.Term L -> nat :=
Formula_depth_rec2 L (fun _ : fol.Formula L => nat * fol.Term L -> nat)
(fun (t t0 : fol.Term L) (p : nat * fol.Term L) =>
let v := fst p in
let s := snd p in
cTriple (cTriple v (codeTerm s) (codeFormula (equal L t t0)))
(codeFormula (substituteFormula L (equal L t t0) v s)) 0)
(fun (r : Relations L) t (p : nat * fol.Term L) =>
let v := fst p in
let s := snd p in
cTriple (cTriple v (codeTerm s) (codeFormula (atomic L r t)))
(codeFormula (substituteFormula L (atomic L r t) v s)) 0) makeTraceImp
makeTraceNot makeTraceForall.

(* Specifications: *)
Lemma makeTraceImpNice :
forall (f2 g : fol.Formula L) (z1 z2 : nat * fol.Term L -> nat),
(forall q : nat * fol.Term L, z1 q = z2 q) ->
forall z3 z4 : nat * fol.Term L -> nat,
(forall q : nat * fol.Term L, z3 q = z4 q) ->
forall q : nat * fol.Term L,
makeTraceImp f2 z1 g z3 q = makeTraceImp f2 z2 g z4 q.
Lemma makeTraceNotNice :
forall (f2 : fol.Formula L) (z1 z2 : nat * fol.Term L -> nat),
(forall q : nat * fol.Term L, z1 q = z2 q) ->
forall q : nat * fol.Term L, makeTraceNot f2 z1 q = makeTraceNot f2 z2 q.
Lemma makeTraceForallNice :
forall (v0 : nat) (a : fol.Formula L)
(z1
z2 : forall b : fol.Formula L,
lt_depth L b (forallH L v0 a) -> nat * fol.Term L -> nat),
(forall (b : fol.Formula L) (q : lt_depth L b (forallH L v0 a))
(r : nat * fol.Term L), z1 b q r = z2 b q r) ->
forall q : nat * fol.Term L,
makeTraceForall v0 a z1 q = makeTraceForall v0 a z2 q.