File tree Expand file tree Collapse file tree 5 files changed +84
-2
lines changed
src/solvers/smt2_incremental
unit/solvers/smt2_incremental Expand file tree Collapse file tree 5 files changed +84
-2
lines changed Original file line number Diff line number Diff line change @@ -361,8 +361,20 @@ static smt_termt convert_expr_to_smt(const minus_exprt &minus)
361
361
362
362
static smt_termt convert_expr_to_smt (const div_exprt ÷)
363
363
{
364
- UNIMPLEMENTED_FEATURE (
365
- " Generation of SMT formula for divide expression: " + divide.pretty ());
364
+ const bool both_operands_bitvector =
365
+ can_cast_type<integer_bitvector_typet>(divide.lhs ().type ()) &&
366
+ can_cast_type<integer_bitvector_typet>(divide.rhs ().type ());
367
+
368
+ if (both_operands_bitvector)
369
+ {
370
+ return smt_bit_vector_theoryt::unsigned_divide (
371
+ convert_expr_to_smt (divide.lhs ()), convert_expr_to_smt (divide.rhs ()));
372
+ }
373
+ else
374
+ {
375
+ UNIMPLEMENTED_FEATURE (
376
+ " Generation of SMT formula for divide expression: " + divide.pretty ());
377
+ }
366
378
}
367
379
368
380
static smt_termt convert_expr_to_smt (const ieee_float_op_exprt &float_operation)
Original file line number Diff line number Diff line change @@ -273,3 +273,26 @@ void smt_bit_vector_theoryt::multiplyt::validate(
273
273
const smt_function_application_termt::factoryt<
274
274
smt_bit_vector_theoryt::multiplyt>
275
275
smt_bit_vector_theoryt::multiply{};
276
+
277
+ const char *smt_bit_vector_theoryt::unsigned_dividet::identifier ()
278
+ {
279
+ return " bvudiv" ;
280
+ }
281
+
282
+ smt_sortt smt_bit_vector_theoryt::unsigned_dividet::return_sort (
283
+ const smt_termt &lhs,
284
+ const smt_termt &rhs)
285
+ {
286
+ return lhs.get_sort ();
287
+ }
288
+
289
+ void smt_bit_vector_theoryt::unsigned_dividet::validate (
290
+ const smt_termt &lhs,
291
+ const smt_termt &rhs)
292
+ {
293
+ validate_bit_vector_predicate_arguments (lhs, rhs);
294
+ }
295
+
296
+ const smt_function_application_termt::factoryt<
297
+ smt_bit_vector_theoryt::unsigned_dividet>
298
+ smt_bit_vector_theoryt::unsigned_divide{};
Original file line number Diff line number Diff line change @@ -108,6 +108,15 @@ class smt_bit_vector_theoryt
108
108
static void validate (const smt_termt &lhs, const smt_termt &rhs);
109
109
};
110
110
static const smt_function_application_termt::factoryt<multiplyt> multiply;
111
+
112
+ struct unsigned_dividet final
113
+ {
114
+ static const char *identifier ();
115
+ static smt_sortt return_sort (const smt_termt &lhs, const smt_termt &rhs);
116
+ static void validate (const smt_termt &lhs, const smt_termt &rhs);
117
+ };
118
+ static const smt_function_application_termt::factoryt<unsigned_dividet>
119
+ unsigned_divide;
111
120
};
112
121
113
122
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H
Original file line number Diff line number Diff line change @@ -345,4 +345,23 @@ TEST_CASE(
345
345
const cbmc_invariants_should_throwt invariants_throw;
346
346
REQUIRE_THROWS (convert_expr_to_smt (mult_exprt{one_bvint, false_exprt{}}));
347
347
}
348
+
349
+ // Division is defined over unsigned numbers only (theory notes say it
350
+ // truncates over zero)
351
+ SECTION (" Division of two constant size bit-vectors" )
352
+ {
353
+ const auto constructed_term =
354
+ convert_expr_to_smt (div_exprt{one_bvint_unsigned, two_bvint_unsigned});
355
+ const auto expected_term =
356
+ smt_bit_vector_theoryt::unsigned_divide (smt_term_one, smt_term_two);
357
+ CHECK (constructed_term == expected_term);
358
+ }
359
+
360
+ SECTION (
361
+ " Ensure that division node conversion fails if the operands are not "
362
+ " bit-vector based" )
363
+ {
364
+ const cbmc_invariants_should_throwt invariants_throw;
365
+ REQUIRE_THROWS (convert_expr_to_smt (div_exprt{one_bvint, false_exprt{}}));
366
+ }
348
367
}
Original file line number Diff line number Diff line change @@ -233,4 +233,23 @@ TEST_CASE(
233
233
// invariant violation.
234
234
REQUIRE_THROWS (smt_bit_vector_theoryt::multiply (true_val, three));
235
235
}
236
+
237
+ SECTION (" Unsigned Division" )
238
+ {
239
+ const auto function_application =
240
+ smt_bit_vector_theoryt::unsigned_divide (two, three);
241
+ REQUIRE (
242
+ function_application.function_identifier () ==
243
+ smt_identifier_termt (" bvudiv" , smt_bit_vector_sortt{8 }));
244
+ REQUIRE (function_application.get_sort () == smt_bit_vector_sortt{8 });
245
+ REQUIRE (function_application.arguments ().size () == 2 );
246
+ REQUIRE (function_application.arguments ()[0 ].get () == two);
247
+ REQUIRE (function_application.arguments ()[1 ].get () == three);
248
+
249
+ cbmc_invariants_should_throwt invariants_throw;
250
+ // Bit-vectors of mismatched sorts are going to hit an invariant violation.
251
+ REQUIRE_THROWS (smt_bit_vector_theoryt::unsigned_divide (three, four));
252
+ // A division of a bool and a bitvector should hit an invariant violation.
253
+ REQUIRE_THROWS (smt_bit_vector_theoryt::unsigned_divide (true_val, three));
254
+ }
236
255
}
You can’t perform that action at this time.
0 commit comments