use super::*;
use crate::gates::Gate;
pub(super) fn rx_cx_chain(circuit: &mut Circuit, qubits: std::ops::Range<usize>) {
for q in qubits.clone() {
circuit.add_gate(Gate::Rx(0.3), &[q]);
}
for q in qubits.start..qubits.end - 1 {
circuit.add_gate(Gate::Cx, &[q, q + 1]);
}
}
#[test]
fn dense_entangled_circuit_is_candidate() {
let mut circuit = Circuit::new(8, 0);
rx_cx_chain(&mut circuit, 0..8);
assert!(auto_terminal_statevector_candidate(&circuit));
}
#[test]
fn decomposable_circuit_is_not_candidate() {
let mut circuit = Circuit::new(12, 0);
rx_cx_chain(&mut circuit, 0..6);
rx_cx_chain(&mut circuit, 6..12);
assert!(!auto_terminal_statevector_candidate(&circuit));
}
#[test]
fn partial_independent_circuit_is_not_candidate() {
let mut circuit = Circuit::new(10, 0);
rx_cx_chain(&mut circuit, 0..8);
rx_cx_chain(&mut circuit, 8..10);
assert!(!auto_terminal_statevector_candidate(&circuit));
}
#[test]
fn clifford_t_inside_the_rank_budget_is_a_candidate() {
let n = 10;
let budget = stabilizer_rank_budget(n);
assert_eq!(budget, 2);
let mut within = Circuit::new(n, 0);
within.add_gate(Gate::H, &[0]);
for q in 0..n - 1 {
within.add_gate(Gate::Cx, &[q, q + 1]);
}
for q in 0..budget {
within.add_gate(Gate::T, &[q]);
}
assert!(auto_terminal_statevector_candidate(&within));
}
#[test]
fn temporal_prefix_circuit_is_not_candidate() {
let n = 8;
let mut circuit = Circuit::new(n, 0);
circuit.add_gate(Gate::H, &[0]);
for _ in 0..3 {
for q in 0..n - 1 {
circuit.add_gate(Gate::Cx, &[q, q + 1]);
}
}
for q in 0..n {
circuit.add_gate(Gate::Rx(0.3), &[q]);
}
assert!(has_temporal_clifford_opportunity(
&BackendKind::Auto,
&circuit
));
assert!(!auto_terminal_statevector_candidate(&circuit));
}
#[test]
fn clifford_only_circuit_is_not_a_temporal_prefix_candidate() {
use crate::circuit::{ClassicalCondition, guarded};
use crate::circuit::{Instruction, SmallVec};
let n = 8;
let mut circuit = Circuit::new(n, n);
circuit.add_gate(Gate::H, &[0]);
for _ in 0..4 {
for q in 0..n - 1 {
circuit.add_gate(Gate::Cx, &[q, q + 1]);
}
}
circuit.add_measure(0, 0);
circuit.instructions.extend(guarded(
ClassicalCondition::BitIsOne(0),
vec![
Instruction::Gate {
gate: Gate::X,
targets: SmallVec::from_slice(&[1]),
},
Instruction::Gate {
gate: Gate::Z,
targets: SmallVec::from_slice(&[2]),
},
],
));
assert!(circuit.is_clifford_only());
assert!(!has_temporal_clifford_opportunity(
&BackendKind::Auto,
&circuit
));
assert!(plan_temporal_clifford(&BackendKind::Auto, &circuit).is_none());
let mut mixed = circuit.clone();
mixed.add_gate(Gate::Rx(0.3), &[0]);
assert!(has_temporal_clifford_opportunity(
&BackendKind::Auto,
&mixed
));
}