12.1 Wprowadzenie
Mamy l= 2 + 2 = 4, ale często wystarcza i- 2 + 2 = 4 (bo arytmetyka nie musi być wcale „taka skomplikowana”) do weryfikowania poprawności programów.
Definicja.
• i- {<p}c{ip} => f= {ip}c{ip} - mówimy, że taki system jest adekwatny
• ^ {¥’}C{V’} =*■ i- {<p}c{?/j} - mówimy, że taki system jest zupełny Ale z zupełnością jest pewien problem1.
Weźmy sobie nasz imperatywny język: a ::= n | X \ a © a © ::= + | - | x | div | mod b ::= a\ © | ->&1 6i ® i>2
© ::= A | V | ^ | <=>
c ::= skip | abort | X := a | if b then c\ else C2 | if b then c | while b do c | ci; C2
Można dołożyć asercje do języka - każda instrukcja w tym języku będzie miała „z przodu” i „z tyłu” jakieś asercje:
c ::= {<£>} skip {tp} |... | {ip} if b then {<p;} c {<pw} ; {ip}
| {<p} while 6 do {ip'} c {y>"} ; {ip}
I M oi; W <!2 {«}
I MM} c W}
I Mc W W>
W Haskellu mamy rekonstrukcję typów2 - zatem nie wszędzie musimy pisać typy. Są jednak miejsca, gdzie takie typy trzeba napisać (bo rekonstrukcja typów jest czasami nierozstrzygalna, ale weryfikacja poprawności już tak - nawet liniowa).
Problem z dowodzeniem poprawności programów polega na tym, że tablica może być za mała... Popatrzmy na taki programik obliczający silnię:
1 I* {X = n}
2 S := 1
3 while X * 1 do
4 S := X x S;
s X := X - 1;
19
mamy np. niezupełność arytmetyki
system typów Haskella jest dużo bardziej skomplikowany niż w SMLu