(* 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.(* 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.(* 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.

(* Specifications: *)
Theorem build_cover : forall l t, build l t -> cover l t.
Theorem build_comp : forall (l1 l2 : list (btree A)) (t1 t2 : btree A), build l1 t1 -> build l2 t2 -> weight_tree_list f l1 = weight_tree_list f l2 -> same_sum_leaves f l1 l2 -> weight_tree f t1 = weight_tree f t2.
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.
Theorem build_permutation : forall (l1 l2 : list (btree A)) (t : btree A), build l1 t -> permutation l1 l2 -> build l2 t.