Section Trees.
Variable A : Set.
Inductive Tree : Set :=
node : A -> Forest -> Tree
with Forest : Set :=
| Nil_Forest : Forest
| Cons_Forest : Tree -> Forest -> Forest.
Fixpoint height_tree (t : Tree) : nat :=
match t with
| node a succs => S (height_forest succs)
end
with height_forest (succs : Forest) : nat :=
match succs with
| Nil_Forest => 0
| Cons_Forest t0 succs => max (height_tree t0) (height_forest succs)
end.
(* Inductive Tree : Set := | node : A -> (list Tree) -> Tree.  Fixpoint height_tree [t:Tree] : nat := Cases t of | (node a succs) => (S (height_forest succs)) end with height_forest[succs:(list Tree)] : nat := Cases succs of | nil => O | (cons t0 succs) => (max (height_tree t0) (height_forest succs)) end. Does not work!! *)
Definition root (t : Tree) := match t with
| node a _ => a
end.
Definition successors (t : Tree) := match t with
| node _ succs => succs
end.
Inductive In_Forest (t0 : Tree) : Forest -> Prop :=
| in_forest_head :
forall succs : Forest, In_Forest t0 (Cons_Forest t0 succs)
| in_forest_tail :
forall (t1 : Tree) (succs : Forest),
In_Forest t0 succs -> In_Forest t0 (Cons_Forest t1 succs).
intros t succs in_t.
elim in_t; clear in_t succs.
intros succs.
simpl in |- *.
apply le_n_max1.
intros t1 succs in_t le_t.
apply le_trans with (height_forest succs).
assumption.
simpl in |- *.
apply le_n_max2.
Qed.
intros P step.
cut (forall (n : nat) (t : Tree), height_tree t <= n -> P t).
intro claim.
intro t.
apply claim with (height_tree t).
trivial.
intros n; elim n; clear n.
intros t; elim t; clear t.
intros a succs u0.
elimtype False.
inversion_clear u0.
intros n ih t.
elim t; clear t.
intros a succs u0.
apply step; clear step.
intros t in_t.
apply ih; clear ih P.
apply le_S_n.
apply le_trans with (S (height_forest succs)).
apply le_n_S.
apply height_in_le; assumption.
assumption.
Qed.
intros P step.
cut (forall (n : nat) (t : Tree), height_tree t <= n -> P t).
intro claim.
intro t.
apply claim with (height_tree t).
trivial.
intros n; elim n; clear n.
intros t; elim t; clear t.
intros a succs u0.
elimtype False.
inversion_clear u0.
intros n ih t.
elim t; clear t.
intros a succs u0.
apply step; clear step.
intros t in_t.
apply ih; clear ih P.
apply le_S_n.
apply le_trans with (S (height_forest succs)).
apply le_n_S.
apply height_in_le; assumption.
assumption.
Qed.
(* Successor relation  *)
Inductive Successor : Tree -> Tree -> Prop :=
| successor_refl : forall t : Tree, Successor t t
| successor_trans :
forall t0 t1 : Tree,
In_Forest t1 (successors t0) ->
forall t2 : Tree, Successor t2 t1 -> Successor t2 t0.
intros t1 t2 u0 t0 u1.
generalize u0; clear u0.
elim u1; clear u1 t0 t1.
trivial.
intros t0 t1 in_t1 t3 suc_t3_t1 ih suc_t2_t3.
apply (successor_trans t0 t1 in_t1 t2).
apply ih; assumption.
Qed.
intros.
apply successor_refl.
Qed.

Lemma Succs_Tree_ind :
forall P : Tree -> Prop,
(forall a : A, P (node a Nil_Forest)) ->
(forall t0 t1 : Tree, Successor t0 t1 -> P t0 -> P t1) ->
forall t : Tree, P t.