Semantyka i weryfikacja programów/Ćwiczenia 4: Różnice pomiędzy wersjami
Nie podano opisu zmian |
Nie podano opisu zmian |
||
Linia 1: | Linia 1: | ||
== Treść == | == Treść == | ||
Linia 47: | Linia 48: | ||
Oto reguły semantyki naturalnej. | Oto reguły semantyki naturalnej. | ||
<math> | <center><math> | ||
n, s \,\longrightarrow\, n | |||
</math></center> | |||
<math> | <center><math> | ||
x, s \,\longrightarrow\, n \quad \mbox{ o ile } s(x) = n | |||
</math></center> | |||
<math> | <center><math> | ||
\frac{e_1, s \,\longrightarrow\, n_1 \quad e_2, s \,\longrightarrow\, n_2} | \frac{e_1, s \,\longrightarrow\, n_1 \quad e_2, s \,\longrightarrow\, n_2} | ||
{e_1 + e_2, s \,\longrightarrow\, n} \quad \mbox{ o ile } n = n_1 + n_2 | {e_1 + e_2, s \,\longrightarrow\, n} \quad \mbox{ o ile } n = n_1 + n_2 | ||
</math></center> | |||
<math> | <center><math> | ||
\frac{e_1, s \,\longrightarrow\, n_1 \quad e_2, s[x \mapsto n] \,\longrightarrow\, n_2} | \frac{e_1, s \,\longrightarrow\, n_1 \quad e_2, s[x \mapsto n] \,\longrightarrow\, n_2} | ||
{\mathbf{let}\, x = e_1 \,\mathbf{in}\, e_2, s \,\longrightarrow\, n_2} | {\mathbf{let}\, x = e_1 \,\mathbf{in}\, e_2, s \,\longrightarrow\, n_2} | ||
</math> | </math></center> | ||
<math> | <center><math> | ||
\frac{e_1, s \,\longrightarrow\, n_1 \quad n_1 \neq 0 \quad e_2, s \,\longrightarrow\, n_2} | \frac{e_1, s \,\longrightarrow\, n_1 \quad n_1 \neq 0 \quad e_2, s \,\longrightarrow\, n_2} | ||
{\mathbf{if}\, e_1 \,\mathbf{then}\, e_2 \,\mathbf{else}\, e_3, s \,\longrightarrow\, n_2} | {\mathbf{if}\, e_1 \,\mathbf{then}\, e_2 \,\mathbf{else}\, e_3, s \,\longrightarrow\, n_2} | ||
</math> | </math></center> | ||
<math> | <center><math> | ||
\frac{e_1, s \,\longrightarrow\, n_1 \quad n_1 = 0 \quad e_3, s \,\longrightarrow\, n_3} | \frac{e_1, s \,\longrightarrow\, n_1 \quad n_1 = 0 \quad e_3, s \,\longrightarrow\, n_3} | ||
{\mathbf{if}\, e_1 \,\mathbf{then}\, e_2 \,\mathbf{else}\, e_3, s \,\longrightarrow\, n_3} | {\mathbf{if}\, e_1 \,\mathbf{then}\, e_2 \,\mathbf{else}\, e_3, s \,\longrightarrow\, n_3} | ||
</math> | </math></center> | ||
Zauważmy, że opisanie zasięgu deklaracji <math> x = e_1 </math> nie predstawia | Zauważmy, że opisanie zasięgu deklaracji <math> x = e_1 </math> nie predstawia | ||
Linia 118: | Linia 119: | ||
Odpowiednia reguła dla wyrażenia <math> \mathbf{let}\, </math> to | Odpowiednia reguła dla wyrażenia <math> \mathbf{let}\, </math> to | ||
<math> | <center><math> | ||
\mathbf{let}\, x = e_1 \,\mathbf{in}\, e_2, s \,\Longrightarrow\, e_2, s[x \mapsto (e_1, s)]. | \mathbf{let}\, x = e_1 \,\mathbf{in}\, e_2, s \,\Longrightarrow\, e_2, s[x \mapsto (e_1, s)]. | ||
</math> | </math></center> | ||
Uważnego czytelnika zapewne zaniepokoił fakt, że <math> \mathbf{State} </math> | Uważnego czytelnika zapewne zaniepokoił fakt, że <math> \mathbf{State} </math> | ||
Linia 160: | Linia 161: | ||
<math> \mathbf{let}\, </math>. Pozostałe reguły pozostają praktyczanie bez zmian. | <math> \mathbf{let}\, </math>. Pozostałe reguły pozostają praktyczanie bez zmian. | ||
<math> | <center><math> | ||
\frac{e, s' \,\longrightarrow\, n} | \frac{e, s' \,\longrightarrow\, n} | ||
{x, s \,\longrightarrow\, n} \quad \mbox{ o ile } s(x) = (e, s') | {x, s \,\longrightarrow\, n} \quad \mbox{ o ile } s(x) = (e, s') | ||
</math> | </math></center> | ||
<math> | <center><math> | ||
\frac{e_2, s[x \mapsto (e_1, s)] \,\longrightarrow\, n} | \frac{e_2, s[x \mapsto (e_1, s)] \,\longrightarrow\, n} | ||
{\mathbf{let}\, x = e_1 \,\mathbf{in}\, e_2, s \,\longrightarrow\, n} | {\mathbf{let}\, x = e_1 \,\mathbf{in}\, e_2, s \,\longrightarrow\, n} | ||
</math> | </math></center> | ||
Linia 219: | Linia 220: | ||
wyrażenia <math> \mathbf{let}\, </math>, gdyż pozostałe reguły pozostają bez zmian | wyrażenia <math> \mathbf{let}\, </math>, gdyż pozostałe reguły pozostają bez zmian | ||
<math> | <center><math> | ||
\frac{e, s \,\longrightarrow\, n} | \frac{e, s \,\longrightarrow\, n} | ||
{x, s \,\longrightarrow\, n} \quad \mbox{ o ile } s(x) = e | {x, s \,\longrightarrow\, n} \quad \mbox{ o ile } s(x) = e | ||
</math> | </math></center> | ||
<math> | <center><math> | ||
\frac{e_2, s[x \mapsto e_1] \,\longrightarrow\, n} | \frac{e_2, s[x \mapsto e_1] \,\longrightarrow\, n} | ||
{\mathbf{let}\, x = e_1 \,\mathbf{in}\, e_2, s \,\longrightarrow\, n} | {\mathbf{let}\, x = e_1 \,\mathbf{in}\, e_2, s \,\longrightarrow\, n} | ||
</math> | </math></center> | ||
Wersja z 17:11, 27 lip 2006
Treść
Napiszemy semantykę naturalną języka wyrażeń (z ), rozważymy strategię gorliwą (jak na wcześniejszych zajęciach) i leniwą. Rozważymy i statyczne i dynamiczne wiązanie identyfikatorów. Następnie rozszerzymy ten język o lambda-abstrakcję i aplikację, otrzymując prosty język funkcyjny.
Różne semantyki wyrażeń
Zadanie 1 (semantyka gorliwa)
Napisz semantykę dużych kroków dla języka wyrażeń, którego semantykę mało-krokową napisaliśmy na jednych z poprzednich ćwiczeń:
Rozwiązanie
Przypomnijmy, że zbiór stanów to
Nasze tranzycje będą postaci , gdzie . Oto reguły semantyki naturalnej.
Zauważmy, że opisanie zasięgu deklaracji nie predstawia w semantyce naturalnej żadnych trudności, w przeciwieństwie do semantyki małych kroków.
Zadanie 2 (semantyka leniwa)
Zmodyfikuj semantykę z poprzedniego zadania, aby uzyskać leniwą ewaluację wyrażeń, zgodnie z dyrektywą: nie obliczaj wyrażenia o ile jego wynik nie jest potrzebny (albo: obliczaj wartość wyrażenia dopiero wtedy, gdy jego wynik jest naprawdę potrzebny). Spójrzmy na przykład:
Według semantyki z poprzedniego zadania wyrażnie to nie ma wartości, bo w deklaracji jest odwołanie do niezainicjowanej zmiennej. Natomiast w semantyce leniwej wyrażenie to obliczy się do wartości , gdyż wyrażenie nie będzie wogóle obliczane. Będzie tak dlatego, że w wyrażeniu nie ma odwołań do zmiennej .
Rozwiązanie
Semantyka leniwa będzie bardzo podobna do tej z poprzedniego zadania. Zasadnicza różnica dotyczy informacji przechowywanej w stanie. Dotychczas , gdyż podwyrażenie w obliczało sie natychmiast. Jeśli chcemy opóżnic obliczenie tego podwyrażenia, to w powinniśmy zapamiętać całe (nieobliczone) wyrażenie wraz ze stanem bieżącym. Czyli
Odpowiednia reguła dla wyrażenia to
Uważnego czytelnika zapewne zaniepokoił fakt, że stoi zarówno po lewej jak i po prawej stronie równania Również zapis może wzbudzić niepokój, gdyż sugeruje on, iż zawiera, jako jeden z elementów pary, obiekt tego samego typu co . Formalnego rozwiązania tego typu dylematów dostarcza teoria dziedzin. Natomiast na użytek semantyki operacyjnej wystarczy, jeśli uznamy, iż równanie stanowi skrótowy zapis następującej definicji. Zdefiniujmy następująco:
i przyjmijmy, że
Parser nie mógł rozpoznać (nieznana funkcja „\nat”): {\displaystyle \mathbf{State} = \bigcup_{n \in \nat} \mathbf{State}_{n} }
Tranzycje będą znów postaci: Podamy tylko reguły dla wystąpienia zmiennej i dla wyrażenia . Pozostałe reguły pozostają praktyczanie bez zmian.
Zadanie 3 (semantyka dynamiczna)
Rozważmy teraz zupełnie inny mechanizm wiązania identyfikatorów, zwany wiązaniem dynamicznym. Dla odróżnienia, dotychczasowy sposób wiązania (widoczności) identyfikatorów będziemy nazywać wiązaniem statycznym. Oto przykładowe wyrażenie:
które nie ma wartości według semantyk z poprzednich zadań, ponieważ odwołanie do zmiennej w deklaracji jest niepoprawne (w pustym stanie początkowym). Tak samo jest nawet w semantyce leniwej, gdyż wartość zmiennej będzie w końcu policzona, i będzie wymagała odwołania do w stanie pustym.
Natomiast wyobrażmy sobie, że zmieniamy semantykę leniwą następująco: odwołanie do zmiennej podczas obliczania wartości będzie odnosiło się nie do stanu w momencie deklaracji , ale do stanu w momencie odwołania do . Jest to dość rewolucyjna zmiana, zapewne sprzeczna z intuicjami programisty (statyczne reguły widoczności zamieniamy na dynamiczne). W szczególności powyższe wyrażenie policzy się w semantyce dynamicznej do wartości 11, ponieważ stan w momencie odwołania do zmiennej przypisuje zmiennej wartość 10 !
Napisz semantykę naturalną dla wiązania dynamicznego.
Rozwiązanie
Teraz w stanie wystarczy przechowywać wyrażenie definiujące wartość danej zmiennej:
Nie potrzebujemy zapamiętywać stanu, w którym byliśmy w momencie deklaracji. Do obliczenia zapamiętanego wyrażenia użyjemy stanu, w którym będziemy w momencie odwołania do danej zmiennej. Znów podajemy tylko reguły dla wystąpienia zmiennej i dla wyrażenia , gdyż pozostałe reguły pozostają bez zmian
Prosty język funkcyjny
Zadanie 1
....
Rozwiązanie
Zadania domowe
Zadanie 1
Podaj przykład wyrażenia takiego, które:
- ma wartość w semantyce statycznej i dynamicznej, ale w każdej inną
- ma wartość w semantyce leniwej a nie ma w dynamicznej
- ma wartość w semantyce dynamicznej a nie ma w leniwej