LK5

advertisement
Денотационная семантика
<двоичное_число>
→
0
|
1
|<двоичное_число>0
|<двоичное_число>1
Mb:
Мb('0') = 0, Мb('1')=1
Мb(<двоичное_число> '0') =
=2 * Мb(<двоичное_число>)
Мb(<двоичное_число> ‘1’) =
=2 * Мb(<двоичное_число>) + 1
<десятичное_число> → 0|1|2|3|4|5|6|7|8|9
| <десятичное_число> (0|1|2|3|4|5|6|7|8|9)
Синтаксические правила:
Md(‘0’) = 0, Md('1') = 1, ,..., Md('9') = 9
Мd(<десятичное_число> '0') =
=10 * Мd(<десятичное_число>)
Мd(<десятичное_число> ‘1’) =
= 10 * Мd(<десятичное_число>) + 1
…
Мd(<десятичное_число> '9') =
= 10 * Мd(<десятичное_число>) + 9
s
{<i1, v1>, <i2, v2>, …, <in, vn>}
VARMAP(ik, s) == vk
<выражение> → <десятичное_число>
| <переменная>
| <двоичное_выражение>
<двоичное_выражение> →
<выражение_слева><оператор><выражение_справа>
<оператор> → + | *
Me (<выражение>,s) 
case <выражение> of
<десятичное_число> => Md(<десятичное_число>, s)
< переменная> =>
if VARMAP(<переменная>, s) = undef
then error
else VARMAP(<переменная>, s)
<двоичное_выражение> =>
if(Me(<двоичное_выражение>.<выражение_слева>, s) = undef OR
Me(<двоичное_выражение>.< выражение_справа >, s) = undef)
then error
else if(<двоичное_выражение>.< оператор > = '+' then
Me(<двоичное_выражение>.<выражение_слева>, s) +
Me(<двоичное_выражение>.<выражение_справа>, s)
else Me(<двоичное_выражение>.<выражение_слева>, s) *
Me(<двоичное_выражение>.<выражение_справа>, s)
Ма(х = Е, s)  if Me(E, s) = error
then error
else
s' = {< i1', v1' >, < i2', v2' >,..., < in', vn' >}
where
for (j = 1, 2, ..., n) if ij <>x then
vj’ = VARMAP(ij’, s);
if ij = x then vj’ = Me(E, s)
Аксиоматическая система Хоара
{P} A {Q}
Законы консеквенции:
{P} A {Q}, Q=>V |- {P} A {V}
{P} A {Q}, W=>P |- {W} A {Q}
Алгебраические типы данных
push:
pop:
top:
empty:
size:
newstack:
stackintegerstack
stackstack
stackinteger  {undefined}
stackboolean
stackinteger
stack
Операции, определяющие тип данных:
1. Генераторы (g: not_xx)
2. Конструкторы (c: x  not_xx)
3. Функции
push(push(push(newstack, 1), 5), 3)
1.
pop(newstack)=
newstack
2.
pop(push(S, I))=
S
3.
top(newstack)=
undefined
4.
top(push(S,I))=
I
5.
empty(newstack)=
true
6.
empty(push(S,I))=
false
7.
size(newstack)=
0
8.
size(push(S,I))=
size(S)+1
Пример:
empty(pop(push(push(newstack, 42), 17)))
А2: empty(push(newstack, 42))
A6: false
Индукция типов данных
1. x, gi, ci, fi, P(y) yx.
2. P(gi)=true
3. P(y)=true => P(ci(y))=true.
4. P(y)=true, yx.
Пример: P(newstack), P(push(x, i))
size(push(S,x))>size(S) – исх. утверждение
Доказательство:
size(S)+1>size(S)
(A8)
newstack:
push(S, x):
0+1>0
size(newstack)+1>size(newstack) (A7)
size(S)+1>size(S)
- гипотеза
size(push(S,x))+1>size(push(S,x)) (A8)
size(S)+1+1>size(S)+1
Методы спецификации программ
Виды спецификаций:
1. Языки спецификации задач
• Языки описания требований;
• Языки функциональных спецификаций.
2. Языки спецификации свойств.
Языки описания требований:
RSL, SDL,PSL.
value
fact : Nat -~-> Nat
fact(n) is if n = 1 then 1 else n * fact(n-1) end
pre n > 0
Языки функциональных спецификаций
SETL, SPECIAL, CLEAR, RDM, CIP-L, META-IV, Jota.
Качества функциональных спецификаций:
• однозначность (точность);
• понятность (ясность);
• полнота описания задачи.
Свойства языков функциональных спецификаций:
• выразительность;
• выполнимость спецификаций;
• доказуемость.
Методы верификации программ
Свойства корректности программ:
1. Частичная корректность
2. Завершение
Суть метода индуктивных утверждений:
• формулируются входное и выходное
утверждения;
• строится промежуточное утверждение;
• формулируется теорема (условия
верификации):
из выведенного утверждения следует
выходное утверждение;
• доказывается теорема.
Алгоритм доказательства правильности
программ:
1. Построить структуру программы.
2. Выписать входное и выходное утверждения.
3. Сформулировать для всех циклов
индуктивные утверждения.
4. Составить список выделенных путей.
5. Построить условия верификации.
6. Доказать условия верификации.
7. Доказать, что выполнение программы
закончится.
Download