Wersja z 09:33, 23 sie 2006
{Języki kontekstowe i automat liniowo ograniczony. Maszyna Turinga}
ĆWICZENIA 12
Ćwiczenie
Rozważmy maszynę Turinga z wykładu (Przykład 1.2) akceptującą
język palindromów, czyli:
Parser nie mógł rozpoznać (błąd składni): {\displaystyle \displaystyle L=\left\{w \overleftarrow{w} \: : \: w\in \left\{0,1\right\}^*\right\} }
Sprawdź, że
- oraz, że
- .
Wskazówka
Aby wykonać (1) rozpocznij od konfiguracji Parser nie mógł rozpoznać (błąd składni): {\displaystyle \displaystyle \sharp \: s_0 1 \: 01101 \sharp}
a następnie wykonuj przejścia zgodnie z diagramem przejść
maszyny z wykładu.
Rozwiązanie
(Ad. 1) Wykonujemy symulację maszyny na pierwszym ze
słów:
Parser nie mógł rozpoznać (nieznana funkcja „\begin{array}”): {\displaystyle \displaystyle \begin{array} {c c c c c c c c} &\sharp \:s_0 1\: 01101 \sharp & \mapsto & \sharp \sharp \: r_1 0\: 1101 \sharp &\mapsto & \sharp \sharp 0 \: r_1' 1\: 101 \sharp &\mapsto & \sharp \sharp 01 \: r_1' 1\: 01 \sharp \\ \mapsto & \sharp \sharp 011 \: r_1' 0\: 1 \sharp & \mapsto & \sharp \sharp 0110 \: r_1' 1 \: \sharp &\mapsto & \sharp \sharp 0110 1 \: r_1' \sharp &\mapsto & \sharp 0110 \: q_1 1\: \sharp \\ \mapsto & \sharp \sharp 011 \: l 0\: \sharp \sharp & \mapsto & \sharp \sharp 01 \: l 1\: 0 \sharp \sharp &\mapsto & \sharp \sharp 0 \: l 1\: 10 \sharp \sharp &\mapsto & \sharp \sharp \: l 0\: 110 \sharp \sharp \\ \mapsto & \sharp \: l \sharp\: 0110 \sharp \sharp & \mapsto & \sharp\sharp \: s_0 0\: 110 \sharp\sharp &\mapsto & \sharp\sharp\sharp \: r_0 1\: 10 \sharp\sharp &\mapsto & \sharp\sharp\sharp 1 \: r_0' 1\: 0 \sharp\sharp \\ \mapsto & \sharp\sharp\sharp 11 \: r_0' 0\: \sharp\sharp & \mapsto & \sharp\sharp\sharp 110 \: r_0' \sharp\: \sharp &\mapsto & \sharp\sharp\sharp 11 \: q_0 0\: \sharp\sharp &\mapsto & \sharp\sharp\sharp 1 \: l 1\: \sharp\sharp\sharp \\ \mapsto & \sharp\sharp\sharp \: l 1\: 1\sharp\sharp\sharp & \mapsto & \sharp\sharp \: l \sharp \: 1 1\sharp\sharp\sharp &\mapsto & \sharp\sharp\sharp \: s_0 1\: 1\sharp\sharp\sharp &\mapsto & \sharp\sharp\sharp\sharp \: r_1 1\: \sharp\sharp\sharp \\ \mapsto & \sharp\sharp\sharp\sharp 1 \: r_1' \sharp\: \sharp\sharp & \mapsto & \sharp\sharp\sharp\sharp \: q_1 1\: \sharp\sharp\sharp &\mapsto & \sharp\sharp\sharp \: l \sharp \: \sharp\sharp\sharp\sharp &\mapsto & \sharp\sharp\sharp\sharp \: s_0 \sharp\: \sharp\sharp\sharp \\ \mapsto & \sharp\sharp\sharp\sharp \: s_A \sharp\: \sharp\sharp\sharp & \circlearrowleft& \end{array} }
Wykazaliśmy, że Parser nie mógł rozpoznać (błąd składni): {\displaystyle \displaystyle \sharp \:s_0 1\: 01101 \sharp \mapsto^* \sharp\sharp\sharp\sharp \: s_A \sharp\: \sharp\sharp\sharp}
. Stan
zatem wprost z definicji .
(Ad. 2) Wykonujemy identyczną symulację na drugim ze słów:
Parser nie mógł rozpoznać (nieznana funkcja „\begin{array}”): {\displaystyle \displaystyle \begin{array} {c c c c c c c c c} &\sharp \:s_0 1\: 010101 \sharp & \mapsto & \sharp \sharp \: r_1 0\: 10101 \sharp &\mapsto & \sharp \sharp 0 \: r_1' 1\: 0101 \sharp &\mapsto & \sharp \sharp 01 \: r_1' 0\: 101 \sharp &\\ \mapsto & \sharp \sharp 010 \: r_1' 1\: 01 \sharp & \mapsto & \sharp \sharp 0101 \: r_1' 0\: 1 \sharp & \mapsto & \sharp \sharp 01010 \: r_1' 1 \: \sharp &\mapsto & \sharp \sharp 01010 1 \: r_1' \sharp &\\ \mapsto & \sharp 01010 \: q_1 1\: \sharp& \mapsto & \sharp \sharp 0101 \: l 0\: \sharp \sharp & \mapsto & \sharp \sharp 010 \: l 1\: 0 \sharp \sharp &\mapsto & \sharp \sharp 0 1\: l 0\: 10 \sharp \sharp &\\ \mapsto & \sharp \sharp 0 \: l 1\: 010 \sharp \sharp& \mapsto & \sharp \sharp \: l 0\: 1010 \sharp \sharp& \mapsto & \sharp \: l \sharp\: 01010 \sharp \sharp & \mapsto & \sharp\sharp \: s_0 0\: 1010 \sharp\sharp &\\ \mapsto & \sharp\sharp\sharp \: r_0 1\: 010 \sharp\sharp & \mapsto & \sharp\sharp\sharp 1 \: r_0' 0\: 10 \sharp\sharp & \mapsto & \sharp\sharp\sharp 10 \: r_0' 1\: 0 \sharp\sharp & \mapsto & \sharp\sharp\sharp 101 \: r_0' 0\: \sharp\sharp &\\ \mapsto & \sharp\sharp\sharp 1010 \: r_0' \sharp\: \sharp & \mapsto & \sharp\sharp\sharp 101 \: q_0 0\: \sharp\sharp & \mapsto & \sharp\sharp\sharp 10 \: l 1\: \sharp\sharp\sharp & \mapsto & \sharp\sharp\sharp \: 1 l 0\: 1\sharp\sharp\sharp &\\ \mapsto & \sharp\sharp\sharp \: l 1\: 01\sharp\sharp\sharp & \mapsto & \sharp\sharp \: l \sharp \: 101\sharp\sharp\sharp & \mapsto & \sharp\sharp\sharp \: s_0 1\: 01\sharp\sharp\sharp & \mapsto & \sharp\sharp\sharp\sharp \: r_1 0\: 1 \sharp\sharp\sharp &\\ \mapsto & \sharp\sharp\sharp\sharp 0 \: r_1 1\: \sharp\sharp\sharp & \mapsto & \sharp\sharp\sharp\sharp 01 \: r_1' \sharp\: \sharp\sharp & \mapsto & \sharp\sharp\sharp\sharp 0\: q_1 1\: \sharp\sharp\sharp & \mapsto & \sharp\sharp\sharp\sharp \: l 0\: \sharp \sharp\sharp\sharp &\\ \mapsto & \sharp\sharp\sharp \: l \sharp \: 0 \sharp\sharp\sharp\sharp & \mapsto & \sharp\sharp\sharp\sharp \: s_0 0 \: \sharp \sharp\sharp\sharp & \mapsto & \sharp\sharp\sharp\sharp \sharp \: r_0 \sharp \: \sharp\sharp\sharp & \mapsto& \sharp\sharp\sharp\sharp \sharp \: s_R \sharp \: \sharp\sharp\sharp& \circlearrowleft\\ \end{array} }
Na ostatniej otrzymanej konfiguracji maszyna się zatrzymuje (następne konfiguracje są identyczne).
Zatem konfiguracja początkowa Parser nie mógł rozpoznać (błąd składni): {\displaystyle \displaystyle \sharp \:s_0 1\: 010101 \sharp}
prowadzić może poprzez relację tylko do
konfiguracji (obliczeń wykonanych) wypisanych powyżej. Żadna z otrzymanych konfiguracji pośrednich
nie zawiera stanu ze zbioru . To z kolei oznacza, że .
Ćwiczenie
Niech będzie dany alfabet . Zaprojektuj maszynę Turinga akceptująca język postaci:
Parser nie mógł rozpoznać (błąd składni): {\displaystyle \displaystyle L=\left\{u\clubsuit w\: : \: u,w\in \left\{0,1\right\}^*\right\} }
Zaprojektuj maszynę Turinga która akceptuje język . Następnie:
- Wypisz elementy składowe maszyny , tzn. zbiory oraz funkcję przejścia
(zapewnij aby ).
- Wykonaj symulację maszyny na słowie
- słowie
- oraz słowie .
Wskazówka
Projektowana maszyna może działać według schematu:
- Przejdź słowo wejściowe od lewego do prawego ogranicznika.
- Jeśli napotkasz symbol oznacz to w stanach maszyny.
- Jeśli napotkasz symbol ponownie to odrzuć.
- Gdy dotarłeś do prawego ogranicznika i nie napotkałeś to odrzuć, w przeciwnym przypadku akceptuj.
Rozwiązanie
(Ad. 1) Wypiszemy maszynę działającą według zaproponowanego we wskazówce schematu.
Zbiór oraz stan początkowy zostały narzucone treścią zadania. Oznaczamy kolejno
oraz definiujemy funkcję przejścia według tabeli:
Uzupelnij tytul
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Wykonujemy kolejno symulację maszyny Turinga na słowach:
(Ad. 2)
Konfiguracja końcowa jest akceptująca, zatem rzeczywiście .
(Ad. 3)
Żadna z otrzymanych konfiguracji nie była akceptująca, zatem .
(Ad. 4)
Tak jak w poprzednim przypadku .
Ćwiczenie
W trakcie wykładu rozważaliśmy język
Parser nie mógł rozpoznać (błąd składni): {\displaystyle \displaystyle L=\left\{3^k\: : \: k=i\cdot j }
dla pewnych Parser nie mógł rozpoznać (błąd składni): {\displaystyle \displaystyle i,j> 1\right\} }
wykazując, że NP .
Uzasadnij, że także
P
Wskazówka
Zastanów się, ile maksymalnie trzeba wykonać mnożeń aby zweryfikować istnienie dla których
Rozwiązanie
Sprawdzamy wszystkie możliwości. Musimy wykonać maksymalnie (wielomianową ilość) mnożeń. Sama weryfikacja
zależności (według uzasadnienia z wykładu) jest wykonywana w czasie wielomianowym.
Pozostaje zaprojektować deterministyczną maszynę generującą ciągi. Można to zrobić według schematu
(maszyna cztero-taśmowa):
- Taśma nr jest tylko do odczytu. Mamy na niej słowo .
- Rozpocznij od zapisania słowa na taśmie nr i słowa na taśmie nr
- Przepisz słowa na taśmę nr według kolejności taśm .
- Sprawdź na taśmie nr czy . Jeśli tak to akceptuj. Inaczej krok następny.
- Dopisz symbol na taśmie nr . Gdy powstało słowo dłuższe niż dopisz symbol na taśmie nr a słowo
na taśmie nr usuń i zapisz na niej słowo .
- Jeśli słowo na taśmie nr jest dłuższe niż to odrzuć. W przeciwnym przypadku przejdź do kroku Uzupelnic setp3|.
Idea tej maszyny jest bardzo prosta. Wykorzystaj taśmy nr (licznik 1) i (licznik 2) jako liczniki a na taśmie wykonuj symulacje.
Zacznij od stanu liczników na i zwiększaj kolejno licznik 1 a po jego przepełnieniu zeruj go (do wartości początkowej )
i zwiększ licznik . Gdy on także się przepełni, to iloczyn stanów liczników przekracza zatem
można zakończyć generowanie ciągów.
W oczywisty sposób otrzymujemy, że ilość wymaganych kroków czasowych maszyny jest ograniczona przez wielomian (dla dużych ).
Dla małych możemy zawsze rozbudować maszynę tak aby akceptowała słowa bez żadnego testowania.
Zatem P .
Ćwiczenie
Uzasadnij że funkcja jest konstruowalna pamięciowo.
Wskazówka
Przypomnij sobie uzasadnienie dla funkcji z wykładu.
Rozwiązanie
Bierzemy maszynę z wykładu konstruującą funkcję . Dodajemy jedna dodatkową taśmę (oznaczmy taśmy przez oraz ).
Drugą taśmę realizujemy poprzez rozszerzenie alfabetu. Jest to spowodowane faktem, że w definicji konstruowalności
pamięciowej wymagane jest istnienie jedno-taśmowej deterministycznej maszyny Turinga.
Konstruujemy maszynę według schematu
- Jeśli słowo wejściowe jest puste to stop.
- Jeśli słowo wejściowe jest inne niż to odrzuć.
- Przepisz słowo wejściowe tak aby znajdowało się na taśmie a taśma była pusta (gdy zaczynamy symulować
dwie taśmy musimy przejść do innego zestawu symboli w którym rozróżniamy taśmy).
- Kopiujemy słowo wejściowe na taśmę .
- Symulujemy maszynę na taśmie .
- Dopisujemy do taśmy słowo wejściowe. W tym momencie zaznaczyliśmy dokładnie komórek taśmy.
- Zamieniamy symbole na (zapominamy o symulacji taśm), wracamy do lewego markera i przechodzimy
do konfiguracji końcowej .
Po zakończeniu cyklu doszliśmy do konfiguracji co było wymagane w definicji.
Ćwiczenie
Uzasadnij że funkcja jest konstruowalna pamięciowo.
Wskazówka
Wykorzystaj konstruowalność pamięciową funkcji .
Rozwiązanie
Wykorzystujemy trzy taśmy (, , ) oraz maszynę konstruującą pamięciowo funkcję .
Docelowa maszyna działa według schematu.
- Jeśli słowo początkowe jest puste wypisz i zatrzymaj się. W przeciwnym wypadku
wykonaj następny krok.
- Jeśli słowo wejściowe jest inne niż to odrzuć.
- Na taśmie wypisz słowo wejściowe, na taśmach i wypisz słowo .
- Wykonaj symulację maszyny na taśmie oraz dopisz symbol do
taśmy (po jednym przebiegu ilość symboli na taśmie wzrasta trzykrotnie)
- Jeśli słowo na taśmie jest krótsze niż słowo na taśmie wykonaj ponownie krok Uzupelnic step4|.
- W tym momencie na taśmie zostało zaznaczone komórek.
Zamieniamy wypisane symbole na (zapominamy o symulacji taśm), wracamy nad pierwszy symbol (przed lewym markerem)
i przechodzimy do konfiguracji końcowej .
Po zakończeniu cyklu doszliśmy do konfiguracji co było wymagane w definicji konstruowalności
pamięciowej.
Zadania domowe
Ćwiczenie
Skonstruuj maszynę Turinga akceptującą język:
Parser nie mógł rozpoznać (błąd składni): {\displaystyle \displaystyle L_1=\left\{www\: : \: w\in \left\{\circ,\bullet,\star\right\}^*\right\} }
Ćwiczenie
Uzasadnij, że język
Parser nie mógł rozpoznać (błąd składni): {\displaystyle \displaystyle L_2=\left\{w_1 w_1 w_2 w_2 \dots w_n w_n \: : \: w_i \in \left\{\circ,\bullet\right\}^+, n>0 \right\} }
jest rozpoznawany przez pewną niedeterministyczna maszynę Turinga .
Podpowiedź: wykorzystaj konstrukcję z wyrocznią. Dla słowa wejściowego przeprowadź weryfikację w trzech
etapach: konstrukcja słów gdzie (wyrocznia), sklejanie, weryfikacja czy .