1mod boolean;
9mod float;
10mod integer;
11mod natural;
12
13use rand::Rng;
14use std::{
15 hash::Hash,
16 ops::{Add, BitAnd, BitOr, Div, Mul, Neg, Not, Rem},
17};
18use thiserror::Error;
19
20use crate::dummy_rng::DummyRng;
21
22pub use boolean::*;
23pub use float::*;
24pub use integer::*;
25pub use natural::*;
26
27#[derive(Debug, Clone, Copy, Error)]
29pub enum TypeError {
30 #[error("type mismatch")]
33 TypeMismatch,
34 #[error("the type of variable is unknown")]
36 UnknownVar,
37 #[error("the bounds violate some constraint")]
39 BadBounds,
40 #[error("the probability violates some constraint")]
42 BadProbability,
43}
44
45#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
47pub enum Type {
48 Boolean,
50 Natural,
52 Integer,
54 Float,
56}
57
58impl Type {
59 pub fn default_value(self) -> Val {
62 match self {
63 Type::Boolean => Val::Boolean(false),
64 Type::Natural => Val::Natural(0),
65 Type::Integer => Val::Integer(0),
66 Type::Float => Val::Float(0.0),
67 }
68 }
69}
70
71#[derive(Debug, Clone, Copy, PartialEq)]
73pub enum Val {
74 Boolean(bool),
76 Natural(Natural),
78 Integer(Integer),
80 Float(Float),
82}
83
84impl Val {
85 pub fn r#type(self) -> Type {
87 match self {
88 Val::Boolean(_) => Type::Boolean,
89 Val::Natural(_) => Type::Natural,
90 Val::Integer(_) => Type::Integer,
91 Val::Float(_) => Type::Float,
92 }
93 }
94}
95
96impl From<bool> for Val {
97 fn from(value: bool) -> Self {
98 Val::Boolean(value)
99 }
100}
101
102impl From<Natural> for Val {
103 fn from(value: Natural) -> Self {
104 Val::Natural(value)
105 }
106}
107
108impl From<Integer> for Val {
109 fn from(value: Integer) -> Self {
110 Val::Integer(value)
111 }
112}
113
114impl From<Float> for Val {
115 fn from(value: Float) -> Self {
116 Val::Float(value)
117 }
118}
119
120#[derive(Debug, Clone)]
126pub enum Expression<V>
127where
128 V: Clone,
129{
130 Boolean(BooleanExpr<V>),
132 Natural(NaturalExpr<V>),
134 Integer(IntegerExpr<V>),
136 Float(FloatExpr<V>),
138}
139
140impl<V> From<Val> for Expression<V>
141where
142 V: Clone,
143{
144 fn from(value: Val) -> Self {
145 match value {
146 Val::Boolean(b) => Expression::Boolean(BooleanExpr::Const(b)),
147 Val::Natural(nat) => Expression::Natural(NaturalExpr::Const(nat)),
148 Val::Integer(int) => Expression::Integer(IntegerExpr::Const(int)),
149 Val::Float(float) => Expression::Float(FloatExpr::Const(float)),
150 }
151 }
152}
153
154impl<V> From<bool> for Expression<V>
155where
156 V: Clone,
157{
158 fn from(value: bool) -> Self {
159 Expression::Boolean(BooleanExpr::from(value))
160 }
161}
162
163impl<V> From<Natural> for Expression<V>
164where
165 V: Clone,
166{
167 fn from(value: Natural) -> Self {
168 Expression::Natural(NaturalExpr::from(value))
169 }
170}
171
172impl<V> From<Integer> for Expression<V>
173where
174 V: Clone,
175{
176 fn from(value: Integer) -> Self {
177 Expression::Integer(IntegerExpr::from(value))
178 }
179}
180
181impl<V> From<Float> for Expression<V>
182where
183 V: Clone,
184{
185 fn from(value: Float) -> Self {
186 Expression::Float(FloatExpr::from(value))
187 }
188}
189
190impl<V> Expression<V>
191where
192 V: Clone,
193{
194 pub fn r#type(&self) -> Type {
199 match self {
200 Expression::Boolean(_) => Type::Boolean,
201 Expression::Natural(_) => Type::Natural,
202 Expression::Integer(_) => Type::Integer,
203 Expression::Float(_) => Type::Float,
204 }
205 }
206
207 pub fn eval<R: Rng>(&self, vars: &dyn Fn(&V) -> Val, rng: &mut R) -> Val {
212 match self {
213 Expression::Boolean(boolean_expr) => Val::Boolean(boolean_expr.eval(vars, rng)),
214 Expression::Natural(natural_expr) => Val::Natural(natural_expr.eval(vars, rng)),
215 Expression::Integer(integer_expr) => Val::Integer(integer_expr.eval(vars, rng)),
216 Expression::Float(float_expr) => Val::Float(float_expr.eval(vars, rng)),
217 }
218 }
219
220 pub fn is_constant(&self) -> bool {
223 match self {
224 Expression::Boolean(boolean_expr) => boolean_expr.is_constant(),
225 Expression::Natural(natural_expr) => natural_expr.is_constant(),
226 Expression::Integer(integer_expr) => integer_expr.is_constant(),
227 Expression::Float(float_expr) => float_expr.is_constant(),
228 }
229 }
230
231 pub fn eval_constant(&self) -> Result<Val, TypeError> {
234 if self.is_constant() {
235 Ok(self.eval(&|_| panic!("no vars"), &mut DummyRng))
236 } else {
237 Err(TypeError::UnknownVar)
238 }
239 }
240
241 pub(crate) fn map<W: Clone>(self, map: &dyn Fn(V) -> W) -> Expression<W> {
242 match self {
243 Expression::Boolean(boolean_expr) => Expression::Boolean(boolean_expr.map(map)),
244 Expression::Natural(natural_expr) => Expression::Natural(natural_expr.map(map)),
245 Expression::Integer(integer_expr) => Expression::Integer(integer_expr.map(map)),
246 Expression::Float(float_expr) => Expression::Float(float_expr.map(map)),
247 }
248 }
249
250 pub(crate) fn context(&self, vars: &dyn Fn(V) -> Option<Type>) -> Result<(), TypeError> {
251 match self {
252 Expression::Boolean(boolean_expr) => boolean_expr.context(vars),
253 Expression::Natural(natural_expr) => natural_expr.context(vars),
254 Expression::Integer(integer_expr) => integer_expr.context(vars),
255 Expression::Float(float_expr) => float_expr.context(vars),
256 }
257 }
258
259 pub fn from_var(var: V, r#type: Type) -> Self {
261 match r#type {
262 Type::Boolean => Expression::Boolean(BooleanExpr::Var(var)),
263 Type::Natural => Expression::Natural(NaturalExpr::Var(var)),
264 Type::Integer => Expression::Integer(IntegerExpr::Var(var)),
265 Type::Float => Expression::Float(FloatExpr::Var(var)),
266 }
267 }
268
269 pub fn equal_to(self, rhs: Self) -> Result<BooleanExpr<V>, TypeError> {
278 match self {
279 Expression::Boolean(boolean_expr) => match rhs {
280 Expression::Boolean(boolean_expr_rhs) => {
281 Ok(BooleanExpr::Implies(Box::new((
282 boolean_expr.clone(),
283 boolean_expr_rhs.clone(),
284 ))) & BooleanExpr::Implies(Box::new((boolean_expr_rhs, boolean_expr))))
285 }
286 Expression::Natural(_) | Expression::Integer(_) | Expression::Float(_) => {
287 Err(TypeError::TypeMismatch)
288 }
289 },
290 Expression::Natural(natural_expr) => match rhs {
291 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
292 Expression::Natural(natural_expr_rhs) => {
293 Ok(BooleanExpr::NatEqual(natural_expr, natural_expr_rhs))
294 }
295 Expression::Integer(integer_expr_rhs) => Ok(BooleanExpr::IntEqual(
296 IntegerExpr::from(natural_expr),
297 integer_expr_rhs,
298 )),
299 Expression::Float(float_expr_rhs) => Ok(BooleanExpr::FloatEqual(
300 FloatExpr::Nat(natural_expr),
301 float_expr_rhs,
302 )),
303 },
304 Expression::Integer(integer_expr) => match rhs {
305 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
306 Expression::Natural(natural_expr_rhs) => Ok(BooleanExpr::IntEqual(
307 integer_expr,
308 IntegerExpr::from(natural_expr_rhs),
309 )),
310 Expression::Integer(integer_expr_rhs) => {
311 Ok(BooleanExpr::IntEqual(integer_expr, integer_expr_rhs))
312 }
313 Expression::Float(float_expr_rhs) => Ok(BooleanExpr::FloatEqual(
314 FloatExpr::Int(integer_expr),
315 float_expr_rhs,
316 )),
317 },
318 Expression::Float(float_expr) => match rhs {
319 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
320 Expression::Natural(natural_expr_rhs) => Ok(BooleanExpr::FloatEqual(
321 float_expr,
322 FloatExpr::Nat(natural_expr_rhs),
323 )),
324 Expression::Integer(integer_expr_rhs) => Ok(BooleanExpr::FloatEqual(
325 float_expr,
326 FloatExpr::Int(integer_expr_rhs),
327 )),
328 Expression::Float(float_expr_rhs) => {
329 Ok(BooleanExpr::FloatEqual(float_expr, float_expr_rhs))
330 }
331 },
332 }
333 }
334
335 pub fn greater_than_or_equal_to(self, rhs: Self) -> Result<BooleanExpr<V>, TypeError> {
341 match self {
342 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
343 Expression::Natural(natural_expr) => match rhs {
344 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
345 Expression::Natural(natural_expr_rhs) => {
346 Ok(BooleanExpr::NatGreaterEq(natural_expr, natural_expr_rhs))
347 }
348 Expression::Integer(integer_expr_rhs) => Ok(BooleanExpr::IntGreaterEq(
349 IntegerExpr::from(natural_expr),
350 integer_expr_rhs,
351 )),
352 Expression::Float(float_expr_rhs) => Ok(BooleanExpr::FloatGreaterEq(
353 FloatExpr::Nat(natural_expr),
354 float_expr_rhs,
355 )),
356 },
357 Expression::Integer(integer_expr) => match rhs {
358 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
359 Expression::Natural(natural_expr_rhs) => Ok(BooleanExpr::IntGreaterEq(
360 integer_expr,
361 IntegerExpr::from(natural_expr_rhs),
362 )),
363 Expression::Integer(integer_expr_rhs) => {
364 Ok(BooleanExpr::IntGreaterEq(integer_expr, integer_expr_rhs))
365 }
366 Expression::Float(float_expr_rhs) => Ok(BooleanExpr::FloatGreaterEq(
367 FloatExpr::Int(integer_expr),
368 float_expr_rhs,
369 )),
370 },
371 Expression::Float(float_expr) => match rhs {
372 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
373 Expression::Natural(natural_expr_rhs) => Ok(BooleanExpr::FloatGreaterEq(
374 float_expr,
375 FloatExpr::Nat(natural_expr_rhs),
376 )),
377 Expression::Integer(integer_expr_rhs) => Ok(BooleanExpr::FloatGreaterEq(
378 float_expr,
379 FloatExpr::Int(integer_expr_rhs),
380 )),
381 Expression::Float(float_expr_rhs) => {
382 Ok(BooleanExpr::FloatGreaterEq(float_expr, float_expr_rhs))
383 }
384 },
385 }
386 }
387
388 pub fn greater_than(self, rhs: Self) -> Result<BooleanExpr<V>, TypeError> {
394 match self {
395 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
396 Expression::Natural(natural_expr) => match rhs {
397 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
398 Expression::Natural(natural_expr_rhs) => {
399 Ok(BooleanExpr::NatGreater(natural_expr, natural_expr_rhs))
400 }
401 Expression::Integer(integer_expr_rhs) => Ok(BooleanExpr::IntGreater(
402 IntegerExpr::from(natural_expr),
403 integer_expr_rhs,
404 )),
405 Expression::Float(float_expr_rhs) => Ok(BooleanExpr::FloatGreater(
406 FloatExpr::from(natural_expr),
407 float_expr_rhs,
408 )),
409 },
410 Expression::Integer(integer_expr) => match rhs {
411 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
412 Expression::Natural(natural_expr_rhs) => Ok(BooleanExpr::IntGreater(
413 integer_expr,
414 IntegerExpr::from(natural_expr_rhs),
415 )),
416 Expression::Integer(integer_expr_rhs) => {
417 Ok(BooleanExpr::IntGreater(integer_expr, integer_expr_rhs))
418 }
419 Expression::Float(float_expr_rhs) => Ok(BooleanExpr::FloatGreater(
420 FloatExpr::from(integer_expr),
421 float_expr_rhs,
422 )),
423 },
424 Expression::Float(float_expr) => match rhs {
425 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
426 Expression::Natural(natural_expr_rhs) => Ok(BooleanExpr::FloatGreater(
427 float_expr,
428 FloatExpr::from(natural_expr_rhs),
429 )),
430 Expression::Integer(integer_expr_rhs) => Ok(BooleanExpr::FloatGreater(
431 float_expr,
432 FloatExpr::from(integer_expr_rhs),
433 )),
434 Expression::Float(float_expr_rhs) => {
435 Ok(BooleanExpr::FloatGreater(float_expr, float_expr_rhs))
436 }
437 },
438 }
439 }
440
441 pub fn less_than(self, rhs: Self) -> Result<BooleanExpr<V>, TypeError> {
447 match self {
448 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
449 Expression::Natural(natural_expr) => match rhs {
450 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
451 Expression::Natural(natural_expr_rhs) => {
452 Ok(BooleanExpr::NatLess(natural_expr, natural_expr_rhs))
453 }
454 Expression::Integer(integer_expr_rhs) => Ok(BooleanExpr::IntLess(
455 IntegerExpr::from(natural_expr),
456 integer_expr_rhs,
457 )),
458 Expression::Float(float_expr_rhs) => Ok(BooleanExpr::FloatLess(
459 FloatExpr::from(natural_expr),
460 float_expr_rhs,
461 )),
462 },
463 Expression::Integer(integer_expr) => match rhs {
464 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
465 Expression::Natural(natural_expr_rhs) => Ok(BooleanExpr::IntLess(
466 integer_expr,
467 IntegerExpr::from(natural_expr_rhs),
468 )),
469 Expression::Integer(integer_expr_rhs) => {
470 Ok(BooleanExpr::IntLess(integer_expr, integer_expr_rhs))
471 }
472 Expression::Float(float_expr_rhs) => Ok(BooleanExpr::FloatLess(
473 FloatExpr::from(integer_expr),
474 float_expr_rhs,
475 )),
476 },
477 Expression::Float(float_expr) => match rhs {
478 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
479 Expression::Natural(natural_expr_rhs) => Ok(BooleanExpr::FloatLess(
480 float_expr,
481 FloatExpr::from(natural_expr_rhs),
482 )),
483 Expression::Integer(integer_expr_rhs) => Ok(BooleanExpr::FloatLess(
484 float_expr,
485 FloatExpr::from(integer_expr_rhs),
486 )),
487 Expression::Float(float_expr_rhs) => {
488 Ok(BooleanExpr::FloatLess(float_expr, float_expr_rhs))
489 }
490 },
491 }
492 }
493
494 pub fn less_than_or_equal_to(self, rhs: Self) -> Result<BooleanExpr<V>, TypeError> {
500 match self {
501 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
502 Expression::Natural(natural_expr) => match rhs {
503 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
504 Expression::Natural(natural_expr_rhs) => {
505 Ok(BooleanExpr::NatLessEq(natural_expr, natural_expr_rhs))
506 }
507 Expression::Integer(integer_expr_rhs) => Ok(BooleanExpr::IntLessEq(
508 IntegerExpr::from(natural_expr),
509 integer_expr_rhs,
510 )),
511 Expression::Float(float_expr_rhs) => Ok(BooleanExpr::FloatLessEq(
512 FloatExpr::Nat(natural_expr),
513 float_expr_rhs,
514 )),
515 },
516 Expression::Integer(integer_expr) => match rhs {
517 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
518 Expression::Natural(natural_expr_rhs) => Ok(BooleanExpr::IntLessEq(
519 integer_expr,
520 IntegerExpr::from(natural_expr_rhs),
521 )),
522 Expression::Integer(integer_expr_rhs) => {
523 Ok(BooleanExpr::IntLessEq(integer_expr, integer_expr_rhs))
524 }
525 Expression::Float(float_expr_rhs) => Ok(BooleanExpr::FloatLessEq(
526 FloatExpr::Int(integer_expr),
527 float_expr_rhs,
528 )),
529 },
530 Expression::Float(float_expr) => match rhs {
531 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
532 Expression::Natural(natural_expr_rhs) => Ok(BooleanExpr::FloatLessEq(
533 float_expr,
534 FloatExpr::Nat(natural_expr_rhs),
535 )),
536 Expression::Integer(integer_expr_rhs) => Ok(BooleanExpr::FloatLessEq(
537 float_expr,
538 FloatExpr::Int(integer_expr_rhs),
539 )),
540 Expression::Float(float_expr_rhs) => {
541 Ok(BooleanExpr::FloatLessEq(float_expr, float_expr_rhs))
542 }
543 },
544 }
545 }
546
547 pub fn ite(self, then: Self, r#else: Self) -> Result<Self, TypeError> {
553 if let Expression::Boolean(r#if) = self {
554 match then {
555 Expression::Boolean(if_boolean_expr) => {
556 if let Expression::Boolean(else_boolean_expr) = r#else {
557 Ok(Expression::Boolean(BooleanExpr::Ite(Box::new((
558 r#if,
559 if_boolean_expr,
560 else_boolean_expr,
561 )))))
562 } else {
563 Err(TypeError::TypeMismatch)
564 }
565 }
566 Expression::Natural(if_natural_expr) => match r#else {
567 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
568 Expression::Natural(else_natural_expr) => Ok(Expression::Natural(
569 NaturalExpr::Ite(Box::new((r#if, if_natural_expr, else_natural_expr))),
570 )),
571 Expression::Integer(else_integer_expr) => {
572 Ok(Expression::Integer(IntegerExpr::Ite(Box::new((
573 r#if,
574 IntegerExpr::from(if_natural_expr),
575 else_integer_expr,
576 )))))
577 }
578 Expression::Float(else_float_expr) => Ok(Expression::Float(FloatExpr::Ite(
579 Box::new((r#if, FloatExpr::from(if_natural_expr), else_float_expr)),
580 ))),
581 },
582 Expression::Integer(if_integer_expr) => match r#else {
583 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
584 Expression::Natural(else_natural_expr) => {
585 Ok(Expression::Integer(IntegerExpr::Ite(Box::new((
586 r#if,
587 if_integer_expr,
588 IntegerExpr::from(else_natural_expr),
589 )))))
590 }
591 Expression::Integer(else_integer_expr) => Ok(Expression::Integer(
592 IntegerExpr::Ite(Box::new((r#if, if_integer_expr, else_integer_expr))),
593 )),
594 Expression::Float(else_float_expr) => Ok(Expression::Float(FloatExpr::Ite(
595 Box::new((r#if, FloatExpr::from(if_integer_expr), else_float_expr)),
596 ))),
597 },
598 Expression::Float(if_float_expr) => match r#else {
599 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
600 Expression::Natural(else_natural_expr) => {
601 Ok(Expression::Float(FloatExpr::Ite(Box::new((
602 r#if,
603 if_float_expr,
604 FloatExpr::from(else_natural_expr),
605 )))))
606 }
607 Expression::Integer(else_integer_expr) => {
608 Ok(Expression::Float(FloatExpr::Ite(Box::new((
609 r#if,
610 if_float_expr,
611 FloatExpr::from(else_integer_expr),
612 )))))
613 }
614 Expression::Float(else_float_expr) => Ok(Expression::Float(FloatExpr::Ite(
615 Box::new((r#if, if_float_expr, else_float_expr)),
616 ))),
617 },
618 }
619 } else {
620 Err(TypeError::TypeMismatch)
621 }
622 }
623}
624
625impl<V: Clone> Neg for Expression<V> {
626 type Output = Result<Expression<V>, TypeError>;
627
628 fn neg(self) -> Self::Output {
629 match self {
630 Expression::Boolean(_) | Expression::Natural(_) => Err(TypeError::TypeMismatch),
631 Expression::Integer(integer_expr) => Ok(Expression::Integer(-integer_expr)),
632 Expression::Float(float_expr) => Ok(Expression::Float(-float_expr)),
633 }
634 }
635}
636
637impl<V: Clone> Not for Expression<V> {
638 type Output = Result<Expression<V>, TypeError>;
639
640 fn not(self) -> Self::Output {
641 match self {
642 Expression::Boolean(boolean_expr) => Ok(Expression::Boolean(!boolean_expr)),
643 Expression::Natural(_) | Expression::Integer(_) | Expression::Float(_) => {
644 Err(TypeError::TypeMismatch)
645 }
646 }
647 }
648}
649
650impl<V: Clone> Add for Expression<V> {
651 type Output = Result<Self, TypeError>;
652
653 fn add(self, rhs: Self) -> Self::Output {
654 match self {
655 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
656 Expression::Natural(natural_expr) => match rhs {
657 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
658 Expression::Natural(natural_expr_rhs) => {
659 Ok(Expression::Natural(natural_expr + natural_expr_rhs))
660 }
661 Expression::Integer(integer_expr_rhs) => Ok(Expression::Integer(
662 IntegerExpr::from(natural_expr) + integer_expr_rhs,
663 )),
664 Expression::Float(float_expr_rhs) => Ok(Expression::Float(
665 FloatExpr::from(natural_expr) + float_expr_rhs,
666 )),
667 },
668 Expression::Integer(integer_expr) => match rhs {
669 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
670 Expression::Natural(natural_expr_rhs) => Ok(Expression::Integer(
671 integer_expr + IntegerExpr::from(natural_expr_rhs),
672 )),
673 Expression::Integer(integer_expr_rhs) => {
674 Ok(Expression::Integer(integer_expr + integer_expr_rhs))
675 }
676 Expression::Float(float_expr_rhs) => Ok(Expression::Float(
677 FloatExpr::from(integer_expr) + float_expr_rhs,
678 )),
679 },
680 Expression::Float(float_expr) => match rhs {
681 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
682 Expression::Natural(natural_expr_rhs) => Ok(Expression::Float(
683 float_expr + FloatExpr::from(natural_expr_rhs),
684 )),
685 Expression::Integer(integer_expr_rhs) => Ok(Expression::Float(
686 float_expr + FloatExpr::from(integer_expr_rhs),
687 )),
688 Expression::Float(float_expr_rhs) => {
689 Ok(Expression::Float(float_expr + float_expr_rhs))
690 }
691 },
692 }
693 }
694}
695
696impl<V: Clone> Mul for Expression<V> {
697 type Output = Result<Self, TypeError>;
698
699 fn mul(self, rhs: Self) -> Self::Output {
700 match self {
701 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
702 Expression::Natural(natural_expr) => match rhs {
703 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
704 Expression::Natural(natural_expr_rhs) => {
705 Ok(Expression::Natural(natural_expr * natural_expr_rhs))
706 }
707 Expression::Integer(integer_expr_rhs) => Ok(Expression::Integer(
708 IntegerExpr::from(natural_expr) * integer_expr_rhs,
709 )),
710 Expression::Float(float_expr_rhs) => Ok(Expression::Float(
711 FloatExpr::from(natural_expr) * float_expr_rhs,
712 )),
713 },
714 Expression::Integer(integer_expr) => match rhs {
715 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
716 Expression::Natural(natural_expr_rhs) => Ok(Expression::Integer(
717 integer_expr * IntegerExpr::from(natural_expr_rhs),
718 )),
719 Expression::Integer(integer_expr_rhs) => {
720 Ok(Expression::Integer(integer_expr * integer_expr_rhs))
721 }
722 Expression::Float(float_expr_rhs) => Ok(Expression::Float(
723 FloatExpr::from(integer_expr) * float_expr_rhs,
724 )),
725 },
726 Expression::Float(float_expr) => match rhs {
727 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
728 Expression::Natural(natural_expr_rhs) => Ok(Expression::Float(
729 float_expr * FloatExpr::from(natural_expr_rhs),
730 )),
731 Expression::Integer(integer_expr_rhs) => Ok(Expression::Float(
732 float_expr * FloatExpr::from(integer_expr_rhs),
733 )),
734 Expression::Float(float_expr_rhs) => {
735 Ok(Expression::Float(float_expr * float_expr_rhs))
736 }
737 },
738 }
739 }
740}
741
742impl<V: Clone> Div for Expression<V> {
743 type Output = Result<Self, TypeError>;
744
745 fn div(self, rhs: Self) -> Self::Output {
746 match self {
747 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
748 Expression::Natural(natural_expr) => match rhs {
749 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
750 Expression::Natural(natural_expr_rhs) => {
751 Ok(Expression::Natural(natural_expr / natural_expr_rhs))
752 }
753 Expression::Integer(integer_expr_rhs) => Ok(Expression::Integer(
754 IntegerExpr::from(natural_expr) / integer_expr_rhs,
755 )),
756 Expression::Float(float_expr_rhs) => Ok(Expression::Float(
757 FloatExpr::from(natural_expr) / float_expr_rhs,
758 )),
759 },
760 Expression::Integer(integer_expr) => match rhs {
761 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
762 Expression::Natural(natural_expr_rhs) => Ok(Expression::Integer(
763 integer_expr / IntegerExpr::from(natural_expr_rhs),
764 )),
765 Expression::Integer(integer_expr_rhs) => {
766 Ok(Expression::Integer(integer_expr / integer_expr_rhs))
767 }
768 Expression::Float(float_expr_rhs) => Ok(Expression::Float(
769 FloatExpr::from(integer_expr) / float_expr_rhs,
770 )),
771 },
772 Expression::Float(float_expr) => match rhs {
773 Expression::Boolean(_) => Err(TypeError::TypeMismatch),
774 Expression::Natural(natural_expr_rhs) => Ok(Expression::Float(
775 float_expr / FloatExpr::from(natural_expr_rhs),
776 )),
777 Expression::Integer(integer_expr_rhs) => Ok(Expression::Float(
778 float_expr / FloatExpr::from(integer_expr_rhs),
779 )),
780 Expression::Float(float_expr_rhs) => {
781 Ok(Expression::Float(float_expr / float_expr_rhs))
782 }
783 },
784 }
785 }
786}
787
788impl<V: Clone> Rem for Expression<V> {
789 type Output = Result<Self, TypeError>;
790
791 fn rem(self, rhs: Self) -> Self::Output {
792 match self {
793 Expression::Natural(natural_expr) => match rhs {
794 Expression::Natural(natural_expr_rhs) => Ok(Expression::Natural(NaturalExpr::Rem(
795 Box::new((natural_expr, natural_expr_rhs)),
796 ))),
797 Expression::Integer(integer_expr_rhs) => Ok(Expression::Integer(IntegerExpr::Rem(
798 Box::new((IntegerExpr::from(natural_expr), integer_expr_rhs)),
799 ))),
800 Expression::Boolean(_) | Expression::Float(_) => Err(TypeError::TypeMismatch),
801 },
802 Expression::Integer(integer_expr) => match rhs {
803 Expression::Natural(natural_expr_rhs) => Ok(Expression::Integer(IntegerExpr::Rem(
804 Box::new((integer_expr, IntegerExpr::from(natural_expr_rhs))),
805 ))),
806 Expression::Integer(integer_expr_rhs) => Ok(Expression::Integer(IntegerExpr::Rem(
807 Box::new((integer_expr, integer_expr_rhs)),
808 ))),
809 Expression::Boolean(_) | Expression::Float(_) => Err(TypeError::TypeMismatch),
810 },
811 Expression::Boolean(_) | Expression::Float(_) => Err(TypeError::TypeMismatch),
812 }
813 }
814}
815
816impl<V: Clone> BitAnd for Expression<V> {
817 type Output = Result<Self, TypeError>;
818
819 fn bitand(self, rhs: Self) -> Self::Output {
820 if let Expression::Boolean(lhs) = self {
821 if let Expression::Boolean(rhs) = rhs {
822 Ok(Expression::Boolean(lhs & rhs))
823 } else {
824 Err(TypeError::TypeMismatch)
825 }
826 } else {
827 Err(TypeError::TypeMismatch)
828 }
829 }
830}
831
832impl<V: Clone> BitOr for Expression<V> {
833 type Output = Result<Self, TypeError>;
834
835 fn bitor(self, rhs: Self) -> Self::Output {
836 if let Expression::Boolean(lhs) = self {
837 if let Expression::Boolean(rhs) = rhs {
838 Ok(Expression::Boolean(lhs | rhs))
839 } else {
840 Err(TypeError::TypeMismatch)
841 }
842 } else {
843 Err(TypeError::TypeMismatch)
844 }
845 }
846}