1use crate::ops::*;
38use gcollections::ops::*;
39use gcollections::*;
40use serde::de::{self, SeqAccess, Visitor};
41use serde::ser::SerializeTuple;
42use serde::{Deserialize, Deserializer, Serialize, Serializer};
43use trilean::SKleene;
44
45use num_traits::{Num, Zero};
46use std::cmp::{max, min};
47use std::fmt::{self, Display, Error, Formatter};
48use std::marker::PhantomData;
49use std::ops::{Add, Mul, Sub};
50
51#[derive(Debug, Copy, Clone)]
53pub struct Interval<Bound> {
54 lb: Bound,
55 ub: Bound,
56}
57
58impl<Bound> Serialize for Interval<Bound>
59where
60 Bound: Serialize + Width + Num,
61{
62 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
63 where
64 S: Serializer,
65 {
66 if self.is_empty() {
67 serializer.serialize_none()
68 } else {
69 let mut tuple = serializer.serialize_tuple(2)?;
70 tuple.serialize_element(&self.lb)?;
71 tuple.serialize_element(&self.ub)?;
72 tuple.end()
73 }
74 }
75}
76
77impl<'de, Bound> Deserialize<'de> for Interval<Bound>
78where
79 Bound: Width + Num + Deserialize<'de>,
80{
81 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
82 where
83 D: Deserializer<'de>,
84 {
85 struct IntervalVisitor<Bound> {
86 marker: PhantomData<fn() -> Bound>,
87 }
88 impl<Bound> IntervalVisitor<Bound> {
89 fn new() -> Self {
90 IntervalVisitor {
91 marker: PhantomData,
92 }
93 }
94 }
95 impl<'de, Bound> Visitor<'de> for IntervalVisitor<Bound>
96 where
97 Bound: Width + Deserialize<'de> + Num,
98 {
99 type Value = Interval<Bound>;
100
101 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
102 formatter.write_str("tuple of two numbers or none")
103 }
104
105 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
106 where
107 A: SeqAccess<'de>,
108 {
109 let lower = seq
110 .next_element::<Bound>()?
111 .ok_or_else(|| de::Error::invalid_length(0, &self))?;
112 let upper = seq
113 .next_element::<Bound>()?
114 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
115 let mut extra_elements = 0;
116 while seq.next_element::<de::IgnoredAny>()?.is_some() {
117 extra_elements += 1;
118 }
119 if extra_elements > 0 {
120 return Err(de::Error::invalid_length(2 + extra_elements, &self));
121 }
122 Ok(Interval::new(lower, upper))
123 }
124
125 fn visit_none<E>(self) -> Result<Self::Value, E>
126 where
127 E: de::Error,
128 {
129 Ok(Interval::<Bound>::empty())
130 }
131 }
132 deserializer.deserialize_any(IntervalVisitor::new())
133 }
134}
135
136impl<Bound> IntervalKind for Interval<Bound> {}
137
138impl<Bound> Collection for Interval<Bound> {
139 type Item = Bound;
140}
141
142impl<Bound> Interval<Bound>
143where
144 Bound: Width + Num,
145{
146 fn into_optional(self) -> Optional<Bound> {
147 if self.is_empty() {
148 Optional::empty()
149 } else if self.is_singleton() {
150 Optional::singleton(self.lb)
151 } else {
152 panic!("Only empty interval or singleton can be transformed into an option.");
153 }
154 }
155}
156
157impl<Bound: Width + Num> Eq for Interval<Bound> {}
158
159impl<Bound> PartialEq<Interval<Bound>> for Interval<Bound>
160where
161 Bound: Width + Num,
162{
163 fn eq(&self, other: &Interval<Bound>) -> bool {
178 if self.is_empty() && other.is_empty() {
179 true
180 } else {
181 self.lb == other.lb && self.ub == other.ub
182 }
183 }
184}
185
186impl<Bound> Interval<Bound>
187where
188 Bound: Clone,
189{
190 fn low(&self) -> Bound {
191 self.lb.clone()
192 }
193 fn up(&self) -> Bound {
194 self.ub.clone()
195 }
196}
197
198impl<Bound> Interval<Bound>
199where
200 Bound: Width + Num,
201{
202 fn min_lb(ub: Bound) -> Interval<Bound> {
203 Interval::new(<Bound as Width>::min_value(), ub)
204 }
205
206 fn max_ub(lb: Bound) -> Interval<Bound> {
207 Interval::new(lb, <Bound as Width>::max_value())
208 }
209}
210
211impl<Bound> Range for Interval<Bound>
212where
213 Bound: Width,
214{
215 fn new(lb: Bound, ub: Bound) -> Interval<Bound> {
245 debug_assert!(
246 lb >= <Bound as Width>::min_value(),
247 "Lower bound exceeds the minimum value of a bound."
248 );
249 debug_assert!(
250 ub <= <Bound as Width>::max_value(),
251 "Upper bound exceeds the maximum value of a bound."
252 );
253 Interval { lb, ub }
254 }
255}
256
257impl<Bound> Bounded for Interval<Bound>
258where
259 Bound: Num + Width + Clone,
260{
261 fn lower(&self) -> Bound {
273 debug_assert!(
274 !self.is_empty(),
275 "Cannot access lower bound on empty interval."
276 );
277 self.low()
278 }
279
280 fn upper(&self) -> Bound {
292 debug_assert!(
293 !self.is_empty(),
294 "Cannot access upper bound on empty interval."
295 );
296 self.up()
297 }
298}
299
300impl<Bound> Singleton for Interval<Bound>
301where
302 Bound: Width + Clone,
303{
304 fn singleton(x: Bound) -> Interval<Bound> {
314 Interval::new(x.clone(), x)
315 }
316}
317
318impl<Bound> Empty for Interval<Bound>
319where
320 Bound: Width + Num,
321{
322 fn empty() -> Interval<Bound> {
331 Interval::new(Bound::one(), Bound::zero())
332 }
333}
334
335impl<Bound> Whole for Interval<Bound>
336where
337 Bound: Width + Num,
338{
339 fn whole() -> Interval<Bound> {
357 Interval::new(<Bound as Width>::min_value(), <Bound as Width>::max_value())
358 }
359}
360
361impl<Bound> Cardinality for Interval<Bound>
363where
364 Bound: Width + Num,
365{
366 type Size = <Bound as Width>::Output;
367
368 fn size(&self) -> <Bound as Width>::Output {
382 if self.lb > self.ub {
383 <<Bound as Width>::Output>::zero()
384 } else {
385 Bound::width(&self.lb, &self.ub)
386 }
387 }
388}
389
390impl<Bound> Disjoint for Interval<Bound>
391where
392 Bound: Width + Num,
393{
394 fn is_disjoint(&self, other: &Interval<Bound>) -> bool {
406 self.is_empty() || other.is_empty() || self.lb > other.ub || other.lb > self.ub
407 }
408}
409
410impl<Bound> Disjoint<Bound> for Interval<Bound>
411where
412 Bound: Num + Ord,
413{
414 fn is_disjoint(&self, value: &Bound) -> bool {
424 !self.contains(value)
425 }
426}
427
428macro_rules! primitive_interval_disjoint
429{
430 ( $( $source:ty ),* ) =>
431 {$(
432 impl Disjoint<Interval<$source>> for $source
433 {
434 #[doc = concat!(
435 r#"
436 Calculates whether a value is excluded from an interval.
437 ```
438 # use interval::prelude::*;
439 assert_eq!((1 as "#, stringify!($source), r#").is_disjoint(&Interval::new(8, 9)), true);
440 assert_eq!((3 as "#, stringify!($source), r#").is_disjoint(&Interval::new(1, 5)), false);
441 assert_eq!((5 as "#, stringify!($source), r#").is_disjoint(&Interval::new(3, 5)), false);
442 assert_eq!((3 as "#, stringify!($source), r#").is_disjoint(&Interval::new(3, 3)), false);
443 assert_eq!((6 as "#, stringify!($source), r#").is_disjoint(&Interval::empty()), true);
444 ```
445 "#
446 )]
447 fn is_disjoint(&self, value: &Interval<$source>) -> bool {
448 value.is_disjoint(self)
449 }
450 }
451 )*}
452}
453
454primitive_interval_disjoint!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize);
455
456impl<Bound> Disjoint<Optional<Bound>> for Interval<Bound>
457where
458 Bound: Num + Ord,
459{
460 fn is_disjoint(&self, value: &Optional<Bound>) -> bool {
472 value.as_ref().map_or(true, |x| self.is_disjoint(x))
473 }
474}
475
476macro_rules! optional_interval_disjoint
477{
478 ( $( $source:ty ),* ) =>
479 {$(
480 impl Disjoint<Interval<$source>> for Optional<$source>
481 {
482 #[doc = concat!(
483 r#"
484 Calculates whether an optional is excluded from an interval.
485 ```
486 # use interval::prelude::*;
487 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(1).is_disjoint(&Interval::new(8, 9)), true);
488 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(3).is_disjoint(&Interval::new(1, 5)), false);
489 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(5).is_disjoint(&Interval::new(3, 5)), false);
490 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(3).is_disjoint(&Interval::new(3, 3)), false);
491 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(6).is_disjoint(&Interval::empty()), true);
492 assert_eq!(Optional::<"#, stringify!($source), r#">::empty().is_disjoint(&Interval::new(4, 7)), true);
493 assert_eq!(Optional::<"#, stringify!($source), r#">::empty().is_disjoint(&Interval::empty()), true);
494 ```
495 "#
496 )]
497 fn is_disjoint(&self, value: &Interval<$source>) -> bool {
498 value.is_disjoint(self)
499 }
500 }
501 )*}
502}
503
504optional_interval_disjoint!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize);
505
506impl<Bound> Overlap for Interval<Bound>
507where
508 Bound: Width + Num,
509{
510 fn overlap(&self, other: &Interval<Bound>) -> bool {
522 !self.is_disjoint(other)
523 }
524}
525
526impl<Bound> Overlap<Bound> for Interval<Bound>
527where
528 Bound: Width + Num,
529{
530 fn overlap(&self, other: &Bound) -> bool {
540 !self.is_disjoint(other)
541 }
542}
543
544impl<Bound> Overlap<Optional<Bound>> for Interval<Bound>
545where
546 Bound: Width + Num,
547{
548 fn overlap(&self, other: &Optional<Bound>) -> bool {
560 !self.is_disjoint(other)
561 }
562}
563
564macro_rules! primitive_interval_overlap
565{
566 ( $( $source:ty ),* ) =>
567 {$(
568 impl Overlap<Interval<$source>> for $source
569 {
570 #[doc = concat!(
571 r#"
572 Calculates whether a value is included in an interval.
573 ```
574 # use interval::prelude::*;
575 assert_eq!((1 as "#, stringify!($source), r#").overlap(&Interval::new(8, 9)), false);
576 assert_eq!((3 as "#, stringify!($source), r#").overlap(&Interval::new(1, 5)), true);
577 assert_eq!((5 as "#, stringify!($source), r#").overlap(&Interval::new(3, 5)), true);
578 assert_eq!((3 as "#, stringify!($source), r#").overlap(&Interval::new(3, 3)), true);
579 assert_eq!((6 as "#, stringify!($source), r#").overlap(&Interval::empty()), false);
580 ```
581 "#
582 )]
583 fn overlap(&self, other: &Interval<$source>) -> bool {
584 !self.is_disjoint(other)
585 }
586 }
587 )*}
588}
589
590primitive_interval_overlap!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize);
591
592macro_rules! optional_interval_overlap
593{
594 ( $( $source:ty ),* ) =>
595 {$(
596 impl Overlap<Interval<$source>> for Optional<$source>
597 {
598 #[doc = concat!(
599 r#"
600 Calculates whether an optional is included in an interval.
601 ```
602 # use interval::prelude::*;
603 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(1).overlap(&Interval::new(8, 9)), false);
604 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(3).overlap(&Interval::new(1, 5)), true);
605 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(5).overlap(&Interval::new(3, 5)), true);
606 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(3).overlap(&Interval::new(3, 3)), true);
607 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(6).overlap(&Interval::empty()), false);
608 assert_eq!(Optional::<"#, stringify!($source), r#">::empty().overlap(&Interval::new(4, 7)), false);
609 assert_eq!(Optional::<"#, stringify!($source), r#">::empty().overlap(&Interval::empty()), false);
610 ```
611 "#
612 )]
613 fn overlap(&self, other: &Interval<$source>) -> bool {
614 !self.is_disjoint(other)
615 }
616 }
617 )*}
618}
619
620optional_interval_overlap!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize);
621
622impl<Bound> Hull for Interval<Bound>
623where
624 Bound: Width + Num,
625{
626 type Output = Interval<Bound>;
627
628 fn hull(&self, other: &Interval<Bound>) -> Interval<Bound> {
639 if self.is_empty() {
640 other.clone()
641 } else if other.is_empty() {
642 self.clone()
643 } else {
644 Interval::new(min(self.low(), other.low()), max(self.up(), other.up()))
645 }
646 }
647}
648
649impl<Bound> Hull<Bound> for Interval<Bound>
650where
651 Bound: Width + Num,
652{
653 type Output = Interval<Bound>;
654
655 fn hull(&self, other: &Bound) -> Interval<Bound> {
665 self.hull(&Interval::singleton(other.clone()))
666 }
667}
668
669macro_rules! primitive_interval_hull
670{
671 ( $( $source:ty ),* ) =>
672 {$(
673 impl Hull<Interval<$source>> for $source
674 {
675 type Output = Interval<$source>;
676
677 #[doc = concat!(
678 r#"
679 Calculates the smallest interval containing an interval and a value.
680 ```
681 # use interval::prelude::*;
682 assert_eq!((3 as "#, stringify!($source), r#").hull(&Interval::new(5, 8)), Interval::new(3, 8));
683 assert_eq!((2 as "#, stringify!($source), r#").hull(&Interval::new(1, 3)), Interval::new(1, 3));
684 assert_eq!((9 as "#, stringify!($source), r#").hull(&Interval::new(2, 6)), Interval::new(2, 9));
685 assert_eq!((4 as "#, stringify!($source), r#").hull(&Interval::singleton(4)), Interval::singleton(4));
686 assert_eq!((5 as "#, stringify!($source), r#").hull(&Interval::empty()), Interval::singleton(5));
687 ```
688 "#
689 )]
690 fn hull(&self, other: &Interval<$source>) -> Interval<$source> {
691 other.hull(self)
692 }
693 }
694 )*}
695}
696
697primitive_interval_hull!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize);
698
699impl<Bound> Contains for Interval<Bound>
700where
701 Bound: Ord,
702{
703 fn contains(&self, value: &Bound) -> bool {
723 value >= &self.lb && value <= &self.ub
724 }
725}
726
727impl<Bound> Subset for Interval<Bound>
728where
729 Bound: Width + Num,
730{
731 fn is_subset(&self, other: &Interval<Bound>) -> bool {
745 if self.is_empty() {
746 true
747 } else {
748 self.lb >= other.lb && self.ub <= other.ub
749 }
750 }
751}
752
753impl<Bound> ProperSubset for Interval<Bound>
754where
755 Bound: Width + Num,
756{
757 fn is_proper_subset(&self, other: &Interval<Bound>) -> bool {
772 self.is_subset(other) && self != other
773 }
774}
775
776impl<Bound> Intersection for Interval<Bound>
777where
778 Bound: Width + Num,
779{
780 type Output = Interval<Bound>;
781
782 fn intersection(&self, other: &Interval<Bound>) -> Interval<Bound> {
793 Interval::new(max(self.low(), other.low()), min(self.up(), other.up()))
794 }
795}
796
797impl<Bound> Intersection<Bound> for Interval<Bound>
798where
799 Bound: Width + Num,
800{
801 type Output = Interval<Bound>;
802 fn intersection(&self, value: &Bound) -> Interval<Bound> {
813 if self.contains(value) {
814 Interval::singleton(value.clone())
815 } else {
816 Interval::empty()
817 }
818 }
819}
820
821impl<Bound> Intersection<Optional<Bound>> for Interval<Bound>
822where
823 Bound: Width + Num,
824{
825 type Output = Interval<Bound>;
826
827 fn intersection(&self, value: &Optional<Bound>) -> Interval<Bound> {
838 value
839 .as_ref()
840 .map_or(Interval::empty(), |x| self.intersection(x))
841 }
842}
843
844macro_rules! optional_interval_intersection
845{
846 ( $( $source:ty ),* ) =>
847 {$(
848 impl Intersection<Interval<$source>> for Optional<$source>
849 {
850 type Output = Optional<$source>;
851 #[doc = concat!(
852 r#"
853 Calculates whether the optional is contained in an interval.
854 ```
855 # use interval::prelude::*;
856 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(4).intersection(&Interval::new(3, 8)), Optional::singleton(4));
857 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(9).intersection(&Interval::new(7, 9)), Optional::singleton(9));
858 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(0).intersection(&Interval::new(1, 4)), Optional::empty());
859 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(9).intersection(&Interval::empty()), Optional::empty());
860 assert_eq!(Optional::<"#, stringify!($source), r#">::empty().intersection(&Interval::new(2, 6)), Optional::empty());
861 ```
862 "#
863 )]
864 fn intersection(&self, other: &Interval<$source>) -> Optional<$source> {
865 self.as_ref().map_or(Optional::empty(), |x| other.intersection(x).into_optional())
866 }
867 }
868 )*}
869}
870
871optional_interval_intersection!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize);
872
873impl<Bound> Difference for Interval<Bound>
874where
875 Bound: Width + Num,
876{
877 type Output = Interval<Bound>;
878
879 fn difference(&self, other: &Interval<Bound>) -> Interval<Bound> {
892 let left = self.intersection(&Interval::min_lb(other.low() - Bound::one()));
901 let right = self.intersection(&Interval::max_ub(other.up() + Bound::one()));
902 left.hull(&right)
903 }
904}
905
906impl<Bound> Difference<Bound> for Interval<Bound>
907where
908 Bound: Num + Clone,
909{
910 type Output = Interval<Bound>;
911
912 fn difference(&self, value: &Bound) -> Interval<Bound> {
924 let mut this = self.clone();
925 if value == &this.lb {
926 this.lb = this.lb + Bound::one();
927 } else if value == &this.ub {
928 this.ub = this.ub - Bound::one();
929 }
930 this
931 }
932}
933
934impl<Bound> Difference<Optional<Bound>> for Interval<Bound>
935where
936 Bound: Ord + Num + Clone,
937{
938 type Output = Interval<Bound>;
939
940 fn difference(&self, value: &Optional<Bound>) -> Interval<Bound> {
949 value
950 .as_ref()
951 .map_or_else(|| self.clone(), |x| self.difference(x))
952 }
953}
954
955macro_rules! optional_interval_difference
956{
957 ( $( $source:ty ),* ) =>
958 {$(
959 impl Difference<Interval<$source>> for Optional<$source>
960 {
961 type Output = Optional<$source>;
962 #[doc = concat!(
963 r#"
964 Calculates whether an optional is outside of an interval.
965 ```
966 # use interval::prelude::*;
967 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(4).difference(&Interval::new(3, 8)), Optional::empty());
968 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(8).difference(&Interval::new(7, 9)), Optional::empty());
969 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(3).difference(&Interval::new(1, 4)), Optional::empty());
970 assert_eq!(Optional::<"#, stringify!($source), r#">::singleton(9).difference(&Interval::empty()), Optional::singleton(9));
971 assert_eq!(Optional::<"#, stringify!($source), r#">::empty().difference(&Interval::new(2, 6)), Optional::empty());
972 ```
973 "#)]
974 fn difference(&self, other: &Interval<$source>) -> Optional<$source> {
975 self.as_ref().map_or(Optional::empty(), |x|
976 if other.contains(x) { Optional::empty() }
977 else { Optional::singleton(x.clone()) }
978 )
979 }
980 }
981 )*}
982}
983
984optional_interval_difference!(i8, u8, i16, u16, i32, u32, i64, u64, isize, usize);
985
986impl<Bound> ShrinkLeft for Interval<Bound>
987where
988 Bound: Num + Width,
989{
990 fn shrink_left(&self, lb: Bound) -> Interval<Bound> {
1005 let mut this = self.clone();
1006 if lb > this.lb {
1007 this.lb = lb;
1008 }
1009 this
1010 }
1011}
1012
1013impl<Bound> ShrinkRight for Interval<Bound>
1014where
1015 Bound: Num + Width,
1016{
1017 fn shrink_right(&self, ub: Bound) -> Interval<Bound> {
1032 let mut this = self.clone();
1033 if ub < this.ub {
1034 this.ub = ub;
1035 }
1036 this
1037 }
1038}
1039
1040forward_all_binop!(impl<Bound: +Num+Width> Add for Interval<Bound>, add);
1041
1042impl<'a, 'b, Bound> Add<&'b Interval<Bound>> for &'a Interval<Bound>
1043where
1044 Bound: Num + Width,
1045{
1046 type Output = Interval<Bound>;
1047
1048 fn add(self, other: &Interval<Bound>) -> Interval<Bound> {
1063 if self.is_empty() || other.is_empty() {
1064 Interval::empty()
1065 } else {
1066 Interval::new(self.lower() + other.lower(), self.upper() + other.upper())
1067 }
1068 }
1069}
1070
1071forward_all_binop!(impl<Bound: +Num+Width+Clone> Add for Interval<Bound>, add, Bound);
1072
1073impl<'a, 'b, Bound> Add<&'b Bound> for &'a Interval<Bound>
1074where
1075 Bound: Num + Width + Clone,
1076{
1077 type Output = Interval<Bound>;
1078
1079 fn add(self, other: &Bound) -> Interval<Bound> {
1095 if self.is_empty() {
1096 Interval::empty()
1097 } else {
1098 Interval::new(self.lower() + other.clone(), self.upper() + other.clone())
1099 }
1100 }
1101}
1102
1103forward_all_binop!(impl<Bound: +Num+Width> Sub for Interval<Bound>, sub);
1104
1105impl<'a, 'b, Bound> Sub<&'b Interval<Bound>> for &'a Interval<Bound>
1106where
1107 Bound: Num + Width,
1108{
1109 type Output = Interval<Bound>;
1110
1111 fn sub(self, other: &Interval<Bound>) -> Interval<Bound> {
1128 if self.is_empty() || other.is_empty() {
1129 Interval::empty()
1130 } else {
1131 Interval::new(self.lower() - other.upper(), self.upper() - other.lower())
1132 }
1133 }
1134}
1135
1136forward_all_binop!(impl<Bound: +Num+Width+Clone> Sub for Interval<Bound>, sub, Bound);
1137
1138impl<'a, 'b, Bound> Sub<&'b Bound> for &'a Interval<Bound>
1139where
1140 Bound: Num + Width + Clone,
1141{
1142 type Output = Interval<Bound>;
1143
1144 fn sub(self, other: &Bound) -> Interval<Bound> {
1160 if self.is_empty() {
1161 Interval::empty()
1162 } else {
1163 Interval::new(self.lower() - other.clone(), self.upper() - other.clone())
1164 }
1165 }
1166}
1167
1168forward_all_binop!(impl<Bound: +Num+Width> Mul for Interval<Bound>, mul);
1169
1170fn min_max<Iter, Item>(mut iter: Iter) -> (Item, Item)
1173where
1174 Iter: Iterator<Item = Item>,
1175 Item: Ord,
1176{
1177 debug_assert!(
1178 iter.size_hint().0 > 2,
1179 "`min_max` expects an iterator (`iter`) yielding at least two elements."
1180 );
1181 let (mut min, mut max) = {
1182 let x = iter.next().unwrap();
1183 let y = iter.next().unwrap();
1184 if x <= y {
1185 (x, y)
1186 } else {
1187 (y, x)
1188 }
1189 };
1190
1191 loop {
1192 let first = match iter.next() {
1198 None => break,
1199 Some(x) => x,
1200 };
1201 let second = match iter.next() {
1202 None => {
1203 if first < min {
1204 min = first;
1205 } else if first >= max {
1206 max = first;
1207 }
1208 break;
1209 }
1210 Some(x) => x,
1211 };
1212 if first <= second {
1213 if first < min {
1214 min = first
1215 }
1216 if second >= max {
1217 max = second
1218 }
1219 } else {
1220 if second < min {
1221 min = second
1222 }
1223 if first >= max {
1224 max = first
1225 }
1226 }
1227 }
1228 (min, max)
1229}
1230
1231impl<'a, 'b, Bound> Mul<&'b Interval<Bound>> for &'a Interval<Bound>
1232where
1233 Bound: Num + Width,
1234{
1235 type Output = Interval<Bound>;
1236
1237 fn mul(self, other: &Interval<Bound>) -> Interval<Bound> {
1252 if self.is_empty() || other.is_empty() {
1253 Interval::empty()
1254 } else {
1255 let (min, max) = min_max(
1256 vec![
1257 self.lower() * other.lower(),
1258 self.lower() * other.upper(),
1259 self.upper() * other.lower(),
1260 self.upper() * other.upper(),
1261 ]
1262 .into_iter(),
1263 );
1264 Interval::new(min, max)
1265 }
1266 }
1267}
1268
1269forward_all_binop!(impl<Bound: +Num+Width+Clone> Mul for Interval<Bound>, mul, Bound);
1270
1271impl<'a, 'b, Bound> Mul<&'b Bound> for &'a Interval<Bound>
1272where
1273 Bound: Num + Width + Clone,
1274{
1275 type Output = Interval<Bound>;
1276
1277 fn mul(self, other: &Bound) -> Interval<Bound> {
1297 if self.is_empty() {
1298 Interval::empty()
1299 } else {
1300 Interval::new(self.lower() * other.clone(), self.upper() * other.clone())
1301 }
1302 }
1303}
1304
1305impl<Bound> Display for Interval<Bound>
1306where
1307 Bound: Display + Width + Num,
1308{
1309 fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
1319 if self.is_empty() {
1320 formatter.write_str("{}")
1321 } else {
1322 formatter.write_fmt(format_args!("[{}..{}]", self.lb, self.ub))
1323 }
1324 }
1325}
1326
1327pub trait ToInterval<Bound> {
1328 fn to_interval(self) -> Interval<Bound>;
1337}
1338
1339impl<Bound> ToInterval<Bound> for Interval<Bound> {
1340 fn to_interval(self) -> Interval<Bound> {
1350 self
1351 }
1352}
1353
1354impl<Bound: Width + Num> ToInterval<Bound> for (Bound, Bound) {
1355 fn to_interval(self) -> Interval<Bound> {
1367 let (a, b) = self;
1368 Interval::new(a, b)
1369 }
1370}
1371
1372impl<Bound: Width + Num> ToInterval<Bound> for () {
1373 fn to_interval(self) -> Interval<Bound> {
1387 Interval::empty()
1388 }
1389}
1390
1391impl<Bound: Width + Num> ToInterval<Bound> for Bound {
1392 fn to_interval(self) -> Interval<Bound> {
1398 Interval::singleton(self)
1399 }
1400}
1401
1402impl<Bound> Join for Interval<Bound>
1403where
1404 Bound: Width + Num,
1405{
1406 fn join(self, other: Interval<Bound>) -> Interval<Bound> {
1407 self.intersection(&other)
1408 }
1409}
1410
1411impl<Bound> Meet for Interval<Bound>
1412where
1413 Bound: Width + Num,
1414{
1415 fn meet(self, other: Interval<Bound>) -> Interval<Bound> {
1416 self.hull(&other)
1417 }
1418}
1419
1420impl<Bound> Entailment for Interval<Bound>
1421where
1422 Bound: Width + Num,
1423{
1424 fn entail(&self, other: &Interval<Bound>) -> SKleene {
1425 if self.is_subset(other) {
1426 SKleene::True
1427 } else if other.is_subset(self) {
1428 SKleene::False
1429 } else {
1430 SKleene::Unknown
1431 }
1432 }
1433}
1434
1435impl<Bound> Top for Interval<Bound>
1436where
1437 Bound: Width + Num,
1438{
1439 fn top() -> Interval<Bound> {
1440 Interval::empty()
1441 }
1442}
1443
1444impl<Bound> Bot for Interval<Bound>
1445where
1446 Bound: Width + Num,
1447{
1448 fn bot() -> Interval<Bound> {
1449 Interval::whole()
1450 }
1451}
1452
1453#[allow(non_upper_case_globals)]
1454#[cfg(test)]
1455mod tests {
1456 use serde_test::{assert_de_tokens, assert_de_tokens_error, assert_tokens, Token};
1457
1458 use super::*;
1459
1460 const empty: Interval<i32> = Interval { lb: 1, ub: 0 };
1461 const invalid: Interval<i32> = Interval { lb: 10, ub: -10 };
1462 const zero: Interval<i32> = Interval { lb: 0, ub: 0 };
1463 const one: Interval<i32> = Interval { lb: 1, ub: 1 };
1464 const ten: Interval<i32> = Interval { lb: 10, ub: 10 };
1465
1466 const i0_1: Interval<i32> = Interval { lb: 0, ub: 1 };
1467 const i0_2: Interval<i32> = Interval { lb: 0, ub: 2 };
1468 const i1_2: Interval<i32> = Interval { lb: 1, ub: 2 };
1469 const i0_10: Interval<i32> = Interval { lb: 0, ub: 10 };
1470 const i1_10: Interval<i32> = Interval { lb: 1, ub: 10 };
1471 const i0_9: Interval<i32> = Interval { lb: 0, ub: 9 };
1472 const i0_15: Interval<i32> = Interval { lb: 0, ub: 15 };
1473 const im5_10: Interval<i32> = Interval { lb: -5, ub: 10 };
1474 const im5_m1: Interval<i32> = Interval { lb: -5, ub: -1 };
1475 const i5_10: Interval<i32> = Interval { lb: 5, ub: 10 };
1476 const i6_10: Interval<i32> = Interval { lb: 6, ub: 10 };
1477 const i0_5: Interval<i32> = Interval { lb: 0, ub: 5 };
1478 const i0_4: Interval<i32> = Interval { lb: 0, ub: 4 };
1479 const im5_5: Interval<i32> = Interval { lb: -5, ub: 5 };
1480 const i20_30: Interval<i32> = Interval { lb: 20, ub: 30 };
1481 const im30_m20: Interval<i32> = Interval { lb: -30, ub: -20 };
1482
1483 #[test]
1484 fn to_interval_id_test() {
1485 let id = i1_2.clone().to_interval();
1486 assert_eq!(i1_2, id);
1487 assert_eq!(i1_2, Interval::new(1, 2));
1488 }
1489
1490 #[test]
1491 fn equality_test() {
1492 assert_eq!(empty, empty);
1493 assert_eq!(empty, invalid);
1494 assert_eq!(invalid, empty);
1495 assert_eq!(i1_2, i1_2);
1496 }
1497
1498 #[test]
1499 fn size_test() {
1500 let whole_i32: Interval<i32> = Interval::<i32>::whole();
1501 let whole_u32: Interval<u32> = Interval::<u32>::whole();
1502
1503 assert_eq!(zero.size(), 1);
1504 assert_eq!(one.size(), 1);
1505 assert_eq!(empty.size(), 0);
1506 assert_eq!(invalid.size(), 0);
1507
1508 assert_eq!(i1_2.size(), 2);
1509 assert_eq!(i0_10.size(), 11);
1510 assert_eq!(im30_m20.size(), 11);
1511
1512 assert_eq!(whole_i32.size(), u32::max_value());
1513 assert_eq!(whole_u32.size(), u32::max_value());
1514 }
1515
1516 #[test]
1517 fn contains_test() {
1518 assert!(i1_2.contains(&1));
1519 assert!(i1_2.contains(&2));
1520 assert!(!i1_2.contains(&0));
1521 assert!(!i1_2.contains(&3));
1522
1523 assert!(zero.contains(&0));
1524 assert!(!zero.contains(&1));
1525
1526 assert!(!empty.contains(&0));
1527 assert!(!empty.contains(&1));
1528 assert!(!empty.contains(&5));
1529 assert!(!empty.contains(&-5));
1530
1531 assert!(!invalid.contains(&0));
1532 assert!(!invalid.contains(&-11));
1533 assert!(!invalid.contains(&11));
1534 }
1535
1536 #[test]
1537 fn is_subset_test() {
1538 let cases = vec![
1539 (zero, zero, true),
1540 (i1_2, i1_2, true),
1541 (empty, empty, true),
1542 (invalid, invalid, true),
1543 ];
1544
1545 let sym_cases = vec![
1551 (empty, zero, (true, false)),
1554 (invalid, zero, (true, false)),
1555 (empty, invalid, (true, true)),
1556 (empty, i1_2, (true, false)),
1559 (empty, i0_10, (true, false)),
1560 (invalid, i1_2, (true, false)),
1561 (i1_2, i0_10, (true, false)),
1564 (i0_4, i5_10, (false, false)),
1567 (i0_5, i5_10, (false, false)),
1570 (im5_5, i0_10, (false, false)),
1573 (i0_10, i20_30, (false, false)),
1576 (i0_10, i0_15, (true, false)),
1579 (im5_10, i0_10, (false, true)),
1582 ];
1583
1584 for (x, y, r) in cases.into_iter() {
1585 assert!(
1586 x.is_subset(&y) == r,
1587 "{:?} is subset of {:?} is not equal to {:?}",
1588 x,
1589 y,
1590 r
1591 );
1592 }
1593
1594 for (x, y, (r1, r2)) in sym_cases.into_iter() {
1595 assert!(
1596 x.is_subset(&y) == r1,
1597 "{:?} is subset of {:?} is not equal to {:?}",
1598 x,
1599 y,
1600 r1
1601 );
1602 assert!(
1603 y.is_subset(&x) == r2,
1604 "{:?} is subset of {:?} is not equal to {:?}",
1605 y,
1606 x,
1607 r2
1608 );
1609 }
1610 }
1611
1612 #[test]
1613 fn is_proper_subset_test() {
1614 let cases = vec![
1615 (zero, zero, false),
1616 (i1_2, i1_2, false),
1617 (empty, empty, false),
1618 (invalid, invalid, false),
1619 ];
1620
1621 let sym_cases = vec![
1627 (empty, zero, (true, false)),
1630 (invalid, zero, (true, false)),
1631 (empty, invalid, (false, false)),
1632 (empty, i1_2, (true, false)),
1635 (empty, i0_10, (true, false)),
1636 (invalid, i1_2, (true, false)),
1637 (i1_2, i0_10, (true, false)),
1640 (i0_4, i5_10, (false, false)),
1643 (i0_5, i5_10, (false, false)),
1646 (im5_5, i0_10, (false, false)),
1649 (i0_10, i20_30, (false, false)),
1652 (i0_10, i0_15, (true, false)),
1655 (im5_10, i0_10, (false, true)),
1658 ];
1659
1660 for (x, y, r) in cases.into_iter() {
1661 assert!(
1662 x.is_proper_subset(&y) == r,
1663 "{:?} is proper subset of {:?} is not equal to {:?}",
1664 x,
1665 y,
1666 r
1667 );
1668 }
1669
1670 for (x, y, (r1, r2)) in sym_cases.into_iter() {
1671 assert!(
1672 x.is_proper_subset(&y) == r1,
1673 "{:?} is proper subset of {:?} is not equal to {:?}",
1674 x,
1675 y,
1676 r1
1677 );
1678 assert!(
1679 y.is_proper_subset(&x) == r2,
1680 "{:?} is proper subset of {:?} is not equal to {:?}",
1681 y,
1682 x,
1683 r2
1684 );
1685 }
1686 }
1687
1688 #[test]
1689 fn intersection_test() {
1690 let cases = vec![
1691 (zero, zero, zero),
1692 (i1_2, i1_2, i1_2),
1693 (empty, empty, empty),
1694 (invalid, invalid, invalid),
1695 ];
1696
1697 let sym_cases = vec![
1703 (empty, zero, empty),
1706 (invalid, zero, empty),
1707 (empty, invalid, empty),
1708 (empty, i1_2, empty),
1711 (empty, i0_10, empty),
1712 (invalid, i1_2, empty),
1713 (i1_2, i0_10, i1_2),
1716 (i0_4, i5_10, empty),
1719 (i0_5, i5_10, 5.to_interval()),
1722 (im5_5, i0_10, (0, 5).to_interval()),
1725 (i0_10, i20_30, empty),
1728 (i0_10, i0_15, i0_10),
1731 (im5_10, i0_10, i0_10),
1734 ];
1735
1736 for (x, y, r) in cases.into_iter() {
1737 assert!(
1738 x.intersection(&y) == r,
1739 "{:?} intersection {:?} is not equal to {:?}",
1740 x,
1741 y,
1742 r
1743 );
1744 }
1745
1746 for (x, y, r) in sym_cases.into_iter() {
1747 assert!(
1748 x.intersection(&y) == r,
1749 "{:?} intersection {:?} is not equal to {:?}",
1750 x,
1751 y,
1752 r
1753 );
1754 assert!(
1755 y.intersection(&x) == r,
1756 "{:?} intersection {:?} is not equal to {:?}",
1757 y,
1758 x,
1759 r
1760 );
1761 }
1762 }
1763
1764 #[test]
1765 fn intersection_value_optional_test() {
1766 let cases = vec![
1767 (1, empty, None, empty, None),
1768 (2, invalid, None, empty, None),
1769 (3, empty, Some(1), empty, None),
1770 (4, i0_10, None, empty, None),
1771 (5, i0_10, Some(0), zero, Some(0)),
1772 (6, i0_10, Some(10), ten, Some(10)),
1773 (7, i0_10, Some(1), one, Some(1)),
1774 (8, i0_10, Some(-1), empty, None),
1775 (9, i0_10, Some(11), empty, None),
1776 (10, one, Some(0), empty, None),
1777 (11, one, Some(1), one, Some(1)),
1778 ];
1779 for (id, x, y, r1, r2) in cases.into_iter() {
1780 let y = y.map_or(Optional::empty(), |y| Optional::singleton(y));
1781 let r2 = r2.map_or(Optional::empty(), |r2| Optional::singleton(r2));
1782 if !y.is_empty() {
1784 assert!(
1785 x.intersection(y.as_ref().unwrap()) == r1,
1786 "Test#{}: {:?} intersection {:?} is not equal to {:?}",
1787 id,
1788 x,
1789 y.as_ref().unwrap(),
1790 r1
1791 );
1792 }
1793 assert!(
1795 x.intersection(&y) == r1,
1796 "Test#{}: {:?} intersection {:?} is not equal to {:?}",
1797 id,
1798 x,
1799 y,
1800 r1
1801 );
1802 assert!(
1804 y.intersection(&x) == r2,
1805 "Test#{}: {:?} intersection {:?} is not equal to {:?}",
1806 id,
1807 y,
1808 x,
1809 r2
1810 );
1811 }
1812 }
1813
1814 #[test]
1815 fn hull_test() {
1816 let cases = vec![
1817 (zero, zero, zero),
1818 (i1_2, i1_2, i1_2),
1819 (empty, empty, empty),
1820 (invalid, invalid, invalid),
1821 ];
1822
1823 let sym_cases = vec![
1829 (empty, zero, zero),
1832 (invalid, zero, zero),
1833 (empty, invalid, empty),
1834 (empty, i1_2, i1_2),
1837 (empty, i0_10, i0_10),
1838 (invalid, i1_2, i1_2),
1839 (i1_2, i0_10, i0_10),
1842 (i0_4, i5_10, i0_10),
1845 (i0_5, i5_10, i0_10),
1848 (im5_5, i0_10, (-5, 10).to_interval()),
1851 (i0_10, i20_30, (0, 30).to_interval()),
1854 (i0_10, i0_15, i0_15),
1857 (im5_10, i0_10, im5_10),
1860 ];
1861
1862 for (x, y, r) in cases.into_iter() {
1863 assert!(
1864 x.hull(&y) == r,
1865 "{:?} hull {:?} is not equal to {:?}",
1866 x,
1867 y,
1868 r
1869 );
1870 }
1871
1872 for (x, y, r) in sym_cases.into_iter() {
1873 assert!(
1874 x.hull(&y) == r,
1875 "{:?} hull {:?} is not equal to {:?}",
1876 x,
1877 y,
1878 r
1879 );
1880 assert!(
1881 y.hull(&x) == r,
1882 "{:?} hull {:?} is not equal to {:?}",
1883 y,
1884 x,
1885 r
1886 );
1887 }
1888 }
1889
1890 #[test]
1891 fn is_disjoint_test() {
1892 let cases = vec![
1893 (zero, zero, false),
1894 (i1_2, i1_2, false),
1895 (empty, empty, true),
1896 (invalid, invalid, true),
1897 ];
1898
1899 let sym_cases = vec![
1905 (empty, zero, true),
1908 (invalid, zero, true),
1909 (empty, invalid, true),
1910 (empty, i1_2, true),
1913 (empty, i0_10, true),
1914 (invalid, i1_2, true),
1915 (i1_2, i0_10, false),
1918 (i0_4, i5_10, true),
1921 (i0_5, i5_10, false),
1924 (im5_5, i0_10, false),
1927 (i0_10, i20_30, true),
1930 (i0_10, i0_15, false),
1933 (im5_10, i0_10, false),
1936 ];
1937
1938 for (x, y, r) in cases.into_iter() {
1939 assert!(
1940 x.is_disjoint(&y) == r,
1941 "{:?} is disjoint of {:?} is not equal to {:?}",
1942 x,
1943 y,
1944 r
1945 );
1946 assert!(
1947 x.overlap(&y) == !r,
1948 "{:?} overlap {:?} is not equal to {:?}",
1949 x,
1950 y,
1951 r
1952 );
1953 }
1954
1955 for (x, y, r) in sym_cases.into_iter() {
1956 assert!(
1957 x.is_disjoint(&y) == r,
1958 "{:?} is disjoint of {:?} is not equal to {:?}",
1959 x,
1960 y,
1961 r
1962 );
1963 assert!(
1964 y.is_disjoint(&x) == r,
1965 "{:?} is disjoint of {:?} is not equal to {:?}",
1966 y,
1967 x,
1968 r
1969 );
1970 assert!(
1971 x.overlap(&y) == !r,
1972 "{:?} overlap {:?} is not equal to {:?}",
1973 x,
1974 y,
1975 r
1976 );
1977 assert!(
1978 y.overlap(&x) == !r,
1979 "{:?} overlap {:?} is not equal to {:?}",
1980 y,
1981 x,
1982 r
1983 );
1984 }
1985 }
1986
1987 fn is_disjoint_cases() -> Vec<(u32, Interval<i32>, i32, bool)> {
1988 vec![
1989 (1, empty, 0, true),
1990 (2, invalid, 0, true),
1991 (3, i0_4, -1, true),
1992 (4, i0_4, 0, false),
1993 (5, i0_4, 2, false),
1994 (6, i0_4, 3, false),
1995 (7, i0_4, 5, true),
1996 ]
1997 }
1998
1999 #[test]
2000 fn is_disjoint_bound_test() {
2001 let cases = is_disjoint_cases();
2002 for (id, x, y, r) in cases.into_iter() {
2003 assert!(
2004 x.is_disjoint(&y) == r,
2005 "Test#{}: {:?} is disjoint of {:?} is not equal to {:?}",
2006 id,
2007 x,
2008 y,
2009 r
2010 );
2011 assert!(
2012 y.is_disjoint(&x) == r,
2013 "Test#{}: {:?} is disjoint of {:?} is not equal to {:?}",
2014 id,
2015 y,
2016 x,
2017 r
2018 );
2019 assert!(
2020 x.overlap(&y) == !r,
2021 "Test#{}: {:?} overlap {:?} is not equal to {:?}",
2022 id,
2023 x,
2024 y,
2025 !r
2026 );
2027 assert!(
2028 y.overlap(&x) == !r,
2029 "Test#{}: {:?} overlap {:?} is not equal to {:?}",
2030 id,
2031 y,
2032 x,
2033 !r
2034 );
2035 }
2036 }
2037
2038 #[test]
2039 fn is_disjoint_option_test() {
2040 let mut cases: Vec<(u32, Interval<i32>, Optional<i32>, bool)> = is_disjoint_cases()
2041 .into_iter()
2042 .map(|(id, a, b, e)| (id, a, Optional::singleton(b), e))
2043 .collect();
2044 cases.extend(vec![
2045 (8, empty, Optional::empty(), true),
2046 (9, invalid, Optional::empty(), true),
2047 (10, i0_4, Optional::empty(), true),
2048 ]);
2049 for (id, x, y, r) in cases.into_iter() {
2050 assert!(
2051 x.is_disjoint(&y) == r,
2052 "Test#{}: {:?} is disjoint of {:?} is not equal to {:?}",
2053 id,
2054 x,
2055 y,
2056 r
2057 );
2058 assert!(
2059 y.is_disjoint(&x) == r,
2060 "Test#{}: {:?} is disjoint of {:?} is not equal to {:?}",
2061 id,
2062 y,
2063 x,
2064 r
2065 );
2066 assert!(
2067 x.overlap(&y) == !r,
2068 "Test#{}: {:?} overlap {:?} is not equal to {:?}",
2069 id,
2070 x,
2071 y,
2072 !r
2073 );
2074 assert!(
2075 y.overlap(&x) == !r,
2076 "Test#{}: {:?} overlap {:?} is not equal to {:?}",
2077 id,
2078 y,
2079 x,
2080 !r
2081 );
2082 }
2083 }
2084
2085 #[test]
2086 fn difference_test() {
2087 let cases = vec![
2088 (1, zero, zero, empty),
2089 (2, i1_2, i1_2, empty),
2090 (3, empty, empty, empty),
2091 (4, invalid, invalid, empty),
2092 ];
2093
2094 let sym_cases = vec![
2100 (5, empty, zero, (empty, zero)),
2103 (6, invalid, zero, (empty, zero)),
2104 (7, empty, invalid, (empty, empty)),
2105 (8, empty, i1_2, (empty, i1_2)),
2108 (9, empty, i0_10, (empty, i0_10)),
2109 (10, invalid, i1_2, (empty, i1_2)),
2110 (11, i1_2, i0_10, (empty, i0_10)),
2113 (12, i0_4, i5_10, (i0_4, i5_10)),
2116 (13, i0_5, i5_10, ((0, 4).to_interval(), i6_10)),
2119 (14, im5_5, i0_10, (im5_m1, i6_10)),
2122 (15, i0_10, i20_30, (i0_10, i20_30)),
2125 (16, i0_10, i0_15, (empty, (11, 15).to_interval())),
2128 (17, im5_10, i0_10, (im5_m1, empty)),
2131 ];
2132
2133 for (id, x, y, r) in cases.into_iter() {
2134 println!("Test #{}", id);
2135 assert!(
2136 x.difference(&y) == r,
2137 "{:?} difference {:?} is not equal to {:?}",
2138 x,
2139 y,
2140 r
2141 );
2142 }
2143
2144 for (id, x, y, (r1, r2)) in sym_cases.into_iter() {
2145 println!("Test #{}", id);
2146 assert!(
2147 x.difference(&y) == r1,
2148 "{:?} difference {:?} is not equal to {:?}",
2149 x,
2150 y,
2151 r1
2152 );
2153 assert!(
2154 y.difference(&x) == r2,
2155 "{:?} difference {:?} is not equal to {:?}",
2156 y,
2157 x,
2158 r2
2159 );
2160 }
2161 }
2162
2163 #[test]
2164 fn difference_value_option_test() {
2165 let cases = vec![
2166 (1, empty, None, empty, None),
2167 (2, invalid, None, empty, None),
2168 (3, empty, Some(1), empty, Some(1)),
2169 (4, i0_10, None, i0_10, None),
2170 (5, i0_10, Some(0), i1_10, None),
2171 (6, i0_10, Some(10), i0_9, None),
2172 (7, i0_10, Some(1), i0_10, None),
2173 (8, i0_10, Some(9), i0_10, None),
2174 (9, i0_10, Some(-1), i0_10, Some(-1)),
2175 (10, i0_10, Some(11), i0_10, Some(11)),
2176 (11, i0_10, Some(100), i0_10, Some(100)),
2177 (12, one, Some(1), empty, None),
2178 ];
2179 for (id, x, y, r1, r2) in cases.into_iter() {
2180 let y = y.map_or(Optional::empty(), |y| Optional::singleton(y));
2181 let r2 = r2.map_or(Optional::empty(), |r2| Optional::singleton(r2));
2182 if y.is_some() {
2184 assert!(
2185 x.difference(y.as_ref().unwrap()) == r1,
2186 "Test#{}: {:?} difference {:?} is not equal to {:?}",
2187 id,
2188 x,
2189 y.as_ref().unwrap(),
2190 r1
2191 );
2192 }
2193 assert!(
2195 x.difference(&y) == r1,
2196 "Test#{}: {:?} difference {:?} is not equal to {:?}",
2197 id,
2198 x,
2199 y,
2200 r1
2201 );
2202 assert!(
2204 y.difference(&x) == r2,
2205 "Test#{}: {:?} difference {:?} is not equal to {:?}",
2206 id,
2207 y,
2208 x,
2209 r2
2210 );
2211 }
2212 }
2213
2214 #[test]
2215 fn shrink_left_test() {
2216 let cases = vec![
2217 (i0_10, -5, i0_10),
2218 (i0_10, 0, i0_10),
2219 (i0_10, 1, i1_10),
2220 (i0_10, 5, i5_10),
2221 (i0_10, 10, ten),
2222 (i0_10, 11, empty),
2223 (i0_10, 100, empty),
2224 (empty, 0, empty),
2225 ];
2226 for (x, y, r) in cases.into_iter() {
2227 assert!(
2228 x.shrink_left(y) == r,
2229 "{:?} shrink_left {:?} is not equal to {:?}",
2230 x,
2231 y,
2232 r
2233 );
2234 }
2235 }
2236
2237 #[test]
2238 fn shrink_right_test() {
2239 let cases = vec![
2240 (i0_10, 15, i0_10),
2241 (i0_10, 10, i0_10),
2242 (i0_10, 9, i0_9),
2243 (i0_10, 5, i0_5),
2244 (i0_10, 0, zero),
2245 (i0_10, -1, empty),
2246 (i0_10, -100, empty),
2247 (empty, 0, empty),
2248 ];
2249 for (x, y, r) in cases.into_iter() {
2250 assert!(
2251 x.shrink_right(y) == r,
2252 "{:?} shrink_right {:?} is not equal to {:?}",
2253 x,
2254 y,
2255 r
2256 );
2257 }
2258 }
2259
2260 #[test]
2261 fn add_sub_mul_bound_test() {
2262 let cases = vec![
2266 (zero, 0, zero, zero, zero),
2267 (i1_2, 0, i1_2, i1_2, zero),
2268 (empty, 0, empty, empty, empty),
2269 (invalid, 0, empty, empty, empty),
2270 (zero, 1, one, (-1, -1).to_interval(), zero),
2271 (i1_2, 1, (2, 3).to_interval(), (0, 1).to_interval(), i1_2),
2272 (empty, 1, empty, empty, empty),
2273 (invalid, 1, empty, empty, empty),
2274 (zero, 3, (3, 3).to_interval(), (-3, -3).to_interval(), zero),
2275 (
2276 i1_2,
2277 3,
2278 (4, 5).to_interval(),
2279 (-2, -1).to_interval(),
2280 (3, 6).to_interval(),
2281 ),
2282 (empty, 3, empty, empty, empty),
2283 (invalid, 3, empty, empty, empty),
2284 ];
2285
2286 for &(x, y, r1, r2, r3) in &cases {
2287 assert!(x + y == r1, "{:?} + {:?} is not equal to {:?}", x, y, r1);
2288 assert!(x - y == r2, "{:?} - {:?} is not equal to {:?}", x, y, r2);
2289 assert!(x * y == r3, "{:?} * {:?} is not equal to {:?}", x, y, r3);
2290 }
2291 }
2292
2293 #[test]
2294 fn add_test() {
2295 let sym_cases = vec![
2299 (zero, zero, zero),
2300 (i1_2, i1_2, (2, 4).to_interval()),
2301 (empty, empty, empty),
2302 (invalid, invalid, empty),
2303 (empty, zero, empty),
2306 (invalid, zero, empty),
2307 (empty, invalid, empty),
2308 (empty, i1_2, empty),
2311 (empty, i0_10, empty),
2312 (invalid, i1_2, empty),
2313 (zero, i0_10, i0_10),
2314 (i1_2, i0_10, (1, 12).to_interval()),
2315 (im5_10, i0_10, (-5, 20).to_interval()),
2316 (im5_10, im30_m20, (-35, -10).to_interval()),
2317 ];
2318
2319 for &(x, y, r) in &sym_cases {
2320 assert!(x + y == r, "{:?} + {:?} is not equal to {:?}", x, y, r);
2321 assert!(y + x == r, "{:?} + {:?} is not equal to {:?}", y, x, r);
2322 }
2323 }
2324
2325 #[test]
2326 fn sub_test() {
2327 let cases = vec![
2331 (zero, zero, zero),
2332 (i1_2, i1_2, (-1, 1).to_interval()),
2333 (empty, empty, empty),
2334 (invalid, invalid, empty),
2335 (empty, zero, empty),
2338 (invalid, zero, empty),
2339 (empty, invalid, empty),
2340 (empty, i1_2, empty),
2343 (empty, i0_10, empty),
2344 (invalid, i1_2, empty),
2345 ];
2346
2347 let sym_cases = vec![
2351 (zero, i0_10, ((-10, 0), (0, 10))),
2352 (i1_2, i0_10, ((-9, 2), (-2, 9))),
2353 (im5_10, i0_10, ((-15, 10), (-10, 15))),
2354 (im5_10, im30_m20, ((15, 40), (-40, -15))),
2355 ];
2356
2357 for &(x, y, r) in &cases {
2358 assert!(x - y == r, "{:?} - {:?} is not equal to {:?}", x, y, r);
2359 assert!(y - x == r, "{:?} - {:?} is not equal to {:?}", y, x, r);
2360 }
2361
2362 for &(x, y, (r1, r2)) in &sym_cases {
2363 let r1 = r1.to_interval();
2364 let r2 = r2.to_interval();
2365 assert!(x - y == r1, "{:?} - {:?} is not equal to {:?}", x, y, r1);
2366 assert!(y - x == r2, "{:?} - {:?} is not equal to {:?}", y, x, r2);
2367 }
2368 }
2369
2370 #[test]
2371 fn mul_test() {
2372 let sym_cases = vec![
2376 (zero, zero, zero),
2377 (i1_2, i1_2, (1, 4).to_interval()),
2378 (empty, empty, empty),
2379 (invalid, invalid, empty),
2380 (empty, zero, empty),
2383 (invalid, zero, empty),
2384 (empty, invalid, empty),
2385 (empty, i1_2, empty),
2388 (empty, i0_10, empty),
2389 (invalid, i1_2, empty),
2390 (zero, i0_10, zero),
2391 (one, i0_10, i0_10),
2392 (i1_2, i0_10, (0, 20).to_interval()),
2393 (im5_10, i0_10, (-50, 100).to_interval()),
2394 (im5_10, im30_m20, (-300, 150).to_interval()),
2395 ];
2396
2397 for &(x, y, r) in &sym_cases {
2398 assert!(x * y == r, "{:?} * {:?} is not equal to {:?}", x, y, r);
2399 assert!(y * x == r, "{:?} * {:?} is not equal to {:?}", y, x, r);
2400 }
2401 }
2402
2403 #[test]
2404 fn test_lattice() {
2405 use gcollections::ops::lattice::test::*;
2406 use trilean::SKleene::*;
2407 let whole = Interval::<i32>::whole();
2408 let tester = LatticeTester::new(
2409 0,
2410 vec![empty, empty, whole, zero, zero, zero, i1_2, i0_10, im5_5],
2411 vec![zero, whole, empty, zero, one, i1_2, i0_10, im5_5, i6_10],
2412 vec![
2414 True, True, False, True, Unknown, Unknown, True, Unknown, Unknown,
2415 ],
2416 vec![empty, empty, empty, zero, empty, empty, i1_2, i0_5, empty],
2417 vec![zero, whole, whole, zero, i0_1, i0_2, i0_10, im5_10, im5_10],
2418 );
2419 tester.test_all();
2420 }
2421
2422 #[test]
2423 fn test_ser_de_interval() {
2424 let interval = Interval::new(10, 20);
2425 assert_tokens(
2426 &interval,
2427 &[
2428 Token::Tuple { len: 2 },
2429 Token::I32(10),
2430 Token::I32(20),
2431 Token::TupleEnd,
2432 ],
2433 );
2434 }
2435
2436 #[test]
2437 fn test_de_interval_mixed_types() {
2438 let interval = Interval::new(-5, 15);
2439 assert_de_tokens::<Interval<i32>>(
2440 &interval,
2441 &[
2442 Token::Tuple { len: 2 },
2443 Token::I32(-5),
2444 Token::I64(15),
2445 Token::TupleEnd,
2446 ],
2447 );
2448 }
2449
2450 #[test]
2451 fn test_de_interval_extra_token() {
2452 assert_de_tokens_error::<Interval<i32>>(
2453 &[
2454 Token::Tuple { len: 3 },
2455 Token::I32(10),
2456 Token::I32(20),
2457 Token::I32(30),
2458 Token::TupleEnd,
2459 ],
2460 "invalid length 3, expected tuple of two numbers or none",
2461 );
2462 }
2463
2464 #[test]
2465 fn test_de_interval_extra_tokens() {
2466 assert_de_tokens_error::<Interval<i32>>(
2467 &[
2468 Token::Tuple { len: 5 },
2469 Token::I32(10),
2470 Token::I32(20),
2471 Token::I32(30),
2472 Token::I32(40),
2473 Token::I32(50),
2474 Token::TupleEnd,
2475 ],
2476 "invalid length 5, expected tuple of two numbers or none",
2477 );
2478 }
2479
2480 #[test]
2481 fn test_ser_de_interval_u8() {
2482 let interval = Interval::<u8>::new(10, 20);
2483 assert_tokens(
2484 &interval,
2485 &[
2486 Token::Tuple { len: 2 },
2487 Token::U8(10),
2488 Token::U8(20),
2489 Token::TupleEnd,
2490 ],
2491 );
2492 }
2493
2494 #[test]
2495 fn test_ser_de_interval_i64() {
2496 let interval = Interval::<i64>::whole();
2497 assert_tokens(
2498 &interval,
2499 &[
2500 Token::Tuple { len: 2 },
2501 Token::I64(<i64 as Width>::min_value()),
2502 Token::I64(<i64 as Width>::max_value()),
2503 Token::TupleEnd,
2504 ],
2505 );
2506 }
2507
2508 #[test]
2509 fn test_ser_de_empty_interval() {
2510 let interval = Interval::<i32>::empty();
2511 assert_tokens(&interval, &[Token::None]);
2512 }
2513}