def test_wavefunction(forest: ForestConnection): # The forest fixture (argument) to this test is to ensure this is # skipped when a forest web api key is unavailable. You could also # pass it to the constructor of WavefunctionSimulator() but it is not # necessary. wfnsim = WavefunctionSimulator() bell = Program( H(0), CNOT(0, 1), ) wfn = wfnsim.wavefunction(bell) np.testing.assert_allclose(wfn.amplitudes, 1 / np.sqrt(2) * np.array([1, 0, 0, 1])) np.testing.assert_allclose(wfn.probabilities(), [0.5, 0, 0, 0.5]) assert wfn.pretty_print() == "(0.71+0j)|00> + (0.71+0j)|11>" bitstrings = wfn.sample_bitstrings(1000) parity = np.sum(bitstrings, axis=1) % 2 assert np.all(parity == 0)
def test_copy(): prog1 = Program( H(0), CNOT(0, 1), ) prog2 = prog1.copy().measure_all() assert prog1.out() == '\n'.join([ 'H 0', 'CNOT 0 1', '' ]) assert prog2.out() == '\n'.join([ 'H 0', 'CNOT 0 1', 'DECLARE ro BIT[2]', 'MEASURE 0 ro[0]', 'MEASURE 1 ro[1]', '', ])
def test_unsupported_ops(): target = Label("target") base_prog = Program( Declare('reg1', 'BIT'), Declare('reg2', 'BIT'), H(0), JumpTarget(target), CNOT(0, 1)) bad_ops = [WAIT, Jump(target), MOVE(MemoryReference('reg1'), MemoryReference('reg2'))] assert to_latex(base_prog) for op in bad_ops: prog = base_prog + op with pytest.raises(ValueError): _ = to_latex(prog)
def test_alloc(): p = Program() p.inst(H(0)) # H 0 q1 = p.alloc() # q1 = 1 q2 = p.alloc() # q2 = 3 p.inst(CNOT(q1, q2)) # CNOT 1 3 p.inst(H(2)) q3 = p.alloc() # q3 = 4 p.inst(X(q3)) # X 4 with pytest.raises(RuntimeError) as e: _ = p.out() assert e.match(r'Qubit q\d+ has not been assigned an index')
def test_transform_with_post_transformation_hooks( bell_circuit_with_qids: Tuple[cirq.Circuit, List[cirq.Qid]]) -> None: """test that a user can transform a `cirq.Circuit` to a `pyquil.Program` functionally with explicit physical qubit address mapping. """ bell_circuit, qubits = bell_circuit_with_qids def reset_hook(program, measurement_id_map): program._instructions.insert(0, Reset()) return program, measurement_id_map reset_hook_spec = create_autospec(reset_hook, side_effect=reset_hook) pragma = Pragma('INTIAL_REWIRING', freeform_string='GREEDY') def rewire_hook(program, measurement_id_map): program._instructions.insert(0, pragma) return program, measurement_id_map rewire_hook_spec = create_autospec(rewire_hook, side_effect=rewire_hook) transformer = transformers.build( qubits=tuple(qubits), post_transformation_hooks=[reset_hook_spec, rewire_hook_spec]) program, _ = transformer(circuit=bell_circuit) assert 1 == reset_hook_spec.call_count assert Reset() in program.instructions, "hook should add reset" assert 1 == rewire_hook_spec.call_count assert pragma in program.instructions, "hook should add pragma" assert H(0) in program.instructions, "bell circuit should include Hadamard" assert CNOT(0, 1) in program.instructions, "bell circuit should include CNOT" assert ( DECLARE("m0", memory_size=2) in program.instructions), "executable should declare a read out bit" assert ( MEASURE(0, ("m0", 0)) in program.instructions ), "executable should measure the first qubit to the first read out bit" assert ( MEASURE(1, ("m0", 1)) in program.instructions ), "executable should measure the second qubit to the second read out bit"
def teleport(start_index, end_index, ancilla_index): """Teleport a qubit from start to end using an ancilla qubit """ p = make_bell_pair(end_index, ancilla_index) # do the teleportation p.inst(CNOT(start_index, ancilla_index)) p.inst(H(start_index)) # measure the results and store them in classical registers [0] and [1] p.measure(start_index, 0) p.measure(ancilla_index, 1) p.if_then(1, X(2)) p.if_then(0, Z(2)) p.measure(end_index, 2) return p
def test_qc_expectation_larger_lattice( client_configuration: QCSClientConfiguration, dummy_compiler: DummyCompiler): qc = QuantumComputer(name="testy!", qam=QVM(client_configuration=client_configuration), compiler=dummy_compiler) q0 = 2 q1 = 3 # bell state program p = Program() p += RESET() p += H(q0) p += CNOT(q0, q1) p.wrap_in_numshots_loop(10) # XX, YY, ZZ experiment sx = ExperimentSetting(in_state=_pauli_to_product_state(sZ(q0) * sZ(q1)), out_operator=sX(q0) * sX(q1)) sy = ExperimentSetting(in_state=_pauli_to_product_state(sZ(q0) * sZ(q1)), out_operator=sY(q0) * sY(q1)) sz = ExperimentSetting(in_state=_pauli_to_product_state(sZ(q0) * sZ(q1)), out_operator=sZ(q0) * sZ(q1)) e = Experiment(settings=[sx, sy, sz], program=p) results = qc.run_experiment(e) # XX expectation value for bell state |00> + |11> is 1 assert np.isclose(results[0].expectation, 1) assert np.isclose(results[0].std_err, 0) assert results[0].total_counts == 40 # YY expectation value for bell state |00> + |11> is -1 assert np.isclose(results[1].expectation, -1) assert np.isclose(results[1].std_err, 0) assert results[1].total_counts == 40 # ZZ expectation value for bell state |00> + |11> is 1 assert np.isclose(results[2].expectation, 1) assert np.isclose(results[2].std_err, 0) assert results[2].total_counts == 40
def test_qubit_placeholder(): p = Program() p.inst(H(0)) # H 0 q1 = QubitPlaceholder() # q1 = 1 q2 = QubitPlaceholder() # q2 = 3 p.inst(CNOT(q1, q2)) # CNOT 1 3 p.inst(H(2)) q3 = QubitPlaceholder() # q3 = 4 p.inst(X(q3)) # X 4 with pytest.raises(RuntimeError) as e: _ = p.out() assert e.match(r"Qubit q\d+ has not been assigned an index")
def test_qubit_placeholder_2(): p = Program() p.inst(H(0)) # H 0 q1 = QubitPlaceholder() # q1 = 1 q2 = QubitPlaceholder() # q2 = 3 p.inst(CNOT(q1, q2)) # CNOT 1 3 p.inst(H(2)) q3 = QubitPlaceholder() # q3 = 4 p.inst(X(q3)) # X 4 with pytest.raises(ValueError) as e: _ = address_qubits(p, {q1: 1, q2: 3, q3: 4}) assert e.match("Your program mixes instantiated qubits with placeholders")
def run_bell_high_level(n_shots=1000): # Step 1. Get a device. Either a QVM or a QPU qc = get_qc('9q-generic-qvm') q = [4, 5] # qubits # Step 2. Construct your program program = Program(H(q[0]), CNOT(q[0], q[1])) # Step 3. Run bitstrings = qc.run_and_measure(program, trials=n_shots) # Bincount bitstrings basis = np.array([2**i for i in range(len(q))]) ints = np.sum(bitstrings * basis, axis=1) print('bincounts', np.bincount(ints)) # Check parity parities = np.sum(bitstrings, axis=1) % 2 print('avg parity', np.mean(parities))
def test_qc_expectation_larger_lattice(forest): device = NxDevice(nx.complete_graph(4)) qc = QuantumComputer(name='testy!', qam=QVM(connection=forest), device=device, compiler=DummyCompiler()) q0 = 2 q1 = 3 # bell state program p = Program() p += RESET() p += H(q0) p += CNOT(q0, q1) p.wrap_in_numshots_loop(10) # XX, YY, ZZ experiment sx = ExperimentSetting(in_state=sZ(q0) * sZ(q1), out_operator=sX(q0) * sX(q1)) sy = ExperimentSetting(in_state=sZ(q0) * sZ(q1), out_operator=sY(q0) * sY(q1)) sz = ExperimentSetting(in_state=sZ(q0) * sZ(q1), out_operator=sZ(q0) * sZ(q1)) e = TomographyExperiment(settings=[sx, sy, sz], program=p) results = qc.experiment(e) # XX expectation value for bell state |00> + |11> is 1 assert np.isclose(results[0].expectation, 1) assert np.isclose(results[0].std_err, 0) assert results[0].total_counts == 40 # YY expectation value for bell state |00> + |11> is -1 assert np.isclose(results[1].expectation, -1) assert np.isclose(results[1].std_err, 0) assert results[1].total_counts == 40 # ZZ expectation value for bell state |00> + |11> is 1 assert np.isclose(results[2].expectation, 1) assert np.isclose(results[2].std_err, 0) assert results[2].total_counts == 40
def test_dagger(): # these gates are their own inverses p = Program().inst(I(0), X(0), Y(0), Z(0), H(0), CNOT(0,1), CCNOT(0,1,2), SWAP(0,1), CSWAP(0,1,2)) assert p.dagger().out() == 'CSWAP 0 1 2\nSWAP 0 1\n' \ 'CCNOT 0 1 2\nCNOT 0 1\nH 0\n' \ 'Z 0\nY 0\nX 0\nI 0\n' # these gates require negating a parameter p = Program().inst(PHASE(pi, 0), RX(pi, 0), RY(pi, 0), RZ(pi, 0), CPHASE(pi, 0, 1), CPHASE00(pi, 0, 1), CPHASE01(pi, 0, 1), CPHASE10(pi, 0, 1), PSWAP(pi, 0, 1)) assert p.dagger().out() == 'PSWAP(-3.141592653589793) 0 1\n' \ 'CPHASE10(-3.141592653589793) 0 1\n' \ 'CPHASE01(-3.141592653589793) 0 1\n' \ 'CPHASE00(-3.141592653589793) 0 1\n' \ 'CPHASE(-3.141592653589793) 0 1\n' \ 'RZ(-3.141592653589793) 0\n' \ 'RY(-3.141592653589793) 0\n' \ 'RX(-3.141592653589793) 0\n' \ 'PHASE(-3.141592653589793) 0\n' # these gates are special cases p = Program().inst(S(0), T(0), ISWAP(0, 1)) assert p.dagger().out() == 'PSWAP(1.5707963267948966) 0 1\n' \ 'RZ(0.7853981633974483) 0\n' \ 'PHASE(-1.5707963267948966) 0\n' # must invert defined gates G = np.array([[0, 1], [0+1j, 0]]) p = Program().defgate("G", G).inst(("G", 0)) assert p.dagger().out() == 'DEFGATE G-INV:\n' \ ' 0.0+-0.0i, 0.0-1.0i\n' \ ' 1.0+-0.0i, 0.0+-0.0i\n\n' \ 'G-INV 0\n' # can also pass in a list of inverses inv_dict = {"G":"J"} p = Program().defgate("G", G).inst(("G", 0)) assert p.dagger(inv_dict=inv_dict).out() == 'J 0\n'
def test_exhaustive_state_dfe_noiseless_qvm(qvm, benchmarker): qvm.qam.random_seed = 1 state_exp = generate_state_dfe_experiment(Program([RX(pi / 2, 0)]), compiler=benchmarker) data, cal = acquire_dfe_data( state_exp, qvm, var=0.01, ) est = direct_fidelity_estimate(data, cal, 'state') assert est.fid_point_est == 1.0 assert est.fid_var_est == 0.0 assert all([exp == 1.0 for exp in data.expectation]) assert all(np.abs(cal) == 1.0 for cal in cal.expectation) state_exp = generate_state_dfe_experiment(Program([H(0), H(1), CZ(0, 1)]), compiler=benchmarker) data, cal = acquire_dfe_data( state_exp, qvm, var=0.01, ) est = direct_fidelity_estimate(data, cal, 'state') assert est.fid_point_est == 1.0 assert est.fid_var_est == 0.0 assert all([exp == 1.0 for exp in data.expectation]) assert all(np.abs(cal) == 1.0 for cal in cal.expectation) state_exp = generate_state_dfe_experiment(Program([H(0), CNOT(0, 1)]), compiler=benchmarker) data, cal = acquire_dfe_data( state_exp, qvm, var=0.01, ) est = direct_fidelity_estimate(data, cal, 'state') assert est.fid_point_est == 1.0 assert est.fid_var_est == 0.0 assert all([exp == 1.0 for exp in data.expectation]) assert all(np.abs(cal) == 1.0 for cal in cal.expectation)
def test_qubit_placeholder_new(): p = Program() q0 = QubitPlaceholder() p.inst(H(q0)) # H 0 q1 = QubitPlaceholder() q2 = QubitPlaceholder() p.inst(CNOT(q1, q2)) # CNOT 1 3 qxxx = QubitPlaceholder() p.inst(H(qxxx)) q3 = QubitPlaceholder() p.inst(X(q3)) # X 4 p = address_qubits(p, {q1: 1, q2: 3, q3: 4, q0: 0, qxxx: 2}) assert p.out() == "H 0\nCNOT 1 3\nH 2\nX 4\n"
def test_diffusion_operator(): """ Checks that the diffusion operator outputs the correct operation """ created = decomposed_diffusion_program(qubits[:2]) desired = pq.Program() for def_gate in created.defined_gates: desired.defgate(def_gate.name, def_gate.matrix) qubit0 = qubits[0] qubit1 = qubits[1] desired.inst(X(qubit0)) desired.inst(X(qubit1)) desired.inst(H(qubit1)) desired.inst(RZ(-np.pi, qubit0)) desired.inst(CNOT(qubit0, qubit1)) desired.inst(RZ(-np.pi, qubit0)) desired.inst(H(qubit1)) desired.inst(X(qubit0)) desired.inst(X(qubit1)) assert desired == created
def create_singlet_state(): """ Returns quantum program that constructs a Singlet state of two spins """ p = Program() # Start by constructing a Triplet state of two spins (Bell state) # 10|> + 01|> # https://en.wikipedia.org/wiki/Triplet_state # p.inst(X(0)) p.inst(H(1)) p.inst(CNOT(1, 0)) # Convert to Singlet # 01|> - 10|> # https://en.wikipedia.org/wiki/Singlet_state # p.inst(Z(1)) return p
def test_alloc(): p = Program() p.inst(H(0)) # H 0 q1 = p.alloc() # q1 = 1 q2 = p.alloc() # q2 = 3 p.inst(CNOT(q1, q2)) # CNOT 1 3 p.inst(H(2)) q3 = p.alloc() # q3 = 4 p.inst(X(q3)) # X 4 assert p.out() == "H 0\n" \ "CNOT 1 3\n" \ "H 2\n" \ "X 4\n"
def nCU1(axis, angle, ctrls, target) -> Program: """ :param axis: {'x', 'y', 'z'} :param angle: REAL :param ctrls: list(int) :param target: int :return: Program """ nCU1_program = Program() n_ctrls = len(ctrls) if n_ctrls == 1: if axis == 'x': nCU1_program.inst(RX(angle / 2, target)) nCU1_program.inst(CNOT(ctrls[0], target)) nCU1_program.inst(RX(-angle / 2, target)) nCU1_program.inst(CNOT(ctrls[0], target)) elif axis == 'y': nCU1_program.inst(RY(angle / 2, target)) nCU1_program.inst(CNOT(ctrls[0], target)) nCU1_program.inst(RY(-angle / 2, target)) nCU1_program.inst(CNOT(ctrls[0], target)) elif axis == 'z': nCU1_program.inst(RZ(angle / 2, target)) nCU1_program.inst(CNOT(ctrls[0], target)) nCU1_program.inst(RZ(-angle / 2, target)) nCU1_program.inst(CNOT(ctrls[0], target)) else: raise Exception(ValueError('Invalid axis value!')) elif n_ctrls > 1: nCU1_program.inst(nCU1(axis, angle / 2, ctrls[1:], target)) nCU1_program.inst(CNOT(ctrls[0], target)) nCU1_program.inst(nCU1(axis, -angle / 2, ctrls[1:], target)) nCU1_program.inst(CNOT(ctrls[0], target)) else: raise Exception(ValueError('Missing control qubits!')) return nCU1_program
def Z_syndrome_extraction(dual_qubits: List[QubitPlaceholder]) -> Program: """ Runs the syndrome extraction circuit for the Z-stabilizers. Detects bit-flip errors on the lattice. :param dual_qubits: List of ancilla and data qubits for the extraction. Assumed to have an identical format to the "primal_qubits" parameter in "X_syndrome_extraction" above. Note that the ancilla qubits live on the nodes of the dual graph (plaquette faces of the primal graph). Also we assume the ancilla is initialized to |0>. :returns: +/- 1 to indicate whether an error has been detected """ pq = Program() ro_Z = pq.declare('ro', 'BIT', 1) # Perform the circuit for i in range(1, len(dual_qubits)): pq += CNOT(dual_qubits[i], dual_qubits[0]) # Measure in the Z-basis pq += MEASURE(dual_qubits[0], ro_Z[0]) return pq
def test_is_protoquil(): prog = Program( Declare('ro', 'BIT'), MEASURE(1, MemoryReference("ro", 0)), H(1), RESET()) validate_protoquil(prog) assert prog.is_protoquil() prog = Program(Declare('ro', 'BIT'), H(0), Y(1), CNOT(0, 1)) \ .measure(0, MemoryReference("ro", 0)) \ .if_then(MemoryReference("ro", 0), Program(X(0)), Program()) with pytest.raises(ValueError): validate_protoquil(prog) assert not prog.is_protoquil() prog = Program(Declare('ro', 'BIT'), ClassicalNot(MemoryReference("ro", 0))) with pytest.raises(ValueError): validate_protoquil(prog) assert not prog.is_protoquil()
def _construct_deutsch_jozsa_circuit( qubits, computational_qubits, ancillas, unitary_matrix ): """ Builds the Deutsch-Jozsa circuit. Which can determine whether a function f mapping `\{0,1\}^n \to \{0,1\}` is constant or balanced, provided that it is one of them. Args: qubits: list of qubits computational_qubits: list of qubits whose results matter ancillas: list of ancillary qubits unitary_matrix: the oracle's unitary_matrix Returns: A program corresponding to the desired instance of Deutsch Jozsa's Algorithm. """ dj_prog = Program() # Put the first ancilla qubit (query qubit) into minus state dj_prog.inst(X(ancillas[0]), H(ancillas[0])) # Apply Hadamard, Oracle, and Hadamard again dj_prog.inst([H(qubit) for qubit in computational_qubits]) # Build the oracle oracle_prog = Program() oracle_prog.defgate(ORACLE_GATE_NAME, unitary_matrix) scratch_bit = ancillas[1] qubits_for_funct = [scratch_bit] + computational_qubits oracle_prog.inst(tuple([ORACLE_GATE_NAME] + qubits_for_funct)) dj_prog += oracle_prog # Here the oracle does not leave the computational qubits unchanged, so we use a CNOT to # to move the result to the query qubit, and then we uncompute with the dagger. dj_prog.inst(CNOT(qubits[0], ancillas[0])) dj_prog += oracle_prog.dagger() dj_prog.inst([H(qubit) for qubit in computational_qubits]) return dj_prog
def create_ghz_program(tree: nx.DiGraph): """ Create a Bell/GHZ state with CNOTs described by tree. :param tree: A tree that describes the CNOTs to perform to create a bell/GHZ state. :return: the program """ assert nx.is_tree(tree), 'Needs to be a tree' nodes = list(nx.topological_sort(tree)) n_qubits = len(nodes) program = Program(H(nodes[0])) for node in nodes: for child in tree.successors(node): program += CNOT(node, child) ro = program.declare('ro', 'BIT', n_qubits) for i, q in enumerate(nodes): program += MEASURE(q, ro[i]) return program
def teleport(start_index, end_index, ancilla_index): """Teleport a qubit from start to end using an ancilla qubit """ program = make_bell_pair(end_index, ancilla_index) ro = program.declare('ro', memory_size=3) # do the teleportation program.inst(CNOT(start_index, ancilla_index)) program.inst(H(start_index)) # measure the results and store them in classical registers [0] and [1] program.measure(start_index, ro[0]) program.measure(ancilla_index, ro[1]) program.if_then(ro[1], X(2)) program.if_then(ro[0], Z(2)) program.measure(end_index, ro[2]) print(program) return program
def test_qc_calibration_2q(client_configuration: QCSClientConfiguration): # noise model with 95% symmetrized readout fidelity per qubit noise_model = asymmetric_ro_model([0, 1], 0.945, 0.955) qc = get_qc("2q-qvm", client_configuration=client_configuration) qc.qam.noise_model = noise_model # bell state program (doesn't matter) p = Program() p += RESET() p += H(0) p += CNOT(0, 1) p.wrap_in_numshots_loop(10000) # ZZ experiment sz = ExperimentSetting(in_state=_pauli_to_product_state(sZ(0) * sZ(1)), out_operator=sZ(0) * sZ(1)) e = Experiment(settings=[sz], program=p) results = qc.calibrate(e) # ZZ expectation should just be (1 - 2 * readout_error_q0) * (1 - 2 * readout_error_q1) np.isclose(results[0].expectation, 0.81, atol=0.01) assert results[0].total_counts == 40000
def test_qc_calibration_1q(forest): # noise model with 95% symmetrized readout fidelity per qubit noise_model = asymmetric_ro_model([0], 0.945, 0.955) qc = get_qc("1q-qvm") qc.qam.noise_model = noise_model # bell state program (doesn't matter) p = Program() p += RESET() p += H(0) p += CNOT(0, 1) p.wrap_in_numshots_loop(10000) # Z experiment sz = ExperimentSetting(in_state=sZ(0), out_operator=sZ(0)) e = Experiment(settings=[sz], program=p) results = qc.calibrate(e) # Z expectation value should just be 1 - 2 * readout_error np.isclose(results[0].expectation, 0.9, atol=0.01) assert results[0].total_counts == 20000
def run_bell_low_level(n_shots=1000): # Step 1. Get some device components qc = get_qc('9q-generic-qvm') compiler = qc.compiler qam = qc.qam del qc q = [4, 5] # qubits # Step 2. Construct your program program = Program() program += H(q[0]) program += CNOT(q[0], q[1]) # Step 2.1. Manage read-out memory ro = program.declare('ro', memory_type='BIT', memory_size='2') program += MEASURE(q[0], ro[0]) program += MEASURE(q[1], ro[1]) # Step 2.2. Run the program in a loop program = program.wrap_in_numshots_loop(n_shots) # Step 3. Compile and run nq_program = compiler.quil_to_native_quil(program) executable = compiler.native_quil_to_executable(nq_program) bitstrings = qam.load(executable) \ .run() \ .wait() \ .read_memory(region_name="ro") # Bincount bitstrings basis = np.array([2**i for i in range(len(q))]) ints = np.sum(bitstrings * basis, axis=1) print('bincounts', np.bincount(ints)) # Check parity parities = np.sum(bitstrings, axis=1) % 2 print('avg parity', np.mean(parities))
def test_expectation(forest: ForestConnection): # The forest fixture (argument) to this test is to ensure this is # skipped when a forest web api key is unavailable. You could also # pass it to the constructor of WavefunctionSimulator() but it is not # necessary. wfnsim = WavefunctionSimulator() bell = Program( H(0), CNOT(0, 1), ) expects = wfnsim.expectation(bell, [ sZ(0) * sZ(1), sZ(0), sZ(1), sX(0) * sX(1), ]) assert expects.size == 4 np.testing.assert_allclose(expects, [1, 0, 0, 1]) pauli_sum = PauliSum([sZ(0) * sZ(1)]) expects = wfnsim.expectation(bell, pauli_sum) assert expects.size == 1 np.testing.assert_allclose(expects, [1])
def test_get_flipped_program(): program = Program() ro = program.declare('ro', memory_type='BIT', memory_size=2) program += Program([ I(0), RX(2.3, 1), CNOT(0, 1), MEASURE(0, ro[0]), MEASURE(1, ro[1]), ]) flipped_program = get_flipped_program(program) lines = flipped_program.out().splitlines() matched = 0 for l1, l2 in zip(lines, lines[1:]): ma = re.match(r'MEASURE (\d) ro\[(\d)\]', l2) if ma is not None: matched += 1 assert int(ma.group(1)) == int(ma.group(2)) assert l1 == 'RX(pi) {}'.format(int(ma.group(1))) assert matched == 2
def CCZ(): t_gate_1 = Program(T(1)).dagger() t_gate_2 = Program(T(2)).dagger() ccz = Program() ccz += CNOT(1,2) ccz += t_gate_2 ccz += CNOT(0,2) ccz += T(2) ccz += CNOT(1,2) ccz += t_gate_2 ccz += CNOT(0,2) ccz += T(1) ccz += T(2) ccz += CNOT(0,1) ccz += T(0) ccz += t_gate_1 ccz += CNOT(0,1) return ccz
def test_is_protoquil(): prog = Program(Declare("ro", "BIT"), MEASURE(1, MemoryReference("ro", 0)), H(1), RESET()) validate_protoquil(prog) assert prog.is_protoquil() prog = (Program(Declare("ro", "BIT"), H(0), Y(1), CNOT(0, 1)).measure( 0, MemoryReference("ro", 0)).if_then(MemoryReference("ro", 0), Program(X(0)), Program())) with pytest.raises(ValueError): validate_protoquil(prog) assert not prog.is_protoquil() prog = Program(Declare("ro", "BIT"), ClassicalNot(MemoryReference("ro", 0))) with pytest.raises(ValueError): validate_protoquil(prog) assert not prog.is_protoquil() prog = Program(DefCalibration("I", [], [Qubit(0)], []), I(0)) with pytest.raises(ValueError): validate_protoquil(prog) assert not prog.is_protoquil() assert prog.is_protoquil(quilt=True)