Semantyka i weryfikacja programów/Ćwiczenia 15: Różnice pomiędzy wersjami
Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Nie podano opisu zmian |
m Zastępowanie tekstu – „.↵</math>” na „</math>” |
||
(Nie pokazano 4 wersji utworzonych przez 3 użytkowników) | |||
Linia 1: | Linia 1: | ||
== Zawartość == | == Zawartość == | ||
Linia 26: | Linia 24: | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><div class="mw-collapsible-content" style="display:none"> | <div class="mw-collapsible mw-made=collapsible mw-collapsed"> | ||
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span> | |||
<div class="mw-collapsible-content" style="display:none"> | |||
Intuicyjnie, pownniśmy wskazać | Intuicyjnie, pownniśmy wskazać wyrażenie, którego wartość maleje w każdym obrocie pętli i jest zawsze nieujemna. | ||
Naturalnym kandydatem jest wyrażenie <math>q</math>. | Naturalnym kandydatem jest wyrażenie <math>q</math>. | ||
W dowodzie poprawności częściowej używaliśmy niezmiennika <math>N \, \equiv \, z \cdot p^q = x^y</math>. | W dowodzie poprawności częściowej używaliśmy niezmiennika <math>N \, \equiv \, z {\cdot} p^q = x^y</math>. | ||
Intuicyjnie mówiąc, dla własności stopu potrzebujemy dodatkowo własności <math>q \geq 0</math>, więc naturalnym pomysłem byłoby dodanie tej własności do niezmiennika. | |||
Dla formalnego dowodu potrzebujemy jednak, "kontrolować" wartość zmiennej <math>q</math> za pomocą zewnętrzenego parametru: | |||
Dla formalnego dowodu | |||
<math>N'(l) \, \equiv \, z \cdot p^q = x^y \land q = l</math>. | <math>N'(l) \, \equiv \, z {\cdot} p^q = x^y \land q = l</math>. | ||
Formalnie rzecz biorąc, wykażemy: | Formalnie rzecz biorąc, wykażemy: | ||
<math>{\color{ | <math>{\color{Brown}[\exists l \geq 0. N'(l)]}</math> | ||
while q <> 0 do | while q <> 0 do | ||
if odd(q) then | if odd(q) then | ||
Linia 56: | Linia 54: | ||
* <math>N'(0) \, \implies \, z = x^y</math>. | * <math>N'(0) \, \implies \, z = x^y</math>. | ||
Zastosujemy teraz następującą regułę dla pętli (jest to odmiana reguły zaprezentowanej na wykładzie, która jest wygodna w tym zadaniu :) | |||
<math> | <math> | ||
\frac{l | \frac{l > 0 \land N'(l) \implies b \quad {\color{Red}[l > 0 \land N'(l)]} I {\color{Red}[N'(l \,\mathrm{div}\, 2)]} \quad N'(0) \implies \neg b} | ||
{{\color{Red}[\exists l. l \geq 0 \land N'(l)]} \mathbf{while}\, b \,\mathbf{do}\, I {\color{Red}[N'(0)]}} | {{\color{Red}[\exists l. l \geq 0 \land N'(l)]} \mathbf{while}\, b \,\mathbf{do}\, I {\color{Red}[N'(0)]}} | ||
</math> | </math> | ||
Wystarczy zatem dowieść: | |||
<math>{\color{Red}[l | <math>{\color{Red}[l > 0 \land N'(l)]}</math> | ||
if odd(q) then | if odd(q) then | ||
z := z * p; | z := z * p; | ||
Linia 79: | Linia 77: | ||
* <math>N'(0) \implies q = 0</math>. | * <math>N'(0) \implies q = 0</math>. | ||
Stosując teraz zwykłe reguły | Stosując teraz zwykłe reguły "przeciągamy" asercję <math>N'(l \,\mathrm{div}\, 2)</math> w tył: | ||
<math>{\color{Red}[l | <math>{\color{Red}[l > 0 \land z {\cdot} p^q = x^y \land q = l]}</math> | ||
if odd(q) then | if odd(q) then | ||
( | ( | ||
<math>{\color{Red}[l | <math>{\color{Red}[l > 0 \land z {\cdot} p^q = x^y \land q = l \land \,\mathrm{odd}(q)]}</math> | ||
<math>{\color{Green}\Downarrow}</math> | <math>{\color{Green}\Downarrow}</math> | ||
<math>{\color{Red}[(z \cdot p) \cdot (p \cdot p)^(q \,\mathrm{div}\, 2) = x^y \land q \,\mathrm{div}\, 2 = l \,\mathrm{div}\, 2]}</math> | <math>{\color{Red}[(z {\cdot} p) {\cdot} (p {\cdot} p)^{(q \,\mathrm{div}\, 2)} = x^y \land q \,\mathrm{div}\, 2 = l \,\mathrm{div}\, 2]}</math> | ||
z := z * p; | z := z * p; | ||
<math>{\color{Red}[z \cdot (p \cdot p)^(q \,\mathrm{div}\, 2) = x^y \land q \,\mathrm{div}\, 2 = l \,\mathrm{div}\, 2]}</math> | <math>{\color{Red}[z {\cdot} (p {\cdot} p)^{(q \,\mathrm{div}\, 2)} = x^y \land q \,\mathrm{div}\, 2 = l \,\mathrm{div}\, 2]}</math> | ||
) | ) | ||
<math>{\color{Red}[z \cdot (p \cdot p)^(q \,\mathrm{div}\, 2) = x^y \land q \,\mathrm{div}\, 2 = l \,\mathrm{div}\, 2]}</math> | <math>{\color{Red}[z {\cdot} (p {\cdot} p)^{(q \,\mathrm{div}\, 2)} = x^y \land q \,\mathrm{div}\, 2 = l \,\mathrm{div}\, 2]}</math> | ||
q := q div 2; | q := q div 2; | ||
<math>{\color{Red}[z \cdot (p \cdot p)^q = x^y \land q = l \,\mathrm{div}\, 2]}</math> | <math>{\color{Red}[z {\cdot} (p {\cdot} p)^q = x^y \land q = l \,\mathrm{div}\, 2]}</math> | ||
p := p * p | p := p * p | ||
<math>{\color{Red}[z \cdot p^q = x^y \land q = l \,\mathrm{div}\, 2]}</math> | <math>{\color{Red}[z {\cdot} p^q = x^y \land q = l \,\mathrm{div}\, 2]}</math> | ||
Oprócz implikacji zaznaczonej w anotacjach, powinniśmy też udowodnić: | |||
W | <math> | ||
l > 0 \land z {\cdot} p^q = x^y \land q = l \land \neg \,\mathrm{odd}(q) \, \implies \, z {\cdot} (p {\cdot} p)^{(q \,\mathrm{div}\, 2)} = x^y \land q \,\mathrm{div}\, 2 = l \,\mathrm{div}\, 2</math> | |||
W przyszłości będziemy pomijać formalny dowód własności stopu i ograniczymy się do podania wyrażenia, które maleje w każdym obiegu pętli. | |||
Będziemy używali następującej notacji: | Będziemy używali następującej notacji: | ||
Linia 111: | Linia 114: | ||
p := p * p | p := p * p | ||
) | ) | ||
<math>{\color{Red}[N \land | <math>{\color{Red}[N \land q = 0]}</math> | ||
... | ... | ||
Linia 117: | Linia 120: | ||
</div></div> | </div></div> | ||
Linia 149: | Linia 151: | ||
(m + 1)^3 \, = \, m^3 + 3 {\cdot} m^2 + 3 {\cdot} m + 1 | (m + 1)^3 \, = \, m^3 + 3 {\cdot} m^2 + 3 {\cdot} m + 1 | ||
</math> | </math> | ||
<math> | <math> | ||
\Sigma_{j = 1}^m \, = \, \frac{m \cdot (m+1)}{2} | \Sigma_{j = 1}^m j \, = \, \frac{m {\cdot} (m+1)}{2} | ||
</math> | </math> | ||
}} | }} | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><div class="mw-collapsible-content" style="display:none"> | <div class="mw-collapsible mw-made=collapsible mw-collapsed"> | ||
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie (poprawność częściowa)</span> | |||
<div class="mw-collapsible-content" style="display:none"> | |||
Zacznijmy od niezmiennika dla pętli zewnętrznej: <math>N_1 \, \equiv \, s = i^3 \land 1 \leq i \leq n</math>. | Zacznijmy od niezmiennika dla pętli zewnętrznej: <math>N_1 \, \equiv \, s = i^3 \land 1 \leq i \leq n</math>. | ||
Linia 198: | Linia 202: | ||
Dwie zaznaczone implikacja są łatwe do udowodnienia. | Dwie zaznaczone implikacja są łatwe do udowodnienia. | ||
Trudniej jest znależć niezmiennik dla pętli wewnętrznej. | Trudniej jest znależć niezmiennik dla pętli wewnętrznej. | ||
Przede wszystkim zauważmy, że jeśli <math>N_1</math> ma się | Przede wszystkim zauważmy, że jeśli <math>N_1</math> ma się "odnawiać" po każdym obrocie zewnętrznej pętli, to wartość dodawana do zmiennej <math>s</math> powinna wynosić: | ||
<math> | <math> | ||
(i+1)^3 - i^3 = 3 \cdot | (i+1)^3 - i^3 = 3 {\cdot} i^2 + 3 {\cdot} i + 1 = 3 {\cdot} (i^2 + i) + 1 = 3 {\cdot} i {\cdot} (i{+}1) + 1. | ||
</math> | </math> | ||
Zatem pętla wewnętrzna powinna prawdopodobnie obliczać na zmiennej <math>k</math> wartość <math>\frac{i \cdot (i+1)}{2} = 1 + 2 + \ldots + i</math>. | Zatem pętla wewnętrzna powinna prawdopodobnie obliczać na zmiennej <math>k</math> wartość <math>\frac{i {\cdot} (i+1)}{2} = 1 + 2 + \ldots + i</math>. | ||
Jeśli uważnie przyjrzymy się pętli wewnętrznej, to zaobserwujemy, że zmienna <math>k</math> przechowuje wartość | Jeśli uważnie przyjrzymy się pętli wewnętrznej, to zaobserwujemy, że zmienna <math>k</math> przechowuje wartość | ||
<math>1 + 2 + \ldots + l</math> plus | <math>1 + 2 + \ldots + l</math> plus "zaczęte" <math>l{+}1</math>, czyli plus <math>p</math>. | ||
Spróbujmy niezmiennik postaci: | Spróbujmy niezmiennik postaci: | ||
<math> | <math> | ||
N_2 \, \equiv \, k = (1 + 2 + \ldots l) + p \land \ldots | N_2 \, \equiv \, k = (1 + 2 + \ldots + l) + p \land \ldots | ||
</math> | </math> | ||
Linia 216: | Linia 220: | ||
Po pierwsze, zawsze zachodzi <math>p \leq l+1</math>. | Po pierwsze, zawsze zachodzi <math>p \leq l+1</math>. | ||
Po drugie, oczekujemy, że spełniony będzie warunek <math>l < i</math>. | Po drugie, oczekujemy, że spełniony będzie warunek <math>l < i</math>. | ||
Zauważmy, że zmienna l nigdy nie osiągnie wartości i, gdyż wcześniej zmienna p osiągnie tę wartość, a wtedy nastąpi od razu wyjście z pętli. | Zauważmy, że zmienna <math>l</math> nigdy nie osiągnie wartości <math>i</math>, gdyż wcześniej zmienna <math>p</math> osiągnie tę wartość, a wtedy nastąpi od razu wyjście z pętli. | ||
Połączmy te ograniczenia w jeden zwięły warunek: | Połączmy te ograniczenia w jeden zwięły warunek: | ||
<math> | <math> | ||
N_2 \, \equiv \, k = (1 + 2 + \ldots l) + p \land 1 \leq p \leq l+1 \leq i | N_2 \, \equiv \, k = (1 + 2 + \ldots + l) + p \land 1 \leq p \leq l+1 \leq i</math> | ||
</math> | |||
Oto odpowiednie anotacje całego programu: | Oto odpowiednie anotacje całego programu: | ||
Linia 255: | Linia 258: | ||
<math>{\color{Red}\{N_2 \land p \geq i\}}</math> | <math>{\color{Red}\{N_2 \land p \geq i\}}</math> | ||
<math>{\color{Green}\Downarrow}</math> <span style="color:brown">// 4 </span> | <math>{\color{Green}\Downarrow}</math> <span style="color:brown">// 4 </span> | ||
<math>{\color{Red}\{N_1[i \mapsto i{+}1][s \mapsto s {+} 6 \cdot k {+} p {-} l]\}}</math> | <math>{\color{Red}\{N_1[i \mapsto i{+}1][s \mapsto s {+} 6 {\cdot} k {+} p {-} l]\}}</math> | ||
s := s + 6 * k + p - l; | s := s + 6 * k + p - l; | ||
i := i + 1; | i := i + 1; | ||
Linia 268: | Linia 271: | ||
* <math>N_1 \land i < n \land k = 1 \land l = 0 \land p = 1 \, \implies \, N_2</math> | * <math>N_1 \land i < n \land k = 1 \land l = 0 \land p = 1 \, \implies \, N_2</math> | ||
* <math>N_2 \land p \geq i \, \implies \, N_1[i \mapsto i{+}1][s \mapsto s {+} 6 \cdot k {+} p {-} l]</math> | * <math>N_2 \land p \geq i \, \implies \, N_1[i \mapsto i{+}1][s \mapsto s {+} 6 {\cdot} k {+} p {-} l]</math>. | ||
Pierwsza z nich jest oczywista, natomiast nie jesteśmy w stanie dowieść drugiej! | Pierwsza z nich jest oczywista, natomiast nie jesteśmy w stanie dowieść drugiej! | ||
Linia 276: | Linia 279: | ||
<math> | <math> | ||
N_2 \, \equiv \, s = i^3 \land k = (1 + 2 + \ldots l) + p \land 1 \leq p \leq l+1 \leq i | N_2 \, \equiv \, s = i^3 \land k = (1 + 2 + \ldots + l) + p \land 1 \leq p \leq l+1 \leq i | ||
</math> | </math> | ||
i wróćmy do ostatniej z implikacji powyżej. | i wróćmy do ostatniej z implikacji powyżej. Wciąż brakuje nam pewnych informacji! | ||
Wciąż brakuje nam pewnych informacji! | Tym razem nie potrafimy pokazać, że zachodzi <math>i{+}1 \leq n</math>, co stanowi część formuły <math>N_1[i \mapsto i{+}1][s \mapsto s {+} 6 {\cdot} k {+} p {-} l]</math>. | ||
Tym razem nie potrafimy | |||
<math>N_1[i \mapsto i{+}1][s \mapsto s {+} 6 \cdot k {+} p {-} l]</math>. | |||
Powinniśmy dodać do <math>N_2</math> warunek <math>i < n</math>, który zachodzi zawsze po wejściu do pętli zewnętrznej. | Powinniśmy dodać do <math>N_2</math> warunek <math>i < n</math>, który zachodzi zawsze po wejściu do pętli zewnętrznej. | ||
Otrzymujemy ostatecznie: | Otrzymujemy ostatecznie: | ||
<math> | <math> | ||
N_2 \, \equiv \, s = i^3 \land i < n \land k = (1 + 2 + \ldots l) + p \land 1 \leq p \leq l+1 \leq i | N_2 \, \equiv \, s = i^3 \land i < n \land k = (1 + 2 + \ldots + l) + p \land 1 \leq p \leq l+1 \leq i</math> | ||
</math> | |||
Teraz dowód ostatniej implikacji jest możliwy. | Teraz dowód ostatniej implikacji jest możliwy. | ||
Zauważmy w szczególności, że warunek <math>p \geq i</math> w połączeniu z warunkiem <math>p \leq l{+}1 \leq i</math> obecnym w <math>N_2</math> | Zauważmy w szczególności, że warunek <math>p \geq i</math> w połączeniu z warunkiem <math>p \leq l{+}1 \leq i</math> obecnym w <math>N_2</math> daje nam <math>p = l{+}1 = i</math>. | ||
daje nam <math>p = l{+}1</math>. | Ponieważ <math>p = l{+}1</math> mamy: | ||
<math> | <math> | ||
s | s + 6 {\cdot} k + p {-} l \, = \, s + 6 {\cdot} (1 + 2 + \ldots + (l{+}1)) + 1 | ||
</math> | </math> | ||
a ponieważ <math> | a ponieważ <math>l{+}1 = i</math>, otrzymujemy: | ||
<math> | <math> | ||
s | s + 6 {\cdot} k + p {-} l \, = \, s + 6 {\cdot} (1 + 2 + \ldots + (l{+}1)) + 1 \, = \, s + 6 {\cdot} (1 + 2 + \ldots + i) + 1 \, = \, s + 6 {\cdot} \frac{i {\cdot} (i+1)}{2} + 1 \, = \, | ||
s + 3 \cdot i^2 + | s + 3 {\cdot} i^2 + 3 {\cdot} i + 1 = (i+1)^3</math> | ||
</math> | |||
Na koniec pozostał nam dowód poprawności instrukcji wewnętrznej w wewnętrznej pętli: | Na koniec pozostał nam dowód poprawności instrukcji wewnętrznej w wewnętrznej pętli: | ||
Linia 333: | Linia 332: | ||
<math> | <math> | ||
N' \, \equiv \, s = i^3 \land i < n \land k = (1 + 2 + \ldots l) + p + 1 \land 1 \leq p \leq l+1 \leq i | N' \, \equiv \, s = i^3 \land i < n \land k = (1 + 2 + \ldots l) + p + 1 \land 1 \leq p \leq l+1 \leq i</math> | ||
</math> | |||
Oto szczegółowa anotacja rozważanego fragmentu programu: | Oto szczegółowa anotacja rozważanego fragmentu programu: | ||
Linia 350: | Linia 348: | ||
<math>{\color{Red}\{N' \land l < p\}}</math> | <math>{\color{Red}\{N' \land l < p\}}</math> | ||
<math>{\color{Green}\Downarrow}</math> <span style="color:brown">// 6 </span> | <math>{\color{Green}\Downarrow}</math> <span style="color:brown">// 6 </span> | ||
<math>{\color{Red}\{N_2[p \mapsto 1][l mapsto l{+}1]\}}</math> | <math>{\color{Red}\{N_2[p \mapsto 1][l \mapsto l{+}1]\}}</math> | ||
l := l + 1; | l := l + 1; | ||
p := 1 | p := 1 | ||
Linia 371: | Linia 369: | ||
* <math>N_2 \land p < i \, \implies \, N'[k \mapsto k{+}1] \land p < i</math> | * <math>N_2 \land p < i \, \implies \, N'[k \mapsto k{+}1] \land p < i</math> | ||
* <math>N' \land l < p < i \, \implies \, N_2[p \mapsto 1][l mapsto l{+}1]</math> | * <math>N' \land l < p < i \, \implies \, N_2[p \mapsto 1][l \mapsto l{+}1]</math> | ||
* <math>N' \land l \geq p < i \, \implies \, N_2[p \mapsto p{+}1]</math>. | * <math>N' \land l \geq p < i \, \implies \, N_2[p \mapsto p{+}1]</math>. | ||
Linia 377: | Linia 375: | ||
</div></div> | </div></div> | ||
Własność stopu pętli zewnętrznej łatwo jest pokazać, gdyż w każdym obiegu rośnie wartość zmiennej i, czyli maleje wartość | <div class="mw-collapsible mw-made=collapsible mw-collapsed"> | ||
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie (poprawność calkowita)</span> | |||
<div class="mw-collapsible-content" style="display:none"> | |||
Własność stopu pętli zewnętrznej łatwo jest pokazać, gdyż w każdym obiegu rośnie wartość zmiennej <math>i</math>, czyli maleje wartość wyrażenia <math>n - i</math>. | |||
Dodatkowo <math>n - i \geq 0</math> zagwarantowane jest przez niezmiennik <math>N_1</math>. | Dodatkowo <math>n - i \geq 0</math> zagwarantowane jest przez niezmiennik <math>N_1</math>. | ||
Trudniej jest pokazać własność stopu pętli wewnętrznej. | Trudniej jest pokazać własność stopu pętli wewnętrznej. | ||
Choć dozór tej pętli to <math>p < i</math>, to zasadnicze znaczenie dla tej pętli ma nie tyle wzrost wartości zmiennej p (zmienna i nie zmienia się w tej pętli) co wzrost wartości zmiennej l. | Choć dozór tej pętli to <math>p < i</math>, to zasadnicze znaczenie dla tej pętli ma nie tyle wzrost wartości zmiennej <math>p</math> (zmienna i nie zmienia się w tej pętli) co wzrost wartości zmiennej <math>l</math>. | ||
Ale wyrażenie <math>i - l</math> nie maleje po każdym obiegu pętli! | Ale wyrażenie <math>i - l</math> nie maleje po każdym obiegu pętli! | ||
Może ono pozostać niezmienione, ale wtedy rośnie na pewno wartość zmiennej p, czyli maleje <math>i - p</math>. | Może ono pozostać niezmienione, ale wtedy rośnie na pewno wartość zmiennej <math>p</math>, czyli maleje <math>i - p</math>. | ||
Widać zatem, że warto tutaj | Widać zatem, że warto tutaj wziąć pod uwagę porządek leksykograficzny par liczb: para wartości wyrażeń <math>\langle i - l, i - p \rangle</math> | ||
maleje w porządku leksykograficznym po każdym obiegu pętli. | maleje w porządku leksykograficznym po każdym obiegu pętli. | ||
Obydwa mają przy tym zawsze wartość większą lub równą 0, dzięki niezmiennikowi <math>N_2</math>. | Obydwa mają przy tym zawsze wartość większą lub równą 0, dzięki niezmiennikowi <math>N_2</math>. | ||
Linia 412: | Linia 411: | ||
<math>{\color{Red}[N_2]}</math> | <math>{\color{Red}[N_2]}</math> | ||
while <math>{\color{Red}[N_2]}</math> p < i do <math>{\color{Red}[\mathbf{decr}\, \langle i {-} l, i {-} p \rangle \,\mathbf{in}\, {\,\mathbb{N}\,}^2 \,\mathbf{wrt}\, <_{\mbox{lex}}]}</math> | while <math>{\color{Red}[N_2]}</math> p < i do <math>{\color{Red}[\mathbf{decr}\, \langle i {-} l, i {-} p \rangle \,\mathbf{in}\, {\,\mathbb{N}\,}^2 \,\mathbf{wrt}\, <_{\mbox{lex}}]}</math> | ||
( | ( | ||
... | ... | ||
) | ) | ||
) | ) | ||
<math>{\color{Red}[N_2 \land p \geq i]}</math> | <math>{\color{Red}[N_2 \land p \geq i]}</math> | ||
<math>{\color{Green}\Downarrow}</math> <span style="color:brown">// 4 </span> | <math>{\color{Green}\Downarrow}</math> <span style="color:brown">// 4 </span> | ||
<math>{\color{Red}[N_1[i \mapsto i{+}1][s \mapsto s {+} 6 \cdot k {+} p {-} l]]}</math> | <math>{\color{Red}[N_1[i \mapsto i{+}1][s \mapsto s {+} 6 {\cdot} k {+} p {-} l]]}</math> | ||
s := s + 6 * k + p - l; | s := s + 6 * k + p - l; | ||
i := i + 1; | i := i + 1; | ||
Linia 437: | Linia 430: | ||
</div></div> | </div></div> | ||
== Zadania domowe == | == Zadania domowe == | ||
Linia 448: | Linia 439: | ||
<math>{\color{Red} | <math>{\color{Red}[(\forall x. 1 \leq x < n \implies A[x] \leq A[x+1]) \land (\forall x. n{+}1 \leq x < 2 {\cdot} n \implies A[x] \leq A[x+1])]}</math> | ||
i := 1; j := 2 * n; | i := 1; j := 2 * n; | ||
while A[i] < A[j] do | while A[i] < A[j] do | ||
Linia 454: | Linia 445: | ||
i := i + 1; | i := i + 1; | ||
j := j - 1; | j := j - 1; | ||
<math>{\color{Red} | <math>{\color{Red}[\forall x, y. 1 \leq x \leq n < y \leq 2 {\cdot} n \implies A[x] \geq A[y]]}</math> |
Aktualna wersja na dzień 21:39, 11 wrz 2023
Zawartość
Ostatnie ćwiczenia poświęcone będa dowodzeniu poprawności całkowitej programów.
Poprawność całkowita
Ćwiczenie 1 (potęgowanie binarne)
Przeprowadź dowód poprawności całkowitej (poprawność częściowa plus własność stopu) potęgowania binarnego:
z := 1; p := x; q := y; while q <> 0 do if odd(q) then z := z * p; q := q div 2; p := p * p
Rozwiązanie
Ćwiczenie 2
Przeprowadź dowód poprawności całkowitej poniższego programu.
s := 1; i := 1; while i < n do k := 1; l := 0; p := 1; while p < i do k := k + 1; if l < p then l := l + 1; p := 1 else p := p + 1; s := s + 6 * k + p - l; i := i + 1;
Wskazówka
Rozwiązanie (poprawność częściowa)
Rozwiązanie (poprawność calkowita)
Zadania domowe
Ćwiczenie 1
Przeprowadź dowód poprawności całkowitej poniższego programu.
i := 1; j := 2 * n; while A[i] < A[j] do ,,zamień A[i] i A[j]"; i := i + 1; j := j - 1;