Skip to content

Commit

Permalink
SMT2: implement range_type
Browse files Browse the repository at this point in the history
This adds missing support for encoding the range_typet to the SMT2 backend.
  • Loading branch information
kroening committed Sep 22, 2024
1 parent d2b4455 commit e21c686
Showing 1 changed file with 48 additions and 3 deletions.
51 changes: 48 additions & 3 deletions src/solvers/smt2/smt2_conv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,7 @@ exprt smt2_convt::parse_rec(const irept &src, const typet &type)
type.id() == ID_integer || type.id() == ID_rational ||
type.id() == ID_real || type.id() == ID_c_enum ||
type.id() == ID_c_enum_tag || type.id() == ID_fixedbv ||
type.id() == ID_floatbv || type.id() == ID_c_bool)
type.id() == ID_floatbv || type.id() == ID_c_bool || type.id() == ID_range)
{
return parse_literal(src, type);
}
Expand Down Expand Up @@ -2920,7 +2920,35 @@ void smt2_convt::convert_typecast(const typecast_exprt &expr)
}
else if(dest_type.id()==ID_range)
{
SMT2_TODO("range typecast");
auto &dest_range_type = to_range_type(dest_type);
const auto dest_size =
dest_range_type.get_to() - dest_range_type.get_from() + 1;
const auto dest_width = address_bits(dest_size);

Check warning on line 2926 in src/solvers/smt2/smt2_conv.cpp

View check run for this annotation

Codecov / codecov/patch

src/solvers/smt2/smt2_conv.cpp#L2923-L2926

Added lines #L2923 - L2926 were not covered by tests
if(src_type.id() == ID_range)
{
auto &src_range_type = to_range_type(src_type);
const auto src_size =
src_range_type.get_to() - src_range_type.get_from() + 1;
const auto src_width = address_bits(src_size);

Check warning on line 2932 in src/solvers/smt2/smt2_conv.cpp

View check run for this annotation

Codecov / codecov/patch

src/solvers/smt2/smt2_conv.cpp#L2929-L2932

Added lines #L2929 - L2932 were not covered by tests
if(src_width < dest_width)
{
out << "((_ zero_extend " << dest_width - src_width << ") ";
convert_expr(src);
out << ')'; // zero_extend

Check warning on line 2937 in src/solvers/smt2/smt2_conv.cpp

View check run for this annotation

Codecov / codecov/patch

src/solvers/smt2/smt2_conv.cpp#L2935-L2937

Added lines #L2935 - L2937 were not covered by tests
}
else if(src_width > dest_width)

Check warning on line 2939 in src/solvers/smt2/smt2_conv.cpp

View check run for this annotation

Codecov / codecov/patch

src/solvers/smt2/smt2_conv.cpp#L2939

Added line #L2939 was not covered by tests
{
out << "((_ extract " << dest_width - 1 << " 0) ";
convert_expr(src);
out << ')'; // extract

Check warning on line 2943 in src/solvers/smt2/smt2_conv.cpp

View check run for this annotation

Codecov / codecov/patch

src/solvers/smt2/smt2_conv.cpp#L2941-L2943

Added lines #L2941 - L2943 were not covered by tests
}
else // src_width == dest_width

Check warning on line 2945 in src/solvers/smt2/smt2_conv.cpp

View check run for this annotation

Codecov / codecov/patch

src/solvers/smt2/smt2_conv.cpp#L2945

Added line #L2945 was not covered by tests
{
convert_expr(src);

Check warning on line 2947 in src/solvers/smt2/smt2_conv.cpp

View check run for this annotation

Codecov / codecov/patch

src/solvers/smt2/smt2_conv.cpp#L2947

Added line #L2947 was not covered by tests
}
}
else
SMT2_TODO("typecast from " + src_type.id_string() + " to range");

Check warning on line 2951 in src/solvers/smt2/smt2_conv.cpp

View check run for this annotation

Codecov / codecov/patch

src/solvers/smt2/smt2_conv.cpp#L2950-L2951

Added lines #L2950 - L2951 were not covered by tests
}
else if(dest_type.id()==ID_floatbv)
{
Expand Down Expand Up @@ -3440,6 +3468,15 @@ void smt2_convt::convert_constant(const constant_exprt &expr)
else
out << value;
}
else if(expr_type.id() == ID_range)

Check warning on line 3471 in src/solvers/smt2/smt2_conv.cpp

View check run for this annotation

Codecov / codecov/patch

src/solvers/smt2/smt2_conv.cpp#L3471

Added line #L3471 was not covered by tests
{
auto &range_type = to_range_type(expr_type);
const auto size = range_type.get_to() - range_type.get_from() + 1;
const auto width = address_bits(size);
const auto value_int = numeric_cast_v<mp_integer>(expr);
out << "(_ bv" << (value_int - range_type.get_from()) << " " << width
<< ")";

Check warning on line 3478 in src/solvers/smt2/smt2_conv.cpp

View check run for this annotation

Codecov / codecov/patch

src/solvers/smt2/smt2_conv.cpp#L3473-L3478

Added lines #L3473 - L3478 were not covered by tests
}
else
UNEXPECTEDCASE("unknown constant: "+expr_type.id_string());
}
Expand Down Expand Up @@ -3641,7 +3678,7 @@ void smt2_convt::convert_plus(const plus_exprt &expr)
}
else if(
expr.type().id() == ID_unsignedbv || expr.type().id() == ID_signedbv ||
expr.type().id() == ID_fixedbv)
expr.type().id() == ID_fixedbv || expr.type().id() == ID_range)
{
// These could be chained, i.e., need not be binary,
// but at least MathSat doesn't like that.
Expand Down Expand Up @@ -5601,6 +5638,14 @@ void smt2_convt::convert_type(const typet &type)
{
out << "state";
}
else if(type.id() == ID_range)

Check warning on line 5641 in src/solvers/smt2/smt2_conv.cpp

View check run for this annotation

Codecov / codecov/patch

src/solvers/smt2/smt2_conv.cpp#L5641

Added line #L5641 was not covered by tests
{
auto &range_type = to_range_type(type);
mp_integer size = range_type.get_to() - range_type.get_from() + 1;

Check warning on line 5644 in src/solvers/smt2/smt2_conv.cpp

View check run for this annotation

Codecov / codecov/patch

src/solvers/smt2/smt2_conv.cpp#L5643-L5644

Added lines #L5643 - L5644 were not covered by tests
if(size <= 0)
UNEXPECTEDCASE("unsuppored range type");
out << "(_ BitVec " << address_bits(size) << ")";

Check warning on line 5647 in src/solvers/smt2/smt2_conv.cpp

View check run for this annotation

Codecov / codecov/patch

src/solvers/smt2/smt2_conv.cpp#L5646-L5647

Added lines #L5646 - L5647 were not covered by tests
}
else
{
UNEXPECTEDCASE("unsupported type: "+type.id_string());
Expand Down

0 comments on commit e21c686

Please sign in to comment.