Skip to content

Commit 1ad4c7f

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

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

354354
static smt_termt convert_expr_to_smt(const div_exprt &divide)
355355
{
356-
UNIMPLEMENTED_FEATURE(
357-
"Generation of SMT formula for divide expression: " + divide.pretty());
356+
PRECONDITION(can_cast_type<bitvector_typet>(divide.lhs().type()));
357+
PRECONDITION(can_cast_type<bitvector_typet>(divide.rhs().type()));
358+
return smt_bit_vector_theoryt::division(
359+
convert_expr_to_smt(divide.lhs()), convert_expr_to_smt(divide.rhs()));
358360
}
359361

360362
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
@@ -117,3 +117,29 @@ void smt_bit_vector_theoryt::multiplicationt::validate(
117117
const smt_function_application_termt::factoryt<
118118
smt_bit_vector_theoryt::multiplicationt>
119119
smt_bit_vector_theoryt::multiplication{};
120+
121+
const char *smt_bit_vector_theoryt::divisiont::identifier()
122+
{
123+
return "bvdiv";
124+
}
125+
126+
smt_sortt smt_bit_vector_theoryt::divisiont::return_sort(
127+
const smt_termt &lhs,
128+
const smt_termt &rhs)
129+
{
130+
// For now, make sure that they have the same bit-width
131+
divisiont::validate(lhs, rhs);
132+
const auto width = lhs.get_sort().cast<smt_bit_vector_sortt>()->bit_width();
133+
return smt_bit_vector_sortt{width};
134+
}
135+
136+
void smt_bit_vector_theoryt::divisiont::validate(
137+
const smt_termt &lhs,
138+
const smt_termt &rhs)
139+
{
140+
validate_bit_vector_predicate_arguments(lhs, rhs);
141+
}
142+
143+
const smt_function_application_termt::factoryt<
144+
smt_bit_vector_theoryt::divisiont>
145+
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
@@ -338,4 +338,23 @@ TEST_CASE(
338338
const cbmc_invariants_should_throwt invariants_throw;
339339
REQUIRE_THROWS(convert_expr_to_smt(mult_exprt{one_bvint, false_exprt{}}));
340340
}
341+
342+
// Division is defined over unsigned numbers only (theory notes say it
343+
// truncates over zero)
344+
SECTION("Division of two constant size bit-vectors")
345+
{
346+
const auto constructed_term =
347+
convert_expr_to_smt(div_exprt{one_bvint_unsigned, two_bvint_unsigned});
348+
const auto expected_term =
349+
smt_bit_vector_theoryt::division(smt_term_one, smt_term_two);
350+
CHECK(constructed_term == expected_term);
351+
}
352+
353+
SECTION(
354+
"Ensure that division node conversion fails if the operands are not "
355+
"bit-vector based")
356+
{
357+
const cbmc_invariants_should_throwt invariants_throw;
358+
REQUIRE_THROWS(convert_expr_to_smt(div_exprt{one_bvint, false_exprt{}}));
359+
}
341360
}

unit/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,4 +219,17 @@ TEST_CASE(
219219
REQUIRE(function_application.arguments()[0].get() == two);
220220
REQUIRE(function_application.arguments()[1].get() == three);
221221
}
222+
223+
SECTION("Division")
224+
{
225+
const auto function_application =
226+
smt_bit_vector_theoryt::division(two, three);
227+
REQUIRE(
228+
function_application.function_identifier() ==
229+
smt_identifier_termt("bvdiv", smt_bit_vector_sortt{8}));
230+
REQUIRE(function_application.get_sort() == smt_bit_vector_sortt{8});
231+
REQUIRE(function_application.arguments().size() == 2);
232+
REQUIRE(function_application.arguments()[0].get() == two);
233+
REQUIRE(function_application.arguments()[1].get() == three);
234+
}
222235
}

0 commit comments

Comments
 (0)