tket_json_rs/clexpr.rs
1//! Classical expressions
2
3pub mod op;
4pub mod operator;
5
6use operator::ClOperator;
7#[cfg(feature = "schemars")]
8use schemars::JsonSchema;
9use serde::de::SeqAccess;
10use serde::ser::SerializeSeq;
11use serde::{Deserialize, Serialize};
12
13/// Data encoding a classical expression.
14///
15/// A classical expression operates over multi-bit registers and/or individual bits,
16/// each identified by an index local to the expression.
17///
18/// This is included in a [`Operation`] when the operation is a [`OpType::ClExpr`].
19///
20/// [`Operation`]: crate::circuit_json::Operation
21/// [`OpType::ClExpr`]: crate::optype::OpType::ClExpr
22#[cfg_attr(feature = "schemars", derive(JsonSchema))]
23#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize)]
24#[non_exhaustive]
25pub struct ClExpr {
26 /// Mapping between bit variables in the expression and the position of the
27 /// corresponding bit in the `args` list.
28 pub bit_posn: Vec<(u32, u32)>,
29 /// The encoded expression.
30 ///
31 /// This expression may only refer to bits and registers by their id either
32 /// in [`Self::bit_posn`] or [`Self::reg_posn`], respectively.
33 pub expr: ClOperator,
34 /// A list of registers defined over the input bits, with a local
35 /// identifier.
36 ///
37 /// `expr` may contain references to these registers by their
38 /// [`InputClRegister::index`].
39 pub reg_posn: Vec<InputClRegister>,
40 /// The output bits of the expression.
41 ///
42 /// This is a list of bit indices in [`ClExpr::bit_posn`].
43 pub output_posn: ClRegisterBits,
44}
45
46/// An input register for a classical expression.
47///
48/// Contains the input index as well as the bits that are part of the register.
49///
50/// Serialized as a list with two elements: the index and the bits.
51#[cfg_attr(feature = "schemars", derive(JsonSchema))]
52#[derive(Debug, Default, PartialEq, Clone)]
53pub struct InputClRegister {
54 /// The identifier for this register variable in the [`ClExpr::expr`] expression.
55 pub index: u32,
56 /// The sequence of positions of bits comprising the register variable.
57 ///
58 /// The indexes in this sequence refer to the bits in the [`ClExpr::bit_posn`] list.
59 pub bits: ClRegisterBits,
60}
61
62/// The sequence of positions of bits in the output.
63///
64/// The indices here refer to the bit identifiers in the operation's [`ClExpr::bit_posn`].
65///
66/// Registers are little-endian, so the first bit is the least significant.
67#[cfg_attr(feature = "schemars", derive(JsonSchema))]
68#[derive(Debug, Default, PartialEq, Clone, Serialize, Deserialize)]
69#[serde(transparent)]
70pub struct ClRegisterBits(pub Vec<u32>);
71
72impl Serialize for InputClRegister {
73 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
74 let mut seq = serializer.serialize_seq(Some(2))?;
75 seq.serialize_element(&self.index)?;
76 seq.serialize_element(&self.bits)?;
77 seq.end()
78 }
79}
80
81impl<'de> Deserialize<'de> for InputClRegister {
82 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
83 struct Visitor;
84
85 impl<'de_vis> serde::de::Visitor<'de_vis> for Visitor {
86 type Value = InputClRegister;
87
88 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
89 formatter.write_str("a list of two elements: the index and the bits")
90 }
91
92 fn visit_seq<A: SeqAccess<'de_vis>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
93 let index = seq
94 .next_element::<u32>()?
95 .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?;
96 let bits = seq
97 .next_element::<ClRegisterBits>()?
98 .ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;
99 Ok(InputClRegister { index, bits })
100 }
101 }
102
103 deserializer.deserialize_seq(Visitor)
104 }
105}