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}