Semantyka i weryfikacja programów/Ćwiczenia 15: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Sl (dyskusja | edycje)
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:




{{rozwiazanie||roz1|


<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ć wrażenie, którego wartość maleje w każdym obrocie pętli i jest zawsze nieujemna.
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>.
Dla własności stopu potrzebujemy dodatkowo własności <math>q \geq 0</math>, więc naturalnym kandydatem jest niezmiennik
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.  
<math>N' \, \equiv \, z \cdot p^q = x^y \land q \leq 0</math>.
Dla formalnego dowodu potrzebujemy jednak, "kontrolować" wartość zmiennej <math>q</math> za pomocą zewnętrzenego parametru:
Dla formalnego dowodu lepiej, jeśli <math>N'</math> będzie miał parametr:


<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{Red}[\exists l \geq 0. N'(l)]}</math>
  <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>.


Stosując następującą regułe dla pętli (jest to odmiana reguły zaprezentowanej na wykładzie wygodna w tym zadaniu :)
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 \,\mathrm{div}\, 2 \geq 0 \land N'(l) \implies b \quad {\color{Red}[l \,\mathrm{div}\, 2 \geq 0 \land N'(l)]} I {\color{Red}[N'(l \,\mathrm{div}\, 2)]} \quad N'(0) \implies \neg b}
\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 dowieść:
Wystarczy zatem dowieść:




   <math>{\color{Red}[l \,\mathrm{div}\, 2 \geq 0 \land N'(l)]}</math>
   <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 ,,przeciągamy" niezmiennik <math>N'(l \,\mathrm{div}\, 2)</math> w tył:
Stosując teraz zwykłe reguły "przeciągamy" asercję <math>N'(l \,\mathrm{div}\, 2)</math> w tył:




   <math>{\color{Red}[l \,\mathrm{div}\, 2 \geq 0 \land z \cdot p^q = x^y \land q = l]}</math>
   <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 \,\mathrm{div}\, 2 \geq 0 \land z \cdot p^q = x^y \land q = l \land \odd(q)]}</math>
     <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 przyszlości będziemy pomijać formalny dowód własności stpu i ograniczymy się do podania wyrażenia, które maleje w każdym obiegu pętli.
<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 \neg \odd(q)]}</math>
  <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>
}}
}}




{{rozwiazanie| (poprawność częściowa)|roz1.1|


<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ę ,,odnawiać" po każdym obrocie zewnętrznej pętli, to wartość dodawana do zmiennej <math>s</math> powinna wynosić:
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 n^2 + 3 \cdot n = 3 \cdot (i^2 + i) = 3 \cdot i \cdot (i+1).  
(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 ,,zaczęte" l+1, czyli plus <math>p</math>.
<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 pokazac, ż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>.
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>. Stąd faktycznie zachodzi:
Ponieważ <math>p = l{+}1</math> mamy:


<math>
<math>
s {+} 6 \cdot k {+} p {-} l \, = \, s + (1 + 2 + \ldots + l) + 1
s + 6 {\cdot} k + p {-} l \, = \, s + 6 {\cdot} (1 + 2 + \ldots + (l{+}1)) + 1
</math>
</math>


a ponieważ <math>p = i</math>, otrzymujemy:
a ponieważ <math>l{+}1 = i</math>, otrzymujemy:


<math>
<math>
s {+} 6 \cdot k {+} p {-} l \, = \, s + 6 \cdot (1 + 2 + \ldots + l) + 1 \, = \, s + 6 \cdot (1 + 2 + \ldots + i) + 1 \, = \, s + 6 \cdot \frac{i \cdot (i+1)}{2} + 1 \, = \,  
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 + 4 \cdot i + 1 = (i+1)^3.
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>
}}


{{rozwiazanie| (poprawność calkowita)|roz1.2|


<div class="mw-collapsible mw-made=collapsible mw-collapsed"><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 i, czyli maleje wartość wyrażeni <math>n - i</math>.
<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 wziąc pod uwagę porządek leksykograficzny par liczb: para wartości wyrażeń <math>\langle i - l, i - p \rangle</math>
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>
   (,
   (
   
     ...
     ...
     if l < p then
      
    (
      l := l + 1;
      p := 1
    )
    else
    (
      p := p + 1;
     )
     )
   )
   )
   <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}\{(\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>
  <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}\{\forall x, y. 1 \leq x \leq n < y \leq 2 \cdot n \implies A[x] \geq A[y]\}}</math>
  <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:


[y0]
z := 1; p := x; q := y;
while q <> 0 do
  if odd(q) then
    z := z * p;
  q := q div 2;
  p := p * p
[z=xy]


Rozwiązanie


Ćwiczenie 2

Przeprowadź dowód poprawności całkowitej poniższego programu.


{n0}

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;
 
{s=n3}


Wskazówka

(m+1)3=m3+3m2+3m+1

Σj=1mj=m(m+1)2


Rozwiązanie (poprawność częściowa)


Rozwiązanie (poprawność calkowita)

Zadania domowe

Ćwiczenie 1

Przeprowadź dowód poprawności całkowitej poniższego programu.


[(x.1x<nA[x]A[x+1])(x.n+1x<2nA[x]A[x+1])]
i := 1; j := 2 * n;
while A[i] < A[j] do
  ,,zamień A[i] i A[j]";
  i := i + 1;
  j := j - 1;
[x,y.1xn<y2nA[x]A[y]]