1use crate::error::{KetError, Result};
6use crate::ir::qubit::LogicalQubit;
7use crate::process::Process;
8
9#[derive(Debug)]
10pub(super) struct CtrlEngine {
11 pub stack: Vec<Vec<Vec<LogicalQubit>>>,
13 list: Vec<LogicalQubit>,
15 is_list_valid: bool,
17}
18
19impl Default for CtrlEngine {
20 fn default() -> Self {
21 Self {
22 stack: vec![Vec::new()],
23 list: Default::default(),
24 is_list_valid: Default::default(),
25 }
26 }
27}
28
29impl CtrlEngine {
30 pub fn get_list(&mut self) -> &[LogicalQubit] {
32 if !self.is_list_valid {
33 self.list = self
34 .stack
35 .last()
36 .unwrap()
37 .clone()
38 .into_iter()
39 .flatten()
40 .collect();
41 self.is_list_valid = true;
42 }
43 &self.list
44 }
45
46 pub fn push(&mut self, qubits: &[LogicalQubit]) -> Result<()> {
48 if qubits.iter().any(|qubit| self.get_list().contains(qubit)) {
49 return Err(KetError::ControlTwice);
50 }
51
52 self.stack.last_mut().unwrap().push(qubits.to_owned());
53 self.is_list_valid = false;
54
55 Ok(())
56 }
57
58 pub fn pop(&mut self) -> Result<()> {
60 self.is_list_valid = false;
61
62 if self.stack.last_mut().unwrap().pop().is_none() {
63 Err(KetError::ControlStackEmpty)
64 } else {
65 Ok(())
66 }
67 }
68
69 pub fn begin(&mut self) -> Result<()> {
71 self.stack.push(vec![]);
72 self.is_list_valid = false;
73 Ok(())
74 }
75
76 pub fn end(&mut self) -> Result<()> {
78 match self.stack.pop() {
79 Some(stack) => {
80 if !stack.is_empty() {
81 Err(KetError::ControlStackNotEmpty)
82 } else {
83 self.is_list_valid = false;
84 if self.stack.is_empty() {
85 Err(KetError::ControlStackRemovePrimary)
86 } else {
87 Ok(())
88 }
89 }
90 }
91 None => Err(KetError::ControlStackRemovePrimary),
92 }
93 }
94}
95
96impl Process {
97 pub fn ctrl_push(&mut self, qubits: &[LogicalQubit]) -> Result<()> {
98 self.adj_ctrl_checks(Some(qubits))?;
99 self.ctrl.push(qubits)
100 }
101
102 pub fn ctrl_pop(&mut self) -> Result<()> {
103 self.ctrl.pop()
104 }
105
106 pub fn adj_begin(&mut self) -> Result<()> {
107 self.adj_ctrl_checks(None)?;
108 self.adj_stack.push(vec![]);
109 Ok(())
110 }
111
112 pub fn adj_end(&mut self) -> Result<()> {
113 if let Some(mut gates) = self.adj_stack.pop() {
114 while let Some(gate) = gates.pop() {
115 self.push_gate(gate.inverse());
116 }
117 Ok(())
118 } else {
119 Err(KetError::InverseScopeEmpty)
120 }
121 }
122
123 pub fn ctrl_begin(&mut self) -> Result<()> {
124 self.adj_ctrl_checks(None)?;
125 self.ctrl.begin()
126 }
127
128 pub fn ctrl_end(&mut self) -> Result<()> {
129 self.adj_ctrl_checks(None)?;
130 self.ctrl.end()
131 }
132}