-
Notifications
You must be signed in to change notification settings - Fork 273
Goto analyzer 5 part2 #961
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
Conversation
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 are a few bits where I'd ask for clarification.
src/analyses/ai.cpp
Outdated
} | ||
|
||
/*******************************************************************\ | ||
Function: variable_sensitivity_domaint::ai_simplify_lhs |
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 case the automatic documentation conversion script relies on this: there should be a blank line before "Function:"
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.
Fixed.
src/analyses/ai.cpp
Outdated
} | ||
else if(condition.id()==ID_member) | ||
{ | ||
member_exprt me = to_member_expr(condition); |
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.
No whitespace around =
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 thought the lint script flagged these. Oh well; fixed.
src/analyses/ai.cpp
Outdated
{ | ||
ie.index() = index; | ||
condition = simplify_expr(ie, ns); | ||
} |
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 not use references in all the above, and thus even avoid the extra ie.index()=index;
(for it would be simplified in place)? I think the same applies below.
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.
Fixed.
src/analyses/ai.h
Outdated
|
||
#include <util/json.h> | ||
#include <util/xml.h> | ||
#include <util/expr.h> | ||
#include <util/simplify_expr.h> |
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 this include required here? (I'd also debate the expr.h as it could be replaced by a forward declaration class exprt;
but that's minor.)
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.
Good point; have moved the simplify_expr.h into ai.cpp. I'm mildly reluctant to forwards declare instead of include except where necessary.
src/analyses/constant_propagator.cpp
Outdated
@@ -331,6 +331,29 @@ void constant_propagator_domaint::assign( | |||
dest.set_to(lhs, rhs); | |||
} | |||
|
|||
/******************************************************************* \ |
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.
That final \
seems way off. (I'm being picky about comments to make sure automated conversion works.)
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.
Fixed.
src/analyses/interval_domain.cpp
Outdated
if(!a.join(d)) | ||
{ | ||
unchanged=condition.is_true(); | ||
condition.make_true(); |
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 does this make sense? (I may not yet have sufficient context, but maybe a comment could be added.)
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've added some comments to explain the flow of the logic.
src/analyses/interval_domain.cpp
Outdated
} | ||
else | ||
{ | ||
d.assume(not_exprt(condition), ns); |
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 this the only other case; what about, e.g., disjunction?
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.
That is the disjunction case :-) There are three things going on here:
-
We want to implement this primarily to be able to check assertions, so reducing to true is sufficient. We can do better and in the new interval domain we are writing, we will, so there is a limit to how much code we want to write here.
-
We could work through all of the cases of exprt here but that code has to be in assume as well to handle branching. So rather than have a wonky duplication, we really want to implement this using assume, merge, top, bottom, etc. which is sufficient to reduce to true.
-
But converting the expression to a domain and doing domain things means we are limited to what the domain can express. Thus disjuncts are a problem. 1 <= a && a <= 2 can be repesented exactly but a < 1 || a > 2 can't. The logic for "put this expression into the most representable normal form" should be in assume a it will be needed there anyway. Thus this call, with the negation, is meant to help it in the case of disjunctions.
How much of that should have been in the comments? :-)
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.
Have added a shortened version of this to explain why it is implemented in the way it is.
src/analyses/interval_domain.h
Outdated
@@ -40,10 +40,15 @@ class interval_domaint:public ai_domain_baset | |||
const ai_baset &ai, | |||
const namespacet &ns) const final; | |||
|
|||
bool join(const interval_domaint &b); |
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 "join" being introduced here, i.e., why not implement this functionality in merge
?
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.
Merge's signature is fixed and requires location arguments. It seemed better to split merge into two (the common interface and join, what is actually does the update) and use join when I wanted to compute the join of two abstract domains, independently of having their location, rather than make up false locations.
Using join (outside of merge) is to help compute ai_simplify in the conjunctive case.
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, seems fair. What irritated me a bit about this was the two verbs with very similar meaning (in this context). Using different verbs suggests that they do different things, but then the difference is very hard to find out (especially when merge
just calls join
). Can we maybe only use one of the two, or else have a comment that explains the difference?
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.
Join is the mathematical operation on the domains. We use this (in merge) to merge together different states. There are uses of join that are not merging (as in ai_simplify) and ways of merging (like delayed joins) that are not (just) join.
... and no-one who hasn't read that or a lot of AI literature will understand that so I'll add it to the comments :-)
…i.cpp. This means that <sstream> is no longer included in ai.h as requested in review.
… domain operation.
FWIW, will approve once the changes have been pushed (and I get back to my desk). |
fa35016
to
ff112c8
Compare
I have fixed / responded to all of the review comments and pushed the new version. |
Looks ok to me. I'm assuming @danpoe and @peterschrammel have been closely involved anyway, as documented in #472. |
src/analyses/interval_domain.cpp
Outdated
a.make_top(); // a is everything | ||
a.assume(condition, ns); // restrict a to an over-approximation | ||
// of when condition is true | ||
|
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.
Remove one blank line.
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.
Fixed.
@danpoe and @thk123 wrote some parts and have been involved (I have tried to preserve authorship but I've had to split / merge / re-order commits and it can get lost). @peterschrammel has reviewed some of it and is ... aware... of what is going on. |
PS There are test cases for these but they depend on the front-end refactoring and are thus in part .. N where N > 2. |
For full correctness, there might still be some bits of code that @lucasccordeiro wrote in some of these parts as well. I've tried to preserve authorship; sorry if it's got lost. |
ff112c8
to
15f628e
Compare
@martin-cs, is this ready to go or do you want to amend this PR? |
@peterschrammel 2 mins? |
15f628e
to
c64448b
Compare
I've pushed a version with more comments to address @tautschnig 's concerns. Assuming that passes all of the tests, then it should be good to go. |
Low risk changes needed for the goto-analyze branch. Mostly additions.
Note that an earlier version of this has been reviewed as part of #472, there have been some changes.