Skip to content

Commit 544f963

Browse files
committed
Add implementation of negation (unary minus - bvneg) operator.
Along with conversion tests and tests of the factory method integrity.
1 parent 1450583 commit 544f963

File tree

5 files changed

+57
-3
lines changed

5 files changed

+57
-3
lines changed

src/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,9 @@ static smt_termt convert_expr_to_smt(const bitnot_exprt &bitwise_not)
154154

155155
static 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+
PRECONDITION(can_cast_type<bitvector_typet>(unary_minus.op().type()));
158+
return smt_bit_vector_theoryt::negation(
159+
convert_expr_to_smt(unary_minus.op()));
160160
}
161161

162162
static smt_termt convert_expr_to_smt(const unary_plus_exprt &unary_plus)

src/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,22 @@ void smt_bit_vector_theoryt::remaindert::validate(
172172
const smt_function_application_termt::factoryt<
173173
smt_bit_vector_theoryt::remaindert>
174174
smt_bit_vector_theoryt::remainder{};
175+
176+
const char *smt_bit_vector_theoryt::negationt::identifier()
177+
{
178+
return "bvneg";
179+
}
180+
181+
smt_sortt
182+
smt_bit_vector_theoryt::negationt::return_sort(const smt_termt &operand)
183+
{
184+
return operand.get_sort();
185+
}
186+
187+
void smt_bit_vector_theoryt::negationt::validate(const smt_termt &operand)
188+
{
189+
}
190+
191+
const smt_function_application_termt::factoryt<
192+
smt_bit_vector_theoryt::negationt>
193+
smt_bit_vector_theoryt::negation{};

src/solvers/smt2_incremental/smt_bit_vector_theory.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ class smt_bit_vector_theoryt
6262
static void validate(const smt_termt &lhs, const smt_termt &rhs);
6363
};
6464
static const smt_function_application_termt::factoryt<remaindert> remainder;
65+
66+
struct negationt final
67+
{
68+
static const char *identifier();
69+
static smt_sortt return_sort(const smt_termt &operand);
70+
static void validate(const smt_termt &operand);
71+
};
72+
static const smt_function_application_termt::factoryt<negationt> negation;
6573
};
6674

6775
#endif // CPROVER_SOLVERS_SMT2_INCREMENTAL_SMT_BIT_VECTOR_THEORY_H

unit/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,4 +366,20 @@ TEST_CASE(
366366
const cbmc_invariants_should_throwt invariants_throw;
367367
REQUIRE_THROWS(convert_expr_to_smt(mod_exprt{one_bvint, false_exprt{}}));
368368
}
369+
370+
SECTION("Unary minus of constant size bit-vector")
371+
{
372+
const auto constructed_term =
373+
convert_expr_to_smt(unary_minus_exprt{one_bvint});
374+
const auto expected_term = smt_bit_vector_theoryt::negation(smt_term_one);
375+
CHECK(constructed_term == expected_term);
376+
}
377+
378+
SECTION(
379+
"Ensure that unary minus node conversion fails if the operand is not a "
380+
"bit-vector")
381+
{
382+
const cbmc_invariants_should_throwt invariants_throw;
383+
REQUIRE_THROWS(convert_expr_to_smt(unary_minus_exprt{true_exprt{}}));
384+
}
369385
}

unit/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,4 +238,15 @@ TEST_CASE(
238238
REQUIRE(function_application.arguments()[0].get() == two);
239239
REQUIRE(function_application.arguments()[1].get() == three);
240240
}
241+
242+
SECTION("Unary Minus")
243+
{
244+
const auto function_application = smt_bit_vector_theoryt::negation(two);
245+
REQUIRE(
246+
function_application.function_identifier() ==
247+
smt_identifier_termt("bvneg", smt_bit_vector_sortt{8}));
248+
REQUIRE(function_application.get_sort() == smt_bit_vector_sortt{8});
249+
REQUIRE(function_application.arguments().size() == 1);
250+
REQUIRE(function_application.arguments()[0].get() == two);
251+
}
241252
}

0 commit comments

Comments
 (0)