
- •2.6. Заключение .............................................................................................................. 22
- •4. Язык исчисления вычислимых предикатов,
- •4.12. Однозначность предикатов .......................................................................................... 45
- •5. Семантика языка предикатного программирования.
- •6.9. Формулы .......................................................................................................................... 78
- •6.9. Процессы ......................................................................................................................... 79
- •6.11. Императивное расширение .......................................................................................... 82
- •7.8. Заключение ................................................................................................................... 108
- •Введение в курс предикатного программирования
- •1. Общее понятие программы
- •1.1. Автоматическая вычислимость
- •1.2. Спецификация программы
- •1.3. Формы спецификации программы
- •Список литературы
- •2. Корректность программ с предикатной спецификацией
- •2.1. Предикатная спецификация программы
- •2.2. Логическая семантика языка программирования
- •2.3. Модель корректности программы
- •2.4. Система правил доказательства корректности операторов
- •2.4.1. Правила для корректного оператора
- •2.4.2. Правила корректности для параллельного оператора
- •2.4.3. Правила корректности для оператора суперпозиции
- •2.4.4. Правила корректности для условного оператора
- •2.5. Система правил вывода программы из спецификации
- •2.5.1. Однозначность предикатов
- •2.5.2. Теорема тождества спецификации и программы
- •2.5.3. Правила корректности для параллельного оператора
- •2.5.4. Правила корректности для оператора суперпозиции
- •2.5.5. Правила корректности для условного оператора
- •2.6. Заключение
- •Список литературы
- •3. Математические основы
- •3.1. Отношения порядка
- •3.2. Наименьшая неподвижная точка
- •3.3. Математическая индукция
- •Список литературы
- •4. Язык исчисления вычислимых предикатов, его логическая и операционная семантика
- •4.1. Структура программы на языке ccp
- •4.2. Система типов данных
- •4.3. Логическая и операционная семантика языка ccp
- •4.4. Семантика вызова предиката
- •4.5. Оператор суперпозиции
- •4.6. Параллельный оператор
- •4.7. Условный оператор
- •4.8. Конструктор предиката
- •4.9. Конструктор массива
- •4.10. Программа
- •4.11. Рекурсивные определения предикатов
- •4.12. Однозначность предикатов
- •Список литературы
- •5. Семантика языка предикатного программирования. Методы доказательства корректности предикатных программ
- •5.1. Язык p1: подстановка определения предиката на место вызова
- •5.2. Язык p2: оператор суперпозиции и параллельный оператор общего вида
- •5.3. Язык p2: другое обобщение оператора суперпозиции
- •5.4. Язык p3: выражения
- •5.5. Методы доказательства корректности рекурсивных программ
- •6. Язык предикатного программирования
- •6.1. Введение
- •6.2. Лексемы
- •6.3. Предикаты
- •6.3.1. Определение предиката
- •6.3.2. Спецификация предиката
- •6.3.3. Вызов предиката
- •6.4. Программа
- •6.5. Операторы
- •6.6. Выражения
- •6.7. Типы
- •6.8. Массивы
- •6.8.1. Описание типа массива
- •6.8.2. Вырезка массива
- •6.8.3. Определение массива
- •6.8.4. Объединение массивов
- •6.9. Формулы
- •6.10. Процессы
- •6.11. Императивное расширение
- •Список литературы
- •7. Технология предикатного программирования
- •7.1. Подстановка определения предиката на место вызова
- •7.2. Замена хвостовой рекурсии циклом
- •7.3. Склеивание переменных
- •7.4. Метод обобщения исходной задачи
- •7.5. Трансформация кодирования структурных объектов
- •7.6. Пример. Сортировка простыми вставками
- •7.7. Гиперфункции
- •7.8. Заключение
- •Список литература
2.3. Модель корректности программы
Рассмотрим программу с предикатной спецификацией на языке, для которого можно построить логическую семантику. Программа со спецификацией представляется в виде тройки Хоара:
{P(x)} S {Q(x, y)} . (2.5)
Здесь программа представлена оператором S, x набор входных данных, y набор результатов.
Закон соответствия программы и спецификации, сформулированный в разд. 2.1, очевидным образом конкретизируется для программы с предикатной спецификацией в виде следующих условий:
входные данные x должны соответствовать предусловию P(x) перед исполнением программы;
входные данные x и результаты y должны удовлетворять постусловию Q(x, y) после завершения исполнения программы.
Во втором условии неявно подразумевается, что исполнение программы на входных данных x завершается. Более точная формулировка условия: если для набора x существует исполнение, завершающееся набором y, то истинно постусловие Q(x, y). Используя обозначения, введенные в разд. 2.2, запишем условие в виде формулы: RUN(S, x, y) Q(x, y). Учитывая свойство согласованности (2.4), второе условие можно представить формулой: LS(S)(x, y) Q(x, y). В итоге, закон соответствия программы и спецификации для программы с предикатной спецификацией выражается следующей формулой:
P(x) & ( LS(S)(x, y) Q(x, y) ) . (2.6)
Замечание. Импликация в обратную сторону, т. е. Q(x, y) LS(S)(x, y), в общем случае неверна. Во многих задачах спецификация Q(x, y) представляется более слабым (общим) условием, допускающим для фиксированного набора x не единственное решение y.
Предусловие P(x) не зависит от оператора S, поскольку значение P(x) определено до исполнения оператора S. Для программы в целом предусловие P(x) считается истинным априори. Истинность предусловия для случая, когда оператор S является частью программы, должна быть доказана, см. разд. 2.4 и 2.5. В любом случае, исполнение оператора S не рассматривается для ложного предусловия. Таким образом, истинность предусловия P(x) определяется как необходимое условие для тройки Хоара (2.5).
Закон соответствия программы и спецификации (2.6) определяет условие корректности программы (2.5). Однако первый конъюнкт P(x) не может входить в условие корректности оператора S, а второй конъюнкт реализуется при условии истинности P(x). Учитывая это, условие корректности программы представляется следующей формулой:
P(x) & LS(S)(x, y) Q(x, y) . (2.7)
Предикат H(x, y) реализуем для конкретного x, если H(x, y) истинен для некоторого y, т. е. $y. H(x, y). Предикат H(x, y) реализуем в области предусловия P(x), если он реализуем для всех x, на которых истинно предусловие, т. е. "x. (P(x) $y. H(x, y)). Предикат H(x, y) является тотальным в области предусловия, если рассматривать его как функцию, отображающую x в y. Спецификация в виде предусловия P(x) и постусловия Q(x, y) реализуема, если постусловие реализуемо в области предусловия.
Рассмотрим ситуацию, когда условие корректности (2.7) истинно, а спецификация нереализуема. Тогда для некоторого x истинно предусловие P(x), а постусловие Q(x, y) ложно для всех y. Из истинности (2.7) следует, что LS(S)(x, y) будет ложной для всех y. Как следствие свойства согласованности (2.4) получим, что y ØRUN(S, x, y) истинно, т. е. исполнение оператора S для данного x не определено. Это означает, что исполнение либо реализуется бесконечно, либо завершается аварийно без получения результата. Подобная ситуация абсурдна в модели применения программы (см. рис. 1) – такое исполнение бессмысленно и не соответствует цели базового процесса.
Таким образом, мы приходим к следующему условию корректности спецификации: спецификация должна быть реализуема, т. е.:
P(x) Þ$y. Q(x, y) . (2.8)
Корректность спецификации является необходимым условием корректности программы, представленной тройкой (2.5).
Определим точное предусловие 6 PE(x) следующей формулой:
PE(x) @ $y. Q(x, y) .
Лемма 2.1. Спецификация с предусловием P(x) и постусловием Q(x, y) реализуема P(x) Þ PE(x).
Ситуация, когда для некоторого набора x, удовлетворяющего предусловию P(x), исполнение оператора S реализуется бесконечно или завершается аварийно без получения результата, т. е. "y. ØRUN(S, x, y), определена выше как недопустимая для программы с предикатной спецификацией. Следовательно, должно быть истинно обратное утверждение: $y. RUN(S, x, y), т. е. исполнение программы завершается с получением некоторого результата y. Данное утверждение эквивалентно $y. LS(S)(x, y), что следует из свойства согласованности (2.4). Таким образом, необходимым условием корректности программы является нормальное завершение исполнения программы для x, удовлетворяющего предусловию P(x). Условие корректности определяется формулой:
P(x) Þ $y. LS(S)(x, y) . (2.9)
Приведенные выше требования объединим в понятии корректности программы. Прежде всего, для программы (2.5) предусловие P(x) всегда истинно. Программа корректна, если спецификация реализуема (условие (2.8)), программа нормально завершается в области предусловия (условие (2.9)) и программа соответствует спецификации (условие (2.7)).
Требования, составляющие корректность программы, избыточны.
Лемма 2.2. Если программа соответствует спецификации и нормально завершается в области предусловия, то спецификация реализуема.
Доказательство. Пусть истинно P(x). Необходимо доказать истинность $y. Q(x, y). Из условия (2.9) следует истинность $y. LS(S)(x, y). Допустим, истинность этой формулы реализуется для некоторого y0. Из условия (2.7) получаем истинность Q(x, y0), а значит – и $y. Q(x, y). □
Таким образом, корректность программы (2.5) определяется двумя условиями: соответствие спецификации (2.7) и нормального завершения (2.9). Объединяя формулы (2.7) и (2.9), получаем итоговую формулу корректности программы:
P(x) Þ [ LS(S)(x, y) Q(x, y) ] & $y. LS(S)(x, y) . (2.10)
Приведенное определение корректности программы соответствует общеизвестному понятию тотальной (или полной) корректности программы. Оно справедливо для программ с предикатной спецификацией и для языков программирования с логической семантикой. Основой данного определения корректности является формализация закона соответствия программы и спецификации для программ с предикатной спецификацией.