Skip to content

Commit 6b99d17

Browse files
committed
Implement and test the conversion of bitxor_expr to bvxor SMT terms.
1 parent 3c0f02e commit 6b99d17

File tree

2 files changed

+89
-3
lines changed

2 files changed

+89
-3
lines changed

src/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,23 @@ static smt_termt convert_expr_to_smt(const bitor_exprt &bitwise_or_expr)
196196

197197
static smt_termt convert_expr_to_smt(const bitxor_exprt &bitwise_xor)
198198
{
199-
UNIMPLEMENTED_FEATURE(
200-
"Generation of SMT formula for bitwise xor expression: " +
201-
bitwise_xor.pretty());
199+
if(std::all_of(
200+
bitwise_xor.operands().cbegin(),
201+
bitwise_xor.operands().cend(),
202+
[](exprt operand) {
203+
return can_cast_type<integer_bitvector_typet>(operand.type());
204+
}))
205+
{
206+
return convert_multiary_operator_to_terms(
207+
bitwise_xor, smt_bit_vector_theoryt::make_xor);
208+
}
209+
else
210+
{
211+
UNIMPLEMENTED_FEATURE(
212+
"Bitwise \"XOR\" conversion requires that all operands have the same "
213+
"sort\n" +
214+
bitwise_xor.pretty());
215+
}
202216
}
203217

204218
static smt_termt convert_expr_to_smt(const bitnot_exprt &bitwise_not)

unit/solvers/smt2_incremental/convert_expr_to_smt.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,3 +565,75 @@ SCENARIO(
565565
}
566566
}
567567
}
568+
569+
SCENARIO(
570+
"Bitwise \"XOR\" expressions are converted to SMT terms",
571+
"[core][smt2_incremental]")
572+
{
573+
GIVEN("three integer bitvectors and their smt-term equivalents")
574+
{
575+
const smt_termt smt_term_one = smt_bit_vector_constant_termt{1, 8};
576+
const smt_termt smt_term_three = smt_bit_vector_constant_termt{3, 8};
577+
const smt_termt smt_term_five = smt_bit_vector_constant_termt{5, 8};
578+
579+
const auto one_bvint = from_integer({1}, signedbv_typet{8});
580+
const auto three_bvint = from_integer({3}, signedbv_typet{8});
581+
const auto five_bvint = from_integer({5}, signedbv_typet{8});
582+
583+
WHEN("a bitxor_exprt with two of them as arguments is converted")
584+
{
585+
const auto constructed_term =
586+
convert_expr_to_smt(bitxor_exprt{one_bvint, three_bvint});
587+
588+
THEN(
589+
"it should be equivalent to a \"bvxor\" term with the operands "
590+
"converted as well")
591+
{
592+
const auto expected_term =
593+
smt_bit_vector_theoryt::make_xor(smt_term_one, smt_term_three);
594+
595+
CHECK(constructed_term == expected_term);
596+
}
597+
}
598+
599+
// bitxor_exprt is similar to bitand_exprt and bitor_exprt, so we need
600+
// to handle the case where we need to convert expressions with arity > 2.
601+
WHEN("a ternary bitxor_exprt gets connverted to smt terms")
602+
{
603+
const exprt::operandst xor_operands{one_bvint, three_bvint, five_bvint};
604+
const multi_ary_exprt first_step{
605+
ID_bitxor, xor_operands, signedbv_typet{8}};
606+
const auto bitxor_expr = to_bitxor_expr(first_step);
607+
608+
const auto constructed_term = convert_expr_to_smt(bitxor_expr);
609+
610+
THEN(
611+
"it should be converted to an appropriate number of nested binary "
612+
"\"bvxor\" terms")
613+
{
614+
// We handle this in much the same way as we do bvand and bvor.
615+
// See the corresponding comments there.
616+
const auto expected_term = smt_bit_vector_theoryt::make_xor(
617+
smt_bit_vector_theoryt::make_xor(smt_term_one, smt_term_three),
618+
smt_term_five);
619+
CHECK(constructed_term == expected_term);
620+
}
621+
}
622+
623+
// Both of the above tests have been testing the positive case so far -
624+
// where everything goes more or less how we expect. Let's see how it does
625+
// with a negative case - where one of the terms is bad or otherwise
626+
// unsuitable for expression.
627+
WHEN("a bitxor_exprt with operands of different types gets converted")
628+
{
629+
const cbmc_invariants_should_throwt invariants_throw;
630+
THEN(
631+
"convert_expr_to_smt should throw an exception because bvxor requires"
632+
"operands of the same sort")
633+
{
634+
CHECK_THROWS(
635+
convert_expr_to_smt(bitxor_exprt{one_bvint, true_exprt{}}));
636+
}
637+
}
638+
}
639+
}

0 commit comments

Comments
 (0)