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

5.4. Язык p3: выражения

Наряду с предикатной (или операторной) формой представления конструкций будем использовать функциональную форму. Пусть имеется вызов предиката A(t: z), где t и z  наборы переменных. Как эквивалентную для вызова A(t: z) будем использовать запись в функциональном стиле: z = A(t). Конструкцию A(t) назовем вызовом функции. В случае, когда z  набор более чем из одной переменной, будем также использовать форму записи |z| = A(t).

Для базисных предикатов языка CCP, соответствующих стандартных арифметических операциям, вместо функциональной формы z = A(t) будем использовать традиционную инфиксную и постфиксную нотацию. Например, базисные предикаты: +(x, y: z), (x, yz), (xy), <(x, yb)  записываются в языке P3 привычным образом: z = x + y, z = x  y, y = x , b = x < y.

В языке P3 вводятся изображения констант. Так, вместо базисных предикатов ConsIntZero( : x) и ConsIntOne( : x) используется запись вида x = 0 и x = 1. Значение x константы целого типа по ее изображению s определяется предикатом valInt(s : x). Например, x = 2089 интерпретируется как вызов valInt(“2089” : x). Аналогичным образом определяются изображения констант для других примитивных типов.

Применение функционального стиля позволяет преобразовать оператор суперпозиции следующим образом:

B(xz); C(x, zy)  z =B(x); C(x, zy)  C(x, B(x)y) .

В языке P3 аргументом вызова является либо переменная, либо вызов функции. При этом вызов функции в качестве аргумента определяется указанным тождеством. Семантика вызова, имеющего вызовы в двух и более аргументах, определяется следующим тождеством:

{ A(x: y) || B(z: t) }; C(y, t: u)  { y = A(x) || t = B(z) }; C(y, t: u)  C(A(x), B(z): u) .

Таким образом, вычисление аргументов вызовов реализуется параллельно.

Определим правила доказательства корректности для вызова предиката, содержащего вызовы среди аргументов. Рассмотрим определение предиката

D(x, z: u) º P(x, z) {C(A(x), B(z): u)} Q(x, z, u) . (5.15)

Пусть предикат A имеет спецификацию PA(x) и QA(x, y), а предикат B  PB(z) и QB(z, t). Если предикаты A и B являются корректными, то корректно следующее определение:

E(x, z: y, t) º PA(x) & PB(z) {A(x: y) || B(z: t)} QA(x, y) & QB(z, t) .

Предикат D можно представить определением

D(x, z: u) º P(x, z) { E(x, z: y, t); C(y, t: u)} Q(x, z, u) . (5.16)

Пусть предикат C со спецификацией PС(y, t) и QС(y, t, u) является корректным. Применим правила RS1 и RS2 для оператора в правой части (5.16). Получим следующие правила.

Правило RS1’. P(x, z) ├ PA(x) & PB(z) & "y,t (QA(x, y) & QB(z, t) Þ PC(y, t)).

Правило RS2’. P(x, z) & $y,t (QA(x, y) & QB(z, t) & QC(y, t, u)) ├ Q(x, z, u).

Допустим, операторы A и B являются однозначными; их спецификации PA(x), QA(x, y), PB(z), QB(z, t) также однозначны. Эквивалентные преобразования RS1’ и RS2’ с учетом однозначности предикатов и спецификаций позволяют устранить переменные y и t, что дает правила RS7 и RS8.

Правило RS7. P(x, z) ├ PA(x) & PB(z) & PC(A(x), B(z)).

Правило RS8. P(x, z) & QC(A(x), B(z), u) ├ Q(x, z, u).

В итоге, справедлива следующая лемма.

Лемма 5.7. Пусть предусловие P(x, z) истинно. Допустим, операторы A, B и C корректны, операторы A и B, а также их спецификации PA(x), QA(x, y), PB(z), QB(z, t) однозначны. Если правила RS7 и RS8 истинны, то оператор (5.15) со спецификацией P(x, z) и Q(x, z, u) является корректным.

Для получения правил серии L применим правила LS1 и LS2 для оператора в правой части (5.16). Получим следующие правила.

Правило LS1’. P(x, z) ├ PA(x) & PB(z).

Правило LS2’. P(x, z) & Q(x, z, u) & QA(x, y) & QB(z, t)├ PC(y, t) & QC(y, t, u).

Предполагая однозначность предикатов A и B, а также их спецификаций, проведем эквивалентные преобразования LS1’ и LS2’, устраняя переменные y и t. Получим следующие правила.

Правило LS8. P(x, z) ├ PA(x) & PB(z).

Правило LS9. P(x, z) & Q(x, z, u)├ PC(A(x), B(z)) & QC(A(x), B(z), u).

Справедлива следующая лемма.

Лемма 5.8. Допустим, спецификация P(x, z) и Q(x, z, u) оператора (5.15) реализуема, операторы A, B и C однозначны в области предусловий и корректны, а их спецификации однозначны. Если правила LS8 и LS9 истинны, то оператор (5.15) является корректным.

Нетрудно проверить, что леммы 5.7 и 5.8 верны для любого числа вызовов, используемых в качестве аргументов вызова предиката C, в том числе и для одного вызова.

Пусть имеется оператор суперпозиции z = a  b; y = z + c. Как определено выше, операции a  b и z + c являются аналогами вызовов предикатов (a, b: z) и +(z, c: y). Применим схему подстановки вызова на место аргумента во втором вызове суперпозиции. Подстановка a  b на место z в операторе y = z + c дает оператор y = (a  b) + c. Здесь используется правило: подставляемая операция на место аргумента другой операции обрамляется круглыми скобками. Таким образом, приходим к известному понятию выражения. Использование правил приоритетов операций, позволяющих опускать круглые скобки, определяет привычную форму записи выражений; например, y = a  b + c.

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

Имеет место тождество

C(xb); if (b) A(xy) else B(xy) if (C(x)) A(xy) else B(xy) .

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

Язык CCP определен как бестиповый язык. При этом тип каждой переменной программы на языке CCP можно распознать, используя информацию о вхождениях переменной в программе. Язык P также можно реализовать как бестиповый подобно языку Лисп. Однако в случае использования полиморфных операций, например «+», можно привести примеры программ, когда невозможно однозначно определить типы переменных, что предопределяет неоднозначность программы. Тем не менее, и при использовании полиморфных операций можно было бы построить бестиповый язык, введя соответствующие ограничения. Язык P определен как типовый. Описания аргументов и результатов предикатов и локальных переменных снабжаются указанием типов в стиле языка C. Тип, математическое описание которого дается в разд. 4.2, кодируется в языке P конструкцией ИЗОБРАЖЕНИЕ-ТИПА; см. разд. 6.7. Аргументация в пользу типового языка заключается в том, что указание типов переменных существенно повышает понимание программы.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]