-
Notifications
You must be signed in to change notification settings - Fork 273
SMT2: support onehot
and onehot0
#8524
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -306,3 +306,37 @@ | |
return extractbits_exprt{op(), 0, type()}; | ||
} | ||
} | ||
|
||
static exprt onehot_lowering(const exprt &expr) | ||
{ | ||
exprt one_seen = false_exprt{}; | ||
const auto width = to_bitvector_type(expr.type()).get_width(); | ||
exprt::operandst more_than_one_seen_disjuncts; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. May I suggest There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
more_than_one_seen_disjuncts.reserve(width); | ||
|
||
for(std::size_t i = 0; i < width; i++) | ||
{ | ||
auto bit = extractbit_exprt{expr, i}; | ||
more_than_one_seen_disjuncts.push_back(and_exprt{bit, one_seen}); | ||
one_seen = or_exprt{one_seen, bit}; | ||
} | ||
|
||
auto more_than_one_seen = disjunction(more_than_one_seen_disjuncts); | ||
|
||
return and_exprt{one_seen, not_exprt{more_than_one_seen}}; | ||
} | ||
|
||
exprt onehot_exprt::lower() const | ||
{ | ||
auto symbol = symbol_exprt{"onehot-op", op().type()}; | ||
|
||
return let_exprt{symbol, op(), onehot_lowering(symbol)}; | ||
} | ||
|
||
exprt onehot0_exprt::lower() const | ||
{ | ||
auto symbol = symbol_exprt{"onehot-op", op().type()}; | ||
|
||
// same as onehot, but on flipped operand bits | ||
return let_exprt{symbol, bitnot_exprt{op()}, onehot_lowering(symbol)}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,15 @@ | ||
// Author: Diffblue Ltd. | ||
|
||
#include <util/arith_tools.h> | ||
#include <util/bitvector_expr.h> | ||
#include <util/bitvector_types.h> | ||
#include <util/cout_message.h> | ||
#include <util/namespace.h> | ||
#include <util/std_expr.h> | ||
#include <util/symbol_table.h> | ||
|
||
#include <solvers/flattening/boolbv.h> | ||
#include <solvers/sat/satcheck.h> | ||
#include <testing-utils/use_catch.h> | ||
|
||
TEST_CASE( | ||
|
@@ -64,3 +71,74 @@ | |
} | ||
} | ||
} | ||
|
||
TEST_CASE("onehot expression lowering", "[core][util][expr]") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you for adding this test; but could There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
{ | ||
console_message_handlert message_handler; | ||
message_handler.set_verbosity(0); | ||
satcheckt satcheck{message_handler}; | ||
symbol_tablet symbol_table; | ||
namespacet ns{symbol_table}; | ||
boolbvt boolbv{ns, satcheck, message_handler}; | ||
unsignedbv_typet u8{8}; | ||
|
||
GIVEN("A bit-vector that is one-hot") | ||
{ | ||
boolbv << onehot_exprt{from_integer(64, u8)}.lower(); | ||
|
||
THEN("the lowering of onehot is true") | ||
{ | ||
REQUIRE(boolbv() == decision_proceduret::resultt::D_SATISFIABLE); | ||
} | ||
} | ||
|
||
GIVEN("A bit-vector that is not one-hot") | ||
{ | ||
boolbv << onehot_exprt{from_integer(5, u8)}.lower(); | ||
|
||
THEN("the lowering of onehot is false") | ||
{ | ||
REQUIRE(boolbv() == decision_proceduret::resultt::D_UNSATISFIABLE); | ||
} | ||
} | ||
|
||
GIVEN("A bit-vector that is not one-hot") | ||
{ | ||
boolbv << onehot_exprt{from_integer(0, u8)}.lower(); | ||
|
||
THEN("the lowering of onehot is false") | ||
{ | ||
REQUIRE(boolbv() == decision_proceduret::resultt::D_UNSATISFIABLE); | ||
} | ||
} | ||
|
||
GIVEN("A bit-vector that is one-hot 0") | ||
{ | ||
boolbv << onehot0_exprt{from_integer(0xfe, u8)}.lower(); | ||
|
||
THEN("the lowering of onehot0 is true") | ||
{ | ||
REQUIRE(boolbv() == decision_proceduret::resultt::D_SATISFIABLE); | ||
} | ||
} | ||
|
||
GIVEN("A bit-vector that is not one-hot 0") | ||
{ | ||
boolbv << onehot0_exprt{from_integer(0x7e, u8)}.lower(); | ||
|
||
THEN("the lowering of onehot0 is false") | ||
{ | ||
REQUIRE(boolbv() == decision_proceduret::resultt::D_UNSATISFIABLE); | ||
} | ||
} | ||
|
||
GIVEN("A bit-vector that is not one-hot 0") | ||
{ | ||
boolbv << onehot0_exprt{from_integer(0xff, u8)}.lower(); | ||
|
||
THEN("the lowering of onehot0 is false") | ||
{ | ||
REQUIRE(boolbv() == decision_proceduret::resultt::D_UNSATISFIABLE); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
testing-utils | ||
util | ||
solvers/flattening | ||
solvers/sat |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about
ID_onehot0
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added, thank you