|
| 1 | +/// A set of gates built upon the custom measurements |
| 2 | +/// provided by the hardware provider. |
| 3 | +/// |
| 4 | +/// Source: |
| 5 | +/// [1] Surface code compilation via edge-disjoint paths |
| 6 | +/// https://arxiv.org/pdf/2110.11493 |
| 7 | + |
| 8 | +/// Apply a CNOT gate to the given qubits. |
| 9 | +/// Source: [1] Figure 3. |
| 10 | +operation CNOT(control : Qubit, target : Qubit) : Unit { |
| 11 | + // Prepare an ancilla qubit in the |+⟩ state. |
| 12 | + use ancilla = Qubit(); |
| 13 | + PrepareX(ancilla); |
| 14 | + |
| 15 | + let a = Mzz(control, ancilla); |
| 16 | + let b = Mxx(ancilla, target); |
| 17 | + let c = Mz(ancilla); |
| 18 | + Reset(ancilla); |
| 19 | + |
| 20 | + if b == One { |
| 21 | + Z(control); |
| 22 | + } |
| 23 | + |
| 24 | + if a != c { |
| 25 | + X(target); |
| 26 | + } |
| 27 | +} |
| 28 | + |
| 29 | + |
| 30 | +/// Prepare a qubit in the |+⟩ state. |
| 31 | +operation PrepareX(q : Qubit) : Unit { |
| 32 | + if Mx(q) == One { |
| 33 | + Z(q); |
| 34 | + } |
| 35 | +} |
| 36 | + |
| 37 | +/// Prepare a qubit in the |0⟩ state. |
| 38 | +operation PrepareZ(q : Qubit) : Unit { |
| 39 | + if Mz(q) == One { |
| 40 | + X(q); |
| 41 | + } |
| 42 | +} |
| 43 | + |
| 44 | +/// Prepare a Bell Pair. |
| 45 | +/// Source: [1] Figure 18a. |
| 46 | +operation BellPair(q1 : Qubit, q2 : Qubit) : Unit { |
| 47 | + // Collapse the qubits onto the Pauli-Z basis. |
| 48 | + Mz(q1); |
| 49 | + Mz(q2); |
| 50 | + |
| 51 | + // If they are not aligned in the Pauli-X basis, phase flip one of them. |
| 52 | + if Mxx(q1, q2) == One { |
| 53 | + Z(q2); |
| 54 | + } |
| 55 | +} |
| 56 | + |
| 57 | +/// Measure a Bell Pair. |
| 58 | +/// Source: [1] Figure 18b. |
| 59 | +/// Below is a map showing how the Bell states map to the Result pairs: |
| 60 | +/// |𝚽⁺⟩ -> (Zero, Zero) |
| 61 | +/// |𝚿⁺⟩ -> (Zero, One) |
| 62 | +/// |𝚽⁻⟩ -> (One, Zero) |
| 63 | +/// |𝚿⁻⟩ -> (One, One) |
| 64 | +operation BellMeasurement(q1 : Qubit, q2 : Qubit) : (Result, Result) { |
| 65 | + let z = Mzz(q1, q2); |
| 66 | + let x = Mxx(q1, q2); |
| 67 | + (x, z) |
| 68 | +} |
| 69 | + |
| 70 | +/// User friendly wrapper around the Mx hardware gate. |
| 71 | +operation Mx(q : Qubit) : Result { |
| 72 | + HardwareIntrinsics.__quantum__qis__mx__body(q) |
| 73 | +} |
| 74 | + |
| 75 | +/// User friendly wrapper around the Mz hardware gate. |
| 76 | +operation Mz(q : Qubit) : Result { |
| 77 | + HardwareIntrinsics.__quantum__qis__mz__body(q) |
| 78 | +} |
| 79 | + |
| 80 | +/// User friendly wrapper around the Mxx hardware gate. |
| 81 | +operation Mxx(q1 : Qubit, q2 : Qubit) : Result { |
| 82 | + HardwareIntrinsics.__quantum__qis__mxx__body(q1, q2) |
| 83 | +} |
| 84 | + |
| 85 | +/// User friendly wrapper around the Mzz hardware gate. |
| 86 | +operation Mzz(q1 : Qubit, q2 : Qubit) : Result { |
| 87 | + HardwareIntrinsics.__quantum__qis__mzz__body(q1, q2) |
| 88 | +} |
0 commit comments