1use super::argument_expression::ArgumentExpression;
2use super::element_expression::ElementExpression;
3use super::numeric_operator::ReduceOperator;
4use super::reference_expression::ReferenceExpression;
5use super::set_expression::SetExpression;
6use super::vector_expression::VectorExpression;
7use crate::state::StateInterface;
8use crate::state_functions::{StateFunctionCache, StateFunctions};
9use crate::table::{Table1D, Table2D};
10use crate::table_data::TableData;
11use crate::table_registry::TableRegistry;
12use crate::variable_type::{Element, Numeric, Set};
13use num_traits::Num;
14use std::iter::{Product, Sum};
15
16#[derive(Debug, PartialEq, Clone)]
18pub enum NumericTableExpression<T: Numeric> {
19 Constant(T),
21 Table(usize, Vec<ElementExpression>),
23 TableReduce(ReduceOperator, usize, Vec<ArgumentExpression>),
25 Table1D(usize, ElementExpression),
27 Table2D(usize, ElementExpression, ElementExpression),
29 Table3D(
31 usize,
32 ElementExpression,
33 ElementExpression,
34 ElementExpression,
35 ),
36 Table1DReduce(ReduceOperator, usize, SetExpression),
38 Table1DVectorReduce(ReduceOperator, usize, VectorExpression),
40 Table2DReduce(ReduceOperator, usize, SetExpression, SetExpression),
42 Table2DVectorReduce(ReduceOperator, usize, VectorExpression, VectorExpression),
44 Table2DSetVectorReduce(ReduceOperator, usize, SetExpression, VectorExpression),
46 Table2DVectorSetReduce(ReduceOperator, usize, VectorExpression, SetExpression),
48 Table2DReduceX(ReduceOperator, usize, SetExpression, ElementExpression),
50 Table2DReduceY(ReduceOperator, usize, ElementExpression, SetExpression),
52 Table2DVectorReduceX(ReduceOperator, usize, VectorExpression, ElementExpression),
54 Table2DVectorReduceY(ReduceOperator, usize, ElementExpression, VectorExpression),
56 Table3DReduce(
58 ReduceOperator,
59 usize,
60 ArgumentExpression,
61 ArgumentExpression,
62 ArgumentExpression,
63 ),
64}
65
66impl<T: Numeric> NumericTableExpression<T> {
67 pub fn eval<U: StateInterface>(
73 &self,
74 state: &U,
75 function_cache: &mut StateFunctionCache,
76 state_functions: &StateFunctions,
77 registry: &TableRegistry,
78 tables: &TableData<T>,
79 ) -> T {
80 match self {
81 Self::Constant(value) => *value,
82 Self::Table(i, args) => {
83 let args: Vec<Element> = args
84 .iter()
85 .map(|x| x.eval(state, function_cache, state_functions, registry))
86 .collect();
87 tables.tables[*i].eval(&args)
88 }
89 Self::TableReduce(op, i, args) => {
90 let args = ArgumentExpression::eval_args(
91 args.iter(),
92 state,
93 function_cache,
94 state_functions,
95 registry,
96 );
97 op.eval_iter(args.into_iter().map(|args| tables.tables[*i].eval(&args)))
98 .unwrap()
99 }
100 Self::Table1D(i, x) => {
101 tables.tables_1d[*i].eval(x.eval(state, function_cache, state_functions, registry))
102 }
103 Self::Table2D(i, x, y) => tables.tables_2d[*i].eval(
104 x.eval(state, function_cache, state_functions, registry),
105 y.eval(state, function_cache, state_functions, registry),
106 ),
107 Self::Table3D(i, x, y, z) => tables.tables_3d[*i].eval(
108 x.eval(state, function_cache, state_functions, registry),
109 y.eval(state, function_cache, state_functions, registry),
110 z.eval(state, function_cache, state_functions, registry),
111 ),
112 Self::Table1DReduce(op, i, SetExpression::Reference(x)) => Self::reduce_table_1d(
113 op,
114 &tables.tables_1d[*i],
115 x.eval(state, function_cache, state_functions, registry)
116 .ones(),
117 ),
118 Self::Table1DReduce(op, i, SetExpression::StateFunction(x)) => Self::reduce_table_1d(
119 op,
120 &tables.tables_1d[*i],
121 function_cache
122 .get_set_value(*x, state, state_functions, registry)
123 .ones(),
124 ),
125 Self::Table1DReduce(op, i, x) => Self::reduce_table_1d(
126 op,
127 &tables.tables_1d[*i],
128 x.eval(state, function_cache, state_functions, registry)
129 .ones(),
130 ),
131 Self::Table1DVectorReduce(op, i, VectorExpression::Reference(x)) => {
132 Self::reduce_table_1d(
133 op,
134 &tables.tables_1d[*i],
135 x.eval(state, function_cache, state_functions, registry)
136 .iter()
137 .copied(),
138 )
139 }
140 Self::Table1DVectorReduce(op, i, x) => Self::reduce_table_1d(
141 op,
142 &tables.tables_1d[*i],
143 x.eval(state, function_cache, state_functions, registry)
144 .into_iter(),
145 ),
146 Self::Table2DReduce(
147 op,
148 i,
149 SetExpression::StateFunction(x),
150 SetExpression::StateFunction(y),
151 ) => {
152 let (x, y) =
153 function_cache.get_set_value_pair(*x, *y, state, state_functions, registry);
154 Self::reduce_table_2d_set_y(op, &tables.tables_2d[*i], x.ones(), y)
155 }
156 Self::Table2DReduce(
157 op,
158 i,
159 SetExpression::StateFunction(x),
160 SetExpression::Reference(y),
161 ) => {
162 let y = y.eval(state, function_cache, state_functions, registry);
163 let x = function_cache
164 .get_set_value(*x, state, state_functions, registry)
165 .ones();
166 Self::reduce_table_2d_set_y(op, &tables.tables_2d[*i], x, y)
167 }
168 Self::Table2DReduce(
169 op,
170 i,
171 SetExpression::Reference(x),
172 SetExpression::StateFunction(y),
173 ) => {
174 let x = x
175 .eval(state, function_cache, state_functions, registry)
176 .ones();
177 let y = function_cache.get_set_value(*y, state, state_functions, registry);
178 Self::reduce_table_2d_set_y(op, &tables.tables_2d[*i], x, y)
179 }
180 Self::Table2DReduce(op, i, SetExpression::StateFunction(x), y) => {
181 let y = y.eval(state, function_cache, state_functions, registry);
182 let x = function_cache
183 .get_set_value(*x, state, state_functions, registry)
184 .ones();
185 Self::reduce_table_2d_set_y(op, &tables.tables_2d[*i], x, &y)
186 }
187 Self::Table2DReduce(op, i, x, SetExpression::StateFunction(y)) => {
188 let x = x.eval(state, function_cache, state_functions, registry);
189 let y = function_cache.get_set_value(*y, state, state_functions, registry);
190 Self::reduce_table_2d_set_y(op, &tables.tables_2d[*i], x.ones(), y)
191 }
192 Self::Table2DReduce(
193 op,
194 i,
195 SetExpression::Reference(x),
196 SetExpression::Reference(y),
197 ) => {
198 let x = x
199 .eval(state, function_cache, state_functions, registry)
200 .ones();
201 let y = y.eval(state, function_cache, state_functions, registry);
202 Self::reduce_table_2d_set_y(op, &tables.tables_2d[*i], x, y)
203 }
204 Self::Table2DReduce(op, i, SetExpression::Reference(x), y) => {
205 let y = y.eval(state, function_cache, state_functions, registry);
206 let x = x
207 .eval(state, function_cache, state_functions, registry)
208 .ones();
209 Self::reduce_table_2d_set_y(op, &tables.tables_2d[*i], x, &y)
210 }
211 Self::Table2DReduce(op, i, x, SetExpression::Reference(y)) => {
212 let x = x.eval(state, function_cache, state_functions, registry);
213 let y = y.eval(state, function_cache, state_functions, registry);
214 Self::reduce_table_2d_set_x(op, &tables.tables_2d[*i], &x, y.ones())
215 }
216 Self::Table2DReduce(op, i, x, y) => {
217 let y = y.eval(state, function_cache, state_functions, registry);
218 Self::reduce_table_2d_set_y(
219 op,
220 &tables.tables_2d[*i],
221 x.eval(state, function_cache, state_functions, registry)
222 .ones(),
223 &y,
224 )
225 }
226 Self::Table2DVectorReduce(
227 op,
228 i,
229 VectorExpression::Reference(x),
230 VectorExpression::Reference(y),
231 ) => {
232 let x = x
233 .eval(state, function_cache, state_functions, registry)
234 .iter()
235 .copied();
236 let y = y
237 .eval(state, function_cache, state_functions, registry)
238 .iter()
239 .copied();
240 Self::reduce_table_2d(op, &tables.tables_2d[*i], x, y)
241 }
242 Self::Table2DVectorReduce(op, i, VectorExpression::Reference(x), y) => {
243 let x = x
244 .eval(state, function_cache, state_functions, registry)
245 .iter()
246 .copied();
247 let y = y
248 .eval(state, function_cache, state_functions, registry)
249 .into_iter();
250 Self::reduce_table_2d(op, &tables.tables_2d[*i], x, y)
251 }
252 Self::Table2DVectorReduce(op, i, x, VectorExpression::Reference(y)) => {
253 let x = x
254 .eval(state, function_cache, state_functions, registry)
255 .into_iter();
256 let y = y
257 .eval(state, function_cache, state_functions, registry)
258 .iter()
259 .copied();
260 Self::reduce_table_2d(op, &tables.tables_2d[*i], x, y)
261 }
262 Self::Table2DVectorReduce(op, i, x, y) => {
263 let x = x
264 .eval(state, function_cache, state_functions, registry)
265 .into_iter();
266 let y = y
267 .eval(state, function_cache, state_functions, registry)
268 .into_iter();
269 Self::reduce_table_2d(op, &tables.tables_2d[*i], x, y)
270 }
271 Self::Table2DSetVectorReduce(
272 op,
273 i,
274 SetExpression::Reference(x),
275 VectorExpression::Reference(y),
276 ) => {
277 let y = y
278 .eval(state, function_cache, state_functions, registry)
279 .iter()
280 .copied();
281 let x = x
282 .eval(state, function_cache, state_functions, registry)
283 .ones();
284 Self::reduce_table_2d(op, &tables.tables_2d[*i], x, y)
285 }
286 Self::Table2DSetVectorReduce(op, i, SetExpression::Reference(x), y) => {
287 let y = y
288 .eval(state, function_cache, state_functions, registry)
289 .into_iter();
290 Self::reduce_table_2d(
291 op,
292 &tables.tables_2d[*i],
293 x.eval(state, function_cache, state_functions, registry)
294 .ones(),
295 y,
296 )
297 }
298 Self::Table2DSetVectorReduce(op, i, x, VectorExpression::Reference(y)) => {
299 let y = y
300 .eval(state, function_cache, state_functions, registry)
301 .iter()
302 .copied();
303 Self::reduce_table_2d(
304 op,
305 &tables.tables_2d[*i],
306 x.eval(state, function_cache, state_functions, registry)
307 .ones(),
308 y,
309 )
310 }
311 Self::Table2DSetVectorReduce(op, i, x, y) => {
312 let y = y
313 .eval(state, function_cache, state_functions, registry)
314 .into_iter();
315 Self::reduce_table_2d(
316 op,
317 &tables.tables_2d[*i],
318 x.eval(state, function_cache, state_functions, registry)
319 .ones(),
320 y,
321 )
322 }
323 Self::Table2DVectorSetReduce(
324 op,
325 i,
326 VectorExpression::Reference(x),
327 SetExpression::Reference(y),
328 ) => {
329 let x = x
330 .eval(state, function_cache, state_functions, registry)
331 .iter()
332 .copied();
333 let y = y.eval(state, function_cache, state_functions, registry);
334 Self::reduce_table_2d_set_y(op, &tables.tables_2d[*i], x, y)
335 }
336 Self::Table2DVectorSetReduce(op, i, x, SetExpression::Reference(y)) => {
337 let x = x
338 .eval(state, function_cache, state_functions, registry)
339 .into_iter();
340 let y = y.eval(state, function_cache, state_functions, registry);
341 Self::reduce_table_2d_set_y(op, &tables.tables_2d[*i], x, y)
342 }
343 Self::Table2DVectorSetReduce(op, i, VectorExpression::Reference(x), y) => {
344 let x = x
345 .eval(state, function_cache, state_functions, registry)
346 .iter()
347 .copied();
348 let y = y.eval(state, function_cache, state_functions, registry);
349 Self::reduce_table_2d_set_y(op, &tables.tables_2d[*i], x, &y)
350 }
351 Self::Table2DVectorSetReduce(op, i, x, y) => {
352 let x = x
353 .eval(state, function_cache, state_functions, registry)
354 .into_iter();
355 let y = y.eval(state, function_cache, state_functions, registry);
356 Self::reduce_table_2d_set_y(op, &tables.tables_2d[*i], x, &y)
357 }
358 Self::Table2DReduceX(op, i, SetExpression::Reference(x), y) => {
359 let y = y.eval(state, function_cache, state_functions, registry);
360 let x = x
361 .eval(state, function_cache, state_functions, registry)
362 .ones();
363 Self::reduce_table_2d_x(op, &tables.tables_2d[*i], x, y)
364 }
365 Self::Table2DReduceX(op, i, x, y) => {
366 let y = y.eval(state, function_cache, state_functions, registry);
367 Self::reduce_table_2d_x(
368 op,
369 &tables.tables_2d[*i],
370 x.eval(state, function_cache, state_functions, registry)
371 .ones(),
372 y,
373 )
374 }
375 Self::Table2DReduceY(op, i, x, SetExpression::Reference(y)) => {
376 let x = x.eval(state, function_cache, state_functions, registry);
377 let y = y
378 .eval(state, function_cache, state_functions, registry)
379 .ones();
380 Self::reduce_table_2d_y(op, &tables.tables_2d[*i], x, y)
381 }
382 Self::Table2DReduceY(op, i, x, y) => {
383 let x = x.eval(state, function_cache, state_functions, registry);
384 Self::reduce_table_2d_y(
385 op,
386 &tables.tables_2d[*i],
387 x,
388 y.eval(state, function_cache, state_functions, registry)
389 .ones(),
390 )
391 }
392 Self::Table2DVectorReduceX(op, i, VectorExpression::Reference(x), y) => {
393 let x = x
394 .eval(state, function_cache, state_functions, registry)
395 .iter()
396 .copied();
397 let y = y.eval(state, function_cache, state_functions, registry);
398 Self::reduce_table_2d_x(op, &tables.tables_2d[*i], x, y)
399 }
400 Self::Table2DVectorReduceX(op, i, x, y) => {
401 let x = x
402 .eval(state, function_cache, state_functions, registry)
403 .into_iter();
404 let y = y.eval(state, function_cache, state_functions, registry);
405 Self::reduce_table_2d_x(op, &tables.tables_2d[*i], x, y)
406 }
407 Self::Table2DVectorReduceY(op, i, x, VectorExpression::Reference(y)) => {
408 let x = x.eval(state, function_cache, state_functions, registry);
409 let y = y
410 .eval(state, function_cache, state_functions, registry)
411 .iter()
412 .copied();
413 Self::reduce_table_2d_y(op, &tables.tables_2d[*i], x, y)
414 }
415 Self::Table2DVectorReduceY(op, i, x, y) => {
416 let x = x.eval(state, function_cache, state_functions, registry);
417 let y = y
418 .eval(state, function_cache, state_functions, registry)
419 .into_iter();
420 Self::reduce_table_2d_y(op, &tables.tables_2d[*i], x, y)
421 }
422 Self::Table3DReduce(op, i, x, y, z) => {
423 let args = ArgumentExpression::eval_args(
424 [x, y, z].into_iter(),
425 state,
426 function_cache,
427 state_functions,
428 registry,
429 );
430 op.eval_iter(
431 args.into_iter()
432 .map(|args| tables.tables_3d[*i].eval(args[0], args[1], args[2])),
433 )
434 .unwrap()
435 }
436 }
437 }
438
439 pub fn simplify(
445 &self,
446 registry: &TableRegistry,
447 tables: &TableData<T>,
448 ) -> NumericTableExpression<T> {
449 match self {
450 Self::Table(i, args) => {
451 let args: Vec<ElementExpression> =
452 args.iter().map(|x| x.simplify(registry)).collect();
453 let mut simplified_args = Vec::with_capacity(args.len());
454 for arg in &args {
455 match arg {
456 ElementExpression::Constant(arg) => {
457 simplified_args.push(*arg);
458 }
459 _ => return Self::Table(*i, args),
460 }
461 }
462 Self::Constant(tables.tables[*i].eval(&simplified_args))
463 }
464 Self::TableReduce(op, i, args) => {
465 let args: Vec<ArgumentExpression> =
466 args.iter().map(|x| x.simplify(registry)).collect();
467 if let Some(args) = ArgumentExpression::simplify_args(args.iter()) {
468 Self::Constant(
469 op.eval_iter(args.into_iter().map(|args| tables.tables[*i].eval(&args)))
470 .unwrap(),
471 )
472 } else {
473 Self::TableReduce(op.clone(), *i, args)
474 }
475 }
476 Self::Table1D(i, x) => match x.simplify(registry) {
477 ElementExpression::Constant(x) => Self::Constant(tables.tables_1d[*i].eval(x)),
478 x => Self::Table1D(*i, x),
479 },
480 Self::Table2D(i, x, y) => match (x.simplify(registry), y.simplify(registry)) {
481 (ElementExpression::Constant(x), ElementExpression::Constant(y)) => {
482 Self::Constant(tables.tables_2d[*i].eval(x, y))
483 }
484 (x, y) => Self::Table2D(*i, x, y),
485 },
486 Self::Table3D(i, x, y, z) => match (
487 x.simplify(registry),
488 y.simplify(registry),
489 z.simplify(registry),
490 ) {
491 (
492 ElementExpression::Constant(x),
493 ElementExpression::Constant(y),
494 ElementExpression::Constant(z),
495 ) => Self::Constant(tables.tables_3d[*i].eval(x, y, z)),
496 (x, y, z) => Self::Table3D(*i, x, y, z),
497 },
498 Self::Table1DReduce(op, i, x) => match x.simplify(registry) {
499 SetExpression::Reference(ReferenceExpression::Constant(x)) => {
500 Self::Constant(Self::reduce_table_1d(op, &tables.tables_1d[*i], x.ones()))
501 }
502 x => Self::Table1DReduce(op.clone(), *i, x),
503 },
504 Self::Table1DVectorReduce(op, i, x) => match x.simplify(registry) {
505 VectorExpression::Reference(ReferenceExpression::Constant(x)) => Self::Constant(
506 Self::reduce_table_1d(op, &tables.tables_1d[*i], x.into_iter()),
507 ),
508 x => Self::Table1DVectorReduce(op.clone(), *i, x),
509 },
510 Self::Table2DReduce(op, i, x, y) => {
511 match (x.simplify(registry), y.simplify(registry)) {
512 (
513 SetExpression::Reference(ReferenceExpression::Constant(x)),
514 SetExpression::Reference(ReferenceExpression::Constant(y)),
515 ) => Self::Constant(Self::reduce_table_2d_set_y(
516 op,
517 &tables.tables_2d[*i],
518 x.ones(),
519 &y,
520 )),
521 (x, y) => Self::Table2DReduce(op.clone(), *i, x, y),
522 }
523 }
524 Self::Table2DVectorReduce(op, i, x, y) => {
525 match (x.simplify(registry), y.simplify(registry)) {
526 (
527 VectorExpression::Reference(ReferenceExpression::Constant(x)),
528 VectorExpression::Reference(ReferenceExpression::Constant(y)),
529 ) => Self::Constant(Self::reduce_table_2d(
530 op,
531 &tables.tables_2d[*i],
532 x.into_iter(),
533 y.into_iter(),
534 )),
535 (x, y) => Self::Table2DVectorReduce(op.clone(), *i, x, y),
536 }
537 }
538 Self::Table2DSetVectorReduce(op, i, x, y) => {
539 match (x.simplify(registry), y.simplify(registry)) {
540 (
541 SetExpression::Reference(ReferenceExpression::Constant(x)),
542 VectorExpression::Reference(ReferenceExpression::Constant(y)),
543 ) => Self::Constant(Self::reduce_table_2d(
544 op,
545 &tables.tables_2d[*i],
546 x.ones(),
547 y.into_iter(),
548 )),
549 (x, y) => Self::Table2DSetVectorReduce(op.clone(), *i, x, y),
550 }
551 }
552 Self::Table2DVectorSetReduce(op, i, x, y) => {
553 match (x.simplify(registry), y.simplify(registry)) {
554 (
555 VectorExpression::Reference(ReferenceExpression::Constant(x)),
556 SetExpression::Reference(ReferenceExpression::Constant(y)),
557 ) => Self::Constant(Self::reduce_table_2d_set_y(
558 op,
559 &tables.tables_2d[*i],
560 x.into_iter(),
561 &y,
562 )),
563 (x, y) => Self::Table2DVectorSetReduce(op.clone(), *i, x, y),
564 }
565 }
566 Self::Table2DReduceX(op, i, x, y) => match (x.simplify(registry), y.simplify(registry))
567 {
568 (
569 SetExpression::Reference(ReferenceExpression::Constant(x)),
570 ElementExpression::Constant(y),
571 ) => Self::Constant(Self::reduce_table_2d_x(
572 op,
573 &tables.tables_2d[*i],
574 x.ones(),
575 y,
576 )),
577 (x, y) => Self::Table2DReduceX(op.clone(), *i, x, y),
578 },
579 Self::Table2DReduceY(op, i, x, y) => match (x.simplify(registry), y.simplify(registry))
580 {
581 (
582 ElementExpression::Constant(x),
583 SetExpression::Reference(ReferenceExpression::Constant(y)),
584 ) => Self::Constant(Self::reduce_table_2d_y(
585 op,
586 &tables.tables_2d[*i],
587 x,
588 y.ones(),
589 )),
590 (x, y) => Self::Table2DReduceY(op.clone(), *i, x, y),
591 },
592 Self::Table2DVectorReduceX(op, i, x, y) => {
593 match (x.simplify(registry), y.simplify(registry)) {
594 (
595 VectorExpression::Reference(ReferenceExpression::Constant(x)),
596 ElementExpression::Constant(y),
597 ) => Self::Constant(Self::reduce_table_2d_x(
598 op,
599 &tables.tables_2d[*i],
600 x.into_iter(),
601 y,
602 )),
603 (x, y) => Self::Table2DVectorReduceX(op.clone(), *i, x, y),
604 }
605 }
606 Self::Table2DVectorReduceY(op, i, x, y) => {
607 match (x.simplify(registry), y.simplify(registry)) {
608 (
609 ElementExpression::Constant(x),
610 VectorExpression::Reference(ReferenceExpression::Constant(y)),
611 ) => Self::Constant(Self::reduce_table_2d_y(
612 op,
613 &tables.tables_2d[*i],
614 x,
615 y.into_iter(),
616 )),
617 (x, y) => Self::Table2DVectorReduceY(op.clone(), *i, x, y),
618 }
619 }
620 Self::Table3DReduce(op, i, x, y, z) => {
621 let x = x.simplify(registry);
622 let y = y.simplify(registry);
623 let z = z.simplify(registry);
624 if let Some(args) = ArgumentExpression::simplify_args([&x, &y, &z].into_iter()) {
625 Self::Constant(
626 op.eval_iter(
627 args.into_iter()
628 .map(|args| tables.tables_3d[*i].eval(args[0], args[1], args[2])),
629 )
630 .unwrap(),
631 )
632 } else {
633 Self::Table3DReduce(op.clone(), *i, x, y, z)
634 }
635 }
636 _ => self.clone(),
637 }
638 }
639
640 fn reduce_table_1d<I>(op: &ReduceOperator, table: &Table1D<T>, x: I) -> T
641 where
642 T: Num + PartialOrd + Sum + Product,
643 I: Iterator<Item = Element>,
644 {
645 op.eval_iter(x.map(|x| table.eval(x))).unwrap()
646 }
647
648 fn reduce_table_2d<I, J>(op: &ReduceOperator, table: &Table2D<T>, x: I, y: J) -> T
649 where
650 T: Num + PartialOrd + Sum + Product,
651 I: Iterator<Item = Element>,
652 J: Iterator<Item = Element> + Clone,
653 {
654 op.eval_iter(x.map(|x| op.eval_iter(y.clone().map(|y| table.eval(x, y))).unwrap()))
655 .unwrap()
656 }
657
658 fn reduce_table_2d_set_x<I>(op: &ReduceOperator, table: &Table2D<T>, x: &Set, y: I) -> T
659 where
660 T: Num + PartialOrd + Sum + Product,
661 I: Iterator<Item = Element>,
662 {
663 op.eval_iter(y.map(|y| op.eval_iter(x.ones().map(|x| table.eval(x, y))).unwrap()))
664 .unwrap()
665 }
666
667 fn reduce_table_2d_set_y<I>(op: &ReduceOperator, table: &Table2D<T>, x: I, y: &Set) -> T
668 where
669 T: Num + PartialOrd + Sum + Product,
670 I: Iterator<Item = Element>,
671 {
672 op.eval_iter(x.map(|x| op.eval_iter(y.ones().map(|y| table.eval(x, y))).unwrap()))
673 .unwrap()
674 }
675
676 fn reduce_table_2d_x<I>(op: &ReduceOperator, table: &Table2D<T>, x: I, y: Element) -> T
677 where
678 T: Num + PartialOrd + Sum + Product,
679 I: Iterator<Item = Element>,
680 {
681 op.eval_iter(x.map(|x| table.eval(x, y))).unwrap()
682 }
683
684 fn reduce_table_2d_y<I>(op: &ReduceOperator, table: &Table2D<T>, x: Element, y: I) -> T
685 where
686 T: Num + PartialOrd + Sum + Product,
687 I: Iterator<Item = Element>,
688 {
689 op.eval_iter(y.map(|y| table.eval(x, y))).unwrap()
690 }
691}
692
693#[cfg(test)]
694mod tests {
695 use super::super::set_expression::SetElementOperation;
696 use super::*;
697 use crate::state::*;
698 use crate::table;
699 use crate::table_data::TableInterface;
700 use rustc_hash::FxHashMap;
701
702 fn generate_registry() -> TableRegistry {
703 let mut name_to_constant = FxHashMap::default();
704 name_to_constant.insert(String::from("f0"), 0);
705
706 let tables_1d = vec![table::Table1D::new(vec![10, 20, 30])];
707 let mut name_to_table_1d = FxHashMap::default();
708 name_to_table_1d.insert(String::from("f1"), 0);
709
710 let tables_2d = vec![table::Table2D::new(vec![
711 vec![10, 20, 30],
712 vec![40, 50, 60],
713 vec![70, 80, 90],
714 ])];
715 let mut name_to_table_2d = FxHashMap::default();
716 name_to_table_2d.insert(String::from("f2"), 0);
717
718 let tables_3d = vec![table::Table3D::new(vec![
719 vec![vec![10, 20, 30], vec![40, 50, 60], vec![70, 80, 90]],
720 vec![vec![10, 20, 30], vec![40, 50, 60], vec![70, 80, 90]],
721 vec![vec![10, 20, 30], vec![40, 50, 60], vec![70, 80, 90]],
722 ])];
723 let mut name_to_table_3d = FxHashMap::default();
724 name_to_table_3d.insert(String::from("f3"), 0);
725
726 let mut map = FxHashMap::default();
727 let key = vec![0, 1, 0, 0];
728 map.insert(key, 100);
729 let key = vec![0, 1, 0, 1];
730 map.insert(key, 200);
731 let key = vec![0, 1, 2, 0];
732 map.insert(key, 300);
733 let key = vec![0, 1, 2, 1];
734 map.insert(key, 400);
735 let tables = vec![table::Table::new(map, 0)];
736 let mut name_to_table = FxHashMap::default();
737 name_to_table.insert(String::from("f4"), 0);
738
739 TableRegistry {
740 integer_tables: TableData {
741 name_to_constant,
742 tables_1d,
743 name_to_table_1d,
744 tables_2d,
745 name_to_table_2d,
746 tables_3d,
747 name_to_table_3d,
748 tables,
749 name_to_table,
750 },
751 ..Default::default()
752 }
753 }
754
755 fn generate_state() -> State {
756 let mut set1 = Set::with_capacity(3);
757 set1.insert(0);
758 set1.insert(2);
759 let mut set2 = Set::with_capacity(3);
760 set2.insert(0);
761 set2.insert(1);
762 State {
763 signature_variables: SignatureVariables {
764 set_variables: vec![set1, set2, Set::with_capacity(3), Set::with_capacity(3)],
765 vector_variables: vec![vec![0, 2], vec![0, 1], vec![], vec![]],
766 ..Default::default()
767 },
768 ..Default::default()
769 }
770 }
771
772 #[test]
773 fn constant_eval() {
774 let registry = generate_registry();
775 let state_functions = StateFunctions::default();
776 let mut function_cache = StateFunctionCache::new(&state_functions);
777 let state = generate_state();
778 let expression = NumericTableExpression::Constant(10);
779 assert_eq!(
780 expression.eval(
781 &state,
782 &mut function_cache,
783 &state_functions,
784 ®istry,
785 ®istry.integer_tables
786 ),
787 10
788 );
789 }
790
791 #[test]
792 fn table_1d_eval() {
793 let registry = generate_registry();
794 let state = generate_state();
795 let state_functions = StateFunctions::default();
796 let mut function_cache = StateFunctionCache::new(&state_functions);
797 let expression = NumericTableExpression::Table1D(0, ElementExpression::Constant(0));
798 assert_eq!(
799 expression.eval(
800 &state,
801 &mut function_cache,
802 &state_functions,
803 ®istry,
804 ®istry.integer_tables
805 ),
806 10
807 );
808 let expression = NumericTableExpression::Table1D(0, ElementExpression::Constant(1));
809 assert_eq!(
810 expression.eval(
811 &state,
812 &mut function_cache,
813 &state_functions,
814 ®istry,
815 ®istry.integer_tables
816 ),
817 20
818 );
819 let expression = NumericTableExpression::Table1D(0, ElementExpression::Constant(2));
820 assert_eq!(
821 expression.eval(
822 &state,
823 &mut function_cache,
824 &state_functions,
825 ®istry,
826 ®istry.integer_tables
827 ),
828 30
829 );
830 }
831
832 #[test]
833 fn table_1d_sum_eval() {
834 let registry = generate_registry();
835 let state = generate_state();
836 let state_functions = StateFunctions::default();
837 let mut function_cache = StateFunctionCache::new(&state_functions);
838 let expression = NumericTableExpression::Table1DReduce(
839 ReduceOperator::Sum,
840 0,
841 SetExpression::Reference(ReferenceExpression::Variable(0)),
842 );
843 assert_eq!(
844 expression.eval(
845 &state,
846 &mut function_cache,
847 &state_functions,
848 ®istry,
849 ®istry.integer_tables
850 ),
851 40
852 );
853 let expression = NumericTableExpression::Table1DReduce(
854 ReduceOperator::Sum,
855 0,
856 SetExpression::Reference(ReferenceExpression::Variable(1)),
857 );
858 assert_eq!(
859 expression.eval(
860 &state,
861 &mut function_cache,
862 &state_functions,
863 ®istry,
864 ®istry.integer_tables
865 ),
866 30
867 );
868 let expression = NumericTableExpression::Table1DReduce(
869 ReduceOperator::Sum,
870 0,
871 SetExpression::Complement(Box::new(SetExpression::Reference(
872 ReferenceExpression::Variable(0),
873 ))),
874 );
875 assert_eq!(
876 expression.eval(
877 &state,
878 &mut function_cache,
879 &state_functions,
880 ®istry,
881 ®istry.integer_tables
882 ),
883 20
884 );
885 }
886
887 #[test]
888 fn table_1d_vector_sum_eval() {
889 let registry = generate_registry();
890 let state = generate_state();
891 let state_functions = StateFunctions::default();
892 let mut function_cache = StateFunctionCache::new(&state_functions);
893 let expression = NumericTableExpression::Table1DVectorReduce(
894 ReduceOperator::Sum,
895 0,
896 VectorExpression::Reference(ReferenceExpression::Variable(0)),
897 );
898 assert_eq!(
899 expression.eval(
900 &state,
901 &mut function_cache,
902 &state_functions,
903 ®istry,
904 ®istry.integer_tables
905 ),
906 40
907 );
908 let expression = NumericTableExpression::Table1DVectorReduce(
909 ReduceOperator::Sum,
910 0,
911 VectorExpression::Reverse(Box::new(VectorExpression::Reference(
912 ReferenceExpression::Variable(0),
913 ))),
914 );
915 assert_eq!(
916 expression.eval(
917 &state,
918 &mut function_cache,
919 &state_functions,
920 ®istry,
921 ®istry.integer_tables
922 ),
923 40
924 );
925 }
926
927 #[test]
928 fn table_1d_set_state_function_reduce_eval() {
929 let mut state_metadata = StateMetadata::default();
930 let ob = state_metadata.add_object_type("ob", 3);
931 assert!(ob.is_ok());
932 let ob = ob.unwrap();
933 let v = state_metadata.add_set_variable("v", ob);
934 assert!(v.is_ok());
935 let v = v.unwrap();
936
937 let mut state_functions = StateFunctions::default();
938 let f = state_functions.add_set_function("f", v.add(0).add(1));
939 assert!(f.is_ok());
940 let f = f.unwrap();
941
942 let mut registry = TableRegistry::default();
943 let t = registry.add_table_1d("t", vec![1, 2]);
944 assert!(t.is_ok());
945 let t = t.unwrap();
946
947 let state = State {
948 signature_variables: SignatureVariables {
949 set_variables: vec![Set::with_capacity(3)],
950 ..Default::default()
951 },
952 ..Default::default()
953 };
954
955 let expression = NumericTableExpression::Table1DReduce(ReduceOperator::Sum, t.id(), f);
956
957 assert_eq!(
958 expression.eval(
959 &state,
960 &mut StateFunctionCache::new(&state_functions),
961 &state_functions,
962 ®istry,
963 ®istry.integer_tables,
964 ),
965 3,
966 );
967 }
968
969 #[test]
970 fn table_2d_eval() {
971 let registry = generate_registry();
972 let state = generate_state();
973 let state_functions = StateFunctions::default();
974 let mut function_cache = StateFunctionCache::new(&state_functions);
975 let expression = NumericTableExpression::Table2D(
976 0,
977 ElementExpression::Constant(0),
978 ElementExpression::Constant(1),
979 );
980 assert_eq!(
981 expression.eval(
982 &state,
983 &mut function_cache,
984 &state_functions,
985 ®istry,
986 ®istry.integer_tables
987 ),
988 20
989 );
990 }
991
992 #[test]
993 fn table_2d_sum_eval() {
994 let registry = generate_registry();
995 let state = generate_state();
996 let state_functions = StateFunctions::default();
997 let mut function_cache = StateFunctionCache::new(&state_functions);
998
999 let expression = NumericTableExpression::Table2DReduce(
1000 ReduceOperator::Sum,
1001 0,
1002 SetExpression::Reference(ReferenceExpression::Variable(0)),
1003 SetExpression::Reference(ReferenceExpression::Variable(1)),
1004 );
1005 assert_eq!(
1006 expression.eval(
1007 &state,
1008 &mut function_cache,
1009 &state_functions,
1010 ®istry,
1011 ®istry.integer_tables
1012 ),
1013 180
1014 );
1015
1016 let expression = NumericTableExpression::Table2DReduce(
1017 ReduceOperator::Sum,
1018 0,
1019 SetExpression::Reference(ReferenceExpression::Variable(0)),
1020 SetExpression::Complement(Box::new(SetExpression::Complement(Box::new(
1021 SetExpression::Reference(ReferenceExpression::Variable(1)),
1022 )))),
1023 );
1024 assert_eq!(
1025 expression.eval(
1026 &state,
1027 &mut function_cache,
1028 &state_functions,
1029 ®istry,
1030 ®istry.integer_tables
1031 ),
1032 180
1033 );
1034
1035 let expression = NumericTableExpression::Table2DReduce(
1036 ReduceOperator::Sum,
1037 0,
1038 SetExpression::Complement(Box::new(SetExpression::Complement(Box::new(
1039 SetExpression::Reference(ReferenceExpression::Variable(0)),
1040 )))),
1041 SetExpression::Reference(ReferenceExpression::Variable(1)),
1042 );
1043 assert_eq!(
1044 expression.eval(
1045 &state,
1046 &mut function_cache,
1047 &state_functions,
1048 ®istry,
1049 ®istry.integer_tables
1050 ),
1051 180
1052 );
1053
1054 let expression = NumericTableExpression::Table2DReduce(
1055 ReduceOperator::Sum,
1056 0,
1057 SetExpression::Complement(Box::new(SetExpression::Complement(Box::new(
1058 SetExpression::Reference(ReferenceExpression::Variable(0)),
1059 )))),
1060 SetExpression::Complement(Box::new(SetExpression::Complement(Box::new(
1061 SetExpression::Reference(ReferenceExpression::Variable(1)),
1062 )))),
1063 );
1064 assert_eq!(
1065 expression.eval(
1066 &state,
1067 &mut function_cache,
1068 &state_functions,
1069 ®istry,
1070 ®istry.integer_tables
1071 ),
1072 180
1073 );
1074 }
1075
1076 #[test]
1077 fn table_2d_vector_sum_eval() {
1078 let registry = generate_registry();
1079 let state = generate_state();
1080 let state_functions = StateFunctions::default();
1081 let mut function_cache = StateFunctionCache::new(&state_functions);
1082
1083 let expression = NumericTableExpression::Table2DVectorReduce(
1084 ReduceOperator::Sum,
1085 0,
1086 VectorExpression::Reference(ReferenceExpression::Variable(0)),
1087 VectorExpression::Reference(ReferenceExpression::Variable(1)),
1088 );
1089 assert_eq!(
1090 expression.eval(
1091 &state,
1092 &mut function_cache,
1093 &state_functions,
1094 ®istry,
1095 ®istry.integer_tables
1096 ),
1097 180
1098 );
1099
1100 let expression = NumericTableExpression::Table2DVectorReduce(
1101 ReduceOperator::Sum,
1102 0,
1103 VectorExpression::Reference(ReferenceExpression::Variable(0)),
1104 VectorExpression::Reverse(Box::new(VectorExpression::Reference(
1105 ReferenceExpression::Variable(1),
1106 ))),
1107 );
1108 assert_eq!(
1109 expression.eval(
1110 &state,
1111 &mut function_cache,
1112 &state_functions,
1113 ®istry,
1114 ®istry.integer_tables
1115 ),
1116 180
1117 );
1118
1119 let expression = NumericTableExpression::Table2DVectorReduce(
1120 ReduceOperator::Sum,
1121 0,
1122 VectorExpression::Reverse(Box::new(VectorExpression::Reference(
1123 ReferenceExpression::Variable(0),
1124 ))),
1125 VectorExpression::Reference(ReferenceExpression::Variable(1)),
1126 );
1127 assert_eq!(
1128 expression.eval(
1129 &state,
1130 &mut function_cache,
1131 &state_functions,
1132 ®istry,
1133 ®istry.integer_tables
1134 ),
1135 180
1136 );
1137
1138 let expression = NumericTableExpression::Table2DVectorReduce(
1139 ReduceOperator::Sum,
1140 0,
1141 VectorExpression::Reverse(Box::new(VectorExpression::Reference(
1142 ReferenceExpression::Variable(0),
1143 ))),
1144 VectorExpression::Reverse(Box::new(VectorExpression::Reference(
1145 ReferenceExpression::Variable(1),
1146 ))),
1147 );
1148 assert_eq!(
1149 expression.eval(
1150 &state,
1151 &mut function_cache,
1152 &state_functions,
1153 ®istry,
1154 ®istry.integer_tables
1155 ),
1156 180
1157 );
1158 }
1159
1160 #[test]
1161 fn table_2d_set_vector_sum_eval() {
1162 let registry = generate_registry();
1163 let state = generate_state();
1164 let state_functions = StateFunctions::default();
1165 let mut function_cache = StateFunctionCache::new(&state_functions);
1166
1167 let expression = NumericTableExpression::Table2DSetVectorReduce(
1168 ReduceOperator::Sum,
1169 0,
1170 SetExpression::Reference(ReferenceExpression::Variable(0)),
1171 VectorExpression::Reference(ReferenceExpression::Variable(1)),
1172 );
1173 assert_eq!(
1174 expression.eval(
1175 &state,
1176 &mut function_cache,
1177 &state_functions,
1178 ®istry,
1179 ®istry.integer_tables
1180 ),
1181 180
1182 );
1183
1184 let expression = NumericTableExpression::Table2DSetVectorReduce(
1185 ReduceOperator::Sum,
1186 0,
1187 SetExpression::Reference(ReferenceExpression::Variable(0)),
1188 VectorExpression::Reverse(Box::new(VectorExpression::Reference(
1189 ReferenceExpression::Variable(1),
1190 ))),
1191 );
1192 assert_eq!(
1193 expression.eval(
1194 &state,
1195 &mut function_cache,
1196 &state_functions,
1197 ®istry,
1198 ®istry.integer_tables
1199 ),
1200 180
1201 );
1202
1203 let expression = NumericTableExpression::Table2DSetVectorReduce(
1204 ReduceOperator::Sum,
1205 0,
1206 SetExpression::Complement(Box::new(SetExpression::Complement(Box::new(
1207 SetExpression::Reference(ReferenceExpression::Variable(0)),
1208 )))),
1209 VectorExpression::Reference(ReferenceExpression::Variable(1)),
1210 );
1211 assert_eq!(
1212 expression.eval(
1213 &state,
1214 &mut function_cache,
1215 &state_functions,
1216 ®istry,
1217 ®istry.integer_tables
1218 ),
1219 180
1220 );
1221
1222 let expression = NumericTableExpression::Table2DSetVectorReduce(
1223 ReduceOperator::Sum,
1224 0,
1225 SetExpression::Complement(Box::new(SetExpression::Complement(Box::new(
1226 SetExpression::Reference(ReferenceExpression::Variable(0)),
1227 )))),
1228 VectorExpression::Reverse(Box::new(VectorExpression::Reference(
1229 ReferenceExpression::Variable(1),
1230 ))),
1231 );
1232 assert_eq!(
1233 expression.eval(
1234 &state,
1235 &mut function_cache,
1236 &state_functions,
1237 ®istry,
1238 ®istry.integer_tables
1239 ),
1240 180
1241 );
1242 }
1243
1244 #[test]
1245 fn table_2d_vector_set_sum_eval() {
1246 let registry = generate_registry();
1247 let state = generate_state();
1248 let state_functions = StateFunctions::default();
1249 let mut function_cache = StateFunctionCache::new(&state_functions);
1250
1251 let expression = NumericTableExpression::Table2DVectorSetReduce(
1252 ReduceOperator::Sum,
1253 0,
1254 VectorExpression::Reference(ReferenceExpression::Variable(0)),
1255 SetExpression::Reference(ReferenceExpression::Variable(1)),
1256 );
1257 assert_eq!(
1258 expression.eval(
1259 &state,
1260 &mut function_cache,
1261 &state_functions,
1262 ®istry,
1263 ®istry.integer_tables
1264 ),
1265 180
1266 );
1267
1268 let expression = NumericTableExpression::Table2DVectorSetReduce(
1269 ReduceOperator::Sum,
1270 0,
1271 VectorExpression::Reverse(Box::new(VectorExpression::Reference(
1272 ReferenceExpression::Variable(0),
1273 ))),
1274 SetExpression::Reference(ReferenceExpression::Variable(1)),
1275 );
1276 assert_eq!(
1277 expression.eval(
1278 &state,
1279 &mut function_cache,
1280 &state_functions,
1281 ®istry,
1282 ®istry.integer_tables
1283 ),
1284 180
1285 );
1286
1287 let expression = NumericTableExpression::Table2DVectorSetReduce(
1288 ReduceOperator::Sum,
1289 0,
1290 VectorExpression::Reference(ReferenceExpression::Variable(0)),
1291 SetExpression::Complement(Box::new(SetExpression::Complement(Box::new(
1292 SetExpression::Reference(ReferenceExpression::Variable(1)),
1293 )))),
1294 );
1295 assert_eq!(
1296 expression.eval(
1297 &state,
1298 &mut function_cache,
1299 &state_functions,
1300 ®istry,
1301 ®istry.integer_tables
1302 ),
1303 180
1304 );
1305
1306 let expression = NumericTableExpression::Table2DVectorSetReduce(
1307 ReduceOperator::Sum,
1308 0,
1309 VectorExpression::Reverse(Box::new(VectorExpression::Reference(
1310 ReferenceExpression::Variable(0),
1311 ))),
1312 SetExpression::Complement(Box::new(SetExpression::Complement(Box::new(
1313 SetExpression::Reference(ReferenceExpression::Variable(1)),
1314 )))),
1315 );
1316 assert_eq!(
1317 expression.eval(
1318 &state,
1319 &mut function_cache,
1320 &state_functions,
1321 ®istry,
1322 ®istry.integer_tables
1323 ),
1324 180
1325 );
1326 }
1327
1328 #[test]
1329 fn table_2d_sum_x_eval() {
1330 let registry = generate_registry();
1331 let state = generate_state();
1332 let state_functions = StateFunctions::default();
1333 let mut function_cache = StateFunctionCache::new(&state_functions);
1334
1335 let expression = NumericTableExpression::Table2DReduceX(
1336 ReduceOperator::Sum,
1337 0,
1338 SetExpression::Reference(ReferenceExpression::Variable(0)),
1339 ElementExpression::Constant(0),
1340 );
1341 assert_eq!(
1342 expression.eval(
1343 &state,
1344 &mut function_cache,
1345 &state_functions,
1346 ®istry,
1347 ®istry.integer_tables
1348 ),
1349 80
1350 );
1351
1352 let expression = NumericTableExpression::Table2DReduceX(
1353 ReduceOperator::Sum,
1354 0,
1355 SetExpression::Complement(Box::new(SetExpression::Complement(Box::new(
1356 SetExpression::Reference(ReferenceExpression::Variable(0)),
1357 )))),
1358 ElementExpression::Constant(0),
1359 );
1360 assert_eq!(
1361 expression.eval(
1362 &state,
1363 &mut function_cache,
1364 &state_functions,
1365 ®istry,
1366 ®istry.integer_tables
1367 ),
1368 80
1369 );
1370 }
1371
1372 #[test]
1373 fn table_2d_vector_sum_x_eval() {
1374 let registry = generate_registry();
1375 let state = generate_state();
1376 let state_functions = StateFunctions::default();
1377 let mut function_cache = StateFunctionCache::new(&state_functions);
1378
1379 let expression = NumericTableExpression::Table2DVectorReduceX(
1380 ReduceOperator::Sum,
1381 0,
1382 VectorExpression::Reference(ReferenceExpression::Variable(0)),
1383 ElementExpression::Constant(0),
1384 );
1385 assert_eq!(
1386 expression.eval(
1387 &state,
1388 &mut function_cache,
1389 &state_functions,
1390 ®istry,
1391 ®istry.integer_tables
1392 ),
1393 80
1394 );
1395
1396 let expression = NumericTableExpression::Table2DVectorReduceX(
1397 ReduceOperator::Sum,
1398 0,
1399 VectorExpression::Reverse(Box::new(VectorExpression::Reference(
1400 ReferenceExpression::Variable(0),
1401 ))),
1402 ElementExpression::Constant(0),
1403 );
1404 assert_eq!(
1405 expression.eval(
1406 &state,
1407 &mut function_cache,
1408 &state_functions,
1409 ®istry,
1410 ®istry.integer_tables
1411 ),
1412 80
1413 );
1414 }
1415
1416 #[test]
1417 fn table_2d_sum_y_eval() {
1418 let registry = generate_registry();
1419 let state = generate_state();
1420 let state_functions = StateFunctions::default();
1421 let mut function_cache = StateFunctionCache::new(&state_functions);
1422
1423 let expression = NumericTableExpression::Table2DReduceY(
1424 ReduceOperator::Sum,
1425 0,
1426 ElementExpression::Constant(0),
1427 SetExpression::Reference(ReferenceExpression::Variable(0)),
1428 );
1429 assert_eq!(
1430 expression.eval(
1431 &state,
1432 &mut function_cache,
1433 &state_functions,
1434 ®istry,
1435 ®istry.integer_tables
1436 ),
1437 40
1438 );
1439
1440 let expression = NumericTableExpression::Table2DReduceY(
1441 ReduceOperator::Sum,
1442 0,
1443 ElementExpression::Constant(0),
1444 SetExpression::Complement(Box::new(SetExpression::Complement(Box::new(
1445 SetExpression::Reference(ReferenceExpression::Variable(0)),
1446 )))),
1447 );
1448 assert_eq!(
1449 expression.eval(
1450 &state,
1451 &mut function_cache,
1452 &state_functions,
1453 ®istry,
1454 ®istry.integer_tables
1455 ),
1456 40
1457 );
1458 }
1459
1460 #[test]
1461 fn table_2d_vector_sum_y_eval() {
1462 let registry = generate_registry();
1463 let state = generate_state();
1464 let state_functions = StateFunctions::default();
1465 let mut function_cache = StateFunctionCache::new(&state_functions);
1466
1467 let expression = NumericTableExpression::Table2DVectorReduceY(
1468 ReduceOperator::Sum,
1469 0,
1470 ElementExpression::Constant(0),
1471 VectorExpression::Reference(ReferenceExpression::Variable(0)),
1472 );
1473 assert_eq!(
1474 expression.eval(
1475 &state,
1476 &mut function_cache,
1477 &state_functions,
1478 ®istry,
1479 ®istry.integer_tables
1480 ),
1481 40
1482 );
1483
1484 let expression = NumericTableExpression::Table2DVectorReduceY(
1485 ReduceOperator::Sum,
1486 0,
1487 ElementExpression::Constant(0),
1488 VectorExpression::Reverse(Box::new(VectorExpression::Reference(
1489 ReferenceExpression::Variable(0),
1490 ))),
1491 );
1492 assert_eq!(
1493 expression.eval(
1494 &state,
1495 &mut function_cache,
1496 &state_functions,
1497 ®istry,
1498 ®istry.integer_tables
1499 ),
1500 40
1501 );
1502 }
1503
1504 #[test]
1505 fn table_2d_set_state_function_element_reduce_x_eval() {
1506 let mut state_metadata = StateMetadata::default();
1507 let ob = state_metadata.add_object_type("ob", 3);
1508 assert!(ob.is_ok());
1509 let ob = ob.unwrap();
1510 let v = state_metadata.add_set_variable("v", ob);
1511 assert!(v.is_ok());
1512 let v = v.unwrap();
1513
1514 let mut state_functions = StateFunctions::default();
1515 let f = state_functions.add_set_function("f", v.add(0).add(1));
1516 assert!(f.is_ok());
1517 let f = f.unwrap();
1518
1519 let mut registry = TableRegistry::default();
1520 let t = registry.add_table_2d("t", vec![vec![1, 2], vec![3, 4]]);
1521 assert!(t.is_ok());
1522 let t = t.unwrap();
1523
1524 let state = State {
1525 signature_variables: SignatureVariables {
1526 set_variables: vec![Set::with_capacity(3)],
1527 ..Default::default()
1528 },
1529 ..Default::default()
1530 };
1531
1532 let expression =
1533 NumericTableExpression::Table2DReduceX(ReduceOperator::Sum, t.id(), f, 1.into());
1534
1535 assert_eq!(
1536 expression.eval(
1537 &state,
1538 &mut StateFunctionCache::new(&state_functions),
1539 &state_functions,
1540 ®istry,
1541 ®istry.integer_tables,
1542 ),
1543 6,
1544 );
1545 }
1546
1547 #[test]
1548 fn table_2d_element_set_state_function_reduce_y_eval() {
1549 let mut state_metadata = StateMetadata::default();
1550 let ob = state_metadata.add_object_type("ob", 3);
1551 assert!(ob.is_ok());
1552 let ob = ob.unwrap();
1553 let v = state_metadata.add_set_variable("v", ob);
1554 assert!(v.is_ok());
1555 let v = v.unwrap();
1556
1557 let mut state_functions = StateFunctions::default();
1558 let f = state_functions.add_set_function("f", v.add(0).add(1));
1559 assert!(f.is_ok());
1560 let f = f.unwrap();
1561
1562 let mut registry = TableRegistry::default();
1563 let t = registry.add_table_2d("t", vec![vec![1, 2], vec![3, 4]]);
1564 assert!(t.is_ok());
1565 let t = t.unwrap();
1566
1567 let state = State {
1568 signature_variables: SignatureVariables {
1569 set_variables: vec![Set::with_capacity(3)],
1570 ..Default::default()
1571 },
1572 ..Default::default()
1573 };
1574
1575 let expression =
1576 NumericTableExpression::Table2DReduceY(ReduceOperator::Sum, t.id(), 1.into(), f);
1577
1578 assert_eq!(
1579 expression.eval(
1580 &state,
1581 &mut StateFunctionCache::new(&state_functions),
1582 &state_functions,
1583 ®istry,
1584 ®istry.integer_tables,
1585 ),
1586 7,
1587 );
1588 }
1589
1590 #[test]
1591 fn table_2d_set_state_function_set_state_function_reduce_eval() {
1592 let mut state_metadata = StateMetadata::default();
1593 let ob = state_metadata.add_object_type("ob", 3);
1594 assert!(ob.is_ok());
1595 let ob = ob.unwrap();
1596 let v = state_metadata.add_set_variable("v", ob);
1597 assert!(v.is_ok());
1598 let v = v.unwrap();
1599
1600 let mut state_functions = StateFunctions::default();
1601 let f = state_functions.add_set_function("f", v.add(0).add(1));
1602 assert!(f.is_ok());
1603 let f = f.unwrap();
1604 let g = state_functions.add_set_function("g", v.add(0).add(1));
1605 assert!(g.is_ok());
1606 let g = g.unwrap();
1607
1608 let mut registry = TableRegistry::default();
1609 let t = registry.add_table_2d("t", vec![vec![1, 2], vec![3, 4]]);
1610 assert!(t.is_ok());
1611 let t = t.unwrap();
1612
1613 let state = State {
1614 signature_variables: SignatureVariables {
1615 set_variables: vec![Set::with_capacity(3)],
1616 ..Default::default()
1617 },
1618 ..Default::default()
1619 };
1620
1621 let expression = NumericTableExpression::Table2DReduce(ReduceOperator::Sum, t.id(), f, g);
1622
1623 assert_eq!(
1624 expression.eval(
1625 &state,
1626 &mut StateFunctionCache::new(&state_functions),
1627 &state_functions,
1628 ®istry,
1629 ®istry.integer_tables,
1630 ),
1631 10,
1632 );
1633 }
1634
1635 #[test]
1636 fn table_2d_set_state_function_set_reference_reduce_eval() {
1637 let mut state_metadata = StateMetadata::default();
1638 let ob = state_metadata.add_object_type("ob", 3);
1639 assert!(ob.is_ok());
1640 let ob = ob.unwrap();
1641 let v = state_metadata.add_set_variable("v", ob);
1642 assert!(v.is_ok());
1643 let v = v.unwrap();
1644
1645 let mut state_functions = StateFunctions::default();
1646 let f = state_functions.add_set_function("f", v.add(0).add(1));
1647 assert!(f.is_ok());
1648 let f = f.unwrap();
1649
1650 let mut registry = TableRegistry::default();
1651 let t = registry.add_table_2d("t", vec![vec![1, 2], vec![3, 4]]);
1652 assert!(t.is_ok());
1653 let t = t.unwrap();
1654
1655 let set = state_metadata.create_set(ob, &[0, 1]);
1656 assert!(set.is_ok());
1657 let set = set.unwrap();
1658
1659 let state = State {
1660 signature_variables: SignatureVariables {
1661 set_variables: vec![Set::with_capacity(3)],
1662 ..Default::default()
1663 },
1664 ..Default::default()
1665 };
1666
1667 let expression =
1668 NumericTableExpression::Table2DReduce(ReduceOperator::Sum, t.id(), f, set.into());
1669
1670 assert_eq!(
1671 expression.eval(
1672 &state,
1673 &mut StateFunctionCache::new(&state_functions),
1674 &state_functions,
1675 ®istry,
1676 ®istry.integer_tables,
1677 ),
1678 10,
1679 );
1680 }
1681
1682 #[test]
1683 fn table_2d_set_reference_set_state_function_reduce_eval() {
1684 let mut state_metadata = StateMetadata::default();
1685 let ob = state_metadata.add_object_type("ob", 3);
1686 assert!(ob.is_ok());
1687 let ob = ob.unwrap();
1688 let v = state_metadata.add_set_variable("v", ob);
1689 assert!(v.is_ok());
1690 let v = v.unwrap();
1691
1692 let mut state_functions = StateFunctions::default();
1693 let f = state_functions.add_set_function("f", v.add(0).add(1));
1694 assert!(f.is_ok());
1695 let f = f.unwrap();
1696
1697 let mut registry = TableRegistry::default();
1698 let t = registry.add_table_2d("t", vec![vec![1, 2], vec![3, 4]]);
1699 assert!(t.is_ok());
1700 let t = t.unwrap();
1701
1702 let set = state_metadata.create_set(ob, &[0, 1]);
1703 assert!(set.is_ok());
1704 let set = set.unwrap();
1705
1706 let state = State {
1707 signature_variables: SignatureVariables {
1708 set_variables: vec![Set::with_capacity(3)],
1709 ..Default::default()
1710 },
1711 ..Default::default()
1712 };
1713
1714 let expression =
1715 NumericTableExpression::Table2DReduce(ReduceOperator::Sum, t.id(), set.into(), f);
1716
1717 assert_eq!(
1718 expression.eval(
1719 &state,
1720 &mut StateFunctionCache::new(&state_functions),
1721 &state_functions,
1722 ®istry,
1723 ®istry.integer_tables,
1724 ),
1725 10,
1726 );
1727 }
1728
1729 #[test]
1730 fn table_3d_eval() {
1731 let registry = generate_registry();
1732 let state = generate_state();
1733 let state_functions = StateFunctions::default();
1734 let mut function_cache = StateFunctionCache::new(&state_functions);
1735 let expression = NumericTableExpression::Table3D(
1736 0,
1737 ElementExpression::Constant(0),
1738 ElementExpression::Constant(0),
1739 ElementExpression::Constant(0),
1740 );
1741 assert_eq!(
1742 expression.eval(
1743 &state,
1744 &mut function_cache,
1745 &state_functions,
1746 ®istry,
1747 ®istry.integer_tables
1748 ),
1749 10
1750 );
1751 }
1752
1753 #[test]
1754 fn table_3d_sum_eval() {
1755 let registry = generate_registry();
1756 let state = generate_state();
1757 let state_functions = StateFunctions::default();
1758 let mut function_cache = StateFunctionCache::new(&state_functions);
1759 let expression = NumericTableExpression::Table3DReduce(
1760 ReduceOperator::Sum,
1761 0,
1762 ArgumentExpression::Element(ElementExpression::Constant(0)),
1763 ArgumentExpression::Set(SetExpression::Reference(ReferenceExpression::Variable(0))),
1764 ArgumentExpression::Vector(VectorExpression::Reference(ReferenceExpression::Variable(
1765 1,
1766 ))),
1767 );
1768 assert_eq!(
1769 expression.eval(
1770 &state,
1771 &mut function_cache,
1772 &state_functions,
1773 ®istry,
1774 ®istry.integer_tables
1775 ),
1776 180
1777 );
1778 }
1779
1780 #[test]
1781 fn table_eval() {
1782 let registry = generate_registry();
1783 let state = generate_state();
1784 let state_functions = StateFunctions::default();
1785 let mut function_cache = StateFunctionCache::new(&state_functions);
1786 let expression = NumericTableExpression::Table(
1787 0,
1788 vec![
1789 ElementExpression::Constant(0),
1790 ElementExpression::Constant(1),
1791 ElementExpression::Constant(0),
1792 ElementExpression::Constant(0),
1793 ],
1794 );
1795 assert_eq!(
1796 expression.eval(
1797 &state,
1798 &mut function_cache,
1799 &state_functions,
1800 ®istry,
1801 ®istry.integer_tables
1802 ),
1803 100
1804 );
1805 let expression = NumericTableExpression::Table(
1806 0,
1807 vec![
1808 ElementExpression::Constant(0),
1809 ElementExpression::Constant(1),
1810 ElementExpression::Constant(0),
1811 ElementExpression::Constant(1),
1812 ],
1813 );
1814 assert_eq!(
1815 expression.eval(
1816 &state,
1817 &mut function_cache,
1818 &state_functions,
1819 ®istry,
1820 ®istry.integer_tables
1821 ),
1822 200
1823 );
1824 let expression = NumericTableExpression::Table(
1825 0,
1826 vec![
1827 ElementExpression::Constant(0),
1828 ElementExpression::Constant(1),
1829 ElementExpression::Constant(2),
1830 ElementExpression::Constant(0),
1831 ],
1832 );
1833 assert_eq!(
1834 expression.eval(
1835 &state,
1836 &mut function_cache,
1837 &state_functions,
1838 ®istry,
1839 ®istry.integer_tables
1840 ),
1841 300
1842 );
1843 let expression = NumericTableExpression::Table(
1844 0,
1845 vec![
1846 ElementExpression::Constant(0),
1847 ElementExpression::Constant(1),
1848 ElementExpression::Constant(2),
1849 ElementExpression::Constant(1),
1850 ],
1851 );
1852 assert_eq!(
1853 expression.eval(
1854 &state,
1855 &mut function_cache,
1856 &state_functions,
1857 ®istry,
1858 ®istry.integer_tables
1859 ),
1860 400
1861 );
1862 }
1863
1864 #[test]
1865 fn table_sum_eval() {
1866 let registry = generate_registry();
1867 let state = generate_state();
1868 let state_functions = StateFunctions::default();
1869 let mut function_cache = StateFunctionCache::new(&state_functions);
1870 let expression = NumericTableExpression::TableReduce(
1871 ReduceOperator::Sum,
1872 0,
1873 vec![
1874 ArgumentExpression::Element(ElementExpression::Constant(0)),
1875 ArgumentExpression::Element(ElementExpression::Constant(1)),
1876 ArgumentExpression::Set(SetExpression::Complement(Box::new(
1877 SetExpression::Complement(Box::new(SetExpression::Reference(
1878 ReferenceExpression::Variable(0),
1879 ))),
1880 ))),
1881 ArgumentExpression::Vector(VectorExpression::Reverse(Box::new(
1882 VectorExpression::Reference(ReferenceExpression::Variable(1)),
1883 ))),
1884 ],
1885 );
1886 assert_eq!(
1887 expression.eval(
1888 &state,
1889 &mut function_cache,
1890 &state_functions,
1891 ®istry,
1892 ®istry.integer_tables
1893 ),
1894 1000
1895 );
1896 }
1897
1898 #[test]
1899 fn constant_simplify() {
1900 let registry = generate_registry();
1901 let expression = NumericTableExpression::Constant(0);
1902 assert_eq!(
1903 expression.simplify(®istry, ®istry.integer_tables),
1904 expression
1905 );
1906 }
1907
1908 #[test]
1909 fn table_1d_simplify() {
1910 let registry = generate_registry();
1911
1912 let expression = NumericTableExpression::Table1D(0, ElementExpression::Constant(0));
1913 assert_eq!(
1914 expression.simplify(®istry, ®istry.integer_tables),
1915 NumericTableExpression::Constant(10)
1916 );
1917
1918 let expression = NumericTableExpression::Table1D(0, ElementExpression::Variable(0));
1919 assert_eq!(
1920 expression.simplify(®istry, ®istry.integer_tables),
1921 expression
1922 );
1923 }
1924
1925 #[test]
1926 fn table_1d_sum_simplify() {
1927 let registry = generate_registry();
1928
1929 let mut set = Set::with_capacity(3);
1930 set.insert(0);
1931 set.insert(1);
1932 let expression = NumericTableExpression::Table1DReduce(
1933 ReduceOperator::Sum,
1934 0,
1935 SetExpression::Reference(ReferenceExpression::Constant(set)),
1936 );
1937 assert_eq!(
1938 expression.simplify(®istry, ®istry.integer_tables),
1939 NumericTableExpression::Constant(30)
1940 );
1941
1942 let expression = NumericTableExpression::Table1DReduce(
1943 ReduceOperator::Sum,
1944 0,
1945 SetExpression::Reference(ReferenceExpression::Variable(0)),
1946 );
1947 assert_eq!(
1948 expression.simplify(®istry, ®istry.integer_tables),
1949 expression
1950 );
1951 }
1952
1953 #[test]
1954 fn table_1d_vector_sum_simplify() {
1955 let registry = generate_registry();
1956
1957 let expression = NumericTableExpression::Table1DVectorReduce(
1958 ReduceOperator::Sum,
1959 0,
1960 VectorExpression::Reference(ReferenceExpression::Constant(vec![0, 1])),
1961 );
1962 assert_eq!(
1963 expression.simplify(®istry, ®istry.integer_tables),
1964 NumericTableExpression::Constant(30)
1965 );
1966
1967 let expression = NumericTableExpression::Table1DVectorReduce(
1968 ReduceOperator::Sum,
1969 0,
1970 VectorExpression::Reference(ReferenceExpression::Variable(0)),
1971 );
1972 assert_eq!(
1973 expression.simplify(®istry, ®istry.integer_tables),
1974 expression
1975 );
1976 }
1977
1978 #[test]
1979 fn table_2d_simplify() {
1980 let registry = generate_registry();
1981
1982 let expression = NumericTableExpression::Table2D(
1983 0,
1984 ElementExpression::Constant(0),
1985 ElementExpression::Constant(0),
1986 );
1987 assert_eq!(
1988 expression.simplify(®istry, ®istry.integer_tables),
1989 NumericTableExpression::Constant(10)
1990 );
1991
1992 let expression = NumericTableExpression::Table2D(
1993 0,
1994 ElementExpression::Constant(0),
1995 ElementExpression::Variable(0),
1996 );
1997 assert_eq!(
1998 expression.simplify(®istry, ®istry.integer_tables),
1999 expression
2000 );
2001 }
2002
2003 #[test]
2004 fn table_2d_sum_simplify() {
2005 let registry = generate_registry();
2006
2007 let mut set = Set::with_capacity(3);
2008 set.insert(0);
2009 set.insert(1);
2010 let expression = NumericTableExpression::Table2DReduce(
2011 ReduceOperator::Sum,
2012 0,
2013 SetExpression::Reference(ReferenceExpression::Constant(set.clone())),
2014 SetExpression::Reference(ReferenceExpression::Constant(set)),
2015 );
2016 assert_eq!(
2017 expression.simplify(®istry, ®istry.integer_tables),
2018 NumericTableExpression::Constant(120)
2019 );
2020
2021 let expression = NumericTableExpression::Table2DReduce(
2022 ReduceOperator::Sum,
2023 0,
2024 SetExpression::Reference(ReferenceExpression::Variable(0)),
2025 SetExpression::Reference(ReferenceExpression::Variable(1)),
2026 );
2027 assert_eq!(
2028 expression.simplify(®istry, ®istry.integer_tables),
2029 expression
2030 );
2031 }
2032
2033 #[test]
2034 fn table_2d_vector_sum_simplify() {
2035 let registry = generate_registry();
2036
2037 let expression = NumericTableExpression::Table2DVectorReduce(
2038 ReduceOperator::Sum,
2039 0,
2040 VectorExpression::Reference(ReferenceExpression::Constant(vec![0, 1])),
2041 VectorExpression::Reference(ReferenceExpression::Constant(vec![0, 1])),
2042 );
2043 assert_eq!(
2044 expression.simplify(®istry, ®istry.integer_tables),
2045 NumericTableExpression::Constant(120)
2046 );
2047
2048 let expression = NumericTableExpression::Table2DVectorReduce(
2049 ReduceOperator::Sum,
2050 0,
2051 VectorExpression::Reference(ReferenceExpression::Variable(0)),
2052 VectorExpression::Reference(ReferenceExpression::Variable(1)),
2053 );
2054 assert_eq!(
2055 expression.simplify(®istry, ®istry.integer_tables),
2056 expression
2057 );
2058 }
2059
2060 #[test]
2061 fn table_2d_set_vector_sum_simplify() {
2062 let registry = generate_registry();
2063
2064 let mut set = Set::with_capacity(3);
2065 set.insert(0);
2066 set.insert(1);
2067 let expression = NumericTableExpression::Table2DSetVectorReduce(
2068 ReduceOperator::Sum,
2069 0,
2070 SetExpression::Reference(ReferenceExpression::Constant(set)),
2071 VectorExpression::Reference(ReferenceExpression::Constant(vec![0, 1])),
2072 );
2073 assert_eq!(
2074 expression.simplify(®istry, ®istry.integer_tables),
2075 NumericTableExpression::Constant(120)
2076 );
2077
2078 let expression = NumericTableExpression::Table2DSetVectorReduce(
2079 ReduceOperator::Sum,
2080 0,
2081 SetExpression::Reference(ReferenceExpression::Variable(0)),
2082 VectorExpression::Reference(ReferenceExpression::Variable(1)),
2083 );
2084 assert_eq!(
2085 expression.simplify(®istry, ®istry.integer_tables),
2086 expression
2087 );
2088 }
2089
2090 #[test]
2091 fn table_2d_vector_set_sum_simplify() {
2092 let registry = generate_registry();
2093
2094 let mut set = Set::with_capacity(3);
2095 set.insert(0);
2096 set.insert(1);
2097 let expression = NumericTableExpression::Table2DVectorSetReduce(
2098 ReduceOperator::Sum,
2099 0,
2100 VectorExpression::Reference(ReferenceExpression::Constant(vec![0, 1])),
2101 SetExpression::Reference(ReferenceExpression::Constant(set)),
2102 );
2103 assert_eq!(
2104 expression.simplify(®istry, ®istry.integer_tables),
2105 NumericTableExpression::Constant(120)
2106 );
2107
2108 let expression = NumericTableExpression::Table2DVectorSetReduce(
2109 ReduceOperator::Sum,
2110 0,
2111 VectorExpression::Reference(ReferenceExpression::Variable(1)),
2112 SetExpression::Reference(ReferenceExpression::Variable(0)),
2113 );
2114 assert_eq!(
2115 expression.simplify(®istry, ®istry.integer_tables),
2116 expression
2117 );
2118 }
2119
2120 #[test]
2121 fn table_2d_sum_x_simplify() {
2122 let registry = generate_registry();
2123
2124 let mut set = Set::with_capacity(3);
2125 set.insert(0);
2126 set.insert(1);
2127 let expression = NumericTableExpression::Table2DReduceX(
2128 ReduceOperator::Sum,
2129 0,
2130 SetExpression::Reference(ReferenceExpression::Constant(set)),
2131 ElementExpression::Constant(0),
2132 );
2133 assert_eq!(
2134 expression.simplify(®istry, ®istry.integer_tables),
2135 NumericTableExpression::Constant(50)
2136 );
2137
2138 let expression = NumericTableExpression::Table2DReduceX(
2139 ReduceOperator::Sum,
2140 0,
2141 SetExpression::Reference(ReferenceExpression::Variable(0)),
2142 ElementExpression::Constant(0),
2143 );
2144 assert_eq!(
2145 expression.simplify(®istry, ®istry.integer_tables),
2146 expression
2147 );
2148 }
2149
2150 #[test]
2151 fn table_2d_sum_y_simplify() {
2152 let registry = generate_registry();
2153
2154 let mut set = Set::with_capacity(3);
2155 set.insert(0);
2156 set.insert(1);
2157 let expression = NumericTableExpression::Table2DReduceY(
2158 ReduceOperator::Sum,
2159 0,
2160 ElementExpression::Constant(0),
2161 SetExpression::Reference(ReferenceExpression::Constant(set)),
2162 );
2163 assert_eq!(
2164 expression.simplify(®istry, ®istry.integer_tables),
2165 NumericTableExpression::Constant(30)
2166 );
2167
2168 let expression = NumericTableExpression::Table2DReduceY(
2169 ReduceOperator::Sum,
2170 0,
2171 ElementExpression::Constant(0),
2172 SetExpression::Reference(ReferenceExpression::Variable(0)),
2173 );
2174 assert_eq!(
2175 expression.simplify(®istry, ®istry.integer_tables),
2176 expression
2177 );
2178 }
2179
2180 #[test]
2181 fn table_2d_vector_sum_x_simplify() {
2182 let registry = generate_registry();
2183
2184 let expression = NumericTableExpression::Table2DVectorReduceX(
2185 ReduceOperator::Sum,
2186 0,
2187 VectorExpression::Reference(ReferenceExpression::Constant(vec![0, 1])),
2188 ElementExpression::Constant(0),
2189 );
2190 assert_eq!(
2191 expression.simplify(®istry, ®istry.integer_tables),
2192 NumericTableExpression::Constant(50)
2193 );
2194
2195 let expression = NumericTableExpression::Table2DVectorReduceX(
2196 ReduceOperator::Sum,
2197 0,
2198 VectorExpression::Reference(ReferenceExpression::Variable(0)),
2199 ElementExpression::Constant(0),
2200 );
2201 assert_eq!(
2202 expression.simplify(®istry, ®istry.integer_tables),
2203 expression
2204 );
2205 }
2206
2207 #[test]
2208 fn table_2d_vector_sum_y_simplify() {
2209 let registry = generate_registry();
2210
2211 let expression = NumericTableExpression::Table2DVectorReduceY(
2212 ReduceOperator::Sum,
2213 0,
2214 ElementExpression::Constant(0),
2215 VectorExpression::Reference(ReferenceExpression::Constant(vec![0, 1])),
2216 );
2217 assert_eq!(
2218 expression.simplify(®istry, ®istry.integer_tables),
2219 NumericTableExpression::Constant(30)
2220 );
2221
2222 let expression = NumericTableExpression::Table2DVectorReduceY(
2223 ReduceOperator::Sum,
2224 0,
2225 ElementExpression::Constant(0),
2226 VectorExpression::Reference(ReferenceExpression::Variable(0)),
2227 );
2228 assert_eq!(
2229 expression.simplify(®istry, ®istry.integer_tables),
2230 expression
2231 );
2232 }
2233
2234 #[test]
2235 fn table_3d_simplify() {
2236 let registry = generate_registry();
2237
2238 let expression = NumericTableExpression::Table3D(
2239 0,
2240 ElementExpression::Constant(0),
2241 ElementExpression::Constant(0),
2242 ElementExpression::Constant(0),
2243 );
2244 assert_eq!(
2245 expression.simplify(®istry, ®istry.integer_tables),
2246 NumericTableExpression::Constant(10)
2247 );
2248
2249 let expression = NumericTableExpression::Table3D(
2250 0,
2251 ElementExpression::Constant(0),
2252 ElementExpression::Constant(0),
2253 ElementExpression::Variable(0),
2254 );
2255 assert_eq!(
2256 expression.simplify(®istry, ®istry.integer_tables),
2257 expression
2258 );
2259 }
2260
2261 #[test]
2262 fn table_3d_sum_simplify() {
2263 let registry = generate_registry();
2264
2265 let mut set = Set::with_capacity(3);
2266 set.insert(0);
2267 set.insert(2);
2268 let expression = NumericTableExpression::Table3DReduce(
2269 ReduceOperator::Sum,
2270 0,
2271 ArgumentExpression::Element(ElementExpression::Constant(0)),
2272 ArgumentExpression::Set(SetExpression::Reference(ReferenceExpression::Constant(set))),
2273 ArgumentExpression::Vector(VectorExpression::Reference(ReferenceExpression::Constant(
2274 vec![0, 1],
2275 ))),
2276 );
2277 assert_eq!(
2278 expression.simplify(®istry, ®istry.integer_tables),
2279 NumericTableExpression::Constant(180)
2280 );
2281
2282 let expression = NumericTableExpression::Table3DReduce(
2283 ReduceOperator::Sum,
2284 0,
2285 ArgumentExpression::Element(ElementExpression::Constant(0)),
2286 ArgumentExpression::Set(SetExpression::Reference(ReferenceExpression::Variable(0))),
2287 ArgumentExpression::Vector(VectorExpression::Reference(ReferenceExpression::Variable(
2288 1,
2289 ))),
2290 );
2291 assert_eq!(
2292 expression.simplify(®istry, ®istry.integer_tables),
2293 expression
2294 );
2295 }
2296
2297 #[test]
2298 fn table_simplify() {
2299 let registry = generate_registry();
2300
2301 let expression = NumericTableExpression::Table(
2302 0,
2303 vec![
2304 ElementExpression::Constant(0),
2305 ElementExpression::Constant(1),
2306 ElementExpression::Constant(0),
2307 ElementExpression::Constant(0),
2308 ],
2309 );
2310 assert_eq!(
2311 expression.simplify(®istry, ®istry.integer_tables),
2312 NumericTableExpression::Constant(100)
2313 );
2314
2315 let expression = NumericTableExpression::Table(
2316 0,
2317 vec![
2318 ElementExpression::Constant(0),
2319 ElementExpression::Constant(1),
2320 ElementExpression::Constant(0),
2321 ElementExpression::Variable(0),
2322 ],
2323 );
2324 assert_eq!(
2325 expression.simplify(®istry, ®istry.integer_tables),
2326 expression
2327 );
2328 }
2329
2330 #[test]
2331 fn table_sum_simplify() {
2332 let registry = generate_registry();
2333
2334 let mut set = Set::with_capacity(3);
2335 set.insert(0);
2336 set.insert(2);
2337 let expression = NumericTableExpression::TableReduce(
2338 ReduceOperator::Sum,
2339 0,
2340 vec![
2341 ArgumentExpression::Element(ElementExpression::Constant(0)),
2342 ArgumentExpression::Element(ElementExpression::Constant(1)),
2343 ArgumentExpression::Set(SetExpression::Complement(Box::new(
2344 SetExpression::Complement(Box::new(SetExpression::Reference(
2345 ReferenceExpression::Constant(set),
2346 ))),
2347 ))),
2348 ArgumentExpression::Vector(VectorExpression::Reverse(Box::new(
2349 VectorExpression::Reference(ReferenceExpression::Constant(vec![0, 1])),
2350 ))),
2351 ],
2352 );
2353 assert_eq!(
2354 expression.simplify(®istry, ®istry.integer_tables),
2355 NumericTableExpression::Constant(1000)
2356 );
2357
2358 let expression = NumericTableExpression::TableReduce(
2359 ReduceOperator::Sum,
2360 0,
2361 vec![
2362 ArgumentExpression::Element(ElementExpression::Constant(0)),
2363 ArgumentExpression::Element(ElementExpression::Constant(1)),
2364 ArgumentExpression::Element(ElementExpression::Constant(0)),
2365 ArgumentExpression::Vector(VectorExpression::Reference(
2366 ReferenceExpression::Variable(0),
2367 )),
2368 ],
2369 );
2370 assert_eq!(
2371 expression.simplify(®istry, ®istry.integer_tables),
2372 expression
2373 );
2374 }
2375}