intervals_rs/
interval.rs

1use std::fmt::{Debug, Display, Formatter};
2use std::hash::Hash;
3
4use crate::interval_limit::IntervalLimit;
5use crate::LimitValue;
6
7#[derive(Debug, Clone, Hash, Eq)]
8pub struct Interval<T: Debug + Display + Clone + Hash + Eq + Ord + PartialEq + PartialOrd> {
9  pub(crate) lower: IntervalLimit<T>,
10  pub(crate) upper: IntervalLimit<T>,
11}
12
13impl<T: Debug + Display + Clone + Hash + Eq + Ord + PartialEq + PartialOrd> PartialEq
14  for Interval<T>
15{
16  /// Verify the identity of this interval and the given interval `other`.
17  ///
18  /// It returns `true` if both intervals are empty, and `false` if only one of them is empty.
19  /// If both are single-element intervals, the limits that are single elements are compared with each other, and `true` is returned if they match.
20  /// If only one of them is a single-element interval, `false` is returned.
21  ///
22  /// - param
23  ///   - other: an interval to be compared
24  /// - return: `true` if they are identical, `false` if they are not
25  fn eq(&self, other: &Self) -> bool {
26    if self.is_empty() & other.is_empty() {
27      true
28    } else if self.is_empty() ^ other.is_empty() {
29      false
30    } else if self.is_single_element() & other.is_single_element() {
31      self.as_lower_limit() == other.as_lower_limit()
32    } else if self.is_single_element() ^ other.is_single_element() {
33      false
34    } else {
35      self.upper == other.upper && self.lower == other.lower
36    }
37  }
38}
39
40impl<T: Debug + Display + Clone + Hash + Eq + Ord + PartialEq + PartialOrd> Interval<T> {
41  /// Generate an interval.
42  ///
43  /// - params
44  ///     - lower: lower interval limit
45  ///     - upper: upper interval limit
46  /// - return: an interval
47  pub fn new(lower: IntervalLimit<T>, upper: IntervalLimit<T>) -> Interval<T> {
48    Self::check_lower_is_less_than_or_equal_upper(&lower, &upper);
49    let mut l = lower.clone();
50    let mut u = upper.clone();
51    if !upper.is_infinity()
52      && !lower.is_infinity()
53      && upper.as_value() == lower.as_value()
54      && (lower.is_open() ^ upper.is_open())
55    {
56      if lower.is_open() {
57        l = IntervalLimit::lower(true, lower.as_value().clone());
58      }
59      if upper.is_open() {
60        u = IntervalLimit::upper(true, upper.as_value().clone());
61      }
62    }
63    Self { lower: l, upper: u }
64  }
65
66  /// Generate an interval.
67  ///
68  /// Mainly used to generate half-open interval (intervals where only one of the upper and lower limits is open).
69  ///
70  /// - params
71  ///     - lower: lower limit, Limitless means there is no limit.
72  ///     - lower_included: specify `true` if the lower limit is included in the interval (closed lower limit).
73  ///     - upper: upper limit, Limitless means there is no limit.
74  ///     - upper_included: specify `true` if the upper limit is included in the interval (closed upper limit)
75  /// - return: an interval
76  /// - panic
77  ///     - if the lower limit is greater than the upper limit
78  pub fn over(
79    lower: LimitValue<T>,
80    lower_included: bool,
81    upper: LimitValue<T>,
82    upper_included: bool,
83  ) -> Self {
84    Self::new(
85      IntervalLimit::lower(lower_included, lower),
86      IntervalLimit::upper(upper_included, upper),
87    )
88  }
89
90  /// Generate an interval with only the lower limit.
91  ///
92  /// The lower limit is the interval that is included (closed) in the interval.
93  ///
94  /// - params
95  ///     - lower: lower limit, Limitless means that there is no limit.
96  /// - return: an interval
97  pub fn and_more(lower: LimitValue<T>) -> Self {
98    Self::closed(lower, LimitValue::<T>::Limitless)
99  }
100
101  /// Generate a closed interval.
102  ///
103  /// - params
104  ///     - lower: lower limit, Limitless means there is no limit.
105  ///     - upper: upper limit, Limitless means there is no limit.
106  /// - return: a closed interval
107  /// - panic
108  ///     - if the lower limit is greater than the upper limit
109  pub fn closed(lower: LimitValue<T>, upper: LimitValue<T>) -> Self {
110    Self::over(lower, true, upper, true)
111  }
112
113  /// Generate an interval with only the lower limit.
114  ///
115  /// The lower limit is the interval that is not included in the (open) interval.
116  ///
117  /// - params
118  ///     - lower: lower limit, Limitless means there is no limit.
119  /// - return: an interval
120  pub fn more_than(lower: LimitValue<T>) -> Self {
121    Self::open(lower, LimitValue::<T>::Limitless)
122  }
123
124  /// Generate an open interval.
125  ///
126  /// - params
127  ///     - lower: lower limit, Limitless means there is no limit.
128  ///     - upper: upper limit, Limitless means there is no limit.
129  /// - return: an open interval
130  pub fn open(lower: LimitValue<T>, upper: LimitValue<T>) -> Self {
131    Self::over(lower, false, upper, false)
132  }
133
134  /// Generate a single-element interval.
135  ///
136  /// - params
137  ///     - element: an limit value
138  /// - return: an interval
139  pub fn single_element(element: LimitValue<T>) -> Self {
140    Self::closed(element.clone(), element)
141  }
142
143  /// Generate an interval with only an upper limit.
144  ///
145  /// The upper limit is the interval that is not included in the (open) interval.
146  ///
147  /// - params
148  ///     - upper: upper limit, Limitless means there is no limit.
149  /// - return: an interval
150  pub fn under(upper: LimitValue<T>) -> Self {
151    Self::open(LimitValue::<T>::Limitless, upper)
152  }
153
154  /// Generate an interval with only an upper limit.
155  ///
156  /// The upper limit is the (closed) interval included in the interval.
157  ///
158  /// - params
159  ///     - upper: upper limit, Limitless means there is no limit.
160  /// - return: an interval
161  pub fn up_to(upper: LimitValue<T>) -> Self {
162    Self::closed(LimitValue::<T>::Limitless, upper)
163  }
164
165  pub fn as_upper_limit(&self) -> &LimitValue<T> {
166    self.upper.as_value()
167  }
168
169  pub fn as_lower_limit(&self) -> &LimitValue<T> {
170    self.lower.as_value()
171  }
172
173  /// Verify that this interval completely encloses the specified interval `other`.
174  ///
175  /// - params
176  ///     - other: an `Interval`
177  /// - return: `true` for full comprehension, `false` otherwise
178  pub fn covers(&self, other: &Interval<T>) -> bool {
179    let lower_pass = self.includes(other.as_lower_limit())
180      || self.as_lower_limit() == other.as_lower_limit() && !other.includes_lower_limit();
181    let upper_pass = self.includes(other.as_upper_limit())
182      || self.as_upper_limit() == other.as_upper_limit() && !other.includes_upper_limit();
183    lower_pass && upper_pass
184  }
185
186  /// Get the interval that lies between this interval and the given interval `other`.
187  ///
188  /// For example, the gap between [3, 5) and [10, 20) is [5, 19).
189  /// If the two intervals have a common part, return an empty interval.
190  ///
191  /// - params
192  ///     - other: an interval to be compared
193  /// - return: gap interval
194  pub fn gap(&self, other: &Interval<T>) -> Interval<T> {
195    if self.intersects(other) {
196      self.empty_of_same_type()
197    } else {
198      self.new_of_same_type(
199        self.lesser_of_upper_limits(other).clone(),
200        !self.lesser_of_upper_included_in_union(other),
201        self.greater_of_lower_limits(other).clone(),
202        !self.greater_of_lower_included_in_union(other),
203      )
204    }
205  }
206
207  /// Verify whether this interval is a single-element interval or not.
208  ///
209  /// A single-element interval has both upper and lower limits, and also indicates that these limits are equal and not an open interval.
210  /// For example, `3 <= x < 3`, `3 <= x <= 3`, and `3 <= x <= 3`.
211  ///
212  /// - return: `true` if it's a single element interval, `false` otherwise
213  pub fn is_single_element(&self) -> bool {
214    if !self.has_upper_limit() {
215      false
216    } else if !self.has_lower_limit() {
217      false
218    } else {
219      self.as_upper_limit() == self.as_lower_limit() && !self.is_empty()
220    }
221  }
222
223  /// Generate a new open interval with the same limits as this interval.
224  ///
225  /// - return: a new interval
226  pub fn empty_of_same_type(&self) -> Interval<T> {
227    self.new_of_same_type(
228      self.as_lower_limit().clone(),
229      false,
230      self.as_lower_limit().clone(),
231      false,
232    )
233  }
234
235  /// Generate a new interval with the same type as this interval.
236  ///
237  /// - params
238  ///     - lower: lower limit, if there is no limit value, then Limitless.
239  ///     - lower_closed: Specify `true` if the lower limit is included in the interval (closed lower limit).
240  ///     - upper: upper limit, if there is no limit value, then Limitless.
241  ///     - upper_closed: specify `true` if the upper limit is included in the interval (closed upper limit)
242  /// - return: an new interval
243  pub fn new_of_same_type(
244    &self,
245    lower: LimitValue<T>,
246    lower_closed: bool,
247    upper: LimitValue<T>,
248    upper_closed: bool,
249  ) -> Interval<T> {
250    Self::over(lower, lower_closed, upper, upper_closed)
251  }
252
253  /// Verify whether or not the specified value `value` is included in this interval.
254  ///
255  /// - params
256  ///     - value: an interval value
257  /// - return: `true` if included, `false` otherwise
258  pub fn includes(&self, value: &LimitValue<T>) -> bool {
259    !self.is_below(value) && !self.is_above(value)
260  }
261
262  /// Verify that the specified value `value` does not exceed the upper limit of this interval.
263  ///
264  /// - params
265  ///     - value: an interval value
266  /// - return: `true` if not exceeded, `false` otherwise
267  pub fn is_below(&self, value: &LimitValue<T>) -> bool {
268    if !self.has_upper_limit() {
269      false
270    } else {
271      *self.as_upper_limit() < *value
272        || *self.as_upper_limit() == *value && !self.includes_upper_limit()
273    }
274  }
275
276  /// Verify that the specified value `value` does not exceed the lower limit of this interval.
277  ///
278  /// - params
279  ///     - value: an interval value
280  /// - return: `true` if not exceeded, `false` otherwise
281  pub fn is_above(&self, value: &LimitValue<T>) -> bool {
282    if !self.has_lower_limit() {
283      false
284    } else {
285      *self.as_lower_limit() > *value
286        || *self.as_lower_limit() == *value && !self.includes_lower_limit()
287    }
288  }
289
290  /// Verify whether this interval is an open interval or not.
291  ///
292  /// - return: `true` if it's an open interval, `false` otherwise (including half-open interval)
293  pub fn is_open(&self) -> bool {
294    !self.includes_lower_limit() && !self.includes_upper_limit()
295  }
296
297  /// Verify whether this interval is a closed interval or not.
298  ///
299  /// - return: `true` if it's a closed interval, `false` otherwise (including half-open interval)
300  pub fn is_closed(&self) -> bool {
301    self.includes_upper_limit() && self.includes_lower_limit()
302  }
303
304  /// Verify whether this interval is empty or not.
305  ///
306  /// The interval is empty means that the upper and lower limits are the same value and the interval is open.
307  /// For example, a state like `3 < x < 3`.
308  ///
309  /// - return: `true` if it's empty, `false` otherwise.
310  pub fn is_empty(&self) -> bool {
311    match (self.as_upper_limit(), self.as_lower_limit()) {
312      (&LimitValue::Limitless, &LimitValue::Limitless) => false,
313      _ => self.is_open() && self.as_upper_limit() == self.as_lower_limit(),
314    }
315  }
316
317  /// Return the product set (common part) of this interval and the given interval `other`.
318  ///
319  /// If the common part does not exist, it returns an empty interval.
320  ///
321  /// - params
322  ///     - other: an interval to be compared
323  pub fn intersect(&self, other: &Interval<T>) -> Interval<T> {
324    let intersect_lower_bound = self.greater_of_lower_limits(other);
325    let intersect_upper_bound = self.lesser_of_upper_limits(other);
326    if *intersect_lower_bound > *intersect_upper_bound {
327      self.empty_of_same_type()
328    } else {
329      self.new_of_same_type(
330        intersect_lower_bound.clone(),
331        self.greater_of_lower_included_in_intersection(other),
332        intersect_upper_bound.clone(),
333        self.lesser_of_upper_included_in_intersection(other),
334      )
335    }
336  }
337
338  /// Verify if there is a common part between this interval and the given interval `other`.
339  ///
340  /// - params
341  ///     - other: a target interval
342  /// - return: `true` if the common part exists, `false` otherwise
343  pub fn intersects(&self, other: &Interval<T>) -> bool {
344    if self.equal_both_limitless(self.as_upper_limit(), other.as_upper_limit()) {
345      true
346    } else if self.equal_both_limitless(self.as_lower_limit(), self.as_lower_limit()) {
347      true
348    } else {
349      let g = self.greater_of_lower_limits(other);
350      let l = self.lesser_of_upper_limits(other);
351      if g < l {
352        true
353      } else if g > l {
354        false
355      } else {
356        self.greater_of_lower_included_in_intersection(other)
357          && self.lesser_of_upper_included_in_intersection(other)
358      }
359    }
360  }
361
362  /// Get whether there is an upper limit or not.
363  ///
364  /// Warning: This method is generally used for the purpose of displaying this value and for interaction with classes that are highly coupled to this class.
365  /// Careless use of this method will unnecessarily increase the coupling between this class and the client-side class.
366  ///
367  /// If you want to use this value for calculations,
368  /// - find another appropriate method or add a new method to this class.
369  /// - find another suitable method or consider adding a new method to this class.
370  ///
371  ///
372  /// - return: `true` if upper limit is present, `false` otherwise
373  pub fn has_upper_limit(&self) -> bool {
374    matches!(self.as_upper_limit(), LimitValue::Limit(_))
375  }
376
377  /// Get whether there is an lower limit or not.
378  ///
379  /// Warning: This method is generally used for the purpose of displaying this value and for interaction with classes that are highly coupled to this class.
380  /// Careless use of this method will unnecessarily increase the coupling between this class and the client-side class.
381  ///
382  /// If you want to use this value for calculations,
383  /// - find another appropriate method or add a new method to this class.
384  /// - find another suitable method or consider adding a new method to this class.
385  ///
386  ///
387  /// - return: `true` if lower limit is present, `false` otherwise
388  pub fn has_lower_limit(&self) -> bool {
389    matches!(self.as_lower_limit(), LimitValue::Limit(_))
390  }
391
392  /// Get whether the upper limit is closed or not.
393  ///
394  /// Warning: This method is generally used for the purpose of displaying this value and for interaction with classes that are highly coupled to this class.
395  /// Careless use of this method will unnecessarily increase the coupling between this class and the client-side class.
396  ///
397  /// If you want to use this value for calculations,
398  /// - find another appropriate method or add a new method to this class.
399  /// - find another suitable method or consider adding a new method to this class.
400  ///
401  /// - return: true` if the upper limit is closed, `false` otherwise
402  pub fn includes_upper_limit(&self) -> bool {
403    self.upper.is_closed()
404  }
405
406  /// Get whether the lower limit is closed or not.
407  ///
408  /// Warning: This method is generally used for the purpose of displaying this value and for interaction with classes that are highly coupled to this class.
409  /// Careless use of this method will unnecessarily increase the coupling between this class and the client-side class.
410  ///
411  /// If you want to use this value for calculations,
412  /// - find another appropriate method or add a new method to this class.
413  /// - find another suitable method or consider adding a new method to this class.
414  ///
415  /// - return: true` if the lower limit is closed, `false` otherwise
416  pub fn includes_lower_limit(&self) -> bool {
417    self.lower.is_closed()
418  }
419
420  pub(crate) fn complement_relative_to(&self, other: &Interval<T>) -> Vec<Interval<T>> {
421    let mut interval_sequence: Vec<Interval<T>> = vec![];
422    if !self.intersects(other) {
423      interval_sequence.push(other.clone());
424      interval_sequence
425    } else {
426      if let Some(left) = self.left_complement_relative_to(other) {
427        interval_sequence.push(left.clone());
428      }
429      if let Some(right) = self.right_complement_relative_to(other) {
430        interval_sequence.push(right.clone());
431      }
432      interval_sequence
433    }
434  }
435
436  fn check_lower_is_less_than_or_equal_upper(lower: &IntervalLimit<T>, upper: &IntervalLimit<T>) {
437    if !(lower.is_lower() && upper.is_upper() && lower <= upper) {
438      panic!("{} is not before or equal to {}", lower, upper)
439    }
440  }
441
442  fn equal_both_limitless(&self, me: &LimitValue<T>, your: &LimitValue<T>) -> bool {
443    matches!((me, your), (&LimitValue::Limitless, &LimitValue::Limitless))
444  }
445
446  /// Return the larger (narrower marginal, more constrained) of the lower limits of this interval and the given interval `other`.
447  ///
448  /// - params
449  ///     - other: limit value for comparison
450  /// - return: greater limit value
451  pub(crate) fn greater_of_lower_limits<'a>(&'a self, other: &'a Interval<T>) -> &'a LimitValue<T> {
452    if *self.as_lower_limit() == LimitValue::Limitless {
453      other.as_lower_limit()
454    } else if *other.as_lower_limit() == LimitValue::Limitless {
455      self.as_lower_limit()
456    } else if self.as_lower_limit() >= other.as_lower_limit() {
457      self.as_lower_limit()
458    } else {
459      other.as_lower_limit()
460    }
461  }
462
463  /// Return the smaller (narrower marginal, more constrained) of the upper limits of this interval and the given interval `other`.
464  ///
465  /// - params
466  ///     - other: limit value for comparison
467  /// - return: lesser limit value
468  pub(crate) fn lesser_of_upper_limits<'a>(&'a self, other: &'a Interval<T>) -> &'a LimitValue<T> {
469    if *self.as_upper_limit() == LimitValue::Limitless {
470      other.as_upper_limit()
471    } else if *other.as_upper_limit() == LimitValue::Limitless {
472      self.as_upper_limit()
473    } else if self.as_upper_limit() <= other.as_upper_limit() {
474      self.as_upper_limit()
475    } else {
476      other.as_upper_limit()
477    }
478  }
479
480  fn greater_of_lower_included_in_intersection(&self, other: &Interval<T>) -> bool {
481    let limit = self.greater_of_lower_limits(other);
482    self.includes(&limit) && other.includes(&limit)
483  }
484
485  fn greater_of_lower_included_in_union(&self, other: &Interval<T>) -> bool {
486    let limit = self.greater_of_lower_limits(other);
487    self.includes(&limit) || other.includes(&limit)
488  }
489
490  fn lesser_of_upper_included_in_intersection(&self, other: &Interval<T>) -> bool {
491    let limit = self.lesser_of_upper_limits(other);
492    self.includes(&limit) && other.includes(&limit)
493  }
494
495  fn lesser_of_upper_included_in_union(&self, other: &Interval<T>) -> bool {
496    let limit = self.lesser_of_upper_limits(other);
497    self.includes(&limit) || other.includes(&limit)
498  }
499
500  /// この区間の下側補区間と与えた区間 `other` の共通部分を返す。
501  ///
502  /// other 比較対象の区間
503  /// return この区間の下側の補区間と、与えた区間の共通部分。存在しない場合は `None`
504  fn left_complement_relative_to(&self, other: &Interval<T>) -> Option<Interval<T>> {
505    // この区間の下側限界値の方が小さいか等しい場合、下側の補区間に共通部分は無い
506    if self.lower <= other.lower {
507      None
508    } else {
509      Some(self.new_of_same_type(
510        other.as_lower_limit().clone(),
511        other.includes_lower_limit(),
512        self.as_lower_limit().clone(),
513        !self.includes_lower_limit(),
514      ))
515    }
516  }
517
518  fn right_complement_relative_to(&self, other: &Interval<T>) -> Option<Interval<T>> {
519    // この区間の上側限界値の方が大きいか等しい場合、上側の補区間に共通部分は無い
520    if self.upper >= other.upper {
521      None
522    } else {
523      Some(self.new_of_same_type(
524        self.as_upper_limit().clone(),
525        !self.includes_upper_limit(),
526        other.as_upper_limit().clone(),
527        other.includes_upper_limit(),
528      ))
529    }
530  }
531}
532
533impl<T: Debug + Display + Clone + Hash + Eq + Ord + PartialEq + PartialOrd> Display
534  for Interval<T>
535{
536  fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
537    if self.is_empty() {
538      write!(f, "{{}}")
539    } else if self.is_single_element() {
540      write!(f, "{{{}}}", self.as_lower_limit().to_string())
541    } else {
542      let mut str = String::new();
543      if self.includes_lower_limit() {
544        str.push('[');
545      } else {
546        str.push('(');
547      }
548      if self.has_lower_limit() {
549        str.push_str(&self.as_lower_limit().to_string());
550      } else {
551        str.push_str(&"Infinity");
552      }
553      str.push_str(&", ");
554      if self.has_upper_limit() {
555        str.push_str(&self.as_upper_limit().to_string());
556      } else {
557        str.push_str(&"Infinity");
558      }
559      if self.includes_upper_limit() {
560        str.push(']');
561      } else {
562        str.push(')');
563      }
564      write!(f, "{}", str)
565    }
566  }
567}