(*********************************************)
(* This file is part of the 'Higman' contrib *)
(* file : tree.v                             *)
(* contains : tree definition and its        *)
(*  associated induction principle           *)
(* author : W.Delobel                        *)
(*********************************************)
Set Implicit Arguments.
Require Export Arith.
Require Export List.
Section Wrap.
Unset Elimination Schemes.
Variable A : Set.
Variable leA : A -> A -> Prop.
Inductive tree : Set :=
| node : A -> list tree -> tree.
Section definitions.
Fixpoint tree_size (t : tree) : nat :=
match t with
| node _ l => S ((fix l_size (l : list tree) : nat :=
match l with
| nil => 0
| t' :: l' => (tree_size t') + (l_size l')
end) l)
end.
Definition root (t : tree) : A :=
match t with
| node a l => a
end.
Definition subtrees (t : tree) : list tree :=
match t with
| node _ l => l
end.
Inductive tree_in_forest : tree -> list tree -> Prop :=
| tif0 : forall t t' l, In t' l -> subtree t t' -> tree_in_forest t l
with subtree : tree -> tree -> Prop :=
| sub0 : forall t, subtree t t
| sub1 : forall t l ts, tree_in_forest t ts -> subtree t (node l ts).
End definitions.
Section tree_rect.
Variables
(P : tree -> Type)
(Q : list tree -> Type).
Hypotheses
(H1 : forall x, P (node x nil))
(H2 : forall f v, Q v -> P (node f v))
(H3 : Q nil)
(H4 : forall t v, P t -> Q v -> Q (t :: v)).
Fixpoint tree_rect_aux t : P t :=
match t as t return P t with
| node f v => H2 f
((fix vt_rect (v : list tree) : Q v :=
match v as v return Q v with
| nil => H3
| cons t' v' => H4 (tree_rect_aux t') (vt_rect v')
end) v)
end.
End tree_rect.
Set Elimination Schemes.
Inductive lforall (P : tree -> Type) : list tree -> Type :=
| lforall_nil : lforall P nil
| lforall_cons : forall a l, lforall P l -> P a -> lforall P (a::l).

(* Specifications: *)
Lemma tree_rect : forall P : tree -> Type,
(forall x, P (node x nil)) -> (forall f v, lforall P v -> P (node f v)) ->
forall t, P t.
Lemma tree_ind : forall P : tree -> Prop,
(forall x, P (node x nil)) -> (forall f v, (forall u, In u v -> P u) -> P (node f v)) ->
forall t, P t.