unfold G1, G2_1.
comp_skip.
eapply comp_spec_eq_impl_eq.
comp_skip.
eapply (@oc_comp_spec_eq _ _ _ _ _ _ _ _ _ _ _ _ _ _ (fun a b => forall x, arrayLookup _ a x = arrayLookup _ b x));
intuition.
eapply comp_spec_symm.
eapply comp_spec_consequence.
eapply randomFunc_mem_spec; intuition.
intuition.
comp_simp.
simpl in *.
intuition.
subst.
eapply comp_spec_eq_refl.
Qed.
Fixpoint arrayLookup_f (A B C : Set)(eqd : EqDec B)(ls : list ((A * B) * C))(a : B) :=
match ls with
| nil => None
| ((x, z), y) :: ls' =>
if (eqb a z) then (Some y) else (arrayLookup_f _ ls' a)
end.
Definition F_randomFunc k_in f d :=
match arrayLookup_f _ f (F k_in d) with
| Some r => ret (r, ((d, F k_in d), r) :: f)
| None => r <-$ {0, 1}^c; ret (r, ((d, F k_in d), r) :: f)
end.
Definition G2_2 :=
k_in <-$ {0, 1}^k;
[b, _] <-$2 A _ _ (F_randomFunc k_in) nil;
ret b.

(* Specifications: *)
Theorem G2_1_2_equiv :
Pr[G2_1] == Pr[G2_2].
Theorem arrayLookup_f_equiv :
forall (A B C : Set) (eqdb : EqDec B) (x1 : list (B * C)) (x2 : list (A * B * C)) (a : B),
list_pred
(fun c0 d =>
fst c0 = snd (fst d) /\ snd c0 = snd d) x1 x2 ->
arrayLookup _ x1 a = arrayLookup_f _ x2 a.