-
Notifications
You must be signed in to change notification settings - Fork 263
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
Opaque block #5761
Opaque block #5761
Conversation
…ng because of incorrect encoding
…s the WF check of the ensures clause, due to DEFASS check
Source/Dafny.sln
Outdated
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExecutionEngine", "..\boogie\Source\ExecutionEngine\ExecutionEngine.csproj", "{0145DC89-7243-41F8-AB3E-F716F04E9BFF}" | ||
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Graph", "..\boogie\Source\Graph\Graph.csproj", "{05DE24BB-D639-40C4-894F-701652F51559}" |
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.
This looks like it switches to using a local version of Boogie. Is that intended to be part of the PR?
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.
Not intended to be merged, but I used that to let it build while waiting for a new Boogie version. I've since reverted that change. Sorry for the noise.
It might be a bit tedious to explicitly specify what a block ensures and in some cases one may just want to be able to selectively reveal the block in e.g. an |
Any mutation that happens inside the block causes all information to be lost about whatever was mutated, so if after the block you use any variable or reference that was mutated inside it, you won't know anything about it. It seems highly unlikely to me that you would want an opaque block without an ensures clause. If you want to supply a name to a block of statements that does not mutate variables from outside its scope, then I think defining a lemma with a transparent body (does not exist at the moment, but I could argue for it) is more appropriate. If you only want to use the lemma inside that method and local variables from the method inside the lemma, so you need to specify fewer parameters for the lemma and arguments for the call, then we could allow defining an inline lemma. |
docs/DafnyRef/Statements.md
Outdated
@@ -2476,4 +2476,27 @@ the expressions is to provide hints to aid Dafny in proving that | |||
step. As shown in the example, comments can also be used to aid | |||
the human reader in cases where Dafny can prove the step automatically. | |||
|
|||
## 8.24. Opaque Block ([grammar](#g-opaque-block)) {#sec-opaque-block} | |||
As a Dafny sequence of statements grows in length, it can become harder to verify later statements in the block. With each statement, new information can become available, and with each modification of the heap, it because more expensive to access information from an older heap version. To enable long lists of statements to maintain a verification cost linear in their size, Dafny users can extract part of this block into a separate method or lemma. However, doing so can introduce some boilerplate, whic is where opaque blocks come in. They achieve a similar effect on verification performance as extracting code, but are less work to use. |
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.
As a Dafny sequence of statements grows in length, it can become harder to verify later statements in the block. With each statement, new information can become available, and with each modification of the heap, it because more expensive to access information from an older heap version. To enable long lists of statements to maintain a verification cost linear in their size, Dafny users can extract part of this block into a separate method or lemma. However, doing so can introduce some boilerplate, whic is where opaque blocks come in. They achieve a similar effect on verification performance as extracting code, but are less work to use. | |
As a Dafny sequence of statements grows in length, it can become harder to verify later statements in the block. With each statement, new information can become available, and with each modification of the heap, it becomes more expensive to access information from an older heap version. To enable long lists of statements to maintain a verification cost closer to linear in their size, Dafny users can extract part of this block into a separate method or lemma. However, doing so can introduce some boilerplate, which is where opaque blocks come in. They achieve a similar effect on verification performance as extracting code, but are easier to use. |
docs/DafnyRef/Statements.md
Outdated
|
||
An opaque block is similar to a block statement: it contains a sequence of zero or more statements, enclosed by curly braces. However, an opaque block is preceded by the keyword 'opaque', and may define ensures and modifies clauses before the curly braces. Anything that happens inside the block is invisible to the statements that come after it, so any effect that you wish to capture must be captured by the ensures clauses of the block. Here is an example: |
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.
An opaque block is similar to a block statement: it contains a sequence of zero or more statements, enclosed by curly braces. However, an opaque block is preceded by the keyword 'opaque', and may define ensures and modifies clauses before the curly braces. Anything that happens inside the block is invisible to the statements that come after it, so any effect that you wish to capture must be captured by the ensures clauses of the block. Here is an example: | |
An opaque block is similar to a block statement: it contains a sequence of zero or more statements, enclosed by curly braces. However, an opaque block is preceded by the keyword 'opaque', and may define ensures and modifies clauses before the curly braces. Anything that happens inside the block is invisible to the statements that come after it, so any externally observable effect must be captured by the ensures clauses of the block. Here is an example: |
docs/DafnyRef/Statements.md
Outdated
|
||
<!-- %check-verify Statements.opaqueBlock.expect --> | ||
```dafny | ||
method OpaqueBlockuser() returns (x: int) |
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.
method OpaqueBlockuser() returns (x: int) | |
method OpaqueBlockUser() returns (x: int) |
// public abstract IEnumerable<IVariable> AssignedVariables { get; } | ||
|
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.
// public abstract IEnumerable<IVariable> AssignedVariables { get; } |
opaque | ||
ensures x > 3 | ||
{ | ||
x := x + y; |
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 you considered testing a AssignOrReturnStmt
?
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 callout. Added some more tests and found bugs.
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.
Sorry for not thinking of it sooner: What about AssignSuchThatStmt
?
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.
Added it and found another bug 🎉
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.
Sorry for the dripping of ideas: What about multiple LHSs and patterns on the 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.
What sort of patterns do you mean? Added the parallel assignment
Description
Example:
Slightly larger program where they're more useful:
Part of the goal of opaque statements is to enable statements blocks to grow in size without getting a quadratic increase in the resources required to prove the block.
When there are multiple paths through the method, if an assertion occurs after a merge, then conceptually it will be asserted for each path through that merge. Encasing the split and merge in an opaque block, as is done above, will simplify verification.
How has this been tested?
opaqueBlock.dfy
By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.