ospf_rust_math/algebra/value_range/
interval.rs

1use crate::algebra::operator::comparison::*;
2
3// for static
4
5pub trait IntervalType: Clone + Copy + PartialEq + Eq {
6    const LB_SIGN: &'static str;
7    const UB_SIGN: &'static str;
8
9    fn lb_op<T: 'static + PartialOrd<Rhs>, Rhs: 'static>() -> Box<dyn ComparisonOperator<T, Rhs>>;
10    fn lb_op_with<T: 'static + PartialOrd<Rhs>, Rhs: 'static>(
11        precision: T,
12    ) -> Box<dyn ComparisonOperator<T, Rhs>>;
13
14    fn ub_op<T: 'static + PartialOrd<Rhs>, Rhs: 'static>() -> Box<dyn ComparisonOperator<T, Rhs>>;
15    fn ub_op_with<T: 'static + PartialOrd<Rhs>, Rhs: 'static>(
16        precision: T,
17    ) -> Box<dyn ComparisonOperator<T, Rhs>>;
18}
19
20pub trait Union<Rhs: IntervalType>: IntervalType {
21    type Result: IntervalType;
22
23    const LB_SIGN: &'static str = Self::Result::LB_SIGN;
24    const UB_SIGN: &'static str = Self::Result::UB_SIGN;
25
26    fn lb_op<T: 'static + PartialOrd<U>, U: 'static>() -> Box<dyn ComparisonOperator<T, U>> {
27        Self::Result::lb_op::<T, U>()
28    }
29
30    fn lb_op_with<T: 'static + PartialOrd<U>, U: 'static>(
31        precision: T,
32    ) -> Box<dyn ComparisonOperator<T, U>> {
33        Self::Result::lb_op_with(precision)
34    }
35
36    fn ub_op<T: 'static + PartialOrd<U>, U: 'static>() -> Box<dyn ComparisonOperator<T, U>> {
37        Self::Result::ub_op()
38    }
39
40    fn ub_op_with<T: 'static + PartialOrd<U>, U: 'static>(
41        precision: T,
42    ) -> Box<dyn ComparisonOperator<T, U>> {
43        Self::Result::ub_op_with(precision)
44    }
45}
46
47pub trait Intersect<Rhs: IntervalType>: IntervalType {
48    type Result: IntervalType;
49
50    const LB_SIGN: &'static str = Self::Result::LB_SIGN;
51    const UB_SIGN: &'static str = Self::Result::UB_SIGN;
52
53    fn lb_op<T: 'static + PartialOrd<U>, U: 'static>() -> Box<dyn ComparisonOperator<T, U>> {
54        Self::Result::lb_op()
55    }
56
57    fn lb_op_with<T: 'static + PartialOrd<U>, U: 'static>(
58        precision: T,
59    ) -> Box<dyn ComparisonOperator<T, U>> {
60        Self::Result::lb_op_with(precision)
61    }
62
63    fn ub_op<T: 'static + PartialOrd<U>, U: 'static>() -> Box<dyn ComparisonOperator<T, U>> {
64        Self::Result::ub_op()
65    }
66
67    fn ub_op_with<T: 'static + PartialOrd<U>, U: 'static>(
68        precision: T,
69    ) -> Box<dyn ComparisonOperator<T, U>> {
70        Self::Result::ub_op_with(precision)
71    }
72}
73
74#[derive(Clone, Copy, PartialEq, Eq)]
75pub struct Open {}
76
77impl IntervalType for Open {
78    const LB_SIGN: &'static str = "(";
79    const UB_SIGN: &'static str = ")";
80
81    fn lb_op<T: 'static + PartialOrd<Rhs>, Rhs: 'static>() -> Box<dyn ComparisonOperator<T, Rhs>> {
82        Less::new()
83    }
84
85    fn lb_op_with<T: 'static + PartialOrd<Rhs>, Rhs: 'static>(
86        precision: T,
87    ) -> Box<dyn ComparisonOperator<T, Rhs>> {
88        Less::new_with(precision)
89    }
90
91    fn ub_op<T: 'static + PartialOrd<Rhs>, Rhs: 'static>() -> Box<dyn ComparisonOperator<T, Rhs>> {
92        Greater::new()
93    }
94
95    fn ub_op_with<T: 'static + PartialOrd<Rhs>, Rhs: 'static>(
96        precision: T,
97    ) -> Box<dyn ComparisonOperator<T, Rhs>> {
98        Greater::new_with(precision)
99    }
100}
101
102impl Union<Open> for Open {
103    type Result = Open;
104}
105
106impl Union<Closed> for Open {
107    type Result = Closed;
108}
109
110impl<T: IntervalType> Intersect<T> for Open {
111    type Result = Open;
112}
113
114#[derive(Clone, Copy, PartialEq, Eq)]
115pub struct Closed {}
116
117impl IntervalType for Closed {
118    const LB_SIGN: &'static str = "[";
119    const UB_SIGN: &'static str = "]";
120
121    fn lb_op<T: 'static + PartialOrd<Rhs>, Rhs: 'static>() -> Box<dyn ComparisonOperator<T, Rhs>> {
122        LessEqual::new()
123    }
124
125    fn lb_op_with<T: 'static + PartialOrd<Rhs>, Rhs: 'static>(
126        precision: T,
127    ) -> Box<dyn ComparisonOperator<T, Rhs>> {
128        LessEqual::new_with(precision)
129    }
130
131    fn ub_op<T: 'static + PartialOrd<Rhs>, Rhs: 'static>() -> Box<dyn ComparisonOperator<T, Rhs>> {
132        GreaterEqual::new()
133    }
134
135    fn ub_op_with<T: 'static + PartialOrd<Rhs>, Rhs: 'static>(
136        precision: T,
137    ) -> Box<dyn ComparisonOperator<T, Rhs>> {
138        GreaterEqual::new_with(precision)
139    }
140}
141
142impl<T: IntervalType> Union<T> for Closed {
143    type Result = Closed;
144}
145
146impl Intersect<Open> for Closed {
147    type Result = Open;
148}
149
150impl Intersect<Closed> for Closed {
151    type Result = Closed;
152}
153
154// for dynamic
155
156#[derive(Clone, Copy, PartialEq, Eq, Debug)]
157pub enum Interval {
158    Open,
159    Closed,
160}
161
162impl Interval {
163    pub fn outer(&self, rhs: &Self) -> bool {
164        match (self, rhs) {
165            (&Self::Closed, &Self::Open) => true,
166            _ => false,
167        }
168    }
169
170    pub fn lb_sign(&self) -> &'static str {
171        match self {
172            Self::Open => <Open as IntervalType>::LB_SIGN,
173            Self::Closed => <Closed as IntervalType>::LB_SIGN,
174        }
175    }
176
177    pub fn ub_sign(&self) -> &'static str {
178        match self {
179            Self::Open => <Open as IntervalType>::UB_SIGN,
180            Self::Closed => <Closed as IntervalType>::UB_SIGN,
181        }
182    }
183
184    pub fn union(&self, rhs: &Self) -> Self {
185        if self == &Self::Closed || rhs == &Self::Closed {
186            Self::Closed
187        } else {
188            Self::Open
189        }
190    }
191
192    pub fn intersect(&self, rhs: &Self) -> Self {
193        if self == &Self::Open || rhs == &Self::Open {
194            Self::Open
195        } else {
196            Self::Closed
197        }
198    }
199
200    pub fn lb_op<T: 'static + PartialOrd<Rhs>, Rhs: 'static>(
201        self,
202    ) -> Box<dyn ComparisonOperator<T, Rhs>> {
203        match self {
204            Self::Open => <Open as IntervalType>::lb_op(),
205            Self::Closed => <Closed as IntervalType>::lb_op(),
206        }
207    }
208
209    pub fn lb_op_with<T: 'static + PartialOrd<Rhs>, Rhs: 'static>(
210        self,
211        precision: T,
212    ) -> Box<dyn ComparisonOperator<T, Rhs>> {
213        match self {
214            Self::Open => <Open as IntervalType>::lb_op_with(precision),
215            Self::Closed => <Closed as IntervalType>::lb_op_with(precision),
216        }
217    }
218
219    pub fn ub_op<T: 'static + PartialOrd<Rhs>, Rhs: 'static>(
220        self,
221    ) -> Box<dyn ComparisonOperator<T, Rhs>> {
222        match self {
223            Self::Open => <Open as IntervalType>::ub_op(),
224            Self::Closed => <Closed as IntervalType>::ub_op(),
225        }
226    }
227
228    pub fn ub_op_with<T: 'static + PartialOrd<Rhs>, Rhs: 'static>(
229        self,
230        precision: T,
231    ) -> Box<dyn ComparisonOperator<T, Rhs>> {
232        match self {
233            Self::Open => <Open as IntervalType>::ub_op_with(precision),
234            Self::Closed => <Closed as IntervalType>::ub_op_with(precision),
235        }
236    }
237}