(* number of nodes in the syntax tree of a formula *)
Fixpoint size s :=
match s with
| var _ => 1
| arr s t => S (size s + size t)
end.
(* list of first k arguments *)
Fixpoint arguments (k: nat) (t: formula) :=
match k with
| 0 => []
| S k =>
match t with
| var _ => []
| arr s t => s :: (arguments k t)
end
end.
(* target after first k arguments *)
Fixpoint target (k: nat) (t: formula) :=
match k with
| 0 => t
| S k =>
match t with
| var _ => t
| arr _ t => target k t
end
end.
(* Hilbert-style calculus with derivation depth *)
Inductive der (Gamma: list formula) : nat -> formula -> Prop :=
| der_var {ζ: nat -> formula} {s t: formula} {k n: nat} :
In s Gamma ->
Forall (der Gamma n) (arguments k (substitute ζ s)) ->
target k (substitute ζ s) = t ->
der Gamma (S n) t.

(* can be replaced by derE *)
Lemma der_0E {n Gamma t} : der Gamma n t -> n = S (Nat.pred n).