Section Free_Variables.
Fixpoint freeVarTerm (s : fol.Term L) : list nat :=
match s with
| fol.var v => v :: nil
| fol.apply f ts => freeVarTerms (arity L (inr _ f)) ts
end
with freeVarTerms (n : nat) (ss : fol.Terms L n) {struct ss} :
list nat :=
match ss with
| Tnil => nil (A:=nat)
| Tcons m t ts => freeVarTerm t ++ freeVarTerms m ts
end.
Fixpoint freeVarFormula (A : fol.Formula L) : list nat :=
match A with
| fol.equal t s => freeVarTerm t ++ freeVarTerm s
| fol.atomic r ts => freeVarTerms _ ts
| fol.impH A B => freeVarFormula A ++ freeVarFormula B
| fol.notH A => freeVarFormula A
| fol.forallH v A => list_remove _ eq_nat_dec v (freeVarFormula A)
end.
Definition ClosedSystem (T : fol.System L) :=
forall (v : nat) (f : fol.Formula L),
mem _ T f -> ~ In v (freeVarFormula f).
Definition closeList (l : list nat) (x : fol.Formula L) :
fol.Formula L :=
list_rec (fun _ => fol.Formula L) x
(fun (a : nat) _ (rec : fol.Formula L) => forallH a rec) l.
Definition close (x : fol.Formula L) : fol.Formula L :=
closeList (no_dup _ eq_nat_dec (freeVarFormula x)) x.
intro.
induction l as [| a l Hrecl].
intros.
elim H.
intros.
induction H as [H| H].
simpl in |- *.
rewrite H.
unfold not in |- *; intros.
elim (In_list_remove2 _ _ _ _ _ H0).
auto.
simpl in |- *.
unfold not in |- *.
intros.
assert
(In v
(freeVarFormula
(list_rec (fun _ => fol.Formula L) x
(fun (a : nat) (_ : list nat) (rec : fol.Formula L) =>
forallH a rec) l))).
eapply In_list_remove1.
apply H0.
apply (Hrecl _ _ H H1).
Qed.
intro.
induction l as [| a l Hrecl].
simpl in |- *.
auto.
simpl in |- *.
intros.
apply Hrecl.
eapply In_list_remove1.
apply H.
Qed.
intros.
unfold close in |- *.
induction (In_dec eq_nat_dec v (no_dup _ eq_nat_dec (freeVarFormula x))).
apply freeVarClosedList1.
auto.
unfold not in |- *; intros.
elim b.
apply no_dup1.
eapply freeVarClosedList2.
apply H.
Qed.
Fixpoint freeVarListFormula (l : fol.Formulas L) :
list nat :=
match l with
| nil => nil (A:=nat)
| f :: l => freeVarFormula f ++ freeVarListFormula l
end.

Lemma In_freeVarListFormulaE :
forall (v : nat) (F : fol.Formulas L),
In v (freeVarListFormula F) ->
exists f : fol.Formula L, In v (freeVarFormula f) /\ In f F.