File tree Expand file tree Collapse file tree 5 files changed +71
-3
lines changed
src/solvers/smt2_incremental
unit/solvers/smt2_incremental Expand file tree Collapse file tree 5 files changed +71
-3
lines changed Original file line number Diff line number Diff line change @@ -154,9 +154,19 @@ static smt_termt convert_expr_to_smt(const bitnot_exprt &bitwise_not)
154154
155155static smt_termt convert_expr_to_smt (const unary_minus_exprt &unary_minus)
156156{
157- UNIMPLEMENTED_FEATURE (
158- " Generation of SMT formula for unary minus expression: " +
159- unary_minus.pretty ());
157+ const bool operand_is_bitvector =
158+ can_cast_type<integer_bitvector_typet>(unary_minus.op ().type ());
159+ if (operand_is_bitvector)
160+ {
161+ return smt_bit_vector_theoryt::negate (
162+ convert_expr_to_smt (unary_minus.op ()));
163+ }
164+ else
165+ {
166+ UNIMPLEMENTED_FEATURE (
167+ " Generation of SMT formula for unary minus expression: " +
168+ unary_minus.pretty ());
169+ }
160170}
161171
162172static smt_termt convert_expr_to_smt (const unary_plus_exprt &unary_plus)
Original file line number Diff line number Diff line change @@ -365,3 +365,22 @@ void smt_bit_vector_theoryt::signed_remaindert::validate(
365365const smt_function_application_termt::factoryt<
366366 smt_bit_vector_theoryt::signed_remaindert>
367367 smt_bit_vector_theoryt::signed_remainder{};
368+
369+ const char *smt_bit_vector_theoryt::negatet::identifier ()
370+ {
371+ return " bvneg" ;
372+ }
373+
374+ smt_sortt smt_bit_vector_theoryt::negatet::return_sort (const smt_termt &operand)
375+ {
376+ return operand.get_sort ();
377+ }
378+
379+ void smt_bit_vector_theoryt::negatet::validate (const smt_termt &operand)
380+ {
381+ const auto operand_sort = operand.get_sort ().cast <smt_bit_vector_sortt>();
382+ INVARIANT (operand_sort, " The operand is expected to have a bit-vector sort." );
383+ }
384+
385+ const smt_function_application_termt::factoryt<smt_bit_vector_theoryt::negatet>
386+ smt_bit_vector_theoryt::negate{};
Original file line number Diff line number Diff line change @@ -144,6 +144,14 @@ class smt_bit_vector_theoryt
144144 };
145145 static const smt_function_application_termt::factoryt<signed_remaindert>
146146 signed_remainder;
147+
148+ struct negatet final
149+ {
150+ static const char *identifier ();
151+ static smt_sortt return_sort (const smt_termt &operand);
152+ static void validate (const smt_termt &operand);
153+ };
154+ static const smt_function_application_termt::factoryt<negatet> negate;
147155};
148156
149157#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H
Original file line number Diff line number Diff line change @@ -399,4 +399,20 @@ TEST_CASE(
399399 const cbmc_invariants_should_throwt invariants_throw;
400400 REQUIRE_THROWS (convert_expr_to_smt (mod_exprt{one_bvint, false_exprt{}}));
401401 }
402+
403+ SECTION (" Unary minus of constant size bit-vector" )
404+ {
405+ const auto constructed_term =
406+ convert_expr_to_smt (unary_minus_exprt{one_bvint});
407+ const auto expected_term = smt_bit_vector_theoryt::negate (smt_term_one);
408+ CHECK (constructed_term == expected_term);
409+ }
410+
411+ SECTION (
412+ " Ensure that unary minus node conversion fails if the operand is not a "
413+ " bit-vector" )
414+ {
415+ const cbmc_invariants_should_throwt invariants_throw;
416+ REQUIRE_THROWS (convert_expr_to_smt (unary_minus_exprt{true_exprt{}}));
417+ }
402418}
Original file line number Diff line number Diff line change @@ -309,4 +309,19 @@ TEST_CASE(
309309 // A remainder of a bool and a bitvector should hit an invariant violation.
310310 REQUIRE_THROWS (smt_bit_vector_theoryt::signed_remainder (true_val, three));
311311 }
312+
313+ SECTION (" Unary Minus" )
314+ {
315+ const auto function_application = smt_bit_vector_theoryt::negate (two);
316+ REQUIRE (
317+ function_application.function_identifier () ==
318+ smt_identifier_termt (" bvneg" , smt_bit_vector_sortt{8 }));
319+ REQUIRE (function_application.get_sort () == smt_bit_vector_sortt{8 });
320+ REQUIRE (function_application.arguments ().size () == 1 );
321+ REQUIRE (function_application.arguments ()[0 ].get () == two);
322+
323+ cbmc_invariants_should_throwt invariants_throw;
324+ // Negation of a value of bool sort should fail with an invariant violation.
325+ REQUIRE_THROWS (smt_bit_vector_theoryt::negate (true_val));
326+ }
312327}
You can’t perform that action at this time.
0 commit comments