Section Formula_Depth_Induction.
Fixpoint depth (A : Formula) : nat :=
match A with
| equal _ _ => 0
| atomic _ _ => 0
| impH A B => S (max (depth A) (depth B))
| notH A => S (depth A)
| forallH _ A => S (depth A)
end.
Definition lt_depth (A B : Formula) : Prop := depth A < depth B.
Definition Formula_depth_rec_rec :
forall P : Formula -> Set,
(forall a : Formula, (forall b : Formula, lt_depth b a -> P b) -> P a) ->
forall (n : nat) (b : Formula), depth b <= n -> P b.
intros P H n.
induction n as [| n Hrecn].
intros.
apply H.
intros.
unfold lt_depth in H1.
rewrite <- (le_n_O_eq _ H0) in H1.
elim (lt_n_O _ H1).
intros.
apply H.
intros.
apply Hrecn.
apply lt_n_Sm_le.
apply lt_le_trans with (depth b).
apply H1.
apply H0.
Defined.
Definition Formula_depth_rec (P : Formula -> Set)
(rec : forall a : Formula, (forall b : Formula, lt_depth b a -> P b) -> P a)
(a : Formula) : P a :=
Formula_depth_rec_rec P rec (depth a) a (le_n (depth a)).

Lemma Formula_depth_rec_indep :
forall (Q P : Formula -> Set)
(rec : forall a : Formula,
(forall b : Formula, lt_depth b a -> Q b -> P b) -> Q a -> P a),
(forall (a : Formula)
(z1 z2 : forall b : Formula, lt_depth b a -> Q b -> P b),
(forall (b : Formula) (p : lt_depth b a) (q : Q b), z1 b p q = z2 b p q) ->
forall q : Q a, rec a z1 q = rec a z2 q) ->
forall (a : Formula) (q : Q a),
Formula_depth_rec (fun x : Formula => Q x -> P x) rec a q =
rec a
(fun (b : Formula) _ =>
Formula_depth_rec (fun x : Formula => Q x -> P x) rec b) q.