Skip to content

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

Merged
merged 6 commits into from
May 24, 2017
Merged

Conversation

martin-cs
Copy link
Collaborator

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.

@martin-cs martin-cs mentioned this pull request May 23, 2017
@tautschnig tautschnig mentioned this pull request May 24, 2017
Copy link
Collaborator

@tautschnig tautschnig left a 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.

}

/*******************************************************************\
Function: variable_sensitivity_domaint::ai_simplify_lhs
Copy link
Collaborator

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:"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

}
else if(condition.id()==ID_member)
{
member_exprt me = to_member_expr(condition);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No whitespace around =

Copy link
Collaborator Author

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.

{
ie.index() = index;
condition = simplify_expr(ie, ns);
}
Copy link
Collaborator

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.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.


#include <util/json.h>
#include <util/xml.h>
#include <util/expr.h>
#include <util/simplify_expr.h>
Copy link
Collaborator

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.)

Copy link
Collaborator Author

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.

@@ -331,6 +331,29 @@ void constant_propagator_domaint::assign(
dest.set_to(lhs, rhs);
}

/******************************************************************* \
Copy link
Collaborator

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.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

if(!a.join(d))
{
unchanged=condition.is_true();
condition.make_true();
Copy link
Collaborator

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.)

Copy link
Collaborator Author

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.

}
else
{
d.assume(not_exprt(condition), ns);
Copy link
Collaborator

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?

Copy link
Collaborator Author

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:

  1. 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.

  2. 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.

  3. 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? :-)

Copy link
Collaborator Author

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.

@@ -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);
Copy link
Collaborator

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?

Copy link
Collaborator Author

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.

Copy link
Collaborator

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?

Copy link
Collaborator Author

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 :-)

@tautschnig
Copy link
Collaborator

FWIW, will approve once the changes have been pushed (and I get back to my desk).

@martin-cs martin-cs force-pushed the goto-analyzer-5-part2 branch from fa35016 to ff112c8 Compare May 24, 2017 09:17
@martin-cs
Copy link
Collaborator Author

I have fixed / responded to all of the review comments and pushed the new version.

@tautschnig
Copy link
Collaborator

Looks ok to me. I'm assuming @danpoe and @peterschrammel have been closely involved anyway, as documented in #472.

a.make_top(); // a is everything
a.assume(condition, ns); // restrict a to an over-approximation
// of when condition is true

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove one blank line.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@martin-cs
Copy link
Collaborator Author

@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.

@martin-cs
Copy link
Collaborator Author

PS There are test cases for these but they depend on the front-end refactoring and are thus in part .. N where N > 2.

@martin-cs
Copy link
Collaborator Author

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.

@martin-cs martin-cs force-pushed the goto-analyzer-5-part2 branch from ff112c8 to 15f628e Compare May 24, 2017 10:34
@peterschrammel
Copy link
Member

@martin-cs, is this ready to go or do you want to amend this PR?

@martin-cs
Copy link
Collaborator Author

@peterschrammel 2 mins?

@martin-cs martin-cs force-pushed the goto-analyzer-5-part2 branch from 15f628e to c64448b Compare May 24, 2017 11:37
@martin-cs
Copy link
Collaborator Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants