[英]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 > 0
或cnt > 0
。
要解決此問題,您需要在變量cnt
和idx
之間添加一些關系,以便 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 > 0
在while
循環結束時成立,即使您沒有在invariant
中明確指定它。這是因為n
在 while 循環的主體中沒有被修改,所以 Dafny 會自動從頭開始傳遞n > 0
的事實。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.