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}