
- •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. Заключение
- •Список литература
6.3.2. Спецификация предиката
Предикат, используемый в программе, должен иметь определение предиката. Если предикат определяется в другом модуле программы, то предикат может быть представлен своей спецификацией.
СПЕЦИФИКАЦИЯ-ПРЕДИКАТА ::=
ИМЯ-ПРЕДИКАТА ОПИСАНИЕ-СПЕЦИФИКАЦИИ-ПРЕДИКАТА
Имя предиката обозначает предикат, представленный описанием спецификации предиката.
ОПИСАНИЕ-СПЕЦИФИКАЦИИ-ПРЕДИКАТА ::=
ОПИСАНИЕ-СПЕЦИФИКАЦИИ-ПРЕДИКАТА-ФУНКЦИИ |
ОПИСАНИЕ-СПЕЦИФИКАЦИИ-ПРЕДИКАТА-ГИПЕРФУНКЦИИ
ОПИСАНИЕ-СПЕЦИФИКАЦИИ-ПРЕДИКАТА-ФУНКЦИИ ::=
ЗАГОЛОВОК-ПРЕДИКАТА [pre ПРЕДУСЛОВИЕ][post ПОСТУСЛОВИЕ]
ОПИСАНИЕ-СПЕЦИФИКАЦИИ-ПРЕДИКАТА-ГИПЕРФУНКЦИИ ::=
ЗАГОЛОВОК-ПРЕДИКАТА-ГИПЕРФУНКЦИИ [ПРЕДУСЛОВИЯ-ГИПЕРФУНКЦИИ]
[ПОСТУСЛОВИЯ-ВЕТВЕЙ]
6.3.3. Вызов предиката
Элементарным оператором программы является вызов предиката.
ВЫЗОВ-ПРЕДИКАТА ::= ВЫЗОВ-ПРЕДИКАТА-ФУНКЦИИ |
ВЫЗОВ-ПРЕДИКАТА-ГИПЕРФУНКЦИИ
ВЫЗОВ-ПРЕДИКАТА-ФУНКЦИИ ::=
ИДЕНТИФИКАЦИЯ-ПРЕДИКАТА ( [АРГУМЕНТЫ] : РЕЗУЛЬТАТЫ )
ИДЕНТИФИКАЦИЯ-ПРЕДИКАТА ::= [ИМЯ-МОДУЛЯ .] ИМЯ-ПРЕДИКАТА |
ВЫРАЖЕНИЕ |
[ОБЪЕКТ-КЛАССА .] ИМЯ-ПРЕДИКАТА
ОБЪЕКТ-КЛАССА ::= ПЕРЕМЕННАЯ
Выражение должно быть предикатного типа. Значением выражения является предикат, запускаемый на исполнение данным вызовом.
АРГУМЕНТЫ ::= СПИСОК-ВЫРАЖЕНИЙ
СПИСОК-ВЫРАЖЕНИЙ ::= ВЫРАЖЕНИЕ [, СПИСОК-ВЫРАЖЕНИЙ]
Типы аргументов вызова должны быть совместимы (см. разд. 6.7) с типами соответствующих аргументов определения (или спецификации) вызываемого предиката.
РЕЗУЛЬТАТЫ ::= ПЕРЕМЕННАЯ [, РЕЗУЛЬТАТЫ] |
РЕЗУЛЬТАТ-ЛОКАЛ [, РЕЗУЛЬТАТЫ]
РЕЗУЛЬТАТ-ЛОКАЛ ::= ОПИСАНИЕ-ПЕРЕМЕННОЙ
ОПИСАНИЕ-ПЕРЕМЕННОЙ ::= ИЗОБРАЖЕНИЕ-ТИПА-ПЕРЕМЕННОЙ ИДЕНТИФИКАТОР
ИЗОБРАЖЕНИЕ-ТИПА-ПЕРЕМЕННОЙ ::=
ИЗОБРАЖЕНИЕ-ТИПА [:blank:] | var [:blank:]
Использование var возможно вместо соответствующего ИЗОБРАЖЕНИЯ-ТИПА, поскольку тип результата-локала в большинстве случаев можно восстановить по определению вызываемого предиката. Описатель var также может использоваться при описании локальной переменной в случае, когда тип этой переменной легко определяется из контекста дальнейшего использования переменной (см. разд. 6.4, 6.5).
Типы результатов вызова должны совпадать с типами соответствующих результатов в определении вызываемого предиката. Переменная, представленная описанием результата-локала, определяется как локальная в теле предиката, содержащем данный вызов. Описание локальной результирующей переменной внутри вызова эквивалентно описанию этой переменной перед вызовом.
Использование специального имени “_” в качестве результирующей переменной обозначает пустой результат: результат по этой позиции, получаемый при завершении исполнения вызова предиката, не используется в дальнейшем исполнении. Имя “_” зарезервировано в языке P его нельзя использовать для именования объектов программы.
ВЫЗОВ-ПРЕДИКАТА-ГИПЕРФУНКЦИИ ::=
ИДЕНТИФИКАЦИЯ-ПРЕДИКАТА ( [АРГУМЕНТЫ] (: РЕЗУЛЬТАТЫ-ВЕТВИ)+ )
РЕЗУЛЬТАТЫ-ВЕТВИ ::= [РЕЗУЛЬТАТЫ] [ОПЕРАТОР-ПЕРЕХОДА]
ОПЕРАТОР-ПЕРЕХОДА ::= # МЕТКА
В качестве метки в операторе указывается либо метка ветви предиката, в теле которого находится данный вызов, либо метка ветви обработчика; подробнее см. в разд. 6.5.
Исполнение вызова предиката реализуется следующим образом. Результатом исполнения аргументов вызова является набор значений. Вычисление каждого аргумента вызова реализуется независимо от вычисления других, т. е. параллельно. Полученный набор значений аргументов присваивается соответствующим входным параметрам определения вызываемого предиката. Далее исполняется тело определения вызываемого предиката. В процессе исполнения тела определяется итоговая ветвь предиката и вычисляются значения результирующих переменных по этой ветви. Наконец, полученные значения результирующих переменных присваиваются соответствующим результирующим переменным вызова предиката, и исполнение вызова завершается по этой ветви вызова. Если в данной ветви вызова указан оператор перехода, то либо происходит переход на локальную метку, либо завершается тело предиката, содержащего вызов, той ветвью, которая указана в операторе перехода. Отметим, что подстановка аргументов и результатов предиката реализуется по значению.
ВЫЗОВ-ФУНКЦИИ ::= ИДЕНТИФИКАЦИЯ-ПРЕДИКАТА ( [АРГУМЕНТЫ] )
Вызов предиката-функции может иметь вид вызова функции. Результатом исполнения является набор значений результирующих переменных предиката.
real r;
sqrt (2 : r);
real q = sqrt (3);
Comp (list(int) s: : int d, list (int) r) // спецификация гиперфункции Comp
pre 1: s = nil
post 2: s = cons(d, r) ;
/* если список s пуст, реализуется первая ветвь гиперфункции, иначе реализуется вторая ветвь с результатами: d первый элемент, r хвост списка */
elemTwo (list(int) s: int e #value : #empty)
pre empty: s = nil or s.cdr = nil
{ Comp (s : #empty : int e1, list(int) s1 #ok)
case ok: Comp (s1 : #empty : e, list(int) s2 #value);
}
post value: e = (s.cdr).car;
/* гиперфункция elemTwo извлекает второй элемент списка, если элемент существует */
Пример 2. Вызовы и определения предикатов и гиперфункций,
спецификация гиперфункции
В определении предиката elemTwo переход по локальной метке ok является излишним. Кроме того, результаты e1 и s2 далее нигде не используются. Определение предиката elemTwo, представленное ниже, исправляет отмеченные недостатки:
elemTwo (list(int) s: int e #value : #empty)
pre 1: s = nil or s.cdr = nil
{ Comp (s : #empty : _, list(int) s1 );
Comp (s1 : #empty : e, _ #value);
}
post value: e = s.cdr.car;