Skip to content

Commit 309bc41

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 309bc41

File tree

5 files changed

+82
-2
lines changed

5 files changed

+82
-2
lines changed

src/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,8 +345,20 @@ 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+
bool both_operands_bitvector =
349+
can_cast_type<bitvector_typet>(minus.lhs().type()) &&
350+
can_cast_type<bitvector_typet>(minus.rhs().type());
351+
352+
if(both_operands_bitvector)
353+
{
354+
return smt_bit_vector_theoryt::subtract(
355+
convert_expr_to_smt(minus.lhs()), convert_expr_to_smt(minus.rhs()));
356+
}
357+
else
358+
{
359+
UNIMPLEMENTED_FEATURE(
360+
"Generation of SMT formula for minus expression: " + minus.pretty());
361+
}
350362
}
351363

352364
static smt_termt convert_expr_to_smt(const div_exprt &divide)

src/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,26 @@ 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+
return lhs.get_sort();
79+
}
80+
81+
void smt_bit_vector_theoryt::subtractiont::validate(
82+
const smt_termt &lhs,
83+
const smt_termt &rhs)
84+
{
85+
validate_bit_vector_predicate_arguments(lhs, rhs);
86+
}
87+
88+
const smt_function_application_termt::factoryt<
89+
smt_bit_vector_theoryt::subtractiont>
90+
smt_bit_vector_theoryt::subtract{};

src/solvers/smt2_incremental/smt_bit_vector_theory.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ 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> subtract;
3139
};
3240

3341
#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::subtract(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: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,4 +193,23 @@ 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::subtract(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+
209+
cbmc_invariants_should_throwt invariants_throw;
210+
// Bit-vectors of mismatched sorts are going to hit an invariant violation.
211+
REQUIRE_THROWS(smt_bit_vector_theoryt::subtract(three, four));
212+
// An addition of a bool and a bitvector should hit an invariant violation.
213+
REQUIRE_THROWS(smt_bit_vector_theoryt::subtract(true_val, three));
214+
}
196215
}

0 commit comments

Comments
 (0)