(* 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.
Open Scope list_scope.
Section DistSingle.
Variable A B : Set.
Hypothesis B_EqDec : EqDec B.
Variable c1 c2 : A -> Comp B.
Variable A_State : Set.
Variable A1 : Comp (A * A_State).
Variable A2 : A_State -> B -> Comp bool.
Definition DistSingle_G(c : A -> Comp B) :=
[a, s_A] <-$2 A1;
b <-$ c a;
A2 s_A b.
Definition DistSingle_Adv :=
| Pr[DistSingle_G c1] - Pr[DistSingle_G c2] |.
End DistSingle.
Section ListHybrid.
Variable A B State : Set.
Variable defA : A.
Variable c1 c2 : A -> Comp B.
Hypothesis c1_wf : forall a, well_formed_comp (c1 a).
Hypothesis c2_wf : forall a, well_formed_comp (c2 a).
Hypothesis A_EqDec : EqDec A.
Hypothesis B_EqDec : EqDec B.
Hypothesis State_EqDec : EqDec State.
Variable A1 : Comp ((list A) * State).
Variable A2 : State -> list B -> Comp bool.
Variable maxA : nat.
Hypothesis maxA_correct :
forall ls s_A,
In (ls, s_A) (getSupport A1) ->
(length ls <= maxA)%nat.
Definition ListHybrid_G (c : A -> Comp B) :=
[lsA, s_A] <-$2 A1;
lsB <-$ compMap _ c lsA;
A2 s_A lsB.
Definition ListHybrid_Advantage :=
| Pr[ListHybrid_G c1] - Pr[ListHybrid_G c2] |.
Definition G_hybrid i :=
[lsA, s_A] <-$2 A1;
lsA1 <- firstn i lsA;
lsA2 <- skipn i lsA;
lsB1 <-$ compMap _ c1 lsA1;
lsB2 <-$ compMap _ c2 lsA2;
A2 s_A (lsB1 ++ lsB2).

Theorem G_2_hybrid_eq :
Pr[ListHybrid_G c2] == Pr[G_hybrid 0].