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.
Proof using.
intros l t1 t2 H H0; apply build_comp with (l1 := l) (l2 := l); auto.
exists l; exists l; simpl in |- *; auto.
Qed.
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.