Skip to content

Commit b4b7cd1

Browse files
committed
Add implementation of multiplication operator bvmul.
Also add tests for its conversion from `mult_exprt` and of the factory integrity.
1 parent 041188a commit b4b7cd1

File tree

5 files changed

+71
-2
lines changed

5 files changed

+71
-2
lines changed

src/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,8 +383,12 @@ convert_expr_to_smt(const euclidean_mod_exprt &euclidean_modulo)
383383

384384
static smt_termt convert_expr_to_smt(const mult_exprt &multiply)
385385
{
386-
UNIMPLEMENTED_FEATURE(
387-
"Generation of SMT formula for multiply expression: " + multiply.pretty());
386+
for(const auto &op : multiply.operands())
387+
{
388+
PRECONDITION(can_cast_type<bitvector_typet>(op.type()));
389+
}
390+
return convert_multiary_operator_to_terms(
391+
multiply, smt_bit_vector_theoryt::multiplication);
388392
}
389393

390394
static smt_termt convert_expr_to_smt(const address_of_exprt &address_of)

src/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,29 @@ void smt_bit_vector_theoryt::subtractiont::validate(
9191
const smt_function_application_termt::factoryt<
9292
smt_bit_vector_theoryt::subtractiont>
9393
smt_bit_vector_theoryt::subtraction{};
94+
95+
const char *smt_bit_vector_theoryt::multiplicationt::identifier()
96+
{
97+
return "bvmul";
98+
}
99+
100+
smt_sortt smt_bit_vector_theoryt::multiplicationt::return_sort(
101+
const smt_termt &lhs,
102+
const smt_termt &rhs)
103+
{
104+
// For now, make sure that they have the same bit-width
105+
multiplicationt::validate(lhs, rhs);
106+
const auto width = lhs.get_sort().cast<smt_bit_vector_sortt>()->bit_width();
107+
return smt_bit_vector_sortt{width};
108+
}
109+
110+
void smt_bit_vector_theoryt::multiplicationt::validate(
111+
const smt_termt &lhs,
112+
const smt_termt &rhs)
113+
{
114+
validate_bit_vector_predicate_arguments(lhs, rhs);
115+
}
116+
117+
const smt_function_application_termt::factoryt<
118+
smt_bit_vector_theoryt::multiplicationt>
119+
smt_bit_vector_theoryt::multiplication{};

src/solvers/smt2_incremental/smt_bit_vector_theory.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@ class smt_bit_vector_theoryt
3737
};
3838
static const smt_function_application_termt::factoryt<subtractiont>
3939
subtraction;
40+
41+
struct multiplicationt final
42+
{
43+
static const char *identifier();
44+
static smt_sortt return_sort(const smt_termt &lhs, const smt_termt &rhs);
45+
static void validate(const smt_termt &lhs, const smt_termt &rhs);
46+
};
47+
static const smt_function_application_termt::factoryt<multiplicationt>
48+
multiplication;
4049
};
4150

4251
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H

unit/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,4 +321,21 @@ TEST_CASE(
321321
REQUIRE_THROWS(
322322
convert_expr_to_smt(minus_exprt{true_exprt{}, false_exprt{}}));
323323
}
324+
325+
SECTION("Multiplication of two constant size bit-vectors")
326+
{
327+
const auto constructed_term =
328+
convert_expr_to_smt(mult_exprt{one_bvint, two_bvint});
329+
const auto expected_term =
330+
smt_bit_vector_theoryt::multiplication(smt_term_one, smt_term_two);
331+
CHECK(constructed_term == expected_term);
332+
}
333+
334+
SECTION(
335+
"Ensure that multiplication node conversion fails if the operands are not "
336+
"bit-vector based")
337+
{
338+
const cbmc_invariants_should_throwt invariants_throw;
339+
REQUIRE_THROWS(convert_expr_to_smt(mult_exprt{one_bvint, false_exprt{}}));
340+
}
324341
}

unit/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,4 +206,17 @@ TEST_CASE(
206206
REQUIRE(function_application.arguments()[0].get() == two);
207207
REQUIRE(function_application.arguments()[1].get() == three);
208208
}
209+
210+
SECTION("Multiplication")
211+
{
212+
const auto function_application =
213+
smt_bit_vector_theoryt::multiplication(two, three);
214+
REQUIRE(
215+
function_application.function_identifier() ==
216+
smt_identifier_termt("bvmul", smt_bit_vector_sortt{8}));
217+
REQUIRE(function_application.get_sort() == smt_bit_vector_sortt{8});
218+
REQUIRE(function_application.arguments().size() == 2);
219+
REQUIRE(function_application.arguments()[0].get() == two);
220+
REQUIRE(function_application.arguments()[1].get() == three);
221+
}
209222
}

0 commit comments

Comments
 (0)