Section HeightPred.
Variable A : Type.
Variable f : A -> nat.
Variable eqA_dec : forall a b : A, {a = b} + {a <> b}.
(* A predicate that associates an initial height, a list of height, a cover and a tree *)
Inductive height_pred : nat -> list nat -> list (btree A) -> btree A -> Prop :=
| height_pred_nil :
forall (n : nat) (t : btree A), height_pred n (n :: nil) (t :: nil) t
| height_pred_node :
forall (n : nat) (ln1 ln2 : list nat) (t1 t2 : btree A)
(l1 l2 : list (btree A)),
height_pred (S n) ln1 l1 t1 ->
height_pred (S n) ln2 l2 t2 ->
height_pred n (ln1 ++ ln2) (l1 ++ l2) (node t1 t2).
Hint Resolve height_pred_nil height_pred_node : core.
Proof using.
intros n ln t l H; elim H; simpl in |- *; auto.
Qed.
Proof using.
intros n ln t l H; elim H; simpl in |- *; auto.
intros; discriminate.
intros n0 ln1 ln2 t1 t2 l1 l2 H0; case ln1; simpl in |- *; auto.
intros; discriminate.
Qed.
Proof using.
intros n ln t l H; elim H; simpl in |- *; auto.
intros; discriminate.
intros n0 ln1 ln2 t1 t2 l1 l2 H0; case l1; simpl in |- *; auto.
intros; discriminate.
Qed.
Proof using.
intros n ln t l H; elim H; simpl in |- *; auto.
intros; repeat rewrite length_app; auto with arith.
Qed.

(* The height and cover list gives a simple relation between weight_tree, sum_leaves and the product of the two lists *)
Theorem height_pred_weight :
forall (n : nat) (ln : list nat) (t : btree A) (l : list (btree A)),
height_pred n ln l t ->
n * sum_leaves f t + weight_tree f t = prod2list f ln l.