unfold left_total.
intuition.
destruct (@dat_exists n _ c).
trivial.
exists (lowDistApproxFromTree eqd x a).
eapply low_tree_approx_same.
trivial.
trivial.
Qed.
Inductive datMap(A B : Set)(f : A -> DistApproxTree B -> Prop) : DistApproxTree A -> DistApproxTree B  -> Prop :=
| datMap_leaf_None :
datMap f (dat_leaf None) (dat_leaf None)
| datMap_leaf_Some :
forall a t,
f a t ->
datMap f (dat_leaf (Some a)) t
| datMap_internal :
forall t1a t2a t1b t2b,
datMap f t1a t1b ->
datMap f t2a t2b ->
datMap f (dat_internal t1a t2a) (dat_internal t1b t2b).
(* a variant of datMap that builds a tree of a maximum depth *)
Inductive datMap_depth(A B : Set)(f : nat -> A -> DistApproxTree B -> Prop) : nat -> DistApproxTree A -> DistApproxTree B -> Prop :=
| datMap_depth_leaf_None :
forall n,
datMap_depth f n (dat_leaf None) (dat_leaf None)
| datMap_depth_leaf_Some :
forall n a t,
f n a t ->
datMap_depth f n (dat_leaf (Some a)) t
| datMap_depth_internal :
forall n t1a t2a t1b t2b,
datMap_depth f n t1a t1b ->
datMap_depth f n t2a t2b ->
datMap_depth f (S n) (dat_internal t1a t2a) (dat_internal t1b t2b).
Definition dat_correct_bind(A B : Set)(c1 : Comp B)(c2 : B -> Comp A)(n : nat)(t : DistApproxTree A) :=
exists tb, dat_correct c1 n tb /\
(datMap_depth (fun n' b ta => (dat_correct (c2 b) n' ta)) n tb t).
Definition dat_correct_bind2(A B : Set)(c1 : Comp B)(c2 : B -> Comp A)(n : nat)(t : DistApproxTree A) :=
exists tb, dat_correct c1 n tb /\
(datMap (fun b ta => (dat_correct (c2 b) n ta)) tb t).

(* Specifications: *)
Lemma lowDistApproxFromTree_eq_0 : forall (A : Set)(eqd : eq_dec A)(t : DistApproxTree A) a,
~In a (getTreeSupport eqd t) ->
lowDistApproxFromTree eqd t a == 0.