phase_rs/circuit_syntax/
term.rs

1//! Circuit-normal terms.
2
3use crate::{
4    circuit_syntax::pattern::PatternC,
5    phase::Phase,
6    typed_syntax::{TermT, TermType},
7};
8
9/// Circuit-normal terms.
10///
11/// These takes the form:
12/// if let q_11 x ... x q_1n then Phase(theta_1) x id(m_1);
13/// ... ;
14/// if let q_l1 x ... x q_ln then Phase(theta_l) x id(m_l)
15#[derive(Clone, Debug, PartialEq)]
16pub struct TermC {
17    pub(crate) clauses: Vec<ClauseC>,
18    pub(crate) ty: TermType,
19}
20
21#[derive(Clone, Debug, PartialEq)]
22pub(crate) struct ClauseC {
23    pub(crate) pattern: PatternC,
24    pub(crate) phase: f64,
25}
26
27impl TermC {
28    /// Return a `TermT` which is the "quotation" of this circuit-normal-form term.
29    /// Realises that all circuit-normal-form terms are also terms.
30    pub fn quote(&self) -> TermT {
31        match self.clauses.len() {
32            0 => TermT::Id(self.ty),
33            1 => self.clauses[0].quote(),
34            _ => TermT::Comp(self.clauses.iter().map(ClauseC::quote).collect()),
35        }
36    }
37}
38
39impl ClauseC {
40    pub(crate) fn quote(&self) -> TermT {
41        let id_qubits = self.pattern.id_qubits();
42        let mut inner = TermT::Phase(Phase::Angle(self.phase));
43        if id_qubits != 0 {
44            inner = TermT::Tensor(vec![inner, TermT::Id(TermType(id_qubits))])
45        }
46
47        TermT::IfLet {
48            pattern: self.pattern.quote(),
49            inner: Box::new(inner),
50        }
51    }
52
53    pub(crate) fn invert(&self) -> ClauseC {
54        ClauseC {
55            pattern: self.pattern.clone(),
56            phase: -self.phase,
57        }
58    }
59}