@@ -215,16 +215,17 @@ def test_CX_gate():
215215def test_classical_control ():
216216 qasm = """OPENQASM 2.0;
217217 qreg q[2];
218- creg m_a [1];
219- measure q[0] -> m_a [0];
220- if (m_a!=0 ) CX q[0], q[1];
218+ creg a [1];
219+ measure q[0] -> a [0];
220+ if (a==1 ) CX q[0],q[1];
221221 """
222222 parser = QasmParser ()
223223
224224 q_0 = cirq .NamedQubit ('q_0' )
225225 q_1 = cirq .NamedQubit ('q_1' )
226226 expected_circuit = cirq .Circuit (
227- cirq .measure (q_0 , key = 'm_a_0' ), cirq .CNOT (q_0 , q_1 ).with_classical_controls ('m_a_0' )
227+ cirq .measure (q_0 , key = 'a_0' ),
228+ cirq .CNOT (q_0 , q_1 ).with_classical_controls (sympy .Eq (sympy .Symbol ('a_0' ), 1 )),
228229 )
229230
230231 parsed_qasm = parser .parse (qasm )
@@ -235,6 +236,62 @@ def test_classical_control():
235236 ct .assert_same_circuits (parsed_qasm .circuit , expected_circuit )
236237 assert parsed_qasm .qregs == {'q' : 2 }
237238
239+ # Note this cannot *exactly* round-trip because the way QASM and Cirq handle measurements
240+ # into classical registers is different. Cirq parses QASM classical registers into m_a_i for i
241+ # in 0..bit_count. Thus the generated key has an extra "_0" at the end.
242+ expected_generated_qasm = f"""// Generated from Cirq v{ cirq .__version__ }
243+
244+ OPENQASM 2.0;
245+ include "qelib1.inc";
246+
247+
248+ // Qubits: [q_0, q_1]
249+ qreg q[2];
250+ creg m_a_0[1];
251+
252+
253+ measure q[0] -> m_a_0[0];
254+ if (m_a_0==1) cx q[0],q[1];
255+ """
256+ assert cirq .qasm (parsed_qasm .circuit ) == expected_generated_qasm
257+
258+
259+ def test_classical_control_multi_bit ():
260+ qasm = """OPENQASM 2.0;
261+ qreg q[2];
262+ creg a[2];
263+ measure q[0] -> a[0];
264+ measure q[0] -> a[1];
265+ if (a==1) CX q[0],q[1];
266+ """
267+ parser = QasmParser ()
268+
269+ q_0 = cirq .NamedQubit ('q_0' )
270+ q_1 = cirq .NamedQubit ('q_1' )
271+
272+ # Since we split the measurement into two, we also need two conditions.
273+ # m_a==1 corresponds to m_a[0]==1, m_a[1]==0
274+ expected_circuit = cirq .Circuit (
275+ cirq .measure (q_0 , key = 'a_0' ),
276+ cirq .measure (q_0 , key = 'a_1' ),
277+ cirq .CNOT (q_0 , q_1 ).with_classical_controls (
278+ sympy .Eq (sympy .Symbol ('a_0' ), 1 ), sympy .Eq (sympy .Symbol ('a_1' ), 0 )
279+ ),
280+ )
281+
282+ parsed_qasm = parser .parse (qasm )
283+
284+ assert parsed_qasm .supportedFormat
285+ assert not parsed_qasm .qelib1Include
286+
287+ ct .assert_same_circuits (parsed_qasm .circuit , expected_circuit )
288+ assert parsed_qasm .qregs == {'q' : 2 }
289+
290+ # Note that this will *not* round-trip, but there's no good way around that due to the
291+ # difference in how Cirq and QASM do multi-bit measurements.
292+ with pytest .raises (ValueError , match = 'QASM does not support multiple conditions' ):
293+ _ = cirq .qasm (parsed_qasm .circuit )
294+
238295
239296def test_CX_gate_not_enough_args ():
240297 qasm = """OPENQASM 2.0;
0 commit comments