Skip to content

Commit 28b2193

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 309bc41 commit 28b2193

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
@@ -393,8 +393,12 @@ convert_expr_to_smt(const euclidean_mod_exprt &euclidean_modulo)
393393

394394
static smt_termt convert_expr_to_smt(const mult_exprt &multiply)
395395
{
396-
UNIMPLEMENTED_FEATURE(
397-
"Generation of SMT formula for multiply expression: " + multiply.pretty());
396+
for(const auto &op : multiply.operands())
397+
{
398+
PRECONDITION(can_cast_type<bitvector_typet>(op.type()));
399+
}
400+
return convert_multiary_operator_to_terms(
401+
multiply, smt_bit_vector_theoryt::multiplication);
398402
}
399403

400404
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
@@ -88,3 +88,29 @@ void smt_bit_vector_theoryt::subtractiont::validate(
8888
const smt_function_application_termt::factoryt<
8989
smt_bit_vector_theoryt::subtractiont>
9090
smt_bit_vector_theoryt::subtract{};
91+
92+
const char *smt_bit_vector_theoryt::multiplicationt::identifier()
93+
{
94+
return "bvmul";
95+
}
96+
97+
smt_sortt smt_bit_vector_theoryt::multiplicationt::return_sort(
98+
const smt_termt &lhs,
99+
const smt_termt &rhs)
100+
{
101+
// For now, make sure that they have the same bit-width
102+
multiplicationt::validate(lhs, rhs);
103+
const auto width = lhs.get_sort().cast<smt_bit_vector_sortt>()->bit_width();
104+
return smt_bit_vector_sortt{width};
105+
}
106+
107+
void smt_bit_vector_theoryt::multiplicationt::validate(
108+
const smt_termt &lhs,
109+
const smt_termt &rhs)
110+
{
111+
validate_bit_vector_predicate_arguments(lhs, rhs);
112+
}
113+
114+
const smt_function_application_termt::factoryt<
115+
smt_bit_vector_theoryt::multiplicationt>
116+
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
@@ -36,6 +36,15 @@ class smt_bit_vector_theoryt
3636
static void validate(const smt_termt &lhs, const smt_termt &rhs);
3737
};
3838
static const smt_function_application_termt::factoryt<subtractiont> subtract;
39+
40+
struct multiplicationt final
41+
{
42+
static const char *identifier();
43+
static smt_sortt return_sort(const smt_termt &lhs, const smt_termt &rhs);
44+
static void validate(const smt_termt &lhs, const smt_termt &rhs);
45+
};
46+
static const smt_function_application_termt::factoryt<multiplicationt>
47+
multiplication;
3948
};
4049

4150
#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
@@ -212,4 +212,17 @@ TEST_CASE(
212212
// An addition of a bool and a bitvector should hit an invariant violation.
213213
REQUIRE_THROWS(smt_bit_vector_theoryt::subtract(true_val, three));
214214
}
215+
216+
SECTION("Multiplication")
217+
{
218+
const auto function_application =
219+
smt_bit_vector_theoryt::multiplication(two, three);
220+
REQUIRE(
221+
function_application.function_identifier() ==
222+
smt_identifier_termt("bvmul", smt_bit_vector_sortt{8}));
223+
REQUIRE(function_application.get_sort() == smt_bit_vector_sortt{8});
224+
REQUIRE(function_application.arguments().size() == 2);
225+
REQUIRE(function_application.arguments()[0].get() == two);
226+
REQUIRE(function_application.arguments()[1].get() == three);
227+
}
215228
}

0 commit comments

Comments
 (0)