Proof using.
intros l1 l2 t H; generalize l2; elim H; clear H l1 l2 t; auto.
intros t l2 H; rewrite permutation_one_inv with (1 := H); auto.
apply build_one.
intros t l1 l2 H H0 H1 l0 H2.
apply build_step with (l2 := l2); auto.
case H.
intros l3 (t1, (t2, (HH1, (HH2, HH3)))).
exists l3; exists t1; exists t2; repeat (split; auto).
apply permutation_trans with (2 := HH2); auto.
apply permutation_sym; auto.
Qed.
Definition obuildf :
forall l : list (btree A),
l <> nil -> ordered (sum_order f) l -> {t : btree A | build l t}.
intros l; elim l using list_length_induction.
intros l1; case l1; clear l1.
intros H H0; case H0; auto.
intros b l0; case l0.
intros H H0 H1; exists b; auto.
apply build_one.
intros b0 l1 H H0 H1.
case (H (insert (le_sum f) (node b b0) l1)); auto.
rewrite <-
permutation_length
with
(1 := insert_permutation _ (le_sum f) l1 (node b b0));
simpl in |- *; auto.
red in |- *; intros H2;
absurd
(length (node b b0 :: l1) = length (insert (le_sum f) (node b b0) l1)).
rewrite H2; simpl in |- *; intros; discriminate.
apply
permutation_length
with (1 := insert_permutation _ (le_sum f) l1 (node b b0));
simpl in |- *; auto.
apply insert_ordered; auto.
intros; apply le_sum_correct1; auto.
intros; apply le_sum_correct2; auto.
apply ordered_inv with (a := b0); auto.
apply ordered_inv with (a := b); auto.
intros t Ht; exists t.
apply build_step with (2 := Ht).
red in |- *; auto.
exists l1; exists b; exists b0; (repeat split; auto).
apply permutation_sym; apply insert_permutation.
Defined.
(* a function to buid tree from a cover list merging smaller trees *)
Definition buildf :
forall l : list (btree A), l <> nil -> {t : btree A | build l t}.
intros l Hl; cut (isort (le_sum f) l <> nil).
intros H1; cut (ordered (sum_order f) (isort (le_sum f) l)).
intros H2; case (obuildf (isort (le_sum f) l) H1 H2).
intros t H3; exists t; auto.
apply build_permutation with (1 := H3); auto.
apply permutation_sym; apply isort_permutation; auto.
apply isort_ordered; auto.
intros; apply le_sum_correct1; auto.
intros; apply le_sum_correct2; auto.
Contradict Hl; apply permutation_nil_inv; auto.
rewrite <- Hl; auto.
apply isort_permutation; auto.
Defined.

(* Merging smaller trees gets the tree of mimimal weight for the given cover *)
Theorem build_correct :
forall (l : list (btree A)) (t : btree A),
l <> nil -> build l t -> cover_min _ f l t.