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 @@ -353,8 +353,10 @@ static smt_termt convert_expr_to_smt(const minus_exprt &minus)
353
353
354
354
static smt_termt convert_expr_to_smt (const div_exprt ÷)
355
355
{
356
- UNIMPLEMENTED_FEATURE (
357
- " Generation of SMT formula for divide expression: " + divide.pretty ());
356
+ PRECONDITION (can_cast_type<bitvector_typet>(divide.lhs ().type ()));
357
+ PRECONDITION (can_cast_type<bitvector_typet>(divide.rhs ().type ()));
358
+ return smt_bit_vector_theoryt::division (
359
+ convert_expr_to_smt (divide.lhs ()), convert_expr_to_smt (divide.rhs ()));
358
360
}
359
361
360
362
static smt_termt convert_expr_to_smt (const ieee_float_op_exprt &float_operation)
Original file line number Diff line number Diff line change @@ -117,3 +117,29 @@ void smt_bit_vector_theoryt::multiplicationt::validate(
117
117
const smt_function_application_termt::factoryt<
118
118
smt_bit_vector_theoryt::multiplicationt>
119
119
smt_bit_vector_theoryt::multiplication{};
120
+
121
+ const char *smt_bit_vector_theoryt::divisiont::identifier ()
122
+ {
123
+ return " bvdiv" ;
124
+ }
125
+
126
+ smt_sortt smt_bit_vector_theoryt::divisiont::return_sort (
127
+ const smt_termt &lhs,
128
+ const smt_termt &rhs)
129
+ {
130
+ // For now, make sure that they have the same bit-width
131
+ divisiont::validate (lhs, rhs);
132
+ const auto width = lhs.get_sort ().cast <smt_bit_vector_sortt>()->bit_width ();
133
+ return smt_bit_vector_sortt{width};
134
+ }
135
+
136
+ void smt_bit_vector_theoryt::divisiont::validate (
137
+ const smt_termt &lhs,
138
+ const smt_termt &rhs)
139
+ {
140
+ validate_bit_vector_predicate_arguments (lhs, rhs);
141
+ }
142
+
143
+ const smt_function_application_termt::factoryt<
144
+ smt_bit_vector_theoryt::divisiont>
145
+ 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 @@ -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 @@ -219,4 +219,17 @@ TEST_CASE(
219
219
REQUIRE (function_application.arguments ()[0 ].get () == two);
220
220
REQUIRE (function_application.arguments ()[1 ].get () == three);
221
221
}
222
+
223
+ SECTION (" Division" )
224
+ {
225
+ const auto function_application =
226
+ smt_bit_vector_theoryt::division (two, three);
227
+ REQUIRE (
228
+ function_application.function_identifier () ==
229
+ smt_identifier_termt (" bvdiv" , smt_bit_vector_sortt{8 }));
230
+ REQUIRE (function_application.get_sort () == smt_bit_vector_sortt{8 });
231
+ REQUIRE (function_application.arguments ().size () == 2 );
232
+ REQUIRE (function_application.arguments ()[0 ].get () == two);
233
+ REQUIRE (function_application.arguments ()[1 ].get () == three);
234
+ }
222
235
}
You can’t perform that action at this time.
0 commit comments