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, RangeFrom, RangeInclusive, RangeToInclusive, 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: Width + Num> ToInterval<Bound> for RangeInclusive<Bound> {
1403 fn to_interval(self) -> Interval<Bound> {
1417 Interval::new(self.start().clone(), self.end().clone())
1418 }
1419}
1420
1421impl<Bound: Width + Num> ToInterval<Bound> for RangeFrom<Bound> {
1422 fn to_interval(self) -> Interval<Bound> {
1436 Interval::new(
1437 self.start.clone(),
1438 max(<Bound as Width>::max_value(), self.start.clone()),
1439 )
1440 }
1441}
1442
1443impl<Bound: Width + Num> ToInterval<Bound> for RangeToInclusive<Bound> {
1444 fn to_interval(self) -> Interval<Bound> {
1464 Interval::new(
1465 min(<Bound as Width>::min_value(), self.end.clone()),
1466 self.end.clone(),
1467 )
1468 }
1469}
1470
1471impl<Bound> Join for Interval<Bound>
1472where
1473 Bound: Width + Num,
1474{
1475 fn join(self, other: Interval<Bound>) -> Interval<Bound> {
1476 self.intersection(&other)
1477 }
1478}
1479
1480impl<Bound> Meet for Interval<Bound>
1481where
1482 Bound: Width + Num,
1483{
1484 fn meet(self, other: Interval<Bound>) -> Interval<Bound> {
1485 self.hull(&other)
1486 }
1487}
1488
1489impl<Bound> Entailment for Interval<Bound>
1490where
1491 Bound: Width + Num,
1492{
1493 fn entail(&self, other: &Interval<Bound>) -> SKleene {
1494 if self.is_subset(other) {
1495 SKleene::True
1496 } else if other.is_subset(self) {
1497 SKleene::False
1498 } else {
1499 SKleene::Unknown
1500 }
1501 }
1502}
1503
1504impl<Bound> Top for Interval<Bound>
1505where
1506 Bound: Width + Num,
1507{
1508 fn top() -> Interval<Bound> {
1509 Interval::empty()
1510 }
1511}
1512
1513impl<Bound> Bot for Interval<Bound>
1514where
1515 Bound: Width + Num,
1516{
1517 fn bot() -> Interval<Bound> {
1518 Interval::whole()
1519 }
1520}
1521
1522#[allow(non_upper_case_globals)]
1523#[cfg(test)]
1524mod tests {
1525 use serde_test::{assert_de_tokens, assert_de_tokens_error, assert_tokens, Token};
1526
1527 use super::*;
1528
1529 const empty: Interval<i32> = Interval { lb: 1, ub: 0 };
1530 const invalid: Interval<i32> = Interval { lb: 10, ub: -10 };
1531 const zero: Interval<i32> = Interval { lb: 0, ub: 0 };
1532 const one: Interval<i32> = Interval { lb: 1, ub: 1 };
1533 const ten: Interval<i32> = Interval { lb: 10, ub: 10 };
1534
1535 const i0_1: Interval<i32> = Interval { lb: 0, ub: 1 };
1536 const i0_2: Interval<i32> = Interval { lb: 0, ub: 2 };
1537 const i1_2: Interval<i32> = Interval { lb: 1, ub: 2 };
1538 const i0_10: Interval<i32> = Interval { lb: 0, ub: 10 };
1539 const i1_10: Interval<i32> = Interval { lb: 1, ub: 10 };
1540 const i0_9: Interval<i32> = Interval { lb: 0, ub: 9 };
1541 const i0_15: Interval<i32> = Interval { lb: 0, ub: 15 };
1542 const im5_10: Interval<i32> = Interval { lb: -5, ub: 10 };
1543 const im5_m1: Interval<i32> = Interval { lb: -5, ub: -1 };
1544 const i5_10: Interval<i32> = Interval { lb: 5, ub: 10 };
1545 const i6_10: Interval<i32> = Interval { lb: 6, ub: 10 };
1546 const i0_5: Interval<i32> = Interval { lb: 0, ub: 5 };
1547 const i0_4: Interval<i32> = Interval { lb: 0, ub: 4 };
1548 const im5_5: Interval<i32> = Interval { lb: -5, ub: 5 };
1549 const i20_30: Interval<i32> = Interval { lb: 20, ub: 30 };
1550 const im30_m20: Interval<i32> = Interval { lb: -30, ub: -20 };
1551
1552 #[test]
1553 fn to_interval_id_test() {
1554 let id = i1_2.clone().to_interval();
1555 assert_eq!(i1_2, id);
1556 assert_eq!(i1_2, Interval::new(1, 2));
1557 }
1558
1559 #[test]
1560 fn equality_test() {
1561 assert_eq!(empty, empty);
1562 assert_eq!(empty, invalid);
1563 assert_eq!(invalid, empty);
1564 assert_eq!(i1_2, i1_2);
1565 }
1566
1567 #[test]
1568 fn size_test() {
1569 let whole_i32: Interval<i32> = Interval::<i32>::whole();
1570 let whole_u32: Interval<u32> = Interval::<u32>::whole();
1571
1572 assert_eq!(zero.size(), 1);
1573 assert_eq!(one.size(), 1);
1574 assert_eq!(empty.size(), 0);
1575 assert_eq!(invalid.size(), 0);
1576
1577 assert_eq!(i1_2.size(), 2);
1578 assert_eq!(i0_10.size(), 11);
1579 assert_eq!(im30_m20.size(), 11);
1580
1581 assert_eq!(whole_i32.size(), u32::max_value());
1582 assert_eq!(whole_u32.size(), u32::max_value());
1583 }
1584
1585 #[test]
1586 fn contains_test() {
1587 assert!(i1_2.contains(&1));
1588 assert!(i1_2.contains(&2));
1589 assert!(!i1_2.contains(&0));
1590 assert!(!i1_2.contains(&3));
1591
1592 assert!(zero.contains(&0));
1593 assert!(!zero.contains(&1));
1594
1595 assert!(!empty.contains(&0));
1596 assert!(!empty.contains(&1));
1597 assert!(!empty.contains(&5));
1598 assert!(!empty.contains(&-5));
1599
1600 assert!(!invalid.contains(&0));
1601 assert!(!invalid.contains(&-11));
1602 assert!(!invalid.contains(&11));
1603 }
1604
1605 #[test]
1606 fn is_subset_test() {
1607 let cases = vec![
1608 (zero, zero, true),
1609 (i1_2, i1_2, true),
1610 (empty, empty, true),
1611 (invalid, invalid, true),
1612 ];
1613
1614 let sym_cases = vec![
1620 (empty, zero, (true, false)),
1623 (invalid, zero, (true, false)),
1624 (empty, invalid, (true, true)),
1625 (empty, i1_2, (true, false)),
1628 (empty, i0_10, (true, false)),
1629 (invalid, i1_2, (true, false)),
1630 (i1_2, i0_10, (true, false)),
1633 (i0_4, i5_10, (false, false)),
1636 (i0_5, i5_10, (false, false)),
1639 (im5_5, i0_10, (false, false)),
1642 (i0_10, i20_30, (false, false)),
1645 (i0_10, i0_15, (true, false)),
1648 (im5_10, i0_10, (false, true)),
1651 ];
1652
1653 for (x, y, r) in cases.into_iter() {
1654 assert!(
1655 x.is_subset(&y) == r,
1656 "{:?} is subset of {:?} is not equal to {:?}",
1657 x,
1658 y,
1659 r
1660 );
1661 }
1662
1663 for (x, y, (r1, r2)) in sym_cases.into_iter() {
1664 assert!(
1665 x.is_subset(&y) == r1,
1666 "{:?} is subset of {:?} is not equal to {:?}",
1667 x,
1668 y,
1669 r1
1670 );
1671 assert!(
1672 y.is_subset(&x) == r2,
1673 "{:?} is subset of {:?} is not equal to {:?}",
1674 y,
1675 x,
1676 r2
1677 );
1678 }
1679 }
1680
1681 #[test]
1682 fn is_proper_subset_test() {
1683 let cases = vec![
1684 (zero, zero, false),
1685 (i1_2, i1_2, false),
1686 (empty, empty, false),
1687 (invalid, invalid, false),
1688 ];
1689
1690 let sym_cases = vec![
1696 (empty, zero, (true, false)),
1699 (invalid, zero, (true, false)),
1700 (empty, invalid, (false, false)),
1701 (empty, i1_2, (true, false)),
1704 (empty, i0_10, (true, false)),
1705 (invalid, i1_2, (true, false)),
1706 (i1_2, i0_10, (true, false)),
1709 (i0_4, i5_10, (false, false)),
1712 (i0_5, i5_10, (false, false)),
1715 (im5_5, i0_10, (false, false)),
1718 (i0_10, i20_30, (false, false)),
1721 (i0_10, i0_15, (true, false)),
1724 (im5_10, i0_10, (false, true)),
1727 ];
1728
1729 for (x, y, r) in cases.into_iter() {
1730 assert!(
1731 x.is_proper_subset(&y) == r,
1732 "{:?} is proper subset of {:?} is not equal to {:?}",
1733 x,
1734 y,
1735 r
1736 );
1737 }
1738
1739 for (x, y, (r1, r2)) in sym_cases.into_iter() {
1740 assert!(
1741 x.is_proper_subset(&y) == r1,
1742 "{:?} is proper subset of {:?} is not equal to {:?}",
1743 x,
1744 y,
1745 r1
1746 );
1747 assert!(
1748 y.is_proper_subset(&x) == r2,
1749 "{:?} is proper subset of {:?} is not equal to {:?}",
1750 y,
1751 x,
1752 r2
1753 );
1754 }
1755 }
1756
1757 #[test]
1758 fn intersection_test() {
1759 let cases = vec![
1760 (zero, zero, zero),
1761 (i1_2, i1_2, i1_2),
1762 (empty, empty, empty),
1763 (invalid, invalid, invalid),
1764 ];
1765
1766 let sym_cases = vec![
1772 (empty, zero, empty),
1775 (invalid, zero, empty),
1776 (empty, invalid, empty),
1777 (empty, i1_2, empty),
1780 (empty, i0_10, empty),
1781 (invalid, i1_2, empty),
1782 (i1_2, i0_10, i1_2),
1785 (i0_4, i5_10, empty),
1788 (i0_5, i5_10, 5.to_interval()),
1791 (im5_5, i0_10, (0, 5).to_interval()),
1794 (i0_10, i20_30, empty),
1797 (i0_10, i0_15, i0_10),
1800 (im5_10, i0_10, i0_10),
1803 ];
1804
1805 for (x, y, r) in cases.into_iter() {
1806 assert!(
1807 x.intersection(&y) == r,
1808 "{:?} intersection {:?} is not equal to {:?}",
1809 x,
1810 y,
1811 r
1812 );
1813 }
1814
1815 for (x, y, r) in sym_cases.into_iter() {
1816 assert!(
1817 x.intersection(&y) == r,
1818 "{:?} intersection {:?} is not equal to {:?}",
1819 x,
1820 y,
1821 r
1822 );
1823 assert!(
1824 y.intersection(&x) == r,
1825 "{:?} intersection {:?} is not equal to {:?}",
1826 y,
1827 x,
1828 r
1829 );
1830 }
1831 }
1832
1833 #[test]
1834 fn intersection_value_optional_test() {
1835 let cases = vec![
1836 (1, empty, None, empty, None),
1837 (2, invalid, None, empty, None),
1838 (3, empty, Some(1), empty, None),
1839 (4, i0_10, None, empty, None),
1840 (5, i0_10, Some(0), zero, Some(0)),
1841 (6, i0_10, Some(10), ten, Some(10)),
1842 (7, i0_10, Some(1), one, Some(1)),
1843 (8, i0_10, Some(-1), empty, None),
1844 (9, i0_10, Some(11), empty, None),
1845 (10, one, Some(0), empty, None),
1846 (11, one, Some(1), one, Some(1)),
1847 ];
1848 for (id, x, y, r1, r2) in cases.into_iter() {
1849 let y = y.map_or(Optional::empty(), |y| Optional::singleton(y));
1850 let r2 = r2.map_or(Optional::empty(), |r2| Optional::singleton(r2));
1851 if !y.is_empty() {
1853 assert!(
1854 x.intersection(y.as_ref().unwrap()) == r1,
1855 "Test#{}: {:?} intersection {:?} is not equal to {:?}",
1856 id,
1857 x,
1858 y.as_ref().unwrap(),
1859 r1
1860 );
1861 }
1862 assert!(
1864 x.intersection(&y) == r1,
1865 "Test#{}: {:?} intersection {:?} is not equal to {:?}",
1866 id,
1867 x,
1868 y,
1869 r1
1870 );
1871 assert!(
1873 y.intersection(&x) == r2,
1874 "Test#{}: {:?} intersection {:?} is not equal to {:?}",
1875 id,
1876 y,
1877 x,
1878 r2
1879 );
1880 }
1881 }
1882
1883 #[test]
1884 fn hull_test() {
1885 let cases = vec![
1886 (zero, zero, zero),
1887 (i1_2, i1_2, i1_2),
1888 (empty, empty, empty),
1889 (invalid, invalid, invalid),
1890 ];
1891
1892 let sym_cases = vec![
1898 (empty, zero, zero),
1901 (invalid, zero, zero),
1902 (empty, invalid, empty),
1903 (empty, i1_2, i1_2),
1906 (empty, i0_10, i0_10),
1907 (invalid, i1_2, i1_2),
1908 (i1_2, i0_10, i0_10),
1911 (i0_4, i5_10, i0_10),
1914 (i0_5, i5_10, i0_10),
1917 (im5_5, i0_10, (-5, 10).to_interval()),
1920 (i0_10, i20_30, (0, 30).to_interval()),
1923 (i0_10, i0_15, i0_15),
1926 (im5_10, i0_10, im5_10),
1929 ];
1930
1931 for (x, y, r) in cases.into_iter() {
1932 assert!(
1933 x.hull(&y) == r,
1934 "{:?} hull {:?} is not equal to {:?}",
1935 x,
1936 y,
1937 r
1938 );
1939 }
1940
1941 for (x, y, r) in sym_cases.into_iter() {
1942 assert!(
1943 x.hull(&y) == r,
1944 "{:?} hull {:?} is not equal to {:?}",
1945 x,
1946 y,
1947 r
1948 );
1949 assert!(
1950 y.hull(&x) == r,
1951 "{:?} hull {:?} is not equal to {:?}",
1952 y,
1953 x,
1954 r
1955 );
1956 }
1957 }
1958
1959 #[test]
1960 fn is_disjoint_test() {
1961 let cases = vec![
1962 (zero, zero, false),
1963 (i1_2, i1_2, false),
1964 (empty, empty, true),
1965 (invalid, invalid, true),
1966 ];
1967
1968 let sym_cases = vec![
1974 (empty, zero, true),
1977 (invalid, zero, true),
1978 (empty, invalid, true),
1979 (empty, i1_2, true),
1982 (empty, i0_10, true),
1983 (invalid, i1_2, true),
1984 (i1_2, i0_10, false),
1987 (i0_4, i5_10, true),
1990 (i0_5, i5_10, false),
1993 (im5_5, i0_10, false),
1996 (i0_10, i20_30, true),
1999 (i0_10, i0_15, false),
2002 (im5_10, i0_10, false),
2005 ];
2006
2007 for (x, y, r) in cases.into_iter() {
2008 assert!(
2009 x.is_disjoint(&y) == r,
2010 "{:?} is disjoint of {:?} is not equal to {:?}",
2011 x,
2012 y,
2013 r
2014 );
2015 assert!(
2016 x.overlap(&y) == !r,
2017 "{:?} overlap {:?} is not equal to {:?}",
2018 x,
2019 y,
2020 r
2021 );
2022 }
2023
2024 for (x, y, r) in sym_cases.into_iter() {
2025 assert!(
2026 x.is_disjoint(&y) == r,
2027 "{:?} is disjoint of {:?} is not equal to {:?}",
2028 x,
2029 y,
2030 r
2031 );
2032 assert!(
2033 y.is_disjoint(&x) == r,
2034 "{:?} is disjoint of {:?} is not equal to {:?}",
2035 y,
2036 x,
2037 r
2038 );
2039 assert!(
2040 x.overlap(&y) == !r,
2041 "{:?} overlap {:?} is not equal to {:?}",
2042 x,
2043 y,
2044 r
2045 );
2046 assert!(
2047 y.overlap(&x) == !r,
2048 "{:?} overlap {:?} is not equal to {:?}",
2049 y,
2050 x,
2051 r
2052 );
2053 }
2054 }
2055
2056 fn is_disjoint_cases() -> Vec<(u32, Interval<i32>, i32, bool)> {
2057 vec![
2058 (1, empty, 0, true),
2059 (2, invalid, 0, true),
2060 (3, i0_4, -1, true),
2061 (4, i0_4, 0, false),
2062 (5, i0_4, 2, false),
2063 (6, i0_4, 3, false),
2064 (7, i0_4, 5, true),
2065 ]
2066 }
2067
2068 #[test]
2069 fn is_disjoint_bound_test() {
2070 let cases = is_disjoint_cases();
2071 for (id, x, y, r) in cases.into_iter() {
2072 assert!(
2073 x.is_disjoint(&y) == r,
2074 "Test#{}: {:?} is disjoint of {:?} is not equal to {:?}",
2075 id,
2076 x,
2077 y,
2078 r
2079 );
2080 assert!(
2081 y.is_disjoint(&x) == r,
2082 "Test#{}: {:?} is disjoint of {:?} is not equal to {:?}",
2083 id,
2084 y,
2085 x,
2086 r
2087 );
2088 assert!(
2089 x.overlap(&y) == !r,
2090 "Test#{}: {:?} overlap {:?} is not equal to {:?}",
2091 id,
2092 x,
2093 y,
2094 !r
2095 );
2096 assert!(
2097 y.overlap(&x) == !r,
2098 "Test#{}: {:?} overlap {:?} is not equal to {:?}",
2099 id,
2100 y,
2101 x,
2102 !r
2103 );
2104 }
2105 }
2106
2107 #[test]
2108 fn is_disjoint_option_test() {
2109 let mut cases: Vec<(u32, Interval<i32>, Optional<i32>, bool)> = is_disjoint_cases()
2110 .into_iter()
2111 .map(|(id, a, b, e)| (id, a, Optional::singleton(b), e))
2112 .collect();
2113 cases.extend(vec![
2114 (8, empty, Optional::empty(), true),
2115 (9, invalid, Optional::empty(), true),
2116 (10, i0_4, Optional::empty(), true),
2117 ]);
2118 for (id, x, y, r) in cases.into_iter() {
2119 assert!(
2120 x.is_disjoint(&y) == r,
2121 "Test#{}: {:?} is disjoint of {:?} is not equal to {:?}",
2122 id,
2123 x,
2124 y,
2125 r
2126 );
2127 assert!(
2128 y.is_disjoint(&x) == r,
2129 "Test#{}: {:?} is disjoint of {:?} is not equal to {:?}",
2130 id,
2131 y,
2132 x,
2133 r
2134 );
2135 assert!(
2136 x.overlap(&y) == !r,
2137 "Test#{}: {:?} overlap {:?} is not equal to {:?}",
2138 id,
2139 x,
2140 y,
2141 !r
2142 );
2143 assert!(
2144 y.overlap(&x) == !r,
2145 "Test#{}: {:?} overlap {:?} is not equal to {:?}",
2146 id,
2147 y,
2148 x,
2149 !r
2150 );
2151 }
2152 }
2153
2154 #[test]
2155 fn difference_test() {
2156 let cases = vec![
2157 (1, zero, zero, empty),
2158 (2, i1_2, i1_2, empty),
2159 (3, empty, empty, empty),
2160 (4, invalid, invalid, empty),
2161 ];
2162
2163 let sym_cases = vec![
2169 (5, empty, zero, (empty, zero)),
2172 (6, invalid, zero, (empty, zero)),
2173 (7, empty, invalid, (empty, empty)),
2174 (8, empty, i1_2, (empty, i1_2)),
2177 (9, empty, i0_10, (empty, i0_10)),
2178 (10, invalid, i1_2, (empty, i1_2)),
2179 (11, i1_2, i0_10, (empty, i0_10)),
2182 (12, i0_4, i5_10, (i0_4, i5_10)),
2185 (13, i0_5, i5_10, ((0, 4).to_interval(), i6_10)),
2188 (14, im5_5, i0_10, (im5_m1, i6_10)),
2191 (15, i0_10, i20_30, (i0_10, i20_30)),
2194 (16, i0_10, i0_15, (empty, (11, 15).to_interval())),
2197 (17, im5_10, i0_10, (im5_m1, empty)),
2200 ];
2201
2202 for (id, x, y, r) in cases.into_iter() {
2203 println!("Test #{}", id);
2204 assert!(
2205 x.difference(&y) == r,
2206 "{:?} difference {:?} is not equal to {:?}",
2207 x,
2208 y,
2209 r
2210 );
2211 }
2212
2213 for (id, x, y, (r1, r2)) in sym_cases.into_iter() {
2214 println!("Test #{}", id);
2215 assert!(
2216 x.difference(&y) == r1,
2217 "{:?} difference {:?} is not equal to {:?}",
2218 x,
2219 y,
2220 r1
2221 );
2222 assert!(
2223 y.difference(&x) == r2,
2224 "{:?} difference {:?} is not equal to {:?}",
2225 y,
2226 x,
2227 r2
2228 );
2229 }
2230 }
2231
2232 #[test]
2233 fn difference_value_option_test() {
2234 let cases = vec![
2235 (1, empty, None, empty, None),
2236 (2, invalid, None, empty, None),
2237 (3, empty, Some(1), empty, Some(1)),
2238 (4, i0_10, None, i0_10, None),
2239 (5, i0_10, Some(0), i1_10, None),
2240 (6, i0_10, Some(10), i0_9, None),
2241 (7, i0_10, Some(1), i0_10, None),
2242 (8, i0_10, Some(9), i0_10, None),
2243 (9, i0_10, Some(-1), i0_10, Some(-1)),
2244 (10, i0_10, Some(11), i0_10, Some(11)),
2245 (11, i0_10, Some(100), i0_10, Some(100)),
2246 (12, one, Some(1), empty, None),
2247 ];
2248 for (id, x, y, r1, r2) in cases.into_iter() {
2249 let y = y.map_or(Optional::empty(), |y| Optional::singleton(y));
2250 let r2 = r2.map_or(Optional::empty(), |r2| Optional::singleton(r2));
2251 if y.is_some() {
2253 assert!(
2254 x.difference(y.as_ref().unwrap()) == r1,
2255 "Test#{}: {:?} difference {:?} is not equal to {:?}",
2256 id,
2257 x,
2258 y.as_ref().unwrap(),
2259 r1
2260 );
2261 }
2262 assert!(
2264 x.difference(&y) == r1,
2265 "Test#{}: {:?} difference {:?} is not equal to {:?}",
2266 id,
2267 x,
2268 y,
2269 r1
2270 );
2271 assert!(
2273 y.difference(&x) == r2,
2274 "Test#{}: {:?} difference {:?} is not equal to {:?}",
2275 id,
2276 y,
2277 x,
2278 r2
2279 );
2280 }
2281 }
2282
2283 #[test]
2284 fn shrink_left_test() {
2285 let cases = vec![
2286 (i0_10, -5, i0_10),
2287 (i0_10, 0, i0_10),
2288 (i0_10, 1, i1_10),
2289 (i0_10, 5, i5_10),
2290 (i0_10, 10, ten),
2291 (i0_10, 11, empty),
2292 (i0_10, 100, empty),
2293 (empty, 0, empty),
2294 ];
2295 for (x, y, r) in cases.into_iter() {
2296 assert!(
2297 x.shrink_left(y) == r,
2298 "{:?} shrink_left {:?} is not equal to {:?}",
2299 x,
2300 y,
2301 r
2302 );
2303 }
2304 }
2305
2306 #[test]
2307 fn shrink_right_test() {
2308 let cases = vec![
2309 (i0_10, 15, i0_10),
2310 (i0_10, 10, i0_10),
2311 (i0_10, 9, i0_9),
2312 (i0_10, 5, i0_5),
2313 (i0_10, 0, zero),
2314 (i0_10, -1, empty),
2315 (i0_10, -100, empty),
2316 (empty, 0, empty),
2317 ];
2318 for (x, y, r) in cases.into_iter() {
2319 assert!(
2320 x.shrink_right(y) == r,
2321 "{:?} shrink_right {:?} is not equal to {:?}",
2322 x,
2323 y,
2324 r
2325 );
2326 }
2327 }
2328
2329 #[test]
2330 fn add_sub_mul_bound_test() {
2331 let cases = vec![
2335 (zero, 0, zero, zero, zero),
2336 (i1_2, 0, i1_2, i1_2, zero),
2337 (empty, 0, empty, empty, empty),
2338 (invalid, 0, empty, empty, empty),
2339 (zero, 1, one, (-1, -1).to_interval(), zero),
2340 (i1_2, 1, (2, 3).to_interval(), (0, 1).to_interval(), i1_2),
2341 (empty, 1, empty, empty, empty),
2342 (invalid, 1, empty, empty, empty),
2343 (zero, 3, (3, 3).to_interval(), (-3, -3).to_interval(), zero),
2344 (
2345 i1_2,
2346 3,
2347 (4, 5).to_interval(),
2348 (-2, -1).to_interval(),
2349 (3, 6).to_interval(),
2350 ),
2351 (empty, 3, empty, empty, empty),
2352 (invalid, 3, empty, empty, empty),
2353 ];
2354
2355 for &(x, y, r1, r2, r3) in &cases {
2356 assert!(x + y == r1, "{:?} + {:?} is not equal to {:?}", x, y, r1);
2357 assert!(x - y == r2, "{:?} - {:?} is not equal to {:?}", x, y, r2);
2358 assert!(x * y == r3, "{:?} * {:?} is not equal to {:?}", x, y, r3);
2359 }
2360 }
2361
2362 #[test]
2363 fn add_test() {
2364 let sym_cases = vec![
2368 (zero, zero, zero),
2369 (i1_2, i1_2, (2, 4).to_interval()),
2370 (empty, empty, empty),
2371 (invalid, invalid, empty),
2372 (empty, zero, empty),
2375 (invalid, zero, empty),
2376 (empty, invalid, empty),
2377 (empty, i1_2, empty),
2380 (empty, i0_10, empty),
2381 (invalid, i1_2, empty),
2382 (zero, i0_10, i0_10),
2383 (i1_2, i0_10, (1, 12).to_interval()),
2384 (im5_10, i0_10, (-5, 20).to_interval()),
2385 (im5_10, im30_m20, (-35, -10).to_interval()),
2386 ];
2387
2388 for &(x, y, r) in &sym_cases {
2389 assert!(x + y == r, "{:?} + {:?} is not equal to {:?}", x, y, r);
2390 assert!(y + x == r, "{:?} + {:?} is not equal to {:?}", y, x, r);
2391 }
2392 }
2393
2394 #[test]
2395 fn sub_test() {
2396 let cases = vec![
2400 (zero, zero, zero),
2401 (i1_2, i1_2, (-1, 1).to_interval()),
2402 (empty, empty, empty),
2403 (invalid, invalid, empty),
2404 (empty, zero, empty),
2407 (invalid, zero, empty),
2408 (empty, invalid, empty),
2409 (empty, i1_2, empty),
2412 (empty, i0_10, empty),
2413 (invalid, i1_2, empty),
2414 ];
2415
2416 let sym_cases = vec![
2420 (zero, i0_10, ((-10, 0), (0, 10))),
2421 (i1_2, i0_10, ((-9, 2), (-2, 9))),
2422 (im5_10, i0_10, ((-15, 10), (-10, 15))),
2423 (im5_10, im30_m20, ((15, 40), (-40, -15))),
2424 ];
2425
2426 for &(x, y, r) in &cases {
2427 assert!(x - y == r, "{:?} - {:?} is not equal to {:?}", x, y, r);
2428 assert!(y - x == r, "{:?} - {:?} is not equal to {:?}", y, x, r);
2429 }
2430
2431 for &(x, y, (r1, r2)) in &sym_cases {
2432 let r1 = r1.to_interval();
2433 let r2 = r2.to_interval();
2434 assert!(x - y == r1, "{:?} - {:?} is not equal to {:?}", x, y, r1);
2435 assert!(y - x == r2, "{:?} - {:?} is not equal to {:?}", y, x, r2);
2436 }
2437 }
2438
2439 #[test]
2440 fn mul_test() {
2441 let sym_cases = vec![
2445 (zero, zero, zero),
2446 (i1_2, i1_2, (1, 4).to_interval()),
2447 (empty, empty, empty),
2448 (invalid, invalid, empty),
2449 (empty, zero, empty),
2452 (invalid, zero, empty),
2453 (empty, invalid, empty),
2454 (empty, i1_2, empty),
2457 (empty, i0_10, empty),
2458 (invalid, i1_2, empty),
2459 (zero, i0_10, zero),
2460 (one, i0_10, i0_10),
2461 (i1_2, i0_10, (0, 20).to_interval()),
2462 (im5_10, i0_10, (-50, 100).to_interval()),
2463 (im5_10, im30_m20, (-300, 150).to_interval()),
2464 ];
2465
2466 for &(x, y, r) in &sym_cases {
2467 assert!(x * y == r, "{:?} * {:?} is not equal to {:?}", x, y, r);
2468 assert!(y * x == r, "{:?} * {:?} is not equal to {:?}", y, x, r);
2469 }
2470 }
2471
2472 #[test]
2473 fn test_lattice() {
2474 use gcollections::ops::lattice::test::*;
2475 use trilean::SKleene::*;
2476 let whole = Interval::<i32>::whole();
2477 let tester = LatticeTester::new(
2478 0,
2479 vec![empty, empty, whole, zero, zero, zero, i1_2, i0_10, im5_5],
2480 vec![zero, whole, empty, zero, one, i1_2, i0_10, im5_5, i6_10],
2481 vec![
2483 True, True, False, True, Unknown, Unknown, True, Unknown, Unknown,
2484 ],
2485 vec![empty, empty, empty, zero, empty, empty, i1_2, i0_5, empty],
2486 vec![zero, whole, whole, zero, i0_1, i0_2, i0_10, im5_10, im5_10],
2487 );
2488 tester.test_all();
2489 }
2490
2491 #[test]
2492 fn test_ser_de_interval() {
2493 let interval = Interval::new(10, 20);
2494 assert_tokens(
2495 &interval,
2496 &[
2497 Token::Tuple { len: 2 },
2498 Token::I32(10),
2499 Token::I32(20),
2500 Token::TupleEnd,
2501 ],
2502 );
2503 }
2504
2505 #[test]
2506 fn test_de_interval_mixed_types() {
2507 let interval = Interval::new(-5, 15);
2508 assert_de_tokens::<Interval<i32>>(
2509 &interval,
2510 &[
2511 Token::Tuple { len: 2 },
2512 Token::I32(-5),
2513 Token::I64(15),
2514 Token::TupleEnd,
2515 ],
2516 );
2517 }
2518
2519 #[test]
2520 fn test_de_interval_extra_token() {
2521 assert_de_tokens_error::<Interval<i32>>(
2522 &[
2523 Token::Tuple { len: 3 },
2524 Token::I32(10),
2525 Token::I32(20),
2526 Token::I32(30),
2527 Token::TupleEnd,
2528 ],
2529 "invalid length 3, expected tuple of two numbers or none",
2530 );
2531 }
2532
2533 #[test]
2534 fn test_de_interval_extra_tokens() {
2535 assert_de_tokens_error::<Interval<i32>>(
2536 &[
2537 Token::Tuple { len: 5 },
2538 Token::I32(10),
2539 Token::I32(20),
2540 Token::I32(30),
2541 Token::I32(40),
2542 Token::I32(50),
2543 Token::TupleEnd,
2544 ],
2545 "invalid length 5, expected tuple of two numbers or none",
2546 );
2547 }
2548
2549 #[test]
2550 fn test_ser_de_interval_u8() {
2551 let interval = Interval::<u8>::new(10, 20);
2552 assert_tokens(
2553 &interval,
2554 &[
2555 Token::Tuple { len: 2 },
2556 Token::U8(10),
2557 Token::U8(20),
2558 Token::TupleEnd,
2559 ],
2560 );
2561 }
2562
2563 #[test]
2564 fn test_ser_de_interval_i64() {
2565 let interval = Interval::<i64>::whole();
2566 assert_tokens(
2567 &interval,
2568 &[
2569 Token::Tuple { len: 2 },
2570 Token::I64(<i64 as Width>::min_value()),
2571 Token::I64(<i64 as Width>::max_value()),
2572 Token::TupleEnd,
2573 ],
2574 );
2575 }
2576
2577 #[test]
2578 fn test_ser_de_empty_interval() {
2579 let interval = Interval::<i32>::empty();
2580 assert_tokens(&interval, &[Token::None]);
2581 }
2582
2583 #[test]
2584 fn range_inclusive_to_interval_test() {
2585 let interval = (-4..=25).to_interval();
2586 assert_eq!(&interval, &Interval::new(-4, 25));
2587 }
2588
2589 #[test]
2590 fn empty_range_inclusive_to_interval_test() {
2591 let interval = (8..=3).to_interval();
2592 assert_eq!(&interval, &Interval::empty());
2593 }
2594
2595 #[test]
2596 fn range_from_to_interval_test() {
2597 let interval = (23u8..).to_interval();
2598 assert_eq!(&interval, &Interval::new(23, 254));
2599 }
2600
2601 #[test]
2602 #[should_panic]
2603 fn range_from_u8_to_interval_edge_case_test() {
2604 let _ = (255u8..).to_interval();
2605 }
2606
2607 #[test]
2608 #[should_panic]
2609 fn range_from_i8_to_interval_edge_case_test() {
2610 let _ = (-128i8..).to_interval();
2611 }
2612
2613 #[test]
2614 fn range_to_inclusive_to_interval_test() {
2615 let interval = (..=8u8).to_interval();
2616 assert_eq!(&interval, &Interval::new(0, 8));
2617 }
2618
2619 #[test]
2620 #[should_panic]
2621 fn range_to_inclusive_u8_to_interval_edge_case_test() {
2622 let _ = (..=255u8).to_interval();
2623 }
2624
2625 #[test]
2626 #[should_panic]
2627 fn range_to_inclusive_i8_to_interval_edge_case_test() {
2628 let _ = (..=-128i8).to_interval();
2629 }
2630}