1 |
3
|
krennw
|
/**
|
2 |
|
|
*
|
3 |
|
|
* OOAS Compiler (Deprecated)
|
4 |
|
|
*
|
5 |
|
|
* Copyright 2015, Institute for Software Technology, Graz University of
|
6 |
|
|
* Technology. Portions are copyright 2015 by the AIT Austrian Institute
|
7 |
|
|
* of Technology. All rights reserved.
|
8 |
|
|
*
|
9 |
|
|
* SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
|
10 |
|
|
*
|
11 |
|
|
* Please notice that this version of the OOAS compiler is considered de-
|
12 |
|
|
* precated. Only the Java version is maintained.
|
13 |
|
|
*
|
14 |
|
|
* Contributors:
|
15 |
|
|
* Willibald Krenn (TU Graz/AIT)
|
16 |
|
|
* Stefan Tiran (TU Graz/AIT)
|
17 |
|
|
*/
|
18 |
|
|
|
19 |
|
|
using System;
|
20 |
|
|
using System.Collections.Generic;
|
21 |
|
|
using System.Text;
|
22 |
|
|
|
23 |
|
|
namespace TUG.Mogentes
|
24 |
|
|
{
|
25 |
|
|
public abstract class AbstractOperations
|
26 |
|
|
{
|
27 |
|
|
public abstract AbstractRange GenericArithmeticCover(AbstractRange type1, AbstractRange type2, ExpressionKind op);
|
28 |
|
|
}
|
29 |
|
|
|
30 |
|
|
public class Operations<T> : AbstractOperations
|
31 |
|
|
{
|
32 |
|
|
public delegate T opUnary(T input);
|
33 |
|
|
public delegate T opBinary(T inputA, T inputB);
|
34 |
|
|
public delegate bool opBinRel(T inputA, T intputB);
|
35 |
|
|
|
36 |
|
|
public opUnary unaryNotImplemented = p => { throw new NotImplementedException(); };
|
37 |
|
|
public opBinary binaryNotImplemented = (a, b) => { throw new NotImplementedException(); };
|
38 |
|
|
public opBinRel binrelNotImplemented = (a, b) => { throw new NotImplementedException(); };
|
39 |
|
|
|
40 |
|
|
// not all operations may be defined, then there needs to be some excpetion..
|
41 |
|
|
public opUnary unMinus;
|
42 |
|
|
public opBinary minus;
|
43 |
|
|
public opBinary plus;
|
44 |
|
|
public opBinary div;
|
45 |
|
|
public opBinary pow;
|
46 |
|
|
public opBinary prod;
|
47 |
|
|
public opBinary mod;
|
48 |
|
|
public opBinRel equal;
|
49 |
|
|
public opBinRel smaller;
|
50 |
|
|
public opBinRel greater;
|
51 |
|
|
|
52 |
|
|
public override AbstractRange GenericArithmeticCover(AbstractRange type1, AbstractRange type2, ExpressionKind op)
|
53 |
|
|
{
|
54 |
|
|
Range<T> a = type1 as Range<T>;
|
55 |
|
|
Range<T> b = type2 as Range<T>;
|
56 |
|
|
|
57 |
|
|
if (a == null || b == null)
|
58 |
|
|
throw new ArgumentException();
|
59 |
|
|
|
60 |
|
|
return GenericArithmeticCover(a, b, op);
|
61 |
|
|
}
|
62 |
|
|
|
63 |
|
|
public Range<T> GenericArithmeticCover(Range<T> type1, Range<T> type2, ExpressionKind op)
|
64 |
|
|
{
|
65 |
|
|
Range<T> result = type1.Create(default(T), default(T));
|
66 |
|
|
Operations<T> o = this; // remove this if method remains in this class..
|
67 |
|
|
|
68 |
|
|
switch (op)
|
69 |
|
|
{
|
70 |
|
|
case ExpressionKind.unminus:
|
71 |
|
|
result.min = o.unMinus(type1.max);
|
72 |
|
|
result.max = o.unMinus(type1.min);
|
73 |
|
|
break;
|
74 |
|
|
case ExpressionKind.unplus:
|
75 |
|
|
break;
|
76 |
|
|
|
77 |
|
|
case ExpressionKind.minus:
|
78 |
|
|
System.Diagnostics.Debug.Assert(type2 != null);
|
79 |
|
|
// we do some sort of resulttype = type1 - type2
|
80 |
|
|
// hence, do the unminus stuff with type 2
|
81 |
|
|
T spare = type2.max;
|
82 |
|
|
type2.max = o.unMinus(type2.min);
|
83 |
|
|
type2.min = o.unMinus(spare);
|
84 |
|
|
// now it's the same with sum.. but c# does not let us fall through..
|
85 |
|
|
result.min = o.plus(type1.min, type2.min);
|
86 |
|
|
result.max = o.plus(type1.max, type2.max);
|
87 |
|
|
break;
|
88 |
|
|
case ExpressionKind.sum:
|
89 |
|
|
System.Diagnostics.Debug.Assert(type2 != null);
|
90 |
|
|
result.min = o.plus(type1.min, type2.min);
|
91 |
|
|
result.max = o.plus(type1.max, type2.max);
|
92 |
|
|
break;
|
93 |
|
|
case ExpressionKind.idiv:
|
94 |
|
|
case ExpressionKind.div:
|
95 |
|
|
System.Diagnostics.Debug.Assert(type2 != null);
|
96 |
|
|
type2.min = o.equal(type2.min, default(T)) ? o.unMinus(type2.precision) : type2.min;
|
97 |
|
|
type2.max = o.equal(type2.max, default(T)) ? type2.precision : type2.max;
|
98 |
|
|
// hmm, brute force.. is there some formula?
|
99 |
|
|
result.max = o.div(type1.min, type2.min);
|
100 |
|
|
result.min = result.max;
|
101 |
|
|
|
102 |
|
|
T tmp = o.div(type1.max, type2.min);
|
103 |
|
|
result.max = o.smaller(result.max, tmp) ? tmp : result.max;
|
104 |
|
|
result.min = o.greater(result.min, tmp) ? tmp : result.min;
|
105 |
|
|
|
106 |
|
|
tmp = o.div(type1.min, type2.max);
|
107 |
|
|
result.max = o.smaller(result.max, tmp) ? tmp : result.max;
|
108 |
|
|
result.min = o.greater(result.min, tmp) ? tmp : result.min;
|
109 |
|
|
|
110 |
|
|
tmp = o.div(type1.max, type2.max);
|
111 |
|
|
result.max = o.smaller(result.max, tmp) ? tmp : result.max;
|
112 |
|
|
result.min = o.greater(result.min, tmp) ? tmp : result.min;
|
113 |
|
|
break;
|
114 |
|
|
case ExpressionKind.mod:
|
115 |
|
|
throw new ArgumentException(); // do this one level up
|
116 |
|
|
case ExpressionKind.pow:
|
117 |
|
|
// ok, this is bad. - just give up here
|
118 |
|
|
result.max = result.typemax;
|
119 |
|
|
result.min = result.typemin;
|
120 |
|
|
break;
|
121 |
|
|
case ExpressionKind.prod:
|
122 |
|
|
// hmm, brute force.. is there some formula?
|
123 |
|
|
result.max = o.prod(type1.min, type2.min);
|
124 |
|
|
result.min = result.max;
|
125 |
|
|
|
126 |
|
|
tmp = o.prod(type1.max, type2.min);
|
127 |
|
|
result.max = o.smaller(result.max, tmp) ? tmp : result.max;
|
128 |
|
|
result.min = o.greater(result.min, tmp) ? tmp : result.min;
|
129 |
|
|
|
130 |
|
|
tmp = o.prod(type1.min, type2.max);
|
131 |
|
|
result.max = o.smaller(result.max, tmp) ? tmp : result.max;
|
132 |
|
|
result.min = o.greater(result.min, tmp) ? tmp : result.min;
|
133 |
|
|
|
134 |
|
|
tmp = o.prod(type1.max, type2.max);
|
135 |
|
|
result.max = o.smaller(result.max, tmp) ? tmp : result.max;
|
136 |
|
|
result.min = o.greater(result.min, tmp) ? tmp : result.min;
|
137 |
|
|
break;
|
138 |
|
|
|
139 |
|
|
default:
|
140 |
|
|
throw new NotImplementedException();
|
141 |
|
|
}
|
142 |
|
|
return result;
|
143 |
|
|
}
|
144 |
|
|
|
145 |
|
|
|
146 |
|
|
public Operations()
|
147 |
|
|
{
|
148 |
|
|
unMinus = unaryNotImplemented;
|
149 |
|
|
minus = binaryNotImplemented;
|
150 |
|
|
plus = binaryNotImplemented;
|
151 |
|
|
div = binaryNotImplemented;
|
152 |
|
|
pow = binaryNotImplemented;
|
153 |
|
|
prod = binaryNotImplemented;
|
154 |
|
|
mod = binaryNotImplemented;
|
155 |
|
|
equal = binrelNotImplemented;
|
156 |
|
|
smaller = binrelNotImplemented;
|
157 |
|
|
greater = binrelNotImplemented;
|
158 |
|
|
}
|
159 |
|
|
|
160 |
|
|
public Operations(opUnary aUnMinus,
|
161 |
|
|
opBinary aMinus,
|
162 |
|
|
opBinary aPlus,
|
163 |
|
|
opBinary aDiv,
|
164 |
|
|
opBinary aPow,
|
165 |
|
|
opBinary aProd,
|
166 |
|
|
opBinary aMod,
|
167 |
|
|
opBinRel aEquality,
|
168 |
|
|
opBinRel aSmaller,
|
169 |
|
|
opBinRel aGreater)
|
170 |
|
|
{
|
171 |
|
|
unMinus = aUnMinus;
|
172 |
|
|
minus = aMinus;
|
173 |
|
|
plus = aPlus;
|
174 |
|
|
div = aDiv;
|
175 |
|
|
pow = aPow;
|
176 |
|
|
prod = aProd;
|
177 |
|
|
mod = aMod;
|
178 |
|
|
equal = aEquality;
|
179 |
|
|
smaller = aSmaller;
|
180 |
|
|
greater = aGreater;
|
181 |
|
|
}
|
182 |
|
|
}
|
183 |
|
|
|
184 |
|
|
|
185 |
|
|
public sealed class IntegerOperations : Operations<int>
|
186 |
|
|
{
|
187 |
|
|
public IntegerOperations()
|
188 |
|
|
: base(p => -p,
|
189 |
|
|
(a, b) => a - b,
|
190 |
|
|
(a, b) => a + b,
|
191 |
|
|
(a, b) => a / b,
|
192 |
|
|
(a, b) => (int)Math.Pow(a, b),
|
193 |
|
|
(a, b) => a * b,
|
194 |
|
|
(a, b) => a % b,
|
195 |
|
|
(a, b) => a == b,
|
196 |
|
|
(a, b) => a < b,
|
197 |
|
|
(a, b) => a > b)
|
198 |
|
|
{ }
|
199 |
|
|
}
|
200 |
|
|
|
201 |
|
|
|
202 |
|
|
public sealed class CheckedIntegerOperations : Operations<int>
|
203 |
|
|
{
|
204 |
|
|
public CheckedIntegerOperations()
|
205 |
|
|
: base(p => { checked { return -p; } },
|
206 |
|
|
(a, b) => { checked { return a - b; } },
|
207 |
|
|
(a, b) => { checked { return a + b; } },
|
208 |
|
|
(a, b) => { checked { return a / b; } },
|
209 |
|
|
(a, b) => { checked { return (int)Math.Pow(a, b); } },
|
210 |
|
|
(a, b) => { checked { return a * b; } },
|
211 |
|
|
(a, b) => a % b,
|
212 |
|
|
(a, b) => a == b,
|
213 |
|
|
(a, b) => a < b,
|
214 |
|
|
(a, b) => a > b)
|
215 |
|
|
{ }
|
216 |
|
|
}
|
217 |
|
|
|
218 |
|
|
|
219 |
|
|
public sealed class SaturatedIntegerOperations : Operations<int>
|
220 |
|
|
{
|
221 |
|
|
private static int SatUnMinus(int input)
|
222 |
|
|
{
|
223 |
|
|
return input == int.MinValue ? int.MaxValue : -input;
|
224 |
|
|
}
|
225 |
|
|
|
226 |
|
|
private static int Subtraction(int a, int b)
|
227 |
|
|
{
|
228 |
|
|
if (b < 0)
|
229 |
|
|
return (a > int.MaxValue + b) ? int.MaxValue : a - b;
|
230 |
|
|
else
|
231 |
|
|
return (a < int.MinValue + b) ? int.MinValue : a - b;
|
232 |
|
|
}
|
233 |
|
|
|
234 |
|
|
private static int Addition(int a, int b)
|
235 |
|
|
{
|
236 |
|
|
if (b < 0)
|
237 |
|
|
return (a < int.MinValue - b) ? int.MinValue : a + b;
|
238 |
|
|
else
|
239 |
|
|
return (a > int.MaxValue - b) ? int.MaxValue : a + b;
|
240 |
|
|
}
|
241 |
|
|
|
242 |
|
|
private static int Division(int a, int b)
|
243 |
|
|
{
|
244 |
|
|
checked { return a / b; };
|
245 |
|
|
}
|
246 |
|
|
|
247 |
|
|
private static int Power(int a, int b)
|
248 |
|
|
{
|
249 |
|
|
Int64 tmp = (Int64)Math.Pow(a, b);
|
250 |
|
|
if (tmp < int.MinValue) return int.MinValue;
|
251 |
|
|
else if (tmp > int.MaxValue) return int.MaxValue;
|
252 |
|
|
else return (int)tmp;
|
253 |
|
|
}
|
254 |
|
|
|
255 |
|
|
private static int Multiplication(int a, int b)
|
256 |
|
|
{
|
257 |
|
|
Int64 tmp = Math.BigMul(a, b);
|
258 |
|
|
if (tmp < int.MinValue) return int.MinValue;
|
259 |
|
|
else if (tmp > int.MaxValue) return int.MaxValue;
|
260 |
|
|
else return (int)tmp;
|
261 |
|
|
}
|
262 |
|
|
|
263 |
|
|
public SaturatedIntegerOperations()
|
264 |
|
|
: base(SatUnMinus, Subtraction, Addition, Division, Power, Multiplication,
|
265 |
|
|
(a, b) => a % b,
|
266 |
|
|
(a, b) => a == b,
|
267 |
|
|
(a, b) => a < b,
|
268 |
|
|
(a, b) => a > b)
|
269 |
|
|
{ }
|
270 |
|
|
}
|
271 |
|
|
|
272 |
|
|
|
273 |
|
|
|
274 |
|
|
public sealed class DoubleOperations : Operations<double>
|
275 |
|
|
{
|
276 |
|
|
public DoubleOperations()
|
277 |
|
|
: base(p => -p,
|
278 |
|
|
(a, b) => a - b,
|
279 |
|
|
(a, b) => a + b,
|
280 |
|
|
(a, b) => a / b,
|
281 |
|
|
(a, b) => Math.Pow(a, b),
|
282 |
|
|
(a, b) => a * b,
|
283 |
|
|
(a, b) => a % b,
|
284 |
|
|
(a, b) => a == b,
|
285 |
|
|
(a, b) => a < b,
|
286 |
|
|
(a, b) => a > b)
|
287 |
|
|
{ }
|
288 |
|
|
}
|
289 |
|
|
|
290 |
|
|
|
291 |
|
|
|
292 |
|
|
public sealed class SaturatedDoubleOperations : Operations<double>
|
293 |
|
|
{
|
294 |
|
|
|
295 |
|
|
private static double checkRange(double aValue)
|
296 |
|
|
{
|
297 |
|
|
if (aValue == double.PositiveInfinity)
|
298 |
|
|
return double.MaxValue;
|
299 |
|
|
else if (aValue == double.NegativeInfinity)
|
300 |
|
|
return double.MinValue;
|
301 |
|
|
else
|
302 |
|
|
return aValue;
|
303 |
|
|
}
|
304 |
|
|
|
305 |
|
|
private static double SatUnMinus(double input)
|
306 |
|
|
{
|
307 |
|
|
return checkRange(-input);
|
308 |
|
|
}
|
309 |
|
|
|
310 |
|
|
private static double Subtraction(double a, double b)
|
311 |
|
|
{
|
312 |
|
|
return checkRange(a - b);
|
313 |
|
|
}
|
314 |
|
|
|
315 |
|
|
private static double Addition(double a, double b)
|
316 |
|
|
{
|
317 |
|
|
return checkRange(a + b);
|
318 |
|
|
}
|
319 |
|
|
|
320 |
|
|
private static double Division(double a, double b)
|
321 |
|
|
{
|
322 |
|
|
return checkRange(a / b);
|
323 |
|
|
}
|
324 |
|
|
|
325 |
|
|
private static double Power(double a, double b)
|
326 |
|
|
{
|
327 |
|
|
return checkRange(Math.Pow(a, b));
|
328 |
|
|
}
|
329 |
|
|
|
330 |
|
|
private static double Multiplication(double a, double b)
|
331 |
|
|
{
|
332 |
|
|
|
333 |
|
|
return checkRange(a * b);
|
334 |
|
|
}
|
335 |
|
|
|
336 |
|
|
private static double Reminder(double a, double b)
|
337 |
|
|
{
|
338 |
|
|
return checkRange(a % b);
|
339 |
|
|
}
|
340 |
|
|
|
341 |
|
|
public SaturatedDoubleOperations()
|
342 |
|
|
: base(SatUnMinus,
|
343 |
|
|
Subtraction,
|
344 |
|
|
Addition,
|
345 |
|
|
Division,
|
346 |
|
|
Power,
|
347 |
|
|
Multiplication,
|
348 |
|
|
Reminder,
|
349 |
|
|
(a, b) => a == b,
|
350 |
|
|
(a, b) => a < b,
|
351 |
|
|
(a, b) => a > b)
|
352 |
|
|
{ }
|
353 |
|
|
}
|
354 |
|
|
|
355 |
|
|
|
356 |
|
|
|
357 |
|
|
} |