(* Use the fundamental lemma, where the "bad" event is that the counter in the oracle gets a value > q.  Then use the qam_count theorem from RndInList to show that the probability of this event is 0.  *)
rewrite G1_eq_G1_count .
rewrite Gi_eq_Gi_count.
eapply ratIdentityIndiscernables.
eapply leRat_impl_eqRat.
eapply leRat_trans.
eapply fundamental_lemma_h.
(* bad events the same*)
unfold G1_count, Gi_count.
fcf_inline_first.
fcf_skip.
fcf_simp.
fcf_inline_first.
fcf_to_prhl.
comp_skip.
apply O1_count_Oi_eq_until_bad.
simpl in H1.
intuition; subst.
fcf_simp.
simpl in *.
fcf_spec_ret; fcf_compute.
(* equal until bad *)
intuition.
unfold G1_count, Gi_count.
fcf_skip.
fcf_simp.
fcf_to_prhl.
comp_skip.
eapply O1_count_Oi_eq_until_bad.
simpl in *; intuition.
fcf_simp.
destruct p; simpl in *.
fcf_spec_ret; fcf_compute;
assert (b1 <= q)%nat by omega; intuition; subst; pairInv; trivial.
(* probability of bad event is 0 *)
unfold G1_count.
fcf_inline_first.
fcf_irr_l.
fcf_simp.
inline_first.
fcf_irr_l.
apply oc_comp_wf; intuition.
eapply O1_count_wf.
fcf_simp.
unfold snd.
fcf_compute.
destruct p.
(* The qam_count theorem takes a function that produces a "count" from the state of the oracle.  This theorem assumes this count increases by at most 1 in each call to the oracle, and that the number of queries is at most q.  Then the result is that the final count is at most q. *)
eapply (qam_count (A1_qam s s0 _) (fun x => snd x)) in H0.
simpl in *.
omega.
intuition.
simpl.
apply O1_count_increases in H1.
omega.
trivial.
eapply rat0_le_all.
Grab Existential Variables.
eauto.
Qed.

(* Specifications: *)
(* Step 2: show that G2 is the same as (Gi 0).  This is much simpler. *)
Theorem G2_eq_Gi_0 :
Pr[G2] == Pr[Gi 0%nat].