-
Notifications
You must be signed in to change notification settings - Fork 261
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
Counterexamples As Assumptions #5013
Counterexamples As Assumptions #5013
Conversation
Edit: right now, one can only get a counterexample in the form of assumptions. To enable test generation behavior, the counterexample model would need to be cross-referenced with the source code, so this is something that could be left as a future PR. |
I think that would be valuable, because if it can be generated, and it does cause an assertion to fail at runtime, it provides a guaranteed counter-example, instead of a counter-example guess (the model produced after an |
Have just pushed a commit that adds a warning to notify the user that the counterexample may not be valid due to the solver returning UNKOWN. I would prefer to leave counterexample execution for future work, since it will be a substantial change/addition to the PR. Executing a counterexample is, I think, indeed the only certain way to determine that the counterexample is valid but it is also not clear how applicable such a feature would be (a lot of Dafny code is not intended for execution and code that is intended for execution can fail verification for reasons that would not come up at runtime). |
docs/DafnyRef/UserGuide.md
Outdated
Note that Danfy cannot guarantee that the counterexample | ||
it reports provably violates the assertion or that the assumptions are not | ||
mutually inconsistent (see [^smt-encoding]), so this output should be | ||
expected manually and treated as a hint. |
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.
expected => inspected
Sounds good, thanks. I'm not sure what the best terminology is for these potential counterexamples, but we can iterate on that. |
docs/DafnyRef/UserGuide.md
Outdated
where to write the counterexample, as well as the | ||
`-proverOpt:O:model_compress=false` and | ||
`-proverOpt:O:model.completion=true` options. | ||
* `-extractCounterexample` - if verification fails, report a possible |
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.
subjective nitpick: possible => potential
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!
@Dargones This PR changes the counterexample API for I imagine an API like; record CounterExampleItem(Position Position, IDictionary<string, Value> Variables, IDictionary<int, Value> Heap);
interface Value;
record Primitive(string content) : Value;
record Unknown() : Value;
record Reference(int number) : Value;
record StructuredValue(string description, IDictionary<string, Value> children) : Value; // description could be the name of the type, or just "object" At some point I think counterexamples in the IDE should be shown using the debugger UI, which would mean we'd have to implement the debug adapter protocol, which has an API not too different from the one above: https://microsoft.github.io/debug-adapter-protocol/specification#Types_Variable |
HI, @keyboardDrummer! Here is a quick PR I made that should fix this: #5847 I agree that in the long term it would be great to use the debugger UI, though this might take one/two weeks of full time work...This PR (as in the one I am leaving the comment on) does a lot of heavy lifting towards that goal, I think. |
Amazing, thanks! |
Problem
Right now Dafny reports counterexamples using special syntax that may be difficult to understand. For example, consider the following Dafny program that defines a standard
List
datatype with a functionView
that maps the list to a sequence of integers:Suppose we were to (incorrectly) assert that the list cannot correspond to the sequence of integers
[1, 2, 3]
, like so:Currently, Dafny would return the following counterexample:
This counterexample is confusing because it does not explain what the meaning of
@0
,@1
, etc. is. The notation is different from the Dafny syntax, and it also does not capture some of the information that is actually contained within the counterexample because there is no way to express this information using this custom syntax. In particular, the counterexample constrains the value returned by callingView()
on thelist
variable. This constrain might be redundant in this particular example but in general, we would want to capture all the information contained in the counterexample.Solution
This PR redesigns the counterexample generation functionality so that counterexamples are represented internally and can be printed as Dafny assumptions. For example, for the program above, the counterexample will now look like this:
While admittedly more verbose because it explores the return values of functions, this counterexample precisely constrains the argument that leads to the assertion violation. In particular, if you were to insert this assumption into the code and revert the assertion, Dafny would verify that this counterexample is correct.
At a high level, this makes the following changes:
By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.