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 @@ -405,11 +405,24 @@ static smt_termt convert_expr_to_smt(const mod_exprt &truncation_modulo)
405
405
can_cast_type<integer_bitvector_typet>(truncation_modulo.lhs ().type ()) &&
406
406
can_cast_type<integer_bitvector_typet>(truncation_modulo.rhs ().type ());
407
407
408
+ const bool both_operands_unsigned =
409
+ can_cast_type<unsignedbv_typet>(truncation_modulo.lhs ().type ()) &&
410
+ can_cast_type<unsignedbv_typet>(truncation_modulo.rhs ().type ());
411
+
408
412
if (both_operands_bitvector)
409
413
{
410
- return smt_bit_vector_theoryt::unsigned_remainder (
411
- convert_expr_to_smt (truncation_modulo.lhs ()),
412
- convert_expr_to_smt (truncation_modulo.rhs ()));
414
+ if (both_operands_unsigned)
415
+ {
416
+ return smt_bit_vector_theoryt::unsigned_remainder (
417
+ convert_expr_to_smt (truncation_modulo.lhs ()),
418
+ convert_expr_to_smt (truncation_modulo.rhs ()));
419
+ }
420
+ else
421
+ {
422
+ return smt_bit_vector_theoryt::signed_remainder (
423
+ convert_expr_to_smt (truncation_modulo.lhs ()),
424
+ convert_expr_to_smt (truncation_modulo.rhs ()));
425
+ }
413
426
}
414
427
else
415
428
{
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 @@ -288,4 +288,23 @@ TEST_CASE(
288
288
// A remainder of a bool and a bitvector should hit an invariant violation.
289
289
REQUIRE_THROWS (smt_bit_vector_theoryt::unsigned_remainder (true_val, three));
290
290
}
291
+
292
+ SECTION (" Signed Remainder" )
293
+ {
294
+ const auto function_application =
295
+ smt_bit_vector_theoryt::signed_remainder (two, three);
296
+ REQUIRE (
297
+ function_application.function_identifier () ==
298
+ smt_identifier_termt (" bvsrem" , smt_bit_vector_sortt{8 }));
299
+ REQUIRE (function_application.get_sort () == smt_bit_vector_sortt{8 });
300
+ REQUIRE (function_application.arguments ().size () == 2 );
301
+ REQUIRE (function_application.arguments ()[0 ].get () == two);
302
+ REQUIRE (function_application.arguments ()[1 ].get () == three);
303
+
304
+ cbmc_invariants_should_throwt invariants_throw;
305
+ // Bit-vectors of mismatched sorts are going to hit an invariant violation.
306
+ REQUIRE_THROWS (smt_bit_vector_theoryt::signed_remainder (three, four));
307
+ // A remainder of a bool and a bitvector should hit an invariant violation.
308
+ REQUIRE_THROWS (smt_bit_vector_theoryt::signed_remainder (true_val, three));
309
+ }
291
310
}
You can’t perform that action at this time.
0 commit comments