Skip to content

Commit 391fd95

Browse files
committed
Add implemenetation of division operator bvdiv.
Along with tests of its conversion and the function application factory integrity.
1 parent 5b3b278 commit 391fd95

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
@@ -343,8 +343,10 @@ static smt_termt convert_expr_to_smt(const minus_exprt &minus)
343343

344344
static smt_termt convert_expr_to_smt(const div_exprt &divide)
345345
{
346-
UNIMPLEMENTED_FEATURE(
347-
"Generation of SMT formula for divide expression: " + divide.pretty());
346+
PRECONDITION(can_cast_type<bitvector_typet>(divide.lhs().type()));
347+
PRECONDITION(can_cast_type<bitvector_typet>(divide.rhs().type()));
348+
return smt_bit_vector_theoryt::division(
349+
convert_expr_to_smt(divide.lhs()), convert_expr_to_smt(divide.rhs()));
348350
}
349351

350352
static smt_termt convert_expr_to_smt(const ieee_float_op_exprt &float_operation)

src/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,29 @@ void smt_bit_vector_theoryt::multiplicationt::validate(
120120
const smt_function_application_termt::factoryt<
121121
smt_bit_vector_theoryt::multiplicationt>
122122
smt_bit_vector_theoryt::multiplication{};
123+
124+
const char *smt_bit_vector_theoryt::divisiont::identifier()
125+
{
126+
return "bvdiv";
127+
}
128+
129+
smt_sortt smt_bit_vector_theoryt::divisiont::return_sort(
130+
const smt_termt &lhs,
131+
const smt_termt &rhs)
132+
{
133+
// For now, make sure that they have the same bit-width
134+
divisiont::validate(lhs, rhs);
135+
const auto width = lhs.get_sort().cast<smt_bit_vector_sortt>()->bit_width();
136+
return smt_bit_vector_sortt{width};
137+
}
138+
139+
void smt_bit_vector_theoryt::divisiont::validate(
140+
const smt_termt &lhs,
141+
const smt_termt &rhs)
142+
{
143+
validate_bit_vector_predicate_arguments(lhs, rhs);
144+
}
145+
146+
const smt_function_application_termt::factoryt<
147+
smt_bit_vector_theoryt::divisiont>
148+
smt_bit_vector_theoryt::division{};

src/solvers/smt2_incremental/smt_bit_vector_theory.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ class smt_bit_vector_theoryt
4646
};
4747
static const smt_function_application_termt::factoryt<multiplicationt>
4848
multiplication;
49+
50+
struct divisiont final
51+
{
52+
static const char *identifier();
53+
static smt_sortt return_sort(const smt_termt &lhs, const smt_termt &rhs);
54+
static void validate(const smt_termt &lhs, const smt_termt &rhs);
55+
};
56+
static const smt_function_application_termt::factoryt<divisiont> division;
4957
};
5058

5159
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H

unit/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,4 +328,23 @@ TEST_CASE(
328328
const cbmc_invariants_should_throwt invariants_throw;
329329
REQUIRE_THROWS(convert_expr_to_smt(mult_exprt{one_bvint, false_exprt{}}));
330330
}
331+
332+
// Division is defined over unsigned numbers only (theory notes say it
333+
// truncates over zero)
334+
SECTION("Division of two constant size bit-vectors")
335+
{
336+
const auto constructed_term =
337+
convert_expr_to_smt(div_exprt{one_bvint_unsigned, two_bvint_unsigned});
338+
const auto expected_term =
339+
smt_bit_vector_theoryt::division(smt_term_one, smt_term_two);
340+
CHECK(constructed_term == expected_term);
341+
}
342+
343+
SECTION(
344+
"Ensure that division node conversion fails if the operands are not "
345+
"bit-vector based")
346+
{
347+
const cbmc_invariants_should_throwt invariants_throw;
348+
REQUIRE_THROWS(convert_expr_to_smt(div_exprt{one_bvint, false_exprt{}}));
349+
}
331350
}

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
REQUIRE(function_application.arguments()[0].get() == two);
213213
REQUIRE(function_application.arguments()[1].get() == three);
214214
}
215+
216+
SECTION("Division")
217+
{
218+
const auto function_application =
219+
smt_bit_vector_theoryt::division(two, three);
220+
REQUIRE(
221+
function_application.function_identifier() ==
222+
smt_identifier_termt("bvdiv", 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)