Skip to content

Commit

Permalink
Migrate nonlocal games: GHZ game classical (#1783)
Browse files Browse the repository at this point in the history
The link to the issue: #1596

This pull request is covering

1. GHZ classic tasks 1.1
2. GHZ task 1.2 (random) is dropped. Task 1.3 is expanded into
implementation of 3 strategies (Alice, Bob and Charlie)
This approach allow to create more complicated output like [true, false,
false] or [r, DrawRandomBool(0.8), not t]
3. GHZ classic task 1.4

---------

Co-authored-by: Mariia Mykhailova <michaylova@gmail.com>
  • Loading branch information
ggridin and tcNickolas authored Aug 8, 2024
1 parent 713401e commit 7ae7a6f
Show file tree
Hide file tree
Showing 19 changed files with 305 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
If Alice and Bob always return TRUE, they will have a 75% win rate, since TRUE TRUE = FALSE, and the AND operation on their input bits will be FALSE with 75% probability.
Alternatively, Alice and Bob could agree to always return FALSE to achieve the same 75% win probability. A classical strategy cannot achieve a higher success probability.
If Alice and Bob always return TRUE, they will have a $75\%$ win rate, since TRUE $\oplus$ TRUE == FALSE, and the AND operation on their input bits will be FALSE with $75\%$ probability.
Alternatively, Alice and Bob could agree to always return FALSE to achieve the same $75\%$ win probability. A classical strategy cannot achieve a higher success probability.

@[solution]({
"id": "nonlocal_games__chsh_classical_strategy_solution",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
**Input:**
**Inputs:**

- Alice and Bob's starting bits (X and Y).
- Alice and Bob's output bits (A and B).

**Output:**
True if Alice and Bob won the CHSH game, that is, if X Y = A B, and false otherwise.
True if Alice and Bob won the CHSH game, that is, if X $\land$ Y = A $\oplus$ B, and false otherwise.

Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
There are four input pairs (X, Y) possible, (0,0), (0,1), (1,0), and (1,1), each with 25% probability.
There are four input pairs (X, Y) possible, (0,0), (0,1), (1,0), and (1,1), each with $25\%$ probability.
In order to win, Alice and Bob have to output different bits if the input is (1,1), and same bits otherwise.

To check whether the win condition holds, you need to compute $x ∧ y$ and $a ⊕ b$ and to compare these values: if they are equal, Alice and Bob won. You can compute these values using [built-in operators](https://learn.microsoft.com/azure/quantum/user-guide/language/expressions/logicalexpressions): $x ∧ y$ as `x and y` and $a ⊕ b$ as `a != b`.
To check whether the win condition holds, you need to compute X $\land$ Y and A $\oplus$ B and to compare these values:
if they are equal, Alice and Bob won. You can compute these values using
[built-in operators](https://learn.microsoft.com/azure/quantum/user-guide/language/expressions/logicalexpressions):
X $\land$ Y as `x and y` and A $\oplus$ B as `a != b`.


@[solution]({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Kata {
operation PlayClassicalGHZ (strategies : (Bool => Bool)[], inputs : Bool[]) : Bool[] {
// Implement your solution here...

return [];
}
}
11 changes: 11 additions & 0 deletions katas/content/nonlocal_games/ghz_classical_game/Solution.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Kata {
operation PlayClassicalGHZ (strategies : (Bool => Bool)[], inputs : Bool[]) : Bool[] {
let r = inputs[0];
let s = inputs[1];
let t = inputs[2];
let a = strategies[0](r);
let b = strategies[1](s);
let c = strategies[2](t);
return [a, b, c];
}
}
50 changes: 50 additions & 0 deletions katas/content/nonlocal_games/ghz_classical_game/Verification.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
namespace Kata.Verification {

// All possible starting bits (r, s and t) that the referee can give
// to Alice, Bob and Charlie.
function RefereeBits () : Bool[][] {
return [[false, false, false],
[true, true, false],
[false, true, true],
[true, false, true]];
}

operation TestStrategy (input : Bool, mode : Int) : Bool {
return mode == 0 ? false | mode == 1 ? true | mode == 2 ? input | not input;
}

operation PlayClassicalGHZ_Reference (strategies : (Bool => Bool)[], inputs : Bool[]) : Bool[] {
let r = inputs[0];
let s = inputs[1];
let t = inputs[2];
let a = strategies[0](r);
let b = strategies[1](s);
let c = strategies[2](t);
return [a, b, c];
}

@EntryPoint()
operation CheckSolution() : Bool {
let inputs = RefereeBits();
for rst in inputs {
// To test the interaction, run it on deterministic strategies (not necessarily good ones)
// This logic helps to detect errors in user PlayClassicalGHZ implementation like
// using the wrong sequence of output bits or not using the strategies at all.
for mode_1 in 0 .. 3 {
for mode_2 in 0 .. 3 {
for mode_3 in 0 .. 3 {
let strategies = [TestStrategy(_, mode_1), TestStrategy(_, mode_2), TestStrategy(_, mode_3)];
let actual = Kata.PlayClassicalGHZ(strategies, rst);
let expected = PlayClassicalGHZ_Reference(strategies, rst);
if actual != expected {
Message($"Expected {expected}, got {actual} for {rst}");
return false;
}
}
}
}
}
Message("Correct!");
true
}
}
8 changes: 8 additions & 0 deletions katas/content/nonlocal_games/ghz_classical_game/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
**Inputs:**

1. An array of three operations which implement the classical strategies of the players (that is, take an input bit and produce an output bit),
2. An array of 3 input bits that should be passed to the players.

**Output:**

An array of three bits that will be produced if each player uses their given strategy.
6 changes: 6 additions & 0 deletions katas/content/nonlocal_games/ghz_classical_game/solution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
You are given both the input bits and the strategy each of the players are using, so you have simply to convert them to the output bits and return those.

@[solution]({
"id": "nonlocal_games__ghz_classical_game_solution",
"codePath": "Solution.qs"
})
19 changes: 19 additions & 0 deletions katas/content/nonlocal_games/ghz_classical_strategy/Placeholder.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Kata {
operation AliceClassical (r : Bool) : Bool {
// Implement your solution here...

return false;
}

operation BobClassical (s : Bool) : Bool {
// Implement your solution here...

return false;
}

operation CharlieClassical (t : Bool) : Bool {
// Implement your solution here...

return false;
}
}
14 changes: 14 additions & 0 deletions katas/content/nonlocal_games/ghz_classical_strategy/Solution.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Kata {
operation AliceClassical (r : Bool) : Bool {
return true;
}

operation BobClassical (s : Bool) : Bool {
return true;
}

operation CharlieClassical (t : Bool) : Bool {
return true;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
namespace Kata.Verification {
open Microsoft.Quantum.Arrays;
open Microsoft.Quantum.Convert;
open Microsoft.Quantum.Logical;
open Microsoft.Quantum.Random;

function WinCondition_Reference (rst : Bool[], abc : Bool[]) : Bool {
return (rst[0] or rst[1] or rst[2]) == (abc[0] != abc[1] != abc[2]);
}

// All possible starting bits (r, s and t) that the referee can give
// to Alice, Bob and Charlie.
function RefereeBits () : Bool[][] {
return [[false, false, false],
[true, true, false],
[false, true, true],
[true, false, true]];
}

operation PlayClassicalGHZ_Reference (strategies : (Bool => Bool)[], inputs : Bool[]) : Bool[] {
let r = inputs[0];
let s = inputs[1];
let t = inputs[2];
let a = strategies[0](r);
let b = strategies[1](s);
let c = strategies[2](t);
return [a, b, c];
}

@EntryPoint()
operation CheckSolution() : Bool {
let inputs = RefereeBits();
let strategies = [Kata.AliceClassical, Kata.BobClassical, Kata.CharlieClassical];

let iterations = 1000;
mutable wins = 0;
for _ in 0 .. iterations - 1 {
for bits in inputs {
let abc = PlayClassicalGHZ_Reference(strategies, bits);
if WinCondition_Reference(bits, abc) {
set wins = wins + 1;
}
}
}
// The solution is correct if the players win 75% (3/4) of the time.
if wins < iterations*Length(inputs)*3/4 {
Message($"Alice, Bob, and Charlie's classical strategy gets {wins} wins out of {iterations*Length(inputs)} possible inputs, which is not optimal");
return false;
}
Message("Correct!");
true
}
}
11 changes: 11 additions & 0 deletions katas/content/nonlocal_games/ghz_classical_strategy/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
In this task you have to implement three functions, one for each player's classical strategy.
Note that they are covered by one test, so you have to implement all of them to pass the test.
In each function, the input is the starting bit of the corresponding player, and it should return the output bit chosen by that player.

**Input:**

Alice, Bob, and Charlie's starting bits (R, S, and T).

**Output:**

Alice, Bob, and Charlie's output bits (A, B, and C) to maximize their chance of winning.
11 changes: 11 additions & 0 deletions katas/content/nonlocal_games/ghz_classical_strategy/solution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
If all three players return TRUE, then A $\oplus$ B $\oplus$ C == TRUE by necessity (since the sum of their bits is odd).
This will win against inputs 011, 101, and 110 and lose against 000.
Another solution is one player retuns TRUE, and two others return FALSE.

Since the four above inputs have equal probability, and represent all possible inputs,
either of these deterministic strategies wins with $75\%$ probability.

@[solution]({
"id": "nonlocal_games__ghz_classical_strategy_solution",
"codePath": "Solution.qs"
})
7 changes: 7 additions & 0 deletions katas/content/nonlocal_games/ghz_win_condition/Placeholder.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Kata {
function WinCondition (rst : Bool[], abc : Bool[]) : Bool {
// Implement your solution here...

return false;
}
}
5 changes: 5 additions & 0 deletions katas/content/nonlocal_games/ghz_win_condition/Solution.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Kata {
function WinCondition (rst : Bool[], abc : Bool[]) : Bool {
return (rst[0] or rst[1] or rst[2]) == (abc[0] != abc[1] != abc[2]);
}
}
34 changes: 34 additions & 0 deletions katas/content/nonlocal_games/ghz_win_condition/Verification.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
namespace Kata.Verification {
open Microsoft.Quantum.Convert;

function WinCondition_Reference (rst : Bool[], abc : Bool[]) : Bool {
return (rst[0] or rst[1] or rst[2]) == (abc[0] != abc[1] != abc[2]);
}

// All possible starting bits (r, s and t) that the referee can give
// to Alice, Bob and Charlie.
function RefereeBits () : Bool[][] {
return [[false, false, false],
[true, true, false],
[false, true, true],
[true, false, true]];
}

@EntryPoint()
function CheckSolution() : Bool {
for rst in RefereeBits() {
for i in 0 .. 1 <<< 3 - 1 {
let abc = IntAsBoolArray(i, 3);
let expected = WinCondition_Reference(rst, abc);
let actual = Kata.WinCondition(rst, abc);

if actual != expected {
Message($"Win condition '{actual}' is wrong for rst={rst}, abc={abc}");
return false;
}
}
}
Message("Correct!");
true
}
}
9 changes: 9 additions & 0 deletions katas/content/nonlocal_games/ghz_win_condition/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
**Inputs:**

1. Alice, Bob and Charlie's input bits (r, s and t), stored as an array of length 3.
The input bits will have zero or two bits set to true.
2. Alice, Bob and Charlie's output bits (a, b and c), stored as an array of length 3.

**Goal:**

True if Alice, Bob and Charlie won the GHZ game, that is, if R $\lor$ S $\lor$ T = A $\oplus$ B $\oplus$ C, and false otherwise.
11 changes: 11 additions & 0 deletions katas/content/nonlocal_games/ghz_win_condition/solution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
There are four inputs possible, (0,0,0), (0,1,1), (1,0,1), and (1,1,0), each with $25\%$ probability.
Therefore, in order to win, the sum of the output bits has to be even if the input is (0,0,0) and odd otherwise.

To check whether the win condition holds, you need to compute the expressions R $\lor$ S $\lor$ T and A $\oplus$ B $\oplus$ C and to compare them:
if they are equal, the game is won. To compute the expressions, you can use [built-in operators](https://learn.microsoft.com/azure/quantum/user-guide/language/expressions/logicalexpressions):
X $\lor$ Y as `x or y` and A $\oplus$ B as `a != b`.

@[solution]({
"id": "nonlocal_games__ghz_win_condition_solution",
"codePath": "Solution.qs"
})
43 changes: 40 additions & 3 deletions katas/content/nonlocal_games/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ In **CHSH Game**, two players (Alice and Bob) try to win the following game:

Each of them is given a bit (Alice gets X and Bob gets Y), and
they have to return new bits (Alice returns A and Bob returns B)
so that X Y = A B. The trick is, they can not communicate during the game.
so that X $\land$ Y = A $\oplus$ B. The trick is, they can not communicate during the game.

> - is the standard bitwise AND operator.
> - is the exclusive or, or XOR operator, so (P Q) is true if exactly one of P and Q is true.
> - $\land$ is the standard bitwise AND operator.
> - $\oplus$ is the exclusive or, or XOR operator, so (P $\oplus$ Q) is true if exactly one of P and Q is true.
To start with, let's take a look at how you would play the classical variant of this game without access to any quantum tools.
Then, let's proceed with quantum strategies for Alice and Bob.
Expand Down Expand Up @@ -189,6 +189,43 @@ In the example below you can compare winning percentage of classical and quantum
@[example]({"id": "nonlocal_games__chsh_e2edemo", "codePath": "./examples/CHSHGameDemo.qs"})

@[section]({
"id": "nonlocal_games__ghz_game",
"title": "GHZ Game"
})

In **GHZ Game** three players (Alice, Bob and Charlie) try to win the following game:

Each of them is given a bit (R, S and T respectively), and they have to return new bits (A, B and C respectively) so that
R $\lor$ S $\lor$ T = A $\oplus$ B $\oplus$ C.
The input bits will have zero or two bits set to true and three or one bits set to false.
The players are free to share information (and even qubits!) before the game starts, but are forbidden from communicating
with each other afterwards.

> - $\lor$ is the standard bitwise OR operator.
> - $\oplus$ is the exclusive or, or XOR operator, so (P $\oplus$ Q) is true if exactly one of P and Q is true.
To start with, take a look at how you would play the classical variant of this game without access to any quantum tools.
Then, let's proceed with quantum strategy and game implementation.

@[exercise]({
"id": "nonlocal_games__ghz_win_condition",
"title": "Win Condition",
"path": "./ghz_win_condition/"
})

@[exercise]({
"id": "nonlocal_games__ghz_classical_strategy",
"title": "Classical Strategy",
"path": "./ghz_classical_strategy/"
})

@[exercise]({
"id": "nonlocal_games__ghz_classical_game",
"title": "Classical GHZ Game",
"path": "./ghz_classical_game/"
})

@[section]({
"id": "nonlocal_games__conclusion",
"title": "Conclusion"
Expand Down

0 comments on commit 7ae7a6f

Please sign in to comment.