- •24.10.12 Лекция 6
- •Метод индукции, использующий меру
- •5. Построение языка предикатного программирования. Методы доказательства корректности предикатных программ (продолжение )
- •Методы доказательства корректности рекурсивных программ
- •Рекурсивное кольцо состоит из единственного определения предиката:
- •Пример 5.1. Программа умножения через сложение.
- •Перепишем вторую цель в виде суперпозиции:
- •Пример 5.2. Программа D(a, b: c) вычисления наибольшего общего делителя (НОД) положительных a
- •6. Язык предикатного программирования
- •Лексемы
- •Определение предиката
- •Операторы
- •Выражения
- •Описания переменных
- •Структура предикатной программы
- •Определения типов
- •Алгебраические типы
- •Списки
- •Массивы
- •Формулы
- •Императивное расширение
24.10.12 Лекция 6
Предикатное программирование
5. Построение языка предикатного программирования. Методы доказательства корректности предикатных программ (прод)
Методы доказательства корректности рекурсивных программ
Примеры
6. Язык предикатного программирования
Лексемы, предикаты, операторы, выражения, типы, массивы, формулы, императивное расширение. Примеры
A0(n: f) |
A1( : c0, c1); A2(n, c0, c1: f) |
|
A1( : c0, c1) |
ConsIntZero( : c0) || ConsIntOne( : c1) |
|
A2(n, c0, c1: f) |
=(n, c0: b); A3(n, c1, b: f) |
|
A3(n, c1, b: f) |
if (b) =(c1: f) else A4(n, c1: f) |
|
A4(n, c1: f) |
-(n, c1: n1); A5(n, n1: f) |
|
A5(n, n1: f) |
A0(n1: f1); (n, f1: f) |
|
Подставим A1 A0; преобразуем к функциональному виду. |
||
A0(n: f) |
A2(n, 0, 1: f) |
|
A2(n, c0, c1: f) |
A3(n, c1, n = c0: f) |
|
A3(n, c1, b: f) |
if (b) f =c1 else A4(n, c1: f) |
|
A4(n, c1: f) |
A5(n, n - c1: f) |
|
A5(n, n1: f) |
f = n A0(n1) |
|
Подставим A3 A2, а A2 A0, A5 A4. |
||
A0(n: f) |
if (n = 0) f =1 else A4(n, 1: f) |
|
A4(n, c1: f) |
f = n A0(n - c1) |
|
A4 A0, получим программу факториала на языке P3. |
||
A0(n: f) |
if (n = 0) f =1 else f = n A0(n - 1) |
Метод индукции, использующий меру
t X. [ ( y X. m(y) < m(t) W(y) ) W(t) ]
u X. W(u) |
(3.5) |
Функция m: X nat называется мерой
Вместо типа nat может использоваться ЧУМ со свойством обрыва бесконечно убывающих цепей (well-founded partial order)
Induct(t, W) y. m(y) < m(t) W(y)) |
|
t X. [ Induct(t, W) W(t) ] u X. W(u) |
(3.5) |
5. Построение языка предикатного программирования. Методы доказательства корректности предикатных программ (продолжение )
Методы доказательства корректности рекурсивных программ
Определения предикатов рекурсивного кольца A1, A2,…, An:
Aj(xj: yj) Pj(xj) {Kj(xj: yj)} Qj(xj, yj); j=1…n; n > 0 (3.36’)
Здесь Pj и Qj ― предусловие и постусловие предиката Aj; xj, yj ― различающиеся наборы переменных.
Aj(x: yj) Pj(x) {Kj(x: yj)} Qj(x, yj); j=1…n; n > 0 |
(5.17) |
Набор x объединяет все наборы xj; j=1…n. Корректность определений предикатов кольца (5.17): W(x) j=1..n.{ Pj(x) ( yj. L(Kj(x: yj))) &
(L(Ki(x: yj)) Qj(x, yj))) } (5.18)
RR: |
Induct(t, W) W(t) |
Induct(t, W)) |
||
|
||||
W(x) |
RR1: |
W(t) |
||
|
||||
|
|
|
||
Induct(t, W) y. m(y) < m(t) W(y)) |
|
|
||
t X. [ Induct(t, W) W(t) ] u X. W(u) |
(3.5) |
Рекурсивное кольцо состоит из единственного определения предиката:
A(x: y) P(x) { S(x: y) } Q(x, y) (5.20)
Здесь S(x: y) оператор, в котором имеются рекурсивные вызовы предиката A. Формула корректности определения (5.20):
Corr(S(x: y), P(x), Q(x, y))
P(x) [ L(S(x: y)) Q(x, y) ] & y. L(S(x: y)) W(x) Corr(A(x: y), P(x), Q(x, y))
Corr(t, A, B(x: y), PB(x), QB(x, y))
Induct(t, A) Corr(B(x: y), PB(x), QB(x, y))
Induct(t, A) u. m(u) < m(t) Corr(A(u: y), P(u), Q(u, y))
P*(x) m(x) < m(t) & P(x) |
t – формальные параметры, |
||
|
x – фактические параметры рекурсивного вызова. |
||
R0: |
Corr(x, A, S(x: y), P(x), Q(x, y)) |
|
|
|
Corr(A(x: y), P(x), Q(x, y) |
|
|
|
|
RR: |
Induct(t, W) W(t) |
|
|
|
W(x) |
|
Corr(B, PB, QB); Corr(C, PC, QC); |
|
P(x) ├ PB(x); P(x) & QB(x, z) ├ PC(z); |
|
P(x) & QB(x, z) & QC(x, z, y) ├ Q(x, y) |
RS: |
Corr(B(x: z); C(x, z: y), P(x), Q(x, y)) |
Обобщение на случай рекурсии:
|
Corr(t, A, B, PB, QB); Corr(t, A, C, PC, QC); |
|
P(x) ├ P*B(x); P(x) & QB(x, z) ├ P*C(z); |
|
P(x) & QB(x, z) & QC(x, z, y) ├ Q(x, y) |
RS: |
Corr(t, A, B(x: z); C(x, z: y), P(x), Q(x, y)) |
Пример 5.1. Программа умножения через сложение.
formula m(nat a: nat) = a; Умн(nat a, b: nat c)
{ if (a = 0) c = 0 else c = b + Умн(a – 1, b) } post c = a b measure m(a);
Corr(A, t, B, P & E, Q); Corr(A, t, C, P & E,
QС: Q)
ГенерируютсяCorr(A,цели:t, if (E) B(x: y) else C(x: y), P(x), Q(x, y))
formula Q(nat a, b, c) = c = a b;
QC1: Corr(Умн, a, c = 0, a = 0, Q);
QC2: Corr(Умн, a, c = b + Умн(a – 1, b), a = 0, Q)
T0: P(x) ├ y. L(S(x: y)); P(x) & L(S(x: y) ├ Q(x, y)
Corr(S(x: y), P(x), Q(x, y))
Генерируется лемма применением T0.2:
QC1: lemma not a = 0 & c = 0 implies Q(a, b, c);
Перепишем вторую цель в виде суперпозиции:
QC2: Corr(Умн, a, Умн(a – 1, b: t); c = b + t, not a = 0, Q)
Corr(A, t, B, PB, QB); Corr(A, t, C, PC, QC); P(x) ├ P*B(x); P(x) & QB(x, z) ├ P*C(z); P(x) & QB(x, z) & QC(x, z, y) ├ Q(x, y)
RS: |
Corr(A, t, B(x: z); C(x, z: y), P(x), Q(x, y)) |
Применяя RS.3, RS.4, RS.5, получим:
formula m(nat a: nat) = a; formula Q(nat a, b, c) = c = a b;
QC2_RS1: lemma not a = 0 implies a – 1 >= 0 & m(a – 1) < m(a);
QC2_RS2: lemma not a = 0 & Q(a – 1, b, t) & c = b + t implies Q(a , b, c);
Пример 5.2. Программа D(a, b: c) вычисления наибольшего общего делителя (НОД) положительных a и b.
x ― делитель a divisor(x, a) z ≥ 0. x z = a divisor2(с, a, b) divisor(с, a) & divisor(с, b)
НОД(c, a, b) divisor2(с, a, b) & x. (divisor2(x, a, b) x ≤ c)
Свойства НОД: |
|
a = b НОД(a, a, b) |
(5.21) |
a > b & НОД(c, a, b) НОД(c, a - b, b) |
(5.22) |
НОД(c, a, b) НОД(c, b, a) |
(5.23) |
formula НОД(nat c, a, b) = divisor2(с, a, b) &
forall nat x. divisor2(x, a, b) implies x <= c;
D(nat a, b: nat c) pre a ≥ 1 & b ≥ 1
{if (a = b) c = a
else if (a < b) D(a, b-a: c) else D(a-b, b: c)
} post НОД(c, a, b) measure a+b; formula m(nat a, b: nat) = a+b; formula P(nat a, b) = a ≥ 1 & b ≥ 1;
Corr(A, t, B, P & E, Q); Corr(A, t, C, P & E,
QС: Q)
Corr(A, t, if (E) B(x: y) else C(x: y), P(x), Q(x, y))
Генерируются цели:
QC1: Corr((D, a, b), c = a, P(a, b) & a = b, НОД(c, a, b)); QC2: Corr((D, a, b), if, P(a, b) & not a = b, НОД(c, a, b));
Вторая цель декомпозируется на подцели:
QC3: Corr((D, a, b), D(a, b-a: c), P(a, b) & not a = b & a < b,
НОД(c, a, b));
QC4: Corr((D, a, b), D(a-b, b: c),
P(a, b) & not a = b & not a < b, НОД(c, a,
QC1: Corr((D, a, b), c = a, P(a, b) & a = b, НОД(c, a, b));
Генерируется лемма применением T0.2:
QC1: lemma P(a, b) & a = b & c = a implies НОД(c, a, b);
Для целей:
QC3: Corr((D, a, b), D(a, b-a: c), P(a, b) & not a = b & a < b,
НОД(c, a, b));
QC4: Corr((D, a, b), D(a-b, b: c),
P(a, b) & not a = b & not a < b, НОД(c, a,
b));
применяеются правило:
Corr(B, PB, QB); Corr(A, t, C, PC, QC); SV(PB(x), QB(x, y)); P(x) ├ PB(x) & P*C(B(x)); P(x) & QC(B(x), y) ├ Q(x, y)
RB: |
Corr(A, t, C(B(x): y), P(x), Q(x, y)) |
QC3: Corr((D, a, b), D(a, b-a: c), P(a, b) & not a = b & a < b,
НОД(c, a, b));
QC4: Corr((D, a, b), D(a-b, b: c),
P(a, b) & not a = b & not a < b, НОД(c, a,
Corr(B, PB, QB); Corr(A, t, C, PC, QC);
применяется правило:
SV(PB(x), QB(x, y)); P(x) ├ PB(x) & P*C(B(x)); P(x) & QC(B(x), y) ├ Q(x, y)
RB: Corr(A, t, C(B(x): y), P(x), Q(x, y))
QC3_RB1: lemma P(a, b) & not a = b & a < b implies b – a >= 0 & P(a, b - a) & m(a, b – a) < m(a, b);
QC3_RB2: lemma P(a, b) & not a = b & a < b & НОД(c, a, b - a)
implies НОД(c, a, b);
QC4_RB1: lemma P(a, b) & not a = b & not a < b implies a – b >= 0 & P(a - b, b) & m(a - b, b) < m(a, b);
lemma P(a, b) & not a = b & not a < b &