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

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Sl (dyskusja | edycje)
Nie podano opisu zmian
Sl (dyskusja | edycje)
Nie podano opisu zmian
Linia 19: Linia 19:
   y := y + x;
   y := y + x;
   x := x + 1
   x := x + 1
  <math>{\color{Red}\{y=\frac{n\cdot(n+1)}{2}\}}</math>
  <math>{\color{Red}\{y=\frac{n{\cdot}(n+1)}{2}\}}</math>




Linia 38: Linia 38:
   x := x + 1
   x := x + 1
  )
  )
  <math>{\color{Red}\{y=\frac{n\cdot(n+1)}{2}\}}</math>
  <math>{\color{Red}\{y=\frac{n{\cdot}(n+1)}{2}\}}</math>




Linia 57: Linia 57:
   x := x + 1
   x := x + 1
  )
  )
  <math>{\color{Red}\{y=\frac{n\cdot(n+1)}{2}\}}</math>
  <math>{\color{Red}\{y=\frac{n{\cdot}(n+1)}{2}\}}</math>




Linia 64: Linia 64:


* <math> n \geq 0 \land x = 1 \land y = 0 \, \implies \, N</math>
* <math> n \geq 0 \land x = 1 \land y = 0 \, \implies \, N</math>
* <math>N \land x > n \, \implies \, y=\frac{n\cdot(n+1)}{2}</math>
* <math>N \land x > n \, \implies \, y=\frac{n{\cdot}(n+1)}{2}</math>


oraz prawdziwa jest trójka:
oraz prawdziwa jest trójka:
Linia 87: Linia 87:




Dla prawdziwości tej reguły powinniśmy, formalnie rzecz biorąc, zgadnąć asercję, która może być wpisana pomiędzy dwie instrukcje przypisania:
Formalnie rzecz biorąc, powinniśmy teraz zgadnąć asercję, która może być wpisana pomiędzy dwie instrukcje przypisania:




Linia 122: Linia 122:
  <math>{\color{Red}\{N \land x \leq n\}}</math>
  <math>{\color{Red}\{N \land x \leq n\}}</math>
     <math>{\color{Green}\Downarrow}</math>          <span style="color:brown">// tę implikację należy udowodnić </span>
     <math>{\color{Green}\Downarrow}</math>          <span style="color:brown">// tę implikację należy udowodnić </span>
  <math>{\color{Red}\{N[x \mapsto x{+}1]\}}</math>
  <math>{\color{Red}\{N[x \mapsto x{+}1][y \mapsto y{+}x]\}}</math>
  y := y + x;
  y := y + x;
  <math>{\color{Red}\{N[x \mapsto x{+}1]\}}</math>
  <math>{\color{Red}\{N[x \mapsto x{+}1]\}}</math>
Linia 129: Linia 129:
Skoro dwie asercje ,,spotkały się", wystarczy teraz udowodnić implikację.
Skoro dwie asercje ,,spotkały się", wystarczy teraz udowodnić implikację.


I tak dalej. To znaczy, podobnie postępujemy z pozostałymi przypisaniami.
I tak dalej. To znaczy, podobnie postępujemy z pozostałymi przypisaniami. A wszędzie, gdzie ,,spotykają się" dwie asercje, dowodzimy implikacji.  
A wszędzie, gdzie ,,spotykają się" dwie asercje, dowodzimy implikacji.  
Podsumowując, poniższe anotacje całego programu powinny stanowić dowód poprawności częściowej:
Podsumowując, poniższe anotacje całego programu powinny stanowić dowód poprawności częściowej:


Linia 153: Linia 152:
  <math>{\color{Red}\{N \land x > n\}}</math>
  <math>{\color{Red}\{N \land x > n\}}</math>
     <math>{\color{Green}\Downarrow}</math>        <span style="color:brown">// 3 </span>
     <math>{\color{Green}\Downarrow}</math>        <span style="color:brown">// 3 </span>
  <math>{\color{Red}\{y=\frac{n\cdot(n+1)}{2}\}}</math>
  <math>{\color{Red}\{y=\frac{n{\cdot}(n+1)}{2}\}}</math>




Linia 160: Linia 159:
# <math>n \geq 0 \land x = 1 \land y = 0 \, \implies \, N</math>
# <math>n \geq 0 \land x = 1 \land y = 0 \, \implies \, N</math>
# <math>N \land x \leq n \, \implies \, N[x \mapsto x{+}1][y \mapsto y{+}x]</math>
# <math>N \land x \leq n \, \implies \, N[x \mapsto x{+}1][y \mapsto y{+}x]</math>
# <math>N \land x > n \, \implies \, y=\frac{n\cdot(n+1)}{2}</math>
# <math>N \land x > n \, \implies \, y=\frac{n{\cdot}(n+1)}{2}</math>


Co ciekawe, to wszystko uczyniliśmy nie wiedząc wogóle, jaki jest niezmiennik pętli!
Co ciekawe, to wszystko uczyniliśmy nie wiedząc wogóle, jaki jest niezmiennik pętli!
Linia 167: Linia 166:
Należy oczywiście uwzględnić również implikacje, które wypisaliśmy powyżej.
Należy oczywiście uwzględnić również implikacje, które wypisaliśmy powyżej.


Spróbujmy <math>N \, \equiv \, y = \frac{x\cdot(x{-}1)}{2} \land x \leq n{+}1</math>.
Spróbujmy <math>N \, \equiv \, y = \frac{x{\cdot}(x{-}1)}{2} \land x \leq n{+}1</math>.


Nierówność <math>x \leq n{+}1</math> jest niezbędna.
Nierówność <math>x \leq n{+}1</math> jest niezbędna. Potrzebujemy jej po to, aby z <math>N \land x > n</math> wywnioskować <math>x = n{+}1</math>.
potrzebujemy jej po to, aby z <math>N \land x > n</math> wywnioskować <math>x = n{+}1</math>.
Implikacje są prawdziwe więc niezmiennik został wybrany poprawnie.
Implikacje są prawdziwe więc niezmiennik został wybrany poprawnie.


Zauważmy, że niezmiennik nie zawiera wymagania <math>x \geq 1</math>.
Zauważmy, że niezmiennik nie zawiera wymagania <math>x \geq 1</math>. Moglibyśmy je jednak dodać otrzymując <math>N' \, \equiv \, y = \frac{x{\cdot}(x{-}1)}{2} \land 1 \leq x \leq n{+}1</math>.
Moglibyśmy je jednak dodać otrzymując <math>N' \, \equiv \, y = \frac{x\cdot(x{-}1)}{2} \land 1 \leq x \leq n{+}1</math>.
Wszystkie implikacje pozostają prawdziwe, więc jest to też poprawny wybór. Ponadto wiedząc, że <math>x \geq 1</math> możemy, dla czytelności, zapisywać niezmiennik w meta-notacji:
Wszystkie implikacje pozostają prawdziwe, więc jest to też poprawny wybór.
Ponadto wiedząc, że <math>x \geq 1</math> możemy, dla czytelności, zapisywać niezmiennik w meta-notacji:


<math>
<math>
N \, \equiv \, y = 1{+}\ldots{+}(x{-}1) \land x \leq n{+}1.
N \, \equiv \, y = 1{+}2{+}\ldots{+}(x{-}1) \land x \leq n{+}1.
</math>
</math>


'''Pytanie:''' dlaczego nie potrzebowaliśmy warunku <math>x \geq 0</math>? Jak będzie działał nasz program, jeśli zmienną x zainicjujemy wartością ujemną (zamiast x := 1)?
'''Pytanie:''' dlaczego nie potrzebowaliśmy warunku <math>x \geq 0</math>? Jak będzie działał nasz program, jeśli zmienną x zainicjujemy wartością ujemną (zamiast x := 1), np. x := -2, y := 3?


<br>
<br>
Linia 188: Linia 184:
<br>
<br>


Niezmiennik pętli będziemy zwykle wpisywać pomiędzy słowem kluczowym while a dozorem pętli.
Niezmiennik pętli będziemy zwykle wpisywać pomiędzy słowem kluczowym while a dozorem pętli. W naszym przypadku otrzymamy następujące anotacje:
W naszym przypadku otrzymamy następujące anotacje:




Linia 214: Linia 209:
<math>{\color{Red}\{n \geq 0 \land x = 1 \land y = 0\}}</math>
<math>{\color{Red}\{n \geq 0 \land x = 1 \land y = 0\}}</math>


pomiędzy początkowe przypisania a pętlę.
pomiędzy początkowe przypisania a pętlę. Mogliśmy uczynić inaczej i wpisać w to miejsce po prostu niezmiennik <math>N</math>. Wtedy należałoby wykazać:
Mogliśmy uczynić inaczej i wpisać w to miejsce po prostu niezmiennik <math>N</math>.
Wtedy należałoby wykazać:




Linia 258: Linia 251:
  <math>{\color{Red}\{N \land x > n\}}</math>
  <math>{\color{Red}\{N \land x > n\}}</math>
     <math>{\color{Green}\Downarrow}</math>        <span style="color:brown">// 3 </span>
     <math>{\color{Green}\Downarrow}</math>        <span style="color:brown">// 3 </span>
  <math>{\color{Red}\{y=\frac{n\cdot(n+1)}{2}\}}</math>
  <math>{\color{Red}\{y=\frac{n{\cdot}(n+1)}{2}\}}</math>




Linia 289: Linia 282:


<math>
<math>
\frac{\alpha \, implies \, \beta[x \mapsto e]}
\frac{\alpha \, \implies \, \beta[x \mapsto e]}
     {{\color{Red}\{\alpha\}} x:= e {\color{Red}\{\beta\}}}
     {{\color{Red}\{\alpha\}} x:= e {\color{Red}\{\beta\}}}
</math>
</math>
Linia 328: Linia 321:
<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"><div class="mw-collapsible-content" style="display:none">


Jako niezmiennik pętli przyjmijmy <math>N \, \equiv \, z \cdot p^q = x^y</math>.
Jako niezmiennik pętli przyjmijmy <math>N \, \equiv \, z {\cdot} p^q = x^y</math>. Oto odpowiednie anotacje naszego programu:
Oto odpowiednie anotacje naszego programu:




Linia 342: Linia 334:
   if odd(q) then
   if odd(q) then
   (
   (
     <math>{\color{Red}\{N \land q \neq 0 \land \odd(q)\}}</math>
     <math>{\color{Red}\{N \land q \neq 0 \land \,\mathrm{odd}(q)\}}</math>
     <math>{\color{Red}\{N[p \mapsto p \cdot p][p \mapsto q \div 2][z \mapsto z \cdot p]\}}</math>
     <math>{\color{Red}\{N[p \mapsto p {\cdot} p][q \mapsto q \,\mathrm{div}\, 2][z \mapsto z {\cdot} p]\}}</math>
     z := z * p
     z := z * p
     <math>{\color{Red}\{N[p \mapsto p \cdot p][p \mapsto q \div 2]\}}</math>
     <math>{\color{Red}\{N[p \mapsto p {\cdot} p][q \mapsto q \,\mathrm{div}\, 2]\}}</math>
   )
   )
   else
   else
   (
   (
     <math>{\color{Red}\{N \land q \neq 0 \land \neq \odd(q)\}}</math>
     <math>{\color{Red}\{N \land q \neq 0 \land \neq \,\mathrm{odd}(q)\}}</math>
     <math>{\color{Red}\{N[p \mapsto p \cdot p][p \mapsto q \div 2]\}}</math>
     <math>{\color{Red}\{N[p \mapsto p {\cdot} p][q \mapsto q \,\mathrm{div}\, 2]\}}</math>
     skip
     skip
     <math>{\color{Red}\{N[p \mapsto p \cdot p][p \mapsto q \div 2]\}}</math>
     <math>{\color{Red}\{N[p \mapsto p {\cdot} p][q \mapsto q \,\mathrm{div}\, 2]\}}</math>
   )
   )
   <math>{\color{Red}\{N[p \mapsto p \cdot p][p \mapsto q \div 2]\}}</math>
   <math>{\color{Red}\{N[p \mapsto p {\cdot} p][q \mapsto q \,\mathrm{div}\, 2]\}}</math>
   q := q div 2;
   q := q div 2;
   <math>{\color{Red}\{N[p \mapsto p \cdot p]\}}</math>
   <math>{\color{Red}\{N[p \mapsto p {\cdot} p]\}}</math>
   p := p * p
   p := p * p
   <math>{\color{Red}\{N\}}</math>
   <math>{\color{Red}\{N\}}</math>
Linia 368: Linia 360:


  <math>{\color{Red}\{y \geq 0\}}</math>
  <math>{\color{Red}\{y \geq 0\}}</math>
  <math>{\color{Red}\{1 \cdot x^y = x^y\}}</math>
  <math>{\color{Red}\{1 {\cdot} x^y = x^y\}}</math>
  z := 1;  
  z := 1;  
  p := x;  
  p := x;  
  q := y;
  q := y;
  while  <math>{\color{Red}\{z \cdot p^q = x^y\}}</math>  q <> 0 do
  while  <math>{\color{Red}\{z {\cdot} p^q = x^y\}}</math>  q <> 0 do
  (
  (
   <math>{\color{Red}\{z \cdot p^q = x^y \land q \neq 0\}}</math>
   <math>{\color{Red}\{z {\cdot} p^q = x^y \land q \neq 0\}}</math>
   if odd(q) then
   if odd(q) then
   (
   (
     <math>{\color{Red}\{z \cdot p^q = x^y \land q \neq 0 \land \odd(q)\}}</math>
     <math>{\color{Red}\{z {\cdot} p^q = x^y \land q \neq 0 \land \,\mathrm{odd}(q)\}}</math>
     <math>{\color{Red}\{(z \cdot p) \cdot (p \cdot p)^(q \div 2) = x^y\}}</math>
     <math>{\color{Red}\{(z {\cdot} p) {\cdot} (p {\cdot} p)^{(q \,\mathrm{div}\, 2)} = x^y\}}</math>
     z := z * p
     z := z * p
     <math>{\color{Red}\{z \cdot (p \cdot p)^(q \div 2) = x^y\}}</math>
     <math>{\color{Red}\{z {\cdot} (p {\cdot} p)^{(q \,\mathrm{div}\, 2)} = x^y\}}</math>
   )
   )
   else
   else
   (
   (
     <math>{\color{Red}\{z \cdot p^q = x^y \land q \neq 0 \land \neq \odd(q)\}}</math>
     <math>{\color{Red}\{z {\cdot} p^q = x^y \land q \neq 0 \land \neq \,\mathrm{odd}(q)\}}</math>
     <math>{\color{Red}\{z \cdot (p \cdot p)^(q \div 2) = x^y\}}</math>
     <math>{\color{Red}\{z {\cdot} (p {\cdot} p)^{(q \,\mathrm{div}\, 2)} = x^y\}}</math>
     skip
     skip
     <math>{\color{Red}\{z \cdot (p \cdot p)^(q \div 2) = x^y\}}</math>
     <math>{\color{Red}\{z {\cdot} (p {\cdot} p)^{(q \,\mathrm{div}\, 2)} = x^y\}}</math>
   )
   )
   <math>{\color{Red}\{z \cdot (p \cdot p)^(q \div 2) = x^y\}}</math>
   <math>{\color{Red}\{z {\cdot} (p {\cdot} p)^{(q \,\mathrm{div}\, 2)} = x^y\}}</math>
   q := q div 2;
   q := q div 2;
   <math>{\color{Red}\{z \cdot (p \cdot p)^q = x^y\}}</math>
   <math>{\color{Red}\{z {\cdot} (p {\cdot} p)^q = x^y\}}</math>
   p := p * p
   p := p * p
   <math>{\color{Red}\{z \cdot p^q = x^y\}}</math>
   <math>{\color{Red}\{z {\cdot} p^q = x^y\}}</math>
  )
  )
  <math>{\color{Red}\{z \cdot p^q = x^y \land q=0\}}</math>
  <math>{\color{Red}\{z {\cdot} p^q = x^y \land q=0\}}</math>
  <math>{\color{Red}\{z = x^y\}}</math>
  <math>{\color{Red}\{z = x^y\}}</math>


Linia 401: Linia 393:
Teraz pozostaje tylko pokazać następujące implikacje:
Teraz pozostaje tylko pokazać następujące implikacje:


* <math>y \geq 0 \, \implies \, 1 \cdot x^y = x^y</math>
* <math>y \geq 0 \, \implies \, 1 {\cdot} x^y = x^y</math>
* <math>z \cdot p^q = x^y \land q \neq 0 \land \odd(q) \, \implies \, (z \cdot p) \cdot (p \cdot p)^(q \div 2) = x^y</math>
* <math>z {\cdot} p^q = x^y \land q \neq 0 \land \,\mathrm{odd}(q) \, \implies \, (z {\cdot} p) {\cdot} (p {\cdot} p)^{(q \,\mathrm{div}\, 2)} = x^y</math>
* <math>z \cdot p^q = x^y \land q \neq 0 \land \neq \odd(q) \, \implies \, z \cdot (p \cdot p)^(q \div 2) = x^y</math>
* <math>z {\cdot} p^q = x^y \land q \neq 0 \land \neq \,\mathrm{odd}(q) \, \implies \, z {\cdot} (p {\cdot} p)^{(q \,\mathrm{div}\, 2)} = x^y</math>
* <math>z \cdot p^q = x^y \land q=0 \, \implies \, z = x^y</math>
* <math>z {\cdot} p^q = x^y \land q=0 \, \implies \, z = x^y</math>


Zauważmy, że w niezmienniku nie wymagamy aby <math>q \geq 0</math>, ponieważ nie jest to potrzebne do udowodnienia powyższych implikacji.
Zauważmy, że w niezmienniku nie wymagamy aby <math>q \geq 0</math>, ponieważ nie jest to potrzebne do udowodnienia powyższych implikacji.
Musimy tylko umówić się, na wszelki wypadek, jak działa operacja div, gdy jej argument jest ujemny.
Musimy tylko umówić się, na wszelki wypadek, jak działa operacja div, gdy jej argument jest ujemny.
Przyjmijmy, że <math>q \div 2 = m</math> wtedy i tylko wtedy gdy największą liczbą parzystą nie większą od <math>q</math> jest
Przyjmijmy, że <math>q \,\mathrm{div}\, 2 = m</math> wtedy i tylko wtedy gdy największą liczbą parzystą nie większą od <math>q</math> jest
<math>2 \cdot m</math>.
<math>2 {\cdot} m</math>.


{{uwaga|||
{{uwaga|||
Linia 417: Linia 409:
}}
}}


'''Pytanie:''' jak będzie działał nasz program, jeśli zmienną q zainicjujemy na wartość ujemną?
'''Pytanie:''' czy niezmiennik pętli jest napewno prawdziwy gdy zmienna q ma wartość ujemną?


</div></div>
</div></div>
Linia 425: Linia 417:
{{cwiczenie|4|cw4|
{{cwiczenie|4|cw4|


Zaproponuj regułe dla instrukcji <math>\mathbf{repeat}\, I \,\mathbf{until}\, b</math>.
Zaproponuj regułę dla instrukcji <math>\mathbf{repeat}\, I \,\mathbf{until}\, b</math>.
}}
}}


Linia 444: Linia 436:


Dwukrotnie odwołujemy się do poprawności częściowej instrukcji <math>I</math>, względem różnych asercji początkowych.
Dwukrotnie odwołujemy się do poprawności częściowej instrukcji <math>I</math>, względem różnych asercji początkowych.
Gdybyśmy chcieli tego uniknąć, moglibyśmy rozważyć <math>\alpha = \beta</math>, otrzymyjąc regułę:
Gdybyśmy chcieli tego uniknąć, moglibyśmy rozważyć <math>\alpha = \beta</math>, otrzymując regułę:


<math>
<math>
Linia 453: Linia 445:
</math>
</math>


Jeśli <math>{\color{Red}\{\beta\}} I {\color{Red}\{\beta\}}</math> to <math>{\color{Red}\{\beta \land \neg b\}} I {\color{Red}\{\beta\}}</math>.
Jeśli <math>{\color{Red}\{\beta\}} I {\color{Red}\{\beta\}}</math> to <math>{\color{Red}\{\beta \land \neg b\}} I {\color{Red}\{\beta\}}</math>. Zatem powyzszą regułę można uprościć:
Zatem powyzszą regułę można uprościć:


<math>
<math>
Linia 510: Linia 501:
{{wskazowka|||
{{wskazowka|||
<math>
<math>
(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>
}}
}}

Wersja z 13:23, 16 sie 2006


Zawartość

Poprawność częściowa prostych programów w języku Tiny.


Poprawność częściowa

Ćwiczenie 1

Przeprowadź dowód poprawności częściowej poniższego programu:


{n1}
x := 1; y := 0;
while x <= n do
  y := y + x;
  x := x + 1
{y=n(n+1)2}


Rozwiązanie

{{{3}}}


Ćwiczenie 2

Uzupełnij poniższe reguły:

?{α}x:=e{β}

?{α}𝐰𝐡𝐢𝐥𝐞b𝐝𝐨I{β}


Rozwiązanie

{{{3}}}


Ćwiczenie 3 (potęgowanie binarne)

Dowiedź poprawności częściowej poniższego programu:


{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}


Wyrażenie odd(q) ma wartość 𝐭𝐫𝐮𝐞 wtedy i tylko wtedy, gdy q jest nieparzyste.

Rozwiązanie

{{{3}}}


Ćwiczenie 4

Zaproponuj regułę dla instrukcji 𝐫𝐞𝐩𝐞𝐚𝐭I𝐮𝐧𝐭𝐢𝐥b.


Rozwiązanie

{{{3}}}


Zadania domowe

Ćwiczenie 1

Wyprowadź ostatnią regułę dla pętli 𝐫𝐞𝐩𝐞𝐚𝐭 z pierwszej reguły.


Ćwiczenie 2

Napisz program obliczający najmniejszy wspólny dzielnik dwóch liczb i przeprowadź dowód poprawności częściowej.


Ćwiczenie 3

Przeprowadź dowód poprawności częściowej:


{x0}
a = 1; b := 1; y := 1;
while y <= x do
  y := y + 3*a + 3*b + 1;
  a = a + 2*b + 1;
  b := b + 1;
{(b1)3x<b3}


Wskazówka

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