File tree 5 files changed +86
-3
lines changed
src/solvers/smt2_incremental
unit/solvers/smt2_incremental 5 files changed +86
-3
lines changed Original file line number Diff line number Diff line change @@ -400,9 +400,22 @@ static smt_termt convert_expr_to_smt(const ieee_float_op_exprt &float_operation)
400
400
401
401
static smt_termt convert_expr_to_smt (const mod_exprt &truncation_modulo)
402
402
{
403
- UNIMPLEMENTED_FEATURE (
404
- " Generation of SMT formula for truncation modulo expression: " +
405
- truncation_modulo.pretty ());
403
+ const bool both_operands_bitvector =
404
+ can_cast_type<integer_bitvector_typet>(truncation_modulo.lhs ().type ()) &&
405
+ can_cast_type<integer_bitvector_typet>(truncation_modulo.rhs ().type ());
406
+
407
+ if (both_operands_bitvector)
408
+ {
409
+ return smt_bit_vector_theoryt::unsigned_remainder (
410
+ convert_expr_to_smt (truncation_modulo.lhs ()),
411
+ convert_expr_to_smt (truncation_modulo.rhs ()));
412
+ }
413
+ else
414
+ {
415
+ UNIMPLEMENTED_FEATURE (
416
+ " Generation of SMT formula for remainder (modulus) expression: " +
417
+ truncation_modulo.pretty ());
418
+ }
406
419
}
407
420
408
421
static smt_termt
Original file line number Diff line number Diff line change @@ -319,3 +319,26 @@ void smt_bit_vector_theoryt::signed_dividet::validate(
319
319
const smt_function_application_termt::factoryt<
320
320
smt_bit_vector_theoryt::signed_dividet>
321
321
smt_bit_vector_theoryt::signed_divide{};
322
+
323
+ const char *smt_bit_vector_theoryt::unsigned_remaindert::identifier ()
324
+ {
325
+ return " bvurem" ;
326
+ }
327
+
328
+ smt_sortt smt_bit_vector_theoryt::unsigned_remaindert::return_sort (
329
+ const smt_termt &lhs,
330
+ const smt_termt &rhs)
331
+ {
332
+ return lhs.get_sort ();
333
+ }
334
+
335
+ void smt_bit_vector_theoryt::unsigned_remaindert::validate (
336
+ const smt_termt &lhs,
337
+ const smt_termt &rhs)
338
+ {
339
+ validate_bit_vector_predicate_arguments (lhs, rhs);
340
+ }
341
+
342
+ const smt_function_application_termt::factoryt<
343
+ smt_bit_vector_theoryt::unsigned_remaindert>
344
+ smt_bit_vector_theoryt::unsigned_remainder{};
Original file line number Diff line number Diff line change @@ -126,6 +126,15 @@ class smt_bit_vector_theoryt
126
126
};
127
127
static const smt_function_application_termt::factoryt<signed_dividet>
128
128
signed_divide;
129
+
130
+ struct unsigned_remaindert final
131
+ {
132
+ static const char *identifier ();
133
+ static smt_sortt return_sort (const smt_termt &lhs, const smt_termt &rhs);
134
+ static void validate (const smt_termt &lhs, const smt_termt &rhs);
135
+ };
136
+ static const smt_function_application_termt::factoryt<unsigned_remaindert>
137
+ unsigned_remainder;
129
138
};
130
139
131
140
#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 @@ -271,4 +271,23 @@ TEST_CASE(
271
271
// A division of a bool and a bitvector should hit an invariant violation.
272
272
REQUIRE_THROWS (smt_bit_vector_theoryt::signed_divide (true_val, three));
273
273
}
274
+
275
+ SECTION (" Unsigned Remainder" )
276
+ {
277
+ const auto function_application =
278
+ smt_bit_vector_theoryt::unsigned_remainder (two, three);
279
+ REQUIRE (
280
+ function_application.function_identifier () ==
281
+ smt_identifier_termt (" bvurem" , smt_bit_vector_sortt{8 }));
282
+ REQUIRE (function_application.get_sort () == smt_bit_vector_sortt{8 });
283
+ REQUIRE (function_application.arguments ().size () == 2 );
284
+ REQUIRE (function_application.arguments ()[0 ].get () == two);
285
+ REQUIRE (function_application.arguments ()[1 ].get () == three);
286
+
287
+ cbmc_invariants_should_throwt invariants_throw;
288
+ // Bit-vectors of mismatched sorts are going to hit an invariant violation.
289
+ REQUIRE_THROWS (smt_bit_vector_theoryt::unsigned_remainder (three, four));
290
+ // A remainder of a bool and a bitvector should hit an invariant violation.
291
+ REQUIRE_THROWS (smt_bit_vector_theoryt::unsigned_remainder (true_val, three));
292
+ }
274
293
}
You can’t perform that action at this time.
0 commit comments