Skip to content

Commit bf20fc9

Browse files
committed
Implement plus overflow to smt terms conversion
1 parent b78ca45 commit bf20fc9

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

src/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,8 +833,44 @@ static smt_termt convert_expr_to_smt(const isnormal_exprt &is_normal_expr)
833833
is_normal_expr.pretty());
834834
}
835835

836+
/// \brief
837+
/// Constructs a term which is true if the most significant bit of \p input
838+
/// is set.
839+
static smt_termt most_significant_bit_is_set(const smt_termt &input)
840+
{
841+
const auto bit_vector_sort = input.get_sort().cast<smt_bit_vector_sortt>();
842+
INVARIANT(
843+
bit_vector_sort,
844+
"Most significant bit can only be extracted from bit vector terms.");
845+
const size_t most_significant_bit_index = bit_vector_sort->bit_width() - 1;
846+
const auto extract_most_significant_bit = smt_bit_vector_theoryt::extract(
847+
most_significant_bit_index, most_significant_bit_index);
848+
return smt_core_theoryt::equal(
849+
extract_most_significant_bit(input), smt_bit_vector_constant_termt{1, 1});
850+
}
851+
836852
static smt_termt convert_expr_to_smt(const plus_overflow_exprt &plus_overflow)
837853
{
854+
const smt_termt left = convert_expr_to_smt(plus_overflow.lhs());
855+
const smt_termt right = convert_expr_to_smt(plus_overflow.rhs());
856+
if(operands_are_of_type<unsignedbv_typet>(plus_overflow))
857+
{
858+
const auto add_carry_bit = smt_bit_vector_theoryt::zero_extend(1);
859+
return most_significant_bit_is_set(
860+
smt_bit_vector_theoryt::add(add_carry_bit(left), add_carry_bit(right)));
861+
}
862+
if(operands_are_of_type<signedbv_typet>(plus_overflow))
863+
{
864+
// Overflow has occurred if the operands have the same sign and adding them
865+
// gives a result of the opposite sign.
866+
const smt_termt msb_left = most_significant_bit_is_set(left);
867+
const smt_termt msb_right = most_significant_bit_is_set(right);
868+
return smt_core_theoryt::make_and(
869+
smt_core_theoryt::equal(msb_left, msb_right),
870+
smt_core_theoryt::distinct(
871+
msb_left,
872+
most_significant_bit_is_set(smt_bit_vector_theoryt::add(left, right))));
873+
}
838874
UNIMPLEMENTED_FEATURE(
839875
"Generation of SMT formula for plus overflow expression: " +
840876
plus_overflow.pretty());

0 commit comments

Comments
 (0)