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,404 +0,0 @@
1
- //===- BoundedZ3Expr.h ----Address Value Sets-------------------------//
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
- * BoundedZ3Expr.h
24
- *
25
- * Created on: Mar 20, 2023
26
- * Author: Xiao Cheng
27
- *
28
- */
29
-
30
- #ifndef SVF_BOUNDEDZ3EXPR_H
31
- #define SVF_BOUNDEDZ3EXPR_H
32
- #define MaxBvLen 64
33
-
34
- #include "Util/Z3Expr.h"
35
-
36
- namespace SVF
37
- {
38
-
39
- /*!
40
- * Atom Z3 expr for unlimited precision integers
41
- */
42
- class BoundedZ3Expr : public Z3Expr
43
- {
44
-
45
- public:
46
- BoundedZ3Expr() = default;
47
-
48
- BoundedZ3Expr(const Z3Expr &z3Expr) : Z3Expr(z3Expr) {}
49
-
50
- BoundedZ3Expr(const z3::expr &e) : Z3Expr(e) {}
51
-
52
- BoundedZ3Expr(s32_t i) : Z3Expr(i) {}
53
-
54
- BoundedZ3Expr(s64_t i) : Z3Expr(getContext().int_val((int64_t)i)) {}
55
-
56
- BoundedZ3Expr(double i) : Z3Expr(getContext().real_val(std::to_string(i).c_str())) {}
57
-
58
- BoundedZ3Expr(const BoundedZ3Expr &z3Expr) : Z3Expr(z3Expr) {}
59
-
60
- inline BoundedZ3Expr &operator=(const BoundedZ3Expr &rhs)
61
- {
62
- Z3Expr::operator=(rhs);
63
- return *this;
64
- }
65
-
66
- BoundedZ3Expr(BoundedZ3Expr &&z3Expr) : Z3Expr(z3Expr) {}
67
-
68
-
69
- inline BoundedZ3Expr &operator=(BoundedZ3Expr &&rhs)
70
- {
71
- Z3Expr::operator=(rhs);
72
- return *this;
73
- }
74
-
75
- bool is_plus_infinite() const
76
- {
77
- return eq(*this, getContext().int_const("+oo"));
78
- }
79
-
80
- bool is_minus_infinite() const
81
- {
82
- return eq(*this, getContext().int_const("-oo"));
83
- }
84
-
85
- bool is_infinite() const
86
- {
87
- return is_plus_infinite() || is_minus_infinite();
88
- }
89
-
90
- void set_plus_infinite()
91
- {
92
- *this = plus_infinity();
93
- }
94
-
95
- void set_minus_infinite()
96
- {
97
- *this = minus_infinity();
98
- }
99
-
100
- static BoundedZ3Expr plus_infinity()
101
- {
102
- return getContext().int_const("+oo");
103
- }
104
-
105
- static BoundedZ3Expr minus_infinity()
106
- {
107
- return getContext().int_const("-oo");
108
- }
109
-
110
- static z3::context &getContext()
111
- {
112
- return Z3Expr::getContext();
113
- }
114
-
115
- bool is_zero() const
116
- {
117
- return getExpr().is_numeral() && eq(getExpr(), Z3Expr(0));
118
- }
119
-
120
- static bool isZero(const BoundedZ3Expr &expr)
121
- {
122
- return expr.is_numeral() && eq(expr.getExpr(), Z3Expr(0));
123
- }
124
-
125
- BoundedZ3Expr equal(const BoundedZ3Expr &rhs) const
126
- {
127
- return getExpr() == rhs.getExpr();
128
- }
129
-
130
- BoundedZ3Expr leq(const BoundedZ3Expr &rhs) const
131
- {
132
- return getExpr() <= rhs.getExpr();
133
- }
134
-
135
- BoundedZ3Expr geq(const BoundedZ3Expr &rhs) const
136
- {
137
- return getExpr() >= rhs.getExpr();
138
- }
139
-
140
- /// Reload operator
141
- //{%
142
- friend BoundedZ3Expr operator==(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
143
- {
144
- return lhs.equal(rhs);
145
- }
146
-
147
- friend BoundedZ3Expr operator!=(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
148
- {
149
- return !lhs.equal(rhs);
150
- }
151
-
152
- friend BoundedZ3Expr operator>(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
153
- {
154
- return !lhs.leq(rhs);
155
- }
156
-
157
- friend BoundedZ3Expr operator<(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
158
- {
159
- return !lhs.geq(rhs);
160
- }
161
-
162
- friend BoundedZ3Expr operator<=(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
163
- {
164
- return lhs.leq(rhs);
165
- }
166
-
167
- friend BoundedZ3Expr operator>=(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
168
- {
169
- return lhs.geq(rhs);
170
- }
171
-
172
- friend BoundedZ3Expr operator+(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
173
- {
174
- if (!lhs.is_infinite() && !rhs.is_infinite())
175
- return lhs.getExpr() + rhs.getExpr();
176
- else if (!lhs.is_infinite() && rhs.is_infinite())
177
- return rhs;
178
- else if (lhs.is_infinite() && !rhs.is_infinite())
179
- return lhs;
180
- else if (eq(lhs, rhs))
181
- return lhs;
182
- else
183
- assert(false && "undefined operation +oo + -oo");
184
- abort();
185
- }
186
-
187
- friend BoundedZ3Expr operator-(const BoundedZ3Expr &lhs)
188
- {
189
- return -lhs.getExpr();
190
- }
191
-
192
- friend BoundedZ3Expr operator-(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
193
- {
194
- if (!lhs.is_infinite() && !rhs.is_infinite())
195
- return lhs.getExpr() - rhs.getExpr();
196
- else if (!lhs.is_infinite() && rhs.is_infinite())
197
- return -rhs;
198
- else if (lhs.is_infinite() && !rhs.is_infinite())
199
- return lhs;
200
- else if (!eq(lhs, rhs))
201
- return lhs;
202
- else
203
- assert(false && "undefined operation +oo - +oo");
204
- abort();
205
- }
206
-
207
- friend BoundedZ3Expr operator*(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
208
- {
209
- if (lhs.is_zero() || rhs.is_zero()) return 0;
210
- else if (lhs.is_infinite() && rhs.is_infinite())
211
- return eq(lhs, rhs) ? plus_infinity() : minus_infinity();
212
- else if (lhs.is_infinite())
213
- return ite(rhs.getExpr() > 0, lhs, -lhs);
214
- else if (rhs.is_infinite())
215
- return ite(lhs.getExpr() > 0, rhs, -rhs);
216
- else
217
- return lhs.getExpr() * rhs.getExpr();
218
- }
219
-
220
- friend BoundedZ3Expr operator/(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
221
- {
222
- if (rhs.is_zero()) assert(false && "divide by zero");
223
- else if (!lhs.is_infinite() && !rhs.is_infinite())
224
- return lhs.getExpr() / rhs.getExpr();
225
- else if (!lhs.is_infinite() && rhs.is_infinite())
226
- return 0;
227
- else if (lhs.is_infinite() && !rhs.is_infinite())
228
- return ite(rhs.getExpr() > 0, lhs, -lhs);
229
- else
230
- // TODO: +oo/-oo L'Hôpital's rule?
231
- return eq(lhs, rhs) ? plus_infinity() : minus_infinity();
232
- abort();
233
- }
234
-
235
- friend BoundedZ3Expr operator%(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
236
- {
237
- if (rhs.is_zero()) assert(false && "divide by zero");
238
- else if (!lhs.is_infinite() && !rhs.is_infinite())
239
- return lhs.getExpr() % rhs.getExpr();
240
- else if (!lhs.is_infinite() && rhs.is_infinite())
241
- return 0;
242
- // TODO: not sure
243
- else if (lhs.is_infinite() && !rhs.is_infinite())
244
- return ite(rhs.getExpr() > 0, lhs, -lhs);
245
- else
246
- // TODO: +oo/-oo L'Hôpital's rule?
247
- return eq(lhs, rhs) ? plus_infinity() : minus_infinity();
248
- abort();
249
- }
250
-
251
- friend BoundedZ3Expr operator^(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
252
- {
253
- return bv2int(int2bv(MaxBvLen, lhs.getExpr()) ^ int2bv(MaxBvLen, rhs.getExpr()), true);
254
- }
255
-
256
- friend BoundedZ3Expr operator&(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
257
- {
258
- return bv2int(int2bv(MaxBvLen, lhs.getExpr()) & int2bv(MaxBvLen, rhs.getExpr()), true);
259
- }
260
-
261
- friend BoundedZ3Expr operator|(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
262
- {
263
- return bv2int(int2bv(MaxBvLen, lhs.getExpr()) | int2bv(MaxBvLen, rhs.getExpr()), true);
264
- }
265
-
266
- friend BoundedZ3Expr ashr(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
267
- {
268
- if (lhs.is_zero())
269
- return lhs;
270
- else if (lhs.is_infinite())
271
- return lhs;
272
- else if (rhs.is_infinite())
273
- return ite(lhs.getExpr() >= 0, BoundedZ3Expr(0), BoundedZ3Expr(-1));
274
- else
275
- {
276
- return bv2int(ashr(int2bv(MaxBvLen, lhs.getExpr()), int2bv(MaxBvLen, rhs.getExpr())), true);
277
- }
278
- }
279
-
280
- friend BoundedZ3Expr shl(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
281
- {
282
- if (lhs.is_zero())
283
- return lhs;
284
- else if (lhs.is_infinite())
285
- return lhs;
286
- else if (rhs.is_infinite())
287
- return ite(lhs.getExpr() >= 0, plus_infinity(), minus_infinity());
288
- else
289
- {
290
- return bv2int(shl(int2bv(MaxBvLen, lhs.getExpr()), int2bv(MaxBvLen, rhs.getExpr())), true);
291
- }
292
- }
293
-
294
- friend BoundedZ3Expr lshr(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
295
- {
296
- return bv2int(lshr(int2bv(MaxBvLen, lhs.getExpr()), int2bv(MaxBvLen, rhs.getExpr())), true);
297
- }
298
-
299
- friend BoundedZ3Expr int2bv(u32_t n, const BoundedZ3Expr &e)
300
- {
301
- return int2bv(n, e.getExpr());
302
- }
303
-
304
- friend BoundedZ3Expr bv2int(const BoundedZ3Expr &e, bool isSigned)
305
- {
306
- return bv2int(e.getExpr(), isSigned);
307
- }
308
-
309
- friend BoundedZ3Expr operator&&(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
310
- {
311
- return lhs.getExpr() && rhs.getExpr();
312
- }
313
-
314
- friend BoundedZ3Expr operator||(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
315
- {
316
- return lhs.getExpr() || rhs.getExpr();
317
- }
318
-
319
- friend BoundedZ3Expr operator!(const BoundedZ3Expr &lhs)
320
- {
321
- return !lhs.getExpr();
322
- }
323
-
324
- friend BoundedZ3Expr ite(const BoundedZ3Expr &cond, const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
325
- {
326
- return ite(cond.getExpr(), lhs.getExpr(), rhs.getExpr());
327
- }
328
-
329
- friend std::ostream &operator<<(std::ostream &out, const BoundedZ3Expr &expr)
330
- {
331
- out << expr.getExpr();
332
- return out;
333
- }
334
-
335
- friend bool eq(const BoundedZ3Expr &lhs, const BoundedZ3Expr &rhs)
336
- {
337
- return eq(lhs.getExpr(), rhs.getExpr());
338
- }
339
-
340
- inline BoundedZ3Expr simplify() const
341
- {
342
- return getExpr().simplify();
343
- }
344
-
345
- inline bool is_true() const
346
- {
347
- return getExpr().is_true();
348
- }
349
-
350
- inline bool is_int() const
351
- {
352
- return getExpr().is_int();
353
- }
354
-
355
- inline bool is_real() const
356
- {
357
- return getExpr().is_real();
358
- }
359
-
360
- inline s64_t getIntNumeral() const
361
- {
362
- assert(is_int() && "not an integer");
363
- int64_t i;
364
- if (getExpr().is_numeral_i64(i))
365
- return (s64_t)get_numeral_int64();
366
- else
367
- return (getExpr() < 0).simplify().is_true() ? INT64_MIN : INT64_MAX;
368
- }
369
-
370
- inline double getRealNumeral() const
371
- {
372
- assert(is_real() && "not a real");
373
- std::string decstr = getExpr().get_decimal_string(10);
374
- return std::stod(decstr);
375
- }
376
-
377
- /// Return Numeral
378
- inline s64_t getNumeral() const
379
- {
380
- int64_t i;
381
- if (getExpr().is_numeral_i64(i))
382
- return (s64_t)get_numeral_int64();
383
- else
384
- {
385
- return (getExpr() < 0).simplify().is_true() ? INT64_MIN : INT64_MAX;
386
- }
387
- }
388
-
389
- s64_t bvLen() const;
390
- //%}
391
- }; // end class ConZ3Expr
392
- } // end namespace SVF
393
-
394
- /// Specialise hash for ConZ3Expr
395
- template<>
396
- struct std::hash<SVF::BoundedZ3Expr>
397
- {
398
- size_t operator()(const SVF::BoundedZ3Expr &z3Expr) const
399
- {
400
- return z3Expr.hash();
401
- }
402
- };
403
- #endif //SVF_BOUNDEDZ3EXPR_H
404
-