File tree Expand file tree Collapse file tree 5 files changed +83
-2
lines changed
src/solvers/smt2_incremental
unit/solvers/smt2_incremental Expand file tree Collapse file tree 5 files changed +83
-2
lines changed Original file line number Diff line number Diff line change @@ -343,8 +343,20 @@ static smt_termt convert_expr_to_smt(const plus_exprt &plus)
343343
344344static smt_termt convert_expr_to_smt (const minus_exprt &minus)
345345{
346- UNIMPLEMENTED_FEATURE (
347- " Generation of SMT formula for minus expression: " + minus.pretty ());
346+ const bool both_operands_bitvector =
347+ can_cast_type<integer_bitvector_typet>(minus.lhs ().type ()) &&
348+ can_cast_type<integer_bitvector_typet>(minus.rhs ().type ());
349+
350+ if (both_operands_bitvector)
351+ {
352+ return smt_bit_vector_theoryt::subtract (
353+ convert_expr_to_smt (minus.lhs ()), convert_expr_to_smt (minus.rhs ()));
354+ }
355+ else
356+ {
357+ UNIMPLEMENTED_FEATURE (
358+ " Generation of SMT formula for minus expression: " + minus.pretty ());
359+ }
348360}
349361
350362static smt_termt convert_expr_to_smt (const div_exprt ÷)
Original file line number Diff line number Diff line change @@ -227,3 +227,26 @@ void smt_bit_vector_theoryt::addt::validate(
227227
228228const smt_function_application_termt::factoryt<smt_bit_vector_theoryt::addt>
229229 smt_bit_vector_theoryt::add{};
230+
231+ const char *smt_bit_vector_theoryt::subtractt::identifier ()
232+ {
233+ return " bvsub" ;
234+ }
235+
236+ smt_sortt smt_bit_vector_theoryt::subtractt::return_sort (
237+ const smt_termt &lhs,
238+ const smt_termt &rhs)
239+ {
240+ return lhs.get_sort ();
241+ }
242+
243+ void smt_bit_vector_theoryt::subtractt::validate (
244+ const smt_termt &lhs,
245+ const smt_termt &rhs)
246+ {
247+ validate_bit_vector_predicate_arguments (lhs, rhs);
248+ }
249+
250+ const smt_function_application_termt::factoryt<
251+ smt_bit_vector_theoryt::subtractt>
252+ smt_bit_vector_theoryt::subtract{};
Original file line number Diff line number Diff line change @@ -92,6 +92,14 @@ class smt_bit_vector_theoryt
9292 static void validate (const smt_termt &lhs, const smt_termt &rhs);
9393 };
9494 static const smt_function_application_termt::factoryt<addt> add;
95+
96+ struct subtractt final
97+ {
98+ static const char *identifier ();
99+ static smt_sortt return_sort (const smt_termt &lhs, const smt_termt &rhs);
100+ static void validate (const smt_termt &lhs, const smt_termt &rhs);
101+ };
102+ static const smt_function_application_termt::factoryt<subtractt> subtract;
95103};
96104
97105#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H
Original file line number Diff line number Diff line change @@ -310,4 +310,22 @@ TEST_CASE(
310310 REQUIRE_THROWS (
311311 convert_expr_to_smt (plus_exprt{one_operand, signedbv_typet{8 }}));
312312 }
313+
314+ SECTION (" Subtraction of two constant size bit-vectors" )
315+ {
316+ const auto constructed_term =
317+ convert_expr_to_smt (minus_exprt{two_bvint, one_bvint});
318+ const auto expected_term =
319+ smt_bit_vector_theoryt::subtract (smt_term_two, smt_term_one);
320+ CHECK (constructed_term == expected_term);
321+ }
322+
323+ SECTION (
324+ " Ensure that subtraction node conversion fails if the operands are not "
325+ " bit-vector based" )
326+ {
327+ const cbmc_invariants_should_throwt invariants_throw;
328+ REQUIRE_THROWS (
329+ convert_expr_to_smt (minus_exprt{true_exprt{}, false_exprt{}}));
330+ }
313331}
Original file line number Diff line number Diff line change @@ -193,4 +193,24 @@ TEST_CASE(
193193 // An addition of a bool and a bitvector should hit an invariant violation.
194194 REQUIRE_THROWS (smt_bit_vector_theoryt::add (three, true_val));
195195 }
196+
197+ SECTION (" Subtraction" )
198+ {
199+ const auto function_application =
200+ smt_bit_vector_theoryt::subtract (two, three);
201+ REQUIRE (
202+ function_application.function_identifier () ==
203+ smt_identifier_termt (" bvsub" , smt_bit_vector_sortt{8 }));
204+ REQUIRE (function_application.get_sort () == smt_bit_vector_sortt{8 });
205+ REQUIRE (function_application.arguments ().size () == 2 );
206+ REQUIRE (function_application.arguments ()[0 ].get () == two);
207+ REQUIRE (function_application.arguments ()[1 ].get () == three);
208+
209+ cbmc_invariants_should_throwt invariants_throw;
210+ // Bit-vectors of mismatched sorts are going to hit an invariant violation.
211+ REQUIRE_THROWS (smt_bit_vector_theoryt::subtract (three, four));
212+ // A subtraction of a bool and a bitvector should hit an
213+ // invariant violation.
214+ REQUIRE_THROWS (smt_bit_vector_theoryt::subtract (true_val, three));
215+ }
196216}
You can’t perform that action at this time.
0 commit comments