[英]Dafny simple assertion does not hold
In exercise_1a
what could be done to make the assertion cnt > 0
valid?在
exercise_1a
1a 中,可以做些什么来使断言cnt > 0
有效?
method exercise_1a(n: int)
requires n > 0
{
var idx := 0;
var cnt := 0;
while idx < n
decreases n - idx
{
idx := idx + 1;
cnt := cnt + 1;
}
assert idx > 0; // valid
assert cnt > 0; // *** invalid ***
}
Surprisingly, this version invalidates the assertion idx > 0
, as well:令人惊讶的是,这个版本也使断言
idx > 0
无效:
method exercise_1b(n: int)
requires n > 0
{
var idx := 0;
var cnt := 0;
while idx < n && cnt < n
decreases n - idx
decreases n - cnt
{
idx := idx + 1;
cnt := cnt + 1;
}
assert idx > 0; // *** invalid ***
assert cnt > 0; // *** invalid ***
}
In your first snippet of code, when the while
loop exits, all Dafny knows is that !(idx < n)
.在您的第一段代码中,当
while
循环退出时,Dafny 只知道!(idx < n)
。 Therefore, it can infer that idx > 0
.因此,它可以推断
idx > 0
。 However, Dafny doesn't know anything about the cnt
variable at this point, so your second assertion fails.但是,Dafny 此时对
cnt
变量一无所知,因此您的第二个断言失败。
In the second snippet of code, when the while
loop exits, all Dafny is knows is that !(idx < n && cnt < n)
(again, the negation of the condition on the while
loop).在第二段代码中,当
while
循环退出时,Dafny 所知道的就是!(idx < n && cnt < n)
(同样,在while
循环上否定条件)。 This is equivalent to idx > n || cnt > n
这相当于
idx > n || cnt > n
idx > n || cnt > n
. idx > n || cnt > n
。 From there, Dafny could infer idx > 0 || cnt > 0
从那里,Dafny 可以推断
idx > 0 || cnt > 0
idx > 0 || cnt > 0
, but it wouldn't be able to prove either idx > 0
or cnt > 0
on its own. idx > 0 || cnt > 0
,但它无法自行证明idx > 0
或cnt > 0
。
To fix this, you need to add some relation between the variables cnt
and idx
that Dafny could check and then use.要解决此问题,您需要在变量
cnt
和idx
之间添加一些关系,以便 Dafny 可以检查然后使用。
while idx < n && cnt < n
decreases n - idx
decreases n - cnt
invariant idx == cnt
{
idx := idx + 1;
cnt := cnt + 1;
}
The extra invariant
line tells Dafny check that idx == cnt
will hold across every iteration of the loop, and then it can use that fact at the end.额外的
invariant
行告诉 Dafny 检查idx == cnt
将在循环的每次迭代中保持不变,然后它可以在最后使用该事实。 However, Dafny would not know to bring the fact idx == cnt
under consideration unless you tell it to do so.但是,除非您告诉它这样做,否则 Dafny 不会知道要考虑
idx == cnt
这个事实。
(As a side note, you'll see that Dafny is able to determine, on its own, that n > 0
holds at the end of the while
loop, even while you don't specify it explicitly as in invariant
. This is because n
is not modified in the body of the while loop, so Dafny will automatically carry across the fact that n > 0
from the beginning.) (作为旁注,您将看到 Dafny能够自行确定
n > 0
在while
循环结束时成立,即使您没有在invariant
中明确指定它。这是因为n
在 while 循环的主体中没有被修改,所以 Dafny 会自动从头开始传递n > 0
的事实。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.