File tree 5 files changed +70
-2
lines changed
src/solvers/smt2_incremental
unit/solvers/smt2_incremental 5 files changed +70
-2
lines changed Original file line number Diff line number Diff line change @@ -343,8 +343,10 @@ static smt_termt convert_expr_to_smt(const minus_exprt &minus)
343
343
344
344
static smt_termt convert_expr_to_smt (const div_exprt ÷)
345
345
{
346
- UNIMPLEMENTED_FEATURE (
347
- " Generation of SMT formula for divide expression: " + divide.pretty ());
346
+ PRECONDITION (can_cast_type<bitvector_typet>(divide.lhs ().type ()));
347
+ PRECONDITION (can_cast_type<bitvector_typet>(divide.rhs ().type ()));
348
+ return smt_bit_vector_theoryt::division (
349
+ convert_expr_to_smt (divide.lhs ()), convert_expr_to_smt (divide.rhs ()));
348
350
}
349
351
350
352
static smt_termt convert_expr_to_smt (const ieee_float_op_exprt &float_operation)
Original file line number Diff line number Diff line change @@ -120,3 +120,29 @@ void smt_bit_vector_theoryt::multiplicationt::validate(
120
120
const smt_function_application_termt::factoryt<
121
121
smt_bit_vector_theoryt::multiplicationt>
122
122
smt_bit_vector_theoryt::multiplication{};
123
+
124
+ const char *smt_bit_vector_theoryt::divisiont::identifier ()
125
+ {
126
+ return " bvdiv" ;
127
+ }
128
+
129
+ smt_sortt smt_bit_vector_theoryt::divisiont::return_sort (
130
+ const smt_termt &lhs,
131
+ const smt_termt &rhs)
132
+ {
133
+ // For now, make sure that they have the same bit-width
134
+ divisiont::validate (lhs, rhs);
135
+ const auto width = lhs.get_sort ().cast <smt_bit_vector_sortt>()->bit_width ();
136
+ return smt_bit_vector_sortt{width};
137
+ }
138
+
139
+ void smt_bit_vector_theoryt::divisiont::validate (
140
+ const smt_termt &lhs,
141
+ const smt_termt &rhs)
142
+ {
143
+ validate_bit_vector_predicate_arguments (lhs, rhs);
144
+ }
145
+
146
+ const smt_function_application_termt::factoryt<
147
+ smt_bit_vector_theoryt::divisiont>
148
+ smt_bit_vector_theoryt::division{};
Original file line number Diff line number Diff line change @@ -46,6 +46,14 @@ class smt_bit_vector_theoryt
46
46
};
47
47
static const smt_function_application_termt::factoryt<multiplicationt>
48
48
multiplication;
49
+
50
+ struct divisiont final
51
+ {
52
+ static const char *identifier ();
53
+ static smt_sortt return_sort (const smt_termt &lhs, const smt_termt &rhs);
54
+ static void validate (const smt_termt &lhs, const smt_termt &rhs);
55
+ };
56
+ static const smt_function_application_termt::factoryt<divisiont> division;
49
57
};
50
58
51
59
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H
Original file line number Diff line number Diff line change @@ -328,4 +328,23 @@ TEST_CASE(
328
328
const cbmc_invariants_should_throwt invariants_throw;
329
329
REQUIRE_THROWS (convert_expr_to_smt (mult_exprt{one_bvint, false_exprt{}}));
330
330
}
331
+
332
+ // Division is defined over unsigned numbers only (theory notes say it
333
+ // truncates over zero)
334
+ SECTION (" Division of two constant size bit-vectors" )
335
+ {
336
+ const auto constructed_term =
337
+ convert_expr_to_smt (div_exprt{one_bvint_unsigned, two_bvint_unsigned});
338
+ const auto expected_term =
339
+ smt_bit_vector_theoryt::division (smt_term_one, smt_term_two);
340
+ CHECK (constructed_term == expected_term);
341
+ }
342
+
343
+ SECTION (
344
+ " Ensure that division node conversion fails if the operands are not "
345
+ " bit-vector based" )
346
+ {
347
+ const cbmc_invariants_should_throwt invariants_throw;
348
+ REQUIRE_THROWS (convert_expr_to_smt (div_exprt{one_bvint, false_exprt{}}));
349
+ }
331
350
}
Original file line number Diff line number Diff line change @@ -212,4 +212,17 @@ TEST_CASE(
212
212
REQUIRE (function_application.arguments ()[0 ].get () == two);
213
213
REQUIRE (function_application.arguments ()[1 ].get () == three);
214
214
}
215
+
216
+ SECTION (" Division" )
217
+ {
218
+ const auto function_application =
219
+ smt_bit_vector_theoryt::division (two, three);
220
+ REQUIRE (
221
+ function_application.function_identifier () ==
222
+ smt_identifier_termt (" bvdiv" , smt_bit_vector_sortt{8 }));
223
+ REQUIRE (function_application.get_sort () == smt_bit_vector_sortt{8 });
224
+ REQUIRE (function_application.arguments ().size () == 2 );
225
+ REQUIRE (function_application.arguments ()[0 ].get () == two);
226
+ REQUIRE (function_application.arguments ()[1 ].get () == three);
227
+ }
215
228
}
You can’t perform that action at this time.
0 commit comments