语言理论 - 循环不变量 - 前/后条件

时间:2011-10-25 22:46:25

标签: java specifications language-theory

我正在为语言理论考试修改工作。我们可以做的一些练习涉及编写前后条件和循环不变量,用于几种方法。

我已经完成了一个,并认为它非常好(请告诉我,如果不是:P),下一个应该是相似的,但有一个简单的方法来解决它。

int sum(int[] a) //method header
Pre: even(a.length) //precondition
Post: result = SUM(i=0;a.length−1) a[i] //postcondition


int sum(int[] a) {
int r = 0;
int k = 0;
while (k < a.length) {
r = r + a[k];
k = k + 1;
}
return r;
}

我将pre / pos + loop inv设为:

Pre: even(a.length) ∧ r = 0 ∧ k = 0
Post: r = SUM(i=0;a.length−1) a[k]
Inv: 0 ≤ k ≤ a.length ∧ r = SUM(i=0; k −1) a[i]

我需要对这些(非常)类似的方法做同样的事情:

1

int r = 0;
int k = a.length-1;
while (k >= 0 ) {
r = r + a[k];
k = k - 1;
}
return r;

2

int r = 0;
int k = 0;
while (k < a.length/2) {
r = r + a[k] + a[a.length-1-k];
k = k + 1;
}
return r;

3

int r = 0;
int k = 0;
while (k < a.length) {
r = r + a[k] + a[k+1];
k = k + 2;
}
return r;

4

int r = 0; int s = 0;
int k = 0; int l = a.length-1;
while (k < l) {
r = r + a[k]; s = s + a[l];
k = k + 1; l = l - 1;
}
return r + s;

所以基本上我要问的是,我的第一部分是正确的(前/后/循环在顶部),如果是这样,这四个如何变化(似乎并不多)。

提前感谢您的帮助。

[编辑]

尝试Q1(不确定质量)

Pre: even(a.length) ∧ r = 0 ∧ k = a.length-1
Post: r = SUM(a.length−1; i=0) a[k] 
Inv: 0 ≤ k ≤ a.length ∧ r = SUM(k-1; i=0) a[i]

2 个答案:

答案 0 :(得分:2)

您的r=SUM应该是r = SUM(i=0;k −1) a[i]

第一个只是向后计数

数字2和4基本等同于l,4是a.length-1-k的别名(看看你是否可以证明你自己),它们都来自数组的任一端并从那里求和< / p>

第三个为计数器变量k增加2,但不变量因此而改变

答案 1 :(得分:1)

有兴趣看到实际的问题,因为......“制定前后条件”是无稽之谈:如果考官要求......改为更好的学校。

你可能会被问到“找到方法终止的最弱前提条件并给出明确定义的答案,在这种情况下是最强的后置条件”:这是一个明智的问题。

另一方面,考虑到第一种方法和所述的前/后条件,询问循环前/后条件和不变量是有意义的,但如上所述,问题应该向后解决:给定预期的方法后置条件,该方法满足后置条件所需的循环最弱条件是什么?

然后:考虑到后置条件,所需的循环最弱的前提条件是什么?鉴于您可以询问是否可以从规定的方法前提条件推断出前提条件(不要忘记方法开始和循环之间的代码)。

在那种形式中,even谓词没有位置,不需要满足循环或方法的后置条件(这是引用的第一个算法)。

您感兴趣的是,您错过了一些重要的前提条件。其中之一是总和在int类型的范围内,但是如果溢出导致非终止,则这是不够的。