Section Build.
Variable A : Type.
Variable f : A -> nat.
(* Iterative the one step predicate *)
Inductive build : list (btree A) -> btree A -> Prop :=
| build_one : forall t : btree A, build (t :: nil) t
| build_step :
forall (t : btree A) (l1 l2 : list (btree A)),
one_step f l1 l2 -> build l2 t -> build l1 t.
Proof using.
intros l t H; elim H; clear H l t; auto.
intros t l1 l2 (l3, (t1, (t2, (HH, (HH1, HH2))))) H0 H1; try assumption.
apply cover_node with (1 := HH1); auto.
apply cover_permutation with (2 := HH2); auto.
Qed.
Proof using.
intros l1 l2 t1 t2 H; generalize l2 t2; elim H; clear H l1 t1 l2 t2.
intros t l2 t2 H H0 (l3, (l4, (H1, (H2, H3)))).
generalize H0; inversion H; clear H0.
simpl in |- *; repeat rewrite <- plus_n_O; auto.
case H4.
intros l5 (t3, (t4, (H8, (H9, H10)))).
absurd (length l2 = length (t3 :: t4 :: l5)).
rewrite permutation_length with (1 := H2).
rewrite <- length_map with (f := sum_leaves f) (l := l4).
rewrite <- H3.
rewrite length_map with (f := sum_leaves f).
rewrite permutation_length with (1 := permutation_sym _ _ _ H1).
simpl in |- *; red in |- *; intros; discriminate.
apply permutation_length with (1 := H9).
intros t l1 l2 H H0 H1 l0 t2 H2 H3 H4.
inversion H2.
case H.
intros l5 (t3, (t4, (H8, (H9, H10)))).
case H4.
intros l6 (l7, (H11, (H12, H13))).
absurd (length l1 = length (t3 :: t4 :: l5)).
rewrite permutation_length with (1 := H11).
rewrite <- length_map with (f := sum_leaves f) (l := l6).
rewrite H13.
rewrite length_map with (f := sum_leaves f).
rewrite permutation_length with (1 := permutation_sym _ _ _ H12).
rewrite <- H5; simpl in |- *; red in |- *; intros; discriminate.
apply permutation_length with (1 := H9).
apply H1 with (1 := H6).
case one_step_comp with (3 := H) (4 := H5); auto.
case one_step_comp with (3 := H) (4 := H5); auto.
Qed.

(* Two built trees have same weight *)
Theorem build_same_weight_tree :
forall (l : list (btree A)) (t1 t2 : btree A),
build l t1 -> build l t2 -> weight_tree f t1 = weight_tree f t2.