induction x1; inversion 1; intuition; simpl in *.
subst.
destruct a.
destruct a2.
simpl in *.
subst.
destruct p.
simpl.
destruct (eqb a0 b0 ); intuition.
Qed.
erewrite arrayLookup_f_equiv ; eauto.
destruct (arrayLookup_f (Bvector_EqDec b) x2 (F x a) ); intuition.
eapply comp_spec_ret; intuition.
simpl.
econstructor.
simpl.
intuition.
trivial.
comp_skip.
apply (oneVector c).
apply (oneVector c).
eapply comp_spec_ret; intuition.
simpl.
econstructor.
intuition.
eauto.
comp_simp.
simpl in *; intuition.
subst.
eapply comp_spec_eq_refl.
Qed.
Fixpoint findCollision_1 (A B : Set)(eqda : EqDec A)(eqdb : EqDec B)(ls : list (A * B))(a : A)(b : B) :=
match ls with
| nil => None
| (a', b') :: ls' => if
(eqb b b' && (negb (eqb a a')))
then (Some a') else (findCollision_1 _ _ ls' a b)
end.
Definition collidesWith (A B : Set)(eqda : EqDec A)(eqdb : EqDec B)(ls : list (A * B))(a : A) b :=
if (findCollision_1 _ _ ls a b) then true else false.
Fixpoint findCollision(A B : Set)(eqda : EqDec A)(eqdb : EqDec B)(ls : list (A * B)) : option (A * A * B) :=
match ls with
| nil => None
| (a, b) :: ls' => let a' := (findCollision_1 _ _ ls' a b) in
match a' with
| None =>  (findCollision _ _ ls')
| Some p' => Some (a, p', b)
end
end.
Definition funcCollision (A B : Set)(eqda : EqDec A)(eqdb : EqDec B)(ls : list (A * B)) :=
if (findCollision _ _ ls) then true else false.
Definition G2_3 :=
k_in <-$ {0, 1}^k;
[b, f] <-$2 A _ _ (F_randomFunc k_in) nil;
ret (b, funcCollision _ _ (fst (split f))).

(* Specifications: *)
Theorem G2_2_3_equiv :
Pr[G2_2] == Pr[x <-$ G2_3; ret fst x].