microsoft/qdk
Publicmirrored fromhttps://github.com/microsoft/qdkAvailable
katas/content/oracles/examples/TestMeetingOracle.qs
79lines · modecode
| 1 | namespace Kata { |
| 2 | open Microsoft.Quantum.Arrays; |
| 3 | open Microsoft.Quantum.Diagnostics; |
| 4 | open Microsoft.Quantum.Convert; |
| 5 | |
| 6 | // The classical function to perform the same computation |
| 7 | function Meeting_Classical(x : Bool[], jasmine : Bool[]) : Bool { |
| 8 | for i in IndexRange(x) { |
| 9 | if (not x[i]) and (not jasmine[i]) { |
| 10 | // They have a day that they can both meet |
| 11 | return true; |
| 12 | } |
| 13 | } |
| 14 | return false; |
| 15 | } |
| 16 | |
| 17 | operation Or_Oracle(x : Qubit[], y : Qubit) : Unit is Adj + Ctl { |
| 18 | X(y); |
| 19 | ApplyControlledOnInt(0, X, x, y); |
| 20 | } |
| 21 | |
| 22 | operation Meeting_Oracle(x : Qubit[], jasmine : Qubit[], z : Qubit) : Unit is Adj + Ctl { |
| 23 | use qs = Qubit[Length(x)]; |
| 24 | within { |
| 25 | for i in IndexRange(qs) { |
| 26 | // Flip q[i] if both you and Jasmine are free on the given day |
| 27 | X(x[i]); |
| 28 | X(jasmine[i]); |
| 29 | CCNOT(x[i], jasmine[i], qs[i]); |
| 30 | } |
| 31 | } apply { |
| 32 | Or_Oracle(qs, z); |
| 33 | } |
| 34 | } |
| 35 | |
| 36 | @EntryPoint() |
| 37 | operation Test_Meeting_Oracle() : Unit { |
| 38 | // There are 2^5 ways to arrange each of the schedules - let's try all of them |
| 39 | for k in 0 .. 2^5 - 1 { |
| 40 | for j in 0 .. 2^5 - 1 { |
| 41 | // Convert your and Jasmine's schedules to bit arrays |
| 42 | let binaryX = IntAsBoolArray(k, 5); |
| 43 | let binaryJasmine = IntAsBoolArray(j, 5); |
| 44 | |
| 45 | // Calculate the function classically |
| 46 | let classicalResult = Meeting_Classical(binaryX, binaryJasmine); |
| 47 | |
| 48 | // Allocate qubits to represent your schedule, Jasmine's schedule, and the output |
| 49 | use (x, jasmine, target) = (Qubit[5], Qubit[5], Qubit()); |
| 50 | // Prepare the quantum schedules in basis states matching the binary schedules |
| 51 | ApplyPauliFromBitString(PauliX, true, binaryX, x); |
| 52 | ApplyPauliFromBitString(PauliX, true, binaryJasmine, jasmine); |
| 53 | |
| 54 | // Apply the quantum oracle |
| 55 | Meeting_Oracle(x, jasmine, target); |
| 56 | |
| 57 | // Compare the result of the quantum oracle with that of the classical oracle |
| 58 | if CheckZero(target) == classicalResult { |
| 59 | Message($"Failed on test case k = {k}, j = {j}. Classical result is not the same as quantum."); |
| 60 | } |
| 61 | |
| 62 | // Undo the preparation of basis states x and jasmine |
| 63 | ApplyPauliFromBitString(PauliX, true, binaryX, x); |
| 64 | ApplyPauliFromBitString(PauliX, true, binaryJasmine, jasmine); |
| 65 | |
| 66 | // Check that the oracle did not change the input states |
| 67 | if not CheckAllZero(x) { |
| 68 | Message($"Failed on test case k = {k}, j = {j}. Input state of x changed."); |
| 69 | } |
| 70 | if not CheckAllZero(jasmine) { |
| 71 | Message($"Failed on test case k = {k}, j = {j}. Input state of jasmine changed."); |
| 72 | } |
| 73 | |
| 74 | Reset(target); |
| 75 | } |
| 76 | } |
| 77 | Message("Success!"); |
| 78 | } |
| 79 | } |