-
Notifications
You must be signed in to change notification settings - Fork 112
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
Allow keeping SMT commands unchanged when Boogie identifiers are renamed #452
Allow keeping SMT commands unchanged when Boogie identifiers are renamed #452
Conversation
665b2fa
to
e0cc6f1
Compare
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.
Just minor changes.
@MikaelMayer : Removing a lock does not appear a minor change to me. |
I could not understand the sentence above in the PR description. Perhaps use extra sentences. |
@RustanLeino : I would appreciate your input on this PR. |
Done. |
I see that you are renaming names as n0, n1, ... Did I get that right? Is it still possible that a minor change to an input file would cause the names assigned to variables x and y to shift? I imagine that the actual assignment of names to x and y would depend on some iteration order. Changes to names other than x and y could cause the iteration order to change. |
Good callout. The steps I'm adding to Boogie are these:
The combination of these allows solver input to remain unchanged, when changes unrelated to the verification condition being solved are made, and when declarations are reordered or renamed. However, you are right that adding something that isn't pruned away might change the names of all the other declarations in the program, due to the naming by order system. One question is whether we should always try to minimise the amount of changes in solver input, or focus solely on providing zero solver input changes when possible. I'm doing the latter since that's the only thing which guarantees no change in solver behavior. If you're adding something that cannot be pruned away, then a small change to solver input is unavoidable. That the renaming scheme makes this a bigger change is something I'm accepting, given the benefit of getting zero solver input changes when only doing a rename. Another reason I'm adding the renaming scheme is because it's useful for Dafny. Dafny names some of the Boogie declarations it compiles to using a global counter, so changes to one proof can effect the names generated for another proof. Renaming those declarations after pruning and reordering in Boogie makes the names only depend on the current proof again. Another way of solving this problem would be for Dafny to generate one Boogie program per verification condition, but that's a big change for us. An improvement to this order based renaming scheme could be to choose a base-name based on a content hash instead having it fixed, but I'm leaving that for another PR since it requires significantly more changes and I saw good results for verification stability in Dafny with the PRs that are published now. |
I think
is a good goal to focus on. |
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 like this option. I have some questions that the code I read didn't answer for me:
- Are only top-level declarations renamed? Or does the renaming also apply to local variables, quantified variables, and incarnation variables?
- Boogie performs "lambda lifting", where it creates a function for each
lambda
binder in the given program. Do these play a part of the renaming? - Under the renaming option, is the output affected? That is, will Boogie rename things back before given back any results to its callers? For example, if you want to use the counterexample display in the Dafny IDE, then will it still know what variables to ask for value for? (If the output is affected, then I have doubts about how useful this PR actually is to Boogie clients.)
var allGood = true; | ||
|
||
foreach (char ch in s) | ||
validIdChar = new bool[255]; |
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 255? I'm guessing it has to do with 255 being close to 2^8. But then, why not use all 256? Or is 255 just an arbitrary "pretty small" 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 don't know, I didn't write this code, just moved it.
…itDebugInformation as a command line option
Don't worry about the types |
Excellent! Thanks. |
Source/Core/CommandLineOptions.cs
Outdated
ps.GetNumericArgument(ref emitDebugInformation); | ||
return true; | ||
|
||
case "discardNames": |
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 find the option name "discardNames" confusing. I have indicated several times before in my feedback that the verb "discard" is inappropriate for what this PR is trying to achieve.
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.
Hey, sorry for not responding to your earlier comment.
Do you have a suggestion for a different name? Your earlier comment seems to indicate something with rename
, but I find that renameNames
does not say enough about what the option does.
The goal of the option is to get verification output that does not depend on the original identifier names and is deterministic. I picked discardNames
to indicate that the original program names are not used, leaving the reader to conclude that they must be replaced using some fixed naming scheme.
Here are some ideas for other names:
replaceNames
, discardAndReplaceNames
, ignoreNames
, or renameBasedOnContent
Do you have a preference or suggestion?
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.
Maybe normalizeNames
?
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.
normalizeNames appears to be the best option so far.
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.
Great, changed it to normalizeNames.
df888b3
…tion behavior of the proof (#1612) In DafnyOptions.cs, turn on Boogie's `Prune` and `NormaliseNames` option, and turn off `EmitDebugInformation`, to increase verification stability. Use `uses` clauses on constants and functions, both in DafnyPrelude.bpl and in generated Boogie declarations, and the `include_dep` attribute on axioms, to ensure not too much is pruned. More information on these Boogie features can be found in the PRs that introduce them: boogie-org/boogie#450, boogie-org/boogie#452, boogie-org/boogie#453, boogie-org/boogie#454, boogie-org/boogie#464 In follow-up PRs, we will replace all `include_dep` with `uses` clauses, since they allow more but still correct pruning. This PR also updates the test `SchorrWaite.dfy` to make it more stable. Changes stolen from #1620
Related Dafny issue: dafny-lang/dafny#1585
This PR includes changes #453
SMT solvers in practice can show significantly different behavior in terms of total runtime and
check-sat
result when identifiers in the input are renamed. Such changes in solver output are often surprising to the Boogie programmer, so this PR introduces an option to normalize names in the Boogie program.Changes
Testing
/normalizeNames:1
option to all tests that inspect the SMT model, to verify that names in the parsed SMT model are correctly translated back to their original name.