File tree Expand file tree Collapse file tree 5 files changed +88
-3
lines changed
src/solvers/smt2_incremental
unit/solvers/smt2_incremental Expand file tree Collapse file tree 5 files changed +88
-3
lines changed Original file line number Diff line number Diff line change @@ -401,9 +401,24 @@ static smt_termt convert_expr_to_smt(const ieee_float_op_exprt &float_operation)
401
401
402
402
static smt_termt convert_expr_to_smt (const mod_exprt &truncation_modulo)
403
403
{
404
- UNIMPLEMENTED_FEATURE (
405
- " Generation of SMT formula for truncation modulo expression: " +
406
- truncation_modulo.pretty ());
404
+ bool both_operands_bitvector =
405
+ can_cast_type<integer_bitvector_typet>(truncation_modulo.lhs ().type ()) &&
406
+ can_cast_type<integer_bitvector_typet>(truncation_modulo.rhs ().type ());
407
+
408
+ if (both_operands_bitvector)
409
+ {
410
+ return smt_bit_vector_theoryt::unsigned_remainder (
411
+ convert_expr_to_smt (truncation_modulo.lhs ()),
412
+ convert_expr_to_smt (truncation_modulo.rhs ()));
413
+ }
414
+ else
415
+ {
416
+ {
417
+ UNIMPLEMENTED_FEATURE (
418
+ " Generation of SMT formula for remainder (modulus) expression: " +
419
+ truncation_modulo.pretty ());
420
+ }
421
+ }
407
422
}
408
423
409
424
static smt_termt
Original file line number Diff line number Diff line change @@ -156,3 +156,26 @@ void smt_bit_vector_theoryt::signed_dividet::validate(
156
156
const smt_function_application_termt::factoryt<
157
157
smt_bit_vector_theoryt::signed_dividet>
158
158
smt_bit_vector_theoryt::signed_divide{};
159
+
160
+ const char *smt_bit_vector_theoryt::unsigned_remaindert::identifier ()
161
+ {
162
+ return " bvurem" ;
163
+ }
164
+
165
+ smt_sortt smt_bit_vector_theoryt::unsigned_remaindert::return_sort (
166
+ const smt_termt &lhs,
167
+ const smt_termt &rhs)
168
+ {
169
+ return lhs.get_sort ();
170
+ }
171
+
172
+ void smt_bit_vector_theoryt::unsigned_remaindert::validate (
173
+ const smt_termt &lhs,
174
+ const smt_termt &rhs)
175
+ {
176
+ validate_bit_vector_predicate_arguments (lhs, rhs);
177
+ }
178
+
179
+ const smt_function_application_termt::factoryt<
180
+ smt_bit_vector_theoryt::unsigned_remaindert>
181
+ smt_bit_vector_theoryt::unsigned_remainder{};
Original file line number Diff line number Diff line change @@ -62,6 +62,15 @@ class smt_bit_vector_theoryt
62
62
};
63
63
static const smt_function_application_termt::factoryt<signed_dividet>
64
64
signed_divide;
65
+
66
+ struct unsigned_remaindert final
67
+ {
68
+ static const char *identifier ();
69
+ static smt_sortt return_sort (const smt_termt &lhs, const smt_termt &rhs);
70
+ static void validate (const smt_termt &lhs, const smt_termt &rhs);
71
+ };
72
+ static const smt_function_application_termt::factoryt<unsigned_remaindert>
73
+ unsigned_remainder;
65
74
};
66
75
67
76
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H
Original file line number Diff line number Diff line change @@ -372,4 +372,23 @@ TEST_CASE(
372
372
const cbmc_invariants_should_throwt invariants_throw;
373
373
REQUIRE_THROWS (convert_expr_to_smt (div_exprt{one_bvint, false_exprt{}}));
374
374
}
375
+
376
+ SECTION (
377
+ " Unsigned remainder (modulus) from truncating division of two constant "
378
+ " size bit-vectors" )
379
+ {
380
+ const auto constructed_term =
381
+ convert_expr_to_smt (mod_exprt{one_bvint_unsigned, two_bvint_unsigned});
382
+ const auto expected_term =
383
+ smt_bit_vector_theoryt::unsigned_remainder (smt_term_one, smt_term_two);
384
+ CHECK (constructed_term == expected_term);
385
+ }
386
+
387
+ SECTION (
388
+ " Ensure that remainder (truncated modulo) node conversion fails if the "
389
+ " operands are not bit-vector based" )
390
+ {
391
+ const cbmc_invariants_should_throwt invariants_throw;
392
+ REQUIRE_THROWS (convert_expr_to_smt (mod_exprt{one_bvint, false_exprt{}}));
393
+ }
375
394
}
Original file line number Diff line number Diff line change @@ -269,4 +269,23 @@ TEST_CASE(
269
269
// A division of a bool and a bitvector should hit an invariant violation.
270
270
REQUIRE_THROWS (smt_bit_vector_theoryt::signed_divide (true_val, three));
271
271
}
272
+
273
+ SECTION (" Unsigned Remainder" )
274
+ {
275
+ const auto function_application =
276
+ smt_bit_vector_theoryt::unsigned_remainder (two, three);
277
+ REQUIRE (
278
+ function_application.function_identifier () ==
279
+ smt_identifier_termt (" bvurem" , smt_bit_vector_sortt{8 }));
280
+ REQUIRE (function_application.get_sort () == smt_bit_vector_sortt{8 });
281
+ REQUIRE (function_application.arguments ().size () == 2 );
282
+ REQUIRE (function_application.arguments ()[0 ].get () == two);
283
+ REQUIRE (function_application.arguments ()[1 ].get () == three);
284
+
285
+ cbmc_invariants_should_throwt invariants_throw;
286
+ // Bit-vectors of mismatched sorts are going to hit an invariant violation.
287
+ REQUIRE_THROWS (smt_bit_vector_theoryt::unsigned_remainder (three, four));
288
+ // A remainder of a bool and a bitvector should hit an invariant violation.
289
+ REQUIRE_THROWS (smt_bit_vector_theoryt::unsigned_remainder (true_val, three));
290
+ }
272
291
}
You can’t perform that action at this time.
0 commit comments