(* dat_better is an inductive predicate that lets us conclude that one tree will produce an approximation that is at least as good as some other tree. *)
Inductive dat_better(A : Set) : DistApproxTree A -> DistApproxTree A -> Prop :=
| dat_better_leaf_None : forall t,
  dat_better t (dat_leaf None)
| dat_better_leaf_Some : forall a,
  dat_better (dat_leaf (Some a)) (dat_leaf (Some a))
| dat_better_internal : forall ta1 ta2 tb1 tb2,
  dat_better ta1 tb1 ->
  dat_better ta2 tb2 ->
  dat_better (dat_internal ta1 ta2) (dat_internal tb1 tb2).(* dat_better is an inductive predicate that lets us conclude that one tree will produce an approximation that is at least as good as some other tree. *)
Inductive dat_better(A : Set) : DistApproxTree A -> DistApproxTree A -> Prop :=
| dat_better_leaf_None : forall t,
  dat_better t (dat_leaf None)
| dat_better_leaf_Some : forall a,
  dat_better (dat_leaf (Some a)) (dat_leaf (Some a))
| dat_better_internal : forall ta1 ta2 tb1 tb2,
  dat_better ta1 tb1 ->
  dat_better ta2 tb2 ->
  dat_better (dat_internal ta1 ta2) (dat_internal tb1 tb2).(* dat_better is an inductive predicate that lets us conclude that one tree will produce an approximation that is at least as good as some other tree. *)
Inductive dat_better(A : Set) : DistApproxTree A -> DistApproxTree A -> Prop :=
| dat_better_leaf_None : forall t,
  dat_better t (dat_leaf None)
| dat_better_leaf_Some : forall a,
  dat_better (dat_leaf (Some a)) (dat_leaf (Some a))
| dat_better_internal : forall ta1 ta2 tb1 tb2,
  dat_better ta1 tb1 ->
  dat_better ta2 tb2 ->
  dat_better (dat_internal ta1 ta2) (dat_internal tb1 tb2).(* dat_better is an inductive predicate that lets us conclude that one tree will produce an approximation that is at least as good as some other tree. *)
Inductive dat_better(A : Set) : DistApproxTree A -> DistApproxTree A -> Prop :=
| dat_better_leaf_None : forall t,
  dat_better t (dat_leaf None)
| dat_better_leaf_Some : forall a,
  dat_better (dat_leaf (Some a)) (dat_leaf (Some a))
| dat_better_internal : forall ta1 ta2 tb1 tb2,
  dat_better ta1 tb1 ->
  dat_better ta2 tb2 ->
  dat_better (dat_internal ta1 ta2) (dat_internal tb1 tb2).

Lemma dat_correct_bind_same_h : forall n (A : Set)(c : Comp A) ls t, dat_correct_h c ls n t -> forall (B : Set)(c1 : Comp B)(c2 : B -> Comp A) t1, c = Bind c1 c2 -> well_formed_comp c1 -> (forall a ls', evalDet_steps (cs_more c1 ls) (cs_done a ls') -> ls' = nil) -> dat_correct_h c1 ls n t1 -> datMap_depth (fun (depth : nat) (b : B) t2 => dat_correct_h (c2 b) nil depth t2) n t1 t.