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