Section RndDup.
Variable eta : nat.
Definition RndDup_G (A : Set)(ls : list A) (x : Bvector eta) :=
rs <-$ compMap _ (fun _ => {0, 1} ^ eta) ls;
ret (if (in_dec (EqDec_dec _) x rs) then true else false).
(* Definition RndDup_G q (x : Bvector eta) := rs <-$ compMap _ (fun _ => {0, 1} ^ eta) (allNatsLt q); ret (if (in_dec (EqDec_dec _) x rs) then true else false). *)
intros.
simpl.
remember (getSupport c1) as ls.
destruct ls.
unfold sumList.
simpl.
assert (Pr  [c1 ] == 0).
eapply getSupport_not_In_evalDist.
rewrite <- Heqls.
simpl.
intuition.
rewrite H.
assert (evalDist c1 false == 0).
eapply getSupport_not_In_evalDist.
rewrite <- Heqls.
simpl.
intuition.
rewrite H0.
repeat rewrite ratMult_0_l.
eapply ratAdd_0_l.
destruct b.
destruct ls.
unfold sumList.
simpl.
rewrite <- ratAdd_0_l.
rewrite ratAdd_0_r at 1.
eapply ratAdd_eqRat_compat.
intuition.
symmetry.
assert (evalDist c1 false == 0).
eapply getSupport_not_In_evalDist.
rewrite <- Heqls.
simpl.
intuition.
rewrite H.
eapply ratMult_0_l.
destruct b.
exfalso.
assert (NoDup (true :: true :: ls))%list.
rewrite Heqls.
eapply getSupport_NoDup.
inversion H; clear H; subst.
simpl in *.
intuition.
destruct ls.
unfold sumList.
simpl.
rewrite <- ratAdd_0_l.
intuition.
destruct b.
assert (NoDup (true :: false :: true :: ls)%list).
rewrite Heqls.
eapply getSupport_NoDup.
inversion H; clear H; subst.
simpl in *.
intuition.
assert (NoDup (true :: false :: false  :: ls)%list).
rewrite Heqls.
eapply getSupport_NoDup.
inversion H; clear H; subst.
inversion H3; clear H3; subst.
simpl in *.
intuition.
destruct ls.
unfold sumList.
simpl.
eapply ratAdd_eqRat_compat; intuition.
assert ( Pr  [c1 ] == 0).
eapply getSupport_not_In_evalDist.
rewrite <- Heqls.
simpl.
intuition.
rewrite H.
rewrite ratMult_0_l.
intuition.
destruct b.
destruct ls.
unfold sumList.
simpl.
rewrite <- ratAdd_0_l.
eapply ratAdd_comm.
destruct b.
assert (NoDup (false :: true :: true :: ls)%list).
rewrite Heqls.
eapply getSupport_NoDup.
inversion H; clear H; subst.
inversion H3; clear H3; subst.
simpl in *.
intuition.
assert (NoDup (false :: true :: false  :: ls)%list).
rewrite Heqls.
eapply getSupport_NoDup.
inversion H; clear H; subst.
simpl in *.
intuition.
assert (NoDup (false :: false  :: ls)%list).
rewrite Heqls.
eapply getSupport_NoDup.
inversion H; clear H; subst.
simpl in *.
intuition.
Qed.

Theorem Prob_or_indep :
forall (c1 c2 : Comp bool),
well_formed_comp c2 ->
Pr[b1 <-$ c1; b2 <-$ c2; ret (b1 || b2)] == Pr[c1] + (evalDist c1 false) * Pr[c2].