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
m Zastępowanie tekstu – „<math> ” na „<math>”
 
(Nie pokazano 10 wersji utworzonych przez 4 użytkowników)
Linia 1: Linia 1:
== Zawarto¶æ ==


== Zawartość ==


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


== Weryfikacja programow ==


== Poprawność częściowa ==


{{cwiczenie|1|cw1|
{{cwiczenie|1|cw1|
Przeprowadź dowód poprawności częściowej poniższego programu:
}}
}}


  <math>{\color{Red}\{n\geq1\}}</math>
 
  <math>{\color{Red}\{n \geq 1\}}</math>
  x := 1; y := 0;
  x := 1; y := 0;
  <math>\mathbf{while}\,</math> x <= n <math>\,\mathbf{do}\,</math>
while x <= n do
  y := y + x;
  x := x + 1
  <math>{\color{Red}\{y=\frac{n{\cdot}(n+1)}{2}\}}</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</span>
<div class="mw-collapsible-content" style="display:none">
 
Najpierw musimy odgadnąć asercję, którą można wpisać pomiędzy początkowe przypisania a pętlę:
 
 
<math>{\color{Red}\{n \geq 1\}}</math>
x := 1;
y := 0;
<math>{\color{Red}\{?\}}</math>
while x <= n do
(
  y := y + x;
  x := x + 1
)
<math>{\color{Red}\{y=\frac{n{\cdot}(n+1)}{2}\}}</math>
 
 
Możemy na przykład "przeciągnąć" asercję początkową wprzód, otrzymując <math>{\color{Red}\{n \geq 0 \land x = 1 \land y = 0\}}</math>.
Teraz wystarczy dowieść następujące dwie trójki Hoare'a:
 
 
<math>{\color{Red}\{n \geq 1\}}</math>
x := 1;
y := 0;
<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>
while x <= n do
(
  y := y + x;
  x := x + 1
)
<math>{\color{Red}\{y=\frac{n{\cdot}(n+1)}{2}\}}</math>
 
 
Zajmijmy się tą ostatnią.
Naszym zadaniem jest teraz odkrycie niezmiennika <math>N</math> takiego, że zachodzą poniższe dwie implikacje:
 
* <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>
 
oraz prawdziwa jest trójka:
 
 
<math>{\color{Red}\{N\}}</math>
while x <= n do
(
   y := y + x;
   y := y + x;
   x := x + 1
   x := x + 1
  <math>\{\color{Green}y=\Sigma_{z=1}^{n}z}\}</math>
)
  <math>{\color{Red}\{N \land x > n\}}</math>
 
 
Aby dowieść tej ostatniej, musimy pokazać:
 
 
<math>{\color{Red}\{N \land x \leq n\}}</math>
y := y + x;
x := x + 1
<math>{\color{Red}\{N\}}</math>
 
 
Formalnie rzecz biorąc, powinniśmy teraz zgadnąć asercję, która może być wpisana pomiędzy dwie instrukcje przypisania:
 
 
<math>{\color{Red}\{N \land x \leq n\}}</math>
y := y + x;
<math>{\color{Red}\{?\}}</math>
x := x + 1
<math>{\color{Red}\{N\}}</math>
 


{{rozwiazanie||roz1|}}
a następnie niezależnie dowieść poprawność każdej z dwóch nstrukcji.
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><div class="mw-collapsible-content" style="display:none">
Ale w "odgadnięciu" pomoże nam reguła dla przypisania, która, intuicyjnie mówiąc, daje sposób na "przeciągnięcie" asercji w tył.
  <math>\{n\geq1\}</math>
Jeśli zastosujemy ją do drugiego przypisania "x := x + 1", otrzymamy:
  x := 1; y := 0;
 
  '''while''' <math>\{y=\frac{x\cdot(x-1)}{2}\, \land\, x \leq n+1\}</math> x <= n '''do'''
 
  <math>\{y=\frac{x\cdot(x-1)}{2}\, \land\, x \leq n+1\, \land\, x \leq n\}</math>
<math>{\color{Red}\{N \land x \leq n\}}</math>
y := y + x;
<math>{\color{Red}\{N[x \mapsto x{+}1]\}}</math>
x := x + 1
<math>{\color{Red}\{N\}}</math>
 
 
Teraz musimy tylko pokazać trójkę:
 
 
<math>{\color{Red}\{N \land x \leq n\}}</math>
y := y + x;
<math>{\color{Red}\{N[x \mapsto x{+}1]\}}</math>
 
 
Użyjmy więc ponownie reguły dla przypisania, otrzymując:
 
 
<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{Red}\{N[x \mapsto x{+}1][y \mapsto y{+}x]\}}</math>
y := y + x;
<math>{\color{Red}\{N[x \mapsto x{+}1]\}}</math>
 
 
Skoro dwie asercje spotkały się, wystarczy teraz udowodnić implikację.
 
I tak dalej. To znaczy, podobnie postępujemy z pozostałymi przypisaniami. 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:
 
 
<math>{\color{Red}\{n \geq 1\}}</math>
  x := 1;  
<math>{\color{Red}\{n \geq 0 \land x = 1\}}</math>
y := 0;
  <math>{\color{Red}\{n \geq 0 \land x = 1 \land y = 0\}}</math>
    <math>{\color{Green}\Downarrow}</math>        <span style="color:brown">// 1 </span>
<math>{\color{Red}\{N\}}</math>
while x <= n do
(
  <math>{\color{Red}\{N \land x \leq n\}}</math>
      <math>{\color{Green}\Downarrow}</math>        <span style="color:brown">// 2 </span>
  <math>{\color{Red}\{N[x \mapsto x{+}1][y \mapsto y{+}x]\}}</math>
  y := y + x;
  <math>{\color{Red}\{N[x \mapsto x{+}1]\}}</math>
  x := x + 1
  <math>{\color{Red}\{N\}}</math>
)
<math>{\color{Red}\{N \land x > n\}}</math>
    <math>{\color{Green}\Downarrow}</math>        <span style="color:brown">// 3 </span>
<math>{\color{Red}\{y=\frac{n{\cdot}(n+1)}{2}\}}</math>
 
 
A jedyne co pozostaje do zrobienia to tylko udowodnienie następujących implikacji:
 
# <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 > 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!
Ale nadszedł wreszcie moment, w którym powinniśmy taki niezmiennik podać.
Musimy go odgadnąć poprzez staranną obserwację tego, co dzieje się wewnątrz pętli.
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>.
 
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>.
Implikacje są prawdziwe, więc niezmiennik został wybrany poprawnie.
 
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>.
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>
N \, \equiv \, y = 1{+}2{+}\ldots{+}(x{-}1) \land x \leq n{+}1</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), np. x := -2, y := 3?
 
<br>
'''Notacja:'''
<br>
 
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:
 
 
<math>{\color{Red}\{n \geq 1\}}</math>
x := 1;
<math>{\color{Red}\{n \geq 0 \land x = 1\}}</math>
y := 0;
<math>{\color{Red}\{n \geq 0 \land x = 1 \land y = 0\}}</math>
    <math>{\color{Green}\Downarrow}</math>        <span style="color:brown">// 1 </span>
<math>{\color{Red}\{N\}}</math>
while  <math>{\color{Red}\{N\}}</math>  x <= n do
(
  <math>{\color{Red}\{N \land x \leq n\}}</math>
  ...
 
 
<br>
'''Wariant:'''
<br>
 
Wróćmy na chwilę do naszej pierwszej decyzji, polegającej na wpisaniu następującej asercji
 
<math>{\color{Red}\{n \geq 0 \land x = 1 \land y = 0\}}</math>
 
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ć:
 
 
<math>{\color{Red}\{n \geq 1\}}</math>
x := 1;
y := 0;
<math>{\color{Red}\{N\}}</math>
 
 
co można, za pomocą znanego nam już "przepychania w tył", zredukować do udowodnienia implikacji:
 
 
<math>{\color{Red}\{n \geq 1\}}</math>
    <math>{\color{Green}\Downarrow}</math>        <span style="color:brown">// 1 </span>
<math>{\color{Red}\{N[y \mapsto 0][x \mapsto 1]\}}</math>
x := 1;
<math>{\color{Red}\{N[y \mapsto 0]\}}</math>
y := 0;
<math>{\color{Red}\{N\}}</math>
 
 
Ostatecznie, anotacje programu wyglądałyby tak:
 
 
<math>{\color{Red}\{n \geq 1\}}</math>
    <math>{\color{Green}\Downarrow}</math>        <span style="color:brown">// 1 </span>
<math>{\color{Red}\{N[y \mapsto 0][x \mapsto 1]\}}</math>
x := 1;
<math>{\color{Red}\{N[y \mapsto 0]\}}</math>
y := 0;
while  <math>{\color{Red}\{N\}}</math>  x <= n do
(
  <math>{\color{Red}\{N \land x \leq n\}}</math>
      <math>{\color{Green}\Downarrow}</math>        <span style="color:brown">// 2 </span>
  <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>
   x := x + 1
   x := x + 1
   <math>\{y=\frac{x\cdot(x-1)}{2}\, \land\, x \leq n+1\}</math>
   <math>{\color{Red}\{N\}}</math>
  <math>\{y=\frac{x\cdot(x-1)}{2}\, \land\, x \leq n+1\, \land\, x>n\}</math>
)
  <math>\{y=\frac{n\cdot(n+1)}{2}\}</math>
<math>{\color{Red}\{N \land x > n\}}</math>
    <math>{\color{Green}\Downarrow}</math>        <span style="color:brown">// 3 </span>
<math>{\color{Red}\{y=\frac{n{\cdot}(n+1)}{2}\}}</math>
 
 
a pierwsza z trzech implikacji to: <math>n \geq 1 \, \implies \, N[y \mapsto 0][x \mapsto 1]</math>.
 
 
</div></div>
 
 
{{cwiczenie|2|cw2|
 
Uzupełnij poniższe reguły:
}}
 
<math>
\frac{?}
    {{\color{Red}\{\alpha\}} x:= e {\color{Red}\{\beta\}}}
</math>
 
<math>
\frac{?}
    {{\color{Red}\{\alpha\}} \mathbf{while}\, b \,\mathbf{do}\, I {\color{Red}\{\beta\}}}
</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</span>
<div class="mw-collapsible-content" style="display:none">
 
<math>
\frac{\alpha \, \implies \, \beta[x \mapsto e]}
    {{\color{Red}\{\alpha\}} x:= e {\color{Red}\{\beta\}}}
</math>
 
<math>
\frac{\alpha \, \implies \, \gamma
      \quad
      {\color{Red}\{\gamma \land b\}} I {\color{Red}\{\gamma\}}
      \quad
      \gamma \land \neg b \, \implies \, \beta}
    {{\color{Red}\{\alpha\}} \mathbf{while}\, b \,\mathbf{do}\, I {\color{Red}\{\beta\}}}
</math>
 
</div></div>
 
 
 
{{cwiczenie|3 (potęgowanie binarne)|cw3|
 
Dowiedź poprawności częściowej poniższego programu:
}}
 
 
<math>{\color{Red}\{y \geq 0\}}</math>
z := 1; p := x; q := y;
while q <> 0 do
  if odd(q) then
    z := z * p;
  q := q div 2;
  p := p * p
<math>{\color{Red}\{z = x^y\}}</math>
 
 
Wyrażenie odd(q) ma wartość <math>\mathbf{true}</math> wtedy i tylko wtedy, gdy q jest nieparzyste.
 
 
 
<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">
 
Jako niezmiennik pętli przyjmijmy <math>N \, \equiv \, z {\cdot} p^q = x^y</math>. Oto odpowiednie anotacje naszego programu:
 
 
<math>{\color{Red}\{y \geq 0\}}</math>
<math>{\color{Red}\{N[q \mapsto y][p \mapsto x][z \mapsto 1]\}}</math>
z := 1;
p := x;
q := y;
while  <math>{\color{Red}\{N\}}</math>  q <> 0 do
(
  <math>{\color{Red}\{N \land q \neq 0\}}</math>
  if odd(q) then
  (
    <math>{\color{Red}\{N \land q \neq 0 \land \,\mathrm{odd}(q)\}}</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
    <math>{\color{Red}\{N[p \mapsto p {\cdot} p][q \mapsto q \,\mathrm{div}\, 2]\}}</math>
  )
  else
  (
    <math>{\color{Red}\{N \land q \neq 0 \land \neq \,\mathrm{odd}(q)\}}</math>
    <math>{\color{Red}\{N[p \mapsto p {\cdot} p][q \mapsto q \,\mathrm{div}\, 2]\}}</math>
    skip
    <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][q \mapsto q \,\mathrm{div}\, 2]\}}</math>
  q := q div 2;
  <math>{\color{Red}\{N[p \mapsto p {\cdot} p]\}}</math>
  p := p * p
  <math>{\color{Red}\{N\}}</math>
)
<math>{\color{Red}\{N \land q=0\}}</math>
<math>{\color{Red}\{z = x^y\}}</math>
 
 
Po podstawieniu niezmiennika:
 
 
<math>{\color{Red}\{y \geq 0\}}</math>
<math>{\color{Red}\{1 {\cdot} x^y = x^y\}}</math>
z := 1;
p := x;
q := y;
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>
  if odd(q) then
  (
    <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 \,\mathrm{div}\, 2)} = x^y\}}</math>
    z := z * p
    <math>{\color{Red}\{z {\cdot} (p {\cdot} p)^{(q \,\mathrm{div}\, 2)} = x^y\}}</math>
  )
  else
  (
    <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 \,\mathrm{div}\, 2)} = x^y\}}</math>
    skip
    <math>{\color{Red}\{z {\cdot} (p {\cdot} p)^{(q \,\mathrm{div}\, 2)} = x^y\}}</math>
  )
  <math>{\color{Red}\{z {\cdot} (p {\cdot} p)^{(q \,\mathrm{div}\, 2)} = x^y\}}</math>
  q := q div 2;
  <math>{\color{Red}\{z {\cdot} (p {\cdot} p)^q = x^y\}}</math>
  p := p * p
  <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 = x^y\}}</math>
 
 
Teraz pozostaje tylko pokazać następujące implikacje:
 
* <math>y \geq 0 \, \implies \, 1 {\cdot} x^y = 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 \,\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>
 
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.
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>.


{{uwaga|||
Warunek <math>q \geq 0</math> gwarantuje, że program się kończy.
Fakt, że go nie potrzebujemy, wiąże się z tym, że dowodzimy tylko poprawność częściową:
wynik będzie poprawny, o ile program się zakończy, ale wcale zakończyć się nie musi!
}}


cdn
'''Pytanie:''' czy niezmiennik pętli jest napewno prawdziwy, gdy zmienna q ma wartość ujemną?


</div></div>
</div></div>




{{cwiczenie|4|cw4|
Zaproponuj regułę dla instrukcji <math>\mathbf{repeat}\, I \,\mathbf{until}\, b</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</span>
<div class="mw-collapsible-content" style="display:none">
<math>\mathbf{repeat}\, I \,\mathbf{until}\, b</math> zachowuje się tak samo jak <math>I; \mathbf{while}\, \neg b \,\mathbf{do}\, I</math>.
Stąd łatwo otrzymać regułę:
<math>
\frac{{\color{Red}\{\alpha\}} I {\color{Red}\{\beta\}}
      \quad
      {\color{Red}\{\beta \land \neg b\}} I {\color{Red}\{\beta\}}}
    {{\color{Red}\{\alpha\}} \mathbf{repeat}\, I \,\mathbf{until}\, b {\color{Red}\{\beta \land b\}}}
</math>
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>, otrzymując regułę:
<math>
\frac{{\color{Red}\{\beta\}} I {\color{Red}\{\beta\}}
      \quad
      {\color{Red}\{\beta \land \neg b\}} I {\color{Red}\{\beta\}}}
    {{\color{Red}\{\beta\}} \mathbf{repeat}\, I \,\mathbf{until}\, b {\color{Red}\{\beta \land b\}}}
</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ć:
<math>
\frac{{\color{Red}\{\beta\}} I {\color{Red}\{\beta\}}}
    {{\color{Red}\{\beta\}} \mathbf{repeat}\, I \,\mathbf{until}\, b {\color{Red}\{\beta \land b\}}}
</math>
otrzymując regułę prostszą, ale słabszą: we wnętrzu pętli nie możemy korzystać z tego, że począwszy od drugiej iteracji nie zachodzi <math>b</math>!
Jeszcze inna możliwość to:
<math>
\frac{{\color{Red}\{\alpha\}} I {\color{Red}\{\beta\}}
      \quad
      \beta \land \neg b \implies \alpha}
    {{\color{Red}\{\alpha\}} \mathbf{repeat}\, I \,\mathbf{until}\, b {\color{Red}\{\beta \land b\}}}
</math>
</div></div>


== Zadania domowe ==
== Zadania domowe ==
Linia 39: Linia 474:


{{cwiczenie|1|cw1.dom|
{{cwiczenie|1|cw1.dom|
Wyprowadź ostatnią regułę dla pętli <math>\mathbf{repeat}\ </math>, z pierwszej reguły.
}}
{{cwiczenie|2|cw2.dom|
Napisz program obliczający największy wspólny dzielnik dwóch liczb i przeprowadź dowód poprawności częściowej.
}}
{{cwiczenie|3|cw3.dom|
Przeprowadź dowód poprawności częściowej:
}}
<math>{\color{Red}\{x \geq 0\}}</math>
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;
<math>{\color{Red}\{(b-1)^3 \leq x < b^3\}}</math>
{{wskazowka|||
<math>
(m + 1)^3 \, = \, m^3 + 3 {{\cdot}} m^2 + 3 {{\cdot}} m + 1
</math>
}}
}}

Aktualna wersja na dzień 22:18, 11 wrz 2023

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


Ćwiczenie 2

Uzupełnij poniższe reguły:

?{α}x:=e{β}

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



Rozwiązanie


Ć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


Ćwiczenie 4

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


Rozwiązanie

Zadania domowe

Ćwiczenie 1

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


Ćwiczenie 2

Napisz program obliczający największy 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