Section FOL.
Context {Sigma : Signature}.
(* **** Subformula *)
Inductive sf : form -> form -> Prop :=
| SImplL phi psi : sf phi (phi --> psi)
| SImplR phi psi : sf psi (phi --> psi)
| SAll phi t : sf (phi [t .: ids]) (∀ phi).
Hint Constructors sf : core.
(* **** Formula size *)
Fixpoint size (phi : form ) :=
match phi with
| Pred _ _ => 0
| Fal => 0
| Impl phi psi => S (size phi + size psi)
| All phi => S (size phi)
end.
(* **** Forall and Vector.t technology **)
Inductive Forall (A : Type) (P : A -> Type) : forall n, vector A n -> Type :=
| Forall_nil : Forall P (@Vector.nil A)
| Forall_cons : forall n (x : A) (l : vector A n), P x -> Forall P l -> Forall P (@Vector.cons A x n l).
Inductive vec_in (A : Type) (a : A) : forall n, vector A n -> Type :=
| vec_inB n (v : vector A n) : vec_in a (cons a v)
| vec_inS a' n (v :vector A n) : vec_in a v -> vec_in a (cons a' v).
Hint Constructors vec_in : core.
(* **** Unused variable **)
Inductive unused_term (n : nat) : term -> Prop :=
| uft_var m : n <> m -> unused_term n (var_term m)
| uft_Func F v : (forall t, vec_in t v -> unused_term n t) -> unused_term n (Func F v).
Inductive unused (n : nat) : form -> Prop :=
| uf_Fal : unused n Fal
| uf_Pred P v : (forall t, vec_in t v -> unused_term n t) -> unused n (Pred P v)
| uf_Impl phi psi : unused n phi -> unused n psi -> unused n (Impl phi psi)
| uf_All phi : unused (S n) phi -> unused n (All phi).
Definition unused_L n A := forall phi, List.In phi A -> unused n phi.
Definition closed phi := forall n, unused n phi.
Proof with eauto using unused.
induction phi.
- exists 0...
- destruct (@vec_unused _ t) as [k H]. 1: eauto using find_unused_term. exists k. eauto using unused.
- destruct IHphi1, IHphi2. exists (x + x0). intros m Hm. constructor; [ apply u | apply u0 ]; lia.
- destruct IHphi. exists x. intros m Hm. constructor. apply u. lia.
Qed.
Definition capture n phi := nat_rect _ phi (fun _ => All) n.
Definition close phi := capture (proj1_sig (find_unused phi)) phi.
Fixpoint big_imp A phi :=
match A with
| List.nil => phi
| a :: A' => a --> (big_imp A' phi)
end.
(* **** Substituting unused variables *)
Definition shift_P P n :=
match n with
| O => False
| S n' => P n'
end.

Lemma subst_unused_term xi sigma P t :
(forall x, dec (P x)) -> (forall m, ~ P m -> xi m = sigma m) -> (forall m, P m -> unused_term m t) ->
subst_term xi t = subst_term sigma t.