Skip to content

Commit 857c88e

Browse files
authored
Merge pull request #8536 from diffblue/fix-boolbv-onehot
Fix `onehot0` flattening
2 parents fb28475 + 26505a9 commit 857c88e

File tree

3 files changed

+98
-10
lines changed

3 files changed

+98
-10
lines changed

Diff for: src/solvers/flattening/boolbv_onehot.cpp

+5-10
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ literalt boolbvt::convert_onehot(const unary_exprt &expr)
1515

1616
bvt op=convert_bv(expr.op());
1717

18+
// onehot0 is the same as onehot with the input bits flipped
19+
if(expr.id() == ID_onehot0)
20+
op = bv_utils.inverted(op);
21+
1822
literalt one_seen=const_literal(false);
1923
literalt more_than_one_seen=const_literal(false);
2024

@@ -25,14 +29,5 @@ literalt boolbvt::convert_onehot(const unary_exprt &expr)
2529
one_seen=prop.lor(*it, one_seen);
2630
}
2731

28-
if(expr.id()==ID_onehot)
29-
return prop.land(one_seen, !more_than_one_seen);
30-
else
31-
{
32-
INVARIANT(
33-
expr.id() == ID_onehot0,
34-
"should be a onehot0 expression as other onehot expression kind has been "
35-
"handled in other branch");
36-
return !more_than_one_seen;
37-
}
32+
return prop.land(one_seen, !more_than_one_seen);
3833
}

Diff for: unit/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ SRC += analyses/ai/ai.cpp \
9696
pointer-analysis/value_set.cpp \
9797
solvers/bdd/miniBDD/miniBDD.cpp \
9898
solvers/flattening/boolbv.cpp \
99+
solvers/flattening/boolbv_onehot.cpp \
99100
solvers/flattening/boolbv_update_bit.cpp \
100101
solvers/floatbv/float_utils.cpp \
101102
solvers/prop/bdd_expr.cpp \

Diff for: unit/solvers/flattening/boolbv_onehot.cpp

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for solvers/flattening/boolbv_onehot
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
11+
#include <util/arith_tools.h>
12+
#include <util/bitvector_expr.h>
13+
#include <util/bitvector_types.h>
14+
#include <util/cout_message.h>
15+
#include <util/namespace.h>
16+
#include <util/std_expr.h>
17+
#include <util/symbol_table.h>
18+
19+
#include <solvers/flattening/boolbv.h>
20+
#include <solvers/sat/satcheck.h>
21+
#include <testing-utils/use_catch.h>
22+
23+
TEST_CASE("onehot flattening", "[core][solvers][flattening][boolbvt][onehot]")
24+
{
25+
console_message_handlert message_handler;
26+
message_handler.set_verbosity(0);
27+
satcheckt satcheck{message_handler};
28+
symbol_tablet symbol_table;
29+
namespacet ns{symbol_table};
30+
boolbvt boolbv{ns, satcheck, message_handler};
31+
unsignedbv_typet u8{8};
32+
33+
GIVEN("A bit-vector that is one-hot")
34+
{
35+
boolbv << onehot_exprt{from_integer(64, u8)};
36+
37+
THEN("the lowering of onehot is true")
38+
{
39+
REQUIRE(boolbv() == decision_proceduret::resultt::D_SATISFIABLE);
40+
}
41+
}
42+
43+
GIVEN("A bit-vector that is not one-hot")
44+
{
45+
boolbv << onehot_exprt{from_integer(5, u8)};
46+
47+
THEN("the lowering of onehot is false")
48+
{
49+
REQUIRE(boolbv() == decision_proceduret::resultt::D_UNSATISFIABLE);
50+
}
51+
}
52+
53+
GIVEN("A bit-vector that is not one-hot")
54+
{
55+
boolbv << onehot_exprt{from_integer(0, u8)};
56+
57+
THEN("the lowering of onehot is false")
58+
{
59+
REQUIRE(boolbv() == decision_proceduret::resultt::D_UNSATISFIABLE);
60+
}
61+
}
62+
63+
GIVEN("A bit-vector that is one-hot 0")
64+
{
65+
boolbv << onehot0_exprt{from_integer(0xfe, u8)};
66+
67+
THEN("the lowering of onehot0 is true")
68+
{
69+
REQUIRE(boolbv() == decision_proceduret::resultt::D_SATISFIABLE);
70+
}
71+
}
72+
73+
GIVEN("A bit-vector that is not one-hot 0")
74+
{
75+
boolbv << onehot0_exprt{from_integer(0x7e, u8)};
76+
77+
THEN("the lowering of onehot0 is false")
78+
{
79+
REQUIRE(boolbv() == decision_proceduret::resultt::D_UNSATISFIABLE);
80+
}
81+
}
82+
83+
GIVEN("A bit-vector that is not one-hot 0")
84+
{
85+
boolbv << onehot0_exprt{from_integer(0xff, u8)};
86+
87+
THEN("the lowering of onehot0 is false")
88+
{
89+
REQUIRE(boolbv() == decision_proceduret::resultt::D_UNSATISFIABLE);
90+
}
91+
}
92+
}

0 commit comments

Comments
 (0)