Skip to content

Commit 4582586

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

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
@@ -169,3 +169,22 @@ void smt_bit_vector_theoryt::remaindert::validate(
169169
const smt_function_application_termt::factoryt<
170170
smt_bit_vector_theoryt::remaindert>
171171
smt_bit_vector_theoryt::remainder{};
172+
173+
const char *smt_bit_vector_theoryt::negationt::identifier()
174+
{
175+
return "bvneg";
176+
}
177+
178+
smt_sortt
179+
smt_bit_vector_theoryt::negationt::return_sort(const smt_termt &operand)
180+
{
181+
return operand.get_sort();
182+
}
183+
184+
void smt_bit_vector_theoryt::negationt::validate(const smt_termt &operand)
185+
{
186+
}
187+
188+
const smt_function_application_termt::factoryt<
189+
smt_bit_vector_theoryt::negationt>
190+
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
@@ -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
@@ -245,4 +245,15 @@ TEST_CASE(
245245
REQUIRE(function_application.arguments()[0].get() == two);
246246
REQUIRE(function_application.arguments()[1].get() == three);
247247
}
248+
249+
SECTION("Unary Minus")
250+
{
251+
const auto function_application = smt_bit_vector_theoryt::negation(two);
252+
REQUIRE(
253+
function_application.function_identifier() ==
254+
smt_identifier_termt("bvneg", smt_bit_vector_sortt{8}));
255+
REQUIRE(function_application.get_sort() == smt_bit_vector_sortt{8});
256+
REQUIRE(function_application.arguments().size() == 1);
257+
REQUIRE(function_application.arguments()[0].get() == two);
258+
}
248259
}

0 commit comments

Comments
 (0)