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

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
m Zastępowanie tekstu – „\</math>” na „\ </math>”
m Zastępowanie tekstu – „.↵</math>” na „</math>”
 
Linia 96: Linia 96:
l, s \,\Longrightarrow, l
l, s \,\Longrightarrow, l
\quad \quad
\quad \quad
n, s \,\Longrightarrow, n.
n, s \,\Longrightarrow, n</math>
</math>


Podobnie jak poprzednio, zakładamy tutaj dla wygody, że <math>\mathbf{Num} \subseteq \mathbf{Exp}</math> oraz <math>\mathbf{Bool} \subseteq \mathbf{BExp}</math>.
Podobnie jak poprzednio, zakładamy tutaj dla wygody, że <math>\mathbf{Num} \subseteq \mathbf{Exp}</math> oraz <math>\mathbf{Bool} \subseteq \mathbf{BExp}</math>.
Linia 125: Linia 124:
\mathbf{false} \land b_2, s \,\Longrightarrow, \mathbf{false}, s
\mathbf{false} \land b_2, s \,\Longrightarrow, \mathbf{false}, s
\quad \quad
\quad \quad
\mathbf{true}  \land b_2, s \,\Longrightarrow, b_2, s.
\mathbf{true}  \land b_2, s \,\Longrightarrow, b_2, s</math>
</math>


Analogicznie reguły prawostronne to:
Analogicznie reguły prawostronne to:
Linia 136: Linia 134:
b_1 \land \mathbf{false}, s \,\Longrightarrow, \mathbf{false}, s
b_1 \land \mathbf{false}, s \,\Longrightarrow, \mathbf{false}, s
\quad \quad
\quad \quad
b_1 \land \mathbf{true}, s \,\Longrightarrow, b_1, s.
b_1 \land \mathbf{true}, s \,\Longrightarrow, b_1, s</math>
</math>


Reguły ''równoległe'' otrzymujemy jako sumę reguł lewo- i prawostronnych (w sumie 6 reguł). Zauważmy, że obliczanie wyrażeń <math>b_1</math> i <math>b_2</math> odbywa się teraz w tzw. "przeplocie": Pojedynczy krok polega na wykonaniu jednego kroku obliczenia <math>b_1</math> albo jednego kroku obliczenia <math>b_2</math>.
Reguły ''równoległe'' otrzymujemy jako sumę reguł lewo- i prawostronnych (w sumie 6 reguł). Zauważmy, że obliczanie wyrażeń <math>b_1</math> i <math>b_2</math> odbywa się teraz w tzw. "przeplocie": Pojedynczy krok polega na wykonaniu jednego kroku obliczenia <math>b_1</math> albo jednego kroku obliczenia <math>b_2</math>.
Linia 167: Linia 164:
n_1 \leq n_2, s \,\Longrightarrow, \mathbf{true}, s  \quad \mbox{ o ile } n_1 \leq n_2
n_1 \leq n_2, s \,\Longrightarrow, \mathbf{true}, s  \quad \mbox{ o ile } n_1 \leq n_2
\quad \quad
\quad \quad
n_1 \leq n_2, s \,\Longrightarrow, \mathbf{false}, s  \quad  \mbox{ o ile } n_1 > n_2.
n_1 \leq n_2, s \,\Longrightarrow, \mathbf{false}, s  \quad  \mbox{ o ile } n_1 > n_2</math>
</math>


Reguły powyższe zależą od semantyki wyrażen arytmetycznych.
Reguły powyższe zależą od semantyki wyrażen arytmetycznych.
Linia 228: Linia 224:


<math>
<math>
\mathbf{while}\, b \,\mathbf{do}\, I, s \,\Longrightarrow, \mathbf{if}\, b \,\mathbf{then}\, (I; \mathbf{while}\, b \,\mathbf{do}\, I) \,\mathbf{else}\, \mathbf{skip}, s.
\mathbf{while}\, b \,\mathbf{do}\, I, s \,\Longrightarrow, \mathbf{if}\, b \,\mathbf{then}\, (I; \mathbf{while}\, b \,\mathbf{do}\, I) \,\mathbf{else}\, \mathbf{skip}, s</math>
</math>


Dzięki temu obliczany warunek logiczny <math>b</math> jest zawsze ''jednorazowy''.
Dzięki temu obliczany warunek logiczny <math>b</math> jest zawsze ''jednorazowy''.
Linia 269: Linia 264:


<math>
<math>
\mathbf{repeat}\, I \,\mathbf{until}\, b, s \,\Longrightarrow, I; \mathbf{if}\, b \,\mathbf{then}\, (\mathbf{repeat}\, I \,\mathbf{until}\, b) \,\mathbf{else}\, \mathbf{skip}, s.
\mathbf{repeat}\, I \,\mathbf{until}\, b, s \,\Longrightarrow, I; \mathbf{if}\, b \,\mathbf{then}\, (\mathbf{repeat}\, I \,\mathbf{until}\, b) \,\mathbf{else}\, \mathbf{skip}, s</math>
</math>


Po drugie, spróbujmy odwołać się do <math>\,\Longrightarrow,^{*}</math> dla dozoru pętli <math>b</math>:
Po drugie, spróbujmy odwołać się do <math>\,\Longrightarrow,^{*}</math> dla dozoru pętli <math>b</math>:
Linia 305: Linia 299:


<math>
<math>
\,\mathbf{do}\, n \,\mathbf{times}\, I, s.
\,\mathbf{do}\, n \,\mathbf{times}\, I, s</math>
</math>


Teraz jest już łatwo:
Teraz jest już łatwo:
Linia 317: Linia 310:
<math>
<math>
\,\mathbf{do}\, n \,\mathbf{times}\, I, s \,\Longrightarrow, s  
\,\mathbf{do}\, n \,\mathbf{times}\, I, s \,\Longrightarrow, s  
\quad \mbox{ o ile } n = 0.
\quad \mbox{ o ile } n = 0</math>
</math>


<br>
<br>
Linia 342: Linia 334:


<math>
<math>
\mathbf{for}\, x = n_1 \,\mathbf{to}\, n_2 \,\mathbf{do}\, I, s.
\mathbf{for}\, x = n_1 \,\mathbf{to}\, n_2 \,\mathbf{do}\, I, s</math>
</math>


Dalsze reguły mogą być podobne do reguł dla pętli <math>\,\mathbf{do}\, n \,\mathbf{times}\, I</math>:
Dalsze reguły mogą być podobne do reguł dla pętli <math>\,\mathbf{do}\, n \,\mathbf{times}\, I</math>:
Linia 363: Linia 354:
<math>
<math>
\mathbf{for}\, x = n_1 \,\mathbf{to}\, n_2 \,\mathbf{do}\, I, s \,\Longrightarrow, I; \mathbf{for}\, x = n_1+1 \,\mathbf{to}\, n_2 \,\mathbf{do}\, I, s[x \mapsto s(x)+1]
\mathbf{for}\, x = n_1 \,\mathbf{to}\, n_2 \,\mathbf{do}\, I, s \,\Longrightarrow, I; \mathbf{for}\, x = n_1+1 \,\mathbf{to}\, n_2 \,\mathbf{do}\, I, s[x \mapsto s(x)+1]
\quad \mbox{ o ile } s(x) \leq n_2.
\quad \mbox{ o ile } s(x) \leq n_2</math>
</math>
Czy semantyka jest taka sama?
Czy semantyka jest taka sama?
(Rozważ sytuację, gdy zmienna <math>x</math> jest zmieniana przez instrukcję <math>I</math>.)
(Rozważ sytuację, gdy zmienna <math>x</math> jest zmieniana przez instrukcję <math>I</math>.)
Linia 376: Linia 366:


<math>
<math>
\,\mathbf{do}\, I \,\mathbf{while}\, b, s \,\Longrightarrow, \mathbf{repeat}\, I \,\mathbf{until}\, \neg b, s.
\,\mathbf{do}\, I \,\mathbf{while}\, b, s \,\Longrightarrow, \mathbf{repeat}\, I \,\mathbf{until}\, \neg b, s</math>
</math>


</div></div>
</div></div>
Linia 456: Linia 445:


<math>
<math>
\epsilon + \epsilon \,\Longrightarrow, \epsilon.
\epsilon + \epsilon \,\Longrightarrow, \epsilon</math>
</math>


Gdy jeden ze składników ma mniej cyfr niż drugi, potrzebujemy reguł:
Gdy jeden ze składników ma mniej cyfr niż drugi, potrzebujemy reguł:
Linia 472: Linia 460:
e 0 + \epsilon \,\Longrightarrow, e 0
e 0 + \epsilon \,\Longrightarrow, e 0
\quad \quad
\quad \quad
e 1 + \epsilon \,\Longrightarrow, e 1.
e 1 + \epsilon \,\Longrightarrow, e 1</math>
</math>


Niestety, nie możemy użyć reguły przemienności:
Niestety, nie możemy użyć reguły przemienności:
Linia 514: Linia 501:
       e 0  \,\,|\,\,
       e 0  \,\,|\,\,
       e 1  \,\,|\,\,
       e 1  \,\,|\,\,
       e_1 + e_2 .
       e_1 + e_2 </math>
</math>


Na przykład <math>p 1 0 1</math> oznacza tę samą liczbę, co <math>\epsilon 1 0 1</math>, ale z dodatkową informacją, że podczas jej obliczania nastąpiło "przepełnienie".
Na przykład <math>p 1 0 1</math> oznacza tę samą liczbę, co <math>\epsilon 1 0 1</math>, ale z dodatkową informacją, że podczas jej obliczania nastąpiło "przepełnienie".
Linia 534: Linia 520:
       \epsilon  \,\,|\,\,
       \epsilon  \,\,|\,\,
       b 0  \,\,|\,\,
       b 0  \,\,|\,\,
       b 1.
       b 1</math>
</math>


reprezentujących sumę liczb binarnych.
reprezentujących sumę liczb binarnych.
Linia 561: Linia 546:
e 0 + p \,\Longrightarrow, e 0
e 0 + p \,\Longrightarrow, e 0
\quad \quad
\quad \quad
e 1 + p \,\Longrightarrow, e 1.
e 1 + p \,\Longrightarrow, e 1</math>
</math>


W takiej sytuacji oczywiście informacja o przepełnieniu zostaje wymazana.
W takiej sytuacji oczywiście informacja o przepełnieniu zostaje wymazana.
Linia 574: Linia 558:
e 0 + \epsilon \,\Longrightarrow, e 0
e 0 + \epsilon \,\Longrightarrow, e 0
\quad \quad
\quad \quad
e 1 + \epsilon \,\Longrightarrow, e 1.
e 1 + \epsilon \,\Longrightarrow, e 1</math>
</math>


z poprzedniego zadania są wystarczające.
z poprzedniego zadania są wystarczające.
Linia 583: Linia 566:


<math>
<math>
p + p \,\Longrightarrow, p.
p + p \,\Longrightarrow, p</math>
</math>


Ale co należy zrobić, gdy tylko jeden ze składników odnotował przepełnienie? <math>p + \epsilon \,\Longrightarrow, ?</math>
Ale co należy zrobić, gdy tylko jeden ze składników odnotował przepełnienie? <math>p + \epsilon \,\Longrightarrow, ?</math>
Linia 593: Linia 575:
p + \epsilon \,\Longrightarrow, \epsilon
p + \epsilon \,\Longrightarrow, \epsilon
\quad \quad
\quad \quad
\epsilon + p \,\Longrightarrow, \epsilon.
\epsilon + p \,\Longrightarrow, \epsilon</math>
</math>


Na koniec zostało najważniejsze: kiedy powinniśmy generować sygnał o przepełnieniu?
Na koniec zostało najważniejsze: kiedy powinniśmy generować sygnał o przepełnieniu?
Linia 603: Linia 584:


<math>
<math>
e_1 1 + e_2 1 \,\Longrightarrow, ((e_1 + e_2) + p 1) 0.
e_1 1 + e_2 1 \,\Longrightarrow, ((e_1 + e_2) + p 1) 0</math>
</math>


Nowy sztuczny składnik <math>p 1</math> zawiera jakby na wszelki wypadek informacje o potencjalnym przepełnieniu.
Nowy sztuczny składnik <math>p 1</math> zawiera jakby na wszelki wypadek informacje o potencjalnym przepełnieniu.

Aktualna wersja na dzień 21:29, 11 wrz 2023

Zawartość

Ćwiczymy dalej semantykę małych kroków. Uzupełnimy semantykę języka Tiny o semantykę operacyjną wyrażeń boolowskich i arytmetycznych. Następnie rozszerzymy nasz język o róznorodne konstrukcje iteracji. Na koniec zdefiniujemy operacje arytmetyczne liczb binarnych.


Rozszerzenia semantyki języka Tiny

Ćwiczenie 1

Semantyka języka Tiny z wykładu używała funkcji semantycznych B,E:StateState dla określenia znaczenia wyrażeń boolowskich i arytmetycznych. Zdefiniuj znaczenie wyrażeń za pomocą semantyki operacyjnej, w stylu małych kroków.


Rozwiązanie


Ćwiczenie 2

Rozszerzmy język Tiny o następujące dobrze znane konstrukcje iteracji:

I::=𝐫𝐞𝐩𝐞𝐚𝐭I𝐮𝐧𝐭𝐢𝐥b|𝐟𝐨𝐫x:=e1𝐭𝐨e2𝐝𝐨I|𝐝𝐨e𝐭𝐢𝐦𝐞𝐬I|𝐝𝐨I𝐰𝐡𝐢𝐥𝐞b

Napisz semantykę małych kroków dla powyższych konstrukcji.


Rozwiązanie

Kalkulator binarny

Ćwiczenie 3

Rozważmy następujący język wyrażeń (liczby binarne z dodawaniem):

e::=ϵ|e0|e1|e1+e2

ϵ oznacza słowo puste, czyli np. ϵ1011 oznacza binarną liczbę 1011. Napisz semantykę operacyjną obliczającą wartość wyrażeń.


Rozwiązanie


Ćwiczenie 4

Rozszerzmy składnię o jeden symbol p oznaczający "przepełnienie":

e::=ϵ|p|e0|e1|e1+e2

Na przykład p101 oznacza tę samą liczbę, co ϵ101, ale z dodatkową informacją, że podczas jej obliczania nastąpiło "przepełnienie". Rozumiemy przez to sytuację, gdy wynik ma więcej cyfr niż każdy z argumentów. Cyfry zero z lewej strony (najbardziej znaczące) również uważamy za pełnoprawne cyfry, nie należy ich usuwać ani dodawać nowych.

Napisz semantykę operacyjną obliczającą wartość wyrażenia wraz z informacja o ewentualnym przepełnieniu. Wynik powinien byc poprawny przynajmniej dla wyrażeń e w składni ograniczonej:

e::=b|e1+e2

b::=ϵ|b0|b1

reprezentujących sumę liczb binarnych.


Rozwiązanie

Zadania domowe

Ćwiczenie 1

Podaj przykład wyrażenia boolowskiego, które nie policzy się ani przy użyciu strategii lewo-, ani prawostronnej, a policzy się przy strategii równoległej.


Ćwiczenie 2

Zmodyfikuj semantykę wyrażeń następująco: dla każdego podwyrażenia niedeterministycznie wybierana jest strategia lewo- albo prawostronna, ale niedozwolony jest "przeplot".


Ćwiczenie 3

Rozważ inną semantykę pętli 𝐟𝐨𝐫x=e1𝐭𝐨e2𝐝𝐨I, w której wyrażenie e2 jest obliczane na nowo przed każdą iteracją pętli.


Ćwiczenie 4

Dodaj do wyrażeń binarnych operację odejmowania.


Ćwiczenie 5

Zaproponuj semantykę przypisania równoległego w języku TINY:

x1:=e1||||xn:=en

polegającego na obliczeniu najpierw wartości wyrażeń e1,,en, a następnie na podstawieniu tych wartości na zmienne x1,,xn.