我正在研究一些Hoare逻辑,我想知道我的方法是否正确。
我有以下程序P:
s = 0
i = 1
while (i <= n) {
s = s + i
i = i + 1
}
它应该满足hoare triple {n> = 0} P {s = n *(n + 1)/ 2}(所以它只取总和)。现在,我最初有| s = i *(i-1)/ 2 |作为我的不变量,工作得很好。但是,从循环结束到我想要的后置条件,我遇到了问题。因为暗示
|s = i*(i-1)/2 & i > n|
=>
| s = n * (n+1) / 2 |
要坚持,我需要证明我是n + 1,而不仅仅是n大于n。所以我想到的是将(i <= n + 1)添加到不变量,以便它变为:
|s = i * (i-1)/2 & i <= n+1|
然后我可以证明该程序,所以我认为它应该是正确的。
尽管如此,我发现不变量有点,不那么“不变”:)。并不像我到目前为止在课程或练习中看到的那样,所以我想知道这里是否有更优雅的解决方案?
答案 0 :(得分:0)
所以我想到的是将(i <= n + 1)添加到不变量,以便它变为:
|s = i * (i-1)/2 & i <= n+1|
尽管如此,我发现不变量有点,不那么“不变”:)。并不像我到目前为止在课程或练习中看到的那样,所以我想知道这里是否有更优雅的解决方案?
没有,考虑到编写代码的方式,这正是要走的路。 (我可以从经验中看出,因为我在几个学期的两个不同的课程中教授Hoare逻辑,因为这是我研究生学习的一部分。)
在编程时,使用i <= n
被认为是一种很好的做法。然而,在你的特定程序中,你也可以写i != n+1
代替,在这种情况下,你的第一个不变量(确实看起来更干净)就足够了
| s=i*(i-1)/2 & i=n+1 |
=>
| s=n*(n+1)/2 |
显然持有。