[英]Dafny rejects a simple postcondition
下面是首次證明各種簡單定理,在這種情況下是關於奇偶性的。 達夫妮/ v。 1.9.9.40414/驗證將2加上偶數會產生偶數,但不接受任何注釋條件。
function IsEven(a : int) : bool
requires a >= 0
{
if a == 0 then true
else if a == 1 then false
else IsEven(a - 2)
}
method Check1(a : int)
requires a >= 0
ensures IsEven(a) ==> IsEven(a + 2)
//ensures IsEven(a) ==> IsEven(a + a)
//ensures IsEven(a) ==> IsEven(a * a)
{
}
當我剛剛開始研究這個出色的工具時,我的方法或實現可能不正確。 任何意見,將不勝感激。
這里發生的事情很少。 我將依次討論這三個后置條件。
由於IsEven
是一個遞歸定義的謂詞,因此,有關它的事實通常需要歸納證明。 您的第一個發布條件很簡單,不需要誘導,這就是它經歷的原因。
您的第二個后置條件確實需要進行歸納證明。 Dafny具有自動執行歸納法的啟發式方法,但是這些啟發式方法僅在某些情況下被調用。 特別是,Dafny將僅嘗試對“重影方法”(也稱為“引理”)進行歸納。
如果在Check1
的method
前面添加關鍵字ghost
(或將method
更改為lemma
,等效),您將看到第二個后置條件通過了 。 這是因為調用了Dafny的歸納啟發法並設法完成了證明。
第三個后置條件更為復雜,因為它涉及非線性算術。 (換句話說,它涉及將兩個變量相乘的非平凡推理。)Dafny的基礎求解器在此類事情上很難推理,因此歸納法的啟發式證明沒有通過。
a * a
是即使a
是連 一種證明方法是在這里 。 我已經將IsEven(a) ==> IsEven(a * a)
分解為自己的引理,稱為EvenSquare
。 我也將其更改為以IsEven(a)
為前提,而不是在后置條件中進行暗示。 (類似的證明也通過暗示來進行,但是對這樣的引理使用前提而不是暗示是慣用的Dafny。)
EvenSquare
的證明是通過在上a
(手動)歸納來實現a
。 基本情況是自動處理的。 在歸納情況下( if
語句的主體),我調用歸納假設(即,我對EvenSquare
進行了遞歸方法調用,以確定(a - 2) * (a - 2)
是偶數)。 然后,我斷言a * a
可以寫為(a - 2) * (a - 2)
和一些偏移量的總和。 斷言將自動調度。 如果我能證明這種平等的右邊是偶數,就可以證明。
為此,我已經知道(a - 2) * (a - 2)
是偶數,因此我首先調用另一個引理來表明偏移量是偶數,因為它是其他值的兩倍。 最后,我調用最后一個引理以表明兩個偶數之和是偶數。
假設兩個引理,這就完成了證明。
仍然需要證明兩次都是偶數,並且兩個偶數之和是偶數。 盡管不完全是瑣碎的事,但它們都沒有EvenSquare
復雜。
引理EvenDouble
證明兩次都是偶數。 (實際上,這是第二個后置條件的增強版本。第二個后置條件表明,將任何偶數加倍是偶數。實際上,將所有(在偶數的定義下為非負數)加倍根本就是偶數。)證明(通過)手動在上a
EvenDouble
收益。 基本情況是自動處理的。 歸納案例僅需要明確調用歸納假設。
引理EvenPlus
幾乎是由Dafny的歸納啟發法自動證明的,除了它會因bug或其他導致解算器循環的問題而跳閘。 經過一點調試后,我確定注解{:induction x}
(或{:induction y}
)使證明不循環。 這些注釋告訴Dafny的試探法嘗試引入哪個變量。 默認情況下,在這種情況下,Dafny嘗試導入兩個 x
和y
,由於某種原因導致求解循環。 但是單獨對這兩個變量進行歸納是可行的。 我正在進一步研究此問題,但是當前的解決方案有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.