Skip to content

Commit a31b70a

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

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
@@ -166,3 +166,22 @@ void smt_bit_vector_theoryt::remaindert::validate(
166166
const smt_function_application_termt::factoryt<
167167
smt_bit_vector_theoryt::remaindert>
168168
smt_bit_vector_theoryt::remainder{};
169+
170+
const char *smt_bit_vector_theoryt::negationt::identifier()
171+
{
172+
return "bvneg";
173+
}
174+
175+
smt_sortt
176+
smt_bit_vector_theoryt::negationt::return_sort(const smt_termt &operand)
177+
{
178+
return operand.get_sort();
179+
}
180+
181+
void smt_bit_vector_theoryt::negationt::validate(const smt_termt &operand)
182+
{
183+
}
184+
185+
const smt_function_application_termt::factoryt<
186+
smt_bit_vector_theoryt::negationt>
187+
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
@@ -61,6 +61,14 @@ class smt_bit_vector_theoryt
6161
static void validate(const smt_termt &lhs, const smt_termt &rhs);
6262
};
6363
static const smt_function_application_termt::factoryt<remaindert> remainder;
64+
65+
struct negationt final
66+
{
67+
static const char *identifier();
68+
static smt_sortt return_sort(const smt_termt &operand);
69+
static void validate(const smt_termt &operand);
70+
};
71+
static const smt_function_application_termt::factoryt<negationt> negation;
6472
};
6573

6674
#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
@@ -376,4 +376,20 @@ TEST_CASE(
376376
const cbmc_invariants_should_throwt invariants_throw;
377377
REQUIRE_THROWS(convert_expr_to_smt(mod_exprt{one_bvint, false_exprt{}}));
378378
}
379+
380+
SECTION("Unary minus of constant size bit-vector")
381+
{
382+
const auto constructed_term =
383+
convert_expr_to_smt(unary_minus_exprt{one_bvint});
384+
const auto expected_term = smt_bit_vector_theoryt::negation(smt_term_one);
385+
CHECK(constructed_term == expected_term);
386+
}
387+
388+
SECTION(
389+
"Ensure that unary minus node conversion fails if the operand is not a "
390+
"bit-vector")
391+
{
392+
const cbmc_invariants_should_throwt invariants_throw;
393+
REQUIRE_THROWS(convert_expr_to_smt(unary_minus_exprt{true_exprt{}}));
394+
}
379395
}

unit/solvers/smt2_incremental/smt_bit_vector_theory.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,4 +251,15 @@ TEST_CASE(
251251
REQUIRE(function_application.arguments()[0].get() == two);
252252
REQUIRE(function_application.arguments()[1].get() == three);
253253
}
254+
255+
SECTION("Unary Minus")
256+
{
257+
const auto function_application = smt_bit_vector_theoryt::negation(two);
258+
REQUIRE(
259+
function_application.function_identifier() ==
260+
smt_identifier_termt("bvneg", smt_bit_vector_sortt{8}));
261+
REQUIRE(function_application.get_sort() == smt_bit_vector_sortt{8});
262+
REQUIRE(function_application.arguments().size() == 1);
263+
REQUIRE(function_application.arguments()[0].get() == two);
264+
}
254265
}

0 commit comments

Comments
 (0)