简体   繁体   English

Dafny 简单断言不成立

[英]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 > 0cnt > 0

To fix this, you need to add some relation between the variables cnt and idx that Dafny could check and then use.要解决此问题,您需要在变量cntidx之间添加一些关系,以便 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 > 0while循环结束时成立,即使您没有在invariant中明确指定它。这是因为n在 while 循环的主体中没有被修改,所以 Dafny 会自动从头开始传递n > 0的事实。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM