循环不变量证明部分正确性

时间:2013-07-28 02:21:46

标签: while-loop proof correctness formal-verification loop-invariant

我正在尝试找到循环不变量,以便我们可以证明此程序部分正确:

{ n >= 1 } pre-condition 
i = 1;
z = 1;
while (i != n) {
  i = i + 1;
  z = z + i*i;
}
{ z = n*(n+1)*(2*n + 1)/6 } post-condition

我真的被卡住了。到目前为止,我尝试过的一些不变量是:

z <= n*(n+1)*(2*n + 1)/6 ^ i <= n

z = i*(i+1)*(2*i + 1)/6 ^ i <= n

我真的很感激一些建议。

1 个答案:

答案 0 :(得分:0)

要找到一个合适的不变量,你必须有一个直觉,调查函数实际上做了什么。在您的示例中,值i^2会连续添加到累加器z。因此函数计算(只需手动完成while循环的前几次迭代然后进行泛化):

1^2 + 2^2 + 3^2 + 4^2 + 5^2 + ... + n^2

或者写得更正式

SUM_{i=1}^{n} i^2

,即i的所有方格的总和,范围从1n

乍一看,这可能看起来不像你的后期条件。但是,可以通过n上的归纳显示上述总和等于

(n*(n+1)*(2*n + 1))/6

我猜这是预期的后置条件。既然我们现在知道后置条件等于这个总和,那么应该很容易从总和中读出不变量。