Skip to content

Commit 7488488

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 426aebb commit 7488488

File tree

5 files changed

+83
-2
lines changed

5 files changed

+83
-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
@@ -343,8 +343,20 @@ static smt_termt convert_expr_to_smt(const plus_exprt &plus)
343343

344344
static smt_termt convert_expr_to_smt(const minus_exprt &minus)
345345
{
346-
UNIMPLEMENTED_FEATURE(
347-
"Generation of SMT formula for minus expression: " + minus.pretty());
346+
const bool both_operands_bitvector =
347+
can_cast_type<integer_bitvector_typet>(minus.lhs().type()) &&
348+
can_cast_type<integer_bitvector_typet>(minus.rhs().type());
349+
350+
if(both_operands_bitvector)
351+
{
352+
return smt_bit_vector_theoryt::subtract(
353+
convert_expr_to_smt(minus.lhs()), convert_expr_to_smt(minus.rhs()));
354+
}
355+
else
356+
{
357+
UNIMPLEMENTED_FEATURE(
358+
"Generation of SMT formula for minus expression: " + minus.pretty());
359+
}
348360
}
349361

350362
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
@@ -227,3 +227,26 @@ void smt_bit_vector_theoryt::addt::validate(
227227

228228
const smt_function_application_termt::factoryt<smt_bit_vector_theoryt::addt>
229229
smt_bit_vector_theoryt::add{};
230+
231+
const char *smt_bit_vector_theoryt::subtractt::identifier()
232+
{
233+
return "bvsub";
234+
}
235+
236+
smt_sortt smt_bit_vector_theoryt::subtractt::return_sort(
237+
const smt_termt &lhs,
238+
const smt_termt &rhs)
239+
{
240+
return lhs.get_sort();
241+
}
242+
243+
void smt_bit_vector_theoryt::subtractt::validate(
244+
const smt_termt &lhs,
245+
const smt_termt &rhs)
246+
{
247+
validate_bit_vector_predicate_arguments(lhs, rhs);
248+
}
249+
250+
const smt_function_application_termt::factoryt<
251+
smt_bit_vector_theoryt::subtractt>
252+
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
@@ -92,6 +92,14 @@ class smt_bit_vector_theoryt
9292
static void validate(const smt_termt &lhs, const smt_termt &rhs);
9393
};
9494
static const smt_function_application_termt::factoryt<addt> add;
95+
96+
struct subtractt final
97+
{
98+
static const char *identifier();
99+
static smt_sortt return_sort(const smt_termt &lhs, const smt_termt &rhs);
100+
static void validate(const smt_termt &lhs, const smt_termt &rhs);
101+
};
102+
static const smt_function_application_termt::factoryt<subtractt> subtract;
95103
};
96104

97105
#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
@@ -310,4 +310,22 @@ TEST_CASE(
310310
REQUIRE_THROWS(
311311
convert_expr_to_smt(plus_exprt{one_operand, signedbv_typet{8}}));
312312
}
313+
314+
SECTION("Subtraction of two constant size bit-vectors")
315+
{
316+
const auto constructed_term =
317+
convert_expr_to_smt(minus_exprt{two_bvint, one_bvint});
318+
const auto expected_term =
319+
smt_bit_vector_theoryt::subtract(smt_term_two, smt_term_one);
320+
CHECK(constructed_term == expected_term);
321+
}
322+
323+
SECTION(
324+
"Ensure that subtraction node conversion fails if the operands are not "
325+
"bit-vector based")
326+
{
327+
const cbmc_invariants_should_throwt invariants_throw;
328+
REQUIRE_THROWS(
329+
convert_expr_to_smt(minus_exprt{true_exprt{}, false_exprt{}}));
330+
}
313331
}

unit/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,4 +193,24 @@ 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+
// A subtraction of a bool and a bitvector should hit an
213+
// invariant violation.
214+
REQUIRE_THROWS(smt_bit_vector_theoryt::subtract(true_val, three));
215+
}
196216
}

0 commit comments

Comments
 (0)