Fixpoint subAllFormula (f : Formula) (m : (nat -> Term)) {struct f} : Formula :=
match f with
| fol.equal t s => equal (subAllTerm t m) (subAllTerm s m)
| fol.atomic r ts => atomic r (subAllTerms _ ts m)
| fol.impH f g =>
impH (subAllFormula f m) (subAllFormula g m)
| fol.notH f => notH (subAllFormula f m)
| fol.forallH n f =>
let nv :=
newVar
(freeVarFormula L f ++
freeVarMap (freeVarFormula L (forallH n f)) m) in
forallH nv
(subAllFormula f
(fun v : nat =>
match eq_nat_dec v n with
| left _ => var nv
| right _ => m v
end))
end.

(* Specifications: *)
Lemma subAllFormula_ext :
forall (f : fol.Formula L) (m1 m2 : nat -> fol.Term L),
(forall m : nat, In m (freeVarFormula L f) -> m1 m = m2 m) ->
subAllFormula f m1 = subAllFormula f m2.
Lemma freeVarSubAllTerm1 :
forall (t : fol.Term L) (m : nat -> fol.Term L) (v : nat),
In v (freeVarTerm L (subAllTerm t m)) ->
exists n : nat, In n (freeVarTerm L t) /\ In v (freeVarTerm L (m n)).
Lemma freeVarSubAllTerms1 :
forall (n : nat) (ts : fol.Terms L n) (m : nat -> fol.Term L) (v : nat),
In v (freeVarTerms L n (subAllTerms n ts m)) ->
exists a : nat, In a (freeVarTerms L n ts) /\ In v (freeVarTerm L (m a)).
Lemma freeVarSubAllTerm2 :
forall (t : fol.Term L) (m : nat -> fol.Term L) (v n : nat),
In n (freeVarTerm L t) ->
In v (freeVarTerm L (m n)) -> In v (freeVarTerm L (subAllTerm t m)).
Lemma freeVarSubAllTerms2 :
forall (a : nat) (ts : fol.Terms L a) (m : nat -> fol.Term L) (v n : nat),
In n (freeVarTerms L a ts) ->
In v (freeVarTerm L (m n)) -> In v (freeVarTerms L a (subAllTerms a ts m)).
Lemma freeVarSubAllFormula1 :
forall (f : fol.Formula L) (m : nat -> fol.Term L) (v : nat),
In v (freeVarFormula L (subAllFormula f m)) ->
exists n : nat, In n (freeVarFormula L f) /\ In v (freeVarTerm L (m n)).
Lemma freeVarSubAllFormula2 :
forall (f : fol.Formula L) (m : nat -> fol.Term L) (v n : nat),
In n (freeVarFormula L f) ->
In v (freeVarTerm L (m n)) -> In v (freeVarFormula L (subAllFormula f m)).
Lemma subSubAllTerm :
forall (t : fol.Term L) (m : nat -> fol.Term L) (v : nat) (s : fol.Term L),
substituteTerm L (subAllTerm t m) v s =
subAllTerm t (fun n : nat => substituteTerm L (m n) v s).
Lemma subSubAllTerms :
forall (n : nat) (ts : fol.Terms L n) (m : nat -> fol.Term L)
(v : nat) (s : fol.Term L),
substituteTerms L n (subAllTerms n ts m) v s =
subAllTerms n ts (fun n : nat => substituteTerm L (m n) v s).
Lemma subSubAllFormula :
forall (T : fol.System L) (f : fol.Formula L) (m : nat -> fol.Term L)
(v : nat) (s : fol.Term L),
folProof.SysPrf L T
(fol.iffH L (substituteFormula L (subAllFormula f m) v s)
(subAllFormula f (fun n : nat => substituteTerm L (m n) v s))).
Lemma subAllTermId :
forall t : fol.Term L, subAllTerm t (fun x : nat => fol.var L x) = t.
Lemma subAllTermsId :
forall (n : nat) (ts : fol.Terms L n),
subAllTerms n ts (fun x : nat => fol.var L x) = ts.
Lemma subAllFormulaId :
forall (T : fol.System L) (f : fol.Formula L),
folProof.SysPrf L T
(fol.iffH L (subAllFormula f (fun x : nat => fol.var L x)) f).
Lemma subAllSubAllTerm :
forall (t : fol.Term L) (m1 m2 : nat -> fol.Term L),
subAllTerm (subAllTerm t m1) m2 =
subAllTerm t (fun n : nat => subAllTerm (m1 n) m2).
Lemma subAllSubAllTerms :
forall (n : nat) (ts : fol.Terms L n) (m1 m2 : nat -> fol.Term L),
subAllTerms n (subAllTerms n ts m1) m2 =
subAllTerms n ts (fun n : nat => subAllTerm (m1 n) m2).
Lemma subAllSubAllFormula :
forall (T : fol.System L) (f : fol.Formula L) (m1 m2 : nat -> fol.Term L),
folProof.SysPrf L T
(fol.iffH L (subAllFormula (subAllFormula f m1) m2)
(subAllFormula f (fun n : nat => subAllTerm (m1 n) m2))).