aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kris7topher@gmail.com>2019-05-08 10:50:48 -0400
committerLibravatar Kristóf Marussy <kris7topher@gmail.com>2019-05-08 10:50:48 -0400
commita892620835e966f2a59c8e6421667e0a9f312736 (patch)
tree0bc3fddca6a7cb76bfa9cb960d1a9493b78e5ae9 /Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme
parentDo not use derived features in satellite case study vql (diff)
downloadVIATRA-Generator-a892620835e966f2a59c8e6421667e0a9f312736.tar.gz
VIATRA-Generator-a892620835e966f2a59c8e6421667e0a9f312736.tar.zst
VIATRA-Generator-a892620835e966f2a59c8e6421667e0a9f312736.zip
Interval arithmetic WIP
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme')
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/interval/Interval.xtend328
1 files changed, 328 insertions, 0 deletions
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/interval/Interval.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/interval/Interval.xtend
new file mode 100644
index 00000000..6d77e77a
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/interval/Interval.xtend
@@ -0,0 +1,328 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.interval
2
3import java.math.BigDecimal
4import java.math.MathContext
5import java.math.RoundingMode
6import org.eclipse.xtend.lib.annotations.Data
7
8abstract class Interval {
9 static val PRECISION = 32
10 static val ROUND_DOWN = new MathContext(PRECISION, RoundingMode.FLOOR)
11 static val ROUND_UP = new MathContext(PRECISION, RoundingMode.CEILING)
12
13 private new() {
14 }
15
16 def abstract boolean isEmpty()
17
18 def abstract boolean hasPositivePart()
19
20 def abstract boolean hasNegativePart()
21
22 def operator_plus() {
23 this
24 }
25
26 abstract def Interval operator_minus()
27
28 abstract def Interval operator_plus(Interval other)
29
30 def operator_minus(Interval other) {
31 this + (-other)
32 }
33
34 abstract def Interval operator_multiply(Interval other)
35
36 abstract def Interval operator_divide(Interval other)
37
38 static val EMPTY = new Interval {
39 override boolean isEmpty() {
40 true
41 }
42
43 override boolean hasPositivePart() {
44 false
45 }
46
47 override boolean hasNegativePart() {
48 false
49 }
50
51 override operator_minus() {
52 EMPTY
53 }
54
55 override operator_plus(Interval other) {
56 EMPTY
57 }
58
59 override operator_multiply(Interval other) {
60 EMPTY
61 }
62
63 override operator_divide(Interval other) {
64 EMPTY
65 }
66 }
67
68 static val ZERO = new Bounded(BigDecimal.ZERO, BigDecimal.ZERO)
69
70 static val UNBOUNDED = new Interval {
71 override boolean isEmpty() {
72 true
73 }
74
75 override boolean hasPositivePart() {
76 true
77 }
78
79 override boolean hasNegativePart() {
80 true
81 }
82
83 override operator_minus() {
84 UNBOUNDED
85 }
86
87 override operator_plus(Interval other) {
88 if (other.empty) {
89 EMPTY
90 } else {
91 UNBOUNDED
92 }
93 }
94
95 override operator_multiply(Interval other) {
96 if (other.empty) {
97 EMPTY
98 } else if (other.hasPositivePart || other.hasNegativePart) {
99 UNBOUNDED
100 } else {
101 ZERO
102 }
103 }
104
105 override operator_divide(Interval other) {
106 if (other.hasPositivePart || other.hasNegativePart) {
107 UNBOUNDED
108 } else {
109 EMPTY
110 }
111 }
112 }
113
114 @Data
115 static class BoundedFromBelow extends Interval {
116 val BigDecimal lower
117
118 override isEmpty() {
119 false
120 }
121
122 override hasPositivePart() {
123 true
124 }
125
126 override hasNegativePart() {
127 lower < BigDecimal.ZERO
128 }
129
130 override operator_minus() {
131 new BoundedFromAbove(lower.negate(ROUND_UP))
132 }
133
134 override operator_plus(Interval other) {
135 switch (other) {
136 BoundedFromBelow:
137 new BoundedFromBelow(lower.add(other.lower, ROUND_DOWN))
138 BoundedFromAbove:
139 UNBOUNDED
140 Bounded:
141 new BoundedFromBelow(lower.add(other.lower, ROUND_DOWN))
142 default:
143 other + this
144 }
145 }
146
147 override operator_multiply(Interval other) {
148 switch (other) {
149 BoundedFromBelow:
150 if (hasNegativePart || other.hasNegativePart) {
151 UNBOUNDED
152 } else {
153 new BoundedFromBelow(lower.multiply(other.lower, ROUND_DOWN))
154 }
155 BoundedFromAbove:
156 if (hasNegativePart || other.hasPositivePart) {
157 UNBOUNDED
158 } else {
159 new BoundedFromAbove(lower.multiply(other.upper, ROUND_UP))
160 }
161 Bounded:
162 if (other.hasNegativePart) {
163 if (other.hasPositivePart) {
164 UNBOUNDED
165 } else {
166 if (lower < BigDecimal.ZERO) {
167 new BoundedFromAbove(lower.multiply(other.lower, ROUND_UP))
168 } else {
169 new BoundedFromAbove(lower.multiply(other.upper, ROUND_UP))
170 }
171 }
172 } else {
173 if (other.hasPositivePart) {
174 if (lower < BigDecimal.ZERO) {
175 new BoundedFromBelow(lower.multiply(other.lower, ROUND_DOWN))
176 } else {
177 new BoundedFromBelow(lower.multiply(other.upper, ROUND_DOWN))
178 }
179 } else {
180 ZERO
181 }
182 }
183 default:
184 other * this
185 }
186 }
187
188 override operator_divide(Interval other) {
189 throw new UnsupportedOperationException("TODO: auto-generated method stub")
190 }
191
192 }
193
194 @Data
195 static class BoundedFromAbove extends Interval {
196 val BigDecimal upper
197
198 override isEmpty() {
199 false
200 }
201
202 override hasPositivePart() {
203 upper > BigDecimal.ZERO
204 }
205
206 override hasNegativePart() {
207 true
208 }
209
210 override operator_minus() {
211 new BoundedFromBelow(upper.negate(ROUND_DOWN))
212 }
213
214 override operator_plus(Interval other) {
215 switch (other) {
216 BoundedFromAbove:
217 UNBOUNDED
218 Bounded:
219 new BoundedFromAbove(upper.add(other.upper, ROUND_UP))
220 default:
221 other + this
222 }
223 }
224
225 override operator_multiply(Interval other) {
226 switch (other) {
227 BoundedFromAbove:
228 if (hasPositivePart || other.hasPositivePart) {
229 UNBOUNDED
230 } else {
231 new BoundedFromBelow(upper.multiply(other.upper, ROUND_DOWN))
232 }
233 Bounded:
234 if (other.hasPositivePart) {
235 if (other.hasNegativePart) {
236 UNBOUNDED
237 } else {
238 if (upper < BigDecimal.ZERO) {
239 new BoundedFromAbove(upper.multiply(other.lower, ROUND_UP))
240 } else {
241 new BoundedFromAbove(upper.multiply(other.upper, ROUND_UP))
242 }
243 }
244 } else {
245 if (other.hasNegativePart) {
246 if (upper < BigDecimal.ZERO) {
247 new BoundedFromBelow(upper.multiply(other.lower, ROUND_DOWN))
248 } else {
249 new BoundedFromBelow(upper.multiply(other.upper, ROUND_DOWN))
250 }
251 } else {
252 ZERO
253 }
254 }
255 default:
256 other * this
257 }
258 }
259
260 override operator_divide(Interval other) {
261 throw new UnsupportedOperationException("TODO: auto-generated method stub")
262 }
263
264 }
265
266 @Data
267 static class Bounded extends Interval {
268 val BigDecimal lower
269 val BigDecimal upper
270
271 new(BigDecimal lower, BigDecimal upper) {
272 if (lower === null) {
273 throw new IllegalArgumentException("Lower bound must be a number")
274 }
275 if (upper === null) {
276 throw new IllegalArgumentException("Upper bound must be a number")
277 }
278 if (lower > upper) {
279 throw new IllegalArgumentException("Lower bound of interval must not be larger than upper bound")
280 }
281 this.lower = lower
282 this.upper = upper
283 }
284
285 override boolean isEmpty() {
286 false
287 }
288
289 override boolean hasPositivePart() {
290 upper > BigDecimal.ZERO
291 }
292
293 override boolean hasNegativePart() {
294 lower < BigDecimal.ZERO
295 }
296
297 override operator_minus() {
298 new Bounded(upper.negate(ROUND_DOWN), lower.negate(ROUND_UP))
299 }
300
301 override operator_plus(Interval other) {
302 if (other instanceof Bounded) {
303 new Bounded(lower.add(other.lower, ROUND_DOWN), upper.add(other.upper, ROUND_UP))
304 } else {
305 other + this
306 }
307 }
308
309 override operator_multiply(Interval other) {
310 if (other instanceof Bounded) {
311 // TODO
312 } else {
313 other * this
314 }
315 }
316
317 override operator_divide(Interval other) {
318 switch (other) {
319 case EMPTY:
320 EMPTY
321 Interval.Bounded:
322 throw new UnsupportedOperationException("TODO")
323 default:
324 throw new IllegalArgumentException("Unknown interval: " + other)
325 }
326 }
327 }
328}