diff options
author | 2019-05-08 17:50:28 -0400 | |
---|---|---|
committer | 2019-05-08 17:50:28 -0400 | |
commit | c925edcadbabcdc6de5e0442105dc30a387d3088 (patch) | |
tree | ccbf051e0040155ade5039896b0bb80274f8479e /Solvers/VIATRA-Solver | |
parent | Interval arithmetic WIP (diff) | |
download | VIATRA-Generator-c925edcadbabcdc6de5e0442105dc30a387d3088.tar.gz VIATRA-Generator-c925edcadbabcdc6de5e0442105dc30a387d3088.tar.zst VIATRA-Generator-c925edcadbabcdc6de5e0442105dc30a387d3088.zip |
Implement interval arithmetic without exponentiation
Diffstat (limited to 'Solvers/VIATRA-Solver')
-rw-r--r-- | Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/Interval.xtend | 74 |
1 files changed, 49 insertions, 25 deletions
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/Interval.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/Interval.xtend index 5b839fbd..cf22315b 100644 --- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/Interval.xtend +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/interval/Interval.xtend | |||
@@ -53,14 +53,34 @@ abstract class Interval { | |||
53 | override operator_divide(Interval other) { | 53 | override operator_divide(Interval other) { |
54 | EMPTY | 54 | EMPTY |
55 | } | 55 | } |
56 | |||
57 | override toString() { | ||
58 | "∅" | ||
59 | } | ||
56 | } | 60 | } |
57 | 61 | ||
58 | public static val Interval ZERO = new NonEmpty(BigDecimal.ZERO, BigDecimal.ZERO) | 62 | public static val Interval ZERO = new NonEmpty(BigDecimal.ZERO, BigDecimal.ZERO) |
59 | 63 | ||
60 | public static val Interval UNBOUNDED = new NonEmpty(null, null) | 64 | public static val Interval UNBOUNDED = new NonEmpty(null, null) |
61 | 65 | ||
66 | static def Interval of(BigDecimal lower, BigDecimal upper) { | ||
67 | new NonEmpty(lower, upper) | ||
68 | } | ||
69 | |||
70 | static def between(double lower, double upper) { | ||
71 | of(new BigDecimal(lower, ROUND_DOWN), new BigDecimal(upper, ROUND_UP)) | ||
72 | } | ||
73 | |||
74 | static def upTo(double upper) { | ||
75 | of(null, new BigDecimal(upper, ROUND_UP)) | ||
76 | } | ||
77 | |||
78 | static def above(double lower) { | ||
79 | of(new BigDecimal(lower, ROUND_DOWN), null) | ||
80 | } | ||
81 | |||
62 | @Data | 82 | @Data |
63 | static class NonEmpty extends Interval { | 83 | private static class NonEmpty extends Interval { |
64 | val BigDecimal lower | 84 | val BigDecimal lower |
65 | val BigDecimal upper | 85 | val BigDecimal upper |
66 | 86 | ||
@@ -141,7 +161,9 @@ abstract class Interval { | |||
141 | } | 161 | } |
142 | 162 | ||
143 | def operator_multiply(NonEmpty other) { | 163 | def operator_multiply(NonEmpty other) { |
144 | if (nonpositive) { | 164 | if (this == ZERO || other == ZERO) { |
165 | ZERO | ||
166 | } else if (nonpositive) { | ||
145 | if (other.nonpositive) { | 167 | if (other.nonpositive) { |
146 | new NonEmpty( | 168 | new NonEmpty( |
147 | upper.multiply(other.upper, ROUND_DOWN), | 169 | upper.multiply(other.upper, ROUND_DOWN), |
@@ -155,7 +177,7 @@ abstract class Interval { | |||
155 | } else { | 177 | } else { |
156 | new NonEmpty( | 178 | new NonEmpty( |
157 | lower.tryMultiply(other.upper, ROUND_DOWN), | 179 | lower.tryMultiply(other.upper, ROUND_DOWN), |
158 | upper.tryMultiply(other.lower, ROUND_UP) | 180 | lower.tryMultiply(other.lower, ROUND_UP) |
159 | ) | 181 | ) |
160 | } | 182 | } |
161 | } else if (nonnegative) { | 183 | } else if (nonnegative) { |
@@ -236,7 +258,11 @@ abstract class Interval { | |||
236 | } | 258 | } |
237 | 259 | ||
238 | def operator_divide(NonEmpty other) { | 260 | def operator_divide(NonEmpty other) { |
239 | if (other.strictlyNegative) { | 261 | if (other == ZERO) { |
262 | EMPTY | ||
263 | } else if (this == ZERO) { | ||
264 | ZERO | ||
265 | } else if (other.strictlyNegative) { | ||
240 | if (nonpositive) { | 266 | if (nonpositive) { |
241 | new NonEmpty( | 267 | new NonEmpty( |
242 | upper.tryDivide(other.lower, ROUND_DOWN), | 268 | upper.tryDivide(other.lower, ROUND_DOWN), |
@@ -271,30 +297,24 @@ abstract class Interval { | |||
271 | ) | 297 | ) |
272 | } | 298 | } |
273 | } else { // other contains 0 | 299 | } else { // other contains 0 |
274 | if (other.lower == BigDecimal.ZERO) { | 300 | if (other.lower == BigDecimal.ZERO) { // 0 == other.lower < other.upper, because [0, 0] was exluded earlier |
275 | if (other.upper == BigDecimal.ZERO) { // [0, 0] | 301 | if (nonpositive) { |
276 | EMPTY | 302 | new NonEmpty(null, upper.tryDivide(other.upper, ROUND_UP)) |
277 | } else { // 0 == other.lower < other.upper | 303 | } else if (nonnegative) { |
278 | if (nonpositive) { | 304 | new NonEmpty(lower.tryDivide(other.upper, ROUND_DOWN), null) |
279 | new NonEmpty(null, upper.tryDivide(other.upper, ROUND_UP)) | 305 | } else { // lower < 0 < upper |
280 | } else if (nonnegative) { | 306 | UNBOUNDED |
281 | new NonEmpty(lower.tryDivide(other.upper, ROUND_DOWN), null) | ||
282 | } else { // lower < 0 < upper | ||
283 | UNBOUNDED | ||
284 | } | ||
285 | } | 307 | } |
286 | } else { | 308 | } else if (other.upper == BigDecimal.ZERO) { // other.lower < other.upper == 0 |
287 | if (other.upper == BigDecimal.ZERO) { // other.lower < other.upper == 0 | 309 | if (nonpositive) { |
288 | if (nonpositive) { | 310 | new NonEmpty(upper.tryDivide(other.lower, ROUND_DOWN), null) |
289 | new NonEmpty(upper.tryDivide(other.lower, ROUND_DOWN), null) | 311 | } else if (nonnegative) { |
290 | } else if (nonnegative) { | 312 | new NonEmpty(null, lower.tryDivide(other.lower, ROUND_UP)) |
291 | new NonEmpty(null, lower.tryDivide(other.lower, ROUND_UP)) | 313 | } else { // lower < 0 < upper |
292 | } else { // lower < 0 < upper | ||
293 | UNBOUNDED | ||
294 | } | ||
295 | } else { // other.lower < 0 < other.upper | ||
296 | UNBOUNDED | 314 | UNBOUNDED |
297 | } | 315 | } |
316 | } else { // other.lower < 0 < other.upper | ||
317 | UNBOUNDED | ||
298 | } | 318 | } |
299 | } | 319 | } |
300 | } | 320 | } |
@@ -314,5 +334,9 @@ abstract class Interval { | |||
314 | a?.divide(b, mc) | 334 | a?.divide(b, mc) |
315 | } | 335 | } |
316 | } | 336 | } |
337 | |||
338 | override toString() { | ||
339 | '''«IF lower === null»(-∞«ELSE»[«lower»«ENDIF», «IF upper === null»∞)«ELSE»«upper»]«ENDIF»''' | ||
340 | } | ||
317 | } | 341 | } |
318 | } | 342 | } |