Semantyka i weryfikacja programów/Ćwiczenia 2
Ćwiczenia 2: Rozszerzenie języka Tiny (małe kroki)
Zadania z rozwiązaniami
Zadanie 1
Semantyka języka Tiny z wykładu używała funkcji semantycznych dla określenie znaczenia wyrażeń boolowskich i arytmetycznych. Zdefiniuj znaczenie wyrażeń za pomocą semantyki operacyjnej, w stylu małych kroków.
Rozwiązanie
Przypomnijmy składnię wyrażeń boolowskich i arytmetycznych:
Chcemy, aby tranzycje dla wyrażeń były postaci: i podobnie dla wyrażeń boolowskich: gdzie .
Zacznijmy od wyrażeń boolowskich.
Przejdźmy do spójników logicznych, powiedzmy . Ponieważ opisujemy teraz pojedyncze (małe) kroki składające się na wykonanie programu, musimy podać w jakiej kolejności będą się obliczać i . Zacznijmy od strategii lewostronnej:
Możemy zaniechać obliczania jeśli oblicza się do false. Oto odpowiednio zmodyfikowane reguły:
Analogicznie reguły prawostronne to:
Reguły równoległe otrzymujemy jako sumę reguł lewo- i prawostronnych (w sumie 6 reguł). Zauważmy, że obliczanie wyrażeń i odbywa się teraz w twz. przeplocie: Pojedynczy krok polega na wykonaniu jednego kroku obliczenia albo jednego kroku obliczenia . Zwróćmy też uwagę, że nasze tranzycje nie posiadają teraz własności determinizmu: wyrażenie może wyewoluować w pojedyńczym kroku albo do albo do . Na szczęście, końcowy wynik, do jakiego oblicza się wyrażenie jest zawsze taki sam, niezależnie od przeplotu.
Oto reguła dla negacji:
Reguły dla są następujące:
Reguły powyższe zależą od semantyki wyrażen arytmetycznych. Zauważmy, że ponownie pozostawiliśmy dowolność jeśli chodzi o kolejność obliczania wyrażeń arytmetycznych e_1 i e_2.
Rozważmy teraz instrukcję warunkową i instrukcję pętli. Najpierw obliczamy wartość dozoru:
a gdy dozór jest już obliczony, podejmujemy decyzję. W przypadku instrukcji warunkowej reguły są oczywiste:
Gorzej jest w przypadku instukcji pętli. Reguła mogłaby wyglądać tak:
ale nie wiemy już, jaki był dozór pętli (widzimy tylko wynik obliczenia tego dozoru w stanie s, czyli ). Możemy odwołać się do tranzytywnego domknięcia relacji (czyli w zadadzie do semantyki dużych kroków):
Takie rozwiązanie nie jest zatem czystą semantyką małych kroków. Istnieją inne możliwe rozwiązania, w stylu małych kroków, np. przy użyciu rozszerzonej składni. Znalezienie takiego rozwiązania pozostawiamy dociekliwemu czytelnikowi.
Reguły dla operacji arytmetycznych pozostawiamy do napisania Czytelnikowi.
Zadanie 2
Rozszerzmy język Tiny o następujące dobrze znane konstrukcje iteracji:
Napisz semantykę małych kroków dla powyższych konstrukcji. Niedozwolone jest korzystanie z jakiejś konstrukcji w semantyce innej, np.
Rozwiązanie
Zadanie 3
Rozszerz język Tiny o następującą instrukcję pętli:
to instrukcja pętli, stanowi instrukcję wewnętrzną. Instrukcja wychodzi z nabliższej pętli i kontynuuje wykonanie programu od pierwszej instrukcji za tą pętlą. Instrukcje powraca na początek instrukcji wewnętrznej.