Skip to main content

ppvm_pauli_word/pattern/
data.rs

1// SPDX-FileCopyrightText: 2026 The PPVM Authors
2// SPDX-License-Identifier: Apache-2.0
3
4// pattern intermediate representation
5
6#[cfg(feature = "bincode")]
7use bincode::{Decode, Encode};
8#[cfg(feature = "serde")]
9use serde::{Deserialize, Serialize};
10
11/// A single-qubit Pauli that is not the identity: `X`, `Y`, or `Z`. Encoded so
12/// the low two bits match [`Pauli`](crate::Pauli) (`X = 1`, `Z = 2`, `Y = 3`),
13/// which lets `From<NotIdentity> for Pauli` be a no-op transmute.
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
15#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
16#[cfg_attr(feature = "bincode", derive(Encode, Decode))]
17#[repr(u8)]
18pub enum NotIdentity {
19    X = 1,
20    Z = 2,
21    Y = 3,
22}
23
24#[derive(Debug, Clone, PartialEq)]
25#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
26#[cfg_attr(feature = "bincode", derive(Encode, Decode))]
27pub(crate) enum OpPattern {
28    Identity,                                   // I
29    Single(NotIdentity),                        // X, Y, Z
30    Double(NotIdentity, NotIdentity),           // [XY]
31    AnyNonIdentity,                             // [XYZ]
32    SingleOrIdentity(NotIdentity),              // X?
33    DoubleOrIdentity(NotIdentity, NotIdentity), // [XY]?
34    AnyPauliOrIdentity,                         // [XYZ]?
35}
36
37impl OpPattern {
38    pub fn add_identity(self) -> Self {
39        match self {
40            OpPattern::Single(not_identity) => OpPattern::SingleOrIdentity(not_identity),
41            OpPattern::Double(left, right) => OpPattern::DoubleOrIdentity(left, right),
42            OpPattern::AnyNonIdentity => OpPattern::AnyPauliOrIdentity,
43            _ => self,
44        }
45    }
46}
47
48#[derive(Debug, Clone, PartialEq)]
49#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
50#[cfg_attr(feature = "bincode", derive(Encode, Decode))]
51pub(crate) enum Decorated {
52    Position(OpPattern, usize), // X1, Y2, Z3
53    Star(OpPattern),            // [XY]*
54    Repeat(OpPattern, usize),   // <OpPattern>{2}
55}
56
57/// A Pauli pattern representing a set of matching Pauli words.
58///
59/// # Example
60/// `[XY]2Z3` represents `X2Z3` or `Y2Z3`.
61/// `Z?` represents any Pauli word with `I` or `Z`.
62#[derive(Debug, Clone, PartialEq)]
63#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
64#[cfg_attr(feature = "bincode", derive(Encode, Decode))]
65pub struct PauliPattern(pub(super) Vec<Decorated>);