Semantyka i weryfikacja programów/Ćwiczenia 1: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Sl (dyskusja | edycje)
Nie podano opisu zmian
Sl (dyskusja | edycje)
Nie podano opisu zmian
Linia 42: Linia 42:
{{rozwiazanie||roz1|
{{rozwiazanie||roz1|


<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 89: Linia 90:
a konfiguracje końcowe to <math>\mathbf{Num}</math>.
a konfiguracje końcowe to <math>\mathbf{Num}</math>.


'''Uwaga:''' Tak naprawdę to druga postać tranzycji nie jest
{{
uwaga||uwaga1|
Tak naprawdę to druga postać tranzycji nie jest
niezbędna, gdyż moglibyśmy umówić się, że konfiguracje końcowe
niezbędna, gdyż moglibyśmy umówić się, że konfiguracje końcowe
to <math>\mathbf{Num} \times \mathbf{State}</math>.
to <math>\mathbf{Num} \times \mathbf{State}</math>.
'''(koniec uwagi)'''
}}


<!--
<!--
Linia 115: Linia 118:
</math>
</math>


Zauważmy, że <math>n</math> po prawej stronie to wyrażenie składające się
Symbol <math>n</math> po lewej stronie to wyrażenie składające się
ze stałej, podczas gdy <math>n</math> po prawej stronie reprezentuje liczbę
ze stałej liczbowej, podczas gdy <math>n</math> po prawej stronie reprezentuje liczbę
będącą wartością wyrażenia.
będącą wartością wyrażenia.


Linia 136: Linia 139:
</math>
</math>


Reguły tej postaci będziem zapisywac tak:
Reguły tej postaci będziemy zapisywać tak:


[[
<math>
\frac{e_1, s \,\Longrightarrow\, e'_1, s}
\frac{e_1, s \,\Longrightarrow\, e'_1, s}
{e_1 + e_2, s \,\Longrightarrow\, e'_1 + e_2, s}.
    {e_1 + e_2, s \,\Longrightarrow\, e'_1 + e_2, s}
</math>
</math>


Linia 157: Linia 160:
</math>
</math>


Zauważmy tutaj pewną subtelność, dotyczącą dwóch wystąpień
Zwróćmy tutaj uwagę na pewną subtelność, dotyczącą dwóch wystąpień
symbolu ''+'': pierwsze wystąpienie oznacza jedną z konstrukcji składniowych
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>.
języka, a drugie oznacza operację dodawania w zbiorze <math>\mathbf{Num}</math>.
Pozwalamy sobie na taką kolizję oznaczeń, gdyż nie powinna ona
Pozwalamy sobie na taką kolizję oznaczeń, gdyż nie powinna ona
prowadzić do niejednoznaczności. Pamiętajmy, że składnia języka jest
prowadzić do niejednoznaczności. Pamiętajmy, że składnia języka jest
składnią abstrajkcyjną, więc zamiast <math>e_1 + e_2</math> moglibyśmy równie
składnią abstrakcyjną, więc zamiast <math>e_1 + e_2</math> moglibyśmy równie
dobrze pisać np. <math>{\mathrm{add}}(e_1, e_2)</math>.
dobrze pisać np. <math>{\mathrm{add}}(e_1, e_2)</math> a wtedy reguła
wyglądałaby tak:


Inna możliwą strategią obliczania <math>e_1 + e_2</math> jest strategia
<math>
\mathrm{add}(n_1, n_2), s \,\Longrightarrow\, n, s \quad \mbox{ o ile } n = n_1 + n_2.
</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
''prawostronna'', którą otrzymujemy zastępując pierwsze dwie z trzech
powyższych reguł przez:
powyższych reguł przez:
Linia 223: Linia 231:
</math>
</math>


 
</div></div>
}}
}}


Linia 261: Linia 269:




===== Przykłady =====
===== Przykład =====


<math>
<math>
Linia 285: Linia 293:
{{rozwiazanie||roz2|
{{rozwiazanie||roz2|


<div class="mw-collapsible mw-made=collapsible mw-collapsed"><div class="mw-collapsible-content" style="display:none">


Podobnie jak poprzednio,  
Podobnie jak poprzednio,  
Linia 387: Linia 396:




===== Wariant 1 =====
<br>
'''Wariant 1'''
<br>
 


Wygodne i eleganckie rozwiązanie tego problemu jest możliwe, jeśli  
Wygodne i eleganckie rozwiązanie tego problemu jest możliwe, jeśli  
Linia 414: Linia 426:
</math>
</math>


Zauważmy, że wyrażenie <math>e \,\mathbf{then}\, x:= n</math> jest w pewnym sensie dualne
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 (choc niewątpliwie istotna) różnica  
do <math>\mathbf{let}\, x = n \,\mathbf{in}\, e</math>, gdyż jedyna (choc niewątpliwie istotna) różnica  
między nimi to kolejność obliczenia <math>e</math> i przypisania wartości
między nimi to kolejność obliczenia <math>e</math> i przypisania wartości
Linia 466: Linia 478:




===== Wariant 2 =====
<br>
'''Wariant 2'''
<br>
 


Zanim przejdziemy do kolejnego wariantu, zastanówmy się czy  
Zanim przejdziemy do kolejnego wariantu, zastanówmy się czy  
Linia 501: Linia 516:


Trzeba jednak w takim razie zadbać o to, aby wyrażenie <math>\mathbf{let}\, x = e_1
Trzeba jednak w takim razie zadbać o to, aby wyrażenie <math>\mathbf{let}\, x = e_1
in e_2</math> obliczało się normalnie tylko wtedy, gdy wartość
\,\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>.
wyrażenia <math>e_1</math> jest różna od <math>\bot</math>.




===== Wariant 3 =====
<br>
'''Wariant 3'''
<br>


Zrewidujmy teraz podstawowe założenia, które dotychczas poczyniliśmy.
Zrewidujmy teraz podstawowe założenia, które dotychczas poczyniliśmy.
Linia 568: Linia 585:
Niekiedy jednak rozszerzanie języka będzie zabronione.
Niekiedy jednak rozszerzanie języka będzie zabronione.


 
</div></div>
}}
}}
   
   
Linia 611: Linia 628:
b \, ::= \,\,  
b \, ::= \,\,  
         \mathbf{true}  \,\,|\,\,
         \mathbf{true}  \,\,|\,\,
         \mathbf{true}  \,\,|\,\,
         \mathbf{false}  \,\,|\,\,
         e_1 \leq e_2  \,\,|\,\,
         e_1 \leq e_2  \,\,|\,\,
         \neg b  \,\,|\,\,
         \neg b  \,\,|\,\,
Linia 630: Linia 647:
Rozważ różne strategie obliczania wyrażeń boolowskich, oraz podejście leniwe.
Rozważ różne strategie obliczania wyrażeń boolowskich, oraz podejście leniwe.
Na przykład w strategii lewostronnej dla <math>b_1 \land b_2</math>,
Na przykład w strategii lewostronnej dla <math>b_1 \land b_2</math>,
gdy <math>b_1</math> zostało obliczone do <math>\mathbf{true}</math>, nie ma wogóle potrzeby
gdy <math>b_1</math> zostało obliczone do <math>\mathbf{false}</math>, nie ma wogóle potrzeby
obliczania <math>b_2</math>.
obliczania <math>b_2</math>.

Wersja z 07:56, 8 sie 2006


Zawartość

Tematem tych zajęć jest semantyka operacyjna wyrażeń (małe kroki).


Zadania z rozwiązaniami

Ćwiczenie 1

Rozważmy bardzo prosty język wyrażeń, którego składnia opisana jest następującą gramatyką:

n::=0|1|

x::=(identyfikatory)

e::=n|x|e1+e2|𝐢𝐟e1𝐭𝐡𝐞𝐧e2𝐞𝐥𝐬𝐞e3

Wynikiem wyrażenienia warunkowego 𝐢𝐟e1𝐭𝐡𝐞𝐧e2𝐞𝐥𝐬𝐞e3 jest wartość wyrażenia e2, o ile wyrażenie e1 oblicza się do wartości różnej od zera; w przeciwnym przypadku wynikiem jest wartość wyrażenia e3.

Zaproponuj semantykę operacyjną (małe kroki) dla tego języka.


Rozwiązanie

{{{3}}}


Ćwiczenie 2

Rozszerzmy język wyrażeń z poprzedniego zadania o jedną konstrukcję

e::=|𝐥𝐞𝐭x=e1𝐢𝐧e2

Wyrażenie 𝐥𝐞𝐭x=e1𝐢𝐧e2 zawiera w sobie deklarację x=e1, która stanowi mechanizm wiązania identyfikatorów w naszym języku. Deklaracja x=e1 wprowadza nową zmienną x oraz przypisuje jej wartość. Wartość wyrażenia 𝐥𝐞𝐭x=e1𝐢𝐧e2 obliczamy następująco: najpierw oblicza się wartość e1, podstawia ją na zmienna x, a następnie oblicza wyrażenie e2. Zakresem zmiennej x jest wyrażenie e2, czyli wewnątrz e2 można odwoływać się (wielokrotnie) do zmiennej x; 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 reguły przesłaniania zmiennych. Np., jeśli w e2 występuje podwyrażenie 𝐥𝐞𝐭x=𝐢𝐧e to odwołania do x wewnątrz e odnoszą się do najbliższej deklaracji zmiennej x.

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.


Przykład

𝐥𝐞𝐭x=0𝐢𝐧𝐥𝐞𝐭y=7𝐢𝐧𝐥𝐞𝐭x=y+3𝐢𝐧x+x+ywynik=24 𝐥𝐞𝐭y=5𝐢𝐧𝐥𝐞𝐭x=(𝐥𝐞𝐭y=3𝐢𝐧y+y)𝐢𝐧x+ywynik=11 Parser nie mógł rozpoznać (błąd składni): {\displaystyle \mathbf{let}\, z = 5 \,\mathbf{in}\, x+z \quad \quad \mapsto \quad \quad \mbox{brak wyniku; odwołanie do niezainicjowanej zmiennej}\, x } 𝐥𝐞𝐭x=1𝐢𝐧𝐥𝐞𝐭x=x+x𝐢𝐧x+xwynik=4


Rozwiązanie

{{{3}}}


Zadania domowe

Zadanie 1

Zapisz wariant 2 semantyki z poprzedniego zadania.


Zadanie 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 e w stanie s jest niemożliwe bo wystąpił błąd, to

e,s*Blad


Zadanie 3

Rozważ rozszerzenie języka wyrażeń o wyrażenia boolowskie:

n::=0|1|

x::=(identyfikatory)

b::=𝐭𝐫𝐮𝐞|𝐟𝐚𝐥𝐬𝐞|e1e2|¬b|b1b2

e::=n|x|e1+e2|𝐢𝐟b𝐭𝐡𝐞𝐧e2𝐞𝐥𝐬𝐞e3|𝐥𝐞𝐭x=e1𝐢𝐧e2

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 b1b2, gdy b1 zostało obliczone do 𝐟𝐚𝐥𝐬𝐞, nie ma wogóle potrzeby obliczania b2.