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 @@ -391,8 +391,22 @@ convert_expr_to_smt(const euclidean_mod_exprt &euclidean_modulo)
391
391
392
392
static smt_termt convert_expr_to_smt (const mult_exprt &multiply)
393
393
{
394
- UNIMPLEMENTED_FEATURE (
395
- " Generation of SMT formula for multiply expression: " + multiply.pretty ());
394
+ if (std::all_of (
395
+ multiply.operands ().cbegin (),
396
+ multiply.operands ().cend (),
397
+ [](exprt operand) {
398
+ return can_cast_type<integer_bitvector_typet>(operand.type ());
399
+ }))
400
+ {
401
+ return convert_multiary_operator_to_terms (
402
+ multiply, smt_bit_vector_theoryt::multiply);
403
+ }
404
+ else
405
+ {
406
+ UNIMPLEMENTED_FEATURE (
407
+ " Generation of SMT formula for multiply expression: " +
408
+ multiply.pretty ());
409
+ }
396
410
}
397
411
398
412
static smt_termt convert_expr_to_smt (const address_of_exprt &address_of)
Original file line number Diff line number Diff line change @@ -250,3 +250,26 @@ void smt_bit_vector_theoryt::subtractt::validate(
250
250
const smt_function_application_termt::factoryt<
251
251
smt_bit_vector_theoryt::subtractt>
252
252
smt_bit_vector_theoryt::subtract{};
253
+
254
+ const char *smt_bit_vector_theoryt::multiplyt::identifier ()
255
+ {
256
+ return " bvmul" ;
257
+ }
258
+
259
+ smt_sortt smt_bit_vector_theoryt::multiplyt::return_sort (
260
+ const smt_termt &lhs,
261
+ const smt_termt &rhs)
262
+ {
263
+ return lhs.get_sort ();
264
+ }
265
+
266
+ void smt_bit_vector_theoryt::multiplyt::validate (
267
+ const smt_termt &lhs,
268
+ const smt_termt &rhs)
269
+ {
270
+ validate_bit_vector_predicate_arguments (lhs, rhs);
271
+ }
272
+
273
+ const smt_function_application_termt::factoryt<
274
+ smt_bit_vector_theoryt::multiplyt>
275
+ smt_bit_vector_theoryt::multiply{};
Original file line number Diff line number Diff line change @@ -100,6 +100,14 @@ class smt_bit_vector_theoryt
100
100
static void validate (const smt_termt &lhs, const smt_termt &rhs);
101
101
};
102
102
static const smt_function_application_termt::factoryt<subtractt> subtract;
103
+
104
+ struct multiplyt final
105
+ {
106
+ static const char *identifier ();
107
+ static smt_sortt return_sort (const smt_termt &lhs, const smt_termt &rhs);
108
+ static void validate (const smt_termt &lhs, const smt_termt &rhs);
109
+ };
110
+ static const smt_function_application_termt::factoryt<multiplyt> multiply;
103
111
};
104
112
105
113
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H
Original file line number Diff line number Diff line change @@ -328,4 +328,21 @@ TEST_CASE(
328
328
REQUIRE_THROWS (
329
329
convert_expr_to_smt (minus_exprt{true_exprt{}, false_exprt{}}));
330
330
}
331
+
332
+ SECTION (" Multiplication of two constant size bit-vectors" )
333
+ {
334
+ const auto constructed_term =
335
+ convert_expr_to_smt (mult_exprt{one_bvint, two_bvint});
336
+ const auto expected_term =
337
+ smt_bit_vector_theoryt::multiply (smt_term_one, smt_term_two);
338
+ CHECK (constructed_term == expected_term);
339
+ }
340
+
341
+ SECTION (
342
+ " Ensure that multiplication node conversion fails if the operands are not "
343
+ " bit-vector based" )
344
+ {
345
+ const cbmc_invariants_should_throwt invariants_throw;
346
+ REQUIRE_THROWS (convert_expr_to_smt (mult_exprt{one_bvint, false_exprt{}}));
347
+ }
331
348
}
Original file line number Diff line number Diff line change @@ -213,4 +213,24 @@ TEST_CASE(
213
213
// invariant violation.
214
214
REQUIRE_THROWS (smt_bit_vector_theoryt::subtract (true_val, three));
215
215
}
216
+
217
+ SECTION (" Multiplication" )
218
+ {
219
+ const auto function_application =
220
+ smt_bit_vector_theoryt::multiply (two, three);
221
+ REQUIRE (
222
+ function_application.function_identifier () ==
223
+ smt_identifier_termt (" bvmul" , smt_bit_vector_sortt{8 }));
224
+ REQUIRE (function_application.get_sort () == smt_bit_vector_sortt{8 });
225
+ REQUIRE (function_application.arguments ().size () == 2 );
226
+ REQUIRE (function_application.arguments ()[0 ].get () == two);
227
+ REQUIRE (function_application.arguments ()[1 ].get () == three);
228
+
229
+ cbmc_invariants_should_throwt invariants_throw;
230
+ // Bit-vectors of mismatched sorts are going to hit an invariant violation.
231
+ REQUIRE_THROWS (smt_bit_vector_theoryt::multiply (three, four));
232
+ // A multiplication of a bool and a bitvector should hit an
233
+ // invariant violation.
234
+ REQUIRE_THROWS (smt_bit_vector_theoryt::multiply (true_val, three));
235
+ }
216
236
}
You can’t perform that action at this time.
0 commit comments