簡體   English   中英

達芙妮拒絕了一個簡單的后置條件

[英]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將僅嘗試對“重影方法”(也稱為“引理”)進行歸納。

如果在Check1method前面添加關鍵字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嘗試導入兩個 xy ,由於某種原因導致求解循環。 但是單獨對這兩個變量進行歸納是可行的。 我正在進一步研究此問題,但是當前的解決方案有效。

暫無
暫無

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

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