Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate nonlocal games: GHZ game classical #1783

Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e4cd3ea
ghz_classical_game initial commit
ggridin Jul 23, 2024
9c5559a
Merge branch 'microsoft:main' into MigrateNonlocalGames-1596-task2-GH…
ggridin Jul 24, 2024
d4a3b24
Fix for Verification bug
ggridin Jul 24, 2024
330a9b4
Merge branch 'MigrateNonlocalGames-1596-task2-GHZ-classical' of https…
ggridin Jul 24, 2024
3fc4056
Add EOFs
ggridin Jul 24, 2024
39f9930
Adding temp changes
ggridin Jul 24, 2024
3efc6f8
Adding temp changes 2
ggridin Jul 24, 2024
ac63f61
Merge branch 'microsoft:main' into MigrateNonlocalGames-1596-task2-GH…
ggridin Jul 27, 2024
2cd1cf3
Merge branch 'microsoft:main' into MigrateNonlocalGames-1596-task2-GH…
ggridin Jul 29, 2024
9e8c943
Address code review comments from parallel PR
ggridin Jul 29, 2024
be9a631
Merge branch 'microsoft:main' into MigrateNonlocalGames-1596-task2-GH…
ggridin Aug 1, 2024
dc9aed3
Merge branch 'main' into MigrateNonlocalGames-1596-task2-GHZ-classical
ggridin Aug 1, 2024
3bb8040
Merge branch 'microsoft:main' into MigrateNonlocalGames-1596-task2-GH…
ggridin Aug 2, 2024
aac5852
Update katas/content/nonlocal_games/ghz_classical_strategy/solution.md
ggridin Aug 3, 2024
0a6d2e4
Update katas/content/nonlocal_games/ghz_classical_game/index.md
ggridin Aug 3, 2024
3e44e18
Update katas/content/nonlocal_games/ghz_classical_game/index.md
ggridin Aug 3, 2024
1813305
Update katas/content/nonlocal_games/ghz_classical_game/Solution.qs
ggridin Aug 3, 2024
8297fb4
Update katas/content/nonlocal_games/ghz_classical_game/index.md
ggridin Aug 4, 2024
586821b
Address code review comments
ggridin Aug 4, 2024
cab22ba
Merge branch 'MigrateNonlocalGames-1596-task2-GHZ-classical' of https…
ggridin Aug 4, 2024
1a98cf8
Address code missed code review comment
ggridin Aug 4, 2024
eb2f112
Merge branch 'microsoft:main' into MigrateNonlocalGames-1596-task2-GH…
ggridin Aug 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 [];
}
}
12 changes: 12 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,12 @@
namespace Kata {
// 3 players, each player has own strategy and receives a bit from the referee
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 operations which implement classical strategies (i.e., takes an input bit and produces an output bit),
2. An array of 3 input bits that should be passed to the players.

**Goal:**

An array of 3 bits that will be produced if each player uses this 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"
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Kata {
operation AliceClassical (x : Bool) : Bool {
// Implement your solution here...

return false;
}

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

return false;
}

operation CharlieClassical (z : 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 (x : Bool) : Bool {
return true;
}

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

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
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]) == Xor(Xor(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[] {
if Length(strategies) != 3 or Length(inputs) != 3 {
return [];
}
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 = 10000;
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 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.
For non-deterministic strategies, DrawRandomBoolean or [DrawRandomInt](https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.random/drawrandomint) functions from Q# library can be used.

**Inputs:**

Alice, Bob, and Charlie's starting bits (X, Y, and Z).

**Goal:**

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 ⊕ b ⊕ 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,
this deterministic strategy wins with $75\%$ probability.

@[solution]({
"id": "nonlocal_games__ghz_classical_strategy_solution",
"codePath": "Solution.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;
}
}
7 changes: 7 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,7 @@
namespace Kata {
open Microsoft.Quantum.Logical;

function WinCondition (rst : Bool[], abc : Bool[]) : Bool {
return (rst[0] or rst[1] or rst[2]) == Xor(Xor(abc[0], abc[1]), abc[2]);
}
}
35 changes: 35 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,35 @@
namespace Kata.Verification {
open Microsoft.Quantum.Convert;
open Microsoft.Quantum.Logical;

function WinCondition_Reference (rst : Bool[], abc : Bool[]) : Bool {
return (rst[0] or rst[1] or rst[2]) == Xor(Xor(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 ∨ s ∨ t = a ⊕ b ⊕ c, and false otherwise.
9 changes: 9 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,9 @@
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 \vee s \vee 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) and logical function `Xor` from the [`Microsoft.Quantum.Logical`](https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.logical/xor) library.

@[solution]({
"id": "nonlocal_games__ghz_win_condition_solution",
"codePath": "Solution.qs"
})
37 changes: 37 additions & 0 deletions katas/content/nonlocal_games/index.md
Original file line number Diff line number Diff line change
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 ∨ s ∨ t = a ⊕ b ⊕ 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.

- ∨ is the standard bitwise OR operator.
- ⊕ is the exclusive or, or XOR operator, so (P ⊕ 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
Loading