Semantyka i weryfikacja programów/Ćwiczenia 6: Różnice pomiędzy wersjami
Nie podano opisu zmian |
Nie podano opisu zmian |
||
Linia 1: | Linia 1: | ||
== | == Zawarto¶æ == | ||
Ostatnie | Ostatnie zajêcia po¶wiêcone semantyce naturalnej. | ||
Rozszerzymy | Rozszerzymy jêzyk Tiny o deklaracje zmiennych i procedur z jednym | ||
parametrem. | parametrem. | ||
Rozwa¿ymy statyczn± i dynamiczn± widoczno¶æ (wi±zanie) | |||
identyfikatorów oraz | identyfikatorów oraz ró¿ne mechanizmy przekazywania | ||
parametrów. | parametrów. | ||
Pracujemy ze | Pracujemy ze ¶rodowiskami i stanami. | ||
== | == Semantyka naturalna procedur == | ||
{{cwiczenie|1 (procedury)|cw1| | {{cwiczenie|1 (procedury)|cw1| | ||
Rozszerzmy | Rozszerzmy jêzyk Tiny o deklaracje i wywo³ania procedur: | ||
<math> | <math> | ||
Linia 33: | Linia 33: | ||
</math> | </math> | ||
Konstrukcja <math>\mathbf{proc}\, x_1(x_2)</math> | Konstrukcja <math>\mathbf{proc}\, x_1(x_2)</math> deklaruje procedurê o nazwie | ||
<math>x_1</math>, której parametrem formalnym jest <math>x_2</math>. | <math>x_1</math>, której parametrem formalnym jest <math>x_2</math>. | ||
Zak³adamy statyczne wi±zanie identyfikatorów i przekazywanie | |||
parametrów przez | parametrów przez zmienn± (to znaczy, ¿e w momencie wywo³ania | ||
procedury, powinna | procedury, powinna zostaæ | ||
przekazana lokacja | przekazana lokacja odpowiadaj±ca parametrowi aktualnemu). | ||
Instrukcja <math>\mathbf{call}\, x_1(x_2)</math> | Instrukcja <math>\mathbf{call}\, x_1(x_2)</math> wywo³uje procedurê <math>x_1</math> | ||
z parametrem aktualnym <math>x_2</math>. | z parametrem aktualnym <math>x_2</math>. | ||
}} | }} | ||
Linia 48: | Linia 48: | ||
<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"> | ||
U¿yjemu ¶rodowisk <math>E \in \mathbf{Env}</math> i stanów <math>s \in \mathbf{Store}</math>: | |||
<math> | <math> | ||
Linia 58: | Linia 58: | ||
Nowym elementem jest zbiór <math>\mathbf{Proc}</math>, potrzebny nam do | Nowym elementem jest zbiór <math>\mathbf{Proc}</math>, potrzebny nam do | ||
przechowywania informacji o procedurach. | przechowywania informacji o procedurach. | ||
Informacja nt procedury, | Informacja nt procedury, któr± musimy przechowywaæ, to: | ||
* nazwa parametru formalnego, | * nazwa parametru formalnego, | ||
* | * cia³o procedury (instrukcja <math>I \in \mathbf{Stmt}</math>) oraz | ||
* '' | * ''¶rodowisko'', w którym procedura zosta³a zadeklarowana. | ||
Zauwa¿my, ¿e nie musimy (i nie powinni¶my) pamiêtaæ stanu | |||
z momentu deklaracji, czyli konkretnych | z momentu deklaracji, czyli konkretnych warto¶ci zmiennych | ||
wówczas zadeklarowanych. | wówczas zadeklarowanych. Pamiêtamy tylko ¶rodowisko, | ||
które wyznacza nam '' | które wyznacza nam ''wi±zanie'' identyfikatorów (nazw | ||
zmiennych i procedur) | zmiennych i procedur) wystêpuj±cych w ciele procedury z | ||
lokacjami (lub opisami procedur z <math>\mathbf{Proc}</math>), a | lokacjami (lub opisami procedur z <math>\mathbf{Proc}</math>), a wiêc z konkretnymi | ||
zmiennymi (lub procedurami). | zmiennymi (lub procedurami). | ||
Widaæ tutaj jasno, jak elegancki i wygodny jest podzia³ na ¶rodowisko | |||
i stan. | i stan. | ||
Linia 77: | Linia 77: | ||
Czyli znów zbiór <math>\mathbf{Env}</math> zadany jest przez równanie. | Czyli znów zbiór <math>\mathbf{Env}</math> zadany jest przez równanie. | ||
Nasze tranzycje | Nasze tranzycje bêd± nastêpuj±cych postaci: | ||
<math> | <math> | ||
Linia 91: | Linia 91: | ||
</math> | </math> | ||
Na | Na uwagê zas³uguje ostatnia postaæ tranzycji: deklaracja, | ||
w | w odró¿nieniu od instrukcji, mo¿e zmieniaæ ¶rodowisko. | ||
Umówmy | Umówmy siê, ¿e ¶rodowisko <math>E'</math> bêdzie rozszerza³o <math>E</math> o informacjê | ||
o nowych identyfikatorach, tzn. tych zadeklarowanych w <math>d</math>. | o nowych identyfikatorach, tzn. tych zadeklarowanych w <math>d</math>. | ||
Zajmijmy | Zajmijmy siê najpierw deklaracjami zmiennych: | ||
<math> | <math> | ||
Linia 114: | Linia 114: | ||
</math> | </math> | ||
Zauwa¿my, ¿e deklaracja procedury nie zmienia stanu, tylko ¶rodowisko, | |||
w | w odró¿nieniu od deklaracji zmiennej. | ||
W | W ¶rodowisku pamiêtamy trójkê <math>\langle x_2, I, E \rangle</math> zawieraj±c± | ||
nazwê parametru formalnego, cia³o procedury oraz ''¶rodowisko | |||
deklaracji procedury''. | deklaracji procedury''. | ||
To ostatnie determinuje statyczne | To ostatnie determinuje statyczne wi±zanie identyfikatorów: | ||
wi±zanie identyfikatorów wystêpuj±cuch w ciele procedury jest | |||
jakby ,, | jakby ,,zamro¿one'' (ustalone) w momencie deklaracji procedury. | ||
Aby | Aby dokoñczyæ semantykê deklaracji potrzebujemy jeszcze jednej regu³y: | ||
<math> | <math> | ||
Linia 131: | Linia 131: | ||
</math> | </math> | ||
która opisuje | która opisuje sekwencyjn± ,,kumulacjê" modyfikacji dokonanych w deklaracjach. | ||
'''Pytanie:''' czy | '''Pytanie:''' czy kolejno¶æ poszczególnych deklaracji ma znaczenie? | ||
Teraz | Teraz okre¶limy semantykê bloku: | ||
<math> | <math> | ||
Linia 144: | Linia 144: | ||
</math> | </math> | ||
Czyli instrukcja | Czyli instrukcja wewnêtrzna wykonywana jest w ¶rodowisku (i stanie) | ||
''wytworzonym'' (rozszerzonym) przez | ''wytworzonym'' (rozszerzonym) przez deklaracjê <math>d</math>. | ||
Stan | Stan koñcowy po wykonaniu bloku to po prostu stan koñcowy <math>s''</math> | ||
po wykonaniu instrukcji | po wykonaniu instrukcji wewnêtrznej. | ||
Mo¿e siê to wydawaæ niepokoj±ce, gdy¿ oznacza, ¿e nowe lokacje, | |||
powo³ane podczas deklaracji <math>d</math>, zachowuj± przechowywan± warto¶æ | |||
równie¿ po wyj¶ciu z bloku. Na szczê¶cie wykonanie | |||
bloku nie ma | bloku nie ma wp³ywu na ¶rodowisko, a to ono decyduje, które | ||
identyfikatory | identyfikatory s± widoczne (zadeklarowane) i ogólniej, które lokacje | ||
s± przypisane identyfikatorom. A wiêc deklaracja <math>d</math> | |||
nie ma | nie ma wp³ywu na ¶rodowisko, w którym zostan± wykonane kolejne | ||
instrukcje. | instrukcje. | ||
Widaæ to jasno w regule dla z³o¿enia sekwencyjnego: | |||
<math> | <math> | ||
Linia 166: | Linia 166: | ||
Pozosta³o nam jeszcze okre¶lenie semantyki wywo³ania procedury: | |||
<math> | <math> | ||
Linia 176: | Linia 176: | ||
</math> | </math> | ||
Czyli uruchamiane jest | Czyli uruchamiane jest cia³o <math>I</math> procedury, | ||
w | w ¶rodowisku <math>E'</math> z miejsca deklaracji tej procedury | ||
zmodyfikowanym o przypisanie <math>x \mapsto l</math> | zmodyfikowanym o przypisanie <math>x \mapsto l</math> | ||
lokacji <math>l</math> do parametru formalnego <math>x</math> procedury. | lokacji <math>l</math> do parametru formalnego <math>x</math> procedury. | ||
Stan, w którym uruchomione jest <math>I</math> to po prostu | Stan, w którym uruchomione jest <math>I</math> to po prostu | ||
stan | stan bie¿±cy z miejsca wo³ania procedury; o prawid³owe | ||
wi±zanie identyfikatorów ,,troszczy" siê wy³±cznie | |||
¶rodowisko <math>E'</math>. | |||
'''Pytanie:''' czy | '''Pytanie:''' czy powy¿sza regu³a dopuszcza rekurencyjne wywo³ania procedury? | ||
Okazuje | Okazuje siê, ¿e niestety nie, gdy¿ w ¶rodowisku | ||
<math>E'[x \mapsto l]</math> nie ma informacji o procedurze <math>x_1</math>, | <math>E'[x \mapsto l]</math> nie ma informacji o procedurze <math>x_1</math>, któr± | ||
w³a¶nie wo³amy. Mo¿e siê zdarzyæ, ¿e <math>E'[x \mapsto l] \in \mathbf{Proc}</math>, ale | |||
oznacza to tylko, | oznacza to tylko, ¿e w miejscu deklaracji procedury <math>x_1</math> | ||
by³a ju¿ wcze¶niej (statycznie) zadeklarowana inna procedura | |||
o tej samej nazwie. | o tej samej nazwie. | ||
Aby | Aby umo¿liwiæ rekurencjê, powinni¶my zadbaæ sami o to, aby | ||
¶rodowisko, w którym wykonujemy <math>I</math> zawiera³o informacjê | |||
o naszej procedurze: | o naszej procedurze: | ||
Linia 205: | Linia 205: | ||
</math> | </math> | ||
Zauwa¿my, ¿e przypisanie <math>x_1 \mapsto \langle x, I, E' \rangle</math> | |||
dodane do <math>E'</math> wystarcza na tylko jedno | dodane do <math>E'</math> wystarcza na tylko jedno wywo³anie rekurencyjne | ||
( | (licz±c w g³±b). Ale ka¿de kolejne wywo³anie dodaje tê informacjê, | ||
czyli | czyli ka¿de wywo³anie procedury przygotowuje ¶rodowisko dla | ||
nastêpnego. | |||
I to jest | I to jest wystarczaj±ce. | ||
'''Pytanie:''' czy | '''Pytanie:''' czy mo¿liwa jest rekurencja wzajemna? | ||
Pozostaje jeszcze jedna kwestia: dodajemy do | Pozostaje jeszcze jedna kwestia: dodajemy do ¶rodowiska <math>E'</math> | ||
dwa przypisania: | dwa przypisania: | ||
<math>x \mapsto l</math> oraz <math>x_1 \mapsto \langle x, I, E' \rangle</math>, | <math>x \mapsto l</math> oraz <math>x_1 \mapsto \langle x, I, E' \rangle</math>, | ||
ale dlaczego w takiej | ale dlaczego w takiej kolejno¶ci. | ||
'''Pytanie:''' co | '''Pytanie:''' co siê stanie, gdy zamienimy tê kolejno¶æ: | ||
<math> | <math> | ||
Linia 229: | Linia 229: | ||
</math> | </math> | ||
Czy obydwie semantyki | Czy obydwie semantyki s± sobie równowa¿ne? | ||
Okazuje | Okazuje siê, ¿e tak nie jest, oto dwa kontrprzyk³ady: | ||
Linia 252: | Linia 252: | ||
Ka¿dy z tych programów uruchomi siê poprawnie w dok³adnie | |||
jednym z wariantów semantyki. | jednym z wariantów semantyki. | ||
'''Pytanie:''' Który w którym? | '''Pytanie:''' Który w którym? | ||
Semantyka | Semantyka pozosta³ych instrukcji i wyra¿eñ jêzyka Tiny pozostaje bez zmian. | ||
Rozwa¿my na koniec problem dealokacji. | |||
Linia 266: | Linia 266: | ||
<br> | <br> | ||
Chcemy, aby ,, | Chcemy, aby ,,posprz±tano" po zakoñczeniu wykonania bloku, | ||
tzn. aby zwolniono te lokacje, które | tzn. aby zwolniono te lokacje, które by³y u¿ywane tylko w tym bloku | ||
i w | i w zwi±zku z tym nie bêd± ju¿ potrzebne. | ||
Oznacza to, | Oznacza to, ¿e powinni¶my przywróciæ nieokre¶lono¶æ stanu dla | ||
wszystkich tych lokacji, które | wszystkich tych lokacji, które by³y u¿yte podczas deklaracji <math>d</math>. | ||
Jest wiele | Jest wiele mo¿liwo¶ci wyra¿enia tego dodatkowego warunku, | ||
np. | np. mo¿emy dodaæ do powy¿szej regu³y | ||
<math> | <math> | ||
Linia 283: | Linia 283: | ||
dodatkowy warunek postaci <math>\mbox{ gdzie } \bar{s} = \ldots</math>. | dodatkowy warunek postaci <math>\mbox{ gdzie } \bar{s} = \ldots</math>. | ||
Proponujemy tu | Proponujemy tu rozwi±zanie ciut bardziej eleganckie. | ||
Zacznijmy od tranzycji | Zacznijmy od tranzycji dokonuj±cych dealokacji, | ||
które | które mog± byæ np. postaci: <math>s'', L \,\longrightarrow\, \bar{s}</math>. | ||
Zak³adamy tutaj, ¿e znamy | |||
zbiór nowo zaalokowanych lokacji <math>L \subseteq \mathbf{Loc}</math>. | zbiór nowo zaalokowanych lokacji <math>L \subseteq \mathbf{Loc}</math>. | ||
Linia 294: | Linia 294: | ||
\frac{s \setminus \{ (l, s(l)) \} , L \setminus \{ l \} \,\longrightarrow\, s'} | \frac{s \setminus \{ (l, s(l)) \} , L \setminus \{ l \} \,\longrightarrow\, s'} | ||
{s, L \,\longrightarrow\, s'} | {s, L \,\longrightarrow\, s'} | ||
\quad \mbox{ o ile } l \in L \mbox{ i } s(l) \mbox{ jest | \quad \mbox{ o ile } l \in L \mbox{ i } s(l) \mbox{ jest okre¶lone} | ||
</math> | </math> | ||
Teraz albo napiszemy w dodatkowym warunku, | Teraz albo napiszemy w dodatkowym warunku, ¿e | ||
<math>L = \mathrm{dom}(s'') \setminus \mathrm{dom}(s)</math>: | <math>L = \mathrm{dom}(s'') \setminus \mathrm{dom}(s)</math>: | ||
Linia 309: | Linia 309: | ||
</math> | </math> | ||
albo | albo mo¿emy poprosiæ o pomoc w posprz±taniu tego, kto ,,naba³agani³", czyli | ||
deklaracjê <math>d</math>. | |||
Niech deklaracja zwraca, oprócz pary <math>(E', s')</math>, | Niech deklaracja zwraca, oprócz pary <math>(E', s')</math>, | ||
dodatkowo zbiór <math>L</math>. | dodatkowo zbiór <math>L</math>. | ||
Oto poprawione | Oto poprawione regu³y dla deklaracji: | ||
Linia 337: | Linia 337: | ||
</math> | </math> | ||
Wtedy ostatecznie | Wtedy ostatecznie regu³a dla bloku wygl±da nastêpuj±co: | ||
<math> | <math> | ||
Linia 350: | Linia 350: | ||
}} | }} | ||
{{cwiczenie|2 ( | {{cwiczenie|2 (wi±zanie dynamiczne)|cw2| | ||
Zastanówmy | Zastanówmy siê, jakich modyfikacji wymaga nasza semantyka, | ||
aby | aby wi±zanie identyfikatorów by³o dynamiczne, zamiast statycznego. | ||
Rozumiemy przez to, | Rozumiemy przez to, ¿e w przypadku odwo³ania do zmiennej | ||
wewn±trz procedury, odwo³ujemy siê do ¶rodowiska w miejscu | |||
wywo³ania tej procedury, zamiast do ¶rodowiska z miejsca | |||
deklaracji jak dotychczas. | deklaracji jak dotychczas. | ||
Tak samo powinno | Tak samo powinno byæ w przypadku wywo³ania innej procedury | ||
wewn±trz procedury, czyli wi±zanie dynamiczne dotyczy i zmiennych | |||
i procedur. | i procedur. | ||
}} | }} | ||
Linia 373: | Linia 373: | ||
<math>\mathbf{begin}\,</math> | <math>\mathbf{begin}\,</math> | ||
<math>\mathbf{var}\,</math> x = 10; | <math>\mathbf{var}\,</math> x = 10; <math>\mathbf{var}\,</math> z = 0; | ||
<math>\mathbf{call}\,</math> p(z); | <math>\mathbf{call}\,</math> p(z); | ||
Linia 381: | Linia 380: | ||
Warto¶æ koñcowa zmiennej <math>z = 10</math>. | |||
Gdyby | Gdyby wi±zanie zmiennej <math>x</math> by³o statyczne, to warto¶æ ta | ||
wynosi³aby <math>1</math>. Podobnie dla procedur: | |||
Linia 399: | Linia 398: | ||
Warto¶æ koñcowa zmiennej <math>z = 8</math>. | |||
Gdyby | Gdyby widoczno¶æ procedury <math>q</math> by³a statyczna, to warto¶æ ta | ||
wynosi³aby <math>4</math>. | |||
A oto | A oto przyk³ad programu, który nie wykona³by siê poprawnie | ||
przy | przy wi±zaniu statycznych, a wykonuje siê poprawnie przy | ||
dynamicznym: | dynamicznym: | ||
<math>\mathbf{begin}\,</math> | <math>\mathbf{begin}\,</math> | ||
<math>\mathbf{proc}\,</math> q(x); \mathbf{call}\, r(x); | <math>\mathbf{proc}\,</math> q(x); <math>\mathbf{call}\,</math> r(x); | ||
<math>\mathbf{proc}\,</math> p(y); | <math>\mathbf{proc}\,</math> p(y); | ||
<math>\mathbf{begin}\,</math> | <math>\mathbf{begin}\,</math> | ||
Linia 418: | Linia 417: | ||
<math>\mathbf{call}\,</math> p(z); | <math>\mathbf{call}\,</math> p(z); | ||
\,\mathbf{end} | <math>\,\mathbf{end}</math> | ||
Warto¶æ koñcowa zmiennej <math>z</math> wynosi <math>14</math>. | |||
Procedura <math>p</math> | Procedura <math>p</math> wywo³uje procedurê <math>q</math>, | ||
,, | ,,przekazuj±c" jej równie¿ ¶rodowisko z miejsca wo³ania, | ||
zawieraj±ce informacjê o procedurze <math>r</math>. Ta ostatnia | |||
przy | przy widoczno¶ci statycznej by³aby lokalna, a teraz nie jest. | ||
Linia 432: | Linia 431: | ||
<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"> | ||
Spójrzmy na | Spójrzmy na regu³ê dla wywo³ania procedury: | ||
<math> | <math> | ||
Linia 442: | Linia 441: | ||
</math> | </math> | ||
O | O statyczno¶ci decyduje to, ¿e wnêtrze procedury <math>I</math> | ||
wykonywane jest w | wykonywane jest w ¶rodowisku zmiejsca deklaracji <math>E'</math>. | ||
Wystarczy | Wystarczy wiêc, je¶li zignorujemy to ¶rodowisko, a zamiast | ||
niego | niego u¿yjemy bie¿±cego ¶rodowiska <math>E</math> (czyli ¶rodowiska | ||
z miejsca | z miejsca wywo³ania): | ||
<math> | <math> | ||
Linia 456: | Linia 455: | ||
</math> | </math> | ||
Oczywi¶cie w takim przypadku w ¶rodowiskach | |||
wystarczy | wystarczy przechowywaæ dla procedur pary <math>\langle x, I \rangle</math>. | ||
Zastanówmy | Zastanówmy siê teraz, jak uwzglêdniæ rekurencjê? Oczywi¶cie | ||
mogliby¶my post±piæ tak jak poprzednio, np. | |||
<math> | <math> | ||
Linia 470: | Linia 469: | ||
</math> | </math> | ||
ale | ale je¶li uwa¿nie przyjrzymy siê tej regule, to okazuje siê, | ||
¿e ,,przelewamy z pustego w pró¿ne". Sci¶lej, | |||
dodajemy do <math>E</math> | dodajemy do <math>E</math> parê <math>x_1 \mapsto \langle x, I \rangle</math>, | ||
która | która ju¿ tam tak naprawdê jest! | ||
Okazuje | Okazuje siê, ¿e dziêki dynamicznemu wi±zaniu identyfikatorów ,,za | ||
darmo" otrzymujemy rekurencje! Tak jest na | darmo" otrzymujemy rekurencje! Tak jest na przyk³ad w programie: | ||
Linia 486: | Linia 485: | ||
poniewa¿ w momencie wywo³ania rekurencyjnego <math>\mathbf{call}\, p(x)</math>, | |||
w | w ¶rodowisku jest ju¿ informacja nt. procedury <math>p</math>! | ||
</div></div> | </div></div> | ||
Linia 493: | Linia 492: | ||
{{cwiczenie|3 ( | {{cwiczenie|3 (ró¿ne mechanizmy przekazywana parametru)|cw3| | ||
Rozwa¿ inne mechanizmy przekazywania parametru (wi±zanie statyczne): | |||
* przez | * przez warto¶æ | ||
<!-- | <!-- | ||
* przez | * przez nazwê leniwie (jak przez warto¶æ, ale leniwa strategia ewaluacji parametru aktualnego) | ||
* przez | * przez nazwê dynamicznie (dynamiczne wi±zanie identyfikatorów podczas obliczania warto¶ci parametru aktualnego) | ||
--> | --> | ||
* in-out | * in-out | ||
Nale¿y wyja¶niæ ostatni mechanizm (in-out). | |||
Parametrem aktualnym jest zmienna, której | Parametrem aktualnym jest zmienna, której warto¶æ jest | ||
przypisywana parametrowi formalnemu (tak jak przy przekazywaniu | przypisywana parametrowi formalnemu (tak jak przy przekazywaniu | ||
przez | przez warto¶æ, gdy parametrem aktualnym jest zmienna). | ||
Ale po | Ale po zakoñczeniu procedury, warto¶æ parametru formalnego, | ||
która | która mog³a zmieniæ siê w czasie dzialania procedury, jest | ||
spowrotem przypisywana na | spowrotem przypisywana na zmienn± bêd±c± parametrem aktualnym | ||
(a | (a wiêc podobnie do przekazywania przez zmienn±). | ||
Parametr formalny jest traktowany jak zmienna lokalna procedury. | Parametr formalny jest traktowany jak zmienna lokalna procedury. | ||
}} | }} | ||
{{rozwiazanie|| | {{rozwiazanie|(przekazywanie parametru przez warto¶æ)|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"><div class="mw-collapsible-content" style="display:none"> | ||
Omówimy tylko | Omówimy tylko instrukcjê wywo³ania procedury, której sk³adnia jest | ||
teraz szersza | teraz szersza ni¿ poprzednio: | ||
<math> | <math> | ||
Linia 532: | Linia 528: | ||
</math> | </math> | ||
Przed | Przed wywo³aniem procedury nale¿y zaalokowaæ now± lokacjê, | ||
któr± przypiszemy parametrowi formalnemu; nastêpnie obliczamy | |||
warto¶æ parametru aktualnego i umieszczamy j± w tej lokacji: | |||
<math> | <math> | ||
Linia 547: | Linia 543: | ||
</div></div> | </div></div> | ||
}} | |||
{{rozwiazanie|(przekazywanie parametru in-out)|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"> | ||
Pocz±tkowo postêpujemy tak jak w przypadku przekazywania przez | |||
warto¶æ: alokujemy now± lokacjê <math>l</math>, któr± przypiszemy | |||
parametrowi formalnemu, i umieszczamy w niej | parametrowi formalnemu, i umieszczamy w niej warto¶æ zmiennej | ||
(<math>x_2</math> w regule | (<math>x_2</math> w regule poni¿ej) bêd±cej parametrem aktualnym. | ||
Zasadnicza | Zasadnicza ró¿nica widoczna jest po zakoñczeniu procedury: warto¶æ z lokacji | ||
<math>l</math> powinna | <math>l</math> powinna zostaæ spowrotem przypisana zmiennej <math>x_2</math>. | ||
Oto | Oto regu³a: | ||
<math> | <math> | ||
Linia 566: | Linia 562: | ||
\quad \mbox{ o ile } | \quad \mbox{ o ile } | ||
E(x_2) = l_2 \in \mathbf{Loc} \mbox{ i } | E(x_2) = l_2 \in \mathbf{Loc} \mbox{ i } | ||
s(l_2) \mbox{ jest | s(l_2) \mbox{ jest okre¶lone i } | ||
E(x_1) = \langle x, I, E' \rangle \in \mathbf{Proc} \mbox{ i } | E(x_1) = \langle x, I, E' \rangle \in \mathbf{Proc} \mbox{ i } | ||
l = \mathtt{newloc}(s) | l = \mathtt{newloc}(s) | ||
Linia 578: | Linia 574: | ||
{{cwiczenie|1|cw1.dom| | |||
Zaadaptuj semantykê ,,deklaracji równoleg³ych" | |||
dla rekurencji wzajemnej wewn±trz jednej deklaracji równoleg³ej. | |||
To znaczy, ¿e procedury zadeklarowane w jednej deklaracji równoleg³ej | |||
mog± siê wzajemniej wywo³ywaæ bez ¿adnych ograniczeñ. | |||
}} | |||
{{cwiczenie|2|cw2.dom| | |||
Zamiast procedur, rozwa¿ funkcje z pojedynczym parametrem | |||
przekazywanym przez zmienn±. | |||
Zamiast procedur, | Wywo³anie funkcji mo¿e teraz pojawiæ siê wewn±trz wyra¿enia: | ||
przekazywanym przez | |||
<math> | <math> | ||
e \, ::= \,\, | e \, ::= \,\, | ||
\ldots \,\,|\,\, | \ldots \,\,|\,\, | ||
\mathbf{call}\, x_1(x_2) | \mathbf{call}\, x_1(x_2). | ||
</math> | </math> | ||
Uwaga na efekty uboczne! | Uwaga na efekty uboczne! | ||
}} | |||
{{cwiczenie|3|cw3.dom| | |||
Rozwa¿ nastêpuj±ce warianty: | |||
* | * wi±zanie zmiennych jest statyczne a procedur dynamiczne | ||
* | * wi±zanie zmiennych jest dymamiczne a procedur statyczne. | ||
}} | |||
{{cwiczenie|4|cw4.dom| | |||
Rozszerz | Rozszerz semantykê procedur tak, aby parametrem aktualnym procedury | ||
mog³a byæ procedura. | |||
}} |
Wersja z 08:03, 9 sie 2006
Zawarto¶æ
Ostatnie zajêcia po¶wiêcone semantyce naturalnej. Rozszerzymy jêzyk Tiny o deklaracje zmiennych i procedur z jednym parametrem. Rozwa¿ymy statyczn± i dynamiczn± widoczno¶æ (wi±zanie) identyfikatorów oraz ró¿ne mechanizmy przekazywania parametrów. Pracujemy ze ¶rodowiskami i stanami.
Semantyka naturalna procedur
Ćwiczenie 1 (procedury)
Rozszerzmy jêzyk Tiny o deklaracje i wywo³ania procedur:
Konstrukcja deklaruje procedurê o nazwie , której parametrem formalnym jest . Zak³adamy statyczne wi±zanie identyfikatorów i przekazywanie parametrów przez zmienn± (to znaczy, ¿e w momencie wywo³ania procedury, powinna zostaæ przekazana lokacja odpowiadaj±ca parametrowi aktualnemu). Instrukcja wywo³uje procedurê z parametrem aktualnym .
Rozwiązanie
Ćwiczenie 2 (wi±zanie dynamiczne)
Zastanówmy siê, jakich modyfikacji wymaga nasza semantyka, aby wi±zanie identyfikatorów by³o dynamiczne, zamiast statycznego. Rozumiemy przez to, ¿e w przypadku odwo³ania do zmiennej wewn±trz procedury, odwo³ujemy siê do ¶rodowiska w miejscu wywo³ania tej procedury, zamiast do ¶rodowiska z miejsca deklaracji jak dotychczas. Tak samo powinno byæ w przypadku wywo³ania innej procedury wewn±trz procedury, czyli wi±zanie dynamiczne dotyczy i zmiennych i procedur.
Przykład
Spójrzmy na kilka prostych programów.
x = 1; p(y); y := y+x; x = 10; z = 0; p(z);
Warto¶æ koñcowa zmiennej .
Gdyby wi±zanie zmiennej by³o statyczne, to warto¶æ ta
wynosi³aby . Podobnie dla procedur:
q(x); x := x+1; p(y); q(y); q(y); q(x); x := x+x; z = 2; p(z);
Warto¶æ koñcowa zmiennej .
Gdyby widoczno¶æ procedury by³a statyczna, to warto¶æ ta
wynosi³aby .
A oto przyk³ad programu, który nie wykona³by siê poprawnie
przy wi±zaniu statycznych, a wykonuje siê poprawnie przy
dynamicznym:
q(x); r(x); p(y); r(x); x := x+x; q(x); z = 7; p(z);
Warto¶æ koñcowa zmiennej wynosi .
Procedura wywo³uje procedurê ,
,,przekazuj±c" jej równie¿ ¶rodowisko z miejsca wo³ania,
zawieraj±ce informacjê o procedurze . Ta ostatnia
przy widoczno¶ci statycznej by³aby lokalna, a teraz nie jest.
Rozwiązanie
Ćwiczenie 3 (ró¿ne mechanizmy przekazywana parametru)
Rozwa¿ inne mechanizmy przekazywania parametru (wi±zanie statyczne):
- przez warto¶æ
- in-out
Nale¿y wyja¶niæ ostatni mechanizm (in-out). Parametrem aktualnym jest zmienna, której warto¶æ jest przypisywana parametrowi formalnemu (tak jak przy przekazywaniu przez warto¶æ, gdy parametrem aktualnym jest zmienna). Ale po zakoñczeniu procedury, warto¶æ parametru formalnego, która mog³a zmieniæ siê w czasie dzialania procedury, jest spowrotem przypisywana na zmienn± bêd±c± parametrem aktualnym (a wiêc podobnie do przekazywania przez zmienn±). Parametr formalny jest traktowany jak zmienna lokalna procedury.
Rozwiązanie (przekazywanie parametru przez warto¶æ)
Rozwiązanie (przekazywanie parametru in-out)
Zadania domowe
Ćwiczenie 1
Zaadaptuj semantykê ,,deklaracji równoleg³ych" dla rekurencji wzajemnej wewn±trz jednej deklaracji równoleg³ej. To znaczy, ¿e procedury zadeklarowane w jednej deklaracji równoleg³ej mog± siê wzajemniej wywo³ywaæ bez ¿adnych ograniczeñ.
Ćwiczenie 2
Zamiast procedur, rozwa¿ funkcje z pojedynczym parametrem przekazywanym przez zmienn±. Wywo³anie funkcji mo¿e teraz pojawiæ siê wewn±trz wyra¿enia:
Uwaga na efekty uboczne!
Ćwiczenie 3
Rozwa¿ nastêpuj±ce warianty:
- wi±zanie zmiennych jest statyczne a procedur dynamiczne
- wi±zanie zmiennych jest dymamiczne a procedur statyczne.
Ćwiczenie 4
Rozszerz semantykê procedur tak, aby parametrem aktualnym procedury mog³a byæ procedura.