ospf_rust_math/algebra/value_range/
value_range.rs

1use std::cmp::{max, Ordering};
2use std::fmt::{Debug, Display, Formatter};
3use std::ops::{
4    Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Range, RangeBounds, RangeFrom, RangeFull,
5    RangeInclusive, RangeTo, RangeToInclusive, Sub, SubAssign
6};
7use std::time::{Duration, Instant};
8
9use chrono::NaiveDateTime;
10
11use crate::algebra::concept::*;
12use crate::algebra::operator::*;
13
14use super::bound::*;
15use super::interval::*;
16use super::value_wrapper::*;
17use super::error::IllegalArgumentError;
18
19pub(self) fn empty<T: 'static + PartialOrd>(
20    lb: &ValueWrapper<T>,
21    ub: &ValueWrapper<T>,
22    lb_interval: Interval,
23    ub_interval: Interval,
24) -> bool {
25    if let ValueWrapper::NegInf = lb {
26        false
27    } else if let ValueWrapper::Inf = ub {
28        false
29    } else if let (ValueWrapper::Value(new_lb), ValueWrapper::Value(new_ub)) = (lb, ub) {
30        !(lb_interval.lb_op())(new_lb, new_ub) || !(ub_interval.ub_op())(new_ub, new_lb)
31    } else {
32        true
33    }
34}
35
36pub(self) fn ls<T>(lhs: &Bound<T>, rhs: &Bound<T>) -> Ordering
37where
38    ValueWrapper<T>: PartialOrd,
39{
40    match lhs.value.partial_cmp(&rhs.value).unwrap() {
41        Ordering::Less => Ordering::Less,
42        Ordering::Equal => {
43            if lhs.interval.outer(&rhs.interval) {
44                Ordering::Less
45            } else {
46                Ordering::Greater
47            }
48        }
49        Ordering::Greater => Ordering::Greater,
50    }
51}
52
53pub(self) fn gr<T>(lhs: &Bound<T>, rhs: &Bound<T>) -> Ordering
54where
55    ValueWrapper<T>: PartialOrd,
56{
57    match lhs.value.partial_cmp(&rhs.value).unwrap() {
58        Ordering::Less => Ordering::Less,
59        Ordering::Equal => {
60            if lhs.interval.outer(&rhs.interval) {
61                Ordering::Less
62            } else {
63                Ordering::Greater
64            }
65        }
66        Ordering::Greater => Ordering::Greater,
67    }
68}
69
70#[derive(Clone, Copy)]
71pub struct ValueRange<T> {
72    pub lb: Bound<T>,
73    pub ub: Bound<T>,
74}
75
76impl<T> ValueRange<T> {
77    pub fn new() -> Self {
78        Self {
79            lb: Bound::new(ValueWrapper::NegInf, Interval::Open),
80            ub: Bound::new(ValueWrapper::Inf, Interval::Open),
81        }
82    }
83
84    pub fn new_with_constant(value: T) -> Self where T: Clone {
85        Self {
86            lb: Bound::new(ValueWrapper::Value(value.clone()), Interval::Closed),
87            ub: Bound::new(ValueWrapper::Value(value), Interval::Closed),
88        }
89    }
90
91    pub fn new_with(
92        lb: T,
93        ub: T,
94        lb_interval: Interval,
95        ub_interval: Interval,
96    ) -> Result<Self, IllegalArgumentError>
97    where
98        T: 'static + PartialOrd + Display,
99    {
100        let lower_bound_value = ValueWrapper::Value(lb);
101        let upper_bound_value = ValueWrapper::Value(ub);
102        Self::new_by(
103            lower_bound_value,
104            upper_bound_value,
105            lb_interval,
106            ub_interval,
107        )
108    }
109
110    pub fn new_with_lb(lb: T, lb_interval: Interval) -> Result<Self, IllegalArgumentError>
111    where
112        T: 'static + PartialOrd + Display,
113    {
114        let lower_bound_value = ValueWrapper::Value(lb);
115        Self::new_by(
116            lower_bound_value,
117            ValueWrapper::Inf,
118            lb_interval,
119            Interval::Open,
120        )
121    }
122
123    pub fn new_with_ub(ub: T, ub_interval: Interval) -> Result<Self, IllegalArgumentError>
124    where
125        T: 'static + PartialOrd + Display,
126    {
127        let upper_bound_value = ValueWrapper::Value(ub);
128        Self::new_by(
129            ValueWrapper::NegInf,
130            upper_bound_value,
131            Interval::Open,
132            ub_interval,
133        )
134    }
135
136    pub fn new_by(
137        lb: ValueWrapper<T>,
138        ub: ValueWrapper<T>,
139        lb_interval: Interval,
140        ub_interval: Interval,
141    ) -> Result<Self, IllegalArgumentError>
142    where
143        T: 'static + PartialOrd + Display,
144    {
145        if !empty(&lb, &ub, lb_interval, ub_interval) {
146            Ok(Self {
147                lb: Bound::new(lb, lb_interval),
148                ub: Bound::new(ub, ub_interval),
149            })
150        } else {
151            Err(IllegalArgumentError {
152                msg: format!(
153                    "Invalid range {}{}, {}{}",
154                    lb_interval.lb_sign(),
155                    lb,
156                    ub,
157                    ub_interval.ub_sign()
158                ),
159            })
160        }
161    }
162
163    pub fn fixed(&self) -> bool
164    where
165        T: PartialEq
166    {
167        self.lb.interval == Interval::Closed
168            && self.ub.interval == Interval::Closed
169            && if let (ValueWrapper::Value(lower_value), ValueWrapper::Value(upper_value)) =
170                (&self.lb.value, &self.ub.value)
171            {
172                let eq_op = Equal::new();
173                eq_op(lower_value, upper_value)
174            } else {
175                false
176            }
177    }
178
179    pub fn fixed_value(&self) -> Option<&ValueWrapper<T>>
180    where
181        T: PartialEq
182    {
183        if self.fixed() {
184            Some(&self.lb.value)
185        } else {
186            None
187        }
188    }
189
190    pub fn mean(&self) -> Result<ValueWrapper<T>, IllegalArgumentError>
191    where
192        T: RealNumber,
193        for<'a> &'a ValueWrapper<T>: Add<&'a ValueWrapper<T>, Output = Result<ValueWrapper<T>, IllegalArgumentError>>,
194        ValueWrapper<T>: for<'a> Div<&'a T, Output = Result<ValueWrapper<T>, IllegalArgumentError>>,
195    {
196        (&self.lb.value + &self.ub.value)? / T::TWO
197    }
198
199    pub fn diff(&self) -> Result<ValueWrapper<T>, IllegalArgumentError>
200    where
201        for<'a> &'a ValueWrapper<T>: Sub<&'a ValueWrapper<T>, Output = Result<ValueWrapper<T>, IllegalArgumentError>>,
202    {
203        &self.ub.value - &self.lb.value
204    }
205
206    pub fn gap(&self) -> Result<ValueWrapper<T>, IllegalArgumentError>
207    where
208        T: RealNumber + Ord,
209        for<'a> &'a T: Abs<Output = T>,
210        for<'a> &'a ValueWrapper<T>: Add<&'a ValueWrapper<T>, Output = Result<ValueWrapper<T>, IllegalArgumentError>>,
211        for<'a> &'a ValueWrapper<T>: Sub<&'a ValueWrapper<T>, Output = Result<ValueWrapper<T>, IllegalArgumentError>>,
212        ValueWrapper<T>: for<'a> Div<&'a T, Output = Result<ValueWrapper<T>, IllegalArgumentError>>,
213    {
214        self.diff()? / max(T::DECIMAL_PRECISION, &self.mean()?.unwrap().abs())
215    }
216
217    pub fn union(&self, rhs: &ValueRange<T>) -> Option<ValueRange<T>>
218    where
219        T: 'static + PartialOrd + Display + Clone,
220    {
221        if self.ub.value < rhs.lb.value || rhs.ub.value < self.lb.value {
222            return None;
223        }
224
225        let new_lb = if self.lb.value < rhs.lb.value {
226            &self.lb.value
227        } else {
228            &rhs.lb.value
229        };
230        let new_lb_interval = match self.lb.value.partial_cmp(&rhs.lb.value) {
231            Some(Ordering::Less) => self.lb.interval,
232            Some(Ordering::Greater) => rhs.lb.interval,
233            _ => self.lb.interval.union(&rhs.lb.interval),
234        };
235        let new_ub = if self.ub.value < rhs.ub.value {
236            &rhs.ub.value
237        } else {
238            &self.ub.value
239        };
240        let new_ub_interval = match self.ub.value.partial_cmp(&rhs.ub.value) {
241            Some(Ordering::Less) => rhs.ub.interval,
242            Some(Ordering::Greater) => self.ub.interval,
243            _ => self.ub.interval.union(&rhs.ub.interval),
244        };
245        match ValueRange::new_by(
246            new_lb.clone(),
247            new_ub.clone(),
248            new_lb_interval,
249            new_ub_interval,
250        ) {
251            Ok(new_range) => Some(new_range),
252            Err(_) => None,
253        }
254    }
255
256    pub fn intersect(&self, rhs: &ValueRange<T>) -> Option<ValueRange<T>>
257    where
258        T: 'static + PartialOrd + Display + Clone,
259    {
260        let new_lb = if self.lb.value < rhs.lb.value {
261            &rhs.lb.value
262        } else {
263            &self.lb.value
264        };
265        let new_lb_interval = if self.lb.value.is_inf_or_neg_inf() {
266            rhs.lb.interval
267        } else if rhs.lb.value.is_inf_or_neg_inf() {
268            self.lb.interval
269        } else {
270            match self.lb.value.partial_cmp(&rhs.lb.value) {
271                Some(Ordering::Less) => rhs.lb.interval,
272                Some(Ordering::Greater) => self.lb.interval,
273                _ => self.lb.interval.intersect(&rhs.lb.interval),
274            }
275        };
276        let new_ub = if self.ub.value < rhs.ub.value {
277            &self.ub.value
278        } else {
279            &rhs.ub.value
280        };
281        let new_ub_interval = if self.ub.value.is_inf_or_neg_inf() {
282            rhs.ub.interval
283        } else if rhs.ub.value.is_inf_or_neg_inf() {
284            self.ub.interval
285        } else {
286            match self.ub.value.partial_cmp(&rhs.ub.value) {
287                Some(Ordering::Less) => self.ub.interval,
288                Some(Ordering::Greater) => rhs.ub.interval,
289                _ => self.ub.interval.intersect(&rhs.ub.interval),
290            }
291        };
292        match ValueRange::new_by(
293            new_lb.clone(),
294            new_ub.clone(),
295            new_lb_interval,
296            new_ub_interval,
297        ) {
298            Ok(new_range) => Some(new_range),
299            Err(_) => None,
300        }
301    }
302
303    pub fn contains(&self, value: &T) -> bool
304    where
305        ValueWrapper<T>: PartialOrd<T>,
306        T: 'static,
307    {
308        (self.lb.interval.lb_op())(&self.lb.value, value)
309            && (self.ub.interval.ub_op())(&self.ub.value, value)
310    }
311
312    pub fn contains_range(&self, range: &ValueRange<T>) -> bool
313    where
314        ValueWrapper<T>: PartialOrd,
315        T: 'static,
316    {
317        let lb_interval = self.lb.interval.intersect(&range.lb.interval);
318        let ub_interval = self.ub.interval.intersect(&range.ub.interval);
319        (lb_interval.lb_op())(&self.lb.value, &range.lb.value)
320            && (ub_interval.ub_op())(&self.ub.value, &range.ub.value)
321    }
322}
323
324impl<T: Display> Display for ValueRange<T> {
325    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
326        write!(
327            f,
328            "{}{}, {}{}",
329            self.lb.interval.lb_sign(),
330            self.lb.value,
331            self.ub.value,
332            self.ub.interval.ub_sign()
333        )
334    }
335}
336
337impl<T: Display> Debug for ValueRange<T> {
338    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
339        write!(
340            f,
341            "{}{}, {}{}",
342            self.lb.interval.lb_sign(),
343            self.lb.value,
344            self.ub.value,
345            self.ub.interval.ub_sign()
346        )
347    }
348}
349
350impl<T> From<Range<T>> for ValueRange<T> {
351    fn from(range: Range<T>) -> Self {
352        Self {
353            lb: Bound::new(ValueWrapper::Value(range.start), Interval::Closed),
354            ub: Bound::new(ValueWrapper::Value(range.end), Interval::Open),
355        }
356    }
357}
358
359impl<T: Clone> From<&Range<T>> for ValueRange<T> {
360    fn from(range: &Range<T>) -> Self {
361        Self {
362            lb: Bound::new(ValueWrapper::Value(range.start.clone()), Interval::Closed),
363            ub: Bound::new(ValueWrapper::Value(range.end.clone()), Interval::Open),
364        }
365    }
366}
367
368impl<T> From<RangeFrom<T>> for ValueRange<T> {
369    fn from(range: RangeFrom<T>) -> Self {
370        Self {
371            lb: Bound::new(ValueWrapper::Value(range.start), Interval::Closed),
372            ub: Bound::new(ValueWrapper::Inf, Interval::Open),
373        }
374    }
375}
376
377impl<T: Clone> From<&RangeFrom<T>> for ValueRange<T> {
378    fn from(range: &RangeFrom<T>) -> Self {
379        Self {
380            lb: Bound::new(ValueWrapper::Value(range.start.clone()), Interval::Closed),
381            ub: Bound::new(ValueWrapper::Inf, Interval::Open),
382        }
383    }
384}
385
386impl<T: Clone> From<RangeInclusive<T>> for ValueRange<T> {
387    fn from(range: RangeInclusive<T>) -> Self {
388        Self {
389            lb: Bound::new(ValueWrapper::Value(range.start().clone()), Interval::Closed),
390            ub: Bound::new(ValueWrapper::Value(range.end().clone()), Interval::Closed),
391        }
392    }
393}
394
395impl<T: Clone> From<&RangeInclusive<T>> for ValueRange<T> {
396    fn from(range: &RangeInclusive<T>) -> Self {
397        Self {
398            lb: Bound::new(ValueWrapper::Value(range.start().clone()), Interval::Closed),
399            ub: Bound::new(ValueWrapper::Value(range.end().clone()), Interval::Closed),
400        }
401    }
402}
403
404impl<T> From<RangeTo<T>> for ValueRange<T> {
405    fn from(range: RangeTo<T>) -> Self {
406        Self {
407            lb: Bound::new(ValueWrapper::NegInf, Interval::Open),
408            ub: Bound::new(ValueWrapper::Value(range.end), Interval::Open),
409        }
410    }
411}
412
413impl<T: Clone> From<&RangeTo<T>> for ValueRange<T> {
414    fn from(range: &RangeTo<T>) -> Self {
415        Self {
416            lb: Bound::new(ValueWrapper::NegInf, Interval::Open),
417            ub: Bound::new(ValueWrapper::Value(range.end.clone()), Interval::Open),
418        }
419    }
420}
421
422impl<T> From<RangeToInclusive<T>> for ValueRange<T> {
423    fn from(range: RangeToInclusive<T>) -> Self {
424        Self {
425            lb: Bound::new(ValueWrapper::NegInf, Interval::Open),
426            ub: Bound::new(ValueWrapper::Value(range.end), Interval::Closed),
427        }
428    }
429}
430
431impl<T: Clone> From<&RangeToInclusive<T>> for ValueRange<T> {
432    fn from(range: &RangeToInclusive<T>) -> Self {
433        Self {
434            lb: Bound::new(ValueWrapper::NegInf, Interval::Open),
435            ub: Bound::new(ValueWrapper::Value(range.end.clone()), Interval::Closed),
436        }
437    }
438}
439
440impl From<RangeFull> for ValueRange<i64> {
441    fn from(_range: RangeFull) -> Self {
442        Self {
443            lb: Bound::new(ValueWrapper::NegInf, Interval::Open),
444            ub: Bound::new(ValueWrapper::Inf, Interval::Open),
445        }
446    }
447}
448
449impl<T> From<&RangeFull> for ValueRange<T> {
450    fn from(_range: &RangeFull) -> Self {
451        Self {
452            lb: Bound::new(ValueWrapper::NegInf, Interval::Open),
453            ub: Bound::new(ValueWrapper::Inf, Interval::Open),
454        }
455    }
456}
457
458impl<T, U> From<&ValueRange<U>> for ValueRange<T>
459where
460    Bound<T>: for<'a> From<&'a Bound<U>>,
461{
462    fn from(value: &ValueRange<U>) -> Self {
463        Self {
464            lb: Bound::from(&value.lb),
465            ub: Bound::from(&value.ub),
466        }
467    }
468}
469
470impl<T, U> PartialEq<ValueRange<U>> for ValueRange<T>
471where
472    ValueWrapper<T>: PartialEq<ValueWrapper<U>>,
473{
474    fn eq(&self, other: &ValueRange<U>) -> bool {
475        self.lb == other.lb && self.ub == other.ub
476    }
477}
478
479macro_rules! value_range_template {
480    ($type:ident, $rhs:ident) => {
481        impl Add<$rhs> for ValueRange<$type> {
482            type Output = Result<ValueRange<<$type as Add<$rhs>>::Output>, IllegalArgumentError>;
483
484            fn add(self, rhs: $rhs) -> Self::Output {
485                let new_lb = (self.lb + rhs)?;
486                let new_ub = (self.ub + rhs)?;
487                Ok(ValueRange {
488                    lb: new_lb,
489                    ub: new_ub,
490                })
491            }
492        }
493
494        impl<'a> Add<&'a $rhs> for ValueRange<$type> {
495            type Output = Result<ValueRange<<$type as Add<$rhs>>::Output>, IllegalArgumentError>;
496
497            fn add(self, rhs: &'a $rhs) -> Self::Output {
498                let new_lb = (self.lb + rhs)?;
499                let new_ub = (self.ub + rhs)?;
500                Ok(ValueRange {
501                    lb: new_lb,
502                    ub: new_ub,
503                })
504            }
505        }
506
507        impl<'a> Add<$rhs> for &'a ValueRange<$type> {
508            type Output = Result<ValueRange<<$type as Add<$rhs>>::Output>, IllegalArgumentError>;
509
510            fn add(self, rhs: $rhs) -> Self::Output {
511                let new_lb = (self.lb + rhs)?;
512                let new_ub = (self.ub + rhs)?;
513                Ok(ValueRange {
514                    lb: new_lb,
515                    ub: new_ub,
516                })
517            }
518        }
519
520        impl<'a, 'b> Add<&'b $rhs> for &'a ValueRange<$type> {
521            type Output = Result<ValueRange<<$type as Add<$rhs>>::Output>, IllegalArgumentError>;
522
523            fn add(self, rhs: &'b $rhs) -> Self::Output {
524                let new_lb = (self.lb + rhs)?;
525                let new_ub = (self.ub + rhs)?;
526                Ok(ValueRange {
527                    lb: new_lb,
528                    ub: new_ub,
529                })
530            }
531        }
532
533        impl AddAssign<$rhs> for ValueRange<$type> {
534            fn add_assign(&mut self, rhs: $rhs) {
535                let new_lb = (self.lb + rhs).expect("illegal argument");
536                let new_ub = (self.ub + rhs).expect("illegal argument");
537                self.lb = new_lb;
538                self.ub = new_ub;
539            }
540        }
541
542        impl<'a> AddAssign<&'a $rhs> for ValueRange<$type> {
543            fn add_assign(&mut self, rhs: &'a $rhs) {
544                let new_lb = (self.lb + rhs).expect("illegal argument");
545                let new_ub = (self.ub + rhs).expect("illegal argument");
546                self.lb = new_lb;
547                self.ub = new_ub;
548            }
549        }
550
551        impl Sub<$rhs> for ValueRange<$type> {
552            type Output = Result<ValueRange<<$type as Sub<$rhs>>::Output>, IllegalArgumentError>;
553
554            fn sub(self, rhs: $rhs) -> Self::Output {
555                let new_lb = (self.lb - rhs)?;
556                let new_ub = (self.ub - rhs)?;
557                Ok(ValueRange {
558                    lb: new_lb,
559                    ub: new_ub,
560                })
561            }
562        }
563
564        impl<'a> Sub<&'a $rhs> for ValueRange<$type> {
565            type Output = Result<ValueRange<<$type as Sub<$rhs>>::Output>, IllegalArgumentError>;
566
567            fn sub(self, rhs: &'a $rhs) -> Self::Output {
568                let new_lb = (self.lb - rhs)?;
569                let new_ub = (self.ub - rhs)?;
570                Ok(ValueRange {
571                    lb: new_lb,
572                    ub: new_ub,
573                })
574            }
575        }
576
577        impl<'a> Sub<$rhs> for &'a ValueRange<$type> {
578            type Output = Result<ValueRange<<$type as Sub<$rhs>>::Output>, IllegalArgumentError>;
579
580            fn sub(self, rhs: $rhs) -> Self::Output {
581                let new_lb = (self.lb - rhs)?;
582                let new_ub = (self.ub - rhs)?;
583                Ok(ValueRange {
584                    lb: new_lb,
585                    ub: new_ub,
586                })
587            }
588        }
589
590        impl<'a, 'b> Sub<&'b $rhs> for &'a ValueRange<$type> {
591            type Output = Result<ValueRange<<$type as Sub<$rhs>>::Output>, IllegalArgumentError>;
592
593            fn sub(self, rhs: &'b $rhs) -> Self::Output {
594                let new_lb = (self.lb - rhs)?;
595                let new_ub = (self.ub - rhs)?;
596                Ok(ValueRange {
597                    lb: new_lb,
598                    ub: new_ub,
599                })
600            }
601        }
602
603        impl SubAssign<$rhs> for ValueRange<$type> {
604            fn sub_assign(&mut self, rhs: $rhs) {
605                let new_lb = (self.lb - rhs).expect("illegal argument");
606                let new_ub = (self.ub - rhs).expect("illegal argument");
607                self.lb = new_lb;
608                self.ub = new_ub;
609            }
610        }
611
612        impl<'a> SubAssign<&'a $rhs> for ValueRange<$type> {
613            fn sub_assign(&mut self, rhs: &'a $rhs) {
614                let new_lb = (self.lb - rhs).expect("illegal argument");
615                let new_ub = (self.ub - rhs).expect("illegal argument");
616                self.lb = new_lb;
617                self.ub = new_ub;
618            }
619        }
620    };
621}
622value_range_template!(Instant, Duration);
623value_range_template!(NaiveDateTime, Duration);
624
625macro_rules! signed_value_range_template {
626    ($($type:ident)*) => ($(
627        impl Neg for ValueRange<$type> {
628            type Output = Result<ValueRange<<$type as Neg>::Output>, IllegalArgumentError>;
629
630            fn neg(self) -> Self::Output {
631                let new_lb = (-self.ub)?;
632                let new_ub = (-self.lb)?;
633                Ok(ValueRange {
634                    lb: new_lb,
635                    ub: new_ub,
636                })
637            }
638        }
639
640        impl Neg for &ValueRange<$type> {
641            type Output = Result<ValueRange<<$type as Neg>::Output>, IllegalArgumentError>;
642
643            fn neg(self) -> Self::Output {
644                let new_lb = (-self.ub)?;
645                let new_ub = (-self.lb)?;
646                Ok(ValueRange {
647                    lb: new_lb,
648                    ub: new_ub,
649                })
650            }
651        }
652    )*)
653}
654signed_value_range_template! { i8 i16 i32 i64 i128 isize f32 f64 }
655
656macro_rules! real_number_value_range_template {
657    ($($type:ident)*) => ($(
658        impl Add<$type> for ValueRange<$type> {
659            type Output = Result<ValueRange<<$type as Add<$type>>::Output>, IllegalArgumentError>;
660
661            fn add(self, rhs: $type) -> Self::Output {
662                let new_lb = (self.lb + rhs)?;
663                let new_ub = (self.ub + rhs)?;
664                Ok(ValueRange {
665                    lb: new_lb,
666                    ub: new_ub,
667                })
668            }
669        }
670
671        impl<'a> Add<&'a $type> for ValueRange<$type> {
672            type Output = Result<ValueRange<<$type as Add<&'a $type>>::Output>, IllegalArgumentError>;
673
674            fn add(self, rhs: &'a $type) -> Self::Output {
675                let new_lb = (self.lb + rhs)?;
676                let new_ub = (self.ub + rhs)?;
677                Ok(ValueRange {
678                    lb: new_lb,
679                    ub: new_ub,
680                })
681            }
682        }
683
684        impl<'a> Add<$type> for &'a ValueRange<$type> {
685            type Output = Result<ValueRange<<&'a $type as Add<$type>>::Output>, IllegalArgumentError>;
686
687            fn add(self, rhs: $type) -> Self::Output {
688                let new_lb = (self.lb + rhs)?;
689                let new_ub = (self.ub + rhs)?;
690                Ok(ValueRange {
691                    lb: new_lb,
692                    ub: new_ub,
693                })
694            }
695        }
696
697        impl<'a, 'b> Add<&'b $type> for &'a ValueRange<$type> {
698            type Output = Result<ValueRange<<&'a $type as Add<&'b $type>>::Output>, IllegalArgumentError>;
699
700            fn add(self, rhs: &'b $type) -> Self::Output {
701                let new_lb = (self.lb + rhs)?;
702                let new_ub = (self.ub + rhs)?;
703                Ok(ValueRange {
704                    lb: new_lb,
705                    ub: new_ub,
706                })
707            }
708        }
709
710        impl AddAssign<$type> for ValueRange<$type> {
711            fn add_assign(&mut self, rhs: $type) {
712                let new_lb = (self.lb + rhs).expect("illegal argument");
713                let new_ub = (self.ub + rhs).expect("illegal argument");
714                self.lb = new_lb;
715                self.ub = new_ub;
716            }
717        }
718
719        impl<'a> AddAssign<&'a $type> for ValueRange<$type> {
720            fn add_assign(&mut self, rhs: &'a $type) {
721                let new_lb = (self.lb + rhs).expect("illegal argument");
722                let new_ub = (self.ub + rhs).expect("illegal argument");
723                self.lb = new_lb;
724                self.ub = new_ub;
725            }
726        }
727
728        impl Add<ValueRange<$type>> for $type {
729            type Output = Result<ValueRange<<$type as Add<$type>>::Output>, IllegalArgumentError>;
730
731            fn add(self, rhs: ValueRange<$type>) -> Self::Output {
732                let new_lb = (self + rhs.lb)?;
733                let new_ub = (self + rhs.ub)?;
734                Ok(ValueRange {
735                    lb: new_lb,
736                    ub: new_ub,
737                })
738            }
739        }
740
741        impl<'a> Add<ValueRange<$type>> for &'a $type {
742            type Output = Result<ValueRange<<&'a $type as Add<$type>>::Output>, IllegalArgumentError>;
743
744            fn add(self, rhs: ValueRange<$type>) -> Self::Output {
745                let new_lb = (self + rhs.lb)?;
746                let new_ub = (self + rhs.ub)?;
747                Ok(ValueRange {
748                    lb: new_lb,
749                    ub: new_ub,
750                })
751            }
752        }
753
754        impl<'a> Add<&'a ValueRange<$type>> for $type {
755            type Output = Result<ValueRange<<$type as Add<&'a $type>>::Output>, IllegalArgumentError>;
756
757            fn add(self, rhs: &'a ValueRange<$type>) -> Self::Output {
758                let new_lb = (self + rhs.lb)?;
759                let new_ub = (self + rhs.ub)?;
760                Ok(ValueRange {
761                    lb: new_lb,
762                    ub: new_ub,
763                })
764            }
765        }
766
767        impl<'a, 'b> Add<&'b ValueRange<$type>> for &'a $type {
768            type Output = Result<ValueRange<<&'a $type as Add<&'b $type>>::Output>, IllegalArgumentError>;
769
770            fn add(self, rhs: &'b ValueRange<$type>) -> Self::Output {
771                let new_lb = (self + rhs.lb)?;
772                let new_ub = (self + rhs.ub)?;
773                Ok(ValueRange {
774                    lb: new_lb,
775                    ub: new_ub,
776                })
777            }
778        }
779
780        impl Add<ValueRange<$type>> for ValueRange<$type> {
781            type Output = Result<ValueRange<<$type as Add<$type>>::Output>, IllegalArgumentError>;
782
783            fn add(self, rhs: ValueRange<$type>) -> Self::Output {
784                let new_lb = (self.lb + rhs.lb)?;
785                let new_ub = (self.ub + rhs.ub)?;
786                Ok(ValueRange {
787                    lb: new_lb,
788                    ub: new_ub,
789                })
790            }
791        }
792
793        impl<'a> Add<&'a ValueRange<$type>> for ValueRange<$type> {
794            type Output = Result<ValueRange<<$type as Add<&'a $type>>::Output>, IllegalArgumentError>;
795
796            fn add(self, rhs: &'a ValueRange<$type>) -> Self::Output {
797                let new_lb = (self.lb + rhs.lb)?;
798                let new_ub = (self.ub + rhs.ub)?;
799                Ok(ValueRange {
800                    lb: new_lb,
801                    ub: new_ub,
802                })
803            }
804        }
805
806        impl<'a> Add<ValueRange<$type>> for &'a ValueRange<$type> {
807            type Output = Result<ValueRange<<&'a $type as Add<$type>>::Output>, IllegalArgumentError>;
808
809            fn add(self, rhs: ValueRange<$type>) -> Self::Output {
810                let new_lb = (self.lb + rhs.lb)?;
811                let new_ub = (self.ub + rhs.ub)?;
812                Ok(ValueRange {
813                    lb: new_lb,
814                    ub: new_ub,
815                })
816            }
817        }
818
819        impl<'a, 'b> Add<&'b ValueRange<$type>> for &'a ValueRange<$type> {
820            type Output = Result<ValueRange<<&'a $type as Add<&'b $type>>::Output>, IllegalArgumentError>;
821
822            fn add(self, rhs: &'b ValueRange<$type>) -> Self::Output {
823                let new_lb = (self.lb + rhs.lb)?;
824                let new_ub = (self.ub + rhs.ub)?;
825                Ok(ValueRange {
826                    lb: new_lb,
827                    ub: new_ub,
828                })
829            }
830        }
831
832        impl AddAssign<ValueRange<$type>> for ValueRange<$type> {
833            fn add_assign(&mut self, rhs: ValueRange<$type>) {
834                let new_lb = (self.lb + rhs.lb).expect("illegal argument");
835                let new_ub = (self.ub + rhs.ub).expect("illegal argument");
836                self.lb = new_lb;
837                self.ub = new_ub;
838            }
839        }
840
841        impl<'a> AddAssign<&'a ValueRange<$type>> for ValueRange<$type> {
842            fn add_assign(&mut self, rhs: &'a ValueRange<$type>) {
843                let new_lb = (self.lb + rhs.lb).expect("illegal argument");
844                let new_ub = (self.ub + rhs.ub).expect("illegal argument");
845                self.lb = new_lb;
846                self.ub = new_ub;
847            }
848        }
849
850        impl Sub<$type> for ValueRange<$type> {
851            type Output = Result<ValueRange<<$type as Sub<$type>>::Output>, IllegalArgumentError>;
852
853            fn sub(self, rhs: $type) -> Self::Output {
854                let new_lb = (self.lb - rhs)?;
855                let new_ub = (self.ub - rhs)?;
856                Ok(ValueRange {
857                    lb: new_lb,
858                    ub: new_ub,
859                })
860            }
861        }
862
863        impl<'a> Sub<&'a $type> for ValueRange<$type> {
864            type Output = Result<ValueRange<<$type as Sub<&'a $type>>::Output>, IllegalArgumentError>;
865
866            fn sub(self, rhs: &'a $type) -> Self::Output {
867                let new_lb = (self.lb - rhs)?;
868                let new_ub = (self.ub - rhs)?;
869                Ok(ValueRange {
870                    lb: new_lb,
871                    ub: new_ub,
872                })
873            }
874        }
875
876        impl<'a> Sub<$type> for &'a ValueRange<$type> {
877            type Output = Result<ValueRange<<&'a $type as Sub<$type>>::Output>, IllegalArgumentError>;
878
879            fn sub(self, rhs: $type) -> Self::Output {
880                let new_lb = (self.lb - rhs)?;
881                let new_ub = (self.ub - rhs)?;
882                Ok(ValueRange {
883                    lb: new_lb,
884                    ub: new_ub,
885                })
886            }
887        }
888
889        impl<'a, 'b> Sub<&'b $type> for &'a ValueRange<$type> {
890            type Output = Result<ValueRange<<&'a $type as Sub<&'b $type>>::Output>, IllegalArgumentError>;
891
892            fn sub(self, rhs: &'b $type) -> Self::Output {
893                let new_lb = (self.lb - rhs)?;
894                let new_ub = (self.ub - rhs)?;
895                Ok(ValueRange {
896                    lb: new_lb,
897                    ub: new_ub,
898                })
899            }
900        }
901
902        impl SubAssign<$type> for ValueRange<$type> {
903            fn sub_assign(&mut self, rhs: $type) {
904                let new_lb = (self.lb - rhs).expect("illegal argument");
905                let new_ub = (self.ub - rhs).expect("illegal argument");
906                self.lb = new_lb;
907                self.ub = new_ub;
908            }
909        }
910
911        impl<'a> SubAssign<&'a $type> for ValueRange<$type> {
912            fn sub_assign(&mut self, rhs: &'a $type) {
913                let new_lb = (self.lb - rhs).expect("illegal argument");
914                let new_ub = (self.ub - rhs).expect("illegal argument");
915                self.lb = new_lb;
916                self.ub = new_ub;
917            }
918        }
919
920        impl Sub<ValueRange<$type>> for $type {
921            type Output = Result<ValueRange<<$type as Sub<$type>>::Output>, IllegalArgumentError>;
922
923            fn sub(self, rhs: ValueRange<$type>) -> Self::Output {
924                let new_lb = (self - rhs.ub)?;
925                let new_ub = (self - rhs.lb)?;
926                Ok(ValueRange {
927                    lb: new_lb,
928                    ub: new_ub,
929                })
930            }
931        }
932
933        impl<'a> Sub<ValueRange<$type>> for &'a $type {
934            type Output = Result<ValueRange<<&'a $type as Sub<$type>>::Output>, IllegalArgumentError>;
935
936            fn sub(self, rhs: ValueRange<$type>) -> Self::Output {
937                let new_lb = (self - rhs.ub)?;
938                let new_ub = (self - rhs.lb)?;
939                Ok(ValueRange {
940                    lb: new_lb,
941                    ub: new_ub,
942                })
943            }
944        }
945
946        impl<'a> Sub<&'a ValueRange<$type>> for $type {
947            type Output = Result<ValueRange<<$type as Sub<&'a $type>>::Output>, IllegalArgumentError>;
948
949            fn sub(self, rhs: &'a ValueRange<$type>) -> Self::Output {
950                let new_lb = (self - rhs.ub)?;
951                let new_ub = (self - rhs.lb)?;
952                Ok(ValueRange {
953                    lb: new_lb,
954                    ub: new_ub,
955                })
956            }
957        }
958
959        impl<'a, 'b> Sub<&'b ValueRange<$type>> for &'a $type {
960            type Output = Result<ValueRange<<&'a $type as Sub<&'b $type>>::Output>, IllegalArgumentError>;
961
962            fn sub(self, rhs: &'b ValueRange<$type>) -> Self::Output {
963                let new_lb = (self - rhs.ub)?;
964                let new_ub = (self - rhs.lb)?;
965                Ok(ValueRange {
966                    lb: new_lb,
967                    ub: new_ub,
968                })
969            }
970        }
971
972        impl Sub<ValueRange<$type>> for ValueRange<$type> {
973            type Output = Result<ValueRange<<$type as Sub<$type>>::Output>, IllegalArgumentError>;
974
975            fn sub(self, rhs: ValueRange<$type>) -> Self::Output {
976                let new_lb = (self.lb - rhs.ub)?;
977                let new_ub = (self.ub - rhs.lb)?;
978                Ok(ValueRange {
979                    lb: new_lb,
980                    ub: new_ub,
981                })
982            }
983        }
984
985        impl<'a> Sub<&'a ValueRange<$type>> for ValueRange<$type> {
986            type Output = Result<ValueRange<<$type as Sub<&'a $type>>::Output>, IllegalArgumentError>;
987
988            fn sub(self, rhs: &'a ValueRange<$type>) -> Self::Output {
989                let new_lb = (self.lb - rhs.ub)?;
990                let new_ub = (self.ub - rhs.lb)?;
991                Ok(ValueRange {
992                    lb: new_lb,
993                    ub: new_ub,
994                })
995            }
996        }
997
998        impl<'a> Sub<ValueRange<$type>> for &'a ValueRange<$type> {
999            type Output = Result<ValueRange<<&'a $type as Sub<$type>>::Output>, IllegalArgumentError>;
1000
1001            fn sub(self, rhs: ValueRange<$type>) -> Self::Output {
1002                let new_lb = (self.lb - rhs.ub)?;
1003                let new_ub = (self.ub - rhs.lb)?;
1004                Ok(ValueRange {
1005                    lb: new_lb,
1006                    ub: new_ub,
1007                })
1008            }
1009        }
1010
1011        impl<'a, 'b> Sub<&'b ValueRange<$type>> for &'a ValueRange<$type> {
1012            type Output = Result<ValueRange<<&'a $type as Sub<&'b $type>>::Output>, IllegalArgumentError>;
1013
1014            fn sub(self, rhs: &'b ValueRange<$type>) -> Self::Output {
1015                let new_lb = (self.lb - rhs.ub)?;
1016                let new_ub = (self.ub - rhs.lb)?;
1017                Ok(ValueRange {
1018                    lb: new_lb,
1019                    ub: new_ub,
1020                })
1021            }
1022        }
1023
1024        impl SubAssign<ValueRange<$type>> for ValueRange<$type> {
1025            fn sub_assign(&mut self, rhs: ValueRange<$type>) {
1026                let new_lb = (self.lb - rhs.ub).expect("illegal argument");
1027                let new_ub = (self.ub - rhs.lb).expect("illegal argument");
1028                self.lb = new_lb;
1029                self.ub = new_ub;
1030            }
1031        }
1032
1033        impl<'a> SubAssign<&'a ValueRange<$type>> for ValueRange<$type> {
1034            fn sub_assign(&mut self, rhs: &'a ValueRange<$type>) {
1035                let new_lb = (self.lb - rhs.ub).expect("illegal argument");
1036                let new_ub = (self.ub - rhs.lb).expect("illegal argument");
1037                self.lb = new_lb;
1038                self.ub = new_ub;
1039            }
1040        }
1041
1042        impl Mul<$type> for ValueRange<$type> {
1043            type Output = Result<ValueRange<<$type as Mul<$type>>::Output>, IllegalArgumentError>;
1044
1045            fn mul(self, rhs: $type) -> Self::Output {
1046                if &rhs >= $type::ZERO {
1047                    let new_lb = (self.lb * rhs)?;
1048                    let new_ub = (self.ub * rhs)?;
1049                    Ok(ValueRange {
1050                        lb: new_lb,
1051                        ub: new_ub,
1052                    })
1053                } else {
1054                    let new_lb = (self.ub * rhs)?;
1055                    let new_ub = (self.lb * rhs)?;
1056                    Ok(ValueRange {
1057                        lb: new_lb,
1058                        ub: new_ub,
1059                    })
1060                }
1061            }
1062        }
1063
1064        impl<'a> Mul<&'a $type> for ValueRange<$type> {
1065            type Output = Result<ValueRange<<$type as Mul<&'a $type>>::Output>, IllegalArgumentError>;
1066
1067            fn mul(self, rhs: &'a $type) -> Self::Output {
1068                if rhs >= $type::ZERO {
1069                    let new_lb = (self.lb * rhs)?;
1070                    let new_ub = (self.ub * rhs)?;
1071                    Ok(ValueRange {
1072                        lb: new_lb,
1073                        ub: new_ub,
1074                    })
1075                } else {
1076                    let new_lb = (self.ub * rhs)?;
1077                    let new_ub = (self.lb * rhs)?;
1078                    Ok(ValueRange {
1079                        lb: new_lb,
1080                        ub: new_ub,
1081                    })
1082                }
1083            }
1084        }
1085
1086        impl<'a> Mul<$type> for &'a ValueRange<$type> {
1087            type Output = Result<ValueRange<<&'a $type as Mul<$type>>::Output>, IllegalArgumentError>;
1088
1089            fn mul(self, rhs: $type) -> Self::Output {
1090                if &rhs >= $type::ZERO {
1091                    let new_lb = (self.lb * rhs)?;
1092                    let new_ub = (self.ub * rhs)?;
1093                    Ok(ValueRange {
1094                        lb: new_lb,
1095                        ub: new_ub,
1096                    })
1097                } else {
1098                    let new_lb = (self.ub * rhs)?;
1099                    let new_ub = (self.lb * rhs)?;
1100                    Ok(ValueRange {
1101                        lb: new_lb,
1102                        ub: new_ub,
1103                    })
1104                }
1105            }
1106        }
1107
1108        impl<'a, 'b> Mul<&'b $type> for &'a ValueRange<$type> {
1109            type Output = Result<ValueRange<<&'a $type as Mul<&'b $type>>::Output>, IllegalArgumentError>;
1110
1111            fn mul(self, rhs: &'b $type) -> Self::Output {
1112                if rhs >= $type::ZERO {
1113                    let new_lb = (self.lb * rhs)?;
1114                    let new_ub = (self.ub * rhs)?;
1115                    Ok(ValueRange {
1116                        lb: new_lb,
1117                        ub: new_ub,
1118                    })
1119                } else {
1120                    let new_lb = (self.ub * rhs)?;
1121                    let new_ub = (self.lb * rhs)?;
1122                    Ok(ValueRange {
1123                        lb: new_lb,
1124                        ub: new_ub,
1125                    })
1126                }
1127            }
1128        }
1129
1130        impl MulAssign<$type> for ValueRange<$type> {
1131            fn mul_assign(&mut self, rhs: $type) {
1132                if &rhs >= $type::ZERO {
1133                    let new_lb = (self.lb * rhs).expect("illegal argument");
1134                    let new_ub = (self.ub * rhs).expect("illegal argument");
1135                    self.lb = new_lb;
1136                    self.ub = new_ub;
1137                } else {
1138                    let new_lb = (self.ub * rhs).expect("illegal argument");
1139                    let new_ub = (self.lb * rhs).expect("illegal argument");
1140                    self.lb = new_lb;
1141                    self.ub = new_ub;
1142                }
1143            }
1144        }
1145
1146        impl<'a> MulAssign<&'a $type> for ValueRange<$type> {
1147            fn mul_assign(&mut self, rhs: &'a $type) {
1148                if rhs >= $type::ZERO {
1149                    let new_lb = (self.lb * rhs).expect("illegal argument");
1150                    let new_ub = (self.ub * rhs).expect("illegal argument");
1151                    self.lb = new_lb;
1152                    self.ub = new_ub;
1153                } else {
1154                    let new_lb = (self.ub * rhs).expect("illegal argument");
1155                    let new_ub = (self.lb * rhs).expect("illegal argument");
1156                    self.lb = new_lb;
1157                    self.ub = new_ub;
1158                }
1159            }
1160        }
1161
1162        impl Mul<ValueRange<$type>> for $type {
1163            type Output = Result<ValueRange<<$type as Mul<$type>>::Output>, IllegalArgumentError>;
1164
1165            fn mul(self, rhs: ValueRange<$type>) -> Self::Output {
1166                if &self >= $type::ZERO {
1167                    let new_lb = (self * rhs.lb)?;
1168                    let new_ub = (self * rhs.ub)?;
1169                    Ok(ValueRange {
1170                        lb: new_lb,
1171                        ub: new_ub,
1172                    })
1173                } else {
1174                    let new_lb = (self * rhs.ub)?;
1175                    let new_ub = (self * rhs.lb)?;
1176                    Ok(ValueRange {
1177                        lb: new_lb,
1178                        ub: new_ub,
1179                    })
1180                }
1181            }
1182        }
1183
1184        impl<'a> Mul<ValueRange<$type>> for &'a $type {
1185            type Output = Result<ValueRange<<&'a $type as Mul<$type>>::Output>, IllegalArgumentError>;
1186
1187            fn mul(self, rhs: ValueRange<$type>) -> Self::Output {
1188                if self >= $type::ZERO {
1189                    let new_lb = (self * rhs.lb)?;
1190                    let new_ub = (self * rhs.ub)?;
1191                    Ok(ValueRange {
1192                        lb: new_lb,
1193                        ub: new_ub,
1194                    })
1195                } else {
1196                    let new_lb = (self * rhs.ub)?;
1197                    let new_ub = (self * rhs.lb)?;
1198                    Ok(ValueRange {
1199                        lb: new_lb,
1200                        ub: new_ub,
1201                    })
1202                }
1203            }
1204        }
1205
1206        impl<'a> Mul<&'a ValueRange<$type>> for $type {
1207            type Output = Result<ValueRange<<$type as Mul<&'a $type>>::Output>, IllegalArgumentError>;
1208
1209            fn mul(self, rhs: &'a ValueRange<$type>) -> Self::Output {
1210                if &self >= $type::ZERO {
1211                    let new_lb = (self * rhs.lb)?;
1212                    let new_ub = (self * rhs.ub)?;
1213                    Ok(ValueRange {
1214                        lb: new_lb,
1215                        ub: new_ub,
1216                    })
1217                } else {
1218                    let new_lb = (self * rhs.ub)?;
1219                    let new_ub = (self * rhs.lb)?;
1220                    Ok(ValueRange {
1221                        lb: new_lb,
1222                        ub: new_ub,
1223                    })
1224                }
1225            }
1226        }
1227
1228        impl<'a, 'b> Mul<&'b ValueRange<$type>> for &'a $type {
1229            type Output = Result<ValueRange<<&'a $type as Mul<&'b $type>>::Output>, IllegalArgumentError>;
1230
1231            fn mul(self, rhs: &'b ValueRange<$type>) -> Self::Output {
1232                if self >= $type::ZERO {
1233                    let new_lb = (self * rhs.lb)?;
1234                    let new_ub = (self * rhs.ub)?;
1235                    Ok(ValueRange {
1236                        lb: new_lb,
1237                        ub: new_ub,
1238                    })
1239                } else {
1240                    let new_lb = (self * rhs.ub)?;
1241                    let new_ub = (self * rhs.lb)?;
1242                    Ok(ValueRange {
1243                        lb: new_lb,
1244                        ub: new_ub,
1245                    })
1246                }
1247            }
1248        }
1249
1250        impl Mul<ValueRange<$type>> for ValueRange<$type> {
1251            type Output = Result<ValueRange<<$type as Mul<$type>>::Output>, IllegalArgumentError>;
1252
1253            fn mul(self, rhs: ValueRange<$type>) -> Self::Output {
1254                let bounds = vec![(self.lb * rhs.lb)?, (self.lb * rhs.ub)?, (self.ub * rhs.lb)?, (self.ub * rhs.ub)?];
1255                let new_lb = bounds.iter().min_by(|lhs, rhs| ls(lhs, rhs)).unwrap();
1256                let new_ub = bounds.iter().max_by(|lhs, rhs| gr(lhs, rhs)).unwrap();
1257                Ok(ValueRange {
1258                    lb: *new_lb,
1259                    ub: *new_ub,
1260                })
1261            }
1262        }
1263
1264        impl<'a> Mul<&'a ValueRange<$type>> for ValueRange<$type> {
1265            type Output = Result<ValueRange<<$type as Mul<&'a $type>>::Output>, IllegalArgumentError>;
1266
1267            fn mul(self, rhs: &'a ValueRange<$type>) -> Self::Output {
1268                let bounds = vec![(self.lb * rhs.lb)?, (self.lb * rhs.ub)?, (self.ub * rhs.lb)?, (self.ub * rhs.ub)?];
1269                let new_lb = bounds.iter().min_by(|lhs, rhs| ls(lhs, rhs)).unwrap();
1270                let new_ub = bounds.iter().max_by(|lhs, rhs| gr(lhs, rhs)).unwrap();
1271                Ok(ValueRange {
1272                    lb: *new_lb,
1273                    ub: *new_ub,
1274                })
1275            }
1276        }
1277
1278        impl<'a> Mul<ValueRange<$type>> for &'a ValueRange<$type> {
1279            type Output = Result<ValueRange<<&'a $type as Mul<$type>>::Output>, IllegalArgumentError>;
1280
1281            fn mul(self, rhs: ValueRange<$type>) -> Self::Output {
1282                let bounds = vec![(self.lb * rhs.lb)?, (self.lb * rhs.ub)?, (self.ub * rhs.lb)?, (self.ub * rhs.ub)?];
1283                let new_lb = bounds.iter().min_by(|lhs, rhs| ls(lhs, rhs)).unwrap();
1284                let new_ub = bounds.iter().max_by(|lhs, rhs| gr(lhs, rhs)).unwrap();
1285                Ok(ValueRange {
1286                    lb: *new_lb,
1287                    ub: *new_ub,
1288                })
1289            }
1290        }
1291
1292        impl<'a, 'b> Mul<&'b ValueRange<$type>> for &'a ValueRange<$type> {
1293            type Output = Result<ValueRange<<&'a $type as Mul<&'b $type>>::Output>, IllegalArgumentError>;
1294
1295            fn mul(self, rhs: &'b ValueRange<$type>) -> Self::Output {
1296                let bounds = vec![(self.lb * rhs.lb)?, (self.lb * rhs.ub)?, (self.ub * rhs.lb)?, (self.ub * rhs.ub)?];
1297                let new_lb = bounds.iter().min_by(|lhs, rhs| ls(lhs, rhs)).unwrap();
1298                let new_ub = bounds.iter().max_by(|lhs, rhs| gr(lhs, rhs)).unwrap();
1299                Ok(ValueRange {
1300                    lb: *new_lb,
1301                    ub: *new_ub,
1302                })
1303            }
1304        }
1305
1306        impl MulAssign<ValueRange<$type>> for ValueRange<$type> {
1307            fn mul_assign(&mut self, rhs: ValueRange<$type>) {
1308                let bounds = vec![
1309                    (self.lb * rhs.lb).expect("illegal argument"),
1310                    (self.lb * rhs.ub).expect("illegal argument"),
1311                    (self.ub * rhs.lb).expect("illegal argument"),
1312                    (self.ub * rhs.ub).expect("illegal argument")
1313                ];
1314                let new_lb = bounds.iter().min_by(|lhs, rhs| ls(lhs, rhs)).unwrap();
1315                let new_ub = bounds.iter().max_by(|lhs, rhs| gr(lhs, rhs)).unwrap();
1316                self.lb = *new_lb;
1317                self.ub = *new_ub;
1318            }
1319        }
1320
1321        impl<'a> MulAssign<&'a ValueRange<$type>> for ValueRange<$type> {
1322            fn mul_assign(&mut self, rhs: &'a ValueRange<$type>) {
1323                let bounds = vec![
1324                    (self.lb * rhs.lb).expect("illegal argument"),
1325                    (self.lb * rhs.ub).expect("illegal argument"),
1326                    (self.ub * rhs.lb).expect("illegal argument"),
1327                    (self.ub * rhs.ub).expect("illegal argument")
1328                ];
1329                let new_lb = bounds.iter().min_by(|lhs, rhs| ls(lhs, rhs)).unwrap();
1330                let new_ub = bounds.iter().max_by(|lhs, rhs| gr(lhs, rhs)).unwrap();
1331                self.lb = *new_lb;
1332                self.ub = *new_ub;
1333            }
1334        }
1335
1336        impl Div<$type> for ValueRange<$type> {
1337            type Output = Result<ValueRange<<$type as Div<$type>>::Output>, IllegalArgumentError>;
1338
1339            fn div(self, rhs: $type) -> Self::Output {
1340                if &rhs > $type::ZERO {
1341                    let new_lb = (self.lb / rhs)?;
1342                    let new_ub = (self.ub / rhs)?;
1343                    Ok(ValueRange {
1344                        lb: new_lb,
1345                        ub: new_ub,
1346                    })
1347                } else if &rhs < $type::ZERO {
1348                    let new_lb = (self.ub / rhs)?;
1349                    let new_ub = (self.lb / rhs)?;
1350                    Ok(ValueRange {
1351                        lb: new_lb,
1352                        ub: new_ub,
1353                    })
1354                } else {
1355                    Err(IllegalArgumentError {
1356                        msg: "division by zero".to_string()
1357                    })
1358                }
1359            }
1360        }
1361
1362        impl<'a> Div<&'a $type> for ValueRange<$type> {
1363            type Output = Result<ValueRange<<$type as Div<&'a $type>>::Output>, IllegalArgumentError>;
1364
1365            fn div(self, rhs: &'a $type) -> Self::Output {
1366                if rhs > $type::ZERO {
1367                    let new_lb = (self.lb / rhs)?;
1368                    let new_ub = (self.ub / rhs)?;
1369                    Ok(ValueRange {
1370                        lb: new_lb,
1371                        ub: new_ub,
1372                    })
1373                } else if rhs < $type::ZERO {
1374                    let new_lb = (self.ub / rhs)?;
1375                    let new_ub = (self.lb / rhs)?;
1376                    Ok(ValueRange {
1377                        lb: new_lb,
1378                        ub: new_ub,
1379                    })
1380                } else {
1381                    Err(IllegalArgumentError {
1382                        msg: "division by zero".to_string()
1383                    })
1384                }
1385            }
1386        }
1387
1388        impl<'a> Div<$type> for &'a ValueRange<$type> {
1389            type Output = Result<ValueRange<<&'a $type as Div<$type>>::Output>, IllegalArgumentError>;
1390
1391            fn div(self, rhs: $type) -> Self::Output {
1392                if &rhs > $type::ZERO {
1393                    let new_lb = (self.lb / rhs)?;
1394                    let new_ub = (self.ub / rhs)?;
1395                    Ok(ValueRange {
1396                        lb: new_lb,
1397                        ub: new_ub,
1398                    })
1399                } else if &rhs < $type::ZERO {
1400                    let new_lb = (self.ub / rhs)?;
1401                    let new_ub = (self.lb / rhs)?;
1402                    Ok(ValueRange {
1403                        lb: new_lb,
1404                        ub: new_ub,
1405                    })
1406                } else {
1407                    Err(IllegalArgumentError {
1408                        msg: "division by zero".to_string()
1409                    })
1410                }
1411            }
1412        }
1413
1414        impl<'a, 'b> Div<&'b $type> for &'a ValueRange<$type> {
1415            type Output = Result<ValueRange<<&'a $type as Div<&'b $type>>::Output>, IllegalArgumentError>;
1416
1417            fn div(self, rhs: &'b $type) -> Self::Output {
1418                if rhs > $type::ZERO {
1419                    let new_lb = (self.lb / rhs)?;
1420                    let new_ub = (self.ub / rhs)?;
1421                    Ok(ValueRange {
1422                        lb: new_lb,
1423                        ub: new_ub,
1424                    })
1425                } else if rhs < $type::ZERO {
1426                    let new_lb = (self.ub / rhs)?;
1427                    let new_ub = (self.lb / rhs)?;
1428                    Ok(ValueRange {
1429                        lb: new_lb,
1430                        ub: new_ub,
1431                    })
1432                } else {
1433                    Err(IllegalArgumentError {
1434                        msg: "division by zero".to_string()
1435                    })
1436                }
1437            }
1438        }
1439
1440        impl DivAssign<$type> for ValueRange<$type> {
1441            fn div_assign(&mut self, rhs: $type) {
1442                if &rhs > $type::ZERO {
1443                    let new_lb = (self.lb / rhs).expect("illegal argument");
1444                    let new_ub = (self.ub / rhs).expect("illegal argument");
1445                    self.lb = new_lb;
1446                    self.ub = new_ub;
1447                } else if &rhs < $type::ZERO {
1448                    let new_lb = (self.ub / rhs).expect("illegal argument");
1449                    let new_ub = (self.lb / rhs).expect("illegal argument");
1450                    self.lb = new_lb;
1451                    self.ub = new_ub;
1452                } else {
1453                    panic!("division by zero")
1454                }
1455            }
1456        }
1457
1458        impl<'a> DivAssign<&'a $type> for ValueRange<$type> {
1459            fn div_assign(&mut self, rhs: &'a $type) {
1460                if rhs > $type::ZERO {
1461                    let new_lb = (self.lb / rhs).expect("illegal argument");
1462                    let new_ub = (self.ub / rhs).expect("illegal argument");
1463                    self.lb = new_lb;
1464                    self.ub = new_ub;
1465                } else if rhs < $type::ZERO {
1466                    let new_lb = (self.ub / rhs).expect("illegal argument");
1467                    let new_ub = (self.lb / rhs).expect("illegal argument");
1468                    self.lb = new_lb;
1469                    self.ub = new_ub;
1470                } else {
1471                    panic!("division by zero")
1472                }
1473            }
1474        }
1475
1476        impl Div<ValueRange<$type>> for $type {
1477            type Output = Result<ValueRange<<$type as Div<$type>>::Output>, IllegalArgumentError>;
1478
1479            fn div(self, rhs: ValueRange<$type>) -> Self::Output {
1480                if &self > $type::ZERO {
1481                    let new_lb = (self / rhs.lb)?;
1482                    let new_ub = (self / rhs.ub)?;
1483                    Ok(ValueRange {
1484                        lb: new_lb,
1485                        ub: new_ub,
1486                    })
1487                } else if &self < $type::ZERO {
1488                    let new_lb = (self / rhs.ub)?;
1489                    let new_ub = (self / rhs.lb)?;
1490                    Ok(ValueRange {
1491                        lb: new_lb,
1492                        ub: new_ub,
1493                    })
1494                } else {
1495                    Err(IllegalArgumentError {
1496                        msg: "division by zero".to_string()
1497                    })
1498                }
1499            }
1500        }
1501
1502        impl<'a> Div<ValueRange<$type>> for &'a $type {
1503            type Output = Result<ValueRange<<&'a $type as Div<$type>>::Output>, IllegalArgumentError>;
1504
1505            fn div(self, rhs: ValueRange<$type>) -> Self::Output {
1506                if self > $type::ZERO {
1507                    let new_lb = (self / rhs.lb)?;
1508                    let new_ub = (self / rhs.ub)?;
1509                    Ok(ValueRange {
1510                        lb: new_lb,
1511                        ub: new_ub,
1512                    })
1513                } else if self < $type::ZERO {
1514                    let new_lb = (self / rhs.ub)?;
1515                    let new_ub = (self / rhs.lb)?;
1516                    Ok(ValueRange {
1517                        lb: new_lb,
1518                        ub: new_ub,
1519                    })
1520                } else {
1521                    Err(IllegalArgumentError {
1522                        msg: "division by zero".to_string()
1523                    })
1524                }
1525            }
1526        }
1527
1528        impl<'a> Div<&'a ValueRange<$type>> for $type {
1529            type Output = Result<ValueRange<<$type as Div<&'a $type>>::Output>, IllegalArgumentError>;
1530
1531            fn div(self, rhs: &'a ValueRange<$type>) -> Self::Output {
1532                if &self > $type::ZERO {
1533                    let new_lb = (self / rhs.lb)?;
1534                    let new_ub = (self / rhs.ub)?;
1535                    Ok(ValueRange {
1536                        lb: new_lb,
1537                        ub: new_ub,
1538                    })
1539                } else if &self < $type::ZERO {
1540                    let new_lb = (self / rhs.ub)?;
1541                    let new_ub = (self / rhs.lb)?;
1542                    Ok(ValueRange {
1543                        lb: new_lb,
1544                        ub: new_ub,
1545                    })
1546                } else {
1547                    Err(IllegalArgumentError {
1548                        msg: "division by zero".to_string()
1549                    })
1550                }
1551            }
1552        }
1553
1554        impl<'a, 'b> Div<&'b ValueRange<$type>> for &'a $type {
1555            type Output = Result<ValueRange<<&'a $type as Div<&'b $type>>::Output>, IllegalArgumentError>;
1556
1557            fn div(self, rhs: &'b ValueRange<$type>) -> Self::Output {
1558                if self > $type::ZERO {
1559                    let new_lb = (self / rhs.lb)?;
1560                    let new_ub = (self / rhs.ub)?;
1561                    Ok(ValueRange {
1562                        lb: new_lb,
1563                        ub: new_ub,
1564                    })
1565                } else if self < $type::ZERO {
1566                    let new_lb = (self / rhs.ub)?;
1567                    let new_ub = (self / rhs.lb)?;
1568                    Ok(ValueRange {
1569                        lb: new_lb,
1570                        ub: new_ub,
1571                    })
1572                } else {
1573                    Err(IllegalArgumentError {
1574                        msg: "division by zero".to_string()
1575                    })
1576                }
1577            }
1578        }
1579    )*)
1580}
1581real_number_value_range_template! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64 }
1582
1583#[macro_export]
1584macro_rules! value_range {
1585    ((..,$ub:expr)) => {
1586        ValueRange::new_with_ub($ub, Interval::Open)
1587    };
1588    (($lb:expr,..)) => {
1589        ValueRange::new_with_lb($lb, Interval::Open)
1590    };
1591    (($lb:expr, $ub:expr)) => {
1592        ValueRange::new_with($lb, $ub, Interval::Open, Interval::Open)
1593    };
1594    ([..,$ub:expr]) => {
1595        ValueRange::new_with_ub($ub, Interval::Closed)
1596    };
1597    ([$lb:expr,..]) => {
1598        ValueRange::new_with_lb($lb, Interval::Closed)
1599    };
1600    ([$lb:expr, $ub:expr]) => {
1601        ValueRange::new_with($lb, $ub, Interval::Closed, Interval::Closed)
1602    };
1603    (($lb:expr)..($ub:expr)) => {
1604        ValueRange::new_with($lb, $ub, Interval::Open, Interval::Open)
1605    };
1606    (($lb:expr)..=($ub:expr)) => {
1607        ValueRange::new_with($lb, $ub, Interval::Closed, Interval::Closed)
1608    };
1609    (($lb:expr)..) => {
1610        ValueRange::new_with_lb($lb, Interval::Closed)
1611    };
1612    (..($ub:expr)) => {
1613        ValueRange::new_with_ub($ub, Interval::Open)
1614    };
1615    (..=($ub:expr)) => {
1616        ValueRange::new_with_ub($ub, Interval::Closed)
1617    };
1618}
1619
1620#[cfg(test)]
1621mod tests {
1622    use super::*;
1623
1624    #[test]
1625    fn test_constructor() {
1626        let open_range = value_range!((1.0f64, 2.0f64));
1627        assert!(open_range.is_ok());
1628        assert_eq!(open_range.as_ref().unwrap().lb.value.unwrap(), &1.0);
1629        assert_eq!(open_range.as_ref().unwrap().ub.interval, Interval::Open);
1630        assert_eq!(open_range.as_ref().unwrap().ub.value.unwrap(), &2.0);
1631        assert_eq!(open_range.as_ref().unwrap().ub.interval, Interval::Open);
1632        let closed_range = value_range!([1.0f64, 2.0f64]);
1633        assert!(closed_range.is_ok());
1634        assert_eq!(closed_range.as_ref().unwrap().lb.value.unwrap(), &1.0);
1635        assert_eq!(closed_range.as_ref().unwrap().ub.interval, Interval::Closed);
1636        assert_eq!(closed_range.as_ref().unwrap().ub.value.unwrap(), &2.0);
1637        assert_eq!(closed_range.as_ref().unwrap().ub.interval, Interval::Closed);
1638        let range_range = value_range!((1.0f64)..(2.0f64)).unwrap();
1639        assert_eq!(range_range.lb.value.unwrap(), &1.0);
1640        assert_eq!(range_range.ub.interval, Interval::Open);
1641        assert_eq!(range_range.ub.value.unwrap(), &2.0);
1642        assert_eq!(range_range.ub.interval, Interval::Open);
1643        let range_inclusive_range = value_range!((1.0f64)..=(2.0f64)).unwrap();
1644        assert_eq!(range_inclusive_range.lb.value.unwrap(), &1.0);
1645        assert_eq!(range_inclusive_range.ub.interval, Interval::Closed);
1646        assert_eq!(range_inclusive_range.ub.value.unwrap(), &2.0);
1647        assert_eq!(range_inclusive_range.ub.interval, Interval::Closed);
1648        let invalid_range = value_range!([2.0f64, 1.0f64]);
1649        assert!(invalid_range.is_err());
1650    }
1651
1652    #[test]
1653    fn test_plus() {
1654        let range = value_range!([1.0f64, 2.0f64]).unwrap();
1655        let added_range = (range + 1.0f64).unwrap();
1656        assert_eq!(added_range.lb.value.unwrap(), &2.0);
1657        assert_eq!(added_range.ub.value.unwrap(), &3.0);
1658        let twice_range = (range + range).unwrap();
1659        assert_eq!(twice_range.lb.value.unwrap(), &2.0);
1660        assert_eq!(twice_range.ub.value.unwrap(), &4.0);
1661        let inf_range = (range + f64::INFINITY).unwrap();
1662        assert_eq!(inf_range.lb.value.unwrap(), f64::INF.as_ref().unwrap());
1663        assert_eq!(inf_range.lb.interval, Interval::Open);
1664        assert_eq!(inf_range.ub.value.unwrap(), f64::INF.as_ref().unwrap());
1665        assert_eq!(inf_range.ub.interval, Interval::Open);
1666        let neg_inf_range = (range - f64::INFINITY).unwrap();
1667        assert_eq!(
1668            neg_inf_range.lb.value.unwrap(),
1669            f64::NEG_INF.as_ref().unwrap()
1670        );
1671        assert_eq!(neg_inf_range.lb.interval, Interval::Open);
1672        assert_eq!(
1673            neg_inf_range.ub.value.unwrap(),
1674            f64::NEG_INF.as_ref().unwrap()
1675        );
1676        assert_eq!(neg_inf_range.ub.interval, Interval::Open);
1677        let inf_range2 = (value_range!([1.0f64, ..]).unwrap() + 1.0f64).unwrap();
1678        assert_eq!(inf_range2.lb.value.unwrap(), &2.0);
1679        assert_eq!(inf_range2.lb.interval, Interval::Closed);
1680        assert_eq!(inf_range2.ub.value.unwrap(), f64::INF.as_ref().unwrap());
1681        assert_eq!(inf_range2.ub.interval, Interval::Open);
1682        let neg_inf_range2 = (value_range!([.., 1.0f64]).unwrap() + 1.0f64).unwrap();
1683        assert_eq!(
1684            neg_inf_range2.lb.value.unwrap(),
1685            f64::NEG_INF.as_ref().unwrap()
1686        );
1687        assert_eq!(neg_inf_range2.lb.interval, Interval::Open);
1688        assert_eq!(neg_inf_range2.ub.value.unwrap(), &2.0);
1689        assert_eq!(neg_inf_range2.ub.interval, Interval::Closed);
1690    }
1691
1692    #[test]
1693    fn test_subtract() {
1694        let range = value_range!([1.0f64, 2.0f64]).unwrap();
1695        let added_range = (range - 1.0f64).unwrap();
1696        assert_eq!(added_range.lb.value.unwrap(), &0.0);
1697        assert_eq!(added_range.ub.value.unwrap(), &1.0);
1698        let twice_range = (range - range).unwrap();
1699        assert_eq!(twice_range.lb.value.unwrap(), &-1.0);
1700        assert_eq!(twice_range.ub.value.unwrap(), &1.0);
1701    }
1702
1703    #[test]
1704    fn test_multiply() {
1705        let range = value_range!([1.0f64, 2.0f64]).unwrap();
1706        let zero_range = (range * 0.0f64).unwrap();
1707        assert!(zero_range.fixed());
1708        assert_eq!(zero_range.fixed_value().unwrap().unwrap(), &0.0);
1709        let twice_range = (range * 2.0f64).unwrap();
1710        assert_eq!(twice_range.lb.value.unwrap(), &2.0);
1711        assert_eq!(twice_range.ub.value.unwrap(), &4.0);
1712        let neg_twice_range = (range * -2.0f64).unwrap();
1713        assert_eq!(neg_twice_range.lb.value.unwrap(), &-4.0);
1714        assert_eq!(neg_twice_range.ub.value.unwrap(), &-2.0);
1715        let square_range = (range * range).unwrap();
1716        assert_eq!(square_range.lb.value.unwrap(), &1.0);
1717        assert_eq!(square_range.ub.value.unwrap(), &4.0);
1718    }
1719
1720    #[test]
1721    fn test_divide() {
1722        let range = value_range!([1.0f64, 2.0f64]).unwrap();
1723        let half_range = (range / 2.0f64).unwrap();
1724        assert_eq!(half_range.lb.value.unwrap(), &0.5);
1725        assert_eq!(half_range.ub.value.unwrap(), &1.0);
1726        let neg_half_range = (range / -2.0f64).unwrap();
1727        assert_eq!(neg_half_range.lb.value.unwrap(), &-1.0);
1728        assert_eq!(neg_half_range.ub.value.unwrap(), &-0.5);
1729    }
1730
1731    #[test]
1732    fn test_intersection() {
1733        let range = value_range!([1.0f64, 3.0f64]).unwrap();
1734        let left_half_range1 = value_range!([0.0f64, 2.0f64]).unwrap().intersect(&range);
1735        assert!(left_half_range1.is_some());
1736        assert_eq!(left_half_range1.unwrap().lb.value.unwrap(), &1.0);
1737        assert_eq!(left_half_range1.unwrap().ub.value.unwrap(), &2.0);
1738        let right_half_range1 = range.intersect(&value_range!([0.0f64, 2.0f64]).unwrap());
1739        assert!(right_half_range1.is_some());
1740        assert_eq!(right_half_range1.unwrap().lb.value.unwrap(), &1.0);
1741        assert_eq!(right_half_range1.unwrap().ub.value.unwrap(), &2.0);
1742        let left_half_range2 = value_range!([2.0f64, 4.0f64]).unwrap().intersect(&range);
1743        assert!(left_half_range2.is_some());
1744        assert_eq!(left_half_range2.unwrap().lb.value.unwrap(), &2.0);
1745        assert_eq!(left_half_range2.unwrap().ub.value.unwrap(), &3.0);
1746        let right_half_range2 = range.intersect(&value_range!([2.0f64, 4.0f64]).unwrap());
1747        assert!(right_half_range2.is_some());
1748        assert_eq!(right_half_range2.unwrap().lb.value.unwrap(), &2.0);
1749        assert_eq!(right_half_range2.unwrap().ub.value.unwrap(), &3.0);
1750        let none_range = range.intersect(&value_range!([4.0f64, 10.0f64]).unwrap());
1751        assert!(none_range.is_none());
1752        let inf_range = range.intersect(&value_range!([1.0f64, ..]).unwrap());
1753        assert!(inf_range.is_some());
1754        assert_eq!(inf_range.as_ref().unwrap().lb.value.unwrap(), &1.0);
1755        assert_eq!(inf_range.as_ref().unwrap().lb.interval, Interval::Closed);
1756        assert_eq!(inf_range.as_ref().unwrap().ub.value.unwrap(), &3.0);
1757        assert_eq!(inf_range.as_ref().unwrap().ub.interval, Interval::Closed);
1758        let neg_inf_range = range.intersect(&value_range!([.., 2.0f64]).unwrap());
1759        assert!(neg_inf_range.is_some());
1760        assert_eq!(neg_inf_range.as_ref().unwrap().lb.value.unwrap(), &1.0);
1761        assert_eq!(
1762            neg_inf_range.as_ref().unwrap().lb.interval,
1763            Interval::Closed
1764        );
1765        assert_eq!(neg_inf_range.as_ref().unwrap().ub.value.unwrap(), &2.0);
1766        assert_eq!(
1767            neg_inf_range.as_ref().unwrap().ub.interval,
1768            Interval::Closed
1769        );
1770    }
1771
1772    #[test]
1773    fn test_union() {
1774        let range = value_range!([1.0f64, 3.0f64]).unwrap();
1775        let union_range1 = range.union(&value_range!([0.0f64, 2.0f64]).unwrap());
1776        assert!(union_range1.is_some());
1777        assert_eq!(union_range1.unwrap().lb.value.unwrap(), &0.0);
1778        assert_eq!(union_range1.unwrap().ub.value.unwrap(), &3.0);
1779        let union_range2 = range.union(&value_range!([2.0f64, 10.0f64]).unwrap());
1780        assert!(union_range2.is_some());
1781        assert_eq!(union_range2.unwrap().lb.value.unwrap(), &1.0);
1782        assert_eq!(union_range2.unwrap().ub.value.unwrap(), &10.0);
1783        let union_range3 = range.union(&value_range!([0.0f64, 10.0f64]).unwrap());
1784        assert!(union_range3.is_some());
1785        assert_eq!(union_range3.unwrap().lb.value.unwrap(), &0.0);
1786        assert_eq!(union_range3.unwrap().ub.value.unwrap(), &10.0);
1787        let none_range = range.union(&value_range!([4.0f64, 10.0f64]).unwrap());
1788        assert!(none_range.is_none());
1789        let inf_range = range.union(&value_range!([1.0f64, ..]).unwrap());
1790        assert!(inf_range.is_some());
1791        assert_eq!(inf_range.as_ref().unwrap().lb.value.unwrap(), &1.0);
1792        assert_eq!(inf_range.as_ref().unwrap().lb.interval, Interval::Closed);
1793        assert_eq!(
1794            inf_range.as_ref().unwrap().ub.value.unwrap(),
1795            f64::INF.as_ref().unwrap()
1796        );
1797        assert_eq!(inf_range.as_ref().unwrap().ub.interval, Interval::Open);
1798        let neg_inf_range = range.union(&value_range!([.., 1.0f64]).unwrap());
1799        assert!(neg_inf_range.is_some());
1800        assert_eq!(
1801            neg_inf_range.as_ref().unwrap().lb.value.unwrap(),
1802            f64::NEG_INF.as_ref().unwrap()
1803        );
1804        assert_eq!(neg_inf_range.as_ref().unwrap().lb.interval, Interval::Open);
1805        assert_eq!(neg_inf_range.as_ref().unwrap().ub.value.unwrap(), &3.0);
1806        assert_eq!(
1807            neg_inf_range.as_ref().unwrap().ub.interval,
1808            Interval::Closed
1809        );
1810    }
1811
1812    #[test]
1813    fn test_contains() {
1814        let range = value_range!([1.0f64, 3.0f64]).unwrap();
1815        assert!(range.contains(&1.0f64));
1816        assert!(range.contains(&2.0f64));
1817        assert!(range.contains(&3.0f64));
1818        assert!(!range.contains(&0.0f64));
1819        assert!(!range.contains(&4.0f64));
1820
1821        assert!(range.contains_range(&value_range!([1.0f64, 2.0f64]).unwrap()));
1822        assert!(range.contains_range(&value_range!([2.0f64, 3.0f64]).unwrap()));
1823        assert!(range.contains_range(&value_range!([1.0f64, 3.0f64]).unwrap()));
1824        assert!(!range.contains_range(&value_range!([0.0f64, 1.0f64]).unwrap()));
1825        assert!(!range.contains_range(&value_range!([0.0f64, 2.0f64]).unwrap()));
1826        assert!(!range.contains_range(&value_range!([2.0f64, 10.0f64]).unwrap()));
1827    }
1828}