File tree Expand file tree Collapse file tree 5 files changed +76
-4
lines changed
src/solvers/smt2_incremental
unit/solvers/smt2_incremental Expand file tree Collapse file tree 5 files changed +76
-4
lines changed Original file line number Diff line number Diff line change @@ -404,11 +404,24 @@ static smt_termt convert_expr_to_smt(const mod_exprt &truncation_modulo)
404404 can_cast_type<integer_bitvector_typet>(truncation_modulo.lhs ().type ()) &&
405405 can_cast_type<integer_bitvector_typet>(truncation_modulo.rhs ().type ());
406406
407+ const bool both_operands_unsigned =
408+ can_cast_type<unsignedbv_typet>(truncation_modulo.lhs ().type ()) &&
409+ can_cast_type<unsignedbv_typet>(truncation_modulo.rhs ().type ());
410+
407411 if (both_operands_bitvector)
408412 {
409- return smt_bit_vector_theoryt::unsigned_remainder (
410- convert_expr_to_smt (truncation_modulo.lhs ()),
411- convert_expr_to_smt (truncation_modulo.rhs ()));
413+ if (both_operands_unsigned)
414+ {
415+ return smt_bit_vector_theoryt::unsigned_remainder (
416+ convert_expr_to_smt (truncation_modulo.lhs ()),
417+ convert_expr_to_smt (truncation_modulo.rhs ()));
418+ }
419+ else
420+ {
421+ return smt_bit_vector_theoryt::signed_remainder (
422+ convert_expr_to_smt (truncation_modulo.lhs ()),
423+ convert_expr_to_smt (truncation_modulo.rhs ()));
424+ }
412425 }
413426 else
414427 {
Original file line number Diff line number Diff line change @@ -342,3 +342,26 @@ void smt_bit_vector_theoryt::unsigned_remaindert::validate(
342342const smt_function_application_termt::factoryt<
343343 smt_bit_vector_theoryt::unsigned_remaindert>
344344 smt_bit_vector_theoryt::unsigned_remainder{};
345+
346+ const char *smt_bit_vector_theoryt::signed_remaindert::identifier ()
347+ {
348+ return " bvsrem" ;
349+ }
350+
351+ smt_sortt smt_bit_vector_theoryt::signed_remaindert::return_sort (
352+ const smt_termt &lhs,
353+ const smt_termt &rhs)
354+ {
355+ return lhs.get_sort ();
356+ }
357+
358+ void smt_bit_vector_theoryt::signed_remaindert::validate (
359+ const smt_termt &lhs,
360+ const smt_termt &rhs)
361+ {
362+ validate_bit_vector_predicate_arguments (lhs, rhs);
363+ }
364+
365+ const smt_function_application_termt::factoryt<
366+ smt_bit_vector_theoryt::signed_remaindert>
367+ smt_bit_vector_theoryt::signed_remainder{};
Original file line number Diff line number Diff line change @@ -135,6 +135,15 @@ class smt_bit_vector_theoryt
135135 };
136136 static const smt_function_application_termt::factoryt<unsigned_remaindert>
137137 unsigned_remainder;
138+
139+ struct signed_remaindert final
140+ {
141+ static const char *identifier ();
142+ static smt_sortt return_sort (const smt_termt &lhs, const smt_termt &rhs);
143+ static void validate (const smt_termt &lhs, const smt_termt &rhs);
144+ };
145+ static const smt_function_application_termt::factoryt<signed_remaindert>
146+ signed_remainder;
138147};
139148
140149#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H
Original file line number Diff line number Diff line change @@ -374,14 +374,22 @@ TEST_CASE(
374374 }
375375
376376 SECTION (
377- " Unsigned remainder (modulus) from truncating division of two constant "
377+ " Remainder (modulus) from truncating division of two constant "
378378 " size bit-vectors" )
379379 {
380+ // Remainder expression with unsigned operands.
380381 const auto constructed_term =
381382 convert_expr_to_smt (mod_exprt{one_bvint_unsigned, two_bvint_unsigned});
382383 const auto expected_term =
383384 smt_bit_vector_theoryt::unsigned_remainder (smt_term_one, smt_term_two);
384385 CHECK (constructed_term == expected_term);
386+
387+ // Remainder expression with signed operands
388+ const auto constructed_term_signed =
389+ convert_expr_to_smt (mod_exprt{one_bvint, two_bvint});
390+ const auto expected_term_signed =
391+ smt_bit_vector_theoryt::signed_remainder (smt_term_one, smt_term_two);
392+ CHECK (constructed_term_signed == expected_term_signed);
385393 }
386394
387395 SECTION (
Original file line number Diff line number Diff line change @@ -290,4 +290,23 @@ TEST_CASE(
290290 // A remainder of a bool and a bitvector should hit an invariant violation.
291291 REQUIRE_THROWS (smt_bit_vector_theoryt::unsigned_remainder (true_val, three));
292292 }
293+
294+ SECTION (" Signed Remainder" )
295+ {
296+ const auto function_application =
297+ smt_bit_vector_theoryt::signed_remainder (two, three);
298+ REQUIRE (
299+ function_application.function_identifier () ==
300+ smt_identifier_termt (" bvsrem" , smt_bit_vector_sortt{8 }));
301+ REQUIRE (function_application.get_sort () == smt_bit_vector_sortt{8 });
302+ REQUIRE (function_application.arguments ().size () == 2 );
303+ REQUIRE (function_application.arguments ()[0 ].get () == two);
304+ REQUIRE (function_application.arguments ()[1 ].get () == three);
305+
306+ cbmc_invariants_should_throwt invariants_throw;
307+ // Bit-vectors of mismatched sorts are going to hit an invariant violation.
308+ REQUIRE_THROWS (smt_bit_vector_theoryt::signed_remainder (three, four));
309+ // A remainder of a bool and a bitvector should hit an invariant violation.
310+ REQUIRE_THROWS (smt_bit_vector_theoryt::signed_remainder (true_val, three));
311+ }
293312}
You can’t perform that action at this time.
0 commit comments