ospf_rust_math/algebra/value_range/
interval.rs1use crate::algebra::operator::comparison::*;
2
3pub 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#[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}