use super::operations::Operation;
#[derive(Debug, Clone, Default)]
pub struct Circuit {
pub num_qubits: usize,
pub num_cbits: usize,
pub operations: Vec<Operation>,
}
impl Circuit {
pub fn new(num_qubits: usize, num_cbits: usize) -> Self {
Self {
num_qubits,
num_cbits,
operations: Vec::new(),
}
}
pub fn add_op(&mut self, op: Operation) {
self.operations.push(op);
}
pub fn validate(&self) -> Vec<String> {
let mut warnings = Vec::new();
let has_measurement = self
.operations
.iter()
.any(|op| matches!(op, Operation::Measure { .. }));
if !has_measurement {
warnings.push("Warning: No measurements found. The circuit will not produce classical output on hardware.".to_string());
}
warnings
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ir::gates::GateType;
#[test]
fn test_circuit_creation() {
let circuit = Circuit::new(2, 2);
assert_eq!(circuit.num_qubits, 2);
assert_eq!(circuit.num_cbits, 2);
assert!(circuit.operations.is_empty());
}
#[test]
fn test_add_op() {
let mut circuit = Circuit::new(1, 0);
let op = Operation::Gate {
name: GateType::H,
qubits: vec![0],
params: vec![],
};
circuit.add_op(op.clone());
assert_eq!(circuit.operations.len(), 1);
assert_eq!(circuit.operations[0], op);
}
#[test]
fn test_validation_no_measurements() {
let mut circuit = Circuit::new(1, 0);
circuit.add_op(Operation::Gate {
name: GateType::H,
qubits: vec![0],
params: vec![],
});
let warnings = circuit.validate();
assert_eq!(warnings.len(), 1);
assert!(warnings[0].contains("No measurements found"));
}
#[test]
fn test_validation_with_measurements() {
let mut circuit = Circuit::new(1, 1);
circuit.add_op(Operation::Measure { qubit: 0, cbit: 0 });
let warnings = circuit.validate();
assert!(warnings.is_empty());
}
}