From f6dbc63dc4ec8c8ed82da0eced138080afcd8615 Mon Sep 17 00:00:00 2001 From: Richard Stein Date: Wed, 29 Jul 2020 17:37:13 -0700 Subject: [PATCH 1/7] new folder for W game --- .vscode/launch.json | 27 ++++++ .vscode/tasks.json | 42 +++++++++ WGame/ReferenceImplementation.qs | 103 ++++++++++++++++++++++ WGame/Tasks.qs | 144 +++++++++++++++++++++++++++++++ WGame/Tests.qs | 142 ++++++++++++++++++++++++++++++ WGame/WGame.csproj | 8 ++ 6 files changed, 466 insertions(+) create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json create mode 100644 WGame/ReferenceImplementation.qs create mode 100644 WGame/Tasks.qs create mode 100644 WGame/Tests.qs create mode 100644 WGame/WGame.csproj diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000000..9607cfe9aab --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,27 @@ +{ + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md + "version": "0.2.0", + "configurations": [ + { + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/BasicGates/bin/Debug/netcoreapp3.1/BasicGates.dll", + "args": [], + "cwd": "${workspaceFolder}/BasicGates", + // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console + "console": "internalConsole", + "stopAtEntry": false + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach", + "processId": "${command:pickProcess}" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000000..7b568663cd4 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,42 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/BasicGates/BasicGates.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/BasicGates/BasicGates.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "${workspaceFolder}/BasicGates/BasicGates.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/WGame/ReferenceImplementation.qs b/WGame/ReferenceImplementation.qs new file mode 100644 index 00000000000..436591ff32b --- /dev/null +++ b/WGame/ReferenceImplementation.qs @@ -0,0 +1,103 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +////////////////////////////////////////////////////////////////////// +// This file contains reference solutions to all tasks. +// The tasks themselves can be found in Tasks.qs file. +// We recommend that you try to solve the tasks yourself first, +// but feel free to look up the solution if you get stuck. +////////////////////////////////////////////////////////////////////// + +namespace Quantum.Kata.WGame { + + open Microsoft.Quantum.Arrays; + open Microsoft.Quantum.Convert; + open Microsoft.Quantum.Math; + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Logical; + + + ////////////////////////////////////////////////////////////////// + // Part I. Classical GHZ + ////////////////////////////////////////////////////////////////// + + // Task 1.1. Win condition + function WinCondition_Reference (rst : Bool[], abc : Bool[]) : Bool { + mutable rstOnes = 0; + mutable abcOnes = 0; + for (i in rst) { if (i) {set rstOnes = rstOnes + 1;} } + for (i in abc) { if (i) {set abcOnes = abcOnes + 1;} } + if (rstOnes == 2) { + return (abcOnes != 1); + } + if (rstOnes == 1) { + return (abcOnes < 3); + } + return (abcOnes == 1); // By initial conditions, if rstOnes is not 1 or 2, it must be 0 + } + + + // Task 1.2. Random classical strategy + operation RandomClassicalStrategy_Reference (input : Bool) : Bool { + return RandomInt(2) == 1; + } + + + // Task 1.3. Best classical strategy + operation BestClassicalStrategy_Reference (input : Bool) : Bool { + // One of several simple strategies that reaches optimal classical win probability. + return false; + } + + + // Task 1.4. Referee classical GHZ game + operation PlayClassicalGHZ_Reference (strategy : (Bool => Bool), inputs : Bool[]) : Bool[] { + return ForEach(strategy, inputs); + } + + + ////////////////////////////////////////////////////////////////// + // Part II. Quantum GHZ + ////////////////////////////////////////////////////////////////// + + // Task 2.1. Entangled triple + operation CreateEntangledTriple_Reference (qs : Qubit[]) : Unit is Adj { + let theta = ArcSin(1.0 / Sqrt(3.0)); + Ry(2.0 * theta, qs[0]); + // Starting from |000>, this produces {sqrt(2/3) |000> + sqrt(1/3) |100>}. + + (ControlledOnBitString([false], H))([qs[0]], qs[1]); + // Hadamard-transforms second qubit when first is 0, + // so this leads to (|000> + |010> + |100>) / sqrt(3). + + (ControlledOnBitString([false, false], X))([qs[0], qs[1]], qs[2]); + // Applies NOT gate to third qubit when first two are both 0, leading to the W state desired. + } + + + // Task 2.2. Quantum strategy + operation QuantumStrategy_Reference (input : Bool, qubit : Qubit) : Bool { + if (input) { + H(qubit); + } + return ResultAsBool(M(qubit)); + } + + + // Task 2.3. Play the GHZ game using the quantum strategy + operation PlayQuantumGHZ_Reference (strategies : (Qubit => Bool)[]) : Bool[] { + + using (qs = Qubit[3]) { + CreateEntangledTriple_Reference(qs); + + let a = strategies[0](qs[0]); + let b = strategies[1](qs[1]); + let c = strategies[2](qs[2]); + + ResetAll(qs); + return [a, b, c]; + } + } + +} diff --git a/WGame/Tasks.qs b/WGame/Tasks.qs new file mode 100644 index 00000000000..65c699daa4d --- /dev/null +++ b/WGame/Tasks.qs @@ -0,0 +1,144 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +namespace Quantum.Kata.WGame { + + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Math; + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Diagnostics; + open Microsoft.Quantum.Logical; + + ////////////////////////////////////////////////////////////////// + // Welcome! + ////////////////////////////////////////////////////////////////// + + // The "W Game" is an original quantum "kata" similar to the GHZ game + // and the CHSH game, but oriented to the properties of the W state. + + // In it 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) according + // to the following table: + + // +-------------------+------------------+ + // | Number of true | Number of true | + // | bits in input | bits in output | + // | between players | needed to win | + // +-------------------+------------------+ + // | 0 | exactly 1 | + // | 1 | 0, 1, or 2 | + // | 2 | 0, 2, or 3 | + // +-------------------+------------------+ + + // All that is given is that at least one of the input bits is set + // to false, leaving seven scenarios that are all equally likely: + + // F,F,F T,F,F F,T,F F,F,T T,T,F T,F,T F,T,T + + // Like the GHZ and CHSH games, the players can not communicate during the game. + + // Each task is wrapped in one operation preceded by the + // description of the task. Each task has a unit test associated + // with it, which initially fails. Your goal is to fill in the + // blank (marked with // ... comment) with some Q# code to make + // the failing test pass. + + + ////////////////////////////////////////////////////////////////// + // Part I. Classical GHZ + ////////////////////////////////////////////////////////////////// + + // Task 1.1. Win condition + // Input: + // 1) Alice, Bob and Charlie's input bits (r, s and t), stored as an array of length 3, + // 2) Alice, Bob and Charlie's output bits (a, b and c), stored as an array of length 3. + // The input bits will have zero, one, or two bits set to true. + // Output: + // True if Alice, Bob and Charlie won the GHZ game (see above table), + // and false otherwise. + function WinCondition (rst : Bool[], abc : Bool[]) : Bool { + // ... + fail "Task 1.1 not implemented yet"; + } + + + // Task 1.2. Random classical strategy + // Input: The input bit for one of the players (r, s or t). + // Output: A random bit that this player will output (a, b or c). + // If all players use this strategy, their win odds will be: + // (1/7 x 1/8) (zero input bits true) + // + (3/7 x 7/8) ( one input bit true) + // + (3/7 x 5/8) ( two input bits true) = 37/56, or about 66.1% of the time. + operation RandomClassicalStrategy (input : Bool) : Bool { + // ... + fail "Task 1.2 not implemented yet"; + } + + + // Task 1.3. Best classical strategy + // Input: The input bit for one of the players (r, s or t). + // Output: A bit that this player will output (a, b or c) to maximize their chance of winning. + // All players will use the same strategy. + // The best classical strategy should win about 6/7 of the time (85.7%). + operation BestClassicalStrategy (input : Bool) : Bool { + // ... + fail "Task 1.3 not implemented yet"; + } + + + // Task 1.4. Referee classical GHZ game + // Inputs: + // 1) an operation which implements a classical strategy + // (i.e., takes an input bit and produces and output bit), + // 2) an array of 3 input bits that should be passed to the players. + // Output: + // An array of 3 bits that will be produced if each player uses this strategy. + operation PlayClassicalGHZ (strategy : (Bool => Bool), inputs : Bool[]) : Bool[] { + // ... + fail "Task 1.4 not implemented yet"; + } + + + ////////////////////////////////////////////////////////////////// + // Part II. Quantum GHZ + ////////////////////////////////////////////////////////////////// + + // In the quantum version of the game, the players still can not + // communicate during the game, but they are allowed to share + // qubits from an entangled triple before the start of the game. + + // Task 2.1. Entangled triple + // Input: An array of three qubits in the |000⟩ state. + // Goal: Create the entangled state |W⟩ = (|001⟩ + |010⟩ + |100⟩) / sqrt(3) on these qubits. + operation CreateEntangledTriple (qs : Qubit[]) : Unit { + // ... + fail "Task 2.1 not implemented yet"; + } + + + // Task 2.2. Quantum strategy + // Inputs: + // 1) The input bit for one of the players (r, s or t), + // 2) That player's qubit of the entangled triple shared between the players. + // Goal: Measure the qubit in the Z basis if the bit is 0 (false), + // or the X basis if the bit is 1 (true), and return the result. + // The state of the qubit after the operation does not matter. + operation QuantumStrategy (input : Bool, qubit : Qubit) : Bool { + // ... + fail "Task 2.2 not implemented yet"; + } + + + // Task 2.3. Play the GHZ game using the quantum strategy + // Input: Operations that return Alice, Bob and Charlie's output bits (a, b and c) based on + // their quantum strategies and given their respective qubits from the entangled triple. + // The players have already been told what their starting bits (r, s and t) are. + // Goal: Return an array of players' output bits (a, b and c). + operation PlayQuantumGHZ (strategies : (Qubit => Bool)[]) : Bool[] { + // ... + fail "Task 2.3 not implemented yet"; + } +} diff --git a/WGame/Tests.qs b/WGame/Tests.qs new file mode 100644 index 00000000000..81a231eeef3 --- /dev/null +++ b/WGame/Tests.qs @@ -0,0 +1,142 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +////////////////////////////////////////////////////////////////////// +// This file contains testing harness for all tasks. +// You should not modify anything in this file. +// The tasks themselves can be found in Tasks.qs file. +////////////////////////////////////////////////////////////////////// + +namespace Quantum.Kata.WGame { + + open Microsoft.Quantum.Math; + open Microsoft.Quantum.Intrinsic; + open Microsoft.Quantum.Convert; + open Microsoft.Quantum.Diagnostics; + + // 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, false, false], + [false, true, false], + [false, false, true], + [true, true, false], + [false, true, true], + [true, false, true]]; + } + + operation T11_WinCondition_Test () : Unit { + for (rst in RefereeBits()) { + for (i in 0..1 <<< 3 - 1) { + let abc = IntAsBoolArray(i, 3); + EqualityFactB( + WinCondition(rst, abc), + WinCondition_Reference(rst, abc), + $"Win condition is wrong for rst={rst}, abc={abc}"); + } + } + } + + + // ------------------------------------------------------ + operation GetClassicalStrategySuccessRate (N : Int, strategy : (Bool => Bool)) : Double { + let inputs = RefereeBits(); + mutable wins = 0; + for (i in 0..N - 1) { + let rst = inputs[RandomInt(Length(inputs))]; + let abc = PlayClassicalGHZ_Reference(strategy, rst); + if (WinCondition_Reference(rst, abc)) { + set wins = wins + 1; + } + } + return IntAsDouble(wins) / IntAsDouble(N); + } + + operation T12_RandomClassical_Test () : Unit { + EqualityWithinToleranceFact(GetClassicalStrategySuccessRate(10000, RandomClassicalStrategy), 0.661, 0.02); + } + + + // ------------------------------------------------------ + operation T13_BestClassical_Test () : Unit { + EqualityWithinToleranceFact(GetClassicalStrategySuccessRate(10000, BestClassicalStrategy), 0.857, 0.02); + } + + + // ------------------------------------------------------ + operation TestStrategy (input : Bool, mode : Int) : Bool { + return mode == 0 ? false | mode == 1 ? true | mode == 2 ? input | not input; + } + + + operation T14_PlayClassicalGHZ_Test () : Unit { + // To test the interaction, run it on several deterministic strategies (not necessarily good ones) + let inputs = RefereeBits(); + for (rst in inputs) { + for (mode in 0..3) { + let result = PlayClassicalGHZ(TestStrategy(_, mode), rst); + let expected = PlayClassicalGHZ_Reference(TestStrategy(_, mode), rst); + AllEqualityFactB(result, expected, $"Unexpected result for rst={rst}"); + } + } + } + + ////////////////////////////////////////////////////////////////// + // Part II. Quantum GHZ + ////////////////////////////////////////////////////////////////// + + operation AssertEqualOnZeroState (N : Int, taskImpl : (Qubit[] => Unit), refImpl : (Qubit[] => Unit is Adj)) : Unit { + using (qs = Qubit[N]) { + // apply operation that needs to be tested + taskImpl(qs); + + // apply adjoint reference operation and check that the result is |0ᴺ⟩ + Adjoint refImpl(qs); + + // assert that all qubits end up in |0⟩ state + AssertAllZero(qs); + } + } + + operation T21_CreateEntangledTriple_Test () : Unit { + AssertEqualOnZeroState(3, CreateEntangledTriple, CreateEntangledTriple_Reference); + } + + + // ------------------------------------------------------ + operation T22_QuantumStrategy_Test () : Unit { + using (q = Qubit()) { + EqualityFactB(QuantumStrategy(false, q), false, "|0⟩ not measured as false"); + Reset(q); + + X(q); + EqualityFactB(QuantumStrategy(false, q), true, "|1⟩ not measured as true"); + Reset(q); + + H(q); + EqualityFactB(QuantumStrategy(true, q), false, "|+⟩ is not measured as false"); + Reset(q); + + X(q); + H(q); + EqualityFactB(QuantumStrategy(true, q), true, "|-⟩ is not measured as true"); + Reset(q); + } + } + + + // ------------------------------------------------------ + operation T23_PlayQuantumGHZ_Test () : Unit { + for (i in 0..1000) { + let rst = (RefereeBits())[RandomInt(Length(RefereeBits()))]; + let strategies = [QuantumStrategy_Reference(rst[0], _), + QuantumStrategy_Reference(rst[1], _), + QuantumStrategy_Reference(rst[2], _)]; + let abc = PlayQuantumGHZ(strategies); + EqualityFactB(WinCondition_Reference(rst, abc), true, + $"Quantum strategy lost: for rst={rst} the players returned abc={abc}"); + } + } + +} diff --git a/WGame/WGame.csproj b/WGame/WGame.csproj new file mode 100644 index 00000000000..23d549942dc --- /dev/null +++ b/WGame/WGame.csproj @@ -0,0 +1,8 @@ + + + + Exe + netcoreapp3.1 + + + From 24a030bf81c6fb283549d37ab3b01ce77b0916b4 Mon Sep 17 00:00:00 2001 From: Richard Stein Date: Wed, 29 Jul 2020 18:25:33 -0700 Subject: [PATCH 2/7] Add W game notebook, and correct references to GHZ -> W game in .qs code --- GHZGame/GHZGame.ipynb | 2 +- WGame/ReferenceImplementation.qs | 12 +- WGame/Tasks.qs | 14 +- WGame/Tests.qs | 14 +- WGame/WGame.ipynb | 316 +++++++++++++++++++++++++++++++ 5 files changed, 337 insertions(+), 21 deletions(-) create mode 100644 WGame/WGame.ipynb diff --git a/GHZGame/GHZGame.ipynb b/GHZGame/GHZGame.ipynb index 4878e2ecbcf..67ece8a7812 100644 --- a/GHZGame/GHZGame.ipynb +++ b/GHZGame/GHZGame.ipynb @@ -289,7 +289,7 @@ "file_extension": ".qs", "mimetype": "text/x-qsharp", "name": "qsharp", - "version": "0.4" + "version": "0.12" } }, "nbformat": 4, diff --git a/WGame/ReferenceImplementation.qs b/WGame/ReferenceImplementation.qs index 436591ff32b..04f56da57bd 100644 --- a/WGame/ReferenceImplementation.qs +++ b/WGame/ReferenceImplementation.qs @@ -19,7 +19,7 @@ namespace Quantum.Kata.WGame { ////////////////////////////////////////////////////////////////// - // Part I. Classical GHZ + // Part I. Classical W game ////////////////////////////////////////////////////////////////// // Task 1.1. Win condition @@ -51,14 +51,14 @@ namespace Quantum.Kata.WGame { } - // Task 1.4. Referee classical GHZ game - operation PlayClassicalGHZ_Reference (strategy : (Bool => Bool), inputs : Bool[]) : Bool[] { + // Task 1.4. Referee classical W game + operation PlayClassicalW_Reference (strategy : (Bool => Bool), inputs : Bool[]) : Bool[] { return ForEach(strategy, inputs); } ////////////////////////////////////////////////////////////////// - // Part II. Quantum GHZ + // Part II. Quantum W game ////////////////////////////////////////////////////////////////// // Task 2.1. Entangled triple @@ -85,8 +85,8 @@ namespace Quantum.Kata.WGame { } - // Task 2.3. Play the GHZ game using the quantum strategy - operation PlayQuantumGHZ_Reference (strategies : (Qubit => Bool)[]) : Bool[] { + // Task 2.3. Play the W game using the quantum strategy + operation PlayQuantumW_Reference (strategies : (Qubit => Bool)[]) : Bool[] { using (qs = Qubit[3]) { CreateEntangledTriple_Reference(qs); diff --git a/WGame/Tasks.qs b/WGame/Tasks.qs index 65c699daa4d..7d0c9526ac3 100644 --- a/WGame/Tasks.qs +++ b/WGame/Tasks.qs @@ -48,7 +48,7 @@ namespace Quantum.Kata.WGame { ////////////////////////////////////////////////////////////////// - // Part I. Classical GHZ + // Part I. Classical W game ////////////////////////////////////////////////////////////////// // Task 1.1. Win condition @@ -57,7 +57,7 @@ namespace Quantum.Kata.WGame { // 2) Alice, Bob and Charlie's output bits (a, b and c), stored as an array of length 3. // The input bits will have zero, one, or two bits set to true. // Output: - // True if Alice, Bob and Charlie won the GHZ game (see above table), + // True if Alice, Bob and Charlie won the W game (see above table), // and false otherwise. function WinCondition (rst : Bool[], abc : Bool[]) : Bool { // ... @@ -89,21 +89,21 @@ namespace Quantum.Kata.WGame { } - // Task 1.4. Referee classical GHZ game + // Task 1.4. Referee classical W game // Inputs: // 1) an operation which implements a classical strategy // (i.e., takes an input bit and produces and output bit), // 2) an array of 3 input bits that should be passed to the players. // Output: // An array of 3 bits that will be produced if each player uses this strategy. - operation PlayClassicalGHZ (strategy : (Bool => Bool), inputs : Bool[]) : Bool[] { + operation PlayClassicalW (strategy : (Bool => Bool), inputs : Bool[]) : Bool[] { // ... fail "Task 1.4 not implemented yet"; } ////////////////////////////////////////////////////////////////// - // Part II. Quantum GHZ + // Part II. Quantum W game ////////////////////////////////////////////////////////////////// // In the quantum version of the game, the players still can not @@ -132,12 +132,12 @@ namespace Quantum.Kata.WGame { } - // Task 2.3. Play the GHZ game using the quantum strategy + // Task 2.3. Play the W game using the quantum strategy // Input: Operations that return Alice, Bob and Charlie's output bits (a, b and c) based on // their quantum strategies and given their respective qubits from the entangled triple. // The players have already been told what their starting bits (r, s and t) are. // Goal: Return an array of players' output bits (a, b and c). - operation PlayQuantumGHZ (strategies : (Qubit => Bool)[]) : Bool[] { + operation PlayQuantumW (strategies : (Qubit => Bool)[]) : Bool[] { // ... fail "Task 2.3 not implemented yet"; } diff --git a/WGame/Tests.qs b/WGame/Tests.qs index 81a231eeef3..ea9358a3262 100644 --- a/WGame/Tests.qs +++ b/WGame/Tests.qs @@ -45,7 +45,7 @@ namespace Quantum.Kata.WGame { mutable wins = 0; for (i in 0..N - 1) { let rst = inputs[RandomInt(Length(inputs))]; - let abc = PlayClassicalGHZ_Reference(strategy, rst); + let abc = PlayClassicalW_Reference(strategy, rst); if (WinCondition_Reference(rst, abc)) { set wins = wins + 1; } @@ -70,20 +70,20 @@ namespace Quantum.Kata.WGame { } - operation T14_PlayClassicalGHZ_Test () : Unit { + operation T14_PlayClassicalW_Test () : Unit { // To test the interaction, run it on several deterministic strategies (not necessarily good ones) let inputs = RefereeBits(); for (rst in inputs) { for (mode in 0..3) { - let result = PlayClassicalGHZ(TestStrategy(_, mode), rst); - let expected = PlayClassicalGHZ_Reference(TestStrategy(_, mode), rst); + let result = PlayClassicalW(TestStrategy(_, mode), rst); + let expected = PlayClassicalW_Reference(TestStrategy(_, mode), rst); AllEqualityFactB(result, expected, $"Unexpected result for rst={rst}"); } } } ////////////////////////////////////////////////////////////////// - // Part II. Quantum GHZ + // Part II. Quantum W game ////////////////////////////////////////////////////////////////// operation AssertEqualOnZeroState (N : Int, taskImpl : (Qubit[] => Unit), refImpl : (Qubit[] => Unit is Adj)) : Unit { @@ -127,13 +127,13 @@ namespace Quantum.Kata.WGame { // ------------------------------------------------------ - operation T23_PlayQuantumGHZ_Test () : Unit { + operation T23_PlayQuantumW_Test () : Unit { for (i in 0..1000) { let rst = (RefereeBits())[RandomInt(Length(RefereeBits()))]; let strategies = [QuantumStrategy_Reference(rst[0], _), QuantumStrategy_Reference(rst[1], _), QuantumStrategy_Reference(rst[2], _)]; - let abc = PlayQuantumGHZ(strategies); + let abc = PlayQuantumW(strategies); EqualityFactB(WinCondition_Reference(rst, abc), true, $"Quantum strategy lost: for rst={rst} the players returned abc={abc}"); } diff --git a/WGame/WGame.ipynb b/WGame/WGame.ipynb new file mode 100644 index 00000000000..6402bd654c2 --- /dev/null +++ b/WGame/WGame.ipynb @@ -0,0 +1,316 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# W Game\n", + "\n", + "The **W Game** quantum kata is an original series of exercises based on the katas for the GHZ\n", + "and CHSH games, introducing an original game inspired by these and referred to here as the \"W game\".\n", + "\n", + "In it three players (Alice, Bob and Charlie) try to win the following game:\n", + "\n", + "Each of them is given a bit (r, s and t respectively), and\n", + "they have to return new bits (a, b and c respectively) so\n", + "that the sum (number of true bits) of their output bits corresponds\n", + "to the sum of the input bits in the following way:\n", + "\n", + "```\n", + "+-------------------------------+----------------------------------+\n", + "| Number of true bits in | Number of true bits in |\n", + "| input between players | output needed to win |\n", + "+-------------------------------+----------------------------------+\n", + "| 0 | exactly 1 |\n", + "| 1 | 0, 1, or 2 |\n", + "| 2 | 0, 2, or 3 |\n", + "+-------------------------------+----------------------------------+\n", + "```\n", + "\n", + "The input bits can be any combination of true or false\n", + "except that all three will not be true (at least one will be false).\n", + "The trick is, the players can not communicate during the game.\n", + "\n", + "The W state represents one of the two non-biseparable classes of three-qubit entangled states; the GHZ state represents the other. These two states cannot be transformed into each other by local (one-qubit) quantum operations, and therefore represent two fundamentally distinct types of tripartite entanglement. For further information: https://en.wikipedia.org/wiki/W_state\n", + "\n", + "Each task is wrapped in one operation preceded by the description of the task.\n", + "Your goal is to fill in the blank (marked with the `// ...` comments)\n", + "with some Q# code that solves the task. To verify your answer, run the cell using Ctrl/⌘+Enter.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To begin, first prepare this notebook for execution (if you skip this step, you'll get \"Syntax does not match any known patterns\" error when you try to execute Q# code in the next cells):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%package Microsoft.Quantum.Katas::0.12.20072031" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "> The package versions in the output of the cell above should always match. If you are running the Notebooks locally and the versions do not match, please install the IQ# version that matches the version of the `Microsoft.Quantum.Katas` package.\n", + ">
\n", + "> How to install the right IQ# version\n", + "> For example, if the version of `Microsoft.Quantum.Katas` package above is 0.1.2.3, the installation steps are as follows:\n", + ">\n", + "> 1. Stop the kernel.\n", + "> 2. Uninstall the existing version of IQ#:\n", + "> dotnet tool uninstall microsoft.quantum.iqsharp -g\n", + "> 3. Install the matching version:\n", + "> dotnet tool install microsoft.quantum.iqsharp -g --version 0.1.2.3\n", + "> 4. Reinstall the kernel:\n", + "> dotnet iqsharp install\n", + "> 5. Restart the Notebook.\n", + ">
\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Part I. Classical W game\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Task 1.1. Win Condition\n", + "**Inputs:** \n", + "\n", + " 1. Alice, Bob and Charlie's input bits (r, s and t), stored as an array of length 3,\n", + "\n", + " 2. Alice, Bob and Charlie's output bits (a, b and c), stored as an array of length 3.\n", + "\n", + "The input bits will have zero, one, or two bits set to true.\n", + "\n", + "**Output:** \n", + "True if Alice, Bob and Charlie won the W game, that is, if:\n", + "\n", + "* All three input bits were false, and there was exactly one true bit among the team's output bits\n", + "* Exactly one input bit was true, and at least one of Alice, Bob or Charlie submitted a false output bit\n", + "* Exactly two input bits were true, and Alice, Bob and Charlie submitted all true, all false, or exactly two true output bits\n", + "\n", + "and false otherwise." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%kata T11_WinCondition_Test \n", + "\n", + "function WinCondition (rst : Bool[], abc : Bool[]) : Bool {\n", + " // ...\n", + " fail \"Task 1.1 not implemented yet\";\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Task 1.2. Random classical strategy\n", + "\n", + "**Input:** The input bit for one of the players (r, s or t).\n", + "\n", + "**Output:** A random bit that this player will output (a, b or c).\n", + "\n", + "If all players use this strategy, they will win about 66% of the time." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%kata T12_RandomClassical_Test \n", + "\n", + "operation RandomClassicalStrategy (input : Bool) : Bool {\n", + " // ...\n", + " fail \"Task 1.2 not implemented yet\";\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Task 1.3. Best classical strategy\n", + "\n", + "**Input:** The input bit for one of the players (r, s or t).\n", + "\n", + "**Output:** A bit that this player will output (a, b or c) to maximize their chance of winning.\n", + "\n", + "All players will use the same strategy.\n", + "The best classical strategy should win about 86% of the time. Multiple optimal classical strategies are possible." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%kata T13_BestClassical_Test \n", + "\n", + "operation BestClassicalStrategy (input : Bool) : Bool {\n", + " // ...\n", + " fail \"Task 1.3 not implemented yet\";\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Task 1.4. Referee classical W game\n", + "\n", + "**Inputs:** \n", + "\n", + " 1. An operation which implements a classical strategy (i.e., takes an input bit and produces an output bit),\n", + "\n", + " 2. An array of 3 input bits that should be passed to the players.\n", + "\n", + "**Output:** \n", + "An array of 3 bits that will be produced if each player uses this strategy." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%kata T14_PlayClassicalW_Test \n", + "\n", + "operation PlayClassicalW (strategy : (Bool => Bool), inputs : Bool[]) : Bool[] {\n", + " // ...\n", + " fail \"Task 1.4 not implemented yet\";\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Part II. Quantum W game\n", + "\n", + "In the quantum version of the game, the players still can not\n", + "communicate during the game, but they are allowed to share \n", + "qubits from an entangled triple before the start of the game.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Task 2.1. Entangled triple\n", + "\n", + "**Input:** An array of three qubits in the $|000\\rangle$ state.\n", + "\n", + "**Goal:** Create the entangled state $|W\\rangle = \\frac{1}{\\sqrt{3}} \\big(|001\\rangle + |010\\rangle + |100\\rangle \\big)$ on these qubits." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%kata T21_CreateEntangledTriple_Test \n", + "\n", + "operation CreateEntangledTriple (qs : Qubit[]) : Unit {\n", + " // ...\n", + " fail \"Task 2.1 not implemented yet\";\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Task 2.2. Quantum strategy\n", + "\n", + "**Inputs:**\n", + "\n", + " 1. The input bit for one of the players (r, s or t),\n", + "\n", + " 2. That player's qubit of the entangled triple shared between the players.\n", + "\n", + "**Goal:** Measure the qubit in the Z basis if the bit is 0 (false), or the X basis if the bit is 1 (true), and return the result.\n", + "\n", + "The state of the qubit after the operation does not matter." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%kata T22_QuantumStrategy_Test \n", + "\n", + "operation QuantumStrategy (input : Bool, qubit : Qubit) : Bool {\n", + " // ...\n", + " fail \"Task 2.2 not implemented yet\";\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Task 2.3. Play the W game using the quantum strategy\n", + "\n", + "**Input:** Operations that return Alice, Bob and Charlie's output bits (a, b and c) based on\n", + "their quantum strategies and given their respective qubits from the entangled triple.\n", + "The players have already been told what their starting bits (r, s and t) are.\n", + "\n", + "**Goal:** Return an array of players' output bits (a, b and c)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%kata T23_PlayQuantumW_Test \n", + "\n", + "operation PlayQuantumW (strategies : (Qubit => Bool)[]) : Bool[] {\n", + " // ...\n", + " fail \"Task 2.3 not implemented yet\";\n", + "}" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Q#", + "language": "qsharp", + "name": "iqsharp" + }, + "language_info": { + "file_extension": ".qs", + "mimetype": "text/x-qsharp", + "name": "qsharp", + "version": "0.12" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 0c7b5ac66fc1401fd9962b6ecda0a4eb183d4196 Mon Sep 17 00:00:00 2001 From: Richard Stein Date: Wed, 29 Jul 2020 21:06:11 -0700 Subject: [PATCH 3/7] Found improved classical strategy, added to simple one --- WGame/ReferenceImplementation.qs | 21 ++++++++++++--- WGame/Tasks.qs | 25 ++++++++++++++---- WGame/Tests.qs | 12 ++++++--- WGame/WGame.ipynb | 44 +++++++++++++++++++++++++++----- 4 files changed, 83 insertions(+), 19 deletions(-) diff --git a/WGame/ReferenceImplementation.qs b/WGame/ReferenceImplementation.qs index 04f56da57bd..fdc7ae2a02a 100644 --- a/WGame/ReferenceImplementation.qs +++ b/WGame/ReferenceImplementation.qs @@ -44,14 +44,27 @@ namespace Quantum.Kata.WGame { } - // Task 1.3. Best classical strategy - operation BestClassicalStrategy_Reference (input : Bool) : Bool { - // One of several simple strategies that reaches optimal classical win probability. + // Task 1.3. Simple classical strategy + operation SimpleClassicalStrategy_Reference (input : Bool) : Bool { + // One of several simple strategies that reaches classical win probability of 6/7. return false; } - // Task 1.4. Referee classical W game + // Task 1.4. Best classical strategy + operation BestClassicalStrategy_Reference (input : Bool) : Bool { + // The optimal classical strategy that I (R.S.L.S.) am aware of: + // - - - If input is true, return true + // - - - If input is false, return true with probability (1 - sqrt(6)/3) ~ 0.1835. + // This reaches a win rate of roughly 89.5%. + if (input) { + return true; + } + return RandomInt(10000) < 1835; + } + + + // Task 1.5. Referee classical W game operation PlayClassicalW_Reference (strategy : (Bool => Bool), inputs : Bool[]) : Bool[] { return ForEach(strategy, inputs); } diff --git a/WGame/Tasks.qs b/WGame/Tasks.qs index 7d0c9526ac3..4b10a5ca4a8 100644 --- a/WGame/Tasks.qs +++ b/WGame/Tasks.qs @@ -78,18 +78,33 @@ namespace Quantum.Kata.WGame { } - // Task 1.3. Best classical strategy + // Task 1.3. Simple classical strategy + // Input: The input bit for one of the players (r, s or t). + // Output: A bit that this player will output (a, b or c) for a good chance of winning. + // All players will use the same strategy. + // Any of several possible naive classical strategies that win 6/7 of the time (85.7%). + operation SimpleClassicalStrategy (input : Bool) : Bool { + // ... + fail "Task 1.3 not implemented yet"; + } + + + // "Bonus" Task 1.4. Best classical strategy // Input: The input bit for one of the players (r, s or t). // Output: A bit that this player will output (a, b or c) to maximize their chance of winning. // All players will use the same strategy. - // The best classical strategy should win about 6/7 of the time (85.7%). + // The optimal classical strategy should win just under 90% of the time. + + // NOTE: Calculus, advanced probability theory, and heavy-duty number crunching + // may come into play here! + // Those who are here for the quantum content, I advise proceeding past this, to 1.5. operation BestClassicalStrategy (input : Bool) : Bool { // ... - fail "Task 1.3 not implemented yet"; + fail "Task 1.4 not implemented yet"; } - // Task 1.4. Referee classical W game + // Task 1.5. Referee classical W game // Inputs: // 1) an operation which implements a classical strategy // (i.e., takes an input bit and produces and output bit), @@ -98,7 +113,7 @@ namespace Quantum.Kata.WGame { // An array of 3 bits that will be produced if each player uses this strategy. operation PlayClassicalW (strategy : (Bool => Bool), inputs : Bool[]) : Bool[] { // ... - fail "Task 1.4 not implemented yet"; + fail "Task 1.5 not implemented yet"; } diff --git a/WGame/Tests.qs b/WGame/Tests.qs index ea9358a3262..c5871d9bda5 100644 --- a/WGame/Tests.qs +++ b/WGame/Tests.qs @@ -59,8 +59,14 @@ namespace Quantum.Kata.WGame { // ------------------------------------------------------ - operation T13_BestClassical_Test () : Unit { - EqualityWithinToleranceFact(GetClassicalStrategySuccessRate(10000, BestClassicalStrategy), 0.857, 0.02); + operation T13_SimpleClassical_Test () : Unit { + EqualityWithinToleranceFact(GetClassicalStrategySuccessRate(10000, SimpleClassicalStrategy), 0.857, 0.02); + } + + + // ------------------------------------------------------ + operation T14_BestClassical_Test () : Unit { + EqualityWithinToleranceFact(GetClassicalStrategySuccessRate(10000, BestClassicalStrategy), 0.895, 0.02); } @@ -70,7 +76,7 @@ namespace Quantum.Kata.WGame { } - operation T14_PlayClassicalW_Test () : Unit { + operation T15_PlayClassicalW_Test () : Unit { // To test the interaction, run it on several deterministic strategies (not necessarily good ones) let inputs = RefereeBits(); for (rst in inputs) { diff --git a/WGame/WGame.ipynb b/WGame/WGame.ipynb index 6402bd654c2..82e21f1dcb2 100644 --- a/WGame/WGame.ipynb +++ b/WGame/WGame.ipynb @@ -149,14 +149,44 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Task 1.3. Best classical strategy\n", + "### Task 1.3. Simple classical strategy\n", + "\n", + "**Input:** The input bit for one of the players (r, s or t).\n", + "\n", + "**Output:** A bit that this player will output (a, b or c) to achieve a good chance of winning.\n", + "\n", + "All players will use the same strategy.\n", + "Multiple naive classical strategies are possible that attain a theoretical win probability of 6/7, or almost 86% of the time." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%kata T13_SimpleClassical_Test \n", + "\n", + "operation SimpleClassicalStrategy (input : Bool) : Bool {\n", + " // ...\n", + " fail \"Task 1.3 not implemented yet\";\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### \"Bonus\" Task 1.4. Best classical strategy\n", "\n", "**Input:** The input bit for one of the players (r, s or t).\n", "\n", "**Output:** A bit that this player will output (a, b or c) to maximize their chance of winning.\n", "\n", "All players will use the same strategy.\n", - "The best classical strategy should win about 86% of the time. Multiple optimal classical strategies are possible." + "The optimal classical strategy should win just under 90% of the time.\n", + "\n", + "Note: This could be thought of as a \"bonus\" task, for those who are into calculus, higher-level probability theory and heavy-duty number crunching." ] }, { @@ -165,11 +195,11 @@ "metadata": {}, "outputs": [], "source": [ - "%kata T13_BestClassical_Test \n", + "%kata T14_BestClassical_Test \n", "\n", "operation BestClassicalStrategy (input : Bool) : Bool {\n", " // ...\n", - " fail \"Task 1.3 not implemented yet\";\n", + " fail \"Task 1.4 not implemented yet\";\n", "}" ] }, @@ -177,7 +207,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Task 1.4. Referee classical W game\n", + "### Task 1.5. Referee classical W game\n", "\n", "**Inputs:** \n", "\n", @@ -195,11 +225,11 @@ "metadata": {}, "outputs": [], "source": [ - "%kata T14_PlayClassicalW_Test \n", + "%kata T15_PlayClassicalW_Test \n", "\n", "operation PlayClassicalW (strategy : (Bool => Bool), inputs : Bool[]) : Bool[] {\n", " // ...\n", - " fail \"Task 1.4 not implemented yet\";\n", + " fail \"Task 1.5 not implemented yet\";\n", "}" ] }, From 2700f2f27fcd138e73caf87e333d1d6e17f5461d Mon Sep 17 00:00:00 2001 From: Richard Stein Date: Wed, 29 Jul 2020 23:59:08 -0700 Subject: [PATCH 4/7] Simplified W game rules, added symmetry condition, updated math --- WGame/ReferenceImplementation.qs | 27 +++++++++++------------ WGame/Tasks.qs | 32 +++++++++++++-------------- WGame/Tests.qs | 18 +++++++-------- WGame/WGame.ipynb | 38 +++++++++++++++----------------- 4 files changed, 56 insertions(+), 59 deletions(-) diff --git a/WGame/ReferenceImplementation.qs b/WGame/ReferenceImplementation.qs index fdc7ae2a02a..27e88ffff6a 100644 --- a/WGame/ReferenceImplementation.qs +++ b/WGame/ReferenceImplementation.qs @@ -24,17 +24,16 @@ namespace Quantum.Kata.WGame { // Task 1.1. Win condition function WinCondition_Reference (rst : Bool[], abc : Bool[]) : Bool { - mutable rstOnes = 0; mutable abcOnes = 0; - for (i in rst) { if (i) {set rstOnes = rstOnes + 1;} } - for (i in abc) { if (i) {set abcOnes = abcOnes + 1;} } - if (rstOnes == 2) { - return (abcOnes != 1); + for (i in abc) { + if (i) { + set abcOnes = abcOnes + 1; + } } - if (rstOnes == 1) { - return (abcOnes < 3); + if (rst[0] or rst[1] or rst[2]) { + return (abcOnes != 1); } - return (abcOnes == 1); // By initial conditions, if rstOnes is not 1 or 2, it must be 0 + return (abcOnes == 1); } @@ -46,21 +45,21 @@ namespace Quantum.Kata.WGame { // Task 1.3. Simple classical strategy operation SimpleClassicalStrategy_Reference (input : Bool) : Bool { - // One of several simple strategies that reaches classical win probability of 6/7. - return false; + // One of several simple strategies that reaches classical win probability of 75%. + return true; } // Task 1.4. Best classical strategy operation BestClassicalStrategy_Reference (input : Bool) : Bool { - // The optimal classical strategy that I (R.S.L.S.) am aware of: + // The optimal classical strategy, under the condition of symmetrical approaches: // - - - If input is true, return true - // - - - If input is false, return true with probability (1 - sqrt(6)/3) ~ 0.1835. - // This reaches a win rate of roughly 89.5%. + // - - - If input is false, return true with probability 1/3. + // This reaches a win rate of 31/36, or roughly 86.1%. if (input) { return true; } - return RandomInt(10000) < 1835; + return RandomInt(3) == 0; } diff --git a/WGame/Tasks.qs b/WGame/Tasks.qs index 4b10a5ca4a8..113b3d6b1ae 100644 --- a/WGame/Tasks.qs +++ b/WGame/Tasks.qs @@ -29,16 +29,17 @@ namespace Quantum.Kata.WGame { // | between players | needed to win | // +-------------------+------------------+ // | 0 | exactly 1 | - // | 1 | 0, 1, or 2 | // | 2 | 0, 2, or 3 | // +-------------------+------------------+ - // All that is given is that at least one of the input bits is set - // to false, leaving seven scenarios that are all equally likely: + // Either two of the input bits will be true, or all will be false; + // thus, these four scenarios are all equally likely: - // F,F,F T,F,F F,T,F F,F,T T,T,F T,F,T F,T,T + // F,F,F T,T,F T,F,T F,T,T // Like the GHZ and CHSH games, the players can not communicate during the game. + // Also, in this form of the game, all the players have to use the same approach, so, + // for instance, the team may not have Charlie follow a different protocol from Alice and Bob. // Each task is wrapped in one operation preceded by the // description of the task. Each task has a unit test associated @@ -55,9 +56,11 @@ namespace Quantum.Kata.WGame { // Input: // 1) Alice, Bob and Charlie's input bits (r, s and t), stored as an array of length 3, // 2) Alice, Bob and Charlie's output bits (a, b and c), stored as an array of length 3. - // The input bits will have zero, one, or two bits set to true. + // The input bits will have zero or two bits set to true. // Output: - // True if Alice, Bob and Charlie won the W game (see above table), + // True if Alice, Bob and Charlie won the W game + // (one true bit between them if no input bits were true + // or any other number of true bits between them if two input bits were true), // and false otherwise. function WinCondition (rst : Bool[], abc : Bool[]) : Bool { // ... @@ -69,9 +72,8 @@ namespace Quantum.Kata.WGame { // Input: The input bit for one of the players (r, s or t). // Output: A random bit that this player will output (a, b or c). // If all players use this strategy, their win odds will be: - // (1/7 x 1/8) (zero input bits true) - // + (3/7 x 7/8) ( one input bit true) - // + (3/7 x 5/8) ( two input bits true) = 37/56, or about 66.1% of the time. + // (1/4 x 3/8) (zero input bits true) + // + (3/4 x 5/8) ( two input bits true) = 9/16, or about 56% of the time. operation RandomClassicalStrategy (input : Bool) : Bool { // ... fail "Task 1.2 not implemented yet"; @@ -82,22 +84,20 @@ namespace Quantum.Kata.WGame { // Input: The input bit for one of the players (r, s or t). // Output: A bit that this player will output (a, b or c) for a good chance of winning. // All players will use the same strategy. - // Any of several possible naive classical strategies that win 6/7 of the time (85.7%). + // Any of several possible naive classical strategies that win 3/4 of the time (75%). operation SimpleClassicalStrategy (input : Bool) : Bool { // ... fail "Task 1.3 not implemented yet"; } - // "Bonus" Task 1.4. Best classical strategy + // Task 1.4. Best classical strategy // Input: The input bit for one of the players (r, s or t). // Output: A bit that this player will output (a, b or c) to maximize their chance of winning. - // All players will use the same strategy. - // The optimal classical strategy should win just under 90% of the time. + // By rule, all players will use the same strategy. + // With this symmetry imposed, the optimal classical strategy should win about 86% of the time. - // NOTE: Calculus, advanced probability theory, and heavy-duty number crunching - // may come into play here! - // Those who are here for the quantum content, I advise proceeding past this, to 1.5. + // Note: Some intermediate probability theory will be involved here. operation BestClassicalStrategy (input : Bool) : Bool { // ... fail "Task 1.4 not implemented yet"; diff --git a/WGame/Tests.qs b/WGame/Tests.qs index c5871d9bda5..1914dbb4f99 100644 --- a/WGame/Tests.qs +++ b/WGame/Tests.qs @@ -18,9 +18,6 @@ namespace Quantum.Kata.WGame { // to Alice, Bob and Charlie. function RefereeBits () : Bool[][] { return [[false, false, false], - [true, false, false], - [false, true, false], - [false, false, true], [true, true, false], [false, true, true], [true, false, true]]; @@ -54,19 +51,19 @@ namespace Quantum.Kata.WGame { } operation T12_RandomClassical_Test () : Unit { - EqualityWithinToleranceFact(GetClassicalStrategySuccessRate(10000, RandomClassicalStrategy), 0.661, 0.02); + EqualityWithinToleranceFact(GetClassicalStrategySuccessRate(10000, RandomClassicalStrategy), 0.5625, 0.02); } // ------------------------------------------------------ operation T13_SimpleClassical_Test () : Unit { - EqualityWithinToleranceFact(GetClassicalStrategySuccessRate(10000, SimpleClassicalStrategy), 0.857, 0.02); + EqualityWithinToleranceFact(GetClassicalStrategySuccessRate(10000, SimpleClassicalStrategy), 0.75, 0.02); } // ------------------------------------------------------ operation T14_BestClassical_Test () : Unit { - EqualityWithinToleranceFact(GetClassicalStrategySuccessRate(10000, BestClassicalStrategy), 0.895, 0.02); + EqualityWithinToleranceFact(GetClassicalStrategySuccessRate(10000, BestClassicalStrategy), 0.8611, 0.02); } @@ -134,15 +131,18 @@ namespace Quantum.Kata.WGame { // ------------------------------------------------------ operation T23_PlayQuantumW_Test () : Unit { - for (i in 0..1000) { + mutable wins = 0; + for (i in 1..10000) { let rst = (RefereeBits())[RandomInt(Length(RefereeBits()))]; let strategies = [QuantumStrategy_Reference(rst[0], _), QuantumStrategy_Reference(rst[1], _), QuantumStrategy_Reference(rst[2], _)]; let abc = PlayQuantumW(strategies); - EqualityFactB(WinCondition_Reference(rst, abc), true, - $"Quantum strategy lost: for rst={rst} the players returned abc={abc}"); + if (WinCondition_Reference(rst, abc)) { + set wins = wins + 1; + } } + EqualityWithinToleranceFact(IntAsDouble(wins) / 10000.0, 0.9375, 0.01); } } diff --git a/WGame/WGame.ipynb b/WGame/WGame.ipynb index 82e21f1dcb2..23d9aa18cf3 100644 --- a/WGame/WGame.ipynb +++ b/WGame/WGame.ipynb @@ -17,19 +17,18 @@ "to the sum of the input bits in the following way:\n", "\n", "```\n", - "+-------------------------------+----------------------------------+\n", - "| Number of true bits in | Number of true bits in |\n", - "| input between players | output needed to win |\n", - "+-------------------------------+----------------------------------+\n", - "| 0 | exactly 1 |\n", - "| 1 | 0, 1, or 2 |\n", - "| 2 | 0, 2, or 3 |\n", - "+-------------------------------+----------------------------------+\n", + "+-------------------------------+---------------------------------------+\n", + "| Number of true bits in | Number of true bits in |\n", + "| input between players | output needed to win |\n", + "+-------------------------------+---------------------------------------+\n", + "| 0 | exactly 1 |\n", + "| 2 | 0, 2, or 3 (i.e. any number but 1) |\n", + "+-------------------------------+---------------------------------------+\n", "```\n", "\n", - "The input bits can be any combination of true or false\n", - "except that all three will not be true (at least one will be false).\n", + "The input will have zero or two bits set to true, and one or three bits set to false.\n", "The trick is, the players can not communicate during the game.\n", + "Also, all the players have to use the same approach (i.e. in this game, the team may not have Charlie follow a different protocol from Alice and Bob).\n", "\n", "The W state represents one of the two non-biseparable classes of three-qubit entangled states; the GHZ state represents the other. These two states cannot be transformed into each other by local (one-qubit) quantum operations, and therefore represent two fundamentally distinct types of tripartite entanglement. For further information: https://en.wikipedia.org/wiki/W_state\n", "\n", @@ -92,14 +91,13 @@ "\n", " 2. Alice, Bob and Charlie's output bits (a, b and c), stored as an array of length 3.\n", "\n", - "The input bits will have zero, one, or two bits set to true.\n", + "The input bits will have zero or two bits set to true.\n", "\n", "**Output:** \n", "True if Alice, Bob and Charlie won the W game, that is, if:\n", "\n", - "* All three input bits were false, and there was exactly one true bit among the team's output bits\n", - "* Exactly one input bit was true, and at least one of Alice, Bob or Charlie submitted a false output bit\n", - "* Exactly two input bits were true, and Alice, Bob and Charlie submitted all true, all false, or exactly two true output bits\n", + "* All three input bits were false, and there was exactly one true bit among the team's output bits;\n", + "* Two input bits were true, and the number of true bits among the team's output bits was any number other than 1\n", "\n", "and false otherwise." ] @@ -128,7 +126,7 @@ "\n", "**Output:** A random bit that this player will output (a, b or c).\n", "\n", - "If all players use this strategy, they will win about 66% of the time." + "If all players use this strategy, they will win about 56% of the time." ] }, { @@ -156,7 +154,7 @@ "**Output:** A bit that this player will output (a, b or c) to achieve a good chance of winning.\n", "\n", "All players will use the same strategy.\n", - "Multiple naive classical strategies are possible that attain a theoretical win probability of 6/7, or almost 86% of the time." + "Multiple naive classical strategies are possible that attain a theoretical win probability of 3/4, or 75% of the time." ] }, { @@ -177,16 +175,16 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### \"Bonus\" Task 1.4. Best classical strategy\n", + "### Task 1.4. Best classical strategy\n", "\n", "**Input:** The input bit for one of the players (r, s or t).\n", "\n", "**Output:** A bit that this player will output (a, b or c) to maximize their chance of winning.\n", "\n", - "All players will use the same strategy.\n", - "The optimal classical strategy should win just under 90% of the time.\n", + "By rule, all players will use the same strategy.\n", + "With this symmetry imposed, the optimal classical strategy should win just over 86% of the time.\n", "\n", - "Note: This could be thought of as a \"bonus\" task, for those who are into calculus, higher-level probability theory and heavy-duty number crunching." + "Some intermediate probability theory is involved here." ] }, { From 2f5830885801c39c2e890a6883064e3cb4565083 Mon Sep 17 00:00:00 2001 From: Richard Stein Date: Thu, 30 Jul 2020 13:38:05 -0700 Subject: [PATCH 5/7] pre-copy W game notebook --- WGame/ReferenceImplementation.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WGame/ReferenceImplementation.qs b/WGame/ReferenceImplementation.qs index 27e88ffff6a..40574baafb6 100644 --- a/WGame/ReferenceImplementation.qs +++ b/WGame/ReferenceImplementation.qs @@ -52,7 +52,7 @@ namespace Quantum.Kata.WGame { // Task 1.4. Best classical strategy operation BestClassicalStrategy_Reference (input : Bool) : Bool { - // The optimal classical strategy, under the condition of symmetrical approaches: + // The optimal classical strategy, under the condition that approaches are common to all players: // - - - If input is true, return true // - - - If input is false, return true with probability 1/3. // This reaches a win rate of 31/36, or roughly 86.1%. From d0e93d16120bc7a3866638e423bd0824743deab3 Mon Sep 17 00:00:00 2001 From: Richard Stein Date: Thu, 30 Jul 2020 15:51:25 -0700 Subject: [PATCH 6/7] Added workbook, adjustment to rules --- WGame/Tasks.qs | 10 +- WGame/WGame.ipynb | 3 +- WGame/Workbook_WGame.ipynb | 613 +++++++++++++++++++++++++++++++++++++ 3 files changed, 623 insertions(+), 3 deletions(-) create mode 100644 WGame/Workbook_WGame.ipynb diff --git a/WGame/Tasks.qs b/WGame/Tasks.qs index 113b3d6b1ae..0d9302307fe 100644 --- a/WGame/Tasks.qs +++ b/WGame/Tasks.qs @@ -38,8 +38,14 @@ namespace Quantum.Kata.WGame { // F,F,F T,T,F T,F,T F,T,T // Like the GHZ and CHSH games, the players can not communicate during the game. - // Also, in this form of the game, all the players have to use the same approach, so, - // for instance, the team may not have Charlie follow a different protocol from Alice and Bob. + + // Also, in this form of the game, all the players have to use the same approach, + // if dependent on the input (i.e. in this game, the team may not have Charlie follow + // a different protocol from Alice and Bob, if any of the protocols depend on the input). + // However, this restriction only applies to strategies for which the composition of the + // team's output bits could vary; the rules permit them individual strategies that are + // independent of the input (such as Bob always outputs true while Alice and Charlie output + // false) allowing them to ensure that exactly one true bit gets submitted between them. // Each task is wrapped in one operation preceded by the // description of the task. Each task has a unit test associated diff --git a/WGame/WGame.ipynb b/WGame/WGame.ipynb index 23d9aa18cf3..89217bc61e5 100644 --- a/WGame/WGame.ipynb +++ b/WGame/WGame.ipynb @@ -28,7 +28,8 @@ "\n", "The input will have zero or two bits set to true, and one or three bits set to false.\n", "The trick is, the players can not communicate during the game.\n", - "Also, all the players have to use the same approach (i.e. in this game, the team may not have Charlie follow a different protocol from Alice and Bob).\n", + "\n", + "**Also,** in this game, all the players have to use the same approach, **if** dependent on the input (i.e. in this game, the team may not have Charlie follow a different protocol from Alice and Bob, **if** any of the protocols depend on the input). **However,** this restriction only applies to strategies for which the composition of the team's output bits could vary; the rules permit them individual strategies that are independent of the input (such as Bob always outputs true while Alice and Charlie output false) allowing them to ensure that exactly one true bit gets submitted between them.\n", "\n", "The W state represents one of the two non-biseparable classes of three-qubit entangled states; the GHZ state represents the other. These two states cannot be transformed into each other by local (one-qubit) quantum operations, and therefore represent two fundamentally distinct types of tripartite entanglement. For further information: https://en.wikipedia.org/wiki/W_state\n", "\n", diff --git a/WGame/Workbook_WGame.ipynb b/WGame/Workbook_WGame.ipynb new file mode 100644 index 00000000000..4bed7ba045b --- /dev/null +++ b/WGame/Workbook_WGame.ipynb @@ -0,0 +1,613 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# W Game\n", + "\n", + "The **W Game** quantum kata is an original series of exercises based on the katas for the GHZ\n", + "and CHSH games, introducing an original game inspired by these and referred to here as the \"W game\".\n", + "\n", + "In it three players (Alice, Bob and Charlie) try to win the following game:\n", + "\n", + "Each of them is given a bit (r, s and t respectively), and\n", + "they have to return new bits (a, b and c respectively) so\n", + "that the sum (number of true bits) of their output bits corresponds\n", + "to the sum of the input bits in the following way:\n", + "\n", + "```\n", + "+-------------------------------+---------------------------------------+\n", + "| Number of true bits in | Number of true bits in |\n", + "| input between players | output needed to win |\n", + "+-------------------------------+---------------------------------------+\n", + "| 0 | exactly 1 |\n", + "| 2 | 0, 2, or 3 (i.e. any number but 1) |\n", + "+-------------------------------+---------------------------------------+\n", + "```\n", + "\n", + "The input will have zero or two bits set to true, and one or three bits set to false.\n", + "The trick is, the players can not communicate during the game.\n", + "\n", + "**Also,** in this game, all the players have to use the same approach, **if** dependent on the input (i.e. in this game, the team may not have Charlie follow a different protocol from Alice and Bob, **if** any of the protocols depend on the input). **However,** this restriction only applies to strategies for which the composition of the team's output bits could vary; the rules permit them individual strategies that are independent of the input (such as Bob always outputs true while Alice and Charlie output false) allowing them to ensure that exactly one true bit gets submitted between them.\n", + "\n", + "The W state represents one of the two non-biseparable classes of three-qubit entangled states; the GHZ state represents the other. These two states cannot be transformed into each other by local (one-qubit) quantum operations, and therefore represent two fundamentally distinct types of tripartite entanglement. For further information: https://en.wikipedia.org/wiki/W_state\n", + "\n", + "Each task is wrapped in one operation preceded by the description of the task.\n", + "Your goal is to fill in the blank (marked with the `// ...` comments)\n", + "with some Q# code that solves the task. To verify your answer, run the cell using Ctrl/⌘+Enter.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To begin, first prepare this notebook for execution (if you skip this step, you'll get \"Syntax does not match any known patterns\" error when you try to execute Q# code in the next cells):" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "application/json": "{\"LastUpdated\":\"2020-07-30T13:43:56.6179927-07:00\",\"IsCompleted\":true,\"Description\":\"Adding package Microsoft.Quantum.Katas::0.12.20072031\",\"Subtask\":\"done\"}", + "text/plain": [ + "Adding package Microsoft.Quantum.Katas::0.12.20072031: done!" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/json": "[\"Microsoft.Quantum.Standard::0.12.20072031\",\"Microsoft.Quantum.Katas::0.12.20072031\"]", + "text/html": [ + "
  • Microsoft.Quantum.Standard::0.12.20072031
  • Microsoft.Quantum.Katas::0.12.20072031
" + ], + "text/plain": [ + "Microsoft.Quantum.Standard::0.12.20072031, Microsoft.Quantum.Katas::0.12.20072031" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%package Microsoft.Quantum.Katas::0.12.20072031" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "> The package versions in the output of the cell above should always match. If you are running the Notebooks locally and the versions do not match, please install the IQ# version that matches the version of the `Microsoft.Quantum.Katas` package.\n", + ">
\n", + "> How to install the right IQ# version\n", + "> For example, if the version of `Microsoft.Quantum.Katas` package above is 0.1.2.3, the installation steps are as follows:\n", + ">\n", + "> 1. Stop the kernel.\n", + "> 2. Uninstall the existing version of IQ#:\n", + "> dotnet tool uninstall microsoft.quantum.iqsharp -g\n", + "> 3. Install the matching version:\n", + "> dotnet tool install microsoft.quantum.iqsharp -g --version 0.1.2.3\n", + "> 4. Reinstall the kernel:\n", + "> dotnet iqsharp install\n", + "> 5. Restart the Notebook.\n", + ">
\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Part I. Classical W game\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Task 1.1. Win Condition\n", + "**Inputs:** \n", + "\n", + " 1. Alice, Bob and Charlie's input bits (r, s and t), stored as an array of length 3,\n", + "\n", + " 2. Alice, Bob and Charlie's output bits (a, b and c), stored as an array of length 3.\n", + "\n", + "The input bits will have zero or two bits set to true.\n", + "\n", + "**Output:** \n", + "True if Alice, Bob and Charlie won the W game, that is, if:\n", + "\n", + "* All three input bits were false, and there was exactly one true bit among the team's output bits;\n", + "* Two input bits were true, and the number of true bits among the team's output bits was any number other than 1\n", + "\n", + "and false otherwise." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "application/json": "\"Success!\"", + "text/plain": [ + "Success!" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%kata T11_WinCondition_Test \n", + "\n", + "function WinCondition (rst : Bool[], abc : Bool[]) : Bool {\n", + " mutable abcOnes = 0;\n", + " for (i in abc) {\n", + " if (i) {\n", + " set abcOnes = abcOnes + 1; // Get number of true bits in output\n", + " }\n", + " }\n", + " if (rst[0] or rst[1] or rst[2]) {\n", + " return (abcOnes != 1); // Condition where two input bits are true\n", + " }\n", + " return (abcOnes == 1); // Condition where zero input bits are true\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Task 1.2. Random classical strategy\n", + "\n", + "**Input:** The input bit for one of the players (r, s or t).\n", + "\n", + "**Output:** A random bit that this player will output (a, b or c).\n", + "\n", + "If all players use this strategy, they will win about 56% of the time." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "application/json": "\"Success!\"", + "text/plain": [ + "Success!" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%kata T12_RandomClassical_Test \n", + "\n", + "operation RandomClassicalStrategy (input : Bool) : Bool {\n", + " let coin = Random([0.5, 0.5]);\n", + " return (coin == 1);\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Task 1.3. Simple classical strategy\n", + "\n", + "**Input:** The input bit for one of the players (r, s or t).\n", + "\n", + "**Output:** A bit that this player will output (a, b or c) to achieve a good chance of winning.\n", + "\n", + "All players will use the same strategy.\n", + "Multiple naive classical strategies are possible that attain a theoretical win probability of 3/4, or 75% of the time." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "application/json": "\"Success!\"", + "text/plain": [ + "Success!" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%kata T13_SimpleClassical_Test \n", + "\n", + "operation SimpleClassicalStrategy (input : Bool) : Bool {\n", + " return true; // One of several simple classical strategies with 75% win odds.\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Task 1.4. Best classical strategy\n", + "\n", + "**Input:** The input bit for one of the players (r, s or t).\n", + "\n", + "**Output:** A bit that this player will output (a, b or c) to maximize their chance of winning.\n", + "\n", + "By rule, all players will use the same strategy.\n", + "With this symmetry imposed, the optimal classical strategy should win just over 86% of the time.\n", + "\n", + "Some intermediate probability theory is involved here." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "application/json": "\"Success!\"", + "text/plain": [ + "Success!" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%kata T14_BestClassical_Test \n", + "\n", + "open Microsoft.Quantum.Math;\n", + "\n", + "// When input is true, always return true;\n", + "// when input is false, return true with probability 1/3 and false with probability 2/3.\n", + "// This always wins against two true bits.\n", + "// Against zero true bits, this maximizes the probability at 4/9 of producing exactly one true output bit to win.\n", + "// This leads to a victory chance of (1/4 * 4/9) + (3/4 * 1) = 31/36, or about 86.11%\n", + "\n", + "operation BestClassicalStrategy (input : Bool) : Bool {\n", + " if (input) {\n", + " return true;\n", + " }\n", + " return RandomInt(3) == 0;\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Task 1.5. Referee classical W game\n", + "\n", + "**Inputs:** \n", + "\n", + " 1. An operation which implements a classical strategy (i.e., takes an input bit and produces an output bit),\n", + "\n", + " 2. An array of 3 input bits that should be passed to the players.\n", + "\n", + "**Output:** \n", + "An array of 3 bits that will be produced if each player uses this strategy." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "application/json": "\"Success!\"", + "text/plain": [ + "Success!" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%kata T15_PlayClassicalW_Test \n", + "\n", + "operation PlayClassicalW (strategy : (Bool => Bool), inputs : Bool[]) : Bool[] {\n", + " // Input bits and strategy are given, so simply convert them to the output bits.\n", + " let r = inputs[0];\n", + " let s = inputs[1];\n", + " let t = inputs[2];\n", + " let a = strategy(r);\n", + " let b = strategy(s);\n", + " let c = strategy(t);\n", + " return [a, b, c];\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Part II. Quantum W game\n", + "\n", + "In the quantum version of the game, the players still can not\n", + "communicate during the game, but they are allowed to share \n", + "qubits from an entangled triple before the start of the game.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Task 2.1. Entangled triple\n", + "\n", + "**Input:** An array of three qubits in the $|000\\rangle$ state.\n", + "\n", + "**Goal:** Create the entangled state $|W\\rangle = \\frac{1}{\\sqrt{3}} \\big(|001\\rangle + |010\\rangle + |100\\rangle \\big)$ on these qubits." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "application/json": "\"Success!\"", + "text/plain": [ + "Success!" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%kata T21_CreateEntangledTriple_Test \n", + "\n", + "operation CreateEntangledTriple (qs : Qubit[]) : Unit {\n", + " let theta = ArcSin(1.0 / Sqrt(3.0));\n", + " Ry(2.0 * theta, qs[0]);\n", + " // Starting from |000>, this produces {sqrt(2/3) |000> + sqrt(1/3) |100>}.\n", + "\n", + " (ControlledOnBitString([false], H))([qs[0]], qs[1]);\n", + " // Hadamard-transforms second qubit when first is 0,\n", + " // so this leads to (|000> + |010> + |100>) / sqrt(3).\n", + "\n", + " (ControlledOnBitString([false, false], X))([qs[0], qs[1]], qs[2]);\n", + " // Applies NOT gate to third qubit when first two are both 0, leading to the W state desired.\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Task 2.2. Quantum strategy\n", + "\n", + "**Inputs:**\n", + "\n", + " 1. The input bit for one of the players (r, s or t),\n", + "\n", + " 2. That player's qubit of the entangled triple shared between the players.\n", + "\n", + "**Goal:** Measure the qubit in the Z basis if the bit is 0 (false), or the X basis if the bit is 1 (true), and return the result.\n", + "\n", + "The state of the qubit after the operation does not matter." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "application/json": "\"Success!\"", + "text/plain": [ + "Success!" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%kata T22_QuantumStrategy_Test \n", + "\n", + "open Microsoft.Quantum.Measurement;\n", + "\n", + "operation QuantumStrategy (input : Bool, qubit : Qubit) : Bool {\n", + " if (input) {\n", + " let q = MResetX(qubit);\n", + " return (q == One);\n", + " }\n", + " else {\n", + " let q = MResetZ(qubit);\n", + " return (q == One);\n", + " }\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Task 2.3. Play the W game using the quantum strategy\n", + "\n", + "**Input:** Operations that return Alice, Bob and Charlie's output bits (a, b and c) based on\n", + "their quantum strategies and given their respective qubits from the entangled triple.\n", + "The players have already been told what their starting bits (r, s and t) are.\n", + "\n", + "**Goal:** Return an array of players' output bits (a, b and c)." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "application/json": "\"Success!\"", + "text/plain": [ + "Success!" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%kata T23_PlayQuantumW_Test \n", + "\n", + "operation PlayQuantumW (strategies : (Qubit => Bool)[]) : Bool[] {\n", + " using (qs = Qubit[3]) {\n", + " CreateEntangledTriple(qs);\n", + " \n", + " let a = strategies[0](qs[0]);\n", + " let b = strategies[1](qs[1]);\n", + " let c = strategies[2](qs[2]);\n", + "\n", + " return [a, b, c];\n", + " }\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Appraisal of quantum strategy\n", + "\n", + "Recall the formula for the win condition:\n", + "\n", + "* The sum of the answer bits must be 1 if the question bits are (0,0,0)\n", + "* The sum of the answer bits must be 0, 2, or 3 (i.e. unequal to 1) if the question bits are (0,1,1), (1,0,1) or (1,1,0).\n", + "\n", + "The standard phase vector for a three-qubit system is:\n", + "\n", + "$\n", + "\\begin{bmatrix}\n", + "\\psi_{000}\\\\\n", + "\\psi_{001}\\\\\n", + "\\psi_{010}\\\\\n", + "\\psi_{011}\\\\\n", + "\\psi_{100}\\\\\n", + "\\psi_{101}\\\\\n", + "\\psi_{110}\\\\\n", + "\\psi_{111}\n", + "\\end{bmatrix}\n", + "$\n", + "\n", + "For the initial W state, this vector has the following values:\n", + "\n", + "$\n", + "\\begin{bmatrix}\n", + "0\\\\\n", + "1/\\sqrt{3}\\\\\n", + "1/\\sqrt{3}\\\\\n", + "0\\\\\n", + "1/\\sqrt{3}\\\\\n", + "0\\\\\n", + "0\\\\\n", + "0\n", + "\\end{bmatrix}\n", + "$\n", + "\n", + "#### Zero input bits true\n", + "\n", + "When the input bits are all false, all three players simply take a Z-basis measurement of their qubit and output the result. One of the qubits will collapse to true and the others to false, so the win condition is met.\n", + "\n", + "#### Two input bits true\n", + "\n", + "When two input bits are true, the players holding the true bits will measure their qubit in the X basis, while the third measures in the Z. This operation is equivalent to the two players holding true input bits performing a Hadamard transform on their qubit and then measuring in the Z. Consider the set of input bits (0,1,1), for which Bob and Charlie perform a Hadamard transform on their qubits. The relevant $8 \\times 8$ operator matrix is:\n", + "\n", + "$\n", + "I \\otimes H \\otimes H =\n", + "\\begin{bmatrix}\n", + "1/2 & 1/2 & 1/2 & 1/2 & 0 & 0 & 0 & 0\\\\\n", + "1/2 & -1/2 & 1/2 & -1/2 & 0 & 0 & 0 & 0\\\\\n", + "1/2 & 1/2 & -1/2 & -1/2 & 0 & 0 & 0 & 0\\\\\n", + "1/2 & -1/2 & -1/2 & 1/2 & 0 & 0 & 0 & 0\\\\\n", + "0 & 0 & 0 & 0 & 1/2 & 1/2 & 1/2 & 1/2\\\\\n", + "0 & 0 & 0 & 0 & 1/2 & -1/2 & 1/2 & -1/2\\\\\n", + "0 & 0 & 0 & 0 & 1/2 & 1/2 & -1/2 & -1/2\\\\\n", + "0 & 0 & 0 & 0 & 1/2 & -1/2 & -1/2 & 1/2\n", + "\\end{bmatrix}\n", + "$\n", + "\n", + "Operating on the W state with this matrix leads to:\n", + "\n", + "$\n", + "\\begin{bmatrix}\n", + "1/\\sqrt{3}\\\\\n", + "0\\\\\n", + "0\\\\\n", + "-1/\\sqrt{3}\\\\\n", + "1/\\sqrt{12}\\\\\n", + "1/\\sqrt{12}\\\\\n", + "1/\\sqrt{12}\\\\\n", + "1/\\sqrt{12}\n", + "\\end{bmatrix}\n", + "$\n", + "\n", + "The players measure this entangled state in the Z basis, with the following outcomes possible:\n", + "\n", + "```\n", + "+-----------------------+--------------------------------+\n", + "| No. of |1> Qubits | Probability of Observation |\n", + "+-----------------------+--------------------------------+\n", + "| 0 | 1/3 |\n", + "| 1 | 1/12 |\n", + "| 2 | 1/2 |\n", + "| 3 | 1/12 |\n", + "+-----------------------+--------------------------------+\n", + "```\n", + "\n", + "The team only loses in the event of one qubit measured at $|1\\rangle$ and the others at $|0\\rangle$. This occurs $1/12$ of the time, so the team's total winning probability is $1/4 + (3/4)(11/12) = 1/4 + 11/16 = 15/16$, or a 93.75% chance. This is a substantial improvement on the 86.11% chance offered by the optimum symmetrical classical strategy in Task 1.4 above." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Q#", + "language": "qsharp", + "name": "iqsharp" + }, + "language_info": { + "file_extension": ".qs", + "mimetype": "text/x-qsharp", + "name": "qsharp", + "version": "0.12" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From b45c184143667f4c65783479fda538707e901465 Mon Sep 17 00:00:00 2001 From: Richard Stein Date: Thu, 30 Jul 2020 16:04:40 -0700 Subject: [PATCH 7/7] added other standard files --- WGame/README.md | 12 ++++++++++++ WGame/TestSuiteRunner.cs | 42 ++++++++++++++++++++++++++++++++++++++++ WGame/WGame.csproj | 16 +++++++++++++-- WGame/WGame.sln | 25 ++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 WGame/README.md create mode 100644 WGame/TestSuiteRunner.cs create mode 100644 WGame/WGame.sln diff --git a/WGame/README.md b/WGame/README.md new file mode 100644 index 00000000000..ae818189f40 --- /dev/null +++ b/WGame/README.md @@ -0,0 +1,12 @@ +# Welcome! + +This "kata" covers the W game, an original example of a +nonlocal (entanglement) game inspired by the well-known GHZ and CHSH games. + +You can [run the W Game kata as a Jupyter Notebook](https://mybinder.org/v2/gh/Microsoft/QuantumKatas/master?filepath=WGame%2FWGame.ipynb)! + +In a nonlocal game, several cooperating players play a game against a referee answering the referee's questions. The players are free to share information +(and even qubits!) before the game starts, but are forbidden from communicating +with each other afterwards. Nonlocal games show that quantum entanglement can be +used to increase the players' chance of winning beyond what would be possible with a +purely classical strategy. diff --git a/WGame/TestSuiteRunner.cs b/WGame/TestSuiteRunner.cs new file mode 100644 index 00000000000..7289e3cad70 --- /dev/null +++ b/WGame/TestSuiteRunner.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. + +////////////////////////////////////////////////////////////////////// +// This file contains parts of the testing harness. +// You should not modify anything in this file. +// The tasks themselves can be found in Tasks.qs file. +////////////////////////////////////////////////////////////////////// + +using Microsoft.Quantum.Simulation.XUnit; +using Microsoft.Quantum.Simulation.Simulators; +using Xunit.Abstractions; +using System.Diagnostics; + +namespace Quantum.Kata.WGame +{ + public class TestSuiteRunner + { + private readonly ITestOutputHelper output; + + public TestSuiteRunner(ITestOutputHelper output) + { + this.output = output; + } + + /// + /// This driver will run all Q# tests (operations named "...Test") + /// that belong to namespace Quantum.Kata.WGame. + /// + [OperationDriver(TestNamespace = "Quantum.Kata.WGame")] + public void TestTarget(TestOperation op) + { + using (var sim = new QuantumSimulator()) + { + // OnLog defines action(s) performed when Q# test calls function Message + sim.OnLog += (msg) => { output.WriteLine(msg); }; + sim.OnLog += (msg) => { Debug.WriteLine(msg); }; + op.TestOperationRunner(sim); + } + } + } +} diff --git a/WGame/WGame.csproj b/WGame/WGame.csproj index 23d549942dc..3914ca4da89 100644 --- a/WGame/WGame.csproj +++ b/WGame/WGame.csproj @@ -1,8 +1,20 @@ - - Exe netcoreapp3.1 + x64 + false + Quantum.Kata.WGame + + + + + + + + + + + diff --git a/WGame/WGame.sln b/WGame/WGame.sln new file mode 100644 index 00000000000..4fdd5de9620 --- /dev/null +++ b/WGame/WGame.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27428.2043 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{AFBF8E91-493B-406D-9FED-5DDA7F21D245}") = "WGame", "WGame.csproj", "{8C8A4A2B-99CC-4669-B2A6-FF75046F30A5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8C8A4A2B-99CC-4669-B2A6-FF75046F30A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8C8A4A2B-99CC-4669-B2A6-FF75046F30A5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8C8A4A2B-99CC-4669-B2A6-FF75046F30A5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8C8A4A2B-99CC-4669-B2A6-FF75046F30A5}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {638BD2DA-E2CE-4D23-B636-53501CA5DE05} + EndGlobalSection +EndGlobal