【问题标题】:How can I prompt Dafny to perform induction on a sequence?如何提示 Dafny 对序列进行归纳?
【发布时间】:2016-08-08 15:38:33
【问题描述】:

我想知道我需要在以下内容中添加什么才能使其通过 dafny?

function mapper (input: seq<int>) : seq<(int, int)>
ensures |mapper(input)| == |input|
{
  if |input| == 0 then []
  else [(0,input[0])] + mapper(input[1..])   
}

// given [(0,n1), (0,n2) ... ] recovers [n1, n2, ...]
function retList (input: seq<(int, int)>, v : int) : seq<int>
ensures |input| >= |retList(input, v)|
ensures forall i :: 0 <= i < |input| && input[i].0 == v ==> input[i].1 in retList(input, v)
ensures forall x,y : int :: (x,y) in input && x == v ==> y in retList(input, v)
{
  if input == [] then []
  else if input[0].0 == v then [input[0].1] + retList(input[1..], v)
  else retList(input[1..], v)
}


method test (input: seq<int>)
requires |input| > 0 
{   
  assert retList(mapper(input), 0) == input;  
}

【问题讨论】:

    标签: formal-verification dafny


    【解决方案1】:

    编辑(我之前的回答不准确):我认为因为归纳涉及input 序列,所以 Dafny 不能自己进行归纳。您编写的代码中没有任何地方可以促使 Dafny 的归纳启发式方法尝试对 input 进行归纳。

    所以你需要写a lemma with input as an argument,当你这样做时,Dafny 会猜测对参数的归纳可能会有所帮助,然后将能够自动进行。您实际上并不需要您添加的任何规范。

    function mapper (input: seq<int>) : seq<(int, int)>
    {
      if |input| == 0 then []
      else [(0,input[0])] + mapper(input[1..])   
    }
    
    lemma allKeysRetainsInput(input: seq<int>)
       ensures retList(mapper(input), 0) == input
    { }  
    
    // given [(v,n1), (v+1,n2), (v,n3), ... ] recovers [n1, n3,...]
    function retList (input: seq<(int, int)>, v : int) : seq<int>
    {
      if input == [] then []
      else if input[0].0 == v then [input[0].1] + retList(input[1..], v)
      else retList(input[1..], v)
    }
    
    method test (input: seq<int>)
      requires |input| > 0 
    {   
      allKeysRetainsInput(input);
      assert retList(mapper(input), 0) == input;  
    }
    

    如果您想查看更多证明,可以关闭该引理的自动归纳。然后你需要手动调用归纳假设

    lemma {:induction false} allKeysRetainsInput(input: seq<int>)
       ensures retList(mapper(input), 0) == input
    { 
      if input != [] {
        allKeysRetainsInput(input[1..]);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-06-28
      • 2018-02-02
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 2015-08-05
      • 2020-07-04
      • 1970-01-01
      • 2016-12-12
      相关资源
      最近更新 更多