我的dafny方法有什么问题。简单方法后置条件可能不成立

时间:2019-07-22 16:28:03

标签: dafny

我是Dafny的新手,我正尝试在不使用*的情况下向5 * m-3 * n计算机编写代码。

有人可以告诉我我的代码有什么问题吗?我认为这是不变的且减少的。

method CalcTerm(m: int, n: nat) returns (res: int)
  ensures res == 5*m-3*n;
{
  var m1: nat := abs(m);
  var n1: nat := n;
  res := 0;

  while (m1!=0)
    invariant m1>=0
    decreases m1
  {
    res := res+5;
    m1 := m1-1;
  }

  if (m<0) { res := -res; }

  while (n1!=0)
    invariant n1 >= 0
    decreases n1
  {
    res := res-3;
    n1 := n1-1;
  }
}

但它一直在说:

A postcondition might not hold on this return path. 29  2

1 个答案:

答案 0 :(得分:0)

您说对了,这个问题与循环不变量有关。我建议阅读Guide中有关断言和循环不变式的两部分。

Dafny仅使用 不变式来“总结”循环的效果。因此,在方法中的第二个循环之后,Dafny将仅知道n1 >= 0并且该循环已终止,因此实际上是n1 == 0。这些信息不足以证明您的后置条件:您需要一个更强的不变性。这可能会帮助您取得进步

invariant res == 5 * m - 3 * (n - n1)

该不变式根据到目前为止已执行循环的迭代次数(res)计算n - n1的值。如果将此不变量添加到第二个循环中,则会得到一个新错误(进度!),该错误可能在输入时不成立。这意味着Dafny能够证明您的后置条件,但在第一个循环完成后无法确定新的不变式为真。再次是因为第一个循环的不变性太弱了。

也许这为您提供了足够的信息,以尝试自己为第一个循环提出另一个不变式。如果您遇到困难,请随时在这里提出更多问题。