Теория языка - Циклические инварианты - Условия до / после - PullRequest
3 голосов
/ 26 октября 2011

Я работаю над ревизионным заданием для экзамена по теории языка. Пара упражнений, которые мы можем выполнить, включают написание условий до и после и циклические инварианты для пары методов.

Я закончил один и думаю, что он довольно хорош (пожалуйста, скажите мне, если это не так: 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 + 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;

Итак, в основном я спрашиваю, верна ли моя первая часть (pre / post / loop вверху), и если да, то как эти четыре изменяются (кажется, не так уж много).

Заранее спасибо за помощь.

[Изменить]

Попытка 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 ]

2 голосов
/ 26 октября 2011

ваш r=SUM, вероятно, должен быть r = SUM(i=0;k −1) a[i]

первый из них имеет значение

числа 2 и 4 по существу эквивалентны с l от 4, являющимся псевдонимом до a.length-1-k (посмотрите, можете ли вы доказать это самостоятельно), они оба идут с любого конца массива и оттуда суммируются

третий принимает приращения 2 для счетчика var k, но из-за этого инвариант не изменяется

1 голос
/ 17 декабря 2011

Интересно увидеть фактический вопрос, потому что ... это бессмысленно "отрабатывать предварительные и последующие условия": если экзаменатор попросил об этом ... перейти в лучшую школу.

Вас могут попросить "найти самое слабое предварительное условие, для которого метод завершается и дает четко определенный ответ, и, в этом случае, самое сильное постусловие": это разумный вопрос.

С другой стороны, учитывая первый метод вместе с указанными предварительными / последующими условиями, имеет смысл спросить о предварительных / последующих условиях цикла и их инвариантах, но, как и выше, вопрос должен быть решен задом наперед: Предполагаемое постусловие метода, какое самое слабое постусловие цикла требуется для того, чтобы метод удовлетворял его постусловию?

Тогда: учитывая это постусловие, какое самое слабое предварительное условие цикла требуется? После этого вы можете спросить, можно ли вывести это предварительное условие из указанного предварительного условия метода (не забывая код между началом метода и циклом).

В этой форме предикат even не имеет места, он не обязан удовлетворять постусловию цикла или метода (это первый процитированный алгоритм).

Что касается интереса, вы пропустили некоторые жизненно важные предварительные условия. Одним из них является то, что сумма находится в диапазоне типа int, однако, хотя это необходимо, этого недостаточно, если переполнение приводит к невозможности завершения.

...