簡體   English   中英

Dafny 簡單斷言不成立

[英]Dafny simple assertion does not hold

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 ***
}

令人驚訝的是,這個版本也使斷言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 ***
}

在您的第一段代碼中,當while循環退出時,Dafny 只知道!(idx < n) 因此,它可以推斷idx > 0 但是,Dafny 此時對cnt變量一無所知,因此您的第二個斷言失敗。

在第二段代碼中,當while循環退出時,Dafny 所知道的就是!(idx < n && cnt < n) (同樣,在while循環上否定條件)。 這相當於idx > n || cnt > n idx > n || cnt > n 從那里,Dafny 可以推斷idx > 0 || cnt > 0 idx > 0 || cnt > 0 ,但它無法自行證明idx > 0cnt > 0

要解決此問題,您需要在變量cntidx之間添加一些關系,以便 Dafny 可以檢查然后使用。

    while idx < n && cnt < n 
        decreases n - idx 
        decreases n - cnt 
        invariant idx == cnt 
    {   
        idx := idx + 1;  
        cnt := cnt + 1;
    }   

額外的invariant行告訴 Dafny 檢查idx == cnt將在循環的每次迭代中保持不變,然后它可以在最后使用該事實。 但是,除非您告訴它這樣做,否則 Dafny 不會知道要考慮idx == cnt這個事實。

(作為旁注,您將看到 Dafny能夠自行確定n > 0while循環結束時成立,即使您沒有在invariant中明確指定它。這是因為n在 while 循環的主體中沒有被修改,所以 Dafny 會自動從頭開始傳遞n > 0的事實。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM