From f1c08d7e40eca0c791fbd035ee4325e95f09486b Mon Sep 17 00:00:00 2001 From: Gregory Gridin Date: Mon, 12 Aug 2024 19:47:47 -0700 Subject: [PATCH 01/18] Migrate nonlocal games #1596 task2 GHZ quantum --- .../Placeholder.qs | 5 + .../ghz_create_entangled_triple/Solution.qs | 17 ++++ .../Verification.qs | 40 ++++++++ .../ghz_create_entangled_triple/index.md | 9 ++ .../ghz_create_entangled_triple/solution.md | 13 +++ .../ghz_quantum_game/Placeholder.qs | 7 ++ .../ghz_quantum_game/Solution.qs | 32 +++++++ .../ghz_quantum_game/Verification.qs | 93 +++++++++++++++++++ .../nonlocal_games/ghz_quantum_game/index.md | 8 ++ .../ghz_quantum_game/solution.md | 11 +++ .../ghz_quantum_strategy/Placeholder.qs | 19 ++++ .../ghz_quantum_strategy/Solution.qs | 27 ++++++ .../ghz_quantum_strategy/Verification.qs | 44 +++++++++ .../ghz_quantum_strategy/index.md | 8 ++ .../ghz_quantum_strategy/solution.md | 12 +++ katas/content/nonlocal_games/index.md | 18 ++++ 16 files changed, 363 insertions(+) create mode 100644 katas/content/nonlocal_games/ghz_create_entangled_triple/Placeholder.qs create mode 100644 katas/content/nonlocal_games/ghz_create_entangled_triple/Solution.qs create mode 100644 katas/content/nonlocal_games/ghz_create_entangled_triple/Verification.qs create mode 100644 katas/content/nonlocal_games/ghz_create_entangled_triple/index.md create mode 100644 katas/content/nonlocal_games/ghz_create_entangled_triple/solution.md create mode 100644 katas/content/nonlocal_games/ghz_quantum_game/Placeholder.qs create mode 100644 katas/content/nonlocal_games/ghz_quantum_game/Solution.qs create mode 100644 katas/content/nonlocal_games/ghz_quantum_game/Verification.qs create mode 100644 katas/content/nonlocal_games/ghz_quantum_game/index.md create mode 100644 katas/content/nonlocal_games/ghz_quantum_game/solution.md create mode 100644 katas/content/nonlocal_games/ghz_quantum_strategy/Placeholder.qs create mode 100644 katas/content/nonlocal_games/ghz_quantum_strategy/Solution.qs create mode 100644 katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs create mode 100644 katas/content/nonlocal_games/ghz_quantum_strategy/index.md create mode 100644 katas/content/nonlocal_games/ghz_quantum_strategy/solution.md diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/Placeholder.qs b/katas/content/nonlocal_games/ghz_create_entangled_triple/Placeholder.qs new file mode 100644 index 0000000000..fc35a3eba4 --- /dev/null +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/Placeholder.qs @@ -0,0 +1,5 @@ +namespace Kata { + operation CreateEntangledTriple (qs : Qubit[]) : Unit { + // Implement your solution here... + } +} diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/Solution.qs b/katas/content/nonlocal_games/ghz_create_entangled_triple/Solution.qs new file mode 100644 index 0000000000..6124064a39 --- /dev/null +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/Solution.qs @@ -0,0 +1,17 @@ +namespace Kata { + operation CreateEntangledTriple (qs : Qubit[]) : Unit is Adj { + X(qs[0]); + X(qs[1]); + + H(qs[0]); + H(qs[1]); + // At this point we have (|000⟩ - |010⟩ - |100⟩ + |110⟩) / 2 + + // Flip the sign of the last term + Controlled Z([qs[0]], qs[1]); + + // Flip the state of the last qubit for the two middle terms + ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]); + ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]); + } +} diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/Verification.qs b/katas/content/nonlocal_games/ghz_create_entangled_triple/Verification.qs new file mode 100644 index 0000000000..c25ae633b4 --- /dev/null +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/Verification.qs @@ -0,0 +1,40 @@ +namespace Kata.Verification { + open Microsoft.Quantum.Diagnostics; + + operation CreateEntangledTriple_Reference (qs : Qubit[]) : Unit is Adj { + X(qs[0]); + X(qs[1]); + + H(qs[0]); + H(qs[1]); + // At this point we have (|000⟩ - |010⟩ - |100⟩ + |110⟩) / 2 + + // Flip the sign of the last term + Controlled Z([qs[0]], qs[1]); + + // Flip the state of the last qubit for the two middle terms + ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]); + ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]); + } + + @EntryPoint() + operation CheckSolution() : Bool { + use qs = Qubit[3]; + // apply operation that needs to be tested + Kata.CreateEntangledTriple(qs); + + // apply adjoint reference operation and check that the result is |0ᴺ⟩ + Adjoint CreateEntangledTriple_Reference(qs); + + // check that all qubits end up in |0⟩ state + let result = CheckAllZero(qs); + ResetAll(qs); + if result { + Message("Correct!"); + } + else { + Message("Entangled triple is not implemented correctly"); + } + return result; + } +} diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md new file mode 100644 index 0000000000..9a62c521e8 --- /dev/null +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md @@ -0,0 +1,9 @@ +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. + +**Input:** +- An array of three qubits in the $|000\rangle$ state. + +**Goal:** +- Create the entangled state $\ket{\Phi} = \frac{1}{2} \big(\ket{000} - \ket{011} - \ket{101} - \ket{110} \big)$ on these qubits. +This state is equivalent to GHZ state $\frac{1}{\sqrt{2}} (\big(\ket{000} + \ket{111} \big)$ up to local unitary operation. diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/solution.md b/katas/content/nonlocal_games/ghz_create_entangled_triple/solution.md new file mode 100644 index 0000000000..ea196a2b7b --- /dev/null +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/solution.md @@ -0,0 +1,13 @@ +1. Apply an X gate to the first and the second qubits to get the $\ket{110}$ state. +2. Appy an H gate to the first and the second qubits to get the following state: +$\frac12 \big( \ket{000} - \ket{010} - \ket{100} + \ket{110} \big)$ +3. Flip the sign of the last term using a controlled Z gate with the first qubit as control and the second qubit as target (or vice versa): +$\frac12 \big( \ket{000} - \ket{010} - \ket{100} -{\color{blue}\ket{110}} \big)$ +4. Now we have the right signs for each term, and the first and the last terms match those of the state we're preparing, so we just need to adjust the two middle terms. +To do this, we can use [ControlledOnBitString](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.canon.controlledonbitstring) operation to flip the state of the last qubit if the first two qubits are in $\ket{01}$ or in $\ket{10}$ states, which gives us: +$\frac{1}{2} \big(\ket{000} - {\color{blue}\ket{011}} - {\color{blue}\ket{101}} - \ket{110} \big)$ + +@[solution]({ + "id": "nonlocal_games__ghz_create_entangled_triple_solution", + "codePath": "Solution.qs" +}) diff --git a/katas/content/nonlocal_games/ghz_quantum_game/Placeholder.qs b/katas/content/nonlocal_games/ghz_quantum_game/Placeholder.qs new file mode 100644 index 0000000000..3ee6e1f331 --- /dev/null +++ b/katas/content/nonlocal_games/ghz_quantum_game/Placeholder.qs @@ -0,0 +1,7 @@ +namespace Kata { + operation PlayQuantumGHZ (strategies : ((Bool, Qubit) => Bool)[], inputs : Bool[]) : Bool[] { + // Implement your solution here... + + return []; + } +} diff --git a/katas/content/nonlocal_games/ghz_quantum_game/Solution.qs b/katas/content/nonlocal_games/ghz_quantum_game/Solution.qs new file mode 100644 index 0000000000..5d05cb9e60 --- /dev/null +++ b/katas/content/nonlocal_games/ghz_quantum_game/Solution.qs @@ -0,0 +1,32 @@ +namespace Kata { + operation CreateEntangledTriple (qs : Qubit[]) : Unit is Adj { + X(qs[0]); + X(qs[1]); + + H(qs[0]); + H(qs[1]); + // At this point we have (|000⟩ - |010⟩ - |100⟩ + |110⟩) / 2 + + // Flip the sign of the last term + Controlled Z([qs[0]], qs[1]); + + // Flip the state of the last qubit for the two middle terms + ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]); + ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]); + } + + operation PlayQuantumGHZ (strategies : ((Bool, Qubit) => Bool)[], inputs : Bool[]) : Bool[] { + use qs = Qubit[3]; + CreateEntangledTriple(qs); + + let r = inputs[0]; + let s = inputs[1]; + let t = inputs[2]; + let a = strategies[0](r, qs[0]); + let b = strategies[1](s, qs[1]); + let c = strategies[2](t, qs[2]); + + ResetAll(qs); + return [a, b, c]; + } +} diff --git a/katas/content/nonlocal_games/ghz_quantum_game/Verification.qs b/katas/content/nonlocal_games/ghz_quantum_game/Verification.qs new file mode 100644 index 0000000000..b9da0bc6f3 --- /dev/null +++ b/katas/content/nonlocal_games/ghz_quantum_game/Verification.qs @@ -0,0 +1,93 @@ +namespace Kata.Verification { + open Microsoft.Quantum.Diagnostics; + open Microsoft.Quantum.Canon; + open Microsoft.Quantum.Logical; + + // 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]]; + } + + 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]); + } + + operation AliceQuantum_Reference (bit : Bool, qubit : Qubit) : Bool { + if bit { + H(qubit); + } + return M(qubit) == One; + } + + operation BobQuantum_Reference (bit : Bool, qubit : Qubit) : Bool { + if bit { + H(qubit); + } + return M(qubit) == One; + } + + operation CharlieQuantum_Reference (bit : Bool, qubit : Qubit) : Bool { + if bit { + H(qubit); + } + return M(qubit) == One; + } + + operation CreateEntangledTriple_Reference (qs : Qubit[]) : Unit is Adj { + X(qs[0]); + X(qs[1]); + + H(qs[0]); + H(qs[1]); + // At this point we have (|000⟩ - |010⟩ - |100⟩ + |110⟩) / 2 + + // Flip the sign of the last term + Controlled Z([qs[0]], qs[1]); + + // Flip the state of the last qubit for the two middle terms + ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]); + ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]); + } + + operation PlayQuantumGHZ_Reference (strategies : ((Bool, Qubit) => Bool)[], inputs : Bool[]) : Bool[] { + use qs = Qubit[3]; + CreateEntangledTriple_Reference(qs); + let r = inputs[0]; + let s = inputs[1]; + let t = inputs[2]; + let a = strategies[0](r, qs[0]); + let b = strategies[1](s, qs[1]); + let c = strategies[2](t, qs[2]); + + ResetAll(qs); + return [a, b, c]; + } + + @EntryPoint() + operation CheckSolution() : Bool { + let inputs = RefereeBits(); + let strategies = [AliceQuantum_Reference, BobQuantum_Reference, CharlieQuantum_Reference]; + for rst in inputs { + let actualBits = Kata.PlayQuantumGHZ(strategies, rst); + if Length(actualBits) != 3 { + Message($"Expected 3 bits from PlayQuantumGHZ, got {Length(actualBits)}"); + return false; + } + let expectedBits = PlayQuantumGHZ_Reference(strategies, rst); + let actualWin = WinCondition_Reference(rst, actualBits); + let expectedWin = WinCondition_Reference(rst, expectedBits); + if actualWin != expectedWin { + Message($"Expected win={expectedWin} {expectedBits}, got {actualBits} for {rst}"); + return false; + } + else { + Message($"Cool {expectedBits}, got {actualBits} for {rst}"); + } + } + true + } +} diff --git a/katas/content/nonlocal_games/ghz_quantum_game/index.md b/katas/content/nonlocal_games/ghz_quantum_game/index.md new file mode 100644 index 0000000000..449fadb22c --- /dev/null +++ b/katas/content/nonlocal_games/ghz_quantum_game/index.md @@ -0,0 +1,8 @@ +Let's play the GHZ game using the quantum strategy. + +**Inputs:** +1. An array of three operations which implement the quantum strategies of the players, +2. An array of 3 input bits that should be passed to the players. + +**Goal:** +An array of three bits that will be produced if each player uses their given strategy. diff --git a/katas/content/nonlocal_games/ghz_quantum_game/solution.md b/katas/content/nonlocal_games/ghz_quantum_game/solution.md new file mode 100644 index 0000000000..f74e5fbea9 --- /dev/null +++ b/katas/content/nonlocal_games/ghz_quantum_game/solution.md @@ -0,0 +1,11 @@ +Putting together the building blocks we've implemented into a strategy is very simple: + +1. Allocate three qubits and prepare our entangled state on them (using `CreateEntangledTriple`). +2. Send one of the qubits to each of the players (this step is \"virtual\", not directly reflected in Q# code, other than making sure that the strategies each act on their qubit only). +3. Have the players perform their measurements on their respective qubits using corresponding elements of the `strategies` array. +4. Return their measurement results. + +@[solution]({ + "id": "nonlocal_games__ghz_quantum_game_solution", + "codePath": "Solution.qs" +}) diff --git a/katas/content/nonlocal_games/ghz_quantum_strategy/Placeholder.qs b/katas/content/nonlocal_games/ghz_quantum_strategy/Placeholder.qs new file mode 100644 index 0000000000..051a08d564 --- /dev/null +++ b/katas/content/nonlocal_games/ghz_quantum_strategy/Placeholder.qs @@ -0,0 +1,19 @@ +namespace Kata { + operation AliceQuantum (bit : Bool, qubit : Qubit) : Bool { + // Implement your solution here... + + return false; + } + + operation BobQuantum (bit : Bool, qubit : Qubit) : Bool { + // Implement your solution here... + + return false; + } + + operation CharlieQuantum (bit : Bool, qubit : Qubit) : Bool { + // Implement your solution here... + + return false; + } +} diff --git a/katas/content/nonlocal_games/ghz_quantum_strategy/Solution.qs b/katas/content/nonlocal_games/ghz_quantum_strategy/Solution.qs new file mode 100644 index 0000000000..3db48f34f0 --- /dev/null +++ b/katas/content/nonlocal_games/ghz_quantum_strategy/Solution.qs @@ -0,0 +1,27 @@ +namespace Kata { + operation AliceQuantum (bit : Bool, qubit : Qubit) : Bool { + if bit { + let res = MResetX(qubit); + return res == One; + } + let res = MResetZ(qubit); + return res == One; + } + + operation BobQuantum (bit : Bool, qubit : Qubit) : Bool { + if bit { + let res = MResetX(qubit); + return res == One; + } + let res = MResetZ(qubit); + return res == One; + } + + // alternative implementation + operation CharlieQuantum (bit : Bool, qubit : Qubit) : Bool { + if bit { + H(qubit); + } + return M(qubit) == One; + } +} diff --git a/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs b/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs new file mode 100644 index 0000000000..93b7be9102 --- /dev/null +++ b/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs @@ -0,0 +1,44 @@ +namespace Kata.Verification { + + @EntryPoint() + operation CheckSolution() : Bool { + use q = Qubit(); + for _ in 1 .. 4 { + // repeat 4 times since we are testing a measurement and wrong basis still might get + // the correct answer, reduces probability of false positives + if (Kata.AliceQuantum(false, q) != false) { + Message("|0⟩ not measured as false"); + Reset(q); + return false; + } + + // apply the Pauli X gate + X(q); + if (Kata.AliceQuantum(false, q) != true) { + Message("|1⟩ not measured as true"); + Reset(q); + return false; + } + + // apply the Hadamard gate + H(q); + if (Kata.AliceQuantum(true, q) != false) { + Message("|+⟩ not measured as false"); + Reset(q); + return false; + } + + // apply the Pauli X and then the Hadamard gate + X(q); + H(q); + if (Kata.AliceQuantum(true, q) != true) { + Message("|-⟩ not measured as true"); + Reset(q); + return false; + } + Reset(q); + } + Message("Correct!"); + true + } +} diff --git a/katas/content/nonlocal_games/ghz_quantum_strategy/index.md b/katas/content/nonlocal_games/ghz_quantum_strategy/index.md new file mode 100644 index 0000000000..a3e03f5fa1 --- /dev/null +++ b/katas/content/nonlocal_games/ghz_quantum_strategy/index.md @@ -0,0 +1,8 @@ +**Inputs:** + +1. The input bit for one of each of the players (R, S and T respectively), +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. diff --git a/katas/content/nonlocal_games/ghz_quantum_strategy/solution.md b/katas/content/nonlocal_games/ghz_quantum_strategy/solution.md new file mode 100644 index 0000000000..7910d9c5f8 --- /dev/null +++ b/katas/content/nonlocal_games/ghz_quantum_strategy/solution.md @@ -0,0 +1,12 @@ +In Q#, you can perform measurements in a specific basis using either the +[Measure operation](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.measure) +or convenient shorthands for measure-and-reset-to-$\ket{0}$ sequence of operations +[MResetZ](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.measurement.mresetz) and +[MResetX](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.measurement.mresetx). + +Alternatively, you can recall that measuring the qubit in the X basis is equivalent to applying an H gate to it and measuring it in the Z basis. + +@[solution]({ + "id": "nonlocal_games__ghz_quantum_strategy_solution", + "codePath": "Solution.qs" +}) diff --git a/katas/content/nonlocal_games/index.md b/katas/content/nonlocal_games/index.md index 2eb25e8aad..6f03c8c6e8 100644 --- a/katas/content/nonlocal_games/index.md +++ b/katas/content/nonlocal_games/index.md @@ -226,6 +226,24 @@ Then, let's proceed with quantum strategy and game implementation. "path": "./ghz_classical_game/" }) +@[exercise]({ + "id": "nonlocal_games__ghz_create_ghz_state", + "title": "Create Entangled Triple", + "path": "./ghz_create_entangled_triple/" +}) + +@[exercise]({ + "id": "nonlocal_games__ghz_quantum_strategy", + "title": "Quantum Strategy", + "path": "./ghz_quantum_strategy/" +}) + +@[exercise]({ + "id": "nonlocal_games__ghz_quantum_game", + "title": "Quantum Game", + "path": "./ghz_quantum_game/" +}) + @[section]({ "id": "nonlocal_games__conclusion", "title": "Conclusion" From 690025861f2a75c711c7a34225c45c0e8d147c5a Mon Sep 17 00:00:00 2001 From: Gregory Gridin Date: Mon, 12 Aug 2024 21:41:59 -0700 Subject: [PATCH 02/18] Migrate nonlocal games #1596 task2 GHZ demo and discussion --- .../nonlocal_games/examples/GHZGameDemo.qs | 92 ++++++++++++ .../ghz_quantum_game/Placeholder.qs | 7 - .../ghz_quantum_game/Solution.qs | 32 ----- .../ghz_quantum_game/Verification.qs | 93 ------------- .../nonlocal_games/ghz_quantum_game/index.md | 8 -- .../ghz_quantum_game/solution.md | 11 -- katas/content/nonlocal_games/index.md | 131 +++++++++++++++++- 7 files changed, 218 insertions(+), 156 deletions(-) create mode 100644 katas/content/nonlocal_games/examples/GHZGameDemo.qs delete mode 100644 katas/content/nonlocal_games/ghz_quantum_game/Placeholder.qs delete mode 100644 katas/content/nonlocal_games/ghz_quantum_game/Solution.qs delete mode 100644 katas/content/nonlocal_games/ghz_quantum_game/Verification.qs delete mode 100644 katas/content/nonlocal_games/ghz_quantum_game/index.md delete mode 100644 katas/content/nonlocal_games/ghz_quantum_game/solution.md diff --git a/katas/content/nonlocal_games/examples/GHZGameDemo.qs b/katas/content/nonlocal_games/examples/GHZGameDemo.qs new file mode 100644 index 0000000000..de31616b3f --- /dev/null +++ b/katas/content/nonlocal_games/examples/GHZGameDemo.qs @@ -0,0 +1,92 @@ +namespace Quantum.Kata.GHZGame { + open Microsoft.Quantum.Random; + open Microsoft.Quantum.Convert; + + function WinCondition (rst : Bool[], abc : Bool[]) : Bool { + return (rst[0] or rst[1] or rst[2]) == (abc[0] != abc[1] != abc[2]); + } + + operation AliceClassical (r : Bool) : Bool { + return true; + } + + operation BobClassical (s : Bool) : Bool { + return true; + } + + operation CharlieClassical (t : Bool) : Bool { + return true; + } + + operation CreateEntangledTriple (qs : Qubit[]) : Unit is Adj { + X(qs[0]); + X(qs[1]); + H(qs[0]); + H(qs[1]); + Controlled Z([qs[0]], qs[1]); + ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]); + ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]); + } + + operation AliceQuantum (bit : Bool, qubit : Qubit) : Bool { + if bit { + let res = MResetX(qubit); + return res == One; + } + let res = MResetZ(qubit); + return res == One; + } + + operation BobQuantum (bit : Bool, qubit : Qubit) : Bool { + if bit { + let res = MResetX(qubit); + return res == One; + } + let res = MResetZ(qubit); + return res == One; + } + + operation CharlieQuantum (bit : Bool, qubit : Qubit) : Bool { + if bit { + let res = MResetX(qubit); + return res == One; + } + let res = MResetZ(qubit); + return res == One; + } + + operation getRandomRefereeBits () : Bool[] { + let mode = DrawRandomInt(0, 3); + if mode == 0 { + return [false, false, false]; + } elif mode == 1 { + return [true, true, false]; + } elif mode == 2 { + return [false, true, true]; + } + return [true, false, true]; + } + + @EntryPoint() + operation GHZ_GameDemo() : Unit { + use (aliceQubit, bobQubit, charlieQubit) = (Qubit(), Qubit(), Qubit()); + mutable classicalWins = 0; + mutable quantumWins = 0; + let iterations = 1000; + for _ in 1 .. iterations { + CreateEntangledTriple([aliceQubit, bobQubit, charlieQubit]); + let inputs = getRandomRefereeBits(); + let coutputs = [AliceClassical(inputs[0]), BobClassical(inputs[1]), CharlieClassical(inputs[2])]; + if WinCondition(inputs, coutputs) { + set classicalWins += 1; + } + let qoutputs = [AliceQuantum(inputs[0], aliceQubit), BobQuantum(inputs[1], bobQubit), CharlieQuantum(inputs[2], charlieQubit)]; + if WinCondition(inputs, qoutputs) { + set quantumWins += 1; + } + ResetAll([aliceQubit, bobQubit, charlieQubit]); + } + Message($"Percentage of classical wins is {100.0*IntAsDouble(classicalWins)/IntAsDouble(iterations)}%"); + Message($"Percentage of quantum wins is {100.0*IntAsDouble(quantumWins)/IntAsDouble(iterations)}%"); + } +} diff --git a/katas/content/nonlocal_games/ghz_quantum_game/Placeholder.qs b/katas/content/nonlocal_games/ghz_quantum_game/Placeholder.qs deleted file mode 100644 index 3ee6e1f331..0000000000 --- a/katas/content/nonlocal_games/ghz_quantum_game/Placeholder.qs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Kata { - operation PlayQuantumGHZ (strategies : ((Bool, Qubit) => Bool)[], inputs : Bool[]) : Bool[] { - // Implement your solution here... - - return []; - } -} diff --git a/katas/content/nonlocal_games/ghz_quantum_game/Solution.qs b/katas/content/nonlocal_games/ghz_quantum_game/Solution.qs deleted file mode 100644 index 5d05cb9e60..0000000000 --- a/katas/content/nonlocal_games/ghz_quantum_game/Solution.qs +++ /dev/null @@ -1,32 +0,0 @@ -namespace Kata { - operation CreateEntangledTriple (qs : Qubit[]) : Unit is Adj { - X(qs[0]); - X(qs[1]); - - H(qs[0]); - H(qs[1]); - // At this point we have (|000⟩ - |010⟩ - |100⟩ + |110⟩) / 2 - - // Flip the sign of the last term - Controlled Z([qs[0]], qs[1]); - - // Flip the state of the last qubit for the two middle terms - ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]); - ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]); - } - - operation PlayQuantumGHZ (strategies : ((Bool, Qubit) => Bool)[], inputs : Bool[]) : Bool[] { - use qs = Qubit[3]; - CreateEntangledTriple(qs); - - let r = inputs[0]; - let s = inputs[1]; - let t = inputs[2]; - let a = strategies[0](r, qs[0]); - let b = strategies[1](s, qs[1]); - let c = strategies[2](t, qs[2]); - - ResetAll(qs); - return [a, b, c]; - } -} diff --git a/katas/content/nonlocal_games/ghz_quantum_game/Verification.qs b/katas/content/nonlocal_games/ghz_quantum_game/Verification.qs deleted file mode 100644 index b9da0bc6f3..0000000000 --- a/katas/content/nonlocal_games/ghz_quantum_game/Verification.qs +++ /dev/null @@ -1,93 +0,0 @@ -namespace Kata.Verification { - open Microsoft.Quantum.Diagnostics; - open Microsoft.Quantum.Canon; - open Microsoft.Quantum.Logical; - - // 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]]; - } - - 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]); - } - - operation AliceQuantum_Reference (bit : Bool, qubit : Qubit) : Bool { - if bit { - H(qubit); - } - return M(qubit) == One; - } - - operation BobQuantum_Reference (bit : Bool, qubit : Qubit) : Bool { - if bit { - H(qubit); - } - return M(qubit) == One; - } - - operation CharlieQuantum_Reference (bit : Bool, qubit : Qubit) : Bool { - if bit { - H(qubit); - } - return M(qubit) == One; - } - - operation CreateEntangledTriple_Reference (qs : Qubit[]) : Unit is Adj { - X(qs[0]); - X(qs[1]); - - H(qs[0]); - H(qs[1]); - // At this point we have (|000⟩ - |010⟩ - |100⟩ + |110⟩) / 2 - - // Flip the sign of the last term - Controlled Z([qs[0]], qs[1]); - - // Flip the state of the last qubit for the two middle terms - ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]); - ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]); - } - - operation PlayQuantumGHZ_Reference (strategies : ((Bool, Qubit) => Bool)[], inputs : Bool[]) : Bool[] { - use qs = Qubit[3]; - CreateEntangledTriple_Reference(qs); - let r = inputs[0]; - let s = inputs[1]; - let t = inputs[2]; - let a = strategies[0](r, qs[0]); - let b = strategies[1](s, qs[1]); - let c = strategies[2](t, qs[2]); - - ResetAll(qs); - return [a, b, c]; - } - - @EntryPoint() - operation CheckSolution() : Bool { - let inputs = RefereeBits(); - let strategies = [AliceQuantum_Reference, BobQuantum_Reference, CharlieQuantum_Reference]; - for rst in inputs { - let actualBits = Kata.PlayQuantumGHZ(strategies, rst); - if Length(actualBits) != 3 { - Message($"Expected 3 bits from PlayQuantumGHZ, got {Length(actualBits)}"); - return false; - } - let expectedBits = PlayQuantumGHZ_Reference(strategies, rst); - let actualWin = WinCondition_Reference(rst, actualBits); - let expectedWin = WinCondition_Reference(rst, expectedBits); - if actualWin != expectedWin { - Message($"Expected win={expectedWin} {expectedBits}, got {actualBits} for {rst}"); - return false; - } - else { - Message($"Cool {expectedBits}, got {actualBits} for {rst}"); - } - } - true - } -} diff --git a/katas/content/nonlocal_games/ghz_quantum_game/index.md b/katas/content/nonlocal_games/ghz_quantum_game/index.md deleted file mode 100644 index 449fadb22c..0000000000 --- a/katas/content/nonlocal_games/ghz_quantum_game/index.md +++ /dev/null @@ -1,8 +0,0 @@ -Let's play the GHZ game using the quantum strategy. - -**Inputs:** -1. An array of three operations which implement the quantum strategies of the players, -2. An array of 3 input bits that should be passed to the players. - -**Goal:** -An array of three bits that will be produced if each player uses their given strategy. diff --git a/katas/content/nonlocal_games/ghz_quantum_game/solution.md b/katas/content/nonlocal_games/ghz_quantum_game/solution.md deleted file mode 100644 index f74e5fbea9..0000000000 --- a/katas/content/nonlocal_games/ghz_quantum_game/solution.md +++ /dev/null @@ -1,11 +0,0 @@ -Putting together the building blocks we've implemented into a strategy is very simple: - -1. Allocate three qubits and prepare our entangled state on them (using `CreateEntangledTriple`). -2. Send one of the qubits to each of the players (this step is \"virtual\", not directly reflected in Q# code, other than making sure that the strategies each act on their qubit only). -3. Have the players perform their measurements on their respective qubits using corresponding elements of the `strategies` array. -4. Return their measurement results. - -@[solution]({ - "id": "nonlocal_games__ghz_quantum_game_solution", - "codePath": "Solution.qs" -}) diff --git a/katas/content/nonlocal_games/index.md b/katas/content/nonlocal_games/index.md index 6f03c8c6e8..5077c51fe7 100644 --- a/katas/content/nonlocal_games/index.md +++ b/katas/content/nonlocal_games/index.md @@ -64,7 +64,7 @@ Then, let's proceed with quantum strategies for Alice and Bob. }) @[section]({ - "id": "nonlocal_games__discussion", + "id": "nonlocal_games__chsh_discussion", "title": "Discussion: Probability of Victory for Quantum Strategy" }) @@ -238,11 +238,132 @@ Then, let's proceed with quantum strategy and game implementation. "path": "./ghz_quantum_strategy/" }) -@[exercise]({ - "id": "nonlocal_games__ghz_quantum_game", - "title": "Quantum Game", - "path": "./ghz_quantum_game/" +@[section]({ + "id": "nonlocal_games__ghz_discussion", + "title": "Discussion: Why the GHZ quantum strategy has a 100% win rate" }) +--------------------------------------------------------------- +Recall the formula for the win condition: +1. The sum of the answer bits must be even if the question bits are (0,0,0) +2. The sum of the answer bits must be odd if the question bits are (1,1,0), (1,0,1) or (0,1,1). + +> As a reminder, the probability "wavefunction" for three qubits is given by the following vector of length 8: +> $$\begin{bmatrix} +\psi_{000}\\ +\psi_{001}\\ +\psi_{010}\\ +\psi_{011}\\ +\psi_{100}\\ +\psi_{101}\\ +\psi_{110}\\ +\psi_{111} +\end{bmatrix}$$ +> $|\psi_{ijk}|^2$ gives the probability of observing the corresponding basis state $\ket{ijk}$ upon measuring the qubit trio. + +Now, the entangled state $\ket{\Phi}$ that Alice, Bob and Charlie have agreed to use is represented as + +$$\begin{bmatrix} ++1/2\\ + 0\\ + 0\\ +-1/2\\ + 0\\ +-1/2\\ +-1/2\\ + 0 +\end{bmatrix}$$ + +Let's first consider the case in which **all three players got the 0 bit**. + +When the players make their measurements, they will collectively get one of the basis states of the original state - 000, 011, 101 or 110. +This measn they'll report back zero \"1\" bits between them (with $25\%$ probability) or two \"1\" bits between them (with $75\%$ probability), +either way satisfying the win condition for the team. + +Now, suppose **Alice gets a 0 bit and the others get 1**. + +Alice, looking at the 0, takes a Z basis measurement as before, while Bob and Charlie each take X basis measurements. +(An X basis measurement is also equivalent to performing a Hadamard transform followed by a standard Z basis measurement, +as the X basis is the $\ket{+}$ / $\ket{-}$, and a Hadamard transform rotates the $\ket{0}$ / $\ket{1}$ basis to $\ket{+}$ / $\ket{-}$.) +So Bob and Charlie apply a Hadamard transform to their qubits, which corresponds to the following transformation applied to the whole system state: + +$$I \otimes H \otimes H = \begin{bmatrix} +1/2 & 1/2 & 1/2 & 1/2 & 0 & 0 & 0 & 0\\ +1/2 & -1/2 & 1/2 & -1/2 & 0 & 0 & 0 & 0\\ +1/2 & 1/2 & -1/2 & -1/2 & 0 & 0 & 0 & 0\\ +1/2 & -1/2 & -1/2 & 1/2 & 0 & 0 & 0 & 0\\ +0 & 0 & 0 & 0 & 1/2 & 1/2 & 1/2 & 1/2\\ +0 & 0 & 0 & 0 & 1/2 & -1/2 & 1/2 & -1/2\\ +0 & 0 & 0 & 0 & 1/2 & 1/2 & -1/2 & -1/2\\ +0 & 0 & 0 & 0 & 1/2 & -1/2 & -1/2 & 1/2 +\end{bmatrix}$$ + +When applied to the original entangled state, all the amplitude shifts to the states corresponding to $\ket{001}$, $\ket{010}$, $\ket{100}$, and $\ket{111}$. +The precise configuration of the new entangled state is + +$$\begin{bmatrix} + 0\\ + 1/2\\ + 1/2\\ + 0\\ +-1/2\\ + 0\\ + 0\\ + 1/2 +\end{bmatrix}$$ + +Now the players perform their measurements, and an odd number of them will see \"1\" (thanks to the new entangled state), again satisfying the win condition. +Similarly, if **Alice and Charlie get \"1\" bits and Bob a \"0\"**, Alice and Charlie will apply Hadamard transforms to their qubits to give the tensor product + +$$ H \otimes I \otimes H = \begin{bmatrix} +1/2 & 1/2 & 0 & 0 & 1/2 & 1/2 & 0 & 0\\ +1/2 & -1/2 & 0 & 0 & 1/2 & -1/2 & 0 & 0\\ +0 & 0 & 1/2 & 1/2 & 0 & 0 & 1/2 & 1/2\\ +0 & 0 & 1/2 & -1/2 & 0 & 0 & 1/2 & -1/2\\ +1/2 & 1/2 & 0 & 0 & -1/2 & -1/2 & 0 & 0\\ +1/2 & -1/2 & 0 & 0 & -1/2 & 1/2 & 0 & 0\\ +0 & 0 & 1/2 & 1/2 & 0 & 0 & -1/2 & -1/2\\ +0 & 0 & 1/2 & -1/2 & 0 & 0 & -1/2 & 1/2 +\end{bmatrix}$$ + +The resulting state vector before the measurement will be the same as in the previous case, except that the $\ket{010}$ state +ends up with the negative amplitude instead of $\ket{100}$. Again the players report back an odd number of true bits between them and the team wins. + +Finally if Charlie got the \"0\" bit and Alice and Bob both got \"1\", the latter two will apply Hadamard transform for the tensor product + +$$ H \otimes H \otimes I = \begin{bmatrix} +1/2 & 0 & 1/2 & 0 & 1/2 & 0 & 1/2 & 0\\ +0 & 1/2 & 0 & 1/2 & 0 & 1/2 & 0 & 1/2\\ +1/2 & 0 & -1/2 & 0 & 1/2 & 0 & -1/2 & 0\\ +0 & 1/2 & 0 & -1/2 & 0 & 1/2 & 0 & -1/2\\ +1/2 & 0 & 1/2 & 0 & -1/2 & 0 & -1/2 & 0\\ +0 & 1/2 & 0 & 1/2 & 0 & -1/2 & 0 & -1/2\\ +1/2 & 0 & -1/2 & 0 & -1/2 & 0 & 1/2 & 0\\ +0 & 1/2 & 0 & -1/2 & 0 & -1/2 & 0 & 1/2 +\end{bmatrix}$$ + +Operating with this on the original entangled state yields $(\ket{100} + \ket{010} - \ket{001} + \ket{111})/2$ and +once more the team will report back an odd number of true bits between them and win. + +@[section]({ + "id": "nonlocal_games__ghz_e2e", + "title": "Running GHZ Game End to End" +}) + +Putting together the building blocks we've implemented into a strategy is very simple: + +1. Allocate three qubits and prepare our entangled state on them (using `CreateEntangledTriple`). +2. Send one of the qubits to each of the players (this step is \"virtual\", not directly reflected in Q# code, other than making sure that the strategies each act on their qubit only). +3. Have the players perform their measurements on their respective qubits using corresponding elements of the `strategies` array. +4. Reset qubits to $\ket{0}$ before they are released. +5. Return their measurement results. + +In the example below you can compare winning percentage of classical and quantum games. + +>You may play with the code and check if there is a difference in results when +>1. The referee picks non-random bits. How can the referee minimize player's win probability? +>2. Players get partially entangled qubit triple. + +@[example]({"id": "nonlocal_games__ghz_e2edemo", "codePath": "./examples/GHZGameDemo.qs"}) @[section]({ "id": "nonlocal_games__conclusion", From f47ca5cf710812f4e0dad446522626ff0a42da25 Mon Sep 17 00:00:00 2001 From: Gregory Gridin Date: Tue, 13 Aug 2024 17:29:42 -0700 Subject: [PATCH 03/18] Bug fixes and wording corrections --- .../nonlocal_games/examples/GHZGameDemo.qs | 16 ++-- .../ghz_create_entangled_triple/index.md | 5 +- .../ghz_quantum_strategy/Verification.qs | 81 +++++++++++-------- katas/content/nonlocal_games/index.md | 3 +- 4 files changed, 59 insertions(+), 46 deletions(-) diff --git a/katas/content/nonlocal_games/examples/GHZGameDemo.qs b/katas/content/nonlocal_games/examples/GHZGameDemo.qs index de31616b3f..e1d4ea26d3 100644 --- a/katas/content/nonlocal_games/examples/GHZGameDemo.qs +++ b/katas/content/nonlocal_games/examples/GHZGameDemo.qs @@ -56,19 +56,15 @@ namespace Quantum.Kata.GHZGame { } operation getRandomRefereeBits () : Bool[] { - let mode = DrawRandomInt(0, 3); - if mode == 0 { - return [false, false, false]; - } elif mode == 1 { - return [true, true, false]; - } elif mode == 2 { - return [false, true, true]; - } - return [true, false, true]; + let bits = [[false, false, false], + [true, true, false], + [false, true, true], + [true, false, true]]; + return bits[DrawRandomInt(0, 3)]; } @EntryPoint() - operation GHZ_GameDemo() : Unit { + operation GHZ_GameDemo () : Unit { use (aliceQubit, bobQubit, charlieQubit) = (Qubit(), Qubit(), Qubit()); mutable classicalWins = 0; mutable quantumWins = 0; diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md index 9a62c521e8..c1eaca7ad9 100644 --- a/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md @@ -2,8 +2,9 @@ In the quantum version of the game, the players still can not communicate during qubits from an entangled triple before the start of the game. **Input:** -- An array of three qubits in the $|000\rangle$ state. +- An array of three qubits in the $\ket{000}$ state. **Goal:** - Create the entangled state $\ket{\Phi} = \frac{1}{2} \big(\ket{000} - \ket{011} - \ket{101} - \ket{110} \big)$ on these qubits. -This state is equivalent to GHZ state $\frac{1}{\sqrt{2}} (\big(\ket{000} + \ket{111} \big)$ up to local unitary operation. +This state is equivalent to the [GHZ state]([GHZ state](https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state)) +$\frac{1}{\sqrt{2}} (\big(\ket{000} + \ket{111} \big)$ up to local unitary operation. diff --git a/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs b/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs index 93b7be9102..ad9f0e12f3 100644 --- a/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs +++ b/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs @@ -1,42 +1,57 @@ namespace Kata.Verification { - @EntryPoint() - operation CheckSolution() : Bool { - use q = Qubit(); - for _ in 1 .. 4 { - // repeat 4 times since we are testing a measurement and wrong basis still might get - // the correct answer, reduces probability of false positives - if (Kata.AliceQuantum(false, q) != false) { - Message("|0⟩ not measured as false"); - Reset(q); - return false; - } + function WinCondition_Reference (rst : Bool[], abc : Bool[]) : Bool { + return (rst[0] or rst[1] or rst[2]) == (abc[0] != abc[1] != abc[2]); + } - // apply the Pauli X gate - X(q); - if (Kata.AliceQuantum(false, q) != true) { - Message("|1⟩ not measured as true"); - Reset(q); - return false; - } + function RefereeBits () : Bool[][] { + return [[false, false, false], + [true, true, false], + [false, true, true], + [true, false, true]]; + } - // apply the Hadamard gate - H(q); - if (Kata.AliceQuantum(true, q) != false) { - Message("|+⟩ not measured as false"); - Reset(q); - return false; - } + operation CreateEntangledTriple_Reference (qs : Qubit[]) : Unit is Adj { + X(qs[0]); + X(qs[1]); + H(qs[0]); + H(qs[1]); + Controlled Z([qs[0]], qs[1]); + ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]); + ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]); + } + + operation PlayQuantumGHZ_Reference (strategies : ((Bool, Qubit) => Bool)[], inputs : Bool[], qubits : Qubit[]) : Bool[] { + let r = inputs[0]; + let s = inputs[1]; + let t = inputs[2]; + let a = strategies[0](r, qubits[0]); + let b = strategies[1](s, qubits[1]); + let c = strategies[2](t, qubits[2]); + return [a, b, c]; + } - // apply the Pauli X and then the Hadamard gate - X(q); - H(q); - if (Kata.AliceQuantum(true, q) != true) { - Message("|-⟩ not measured as true"); - Reset(q); - return false; + @EntryPoint() + operation CheckSolution () : Bool { + use qs = Qubit[3]; + let inputs = RefereeBits(); + let strategies = [Kata.AliceQuantum, Kata.BobQuantum, Kata.CharlieQuantum]; + + let iterations = 1000; + mutable wins = 0; + for _ in 0 .. iterations - 1 { + for bits in inputs { + CreateEntangledTriple_Reference(qs); + let abc = PlayQuantumGHZ_Reference(strategies, bits, qs); + if WinCondition_Reference(bits, abc) { + set wins = wins + 1; + } + ResetAll(qs); } - Reset(q); + } + if wins < iterations*Length(inputs) { + Message($"Alice, Bob, and Charlie's classical strategy gets {wins} wins out of {iterations*Length(inputs)} possible inputs, which is not optimal"); + return false; } Message("Correct!"); true diff --git a/katas/content/nonlocal_games/index.md b/katas/content/nonlocal_games/index.md index 5077c51fe7..ded39ccd8f 100644 --- a/katas/content/nonlocal_games/index.md +++ b/katas/content/nonlocal_games/index.md @@ -361,7 +361,8 @@ In the example below you can compare winning percentage of classical and quantum >You may play with the code and check if there is a difference in results when >1. The referee picks non-random bits. How can the referee minimize player's win probability? ->2. Players get partially entangled qubit triple. +>2. Players get the [GHZ state](https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state). +> How to change the quantum strategies to get $100\%$ win rate? @[example]({"id": "nonlocal_games__ghz_e2edemo", "codePath": "./examples/GHZGameDemo.qs"}) From 1d1b2a385fd8905aa9e01f35cfc34f7c18d95e2c Mon Sep 17 00:00:00 2001 From: Gregory Gridin Date: Tue, 13 Aug 2024 17:54:58 -0700 Subject: [PATCH 04/18] Copy-paste error fix --- .../content/nonlocal_games/ghz_quantum_strategy/Verification.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs b/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs index ad9f0e12f3..989ea81c52 100644 --- a/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs +++ b/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs @@ -50,7 +50,7 @@ namespace Kata.Verification { } } if wins < iterations*Length(inputs) { - Message($"Alice, Bob, and Charlie's classical strategy gets {wins} wins out of {iterations*Length(inputs)} possible inputs, which is not optimal"); + Message($"Player's quantum strategies get {wins} wins out of {iterations*Length(inputs)} possible inputs, which is not optimal"); return false; } Message("Correct!"); From 1a6c78674f78241512c3f94f80e4bfffd08d970e Mon Sep 17 00:00:00 2001 From: Gregory Gridin Date: Tue, 13 Aug 2024 18:37:57 -0700 Subject: [PATCH 05/18] Fix title capitalization --- katas/content/nonlocal_games/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/katas/content/nonlocal_games/index.md b/katas/content/nonlocal_games/index.md index ded39ccd8f..d553e05070 100644 --- a/katas/content/nonlocal_games/index.md +++ b/katas/content/nonlocal_games/index.md @@ -240,7 +240,7 @@ Then, let's proceed with quantum strategy and game implementation. @[section]({ "id": "nonlocal_games__ghz_discussion", - "title": "Discussion: Why the GHZ quantum strategy has a 100% win rate" + "title": "Discussion: Why the GHZ Quantum Strategy has a 100% Win Rate" }) --------------------------------------------------------------- Recall the formula for the win condition: From efceb5a8476308bc7bc44cb643df65667c9884aa Mon Sep 17 00:00:00 2001 From: Gregory Gridin <51379812+ggridin@users.noreply.github.com> Date: Mon, 26 Aug 2024 18:11:38 -0700 Subject: [PATCH 06/18] Update katas/content/nonlocal_games/ghz_create_entangled_triple/index.md Co-authored-by: Mariia Mykhailova --- .../content/nonlocal_games/ghz_create_entangled_triple/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md index c1eaca7ad9..840c3dc587 100644 --- a/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md @@ -2,7 +2,7 @@ In the quantum version of the game, the players still can not communicate during qubits from an entangled triple before the start of the game. **Input:** -- An array of three qubits in the $\ket{000}$ state. +An array of three qubits in the $\ket{000}$ state. **Goal:** - Create the entangled state $\ket{\Phi} = \frac{1}{2} \big(\ket{000} - \ket{011} - \ket{101} - \ket{110} \big)$ on these qubits. From 2e7d518f832026ca709043286818c59d30a1a3e2 Mon Sep 17 00:00:00 2001 From: Gregory Gridin <51379812+ggridin@users.noreply.github.com> Date: Mon, 26 Aug 2024 18:12:31 -0700 Subject: [PATCH 07/18] Update katas/content/nonlocal_games/ghz_create_entangled_triple/index.md Co-authored-by: Mariia Mykhailova --- .../content/nonlocal_games/ghz_create_entangled_triple/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md index 840c3dc587..a335665386 100644 --- a/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md @@ -5,6 +5,6 @@ qubits from an entangled triple before the start of the game. An array of three qubits in the $\ket{000}$ state. **Goal:** -- Create the entangled state $\ket{\Phi} = \frac{1}{2} \big(\ket{000} - \ket{011} - \ket{101} - \ket{110} \big)$ on these qubits. +Create the entangled state $\ket{\Phi} = \frac{1}{2} \big(\ket{000} - \ket{011} - \ket{101} - \ket{110} \big)$ on these qubits. This state is equivalent to the [GHZ state]([GHZ state](https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state)) $\frac{1}{\sqrt{2}} (\big(\ket{000} + \ket{111} \big)$ up to local unitary operation. From 57f299046fdf3037ae9e681a19aa8665155bb8e0 Mon Sep 17 00:00:00 2001 From: Gregory Gridin <51379812+ggridin@users.noreply.github.com> Date: Mon, 26 Aug 2024 18:13:08 -0700 Subject: [PATCH 08/18] Update katas/content/nonlocal_games/ghz_create_entangled_triple/index.md Co-authored-by: Mariia Mykhailova --- .../content/nonlocal_games/ghz_create_entangled_triple/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md index a335665386..7050b0e799 100644 --- a/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md @@ -7,4 +7,4 @@ An array of three qubits in the $\ket{000}$ state. **Goal:** Create the entangled state $\ket{\Phi} = \frac{1}{2} \big(\ket{000} - \ket{011} - \ket{101} - \ket{110} \big)$ on these qubits. This state is equivalent to the [GHZ state]([GHZ state](https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state)) -$\frac{1}{\sqrt{2}} (\big(\ket{000} + \ket{111} \big)$ up to local unitary operation. +$\frac{1}{\sqrt{2}} \big(\ket{000} + \ket{111} \big)$ up to local unitary operation. From 2483972ddbe34afb10c1fa245e7f52742ab4d583 Mon Sep 17 00:00:00 2001 From: Gregory Gridin <51379812+ggridin@users.noreply.github.com> Date: Mon, 26 Aug 2024 18:13:56 -0700 Subject: [PATCH 09/18] Update katas/content/nonlocal_games/ghz_create_entangled_triple/solution.md Co-authored-by: Mariia Mykhailova --- .../nonlocal_games/ghz_create_entangled_triple/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/solution.md b/katas/content/nonlocal_games/ghz_create_entangled_triple/solution.md index ea196a2b7b..52c6502b8a 100644 --- a/katas/content/nonlocal_games/ghz_create_entangled_triple/solution.md +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/solution.md @@ -1,6 +1,6 @@ 1. Apply an X gate to the first and the second qubits to get the $\ket{110}$ state. 2. Appy an H gate to the first and the second qubits to get the following state: -$\frac12 \big( \ket{000} - \ket{010} - \ket{100} + \ket{110} \big)$ +$$\frac12 \big( \ket{000} - \ket{010} - \ket{100} + \ket{110} \big)$$ 3. Flip the sign of the last term using a controlled Z gate with the first qubit as control and the second qubit as target (or vice versa): $\frac12 \big( \ket{000} - \ket{010} - \ket{100} -{\color{blue}\ket{110}} \big)$ 4. Now we have the right signs for each term, and the first and the last terms match those of the state we're preparing, so we just need to adjust the two middle terms. From 33b5897265a461642377727cb43528802dba20af Mon Sep 17 00:00:00 2001 From: Gregory Gridin <51379812+ggridin@users.noreply.github.com> Date: Mon, 26 Aug 2024 18:14:25 -0700 Subject: [PATCH 10/18] Update katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs Co-authored-by: Mariia Mykhailova --- .../content/nonlocal_games/ghz_quantum_strategy/Verification.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs b/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs index 989ea81c52..13e1557c80 100644 --- a/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs +++ b/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs @@ -50,7 +50,7 @@ namespace Kata.Verification { } } if wins < iterations*Length(inputs) { - Message($"Player's quantum strategies get {wins} wins out of {iterations*Length(inputs)} possible inputs, which is not optimal"); + Message($"Players' quantum strategies get {wins} wins out of {iterations*Length(inputs)} runs, which is not optimal"); return false; } Message("Correct!"); From e0d1b9dbd0eed25b311e9f43c88783c08bde38ba Mon Sep 17 00:00:00 2001 From: Gregory Gridin <51379812+ggridin@users.noreply.github.com> Date: Mon, 26 Aug 2024 18:14:51 -0700 Subject: [PATCH 11/18] Update katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs Co-authored-by: Mariia Mykhailova --- .../content/nonlocal_games/ghz_quantum_strategy/Verification.qs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs b/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs index 13e1557c80..3b7c2d8023 100644 --- a/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs +++ b/katas/content/nonlocal_games/ghz_quantum_strategy/Verification.qs @@ -39,7 +39,7 @@ namespace Kata.Verification { let iterations = 1000; mutable wins = 0; - for _ in 0 .. iterations - 1 { + for _ in 1 .. iterations { for bits in inputs { CreateEntangledTriple_Reference(qs); let abc = PlayQuantumGHZ_Reference(strategies, bits, qs); From 3ed29cb0325f257a674c748c83fd4caee7eb1f13 Mon Sep 17 00:00:00 2001 From: Gregory Gridin <51379812+ggridin@users.noreply.github.com> Date: Mon, 26 Aug 2024 18:16:30 -0700 Subject: [PATCH 12/18] Update katas/content/nonlocal_games/ghz_create_entangled_triple/index.md Co-authored-by: Mariia Mykhailova --- .../content/nonlocal_games/ghz_create_entangled_triple/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md index 7050b0e799..9f830fbdda 100644 --- a/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md @@ -6,5 +6,5 @@ An array of three qubits in the $\ket{000}$ state. **Goal:** Create the entangled state $\ket{\Phi} = \frac{1}{2} \big(\ket{000} - \ket{011} - \ket{101} - \ket{110} \big)$ on these qubits. -This state is equivalent to the [GHZ state]([GHZ state](https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state)) +This state is equivalent to the three-qubit [GHZ state](https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state) $\frac{1}{\sqrt{2}} \big(\ket{000} + \ket{111} \big)$ up to local unitary operation. From 16e6e6877c7723bff933314e74610b097e927345 Mon Sep 17 00:00:00 2001 From: Gregory Gridin Date: Wed, 28 Aug 2024 20:26:53 -0700 Subject: [PATCH 13/18] Addressing PR comments, step 1 --- .../nonlocal_games/examples/GHZGameDemo.qs | 18 +++++-------- .../ghz_create_entangled_triple/Solution.qs | 6 ----- .../Verification.qs | 25 ++----------------- .../ghz_create_entangled_triple/index.md | 2 +- .../ghz_create_entangled_triple/solution.md | 2 +- .../ghz_quantum_strategy/Solution.qs | 12 +++------ .../ghz_quantum_strategy/index.md | 3 +++ .../ghz_quantum_strategy/solution.md | 6 ++--- katas/content/nonlocal_games/index.md | 2 +- 9 files changed, 21 insertions(+), 55 deletions(-) diff --git a/katas/content/nonlocal_games/examples/GHZGameDemo.qs b/katas/content/nonlocal_games/examples/GHZGameDemo.qs index e1d4ea26d3..d1a90d8d80 100644 --- a/katas/content/nonlocal_games/examples/GHZGameDemo.qs +++ b/katas/content/nonlocal_games/examples/GHZGameDemo.qs @@ -30,29 +30,23 @@ namespace Quantum.Kata.GHZGame { operation AliceQuantum (bit : Bool, qubit : Qubit) : Bool { if bit { - let res = MResetX(qubit); - return res == One; + return MResetX(qubit) == One; } - let res = MResetZ(qubit); - return res == One; + return MResetZ(qubit) == One; } operation BobQuantum (bit : Bool, qubit : Qubit) : Bool { if bit { - let res = MResetX(qubit); - return res == One; + return MResetX(qubit) == One; } - let res = MResetZ(qubit); - return res == One; + return MResetZ(qubit) == One; } operation CharlieQuantum (bit : Bool, qubit : Qubit) : Bool { if bit { - let res = MResetX(qubit); - return res == One; + return MResetX(qubit) == One; } - let res = MResetZ(qubit); - return res == One; + return MResetZ(qubit) == One; } operation getRandomRefereeBits () : Bool[] { diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/Solution.qs b/katas/content/nonlocal_games/ghz_create_entangled_triple/Solution.qs index 6124064a39..77314a6679 100644 --- a/katas/content/nonlocal_games/ghz_create_entangled_triple/Solution.qs +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/Solution.qs @@ -2,15 +2,9 @@ namespace Kata { operation CreateEntangledTriple (qs : Qubit[]) : Unit is Adj { X(qs[0]); X(qs[1]); - H(qs[0]); H(qs[1]); - // At this point we have (|000⟩ - |010⟩ - |100⟩ + |110⟩) / 2 - - // Flip the sign of the last term Controlled Z([qs[0]], qs[1]); - - // Flip the state of the last qubit for the two middle terms ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]); ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]); } diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/Verification.qs b/katas/content/nonlocal_games/ghz_create_entangled_triple/Verification.qs index c25ae633b4..039384cd56 100644 --- a/katas/content/nonlocal_games/ghz_create_entangled_triple/Verification.qs +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/Verification.qs @@ -1,40 +1,19 @@ namespace Kata.Verification { open Microsoft.Quantum.Diagnostics; + open Microsoft.Quantum.Katas; operation CreateEntangledTriple_Reference (qs : Qubit[]) : Unit is Adj { X(qs[0]); X(qs[1]); - H(qs[0]); H(qs[1]); - // At this point we have (|000⟩ - |010⟩ - |100⟩ + |110⟩) / 2 - - // Flip the sign of the last term Controlled Z([qs[0]], qs[1]); - - // Flip the state of the last qubit for the two middle terms ApplyControlledOnBitString([false, true], X, [qs[0], qs[1]], qs[2]); ApplyControlledOnBitString([true, false], X, [qs[0], qs[1]], qs[2]); } @EntryPoint() operation CheckSolution() : Bool { - use qs = Qubit[3]; - // apply operation that needs to be tested - Kata.CreateEntangledTriple(qs); - - // apply adjoint reference operation and check that the result is |0ᴺ⟩ - Adjoint CreateEntangledTriple_Reference(qs); - - // check that all qubits end up in |0⟩ state - let result = CheckAllZero(qs); - ResetAll(qs); - if result { - Message("Correct!"); - } - else { - Message("Entangled triple is not implemented correctly"); - } - return result; + CheckOperationsEquivalenceOnZeroStateWithFeedback(Kata.CreateEntangledTriple, CreateEntangledTriple_Reference, 3) } } diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md index 9f830fbdda..7ec0b038df 100644 --- a/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md @@ -7,4 +7,4 @@ An array of three qubits in the $\ket{000}$ state. **Goal:** Create the entangled state $\ket{\Phi} = \frac{1}{2} \big(\ket{000} - \ket{011} - \ket{101} - \ket{110} \big)$ on these qubits. This state is equivalent to the three-qubit [GHZ state](https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state) -$\frac{1}{\sqrt{2}} \big(\ket{000} + \ket{111} \big)$ up to local unitary operation. +$\frac{1}{\sqrt{2}} \big(\ket{000} + \ket{111} \big)$ up to local unitary operations. diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/solution.md b/katas/content/nonlocal_games/ghz_create_entangled_triple/solution.md index 52c6502b8a..e8aef0666b 100644 --- a/katas/content/nonlocal_games/ghz_create_entangled_triple/solution.md +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/solution.md @@ -4,7 +4,7 @@ $$\frac12 \big( \ket{000} - \ket{010} - \ket{100} + \ket{110} \big)$$ 3. Flip the sign of the last term using a controlled Z gate with the first qubit as control and the second qubit as target (or vice versa): $\frac12 \big( \ket{000} - \ket{010} - \ket{100} -{\color{blue}\ket{110}} \big)$ 4. Now we have the right signs for each term, and the first and the last terms match those of the state we're preparing, so we just need to adjust the two middle terms. -To do this, we can use [ControlledOnBitString](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.canon.controlledonbitstring) operation to flip the state of the last qubit if the first two qubits are in $\ket{01}$ or in $\ket{10}$ states, which gives us: +To do this, we can use [ControlledOnBitString](https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.canon/applycontrolledonbitstring) operation to flip the state of the last qubit if the first two qubits are in $\ket{01}$ or in $\ket{10}$ states, which gives us: $\frac{1}{2} \big(\ket{000} - {\color{blue}\ket{011}} - {\color{blue}\ket{101}} - \ket{110} \big)$ @[solution]({ diff --git a/katas/content/nonlocal_games/ghz_quantum_strategy/Solution.qs b/katas/content/nonlocal_games/ghz_quantum_strategy/Solution.qs index 3db48f34f0..6904f2ad8e 100644 --- a/katas/content/nonlocal_games/ghz_quantum_strategy/Solution.qs +++ b/katas/content/nonlocal_games/ghz_quantum_strategy/Solution.qs @@ -1,20 +1,16 @@ namespace Kata { operation AliceQuantum (bit : Bool, qubit : Qubit) : Bool { if bit { - let res = MResetX(qubit); - return res == One; + return MResetX(qubit) == One; } - let res = MResetZ(qubit); - return res == One; + return MResetZ(qubit) == One; } operation BobQuantum (bit : Bool, qubit : Qubit) : Bool { if bit { - let res = MResetX(qubit); - return res == One; + return MResetX(qubit) == One; } - let res = MResetZ(qubit); - return res == One; + return MResetZ(qubit) == One; } // alternative implementation diff --git a/katas/content/nonlocal_games/ghz_quantum_strategy/index.md b/katas/content/nonlocal_games/ghz_quantum_strategy/index.md index a3e03f5fa1..7b5cca4e3b 100644 --- a/katas/content/nonlocal_games/ghz_quantum_strategy/index.md +++ b/katas/content/nonlocal_games/ghz_quantum_strategy/index.md @@ -1,3 +1,6 @@ +In this task you have to implement three functions, one for each player's quantum strategy. +Note that they are covered by one test, so you have to implement all of them to pass the test. + **Inputs:** 1. The input bit for one of each of the players (R, S and T respectively), diff --git a/katas/content/nonlocal_games/ghz_quantum_strategy/solution.md b/katas/content/nonlocal_games/ghz_quantum_strategy/solution.md index 7910d9c5f8..861d9f78e3 100644 --- a/katas/content/nonlocal_games/ghz_quantum_strategy/solution.md +++ b/katas/content/nonlocal_games/ghz_quantum_strategy/solution.md @@ -1,8 +1,8 @@ In Q#, you can perform measurements in a specific basis using either the -[Measure operation](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic.measure) +[Measure operation](https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.intrinsic/measure) or convenient shorthands for measure-and-reset-to-$\ket{0}$ sequence of operations -[MResetZ](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.measurement.mresetz) and -[MResetX](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.measurement.mresetx). +[MResetZ](https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.measurement/mresetz) and +[MResetX](https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.measurement/mresetx). Alternatively, you can recall that measuring the qubit in the X basis is equivalent to applying an H gate to it and measuring it in the Z basis. diff --git a/katas/content/nonlocal_games/index.md b/katas/content/nonlocal_games/index.md index d553e05070..6dd1bde391 100644 --- a/katas/content/nonlocal_games/index.md +++ b/katas/content/nonlocal_games/index.md @@ -227,7 +227,7 @@ Then, let's proceed with quantum strategy and game implementation. }) @[exercise]({ - "id": "nonlocal_games__ghz_create_ghz_state", + "id": "nonlocal_games__ghz_create_entangled_state", "title": "Create Entangled Triple", "path": "./ghz_create_entangled_triple/" }) From 2273a6d836be7dcc1080b4e787b5d30bfe1cd19c Mon Sep 17 00:00:00 2001 From: Gregory Gridin Date: Wed, 28 Aug 2024 20:35:34 -0700 Subject: [PATCH 14/18] Re-phrase quantum strategy assignment --- katas/content/nonlocal_games/ghz_quantum_strategy/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/katas/content/nonlocal_games/ghz_quantum_strategy/index.md b/katas/content/nonlocal_games/ghz_quantum_strategy/index.md index 7b5cca4e3b..c604c7906f 100644 --- a/katas/content/nonlocal_games/ghz_quantum_strategy/index.md +++ b/katas/content/nonlocal_games/ghz_quantum_strategy/index.md @@ -1,5 +1,5 @@ -In this task you have to implement three functions, one for each player's quantum strategy. -Note that they are covered by one test, so you have to implement all of them to pass the test. +In this task, you should implement three functions, one for each player's quantum strategy. +Note that they are covered by one test, so you must implement all of them to pass the test. **Inputs:** From 13dde36b2372459b68acffea74e711cb869bf2cc Mon Sep 17 00:00:00 2001 From: Gregory Gridin Date: Wed, 28 Aug 2024 20:57:51 -0700 Subject: [PATCH 15/18] Warning fix: classic strategies should be functions --- katas/content/nonlocal_games/examples/GHZGameDemo.qs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/katas/content/nonlocal_games/examples/GHZGameDemo.qs b/katas/content/nonlocal_games/examples/GHZGameDemo.qs index d1a90d8d80..3858ee2460 100644 --- a/katas/content/nonlocal_games/examples/GHZGameDemo.qs +++ b/katas/content/nonlocal_games/examples/GHZGameDemo.qs @@ -6,15 +6,15 @@ namespace Quantum.Kata.GHZGame { return (rst[0] or rst[1] or rst[2]) == (abc[0] != abc[1] != abc[2]); } - operation AliceClassical (r : Bool) : Bool { + function AliceClassical (r : Bool) : Bool { return true; } - operation BobClassical (s : Bool) : Bool { + function BobClassical (s : Bool) : Bool { return true; } - operation CharlieClassical (t : Bool) : Bool { + function CharlieClassical (t : Bool) : Bool { return true; } From fd1e365b536d23a0666eb348d633c6910cf27b06 Mon Sep 17 00:00:00 2001 From: Gregory Gridin Date: Tue, 3 Sep 2024 18:19:31 -0700 Subject: [PATCH 16/18] Add reference to GHZ and triple states equivalence discussion --- .../content/nonlocal_games/ghz_create_entangled_triple/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md index 7ec0b038df..0859c3b6f5 100644 --- a/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md @@ -8,3 +8,4 @@ An array of three qubits in the $\ket{000}$ state. Create the entangled state $\ket{\Phi} = \frac{1}{2} \big(\ket{000} - \ket{011} - \ket{101} - \ket{110} \big)$ on these qubits. This state is equivalent to the three-qubit [GHZ state](https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state) $\frac{1}{\sqrt{2}} \big(\ket{000} + \ket{111} \big)$ up to local unitary operations. +Please refer to the follow-up GHZ Quantum Strategy discussion for details. From 1eff1e54330ea3536703a22a498234e3e66244cc Mon Sep 17 00:00:00 2001 From: Gregory Gridin Date: Wed, 4 Sep 2024 12:34:53 -0700 Subject: [PATCH 17/18] Apply better formatting --- .../nonlocal_games/ghz_create_entangled_triple/index.md | 7 ++++--- .../nonlocal_games/ghz_create_entangled_triple/solution.md | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md index 0859c3b6f5..4566d06dcb 100644 --- a/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/index.md @@ -6,6 +6,7 @@ An array of three qubits in the $\ket{000}$ state. **Goal:** Create the entangled state $\ket{\Phi} = \frac{1}{2} \big(\ket{000} - \ket{011} - \ket{101} - \ket{110} \big)$ on these qubits. -This state is equivalent to the three-qubit [GHZ state](https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state) -$\frac{1}{\sqrt{2}} \big(\ket{000} + \ket{111} \big)$ up to local unitary operations. -Please refer to the follow-up GHZ Quantum Strategy discussion for details. + +>This state is equivalent to the three-qubit [GHZ state](https://en.wikipedia.org/wiki/Greenberger%E2%80%93Horne%E2%80%93Zeilinger_state) +>$$\frac{1}{\sqrt{2}} \big(\ket{000} + \ket{111} \big)$$ +>up to local unitary operations. Please refer to the follow-up GHZ Quantum Strategy discussion for details. diff --git a/katas/content/nonlocal_games/ghz_create_entangled_triple/solution.md b/katas/content/nonlocal_games/ghz_create_entangled_triple/solution.md index e8aef0666b..674cac56f7 100644 --- a/katas/content/nonlocal_games/ghz_create_entangled_triple/solution.md +++ b/katas/content/nonlocal_games/ghz_create_entangled_triple/solution.md @@ -2,10 +2,10 @@ 2. Appy an H gate to the first and the second qubits to get the following state: $$\frac12 \big( \ket{000} - \ket{010} - \ket{100} + \ket{110} \big)$$ 3. Flip the sign of the last term using a controlled Z gate with the first qubit as control and the second qubit as target (or vice versa): -$\frac12 \big( \ket{000} - \ket{010} - \ket{100} -{\color{blue}\ket{110}} \big)$ +$$\frac12 \big( \ket{000} - \ket{010} - \ket{100} -{\color{blue}\ket{110}} \big)$$ 4. Now we have the right signs for each term, and the first and the last terms match those of the state we're preparing, so we just need to adjust the two middle terms. To do this, we can use [ControlledOnBitString](https://learn.microsoft.com/qsharp/api/qsharp-lang/microsoft.quantum.canon/applycontrolledonbitstring) operation to flip the state of the last qubit if the first two qubits are in $\ket{01}$ or in $\ket{10}$ states, which gives us: -$\frac{1}{2} \big(\ket{000} - {\color{blue}\ket{011}} - {\color{blue}\ket{101}} - \ket{110} \big)$ +$$\frac{1}{2} \big(\ket{000} - {\color{blue}\ket{011}} - {\color{blue}\ket{101}} - \ket{110} \big)$$ @[solution]({ "id": "nonlocal_games__ghz_create_entangled_triple_solution", From b9aa3d399d0b22f0bf76e2de24bd1f4905b1d8ae Mon Sep 17 00:00:00 2001 From: Gregory Gridin <51379812+ggridin@users.noreply.github.com> Date: Mon, 7 Oct 2024 14:48:27 -0700 Subject: [PATCH 18/18] Update katas/content/nonlocal_games/index.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: César Zaragoza Cortés --- katas/content/nonlocal_games/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/katas/content/nonlocal_games/index.md b/katas/content/nonlocal_games/index.md index 6dd1bde391..1d683bb1d1 100644 --- a/katas/content/nonlocal_games/index.md +++ b/katas/content/nonlocal_games/index.md @@ -276,7 +276,7 @@ $$\begin{bmatrix} Let's first consider the case in which **all three players got the 0 bit**. When the players make their measurements, they will collectively get one of the basis states of the original state - 000, 011, 101 or 110. -This measn they'll report back zero \"1\" bits between them (with $25\%$ probability) or two \"1\" bits between them (with $75\%$ probability), +This means they'll report back zero \"1\" bits between them (with $25\%$ probability) or two \"1\" bits between them (with $75\%$ probability), either way satisfying the win condition for the team. Now, suppose **Alice gets a 0 bit and the others get 1**.