簡體   English   中英

在dafny中編寫歸納引理

[英]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.

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