File tree Expand file tree Collapse file tree 5 files changed +70
-2
lines changed
src/solvers/smt2_incremental
unit/solvers/smt2_incremental Expand file tree Collapse file tree 5 files changed +70
-2
lines changed Original file line number Diff line number Diff line change @@ -363,8 +363,10 @@ static smt_termt convert_expr_to_smt(const minus_exprt &minus)
363
363
364
364
static smt_termt convert_expr_to_smt (const div_exprt ÷)
365
365
{
366
- UNIMPLEMENTED_FEATURE (
367
- " Generation of SMT formula for divide expression: " + divide.pretty ());
366
+ PRECONDITION (can_cast_type<bitvector_typet>(divide.lhs ().type ()));
367
+ PRECONDITION (can_cast_type<bitvector_typet>(divide.rhs ().type ()));
368
+ return smt_bit_vector_theoryt::division (
369
+ convert_expr_to_smt (divide.lhs ()), convert_expr_to_smt (divide.rhs ()));
368
370
}
369
371
370
372
static smt_termt convert_expr_to_smt (const ieee_float_op_exprt &float_operation)
Original file line number Diff line number Diff line change @@ -114,3 +114,29 @@ void smt_bit_vector_theoryt::multiplicationt::validate(
114
114
const smt_function_application_termt::factoryt<
115
115
smt_bit_vector_theoryt::multiplicationt>
116
116
smt_bit_vector_theoryt::multiplication{};
117
+
118
+ const char *smt_bit_vector_theoryt::divisiont::identifier ()
119
+ {
120
+ return " bvdiv" ;
121
+ }
122
+
123
+ smt_sortt smt_bit_vector_theoryt::divisiont::return_sort (
124
+ const smt_termt &lhs,
125
+ const smt_termt &rhs)
126
+ {
127
+ // For now, make sure that they have the same bit-width
128
+ divisiont::validate (lhs, rhs);
129
+ const auto width = lhs.get_sort ().cast <smt_bit_vector_sortt>()->bit_width ();
130
+ return smt_bit_vector_sortt{width};
131
+ }
132
+
133
+ void smt_bit_vector_theoryt::divisiont::validate (
134
+ const smt_termt &lhs,
135
+ const smt_termt &rhs)
136
+ {
137
+ validate_bit_vector_predicate_arguments (lhs, rhs);
138
+ }
139
+
140
+ const smt_function_application_termt::factoryt<
141
+ smt_bit_vector_theoryt::divisiont>
142
+ smt_bit_vector_theoryt::division{};
Original file line number Diff line number Diff line change @@ -45,6 +45,14 @@ class smt_bit_vector_theoryt
45
45
};
46
46
static const smt_function_application_termt::factoryt<multiplicationt>
47
47
multiplication;
48
+
49
+ struct divisiont final
50
+ {
51
+ static const char *identifier ();
52
+ static smt_sortt return_sort (const smt_termt &lhs, const smt_termt &rhs);
53
+ static void validate (const smt_termt &lhs, const smt_termt &rhs);
54
+ };
55
+ static const smt_function_application_termt::factoryt<divisiont> division;
48
56
};
49
57
50
58
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H
Original file line number Diff line number Diff line change @@ -338,4 +338,23 @@ TEST_CASE(
338
338
const cbmc_invariants_should_throwt invariants_throw;
339
339
REQUIRE_THROWS (convert_expr_to_smt (mult_exprt{one_bvint, false_exprt{}}));
340
340
}
341
+
342
+ // Division is defined over unsigned numbers only (theory notes say it
343
+ // truncates over zero)
344
+ SECTION (" Division of two constant size bit-vectors" )
345
+ {
346
+ const auto constructed_term =
347
+ convert_expr_to_smt (div_exprt{one_bvint_unsigned, two_bvint_unsigned});
348
+ const auto expected_term =
349
+ smt_bit_vector_theoryt::division (smt_term_one, smt_term_two);
350
+ CHECK (constructed_term == expected_term);
351
+ }
352
+
353
+ SECTION (
354
+ " Ensure that division node conversion fails if the operands are not "
355
+ " bit-vector based" )
356
+ {
357
+ const cbmc_invariants_should_throwt invariants_throw;
358
+ REQUIRE_THROWS (convert_expr_to_smt (div_exprt{one_bvint, false_exprt{}}));
359
+ }
341
360
}
Original file line number Diff line number Diff line change @@ -225,4 +225,17 @@ TEST_CASE(
225
225
REQUIRE (function_application.arguments ()[0 ].get () == two);
226
226
REQUIRE (function_application.arguments ()[1 ].get () == three);
227
227
}
228
+
229
+ SECTION (" Division" )
230
+ {
231
+ const auto function_application =
232
+ smt_bit_vector_theoryt::division (two, three);
233
+ REQUIRE (
234
+ function_application.function_identifier () ==
235
+ smt_identifier_termt (" bvdiv" , smt_bit_vector_sortt{8 }));
236
+ REQUIRE (function_application.get_sort () == smt_bit_vector_sortt{8 });
237
+ REQUIRE (function_application.arguments ().size () == 2 );
238
+ REQUIRE (function_application.arguments ()[0 ].get () == two);
239
+ REQUIRE (function_application.arguments ()[1 ].get () == three);
240
+ }
228
241
}
You can’t perform that action at this time.
0 commit comments