use onq::{
Circuit, CircuitBuilder, OnqError, Operation, QduId, StableState, simulation::SimulationResult,
simulation::Simulator,
};
use std::f64::consts::PI;
fn qid(id: u64) -> QduId {
QduId(id)
}
fn check_stable_state(result: &SimulationResult, qdu_id: QduId, expected_state_val: u64) {
match result.get_stable_state(&qdu_id) {
Some(StableState::ResolvedQuality(val)) => {
assert_eq!(*val, expected_state_val, "Mismatch for QDU {}", qdu_id);
}
_ => panic!(
"QDU {} was not stabilized or result is not ResolvedQuality",
qdu_id
),
}
}
#[test]
fn test_empty_circuit() -> Result<(), OnqError> {
let circuit = Circuit::new();
let simulator = Simulator::new();
let result = simulator.run(&circuit)?;
assert!(
result.all_stable_outcomes().is_empty(),
"Empty circuit should yield empty results"
);
Ok(())
}
#[test]
fn test_initial_state_stabilization() -> Result<(), OnqError> {
let q0 = qid(0);
let circuit = CircuitBuilder::new()
.add_op(Operation::Stabilize { targets: vec![q0] })
.build();
let simulator = Simulator::new();
let result = simulator.run(&circuit)?;
assert_eq!(
result.all_stable_outcomes().len(),
1,
"Should have one result"
);
check_stable_state(&result, q0, 0); Ok(())
}
#[test]
fn test_two_qdus_initial_state_stabilization() -> Result<(), OnqError> {
let q0 = qid(0);
let q1 = qid(1);
let circuit = CircuitBuilder::new()
.add_op(Operation::Stabilize {
targets: vec![q0, q1],
})
.build();
let simulator = Simulator::new();
let result = simulator.run(&circuit)?;
assert_eq!(
result.all_stable_outcomes().len(),
2,
"Should have two results"
);
check_stable_state(&result, q0, 0); check_stable_state(&result, q1, 0); Ok(())
}
#[test]
fn test_identity_operation() -> Result<(), OnqError> {
let q0 = qid(0);
let circuit = CircuitBuilder::new()
.add_op(Operation::InteractionPattern {
target: q0,
pattern_id: "Identity".to_string(), })
.add_op(Operation::Stabilize { targets: vec![q0] })
.build();
let simulator = Simulator::new();
let result = simulator.run(&circuit)?;
check_stable_state(&result, q0, 0); Ok(())
}
#[test]
fn test_quality_flip_operation() -> Result<(), OnqError> {
let q0 = qid(0);
let circuit = CircuitBuilder::new()
.add_op(Operation::InteractionPattern {
target: q0,
pattern_id: "QualityFlip".to_string(), })
.add_op(Operation::Stabilize { targets: vec![q0] })
.build();
let simulator = Simulator::new();
let result = simulator.run(&circuit)?;
check_stable_state(&result, q0, 1);
Ok(())
}
#[test]
fn test_phase_shift_operation() -> Result<(), OnqError> {
let q0 = qid(0);
let circuit = CircuitBuilder::new()
.add_op(Operation::PhaseShift {
target: q0,
theta: PI / 2.0,
}) .add_op(Operation::Stabilize { targets: vec![q0] })
.build();
let simulator = Simulator::new();
let result = simulator.run(&circuit)?;
check_stable_state(&result, q0, 0);
Ok(())
}
#[test]
fn test_two_qdus_flip_one() -> Result<(), OnqError> {
let q0 = qid(0);
let q1 = qid(1);
let circuit = CircuitBuilder::new()
.add_op(Operation::InteractionPattern {
target: q1, pattern_id: "QualityFlip".to_string(),
})
.add_op(Operation::Stabilize {
targets: vec![q0, q1],
})
.build();
let simulator = Simulator::new();
let result = simulator.run(&circuit)?;
assert_eq!(result.all_stable_outcomes().len(), 2);
check_stable_state(&result, q0, 0); check_stable_state(&result, q1, 1); Ok(())
}
#[test]
fn test_undefined_interaction_pattern() {
let q0 = qid(0);
let circuit = CircuitBuilder::new()
.add_op(Operation::InteractionPattern {
target: q0,
pattern_id: "ThisPatternDoesNotExist".to_string(), })
.add_op(Operation::Stabilize { targets: vec![q0] })
.build();
let simulator = Simulator::new();
let result = simulator.run(&circuit);
assert!(
result.is_err(),
"Expected an error for undefined pattern ID"
);
match result.err().unwrap() {
OnqError::InvalidOperation { message } => {
assert!(
message.contains("Interaction Pattern 'ThisPatternDoesNotExist' is not defined"),
"Incorrect error message: {}",
message
);
}
e => panic!("Expected InvalidOperation error, got {:?}", e),
}
}