qudit_expr/expressions/
named.rs1use itertools::Itertools;
2use qudit_core::RealScalar;
3use serde::{Deserialize, Serialize};
4use std::{
5 collections::HashMap,
6 ops::{Deref, DerefMut},
7};
8
9use crate::ComplexExpression;
10
11#[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
12pub struct ExpressionBody {
13 body: Vec<ComplexExpression>,
14}
15
16impl ExpressionBody {
17 pub fn new(body: Vec<ComplexExpression>) -> Self {
18 Self { body }
19 }
20
21 pub fn num_elements(&self) -> usize {
22 self.body.len()
23 }
24
25 pub fn elements(&self) -> &[ComplexExpression] {
26 &self.body
27 }
28
29 pub fn elements_mut(&mut self) -> &mut [ComplexExpression] {
30 &mut self.body
31 }
32
33 pub fn conjugate(&mut self) {
34 for expr in self.body.iter_mut() {
35 expr.conjugate_in_place()
36 }
37 }
38
39 pub fn apply_element_permutation(&mut self, elem_perm: &[usize]) {
40 let mut swap_vec = vec![];
42 std::mem::swap(&mut swap_vec, &mut self.body);
43 self.body = swap_vec
44 .into_iter()
45 .enumerate()
46 .sorted_by(|(old_idx_a, _), (old_idx_b, _)| {
47 elem_perm[*old_idx_a].cmp(&elem_perm[*old_idx_b])
48 })
49 .map(|(_, expr)| expr)
50 .collect();
51 }
52
53 pub fn rename(&mut self, var_map: HashMap<String, String>) {
54 for elem in self.body.iter_mut() {
55 *elem = elem.map_var_names(&var_map);
56 }
57 }
58}
59
60impl From<Vec<ComplexExpression>> for ExpressionBody {
61 fn from(value: Vec<ComplexExpression>) -> Self {
62 ExpressionBody::new(value)
63 }
64}
65
66impl From<ExpressionBody> for Vec<ComplexExpression> {
67 fn from(value: ExpressionBody) -> Self {
68 value.body
69 }
70}
71
72impl AsRef<[ComplexExpression]> for ExpressionBody {
73 fn as_ref(&self) -> &[ComplexExpression] {
74 self.elements()
75 }
76}
77
78impl Deref for ExpressionBody {
79 type Target = [ComplexExpression];
80
81 fn deref(&self) -> &Self::Target {
82 &self.body
83 }
84}
85
86impl DerefMut for ExpressionBody {
87 fn deref_mut(&mut self) -> &mut Self::Target {
88 &mut self.body
89 }
90}
91
92#[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)]
93pub struct BoundExpressionBody {
94 variables: Vec<String>,
95 body: ExpressionBody,
96}
97
98impl BoundExpressionBody {
99 pub fn new<B: Into<ExpressionBody>>(variables: Vec<String>, body: B) -> Self {
100 Self {
101 variables,
102 body: body.into(),
103 }
104 }
105
106 pub fn num_params(&self) -> usize {
107 self.variables.len()
108 }
109
110 pub fn variables(&self) -> &[String] {
111 &self.variables
112 }
113
114 pub fn set_variables(&mut self, new_variables: Vec<String>) {
115 self.variables = new_variables;
116 }
117
118 pub fn num_elements(&self) -> usize {
119 self.body.num_elements()
120 }
121
122 pub fn elements(&self) -> &[ComplexExpression] {
123 self.body.elements()
124 }
125
126 pub fn elements_mut(&mut self) -> &mut [ComplexExpression] {
127 self.body.elements_mut()
128 }
129
130 pub fn conjugate(&mut self) {
131 self.body.conjugate()
132 }
133
134 pub fn destruct(self) -> (Vec<String>, Vec<ComplexExpression>) {
135 let Self { variables, body } = self;
136 (variables, body.into())
137 }
138
139 pub fn apply_element_permutation(&mut self, elem_perm: &[usize]) {
140 self.body.apply_element_permutation(elem_perm);
141 }
142
143 pub fn alpha_rename(&mut self, starting_number: Option<usize>) {
144 let start = starting_number.unwrap_or_default();
145
146 let mut var_map = HashMap::new();
147 let mut new_vars = Vec::new();
148
149 for (var_id, var) in (start..).zip(self.variables()) {
150 let new_var_name = format!("alpha_{}", var_id);
151 new_vars.push(new_var_name.clone());
152 var_map.insert(var.clone(), new_var_name);
153 }
154
155 self.body.rename(var_map);
156 self.variables = new_vars;
157 }
158
159 pub fn get_arg_map<R: RealScalar>(&self, args: &[R]) -> HashMap<&str, R> {
160 self.variables()
161 .iter()
162 .zip(args.iter())
163 .map(|(a, b)| (a.as_str(), *b))
164 .collect()
165 }
166}
167
168impl AsRef<[ComplexExpression]> for BoundExpressionBody {
169 fn as_ref(&self) -> &[ComplexExpression] {
170 self.elements()
171 }
172}
173
174impl Deref for BoundExpressionBody {
175 type Target = ExpressionBody;
176
177 fn deref(&self) -> &Self::Target {
178 &self.body
179 }
180}
181
182impl DerefMut for BoundExpressionBody {
183 fn deref_mut(&mut self) -> &mut Self::Target {
184 &mut self.body
185 }
186}
187
188#[derive(Debug, Clone, Serialize, Deserialize)]
189pub struct NamedExpression {
190 name: String,
191 body: BoundExpressionBody,
192}
193
194impl NamedExpression {
195 pub fn new<S: Into<String>, B: Into<ExpressionBody>>(
196 name: S,
197 variables: Vec<String>,
198 body: B,
199 ) -> Self {
200 Self {
201 name: name.into(),
202 body: BoundExpressionBody::new(variables, body),
203 }
204 }
205
206 pub fn from_body_with_name(name: String, body: BoundExpressionBody) -> Self {
207 Self { name, body }
208 }
209
210 pub fn name(&self) -> &str {
211 &self.name
212 }
213
214 pub fn set_name(&mut self, new_name: impl Into<String>) {
215 self.name = new_name.into();
216 }
217
218 pub fn set_variables(&mut self, new_variables: Vec<String>) {
219 self.body.set_variables(new_variables);
220 }
221
222 pub fn destruct(self) -> (String, Vec<String>, Vec<ComplexExpression>) {
223 let Self { name, body } = self;
224 let (variables, body) = body.destruct();
225 (name, variables, body)
226 }
227
228 pub fn apply_element_permutation(&mut self, elem_perm: &[usize]) {
229 self.body.apply_element_permutation(elem_perm);
230 }
231}
232
233impl AsRef<[ComplexExpression]> for NamedExpression {
234 fn as_ref(&self) -> &[ComplexExpression] {
235 self.elements()
236 }
237}
238
239impl AsRef<BoundExpressionBody> for NamedExpression {
240 fn as_ref(&self) -> &BoundExpressionBody {
241 &self.body
242 }
243}
244
245impl<B: AsRef<[ComplexExpression]>> PartialEq<B> for NamedExpression {
246 fn eq(&self, other: &B) -> bool {
247 self.elements() == other.as_ref()
248 }
249}
250
251impl Eq for NamedExpression {}
252
253impl Deref for NamedExpression {
254 type Target = BoundExpressionBody;
255
256 fn deref(&self) -> &Self::Target {
257 &self.body
258 }
259}
260
261impl DerefMut for NamedExpression {
262 fn deref_mut(&mut self) -> &mut Self::Target {
263 &mut self.body
264 }
265}