File tree Expand file tree Collapse file tree 5 files changed +84
-2
lines changed
src/solvers/smt2_incremental
unit/solvers/smt2_incremental Expand file tree Collapse file tree 5 files changed +84
-2
lines changed Original file line number Diff line number Diff line change @@ -361,8 +361,20 @@ static smt_termt convert_expr_to_smt(const minus_exprt &minus)
361361
362362static smt_termt convert_expr_to_smt (const div_exprt ÷)
363363{
364- UNIMPLEMENTED_FEATURE (
365- " Generation of SMT formula for divide expression: " + divide.pretty ());
364+ const bool both_operands_bitvector =
365+ can_cast_type<integer_bitvector_typet>(divide.lhs ().type ()) &&
366+ can_cast_type<integer_bitvector_typet>(divide.rhs ().type ());
367+
368+ if (both_operands_bitvector)
369+ {
370+ return smt_bit_vector_theoryt::unsigned_divide (
371+ convert_expr_to_smt (divide.lhs ()), convert_expr_to_smt (divide.rhs ()));
372+ }
373+ else
374+ {
375+ UNIMPLEMENTED_FEATURE (
376+ " Generation of SMT formula for divide expression: " + divide.pretty ());
377+ }
366378}
367379
368380static smt_termt convert_expr_to_smt (const ieee_float_op_exprt &float_operation)
Original file line number Diff line number Diff line change @@ -273,3 +273,26 @@ void smt_bit_vector_theoryt::multiplyt::validate(
273273const smt_function_application_termt::factoryt<
274274 smt_bit_vector_theoryt::multiplyt>
275275 smt_bit_vector_theoryt::multiply{};
276+
277+ const char *smt_bit_vector_theoryt::unsigned_dividet::identifier ()
278+ {
279+ return " bvudiv" ;
280+ }
281+
282+ smt_sortt smt_bit_vector_theoryt::unsigned_dividet::return_sort (
283+ const smt_termt &lhs,
284+ const smt_termt &rhs)
285+ {
286+ return lhs.get_sort ();
287+ }
288+
289+ void smt_bit_vector_theoryt::unsigned_dividet::validate (
290+ const smt_termt &lhs,
291+ const smt_termt &rhs)
292+ {
293+ validate_bit_vector_predicate_arguments (lhs, rhs);
294+ }
295+
296+ const smt_function_application_termt::factoryt<
297+ smt_bit_vector_theoryt::unsigned_dividet>
298+ smt_bit_vector_theoryt::unsigned_divide{};
Original file line number Diff line number Diff line change @@ -108,6 +108,15 @@ class smt_bit_vector_theoryt
108108 static void validate (const smt_termt &lhs, const smt_termt &rhs);
109109 };
110110 static const smt_function_application_termt::factoryt<multiplyt> multiply;
111+
112+ struct unsigned_dividet final
113+ {
114+ static const char *identifier ();
115+ static smt_sortt return_sort (const smt_termt &lhs, const smt_termt &rhs);
116+ static void validate (const smt_termt &lhs, const smt_termt &rhs);
117+ };
118+ static const smt_function_application_termt::factoryt<unsigned_dividet>
119+ unsigned_divide;
111120};
112121
113122#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H
Original file line number Diff line number Diff line change @@ -345,4 +345,23 @@ TEST_CASE(
345345 const cbmc_invariants_should_throwt invariants_throw;
346346 REQUIRE_THROWS (convert_expr_to_smt (mult_exprt{one_bvint, false_exprt{}}));
347347 }
348+
349+ // Division is defined over unsigned numbers only (theory notes say it
350+ // truncates over zero)
351+ SECTION (" Division of two constant size bit-vectors" )
352+ {
353+ const auto constructed_term =
354+ convert_expr_to_smt (div_exprt{one_bvint_unsigned, two_bvint_unsigned});
355+ const auto expected_term =
356+ smt_bit_vector_theoryt::unsigned_divide (smt_term_one, smt_term_two);
357+ CHECK (constructed_term == expected_term);
358+ }
359+
360+ SECTION (
361+ " Ensure that division node conversion fails if the operands are not "
362+ " bit-vector based" )
363+ {
364+ const cbmc_invariants_should_throwt invariants_throw;
365+ REQUIRE_THROWS (convert_expr_to_smt (div_exprt{one_bvint, false_exprt{}}));
366+ }
348367}
Original file line number Diff line number Diff line change @@ -233,4 +233,23 @@ TEST_CASE(
233233 // invariant violation.
234234 REQUIRE_THROWS (smt_bit_vector_theoryt::multiply (true_val, three));
235235 }
236+
237+ SECTION (" Unsigned Division" )
238+ {
239+ const auto function_application =
240+ smt_bit_vector_theoryt::unsigned_divide (two, three);
241+ REQUIRE (
242+ function_application.function_identifier () ==
243+ smt_identifier_termt (" bvudiv" , smt_bit_vector_sortt{8 }));
244+ REQUIRE (function_application.get_sort () == smt_bit_vector_sortt{8 });
245+ REQUIRE (function_application.arguments ().size () == 2 );
246+ REQUIRE (function_application.arguments ()[0 ].get () == two);
247+ REQUIRE (function_application.arguments ()[1 ].get () == three);
248+
249+ cbmc_invariants_should_throwt invariants_throw;
250+ // Bit-vectors of mismatched sorts are going to hit an invariant violation.
251+ REQUIRE_THROWS (smt_bit_vector_theoryt::unsigned_divide (three, four));
252+ // A division of a bool and a bitvector should hit an invariant violation.
253+ REQUIRE_THROWS (smt_bit_vector_theoryt::unsigned_divide (true_val, three));
254+ }
236255}
You can’t perform that action at this time.
0 commit comments