Практическое занятие №8

advertisement
Практическое занятие №8
Тема: Доказательство правильности программ.
1.
Математическая индукция.
Математическая индукция представляет собой общий способ доказательства. Он
положен в основу всех приемов доказательства правильности программ для ЭВМ.
2.
Принцип строгой индукции.
Пусть S(n) – некоторое высказывание о целом числе n и требуется доказать, что S(n)
справедливо для всех положительных n. Для этого необходимо:
1. Доказать, что справедливо S(1);
2. Доказать, что если справедливы высказывания S(1), S(2), …, S(n) для всех
положительных n, то справедливо S(n+1).
3.
Принцип обобщенной индукции.
Метод математической индукции можно обобщить и применять не только для
доказательства высказываний о множестве положительных целых чисел, но и о более общих
множествах некоторых объектов.
Пусть Х – вполне упорядоченное (см. Практическое занятие №2) относительно <
множество, а S(x) – некоторое высказывание, касающееся элемента х  Х. Если требуется
доказать справедливость S(x) для всех х  Х, то необходимо:
1. Доказать, что справедливо S(х0), где х0 – наименьший элемент в Х.
2. Доказать для всех х  Х, удовлетворяющих условию х0 < x, что если справедливо S(у)
для всех у < x, то справедливо и S(х).
Пример 1. Множество всех упорядоченных пар неотрицательных целых чисел вполне
упорядоченно с помощью отношения лексикографического порядка <. Это отношение
определяется так: отношение (n1, n2) < (n3, n4) справедливо, если и только если (n1 < n3) или (n3 =
n1 и n2 < n4). Рассмотрим последовательность чисел, определенную следующим образом: S0,0 =0,
а для любой другой пары неотрицательных чисел n, m
S m1,n  1, если n  0
S m ,n  
S m,n1  1, если n  0
Доказать, что Sm,n = n+m для любых неотрицательных целых чисел n, m.
Применим принцип обобщенной индукции на множестве Х упорядоченных пар
неотрицательных целых чисел <m, n>:
1. Так как пара <0, 0> - наименьший элемент Х, очевидна справедливость п. 3.1.
2. Пусть Sp,q = p + q для <p, q> < <m, n> (гипотеза индукции). Доказать, что Sm,n = m + n.
Если n = 0, то Sm,n = Sm-1,n + 1. Однако <m-1, n> < <m, n>, следовательно, Sm-1,n = m – 1 +
n. Поэтому Sm,n = Sm-1,n +1 = m +n. Если n0, Sm,n = Sm,n-1 + 1 по определению. Но <m, n-1> < <m,
n> и по гипотезе Sm,n = m + n -1. Следовательно, Sm,n = Sm,n-1 + 1 = (m+n-1) + 1 = m + n.
Пример 2. Доказать, что ниже приведенная схема программы правильна. Это значит, что
программа завершится и вычислит произведение J = MN любых целых чисел M и N, M  0.
4
Stop
х
1
Рисунок 1.
Start
2
I=0; J=0
T
3
I=M
F
J=J+N; I=I+1
1. При первом попадании (n = 1) в точку х имеем I = 0; J = 0. Утверждение J = IN = 0
справедливо.
1
2. Предположим, что J = IN справедливо при n-ом попадании в точку х. Нужно
показать, что если будет n + 1 попадание в точку х, то утверждение J = IN опять будет
справедливо.
Пусть I, J при n-ом проходе через точку х принимают значения In, Jn. Тогда гипотеза
индукции Jn = InN. Единственный способ попасть в точку х – выполнить тело цикла, пройдя
через операторы 2 и 3 и возвратиться в точку х. А это означает, что In+1 = In + 1, Jn+1 = Jn + N =
InN + N = (In + 1)N = In+1N.
Итак, мы показали, что если программа закончит выполнение при I = M, то J = MN.
Обратите внимание, если M < 0, то доказательство останется корректным, т. е. J = IN при
каждом попадании в точку х. Но при M < 0 цикл будет выполняться бесконечно и выполнение
программы не закончится. Докажем с помощью индукции по переменной m (0  m  M), что
при выполнении программы в конце концов будет достигнута точка х с I = M.
1. При первом попадании в точку х имеем I = 0. Утверждение справедливо для m = 0.
При М = 0 это уже обеспечивает конечный результат.
2. Предположим, что при выполнении программы, в конце концов, будет попадание в
точку х при I = m. Нужно показать, что будет попадание в точку х с I = m + 1. В точке х с I = m
отношение I = M ложно, так как m < M, и, следовательно, цикл выполнится еще один раз и
снова будет попадание в точку х. При таком возврате значение I увеличится на 1 и будет
попадание в точку х с I = m + 1.
4.
Метод индуктивных утверждений
Метод индуктивных утверждений независимо сформулирован К. Флойдом и П. Науром.
Суть этого метода состоит в следующем:
1) формулируются входное и выходное утверждения: входное утверждение описывает
все необходимые входные условия для программы (или программного фрагмента), выходное
утверждение описывает ожидаемый результат;
2) предполагая истинным входное утверждение, строится выведенное утверждение,
которое выводится на основании семантики операторов, расположенных между входом и
выходом (входным и выходным утверждениями);
3) формулируется теорема (условия верификации): из выведенного утверждения
следует выходное утверждение;
4) доказывается теорема, что свидетельствует о правильности программы (программного
фрагмента).
Пусть А – утверждение, описывающее предполагаемые свойства данных в программе, а
С - утверждение, описывающее то, что по предположению требуется получить в результате
выполнения программы (утверждение о правильности). Программа частично правильна, если
при каждом ее выполнении с данными, удовлетворяющими предположению А, будет
справедливо утверждение С при условии, что программа закончится.
Программа полностью правильна, если она частично правильна и заканчивается при всех
данных удовлетворяющих предположению А.
5.
Доказательство
утверждений
правильности
программ
с
помощью
индуктивных
Для доказательства частичной правильности свяжем утверждение А с началом
программы, а утверждение С с конечной точкой программы. Выявим закономерности,
относящиеся к значениям переменных, и свяжем соответствующие утверждения (условия
верификации), по крайней мере, с одной из точек в каждом цикле. Для каждого пути в
программе, ведущего из точки i, связанной с утверждением Аi, в точку j, связанную с
утверждением Аj, (при условии, что на этом пути нет точек с какими-либо дополнительными
утверждениями), докажем, что если мы попали в точку i и справедливо с утверждение Аi, а
затем прошли от точки i до точки j, то при попадании в точку j будет справедливо с
утверждение Аj. Для циклов точки i и j могут быть одной и той же точкой.
2
Для доказательства полной правильности программы сначала нужно доказать ее
частичную правильность, а затем уже доказать, что программа когда-нибудь завершится.
Алгоритм доказательства правильности программы методом индуктивных утверждений:
1) Построить структуру программы.
2) Выписать входное и выходное утверждения.
3) Сформулировать для всех циклов индуктивные утверждения.
4) Составить список выделенных путей.
5) Построить условия верификации.
6) Доказать условие верификации.
7) Доказать, что выполнение программы закончится.
6.
Структурная индукция
Доказательство правильности рекурсивных программ осуществляется с помощью
индукции, которая производится «по структуре» данных, обрабатываемых программой.
Следует сопоставить интуитивное понятие более простых данных (допустимых аргументов
функции) и более сложных с отношением во вполне упорядоченном множестве значений
данных или свойств этих данных. Например, если данные представлены списками, то
индукцию можно проводить по длине списка. Тогда этапы доказательства правильности
рекурсивных программ аналогичны этапам доказательства правильности работы программы
для всех допустимых аргументов с помощью метода обобщенной индукции. Эти этапы такие:
1.
Доказать, что программа работает правильно для простейших данных.
2.
Доказать, что программа работает правильно для более сложных данных в
предположении, что она работает правильно для более простых данных.
Например, при доказательстве правильности рекурсивной программы вычисления
факториала с помощью структурной индукции следует использовать простую индукцию по
положительным целым числам.
7.
Аксиоматическое доказательство частичной правильности программ.
Утверждения, сформулированные на языке исчисления предикатов, используются для
доказательства частичной правильности программ. При этом следует доказать истинность
триады Хоара {Q} S {R}, где предикат Q - предусловие или входное утверждение для
программы (фрагмента программы) S, предикат R - постусловие или выходное утверждение.
8.
Правила верификации К. Хоара.
A1. Аксиома присваивания: {Ro} x := e {R}
A2. Если {Q} S {P} и {P} => {R}, то {Q} S {R}
A3. Если {Q} S {P} и {R} => {Q}, то {R} S {P}
Пусть S - это последовательность из двух операторов S1; S2 (составной оператор).
A4. Если {Q} S1 {P1} и {P1} S2 {R}, то {Q} S {R}.
Очевидно, что это правило можно сформулировать для последовательности, состоящей
из n операторов.
Правило для условного оператора (краткая форма).
A5. Если {Q AND B} S1 {R} и {Q NOT B} => {R}, то {Q} if B then S1 {R}.
Правило для альтернативного оператора (полная форма условного оператора ).
A6. Если {Q AND B} S1 {R} и {Q NOT B} S2 {R}, то {Q} if B then S1 else S2 {R}.
Правила для оператора цикла until.
A7. Если {Q AND NOT B} S1 {Q}, то {Q} repeat S1 until B {Q AND NOT B}
Правила для оператора цикла while.
A8. Если {Q AND B} S1 {Q}, то {Q} while B do S1 {Q AND NOT B}
Пример доказательства истинности триад Хоара приведен в лекциях.
3
Задания
1.
2.
3.
4.
5.
6.
Доказать для n  0 свойство чисел Фибоначчи, у которых fn+1 = fn + fn-1, f0 = 0, f1 = 1:
Пусть а = (1 + 5)/2. Доказать для чисел Фибоначчи при n  0:
Определить чему равен I в момент окончания цикла в программе (схема на рисунке 1 при
замене операторов) и доказать это:
Доказать методом индуктивных утверждений правильность программы, написанной
Вами на практическом занятии №5.
Доказать правильность рекурсивной программы, написанной Вами на практическом
занятии №7.
Доказать аксиоматически частичную правильность программы, написанной Вами на
практическом занятии №5.
Вариант 1.
1. f0 + f1 + … + fn = fn+2 – 1
2. fn  an-1
3. Оператор 1: I = I0, 2: I  M, 3: I = F(I), T поменялись местами F
Вариант 2.
1. f02 + f12 + … + fn2 = fnfn+1
2. an-2  fn
3. Оператор 1: I = I0, 2: M  I, 3: I = G(I), T поменялись местами F
Вариант 3.
1. f2 + f4 + … + f2n = f2n+1 - 1
2. fn  (7/4)n-1
3. Оператор 1: I = I0, 2: I  M, 3: I = 2*I, T поменялись местами F
4
Download