carl  24.04
Computer ARithmetic Library
BVValue.h
Go to the documentation of this file.
1 /**
2  * @file BVValue.h
3  * @author Andreas Krueger <andreas.krueger@rwth-aachen.de>
4  */
5 
6 #pragma once
7 
10 
11 #include <array>
12 #include <boost/dynamic_bitset.hpp>
13 #include <limits>
14 #include <memory>
15 
16 namespace carl {
17 class BVValue {
18 public:
19  using Base = boost::dynamic_bitset<uint>;
20 
21 private:
23 
24  template<std::size_t len>
25  explicit BVValue(const std::array<uint, len>& a)
26  : mValue(a.begin(), a.end()) {}
27 
28 public:
29  BVValue() = default;
30 
31  explicit BVValue(Base&& value)
32  : mValue(std::move(value)) {}
33 
34  explicit BVValue(std::size_t _width, uint _value = 0)
35  : BVValue(std::array<uint, 1>({{_value}})) {
36  mValue.resize(_width);
37  }
38 #ifdef USE_CLN_NUMBERS
39  explicit BVValue(std::size_t _width, const cln::cl_I& _value)
40  : mValue(_width) {
41  for (std::size_t i = 0; i < _width; ++i) {
42  mValue[i] = cln::logbitp(i, _value);
43  }
44  }
45 #endif
46  BVValue(std::size_t _width, const mpz_class& _value);
47 
48  template<typename BlockInputIterator>
49  explicit BVValue(BlockInputIterator _first, BlockInputIterator _last)
50  : mValue(_first, _last) {
51  }
52 
53  template<typename Char, typename Traits, typename Alloc>
54  explicit BVValue(const std::basic_string<Char, Traits, Alloc>& _s,
55  typename std::basic_string<Char, Traits, Alloc>::size_type _pos = 0,
56  typename std::basic_string<Char, Traits, Alloc>::size_type _n = std::basic_string<Char, Traits, Alloc>::npos)
57  : mValue(_s, _pos, _n) {
58  }
59 
60  explicit operator const Base&() const {
61  return mValue;
62  }
63 
64  const Base& base() const {
65  return mValue;
66  }
67 
68  std::size_t width() const {
69  return mValue.size();
70  }
71 
72  std::string toString() const {
73  std::string output;
74  boost::to_string(mValue, output);
75  return "#b" + output;
76  }
77 
78  bool is_zero() const {
79  return mValue.none();
80  }
81 
82  BVValue rotateLeft(std::size_t _n) const {
83  Base lowerPart(mValue);
84  Base upperPart(mValue);
85 
86  lowerPart <<= _n % width();
87  upperPart >>= width() - (_n % width());
88 
89  return BVValue(lowerPart ^ upperPart);
90  }
91 
92  BVValue rotateRight(std::size_t _n) const {
93  return rotateLeft(width() - (_n % width()));
94  }
95 
96  BVValue repeat(std::size_t _n) const {
97  assert(_n > 0);
98  BVValue repeated(_n * width());
99  // Todo: Implement with shifts instead of copying every single bit.
100  for (std::size_t i = 0; i < repeated.width(); ++i) {
101  repeated[i] = (*this)[i % width()];
102  }
103  return repeated;
104  }
105 
106  BVValue extendUnsignedBy(std::size_t _n) const {
107  Base copy(mValue);
108  copy.resize(width() + _n);
109  return BVValue(std::move(copy));
110  }
111 
112  BVValue extendSignedBy(std::size_t _n) const {
113  Base copy(mValue);
114  copy.resize(width() + _n, (*this)[width() - 1]);
115  return BVValue(std::move(copy));
116  }
117 
118  Base::reference operator[](std::size_t _index) {
119  assert(_index < width());
120  return mValue[_index];
121  }
122 
123  bool operator[](std::size_t _index) const {
124  assert(_index < width());
125  return mValue[_index];
126  }
127 
128  BVValue concat(const BVValue& _other) const;
129 
130  BVValue divideSigned(const BVValue& _other) const;
131 
132  BVValue remSigned(const BVValue& _other) const;
133 
134  BVValue modSigned(const BVValue& _other) const;
135 
136  BVValue rightShiftArithmetic(const BVValue& _other) const {
137  return shift(_other, false, true);
138  }
139 
140  BVValue extract(std::size_t _highest, std::size_t _lowest) const;
141 
142  BVValue shift(const BVValue& _other, bool _left, bool _arithmetic = false) const;
143 
144  BVValue divideUnsigned(const BVValue& _other, bool _returnRemainder = false) const;
145 };
146 
147 inline bool operator==(const BVValue& lhs, const BVValue& rhs) {
148  return lhs.base() == rhs.base();
149 }
150 
151 inline bool operator<(const BVValue& lhs, const BVValue& rhs) {
152  return lhs.base() < rhs.base();
153 }
154 
155 inline BVValue operator~(const BVValue& val) {
156  return BVValue(~val.base());
157 }
158 
159 BVValue operator+(const BVValue& lhs, const BVValue& rhs);
160 BVValue operator*(const BVValue& lhs, const BVValue& rhs);
161 
162 inline BVValue operator-(const BVValue& val) {
163  return ~val + BVValue(val.width(), 1);
164 }
165 
166 inline BVValue operator-(const BVValue& lhs, const BVValue& rhs) {
167  assert(lhs.width() == rhs.width());
168  return lhs + (-rhs);
169 }
170 
171 inline BVValue operator%(const BVValue& lhs, const BVValue& rhs) {
172  return lhs.divideUnsigned(rhs, true);
173 }
174 
175 inline BVValue operator/(const BVValue& lhs, const BVValue& rhs) {
176  return lhs.divideUnsigned(rhs);
177 }
178 
179 inline BVValue operator&(const BVValue& lhs, const BVValue& rhs) {
180  assert(lhs.width() == rhs.width());
181  return BVValue(lhs.base() & rhs.base());
182 }
183 
184 inline BVValue operator|(const BVValue& lhs, const BVValue& rhs) {
185  assert(lhs.width() == rhs.width());
186  return BVValue(lhs.base() | rhs.base());
187 }
188 
189 inline BVValue operator^(const BVValue& lhs, const BVValue& rhs) {
190  assert(lhs.width() == rhs.width());
191  return BVValue(lhs.base() ^ rhs.base());
192 }
193 
194 inline BVValue operator<<(const BVValue& lhs, const BVValue& rhs) {
195  return lhs.shift(rhs, true);
196 }
197 
198 inline BVValue operator>>(const BVValue& lhs, const BVValue& rhs) {
199  return lhs.shift(rhs, false, false);
200 }
201 
202 inline std::ostream& operator<<(std::ostream& os, const BVValue& val) {
203  return os << "#b" << static_cast<BVValue::Base>(val);
204 }
205 
206 } // namespace carl
207 
208 namespace std {
209 /**
210  * Implements std::hash for bit vector values.
211  */
212 template<>
213 struct hash<carl::BVValue> {
214  /**
215  * @param _value The bit vector value to get the hash for.
216  * @return The hash of the given bit vector value.
217  */
218  std::size_t operator()(const carl::BVValue& _value) const {
219  return std::hash<carl::BVValue::Base>()(static_cast<carl::BVValue::Base>(_value));
220  }
221 };
222 } // namespace std
carl is the main namespace for the library.
BVValue operator&(const BVValue &lhs, const BVValue &rhs)
Definition: BVValue.h:179
std::uint64_t uint
Definition: numbers.h:16
Interval< Number > operator/(const Interval< Number > &lhs, const Number &rhs)
Operator for the division of an interval and a number.
Definition: operators.h:453
Interval< Number > operator+(const Interval< Number > &lhs, const Interval< Number > &rhs)
Operator for the addition of two intervals.
Definition: operators.h:261
bool operator<(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
BVValue operator^(const BVValue &lhs, const BVValue &rhs)
Definition: BVValue.h:189
BitVector operator|(const BitVector &lhs, const BitVector &rhs)
Definition: BitVector.cpp:6
std::ostream & operator<<(std::ostream &os, const BasicConstraint< Poly > &c)
Prints the given constraint on the given stream.
Interval< Number > operator*(const Interval< Number > &lhs, const Interval< Number > &rhs)
Operator for the multiplication of two intervals.
Definition: operators.h:386
BVValue operator~(const BVValue &val)
Definition: BVValue.h:155
BVValue operator%(const BVValue &lhs, const BVValue &rhs)
Definition: BVValue.h:171
Interval< Number > operator-(const Interval< Number > &rhs)
Unary minus.
Definition: operators.h:318
bool operator==(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
BVValue operator>>(const BVValue &lhs, const BVValue &rhs)
Definition: BVValue.h:198
BVValue modSigned(const BVValue &_other) const
Definition: BVValue.cpp:90
BVValue extract(std::size_t _highest, std::size_t _lowest) const
Definition: BVValue.cpp:114
std::string toString() const
Definition: BVValue.h:72
BVValue concat(const BVValue &_other) const
Definition: BVValue.cpp:46
BVValue repeat(std::size_t _n) const
Definition: BVValue.h:96
BVValue divideUnsigned(const BVValue &_other, bool _returnRemainder=false) const
Definition: BVValue.cpp:158
BVValue(const std::array< uint, len > &a)
Definition: BVValue.h:25
std::size_t width() const
Definition: BVValue.h:68
BVValue rotateLeft(std::size_t _n) const
Definition: BVValue.h:82
BVValue(const std::basic_string< Char, Traits, Alloc > &_s, typename std::basic_string< Char, Traits, Alloc >::size_type _pos=0, typename std::basic_string< Char, Traits, Alloc >::size_type _n=std::basic_string< Char, Traits, Alloc >::npos)
Definition: BVValue.h:54
BVValue()=default
BVValue shift(const BVValue &_other, bool _left, bool _arithmetic=false) const
Definition: BVValue.cpp:125
BVValue rotateRight(std::size_t _n) const
Definition: BVValue.h:92
BVValue extendSignedBy(std::size_t _n) const
Definition: BVValue.h:112
boost::dynamic_bitset< uint > Base
Definition: BVValue.h:19
Base mValue
Definition: BVValue.h:22
BVValue extendUnsignedBy(std::size_t _n) const
Definition: BVValue.h:106
BVValue rightShiftArithmetic(const BVValue &_other) const
Definition: BVValue.h:136
BVValue(Base &&value)
Definition: BVValue.h:31
bool operator[](std::size_t _index) const
Definition: BVValue.h:123
bool is_zero() const
Definition: BVValue.h:78
const Base & base() const
Definition: BVValue.h:64
BVValue divideSigned(const BVValue &_other) const
Definition: BVValue.cpp:56
BVValue(std::size_t _width, uint _value=0)
Definition: BVValue.h:34
BVValue(BlockInputIterator _first, BlockInputIterator _last)
Definition: BVValue.h:49
BVValue remSigned(const BVValue &_other) const
Definition: BVValue.cpp:73
Base::reference operator[](std::size_t _index)
Definition: BVValue.h:118
std::size_t operator()(const carl::BVValue &_value) const
Definition: BVValue.h:218