Skip to content

Commit 272fd5c

Browse files
author
Daniel Kroening
committed
added means to perform bit-wise operations on the bit-vector representation
1 parent ec8b34d commit 272fd5c

File tree

3 files changed

+56
-27
lines changed

3 files changed

+56
-27
lines changed

src/util/arith_tools.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,35 @@ void mp_max(mp_integer &a, const mp_integer &b)
262262
if(b>a)
263263
a=b;
264264
}
265+
266+
/// perform a binary bit-wise operation, given as a functor,
267+
/// on a bit-vector representation
268+
/// \param f: the functor
269+
irep_idt bitvector_bitwise_op(
270+
const irep_idt &a,
271+
const irep_idt &b,
272+
const std::function<bool(bool, bool)> f)
273+
{
274+
PRECONDITION(a.size() == b.size());
275+
276+
std::string result(a.size(), ' ');
277+
278+
for(std::size_t i = 0; i < result.size(); i++)
279+
{
280+
const bool bit_a = a[i] == '1';
281+
const bool bit_b = b[i] == '1';
282+
const bool bit_result = f(bit_a, bit_b);
283+
result[i] = bit_result ? '1' : '0';
284+
}
285+
286+
return result;
287+
}
288+
289+
/// perform a unary bit-wise operation, given as a functor,
290+
/// on a bit-vector representation
291+
/// \param f: the functor
292+
irep_idt
293+
bitvector_bitwise_op(const irep_idt &a, const std::function<bool(bool)> f)
294+
{
295+
return bitvector_bitwise_op(a, a, [f](bool a, bool) { return f(a); });
296+
}

src/util/arith_tools.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,15 @@ mp_integer power(const mp_integer &base, const mp_integer &exponent);
164164
void mp_min(mp_integer &a, const mp_integer &b);
165165
void mp_max(mp_integer &a, const mp_integer &b);
166166

167+
/// perform a binary bit-wise operation, given as a functor,
168+
/// on a bit-vector representation
169+
irep_idt bitvector_bitwise_op(
170+
const irep_idt &,
171+
const irep_idt &,
172+
std::function<bool(bool, bool)>);
173+
174+
/// perform a unnary bit-wise operation, given as a functor,
175+
/// on a bit-vector representation
176+
irep_idt bitvector_bitwise_op(const irep_idt &, std::function<bool(bool)>);
177+
167178
#endif // CPROVER_UTIL_ARITH_TOOLS_H

src/util/simplify_expr_int.cpp

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -717,9 +717,6 @@ bool simplify_exprt::simplify_bitwise(exprt &expr)
717717

718718
while(expr.operands().size()>=2)
719719
{
720-
const irep_idt &a_str=expr.op0().get(ID_value);
721-
const irep_idt &b_str=expr.op1().get(ID_value);
722-
723720
if(!expr.op0().is_constant())
724721
break;
725722

@@ -732,30 +729,21 @@ bool simplify_exprt::simplify_bitwise(exprt &expr)
732729
if(expr.op1().type()!=expr.type())
733730
break;
734731

735-
INVARIANT(
736-
a_str.size() == b_str.size(),
737-
"bitvectors of the same type have the same size");
732+
const auto &a_val = to_constant_expr(expr.op0()).get_value();
733+
const auto &b_val = to_constant_expr(expr.op1()).get_value();
738734

739-
std::string new_value;
740-
new_value.resize(width);
735+
std::function<bool(bool, bool)> f;
741736

742737
if(expr.id()==ID_bitand)
743-
{
744-
for(std::size_t i=0; i<width; i++)
745-
new_value[i]=(a_str[i]=='1' && b_str[i]=='1')?'1':'0';
746-
}
738+
f = [](bool a, bool b) { return a & b; };
747739
else if(expr.id()==ID_bitor)
748-
{
749-
for(std::size_t i=0; i<width; i++)
750-
new_value[i]=(a_str[i]=='1' || b_str[i]=='1')?'1':'0';
751-
}
740+
f = [](bool a, bool b) { return a | b; };
752741
else if(expr.id()==ID_bitxor)
753-
{
754-
for(std::size_t i=0; i<width; i++)
755-
new_value[i]=((a_str[i]=='1')!=(b_str[i]=='1'))?'1':'0';
756-
}
742+
f = [](bool a, bool b) { return a ^ b; };
757743
else
758-
break;
744+
UNREACHABLE;
745+
746+
const irep_idt new_value = bitvector_bitwise_op(a_val, b_val, f);
759747

760748
constant_exprt new_op(new_value, expr.type());
761749

@@ -1284,12 +1272,10 @@ bool simplify_exprt::simplify_bitnot(exprt &expr)
12841272
{
12851273
if(op.id()==ID_constant)
12861274
{
1287-
std::string value=op.get_string(ID_value);
1288-
1289-
for(auto &ch : value)
1290-
ch=(ch=='0')?'1':'0';
1291-
1292-
expr = constant_exprt(value, op.type());
1275+
const auto &value = to_constant_expr(op).get_value();
1276+
const auto new_value =
1277+
bitvector_bitwise_op(value, [](bool a) { return !a; });
1278+
expr = constant_exprt(new_value, op.type());
12931279
return false;
12941280
}
12951281
}

0 commit comments

Comments
 (0)