-
Notifications
You must be signed in to change notification settings - Fork 269
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
Function by method bodies should not be allowed to contain expect statements #1376
Comments
How would this apply to the documentation's example of using |
It just implies the method would need to declare It would be useful in the future for Dafny to still support termination proofs of methods that call other methods with |
Thank you for pointing out that it would be good for Dafny to offer to track the use of It's sort of related to non-termination, in that A primary use of the method Random(n: int32) returns (r: int32)
requires 0 < n
ensures 0 <= r < n
{
r := JavaRandom(n);
expect 0 <= r < n;
}
method {:extern "java.util.Random"} JavaRandom(n: int32) returns (r: int32)
requires 0 < n shows how the So, while tracking " |
Note that if we ever add a feature to automatically generate Also, what would be the benefit of tracking expect-effects? Why would a programmer want to track where in their code there is the potential for a halt due to unverified downstream code? Would the expect-effect tracking allow the programmer to avoid code like this?
I would like to understand the use-case for except-effect tracking better before adding it as a feature. I also wonder whether just tracking halts is enough, or whether this would also create the need for a mechanism to recover from halts. |
As the original author of The primary motivation was really being able to write tests in Dafny. We initially found that using method Expect(p: bool) returns (result: Result<()>)
ensures result.Success? ==> p
{
if p {
return Success(());
} else {
return Failure("Failed expectation");
}
} One of the more serious issues with this approach was that it was too easy to accidentally ignore the result: var someValue := GoDoAThing();
var _ := Expect(someValue == 42); This actually has no effect, even if var _ :- Expect(someValue == 42); Since @keyboardDrummer: I agree that halting is the real effect to track rather than In my opinion, an error state that is recoverable should be modelled as an explicit value and likely handled/propagated using @RustanLeino: I think you're correct that |
In case you call a method that halts then I think you wouldn't do anything with the post-condition. Could you not compute a replacement post-condition based on the modifies clause that implements the maximum disturbance the method could have? To be clear, the reason I mentioned a recovery mechanism is that I don't understand yet what the purpose is of tracking whether code can halt or not, and being able to recover from halted code would give tracking it more use. |
Having mulled this over for a while, I've arrived at a concrete alternate proposal.
I assert that by default As an aside, I've wanted to find a way for Dafny to support more "incremental verification", so that people can get started and make progress on Dafny code quicker, while tracking the fact that they still have work to do to prove correctness. This would mirror the benefits of gradual typing. I've arrived at the conclusion that |
I agree with this view of To make sure I understand the alternate proposal, @robin-aws , you're suggesting that we not have any other finer-gain As a general design point (now addressing @keyboardDrummer 's points and questions), I think that it seems reasonable for a verified language to offer some kind of control over each possible effect in the language. Since |
That's correct - I'm suggesting that the course-grained CLI flag is enough, mainly just to let the build process specify the scope where The only advantage I can think of for the |
Similar to #1346, which is about tracking the side-effects of
print
, in particular in the context of function by methods, but arguably more concerning.This creates a function whose specification-time behavior does not completely align with its compiled behavior:
BadFunction(0)
is equal to0
and yet halts at run time.In retrospect, I would argue that
expect
is tightly coupled to termination proofs: a failed expect statement causes a method to fail to terminate just as infinite recursion would. I propose forbiddingexpect
statements in any method that does not havedecreases *
, which would would then forbid its use in function by methods since they cannot skip termination proofs with that syntax. This would break backwards compatibility but could be reasonable, givenexpect
is only used in test code to the best of my knowledge.The text was updated successfully, but these errors were encountered: