Semantyka i weryfikacja programów/Ćwiczenia 5: Różnice pomiędzy wersjami
m Zastępowanie tekstu – „\</math>” na „\ </math>” |
m Zastępowanie tekstu – „.↵</math>” na „</math>” |
||
Linia 57: | Linia 57: | ||
<math> | <math> | ||
I, s \,\longrightarrow\, s' \quad \quad \quad e, s \,\longrightarrow\, n | I, s \,\longrightarrow\, s' \quad \quad \quad e, s \,\longrightarrow\, n</math> | ||
</math> | |||
Zacznijmy od najprostszego przypadku, gdy nie ma wogóle potrzeby uruchamiania instrukcji wewnętrznej <math>I_1</math>, ponieważ wartość wyrażenia <math>e_1</math> jest większa od <math>e_2</math>: | Zacznijmy od najprostszego przypadku, gdy nie ma wogóle potrzeby uruchamiania instrukcji wewnętrznej <math>I_1</math>, ponieważ wartość wyrażenia <math>e_1</math> jest większa od <math>e_2</math>: | ||
Linia 69: | Linia 68: | ||
I_2, s \,\longrightarrow\, s'} | I_2, s \,\longrightarrow\, s'} | ||
{\mathbf{for}\, x = e_1 \,\mathbf{to}\, e_2 \,\mathbf{try}\, I_1 \,\mathbf{else}\, I_2, s \,\longrightarrow\, s'} | {\mathbf{for}\, x = e_1 \,\mathbf{to}\, e_2 \,\mathbf{try}\, I_1 \,\mathbf{else}\, I_2, s \,\longrightarrow\, s'} | ||
\quad \mbox{ o ile } n_1 > n_2 | \quad \mbox{ o ile } n_1 > n_2</math> | ||
</math> | |||
Po prostu uruchamiamy instrukcję <math>I_2</math> w stanie <math>s</math>, ignorując <math>I_1</math>. | Po prostu uruchamiamy instrukcję <math>I_2</math> w stanie <math>s</math>, ignorując <math>I_1</math>. | ||
Linia 84: | Linia 82: | ||
I_1, s[x \mapsto n_1] \,\longrightarrow\, s'} | I_1, s[x \mapsto n_1] \,\longrightarrow\, s'} | ||
{\mathbf{for}\, x = e_1 \,\mathbf{to}\, e_2 \,\mathbf{try}\, I_1 \,\mathbf{else}\, I_2, s \,\longrightarrow\, s'[x \mapsto s(x)]} | {\mathbf{for}\, x = e_1 \,\mathbf{to}\, e_2 \,\mathbf{try}\, I_1 \,\mathbf{else}\, I_2, s \,\longrightarrow\, s'[x \mapsto s(x)]} | ||
\quad \mbox{ o ile } n_1 \leq n_2 | \quad \mbox{ o ile } n_1 \leq n_2</math> | ||
</math> | |||
Tym razem uruchamiamy instrukcję <math>I_1</math>, podstawiając na zmienną <math>x</math> wartość <math>n_1</math>. | Tym razem uruchamiamy instrukcję <math>I_1</math>, podstawiając na zmienną <math>x</math> wartość <math>n_1</math>. | ||
Linia 94: | Linia 91: | ||
<math> | <math> | ||
I, s \,\longrightarrow\, \mbox{było-}\mathbf{fail} | I, s \,\longrightarrow\, \mbox{było-}\mathbf{fail}</math> | ||
</math> | |||
Mówiąc formalnie, poszerzamy zbiór konfiguracji o jeden element <math>\mbox{było-}\mathbf{fail}</math>. | Mówiąc formalnie, poszerzamy zbiór konfiguracji o jeden element <math>\mbox{było-}\mathbf{fail}</math>. | ||
Linia 117: | Linia 113: | ||
\mathbf{for}\, x = e_1 + 1 \,\mathbf{to}\, e_2 \,\mathbf{try}\, I_1 \,\mathbf{else}\, I_2, s \,\longrightarrow\, s'} | \mathbf{for}\, x = e_1 + 1 \,\mathbf{to}\, e_2 \,\mathbf{try}\, I_1 \,\mathbf{else}\, I_2, s \,\longrightarrow\, s'} | ||
{\mathbf{for}\, x = e_1 \,\mathbf{to}\, e_2 \,\mathbf{try}\, I_1 \,\mathbf{else}\, I_2, s \,\longrightarrow\, s'} | {\mathbf{for}\, x = e_1 \,\mathbf{to}\, e_2 \,\mathbf{try}\, I_1 \,\mathbf{else}\, I_2, s \,\longrightarrow\, s'} | ||
\quad \mbox{ o ile } n_1 \leq n_2 | \quad \mbox{ o ile } n_1 \leq n_2</math> | ||
</math> | |||
Zwróćmy uwagę na pewnien niezwykle istotny szczegół: po zakończeniu wykonania instrukcji <math>\mathbf{for}\, x = e_1 + 1 \,\mathbf{to}\, e_2 \,\mathbf{try}\, I_1 \,\mathbf{else}\, I_2</math> otrzymujemy stan <math>s'</math>, w którym '''nie przywracamy''' wartości zmiennej <math>x</math>. | Zwróćmy uwagę na pewnien niezwykle istotny szczegół: po zakończeniu wykonania instrukcji <math>\mathbf{for}\, x = e_1 + 1 \,\mathbf{to}\, e_2 \,\mathbf{try}\, I_1 \,\mathbf{else}\, I_2</math> otrzymujemy stan <math>s'</math>, w którym '''nie przywracamy''' wartości zmiennej <math>x</math>. | ||
Linia 234: | Linia 229: | ||
<math> | <math> | ||
\mathbf{Store} = \mathbf{Loc} \to_{\mathrm{fin}} \mathbf{Num} | \mathbf{Store} = \mathbf{Loc} \to_{\mathrm{fin}} \mathbf{Num}</math> | ||
</math> | |||
Dla ścisłości używamy innej nazwy (<math>\mathbf{Store}</math>), ale będziemy zwykle używać podobnych symboli jak dotychczas <math>s, s', s_1, \ldots \in \mathbf{Store}</math> itp. do nazywania stanów. | Dla ścisłości używamy innej nazwy (<math>\mathbf{Store}</math>), ale będziemy zwykle używać podobnych symboli jak dotychczas <math>s, s', s_1, \ldots \in \mathbf{Store}</math> itp. do nazywania stanów. | ||
Linia 274: | Linia 268: | ||
<math> | <math> | ||
\mathtt{newloc}(s) \notin \mathrm{dom}(s) | \mathtt{newloc}(s) \notin \mathrm{dom}(s)</math> | ||
</math> | |||
Dla ilustracji popatrzmy na przykładową regułę dla deklaracji. | Dla ilustracji popatrzmy na przykładową regułę dla deklaracji. | ||
Linia 283: | Linia 276: | ||
E[x \mapsto l] \,\vdash\, I, s[l \mapsto n] \,\longrightarrow\, s'} | E[x \mapsto l] \,\vdash\, I, s[l \mapsto n] \,\longrightarrow\, s'} | ||
{E \,\vdash\, \mathbf{begin}\, \mathbf{var}\, x=e;\, I \,\mathbf{end}, s \,\longrightarrow\, s'} | {E \,\vdash\, \mathbf{begin}\, \mathbf{var}\, x=e;\, I \,\mathbf{end}, s \,\longrightarrow\, s'} | ||
\quad \mbox{ gdzie } l = \mathtt{newloc}(s) | \quad \mbox{ gdzie } l = \mathtt{newloc}(s)</math> | ||
</math> | |||
Zauważmy, że stan <math>s'</math> po zakończeniu instrukcji <math>\mathbf{begin}\, \mathbf{var}\, x=e;\, I \,\mathbf{end}</math> zawiera informację o zmiennej lokalnej <math>x</math>, tzn. <math>s(l)</math> jest określone. | Zauważmy, że stan <math>s'</math> po zakończeniu instrukcji <math>\mathbf{begin}\, \mathbf{var}\, x=e;\, I \,\mathbf{end}</math> zawiera informację o zmiennej lokalnej <math>x</math>, tzn. <math>s(l)</math> jest określone. | ||
Linia 380: | Linia 372: | ||
E[x \mapsto l] \,\vdash\, I, s[l \mapsto n] \,\longrightarrow\, s'} | E[x \mapsto l] \,\vdash\, I, s[l \mapsto n] \,\longrightarrow\, s'} | ||
{E \,\vdash\, \mathbf{begin}\, \mathbf{var}\, x=e;\, I \,\mathbf{end}, s \,\longrightarrow\, s' \setminus \{ (l, s'(l)) \}} | {E \,\vdash\, \mathbf{begin}\, \mathbf{var}\, x=e;\, I \,\mathbf{end}, s \,\longrightarrow\, s' \setminus \{ (l, s'(l)) \}} | ||
\quad \mbox{ gdzie } l = \mathtt{newloc}(s) | \quad \mbox{ gdzie } l = \mathtt{newloc}(s)</math> | ||
</math> | |||
</div></div> | </div></div> |
Aktualna wersja na dzień 21:30, 11 wrz 2023
Zawartość
Kontynuujemy ćwiczenie semantyki naturalnej, dodając pewne konstrukcje do języka TINY. W szczególności rozszerzymy go o deklaracje zmiennych (bloki). Po raz pierwszy roszdzielimy informację przechowywaną w konfiguracji na środowisko określające wiązanie identyfikatorów i stan przechowujący wartości zmiennych. Będzie to przygotowanie do kolejnych zajęć.
Semantyka naturalna pewnej instrukcji ,
Ćwiczenie 1
Rozszerzamy język TINY następująco:
Znaczenie instrukcji jest następujące. Obliczamy wartości wyrażeń i . Jeśli pierwsza z nich jest mniejsza od lub równa drugiej, podstawiamy pierwszą wartość (wartość wyrażenia ) na zmienną i uruchamiamy . Jeśli w nie zostanie napotkana instrukcja , kończymy instrukcję , i przyracamy wartość zmiennej sprzed tej instrukcji. Natomiast jeśli w zostanie napotkana instrukcja , podstawiamy na kolejną, o jeden większą wartość, przywracamy wartości wszystkich pozostałych zmiennych sprzed instrukcji , i ponownie wykonujemy . Powtarzamy w ten sposób, aż zakończy się nie napotkawszy , albo wartość zmiennej przekroczy wartość wyrażenia obliczoną na początku. W pierwszym przypadku kończymy instrukcję , i przyracamy wartość zmiennej sprzed tej instrukcji. W drugim przywracamy wartości wszystkich zmiennych sprzed instrukcji , i uruchamiamy .
Przykład
Oto przykładowy program:
x := 0; y := 1; , x := 1 , 5 , y := y+1; , x <= 4 , z:= x
Wartości zmiennych po zakończeniu programu to: .
Rozwiązanie
Semantyka naturalna bloków
Ćwiczenie 2 (bloki i deklaracje zmiennych)
Rozszerz semantykę języka TINY o deklarację zmiennej:
Zasięgiem zmiennej jest instrukcja , czyli wnętrze bloku, w którym jest zadeklarowana. Zakładamy zwykłe (statyczne) reguły widoczności, przesłaniania, itp.
Rozwiązanie
Zadania domowe
Ćwiczenie 1
Napisz semantykę naturalną dla następującego rozszerzenia języka TINY:
Instrukcja oznacza podniesienie wyjątku o nazwie . Instrukcja wykonuje . Jeśli podczas wykonania zostanie podniesiony wyjątek , i albo , to następuje przerwanie i sterowanie zostaje przeniesione do (następuje obsługa wyjątku). Jeśli zaś podczas wykonania zostanie podniesiony wyjątek oraz i , to obsługa wyjątku przekazana jest do najbliższej instrukcji , otaczającej . Umawiamy się, że otacza i wszystkie instrukcje wewnątrz , ale nie otacza .
Ćwiczenie 2
Zaproponuj modyfikację semantyki, w której deklaracja jest wykonywana "równolegle", analogicznie do przypisania równoległego. Przy takiej semantyce kolejność poszczególnych deklaracji powinna być nieistotna.