unfold TrueMult_G, TrueSingle_G.
simpl in *.
eapply leRat_trans.
2:{
eapply eqRat_impl_leRat.
eapply sumList_factor_constant_l.
}
eapply sumList_le.
intuition.
eapply leRat_trans.
2:{
eapply eqRat_impl_leRat.
symmetry.
rewrite ratMult_comm.
eapply ratMult_assoc.
}
eapply ratMult_leRat_compat.
intuition.
specialize (@compMap_Q_eq_compFold _ _ Q n (c a) false); intuition.
rewrite H0.
rewrite prob_sum_le_mult.
rewrite ratMult_comm.
eapply ratMult_leRat_compat; intuition.
Local Transparent evalDist.
simpl.
reflexivity.
Qed.
End TrueSingle_impl_Mult.
Section TrueMult_impl_Repeat.
Variable A B : Set.
Hypothesis eqdb : EqDec B.
Variable A1 : Comp A.
Hypothesis A1_wf :
well_formed_comp A1.
Variable c : A -> Comp B.
Variable f P : B -> bool.
Hypothesis c_wf :
forall x, In x (getSupport A1) -> well_formed_comp (c x).
Hypothesis Repeat_c_terminating :
forall x, In x (getSupport A1) ->
exists x1 : B, In x1 (filter P (getSupport (c x))).
Definition TrueRepeat_G :=
a <-$ A1;
b <-$ Repeat (c a) P;
ret (f b).
Variable n : nat.
Variable failProb : Rat.
Hypothesis failProb_correct :
forall (a : A),
In a (getSupport A1) ->
Pr[x <-$ c a; ret negb (P x)] <= failProb.
Definition TrueRepeat_G1 :=
a <-$ A1;
bs <-$ compMap _ (fun _ => c a) (forNats n);
b_opt <- hd_error (filter P bs);
b' <-$ Repeat (c a) P;
b <- match b_opt with
| None => b'
| Some x => x
end;
ret (f b).

(* Specifications: *)
Theorem  TrueRepeat_G_G1_equiv :
Pr[ TrueRepeat_G] == Pr[TrueRepeat_G1].