SMTStabilizer API
Public API documentation for SMTStabilizer
Loading...
Searching...
No Matches
bitvector.h
Go to the documentation of this file.
1/***
2 * Bitwuzla: Satisfiability Modulo Theories (SMT) solver.
3 *
4 * Copyright (C) 2020 by the authors listed in the AUTHORS file at
5 * https://github.com/bitwuzla/bitwuzla/blob/main/AUTHORS
6 *
7 * This file is part of Bitwuzla under the MIT license. See COPYING for more
8 * information at https://github.com/bitwuzla/bitwuzla/blob/main/COPYING
9 */
10// Modified by Xiang Zhang, 2026
11// Additional changes licensed under the MIT License
12#ifndef BZLA__BV_BITVECTOR_H
13#define BZLA__BV_BITVECTOR_H
14
15#include <gmpxx.h>
16
17#include <cstdint>
18#include <functional>
19#include <string>
20
21namespace stabilizer::util {
22
23/* -------------------------------------------------------------------------- */
24
25/* -------------------------------------------------------------------------- */
26
27class BitVector {
28 public:
29 // mpz_*_ui functions have unsigned long (or mp_bitcnt_t) arguments, which is
30 // represented as 64 bit on Linux and macOS 64-bit systems. On 64-bit Windows
31 // unsigned long has a size of 32 bit, which affects the values stored in
32 // d_val_uint64 if being passed to a mpz_*_ui function.
33 // In order to avoid values being truncated, for Windows we store all values
34 // that require more than 32 bit as GMP integer. Else, we store values up to
35 // 64-bit in d_val_uint64.
36 static constexpr size_t s_native_size = sizeof(unsigned long) * 8;
37 static_assert(s_native_size == sizeof(mp_bitcnt_t) * 8, "");
38
47 static bool fits_in_size(uint64_t size, const std::string &str, uint32_t base);
55 static bool fits_in_size(uint64_t size, uint64_t value, bool sign = false);
56
63 static bool fits_in_size(uint64_t size, const mpz_t value);
64
81 static BitVector from_ui(uint64_t size, uint64_t value, bool truncate = false);
98 static BitVector from_si(uint64_t size, int64_t value, bool truncate = false);
99
104 static BitVector mk_true();
109 static BitVector mk_false();
140
148 static BitVector bvite(const BitVector &c, const BitVector &t, const BitVector &e);
149
151 BitVector();
157
166 BitVector(uint64_t size, const std::string &value, uint32_t base = 2);
167
177 BitVector(uint64_t size, const mpz_t value, bool truncate = false);
178
180 BitVector(const BitVector &other);
183
185 ~BitVector();
186
189
191 size_t hash() const;
192
194 bool is_null() const { return d_size == 0; }
195
200 void iset(uint64_t value);
206 void iset(const BitVector &bv);
207 // /**
208 // * Set the value of this bit-vector to a random value between `from` and
209 // `to`
210 // * (in-place).
211 // * @param rng The random number generator.
212 // * @param from A bit-vector representing the `from` value.
213 // * @param to A bit-vector representing the `to` value.
214 // */
215 // void iset(RNG& rng,
216 // const BitVector& from,
217 // const BitVector& to,
218 // bool is_signed);
219
224 bool operator==(const BitVector &bv) const;
229 bool operator!=(const BitVector &bv) const;
230
237 std::string str(uint32_t base = 2) const;
245 uint64_t to_uint64(bool truncate = false) const;
246
248 uint64_t size() const { return d_size; }
249
258 int32_t compare(const BitVector &bv) const;
267 int32_t signed_compare(const BitVector &bv) const;
268
274 bool bit(uint64_t idx) const;
280 void set_bit(uint64_t idx, bool value);
285 void flip_bit(uint64_t idx);
287 bool lsb() const;
289 bool msb() const;
290
292 bool is_true() const;
294 bool is_false() const;
296 bool is_zero() const;
298 bool is_ones() const;
300 bool is_one() const;
302 bool is_min_signed() const;
304 bool is_max_signed() const;
305
307 bool is_power_of_two() const;
308
313 bool is_neg_overflow() const;
320 bool is_uadd_overflow(const BitVector &bv) const;
327 bool is_sadd_overflow(const BitVector &bv) const;
334 bool is_usub_overflow(const BitVector &bv) const;
341 bool is_ssub_overflow(const BitVector &bv) const;
348 bool is_umul_overflow(const BitVector &bv) const;
355 bool is_smul_overflow(const BitVector &bv) const;
362 bool is_sdiv_overflow(const BitVector &bv) const;
363
372
373 /* ----------------------------------------------------------------------- */
374 /* Bit-vector operations. */
375 /* ----------------------------------------------------------------------- */
376
382 BitVector bvneg() const;
387 BitVector bvnot() const;
392 BitVector bvinc() const;
397 BitVector bvdec() const;
404 BitVector bvredand() const;
411 BitVector bvredor() const;
418 BitVector bvredxor() const;
425 BitVector bvnego() const;
426
433 BitVector bvadd(const BitVector &bv) const;
440 BitVector bvsub(const BitVector &bv) const;
447 BitVector bvand(const BitVector &bv) const;
454 BitVector bvimplies(const BitVector &bv) const;
461 BitVector bvnand(const BitVector &bv) const;
468 BitVector bvnor(const BitVector &bv) const;
475 BitVector bvor(const BitVector &bv) const;
482 BitVector bvxnor(const BitVector &bv) const;
489 BitVector bvxor(const BitVector &bv) const;
496 BitVector bveq(const BitVector &bv) const;
503 BitVector bvne(const BitVector &bv) const;
510 BitVector bvult(const BitVector &bv) const;
518 BitVector bvule(const BitVector &bv) const;
525 BitVector bvugt(const BitVector &bv) const;
533 BitVector bvuge(const BitVector &bv) const;
540 BitVector bvslt(const BitVector &bv) const;
548 BitVector bvsle(const BitVector &bv) const;
555 BitVector bvsgt(const BitVector &bv) const;
563 BitVector bvsge(const BitVector &bv) const;
579 BitVector bvshl(const BitVector &bv) const;
595 BitVector bvshr(const BitVector &bv) const;
611 BitVector bvashr(const BitVector &bv) const;
618 BitVector bvmul(const BitVector &bv) const;
625 BitVector bvudiv(const BitVector &bv) const;
632 BitVector bvurem(const BitVector &bv) const;
639 BitVector bvsdiv(const BitVector &bv) const;
646 BitVector bvsrem(const BitVector &bv) const;
653 BitVector bvsmod(const BitVector &bv) const;
654
661 BitVector bvuaddo(const BitVector &bv) const;
668 BitVector bvsaddo(const BitVector &bv) const;
675 BitVector bvusubo(const BitVector &bv) const;
682 BitVector bvssubo(const BitVector &bv) const;
683
690 BitVector bvumulo(const BitVector &bv) const;
697 BitVector bvsmulo(const BitVector &bv) const;
704 BitVector bvsdivo(const BitVector &bv) const;
705
713 BitVector bvconcat(const BitVector &bv) const;
714
723
730 BitVector bvzext(uint64_t n) const;
737 BitVector bvsext(uint64_t n) const;
738
745
751 BitVector bvroli(uint64_t n) const;
757 BitVector bvrol(const BitVector &n) const;
758
764 BitVector bvrori(uint64_t n) const;
770 BitVector bvror(const BitVector &n) const;
771
781 BitVector bvmodinv() const;
782
789 BitVector bvpow(const mpz_t exp) const;
790
791 /* ----------------------------------------------------------------------- */
792 /* In-place versions of bit-vector operations. */
793 /* */
794 /* Note: This bit-vector may not be null. */
795 /* */
796 /* Result is stored in this bit-vector. */
797 /* Return a reference to this bit-vector. */
798 /* ----------------------------------------------------------------------- */
799
809 BitVector &ibvneg(const BitVector &bv);
818 BitVector &ibvneg();
819
829 BitVector &ibvnot(const BitVector &bv);
838 BitVector &ibvnot();
839
849 BitVector &ibvinc(const BitVector &bv);
858 BitVector &ibvinc();
859
869 BitVector &ibvdec(const BitVector &bv);
878 BitVector &ibvdec();
879
907
935
963
976 BitVector &ibvnego(const BitVector &bv);
990
1001 BitVector &ibvadd(const BitVector &bv0, const BitVector &bv1);
1011 BitVector &ibvadd(const BitVector &bv);
1012
1023 BitVector &ibvand(const BitVector &bv0, const BitVector &bv1);
1033 BitVector &ibvand(const BitVector &bv);
1034
1045 BitVector &ibvimplies(const BitVector &bv0, const BitVector &bv1);
1056
1067 BitVector &ibvnand(const BitVector &bv0, const BitVector &bv1);
1077 BitVector &ibvnand(const BitVector &bv);
1078
1089 BitVector &ibvnor(const BitVector &bv0, const BitVector &bv1);
1099 BitVector &ibvnor(const BitVector &bv);
1100
1111 BitVector &ibvor(const BitVector &bv0, const BitVector &bv1);
1121 BitVector &ibvor(const BitVector &bv);
1122
1133 BitVector &ibvsub(const BitVector &bv0, const BitVector &bv1);
1143 BitVector &ibvsub(const BitVector &bv);
1144
1155 BitVector &ibvxnor(const BitVector &bv0, const BitVector &bv1);
1165 BitVector &ibvxnor(const BitVector &bv);
1166
1177 BitVector &ibvxor(const BitVector &bv0, const BitVector &bv1);
1187 BitVector &ibvxor(const BitVector &bv);
1188
1199 BitVector &ibveq(const BitVector &bv0, const BitVector &bv1);
1209 BitVector &ibveq(const BitVector &bv);
1210
1221 BitVector &ibvne(const BitVector &bv0, const BitVector &bv1);
1231 BitVector &ibvne(const BitVector &bv);
1232
1243 BitVector &ibvult(const BitVector &bv0, const BitVector &bv1);
1253 BitVector &ibvult(const BitVector &bv);
1254
1266 BitVector &ibvule(const BitVector &bv0, const BitVector &bv1);
1277 BitVector &ibvule(const BitVector &bv);
1278
1289 BitVector &ibvugt(const BitVector &bv0, const BitVector &bv1);
1300 BitVector &ibvugt(const BitVector &bv);
1301
1313 BitVector &ibvuge(const BitVector &bv0, const BitVector &bv1);
1324 BitVector &ibvuge(const BitVector &bv);
1325
1336 BitVector &ibvslt(const BitVector &bv0, const BitVector &bv1);
1346 BitVector &ibvslt(const BitVector &bv);
1347
1359 BitVector &ibvsle(const BitVector &bv0, const BitVector &bv1);
1370 BitVector &ibvsle(const BitVector &bv);
1371
1382 BitVector &ibvsgt(const BitVector &bv0, const BitVector &bv1);
1392 BitVector &ibvsgt(const BitVector &bv);
1393
1405 BitVector &ibvsge(const BitVector &bv0, const BitVector &bv1);
1416 BitVector &ibvsge(const BitVector &bv);
1417
1443
1455 BitVector &ibvshl(const BitVector &bv, const BitVector &shift);
1467 BitVector &ibvshl(const BitVector &bv);
1468
1494
1506 BitVector &ibvshr(const BitVector &bv, const BitVector &shift);
1518 BitVector &ibvshr(const BitVector &bv);
1519
1544
1568 BitVector &ibvashr(const BitVector &bv);
1569
1580 BitVector &ibvmul(const BitVector &bv0, const BitVector &bv1);
1590 BitVector &ibvmul(const BitVector &bv);
1591
1602 BitVector &ibvudiv(const BitVector &bv0, const BitVector &bv1);
1612 BitVector &ibvudiv(const BitVector &bv);
1613
1624 BitVector &ibvurem(const BitVector &bv0, const BitVector &bv1);
1634 BitVector &ibvurem(const BitVector &bv);
1635
1646 BitVector &ibvsdiv(const BitVector &bv0, const BitVector &bv1);
1656 BitVector &ibvsdiv(const BitVector &bv);
1657
1669 BitVector &ibvsrem(const BitVector &bv0, const BitVector &bv1);
1680 BitVector &ibvsrem(const BitVector &bv);
1681
1693 BitVector &ibvsmod(const BitVector &bv0, const BitVector &bv1);
1704 BitVector &ibvsmod(const BitVector &bv);
1705
1717 BitVector &ibvuaddo(const BitVector &bv0, const BitVector &bv1);
1728 BitVector &ibvuaddo(const BitVector &bv);
1729
1741 BitVector &ibvsaddo(const BitVector &bv0, const BitVector &bv1);
1752 BitVector &ibvsaddo(const BitVector &bv);
1753
1765 BitVector &ibvusubo(const BitVector &bv0, const BitVector &bv1);
1776 BitVector &ibvusubo(const BitVector &bv);
1777
1789 BitVector &ibvssubo(const BitVector &bv0, const BitVector &bv1);
1800 BitVector &ibvssubo(const BitVector &bv);
1801
1813 BitVector &ibvumulo(const BitVector &bv0, const BitVector &bv1);
1824 BitVector &ibvumulo(const BitVector &bv);
1825
1837 BitVector &ibvsmulo(const BitVector &bv0, const BitVector &bv1);
1848 BitVector &ibvsmulo(const BitVector &bv);
1849
1861 BitVector &ibvsdivo(const BitVector &bv0, const BitVector &bv1);
1872 BitVector &ibvsdivo(const BitVector &bv);
1873
1882 BitVector &ibvconcat(const BitVector &bv0, const BitVector &bv1);
1895
1919
1941
1963
1985
2007
2029
2040 BitVector &ibvrol(const BitVector &bv, const BitVector &n);
2050 BitVector &ibvrol(const BitVector &n);
2051
2062 BitVector &ibvror(const BitVector &bv, const BitVector &n);
2072 BitVector &ibvror(const BitVector &n);
2073
2084 BitVector &ibvite(const BitVector &c, const BitVector &t, const BitVector &e);
2085
2113
2121 BitVector &ibvpow(const BitVector &base, const mpz_t exp);
2122
2130 BitVector &ibvpow(const mpz_t exp);
2131
2142 void bvudivurem(const BitVector &bv, BitVector *quot, BitVector *rem) const;
2143
2145 const mpz_t &gmp_value() const;
2146
2148 mpz_class to_mpz() const;
2149
2150 private:
2167 uint64_t count_leading(bool zeros) const;
2173 bool shift_is_uint64(uint64_t *res) const;
2185 uint64_t get_limb(void *limb, uint64_t nbits_rem, bool zeros) const;
2186
2195 bool is_gmp() const { return d_size > s_native_size; }
2196
2208 union {
2211 };
2212};
2213
2214std::ostream &operator<<(std::ostream &out, const BitVector &bv);
2215
2216/* -------------------------------------------------------------------------- */
2217
2218} // namespace stabilizer::util
2219
2220/* -------------------------------------------------------------------------- */
2221
2222#endif
BitVector & ibvsext(const BitVector &bv, uint64_t n)
BitVector bvmodinv() const
static BitVector mk_min_signed(uint64_t size)
BitVector bvumulo(const BitVector &bv) const
BitVector & ibveq(const BitVector &bv0, const BitVector &bv1)
BitVector bvredor() const
BitVector bvshl(uint64_t shift) const
BitVector bvudiv(const BitVector &bv) const
BitVector & ibvpow(const BitVector &base, const mpz_t exp)
uint64_t to_uint64(bool truncate=false) const
BitVector & ibvsdivo(const BitVector &bv0, const BitVector &bv1)
BitVector & ibvule(const BitVector &bv0, const BitVector &bv1)
BitVector bvusubo(const BitVector &bv) const
BitVector bvand(const BitVector &bv) const
BitVector & ibvsrem(const BitVector &bv0, const BitVector &bv1)
BitVector bvroli(uint64_t n) const
BitVector bvnego() const
BitVector & ibvsub(const BitVector &bv0, const BitVector &bv1)
static BitVector mk_max_signed(uint64_t size)
BitVector bvslt(const BitVector &bv) const
uint64_t count_leading_ones() const
BitVector & ibvult(const BitVector &bv0, const BitVector &bv1)
static BitVector mk_one(uint64_t size)
BitVector & ibvsgt(const BitVector &bv0, const BitVector &bv1)
BitVector & ibvsmod(const BitVector &bv0, const BitVector &bv1)
BitVector & ibvuaddo(const BitVector &bv0, const BitVector &bv1)
BitVector bvextract(uint64_t idx_hi, uint64_t idx_lo) const
BitVector bvshr(uint64_t shift) const
BitVector & ibvzext(const BitVector &bv, uint64_t n)
BitVector bvredand() const
static BitVector from_si(uint64_t size, int64_t value, bool truncate=false)
static uint64_t uint64_fdiv_r_2exp(uint64_t size, uint64_t val)
uint64_t count_trailing_zeros() const
uint64_t count_trailing_ones() const
BitVector bvashr(uint64_t shift) const
bool operator!=(const BitVector &bv) const
BitVector bvsle(const BitVector &bv) const
BitVector & ibvrori(const BitVector &bv, uint64_t n)
BitVector bveq(const BitVector &bv) const
BitVector & ibvxor(const BitVector &bv0, const BitVector &bv1)
BitVector bvinc() const
BitVector bvsub(const BitVector &bv) const
BitVector bvnand(const BitVector &bv) const
BitVector & operator=(const BitVector &other)
bool is_sadd_overflow(const BitVector &bv) const
bool is_uadd_overflow(const BitVector &bv) const
BitVector & ibvnand(const BitVector &bv0, const BitVector &bv1)
static BitVector mk_ones(uint64_t size)
BitVector & ibvite(const BitVector &c, const BitVector &t, const BitVector &e)
BitVector & ibvudiv(const BitVector &bv0, const BitVector &bv1)
BitVector bvsaddo(const BitVector &bv) const
BitVector bvsdiv(const BitVector &bv) const
BitVector & ibvxnor(const BitVector &bv0, const BitVector &bv1)
BitVector bvrori(uint64_t n) const
BitVector bvconcat(const BitVector &bv) const
BitVector & ibvor(const BitVector &bv0, const BitVector &bv1)
BitVector bvule(const BitVector &bv) const
void flip_bit(uint64_t idx)
BitVector bvsext(uint64_t n) const
static BitVector mk_false()
BitVector bvurem(const BitVector &bv) const
bool is_sdiv_overflow(const BitVector &bv) const
void set_bit(uint64_t idx, bool value)
BitVector bvuge(const BitVector &bv) const
bool is_smul_overflow(const BitVector &bv) const
uint64_t get_limb(void *limb, uint64_t nbits_rem, bool zeros) const
uint64_t count_leading_zeros() const
BitVector bvsdivo(const BitVector &bv) const
BitVector & ibvuge(const BitVector &bv0, const BitVector &bv1)
BitVector & ibvextract(const BitVector &bv, uint64_t idx_hi, uint64_t idx_lo)
BitVector & ibvashr(const BitVector &bv, uint64_t shift)
BitVector & ibvsge(const BitVector &bv0, const BitVector &bv1)
static BitVector mk_zero(uint64_t size)
BitVector bvpow(const mpz_t exp) const
BitVector bvzext(uint64_t n) const
BitVector bvneg() const
BitVector & ibvnor(const BitVector &bv0, const BitVector &bv1)
BitVector bvdec() const
BitVector bvor(const BitVector &bv) const
void bvudivurem(const BitVector &bv, BitVector *quot, BitVector *rem) const
BitVector bvmul(const BitVector &bv) const
BitVector bvrol(const BitVector &n) const
std::string str(uint32_t base=2) const
BitVector & ibvumulo(const BitVector &bv0, const BitVector &bv1)
BitVector bvnot() const
int32_t compare(const BitVector &bv) const
uint64_t count_leading(bool zeros) const
BitVector bvssubo(const BitVector &bv) const
BitVector bvxnor(const BitVector &bv) const
static BitVector mk_true()
BitVector bvsge(const BitVector &bv) const
BitVector & ibvsaddo(const BitVector &bv0, const BitVector &bv1)
BitVector & ibvadd(const BitVector &bv0, const BitVector &bv1)
BitVector & ibvsle(const BitVector &bv0, const BitVector &bv1)
BitVector bvnor(const BitVector &bv) const
static BitVector from_ui(uint64_t size, uint64_t value, bool truncate=false)
BitVector bvrepeat(uint64_t n) const
BitVector bvuaddo(const BitVector &bv) const
bool operator==(const BitVector &bv) const
BitVector bvsmulo(const BitVector &bv) const
BitVector bvredxor() const
BitVector & ibvrepeat(const BitVector &bv, uint64_t n)
BitVector & ibvugt(const BitVector &bv0, const BitVector &bv1)
BitVector bvsmod(const BitVector &bv) const
void iset(uint64_t value)
BitVector & ibvsdiv(const BitVector &bv0, const BitVector &bv1)
BitVector & ibvshr(const BitVector &bv, uint64_t shift)
BitVector & ibvslt(const BitVector &bv0, const BitVector &bv1)
BitVector bvadd(const BitVector &bv) const
BitVector & ibvroli(const BitVector &bv, uint64_t n)
BitVector & ibvimplies(const BitVector &bv0, const BitVector &bv1)
BitVector bvugt(const BitVector &bv) const
BitVector & ibvand(const BitVector &bv0, const BitVector &bv1)
BitVector & ibvrol(const BitVector &bv, const BitVector &n)
BitVector & ibvror(const BitVector &bv, const BitVector &n)
BitVector & ibvconcat(const BitVector &bv0, const BitVector &bv1)
BitVector bvimplies(const BitVector &bv) const
BitVector bvsrem(const BitVector &bv) const
bool shift_is_uint64(uint64_t *res) const
bool is_usub_overflow(const BitVector &bv) const
BitVector & ibvsmulo(const BitVector &bv0, const BitVector &bv1)
BitVector bvsgt(const BitVector &bv) const
BitVector bvxor(const BitVector &bv) const
static BitVector bvite(const BitVector &c, const BitVector &t, const BitVector &e)
BitVector bvult(const BitVector &bv) const
BitVector & ibvurem(const BitVector &bv0, const BitVector &bv1)
static constexpr size_t s_native_size
Definition bitvector.h:36
BitVector & ibvssubo(const BitVector &bv0, const BitVector &bv1)
bool is_ssub_overflow(const BitVector &bv) const
BitVector & ibvne(const BitVector &bv0, const BitVector &bv1)
BitVector & ibvusubo(const BitVector &bv0, const BitVector &bv1)
static bool fits_in_size(uint64_t size, const std::string &str, uint32_t base)
Definition bitvector.cpp:73
const mpz_t & gmp_value() const
int32_t signed_compare(const BitVector &bv) const
BitVector bvror(const BitVector &n) const
uint64_t size() const
Definition bitvector.h:248
BitVector & ibvshl(const BitVector &bv, uint64_t shift)
BitVector bvne(const BitVector &bv) const
BitVector & ibvmul(const BitVector &bv0, const BitVector &bv1)
bool bit(uint64_t idx) const
bool is_umul_overflow(const BitVector &bv) const
std::ostream & operator<<(std::ostream &out, const BitVector &bv)