Fixpoint PairwiseEqual (T : fol.System L) (n : nat) {struct n} :
fol.Terms L n -> fol.Terms L n -> Prop :=
match n return (fol.Terms L n -> fol.Terms L n -> Prop) with
| O => fun ts ss : fol.Terms L 0 => True
| S x =>
fun ts ss : fol.Terms L (S x) =>
let (a, b) := proj1_sig (consTerms L x ts) in
let (c, d) := proj1_sig (consTerms L x ss) in
SysPrf T (equal a c) /\ PairwiseEqual T x b d
end.
Let termsMap (m : nat) (ts ss : fol.Terms L m) : nat -> fol.Term L.
induction m as [| m Hrecm].
exact (fun n : nat => var n).
induction (consTerms L _ ts).
induction x as (a, b).
induction (consTerms L _ ss).
induction x as (a0, b0).
exact
(fun n : nat =>
match eq_nat_dec n (m + m) with
| left _ => a
| right _ =>
match eq_nat_dec n (S (m + m)) with
| left _ => a0
| right _ => Hrecm b b0 n
end
end).
Defined.
Remark subAllnVars1 :
forall (a : nat) (ts ss : fol.Terms L a),
ts = subAllTerms L _ (fst (nVars L a)) (termsMap a ts ss).
Remark subAllnVars2 :
forall (a : nat) (ts ss : fol.Terms L a),
ss = subAllTerms L _ (snd (nVars L a)) (termsMap a ts ss).
Remark addPairwiseEquals :
forall (T : fol.System L) (n : nat) (ts ss : fol.Terms L n),
PairwiseEqual T n ts ss ->
forall m0 : nat -> fol.Term L,
(forall q : nat, q < n + n -> m0 q = termsMap n ts ss q) ->
forall f0 : fol.Formula L,
SysPrf T
(subAllFormula L
(nat_rec (fun _ : nat => fol.Formula L) f0
(fun (n : nat) (Hrecn : fol.Formula L) =>
fol.impH L
(fol.equal L (fol.var L (n + n)) (fol.var L (S (n + n)))) Hrecn)
n) m0) -> SysPrf T (subAllFormula L f0 m0).

Lemma subWithEquals :
forall (f : fol.Formula L) (v : nat) (a b : fol.Term L) (T : fol.System L),
SysPrf T (equal a b) ->
SysPrf T (impH (substituteFormula L f v a) (substituteFormula L f v b)).