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}