Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lectures / lecture10.ppt
Скачиваний:
9
Добавлен:
06.06.2015
Размер:
402.94 Кб
Скачать

21.11.12 Лекция 10

Предикатное программирование

7. Технология предикатного программирования (прод)

Разработка и верификация программ вычисления целочисленного квадратного корня, целой части вещественного числа и целочисленного двоичного логарифма

8. Язык, технология и методы верификации других классов программ

Класс объектно-ориентированных программ Класс простых процессов.

Примеры. Гадание на кофейных зернах. Электронные часы с будильником

Класс реактивных систем

7. Технология предикатного программирования 7.6. Разработка и верификация программ стандартных функций

Иллюстрация методов разработки и верификации

Построение и верификация быстрых программ для стандартных функций:

floor – целая часть плавающего числа, представленного в бинарном формате в соответствии со стандартом IEEE 754-2008;

isqrt – целочисленный квадратный корень;

ilog2 – целочисленный двоичный логарифм.

Программы данных стандартных функций на языке C++ используются в отечественной системе спутниковой навигации “Навител Навигатор” для автомобилей (корпорация Центр Навигационных Технологий).

static const uint32_t small_limit = 17;

static const uint32_t small_sqrts[small_limit] =

//

0

1

2

3

4

5

6

7

8

9

10 11 12 13 14 15 16

{0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4};

#define sqrtBit(k)

 

 

\

 

 

 

t = s + (1UL << (k - 1));

 

 

t <<= k + 1;

if (_n >= t) {_n -= t; s |= 1UL << k;}

uint32_t os::isqrt(uint32_t _n) { if (_n < small_limit)

return small_sqrts[_n]; uint32_t s = 0UL;

if (_n >= 1UL<<30) { _n -= 1UL<<30; s = 1UL<<15; } uint32_t t;

sqrtBit(14); sqrtBit(13); sqrtBit(12); sqrtBit(11); sqrtBit(10); sqrtBit(9); sqrtBit(8); sqrtBit(7); sqrtBit(6); sqrtBit(5);

sqrtBit(4); sqrtBit(3); sqrtBit(2); sqrtBit(1); if (_n > s<<1)

s |= 1UL; return s;

}

Разработка программы вычисления целочисленного квадратного корня

Спецификация isqrt :

m = isqrt(x) = floor(sqrt(x)) ,

где z = floor(t) – целая часть вещественного аргумента t со спецификацией t <= z < t+1.

Спецификацией t = sqrt(x) является формула t^2 = x.

Таким образом, функция isqrt имеет спецификацию:

formula Isqrt(nat x, m) = m^2 <= x & x < (m + 1)^2; isqrt(nat x : nat m) post Isqrt(x, m);

Спецификация для предиката isqrt(nat x : nat m) есть [ true , Isqrt(x, m)]

Построение (синтез) программы для предиката isqrt

formula Isqrt(nat x, m) = m^2 <= x & x < (m + 1)^2; isqrt(nat x : nat m) post Isqrt(x, m);

Синтезируем простейшую программу, вычисляющую результат m последовательным перебором с нуля.

Применяется метод обобщения исходной задачи isqrt. Рассмотрим задачу sq0, определяемую спецификацией: formula P_sq0(nat x, k) = k^2 <= x

sq0(nat x, k: nat m) pre P_sq0(x, k) post Isqrt(x, m);

Задача isqrt(x : m) сводится к sq0(x, 0: m) : isqrt(nat x : nat m) { sq0(x, 0: m) } post Isqrt(x, m)

Построение программы для предиката sq0

formula Isqrt(nat x, m) = m^2 <= x & x < (m + 1)^2; isqrt(nat x : nat m) { sq0(x, 0: m) } post Isqrt(x, m) formula P_sq0(nat x, k) = k^2 <= x

sq0(nat x, k: nat m) pre P_sq0(x, k) post Isqrt(x, m);

Построить программу S1(x, k: m) для sq0 и доказать формулу корректности: P_sq0(x, k) & Isqrt(x, m) LS(S1(x, k: m)).

Решение строится разбором случаев по условию x < (k + 1)^2.

1)истина – решение задачи: m = k.

2)ложь – решение сводится к sq0(x, k + 1: m) для следующего значения k.

formula e(nat x, k: nat) = (x<(k + 1)^2)? 0 : x – k^2; sq0(nat x, k : nat m) pre P_sq0(x, k)

{ if (x < (k + 1)^2) m = k else sq0(x, k + 1: m) } post Isqrt(x, m) measure e(k, x);

Более эффективная версия программы isqrt

sq0(nat x, k : nat m) pre P_sq0(x, k)

{ if (x < (k + 1)^2) m = k else sq0(x, k + 1: m) } post Isqrt(x, m); Недостаток ─ вычисление квадрата в (k + 1)^2.

(k + 1)^2=p =k^2 + 2* k + 1 Дополнительный параметра n = k^2.

Параметр d = 2* k + 1 позволяет заменить умножение сложением. x < (k + 1)^2 эквивалентно x - k^2 < 2* k + 1

Вместо x и n можно перейти к одному параметру y = x - k^2. Соответствующее обобщение задачи sqrt есть предикат sq1: formula P_sq1(nat x, y, k, d) = k^2 <= x & d = 2 * k + 1 & y = x - k^2 ; sq1(nat x, y, k, d: nat m) pre P_sq1(x, y, k, d) post Isqrt(x, m);

Результатом является программа:

isqrt(nat x : nat m) { sq1(x, x, 0, 1: m) } post Isqrt(x, m); sq1(nat x, y, k, d: nat m) pre P_sq1(x, y, k, d)

{ if (y < d) m = k else sq1(x, y – d, k + 1, d + 2: m) } post Isqrt(x, m);

Алгоритм вычисления целочисленного квадратного корня через двоичное разложение

Спецификация:

formula Isqrt(nat n, s) = s^2 <= n & n < (s + 1)^2; formula P_sqp(nat n, p) = p > 0 & n < 2^(2*p); isqrt1(nat n, p: nat s) pre P_sqp(n, p) post Isqrt(n, s);

s состоит не более чем из p двоичных цифр !!

Значение старшей цифры равно 0, если n < 2^(2*(p-1)) и 1 в противном случае. Алгоритм определяет цифры начиная со старшей и далее. Пусть q очередное приближение для результата s в виде старших двоичных цифр с номерами от p до k+1. Тогда должно выполняться условие q^2 <= n < (q + 2^k)^2.

2^(2*(p-1))

0

2^(2*p)

p

 

k

 

1

 

 

 

 

 

Спецификация обобщающей задачи:

formula P_sq2(nat n, p, k, q) =

P_sqp(n, p) & k <= p & q^2 <= n & n < (q + 2^k)^2 ; sq2(nat n, p, k, q : nat s) pre P_sq2(n, p, k, q) post Isqrt(n, s);

isqrt1(nat n, p: nat s) pre P_sqp(n, p) { sq2(n, p, p, 0: s) } post Isqrt(n, s);

formula P_sq2(nat n, p, k, q) =

P_sqp(n, p) & k <= p & q^2 <= n & n < (q + 2^k)^2 ; sq2(nat n, p, k, q : nat s) pre P_sq2(n, p, k, q) post Isqrt(n, s);

При k = 0 решением задачи sq2 будет s = q. Если в s цифра с номером k есть 1, то следующим приближением для q будет q + 2^(k-1). Если n < (q + 2^(k-1))^2, то цифра с номером k есть 0, иначе 1.

sq2(nat n, p, q, k: nat s) pre P_sq2(n, p, k, q) { if (k = 0) s = q

else if ( n < (q + 2^(k-1))^2 ) sq2(n, p, k - 1, q : s) else sq2(n, p, k - 1, q + 2^(k-1) : s)

} post Isqrt(n, s);

Соседние файлы в папке lectures