Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
39
Добавлен:
23.03.2015
Размер:
1.05 Mб
Скачать

Анализ программ, не содержащих ветвлений

Для доказательства правильности программ мы будем использовать формулы полной корректности. Каждая такая формула включает в себя два предиката – предусловие и постусловие, а также сегмент программы. Областью предикатов является набор всевозможных состояний переменных программы, получаемых в ходе вычислений.

Формула полной корректности имеет вид

{P} S1;S2;…Sn {Q}

и утверждает , что если состояние процесса вычислений перед выполнением операторов S1;S2;…Sn удовлетворяет предусловию P, то выполнение операторов S1;S2;…Sn гарантирует выполнение постусловия {Q}. Разумеется, если в начальном состоянии предусловие ложно, то вся формула истинна. Это аналогично правилу логики, утверждающему , что

(FALSE  P)  TRUE.

Видно, что пара предикатов в этих формулах очень напоминает тело спецификации процедуры: предусловие похоже на Requires, а постусловие – на Effects.

Например.

{TRUE}

X:=0; Y:=1;

{Y > X}

Как это доказать? Используя смысл операции присваивания, видно, что выполнение двух операторов присваивания даст значения переменным Y=1 и X=0. Из теории целых чисел известно, что 1 > 0, ч.т.д.

Что мы использовали:

  1. порядок вычислений в программе (управляющий поток);

  2. смысл оператора присваивания (:=);

  3. значение операции > для целых чисел.

Основной прием доказательства можно сформулировать следующим образом:

  1. Локализация всех путей между двумя предикатами.

  2. Для каждого пути выполняется проход назад от конечного предиката до обнаружения производного предиката P, который должен быть истинен по отношению к первому оператору в данном пути, если при этом был истинен конечный предикат.

  3. Информация о типах значений переменных, входящих в предикаты, используется для установления того факта, что предусловие для каждого пути включает производный предикат P.

Это доказательство можно расписать более подробно. Проход назад через второе присваивание с исходной посылкой Y > X упрощает данный фрагмент программы до следующего

{ TRUE }

X:=0;

{1 > X },

а дальнейший проход дает

TRUE  1 > 0,

которое упрощается до TRUE, следуя правилам логики целых чисел.

В построении этого доказательства мы воспользовались следующим правилом (аксиомой) присваивания:

Пусть Р есть любой предикат, а E - есть выражение свободное от побочных эффектов: тогда если Р истинен после присваивания X := E, то Р с E, подставленным во все свободные вхождения X (т.е. вхождения не связанные квантором) перед этим присваиванием, должен быть истинен.

Или другими словами:

Для того, чтобы P было верным после выполнения X:=E (где E – выражение) достаточно, чтобы P[E  X] (т.е. свойство P после замены всех вхождений X на E) было верно изначально или кратко

{ P[E  X]} X:=E {P}.

Это означает, что предикат P, в котором E подставлено во все свободные вхождения X, есть самое слабое предусловие, обеспечивающее истинность P после присваивания X:=P.

Кажется несколько странным выполнение прохода назад по программе. Но преимущество этого способа заключается в том, что таким образом мы последовательно достигаем поставленной цели: на каждом шаге, зная, что мы хотим удостовериться в правильном выполнении каждого фрагмента программы, мы вычисляем то, что должно быть истинным по отношению к данному шагу. По достижении начала программы мы получаем самое слабое условие, выполнение которого достаточно для подтверждения истинности постусловия (“самое слабое” в том смысле, что его включает в себя любое другое достаточное предусловие). Мы завершаем доказательство, показывая, что исходное предусловие включает в себя полученное нами самое слабое предусловие.

Если двигаться вперед, то необходимо начать с того, что предполагается истинным в начале выполнения программы, и вычислить то, что должно быть истинным по завершении данной части. Достигнув, таким образом, конца программы, мы будем иметь самое сильное постусловие, вытекающее из исходного предусловия (“самое сильное” в том смысле, что оно предполагает выполнение любых других значимых постусловий). В этом случае мы завершаем доказательство, если покажем, что это самое строгое постусловие включает в себя необходимое постусловие.

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

Эти два метода доказательства можно проиллюстрировать с помощью следующих рисунков:

Достаточное предусловие (P)

Необходимое

постусловие (Q)

S1; S2; … Sn

Самое слабое предусловие

Рис. 1 . Проход назад.

Достаточное предусловие (P) Самое сильное постусловие

S1; S2; … Sn

Необходимое

постусловие (Q)

Рис. 2. Проход вперед.

Мы видим, что предусловие и постусловие аналогичны предложениям Requires и Effects в спецификациях процедур. Но между ними есть существенное различие. В спецификациях процедуры предикат Effects имеет дело с двумя состояниями: до и после обращения. Когда мы ссылаемся на значение формального параметра, то рассматриваем его (порой неявно) как имеющий префикс пре- и пост-. В формуле полной корректности каждый предикат относится только к одному состоянию. Это порождает небольшую проблему, возникающую при необходимости установления связи между начальными и конечными значенгиями.

Например, рассмотрим формулу полной корректности, утверждающую, что оператор X:=X+1 приводит к увеличению X на 1. Необходимо, чтобы постусловие ссылалось как к начальному, так и к конечному значению X. Для этого введем в предусловие новую переменную X0 и считая, что она имеет такое же значение как и X. Запишем

{ X0=X } X:=X+1 {X>X0 }

Для доказательства продвинем предикат X > X0 через оператор присваивания:

X+1>X0.

Учтем, что X0=X, получим

X0+1>X0 или 1>0,

что упрощается до TRUE.

Рассмотрим несколько примеров доказательства.

Пример 1. Необходимо доказать формулу полной корректности

{ X>n } X:=X+1 {X>n+1 } (1)

Доказательство. Продвинем предикат {X>n+1 } через оператор присваивания. Получим самое слабое предусловие {X+1>n+1 } или {X>n }. Как видим самое слабое предусловие не шире (в точности совпадает) достаточного предусловия. Формула доказана.

Пример 2. Доказать

{0<X<1} X:=1/X+Y {X>Y+1}. (2)

Доказательство. Продвинем предикат {X>Y+1} через оператор присваивания. Получим самое слабое предусловие {1/X+Y>Y+1}. Теперь докажем, что достаточное предуслове включает (из него следует) самое слабое предусловие. Т.е. нам надо доказать тождественную истинность формулы

(0<X<1)  (1/X+Y>Y+1)

Заметим, что (0<X<1)  (1/X>1).

Добавив к обеим частям неравенства по Y, получим

(0<X<1)  (1/X>1)  (1/X+Y>Y+1)

ч.т.д.

Аксиома последовательного выполнения.

Соседние файлы в папке POSIBNIK