我是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
答案 0 :(得分:0)
您说对了,这个问题与循环不变量有关。我建议阅读Guide中有关断言和循环不变式的两部分。
Dafny仅使用 不变式来“总结”循环的效果。因此,在方法中的第二个循环之后,Dafny将仅知道n1 >= 0
并且该循环已终止,因此实际上是n1 == 0
。这些信息不足以证明您的后置条件:您需要一个更强的不变性。这可能会帮助您取得进步
invariant res == 5 * m - 3 * (n - n1)
该不变式根据到目前为止已执行循环的迭代次数(res
)计算n - n1
的值。如果将此不变量添加到第二个循环中,则会得到一个新错误(进度!),该错误可能在输入时不成立。这意味着Dafny能够证明您的后置条件,但在第一个循环完成后无法确定新的不变式为真。再次是因为第一个循环的不变性太弱了。
也许这为您提供了足够的信息,以尝试自己为第一个循环提出另一个不变式。如果您遇到困难,请随时在这里提出更多问题。