Skip to content

Commit 632093c

Browse files
committed
SMT2: implement unary minus on ranges
This implements unary minus on the range type in the SMT2 backend.
1 parent 37d92db commit 632093c

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-4
lines changed

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

+13-4
Original file line numberDiff line numberDiff line change
@@ -1320,17 +1320,26 @@ void smt2_convt::convert_expr(const exprt &expr)
13201320
else if(expr.id()==ID_unary_minus)
13211321
{
13221322
const unary_minus_exprt &unary_minus_expr = to_unary_minus_expr(expr);
1323+
const auto &type = expr.type();
13231324

13241325
if(
1325-
unary_minus_expr.type().id() == ID_rational ||
1326-
unary_minus_expr.type().id() == ID_integer ||
1327-
unary_minus_expr.type().id() == ID_real)
1326+
type.id() == ID_rational || type.id() == ID_integer ||
1327+
type.id() == ID_real)
13281328
{
13291329
out << "(- ";
13301330
convert_expr(unary_minus_expr.op());
13311331
out << ")";
13321332
}
1333-
else if(unary_minus_expr.type().id() == ID_floatbv)
1333+
else if(type.id() == ID_range)
1334+
{
1335+
auto &range_type = to_range_type(type);
1336+
PRECONDITION(type == unary_minus_expr.op().type());
1337+
// turn -x into 0-x
1338+
auto minus_expr =
1339+
minus_exprt{range_type.zero_expr(), unary_minus_expr.op()};
1340+
convert_expr(minus_expr);
1341+
}
1342+
else if(type.id() == ID_floatbv)
13341343
{
13351344
// this has no rounding mode
13361345
if(use_FPA_theory)

Diff for: src/util/std_types.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,23 @@ void bitvector_typet::width(const mp_integer &width)
165165
set_width(numeric_cast_v<std::size_t>(width));
166166
}
167167

168+
bool range_typet::includes(const mp_integer &singleton) const
169+
{
170+
return get_from() <= singleton && singleton <= get_to();
171+
}
172+
173+
constant_exprt range_typet::one_expr() const
174+
{
175+
PRECONDITION(includes(1));
176+
return constant_exprt{ID_1, *this};
177+
}
178+
179+
constant_exprt range_typet::zero_expr() const
180+
{
181+
PRECONDITION(includes(0));
182+
return constant_exprt{ID_0, *this};
183+
}
184+
168185
void range_typet::set_from(const mp_integer &from)
169186
{
170187
set(ID_from, integer2string(from));

Diff for: src/util/std_types.h

+3
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,9 @@ class range_typet:public typet
10121012

10131013
mp_integer get_from() const;
10141014
mp_integer get_to() const;
1015+
bool includes(const mp_integer &) const;
1016+
constant_exprt zero_expr() const;
1017+
constant_exprt one_expr() const;
10151018

10161019
void set_from(const mp_integer &_from);
10171020
void set_to(const mp_integer &to);

0 commit comments

Comments
 (0)