SMTStabilizer API
Public API documentation for SMTStabilizer
Loading...
Searching...
No Matches
util.cpp
Go to the documentation of this file.
1/* -*- Source -*-
2 *
3 * The Util Functions
4 *
5 * Author: Fuqi Jia <jiafq@ios.ac.cn>
6 *
7 * Copyright (C) 2025 Fuqi Jia
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 */
27// Modified by Xiang Zhang, 2026
28// Additional changes licensed under the MIT License
29#include "util.h"
30
31#include <algorithm>
32#include <cmath>
33#include <cstdint>
34#include <iomanip>
35#include <sstream>
36#include <stdexcept>
37#include <string>
38#include <vector>
39
40#include "util/bitvector.h"
41namespace stabilizer::parser {
42
43bool TypeChecker::isNumber(const std::string &str) {
44 return isInt(str) || isReal(str);
45}
46
47bool TypeChecker::isInt(const std::string &str) {
48 if (str.empty())
49 return false;
50 for (size_t i = 0; i < str.size(); i++) {
51 if (i == 0 && (str[i] == '-' || str[i] == '+'))
52 continue;
53 if (!isdigit(str[i]))
54 return false;
55 }
56 return true;
57}
58bool TypeChecker::isReal(const std::string &str) {
59 if (str.empty())
60 return false;
61 bool has_dot = false;
62 for (size_t i = 0; i < str.size(); i++) {
63 if (i == 0 && (str[i] == '-' || str[i] == '+'))
64 continue;
65 if (str[i] == '.' && !has_dot) {
66 has_dot = true;
67 continue;
68 }
69 if (!isdigit(str[i]))
70 return false;
71 }
72 return true;
73}
74
75bool TypeChecker::isScientificNotation(const std::string &str) {
76 if (str.empty())
77 return false;
78
79 // find 'E' or 'e' character
80 size_t e_pos = str.find_first_of("Ee");
81 if (e_pos == std::string::npos || e_pos == 0)
82 return false;
83
84 // check if the part before E is a valid real number
85 std::string mantissa = str.substr(0, e_pos);
86 if (!TypeChecker::isReal(mantissa))
87 return false;
88
89 // extract the part after E
90 std::string exponent = str.substr(e_pos + 1);
91
92 // if the exponent part is empty, not a valid scientific notation
93 if (exponent.empty())
94 return false;
95
96 // create a copy without spaces for checking
97 std::string exponent_no_spaces = exponent;
98 exponent_no_spaces.erase(
99 std::remove_if(exponent_no_spaces.begin(), exponent_no_spaces.end(), [](unsigned char c) { return std::isspace(c); }),
100 exponent_no_spaces.end());
101
102 // if the exponent part is empty after removing spaces, not a valid scientific
103 // notation
104 if (exponent_no_spaces.empty())
105 return false;
106
107 // handle possible parentheses
108 if (exponent_no_spaces[0] == '(') {
109 // find right parenthesis
110 size_t close_pos = exponent_no_spaces.find(')');
111 if (close_pos != std::string::npos) {
112 // extract the content inside parentheses
113 exponent_no_spaces = exponent_no_spaces.substr(1, close_pos - 1);
114 }
115 else {
116 // no right parenthesis found, possibly incomplete expression
117 exponent_no_spaces = exponent_no_spaces.substr(1);
118 }
119 }
120
121 // if the exponent part is empty after handling parentheses, not a valid
122 // scientific notation
123 if (exponent_no_spaces.empty())
124 return false;
125
126 // check if the exponent part is a valid integer
127 if (exponent_no_spaces[0] == '+' || exponent_no_spaces[0] == '-') {
128 // if "E-" or "E+", there must be a digit after it
129 if (exponent_no_spaces.size() == 1)
130 return false;
131 // check if the part after "E-" or "E+" is all digits
132 for (size_t i = 1; i < exponent_no_spaces.size(); i++) {
133 if (!isdigit(exponent_no_spaces[i]))
134 return false;
135 }
136 }
137 else {
138 // if there is no sign, the whole exponent part must be all digits
139 for (char c : exponent_no_spaces) {
140 if (!isdigit(c))
141 return false;
142 }
143 }
144
145 return true;
146}
147
148std::string ConversionUtils::parseScientificNotation(const std::string &str) {
149 // find 'E' or 'e' character
150 size_t e_pos = str.find_first_of("Ee");
151 if (e_pos == std::string::npos)
152 return str;
153
154 try {
155 // extract the mantissa part
156 std::string mantissa = str.substr(0, e_pos);
157
158 // check if the mantissa part is a valid real number
159 if (!TypeChecker::isReal(mantissa))
160 return str;
161
162 // extract the exponent part
163 std::string exponent = str.substr(e_pos + 1);
164
165 // if the exponent part is empty, return the original string
166 if (exponent.empty())
167 return str;
168
169 // create a copy without spaces for processing
170 std::string exponent_no_spaces = exponent;
171 exponent_no_spaces.erase(
172 std::remove_if(exponent_no_spaces.begin(), exponent_no_spaces.end(), [](unsigned char c) { return std::isspace(c); }),
173 exponent_no_spaces.end());
174
175 // if the exponent part is empty after removing spaces, return the original
176 // string
177 if (exponent_no_spaces.empty())
178 return str;
179
180 // handle possible parentheses
181 if (exponent_no_spaces[0] == '(') {
182 // find right parenthesis
183 size_t close_pos = exponent_no_spaces.find(')');
184 if (close_pos != std::string::npos) {
185 // extract the content inside parentheses
186 exponent_no_spaces = exponent_no_spaces.substr(1, close_pos - 1);
187 }
188 else {
189 // no right parenthesis found, possibly incomplete expression
190 exponent_no_spaces = exponent_no_spaces.substr(1);
191 }
192 }
193
194 // if the exponent part is empty after handling parentheses, return the
195 // original string
196 if (exponent_no_spaces.empty())
197 return str;
198
199 // convert scientific notation to normal real number
200 // TODO!!
201 Real mantissa_val = Real(mantissa);
202 Real exponent_val = Real(exponent_no_spaces);
203
204 // calculate the result
205 Real result = mantissa_val *
206 stabilizer::parser::MathUtils::pow(Real(10.0), exponent_val);
207
208 // convert to string
209 std::ostringstream oss;
210 oss << std::setprecision(16) << toString(result);
211 return oss.str();
212 }
213 catch (const std::exception &e) {
214 // conversion failed, return the original string
215 return str;
216 }
217}
218
219bool TypeChecker::isBV(const std::string &str) {
220 if (str.empty())
221 return false;
222 if (str.size() < 3)
223 return false;
224 if (str[0] != '#')
225 return false;
226 if (str[1] != 'b' && str[1] != 'x' && str[1] != 'd' && str[1] != 'B' &&
227 str[1] != 'X' && str[1] != 'D')
228 return false;
229 for (size_t i = 2; i < str.size(); i++) {
230 if ((str[1] == 'b' || str[1] == 'B') && (str[i] != '0' && str[i] != '1'))
231 return false;
232 if ((str[1] == 'x' || str[1] == 'X') &&
233 (str[i] != '0' && str[i] != '1' && str[i] != '2' && str[i] != '3' &&
234 str[i] != '4' && str[i] != '5' && str[i] != '6' && str[i] != '7' &&
235 str[i] != '8' && str[i] != '9' && str[i] != 'a' && str[i] != 'A' &&
236 str[i] != 'b' && str[i] != 'B' && str[i] != 'c' && str[i] != 'C' &&
237 str[i] != 'd' && str[i] != 'D' && str[i] != 'e' && str[i] != 'E' &&
238 str[i] != 'f' && str[i] != 'F'))
239 return false;
240 if ((str[1] == 'd' || str[1] == 'D') &&
241 (str[i] != '0' && str[i] != '1' && str[i] != '2' && str[i] != '3' &&
242 str[i] != '4' && str[i] != '5' && str[i] != '6' && str[i] != '7' &&
243 str[i] != '8' && str[i] != '9'))
244 return false;
245 }
246 return true;
247}
248bool TypeChecker::isFP(const std::string &str) {
249 if (str.empty())
250 return false;
251 if (str.size() < 4)
252 return false;
253 if (str.substr(0, 3) != "(fp")
254 return false;
255 if (str[str.size() - 1] != ')')
256 return false;
257 return true;
258}
259bool TypeChecker::isString(const std::string &str) {
260 if (str.empty())
261 return false;
262 if (str[0] != '"' || str[str.size() - 1] != '"')
263 return false;
264 return true;
265}
266
267Integer MathUtils::pow(const Integer &base, const Integer &exp) {
268 if (exp == 0)
269 return 1;
270 Integer result = base;
271 for (Integer i = 1; i < exp; i++) {
272 result *= base;
273 }
274 return result;
275}
276Real MathUtils::pow(const Real &base, const Real &exp) { return base.pow(exp); }
277
279 if (b == 0)
280 return a;
281 return MathUtils::gcd(b, a % b);
282}
283
285 return a * b / stabilizer::parser::MathUtils::gcd(a, b);
286}
287
289 if (i < 0) {
290 throw std::runtime_error("Error: MathUtils::sqrt of negative number");
291 }
292 return HighPrecisionReal(i).sqrt();
293}
295 if (r < 0) {
296 throw std::runtime_error("Error: MathUtils::sqrt of negative number");
297 }
298 return r.sqrt();
299}
300
302 if (i < 0) {
303 return Real(0);
304 }
305 return HighPrecisionReal(i).sqrt();
306}
307
309 if (r < 0) {
310 return Real(0);
311 }
312 return r.sqrt();
313}
314
315Integer MathUtils::ceil(const Real &r) { return r.ceil().toInteger(); }
316Integer MathUtils::floor(const Real &r) { return r.floor().toInteger(); }
317Integer MathUtils::round(const Real &r) { return r.round().toInteger(); }
318
320 if (n <= 1)
321 return false;
322 if (n == 2)
323 return true;
324 if (n % 2 == 0)
325 return false;
326 for (Integer i = 3; i * i <= n; i += 2) {
327 if (n % i == 0)
328 return false;
329 }
330 return true;
331}
332
333bool MathUtils::isEven(const Integer &n) { return n % 2 == 0; }
334
335bool MathUtils::isOdd(const Integer &n) { return n % 2 != 0; }
336
338 Integer res = 1;
339 for (Integer i = 1; i <= n; i++) {
340 res *= i;
341 }
342 return res;
343}
344
345std::string BitVectorUtils::bvNot(const std::string &bv) {
346 condAssert(bv[0] == '#' && bv[1] == 'b',
347 "BitVectorUtils::bvNot: invalid bitvector");
348 std::string res = "#b";
349 for (size_t i = 2; i < bv.size(); i++) {
350 res += bv[i] == '1' ? '0' : '1';
351 }
352 return res;
353}
354std::string BitVectorUtils::bvAnd(const std::string &bv1,
355 const std::string &bv2) {
356 condAssert(bv1[0] == '#' && bv1[1] == 'b',
357 "BitVectorUtils::bvAnd: invalid bitvector");
358 condAssert(bv2[0] == '#' && bv2[1] == 'b',
359 "BitVectorUtils::bvAnd: invalid bitvector");
360 std::string res = "#b";
361 for (size_t i = 2; i < bv1.size(); i++) {
362 res += bv1[i] == '1' && bv2[i] == '1' ? '1' : '0';
363 }
364 return res;
365}
366std::string BitVectorUtils::bvOr(const std::string &bv1,
367 const std::string &bv2) {
368 condAssert(bv1[0] == '#' && bv1[1] == 'b',
369 "BitVectorUtils::bvOr: invalid bitvector");
370 condAssert(bv2[0] == '#' && bv2[1] == 'b',
371 "BitVectorUtils::bvOr: invalid bitvector");
372 std::string res = "#b";
373 for (size_t i = 2; i < bv1.size(); i++) {
374 res += bv1[i] == '1' || bv2[i] == '1' ? '1' : '0';
375 }
376 return res;
377}
378std::string BitVectorUtils::bvXor(const std::string &bv1,
379 const std::string &bv2) {
380 condAssert(bv1[0] == '#' && bv1[1] == 'b',
381 "BitVectorUtils::bvXor: invalid bitvector");
382 condAssert(bv2[0] == '#' && bv2[1] == 'b',
383 "BitVectorUtils::bvXor: invalid bitvector");
384 std::string res = "#b";
385 for (size_t i = 2; i < bv1.size(); i++) {
386 res += bv1[i] != bv2[i] ? '1' : '0';
387 }
388 return res;
389}
390std::string BitVectorUtils::bvNand(const std::string &bv1,
391 const std::string &bv2) {
392 condAssert(bv1[0] == '#' && bv1[1] == 'b',
393 "BitVectorUtils::bvNand: invalid bitvector");
394 condAssert(bv2[0] == '#' && bv2[1] == 'b',
395 "BitVectorUtils::bvNand: invalid bitvector");
396 std::string res = "#b";
397 for (size_t i = 2; i < bv1.size(); i++) {
398 res += bv1[i] == '1' && bv2[i] == '1' ? '0' : '1';
399 }
400 return res;
401}
402std::string BitVectorUtils::bvNor(const std::string &bv1,
403 const std::string &bv2) {
404 condAssert(bv1[0] == '#' && bv1[1] == 'b',
405 "BitVectorUtils::bvNor: invalid bitvector");
406 condAssert(bv2[0] == '#' && bv2[1] == 'b',
407 "BitVectorUtils::bvNor: invalid bitvector");
408 std::string res = "#b";
409 for (size_t i = 2; i < bv1.size(); i++) {
410 res += bv1[i] == '0' && bv2[i] == '0' ? '1' : '0';
411 }
412 return res;
413}
414std::string BitVectorUtils::bvXnor(const std::string &bv1,
415 const std::string &bv2) {
416 condAssert(bv1[0] == '#' && bv1[1] == 'b',
417 "BitVectorUtils::bvXnor: invalid bitvector");
418 condAssert(bv2[0] == '#' && bv2[1] == 'b',
419 "BitVectorUtils::bvXnor: invalid bitvector");
420 std::string res = "#b";
421 for (size_t i = 2; i < bv1.size(); i++) {
422 res += bv1[i] == bv2[i] ? '1' : '0';
423 }
424 return res;
425}
426
427std::string BitVectorUtils::bvNeg(const std::string &bv) {
428 condAssert(bv[0] == '#' && bv[1] == 'b',
429 "BitVectorUtils::bvNeg: invalid bitvector");
430 util::BitVector cbv(bv.size() - 2, bv.substr(2));
431 cbv.ibvneg();
432 return "#b" + cbv.str();
433}
434
435std::string BitVectorUtils::bvAdd(const std::string &bv1,
436 const std::string &bv2) {
437 condAssert(bv1[0] == '#' && bv1[1] == 'b',
438 "BitVectorUtils::bvAdd: invalid bitvector");
439 condAssert(bv2[0] == '#' && bv2[1] == 'b',
440 "BitVectorUtils::bvAdd: invalid bitvector");
441
442 util::BitVector cbv1(bv1.size() - 2, bv1.substr(2));
443 util::BitVector cbv2(bv2.size() - 2, bv2.substr(2));
444 cbv1.ibvadd(cbv2);
445 return "#b" + cbv1.str();
446}
447std::string BitVectorUtils::bvSub(const std::string &bv1,
448 const std::string &bv2) {
449 condAssert(bv1[0] == '#' && bv1[1] == 'b',
450 "BitVectorUtils::bvSub: invalid bitvector");
451 condAssert(bv2[0] == '#' && bv2[1] == 'b',
452 "BitVectorUtils::bvSub: invalid bitvector");
453
454 util::BitVector cbv1(bv1.size() - 2, bv1.substr(2));
455 util::BitVector cbv2(bv2.size() - 2, bv2.substr(2));
456 cbv1.ibvsub(cbv2);
457 return "#b" + cbv1.str();
458}
459std::string BitVectorUtils::bvMul(const std::string &bv1,
460 const std::string &bv2) {
461 condAssert(bv1.rfind("#b", 0) == 0,
462 "BitVectorUtils::bvMul: invalid bitvector");
463 condAssert(bv2.rfind("#b", 0) == 0,
464 "BitVectorUtils::bvMul: invalid bitvector");
465
466 util::BitVector cbv1(bv1.size() - 2, bv1.substr(2));
467 util::BitVector cbv2(bv2.size() - 2, bv2.substr(2));
468 cbv1.ibvmul(cbv2);
469 return "#b" + cbv1.str();
470}
471
472std::string BitVectorUtils::bvUdiv(const std::string &bv1,
473 const std::string &bv2) {
474 condAssert(bv1[0] == '#' && bv1[1] == 'b',
475 "BitVectorUtils::bvUdiv: invalid bitvector");
476 condAssert(bv2[0] == '#' && bv2[1] == 'b',
477 "BitVectorUtils::bvUdiv: invalid bitvector");
478
479 util::BitVector cbv1(bv1.size() - 2, bv1.substr(2));
480 util::BitVector cbv2(bv2.size() - 2, bv2.substr(2));
481 cbv1.ibvudiv(cbv2);
482 return "#b" + cbv1.str();
483}
484std::string BitVectorUtils::bvUrem(const std::string &bv1,
485 const std::string &bv2) {
486 condAssert(bv1[0] == '#' && bv1[1] == 'b',
487 "BitVectorUtils::bvUrem: invalid bitvector");
488 condAssert(bv2[0] == '#' && bv2[1] == 'b',
489 "BitVectorUtils::bvUrem: invalid bitvector");
490 util::BitVector cbv1(bv1.size() - 2, bv1.substr(2));
491 util::BitVector cbv2(bv2.size() - 2, bv2.substr(2));
492 cbv1.ibvurem(cbv2);
493 return "#b" + cbv1.str();
494}
495std::string BitVectorUtils::bvUmod(const std::string &bv1,
496 const std::string &bv2) {
497 condAssert(bv1[0] == '#' && bv1[1] == 'b',
498 "BitVectorUtils::bvUmod: invalid bitvector");
499 condAssert(bv2[0] == '#' && bv2[1] == 'b',
500 "BitVectorUtils::bvUmod: invalid bitvector");
501 std::string res = stabilizer::parser::BitVectorUtils::bvUrem(bv1, bv2);
502 return res;
503}
504std::string BitVectorUtils::bvSdiv(const std::string &bv1,
505 const std::string &bv2) {
506 condAssert(bv1[0] == '#' && bv1[1] == 'b',
507 "BitVectorUtils::bvSdiv: invalid bitvector");
508 condAssert(bv2[0] == '#' && bv2[1] == 'b',
509 "BitVectorUtils::bvSdiv: invalid bitvector");
510
511 util::BitVector cbv1(bv1.size() - 2, bv1.substr(2));
512 util::BitVector cbv2(bv2.size() - 2, bv2.substr(2));
513 cbv1.ibvsdiv(cbv2);
514 return "#b" + cbv1.str();
515}
516std::string BitVectorUtils::bvSrem(const std::string &bv1,
517 const std::string &bv2) {
518 condAssert(bv1[0] == '#' && bv1[1] == 'b',
519 "BitVectorUtils::bvSrem: invalid bitvector");
520 condAssert(bv2[0] == '#' && bv2[1] == 'b',
521 "BitVectorUtils::bvSrem: invalid bitvector");
522
523 util::BitVector cbv1(bv1.size() - 2, bv1.substr(2));
524 util::BitVector cbv2(bv2.size() - 2, bv2.substr(2));
525 cbv1.ibvsrem(cbv2);
526 return "#b" + cbv1.str();
527}
528std::string BitVectorUtils::bvSmod(const std::string &bv1,
529 const std::string &bv2) {
530 condAssert(bv1[0] == '#' && bv1[1] == 'b',
531 "BitVectorUtils::bvSmod: invalid bitvector");
532 condAssert(bv2[0] == '#' && bv2[1] == 'b',
533 "BitVectorUtils::bvSmod: invalid bitvector");
534
535 util::BitVector cbv1(bv1.size() - 2, bv1.substr(2));
536 util::BitVector cbv2(bv2.size() - 2, bv2.substr(2));
537 cbv1.ibvsmod(cbv2);
538 return "#b" + cbv1.str();
539}
540
541std::string BitVectorUtils::bvShl(const std::string &bv, const std::string &n) {
542 // left shift
543 condAssert(bv[0] == '#' && bv[1] == 'b',
544 "BitVectorUtils::bvShl: invalid bitvector");
545 condAssert(n[0] == '#' && n[1] == 'b',
546 "BitVectorUtils::bvShl: invalid bitvector");
547
548 util::BitVector cbv(bv.size() - 2, bv.substr(2));
549 cbv.ibvshl(util::BitVector(n.size() - 2, n.substr(2)));
550 return "#b" + cbv.str();
551}
552std::string BitVectorUtils::bvLshr(const std::string &bv,
553 const std::string &n) {
554 // logical right shift
555 condAssert(bv[0] == '#' && bv[1] == 'b',
556 "BitVectorUtils::bvLshr: invalid bitvector");
557 condAssert(n[0] == '#' && n[1] == 'b',
558 "BitVectorUtils::bvLshr: invalid bitvector");
559
560 util::BitVector cbv(bv.size() - 2, bv.substr(2));
561 cbv.ibvshr(util::BitVector(n.size() - 2, n.substr(2)));
562 return "#b" + cbv.str();
563}
564std::string BitVectorUtils::bvAshr(const std::string &bv,
565 const std::string &n) {
566 // arithmetic right shift
567 condAssert(bv[0] == '#' && bv[1] == 'b',
568 "BitVectorUtils::bvAshr: invalid bitvector");
569 condAssert(n[0] == '#' && n[1] == 'b',
570 "BitVectorUtils::bvAshr: invalid bitvector");
571
572 util::BitVector cbv(bv.size() - 2, bv.substr(2));
573 cbv.ibvashr(util::BitVector(n.size() - 2, n.substr(2)));
574 return "#b" + cbv.str();
575}
576
577std::string BitVectorUtils::bvConcat(const std::string &bv1,
578 const std::string &bv2) {
579 condAssert(bv1[0] == '#' && bv1[1] == 'b',
580 "BitVectorUtils::bvConcat: invalid bitvector");
581 condAssert(bv2[0] == '#' && bv2[1] == 'b',
582 "BitVectorUtils::bvConcat: invalid bitvector");
583 return "#b" + bv1.substr(2, bv1.size() - 2) + bv2.substr(2, bv2.size() - 2);
584}
585std::string BitVectorUtils::bvExtract(const std::string &bv, const Integer &i, const Integer &j) {
586 condAssert(bv[0] == '#' && bv[1] == 'b',
587 "BitVectorUtils::bvExtract: invalid bitvector");
588 condAssert(i >= j,
589 "BitVectorUtils::bvExtract: i must be greater than or equal to j");
590
591 // for bitvector "#b1010", bit3=1, bit2=0, bit1=1, bit0=0
592 size_t bit_width = bv.size() - 2; // actual bit width
593 size_t start_pos =
594 2 + (bit_width - 1 - i.toULong()); // start position from left
595 size_t length = i.toULong() - j.toULong() + 1; // length of extracted bits
596
597 return "#b" + bv.substr(start_pos, length);
598}
599std::string BitVectorUtils::bvRepeat(const std::string &bv, const Integer &n) {
600 condAssert(bv[0] == '#' && bv[1] == 'b',
601 "BitVectorUtils::bvRepeat: invalid bitvector");
602 std::string res = "";
603 for (size_t i = 0; i < n.toULong(); i++) {
604 res += bv.substr(2);
605 }
606 return "#b" + res;
607}
608std::string BitVectorUtils::bvZeroExtend(const std::string &bv,
609 const Integer &n) {
610 condAssert(bv[0] == '#' && bv[1] == 'b',
611 "BitVectorUtils::bvZeroExtend: invalid bitvector");
612 return "#b" + std::string(n.toULong(), '0') + bv.substr(2);
613}
614std::string BitVectorUtils::bvSignExtend(const std::string &bv,
615 const Integer &n) {
616 condAssert(bv[0] == '#' && bv[1] == 'b',
617 "BitVectorUtils::bvSignExtend: invalid bitvector");
618 return "#b" + std::string(n.toULong(), bv[2]) + bv.substr(2);
619}
620
621std::string BitVectorUtils::bvRotateLeft(const std::string &bv,
622 const Integer &n) {
623 condAssert(bv[0] == '#' && bv[1] == 'b',
624 "BitVectorUtils::bvRotateLeft: invalid bitvector");
625 Integer real_n = n % (bv.size() - 2);
626 return "#b" + bv.substr(2 + n.toULong()) + bv.substr(2, n.toULong());
627}
628std::string BitVectorUtils::bvRotateRight(const std::string &bv,
629 const Integer &n) {
630 condAssert(bv[0] == '#' && bv[1] == 'b',
631 "BitVectorUtils::bvRotateRight: invalid bitvector");
632 Integer real_n = n % (bv.size() - 2);
633 return "#b" + bv.substr(2 + bv.size() - 2 - n.toULong()) +
634 bv.substr(2, bv.size() - 2 - n.toULong());
635}
636
637bool BitVectorUtils::bvComp(const std::string &bv1, const std::string &bv2, const NODE_KIND &kind) {
638 condAssert(bv1[0] == '#' && bv1[1] == 'b',
639 "BitVectorUtils::bvComp: invalid bitvector");
640 condAssert(bv2[0] == '#' && bv2[1] == 'b',
641 "BitVectorUtils::bvComp: invalid bitvector");
642 switch (kind) {
644 return bv1 == bv2;
646 return bv1 != bv2;
671 default:
672 return false;
673 }
674}
675
676bool BitVectorUtils::bvIsMaxSigned(const std::string &bv) {
677 condAssert(bv[0] == '#' && bv[1] == 'b',
678 "BitVectorUtils::bvIsMaxSigned: invalid bitvector");
679 if (bv[2] != '0')
680 return false;
681 return std::all_of(bv.begin() + 3, bv.end(), [](char c) { return c == '1'; });
682}
683
684bool BitVectorUtils::bvIsMinSigned(const std::string &bv) {
685 condAssert(bv[0] == '#' && bv[1] == 'b',
686 "BitVectorUtils::bvIsMinSigned: invalid bitvector");
687 if (bv[2] != '1')
688 return false;
689 return std::all_of(bv.begin() + 3, bv.end(), [](char c) { return c == '0'; });
690}
691
692bool BitVectorUtils::bvIsMaxUnsigned(const std::string &bv) {
693 condAssert(bv[0] == '#' && bv[1] == 'b',
694 "BitVectorUtils::bvIsMaxUnsigned: invalid bitvector");
695 return std::all_of(bv.begin() + 2, bv.end(), [](char c) { return c == '1'; });
696}
697
698bool BitVectorUtils::bvIsNegOne(const std::string &bv) {
699 condAssert(bv[0] == '#' && bv[1] == 'b',
700 "BitVectorUtils::bvIsNegOne: invalid bitvector");
701 return std::all_of(bv.begin() + 2, bv.end(), [](char c) { return c == '1'; });
702}
703
704int BitVectorUtils::bvCompareToUint(const std::string &bv, const uint64_t &u) {
705 condAssert(bv[0] == '#' && bv[1] == 'b',
706 "BitVectorUtils::bvCompareToUint: invalid bitvector");
707 if (bv.size() > 64 + 2 && std::any_of(bv.begin() + 2, bv.end() - 64, [](char c) { return c == '1'; }))
708 return 1; // bv > u
709 else {
710 uint64_t bv_value = bvToNat(bv).toULong();
711 if (bv_value < u)
712 return -1; // bv < u
713 else if (bv_value > u)
714 return 1; // bv > u
715 else
716 return 0; // bv == u
717 }
718}
719
720std::string BitVectorUtils::mkOnes(const Integer &n) {
721 return "#b" + std::string(n.toULong(), '1');
722}
723
724Integer BitVectorUtils::bvToNat(const std::string &bv) {
725 condAssert(bv[0] == '#' && bv[1] == 'b',
726 "BitVectorUtils::bvToNat: invalid bitvector");
727 Integer res = 0;
728 for (size_t i = 2; i < bv.size(); i++) {
729 res = res * 2 + (bv[i] == '1' ? 1 : 0);
730 }
731 return res;
732}
733std::string BitVectorUtils::natToBv(const Integer &i, const Integer &n) {
734 std::string res = "#b";
735 std::string bin = i.toString(2);
736 if (bin.size() < n.toULong()) {
737 res += std::string(n.toULong() - bin.size(), '0') + bin;
738 }
739 else {
740 res += bin.substr(bin.size() - n.toULong(), n.toULong());
741 }
742 return res;
743}
744std::string hexToBv(const std::string &hex) {
745 std::string res = "#b";
746 for (size_t i = 0; i < hex.size(); i++) {
747 switch (hex[i]) {
748 case '0':
749 res += "0000";
750 break;
751 case '1':
752 res += "0001";
753 break;
754 case '2':
755 res += "0010";
756 break;
757 case '3':
758 res += "0011";
759 break;
760 case '4':
761 res += "0100";
762 break;
763 case '5':
764 res += "0101";
765 break;
766 case '6':
767 res += "0110";
768 break;
769 case '7':
770 res += "0111";
771 break;
772 case '8':
773 res += "1000";
774 break;
775 case '9':
776 res += "1001";
777 break;
778 case 'a':
779 res += "1010";
780 break;
781 case 'A':
782 res += "1010";
783 break;
784 case 'b':
785 res += "1011";
786 break;
787 case 'B':
788 res += "1011";
789 break;
790 case 'c':
791 res += "1100";
792 break;
793 case 'C':
794 res += "1100";
795 break;
796 case 'd':
797 res += "1101";
798 break;
799 case 'D':
800 res += "1101";
801 break;
802 case 'e':
803 res += "1110";
804 break;
805 case 'E':
806 res += "1110";
807 break;
808 case 'f':
809 res += "1111";
810 break;
811 case 'F':
812 res += "1111";
813 break;
814 default:
815 condAssert(false, "hexToBv: invalid hex character");
816 }
817 }
818 return res;
819}
820std::string decToBv(const std::string &dec) {
821 std::string res = "#b";
822 Integer i = Integer(dec);
823 std::string bin = i.toString(2);
824 return res + bin;
825}
826
827std::string BitVectorUtils::natToBv(const std::string &i, const Integer &n) {
828 if (i.size() > 2 && i[0] == '#' && i[1] == 'b') {
829 // zero-extend
830 std::string res = "#b";
831 std::string bin = i.substr(2, i.size() - 2);
832 if (bin.size() < n.toULong()) {
833 res += std::string(n.toULong() - bin.size(), '0') + bin;
834 }
835 else {
836 res += bin.substr(bin.size() - n.toULong(), n.toULong());
837 }
838 return res;
839 }
840 else if (i.size() > 2 && i[0] == '#' && i[1] == 'x') {
841 // #x -> #b
842 return hexToBv(i.substr(2, i.size() - 2));
843 }
844 else if (i.size() > 2 && i[0] == '#' && i[1] == 'd') {
845 // #d -> #b
846 return decToBv(i.substr(2, i.size() - 2));
847 }
848 else {
849 return BitVectorUtils::natToBv(Integer(i), n);
850 }
851}
852Integer BitVectorUtils::bvToInt(const std::string &bv) {
853 condAssert(bv[0] == '#' && bv[1] == 'b',
854 "BitVectorUtils::bvToInt: invalid bitvector");
855 if (bv[2] == '0') {
856 Integer res = 0;
857 for (size_t i = 3; i < bv.size(); i++) {
858 res = res * 2 + (bv[i] == '1' ? 1 : 0);
859 }
860 return res;
861 }
862 else {
863 Integer res = -1;
864 for (size_t i = 3; i < bv.size(); i++) {
865 res = res * 2 + (bv[i] == '0' ? 1 : 0);
866 }
867 return res;
868 }
869}
870std::string BitVectorUtils::intToBv(const Integer &i, const Integer &n) {
871 if (i >= 0) {
872 std::string res = "#b0";
873 std::string bin = i.toString(2);
874 if (bin.size() < n.toULong()) {
875 res += std::string(n.toULong() - bin.size(), '0') + bin;
876 }
877 else {
878 res += bin.substr(bin.size() - n.toULong(), n.toULong());
879 }
880 return res;
881 }
882 else {
883 std::string res = "#b1";
884 Integer j = -i;
885 std::string bin = j.toString(2);
886 if (bin.size() < n.toULong()) {
887 res += std::string(n.toULong() - bin.size(), '0') + bin;
888 }
889 else {
890 res += bin.substr(bin.size() - n.toULong(), n.toULong());
891 }
892 return res;
893 }
894}
895
896// TODO??
897std::string FloatingPointUtils::fpToUbv(const std::string &fp,
898 const Integer &n) {
899 condAssert(fp[0] == '#' && fp[1] == 'x',
900 "FloatingPointUtils::fpToUbv: invalid floating point");
901 std::string res = "";
902 bool isNeg = fp[2] == '1';
903 if (!isNeg) {
904 res = fp.substr(3, fp.size() - 3);
905 }
906 else {
907 res = fp.substr(3, fp.size() - 3);
908 }
909 if (res.size() < n.toULong() - 1) {
910 res = std::string(n.toULong() - res.size() - 1, '0') + res;
911 }
912 else {
913 res = res.substr(res.size() - n.toULong() + 1, n.toULong() - 1);
914 }
915 if (isNeg) {
916 res = "b1" + res;
917 }
918 else {
919 res = "b0" + res;
920 }
921 return res;
922}
923std::string FloatingPointUtils::fpToSbv(const std::string &fp,
924 const Integer &n) {
925 condAssert(fp[0] == '#' && fp[1] == 'x',
926 "FloatingPointUtils::fpToSbv: invalid floating point");
927 std::string res = "";
928 bool isNeg = fp[2] == '1';
929 if (!isNeg) {
930 res = fp.substr(3, fp.size() - 3);
931 }
932 else {
933 res = "b1" + fp.substr(3, fp.size() - 3);
934 }
935 if (res.size() < n.toULong() - 1) {
936 res = std::string(n.toULong() - res.size() - 1, '0') + res;
937 }
938 else {
939 res = res.substr(res.size() - n.toULong() + 1, n.toULong() - 1);
940 }
941 if (isNeg) {
942 res = "b1" + res;
943 }
944 else {
945 res = "b0" + res;
946 }
947 return res;
948}
949
950std::string StringUtils::strSubstr(const std::string &s, const Integer &i, const Integer &j) {
951 // remove the quotes
952 std::string s_clean = (s[0] == '"' && s[s.length() - 1] == '"')
953 ? s.substr(1, s.length() - 2)
954 : s;
955
956 // extract the substring
957 size_t start = i.toULong();
958 size_t length = j.toULong();
959
960 // ensure not out of range
961 if (start >= s_clean.length()) {
962 return "\"\"";
963 }
964 if (start + length > s_clean.length()) {
965 length = s_clean.length() - start;
966 }
967
968 std::string result = s_clean.substr(start, length);
969 return "\"" + result + "\"";
970}
971bool StringUtils::strPrefixof(const std::string &s, const std::string &t) {
972 std::string s_clean = (s[0] == '"' && s[s.length() - 1] == '"')
973 ? s.substr(1, s.length() - 2)
974 : s;
975 std::string t_clean = (t[0] == '"' && t[t.length() - 1] == '"')
976 ? t.substr(1, t.length() - 2)
977 : t;
978
979 // check if s is a prefix of t
980 if (s_clean.size() > t_clean.size())
981 return false;
982 return t_clean.substr(0, s_clean.size()) == s_clean;
983}
984bool StringUtils::strSuffixof(const std::string &s, const std::string &t) {
985 std::string s_clean = (s[0] == '"' && s[s.length() - 1] == '"')
986 ? s.substr(1, s.length() - 2)
987 : s;
988 std::string t_clean = (t[0] == '"' && t[t.length() - 1] == '"')
989 ? t.substr(1, t.length() - 2)
990 : t;
991
992 // check if s is a suffix of t
993 if (s_clean.size() > t_clean.size())
994 return false;
995 return t_clean.substr(t_clean.size() - s_clean.size(), s_clean.size()) ==
996 s_clean;
997}
998bool StringUtils::strContains(const std::string &s, const std::string &t) {
999 std::string s_clean = (s[0] == '"' && s[s.length() - 1] == '"')
1000 ? s.substr(1, s.length() - 2)
1001 : s;
1002 std::string t_clean = (t[0] == '"' && t[t.length() - 1] == '"')
1003 ? t.substr(1, t.length() - 2)
1004 : t;
1005 return s_clean.find(t_clean) != std::string::npos;
1006}
1007Integer StringUtils::strIndexof(const std::string &s, const std::string &t, const Integer &i) {
1008 // remove the quotes from the string
1009 std::string s_clean = (s[0] == '"' && s[s.length() - 1] == '"')
1010 ? s.substr(1, s.length() - 2)
1011 : s;
1012 std::string t_clean = (t[0] == '"' && t[t.length() - 1] == '"')
1013 ? t.substr(1, t.length() - 2)
1014 : t;
1015
1016 // if i is out of range, return -1
1017 if (i.toULong() > s_clean.length()) {
1018 return -1;
1019 }
1020
1021 size_t pos = s_clean.find(t_clean, i.toULong());
1022 return (pos == std::string::npos) ? Integer(-1) : Integer(pos);
1023}
1024std::string StringUtils::strCharAt(const std::string &s, const Integer &i) {
1025 std::string s_clean = (s[0] == '"' && s[s.length() - 1] == '"')
1026 ? s.substr(1, s.length() - 2)
1027 : s;
1028 return "\"" + s_clean.substr(i.toULong(), 1) + "\"";
1029}
1030std::string StringUtils::strUpdate(const std::string &s, const Integer &i, const std::string &t) {
1031 std::string s_clean = (s[0] == '"' && s[s.length() - 1] == '"')
1032 ? s.substr(1, s.length() - 2)
1033 : s;
1034 std::string t_clean = (t[0] == '"' && t[t.length() - 1] == '"')
1035 ? t.substr(1, t.length() - 2)
1036 : t;
1037 return "\"" + s_clean.substr(0, i.toULong()) + t_clean +
1038 s_clean.substr(i.toULong() + t_clean.size(),
1039 s_clean.size() - i.toULong() - t_clean.size()) +
1040 "\"";
1041}
1042std::string StringUtils::strReplace(const std::string &s, const std::string &t, const std::string &u) {
1043 // remove the quotes from the string
1044 std::string s_clean = (s[0] == '"' && s[s.length() - 1] == '"')
1045 ? s.substr(1, s.length() - 2)
1046 : s;
1047 std::string t_clean = (t[0] == '"' && t[t.length() - 1] == '"')
1048 ? t.substr(1, t.length() - 2)
1049 : t;
1050 std::string u_clean = (u[0] == '"' && u[u.length() - 1] == '"')
1051 ? u.substr(1, u.length() - 2)
1052 : u;
1053
1054 size_t pos = s_clean.find(t_clean);
1055 if (pos == std::string::npos)
1056 return s;
1057 std::string result =
1058 s_clean.substr(0, pos) + u_clean + s_clean.substr(pos + t_clean.length());
1059 // add the quotes and return
1060 return "\"" + result + "\"";
1061}
1062std::string StringUtils::strReplaceAll(const std::string &s,
1063 const std::string &t,
1064 const std::string &u) {
1065 // remove the quotes from the string
1066 std::string s_clean = (s[0] == '"' && s[s.length() - 1] == '"')
1067 ? s.substr(1, s.length() - 2)
1068 : s;
1069 std::string t_clean = (t[0] == '"' && t[t.length() - 1] == '"')
1070 ? t.substr(1, t.length() - 2)
1071 : t;
1072 std::string u_clean = (u[0] == '"' && u[u.length() - 1] == '"')
1073 ? u.substr(1, u.length() - 2)
1074 : u;
1075
1076 std::string res = s_clean;
1077 size_t pos = res.find(t_clean);
1078 while (pos != std::string::npos) {
1079 res = res.substr(0, pos) + u_clean + res.substr(pos + t_clean.length());
1080 pos = res.find(t_clean, pos + u_clean.size());
1081 }
1082 // add the quotes and return
1083 return "\"" + res + "\"";
1084}
1085std::string StringUtils::strToLower(const std::string &s) {
1086 std::string res = (s[0] == '"' && s[s.length() - 1] == '"')
1087 ? s.substr(1, s.length() - 2)
1088 : s;
1089 for (char &c : res) {
1090 c = tolower(c);
1091 }
1092 return "\"" + res + "\"";
1093}
1094std::string StringUtils::strToUpper(const std::string &s) {
1095 std::string res = (s[0] == '"' && s[s.length() - 1] == '"')
1096 ? s.substr(1, s.length() - 2)
1097 : s;
1098 for (char &c : res) {
1099 c = toupper(c);
1100 }
1101 return "\"" + res + "\"";
1102}
1103std::string StringUtils::strRev(const std::string &s) {
1104 std::string res = (s[0] == '"' && s[s.length() - 1] == '"')
1105 ? s.substr(1, s.length() - 2)
1106 : s;
1107 return "\"" + std::string(res.rbegin(), res.rend()) + "\"";
1108}
1109
1110// toString
1111std::string ConversionUtils::toString(const Integer &i) { return i.toString(); }
1112std::string ConversionUtils::toString(const Real &r) { return r.toString(); }
1113std::string ConversionUtils::toString(const int &i) {
1114 return std::to_string(i);
1115}
1116std::string ConversionUtils::toString(const double &d) {
1117 return std::to_string(d);
1118}
1119std::string ConversionUtils::toString(const float &f) {
1120 return std::to_string(f);
1121}
1122std::string ConversionUtils::toString(const long &l) {
1123 return std::to_string(l);
1124}
1125std::string ConversionUtils::toString(const short &s) {
1126 return std::to_string(s);
1127}
1128std::string ConversionUtils::toString(const char &c) {
1129 return std::string(1, c);
1130}
1131std::string ConversionUtils::toString(const bool &b) {
1132 return b ? "true" : "false";
1133}
1134
1135std::string ConversionUtils::escapeString(const std::string &s) {
1136 std::string result = "";
1137 for (char c : s) {
1138 switch (c) {
1139 case '\n': // newline
1140 result += "\\n";
1141 break;
1142 case '\t': // tab
1143 result += "\\t";
1144 break;
1145 case '\r': // carriage return
1146 result += "\\r";
1147 break;
1148 case '\\': // backslash
1149 result += "\\\\";
1150 break;
1151 case '"': // double quote
1152 result += "\\\"";
1153 break;
1154 case '\'': // single quote
1155 result += "\\'";
1156 break;
1157 case '\0': // null character
1158 result += "\\0";
1159 break;
1160 case '\a': // alert
1161 result += "\\a";
1162 break;
1163 case '\b': // backspace
1164 result += "\\b";
1165 break;
1166 case '\f': // form feed
1167 result += "\\f";
1168 break;
1169 case '\v': // vertical tab
1170 result += "\\v";
1171 break;
1172 default:
1173 // for non-printable characters, use hexadecimal escape
1174 if (c < 32 || c > 126) {
1175 std::ostringstream oss;
1176 oss << "\\x" << std::hex << std::setfill('0') << std::setw(2)
1177 << (unsigned char)c;
1178 result += oss.str();
1179 }
1180 else {
1181 result += c;
1182 }
1183 break;
1184 }
1185 }
1186 return result;
1187}
1188
1189std::string ConversionUtils::unescapeString(const std::string &s) {
1190 std::string result = "";
1191 size_t i = 0;
1192 while (i < s.length()) {
1193 if (s[i] == '\\' && i + 1 < s.length()) {
1194 switch (s[i + 1]) {
1195 case 'n': // newline
1196 result += '\n';
1197 break;
1198 case 't': // tab
1199 result += '\t';
1200 break;
1201 case 'r': // carriage return
1202 result += '\r';
1203 break;
1204 case '\\': // backslash
1205 result += '\\';
1206 break;
1207 case '"': // double quote
1208 result += '"';
1209 break;
1210 case '\'': // single quote
1211 result += '\'';
1212 break;
1213 case '0': // null character
1214 result += '\0';
1215 break;
1216 case 'a': // alert
1217 result += '\a';
1218 break;
1219 case 'b': // backspace
1220 result += '\b';
1221 break;
1222 case 'f': // form feed
1223 result += '\f';
1224 break;
1225 case 'v': // vertical tab
1226 result += '\v';
1227 break;
1228 case 'x': // hexadecimal escape \xHH
1229 if (i + 3 < s.length()) {
1230 std::string hexStr = s.substr(i + 2, 2);
1231 try {
1232 unsigned char value =
1233 static_cast<unsigned char>(std::stoi(hexStr, nullptr, 16));
1234 result += value;
1235 i += 2; // skip two hexadecimal characters
1236 }
1237 catch (...) {
1238 // if hexadecimal parsing fails, keep the original character
1239 result += s[i];
1240 i--; // back one character, because i+=2 later
1241 }
1242 }
1243 else {
1244 // incomplete hexadecimal escape, keep the original character
1245 result += s[i];
1246 i--; // back one character, because i+=2 later
1247 }
1248 break;
1249 default:
1250 // if not a known escape character, keep the backslash and character
1251 result += s[i];
1252 result += s[i + 1];
1253 break;
1254 }
1255 i += 2; // skip the escape character and the next character
1256 }
1257 else {
1258 result += s[i]; // if the current character is not an escape character,
1259 // add it directly
1260 i++;
1261 }
1262 }
1263 return result;
1264}
1265} // namespace stabilizer::parser
#define condAssert(cond, msg)
Definition asserting.h:35
static std::string bvNand(const std::string &bv1, const std::string &bv2)
Definition util.cpp:390
static bool bvComp(const std::string &bv1, const std::string &bv2, const NODE_KIND &kind)
Definition util.cpp:637
static std::string bvUdiv(const std::string &bv1, const std::string &bv2)
Definition util.cpp:472
static std::string bvExtract(const std::string &bv, const Integer &i, const Integer &j)
Definition util.cpp:585
static std::string bvSub(const std::string &bv1, const std::string &bv2)
Definition util.cpp:447
static std::string bvUmod(const std::string &bv1, const std::string &bv2)
Definition util.cpp:495
static std::string bvZeroExtend(const std::string &bv, const Integer &n)
Definition util.cpp:608
static std::string bvSdiv(const std::string &bv1, const std::string &bv2)
Definition util.cpp:504
static int bvCompareToUint(const std::string &bv, const uint64_t &u)
Definition util.cpp:704
static std::string bvShl(const std::string &bv, const std::string &n)
Definition util.cpp:541
static std::string bvLshr(const std::string &bv, const std::string &n)
Definition util.cpp:552
static bool bvIsMaxUnsigned(const std::string &bv)
Definition util.cpp:692
static std::string bvConcat(const std::string &bv1, const std::string &bv2)
Definition util.cpp:577
static std::string bvXor(const std::string &bv1, const std::string &bv2)
Definition util.cpp:378
static std::string bvRotateLeft(const std::string &bv, const Integer &n)
Definition util.cpp:621
static std::string bvNot(const std::string &bv)
Definition util.cpp:345
static bool bvIsMaxSigned(const std::string &bv)
Definition util.cpp:676
static Integer bvToNat(const std::string &bv)
Definition util.cpp:724
static std::string natToBv(const Integer &i, const Integer &n)
Definition util.cpp:733
static std::string bvSignExtend(const std::string &bv, const Integer &n)
Definition util.cpp:614
static std::string bvSrem(const std::string &bv1, const std::string &bv2)
Definition util.cpp:516
static Integer bvToInt(const std::string &bv)
Definition util.cpp:852
static std::string bvRotateRight(const std::string &bv, const Integer &n)
Definition util.cpp:628
static bool bvIsNegOne(const std::string &bv)
Definition util.cpp:698
static std::string bvXnor(const std::string &bv1, const std::string &bv2)
Definition util.cpp:414
static std::string bvOr(const std::string &bv1, const std::string &bv2)
Definition util.cpp:366
static std::string bvUrem(const std::string &bv1, const std::string &bv2)
Definition util.cpp:484
static std::string mkOnes(const Integer &n)
Definition util.cpp:720
static std::string bvNeg(const std::string &bv)
Definition util.cpp:427
static std::string bvSmod(const std::string &bv1, const std::string &bv2)
Definition util.cpp:528
static std::string bvAshr(const std::string &bv, const std::string &n)
Definition util.cpp:564
static std::string bvNor(const std::string &bv1, const std::string &bv2)
Definition util.cpp:402
static bool bvIsMinSigned(const std::string &bv)
Definition util.cpp:684
static std::string bvAnd(const std::string &bv1, const std::string &bv2)
Definition util.cpp:354
static std::string bvRepeat(const std::string &bv, const Integer &n)
Definition util.cpp:599
static std::string intToBv(const Integer &i, const Integer &n)
Definition util.cpp:870
static std::string bvAdd(const std::string &bv1, const std::string &bv2)
Definition util.cpp:435
static std::string bvMul(const std::string &bv1, const std::string &bv2)
Definition util.cpp:459
static std::string toString(const Integer &i)
Definition util.cpp:1111
static std::string parseScientificNotation(const std::string &str)
Definition util.cpp:148
static std::string unescapeString(const std::string &s)
Definition util.cpp:1189
static std::string escapeString(const std::string &s)
Definition util.cpp:1135
static std::string fpToSbv(const std::string &fp, const Integer &n)
Definition util.cpp:923
static std::string fpToUbv(const std::string &fp, const Integer &n)
Definition util.cpp:897
std::string toString(int base=10) const
Definition number.cpp:1026
HighPrecisionReal sqrt() const
Definition number.cpp:291
HighPrecisionReal ceil() const
Definition number.cpp:315
HighPrecisionReal floor() const
Definition number.cpp:321
HighPrecisionReal pow(const HighPrecisionReal &exp) const
Definition number.cpp:307
HighPrecisionReal round() const
Definition number.cpp:327
static Real safeSqrt(const Integer &i)
Definition util.cpp:301
static Real sqrt(const Integer &i)
Definition util.cpp:288
static bool isEven(const Integer &n)
Definition util.cpp:333
static Integer lcm(const Integer &a, const Integer &b)
Definition util.cpp:284
static Integer pow(const Integer &base, const Integer &exp)
Definition util.cpp:267
static Integer factorial(const Integer &n)
Definition util.cpp:337
static Integer round(const Real &r)
Definition util.cpp:317
static bool isPrime(const Integer &n)
Definition util.cpp:319
static Integer gcd(const Integer &a, const Integer &b)
Definition util.cpp:278
static bool isOdd(const Integer &n)
Definition util.cpp:335
static Integer floor(const Real &r)
Definition util.cpp:316
static Integer ceil(const Real &r)
Definition util.cpp:315
static std::string strToUpper(const std::string &s)
Definition util.cpp:1094
static std::string strCharAt(const std::string &s, const Integer &i)
Definition util.cpp:1024
static bool strSuffixof(const std::string &s, const std::string &t)
Definition util.cpp:984
static std::string strReplaceAll(const std::string &s, const std::string &t, const std::string &u)
Definition util.cpp:1062
static Integer strIndexof(const std::string &s, const std::string &t, const Integer &i)
Definition util.cpp:1007
static std::string strSubstr(const std::string &s, const Integer &i, const Integer &j)
Definition util.cpp:950
static std::string strReplace(const std::string &s, const std::string &t, const std::string &u)
Definition util.cpp:1042
static bool strContains(const std::string &s, const std::string &t)
Definition util.cpp:998
static std::string strToLower(const std::string &s)
Definition util.cpp:1085
static std::string strUpdate(const std::string &s, const Integer &i, const std::string &t)
Definition util.cpp:1030
static bool strPrefixof(const std::string &s, const std::string &t)
Definition util.cpp:971
static std::string strRev(const std::string &s)
Definition util.cpp:1103
static bool isReal(const std::string &str)
Definition util.cpp:58
static bool isScientificNotation(const std::string &str)
Definition util.cpp:75
static bool isFP(const std::string &str)
Definition util.cpp:248
static bool isString(const std::string &str)
Definition util.cpp:259
static bool isInt(const std::string &str)
Definition util.cpp:47
static bool isBV(const std::string &str)
Definition util.cpp:219
static bool isNumber(const std::string &str)
Definition util.cpp:43
BitVector & ibvsrem(const BitVector &bv0, const BitVector &bv1)
BitVector & ibvsub(const BitVector &bv0, const BitVector &bv1)
BitVector & ibvsmod(const BitVector &bv0, const BitVector &bv1)
BitVector & ibvudiv(const BitVector &bv0, const BitVector &bv1)
BitVector & ibvashr(const BitVector &bv, uint64_t shift)
std::string str(uint32_t base=2) const
BitVector & ibvadd(const BitVector &bv0, const BitVector &bv1)
BitVector & ibvneg(const BitVector &bv)
BitVector & ibvsdiv(const BitVector &bv0, const BitVector &bv1)
BitVector & ibvshr(const BitVector &bv, uint64_t shift)
BitVector & ibvurem(const BitVector &bv0, const BitVector &bv1)
BitVector & ibvshl(const BitVector &bv, uint64_t shift)
BitVector & ibvmul(const BitVector &bv0, const BitVector &bv1)
HighPrecisionInteger Integer
Definition number.h:136
HighPrecisionReal Real
Definition number.h:270
std::string decToBv(const std::string &dec)
Definition util.cpp:820
std::string hexToBv(const std::string &hex)
Definition util.cpp:744