Języki formalne i automaty Ćwiczenia 8 Autor: Marcin Orchel Spis treści Spis treści... 1 Wstęp teoretyczny... 2 Konwersja NFA do DFA... 2 Minimalizacja liczby stanów DFA... 4 Konwersja automatu DFA do gramatyki regularnej.... 7 Konwersja gramatyki regularnej do FA... 8 Zadania... 9 Zadania na 3.0... 9 Zadania na 4.0... 9 Zadania na 5.0... 9
Wstęp teoretyczny Konwersja NFA do DFA Dany jest przykładowy niedeterministyczny automat skończony: Automat ten jest niedeterministyczny ponieważ: ze stanu q0 wychodzą dwie tranzycje a ze stanu q0 wychodzą dwie tranzycje b, ze stanu q1 wychodzą dwie tranzycje a, istnieje ε-tranzycja ze stanu q2. Rozpoczynamy konstrukcję DFA: 1. Tworzymy stan q0 automatu DFA odpowiadający stanowi 0 automatu NFA. Ze stanu 0 po przeczytaniu terminala a możemy przejść do stanów 1, lub 2 lub 0. Dlatego tworzymy stan q1 z informacją, że odpowiada on stanom 0,1,2 z DFA. Natomiast po przeczytaniu terminala b możemy dojść do stanów 1 lub 3. Ponieważ w DFA stan 3 był stanem końcowym, a stan q2 odpowiada m.in. stanowi 3, a więc stan q2 również będzie końcowy.
2. Następnie analizujemy nowo powstały stan q1. Za pomocą tranzycji a możemy dojść z niego do stanów 1, 3, 2, 0. Tworzymy stan q3 odpowiadający tym stanom. Stan q3 odpowiada m.in. stanowi końcowemu 3, a więc również będzie końcowy. Za pomocą tranzycji b możemy dojść do 1 lub 3. Stan odpowiadający tym stanom już istnieje, jest to stan q2, dlatego nie tworzymy nowego stanu, tylko prowadzimy tranzycję b do istniejącego. 3. Następnie analizujemy stan q3. Po tranzycji a lub b możemy dojść do stanów 1, 3, 2, 0.
4. Analizujemy stan q2. Po tranzycji a możemy dojść do 1,3, a po tranzycji b możemy dojść do 0,2. Jako, że nie ma stanu, który odpowiada tym stanom tworzymy nowy stan q4. 5. Analizujemy stan q4. Za pomocą tranzycji a możemy dojść do 0, 1, 2. Za pomocą tranzycji b możemy dojść do 1,3. Minimalizacja liczby stanów DFA
Na początku tworzymy stan główny, któremu odpowiadają wszystkie stany automatu wyjściowego DFA. Następnie rozdzielamy ten stan na dwa, jednemu z nich odpowiadają stany końcowe DFA, a drugiemu pozostałe stany DFA. Dla podane przykładu wygląda to następująco: W każdym kroku będziemy próbowali zbiór stanów DFA odpowiadający wybranemu stanowi w drzewie podzielić na dwa podzbiory, z których będą utworzone odpowiednio dwa nowe stany w drzewie. Podział polega na tym, że dla wybranego typu tranzycji jeden podzbiór zawiera stany DFA, z których istnieją tranzycje wybranego typu do pozostałych stanów drzewa. A drugi podzbiór to pozostałe stany DFA w wybranym stanie drzewa. Podział jest możliwy, kiedy oba podzbiory są niepuste. Jeśli istnieją różne możliwości podziału ze względu na wybrany typ tranzycji to wybieramy dowolnie jeden z podziałów. Jeśli dla żadnego stanu i dla żadnej tranzycji podział już nie jest możliwy otrzymaliśmy końcowe drzewo, z którego budujemy automat minimalny DFA. Automat minimalny będzie składał się ze stanów bedącymi liściami tego drzewa. Tranzycje między stanami automatu minimalnego będą odpowiadały odpowiednim tranzycjom z wyjściowego automatu. W podanym przykładzie algorytm będzie wyglądał następująco: Na początku próbujemy rozdzielić grupę Nonfinal. Bierzemy pod uwagę wszystkie terminale po kolei i sprawdzamy czy istnieją tranzycje z tymi terminalami do pozostałych grup. Weźmy pod uwagę terminal b. Z grupy Nonfinal nie ma żadnej tranzycji b do grupy Final, więc bierzemy pod uwagę
kolejny terminal, a. Do grupy Final istnieją dwie tranzycje a, ze stanów 0 i 4. A więc grupę Nonfinal rozdzielamy na dwie, w jednej znajdą się stany 0 i 4, a w drugiej wszystkie pozostałe stany: 1,2,3,5: Grupa 0,4 nie może być rozdzielona, ponieważ gdy wybierzemy zarówno tranzycje a jak i b, to wychodzą one do pozostałych grup z obu stanów 0,4, a więc jeden z podzbiorów byłby pusty.teraz próbujemy rozdzielić grupę 1,2,3,5. Do grupy 0,4 dochodzą od niej tranzycje a oraz b.wybieramy jedną z nich, np. b. Tranzycje b odchodzą ze stanów 2,3,5. A więc tworzymy podzbiór 2,3,5, oraz podzbiór z pozostałymi stanami, a więc podzbiór ze stanem 1: Grupy 2,3,5 nie możemy już rozdzielić, ponieważ gdy wybierzemy typ tranzycji a to nie ma takich tranzycji od tej grupy na zewnątrz. Gdy wybierzemy typ tranzycji b, to ze wszystkich stanów 2,3,5
wychodzą tranzycje b na zewnątrz grupy, a więc podział nie jest możliwy. Kończymy budowę drzewa stanów, ponieważ żadnego liścia nie można już rozdzielić. Wszystkie liście tworzą stany zminimalizowanego automatu pozostało dodać tranzycje pomiędzy tymi stanami. Dodajemy każdą tranzycję z wyjściowego automatu. Ostatecznie otrzymujemy następujący automat: Konwersja automatu DFA do gramatyki regularnej. Mamy dany DFA: W pierwszym kroku każdemu stanowi zostaje przyporządkowany unikalny symbol nieterminalny, przy czym stanowi q0 zostaje przyporządkowany symbol startowy S:
Każdej tranzycji odpowiada jedna produkcja w gramatyce prawostronnie liniowej. Tranzycji a ze stanu q0 odpowiada produkcja S as, itp. Ponadto dla każdego stanu końcowego dodajemy tranzycje do ε. Ostatecznie: S as A ε B ba S ba A ab Konwersja gramatyki regularnej do FA Przykład: Mamy daną gramatykę: S ab S bs S ε B as B bb B a Dla każdego nieterminala tworzymy osobny stan, oraz dodatkowo tworzymy stan, który będzie stanem końcowym. Dla ε-produkcji oraz dla produkcji, które po prawej stronie mają terminal prowadzimy tranzycje do stanu końcowego. W rezultacie otrzymujemy:
Zadania Zadania na 3.0 Skonwertuj podany NFA do DFA: Wyprowadź gramatykę dla tego automatu. Przekonwertuj z powrotem gramatykę do automatu. Dla poniższej gramatyki wyprowadź FA: S A S as A ε A ab B ba Zadania na 4.0 Zadanie 13.1 ze strony http://kompilatory.agh.edu.pl/pages/ta-zadania/%20zadania13- minimalizacja.htm. Zadania na 5.0 Zaimplementować automat NFA z zadania na 3.0 w Javie.