File tree 5 files changed +71
-3
lines changed
src/solvers/smt2_incremental
unit/solvers/smt2_incremental 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)
154
154
155
155
static smt_termt convert_expr_to_smt (const unary_minus_exprt &unary_minus)
156
156
{
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
+ }
160
170
}
161
171
162
172
static smt_termt convert_expr_to_smt (const unary_plus_exprt &unary_plus)
Original file line number Diff line number Diff line change @@ -202,3 +202,22 @@ void smt_bit_vector_theoryt::signed_remaindert::validate(
202
202
const smt_function_application_termt::factoryt<
203
203
smt_bit_vector_theoryt::signed_remaindert>
204
204
smt_bit_vector_theoryt::signed_remainder{};
205
+
206
+ const char *smt_bit_vector_theoryt::negatet::identifier ()
207
+ {
208
+ return " bvneg" ;
209
+ }
210
+
211
+ smt_sortt smt_bit_vector_theoryt::negatet::return_sort (const smt_termt &operand)
212
+ {
213
+ return operand.get_sort ();
214
+ }
215
+
216
+ void smt_bit_vector_theoryt::negatet::validate (const smt_termt &operand)
217
+ {
218
+ const auto operand_sort = operand.get_sort ().cast <smt_bit_vector_sortt>();
219
+ INVARIANT (operand_sort, " The operand is expected to have a bit-vector sort." );
220
+ }
221
+
222
+ const smt_function_application_termt::factoryt<smt_bit_vector_theoryt::negatet>
223
+ smt_bit_vector_theoryt::negate{};
Original file line number Diff line number Diff line change @@ -80,6 +80,14 @@ class smt_bit_vector_theoryt
80
80
};
81
81
static const smt_function_application_termt::factoryt<signed_remaindert>
82
82
signed_remainder;
83
+
84
+ struct negatet final
85
+ {
86
+ static const char *identifier ();
87
+ static smt_sortt return_sort (const smt_termt &operand);
88
+ static void validate (const smt_termt &operand);
89
+ };
90
+ static const smt_function_application_termt::factoryt<negatet> negate;
83
91
};
84
92
85
93
#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(
399
399
const cbmc_invariants_should_throwt invariants_throw;
400
400
REQUIRE_THROWS (convert_expr_to_smt (mod_exprt{one_bvint, false_exprt{}}));
401
401
}
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
+ }
402
418
}
Original file line number Diff line number Diff line change @@ -307,4 +307,19 @@ TEST_CASE(
307
307
// A remainder of a bool and a bitvector should hit an invariant violation.
308
308
REQUIRE_THROWS (smt_bit_vector_theoryt::signed_remainder (true_val, three));
309
309
}
310
+
311
+ SECTION (" Unary Minus" )
312
+ {
313
+ const auto function_application = smt_bit_vector_theoryt::negate (two);
314
+ REQUIRE (
315
+ function_application.function_identifier () ==
316
+ smt_identifier_termt (" bvneg" , smt_bit_vector_sortt{8 }));
317
+ REQUIRE (function_application.get_sort () == smt_bit_vector_sortt{8 });
318
+ REQUIRE (function_application.arguments ().size () == 1 );
319
+ REQUIRE (function_application.arguments ()[0 ].get () == two);
320
+
321
+ cbmc_invariants_should_throwt invariants_throw;
322
+ // Negation of a value of bool sort should fail with an invariant violation.
323
+ REQUIRE_THROWS (smt_bit_vector_theoryt::negate (true_val));
324
+ }
310
325
}
You can’t perform that action at this time.
0 commit comments