Skip to content

Commit ce40fbd

Browse files
authored
Merge pull request #8508 from diffblue/smt-bv
SMT2: bvnor, bvnand are binary only; add bvxnor
2 parents 436ed5d + 99376ab commit ce40fbd

File tree

2 files changed

+60
-7
lines changed

2 files changed

+60
-7
lines changed

Diff for: src/solvers/smt2/smt2_conv.cpp

+57-6
Original file line numberDiff line numberDiff line change
@@ -1220,12 +1220,9 @@ void smt2_convt::convert_expr(const exprt &expr)
12201220

12211221
convert_expr(expr.operands().front());
12221222
}
1223-
else if(expr.id()==ID_concatenation ||
1224-
expr.id()==ID_bitand ||
1225-
expr.id()==ID_bitor ||
1226-
expr.id()==ID_bitxor ||
1227-
expr.id()==ID_bitnand ||
1228-
expr.id()==ID_bitnor)
1223+
else if(
1224+
expr.id() == ID_concatenation || expr.id() == ID_bitand ||
1225+
expr.id() == ID_bitor || expr.id() == ID_bitxor)
12291226
{
12301227
DATA_INVARIANT_WITH_DIAGNOSTICS(
12311228
expr.operands().size() >= 2,
@@ -1255,6 +1252,60 @@ void smt2_convt::convert_expr(const exprt &expr)
12551252

12561253
out << ")";
12571254
}
1255+
else if(
1256+
expr.id() == ID_bitxnor || expr.id() == ID_bitnand ||
1257+
expr.id() == ID_bitnor)
1258+
{
1259+
// SMT-LIB only has these as a binary expression,
1260+
// owing to their ambiguity.
1261+
if(expr.operands().size() == 2)
1262+
{
1263+
const auto &binary_expr = to_binary_expr(expr);
1264+
1265+
out << '(';
1266+
if(binary_expr.id() == ID_bitxnor)
1267+
out << "bvxnor";
1268+
else if(binary_expr.id() == ID_bitnand)
1269+
out << "bvnand";
1270+
else if(binary_expr.id() == ID_bitnor)
1271+
out << "bvnor";
1272+
out << ' ';
1273+
flatten2bv(binary_expr.op0());
1274+
out << ' ';
1275+
flatten2bv(binary_expr.op1());
1276+
out << ')';
1277+
}
1278+
else if(expr.operands().size() == 1)
1279+
{
1280+
out << "(bvnot ";
1281+
flatten2bv(to_unary_expr(expr).op());
1282+
out << ')';
1283+
}
1284+
else if(expr.operands().size() >= 3)
1285+
{
1286+
out << "(bvnot (";
1287+
if(expr.id() == ID_bitxnor)
1288+
out << "bvxor";
1289+
else if(expr.id() == ID_bitnand)
1290+
out << "bvand";
1291+
else if(expr.id() == ID_bitnor)
1292+
out << "bvor";
1293+
1294+
for(const auto &op : expr.operands())
1295+
{
1296+
out << ' ';
1297+
flatten2bv(op);
1298+
}
1299+
1300+
out << "))"; // bvX, bvnot
1301+
}
1302+
else
1303+
{
1304+
DATA_INVARIANT(
1305+
expr.operands().size() >= 1,
1306+
expr.id_string() + " should have at least one operand");
1307+
}
1308+
}
12581309
else if(expr.id()==ID_bitnot)
12591310
{
12601311
const bitnot_exprt &bitnot_expr = to_bitnot_expr(expr);

Diff for: src/util/bitvector_expr.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ class bitxnor_exprt : public multi_ary_exprt
253253
{
254254
public:
255255
bitxnor_exprt(exprt _op0, exprt _op1)
256-
: multi_ary_exprt(std::move(_op0), ID_bitxnor, std::move(_op1))
256+
: multi_ary_exprt(_op0, ID_bitxnor, _op1, _op0.type())
257257
{
258258
}
259259

@@ -278,13 +278,15 @@ inline bool can_cast_expr<bitxnor_exprt>(const exprt &base)
278278
inline const bitxnor_exprt &to_bitxnor_expr(const exprt &expr)
279279
{
280280
PRECONDITION(expr.id() == ID_bitxnor);
281+
bitxnor_exprt::check(expr, validation_modet::INVARIANT);
281282
return static_cast<const bitxnor_exprt &>(expr);
282283
}
283284

284285
/// \copydoc to_bitxnor_expr(const exprt &)
285286
inline bitxnor_exprt &to_bitxnor_expr(exprt &expr)
286287
{
287288
PRECONDITION(expr.id() == ID_bitxnor);
289+
bitxnor_exprt::check(expr, validation_modet::INVARIANT);
288290
return static_cast<bitxnor_exprt &>(expr);
289291
}
290292

0 commit comments

Comments
 (0)