import numpy as np import pytest from qiskit.quantum_info import Statevector from reachy_bloch.circuit_library import get_circuit from reachy_bloch.executor import QuantumExecutor, StepResult S2 = 1 / np.sqrt(2) def test_bell_yields_four_steps(): qc = get_circuit("bell_state").qc # H, CX, measure, measure steps = list(QuantumExecutor().step_through(qc)) assert len(steps) == 4 assert all(isinstance(s, StepResult) for s in steps) def test_bell_statevector_after_cx_is_correct(): qc = get_circuit("bell_state").qc steps = list(QuantumExecutor().step_through(qc)) sv = steps[1].statevector # the CX step assert sv is not None expected = Statevector([S2, 0, 0, S2]) assert sv.equiv(expected) def test_measure_steps_have_outcome_and_no_statevector(): qc = get_circuit("bell_state").qc steps = list(QuantumExecutor(seed=7).step_through(qc)) measures = [s for s in steps if s.measurement is not None] assert len(measures) == 2 for m in measures: assert m.measurement in {"0", "1"} assert m.statevector is None def test_bell_measurements_are_correlated(): # Entangled Bell pair must collapse together: both qubits always match. qc = get_circuit("bell_state").qc for seed in range(20): outcomes = [ s.measurement for s in QuantumExecutor(seed=seed).step_through(qc) if s.measurement is not None ] assert outcomes[0] == outcomes[1], f"seed {seed}: {outcomes} not correlated" def test_gate_labels_present(): qc = get_circuit("hadamard_demo").qc labels = [s.gate_label for s in QuantumExecutor().step_through(qc)] assert labels[0].lower().startswith("h") assert "measure" in labels[-1].lower() from qiskit import QuantumCircuit def test_more_than_two_qubits_refused(): qc = QuantumCircuit(3) qc.h(0) with pytest.raises(ValueError, match="1 and 2 qubit"): list(QuantumExecutor().step_through(qc))