File tree 5 files changed +76
-4
lines changed
src/solvers/smt2_incremental
unit/solvers/smt2_incremental 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)
404
404
can_cast_type<integer_bitvector_typet>(truncation_modulo.lhs ().type ()) &&
405
405
can_cast_type<integer_bitvector_typet>(truncation_modulo.rhs ().type ());
406
406
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
+
407
411
if (both_operands_bitvector)
408
412
{
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
+ }
412
425
}
413
426
else
414
427
{
Original file line number Diff line number Diff line change @@ -342,3 +342,26 @@ void smt_bit_vector_theoryt::unsigned_remaindert::validate(
342
342
const smt_function_application_termt::factoryt<
343
343
smt_bit_vector_theoryt::unsigned_remaindert>
344
344
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
135
135
};
136
136
static const smt_function_application_termt::factoryt<unsigned_remaindert>
137
137
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;
138
147
};
139
148
140
149
#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(
374
374
}
375
375
376
376
SECTION (
377
- " Unsigned remainder (modulus) from truncating division of two constant "
377
+ " Remainder (modulus) from truncating division of two constant "
378
378
" size bit-vectors" )
379
379
{
380
+ // Remainder expression with unsigned operands.
380
381
const auto constructed_term =
381
382
convert_expr_to_smt (mod_exprt{one_bvint_unsigned, two_bvint_unsigned});
382
383
const auto expected_term =
383
384
smt_bit_vector_theoryt::unsigned_remainder (smt_term_one, smt_term_two);
384
385
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);
385
393
}
386
394
387
395
SECTION (
Original file line number Diff line number Diff line change @@ -290,4 +290,23 @@ TEST_CASE(
290
290
// A remainder of a bool and a bitvector should hit an invariant violation.
291
291
REQUIRE_THROWS (smt_bit_vector_theoryt::unsigned_remainder (true_val, three));
292
292
}
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
+ }
293
312
}
You can’t perform that action at this time.
0 commit comments