-
Notifications
You must be signed in to change notification settings - Fork 262
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
Failure to Prove Existential with Subsequence #4920
Comments
In general, it's better for dafny if anything after the "::" of an So the following works and is also usable and more deterministic because the trigger is obvious for Dafny predicate BetterShape<T>(idx: nat, xs: seq<T>, n: nat, P: seq<T> -> bool)
{
idx <= |xs| - n && P(xs[idx..idx + n])
}
lemma Test<T>(xs: seq<T>, n: nat, P: seq<T> -> bool)
ensures exists idx: nat :: BetterShape(idx, xs, n, P)
{
assume exists idx: nat :: BetterShape(idx, xs, n, P);
} |
Thanks, that’s good to know. The predicate trick works for the thing I was actually trying to prove, but I’m still surprised that triggers matter at all in this example. Shouldn't |
What do you mean by non-ambiguous on this context?
That surprises me as well, but I guess for quantifiers this doesn't hold because I think quantifiers are only useable when their trigger is found, and in your problematic example, Dafny did not add any triggers to the quantifier in the assume clause so in effect it becomes unusable. That said, I don't know how to add the right triggers to get your original example to work. I would have hoped this would work but it doesn't: lemma Test<T>(xs: seq<T>, n: nat, P: seq<T> -> bool)
ensures exists idx: nat :: idx <= |xs| - n && P(xs[idx..idx + n])
{
assume exists idx: nat {:trigger P(xs[idx..idx + n])} :: idx <= |xs| - n && P(xs[idx..idx + n]);
var idx: nat :| idx <= |xs| - n && P(xs[idx..idx + n]);
} @MikaelMayer besides the predicate workaround you gave, could you explain why the original code, and the one with triggers added, does not work? |
By non-ambiguous, I mean it's obvious what the trigger should be. Complex expressions can have non-trivial triggers which I call ambiguous, because there could be several possible triggers. Z3 has its own sets of triggers and, if Dafny does not specify triggers, Z3 might still be able to detect patterns and prove things. But Z3's mechanism is not dependable enough for Dafny's needs, so Dafny prefers to generate triggers when possible. Originally the triggers were written by hand, but because triggers generally followed rules of thumb that were pretty straightforward, their detection is now mostly automatic.
The expression Other solutions include:
lemma Test<T>(xs: seq<T>, n: nat, P: seq<T> -> bool)
ensures exists idx: nat, idxn: nat :: idxn == idx + n <= |xs| && P(xs[idx..idxn])
{
assume exists idx: nat, idxn: nat :: idxn == idx + n <= |xs| && P(xs[idx..idxn]);
var idx: nat, idxn: nat :| idxn == idx + n && idx <= |xs| - n && P(xs[idx..idxn]);
}
function plus(idx: nat, n: nat): nat { idx + n }
lemma Test<T>(xs: seq<T>, n: nat, P: seq<T> -> bool)
ensures exists idx: nat :: idx <= |xs| - n && P(xs[idx..plus(idx, n)])
{
assume exists idx: nat :: idx <= |xs| - n && P(xs[idx..plus(idx, n)]);
var idx: nat :| idx <= |xs| - n && P(xs[idx..plus(idx, n)]);
} Hope it helps! |
That's good info and it answers my question. I made a related issue: #4958 could you check if that makes sense?
Thanks! These provide good clarifications. |
I think in the case of quantifiers, you should see
while @RustanLeino would it be possible to automatically introduce names for quantifiers so that the expectation that |
This is true only if quantifiers in The various alternative formulations that @MikaelMayer showed are good. Here is one more that works in this case (it works by removing the
Rather than having an The strategy of introducing a name for the entire body ( |
I've changed the bug label into enhancement. It seems there's an opportunity to improve either documentation or error reporting, although how exactly does not seem obvious. |
Dafny version
4.4.0
Code to produce this issue
Command to run and resulting output
What happened?
While trying to prove the existence of a subsequence with some property, I found that Dafny couldn't verify the postcondition even when I assumed it. Of course, in the simplified example above,
P
may not hold for any subsequence, but it shouldn't matter since the body of the lemma assumes it does.I tried several of the tricks with triggers suggested in #2721, but I couldn't find one that helped.
What type of operating system are you experiencing the problem on?
Linux
The text was updated successfully, but these errors were encountered: