-
Notifications
You must be signed in to change notification settings - Fork 273
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
miniBDD: added a non-recursive variant of APPLY #1144
Conversation
A performance comparison would be interesting. |
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.
See detailed comments plus all the linter's complaints.
src/solvers/miniBDD/miniBDD.cpp
Outdated
|
||
G[key]=u; | ||
|
||
return u; | ||
} | ||
|
||
mini_bddt mini_bdd_applyt::APP_non_rec(const mini_bddt &_x, const mini_bddt &_y) | ||
{ | ||
struct e |
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.
Contesting for the least descriptive type name of the year? :-) In absence of any comment, this isn't exactly helping readability.
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.
it should also end on t
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.
e -> et? ;)
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.
technically, t
would be ok
src/solvers/miniBDD/miniBDD.cpp
Outdated
break; | ||
|
||
default: | ||
assert(false); |
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.
There is no case other than INIT
or FINISH
, the default
is unnecessary.
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.
done
src/solvers/miniBDD/miniBDD.cpp
Outdated
e(mini_bddt &_result, const mini_bddt &_x, const mini_bddt &_y): | ||
result(_result), x(_x), y(_y), var(0), phase(INIT) { } | ||
mini_bddt &result, x, y, lr, hr; | ||
std::pair<unsigned, unsigned> key; |
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.
Why is key
not being initialised? (It is done via a separate assignment later on for some reason.)
src/solvers/miniBDD/miniBDD.cpp
Outdated
|
||
G[key]=u; | ||
|
||
return u; | ||
} | ||
|
||
mini_bddt mini_bdd_applyt::APP_non_rec(const mini_bddt &_x, const mini_bddt &_y) | ||
{ | ||
struct e |
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.
it should also end on t
src/solvers/miniBDD/miniBDD.cpp
Outdated
mini_bddt &result, x, y, lr, hr; | ||
std::pair<unsigned, unsigned> key; | ||
unsigned var; | ||
enum { INIT, FINISH } phase; |
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.
I'd prefer
enum class phaset { INIT, FINISH};
phaset phase;
src/solvers/miniBDD/miniBDD.cpp
Outdated
} | ||
} | ||
|
||
assert(u.is_initialized()); |
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.
should be POSTCONDITION
src/solvers/miniBDD/miniBDD.cpp
Outdated
assert(x.low().var()>t.var); | ||
assert(y.low().var()>t.var); | ||
assert(x.high().var()>t.var); | ||
assert(y.high().var()>t.var); |
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.
INVARIANT
instead of assert
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.
This is un-obvious: there is some intent to maintain MiniBDD as a library that can be separately distributed.
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.
In that case please add linter overrides (and possibly the above explanation).
@kroening I did some tests with EBMC on 4 smv models from
this is average run-time over 10 runs, with the patch for
|
@mgudemann oh, wow, this is bigger than I thought it would be. |
db2da98
to
8a8f5f2
Compare
@kroening I'll see whether I find others that use a non-trivial amount of time and also do not require excessive resources when using BDDs. The above are all converted from AIG, that may skew the results a bit. I'll see whether I find other .smv or Verilog files. |
8a8f5f2
to
bda4ec5
Compare
Ready to go? |
I did a small benchmark on the
which shows a very slight advantage for the recursive variant with the exception of the first model. In conclusion I think the recursive version can be significantly worse (maybe if the recursion depth is very high?) and in the best case is slighly better (as it is shorter / less complex?) Overall, this is ready for merge. |
src/solvers/miniBDD/miniBDD.cpp
Outdated
{ | ||
t.var=x.var(); | ||
t.phase=stack_elementt::phaset::FINISH; | ||
assert(x.low().var()>t.var); |
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.
Linter overrides, please.
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.
done
src/solvers/miniBDD/miniBDD.cpp
Outdated
case stack_elementt::phaset::INIT: | ||
{ | ||
// dynamic programming | ||
t.key=std::pair<unsigned, unsigned>(x.node_number(), y.node_number()); |
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.
I think I've asked this before: why is this not part of the constructor?
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.
done
bda4ec5
to
a71ca41
Compare
As said before I'm unhappy about the absence of tests, but I don't want to stand in the way of others approving of this.
@@ -22,6 +22,7 @@ Author: Daniel Kroening, [email protected] | |||
|
|||
void mini_bdd_nodet::remove_reference() | |||
{ | |||
// NOLINTNEXTLINE(build/deprecated) |
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.
Use PRECONDITION()
, INVARIANT()
, etc from https://github.com/diffblue/cbmc/blob/master/src/util/invariant.h rather than silencing the linter.
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.
See #1144 (comment).
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.
Ok.
This adds a non-recursive variant of APPLY, for systems that have limited stacks.
The commit retains the recursive variant, which is much easier to read.