Semantyka i weryfikacja programów/Ćwiczenia 1: Różnice pomiędzy wersjami
m Zastępowanie tekstu – „.↵</math>” na „</math>” |
|||
(Nie pokazano 6 wersji utworzonych przez 2 użytkowników) | |||
Linia 1: | Linia 1: | ||
== Zawartość == | == Zawartość == | ||
Linia 33: | Linia 32: | ||
}} | }} | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> | |||
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span> | |||
<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"> | |||
Zacznijmy od ustalenia notacji i dziedzin syntaktycznych. | Zacznijmy od ustalenia notacji i dziedzin syntaktycznych. | ||
Linia 52: | Linia 50: | ||
<math> | <math> | ||
e, s \,\Longrightarrow | e, s \,\Longrightarrow, e', s | ||
</math> | </math> | ||
Linia 61: | Linia 59: | ||
<math> | <math> | ||
e, s \,\Longrightarrow | e, s \,\Longrightarrow, n | ||
</math> | </math> | ||
Linia 82: | Linia 80: | ||
<math> | <math> | ||
n, s \,\Longrightarrow | n, s \,\Longrightarrow, n | ||
</math> | </math> | ||
Linia 90: | Linia 88: | ||
<math> | <math> | ||
x, s \,\Longrightarrow | x, s \,\Longrightarrow, n, s \quad \mbox{ o ile } s(x) = n</math> | ||
</math> | |||
Teraz zajmiemy się dodawaniem <math>e_1 + e_2</math>. Ponieważ semantyka jest w stylu małych kroków, musimy zdecydować się, czy najpierw obliczyć pierwszy (lewy) składnik <math>e_1</math>, czy drugi? | Teraz zajmiemy się dodawaniem <math>e_1 + e_2</math>. Ponieważ semantyka jest w stylu małych kroków, musimy zdecydować się, czy najpierw obliczyć pierwszy (lewy) składnik <math>e_1</math>, czy drugi? | ||
Linia 97: | Linia 94: | ||
<math> | <math> | ||
e_1 + e_2, s \,\Longrightarrow | e_1 + e_2, s \,\Longrightarrow, e'_1 + e_2, s | ||
\quad \mbox{ o ile } \quad | \quad \mbox{ o ile } \quad | ||
e_1, s \,\Longrightarrow | e_1, s \,\Longrightarrow, e'_1, s</math> | ||
</math> | |||
Reguły tej postaci będziemy zapisywać tak: | Reguły tej postaci będziemy zapisywać tak: | ||
<math> | <math> | ||
\frac{e_1, s \,\Longrightarrow | \frac{e_1, s \,\Longrightarrow, e'_1, s} | ||
{e_1 + e_2, s \,\Longrightarrow | {e_1 + e_2, s \,\Longrightarrow, e'_1 + e_2, s} | ||
</math> | </math> | ||
Linia 113: | Linia 109: | ||
<math> | <math> | ||
\frac{e_2, s \,\Longrightarrow | \frac{e_2, s \,\Longrightarrow, e'_2, s} | ||
{n + e_2, s \,\Longrightarrow | {n + e_2, s \,\Longrightarrow, n + e'_2, s}</math> | ||
</math> | |||
A na końcu dodajemy: | A na końcu dodajemy: | ||
<math> | <math> | ||
n_1 + n_2, s \,\Longrightarrow | n_1 + n_2, s \,\Longrightarrow, n, s \quad \mbox{ o ile } n = n_1 + n_2</math> | ||
</math> | |||
Zwróćmy tutaj uwagę na pewną subtelność, dotyczącą dwóch wystąpień symbolu <math>+</math>: pierwsze wystąpienie oznacza jedną z konstrukcji składniowych języka, a drugie oznacza operację dodawania w zbiorze <math>\mathbf{Num}</math>. | Zwróćmy tutaj uwagę na pewną subtelność, dotyczącą dwóch wystąpień symbolu <math>+</math>: pierwsze wystąpienie oznacza jedną z konstrukcji składniowych języka, a drugie oznacza operację dodawania w zbiorze <math>\mathbf{Num}</math>. | ||
Linia 127: | Linia 121: | ||
<math> | <math> | ||
\mathrm{add}(n_1, n_2), s \,\Longrightarrow | \mathrm{add}(n_1, n_2), s \,\Longrightarrow, n, s \quad \mbox{ o ile } n = n_1 + n_2</math> | ||
</math> | |||
Inną możliwą strategią obliczania <math>e_1 + e_2</math> jest strategia "prawostronna", którą otrzymujemy zastępując pierwsze dwie z trzech powyższych reguł przez: | Inną możliwą strategią obliczania <math>e_1 + e_2</math> jest strategia "prawostronna", którą otrzymujemy zastępując pierwsze dwie z trzech powyższych reguł przez: | ||
<math> | <math> | ||
\frac{e_2, s \,\Longrightarrow | \frac{e_2, s \,\Longrightarrow, e'_2, s} | ||
{e_1 + e_2, s \,\Longrightarrow | {e_1 + e_2, s \,\Longrightarrow, e_1 + e'_2} | ||
\quad \quad | \quad \quad | ||
\frac{e_1, s \,\Longrightarrow | \frac{e_1, s \,\Longrightarrow, e'_1, s} | ||
{e_1 + n, s \,\Longrightarrow | {e_1 + n, s \,\Longrightarrow, e'_1 + n, s}</math> | ||
</math> | |||
Ponadto, jeśli przyjmiemy regułę pierwszą (dla <math>e_1</math>), trzecią i czwartą (dla <math>e_2</math>), otrzymamy strategię "równoległą", polegającą na obliczaniu jednocześnie <math>e_1</math> i <math>e_2</math>: | Ponadto, jeśli przyjmiemy regułę pierwszą (dla <math>e_1</math>), trzecią i czwartą (dla <math>e_2</math>), otrzymamy strategię "równoległą", polegającą na obliczaniu jednocześnie <math>e_1</math> i <math>e_2</math>: | ||
<math> | <math> | ||
\frac{e_1, s \,\Longrightarrow | \frac{e_1, s \,\Longrightarrow, e'_1, s} | ||
{e_1 + e_2, s \,\Longrightarrow | {e_1 + e_2, s \,\Longrightarrow, e'_1 + e_2, s} | ||
\quad \quad | \quad \quad | ||
\frac{e_2, s \,\Longrightarrow | \frac{e_2, s \,\Longrightarrow, e'_2, s} | ||
{e_1 + e_2, s \,\Longrightarrow | {e_1 + e_2, s \,\Longrightarrow, e_1 + e'_2} | ||
\quad \quad | \quad \quad | ||
n_1 + n_2, s \,\Longrightarrow | n_1 + n_2, s \,\Longrightarrow, n, s \quad \mbox{ o ile } n = n_1 + n_2</math> | ||
</math> | |||
Bardziej precyzyjnie mówiąc, małe kroki obliczające obydwa podwyrażenia przeplatają się, i to w dowolny sposób. | Bardziej precyzyjnie mówiąc, małe kroki obliczające obydwa podwyrażenia przeplatają się, i to w dowolny sposób. | ||
Linia 157: | Linia 148: | ||
<math> | <math> | ||
e_1 + e_2, s \,\Longrightarrow | e_1 + e_2, s \,\Longrightarrow, e'_1 + e_2, s | ||
\quad \quad \quad | \quad \quad \quad | ||
e_1 + e_2, s \,\Longrightarrow | e_1 + e_2, s \,\Longrightarrow, e_1 + e'_2, s</math> | ||
</math> | |||
Zauważmy natomiast, że kolejność przeplatania się małych kroków obliczających <math>e_1</math> i <math>e_2</math> nie wpływa w tym przypadku na końcową wartość całego wyrażenia. | Zauważmy natomiast, że kolejność przeplatania się małych kroków obliczających <math>e_1</math> i <math>e_2</math> nie wpływa w tym przypadku na końcową wartość całego wyrażenia. | ||
Linia 167: | Linia 157: | ||
<math> | <math> | ||
\frac{e_1, s \,\Longrightarrow | \frac{e_1, s \,\Longrightarrow, e'_1, s} | ||
{\mathbf{if}\, e_1 \,\mathbf{then}\, e_2 \,\mathbf{else}\, e_3, s \,\Longrightarrow | {\mathbf{if}\, e_1 \,\mathbf{then}\, e_2 \,\mathbf{else}\, e_3, s \,\Longrightarrow, \mathbf{if}\, e'_1 \,\mathbf{then}\, e_2 \,\mathbf{else}\, e_3, s} | ||
</math> | </math> | ||
<math> | <math> | ||
\mathbf{if}\, n \,\mathbf{then}\, e_2 \,\mathbf{else}\, e_3, s \,\Longrightarrow | \mathbf{if}\, n \,\mathbf{then}\, e_2 \,\mathbf{else}\, e_3, s \,\Longrightarrow, e_2, s \quad \mbox{ o ile } n \neq 0 | ||
</math> | </math> | ||
<math> | <math> | ||
\mathbf{if}\, n \,\mathbf{then}\, e_2 \,\mathbf{else}\, e_3, s \,\Longrightarrow | \mathbf{if}\, n \,\mathbf{then}\, e_2 \,\mathbf{else}\, e_3, s \,\Longrightarrow, e_3, s \quad \mbox{ o ile } n = 0 | ||
</math> | </math> | ||
</div></div> | </div></div> | ||
Linia 220: | Linia 210: | ||
<math> | <math> | ||
\mathbf{let}\, z = 5 \,\mathbf{in}\, x+z | \mathbf{let}\, z = 5 \,\mathbf{in}\, x+z \quad \quad \mapsto \quad \quad \mbox{ brak wyniku, odwołanie do niezainicjowanej zmiennej } x | ||
\quad \quad \mapsto \quad \quad \mbox{brak wyniku | |||
zmiennej} | |||
</math> | </math> | ||
Linia 229: | Linia 217: | ||
\quad \quad \mapsto \quad \quad \mbox{wynik} = 4 | \quad \quad \mapsto \quad \quad \mbox{wynik} = 4 | ||
</math> | </math> | ||
<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"> | ||
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span> | |||
<div class="mw-collapsible-content" style="display:none"> | |||
Podobnie jak poprzednio, stan powinien opisywać wartości przypisane zmiennym. | Podobnie jak poprzednio, stan powinien opisywać wartości przypisane zmiennym. | ||
Linia 247: | Linia 233: | ||
<math> | <math> | ||
e, \emptyset \,\Longrightarrow^{*}\, n | e, \emptyset \,\Longrightarrow^{*}\, n</math> | ||
</math> | |||
Będziemy potrzebowac tranzycji dwóch postaci, podobnie jak poprzednio, ale pierwsza postać będzie nieco ogólniejsza: | Będziemy potrzebowac tranzycji dwóch postaci, podobnie jak poprzednio, ale pierwsza postać będzie nieco ogólniejsza: | ||
<math> | <math> | ||
e, s \,\Longrightarrow | e, s \,\Longrightarrow, e', s'</math> | ||
</math> | |||
Tranzycja ta oznacza mały krok w trakcie obliczania wyrażenia <math>e</math> w stanie <math>s</math>, w wyniku którego <math>e</math> wyewoluowało do <math>e'</math>, a nowym stanem jest <math>s'</math>. | Tranzycja ta oznacza mały krok w trakcie obliczania wyrażenia <math>e</math> w stanie <math>s</math>, w wyniku którego <math>e</math> wyewoluowało do <math>e'</math>, a nowym stanem jest <math>s'</math>. | ||
Linia 263: | Linia 247: | ||
<math> | <math> | ||
x, s \,\Longrightarrow | x, s \,\Longrightarrow, n, s \quad \mbox{ o ile } s(x) \mbox{ jest określone i } s(x) = n | ||
</math> | </math> | ||
Linia 270: | Linia 254: | ||
<math> | <math> | ||
\mathbf{let}\, x = n \,\mathbf{in}\, e_2, s \,\Longrightarrow | \mathbf{let}\, x = n \,\mathbf{in}\, e_2, s \,\Longrightarrow, e_2, s[x \mapsto n]</math> | ||
</math> | |||
Notacja <math>s[x \mapsto n]</math> oznacza stan <math>s</math>, który zmodyfikowano przypisując zmiennej <math>x</math> wartość <math>n</math>, niezależnie od tego, czy <math>s(x)</math> było określone, czy nie, i pozostawiając niezmienione wartości dla pozostałych zmiennych. | Notacja <math>s[x \mapsto n]</math> oznacza stan <math>s</math>, który zmodyfikowano przypisując zmiennej <math>x</math> wartość <math>n</math>, niezależnie od tego, czy <math>s(x)</math> było określone, czy nie, i pozostawiając niezmienione wartości dla pozostałych zmiennych. | ||
Linia 289: | Linia 272: | ||
<math> | <math> | ||
\frac{e_1, s \,\Longrightarrow | \frac{e_1, s \,\Longrightarrow, e'_1, s'} | ||
{\mathbf{let}\, x = e_1 \,\mathbf{in}\, e_2, s \,\Longrightarrow | {\mathbf{let}\, x = e_1 \,\mathbf{in}\, e_2, s \,\Longrightarrow, \mathbf{let}\, x = e'_1 \,\mathbf{in}\, e_2, s'} | ||
</math> | </math> | ||
Linia 308: | Linia 291: | ||
<math> | <math> | ||
\mathbf{let}\, x = (\mathbf{let}\, z = 4 \,\mathbf{in}\, z+z+z) \,\mathbf{in}\, z, \emptyset \,\Longrightarrow | \mathbf{let}\, x = (\mathbf{let}\, z = 4 \,\mathbf{in}\, z+z+z) \,\mathbf{in}\, z, \emptyset \,\Longrightarrow, | ||
\mathbf{let}\, x = z+z+z \,\mathbf{in}\, z, \emptyset[z \mapsto 4] \,\Longrightarrow | \mathbf{let}\, x = z+z+z \,\mathbf{in}\, z, \emptyset[z \mapsto 4] \,\Longrightarrow, \quad \ldots \quad \,\Longrightarrow, | ||
\mathbf{let}\, x = 12 \,\mathbf{in}\, z, \emptyset[z \mapsto 4] \,\Longrightarrow | \mathbf{let}\, x = 12 \,\mathbf{in}\, z, \emptyset[z \mapsto 4] \,\Longrightarrow, | ||
12, \emptyset[z \mapsto 4] \,\Longrightarrow | 12, \emptyset[z \mapsto 4] \,\Longrightarrow, | ||
12 ! | 12 ! | ||
</math> | </math> | ||
Linia 326: | Linia 309: | ||
<math> | <math> | ||
\mathbf{let}\, x = n \,\mathbf{in}\, e_2, s \,\Longrightarrow | \mathbf{let}\, x = n \,\mathbf{in}\, e_2, s \,\Longrightarrow, e_2, s[x \mapsto n]</math> | ||
</math> | |||
powinna zostać zastąpiona przez | powinna zostać zastąpiona przez | ||
<math> | <math> | ||
\mathbf{let}\, x = n \,\mathbf{in}\, e_2, s \,\Longrightarrow\, e_2 \,\mathbf{then}\, \mbox{ | \mathbf{let}\, x = n \,\mathbf{in}\, e_2, s \,\Longrightarrow\, e_2 \,\mathbf{then}\, \mbox{przywróć wartość zmiennej x}, s[x \mapsto n]</math> | ||
</math> | |||
czyli potrzebujemy konstrukcji składniowej, która polega na obliczeniu wyrażenia <math>e_2</math>, a następnie na przypisaniu zmiennej <math>x</math> danej wartości. | czyli potrzebujemy konstrukcji składniowej, która polega na obliczeniu wyrażenia <math>e_2</math>, a następnie na przypisaniu zmiennej <math>x</math> danej wartości. | ||
Linia 341: | Linia 322: | ||
e \, ::= \,\, | e \, ::= \,\, | ||
\ldots \,\,|\,\, | \ldots \,\,|\,\, | ||
e \,\mathbf{then}\, x := n | e \,\mathbf{then}\, x := n</math> | ||
</math> | |||
Wyrażenie <math>e \,\mathbf{then}\, x:= n</math> jest w pewnym sensie dualne do <math>\mathbf{let}\, x = n \,\mathbf{in}\, e</math>, gdyż jedyna (choć niewątpliwie istotna) różnica między nimi to kolejność obliczenia <math>e</math> i przypisania wartości na zmienną <math>x</math>. | Wyrażenie <math>e \,\mathbf{then}\, x:= n</math> jest w pewnym sensie dualne do <math>\mathbf{let}\, x = n \,\mathbf{in}\, e</math>, gdyż jedyna (choć niewątpliwie istotna) różnica między nimi to kolejność obliczenia <math>e</math> i przypisania wartości na zmienną <math>x</math>. | ||
Linia 348: | Linia 328: | ||
<math> | <math> | ||
\mathbf{let}\, x = n \,\mathbf{in}\, e_2, s \,\Longrightarrow | \mathbf{let}\, x = n \,\mathbf{in}\, e_2, s \,\Longrightarrow, e_2 \,\mathbf{then}\, x := n', s[x \mapsto n] \quad | ||
\mbox{ o ile } s(x) = n' | \mbox{ o ile } s(x) = n'</math> | ||
</math> | |||
Pewna trudność pojawia się w sytuacji, gdy <math>s(x)</math> jest nieokreślone, czyli gdy zmienna <math>x</math> jest niezainicjowana -- reguła powyższa nie obejmuje wogóle takiej sytuacji. | Pewna trudność pojawia się w sytuacji, gdy <math>s(x)</math> jest nieokreślone, czyli gdy zmienna <math>x</math> jest niezainicjowana -- reguła powyższa nie obejmuje wogóle takiej sytuacji. | ||
Linia 366: | Linia 345: | ||
<math> | <math> | ||
\mathbf{let}\, x = n \,\mathbf{in}\, e_2, s \,\Longrightarrow | \mathbf{let}\, x = n \,\mathbf{in}\, e_2, s \,\Longrightarrow, e_2 \,\mathbf{then}\, x := \bot, s[x \mapsto n] \quad | ||
\mbox{ o ile } s(x) \, \mbox{ jest nieokreślone} | \mbox{ o ile } s(x) \, \mbox{ jest nieokreślone}</math> | ||
</math> | |||
Rozwiązanie to jest odrobinę nieeleganckie, gdyż prawie identyczne reguły musimy napisać dwukrotnie. | Rozwiązanie to jest odrobinę nieeleganckie, gdyż prawie identyczne reguły musimy napisać dwukrotnie. | ||
Linia 374: | Linia 352: | ||
<math> | <math> | ||
\frac{e, s \,\Longrightarrow | \frac{e, s \,\Longrightarrow, e', s'} | ||
{e \,\mathbf{then}\, x := n, s \,\Longrightarrow | {e \,\mathbf{then}\, x := n, s \,\Longrightarrow, e' \,\mathbf{then}\, x:= n, s'} | ||
</math> | </math> | ||
<math> | <math> | ||
n' \,\mathbf{then}\, x := n, s \,\Longrightarrow | n' \,\mathbf{then}\, x := n, s \,\Longrightarrow, n', s[x \mapsto n] | ||
</math> | </math> | ||
<math> | <math> | ||
n' \,\mathbf{then}\, x := \bot, s \,\Longrightarrow | n' \,\mathbf{then}\, x := \bot, s \,\Longrightarrow, n', s' \quad \mbox{ o ile } s(x) | ||
\mbox{ jest określone i } s' = s \setminus \{ (x, s(x)) \} | \mbox{ jest określone i } s' = s \setminus \{ (x, s(x)) \} | ||
</math> | </math> | ||
Linia 408: | Linia 386: | ||
<math> | <math> | ||
n + \bot = \bot + n = \bot | n + \bot = \bot + n = \bot</math> | ||
</math> | |||
Trzeba jednak w takim razie zadbać o to, aby wyrażenie <math>\mathbf{let}\, x = e_1 \,\mathbf{in}\, e_2</math> obliczało się normalnie tylko wtedy, gdy wartość wyrażenia <math>e_1</math> jest różna od <math>\bot</math>. | Trzeba jednak w takim razie zadbać o to, aby wyrażenie <math>\mathbf{let}\, x = e_1 \,\mathbf{in}\, e_2</math> obliczało się normalnie tylko wtedy, gdy wartość wyrażenia <math>e_1</math> jest różna od <math>\bot</math>. | ||
Linia 421: | Linia 398: | ||
<math> | <math> | ||
e, s \,\Longrightarrow | e, s \,\Longrightarrow, e', s' | ||
</math> | </math> | ||
Linia 428: | Linia 405: | ||
<math> | <math> | ||
e, s \,\Longrightarrow | e, s \,\Longrightarrow, e', s ? | ||
</math> | </math> | ||
Linia 434: | Linia 411: | ||
<math> | <math> | ||
\frac{e_1, s \,\Longrightarrow | \frac{e_1, s \,\Longrightarrow, e'_1, s} | ||
{\mathbf{let}\, x = e_1 \,\mathbf{in}\, e_2, s \,\Longrightarrow | {\mathbf{let}\, x = e_1 \,\mathbf{in}\, e_2, s \,\Longrightarrow, \mathbf{let}\, x = e'_1 \,\mathbf{in}\, e_2, s} | ||
</math> | </math> | ||
Linia 443: | Linia 420: | ||
<math> | <math> | ||
\frac{e, s[x \mapsto n] \,\Longrightarrow | \frac{e, s[x \mapsto n] \,\Longrightarrow, e', s[x \mapsto n] } | ||
{\mathbf{let}\, x = n \,\mathbf{in}\, e, s \,\Longrightarrow | {\mathbf{let}\, x = n \,\mathbf{in}\, e, s \,\Longrightarrow, \mathbf{let}\, x = n \,\mathbf{in}\, e', s}</math> | ||
</math> | |||
Okazuje się, że wszystko jest w porządku. Wyrażenie <math>e</math> obliczamy w prawidłowym stanie, tzn. z wartością <math>n</math> przypisaną zmiennej <math>x</math>. | Okazuje się, że wszystko jest w porządku. Wyrażenie <math>e</math> obliczamy w prawidłowym stanie, tzn. z wartością <math>n</math> przypisaną zmiennej <math>x</math>. | ||
Linia 454: | Linia 430: | ||
<math> | <math> | ||
\mathbf{let}\, x = n \,\mathbf{in}\, n', s \,\Longrightarrow | \mathbf{let}\, x = n \,\mathbf{in}\, n', s \,\Longrightarrow, n', s | ||
</math> | </math> | ||
Linia 462: | Linia 438: | ||
</div></div> | </div></div> | ||
== Zadania domowe == | == Zadania domowe == | ||
Linia 480: | Linia 455: | ||
<math> | <math> | ||
e, s \,\Longrightarrow^{*}\, \mathtt{Blad} | e, s \,\Longrightarrow^{*}\, \mathtt{Blad}</math> | ||
</math> | |||
}} | }} | ||
Aktualna wersja na dzień 21:29, 11 wrz 2023
Zawartość
Tematem tych zajęć jest semantyka operacyjna wyrażeń (małe kroki).
Semantyka operacyjna wyrażeń
Ćwiczenie 1
Rozważmy bardzo prosty język wyrażeń, którego składnia opisana jest następującą gramatyką:
Wynikiem wyrażenienia warunkowego jest wartość wyrażenia , o ile wyrażenie oblicza się do wartości różnej od zera; w przeciwnym przypadku wynikiem jest wartość wyrażenia .
Zaproponuj semantykę operacyjną (małe kroki) dla tego języka.
Rozwiązanie
Ćwiczenie 2
Rozszerzmy język wyrażeń z poprzedniego zadania o jedną konstrukcję
Wyrażenie zawiera w sobie deklarację , która stanowi mechanizm wiązania identyfikatorów w naszym języku. Deklaracja wprowadza nową zmienną oraz przypisuje jej wartość. Wartość wyrażenia obliczamy następująco: najpierw oblicza się wartość , podstawia ją za zmienną , a następnie oblicza wyrażenie . Zakresem zmiennej jest wyrażenie , czyli wewnątrz można odwoływać się (wielokrotnie) do zmiennej ; Ogólniej, odwołania do zmiennej w wyrażeniu odnoszą się do "najbliższej" (najbardziej zagnieżdzonej) deklaracji tej zmiennej. Taki mechanizm wiązania identyfikatorów nazywamy wiązaniem statycznym. Przyjmujemy zwykłe (statyczne) reguły przesłaniania zmiennych, np. jeśli w występuje podwyrażenie , to deklaracja "przesłania" deklarację w wyrażeniu .
Zakładamy, że na początku wartości wszystkich zmiennych są nieokreślone, czyli zmienne są niezainicjowane, a odwołanie do niezainicjowanej zmiennej jest uważane za niepoprawne.
{{przyklad|||
Rozwiązanie
Zadania domowe
Ćwiczenie 1
Zapisz wariant 2 semantyki z poprzedniego zadania.
Ćwiczenie 2
Dotychczas wystąpienie błędu podczas obliczania wyrażenia, np. odwołanie do niezainicjowanej zmiennej, powodowało, że wyrażenie nie posiadało wartości (nie było ciągu tranzycji prowadzących do konfiguracji końcowej). Zmodyfikuj którąś z semantyk z poprzednich zadań tak, aby błąd był komunikowany jako jedna z konfiguracji końcowych. To znaczy: jeśli obliczenie wyrażenia w stanie jest niemożliwe bo wystąpił błąd, to
Ćwiczenie 3
Rozważ rozszerzenie języka wyrażeń o wyrażenia boolowskie:
Zaproponuj semantykę małych kroków dla tego języka. Rozważ różne strategie obliczania wyrażeń boolowskich, oraz podejście leniwe. Na przykład w strategii lewostronnej dla , gdy zostało obliczone do , w podejściu leniwym nie ma wogóle potrzeby obliczania .