|
| 1 | +# Mermin-Peres Magic Square Game Algorithm |
| 2 | +# https://www.gregegan.net/SCIENCE/MPMS/MPMS.html |
| 3 | +using Yao |
| 4 | + |
| 5 | +# measurement operator table |
| 6 | +# see Table S1 in https://arxiv.org/abs/2206.12042 |
| 7 | +const magic_square = [kron(I2, Z) kron(Z, I2) kron(Z, Z) |
| 8 | + kron(X, I2) kron(I2, X) kron(X, X) |
| 9 | + kron(-X, Z) kron(-Z, X) kron(Y, Y)] |
| 10 | + |
| 11 | +""" |
| 12 | + bell_state(which::Int) -> AbstractRegister |
| 13 | +
|
| 14 | +Initialize bell state on a quantum register. |
| 15 | +
|
| 16 | +# Arguments |
| 17 | +- `which::Int`: which of the four bell states to initialize |
| 18 | + 1 corresponds to ``(|00> + |11>)/√2`` |
| 19 | + 2 corresponds to ``(|00> - |11>)/√2`` |
| 20 | + 3 corresponds to ``(|01> + |10>)/√2`` |
| 21 | + 4 corresponds to ``(|01> - |10>)/√2`` |
| 22 | +
|
| 23 | +# Returns |
| 24 | +- `AbstractRegister`: the register on which we have initialized the bell state |
| 25 | +""" |
| 26 | +function bell_state(which::Int) |
| 27 | + |
| 28 | + @assert 1 <= which <= 4 "Input $(which) is not in range 1..4" |
| 29 | + reg = zero_state(2) |
| 30 | + apply!(reg, chain(put(2, 1 => H), cnot(2, 1, 2))) |
| 31 | + (which == 2 || which == 4) && apply!(reg, put(2, 1 => Z)) |
| 32 | + (which == 3 || which == 4) && apply!(reg, put(2, 1 => X)) |
| 33 | + return reg |
| 34 | +end |
| 35 | + |
| 36 | +# Alice perform Measurement using Operator specified by row idx |
| 37 | +alice_measure!(reg::AbstractRegister, row::Int) = [real(measure!(op, reg, (1, 3))) for op in magic_square[row, :]] |
| 38 | +# Bob perform Measurement using Operator specified by row idx |
| 39 | +bob_measure!(reg::AbstractRegister, col::Int) = [real(measure!(op, reg, (2, 4))) for op in magic_square[:, col]] |
| 40 | + |
| 41 | +""" |
| 42 | + input_idx(which::String) -> Int |
| 43 | +
|
| 44 | +# Arguments |
| 45 | +- `which::String`: whether user is asked to provide the index for the row or column |
| 46 | +
|
| 47 | +# Returns |
| 48 | +- `Int`: index determined by the user |
| 49 | +""" |
| 50 | +function input_idx(which::String) |
| 51 | + idx = 0 |
| 52 | + while idx > 3 || idx < 1 |
| 53 | + println("Please provide a $which number in the range [1,3]") |
| 54 | + try |
| 55 | + idx = parse(Int64, readline()) |
| 56 | + catch e |
| 57 | + showerror(stdout, e) |
| 58 | + println(" Please enter a NUMBER!") |
| 59 | + end |
| 60 | + end |
| 61 | + return idx |
| 62 | +end |
| 63 | + |
| 64 | +function main() |
| 65 | + println("Dealer: Let's Play Mermin's Magic Square Game!") |
| 66 | + |
| 67 | + # ask the user to input row and column index |
| 68 | + i = input_idx("row") |
| 69 | + j = input_idx("column") |
| 70 | + |
| 71 | + println("Alice will provide three numbers to be written on row: $(i)") |
| 72 | + println("Bob will provide three numbers to be written on column: $(j)") |
| 73 | + |
| 74 | + # Initialize two pairs of bell state ``(|00> + |11>) ⊗ (|00> + |11>)/2``. |
| 75 | + # First qubit of each bell state pair belongs to Alice and the others belong to Bob. |
| 76 | + reg1 = join(bell_state(1), bell_state(1)) |
| 77 | + |
| 78 | + # do measurement and get answer string |
| 79 | + a1, a2, a3 = alice_measure!(reg1, i) |
| 80 | + b1, b2, b3 = bob_measure!(reg1, j) |
| 81 | + |
| 82 | + println("Alice should give answer: $a1 , $a2 , $a3") |
| 83 | + println("Bob should give answer: $b1 , $b2 , $b3") |
| 84 | + #We should see j_th element in [a1,a2,a3] is equal to i_th element in [b1,b2,b3] |
| 85 | + @assert [a1, a2, a3][j] == [b1, b2, b3][i] ("Opps, something is wrong, the j_th item in |
| 86 | + Alice's answer does not match the i_th item in Bob's answer") |
| 87 | + |
| 88 | + # To reveal some magic behind the scenes, you may check that |
| 89 | + # measurements on each row and each columns commute with |
| 90 | + # each other and all are hermitian |
| 91 | + @assert (all(k -> iscommute(magic_square[k, :]...), 1:3) && |
| 92 | + all(k -> iscommute(magic_square[:, k]...), 1:3) && |
| 93 | + all(ishermitian, magic_square)) |
| 94 | +end |
| 95 | + |
| 96 | + |
| 97 | +main() |
0 commit comments