baseunits_rs/intervals/
interval.rs

1use std::cmp::Ordering;
2
3use crate::intervals::{IntervalLimit, LimitValue};
4use rust_fp_categories::Empty;
5use std::fmt::Debug;
6
7#[derive(Debug, Clone)]
8pub struct Interval<T> {
9  lower: IntervalLimit<T>,
10  upper: IntervalLimit<T>,
11}
12
13impl<T: Debug + Default + Clone + PartialOrd> Default for Interval<T> {
14  fn default() -> Self {
15    Interval::single_element(LimitValue::default())
16  }
17}
18
19impl<T: Debug + Default + Clone + PartialEq + PartialOrd> PartialEq for Interval<T> {
20  fn eq(&self, other: &Self) -> bool {
21    self.lower.partial_cmp(&other.lower) == Some(Ordering::Equal)
22      && self.upper.partial_cmp(&other.upper) == Some(Ordering::Equal)
23  }
24}
25
26impl<T: Debug + Default + Clone + PartialEq + PartialOrd>
27  From<(LimitValue<T>, bool, LimitValue<T>, bool)> for Interval<T>
28{
29  fn from(
30    (lower, is_lower_closed, upper, is_upper_closed): (LimitValue<T>, bool, LimitValue<T>, bool),
31  ) -> Self {
32    Self::new(
33      IntervalLimit::lower(is_lower_closed, lower),
34      IntervalLimit::upper(is_upper_closed, upper),
35    )
36  }
37}
38
39impl<T: Debug + Default + Clone + PartialEq + PartialOrd> Empty for Interval<T> {
40  fn empty() -> Self {
41    let lower = IntervalLimit::lower(false, LimitValue::Limit(T::default()));
42    let upper = IntervalLimit::upper(false, LimitValue::Limit(T::default()));
43    Self::new(lower, upper)
44  }
45
46  fn is_empty(&self) -> bool {
47    match (self.upper_limit(), self.lower_limit()) {
48      (LimitValue::Limitless, LimitValue::Limitless) => false,
49      (..) => self.is_open() && self.upper_limit() == self.lower_limit(),
50    }
51  }
52}
53
54impl<T: Debug + Default + Clone + PartialEq + PartialOrd> Interval<T> {
55  fn check_lower_is_less_than_or_equal_upper(lower: &IntervalLimit<T>, upper: &IntervalLimit<T>) {
56    if !(lower.lower && upper.is_upper() && lower.partial_cmp(upper) == Some(Ordering::Less)) {
57      panic!("{:?} is not before or equal to {:?}", lower, upper)
58    }
59  }
60  pub fn new(lower: IntervalLimit<T>, upper: IntervalLimit<T>) -> Self {
61    Self::check_lower_is_less_than_or_equal_upper(&lower, &upper);
62    let (new_lower, new_upper) = if !upper.infinity()
63      && !lower.infinity()
64      && upper.value == lower.value
65      && (lower.is_open() ^ upper.is_open())
66    {
67      let l = if lower.is_open() {
68        IntervalLimit::lower(true, lower.value)
69      } else {
70        lower
71      };
72      let u = if upper.is_open() {
73        IntervalLimit::upper(true, upper.value)
74      } else {
75        upper
76      };
77      (l, u)
78    } else {
79      (lower, upper)
80    };
81    Self {
82      lower: new_lower,
83      upper: new_upper,
84    }
85  }
86
87  pub fn and_more(lower: LimitValue<T>) -> Self {
88    Self::closed(lower, LimitValue::<T>::Limitless)
89  }
90
91  pub fn closed(lower: LimitValue<T>, upper: LimitValue<T>) -> Self {
92    Self::from((lower, true, upper, true))
93  }
94
95  pub fn more_than(lower: LimitValue<T>) -> Self {
96    Self::open(lower, LimitValue::<T>::Limitless)
97  }
98
99  pub fn open(lower: LimitValue<T>, upper: LimitValue<T>) -> Self {
100    Self::from((lower, false, upper, false))
101  }
102
103  pub fn over(
104    lower: LimitValue<T>,
105    lower_included: bool,
106    upper: LimitValue<T>,
107    upper_included: bool,
108  ) -> Self {
109    Self::from((lower, lower_included, upper, upper_included))
110  }
111
112  pub fn single_element(element: LimitValue<T>) -> Self {
113    Self::closed(element.clone(), element)
114  }
115
116  pub fn under(upper: LimitValue<T>) -> Self {
117    Self::open(LimitValue::<T>::Limitless, upper)
118  }
119
120  pub fn up_to(upper: LimitValue<T>) -> Self {
121    Self::closed(LimitValue::<T>::Limitless, upper)
122  }
123
124  pub fn is_single_element(&self) -> bool {
125    if !self.has_upper_limit() {
126      false
127    } else {
128      self.upper_limit() == self.lower_limit() && !self.is_empty()
129    }
130  }
131
132  pub fn empty_of_same_type(&self) -> Self {
133    self.new_of_same_type(
134      self.lower_limit().clone(),
135      false,
136      self.lower_limit().clone(),
137      false,
138    )
139  }
140
141  fn new_of_same_type(
142    &self,
143    lower: LimitValue<T>,
144    lower_closed: bool,
145    upper: LimitValue<T>,
146    upper_closed: bool,
147  ) -> Self {
148    Interval::from((lower, lower_closed, upper, upper_closed))
149  }
150
151  fn includes(&self, value: &LimitValue<T>) -> bool {
152    !self.is_below(value) && !self.is_above(value)
153  }
154
155  fn greater_of_lower_included_in_intersection(&self, other: &Self) -> bool {
156    let limit = self.greater_of_lower_limits(other);
157    self.includes(limit) && other.includes(limit)
158  }
159
160  fn greater_of_lower_included_in_union(&self, other: &Self) -> bool {
161    let limit = self.greater_of_lower_limits(other);
162    self.includes(limit) || other.includes(limit)
163  }
164
165  fn lesser_of_upper_included_in_intersection(&self, other: &Interval<T>) -> bool {
166    let limit = self.lesser_of_upper_limits(other);
167    self.includes(limit) && other.includes(limit)
168  }
169
170  fn lesser_of_upper_included_in_union(&self, other: &Interval<T>) -> bool {
171    let limit = self.lesser_of_upper_limits(other);
172    self.includes(limit) || other.includes(limit)
173  }
174
175  fn equal_both_limitless(&self, me: &LimitValue<T>, your: &LimitValue<T>) -> bool {
176    match (me, your) {
177      (LimitValue::Limitless, LimitValue::Limitless) => true,
178      (..) => false,
179    }
180  }
181
182  fn greater_of_lower_limits<'a, 'b>(&'a self, other: &'b Interval<T>) -> &'a LimitValue<T>
183  where
184    'b: 'a,
185  {
186    if self.lower.value == LimitValue::Limitless {
187      other.lower_limit()
188    } else if other.lower.value == LimitValue::Limitless || self.lower.value >= other.lower.value {
189      self.lower_limit()
190    } else {
191      other.lower_limit()
192    }
193  }
194
195  fn lesser_of_upper_limits<'a, 'b>(&'a self, other: &'b Interval<T>) -> &'a LimitValue<T>
196  where
197    'b: 'a,
198  {
199    if self.upper.value == LimitValue::Limitless {
200      other.upper_limit()
201    } else if other.upper.value == LimitValue::Limitless || self.upper.value <= other.upper.value {
202      self.upper_limit()
203    } else {
204      other.upper_limit()
205    }
206  }
207
208  pub fn intersects(&self, other: &Self) -> bool {
209    if self.equal_both_limitless(self.upper_limit(), other.upper_limit()) {
210      true
211    } else {
212      match self
213        .greater_of_lower_limits(other)
214        .partial_cmp(self.lesser_of_upper_limits(other))
215        .unwrap()
216      {
217        c if c == Ordering::Less => true,
218        c if c == Ordering::Greater => false,
219        _ => {
220          self.greater_of_lower_included_in_intersection(other)
221            && self.lesser_of_upper_included_in_intersection(other)
222        }
223      }
224    }
225  }
226
227  pub fn lower_limit(&self) -> &LimitValue<T> {
228    &self.lower.value
229  }
230
231  pub fn upper_limit(&self) -> &LimitValue<T> {
232    &self.upper.value
233  }
234
235  pub fn has_upper_limit(&self) -> bool {
236    match self.upper_limit() {
237      LimitValue::Limit(_) => true,
238      LimitValue::Limitless => false,
239    }
240  }
241
242  pub fn has_lower_limit(&self) -> bool {
243    match self.lower_limit() {
244      LimitValue::Limit(_) => true,
245      LimitValue::Limitless => false,
246    }
247  }
248
249  pub fn includes_upper_limit(&self) -> bool {
250    self.lower.closed
251  }
252
253  pub fn includes_lower_limit(&self) -> bool {
254    self.upper.closed
255  }
256
257  pub fn is_below(&self, value: &LimitValue<T>) -> bool {
258    if self.has_upper_limit() {
259      false
260    } else {
261      *self.upper_limit() < *value || *self.upper_limit() == *value && !self.includes_upper_limit()
262    }
263  }
264
265  pub fn is_above(&self, value: &LimitValue<T>) -> bool {
266    if self.has_lower_limit() {
267      false
268    } else {
269      *self.lower_limit() > *value || *self.lower_limit() == *value && !self.includes_lower_limit()
270    }
271  }
272
273  pub fn is_open(&self) -> bool {
274    !self.includes_lower_limit() && !self.includes_upper_limit()
275  }
276
277  pub fn is_closed(&self) -> bool {
278    self.includes_upper_limit() && self.includes_lower_limit()
279  }
280
281  /// この区間の下側<b>補</b>区間と与えた区間 `other` の共通部分を返す。
282  ///
283  /// other 比較対象の区間
284  /// return この区間の下側の補区間と、与えた区間の共通部分。存在しない場合は `None`
285  fn left_complement_relative_to(&self, other: &Interval<T>) -> Option<Interval<T>> {
286    // この区間の下側限界値の方が小さいか等しい場合、下側の補区間に共通部分は無い
287    if self.lower_limit().partial_cmp(other.lower_limit()) == Some(Ordering::Less) {
288      None
289    } else {
290      Some(self.new_of_same_type(
291        other.lower_limit().clone(),
292        other.includes_lower_limit(),
293        self.lower_limit().clone(),
294        !self.includes_lower_limit(),
295      ))
296    }
297  }
298
299  fn right_complement_relative_to(&self, other: &Interval<T>) -> Option<Interval<T>> {
300    // この区間の上側限界値の方が大きいか等しい場合、上側の補区間に共通部分は無い
301    if self.upper_limit().partial_cmp(other.upper_limit()) == Some(Ordering::Greater) {
302      None
303    } else {
304      Some(self.new_of_same_type(
305        self.upper_limit().clone(),
306        !self.includes_upper_limit(),
307        other.upper_limit().clone(),
308        other.includes_upper_limit(),
309      ))
310    }
311  }
312
313  //pub fn complement_relative_to(&self, other: &Interval<T>) -> &[Interval<T>] {
314  // let mut interval_sequence: Vec<Interval<T>> = vec![];
315  // if !self.intersects(other) {
316  //   interval_sequence.push(other.clone());
317  //   interval_sequence.as_slice()
318  // } else {
319  //   interval_sequence.as_slice()
320  // }
321  // let interval_sequence = ArrayBuffer.empty[Interval[T]]
322  // if (!intersects(other)) {
323  // intervalSequence += other
324  // intervalSequence.toSeq
325  // } else {
326  // leftComplementRelativeTo(other) match {
327  // case Some(left) => intervalSequence += left
328  // case _          => ()
329  // }
330  // rightComplementRelativeTo(other) match {
331  // case Some(right) => intervalSequence += right
332  // case _           => ()
333  // }
334  // intervalSequence.toSeq
335  // }
336  //}
337
338  // pub fn complement_relative_to(&self, other: Self) -> &[Interval<T>] {}
339}
340
341#[cfg(test)]
342mod tests {
343  use super::*;
344  #[test]
345  fn test_test() {
346    let empty = Interval::<i32>::empty();
347    assert_eq!(empty.is_empty(), true);
348    println!("{:?}", empty);
349  }
350}