stabilizer_ch_form_rust/circuit/
clifford_gate.rs

1use std::fmt;
2
3/// Represents a Clifford gate in a quantum circuit.
4#[derive(Debug, Clone, PartialEq)]
5pub enum CliffordGate {
6    H(usize),
7    X(usize),
8    Y(usize),
9    Z(usize),
10    S(usize),
11    Sdg(usize),
12    SqrtX(usize),
13    SqrtXdg(usize),
14    CX(usize, usize),
15    CZ(usize, usize),
16    Swap(usize, usize),
17}
18
19impl CliffordGate {
20    /// Returns the QASM 2.0 string representation for this gate.
21    pub fn to_qasm_str(&self, reg_name: &str) -> String {
22        match self {
23            CliffordGate::H(q) => format!("h {}[{}];", reg_name, q),
24            CliffordGate::X(q) => format!("x {}[{}];", reg_name, q),
25            CliffordGate::Y(q) => format!("y {}[{}];", reg_name, q),
26            CliffordGate::Z(q) => format!("z {}[{}];", reg_name, q),
27            CliffordGate::S(q) => format!("s {}[{}];", reg_name, q),
28            CliffordGate::Sdg(q) => format!("sdg {}[{}];", reg_name, q),
29            CliffordGate::SqrtX(q) => format!("sx {}[{}];", reg_name, q),
30            CliffordGate::SqrtXdg(q) => format!("sxdg {}[{}];", reg_name, q),
31            CliffordGate::CX(c, t) => format!("cx {}[{}], {}[{}];", reg_name, c, reg_name, t),
32            CliffordGate::CZ(q1, q2) => format!("cz {}[{}], {}[{}];", reg_name, q1, reg_name, q2),
33            CliffordGate::Swap(q1, q2) => {
34                format!("swap {}[{}], {}[{}];", reg_name, q1, reg_name, q2)
35            }
36        }
37    }
38
39    /// Returns a new `CliffordGate` with qubit indices shifted by the specified offset.
40    pub(crate) fn shifted(&self, offset: usize) -> Self {
41        let mut new_gate = self.clone();
42        match &mut new_gate {
43            CliffordGate::H(q)
44            | CliffordGate::X(q)
45            | CliffordGate::Y(q)
46            | CliffordGate::Z(q)
47            | CliffordGate::S(q)
48            | CliffordGate::Sdg(q)
49            | CliffordGate::SqrtX(q)
50            | CliffordGate::SqrtXdg(q) => {
51                *q += offset;
52            }
53            CliffordGate::CX(c, t) | CliffordGate::CZ(c, t) | CliffordGate::Swap(c, t) => {
54                *c += offset;
55                *t += offset;
56            }
57        }
58        new_gate
59    }
60}
61
62impl fmt::Display for CliffordGate {
63    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64        match self {
65            CliffordGate::H(q) => write!(f, "H({})", q),
66            CliffordGate::X(q) => write!(f, "X({})", q),
67            CliffordGate::Y(q) => write!(f, "Y({})", q),
68            CliffordGate::Z(q) => write!(f, "Z({})", q),
69            CliffordGate::S(q) => write!(f, "S({})", q),
70            CliffordGate::Sdg(q) => write!(f, "Sdg({})", q),
71            CliffordGate::SqrtX(q) => write!(f, "SqrtX({})", q),
72            CliffordGate::SqrtXdg(q) => write!(f, "SqrtXdg({})", q),
73            CliffordGate::CX(c, t) => write!(f, "CX({}, {})", c, t),
74            CliffordGate::CZ(q1, q2) => write!(f, "CZ({}, {})", q1, q2),
75            CliffordGate::Swap(q1, q2) => write!(f, "Swap({}, {})", q1, q2),
76        }
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    use super::*;
83
84    #[test]
85    fn test_clifford_gate_display() {
86        let h_gate = CliffordGate::H(0);
87        assert_eq!(format!("{}", h_gate), "H(0)");
88        let cx_gate = CliffordGate::CX(1, 2);
89        assert_eq!(format!("{}", cx_gate), "CX(1, 2)");
90    }
91
92    #[test]
93    fn test_clifford_gate_to_qasm_str() {
94        let h_gate = CliffordGate::H(0);
95        assert_eq!(h_gate.to_qasm_str("q"), "h q[0];");
96        let cx_gate = CliffordGate::CX(1, 2);
97        assert_eq!(cx_gate.to_qasm_str("q"), "cx q[1], q[2];");
98    }
99}