Fixpoint datDepth (A : Set)(t : DistApproxTree A) : nat :=
  match t with
    | dat_leaf o => O
    | dat_internal t1 t2 =>
      S (max (datDepth t1) (datDepth t2))
  end.

(* Specifications: *)
Lemma datMap_depth_better' : forall (B : Set)(tb1 tb2 : DistApproxTree B), dat_better tb1 tb2 -> forall (A : Set)(rel : nat -> B -> DistApproxTree A -> Prop) n n' t1 t2, datMap_depth rel n tb1 t1 -> datMap (rel n') tb2 t2 -> n >= n' + (datDepth tb2) -> (forall b n1 n2 t1 t2, rel n1 b t1 -> rel n2 b t2 -> n1 >= n2 -> dat_better t1 t2) -> dat_better t1 t2.
Lemma datCorrect_datDepth : forall (A : Set)(c : Comp A) n t, dat_correct c n t -> (datDepth t <= n)%nat.
Lemma dat_better_bind_div2 : forall (A B : Set)(c1 : Comp B)(c2 : B -> Comp A) n t1 t2, dat_correct_bind c1 c2 n t1 -> dat_correct_bind2 c1 c2 (div2 n) t2 -> dat_better t1 t2.
Lemma lowDistApprox_bind_le_div2 : forall (A B : Set)(c1 : Comp B)(c2 : B -> Comp A) a n r1 r2, well_formed_comp c1 -> (forall b, In b (getSupport c1) -> well_formed_comp (c2 b)) -> lowDistApprox_bind c1 c2 a (div2 n) r1 -> lowDistApprox (Bind c1 c2) a n r2 -> r1 <= r2.
Lemma lowDistApprox_bind_left_total : forall (A B : Set)(c1 : Comp B)(c2 : B -> Comp A) a, well_formed_comp c1 -> (forall b, In b (getSupport c1) -> well_formed_comp (c2 b)) -> left_total (lowDistApprox_bind c1 c2 a).
Lemma lowDistApprox_bind_div2_left_total : forall (A B : Set)(c1 : Comp B)(c2 : B -> Comp A) a, well_formed_comp c1 -> (forall b, In b (getSupport c1) -> well_formed_comp (c2 b)) -> left_total (fun n => lowDistApprox_bind c1 c2 a (div2 n)).
Lemma rel_map_Rnd_NoDup : forall n ls, rel_map (evalDet (Rnd n)) (getAllBlists n) ls -> NoDup ls.
Lemma rel_map_Rnd_any_in : forall n ls (a : Bvector n), rel_map (evalDet (Rnd n)) (getAllBlists n) ls -> In (ca_done a) ls.