Semantyka i weryfikacja programów/Ćwiczenia 3: Różnice pomiędzy wersjami
Nie podano opisu zmian |
Nie podano opisu zmian |
||
Linia 1: | Linia 1: | ||
== | == Zawarto¶æ == | ||
Koñczymy semantykê ma³ych kroków i rozpoczynamy semantykê naturaln± (du¿e kroki). | |||
Uzupe³nimy semantykê naturaln± jêzyka Tiny o semantykê naturaln± | |||
wyra¿eñ boolowskich i arytmetycznych oraz semantykê b³êdów wykonania. | |||
Wreszcie dodamy now± instrukcjê pêtli <math>\mathbf{loop}\,</math> pozwalaj±c± na | |||
Wreszcie dodamy | |||
niestrukturalne przerwanie lub wznowienie iteracji (instrukcje <math>\mathbf{exit}</math> i <math>\mathbf{continue}</math>). | niestrukturalne przerwanie lub wznowienie iteracji (instrukcje <math>\mathbf{exit}</math> i <math>\mathbf{continue}</math>). | ||
== Rozszerzenia semantyki | == Rozszerzenia semantyki jêzyka Tiny == | ||
{{cwiczenie|1|cw1| | {{cwiczenie|1|cw1| | ||
Zdefiniuj znaczenie | Zdefiniuj znaczenie wyra¿eñ boolowskich i arytmetycznych | ||
w | w jêzyku Tiny, w stylu du¿ych kroków (semantyka naturalna). | ||
}} | }} | ||
Linia 25: | 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"><div class="mw-collapsible-content" style="display:none"> | ||
Przypomnijmy | Przypomnijmy sk³adniê wyra¿eñ boolowskich i arytmetycznych | ||
jezyka Tiny: | jezyka Tiny: | ||
Linia 57: | Linia 56: | ||
</math> | </math> | ||
Chcemy, aby tranzycje | Chcemy, aby tranzycje wyra¿eñ wygl±da³y nastêpuj±co: | ||
<math> | <math> | ||
Linia 65: | Linia 64: | ||
</math> | </math> | ||
gdzie <math>s \in \mathbf{State}</math>, <math>n \in</math> jest | gdzie <math>s \in \mathbf{State}</math>, <math>n \in</math> jest liczb± ca³kowit±, | ||
<math>n \in \mathbf{Num}</math>, a <math>l \in \mathbf{Bool} = \{ \mathbf{true}, \mathbf{false} \}</math>. | <math>n \in \mathbf{Num}</math>, a <math>l \in \mathbf{Bool} = \{ \mathbf{true}, \mathbf{false} \}</math>. | ||
Tranzycja taka oznacza, | Tranzycja taka oznacza, ¿e wyra¿enie <math>e</math> w stanie <math>s</math> wylicza siê do | ||
warto¶ci <math>n</math> oraz analogicznie, wyra¿enie logiczne <math>b</math> w | |||
stanie <math>s</math> wylicza | stanie <math>s</math> wylicza siê do <math>l</math>. | ||
Zatem zbiór konfiguracji dla semantyki | Zatem zbiór konfiguracji dla semantyki ca³ego jêzyka Tiny to znów | ||
<math> | <math> | ||
Linia 76: | Linia 75: | ||
\mathbf{Num} \, \cup \, \mathbf{Bool} \, \cup \, \mathbf{State} | \mathbf{Num} \, \cup \, \mathbf{Bool} \, \cup \, \mathbf{State} | ||
</math> | </math> | ||
a konfiguracje | a konfiguracje koñcowe to <math>\mathbf{State}</math> tak jak poprzednio. | ||
Tranzycje dla instrukcji | Tranzycje dla instrukcji pozostaj± zasadniczo bez zmian, z tym, | ||
¿e odwo³ania do funkcji semantycznych dla wyra¿en zastêpujemy | |||
przez odpowiednie tranzycje. | przez odpowiednie tranzycje. | ||
Np. dla instrukcji | Np. dla instrukcji pêtli bêdziemy mieæ nastêpuj±ce regu³y: | ||
<math> | <math> | ||
Linia 93: | Linia 92: | ||
Podobnie dla instrukcji warunkowej. | Podobnie dla instrukcji warunkowej. | ||
Teraz zajmiemy | Teraz zajmiemy siê tranzycjami dla wyra¿eñ. | ||
Zacznijmy od stalych arytmetycznych i boolowskich: | Zacznijmy od stalych arytmetycznych i boolowskich: | ||
Linia 102: | Linia 101: | ||
</math> | </math> | ||
Operatory arytmetyczne definiujemy | Operatory arytmetyczne definiujemy nastêpuj±co: | ||
<math> | <math> | ||
Linia 111: | Linia 110: | ||
</math> | </math> | ||
Czyli aby | Czyli aby obliczyæ sumê <math>e_1 + e_2</math> w stanie | ||
<math>s</math>, trzeba najpierw | <math>s</math>, trzeba najpierw obliczyæ <math>e_1</math> i | ||
<math>e_2</math> w tym stanie, a | <math>e_2</math> w tym stanie, a nastêpnie dodaæ obliczone warto¶ci. | ||
Zauwa¿my, ¿e nie specyfikujemy kolejno¶ci, w jakiej maj± siê | |||
obliczaæ obydwa podwyra¿enia. | |||
I | I choæ tutaj nie ma to ¿adnego znaczenia, w przysz³o¶ci | ||
bêdzie inaczej, gdy jezyk bêdzie umo¿liwia³ efekty uboczne | |||
podczas obliczania | podczas obliczania wyra¿eñ. | ||
Podobne | Podobne regu³y mo¿na napisaæ dla pozosta³ych operacji | ||
arytmnetycznych, oraz dla spójników logicznych: | arytmnetycznych, oraz dla spójników logicznych: | ||
Linia 130: | Linia 129: | ||
</math> | </math> | ||
Oto inny wariant, | Oto inny wariant, regu³y lewo-stronne (poniewa¿ rozpoczynamy od ''lewego'' koniunktu): | ||
<math> | <math> | ||
Linia 143: | Linia 142: | ||
Inny wariant to wariant prawo-stronny ( | Inny wariant to wariant prawo-stronny ( | ||
najpierw <math>b_2</math>, potem <math>b_1</math>). | najpierw <math>b_2</math>, potem <math>b_1</math>). | ||
Wreszcie | Wreszcie rozwa¿my kombinacjê obydwu semantyk (regu³y ''równoleg³e''): | ||
<math> | <math> | ||
Linia 153: | Linia 152: | ||
</math> | </math> | ||
Czyli | Czyli je¶li którekolwiek z podwyra¿eñ daje wynik <math>\mathbf{false}</math>, | ||
to taki wynik zyskuje | to taki wynik zyskuje ca³e wyra¿enie. | ||
Dodatkowo potrzebujemy jeszcze | Dodatkowo potrzebujemy jeszcze regu³y: | ||
<math> | <math> | ||
Linia 163: | Linia 162: | ||
</math> | </math> | ||
W naszym prostym | W naszym prostym jêzyku wszystkie cztery warianty | ||
s± równowa¿ne. | |||
Regu³y dla pozosta³ych spójników logicznych, dla | |||
negacji oraz dla instrukcji przypisania pozostawiamy jako proste | negacji oraz dla instrukcji przypisania pozostawiamy jako proste | ||
æwiczenie. | |||
</div></div> | </div></div> | ||
Linia 175: | Linia 174: | ||
{{cwiczenie|2|cw2| | {{cwiczenie|2|cw2| | ||
Rozwa¿ dodatkowo operacjê dzielenia: | |||
<math> | <math> | ||
Linia 182: | Linia 181: | ||
</math> | </math> | ||
i rozszerz | i rozszerz semantykê z poprzedniego zadania. | ||
Dzielenie przez zero jest | Dzielenie przez zero jest b³±dem i koñczy natychmiast wykonanie | ||
programu. | programu. | ||
Oprócz stanu wynikiem programu powinna byc informacja o | Oprócz stanu wynikiem programu powinna byc informacja o b³êdzie, | ||
je¶li b³±d wyst±pi³. | |||
}} | }} | ||
Linia 194: | Linia 193: | ||
<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"> | ||
Dopóki nie | Dopóki nie wyst±pi b³±d dzielenia przez zero, semantyka programu | ||
powinna | powinna byæ identyczna jak w poprzednim zadaniu. Zatem pozostawiamy | ||
wszystkie | wszystkie regu³y z poprzedniego zadania. | ||
Dodatkowo potrzebujemy | Dodatkowo potrzebujemy regu³, które opisz± | ||
* kiedy powstaje | * kiedy powstaje b³±d oraz | ||
* jak zachowuje | * jak zachowuje siê program po wyst±pieniu b³êdu | ||
Zaczynamy od pierwszego punktu. | Zaczynamy od pierwszego punktu. | ||
W tym celu dodajemy do konfiguracji | W tym celu dodajemy do konfiguracji jedn± konfiguracjê koñcow± | ||
<math>\mathtt{Blad}</math>. | <math>\mathtt{Blad}</math>. | ||
Regu³a opisuj±ca powstanie b³êdu mo¿e wygl±daæ np. tak | |||
( | (du¿e i ma³e kroki): | ||
<math> | <math> | ||
Linia 215: | Linia 214: | ||
</math> | </math> | ||
Pomijamy tutaj | Pomijamy tutaj regu³y dla przypadku, gdy <math>e_2</math> | ||
oblicza | oblicza siê do warto¶ci ró¿nej od zera. | ||
Ponadto dla | Ponadto dla czytelno¶ci przyjêli¶my, ¿e wynikiem tranzycji jest | ||
wy³±cznie informacja o b³êdzie, a stan jest zapominany. | |||
Bez trudu | Bez trudu mo¿naby wszystkie regu³y (zarówno te powy¿ej jak i te | ||
poni¿ej) zmodyfikowaæ tak, by wraz z | |||
informacj± o b³êdzie zwracany by³ te¿ stan, w którym b³±d siê | |||
pojawi³. Np. ostatnia regu³a wygl±da³aby nastêpuj±co: | |||
<math> | <math> | ||
Linia 231: | Linia 230: | ||
</math> | </math> | ||
i zamiast | i zamiast pojedyñczej konfiguracji koñcowej <math>\mathtt{Blad}</math> potrzebowaliby¶my | ||
oczywi¶cie ca³ego zbioru <math>\{ \mathtt{Blad} \} \times \mathbf{State}</math>. | |||
Przejd¼my teraz do drugiego punktu. Potrzebujemy dodatkowych regu³, | |||
które | które zagwarantuj±, ¿e b³±d, raz pojawiwszy siê, propaguje siê przez | ||
wszystkie konstrukcje | wszystkie konstrukcje sk³adniowe, a normalne obliczenie wyra¿enia | ||
jest wstrzymame. | jest wstrzymame. | ||
Linia 247: | Linia 246: | ||
</math> | </math> | ||
Nastêpnie, b³±d w wyra¿eniu powinien wstrzymaæ normalne wykonanie instrukcji: | |||
<math> | <math> | ||
Linia 264: | Linia 263: | ||
</math> | </math> | ||
I wreszcie | I wreszcie b³±d powinien propagowaæ siê do kolejnych instrukcji: | ||
<math> | <math> | ||
Linia 288: | Linia 287: | ||
</math> | </math> | ||
Zwróæmy szczególnie uwagê na ostatni± regu³ê dla pêtli <math>\mathbf{while}\,</math>: | |||
wyra¿a ona przypadek, gdy b³±d zosta³ wygenerowany | |||
nie w pierwszym obiegu | nie w pierwszym obiegu pêtli, ale w którym¶ z kolejnych. | ||
Musieli¶my rozwa¿yc równie¿ ten przypadek, poniewa¿ wybrali¶my | |||
podej¶cie du¿ych kroków; w podej¶ciu ma³ych kroków nie by³oby | |||
to zapewne konieczne. | to zapewne konieczne. | ||
Linia 301: | Linia 300: | ||
{{cwiczenie|3|cw3| | {{cwiczenie|3|cw3| | ||
Rozszerzmy jêzyk Tiny o nastêpuj±c± instrukcjê pêtli: | |||
<math> | <math> | ||
Linia 310: | Linia 309: | ||
</math> | </math> | ||
<math>\mathbf{loop}\, I</math> to instrukcja | <math>\mathbf{loop}\, I</math> to instrukcja pêtli, <math>I</math> stanowi instrukcjê wewnêtrzn±. | ||
Instrukcja <math>\mathbf{exit}</math> wychodzi z | Instrukcja <math>\mathbf{exit}</math> wychodzi z nabli¿szej otaczaj±cej pêtli <math>\mathbf{loop}\,</math> | ||
i kontynuuje wykonanie programu od pierwszej instrukcji za | i kontynuuje wykonanie programu od pierwszej instrukcji za t± pêtl±. | ||
Instrukcja <math>\mathbf{continue}</math> powraca na pocz±tek instrukcji wewnêtrznej | |||
najbli¿szej otaczaj±cej pêtli <math>\mathbf{loop}\,</math>. | |||
Pozwa¿ zarówno semantykê naturaln± jak i semantykê ma³ych kroków. | |||
}} | }} | ||
{{rozwiazanie||roz3.1| | {{rozwiazanie|(semantyka naturalna)|roz3.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"><div class="mw-collapsible-content" style="display:none"> | ||
Dodamy do | Dodamy do regu³ semantyki naturalnej dla jêzyka Tiny | ||
kilka nowych | kilka nowych regu³ opisuj±cych now± konstrukcjê jêzyka | ||
i jej ,, | i jej ,,interakcjê\'' z pozosta³ymi konstrukcjami. | ||
Pomys³ polega na dodaniu specjalnych konfiguracji zawieraj±cych | |||
informacjê o tym, ¿e zosta³a wykonana instrukcja <math>\mathbf{exit}</math> | |||
lub <math>\mathbf{continue}</math>. Oto odpowiednie | lub <math>\mathbf{continue}</math>. Oto odpowiednie regu³y: | ||
<math> | <math> | ||
\mathbf{exit}, s \,\longrightarrow\, s, \mbox{ | \mathbf{exit}, s \,\longrightarrow\, s, \mbox{by³o-}\mathbf{exit} | ||
\quad \quad | \quad \quad | ||
\mathbf{continue}, s \,\longrightarrow\, s, \mbox{ | \mathbf{continue}, s \,\longrightarrow\, s, \mbox{by³o-}\mathbf{continue}. | ||
</math> | </math> | ||
Czyli instrukcje <math>\mathbf{exit}</math> i <math>\mathbf{continue}</math> nie | Czyli instrukcje <math>\mathbf{exit}</math> i <math>\mathbf{continue}</math> nie modyfikuj± | ||
stanu <math>s</math>, ale | stanu <math>s</math>, ale zostawiaj± po sobie ,,¶lad". | ||
Zauwa¿my, ¿e taki ¶lad zostaje pozostawiony tylko wtedy, jesli | |||
nie | nie by³o dotychczas innego ¶ladu, to znaczy je¶li <math>\mathbf{exit}</math> | ||
(lub <math>\mathbf{continue}</math>) | (lub <math>\mathbf{continue}</math>) zosta³o wykonane w zwyk³ym stanie <math>s</math>. | ||
Oczywi¶cie poszerzamy odpowiednio zbiór konfiguracji o: | |||
<math> | <math> | ||
\mathbf{State} \times \{ \mbox{ | \mathbf{State} \times \{ \mbox{by³o-}\mathbf{exit}, \mbox{by³o-}\mathbf{continue} \} | ||
</math> | </math> | ||
'''Pytanie''': jakie powinno | '''Pytanie''': jakie powinno byæ zachowanie <math>\mathbf{exit}</math> i | ||
<math>\mathbf{continue}</math> w konfiguracji <math>s, \mbox{ | <math>\mathbf{continue}</math> w konfiguracji <math>s, \mbox{by³o-}\mathbf{exit}</math> | ||
lub <math>s, \mbox{ | lub <math>s, \mbox{by³o-}\mathbf{continue}</math>? | ||
Czy instrukcje <math>\mathbf{exit}</math> i <math>\mathbf{continue}</math> | Czy instrukcje <math>\mathbf{exit}</math> i <math>\mathbf{continue}</math> | ||
bêd± faktycznie wykonywane w takich konfiguracjach? | |||
Zapiszmy teraz jak inne instrukcje | Zapiszmy teraz jak inne instrukcje korzystaj± z dodatkowej informacji | ||
( | (¶ladu) zawartej w konfiguracjach. | ||
Oczywi¶cie beneficjentem tej informacji jest instrukcji <math>\mathbf{loop}\,</math>: | |||
<math> | <math> | ||
\frac{I, s \,\longrightarrow\, s', \mbox{ | \frac{I, s \,\longrightarrow\, s', \mbox{by³o-}\mathbf{exit}} | ||
{\mathbf{loop}\, I, s \,\longrightarrow\, s'} | {\mathbf{loop}\, I, s \,\longrightarrow\, s'} | ||
\quad \quad | \quad \quad | ||
\frac{I, s \,\longrightarrow\, s', \mbox{ | \frac{I, s \,\longrightarrow\, s', \mbox{by³o-}\mathbf{continue} \quad \quad \mathbf{loop}\, I, s' \,\longrightarrow\, s''} | ||
{\mathbf{loop}\, I, s \,\longrightarrow\, s''} | {\mathbf{loop}\, I, s \,\longrightarrow\, s''} | ||
</math> | </math> | ||
Czyli w | Czyli w zale¿no¶ci od tego, jaki ¶lad zosta³ zarejestrowany | ||
podczas wykonania <math>I</math>, albo | podczas wykonania <math>I</math>, albo koñczymy wykonanie pêtli <math>\mathbf{loop}\,</math>, | ||
albo rozpoczynamy | albo rozpoczynamy kolejn± iteracjê. | ||
Zauwa¿my, ¿e stan <math>s'</math> mo¿e byæ ró¿ny od <math>s</math>, poniewa¿ | |||
zanim | zanim wykona³a siê ktora¶ z instrukcji <math>\mathbf{exit}</math> lub | ||
<math>\mathbf{continue}</math>, | <math>\mathbf{continue}</math>, mog³y zostaæ zmienione warto¶ci niektórych zmiennych. | ||
Oczywi¶cie, je¶li instrukcja wewnêtrzna <math>I</math> zakoñczy³a siê | |||
''normalnie'', kontynuujemy wykonanie | ''normalnie'', kontynuujemy wykonanie pêtli podobnie jak w przypadku | ||
wywo³ania <math>\mathbf{continue}</math>: | |||
<math> | <math> | ||
Linia 383: | Linia 382: | ||
</math> | </math> | ||
'''Pytanie:''' czy potrzebujemy dodatkowo | '''Pytanie:''' czy potrzebujemy dodatkowo regu³ postaci: | ||
<math> | <math> | ||
\frac{I, s \,\longrightarrow\, s' \quad \quad \mathbf{loop}\, I, s' \,\longrightarrow\, s'', \mbox{ | \frac{I, s \,\longrightarrow\, s' \quad \quad \mathbf{loop}\, I, s' \,\longrightarrow\, s'', \mbox{by³o-}\mathbf{exit}} | ||
{\mathbf{loop}\, I, s \,\longrightarrow\, s'', \mbox{ | {\mathbf{loop}\, I, s \,\longrightarrow\, s'', \mbox{by³o-}\mathbf{exit}} | ||
\quad \quad | \quad \quad | ||
\frac{I, s \,\longrightarrow\, s', \mbox{ | \frac{I, s \,\longrightarrow\, s', \mbox{by³o-}\mathbf{continue} \quad \quad \mathbf{loop}\, I, s' \,\longrightarrow\, s'', \mbox{by³o-}\mathbf{exit}} | ||
{\mathbf{loop}\, I, s \,\longrightarrow\, s'', \mbox{ | {\mathbf{loop}\, I, s \,\longrightarrow\, s'', \mbox{by³o-}\mathbf{exit}} | ||
</math> | </math> | ||
Okazuje | Okazuje siê ¿e nie, poniewa¿ ¶lad powinien zostaæ zawsze | ||
,,wymazany" przez | ,,wymazany" przez pêtlê <math>\mathbf{loop}\,</math>. | ||
<!-- | <!-- | ||
Poza tym | Poza tym regu³y te wykracza³yby poza klasyczna podej¶cie semantyki | ||
naturalnej, w którym zwykle | naturalnej, w którym zwykle bezpo¶rednio definiujemy | ||
tranzycje postaci <math>I, s \,\longrightarrow\, s'</math>. | tranzycje postaci <math>I, s \,\longrightarrow\, s'</math>. | ||
--> | --> | ||
Teraz musimy | Teraz musimy okre¶liæ zachowanie wszystkich instrukcji w sytuacji, | ||
gdy | gdy bie¿±ca konfiguracja zawiera ju¿ ¶lad. Zasadniczo, powinni¶my | ||
zaniechaæ wykonania instrukcji (w przypadku pêtli, powinni¶my | |||
zaniechaæ dalszego iterowania tej pêtli). | |||
Oto odpowiednie | Oto odpowiednie regu³y dla <math>\mbox{by³o-}\mathbf{exit}</math>: | ||
<math> | <math> | ||
\frac{I_1, s \,\longrightarrow\, s', \mbox{ | \frac{I_1, s \,\longrightarrow\, s', \mbox{by³o-}\mathbf{exit}} | ||
{I_1;\, I_2, s \,\longrightarrow\, s', \mbox{ | {I_1;\, I_2, s \,\longrightarrow\, s', \mbox{by³o-}\mathbf{exit}} | ||
\quad \quad | \quad \quad | ||
\frac{I_1, s \,\longrightarrow\, s' \quad \quad I_2, s' \,\longrightarrow\, s'', \mbox{ | \frac{I_1, s \,\longrightarrow\, s' \quad \quad I_2, s' \,\longrightarrow\, s'', \mbox{by³o-}\mathbf{exit}} | ||
{I_1;\, I_2, s \,\longrightarrow\, s'', \mbox{ | {I_1;\, I_2, s \,\longrightarrow\, s'', \mbox{by³o-}\mathbf{exit}} | ||
</math> | </math> | ||
<math> | <math> | ||
\frac{b, s \,\longrightarrow\, \mathbf{true} \quad \quad I_1, s \,\longrightarrow\, s', \mbox{ | \frac{b, s \,\longrightarrow\, \mathbf{true} \quad \quad I_1, s \,\longrightarrow\, s', \mbox{by³o-}\mathbf{exit}} | ||
{\mathbf{if}\, b \,\mathbf{then}\, I_1 \,\mathbf{else}\, I_2, s \,\longrightarrow\, s', \mbox{ | {\mathbf{if}\, b \,\mathbf{then}\, I_1 \,\mathbf{else}\, I_2, s \,\longrightarrow\, s', \mbox{by³o-}\mathbf{exit}} | ||
\quad \quad | \quad \quad | ||
\frac{b, s \,\longrightarrow\, \mathbf{false} \quad \quad I_2, s \,\longrightarrow\, s', \mbox{ | \frac{b, s \,\longrightarrow\, \mathbf{false} \quad \quad I_2, s \,\longrightarrow\, s', \mbox{by³o-}\mathbf{exit}} | ||
{\mathbf{if}\, b \,\mathbf{then}\, I_1 \,\mathbf{else}\, I_2, s \,\longrightarrow\, s', \mbox{ | {\mathbf{if}\, b \,\mathbf{then}\, I_1 \,\mathbf{else}\, I_2, s \,\longrightarrow\, s', \mbox{by³o-}\mathbf{exit}} | ||
</math> | </math> | ||
<math> | <math> | ||
\frac{b, s \,\longrightarrow\, \mathbf{true} \quad \quad I, s \,\longrightarrow\, s', \mbox{ | \frac{b, s \,\longrightarrow\, \mathbf{true} \quad \quad I, s \,\longrightarrow\, s', \mbox{by³o-}\mathbf{exit}} | ||
{\mathbf{while}\, b \,\mathbf{do}\, I, s \,\longrightarrow\, s', \mbox{ | {\mathbf{while}\, b \,\mathbf{do}\, I, s \,\longrightarrow\, s', \mbox{by³o-}\mathbf{exit}} | ||
\quad \quad | \quad \quad | ||
\frac{b, s \,\longrightarrow\, \mathbf{true} \quad \quad I, s \,\longrightarrow\, s' \quad \quad | \frac{b, s \,\longrightarrow\, \mathbf{true} \quad \quad I, s \,\longrightarrow\, s' \quad \quad | ||
\mathbf{while}\, b \,\mathbf{do}\, I, s' \,\longrightarrow\, s'', \mbox{ | \mathbf{while}\, b \,\mathbf{do}\, I, s' \,\longrightarrow\, s'', \mbox{by³o-}\mathbf{exit}} | ||
{\mathbf{while}\, b \,\mathbf{do}\, I, s \,\longrightarrow\, s', \mbox{ | {\mathbf{while}\, b \,\mathbf{do}\, I, s \,\longrightarrow\, s', \mbox{by³o-}\mathbf{exit}} | ||
</math> | </math> | ||
Pominêli¶my zupe³nie analogiczne regu³y dla <math>\mbox{by³o-}\mathbf{continue}</math>. | |||
Zauwa¿my, ¿e dla pêtli <math>\mathbf{while}\,</math> nie rozpatrujemy przypadku, | |||
gdy dozór <math>b</math> oblicza | gdy dozór <math>b</math> oblicza siê do <math>\mathbf{false}</math>, gdy¿ w tym przypadku | ||
nie ma | nie ma mo¿liwo¶ci wygenerowania ¶ladu. | ||
Zauwa¿my, ¿e nasze regu³y nie pozwalaj± na dodanie drugiego (kolejnego) ¶ladu! | |||
Linia 444: | Linia 443: | ||
{{rozwiazanie||roz3.2| | {{rozwiazanie|(ma³e kroki)|roz3.2| | ||
<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"> | ||
W semantyce naturalnej | W semantyce naturalnej musieli¶my napisaæ wiele regu³ aby | ||
zapewniæ pomijanie instrukcji w sytuacji, gdy zosta³ juz | |||
zarejestrowany | zarejestrowany jaki¶ ¶lad. By³o to do¶æ uci±¿liwe. | ||
Okazuje | Okazuje siê, ¿e podej¶cie ma³o-krokowe oferuje mo¿liwo¶æ | ||
bardziej eleganckiego | bardziej eleganckiego rozwi±zania. | ||
Punktem startowym | Punktem startowym sê teraz regu³y ma³o-krokowe dla jêzyka Tiny. | ||
Podobnie jak poprzednio rozszerzymy zbiór konfiguracji i podobnie | Podobnie jak poprzednio rozszerzymy zbiór konfiguracji i podobnie | ||
opiszemy, jak powstaje | opiszemy, jak powstaje ¶lad: | ||
<math> | <math> | ||
\mathbf{exit}, s \,\Longrightarrow\, s, \mbox{ | \mathbf{exit}, s \,\Longrightarrow\, s, \mbox{by³o-}\mathbf{exit} | ||
\quad \quad | \quad \quad | ||
\mathbf{continue}, s \,\Longrightarrow\, s, \mbox{ | \mathbf{continue}, s \,\Longrightarrow\, s, \mbox{by³o-}\mathbf{continue}. | ||
</math> | </math> | ||
Ponadto musimy | Ponadto musimy okre¶liæ sposób, w jaki ma³y krok | ||
mniejszej instrukcji zostaje zamieniony na | mniejszej instrukcji zostaje zamieniony na ma³y krok | ||
wiêkszej. Np. | |||
<math> | <math> | ||
\frac{I_1, s \,\Longrightarrow\, s', \mbox{ | \frac{I_1, s \,\Longrightarrow\, s', \mbox{by³o-}\mathbf{exit}} | ||
{I_1;\, I_2, s \,\Longrightarrow\, s', \mbox{ | {I_1;\, I_2, s \,\Longrightarrow\, s', \mbox{by³o-}\mathbf{exit}} | ||
\quad \quad | \quad \quad | ||
\mbox{ i analogicznie dla } \mbox{ | \mbox{ i analogicznie dla } \mbox{by³o-}\mathbf{continue}. | ||
</math> | </math> | ||
Nie musimy zajmowac | Nie musimy zajmowac siê przypadkiem, gdy ¶lad | ||
powstaje w <math>I_2</math>, bo | powstaje w <math>I_2</math>, bo wybrali¶my podej¶cie ma³o-krokowe. | ||
Ponadto, nie musimy | Ponadto, nie musimy opisywaæ instrukcji warunkowej i pêtli <math>\mathbf{while}\,</math>, | ||
poniewa¿ ¶lad nie mo¿e powstaæ podczas obliczania dozoru! | |||
Wreszcie zobaczmy jak zachowuje | Wreszcie zobaczmy jak zachowuje siê pêtla <math>\mathbf{loop}\,</math>: | ||
<math> | <math> | ||
\frac{I, s \,\Longrightarrow\, s', \mbox{ | \frac{I, s \,\Longrightarrow\, s', \mbox{by³o-}\mathbf{exit}} | ||
{\mathbf{loop}\, I, s \,\Longrightarrow\, s'} | {\mathbf{loop}\, I, s \,\Longrightarrow\, s'} | ||
\quad \quad | \quad \quad | ||
\frac{I, s \,\Longrightarrow\, s', \mbox{ | \frac{I, s \,\Longrightarrow\, s', \mbox{by³o-}\mathbf{continue}} | ||
{\mathbf{loop}\, I, s \,\Longrightarrow\, \mathbf{loop}\, I, s'} | {\mathbf{loop}\, I, s \,\Longrightarrow\, \mathbf{loop}\, I, s'} | ||
</math> | </math> | ||
Regu³y te s± prawie identyczne do regu³ semantyki naturalnej dla tej | |||
sytuacji! | sytuacji! | ||
Natomiast korzystamy z tego, | Natomiast korzystamy z tego, ¿e w podej¶ciu ma³o-krokowym zmiana konfiguracji | ||
na <math>s', \mbox{ | na <math>s', \mbox{by³o-}\mathbf{exit}</math> czy <math>s', \mbox{by³o-}\mathbf{continue}</math> jest | ||
''natychmiast'' widoczna w instrukcji <math>\mathbf{loop}\, I</math>, nawet | ''natychmiast'' widoczna w instrukcji <math>\mathbf{loop}\, I</math>, nawet je¶li | ||
<math>\mathbf{exit}</math> czy <math>\mathbf{continue}</math> | <math>\mathbf{exit}</math> czy <math>\mathbf{continue}</math> zosta³o wywo³ane g³êboko wewn±trz | ||
<math>I</math>! | <math>I</math>! | ||
Niestety | Niestety powy¿sze regu³y '''nie s± poprawne'''! | ||
Dlaczego? Jak zwykle w semantyce | Dlaczego? Jak zwykle w semantyce ma³ych kroków, wykonuj±c instrukcjê | ||
wewnêtrzn± ''zapominamy'' stopniowo jaka by³a ona na pocz±tku. | |||
I w | I w zwi±zku z tym nie potrafimy poprawnie powróciæ do wykonywania | ||
pêtli <math>\mathbf{loop}\,</math> po wywo³aniu <math>\mathbf{continue}</math>. | |||
Prostym sposobem poprawienia naszego | Prostym sposobem poprawienia naszego blêdu jest rozszerzenie sk³adni | ||
tak, aby | tak, aby mo¿liwe by³o jednorazowe rozwiniêcie pêtli <math>\mathbf{loop}\,</math>: | ||
<math> | <math> | ||
Linia 512: | Linia 511: | ||
</math> | </math> | ||
Teraz | Teraz mo¿emy zapisaæ dwie powy¿sze regu³y dla <math>\mathbf{loop}\,</math> w poprawnej | ||
wersji, | wersji, pamiêtaj±c o tym, ¿e <math>\mbox{by³o-}\mathbf{exit}</math> i | ||
<math>\mbox{ | <math>\mbox{by³o-}\mathbf{continue}</math> pojawi± siê nie w instrukcji wewnêtrznej, | ||
ale w jej ''kopii'' umieszczonej przed <math>\,\mathbf{then}\,</math>: | ale w jej ''kopii'' umieszczonej przed <math>\,\mathbf{then}\,</math>: | ||
<math> | <math> | ||
\frac{I', s \,\Longrightarrow\, s', \mbox{ | \frac{I', s \,\Longrightarrow\, s', \mbox{by³o-}\mathbf{exit}} | ||
{I' \,\mathbf{then}\, \mathbf{loop}\, I, s \,\Longrightarrow\, s'} | {I' \,\mathbf{then}\, \mathbf{loop}\, I, s \,\Longrightarrow\, s'} | ||
\quad \quad | \quad \quad | ||
\frac{I', s \,\Longrightarrow\, s', \mbox{ | \frac{I', s \,\Longrightarrow\, s', \mbox{by³o-}\mathbf{continue}} | ||
{I; \,\mathbf{then}\, \mathbf{loop}\, I, s \,\Longrightarrow\, \mathbf{loop}\, I, s'} | {I; \,\mathbf{then}\, \mathbf{loop}\, I, s \,\Longrightarrow\, \mathbf{loop}\, I, s'} | ||
\quad \quad | \quad \quad | ||
Linia 528: | Linia 527: | ||
</math> | </math> | ||
Potrzebujemy | Potrzebujemy te¿ dodatkowej regu³y dla obliczeñ wewn±trz instrukcji | ||
stoj±cej przed <math>\,\mathbf{then}\,</math> (w szczególno¶ci mo¿e ona zawieraæ | |||
zagnie¿dzone pêtle <math>\mathbf{loop}\,</math> : | |||
<math> | <math> | ||
Linia 537: | Linia 536: | ||
</math> | </math> | ||
Na koniec | Na koniec zauwa¿my, ¿e stan <math>s'</math> w | ||
pierwszych dwóch z | pierwszych dwóch z powy¿szych regu³ nigdy nie jest ró¿ny | ||
od <math>s</math>. Zatem | od <math>s</math>. Zatem równowa¿nie mogliby¶my zamieniæ <math>s'</math> na <math>s</math> | ||
w | w powy¿szych dwóch regu³ach. Ale wtedy okazuje siê , <math>s</math> | ||
w parze z <math>\mbox{ | w parze z <math>\mbox{by³o-}\mathbf{exit}</math> albo <math>\mbox{by³o-}\mathbf{continue}</math> jest nadmiarowe | ||
i | i mo¿e zostaæ wyeliminowane. | ||
Zatem ostatecznie nasze | Zatem ostatecznie nasze regu³y mog± wygl±daæ tak: | ||
<math> | <math> | ||
\mathbf{exit}, s \,\Longrightarrow\, \mbox{ | \mathbf{exit}, s \,\Longrightarrow\, \mbox{by³o-}\mathbf{exit} | ||
\quad \quad | \quad \quad | ||
\mathbf{continue}, s \,\Longrightarrow\, \mbox{ | \mathbf{continue}, s \,\Longrightarrow\, \mbox{by³o-}\mathbf{continue} | ||
</math> | </math> | ||
<math> | <math> | ||
\frac{I_1, s \,\Longrightarrow\, \mbox{ | \frac{I_1, s \,\Longrightarrow\, \mbox{by³o-}\mathbf{exit}} | ||
{I_1;\, I_2, s \,\Longrightarrow\, \mbox{ | {I_1;\, I_2, s \,\Longrightarrow\, \mbox{by³o-}\mathbf{exit}} | ||
\quad \quad | \quad \quad | ||
\frac{I_1, s \,\Longrightarrow\, \mbox{ | \frac{I_1, s \,\Longrightarrow\, \mbox{by³o-}\mathbf{continue}} | ||
{I_1;\, I_2, s \,\Longrightarrow\, \mbox{ | {I_1;\, I_2, s \,\Longrightarrow\, \mbox{by³o-}\mathbf{continue}} | ||
</math> | </math> | ||
Linia 565: | Linia 564: | ||
<math> | <math> | ||
\frac{I', s \,\Longrightarrow\, \mbox{ | \frac{I', s \,\Longrightarrow\, \mbox{by³o-}\mathbf{exit}} | ||
{I' \,\mathbf{then}\, \mathbf{loop}\, I, s \,\Longrightarrow\, s} | {I' \,\mathbf{then}\, \mathbf{loop}\, I, s \,\Longrightarrow\, s} | ||
\quad \quad | \quad \quad | ||
\frac{I', s \,\Longrightarrow\, \mbox{ | \frac{I', s \,\Longrightarrow\, \mbox{by³o-}\mathbf{continue}} | ||
{I; \,\mathbf{then}\, \mathbf{loop}\, I, s \,\Longrightarrow\, \mathbf{loop}\, I, s} | {I; \,\mathbf{then}\, \mathbf{loop}\, I, s \,\Longrightarrow\, \mathbf{loop}\, I, s} | ||
\quad \quad | \quad \quad | ||
Linia 581: | Linia 580: | ||
a zbiór konfiguracji poszerzamy tylko o dwie nowe konfiguracje | a zbiór konfiguracji poszerzamy tylko o dwie nowe konfiguracje | ||
<math>\{ \mbox{ | <math>\{ \mbox{by³o-}\mathbf{exit}, \mbox{by³o-}\mathbf{continue} \}</math>. | ||
</div></div> | </div></div> | ||
Linia 590: | Linia 589: | ||
{{cwiczenie|1|cw1.dom| | |||
Zaproponuj | Zaproponuj semantykê ma³o-krokow± dla rozszerzeñ jêzyka Tiny, które | ||
studiowali¶my powy¿ej. | |||
}} | |||
{{cwiczenie|2|cw2.dom| | |||
Napisz | Napisz semantyjê naturaln± dla nieznacznie rozszerzonej wersji instrukcji <math>\mathbf{loop}\,</math>: | ||
<math> | <math> | ||
Linia 607: | Linia 607: | ||
</math> | </math> | ||
Identyfikator <math>x</math> | Identyfikator <math>x</math> pe³ni tutaj rolê etykiety zwi±zanej z | ||
instrukcj± <math>\mathbf{loop}\,</math>, jest te¿ parametrem dwóch pozosta³ych | |||
instrukcji. <math>\mathbf{exit} x</math> | instrukcji. <math>\mathbf{exit} x</math> koñczy teraz najbli¿sz± otaczaj±c± pêtlê <math>\mathbf{loop}\,</math> | ||
o etykiecie <math>x</math>. Podobnie <math>\mathbf{continue} x</math> wznawia | o etykiecie <math>x</math>. Podobnie <math>\mathbf{continue} x</math> wznawia najbli¿sz± | ||
otaczaj±c± pêtlê o etykiecie <math>x</math>. | |||
{{przyklad||| | |||
Program | |||
x: <math>\mathbf{loop}\,</math> | x: <math>\mathbf{loop}\,</math> | ||
Linia 624: | Linia 625: | ||
a := a+2; | a := a+2; | ||
}} | |||
koñczy dzia³anie z warto¶ci± zmiennej <math>a = 3</math>. | |||
Za | Za pomoc± wciêæ okre¶lili¶my, do wnêtrza której pêtli | ||
<math>\mathbf{loop}\,</math> | <math>\mathbf{loop}\,</math> nale¿y ka¿da z trzech ostatnich instrukcji przypisania. | ||
Niejednoznaczno¶æ bierze siê oczywi¶cie st±d, ¿e | |||
pracujemy ze | pracujemy ze sk³adni± abstrakcyjn±. Sk³adnia konkretna zawiera³aby | ||
prawdopodobnie | prawdopodobnie jak±¶ konstukcjê ''zamykaj±c±'' pêtlê <math>\mathbf{loop}\,</math>, | ||
np. <math>\mathbf{loop}\, I \,\mathbf{end}\mathbf{loop}\,</math>. | np. <math>\mathbf{loop}\, I \,\mathbf{end}\mathbf{loop}\,</math>. | ||
}} | |||
{{cwiczenie|3|cw3.dom| | |||
Napisz | Napisz semantykê naturaln± i ma³o-krokow± dla rozszerzenia | ||
jêzyka Tiny o wyra¿enia z efektami ubocznymi: | |||
<math> | <math> | ||
Linia 647: | Linia 650: | ||
</math> | </math> | ||
Obliczenie | Obliczenie wyra¿enia <math>\,\mathbf{do}\, I \,\mathbf{then}\, e</math> polega na wykonaniu <math>I</math> | ||
a potem na obliczeniu <math>e</math>. | a potem na obliczeniu <math>e</math>. Warto¶æ wyra¿enia <math>x:= e</math> jest taka | ||
jak | jak warto¶æ wyra¿enia <math>e</math> a efektem ubocznym jest | ||
podstawienie tej | podstawienie tej warto¶ci na zmienn± <math>x</math>. | ||
}} |
Wersja z 07:59, 9 sie 2006
Zawarto¶æ
Koñczymy semantykê ma³ych kroków i rozpoczynamy semantykê naturaln± (du¿e kroki). Uzupe³nimy semantykê naturaln± jêzyka Tiny o semantykê naturaln± wyra¿eñ boolowskich i arytmetycznych oraz semantykê b³êdów wykonania. Wreszcie dodamy now± instrukcjê pêtli pozwalaj±c± na niestrukturalne przerwanie lub wznowienie iteracji (instrukcje i ).
Rozszerzenia semantyki jêzyka Tiny
Ćwiczenie 1
Zdefiniuj znaczenie wyra¿eñ boolowskich i arytmetycznych w jêzyku Tiny, w stylu du¿ych kroków (semantyka naturalna).
Rozwiązanie
Ćwiczenie 2
Rozwa¿ dodatkowo operacjê dzielenia:
i rozszerz semantykê z poprzedniego zadania. Dzielenie przez zero jest b³±dem i koñczy natychmiast wykonanie programu. Oprócz stanu wynikiem programu powinna byc informacja o b³êdzie, je¶li b³±d wyst±pi³.
Rozwiązanie
Ćwiczenie 3
Rozszerzmy jêzyk Tiny o nastêpuj±c± instrukcjê pêtli:
to instrukcja pêtli, stanowi instrukcjê wewnêtrzn±. Instrukcja wychodzi z nabli¿szej otaczaj±cej pêtli i kontynuuje wykonanie programu od pierwszej instrukcji za t± pêtl±. Instrukcja powraca na pocz±tek instrukcji wewnêtrznej najbli¿szej otaczaj±cej pêtli .
Pozwa¿ zarówno semantykê naturaln± jak i semantykê ma³ych kroków.
Rozwiązanie (semantyka naturalna)
Rozwiązanie (ma³e kroki)
Zadania domowe
Ćwiczenie 1
Zaproponuj semantykê ma³o-krokow± dla rozszerzeñ jêzyka Tiny, które studiowali¶my powy¿ej.
Ćwiczenie 2
Napisz semantyjê naturaln± dla nieznacznie rozszerzonej wersji instrukcji :
Identyfikator pe³ni tutaj rolê etykiety zwi±zanej z instrukcj± , jest te¿ parametrem dwóch pozosta³ych instrukcji. koñczy teraz najbli¿sz± otaczaj±c± pêtlê o etykiecie . Podobnie wznawia najbli¿sz± otaczaj±c± pêtlê o etykiecie .
Przykład
koñczy dzia³anie z warto¶ci± zmiennej . Za pomoc± wciêæ okre¶lili¶my, do wnêtrza której pêtli nale¿y ka¿da z trzech ostatnich instrukcji przypisania. Niejednoznaczno¶æ bierze siê oczywi¶cie st±d, ¿e pracujemy ze sk³adni± abstrakcyjn±. Sk³adnia konkretna zawiera³aby prawdopodobnie jak±¶ konstukcjê zamykaj±c± pêtlê , np. .
Ćwiczenie 3
Napisz semantykê naturaln± i ma³o-krokow± dla rozszerzenia jêzyka Tiny o wyra¿enia z efektami ubocznymi:
Obliczenie wyra¿enia polega na wykonaniu a potem na obliczeniu . Warto¶æ wyra¿enia jest taka jak warto¶æ wyra¿enia a efektem ubocznym jest podstawienie tej warto¶ci na zmienn± .