Skip to content
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

Merged
merged 40 commits into from
Nov 22, 2021

Conversation

keyboardDrummer
Copy link
Collaborator

@keyboardDrummer keyboardDrummer commented Nov 11, 2021

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

  • Enables normalizing any names that occur in the Boogie program when translating it into SMT commands.
  • Remove unused code that was in SMTLibNamer and UniqueNamer

Testing

  • Add a test that checks that renaming various elements in a Boogie program does not effect the solver input.
  • Add the /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.

Source/Provers/SMTLib/SmtLibNameUtils.cs Show resolved Hide resolved
Source/UnitTests/ExecutionEngineTests/ProofIsolation.cs Outdated Show resolved Hide resolved
Source/UnitTests/ExecutionEngineTests/ProofIsolation.cs Outdated Show resolved Hide resolved
Source/VCGeneration/Checker.cs Outdated Show resolved Hide resolved
Copy link
Collaborator

@MikaelMayer MikaelMayer left a comment

Choose a reason for hiding this comment

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

Just minor changes.

@shazqadeer
Copy link
Contributor

@MikaelMayer : Removing a lock does not appear a minor change to me.

@shazqadeer
Copy link
Contributor

This PR enables discarding any names that occur in the Boogie program when translating it into SMT commands.

I could not understand the sentence above in the PR description. Perhaps use extra sentences.

@shazqadeer
Copy link
Contributor

@RustanLeino : I would appreciate your input on this PR.

@keyboardDrummer keyboardDrummer changed the title Enable discarding names when translating to SMT Enable keeping SMT commands constant when Boogie identifiers are renamed Nov 12, 2021
@keyboardDrummer keyboardDrummer changed the title Enable keeping SMT commands constant when Boogie identifiers are renamed Allow keeping SMT commands constant when Boogie identifiers are renamed Nov 12, 2021
@keyboardDrummer
Copy link
Collaborator Author

This PR enables discarding any names that occur in the Boogie program when translating it into SMT commands.

I could not understand the sentence above in the PR description. Perhaps use extra sentences.

Done.

@shazqadeer
Copy link
Contributor

  • The PR title talks about renaming which is an accurate description of the goals of the PR. However, the PR description talks about discarding which is misleading and confusing.
  • The option name DiscardNames is confusing and should be renamed to something that indicates that variables in the input are being renamed according to some scheme to product the SMT output.

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.

@keyboardDrummer
Copy link
Collaborator Author

keyboardDrummer commented Nov 14, 2021

  • The PR title talks about renaming which is an accurate description of the goals of the PR. However, the PR description talks about discarding which is misleading and confusing.
  • The option name DiscardNames is confusing and should be renamed to something that indicates that variables in the input are being renamed according to some scheme to product the SMT output.

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.

@RustanLeino
Copy link
Contributor

I think

focus solely on providing zero solver input changes when possible

is a good goal to focus on.

Copy link
Contributor

@RustanLeino RustanLeino left a 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];
Copy link
Contributor

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?

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 don't know, I didn't write this code, just moved it.

Source/UnitTests/ExecutionEngineTests/ProofIsolation.cs Outdated Show resolved Hide resolved
Source/Core/CommandLineOptions.cs Outdated Show resolved Hide resolved
@RustanLeino
Copy link
Contributor

I could look into why those names are maintained, but we can also leave it for later.

Don't worry about the types T@T and T@U and the function tickleBool, etc. These are always added by Boogie, so they will be the same for any input.

@RustanLeino
Copy link
Contributor

The output was effected but I've since changed the ModelParser so it automatically reverts the renaming when recovering a model from Z3, this makes the counterexample display unchanged by this PR.

Excellent! Thanks.

RustanLeino
RustanLeino previously approved these changes Nov 17, 2021
MikaelMayer
MikaelMayer previously approved these changes Nov 17, 2021
@shazqadeer shazqadeer changed the title Allow keeping SMT commands constant when Boogie identifiers are renamed Allow keeping SMT commands unchanged when Boogie identifiers are renamed Nov 21, 2021
ps.GetNumericArgument(ref emitDebugInformation);
return true;

case "discardNames":
Copy link
Contributor

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.

Copy link
Collaborator Author

@keyboardDrummer keyboardDrummer Nov 22, 2021

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?

Copy link
Member

Choose a reason for hiding this comment

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

Maybe normalizeNames?

Copy link
Contributor

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.

Copy link
Collaborator Author

@keyboardDrummer keyboardDrummer Nov 22, 2021

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.

@keyboardDrummer keyboardDrummer merged commit 9f53039 into boogie-org:master Nov 22, 2021
@keyboardDrummer keyboardDrummer deleted the thrashingNamer branch November 22, 2021 17:44
keyboardDrummer added a commit to dafny-lang/dafny that referenced this pull request Dec 10, 2021
…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants