|
|
Linia 41: |
Linia 41: |
| }} | | }} |
|
| |
|
| {{rozwiazanie||roz1|
| |
|
| |
|
| <div class="mw-collapsible mw-made=collapsible mw-collapsed">
| | Powyższy język to tak naprawdę Tiny z wykładu rozszerzony o jedną |
|
| | konstrukcję: pętlę {\bf repeat}. Spróbuj wykonać to ćwiczenie nie |
| <div class="mw-collapsible-content" style="display:none">
| | sięgając do notatek z wykładu. Jeśli napotkasz trudności, odkrywaj |
| | kolejne elementy poniższego opisu. |
| | |
| | Kategorie składniowe występujące w tym języku to: |
| | * wyrażenia Exp |
| | * wyrażenia logiczne BExp |
| | * instrukcje Stmt |
| | * oraz, jak zwykle, stałe liczbowe Num |
| | |
| | Zaczynamy jak zwykle od opisu dziedzin semantycznych. Nie przejmujemy |
| | się na razie szczegółami związanymi z konstrukcjami stałopunktowymi |
| | oraz umieszczeniem pineski we właściwych dziedzinach. Zakładamy, że |
| | wszystkie zmienne są zainicjowane na zero. |
|
| |
|
| '''Funkcje semantyczne:'''
| | Użyjemy elementarnych dziedzin z wykładu: |
| | * Int = \{\ldots, -1, 0, 1, \ldots\} zawierający denotacje stałych |
| | liczbowych |
| | * Bool = \{\tt, \ff\} zawierający wartości logiczne |
| | * Var zawierający wszystkie dozwolone identyfikatory |
|
| |
|
| | <div class="mw-collapsible mw-made=collapsible mw-collapsed"> |
| | Przypomnijmy, że wartość wyrażenia arytmetycznego $e$ zależy od |
| <div class="mw-collapsible-content" style="display:none"> | | <div class="mw-collapsible-content" style="display:none"> |
| __HIDE__
| | wartości wszystkich występujących w nim zmiennych. |
| | | </div> |
| <math>\begin{array} {lcl}
| |
| \mathcal{E} & : & Exp \to Env \to S \to EV + \{err\}\\
| |
| \mathcal{D} & : & Dec \to Env \to S \to Env\times S + \{(err,err)\}\\
| |
| \mathcal{I} & : & Ins \to Env \to S \to S_{\bot} + \{err\}_{\bot}\\
| |
| \end{array} </math>
| |
| </div> | | </div> |
| '''R"ownania:'''<br>
| |
|
| |
|
| <math>\mathcal{E}[\![ n ]\!] = \lambda \varrho\in Env \cdot \lambda s\in S \cdot n</math><br>
| | Wartości te są ,,pamiętane'' w stanie, który jest funkcją ze zbioru |
| | Var w zbiór Int. Zbiór wszystkich stanów to: |
| | \[ State = Var \ra Int \] |
|
| |
|
| <math>\mathcal{E}[\![ x ]\!] = \lambda \varrho\in Env\cdot\lambda s\in S\cdot\\
| | Zdefiniujmy następnie niezbędne funkcje semantyczne. |
| \hspace*{1.5cm}\ \mathrm{if}\ x\not\in
| | * Dla wyrażeń mamy |
| dom(\varrho)\ \mathrm{then}\ err\\
| | \[\E & : & Exp \ra State \ra Int \] |
| \hspace*{1.5cm}\ \mathrm{else}\ \mathrm{if}\ \varrho x\not\in Loc\ \mathrm{then}\ err\\
| | * Dla wyrażeń logicznych: |
| \hspace*{1.5cm}\ \mathrm{else}\ \mathrm{if}\ s(\varrho x)
| | \[\B & : & BExp \ra State \ra Bool \] |
| \not\in\mathbb{N}\ \mathrm{then}\ err\\
| | * Dla instrukcji: |
| \hspace*{1.5cm}\ \mathrm{else}\ s(\varrho x)</math><br>
| | \[\I & : & Stmt \ra Stmt \ra Stmt \] |
| | | * Oraz oczywistą funkcję dla stałych całkowitych: |
| <math>\mathcal{E}[\![ e_1\ {\tt +}\ e_2 ]\!] = \lambda\varrho\in Env\cdot\lambda s\in S\cdot\\
| | \[\Z & : & Num \ra Z \] |
| \hspace*{1.5cm}\ \mathrm{if}\ \mathcal{E}[\![ e_1 ]\!]\varrho s\not\in\mathbb{N}\ \mathrm{or}\
| |
| \mathcal{E}[\![ e_2 ]\!]\varrho s\not\in\mathbb{N}\ \mathrm{then}\ err\\
| |
| \hspace*{1.5cm}\ \mathrm{else}\ \mathcal{E}[\![ e_1 ]\!]\varrho s +\mathcal{E}[\![ e_2 ]\!]\varrho s</math><br>
| |
| | |
| <math>\mathcal{D}[\![ {\tt var}\ x\ {\tt = 0} ]\!] = \lambda\varrho\in Env\cdot\lambda s\in S\cdot\\
| |
| \hspace*{1.5cm}\ \mathrm{if}\ s^{-1}(\{free\})=\emptyset\ \mathrm{then}\ (err,err)\\
| |
| \hspace*{1.5cm}\ \mathrm{else}\ \mathrm{let}\ l = \mathrm{min}(s^{-1}(\{free\}))\\ | |
| \hspace*{1.5cm}\mathrm{in}\ (\varrho[l/x],s[0/l])</math><br>
| |
| | |
| <math>\mathcal{D}[\![ {\tt proc}\ x{\tt (}y{\tt )}\ {\tt \{}\ i\ {\tt \}} ]\!] =
| |
| \lambda\varrho\in Env\cdot\lambda s_0\in S\cdot\\
| |
| \hspace*{1.5cm}\ \mathrm{if}\ x=y\ \mathrm{then}\ (err,err)\\
| |
| \hspace*{1.5cm}\ \mathrm{else}\ \mathrm{let}\ F = \lambda f\in Proc\cdot\\
| |
| \hspace*{1.5cm}\hspace*{0.5cm}\lambda l\in Loc\cdot\lambda s\in S\cdot\\
| |
| \hspace*{1.5cm}\hspace*{1.5cm}\ \mathrm{if}\ s l\not\in\mathbb{N}\ \mathrm{then}\ err\\
| |
| \hspace*{1.5cm}\hspace*{1.5cm}\ \mathrm{else}\ \mathrm{if}\ s^{-1}(\{free\})=\emptyset\ \mathrm{then}\ err\\
| |
| \hspace*{1.5cm}\hspace*{1.5cm}\ \mathrm{else}\ \mathrm{let}\ l'=\mathrm{min}(s^{-1}(\{free\}))\\
| |
| \hspace*{1.5cm}\hspace*{1.5cm}\mathrm{in}\ \mathcal{I}[\![ i ]\!]\varrho[f/x][l'/y]s[s l / l']\\
| |
| \hspace*{1.5cm}\mathrm{in}\ (\varrho[FIX(F)/x],s_0)</math><br>
| |
| | |
| <math>\mathcal{D}[\![ d_1\ {\tt ;}\ d_2 ]\!] = \lambda\varrho\in Env\cdot\lambda s\in S\cdot\\
| |
| \hspace*{1.5cm}\mathrm{let}\ (\varrho',s') = \mathcal{D}[\![ d_1 ]\!]\\
| |
| \hspace*{1.5cm}\mathrm{in}\ \ \mathrm{if}\ \varrho'=err\ \mathrm{then}\ (err,err)\\
| |
| \hspace*{1.5cm}\ \mathrm{else}\ \mathcal{D}[\![ d_2 ]\!]\varrho' s'</math><br>
| |
| | |
| <math>\mathcal{I}[\![ x\ {\tt :=}\ e ]\!] = \lambda\varrho\in Env\cdot\lambda s\in S\cdot\\
| |
| \hspace*{1.5cm}\ \mathrm{if}\ x\not\in dom(\varrho)\ \mathrm{then}\ err\\
| |
| \hspace*{1.5cm}\ \mathrm{else}\ \mathrm{if}\ \varrho x\not\in Loc\ \mathrm{then}\ err\\
| |
| \hspace*{1.5cm}\ \mathrm{else}\ \mathrm{if}\ s(\varrho x)\not\in\mathbb{N}\ \mathrm{then}\ err\\
| |
| \hspace*{1.5cm}\ \mathrm{else}\ \mathrm{if}\ \mathcal{E}[\![ e ]\!]\varrho s\not\in\mathbb{N}\ \mathrm{then}\ err\\
| |
| \hspace*{1.5cm}\ \mathrm{else}\ s[\mathcal{E}[\![ e ]\!]\varrho s/ \varrho x]</math><br>
| |
| | |
| <math>\mathcal{I}[\![ i_1\ {\tt ;}\ i_2 ]\!] = \lambda\varrho\in Env\cdot\lambda s\in S\cdot\\
| |
| \hspace*{1.5cm}\ \mathrm{if}\ \mathcal{I}[\![ i_1 ]\!]\varrho s = err\ \mathrm{then}\ err\\
| |
| \hspace*{1.5cm}\ \mathrm{else}\ \mathcal{I}[\![ i_2 ]\!]\varrho(\mathcal{I}[\![ i_1 ]\!]\varrho s)</math><br>
| |
| | |
| <math>\mathcal{I}[\![ {\tt skip} ]\!] = \lambda\varrho\in Env\cdot\lambda s\in S\cdot s</math><br>
| |
| | |
| <math>\mathcal{I}[\![ {\tt begin}\ d\ {\tt in}\ i\ {\tt end} ]\!] = \lambda\varrho\in
| |
| Env\cdot\lambda s\in S\cdot\\
| |
| \hspace*{1.5cm}\mathrm{let}\ (\varrho',s') = \mathcal{D}[\![ d ]\!]\\
| |
| \hspace*{1.5cm}\mathrm{in}\ \mathrm{if}\ \varrho'=err\ \mathrm{then}\ err\\
| |
| \hspace*{1.5cm}\ \mathrm{else}\ \mathcal{I}[\![ i ]\!]\varrho' s'</math><br>
| |
| | |
| <math>\mathcal{I}[\![ {\tt if}\ e\ {\tt = 0\ then\ }i{\tt\ fi} ]\!] = \lambda\varrho\in
| |
| Env\cdot\lambda s\in S\cdot\\
| |
| \hspace*{1.5cm}\ \mathrm{if}\ \mathcal{E}[\![ e ]\!]\varrho s\not\in\mathbb{N}\ \mathrm{then}\ err\\
| |
| \hspace*{1.5cm}\ \mathrm{else}\ \mathrm{if}\ \mathcal{E}[\![ e ]\!]\varrho s = 0\ \mathrm{then}\ \mathcal{I}[\![ i ]\!]\varrho s\\
| |
| \hspace*{1.5cm}\ \mathrm{else}\ s</math><br>
| |
| | |
| <math>\mathcal{I}[\![ {\tt while}\ e\ {\tt \ne 0\ do}\ i\ {\tt done} ]\!] =
| |
| \lambda\varrho\in Env\cdot\lambda s_0\in S\cdot\\
| |
| \hspace*{1.5cm}\mathrm{let}\ F = \lambda f\in S\to S_{\bot}+\{err\}_{\bot}\cdot\\
| |
| \hspace*{1.5cm}\hspace*{0.5cm} \lambda s\in S\cdot\\
| |
| \hspace*{1.5cm}\hspace*{1.5cm}\mathrm{let}\ n=\mathcal{E}[\![ e ]\!]\varrho s\\
| |
| \hspace*{1.5cm}\hspace*{1.5cm}\mathrm{in}\ \mathrm{if}\ n\not\in\mathbb{N}\ \mathrm{then}\ err\\
| |
| \hspace*{1.5cm}\hspace*{1.5cm}\ \mathrm{else}\ \mathrm{if}\ n = 0\ \mathrm{then}\ s\\
| |
| \hspace*{1.5cm}\hspace*{1.5cm}\ \mathrm{else}\ f s\\
| |
| \hspace*{1.5cm}\mathrm{in} FIX(F) s_0</math><br>
| |
| | |
| <math>\mathcal{I}[\![ {\tt call}\ x_1{\tt (}x_2{\tt )} ]\!] = \lambda \varrho\in
| |
| Env\cdot\lambda s\in S\cdot\\
| |
| \hspace*{1.5cm}\ \mathrm{if}\ x_1\not\in dom(\varrho)\ \mathrm{then}\ err\\
| |
| \hspace*{1.5cm}\ \mathrm{else}\ \mathrm{if}\ \varrho x_1\not\in Proc\ \mathrm{then}\ err\\
| |
| \hspace*{1.5cm}\ \mathrm{else}\ \mathrm{if}\ x_2\not\in dom(\varrho)\ \mathrm{then}\ err\\
| |
| \hspace*{1.5cm}\ \mathrm{else}\ \mathrm{if}\ \varrho x_2\not\in Loc\ \mathrm{then}\ err\\
| |
| \hspace*{1.5cm}\ \mathrm{else}\ \mathrm{if}\ s(\varrho x_2)\not\in\mathbb{N}\ \mathrm{then}\ err\\
| |
| \hspace*{1.5cm}\ \mathrm{else}\ \varrho x_1 (\varrho x_2)</math><br>
| |
| | |
| | |
| </div>
| |
| </div>
| |
| }}
| |
|
| |
|
| === Pętla '''for''' === | | === Pętla '''for''' === |
Semantyka bezpośrednia instrukcji. Konstrukcje iteracyjne.
Pętle while i repeat
Ćwiczenie 1
Zdefiniuj semantykę denotacyjną następującego języka:
Pętla polega na wykonaniu instrukcji i, a następnie wyliczeniu warunku logicznego b. Jeśli warunek jest prawdziwy wykonanie pętli kończy się, w przeciwnym razie powracamy do wykonania instrukcji i.
Powyższy język to tak naprawdę Tiny z wykładu rozszerzony o jedną
konstrukcję: pętlę {\bf repeat}. Spróbuj wykonać to ćwiczenie nie
sięgając do notatek z wykładu. Jeśli napotkasz trudności, odkrywaj
kolejne elementy poniższego opisu.
Kategorie składniowe występujące w tym języku to:
- wyrażenia Exp
- wyrażenia logiczne BExp
- instrukcje Stmt
- oraz, jak zwykle, stałe liczbowe Num
Zaczynamy jak zwykle od opisu dziedzin semantycznych. Nie przejmujemy
się na razie szczegółami związanymi z konstrukcjami stałopunktowymi
oraz umieszczeniem pineski we właściwych dziedzinach. Zakładamy, że
wszystkie zmienne są zainicjowane na zero.
Użyjemy elementarnych dziedzin z wykładu:
- Int = \{\ldots, -1, 0, 1, \ldots\} zawierający denotacje stałych
liczbowych
- Bool = \{\tt, \ff\} zawierający wartości logiczne
- Var zawierający wszystkie dozwolone identyfikatory
Przypomnijmy, że wartość wyrażenia arytmetycznego $e$ zależy od
wartości wszystkich występujących w nim zmiennych.
Wartości te są ,,pamiętane w stanie, który jest funkcją ze zbioru
Var w zbiór Int. Zbiór wszystkich stanów to:
\[ State = Var \ra Int \]
Zdefiniujmy następnie niezbędne funkcje semantyczne.
\[\E & : & Exp \ra State \ra Int \]
\[\B & : & BExp \ra State \ra Bool \]
\[\I & : & Stmt \ra Stmt \ra Stmt \]
- Oraz oczywistą funkcję dla stałych całkowitych:
\[\Z & : & Num \ra Z \]
Pętla for
Ćwiczenie 2
Rozszerzmy język z poprzedniego zadania o instrukcję:
Wykonanie takiej pętli polega na:
- Wyliczeniu wartości wyrażenia .
- Przypisaniu wartości na zmienną .
- Wyliczeniu wartości wyrażenia .
- Jeśli , to pętla kończy się.
- W przeciwnym razie:
- Wykonujemy instrukcję .
- Zwiększamy zmienną o 1.
- Powracamy do punktu 3.
Zauważmy, że wyrażenie jest tu wyliczane tylko raz, ale oblicza się przy każdym obrocie pętli.
Rozwiązanie
{{{3}}}
Ćwiczenie 3
Zmieńmy semantykę instrukcji for z poprzedniego zadania tak, aby
oba wyrażenia obliczały się tylko raz. Tym razem wyliczenie pętli polega na:
- Wyliczeniu wartości wyrażenia .
- Przypisaniu wartości na zmienną .
- Wyliczeniu wartości wyrażenia .
- Jeśli , to pętla kończy się.
- W przeciwnym razie:
- Wykonujemy instrukcję .
- Zwiększamy zmienną o 1.
- Powracamy do punktu 4.
Rozwiązanie
{{{3}}}
O pętli for można jednak myśleć jeszcze inaczej. Można wymagać, aby wszelkie zmiany wartości zmiennej sterującej wewnątrz wykonania pętli nie miały wpływu na liczbę iteracji tej pętli. Przykładowo przy semantyce z poprzedniego zadania pętla:
for x := 1 to 10 do
x := x + 1;
y := y + x;
wykonuje}} się pięć razy, a zmienna y jest zwiększana łącznie o 2+4+6+8+10. Jeśli uznamy, że zmiany zmiennej x wewnątrz pętli nie wpływają na liczbę iteracji, to pętla wykona się 10 razy, a zmienna y zostanie zwiększona o 2+3+4+5+6+7+8+9+10+11.
Ćwiczenie 4
Zdefiniuj taką semantykę.
Rozwiązanie
{{{3}}}
Ćwiczenie 5
W języku C pętla for ma następującą postać:
Jej wykonanie polega na:
- Wykonaniu instrukcji .
- Wyliczeniu wartości wyrażenia .
- Jeśli wyrażenie wylicza się do fałszu, to pętla kończy się.
- W przeciwnym razie:
- Wykonujemy instrukcję .
- Wykonujemy instrukcję .
- Powracamy do punktu 2.
Rozwiązanie
{{{3}}}