Skip to content

Commit 3ba30db

Browse files
committed
SMT2: bvnor, bvnand are binary only; add bvxnor
The SMT-LIB2 expressions bvnor and bvnand are not multi-ary. Furthermore, this adds the (binary) bvxnor expression.
1 parent e8d3409 commit 3ba30db

File tree

2 files changed

+30
-8
lines changed

2 files changed

+30
-8
lines changed

src/solvers/smt2/smt2_conv.cpp

Lines changed: 25 additions & 6 deletions
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,28 @@ 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+
// only exist as a binary expression
1260+
const auto &bitxnor = to_bitxnor_expr(expr);
1261+
DATA_INVARIANT(
1262+
expr.operands().size() == 2, "bitxnor should have two operands");
1263+
1264+
out << '(';
1265+
if(expr.id() == ID_bitxnor)
1266+
out << "bvxnor";
1267+
else if(expr.id() == ID_bitnand)
1268+
out << "bvnand";
1269+
else if(expr.id() == ID_bitnor)
1270+
out << "bvnor";
1271+
out << ' ';
1272+
flatten2bv(bitxnor.op0());
1273+
out << ' ';
1274+
flatten2bv(bitxnor.op1());
1275+
out << ')';
1276+
}
12581277
else if(expr.id()==ID_bitnot)
12591278
{
12601279
const bitnot_exprt &bitnot_expr = to_bitnot_expr(expr);

src/util/bitvector_expr.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,11 +191,12 @@ inline bitxor_exprt &to_bitxor_expr(exprt &expr)
191191
}
192192

193193
/// \brief Bit-wise XNOR
194-
class bitxnor_exprt : public multi_ary_exprt
194+
/// Binary, not multi-ary, to avoid the ambiguity.
195+
class bitxnor_exprt : public binary_exprt
195196
{
196197
public:
197198
bitxnor_exprt(exprt _op0, exprt _op1)
198-
: multi_ary_exprt(std::move(_op0), ID_bitxnor, std::move(_op1))
199+
: binary_exprt(std::move(_op0), ID_bitxnor, std::move(_op1))
199200
{
200201
}
201202
};
@@ -215,13 +216,15 @@ inline bool can_cast_expr<bitxnor_exprt>(const exprt &base)
215216
inline const bitxnor_exprt &to_bitxnor_expr(const exprt &expr)
216217
{
217218
PRECONDITION(expr.id() == ID_bitxnor);
219+
bitxnor_exprt::check(expr);
218220
return static_cast<const bitxnor_exprt &>(expr);
219221
}
220222

221223
/// \copydoc to_bitxnor_expr(const exprt &)
222224
inline bitxnor_exprt &to_bitxnor_expr(exprt &expr)
223225
{
224226
PRECONDITION(expr.id() == ID_bitxnor);
227+
bitxnor_exprt::check(expr);
225228
return static_cast<bitxnor_exprt &>(expr);
226229
}
227230

0 commit comments

Comments
 (0)