intuition.
eapply det_eq_impl_dist_sem_eq; trivial.
destruct H0.
eapply well_formed_Repeat; trivial.
unfold eq_dec.
intuition.
eapply (EqDec_dec _).
eauto.
econstructor; intuition.
destruct (P b).
econstructor.
destruct H0.
econstructor.
unfold eq_dec.
intuition.
eapply (EqDec_dec _).
trivial.
eauto.
unfold DetSem.evalDet_equiv.
intuition.
inversion H1; clear H1; subst.
inversion H2; clear H2; subst.
simpl in *.
eapply evalDet_steps_bind_done_inv in H6.
destruct H6.
destruct H1.
intuition.
econstructor.
eapply evalDet_steps_trans.
eapply evalDet_steps_bind_done.
eauto.
destruct (P x).
inversion H3; clear H3; subst.
simpl in *.
inversion H7; clear H7; subst.
econstructor.
eauto.
simpl.
2:eassumption.
constructor.
inversion H2; clear H2; subst.
simpl in *.
apply evalDet_steps_bind_eof_inv in H6.
intuition.
econstructor.
eapply evalDet_bind_eof.
trivial.
destruct H1.
destruct H1.
intuition.
econstructor.
eapply evalDet_steps_trans.
eapply evalDet_steps_bind_done.
eauto.
destruct (P x).
inversion H3; clear H3; subst.
simpl in *.
inversion H7.
trivial.
inversion H1; clear H1; subst.
eapply evalDet_steps_bind_done_inv in H2.
destruct H2.
destruct H1.
intuition.
econstructor.
econstructor.
eauto.
simpl.
eapply evalDet_steps_trans.
eapply evalDet_steps_bind_done.
eauto.
destruct (P x).
inversion H3; clear H3; subst.
simpl in *.
inversion H7; clear H7; subst.
econstructor.
eauto.
simpl.
2:eassumption.
constructor.
apply evalDet_steps_bind_eof_inv in H2.
intuition.
econstructor.
econstructor.
eauto.
simpl.
eapply evalDet_bind_eof.
trivial.
destruct H1.
destruct H1.
intuition.
econstructor.
econstructor.
eauto.
simpl.
eapply evalDet_steps_trans.
eapply evalDet_steps_bind_done.
eauto.
destruct (P x).
inversion H3; clear H3; subst.
simpl in *.
inversion H7.
trivial.
Qed.

(* rules related to case splits and specifications *)
Lemma evalDist_seq_case_split_eq : forall (B : Set)(e : B -> bool) v v1 v2 (A : Set)(c : Comp B)(f : B -> Comp A) a,
well_formed_comp c ->
Pr[b <-$ c; ret (e b)] == v ->
(forall b, (e b) = true -> (evalDist (f b) a) == v1) ->
(forall b, (e b) = false -> (evalDist (f b) a) == v2) ->
(evalDist (Bind c f) a == v * v1 + (ratSubtract 1 v) * v2).