![](/img/trans.png)
[英]Dafny precondition 0 <= size < capacity might not hold
[英]Why does Dafny think there might be a problem with this precondition when using a ghost variable?
假設我有以下課程:
class Testing {
ghost var myGhostVar: int;
method Init()
modifies this
ensures this.myGhostVar == -1
{
this.myGhostVar := -1;
assert this.myGhostVar == -1;
}
method MyTestingMethod(list: array<int>, t: int)
modifies this
requires list.Length > 1
requires this.myGhostVar == -1
requires t == -1
ensures MyPredicate(list, myGhostVar)
ensures this.myGhostVar < list.Length
{
this.Init();
assert this.myGhostVar < 0;
assert list.Length > 0;
assert this.myGhostVar < list.Length;
}
predicate MyPredicate(list: array<int>, startIndex: int)
requires startIndex < list.Length
{
true
}
}
出於某種原因,達夫尼說對MyPredicate(...)
的調用可能不成立。 但是,如果我改為使用t
作為參數而不是myGhostVar
; 達夫尼沒有抱怨。
兩者都有相同的requires
謂詞,這使它有點混亂。 使用幽靈變量時我缺少什么嗎?
這不是 ghost 變量的問題 - 如果刪除ghost
關鍵字,您可以檢查並查看是否會遇到相同的問題。
問題是要調用MyPredicate(list, myGhostVar)
,您需要滿足先決條件,這里是myGhostVar < list.Length
。
實際上,您的確保條款中有此條件,這很棒!
ensures MyPredicate(list, myGhostVar)
ensures this.myGhostVar < list.Length
但是您對MyPredicate
的調用是在您需要的條件之前。 嘗試翻轉順序:
ensures this.myGhostVar < list.Length
ensures MyPredicate(list, myGhostVar)
你應該看到達夫尼不再抱怨了。
在一般情況下,Dafny將試圖證明,一個內部的前置條件ensures
條款持有使用以前的保證條款。
兩者都有相同的 requires 謂詞,這使它有點混亂。 使用幽靈變量時我缺少什么嗎?
在這里,我想你是在問條款
requires this.myGhostVar == -1
requires t == -1
並想知道為什么它不能使用this.myGhostVar == -1
前提條件來證明this.myGhostVar < list.Length
。
答案是this.myGhostVar == -1
是一個先決條件,這意味着 Dafny 知道它在進入時保持,但是this.myGhostVar
的值可能會在方法執行期間發生變化。 因此,在檢查后置條件時,這對 Dafny 沒有幫助。
請注意,在檢查其后置條件的格式良好時,Dafny 不會查看其方法的主體。 為此,Dafny 只知道您在方法簽名中告訴它的內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.