- •24.10.12 Лекция 6
- •Метод индукции, использующий меру
- •5. Построение языка предикатного программирования. Методы доказательства корректности предикатных программ (продолжение )
- •Методы доказательства корректности рекурсивных программ
- •Рекурсивное кольцо состоит из единственного определения предиката:
- •Пример 5.1. Программа умножения через сложение.
- •Перепишем вторую цель в виде суперпозиции:
- •Пример 5.2. Программа D(a, b: c) вычисления наибольшего общего делителя (НОД) положительных a
- •6. Язык предикатного программирования
- •Лексемы
- •Определение предиката
- •Операторы
- •Выражения
- •Описания переменных
- •Структура предикатной программы
- •Определения типов
- •Алгебраические типы
- •Списки
- •Массивы
- •Формулы
- •Императивное расширение
6. Язык предикатного программирования
Лексемы
ЛЕКСЕМА ::= ИДЕНТИФИКАТОР | КЛЮЧЕВОЕ-СЛОВО | КОНСТАНТА | ОПЕРАЦИЯ | РАЗДЕЛИТЕЛЬ| МЕТКА
ИДЕНТИФИКАТОР ::= ( _ | [:alpha:] ) (_ | [:alnum:])*
КЛЮЧЕВОЕ-СЛОВО ::=
int | nat | real | inf | nan | char | string | bool | true | false | nil | type | in | subtype | enum | struct | union | array |
| set | predicate | lambda | module | measure | import | if | else | for | switch | case | pre | post| or | xor
ОПЕРАЦИЯ ::= + | - | * | / | % | ^ | ! | << | >> | ~ | & | | | ? |
= | < | > | <= | >= | != | <-
РАЗДЕЛИТЕЛЬ ::= ( | ) | [ | ] | { | } | , | ; | : | . | .. | [:blank:] КОНСТАНТА ::= ЦЕЛАЯ-КОНСТАНТА |
ВЕЩЕСТВЕННАЯ-КОНСТАНТА | СИМВОЛЬНАЯ-КОНСТАНТА | СТРОКОВАЯ-КОНСТАНТА | ЛОГИЧЕСКАЯ-КОНСТАНТА
СТРОКОВАЯ-КОНСТАНТА ::= ” СИМВОЛ* ” ЛОГИЧЕСКАЯ-КОНСТАНТА ::= true | false
Определение предиката
<имя предиката> (<описания аргументов> : <описания результатов>)
[ pre <предусловие>] [ {<оператор>} ]
[post <постусловие>; ]
sign(real x: int s)
{ if (x>0) s = 1 else if (x = 0) s = 0 else s = -1 } post s = sign(x)
Операторы
Оператор <переменная> = <выражение>
присваивания
Вызов <имя предиката>([<аргументы>]: <результаты> )
предиката <выражение>([<аргументы>]: <результаты> ) Параллельный <оператор1> ||…|| <операторN>
оператор |
|
|
|
Условный |
if (<условие>) <оператор1> |
||
оператор |
else <оператор2> |
||
Оператор |
switch (<выр>) { |
||
выбора |
case выр1: <оператор1> |
||
……………………………. |
|||
case вырN: <операторN> |
|
|
|
|
|||
default : |
<операторN+1 > |
||
} |
<описание переменных> |
||
Оператор суперпозиции <оператор1> ;…; <операторN>
Выражения
<выражение> ::= <первичное> |
<выражение> <знак бинарной операции> <выражение> | <знак унарной операции> <выражение> |
<условное выражение>
<знак унарной операции> ::= + | - | ! | ~ |
|||
<знак бинарной операции> ::= * | / | % | + | - | << | >> | |
|||
= | & | ^ | or | xor |
in | > | <= | >= | = | ! |
||
|
|||
<первичное>::= |
<переменная> | <константа> | |
||
|
<агрегат> | <модификация> |
||
|
<вызов функции> | <имя предиката> | |
||
|
<имя типа> | <генератор предиката> | |
||
|
(<выражение>) | <элемент списка> | |
||
|
<определение массива> | <конструктор> | |
||
|
<распознаватель> | <поле объединения> |
||
a & b |
if (a) |
b else |
false |
a or b |
if (a) |
true |
else b |
Описания переменных
real pi = 3.14, x, y, z;
A(real x, y: nat n)
{ Complex φz; B(x, y: φz); C(φz: n) }
A(real x, y: nat n)
{ B(x, y: Complex φz); C(φz: n) }
A(real x, y: nat n)
{ Complex φz = B(x, y); C(φz: n) }
Структура предикатной программы
module <имя модуля>
[( <описания параметров модуля> ) ]; <список описаний>
Модуль последовательность импорта, описаний типов, глобальных переменных и определений предикатов
Области локализации
Определения типов
type <имя типа> [(<параметры>)] = <изображение типа>;
Базисные типы bool, nat, int, real, char
Структурные типы
struct (<тип поля1> <пробел> <имя поля1> , … ) <алгебраический тип>
set (<тип конечного базового множества> )
array (<тип элемента>, <список типов индексов> )
predicate ( <типы аргументов> : <типы результатов> ) pre … post …
type Complex = struct(real re, im ); type Diapason(nat n) = 1..n+1;
type Ar(nat n) = array(real, Diapason(n), 1..5);
Алгебраические типы
union ( <описание конструкторов>) <описание конструктора>::=
<имя конструктора> [ ( <описание полей>) ]
<конструктор>::= <имя конструктора> [ ( <список выражений>) ]
<распознаватель>::= <имя конструктора>? [ ( <выражение>) ]
<поле объединения>::= <первичное выражение> . <имя поля>
Списки
Seq(T) = NIL + (T Seq)
type list (type T) = union ( nil,
cons (T car, list(T) cdr)
);
switch (s) { case nil: 0
case cons(h, t): 1 + length(t) };
list(T) |
x, y, z; |
|
|
T a; |
|
|
|
z = a |
z = x + y |
z = a + y z = x + y + a |
|
x.car |
x.cdr |
last(x) |
len(x) |
z.car = { CompUnion(z: i, x, y) ; CompStruct(y: u, v); u }
