Skip to content

Commit 6aadc83

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

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

364364
static smt_termt convert_expr_to_smt(const div_exprt &divide)
365365
{
366-
UNIMPLEMENTED_FEATURE(
367-
"Generation of SMT formula for divide expression: " + divide.pretty());
366+
PRECONDITION(can_cast_type<bitvector_typet>(divide.lhs().type()));
367+
PRECONDITION(can_cast_type<bitvector_typet>(divide.rhs().type()));
368+
return smt_bit_vector_theoryt::division(
369+
convert_expr_to_smt(divide.lhs()), convert_expr_to_smt(divide.rhs()));
368370
}
369371

370372
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
@@ -114,3 +114,29 @@ void smt_bit_vector_theoryt::multiplicationt::validate(
114114
const smt_function_application_termt::factoryt<
115115
smt_bit_vector_theoryt::multiplicationt>
116116
smt_bit_vector_theoryt::multiplication{};
117+
118+
const char *smt_bit_vector_theoryt::divisiont::identifier()
119+
{
120+
return "bvdiv";
121+
}
122+
123+
smt_sortt smt_bit_vector_theoryt::divisiont::return_sort(
124+
const smt_termt &lhs,
125+
const smt_termt &rhs)
126+
{
127+
// For now, make sure that they have the same bit-width
128+
divisiont::validate(lhs, rhs);
129+
const auto width = lhs.get_sort().cast<smt_bit_vector_sortt>()->bit_width();
130+
return smt_bit_vector_sortt{width};
131+
}
132+
133+
void smt_bit_vector_theoryt::divisiont::validate(
134+
const smt_termt &lhs,
135+
const smt_termt &rhs)
136+
{
137+
validate_bit_vector_predicate_arguments(lhs, rhs);
138+
}
139+
140+
const smt_function_application_termt::factoryt<
141+
smt_bit_vector_theoryt::divisiont>
142+
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
@@ -45,6 +45,14 @@ class smt_bit_vector_theoryt
4545
};
4646
static const smt_function_application_termt::factoryt<multiplicationt>
4747
multiplication;
48+
49+
struct divisiont final
50+
{
51+
static const char *identifier();
52+
static smt_sortt return_sort(const smt_termt &lhs, const smt_termt &rhs);
53+
static void validate(const smt_termt &lhs, const smt_termt &rhs);
54+
};
55+
static const smt_function_application_termt::factoryt<divisiont> division;
4856
};
4957

5058
#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
@@ -225,4 +225,17 @@ TEST_CASE(
225225
REQUIRE(function_application.arguments()[0].get() == two);
226226
REQUIRE(function_application.arguments()[1].get() == three);
227227
}
228+
229+
SECTION("Division")
230+
{
231+
const auto function_application =
232+
smt_bit_vector_theoryt::division(two, three);
233+
REQUIRE(
234+
function_application.function_identifier() ==
235+
smt_identifier_termt("bvdiv", smt_bit_vector_sortt{8}));
236+
REQUIRE(function_application.get_sort() == smt_bit_vector_sortt{8});
237+
REQUIRE(function_application.arguments().size() == 2);
238+
REQUIRE(function_application.arguments()[0].get() == two);
239+
REQUIRE(function_application.arguments()[1].get() == three);
240+
}
228241
}

0 commit comments

Comments
 (0)