Skip to content

Commit 041188a

Browse files
committed
Add implementation of arithmetic operator bvsub.
Also add tests for it, both the conversion of `minus_exprt` to it, and the node factory constructing the nodes appropriately.
1 parent d3a3eb5 commit 041188a

File tree

5 files changed

+70
-2
lines changed

5 files changed

+70
-2
lines changed

src/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,8 +345,10 @@ static smt_termt convert_expr_to_smt(const plus_exprt &plus)
345345

346346
static smt_termt convert_expr_to_smt(const minus_exprt &minus)
347347
{
348-
UNIMPLEMENTED_FEATURE(
349-
"Generation of SMT formula for minus expression: " + minus.pretty());
348+
PRECONDITION(can_cast_type<bitvector_typet>(minus.lhs().type()));
349+
PRECONDITION(can_cast_type<bitvector_typet>(minus.rhs().type()));
350+
return smt_bit_vector_theoryt::subtraction(
351+
convert_expr_to_smt(minus.lhs()), convert_expr_to_smt(minus.rhs()));
350352
}
351353

352354
static smt_termt convert_expr_to_smt(const div_exprt &divide)

src/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,29 @@ void smt_bit_vector_theoryt::additiont::validate(
6565
const smt_function_application_termt::factoryt<
6666
smt_bit_vector_theoryt::additiont>
6767
smt_bit_vector_theoryt::add{};
68+
69+
const char *smt_bit_vector_theoryt::subtractiont::identifier()
70+
{
71+
return "bvsub";
72+
}
73+
74+
smt_sortt smt_bit_vector_theoryt::subtractiont::return_sort(
75+
const smt_termt &lhs,
76+
const smt_termt &rhs)
77+
{
78+
// For now, make sure that they have the same bit-width
79+
subtractiont::validate(lhs, rhs);
80+
const auto width = lhs.get_sort().cast<smt_bit_vector_sortt>()->bit_width();
81+
return smt_bit_vector_sortt{width};
82+
}
83+
84+
void smt_bit_vector_theoryt::subtractiont::validate(
85+
const smt_termt &lhs,
86+
const smt_termt &rhs)
87+
{
88+
validate_bit_vector_predicate_arguments(lhs, rhs);
89+
}
90+
91+
const smt_function_application_termt::factoryt<
92+
smt_bit_vector_theoryt::subtractiont>
93+
smt_bit_vector_theoryt::subtraction{};

src/solvers/smt2_incremental/smt_bit_vector_theory.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ class smt_bit_vector_theoryt
2828
static void validate(const smt_termt &lhs, const smt_termt &rhs);
2929
};
3030
static const smt_function_application_termt::factoryt<additiont> add;
31+
32+
struct subtractiont final
33+
{
34+
static const char *identifier();
35+
static smt_sortt return_sort(const smt_termt &lhs, const smt_termt &rhs);
36+
static void validate(const smt_termt &lhs, const smt_termt &rhs);
37+
};
38+
static const smt_function_application_termt::factoryt<subtractiont>
39+
subtraction;
3140
};
3241

3342
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H

unit/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,4 +303,22 @@ TEST_CASE(
303303
REQUIRE_THROWS(
304304
convert_expr_to_smt(plus_exprt{operands, signedbv_typet{8}}));
305305
}
306+
307+
SECTION("Subtraction of two constant size bit-vectors")
308+
{
309+
const auto constructed_term =
310+
convert_expr_to_smt(minus_exprt{two_bvint, one_bvint});
311+
const auto expected_term =
312+
smt_bit_vector_theoryt::subtraction(smt_term_two, smt_term_one);
313+
CHECK(constructed_term == expected_term);
314+
}
315+
316+
SECTION(
317+
"Ensure that subtraction node conversion fails if the operands are not "
318+
"bit-vector based")
319+
{
320+
const cbmc_invariants_should_throwt invariants_throw;
321+
REQUIRE_THROWS(
322+
convert_expr_to_smt(minus_exprt{true_exprt{}, false_exprt{}}));
323+
}
306324
}

unit/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,4 +193,17 @@ TEST_CASE(
193193
// An addition of a bool and a bitvector should hit an invariant violation.
194194
REQUIRE_THROWS(smt_bit_vector_theoryt::add(three, true_val));
195195
}
196+
197+
SECTION("Subtraction")
198+
{
199+
const auto function_application =
200+
smt_bit_vector_theoryt::subtraction(two, three);
201+
REQUIRE(
202+
function_application.function_identifier() ==
203+
smt_identifier_termt("bvsub", smt_bit_vector_sortt{8}));
204+
REQUIRE(function_application.get_sort() == smt_bit_vector_sortt{8});
205+
REQUIRE(function_application.arguments().size() == 2);
206+
REQUIRE(function_application.arguments()[0].get() == two);
207+
REQUIRE(function_application.arguments()[1].get() == three);
208+
}
196209
}

0 commit comments

Comments
 (0)