[英]writing inductive lemmas in dafny
我想在dafny中證明以下內容:
function append(xs: seq<int>) : seq<int> {
if |xs| == 0 then []
else [xs[0]] + append(xs[1..])
}
method test(o:seq<int>, xs: seq<int>, i:int)
requires 0 <= i < |xs|
{
if o == append(xs[..i])
{
assert o + [xs[i]] == append(xs[..(i+1)]);
}
}
我相信這需要使用引理編寫歸納證明,但是我不確定如何編寫引理。 在線文檔給出了在序列內容上使用結構歸納的示例,但是我認為在這種情況下,我認為歸納步驟需要在i
? 我試圖寫一個如下:
lemma appendLemma (xs:seq<int>, o:seq<int>, i:int)
requires 0 <= i < |xs|
requires o == append(xs[..i])
ensures o + [xs[i]] == append(xs[..(i+1)])
{
if i == 0
{
assert o + [xs[0]] == append(xs[..1]);
}
else
{
appendLemma(xs, o, i);
// what to do here?
}
}
但它一直在要求一個減少子句,在這種情況下,我不確定是否有一個?
您將對序列的長度(xs和o)進行歸納,然后我也必須減小,正如您在下面的證明中所看到的。 所以你可以說你對我做了歸納。 但是無論您做什么,對appendLemma的內部調用都必須在較小的參數上 。 它代表歸納假設,請參見。 這就是Dafny抱怨解雇的原因。
由於我們對函數append的了解僅是其歸納定義,因此以頭/尾的方式進行,我們必須在appendLemma的證明中遵循該方式,並將歸納應用於xs的尾部。
我需要一個額外的引理( appendIsCopyLemma
)來捕捉Levent appendIsCopyLemma
的觀察結果,該appendIsCopyLemma
實際上是一個簡單的副本。 請注意,Dafny無需進一步幫助即可驗證該引理,但您必須在appendLemma的證明中明確調用它(兩次)。
請注意,Dafny現在會自己推斷出Dafny在原始代碼中遺漏的減少子句; 遞歸調用的參數現在已經足夠了。
// Verified by Dafny 2.2.0
// definition of append and test in the question above
lemma appendIsCopyLemma(xs: seq<int>)
ensures xs == append(xs);
{ }
lemma appendLemma (xs:seq<int>, o:seq<int>, i:int)
// decreases i; // Dafny can infer a decrease clause by itself
requires 0 <= i < |xs|
requires o == append(xs[..i])
ensures o + [xs[i]] == append(xs[..(i+1)])
{
if |xs| == 1 || i == 0
{
assert o + [xs[0]] == append(xs[..1]); //redundant
}
else
{
appendIsCopyLemma(xs[..i]);
assert o[1..] == xs[1..][..i-1];
appendLemma(xs[1..], o[1..], i-1);
appendIsCopyLemma(xs[..i+1]);
assert xs[..i+1] == append(xs[..i+1]);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.