cqlib_core/circuit/control_flow/
while_op.rs1use super::ControlBody;
14use crate::circuit::classical_expr::ClassicalExpr;
15use crate::circuit::{CircuitError, ClassicalType, ClassicalValue, ClassicalVar, Qubit};
16use std::collections::BTreeSet;
17
18#[derive(Debug, Clone, PartialEq)]
20pub struct WhileOp {
21 condition: ClassicalExpr,
22 body: ControlBody,
23}
24
25impl WhileOp {
26 pub fn new(condition: ClassicalExpr, body: ControlBody) -> Result<Self, CircuitError> {
28 if condition.ty() != ClassicalType::Bool {
29 return Err(CircuitError::InvalidOperation(format!(
30 "while condition must be Bool, got {:?}",
31 condition.ty()
32 )));
33 }
34 Ok(Self { condition, body })
35 }
36
37 pub fn condition(&self) -> &ClassicalExpr {
39 &self.condition
40 }
41
42 pub fn body(&self) -> &ControlBody {
44 &self.body
45 }
46
47 pub fn classical_var_reads(&self) -> BTreeSet<ClassicalVar> {
49 self.condition.vars()
50 }
51
52 pub fn classical_value_reads(&self) -> BTreeSet<ClassicalValue> {
54 self.condition.values()
55 }
56
57 pub fn used_qubits(&self) -> BTreeSet<Qubit> {
59 self.body.used_qubits()
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use super::WhileOp;
66 use crate::circuit::{
67 CircuitId, ClassicalExpr, ClassicalType, ClassicalValue, ClassicalVar, ControlBody,
68 };
69
70 #[test]
71 fn while_requires_bool_condition() {
72 assert!(WhileOp::new(ClassicalExpr::bool_literal(true), ControlBody::new(vec![])).is_ok());
73 assert!(WhileOp::new(ClassicalExpr::bit_literal(true), ControlBody::new(vec![])).is_err());
74 }
75
76 #[test]
77 fn while_reports_condition_reads() {
78 let circuit_id = CircuitId::new();
79 let bit = ClassicalVar::new(circuit_id, 3, ClassicalType::Bit);
80 let value = ClassicalValue::new(circuit_id, 4, ClassicalType::Bit);
81 let condition = ClassicalExpr::try_and(
82 ClassicalExpr::bit_to_bool(bit.expr()).unwrap(),
83 ClassicalExpr::bit_to_bool(value.expr()).unwrap(),
84 )
85 .unwrap();
86 let op = WhileOp::new(condition, ControlBody::new(vec![])).unwrap();
87
88 assert!(op.classical_var_reads().contains(&bit));
89 assert!(op.classical_value_reads().contains(&value));
90 }
91}