(* Copyright 2012-2015 by Adam Petcher.				* * Use of this source code is governed by the license described	* * in the LICENSE file at the root of the source tree.		*)
Set Implicit Arguments.
Local Open Scope nat_scope.
Opaque getSupport.
induction 1; intuition; simpl in *.
(* Bind case *)
repeat simp_in_support.
destruct x.
rewrite mult_plus_distr_r.
pose proof H4.
eapply (IHqueries_at_most _ count) in H4.
eapply (H1 _ _ S count) in H5.
rewrite H5.
rewrite plus_comm.
rewrite <- (plus_assoc).
rewrite (plus_comm (q2 * n)).
rewrite plus_assoc.
eapply plus_le_compat.
eauto.
eapply le_refl.
intuition.
intuition.
(* query case *)
rewrite plus_0_r.
eapply H; eauto.
(* ret case *)
Transparent getSupport.
repeat simp_in_support.
intuition.
(* run case *)
repeat simp_in_support.
destruct x.
simpl in *.
specialize (IHqueries_at_most (S * S0)%type (fun p =>  count (snd p)) _
(fun (x : S * S0) (y : A) =>
p <-$ (oc (fst x) y) S0 eqds0 o (snd x);
ret (fst (fst p), (snd (fst p), snd p)))
(s, s0) (q2 * n)
).
eapply le_trans.
eapply IHqueries_at_most.
intuition.
simpl.
repeat simp_in_support.
destruct x.
simpl in *.
eapply H1.
eauto.
eauto.
eauto.
simpl.
rewrite mult_assoc.
intuition.
(* trans case *)
eapply le_trans.
eapply IHqueries_at_most.
eauto.
eauto.
eapply plus_le_compat; intuition.
eapply mult_le_compat; intuition.
Grab Existential Variables.
repeat econstructor.
eauto.
Qed.
Local Open Scope rat_scope.

Theorem evalDist_bind_event_le :
forall (A : Set)(c : Comp A)(f : A -> Comp bool)(evta : A -> bool) (k1 k2 : Rat),
Pr[a <-$ c; ret (evta a)] <= k1 ->
(forall a, In a (getSupport c) -> evta a = false -> Pr[f a] <= k2) ->
Pr[a <-$ c; f a] <= k1 + k2.