3

我正在为语言理论考试做修订作业。我们可以做的一些练习包括为几种方法编写前置条件和后置条件以及循环不变量。

我已经完成了一个,并且认为它非常好(如果不是,请告诉我: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]
4

2 回答 2

2

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

第一个只是倒数

数字 2 和 4 本质上等同于lfrom 4 是 to 的别名a.length-1-k(看看你是否可以证明自己)它们都从数组的任一端开始并从那里求和

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

于 2011-10-25T23:16:27.640 回答
1

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

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

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

那么:给定后置条件,循环所需的最弱前置条件是什么?假设您可以询问是否可以从所述方法的前提条件中推断出该前提条件(不要忘记方法开始和循环之间的代码)。

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

出于兴趣,您错过了一些重要的先决条件。其中之一是总和在 type 的范围内int,但是虽然这是必要的,但如果溢出导致不终止是不够的。

于 2011-12-17T09:41:50.930 回答