1use crate::clexpr::ClExpr;
5use crate::opbox::OpBox;
6use crate::optype::OpType;
7use crate::register::{Bit, BitRegister, ElementId, Qubit};
8
9#[cfg(feature = "schemars")]
10use schemars::JsonSchema;
11use serde::{Deserialize, Serialize};
12
13#[cfg_attr(feature = "schemars", derive(JsonSchema))]
17#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
18pub struct CustomGate {
19 pub name: String,
21 pub args: Vec<String>,
23 pub definition: Box<SerialCircuit>,
25}
26
27#[cfg_attr(feature = "schemars", derive(JsonSchema))]
29#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq, Hash)]
30#[serde(transparent)]
31pub struct Matrix<T = f64> {
32 pub data: Vec<Vec<(T, T)>>,
34}
35
36#[cfg_attr(feature = "schemars", derive(JsonSchema))]
38#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq, Hash)]
39#[serde(untagged)]
40#[non_exhaustive]
41pub enum ClassicalExpUnit {
42 U32(u32),
44 Bit(Bit),
46 BitRegister(BitRegister),
48 ClassicalExpUnit(ClassicalExp),
50}
51
52#[cfg_attr(feature = "schemars", derive(JsonSchema))]
54#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq, Hash)]
55pub struct ClassicalExp {
56 pub args: Vec<ClassicalExpUnit>,
58 pub op: String,
60}
61
62#[cfg_attr(feature = "schemars", derive(JsonSchema))]
64#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
65pub struct Conditional {
66 pub op: Box<Operation>,
68 pub width: u32,
70 pub value: u32,
72}
73
74#[cfg_attr(feature = "schemars", derive(JsonSchema))]
82#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
83#[serde(untagged)]
84#[non_exhaustive]
85pub enum Classical {
86 MultiBit {
88 op: Box<Operation>,
90 n: u32,
92 },
93 RangePredicate {
95 n_i: u32,
97 lower: u64,
99 upper: u64,
101 },
102 Explicit {
104 n_i: u32,
106 name: String,
108 values: Vec<bool>,
110 },
111 ClassicalTransform {
113 n_io: u32,
115 name: String,
117 values: Vec<u32>,
119 },
120 CopyBits {
122 n_i: u32,
124 },
125 SetBits {
127 values: Vec<bool>,
129 },
130}
131
132#[cfg_attr(feature = "schemars", derive(JsonSchema))]
134#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
135pub struct Wasm {
136 n: u64,
137 ww_n: u64,
138 width_i_parameter: Vec<u64>,
139 width_o_parameter: Vec<u64>,
140 func_name: String,
141 wasm_file_uid: String,
142}
143
144#[cfg_attr(feature = "schemars", derive(JsonSchema))]
146#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
147#[non_exhaustive]
148pub struct Operation<P = String> {
149 #[serde(rename = "type")]
151 pub op_type: OpType,
152 #[serde(skip_serializing_if = "Option::is_none")]
154 pub n_qb: Option<u32>,
155 #[serde(skip_serializing_if = "Option::is_none")]
157 pub data: Option<String>,
158 #[serde(skip_serializing_if = "Option::is_none")]
160 pub params: Option<Vec<P>>,
161 #[serde(rename = "box")]
163 #[serde(skip_serializing_if = "Option::is_none")]
164 pub op_box: Option<OpBox>,
165 #[serde(skip_serializing_if = "Option::is_none")]
169 #[serde(rename = "expr")]
170 pub classical_expr: Option<ClExpr>,
171 #[serde(skip_serializing_if = "Option::is_none")]
173 pub signature: Option<Vec<String>>,
174 #[serde(skip_serializing_if = "Option::is_none")]
176 pub conditional: Option<Conditional>,
177 #[serde(skip_serializing_if = "Option::is_none")]
179 pub classical: Option<Box<Classical>>,
180 #[serde(skip_serializing_if = "Option::is_none")]
182 pub wasm: Option<Box<Wasm>>,
183}
184
185#[cfg_attr(feature = "schemars", derive(JsonSchema))]
187#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
188pub struct Command<P = String> {
189 pub op: Operation<P>,
191 pub args: Vec<ElementId>,
195 #[serde(skip_serializing_if = "Option::is_none")]
197 pub opgroup: Option<String>,
198}
199
200#[cfg_attr(feature = "schemars", derive(JsonSchema))]
203#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq, Hash)]
204#[serde(transparent)]
205pub struct Permutation(pub Vec<(Vec<bool>, Vec<bool>)>);
206
207#[cfg_attr(feature = "schemars", derive(JsonSchema))]
209#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq, Hash)]
210pub struct ImplicitPermutation(pub Qubit, pub Qubit);
211
212#[cfg_attr(feature = "schemars", derive(JsonSchema))]
214#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
215#[non_exhaustive]
216pub struct SerialCircuit<P = String> {
217 #[serde(skip_serializing_if = "Option::is_none")]
219 pub name: Option<String>,
220 pub phase: P,
222 pub commands: Vec<Command<P>>,
224 pub qubits: Vec<Qubit>,
226 pub bits: Vec<Bit>,
228 pub implicit_permutation: Vec<ImplicitPermutation>,
230 #[serde(skip_serializing_if = "Option::is_none")]
232 pub number_of_ws: Option<u64>,
233 #[serde(skip_serializing_if = "Option::is_none")]
235 pub number_of_rs: Option<u64>,
236 #[serde(skip_serializing_if = "Option::is_none")]
238 pub created_qubits: Option<Vec<Qubit>>,
239 #[serde(skip_serializing_if = "Option::is_none")]
241 pub discarded_qubits: Option<Vec<Bit>>,
242}
243
244impl<P> Default for Operation<P> {
245 fn default() -> Self {
246 Self {
247 op_type: Default::default(),
248 n_qb: None,
249 data: None,
250 params: None,
251 op_box: None,
252 classical_expr: None,
253 signature: None,
254 conditional: None,
255 classical: None,
256 wasm: None,
257 }
258 }
259}
260
261impl<P: Default> Default for SerialCircuit<P> {
262 fn default() -> Self {
263 Self {
264 name: None,
265 phase: Default::default(),
266 commands: Default::default(),
267 qubits: Default::default(),
268 bits: Default::default(),
269 implicit_permutation: Default::default(),
270 number_of_ws: None,
271 number_of_rs: None,
272 created_qubits: None,
273 discarded_qubits: None,
274 }
275 }
276}
277
278impl<P> Operation<P> {
279 pub fn from_optype(op_type: OpType) -> Self {
284 Self {
285 op_type,
286 ..Operation::default()
287 }
288 }
289
290 pub fn map_params<Q>(self, f: impl FnMut(P) -> Q) -> Operation<Q> {
295 Operation {
296 op_type: self.op_type,
297 n_qb: self.n_qb,
298 data: self.data,
299 params: self
300 .params
301 .map(|params| params.into_iter().map(f).collect()),
302 op_box: self.op_box,
303 classical_expr: self.classical_expr,
304 signature: self.signature,
305 conditional: self.conditional,
306 classical: self.classical,
307 wasm: self.wasm,
308 }
309 }
310}
311
312impl<P> Command<P> {
313 pub fn map_params<Q>(self, f: impl FnMut(P) -> Q) -> Command<Q> {
318 Command {
319 op: self.op.map_params(f),
320 args: self.args,
321 opgroup: self.opgroup,
322 }
323 }
324}
325
326impl<P> SerialCircuit<P> {
327 pub fn new(name: Option<String>, phase: P) -> Self {
329 Self {
330 name,
331 phase,
332 commands: Vec::new(),
333 qubits: Vec::new(),
334 bits: Vec::new(),
335 implicit_permutation: Vec::new(),
336 number_of_ws: None,
337 number_of_rs: None,
338 created_qubits: None,
339 discarded_qubits: None,
340 }
341 }
342
343 pub fn map_params<Q>(self, mut f: impl FnMut(P) -> Q) -> SerialCircuit<Q> {
348 let phase = f(self.phase);
349 let commands = self
350 .commands
351 .into_iter()
352 .map(|c| c.map_params(&mut f))
353 .collect();
354 SerialCircuit {
355 name: self.name,
356 phase,
357 commands,
358 qubits: self.qubits,
359 bits: self.bits,
360 implicit_permutation: self.implicit_permutation,
361 number_of_ws: self.number_of_ws,
362 number_of_rs: self.number_of_rs,
363 created_qubits: self.created_qubits,
364 discarded_qubits: self.discarded_qubits,
365 }
366 }
367}