svf-lib 1.0.1998 → 1.0.2000

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,478 +0,0 @@
1
- //===- NumericLiteral.h ----Number wrapper for domains------------------//
2
- //
3
- // SVF: Static Value-Flow Analysis
4
- //
5
- // Copyright (C) <2013-2022> <Yulei Sui>
6
- //
7
-
8
- // This program is free software: you can redistribute it and/or modify
9
- // it under the terms of the GNU Affero General Public License as published by
10
- // the Free Software Foundation, either version 3 of the License, or
11
- // (at your option) any later version.
12
-
13
- // This program is distributed in the hope that it will be useful,
14
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- // GNU Affero General Public License for more details.
17
-
18
- // You should have received a copy of the GNU Affero General Public License
19
- // along with this program. If not, see <http://www.gnu.org/licenses/>.
20
- //
21
- //===----------------------------------------------------------------------===//
22
- /*
23
- * NumericLiteral.h
24
- *
25
- * Created on: Aug 4, 2022
26
- * Author: Xiao Cheng, Jiawei Wang
27
- *
28
- */
29
-
30
- #ifndef Z3_EXAMPLE_Number_H
31
- #define Z3_EXAMPLE_Number_H
32
-
33
- #include "Util/GeneralType.h"
34
- #include "AE/Core/BoundedZ3Expr.h"
35
-
36
- namespace SVF
37
- {
38
- class NumericLiteral
39
- {
40
- private:
41
- BoundedZ3Expr _n;
42
-
43
- public:
44
- /// Default constructor
45
- NumericLiteral() = delete;
46
-
47
- /// Create a new NumericLiteral from s32_t
48
-
49
- NumericLiteral(const Z3Expr &z3Expr) : _n(z3Expr) {}
50
-
51
- NumericLiteral(const z3::expr &e) : _n(e) {}
52
-
53
- NumericLiteral(float i) : _n(getContext().real_val(std::to_string(i).c_str())) {}
54
-
55
- NumericLiteral(double i) : _n(getContext().real_val(std::to_string(i).c_str())) {}
56
-
57
- NumericLiteral(s32_t i) : _n(i) {}
58
-
59
- NumericLiteral(s64_t i) : _n(i) {}
60
-
61
- NumericLiteral(BoundedZ3Expr z3Expr) : _n(std::move(z3Expr)) {}
62
-
63
- virtual ~NumericLiteral() = default;
64
-
65
- /// Copy Constructor
66
- NumericLiteral(const NumericLiteral &) = default;
67
-
68
- /// Move Constructor
69
- NumericLiteral(NumericLiteral &&) = default;
70
-
71
- /// Operator = , another Copy Constructor
72
- inline NumericLiteral &operator=(const NumericLiteral &) = default;
73
-
74
- /// Operator = , another Move Constructor
75
- inline NumericLiteral &operator=(NumericLiteral &&) = default;
76
-
77
- static NumericLiteral plus_infinity()
78
- {
79
- return BoundedZ3Expr::plus_infinity();
80
- }
81
-
82
- static NumericLiteral minus_infinity()
83
- {
84
- return BoundedZ3Expr::minus_infinity();
85
- }
86
-
87
- static z3::context &getContext()
88
- {
89
- return BoundedZ3Expr::getContext();
90
- }
91
-
92
- const std::string to_string() const
93
- {
94
- return _n.to_string();
95
- }
96
-
97
- /// Check if this is minus infinity
98
- inline bool is_minus_infinity() const
99
- {
100
- return _n.is_minus_infinite();
101
- }
102
-
103
- /// Check if this is plus infinity
104
- inline bool is_plus_infinity() const
105
- {
106
- return _n.is_plus_infinite();
107
- }
108
-
109
- /// Check if this is infinity (either of plus/minus)
110
- inline bool is_infinity() const
111
- {
112
- return is_minus_infinity() || is_plus_infinity();
113
- }
114
-
115
- /// Check if this is zero
116
- inline bool is_zero() const
117
- {
118
- return _n.is_zero();
119
- }
120
-
121
- inline bool is_int() const
122
- {
123
- return _n.is_int();
124
- }
125
-
126
- inline bool is_real() const
127
- {
128
- return _n.is_real();
129
- }
130
-
131
- /// Return Numeral, default type is double in case to support both int and float
132
- inline s64_t getNumeral() const
133
- {
134
- return _n.getNumeral();
135
- }
136
-
137
- /// Return Expr
138
- inline Z3Expr getExpr() const
139
- {
140
- return _n.getExpr();
141
- }
142
-
143
- inline double getRealNumeral() const
144
- {
145
- return _n.getRealNumeral();
146
- }
147
-
148
- inline s64_t getIntNumeral() const
149
- {
150
- return _n.getIntNumeral();
151
- }
152
-
153
- /// Check two object is equal
154
- bool equal(const NumericLiteral &rhs) const
155
- {
156
- return eq(*this, rhs);
157
- }
158
-
159
- /// Less then or equal
160
- bool leq(const NumericLiteral &rhs) const
161
- {
162
- if (is_infinity() ^ rhs.is_infinity())
163
- {
164
- if (is_infinity())
165
- {
166
- return is_minus_infinity();
167
- }
168
- else
169
- {
170
- return rhs.is_plus_infinity();
171
- }
172
- }
173
- if(is_infinity() && rhs.is_infinity())
174
- {
175
- if(is_minus_infinity()) return true;
176
- else return rhs.is_plus_infinity();
177
- }
178
- else
179
- return _n.leq(rhs._n).simplify().is_true();
180
- }
181
-
182
- // Greater than or equal
183
- bool geq(const NumericLiteral &rhs) const
184
- {
185
- if (is_infinity() ^ rhs.is_infinity())
186
- {
187
- if (is_infinity())
188
- {
189
- return is_plus_infinity();
190
- }
191
- else
192
- {
193
- return rhs.is_minus_infinity();
194
- }
195
- }
196
- if(is_infinity() && rhs.is_infinity())
197
- {
198
- if(is_plus_infinity()) return true;
199
- else return rhs.is_minus_infinity();
200
- }
201
- else
202
- return _n.geq(rhs._n).simplify().is_true();
203
- }
204
-
205
-
206
- /// Reload operator
207
- //{%
208
- friend NumericLiteral operator==(const NumericLiteral &lhs, const NumericLiteral &rhs)
209
- {
210
- return eq(lhs, rhs) ? 1 : 0;
211
- }
212
-
213
- friend NumericLiteral operator!=(const NumericLiteral &lhs, const NumericLiteral &rhs)
214
- {
215
- return !eq(lhs, rhs) ? 1 : 0;
216
- }
217
-
218
- friend NumericLiteral operator>(const NumericLiteral &lhs, const NumericLiteral &rhs)
219
- {
220
- return (!lhs.leq(rhs)) ? 1 : 0;
221
- }
222
-
223
- friend NumericLiteral operator<(const NumericLiteral &lhs, const NumericLiteral &rhs)
224
- {
225
- return (!lhs.geq(rhs)) ? 1 : 0;
226
- }
227
-
228
- friend NumericLiteral operator<=(const NumericLiteral &lhs, const NumericLiteral &rhs)
229
- {
230
- return lhs.leq(rhs) ? 1 : 0;
231
- }
232
-
233
- friend NumericLiteral operator>=(const NumericLiteral &lhs, const NumericLiteral &rhs)
234
- {
235
- return lhs.geq(rhs) ? 1 : 0;
236
- }
237
-
238
- friend NumericLiteral operator+(const NumericLiteral &lhs, const NumericLiteral &rhs)
239
- {
240
- if (!lhs.is_infinity() && !rhs.is_infinity())
241
- return (lhs._n + rhs._n).simplify();
242
- else if (!lhs.is_infinity() && rhs.is_infinity())
243
- return rhs;
244
- else if (lhs.is_infinity() && !rhs.is_infinity())
245
- return lhs;
246
- else if (eq(lhs, rhs))
247
- return lhs;
248
- else
249
- {
250
- assert(false && "undefined operation +oo + -oo");
251
- abort();
252
- }
253
- }
254
-
255
- friend NumericLiteral operator-(const NumericLiteral &lhs, const NumericLiteral &rhs)
256
- {
257
- if (!lhs.is_infinity() && !rhs.is_infinity())
258
- return (lhs._n - rhs._n).simplify();
259
- else if (!lhs.is_infinity() && rhs.is_infinity())
260
- return -rhs;
261
- else if (lhs.is_infinity() && !rhs.is_infinity())
262
- return lhs;
263
- else if (!eq(lhs, rhs))
264
- return lhs;
265
- else
266
- {
267
- assert(false && "undefined operation +oo - +oo");
268
- abort();
269
- }
270
- }
271
-
272
- friend NumericLiteral operator*(const NumericLiteral &lhs, const NumericLiteral &rhs)
273
- {
274
- if (lhs.is_zero() || rhs.is_zero())
275
- return 0;
276
- else if (lhs.is_infinity() && rhs.is_infinity())
277
- return eq(lhs, rhs) ? plus_infinity() : minus_infinity();
278
- else if (lhs.is_infinity())
279
- return !rhs.leq(0) ? lhs : -lhs;
280
- else if (rhs.is_infinity())
281
- return !lhs.leq(0) ? rhs : -rhs;
282
- else
283
- return (lhs._n * rhs._n).simplify();
284
- }
285
-
286
- friend NumericLiteral operator/(const NumericLiteral &lhs, const NumericLiteral &rhs)
287
- {
288
- if (rhs.is_zero())
289
- {
290
-
291
- assert(false && "divide by zero");
292
- abort();
293
- }
294
- else if (!lhs.is_infinity() && !rhs.is_infinity())
295
- return (lhs._n / rhs._n).simplify();
296
- else if (!lhs.is_infinity() && rhs.is_infinity())
297
- return 0;
298
- else if (lhs.is_infinity() && !rhs.is_infinity())
299
- return !rhs.leq(0) ? lhs : -lhs;
300
- else
301
- // TODO: +oo/-oo L'Hôpital's rule?
302
- return eq(lhs, rhs) ? plus_infinity() : minus_infinity();
303
- }
304
-
305
- friend NumericLiteral operator%(const NumericLiteral &lhs, const NumericLiteral &rhs)
306
- {
307
- if (rhs.is_zero())
308
- {
309
- assert(false && "divide by zero");
310
- abort();
311
- }
312
- else if (!lhs.is_infinity() && !rhs.is_infinity())
313
- return (lhs._n % rhs._n).simplify();
314
- else if (!lhs.is_infinity() && rhs.is_infinity())
315
- return 0;
316
- // TODO: not sure
317
- else if (lhs.is_infinity() && !rhs.is_infinity())
318
- return !rhs.leq(0) ? lhs : -lhs;
319
- else
320
- // TODO: +oo/-oo L'Hôpital's rule?
321
- return eq(lhs, rhs) ? plus_infinity() : minus_infinity();
322
- }
323
-
324
- // TODO: logic operation for infinity?
325
- friend NumericLiteral operator^(const NumericLiteral &lhs, const NumericLiteral &rhs)
326
- {
327
- return (lhs._n ^ rhs._n).simplify();
328
- }
329
-
330
- friend NumericLiteral operator&(const NumericLiteral &lhs, const NumericLiteral &rhs)
331
- {
332
- return (lhs._n & rhs._n).simplify();
333
- }
334
-
335
- friend NumericLiteral operator|(const NumericLiteral &lhs, const NumericLiteral &rhs)
336
- {
337
- return (lhs._n | rhs._n).simplify();
338
- }
339
-
340
- friend NumericLiteral operator>>(const NumericLiteral &lhs, const NumericLiteral &rhs)
341
- {
342
- assert(rhs.geq(0) && "rhs should be greater or equal than 0");
343
- if (lhs.is_zero())
344
- return lhs;
345
- else if (lhs.is_infinity())
346
- return lhs;
347
- else if (rhs.is_infinity())
348
- return lhs.geq(0) ? 0 : -1;
349
- else
350
- return (s32_t) lhs.getNumeral() >> (s32_t) rhs.getNumeral();
351
- }
352
-
353
- friend NumericLiteral operator<<(const NumericLiteral &lhs, const NumericLiteral &rhs)
354
- {
355
- assert(rhs.geq(0) && "rhs should be greater or equal than 0");
356
- if (lhs.is_zero())
357
- return lhs;
358
- else if (lhs.is_infinity())
359
- return lhs;
360
- else if (rhs.is_infinity())
361
- return lhs.geq(0) ? plus_infinity() : minus_infinity();
362
- else
363
- return (s32_t) lhs.getNumeral() << (s32_t) rhs.getNumeral();
364
- }
365
-
366
- friend NumericLiteral operator&&(const NumericLiteral &lhs, const NumericLiteral &rhs)
367
- {
368
- return (lhs._n && rhs._n).simplify();
369
- }
370
-
371
- friend NumericLiteral operator||(const NumericLiteral &lhs, const NumericLiteral &rhs)
372
- {
373
- return (lhs._n || rhs._n).simplify();
374
- }
375
-
376
- friend NumericLiteral operator!(const NumericLiteral &lhs)
377
- {
378
- return (!lhs._n).simplify();
379
- }
380
-
381
- friend NumericLiteral operator-(const NumericLiteral &lhs)
382
- {
383
- if (lhs.is_plus_infinity())
384
- {
385
- return minus_infinity();
386
- }
387
- else if (lhs.is_minus_infinity())
388
- {
389
- return plus_infinity();
390
- }
391
- else
392
- return (-lhs._n).simplify();
393
- }
394
-
395
- /// Return ite? lhs : rhs
396
- friend NumericLiteral ite(const NumericLiteral &cond, const NumericLiteral &lhs, const NumericLiteral &rhs)
397
- {
398
- return ite(cond._n, lhs._n, rhs._n).simplify();
399
- }
400
-
401
- friend std::ostream &operator<<(std::ostream &out, const NumericLiteral &expr)
402
- {
403
- if (expr.is_plus_infinity())
404
- out << "+INF";
405
- else if (expr.is_minus_infinity())
406
- out << "-INF";
407
- else
408
- out << expr._n;
409
- return out;
410
- }
411
-
412
- friend bool eq(const NumericLiteral &lhs, const NumericLiteral &rhs)
413
- {
414
- return eq(lhs._n, rhs._n);
415
- }
416
-
417
- friend NumericLiteral min(const NumericLiteral &lhs, const NumericLiteral &rhs)
418
- {
419
- return lhs.leq(rhs) ? lhs : rhs;
420
- }
421
-
422
- friend NumericLiteral max(const NumericLiteral &lhs, const NumericLiteral &rhs)
423
- {
424
- return lhs.leq(rhs) ? rhs : lhs;
425
- }
426
-
427
- friend NumericLiteral abs(const NumericLiteral &lhs)
428
- {
429
- return lhs.leq(0) ? -lhs : lhs;
430
- }
431
-
432
- // TODO: how to use initializer_list as argument?
433
- static NumericLiteral min(std::vector<NumericLiteral>& _l)
434
- {
435
- NumericLiteral ret(plus_infinity());
436
- for (const auto &it: _l)
437
- {
438
- if (it.is_minus_infinity())
439
- return minus_infinity();
440
- else if (!it.geq(ret))
441
- {
442
- ret = it;
443
- }
444
- }
445
- return ret;
446
- }
447
-
448
- static NumericLiteral max(std::vector<NumericLiteral>& _l)
449
- {
450
- NumericLiteral ret(minus_infinity());
451
- for (const auto &it: _l)
452
- {
453
- if (it.is_plus_infinity())
454
- return plus_infinity();
455
- else if (!it.leq(ret))
456
- {
457
- ret = it;
458
- }
459
- }
460
- return ret;
461
- }
462
-
463
- //%}
464
-
465
-
466
- }; // end class NumericLiteral
467
- } // end namespace SVF
468
-
469
- /// Specialise hash for NumericLiteral
470
- template<>
471
- struct std::hash<SVF::NumericLiteral>
472
- {
473
- size_t operator()(const SVF::NumericLiteral &n) const
474
- {
475
- return n.getNumeral();
476
- }
477
- };
478
- #endif //Z3_EXAMPLE_Number_H