1use super::operations::Operation;
2
3#[derive(Debug, Clone, Default)]
8pub struct Circuit {
9 pub num_qubits: usize,
11 pub num_cbits: usize,
13 pub operations: Vec<Operation>,
15}
16
17impl Circuit {
18 pub fn new(num_qubits: usize, num_cbits: usize) -> Self {
25 Self {
26 num_qubits,
27 num_cbits,
28 operations: Vec::new(),
29 }
30 }
31
32 pub fn add_op(&mut self, op: Operation) {
34 self.operations.push(op);
35 }
36
37 pub fn validate(&self) -> Vec<String> {
42 let mut warnings = Vec::new();
43 let has_measurement = self
44 .operations
45 .iter()
46 .any(|op| matches!(op, Operation::Measure { .. }));
47
48 if !has_measurement {
49 warnings.push("Warning: No measurements found. The circuit will not produce classical output on hardware.".to_string());
50 }
51
52 warnings
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59 use crate::ir::gates::GateType;
60
61 #[test]
62 fn test_circuit_creation() {
63 let circuit = Circuit::new(2, 2);
64 assert_eq!(circuit.num_qubits, 2);
65 assert_eq!(circuit.num_cbits, 2);
66 assert!(circuit.operations.is_empty());
67 }
68
69 #[test]
70 fn test_add_op() {
71 let mut circuit = Circuit::new(1, 0);
72 let op = Operation::Gate {
73 name: GateType::H,
74 qubits: vec![0],
75 params: vec![],
76 };
77 circuit.add_op(op.clone());
78 assert_eq!(circuit.operations.len(), 1);
79 assert_eq!(circuit.operations[0], op);
80 }
81
82 #[test]
83 fn test_validation_no_measurements() {
84 let mut circuit = Circuit::new(1, 0);
85 circuit.add_op(Operation::Gate {
86 name: GateType::H,
87 qubits: vec![0],
88 params: vec![],
89 });
90 let warnings = circuit.validate();
91 assert_eq!(warnings.len(), 1);
92 assert!(warnings[0].contains("No measurements found"));
93 }
94
95 #[test]
96 fn test_validation_with_measurements() {
97 let mut circuit = Circuit::new(1, 1);
98 circuit.add_op(Operation::Measure { qubit: 0, cbit: 0 });
99 let warnings = circuit.validate();
100 assert!(warnings.is_empty());
101 }
102}