induction t; intuition.
inversion H1; clear H1; subst.
inversion H4; clear H4; subst.
inversion H2; clear H2; subst.
simpl in *.
apply evalDet_steps_bind_done_inv in H6.
destruct H6. destruct H1.
intuition.
assert (evalDet_steps (cs_more c (ls1 ++ ls2)) (cs_done a (nil ++ ls2))).
eapply evalDet_steps_app_eq.
eauto.
simpl in *.
specialize (evalDet_steps_done_func H1 H2); intuition; subst.
clear H1.
econstructor.
econstructor.
rewrite H0 in H3.
eauto.
econstructor.
intuition.
inversion H1; clear H1; subst.
eapply H4.
econstructor.
econstructor.
eauto.
simpl.
eapply evalDet_steps_trans.
eapply evalDet_steps_bind_done.
eapply evalDet_steps_app_eq.
eauto.
rewrite H0.
simpl.
eauto.
inversion H1; clear H1; subst.
econstructor.
intuition.
inversion H1; clear H1; subst.
eapply H4.
econstructor.
econstructor.
eauto.
simpl.
eapply evalDet_steps_trans.
eapply evalDet_steps_bind_done.
eapply evalDet_steps_app_eq.
eauto.
rewrite H0.
simpl.
eauto.
eapply IHt1.
eauto.
trivial.
rewrite app_assoc.
trivial.
eapply IHt2.
eauto.
trivial.
rewrite app_assoc.
trivial.
Qed.
Inductive datRepeat_depth (A : Set)(f : nat -> DistApproxTree A -> Prop)(P : A -> bool) : nat -> nat -> DistApproxTree A -> DistApproxTree A -> Prop :=
| datRepeat_depth_leaf_None : forall n depth,
datRepeat_depth f P n depth (dat_leaf None) (dat_leaf None)
| datRepeat_depth_leaf_Some_yes : forall a n depth,
P a = true ->
datRepeat_depth f P n depth (dat_leaf (Some a)) (dat_leaf (Some a))
| datRepeat_depth_leaf_Some_no : forall a depth,
P a = false ->
datRepeat_depth f P O depth (dat_leaf (Some a)) (dat_leaf None)
| datRepeat_depth_leaf_Some_repeat : forall a t t' n depth,
P a = false ->
f depth t ->
datRepeat_depth f P n depth t t' ->
datRepeat_depth f P (S n) depth (dat_leaf (Some a)) t'
| datRepeat_depth_internal : forall n depth t1 t2 t1' t2',
datRepeat_depth f P n depth t1 t1' ->
datRepeat_depth f P n depth t2 t2' ->
datRepeat_depth f P n (S depth) (dat_internal t1 t2) (dat_internal t1' t2').
Definition dat_correct_repeat(A : Set) (c : Comp A)(P : A -> bool)(n : nat)(t : DistApproxTree A) :=
exists t1 : DistApproxTree A,
dat_correct c n t1 /\
datRepeat_depth (dat_correct c) P n n t1 t.

(* Specifications: *)
Lemma datRepeat_depth_0 : forall n2 n1 (A : Set)(f : nat -> DistApproxTree A -> Prop) P t1 t2,
datRepeat_depth f P n1 O t1 t2 ->
n2 >= n1 ->
f O (dat_leaf None) ->
datRepeat_depth f P n2 O t1 t2.