|
|
(Nie pokazano 15 wersji utworzonych przez 3 użytkowników) |
Linia 8: |
Linia 8: |
| teoretyczne podstawy teorii rozstrzygalności oraz przeanalizujemy | | teoretyczne podstawy teorii rozstrzygalności oraz przeanalizujemy |
| kilka problemów nierozstrzygalnych w teorii języków. | | kilka problemów nierozstrzygalnych w teorii języków. |
| | |
| | __FORCETOC__ |
|
| |
|
| ==Klasy złożoności obliczeniowej== | | ==Klasy złożoności obliczeniowej== |
Linia 20: |
Linia 22: |
|
| |
|
| {{definicja|1.1|| | | {{definicja|1.1|| |
| Ustalmy funkcje <math>\displaystyle t,s:\mathbb{N}\rightarrow \mathbb{N}</math>. Mówimy, że | | Ustalmy funkcje <math>t,s:\mathbb{N}\rightarrow \mathbb{N}</math>. Mówimy, że |
| maszyna Turinga <math>\displaystyle \mathcal{MT}</math> (deterministyczna lub | | maszyna Turinga <math>\mathcal{MT}</math> (deterministyczna lub |
| niedeterministyczna) '''akceptuje słowo <math>\displaystyle w\in \Sigma_I^*</math> w | | niedeterministyczna) '''akceptuje słowo <math>w\in \Sigma_I^*</math> w |
| czasie <math>\displaystyle t(|w|)</math>''', jeśli istnieje ciąg <math>\displaystyle k\leqslant t(|w|)</math> konfiguracji | | czasie <math>t(|w|)</math>''', jeśli istnieje ciąg <math>k\leqslant t(|w|)</math> konfiguracji |
| <math>\displaystyle d_1,d_2,\dots, d_k</math> takich, że <math>\displaystyle d_1=\sharp s_0 w \sharp</math>, <math>\displaystyle d_k= | | <math>d_1,d_2,\dots, d_k</math> takich, że <math>d_1=\sharp s_0 w \sharp</math>, <math>d_k= |
| \sharp w_{1}s_{F}w_{2}\sharp</math> dla pewnych <math>\displaystyle w_{1},w_{2}\in \Sigma | | \sharp w_{1}s_{F}w_{2}\sharp</math> dla pewnych <math>w_{1},w_{2}\in \Sigma |
| _{T}^{*},s_{F}\in S_{F}</math> oraz <math>\displaystyle d_i \mapsto d_{i+1}</math> dla | | _{T}^{*},s_{F}\in S_{F}</math> oraz <math>d_i \mapsto d_{i+1}</math> dla |
| <math>\displaystyle i=1,\dots,k-1</math>. | | <math>i=1,\dots,k-1</math>. |
|
| |
|
| Jeśli istnieje ciąg konfiguracji <math>\displaystyle d_1 \mapsto d_2 \mapsto \dots | | Jeśli istnieje ciąg konfiguracji <math>d_1 \mapsto d_2 \mapsto \dots |
| \mapsto d_m</math>, gdzie <math>\displaystyle d_1=\sharp s_0 w \sharp</math>, <math>\displaystyle d_m</math> jest | | \mapsto d_m</math>, gdzie <math>d_1=\sharp s_0 w \sharp</math>, <math>d_m</math> jest |
| konfiguracją akceptującą (tzn. <math>\displaystyle d_m= \sharp w_{1}s_{F}w_{2}\sharp</math> | | konfiguracją akceptującą (tzn. <math>d_m= \sharp w_{1}s_{F}w_{2}\sharp</math> |
| dla pewnych <math>\displaystyle w_{1},w_{2}\in \Sigma _{T}^{*},s_{F}\in S_{F}</math>) oraz | | dla pewnych <math>w_{1},w_{2}\in \Sigma _{T}^{*},s_{F}\in S_{F}</math>) oraz |
| dodatkowo <math>\displaystyle |d_i|\leqslant s(|w|)+2</math>, to mówimy, że maszyna <math>\displaystyle \mathcal{MT}</math> | | dodatkowo <math>|d_i|\leqslant s(|w|)+2</math>, to mówimy, że maszyna <math>\mathcal{MT}</math> |
| '''akceptuje słowo <math>\displaystyle w\in \Sigma_I^*</math> w pamięci <math>\displaystyle s(|w|)</math>'''. | | '''akceptuje słowo <math>w\in \Sigma_I^*</math> w pamięci <math>s(|w|)</math>'''. |
|
| |
|
| Mówimy, że '''język <math>\displaystyle L</math> jest akceptowany w czasie <math>\displaystyle t(n)</math> | | Mówimy, że '''język <math>L</math> jest akceptowany w czasie <math>t(n)</math> |
| (pamięci <math>\displaystyle s(n)</math>)''', jeśli istnieje maszyna Turinga <math>\displaystyle \mathcal{MT}</math>, dla | | (pamięci <math>s(n)</math>)''', jeśli istnieje maszyna Turinga <math>\mathcal{MT}</math>, dla |
| której <math>\displaystyle L(\mathcal{MT})=L</math> oraz każde słowo <math>\displaystyle w\in L</math> jest | | której <math>L(\mathcal{MT})=L</math> oraz każde słowo <math>w\in L</math> jest |
| akceptowane w czasie <math>\displaystyle t(|w|)</math> (pamięci <math>\displaystyle s(|w|)</math> odpowiednio). | | akceptowane w czasie <math>t(|w|)</math> (pamięci <math>s(|w|)</math> odpowiednio). |
| }} | | }} |
|
| |
|
Linia 48: |
Linia 50: |
| informacje, a jedynie te, do których następował zapis. Dzięki temu | | informacje, a jedynie te, do których następował zapis. Dzięki temu |
| zabiegowi można w sposób "rozsądny" mówić o akceptacji słowa w | | zabiegowi można w sposób "rozsądny" mówić o akceptacji słowa w |
| pamięci <math>\displaystyle \log n</math> itp. W ujęciu prezentowanym w tym wykładzie | | pamięci <math>\log n</math> itp. W ujęciu prezentowanym w tym wykładzie |
| zajmujemy się akceptacją w pamięci <math>\displaystyle n^k</math>, dla <math>\displaystyle k\geqslant 1</math>, zatem nie ma | | zajmujemy się akceptacją w pamięci <math>n^k</math>, dla <math>k\geqslant 1</math>, zatem nie ma |
| potrzeby dodatkowego definiowania maszyn Turinga off-line. | | potrzeby dodatkowego definiowania maszyn Turinga off-line. |
| }} | | }} |
|
| |
|
| {{definicja|1.2|| | | {{definicja|1.2|| |
| Oznaczmy przez <math>\displaystyle Dtime(t(n))</math> oraz <math>\displaystyle Dspace(s(n))</math> rodzinę języków | | Oznaczmy przez <math>Dtime(t(n))</math> oraz <math>Dspace(s(n))</math> rodzinę języków |
| akceptowanych w czasie <math>\displaystyle t(n)</math> i odpowiednio pamięci <math>\displaystyle s(n)</math> przez | | akceptowanych w czasie <math>t(n)</math> i odpowiednio pamięci <math>s(n)</math> przez |
| deterministyczną maszynę Turinga. Dla maszyn niedeterministycznych | | deterministyczną maszynę Turinga. Dla maszyn niedeterministycznych |
| wprowadzamy w identyczny sposób klasy <math>\displaystyle Ntime(t(n))</math> oraz | | wprowadzamy w identyczny sposób klasy <math>Ntime(t(n))</math> oraz |
| <math>\displaystyle Nspace(s(n))</math>. | | <math>Nspace(s(n))</math>. |
|
| |
|
| Określamy następujące klasy złożoności (klasy języków): | | Określamy następujące klasy złożoności (klasy języków): |
|
| |
|
| <center><math>\displaystyle \aligned \textbd{P} \displaystyle =\bigcup_{k=0}^\infty Dtime(n^k), &\qquad\qquad& | | <center><math>\begin{align} \mathbf{P} =\bigcup_{k=0}^\infty Dtime(n^k), &\qquad\qquad& |
| \textbd{NP} \displaystyle =\bigcup_{k=0}^\infty Ntime(n^k), | | \mathbf{NP} =\bigcup_{k=0}^\infty Ntime(n^k), |
| \\ | | \\ |
| \textbd{PSPACE} \displaystyle =\bigcup_{k=0}^\infty Dspace(n^k), && | | \mathbf{PSPACE} =\bigcup_{k=0}^\infty Dspace(n^k), && |
| \textbd{NSPACE} \displaystyle =\bigcup_{k=0}^\infty Nspace(n^k). | | \mathbf{NSPACE} =\bigcup_{k=0}^\infty Nspace(n^k). |
| \endaligned</math></center> | | \end{align}</math></center> |
|
| |
|
| }} | | }} |
|
| |
|
| Wprost z definicji otrzymujemy zależności '''P''' <math>\displaystyle \subset </math> '''NP''' oraz '''PSPACE''' <math>\displaystyle \subset </math> '''NPSPACE''' . W dalszej części wykładu udowodnimy kilka mniej oczywistych zależności. | | Wprost z definicji otrzymujemy zależności '''P''' <math>\subset</math> '''NP''' oraz '''PSPACE''' <math>\subset</math> '''NPSPACE''' . W dalszej części wykładu udowodnimy kilka mniej oczywistych zależności. |
|
| |
|
| {{przyklad|1.1|| | | {{przyklad|1.1|| |
| Rozważmy język: | | Rozważmy język: |
| <center><math>\displaystyle | | <center><math> |
| L=\left\{1^i 2^j 3^k\: k=i\cdot j,\: i,j\geqslant 1\right\}. | | L = \left\{1^i 2^j 3^k: k=i\cdot j,: i,j\geqslant 1\}\right</math></center> |
| </math></center> | |
|
| |
|
| Język <math>\displaystyle L\in </math> '''P''' . Deterministyczna maszyna Turinga | | Język <math>L\in</math> '''P''' . Deterministyczna maszyna Turinga |
| <math>\displaystyle MT_3</math> akceptująca taki język może wyglądać następująco (zaczynamy | | <math>MT_3</math> akceptująca taki język może wyglądać następująco (zaczynamy |
| od konfiguracji <math>\displaystyle \sharp s_0 w \sharp</math>): | | od konfiguracji <math>\sharp s_0 w \sharp</math>): |
| # Jeśli symbol pod głowicą, to <math>\displaystyle 1</math> zamień go na <math>\displaystyle\sharp</math>. Inaczej odrzuć. | | # Jeśli symbol pod głowicą, to <math>1</math> zamień go na <math>\sharp</math>. Inaczej odrzuć. |
| # Przejdź od lewego ogranicznika do prawego, sprawdzając, czy po <math>\displaystyle 1</math> występuje <math>\displaystyle 1</math> lub <math>\displaystyle 2</math>, po <math>\displaystyle 2</math> tylko <math>\displaystyle 2</math> lub <math>\displaystyle 3</math>, a po <math>\displaystyle 3</math> kolejny symbol <math>\displaystyle 3</math> lub ogranicznik. Jeśli ta zależność nie jest spełniona, odrzuć. Gdy osiągniesz ogranicznik wykonaj następny krok. | | # Przejdź od lewego ogranicznika do prawego, sprawdzając, czy po <math>1</math> występuje <math>1</math> lub <math>2</math>, po <math>2</math> tylko <math>2</math> lub <math>3</math>, a po <math>3</math> kolejny symbol <math>3</math> lub ogranicznik. Jeśli ta zależność nie jest spełniona, odrzuć. Gdy osiągniesz ogranicznik wykonaj następny krok. |
| # Gdy przed ogranicznikiem nie znajduje się symbol <math>\displaystyle 3</math>, odrzuć. W przeciwnym razie zamień symbol <math>\displaystyle 3</math> na <math>\displaystyle \sharp</math>, a następnie poruszaj się w lewo, aż dotrzesz do symbolu innego niż <math>\displaystyle 3</math> i <math>\displaystyle \diamondsuit</math>. | | # Gdy przed ogranicznikiem nie znajduje się symbol <math>3</math>, odrzuć. W przeciwnym razie zamień symbol <math>3</math> na <math>\sharp</math>, a następnie poruszaj się w lewo, aż dotrzesz do symbolu innego niż <math>3</math> i <math>\diamondsuit</math>. |
| # Jeśli symbol do którego dotarłeś to <math>\displaystyle 2</math>, zamień go na <math>\displaystyle \diamondsuit</math>. Sprawdź symbol po lewej. Jeśli to <math>\displaystyle 2</math>, poruszaj się w prawo aż do ogranicznika. Następnie przejdź do kroku 3. | | # Jeśli symbol do którego dotarłeś to <math>2</math>, zamień go na <math>\diamondsuit</math>. Sprawdź symbol po lewej. Jeśli to <math>2</math>, poruszaj się w prawo aż do ogranicznika. Następnie przejdź do kroku 3. |
| # Jeśli dotarłeś do symbolu <math>\displaystyle 1</math>, poruszaj się w lewo aż do ogranicznika. Zamień symbol <math>\displaystyle 1</math> przy ograniczniku na <math>\displaystyle \sharp</math>, a następnie idź w prawo, zamieniając wszystkie symbole <math>\displaystyle \diamondsuit</math> na <math>\displaystyle 2</math>. Gdy dojdziesz do ogranicznika, przejdź do kroku <math>\displaystyle 3</math>. | | # Jeśli dotarłeś do symbolu <math>1</math>, poruszaj się w lewo aż do ogranicznika. Zamień symbol <math>1</math> przy ograniczniku na <math>\sharp</math>, a następnie idź w prawo, zamieniając wszystkie symbole <math>\diamondsuit</math> na <math>2</math>. Gdy dojdziesz do ogranicznika, przejdź do kroku <math>3</math>. |
| # Jeśli dotarłeś do ogranicznika, oznacza to, że skasowano już wszystkie symbole <math>\displaystyle 1</math>. Przejdź w prawo aż do ogranicznika. Jeśli natrafisz na symbol <math>\displaystyle 3</math>, odrzuć. W przeciwnym przypadku, akceptuj. | | # Jeśli dotarłeś do ogranicznika, oznacza to, że skasowano już wszystkie symbole <math>1</math>. Przejdź w prawo aż do ogranicznika. Jeśli natrafisz na symbol <math>3</math>, odrzuć. W przeciwnym przypadku, akceptuj. |
|
| |
|
| Nietrudno zaobserwować, że maszyna <math>\displaystyle MT_3</math> przechodzi przez taśmę w prawo i w lewo tyle | | Nietrudno zaobserwować, że maszyna <math>MT_3</math> przechodzi przez taśmę w prawo i w lewo tyle |
| razy, ile symboli <math>\displaystyle 3</math> zawiera taśma oraz wykonuje jeden dodatkowy | | razy, ile symboli <math>3</math> zawiera taśma oraz wykonuje jeden dodatkowy |
| przebieg na starcie. Zatem słowa z <math>\displaystyle L</math> są akceptowane w | | przebieg na starcie. Zatem słowa z <math>L</math> są akceptowane w |
| czasie ograniczonym wielomianowo. | | czasie ograniczonym wielomianowo. |
| }} | | }} |
Linia 98: |
Linia 99: |
|
| |
|
| Rozważmy teraz język | | Rozważmy teraz język |
| <center><math>\displaystyle | | <center><math> |
| L=\left\{3^k\: : \: k=i\cdot j </math> dla pewnych <math>\displaystyle i,j> 1\rbrace. | | L = \{ 3^k:k=i\cdot j \text{ dla pewnych }i,j> 1\}</math></center> |
| </math></center> | |
|
| |
|
| Najprostszą metodą uzasadnienia, że <math>\displaystyle L\in </math> '''NP''' jest | | Najprostszą metodą uzasadnienia, że <math>L\in</math> '''NP''' jest |
| konstrukcja tak zwanej wyroczni. Polega ona na następującej | | konstrukcja tak zwanej wyroczni. Polega ona na następującej |
| dwuetapowej procedurze: | | dwuetapowej procedurze: |
Linia 109: |
Linia 109: |
|
| |
|
| W naszym przykładzie Etap 1 wygląda następująco: | | W naszym przykładzie Etap 1 wygląda następująco: |
| # Użyj dwóch taśm. Na pierwszej z nich znajduje się <math>\displaystyle 3^k</math>. | | # Użyj dwóch taśm. Na pierwszej z nich znajduje się <math>3^k</math>. |
| # Idź po pierwszej taśmie, wykorzystując niedeterministyczną funkcję przejść. Napotykając <math>\displaystyle 3</math>, możesz wypisać <math>\displaystyle 1</math> na taśmie drugiej i przejść o jedną komórkę w prawo na taśmie pierwszej lub przejść do następnego kroku. Jeśli dotarłeś do prawego ogranicznika taśmy pierwszej, przejdź do kroku 3. | | # Idź po pierwszej taśmie, wykorzystując niedeterministyczną funkcję przejść. Napotykając <math>3</math>, możesz wypisać <math>1</math> na taśmie drugiej i przejść o jedną komórkę w prawo na taśmie pierwszej lub przejść do następnego kroku. Jeśli dotarłeś do prawego ogranicznika taśmy pierwszej, przejdź do kroku 3. |
| # Powróć do początku pierwszej taśmy. Wykonaj sekwencję jak w kroku <math>\displaystyle 2</math>, z tą różnicą, że teraz na drugiej taśmie wypisuj symbole <math>\displaystyle 2</math>. | | # Powróć do początku pierwszej taśmy. Wykonaj sekwencję jak w kroku <math>2</math>, z tą różnicą, że teraz na drugiej taśmie wypisuj symbole <math>2</math>. |
| # Jako ostatnią część tego etapu przekopiuj symbole <math>\displaystyle 3</math> z pierwszej taśmy na drugą (po symbolach <math>\displaystyle 1</math> i <math>\displaystyle 2</math>). | | # Jako ostatnią część tego etapu przekopiuj symbole <math>3</math> z pierwszej taśmy na drugą (po symbolach <math>1</math> i <math>2</math>). |
|
| |
|
| W konstrukcji wykorzystaliśmy dwie taśmy, ale oczywiście w | | W konstrukcji wykorzystaliśmy dwie taśmy, ale oczywiście w |
Linia 120: |
Linia 120: |
|
| |
|
| Etap 2 polega na weryfikacji, czy na taśmie drugiej znajduje się | | Etap 2 polega na weryfikacji, czy na taśmie drugiej znajduje się |
| słowo postaci <math>\displaystyle 1^i 2^j 3^k</math>, gdzie <math>\displaystyle i,j>1</math> oraz <math>\displaystyle k=i\cdot j</math>. Jeśli tak, to słowo wejściowe <math>\displaystyle 3^k</math> pochodziło z języka <math>\displaystyle L</math> i akceptujemy. Można do tego wykorzystać deterministyczną maszynę Turinga, niemal identyczną z opisaną w przykładzie poprzednim. | | słowo postaci <math>1^i 2^j 3^k</math>, gdzie <math>i,j>1</math> oraz <math>k=i\cdot j</math>. Jeśli tak, to słowo wejściowe <math>3^k</math> pochodziło z języka <math>L</math> i akceptujemy. Można do tego wykorzystać deterministyczną maszynę Turinga, niemal identyczną z opisaną w przykładzie poprzednim. |
|
| |
|
| Jeśli słowo wejściowe pochodzi z języka <math>\displaystyle L</math>, to jedno z obliczeń maszyny niedeterministycznej z Etapu 1. prowadzi do konstrukcji odpowiedniego słowa na drugiej taśmie. Nie wiemy, jaka dokładnie ścieżka obliczeń ma być wykorzystana, ale dla akceptacji języka <math>\displaystyle L</math> nie ma to znaczenia. | | Jeśli słowo wejściowe pochodzi z języka <math>L</math>, to jedno z obliczeń maszyny niedeterministycznej z Etapu 1. prowadzi do konstrukcji odpowiedniego słowa na drugiej taśmie. Nie wiemy, jaka dokładnie ścieżka obliczeń ma być wykorzystana, ale dla akceptacji języka <math>L</math> nie ma to znaczenia. |
|
| |
|
| Zastanów się, czy da się wykazać, że także <math>\displaystyle L\in </math> '''P''' | | Zastanów się, czy da się wykazać, że także <math>L\in</math> '''P''' |
| (Ćwiczenie '''1.3''', do tego wykładu). | | (Ćwiczenie '''1.3''', do tego wykładu). |
| }} | | }} |
|
| |
|
| {{definicja|1.3|| | | {{definicja|1.3|| |
| Funkcja <math>\displaystyle s(n)</math> jest '''konstruowalna pamięciowo''', jeśli istnieje maszyna Turinga <math>\displaystyle \mathcal{MT}=(\Sigma _{T},S,f,s_{0},S_{F})</math>, dla | | Funkcja <math>s(n)</math> jest '''konstruowalna pamięciowo''', jeśli istnieje maszyna Turinga <math>\mathcal{MT}=(\Sigma _{T},S,f,s_{0},S_{F})</math>, dla |
| której <math>\displaystyle d_1 \mapsto^* d_2</math>, gdzie <math>\displaystyle d_1=\sharp s_0 1^n \sharp</math>, | | której <math>d_1 \mapsto^* d_2</math>, gdzie <math>d_1=\sharp s_0 1^n \sharp</math>, |
| <math>\displaystyle d_2=\sharp s_1 1^{s(n)} w \sharp</math> dla <math>\displaystyle s_1\in S_F</math>, <math>\displaystyle w\in | | <math>d_2=\sharp s_1 1^{s(n)} w \sharp</math> dla <math>s_1\in S_F</math>, <math>w\in |
| (\Sigma_T\setminus \left\{1\right\})^*</math> oraz dodatkowo <math>\displaystyle d_2</math> jest | | (\Sigma_T\setminus \left\{1\right\})^*</math> oraz dodatkowo <math>d_2</math> jest |
| konfiguracją końcową. | | konfiguracją końcową. |
| }} | | }} |
|
| |
|
| Inaczej mówiąc, funkcję <math>\displaystyle s(n)</math> nazywamy konstruowalną pamięciowo, jeśli istnieje maszyna Turinga <math>\displaystyle \mathcal{MT}</math>, otrzymując na wejściu | | Inaczej mówiąc, funkcję <math>s(n)</math> nazywamy konstruowalną pamięciowo, jeśli istnieje maszyna Turinga <math>\mathcal{MT}</math>, otrzymując na wejściu |
| słowo <math>\displaystyle w</math> długości <math>\displaystyle |w|=n</math>, zaznacza na taśmie roboczej <math>\displaystyle s(n)</math> klatek i zatrzymuje się (akceptując słowo <math>\displaystyle w</math>). | | słowo <math>w</math> długości <math>|w|=n</math>, zaznacza na taśmie roboczej <math>s(n)</math> klatek i zatrzymuje się (akceptując słowo <math>w</math>). |
|
| |
|
| {{przyklad|1.3|| | | {{przyklad|1.3|| |
| Funkcja <math>\displaystyle s(n)=2n</math> jest konstruowalna pamięciowo. Maszyna <math>\displaystyle MT_4</math>, | | Funkcja <math>s(n)=2n</math> jest konstruowalna pamięciowo. Maszyna <math>MT_4</math>, |
| która konstruuje <math>\displaystyle s(n)</math> działa według schematu: | | która konstruuje <math>s(n)</math> działa według schematu: |
| # Przejdź do prawego markera. Jeśli napotkano symbol inny niż <math>\displaystyle 1</math>, to odrzuć. | | # Przejdź do prawego markera. Jeśli napotkano symbol inny niż <math>1</math>, to odrzuć. |
| # Idź w lewo aż do pierwszego symbolu <math>\displaystyle 1</math> lub markera <math>\displaystyle \sharp</math> | | # Idź w lewo aż do pierwszego symbolu <math>1</math> lub markera <math>\sharp</math> |
| # Jeśli napotkałeś symbol <math>\displaystyle 1</math>, zamień go na <math>\displaystyle \clubsuit</math> i przejdź do prawego markera. Dopisz do słowa symbol <math>\displaystyle \clubsuit</math> (zwiększając tym samym długość słowa na taśmie o <math>\displaystyle 1</math>). Następnie powtórz cykl od <math>\displaystyle 2</math>. | | # Jeśli napotkałeś symbol <math>1</math>, zamień go na <math>\clubsuit</math> i przejdź do prawego markera. Dopisz do słowa symbol <math>\clubsuit</math> (zwiększając tym samym długość słowa na taśmie o <math>1</math>). Następnie powtórz cykl od <math>2</math>. |
| # Jeśli napotkałeś marker, idź w prawo, zamieniając wszystkie wystąpienia <math>\displaystyle \clubsuit</math> na <math>\displaystyle 1</math>. Następnie wracaj do lewego markera i zatrzymaj się, akceptując. | | # Jeśli napotkałeś marker, idź w prawo, zamieniając wszystkie wystąpienia <math>\clubsuit</math> na <math>1</math>. Następnie wracaj do lewego markera i zatrzymaj się, akceptując. |
|
| |
|
| }} | | }} |
Linia 151: |
Linia 151: |
| {{kotwica|tw.1.1|}}{{twierdzenie|1.1 liniowa kompresja pamięci|| | | {{kotwica|tw.1.1|}}{{twierdzenie|1.1 liniowa kompresja pamięci|| |
|
| |
|
| Niech będzie dany język <math>\displaystyle L</math> oraz maszyna Turinga | | Niech będzie dany język <math>L</math> oraz maszyna Turinga |
| <math>\displaystyle \mathcal{TM}</math> akceptująca <math>\displaystyle L</math> w pamięci <math>\displaystyle s(n)</math>. Dla dowolnego | | <math>\mathcal{TM}</math> akceptująca <math>L</math> w pamięci <math>s(n)</math>. Dla dowolnego |
| <math>\displaystyle \varepsilon>0</math> istnieje maszyna Turinga <math>\displaystyle \mathcal{TM}'</math> akceptująca <math>\displaystyle L</math> w | | <math>\varepsilon>0</math> istnieje maszyna Turinga <math>\mathcal{TM}'</math> akceptująca <math>L</math> w |
| pamięci <math>\displaystyle \max\left\{n,\varepsilon s(n)\right\}</math>. | | pamięci <math>\max\left\{n,\varepsilon s(n)\right\}</math>. |
| }} | | }} |
|
| |
|
| {{dowod||| | | {{dowod||| |
| (''Szkic'') | | (''Szkic'') |
| Ustalamy liczbę naturalną <math>\displaystyle k</math>, dla której <math>\displaystyle \varepsilon k\geqslant 2</math>. Maszynę | | Ustalamy liczbę naturalną <math>k</math>, dla której <math>\varepsilon k\geqslant 2</math>. Maszynę |
| <math>\displaystyle \mathcal{TM}'</math> definiujemy następująco: | | <math>\mathcal{TM}'</math> definiujemy następująco: |
| # Przekoduj słowo wejściowe, łącząc po <math>\displaystyle r</math> kolejnych symboli w jeden blok stanowiący nowy symbol na taśmie. | | # Przekoduj słowo wejściowe, łącząc po <math>r</math> kolejnych symboli w jeden blok stanowiący nowy symbol na taśmie. |
| # Symuluj maszynę <math>\displaystyle \mathcal{MT}</math> na skompresowanej taśmie. Położenie głowicy wewnątrz bloku zakoduj w stanach maszyny <math>\displaystyle \mathcal{MT}'</math>. | | # Symuluj maszynę <math>\mathcal{MT}</math> na skompresowanej taśmie. Położenie głowicy wewnątrz bloku zakoduj w stanach maszyny <math>\mathcal{MT}'</math>. |
|
| |
|
| Zauważmy, że w kroku <math>\displaystyle 1</math>. maszyna <math>\displaystyle \mathcal{MT}'</math> wykorzystuje <math>\displaystyle n</math> | | Zauważmy, że w kroku <math>1</math>. maszyna <math>\mathcal{MT}'</math> wykorzystuje <math>n</math> |
| komórek pamięci do odczytania słowa wejściowego. Kompresja taśmy | | komórek pamięci do odczytania słowa wejściowego. Kompresja taśmy |
| zapewnia, że podczas symulowania maszyny <math>\displaystyle \mathcal{MT}</math> nie | | zapewnia, że podczas symulowania maszyny <math>\mathcal{MT}</math> nie |
| wykorzystamy więcej niż <math>\displaystyle \lceil \frac{s(n)}{k}\rceil \leqslant \varepsilon s(n)</math> | | wykorzystamy więcej niż <math>\lceil \frac{s(n)}{k}\rceil \leqslant \varepsilon s(n)</math> |
| komórek. Jednocześnie można założyć, że <math>\displaystyle \mathcal{MT}'</math> akceptuje | | komórek. Jednocześnie można założyć, że <math>\mathcal{MT}'</math> akceptuje |
| słowa wejściowe z języka <math>\displaystyle L</math> o długości mniejszej niż <math>\displaystyle k</math> bez | | słowa wejściowe z języka <math>L</math> o długości mniejszej niż <math>k</math> bez |
| symulowania <math>\displaystyle \mathcal{MT}</math>. | | symulowania <math>\mathcal{MT}</math>. |
| }} | | }} |
|
| |
|
| {{twierdzenie|1.2 Savitch|| | | {{twierdzenie|1.2 Savitch|| |
|
| |
|
| Dla dowolnej funkcji <math>\displaystyle s(n)</math> konstruowalnej pamięciowo spełniającej | | Dla dowolnej funkcji <math>s(n)</math> konstruowalnej pamięciowo spełniającej |
| warunek <math>\displaystyle s(n)\geqslant \log_2 n</math> prawdziwa jest inkluzja | | warunek <math>s(n)\geqslant \log_2 n</math> prawdziwa jest inkluzja |
| <math>\displaystyle Nspace(s(n))\subset DSpace(s^2(n))</math>. | | <math>Nspace(s(n))\subset DSpace(s^2(n))</math>. |
| }} | | }} |
|
| |
|
| {{dowod||| | | {{dowod||| |
| Niech <math>\displaystyle \mathcal{NMT}</math> będzie niedeterministyczną maszyną Turinga | | Niech <math>\mathcal{NMT}</math> będzie niedeterministyczną maszyną Turinga |
| akceptującą język <math>\displaystyle L=L(\mathcal{NMT})</math> w pamięci <math>\displaystyle s(n)</math>. Niech | | akceptującą język <math>L=L(\mathcal{NMT})</math> w pamięci <math>s(n)</math>. Niech |
| <math>\displaystyle k(n)</math> oznacza liczbę konfiguracji potrzebną do zaakceptowania słowa | | <math>k(n)</math> oznacza liczbę konfiguracji potrzebną do zaakceptowania słowa |
| o długości <math>\displaystyle n</math>. Istnieje liczba <math>\displaystyle c>1</math>, dla której <math>\displaystyle k(n)\leqslant c^{s(n)}</math>, co z kolei oznacza, że każde słowo o długości <math>\displaystyle n</math> jest akceptowane w <math>\displaystyle c^{s(n)}</math> krokach czasowych. | | o długości <math>n</math>. Istnieje liczba <math>c>1</math>, dla której <math>k(n)\leqslant c^{s(n)}</math>, co z kolei oznacza, że każde słowo o długości <math>n</math> jest akceptowane w <math>c^{s(n)}</math> krokach czasowych. |
| }} | | }} |
| Rozważmy algorytm: | | Rozważmy algorytm: |
|
| |
|
| {{algorytm||| | | {{algorytm||| |
| 1 Wejście: słowo <math>\displaystyle w</math> długości <math>\displaystyle |w|=n</math> | | 1 Wejście: słowo <math>w</math> długości <math>|w|=n</math> |
| 2 oblicz <math>\displaystyle s(n)</math> | | 2 oblicz <math>s(n)</math> |
| 3 '''for''' każda konfiguracja akceptująca <math>\displaystyle d_A</math> dla której <math>\displaystyle |d_A|\leqslant s(n)</math> | | 3 '''for''' każda konfiguracja akceptująca <math>d_A</math> dla której <math>|d_A|\leqslant s(n)</math> |
| 4 '''do if''' Test(<math>\displaystyle \sharp s_0 w \sharp</math>, <math>\displaystyle d_A</math>, <math>\displaystyle s(n) \log_2 c</math>) '''then''' akceptuj | | 4 '''do if''' Test(<math>\sharp s_0 w \sharp</math>, <math>d_A</math>, <math>s(n) \log_2 c</math>) '''then''' akceptuj |
| }} | | }} |
|
| |
|
| gdzie procedura Test ma następującą postać: | | gdzie procedura Test ma następującą postać: |
|
| |
|
| {{algorytm|'''Procedure''' Test(<math>\displaystyle d</math>,<math>\displaystyle d'</math>,<math>\displaystyle i</math>)|| | | {{algorytm|'''Procedure''' Test(<math>d</math>,<math>d'</math>,<math>i</math>)|| |
| 1 '''if''' <math>\displaystyle i=0</math> '''and''' [ (<math>\displaystyle d=d'</math>) '''or''' (<math>\displaystyle d\mapsto d'</math>)] '''then return true''' | | 1 '''if''' <math>i=0</math> '''and''' [ (<math>d=d'</math>) '''or''' (<math>d\mapsto d'</math>)] '''then return true''' |
| 2 '''else for''' każda konfiguracja <math>\displaystyle d''</math> dla której <math>\displaystyle |d''|\leqslant s(n)</math> | | 2 '''else for''' każda konfiguracja <math>d''</math> dla której <math>|d''|\leqslant s(n)</math> |
| 3 '''do if''' Test(<math>\displaystyle d</math>,<math>\displaystyle d''</math>,<math>\displaystyle i-1</math>) '''and''' Test <math>\displaystyle d''</math>,<math>\displaystyle d'</math>,<math>\displaystyle i-1</math>) | | 3 '''do if''' Test(<math>d</math>,<math>d''</math>,<math>i-1</math>) '''and''' Test <math>d''</math>,<math>d'</math>,<math>i-1</math>) |
| 4 '''then return true'''; | | 4 '''then return true'''; |
| 5 '''return false''' | | 5 '''return false''' |
Linia 208: |
Linia 208: |
| maszyny Turinga. Założenie dotyczące konstruowalności pamięciowej | | maszyny Turinga. Założenie dotyczące konstruowalności pamięciowej |
| jest istotnie wykorzystywane w tej konstrukcji przy implementacji | | jest istotnie wykorzystywane w tej konstrukcji przy implementacji |
| linii 3 algorytmu i linii 2 procedury Test. Musimy zaznaczyć <math>\displaystyle s(n)</math> | | linii 3 algorytmu i linii 2 procedury Test. Musimy zaznaczyć <math>s(n)</math> |
| komórek taśmy, aby móc konstruować konfiguracje o długości | | komórek taśmy, aby móc konstruować konfiguracje o długości |
| ograniczonej przez <math>\displaystyle s(n)</math> i móc następnie wykonywać na nich | | ograniczonej przez <math>s(n)</math> i móc następnie wykonywać na nich |
| symulację maszyny <math>\displaystyle \mathcal{NMT}</math>. | | symulację maszyny <math>\mathcal{NMT}</math>. |
|
| |
|
| Zauważmy, że ilość konfiguracji jest ograniczona przez <math>\displaystyle s(n)</math>, a | | Zauważmy, że ilość konfiguracji jest ograniczona przez <math>s(n)</math>, a |
| głębokość rekursji przez <math>\displaystyle \log c^{s(n)}</math>. Oznacza to, że jesteśmy w | | głębokość rekursji przez <math>\log c^{s(n)}</math>. Oznacza to, że jesteśmy w |
| stanie skonstruować maszynę Turinga, która wymaga <math>\displaystyle c' s^2(n)</math> pamięci, gdzie <math>\displaystyle c'</math> jest pewną stałą. Na mocy Twierdzenia [[#tw.1.1|1.1]] jesteśmy w stanie określić maszynę <math>\displaystyle \mathcal{MT}</math> działającą w pamięci <math>\displaystyle s^2(n)</math>. | | stanie skonstruować maszynę Turinga, która wymaga <math>c' s^2(n)</math> pamięci, gdzie <math>c'</math> jest pewną stałą. Na mocy Twierdzenia [[#tw.1.1|1.1]] jesteśmy w stanie określić maszynę <math>\mathcal{MT}</math> działającą w pamięci <math>s^2(n)</math>. |
|
| |
|
| {{wniosek|1.1|| | | {{wniosek|1.1|| |
| <center> '''PSPACE''' <math>\displaystyle = </math> '''NPSPACE''' </center> | | <center> '''PSPACE''' <math>=</math> '''NPSPACE''' </center> |
|
| |
|
| }} | | }} |
|
| |
|
| {{lemat|1.1|| | | {{lemat|1.1|| |
| Jeśli <math>\displaystyle g(n)\geqslant n</math>, to <math>\displaystyle Dtime(g(n))\subset Dspace(g(n))</math> oraz | | Jeśli <math>g(n)\geqslant n</math>, to <math>Dtime(g(n))\subset Dspace(g(n))</math> oraz |
| <math>\displaystyle Ntime(g(n))\subset Nspace(g(n))</math>. | | <math>Ntime(g(n))\subset Nspace(g(n))</math>. |
| }} | | }} |
|
| |
|
| {{dowod||| | | {{dowod||| |
| Niech będzie dana maszyna deterministyczna <math>\displaystyle \mathcal{MT}</math> | | Niech będzie dana maszyna deterministyczna <math>\mathcal{MT}</math> |
| akceptująca dany język <math>\displaystyle L</math> w czasie <math>\displaystyle g(n)</math>. Do akceptacji słowa <math>\displaystyle w</math> | | akceptująca dany język <math>L</math> w czasie <math>g(n)</math>. Do akceptacji słowa <math>w</math> |
| o długości <math>\displaystyle n</math> maszyna wykorzystuje co najwyżej <math>\displaystyle g(n)</math> kroków | | o długości <math>n</math> maszyna wykorzystuje co najwyżej <math>g(n)</math> kroków |
| czasowych, czyli odwiedza co najwyżej <math>\displaystyle g(n)+1</math> komórek taśmy. | | czasowych, czyli odwiedza co najwyżej <math>g(n)+1</math> komórek taśmy. |
|
| |
|
| Na podstawie Twierdzenia [[#tw.1.1|1.1]] istnieje maszyna Turinga | | Na podstawie Twierdzenia [[#tw.1.1|1.1]] istnieje maszyna Turinga |
| <math>\displaystyle \mathcal{MT}'</math> wykorzystująca | | <math>\mathcal{MT}'</math> wykorzystująca |
| <center><math>\displaystyle | | <center><math> |
| \max \left\{n, \frac{1}{2}(g(n)+1)\right\}\leqslant g(n) | | \max \left\{n, \frac{1}{2}(g(n)+1)\right\}\leqslant g(n) |
| </math></center> | | </math></center> |
Linia 244: |
Linia 244: |
|
| |
|
| {{wniosek|1.2|| | | {{wniosek|1.2|| |
| <center> '''P''' <math>\displaystyle \subset </math> '''NP''' <math>\displaystyle \subset | | <center> '''P''' <math>\subset</math> '''NP''' <math>\subset |
| </math> '''PSPACE''' <math>\displaystyle = </math> '''NPSPACE''' </center> | | </math> '''PSPACE''' <math>=</math> '''NPSPACE''' </center> |
|
| |
|
| }} | | }} |
|
| |
|
| {{uwaga|1.2|| | | {{uwaga|1.2|| |
| Nie jest znany przykład wykazujący silną inkluzję '''P''' <math>\displaystyle \varsubsetneq </math> '''NP''' ani dowód wykluczający istnienie takiego przykładu. Powszechnie uznawana | | Nie jest znany przykład wykazujący silną inkluzję '''P''' <math>\varsubsetneq</math> '''NP''' ani dowód wykluczający istnienie takiego przykładu. Powszechnie uznawana |
| hipoteza głosi: | | hipoteza głosi: |
| <center> '''P''' <math>\displaystyle \neq </math> '''NP'''. </center> | | <center> '''P''' <math>\neq</math> '''NP'''. </center> |
|
| |
|
| Rozstrzygnięcie jej prawdziwości lub fałszywości stanowi jeden z | | Rozstrzygnięcie jej prawdziwości lub fałszywości stanowi jeden z |
| najważniejszych, a zarazem najtrudniejszych problemów współczesnej | | najważniejszych, a zarazem najtrudniejszych problemów współczesnej |
| informatyki. Jak widzieliśmy w Przykładzie [[#prz.1.2|1.2]], nawet w | | informatyki. Jak widzieliśmy w Przykładzie [[#prz.1.2|1.2]], nawet w |
| przypadku konkretnego języka <math>\displaystyle L\in </math> '''NP''', problem | | przypadku konkretnego języka <math>L\in</math> '''NP''', problem |
| uzasadnienia, że także <math>\displaystyle L\in </math> '''P''', jest nietrywialny, | | uzasadnienia, że także <math>L\in</math> '''P''', jest nietrywialny, |
| gdyż wymaga zazwyczaj konstrukcji całkiem nowej maszyny Turinga niż | | gdyż wymaga zazwyczaj konstrukcji całkiem nowej maszyny Turinga niż |
| ta do weryfikacji <math>\displaystyle L\in </math> '''NP''' . | | ta do weryfikacji <math>L\in</math> '''NP''' . |
| }} | | }} |
|
| |
|
| ==2. Redukcja i problemy zupełne== | | ==Redukcja i problemy zupełne== |
|
| |
|
| {{definicja|2.1 transformacja wielomianowa|| | | {{definicja|2.1 transformacja wielomianowa|| |
|
| |
|
| Niech <math>\displaystyle L_1,L_2</math> będą dowolnymi językami nad pewnym alfabetem | | Niech <math>L_1,L_2</math> będą dowolnymi językami nad pewnym alfabetem |
| <math>\displaystyle \Sigma_I</math>. Mówimy, że <math>\displaystyle L_1</math> redukuje się do <math>\displaystyle L_2</math> w czasie | | <math>\Sigma_I</math>. Mówimy, że <math>L_1</math> redukuje się do <math>L_2</math> w czasie |
| wielomianowym, co oznaczamy <math>\displaystyle L_1 \propto L_2</math>, gdy istnieje | | wielomianowym, co oznaczamy <math>L_1 \propto L_2</math>, gdy istnieje |
| deterministyczna maszyna Turinga <math>\displaystyle \mathcal{MT}=(\Sigma | | deterministyczna maszyna Turinga <math>\mathcal{MT}=(\Sigma |
| _{T},S,f,s_{0},S_{F})</math> taka, że dla dowolnego <math>\displaystyle w\in \Sigma_I^*</math> | | _{T},S,f,s_{0},S_{F})</math> taka, że dla dowolnego <math>w\in \Sigma_I^*</math> |
| istnieje <math>\displaystyle w'\in \Sigma_I^*</math> i stan <math>\displaystyle s_1\in S_F</math> o własności | | istnieje <math>w'\in \Sigma_I^*</math> i stan <math>s_1\in S_F</math> o własności |
| <center><math>\displaystyle | | <center><math> |
| \sharp s_0 w \sharp \mapsto^* \sharp s_1 w' \sharp | | \sharp s_0 w \sharp \mapsto^* \sharp s_1 w' \sharp |
| </math></center> | | </math></center> |
|
| |
|
| oraz | | oraz |
| <center><math>\displaystyle | | <center><math> |
| w\in L_1 \quad \Longleftrightarrow \quad w' \in L_2. | | w\in L_1 \quad \Longleftrightarrow \quad w' \in L_2</math></center> |
| </math></center> | |
|
| |
|
| }} | | }} |
|
| |
|
| {{lemat|2.1|| | | {{lemat|2.1|| |
| Załóżmy, że <math>\displaystyle L_1 \propto L_2</math>. Wtedy zachodzą implikacje: | | Załóżmy, że <math>L_1 \propto L_2</math>. Wtedy zachodzą implikacje: |
| # <math>\displaystyle L_2 \in </math> '''P''' <math>\displaystyle \quad \Longrightarrow \quad L_1 \in </math> '''P''', | | # <math>L_2 \in</math> '''P''' <math>\quad \Longrightarrow \quad L_1 \in</math> '''P''', |
| # <math>\displaystyle L_2 \in </math> '''NP''' <math>\displaystyle \quad \Longrightarrow \quad L_1 \in </math> '''NP''', | | # <math>L_2 \in</math> '''NP''' <math>\quad \Longrightarrow \quad L_1 \in</math> '''NP''', |
| # <math>\displaystyle L_2 \in </math> '''PSPACE''' <math>\displaystyle \quad \Longrightarrow \quad L_1 \in </math> '''PSPACE'''. | | # <math>L_2 \in</math> '''PSPACE''' <math>\quad \Longrightarrow \quad L_1 \in</math> '''PSPACE'''. |
|
| |
|
| }} | | }} |
|
| |
|
| {{dowod||| | | {{dowod||| |
| Dane słowo <math>\displaystyle w</math> transformujemy do <math>\displaystyle w'</math> w czasie wielomianowym, co gwarantuje założenie <math>\displaystyle L_1 \propto L_2</math>. Dzięki założeniu <math>\displaystyle L_2 \in </math> '''P''' możemy rozstrzygnąć, czy <math>\displaystyle w'\in L_2</math> (tzn. jeśli akceptujemy <math>\displaystyle w'</math>, to robimy to w czasie wielomianowym). Tym sposobem (korzystając z definicji transformacji wielomianowej) akceptujemy <math>\displaystyle w</math> w czasie wielomianowym, o ile tylko <math>\displaystyle w\in L_1</math>. Dowód dla pozostałych implikacji jest identyczny. | | Dane słowo <math>w</math> transformujemy do <math>w'</math> w czasie wielomianowym, co gwarantuje założenie <math>L_1 \propto L_2</math>. Dzięki założeniu <math>L_2 \in</math> '''P''' możemy rozstrzygnąć, czy <math>w'\in L_2</math> (tzn. jeśli akceptujemy <math>w'</math>, to robimy to w czasie wielomianowym). Tym sposobem (korzystając z definicji transformacji wielomianowej) akceptujemy <math>w</math> w czasie wielomianowym, o ile tylko <math>w\in L_1</math>. Dowód dla pozostałych implikacji jest identyczny. |
| }} | | }} |
|
| |
|
| {{definicja|2.2|| | | {{definicja|2.2|| |
| Niech <math>\displaystyle \mathcal{C}</math> oznacza pewną klasę języków. Język <math>\displaystyle L</math> nazywamy '''<math>\displaystyle \mathcal{C}</math>-trudnym''', jeśli spełniony jest warunek: | | Niech <math>\mathcal{C}</math> oznacza pewną klasę języków. Język <math>L</math> nazywamy '''<math>\mathcal{C}</math>-trudnym''', jeśli spełniony jest warunek: |
| <center><math>\displaystyle | | <center><math> |
| \forall\; L' \in \mathcal{C} \quad L'\propto L. | | \forall\; L' \in \mathcal{C} \quad L'\propto L</math></center> |
| </math></center> | |
|
| |
|
| Jeżeli dodatkowo spełniony jest warunek <math>\displaystyle L\in \mathcal{C}</math>, to język <math>\displaystyle L</math> nazywamy '''<math>\displaystyle \mathcal{C}</math>-zupełnym'''. | | Jeżeli dodatkowo spełniony jest warunek <math>L\in \mathcal{C}</math>, to język <math>L</math> nazywamy '''<math>\mathcal{C}</math>-zupełnym'''. |
| }} | | }} |
|
| |
|
| Intuicyjnie, fakt, że język jest <math>\displaystyle \mathcal{C}</math>-zupełny, oznacza, że jest on najbardziej skomplikowany (pod względem obliczeniowym) wśród języków z klasy <math>\displaystyle \mathcal{C}</math>, natomiast język <math>\displaystyle \mathcal{C}</math>-trudny jest bardziej skomplikowany niż każdy z klasy | | Intuicyjnie, fakt, że język jest <math>\mathcal{C}</math>-zupełny, oznacza, że jest on najbardziej skomplikowany (pod względem obliczeniowym) wśród języków z klasy <math>\mathcal{C}</math>, natomiast język <math>\mathcal{C}</math>-trudny jest bardziej skomplikowany niż każdy z klasy |
| <math>\displaystyle \mathcal{C}</math>, choć sam nie musi do niej należeć. | | <math>\mathcal{C}</math>, choć sam nie musi do niej należeć. |
|
| |
|
| {{uwaga|2.1|| | | {{uwaga|2.1|| |
Linia 315: |
Linia 313: |
| {{przyklad|2.1|| | | {{przyklad|2.1|| |
| Rozważmy języki: | | Rozważmy języki: |
| <center><math>\displaystyle | | <center><math> |
| L_1=\left\{1^i 2^j 3^k\: k=i\cdot j,\: i,j\geqslant 1\right\}\quad,\quad | | L_1=\left\{1^i 2^j 3^k: k=i\cdot j,: i,j\geqslant 1\right\}\quad,\quad |
| L_2=\left\{1^i 2^j 4^{2k}\: k=i\cdot j,\: i,j\geqslant 1\right\}. | | L_2=\left\{1^i 2^j 4^{2k}: k=i\cdot j,: i,j\geqslant 1\right\}</math></center> |
| </math></center> | |
|
| |
|
| Języki: <math>\displaystyle L_1</math> oraz <math>\displaystyle L_2</math> wyglądają na bardzo podobne, zatem wydaje się, że <math>\displaystyle L_1 \propto L_2</math> oraz <math>\displaystyle L_2 \propto L_1</math>. Uzasadnienie tego faktu jest prawie natychmiastowe. | | Języki: <math>L_1</math> oraz <math>L_2</math> wyglądają na bardzo podobne, zatem wydaje się, że <math>L_1 \propto L_2</math> oraz <math>L_2 \propto L_1</math>. Uzasadnienie tego faktu jest prawie natychmiastowe. |
| }} | | }} |
| Konstruujemy deterministyczną maszynę Turinga która działa w | | Konstruujemy deterministyczną maszynę Turinga która działa w |
| następujący sposób: | | następujący sposób: |
| # {{kotwica|prz.1|}} Jeśli słowo wejściowe jest puste, to stop. | | # {{kotwica|prz.1|}} Jeśli słowo wejściowe jest puste, to stop. |
| # Przejdź do prawego ogranicznika. Jeśli przy ograniczniku nie występuje symbol <math>\displaystyle 4</math>, to wykonaj krok [[#prz.1|1]]. | | # Przejdź do prawego ogranicznika. Jeśli przy ograniczniku nie występuje symbol <math>4</math>, to wykonaj krok [[#prz.1|1]]. |
| # Jeśli w słowie wejściowym występuje symbol <math>\displaystyle 4</math>, to sprawdź, czy słowo przetwarzane jest postaci <math>\displaystyle \sharp w 4^s \sharp</math>, gdzie <math>\displaystyle s\geqslant 1</math> oraz <math>\displaystyle w\in (\Sigma_I\setminus \left\{4\right\})^*</math> oraz czy dodatkowo <math>\displaystyle s</math> jest liczbą parzystą. Jeśli nie, to wykonaj krok [[#prz.1|1]]. | | # Jeśli w słowie wejściowym występuje symbol <math>4</math>, to sprawdź, czy słowo przetwarzane jest postaci <math>\sharp w 4^s \sharp</math>, gdzie <math>s\geqslant 1</math> oraz <math>w\in (\Sigma_I\setminus \left\{4\right\})^*</math> oraz czy dodatkowo <math>s</math> jest liczbą parzystą. Jeśli nie, to wykonaj krok [[#prz.1|1]]. |
| # Zamień słowo <math>\displaystyle 4^s</math> na słowo <math>\displaystyle 3^{\frac{s}{2}}\sharp^{\frac{s}{2}}</math> i wykonaj krok [[#prz.1|1]]. | | # Zamień słowo <math>4^s</math> na słowo <math>3^{\frac{s}{2}}\sharp^{\frac{s}{2}}</math> i wykonaj krok [[#prz.1|1]]. |
| # Przejdź nad pierwszy symbol po lewym ograniczniku i zatrzymaj się. | | # Przejdź nad pierwszy symbol po lewym ograniczniku i zatrzymaj się. |
|
| |
|
| W ten sposób zawsze przeprowadzamy konfigurację <math>\displaystyle \sharp s_0 w \sharp | | W ten sposób zawsze przeprowadzamy konfigurację <math>\sharp s_0 w \sharp |
| </math> na konfigurację <math>\displaystyle \sharp s_1 w' \sharp</math>, przy czym <math>\displaystyle w'=1^i 2^j 3^k</math> | | </math> na konfigurację <math>\sharp s_1 w' \sharp</math>, przy czym <math>w'=1^i 2^j 3^k</math> |
| tylko, gdy <math>\displaystyle w=1^i 2^j 4^{2k}</math>. Zatem <math>\displaystyle w\in L_2</math> wtedy i tylko wtedy, gdy <math>\displaystyle w'\in L_1</math>. Wykazaliśmy, że <math>\displaystyle L_2 \propto L_1</math>. | | tylko, gdy <math>w=1^i 2^j 4^{2k}</math>. Zatem <math>w\in L_2</math> wtedy i tylko wtedy, gdy <math>w'\in L_1</math>. Wykazaliśmy, że <math>L_2 \propto L_1</math>. |
| | |
| Warunek <math>\displaystyle L_1 \propto L_2</math> otrzymujemy w sposób identyczny. Trzeba
| |
| tylko wypisać odpowiednią ilość symboli <math>\displaystyle 4</math> (a wiemy już, jak
| |
| konstruować liczbę <math>\displaystyle 2n</math>, mając dane <math>\displaystyle n</math>).
| |
| | |
| ==3. Języki maszyn Turinga i rodzina <math>\displaystyle \mathcal{L}_{0}</math>==
| |
| | |
| Powstaje naturalne pytanie o związki pomiędzy klasą
| |
| języków rozpoznawanych przez maszyny Turinga a klasami zadanymi
| |
| poprzez gramatyki. Odpowiemy na to pytanie w tej części
| |
| wykładu.
| |
| | |
| {{twierdzenie|3.1||
| |
| Każdy język akceptowany przez maszynę Turinga jest typu
| |
| '''(0)'''.
| |
| | |
| <center><math>\displaystyle \mathcal{L}(MT)\subset \mathcal{L}_{0}.</math></center>
| |
| | |
| }}
| |
| | |
| {{dowod|||
| |
| Niech <math>\displaystyle L </math> będzie językiem akceptowanym przez maszynę Turinga <math>\displaystyle \mathbf{MT}=(\Sigma _{T},S,f,s_{0},S_{F}) </math> , o której założymy, że
| |
| <math>\displaystyle f(s_{0},\#)=(s',\#,1) </math> , jeśli para <math>\displaystyle (s_{0},\#) </math> należy do
| |
| dziedziny funkcji przejść <math>\displaystyle f </math> maszyny Turinga. Założenie to nie
| |
| ogranicza ogólności rozważań. Wyróżnimy pewien podzbiór <math>\displaystyle \overline{S}_{F} </math> zbioru stanów <math>\displaystyle S </math> , którego elementy,
| |
| jak wskazuje oznaczenie, skojarzone są ze stanami końcowymi. Do
| |
| zbioru <math>\displaystyle \overline{S}_{F} </math> należy każdy stan <math>\displaystyle \overline{s}\in S
| |
| </math> , dla którego istnieje ciąg stanów <math>\displaystyle s_{1}=\overline{s},...,s_{k} </math> dla <math>\displaystyle k\geqslant 1 </math> taki, że <math>\displaystyle (s_{i},\#)\rightarrow (s_{i+1},\#,0) </math> dla <math>\displaystyle k=1,...,k-1 </math> oraz
| |
| <math>\displaystyle (s_{k},\#)\rightarrow (s,\#,1) </math> , gdzie <math>\displaystyle s\in S_{F} </math> .
| |
| Zauważmy, iż wraz ze stanem <math>\displaystyle \overline{s} </math> do zbioru <math>\displaystyle \overline{S}_{F} </math> należą wszystkie elementy ciągu <math>\displaystyle s_{1}=\overline{s},...,s_{k} </math> .
| |
| | |
| Określamy teraz gramatykę <math>\displaystyle G=(V_{N},V_{T},v_{0},P) </math> . Zbiór
| |
| symboli nieterminalnych <math>\displaystyle V_{N} </math> zawiera wyłącznie
| |
| następujące symbole:
| |
| # dla każdego stanu <math>\displaystyle s\in S </math> i <math>\displaystyle a\in \Sigma _{T}\setminus \{\#\} </math> symbole <math>\displaystyle v_{sa},\: ^{\#}v_{sa},\: v_{sa}^{\#},\: ^{\#}v_{sa}^{\#}, </math>
| |
| # dla każdej litery <math>\displaystyle a\in \Sigma _{T}\setminus \{\#\} </math> symbole <math>\displaystyle \, ^{\#}a </math> i <math>\displaystyle a^{\#}, </math>
| |
| # wszystkie elementy zbioru <math>\displaystyle \Sigma _{T}\setminus (\Sigma _{I}\cup \{\#\}), </math>
| |
| # symbole <math>\displaystyle v_{0},\: v_{1} </math> nie należące do <math>\displaystyle \Sigma _{T}. </math>
| |
| | |
| Zbiór praw <math>\displaystyle P </math> składa się z praw wymienionych poniżej:
| |
| # <math>\displaystyle v_{0}\rightarrow \, ^{\#}v_{sa}^{\#} </math> , <math>\displaystyle v_{0}\rightarrow v_{1}v_{sa}^{\#} </math>, jeśli <math>\displaystyle f(s,a)=(\overline{s},b,1) </math> dla pewnego <math>\displaystyle b\in \Sigma _{T}\setminus \{\#\} </math> , <math>\displaystyle \overline{s}\in \overline{S}_{F} </math> ,
| |
| # <math>\displaystyle v_{1}\rightarrow \, ^{\#}a </math> , <math>\displaystyle v_{1}\rightarrow v_{1}a </math> dla każdego <math>\displaystyle a\in \Sigma _{T}\setminus \{\#\} </math> ,
| |
| # <math>\displaystyle v_{s_{1}c}b\rightarrow cv_{sa} </math> , <math>\displaystyle \, ^{\#}v_{s_{1}c}b\rightarrow \, ^{\#}cv_{sa} </math> , <math>\displaystyle v_{s_{1}c}b^{\#}\rightarrow cv^{\#}_{sa} </math> , <math>\displaystyle \, ^{\#}v_{s_{1}c}b^{\#}\rightarrow \, ^{\#}cv^{\#}_{sa} </math>, jeśli <math>\displaystyle f(s,a)=(s_{1},b,-1) </math> i <math>\displaystyle c\in \Sigma _{T}\setminus \{\#\} </math> ,
| |
| # <math>\displaystyle bv_{s_{1}c}\rightarrow v_{sa}c </math> , <math>\displaystyle \, ^{\#}bv_{s_{1}c}\rightarrow \, ^{\#}v_{sa}c </math> , <math>\displaystyle bv_{s_{1}c}^{\#}\rightarrow v_{sa}c^{\#} </math> , <math>\displaystyle \, ^{\#}bv_{s_{1}c}^{\#}\rightarrow \, ^{\#}v_{sa}c^{\#} </math>, jeśli <math>\displaystyle f(s,a)=(s_{1},b,1) </math> i <math>\displaystyle c\in \Sigma _{T}\setminus \{\#\} </math> ,
| |
| # <math>\displaystyle v_{s_{1}b}\rightarrow v_{sa} </math> , <math>\displaystyle \, ^{\#}v_{s_{1}b}\rightarrow \, ^{\#}v_{sa} </math> , <math>\displaystyle v_{s_{1}b}^{\#}\rightarrow v^{\#}_{sa} </math> , <math>\displaystyle \, ^{\#}v_{s_{1}b}^{\#}\rightarrow \, ^{\#}v^{\#}_{sa} </math>, jeśli <math>\displaystyle f(s,a)=(s_{1},b,0) </math> ,
| |
| # <math>\displaystyle v_{s_{1}b}^{\#}\rightarrow v^{\#}_{sa} </math> , <math>\displaystyle \, ^{\#}v_{s_{1}b}^{\#}\rightarrow \, ^{\#}v^{\#}_{sa} </math> , jeśli istnieją <math>\displaystyle s_{1}',...,s_{k}'\in S </math> dla <math>\displaystyle k\geqslant 1 </math>, takie że <math>\displaystyle f(s,a)=(s_{1}',b,1) </math> , <math>\displaystyle f(s_{i}',\#)=(s_{i+1}',\#,0) </math> dla <math>\displaystyle i=1,...,k-1 </math> oraz <math>\displaystyle f(s_{k}',\#)=(s_{1},\#,-1) </math> ,
| |
| # <math>\displaystyle \, ^{\#}v_{s_{1}b}\rightarrow \, ^{\#}v_{sa} </math> , <math>\displaystyle \, ^{\#}v_{s_{1}b}^{\#}\rightarrow \, ^{\#}v^{\#}_{sa} </math> , jeśli istnieją <math>\displaystyle s_{1}',...,s_{k}'\in S </math> dla <math>\displaystyle k\geqslant 1 </math> takie, że <math>\displaystyle f(s,a)=(s_{1}',b,-1) </math> , <math>\displaystyle f(s_{i}',\#)=(s_{i+1}',\#,0) </math> dla <math>\displaystyle i=1,...,k-1 </math> oraz <math>\displaystyle f(s_{k}',\#)=(s_{1},\#,1) </math> ,
| |
| # <math>\displaystyle a^{\#}\rightarrow a </math> dla wszystkich <math>\displaystyle a\in \Sigma _{T}\setminus \{\#\} </math> ,
| |
| # <math>\displaystyle \, ^{\#}v_{sa}\rightarrow a </math> , <math>\displaystyle \, ^{\#}v_{sa}^{\#}\rightarrow a </math> , jeśli <math>\displaystyle f(s_{0},\#)=(s,\#,1) </math> (porównaj założenie na początku dowodu),
| |
| # <math>\displaystyle v_{0}\Rightarrow 1 </math>, jeśli <math>\displaystyle 1\in L </math> .
| |
| | |
| Określona powyżej gramatyka <math>\displaystyle G </math> jest gramatyką typu
| |
| '''(0)'''. Rozważmy teraz dowolne słowo <math>\displaystyle w </math> , dla którego
| |
| istnieje wyprowadzenie w gramatyce <math>\displaystyle G </math> ze stanu
| |
| początkowego <math>\displaystyle v_{0} </math> przy użyciu praw 1-7. Słowo <math>\displaystyle w </math> zawiera
| |
| dokładnie jeden z następujących symboli <math>\displaystyle v_{sa},\,
| |
| ^{\#}v_{sa},v_{sa}^{\#} </math> lub <math>\displaystyle \, ^{\#}v_{sa}^{\#} </math> . Pierwsza
| |
| litera słowa <math>\displaystyle w </math> oznaczona jest markerem <math>\displaystyle \# </math> z lewej
| |
| strony, a ostatnia litera słowa <math>\displaystyle w </math> oznaczona jest markerem <math>\displaystyle \# </math> ze strony prawej. Ponadto żadna z liter występujących pomiędzy
| |
| pierwszą a ostatnią nie jest oznaczona markerem <math>\displaystyle \# </math> . Z każdym
| |
| takim słowem kojarzymy konfigurację poprzez zastąpienie symbolu <math>\displaystyle v_{sa} </math> przez <math>\displaystyle sa </math> oraz przez dopisanie symbolu <math>\displaystyle \# </math> po
| |
| lewej lub prawej stronie znaczonej przez ten marker litery, zgodnie
| |
| z jego występowaniem. Jeśli np. <math>\displaystyle w=\, ^{\#}v_{sa}^{\#} </math> , to
| |
| skojarzona konfiguracja jest postaci <math>\displaystyle \#sa\# </math> . Zauważmy, że
| |
| jeśli słowa <math>\displaystyle u </math> i <math>\displaystyle w </math> są w powyższej formie, to fakt, iż <math>\displaystyle u\mapsto^{*}w </math> , jest równoważny stwierdzeniu, że z
| |
| konfiguracji skojarzonej ze słowem <math>\displaystyle w </math> maszyna Turinga
| |
| <math>\displaystyle MT </math> może przejść (bezpośrednie następstwo) do
| |
| konfiguracji skojarzonej ze słowem <math>\displaystyle u </math> . Każdy krok
| |
| obliczenia realizowanego przez <math>\displaystyle MT </math> ma swój odpowiednik - krok w
| |
| wyprowadzeniu w gramatyce <math>\displaystyle G </math> . Z tym, że wobec praw 6 i 7
| |
| sekwencja obliczeń
| |
| | |
| <center><math>\displaystyle vsa\#\rightarrow vbs_{1}'\#\rightarrow ...\rightarrow
| |
| vbs_{k}'\#\rightarrow vs_{1}b\#</math></center>
| |
| | |
| jest traktowana jako jeden krok w
| |
| obliczeniu prowadzonym przez maszynę Turinga. Analogicznie
| |
| traktujemy sekwencję z markerem <math>\displaystyle \# </math> występującym po lewej
| |
| stronie. Ze stanu początkowego <math>\displaystyle v_{0} </math> gramatyki <math>\displaystyle G </math>
| |
| można wyprowadzić wszystkie słowa <math>\displaystyle w </math> , dla których konfiguracja
| |
| jest równa <math>\displaystyle \#vsa\# </math>, dla pewnego <math>\displaystyle v\in (\Sigma _{I}\setminus
| |
| \{\#\})^{*} </math> oraz maszyna Turinga realizuje obliczenie:
| |
| | |
| <center><math>\displaystyle sa\#\rightarrow bs_{1}'\#\rightarrow ...\rightarrow
| |
| bs_{k}'\#\rightarrow b\#s_{1},\quad s_{1}\in S_{F}.</math></center>
| |
| | |
| Wynika to z
| |
| praw 1 i 2 skonstruowanej gramatyki <math>\displaystyle G </math> . Z kolei prawa
| |
| typu 9 służą do zastąpienia symboli nieterminalnych typu
| |
| <math>\displaystyle \, ^{\#}v_{sa},\, ^{\#}v_{sa}^{\#} </math> przez litery terminalne,
| |
| a prawa typu 8 eliminują symbole nieterminalne typu <math>\displaystyle a^{\#} </math> . A
| |
| zatem dla niepustego słowa <math>\displaystyle w\in (\Sigma _{I}\setminus \{\#\})^{*}
| |
| </math> spełniona jest równoważność
| |
| | |
| <center><math>\displaystyle v_{0}\mapsto_{G}^{*}w\: \Leftrightarrow \: s_{0}\#w\#\rightarrow
| |
| _{TM}^{*}\#u\#s_{1}, </math></center>
| |
| | |
| gdzie <math>\displaystyle u\in (\Sigma _{I}\setminus
| |
| \{\#\})^{*} </math> oraz <math>\displaystyle s_{1}\in S_{F} </math> . Prawo 10. zapewnia, że
| |
| powyższa równoważność prawdziwa jest także dla słowa pustego <math>\displaystyle 1
| |
| </math> . A to kończy dowód tego twierdzenia.
| |
| | |
| }}
| |
| | |
| Język <math>\displaystyle L </math> nazywamy '''rekurencyjnie przeliczalnym''',
| |
| jeśli istnieje efektywny
| |
| algorytm wyliczający wyłącznie słowa z <math>\displaystyle L </math> . Przez efektywny
| |
| algorytm rozumiemy skończony zbiór instrukcji, który w jednoznaczny
| |
| sposób opisuje działanie tego algorytmu. Klasę języków rekurencyjnie
| |
| przeliczalnych oznaczamy symbolem <math>\displaystyle \mathcal{RP} </math> .
| |
| | |
| Zauważmy, że każda gramatyka <math>\displaystyle G </math> typu '''(0)''' jest
| |
| algorytmem wyliczającym wyłącznie słowa z <math>\displaystyle L=L(G) </math> . Dla każdej
| |
| liczby naturalnej <math>\displaystyle k </math> można bowiem rozważyć skończony zbiór
| |
| wyprowadzeń w <math>\displaystyle G </math>, rozpoczynających się od symbolu początkowego
| |
| <math>\displaystyle v_{0} </math> i o długości równej <math>\displaystyle k </math> . Z tego zbioru można z kolei
| |
| wybrać wyłącznie te wyprowadzenia, które kończą się słowem
| |
| nad alfabetem terminalnym gramatyki <math>\displaystyle G </math> i tylko te
| |
| słowa dodawać do listy składającej się na język <math>\displaystyle L </math> . Są to, jak
| |
| łatwo zauważyć, wszystkie słowa języka <math>\displaystyle L </math> i nic ponadto. A
| |
| zatem
| |
| | |
| {{twierdzenie|3.2||
| |
| Każdy język typu '''(0)''' jest językiem rekurencyjnie
| |
| przeliczalnym, czyli <math>\displaystyle \mathcal{L}_{0}\subset \mathcal{RP} </math> .
| |
| | |
| }}
| |
| | |
| Język <math>\displaystyle L </math> nazywamy '''rekurencyjnym''',
| |
| jeśli istnieje efektywny algorytm
| |
| rozstrzygający dla każdego słowa <math>\displaystyle w\in A^{*} </math> jego
| |
| przynależność do języka <math>\displaystyle L </math> . Klasę języków
| |
| rekurencyjnych oznaczamy symbolem <math>\displaystyle \mathcal{R} </math> .
| |
| | |
| Klasa języków kontekstowych zawiera się istotnie w klasie
| |
| języków rekurencyjnych, o czym przekonuje poniższe
| |
| twierdzenie.
| |
| | |
| {{twierdzenie|3.3||
| |
| Każdy język kontekstowy jest językiem rekurencyjnym, czyli <math>\displaystyle \mathcal{L}_{1}\subset \mathcal{R}.</math>
| |
| | |
| }}
| |
| | |
| {{dowod|||
| |
| Niech <math>\displaystyle L </math> będzie dowolnym językiem kontekstowym. Istnieje więc
| |
| gramatyka kontekstowa <math>\displaystyle G=(V_{N},V_{T},v_{0},P) </math> taka, że <math>\displaystyle L=L(G) </math> . Bezpośrednio z definicji gramatyki
| |
| kontekstowej wynika, iż słowo puste <math>\displaystyle 1\in L </math> wtedy i tylko
| |
| wtedy, gdy <math>\displaystyle v_{0}\rightarrow 1\in P </math> . Załóżmy teraz, że dane
| |
| jest słowo <math>\displaystyle w\in V^{*}_{T} </math> , o którym mamy zadecydować, czy
| |
| należy do języka <math>\displaystyle L </math> . W tym celu rozważmy wszystkie ciągi słów
| |
| | |
| <center><math>\displaystyle y_{0}=v_{0},\: y_{1},...,y_{n-1},\: y_{n}=w</math></center>
| |
| | |
| o tej własności, że <math>\displaystyle y_{i}\in (V_{N}\cup V_{T})^{*} </math> są parami różne, dla <math>\displaystyle i=0,...,n
| |
| </math> , <math>\displaystyle n\geqslant 1 </math> oraz <math>\displaystyle \mid y_{i}\mid \leqslant \mid y_{i+1}\mid </math> .
| |
| Ilość takich ciągów jest skończona i słowo <math>\displaystyle w\in L </math> wtedy i
| |
| tylko wtedy, gdy wśród powyższych ciągów znajdziemy choć jeden taki,
| |
| że tworzy wyprowadzenie w gramatyce <math>\displaystyle G </math> . Czyli
| |
| | |
| <center><math>\displaystyle y_{0}=v_{0}\rightarrow y_{1}\rightarrow ...\rightarrow
| |
| y_{n-1}\rightarrow y_{n}=w. </math></center>
| |
| | |
| Ponieważ ilość ciągów podlegających rozważaniom jest
| |
| skończona oraz ponieważ stwierdzenie, czy pomiędzy dowolnymi słowami
| |
| zachodzi relacja <math>\displaystyle \rightarrow </math> , sprowadza się do przeszukania
| |
| skończonego zbioru praw <math>\displaystyle P </math> , efektywnie rozstrzygniemy, czy <math>\displaystyle w
| |
| </math> należy do języka <math>\displaystyle L </math>, czy też nie.
| |
| | |
| }}
| |
| | |
| Uzyskane dotąd rezultaty możemy podsumować następująco:
| |
| | |
| <center><math>\displaystyle \mathcal{L}(MT)\subset \mathcal{L}_{0}\subset \mathcal{RP}.</math></center>
| |
| | |
| W określeniu języka rekurencyjnie przeliczalnego oraz języka
| |
| rekurencyjnego wystąpiło pojęcie efektywnego algorytmu,
| |
| efektywnej procedury. Pojęcie to, intuicyjnie dość jasne, nie
| |
| zostało precyzyjnie określone. Co za tym idzie, dla
| |
| matematycznie poprawnych definicji języka rekurencyjnie
| |
| przeliczalnego i języka rekurencyjnego należałoby
| |
| sformalizować pojęcie algorytmu. W dotychczasowych rozważaniach
| |
| intuicja efektywnej procedury była o tyle wystarczająca, że
| |
| naszym celem było wskazanie istnienia takiej procedury. W
| |
| sytuacji, gdyby naszym celem było wykazanie, że taka procedura nie
| |
| istnieje, formalizacja tego pojęcia byłaby wręcz konieczna. We
| |
| wszystkich takich przypadkach powszechnie przyjmuje się, że maszyna
| |
| Turinga jest właśnie taką formalizacją. Na zdefiniowaną
| |
| w poprzednim wykładzie maszynę Turinga można spojrzeć jako na
| |
| algorytm, efektywną procedurę dającą odpowiedź pozytywną lub
| |
| negatywną w zależności od akceptacji lub nieakceptowania słowa
| |
| wejściowego. Proces obliczenia prowadzony przez maszynę Turinga
| |
| zgadza się z intuicyjnym rozumieniem algorytmu. O tym, że
| |
| każda efektywna procedura jest reprezentowana przez pewną
| |
| maszynę Turinga, mówi, powszechnie przyjęta jako prawdziwa, teza
| |
| Churcha.
| |
| | |
| '''Teza Churcha'''
| |
| | |
| ''Każda efektywna''
| |
| ''procedura (algorytm) da się opisać przez maszynę Turinga. ''
| |
| | |
| Konsekwencją przyjęcia tezy Churcha jest inkluzja <math>\displaystyle \mathcal{RP}\subset \mathcal{L}(MT) </math> . Biorąc pod uwagę udowodnione
| |
| powyżej twierdzenia, mamy:
| |
| | |
| <center><math>\displaystyle \mathcal{L}(MT)\subset \mathcal{L}_{0}\subset \mathcal{RP},</math></center>
| |
| | |
| co ostatecznie prowadzi do równości <math>\displaystyle \mathcal{L}_{0}=\mathcal{L}(MT) </math> .
| |
| | |
| ==4. Rodziny <math>\displaystyle \mathcal{L}_{1}</math> i <math>\displaystyle \mathcal{L}_{0}</math> - zamkniętość na działania==
| |
| | |
| Dla kompletności tej części wykładu przedstawimy własności
| |
| zamkniętości rodziny języków kontekstowych <math>\displaystyle \mathcal{L}_{1}
| |
| </math> i języków typu '''(0)''' <math>\displaystyle \mathcal{L}_{0} </math> ze względu na
| |
| najczęściej używane operacje. W niektórych przypadkach dowody
| |
| dotyczące obu klas są takie same. W dowodach posłużymy się specjalną
| |
| postacią gramatyk, a mianowicie taką, w której symbole terminalne
| |
| występują tylko po prawej stronie. Prawdziwe bowiem jest twierdzenie
| |
| | |
| {{twierdzenie|4.1||
| |
| Dla każdej gramatyki istnieje równoważna gramatyka tego
| |
| samego typu taka, że każda produkcja, w której występuje symbol
| |
| terminalny <math>\displaystyle a </math> , jest postaci <math>\displaystyle v\longrightarrow a </math> .
| |
| | |
| }}
| |
| | |
| Elementarny dowód tej własności pozostawiamy jako zadanie
| |
| domowe.
| |
| | |
| {{twierdzenie|4.2||}}
| |
| Rodziny <math>\displaystyle \mathcal{L}_{0} </math> i <math>\displaystyle \mathcal{L}_{1} </math> są zamknięte
| |
| ze względu na:
| |
| # {{kotwica|pkt.1|}}sumę mnogościową,
| |
| # {{kotwica|pkt.2|}}iloczyn mnogościowy,
| |
| # {{kotwica|pkt.3|}}katenację,
| |
| # {{kotwica|pkt.4|}}iterację <math>\displaystyle * </math>,
| |
| # {{kotwica|pkt.5|}}odbicie zwierciadlane.
| |
| | |
| {{dowod|||
| |
| | |
| [[#pkt.1|1.]] Niech dla <math>\displaystyle i=1,2 \displaystyle G_{i}=(V_{N}^{i},V_{T},v_{0}^{i},P_{i}) </math> będą gramatykami
| |
| typu <math>\displaystyle (1) </math> (odpowiednio typu <math>\displaystyle (0) </math> ) takimi, że <math>\displaystyle V_{N}^{1}\cap V_{N}^{2}=\emptyset </math> . I niech <math>\displaystyle L_{i}=L(G_{i}) </math> .
| |
| Określamy gramatykę <math>\displaystyle G </math> typu <math>\displaystyle (1) </math> (typu <math>\displaystyle (0) </math> )
| |
| generującą język <math>\displaystyle L_{1}\cup L_{2} </math> .
| |
| | |
| Jeśli <math>\displaystyle 1\notin L_{1}\cup L_{2} </math> , to przyjmujemy:
| |
| | |
| <center><math>\displaystyle G=(V_{N}^{1}\cup V_{N}^{2}\cup \left\{ v_{0}\right\}
| |
| ,V_{T},v_{0},P_{1}\cup P_{2}\cup \left\{ v_{0}\rightarrow
| |
| v_{0}^{1},\, v_{0}\rightarrow v_{0}^{2}\right\} ).</math></center>
| |
| | |
| Zauważmy, że wówczas w żadnej z gramatyk nie ma prawa wymazującego.
| |
| Jeśli natomiast <math>\displaystyle 1\in L_{1}\cup L_{2} </math> , to konstruujemy
| |
| gramatykę <math>\displaystyle G </math> dla języków <math>\displaystyle L_{1}\setminus \left\{ 1\right\}
| |
| </math> i <math>\displaystyle L_{2}\setminus \left\{ 1\right\} </math> , jak powyżej, a
| |
| następnie dodajemy nowy symbol początkowy <math>\displaystyle \overline{v}_{0} </math> i
| |
| prawa <math>\displaystyle \overline{v}_{0}\rightarrow v_{0},\,
| |
| \overline{v}_{0}\rightarrow 1 </math> .
| |
| | |
| [[#pkt.2|2.]] Przecięcie udowodnimy tylko dla języków typu <math>\displaystyle (0)
| |
| </math> . Dowód dla języków kontekstowych został przeprowadzony
| |
| wcześniej.
| |
| | |
| Niech dla <math>\displaystyle i=1,2 \displaystyle G_{i}=(V_{N}^{i},V_{T},v_{0}^{i},P_{i}) </math>
| |
| będą gramatykami typu <math>\displaystyle (0) </math> takimi, że <math>\displaystyle V_{N}^{1}\cap
| |
| V_{N}^{2}=\emptyset </math> . Niech <math>\displaystyle L_{i}=L(G_{i}) </math> . Określamy
| |
| gramatykę <math>\displaystyle G </math> typu <math>\displaystyle (0) </math> generującą język <math>\displaystyle L_{1}\cap L_{2}
| |
| </math>, przyjmując:
| |
| | |
| <center><math>\displaystyle G=(V_{N}^{1}\cup V_{N}^{2}\cup V_{N},V_{T},v_{0},P_{1}\cup P_{2}\cup
| |
| P),</math></center>
| |
| | |
| gdzie: <math>\displaystyle V_{N}=\left\{ v_{a}\, :\, a\in V_{T}\right\} \cup \left\{ v_{0},\overline{v}_{1},\overline{v}_{2}\right\} </math> ,
| |
| a do zbioru <math>\displaystyle P </math> należą prawa: <br>
| |
| (1) <math>\displaystyle v_{0}\rightarrow \overline{v}_{1}v_{0}^{1}\overline{v}_{2}v_{0}^{2}\overline{v}_{1}, </math> <br>
| |
| (2) <math>\displaystyle \overline{v}_{2}a\rightarrow v_{a}\overline{v}_{2} </math> dla <math>\displaystyle \forall a\in V_{T}, </math> <br>
| |
| (3) <math>\displaystyle bv_{a}\rightarrow v_{a}b </math> dla <math>\displaystyle \forall a,b\in V_{T}, </math> <br>
| |
| (4) <math>\displaystyle \overline{v}_{1}v_{a}a\rightarrow a\overline{v}_{1} </math> dla <math>\displaystyle \forall a\in V_{T}, </math> <br>
| |
| (5) <math>\displaystyle \overline{v}_{1}\overline{v}_{2}\overline{v}_{1}\rightarrow 1. </math> <br>
| |
| Przy pomocy prawa (1) i wszystkich praw ze zbioru <math>\displaystyle P_{1}\cup P_{2}
| |
| </math> można wygenerować zbiór słów:
| |
| | |
| <center><math>\displaystyle \left\{ \overline{v}_{1}w_{1}\overline{v}_{2}w_{2}\overline{v}_{1}\,
| |
| :\, w_{1}\in L_{1},\, w_{2}\in L_{2}\right\} .</math></center>
| |
| | |
| Z dowolnego słowa należącego do tego zbioru, korzystając
| |
| z praw (2)-(4), można wyprowadzić słowo <math>\displaystyle w_{1}\overline{v}_{1}\overline{v}_{2}\overline{v}_{1} </math> wtedy i
| |
| tylko wtedy, gdy <math>\displaystyle w_{1}=w_{2} </math> . Korzystając z prawa (5), dostajemy słowo <math>\displaystyle w_{1} </math> . A więc <math>\displaystyle L(\overline{G})=L_{1}\cap
| |
| L_{2} </math> .
| |
| | |
| [[#pkt.3|3.]] Niech dla <math>\displaystyle i=1,2 \displaystyle G_{i}=(V_{N}^{i},V_{T},v_{0}^{i},P_{i}) </math> będą tak jak poprzednio
| |
| gramatykami typu <math>\displaystyle (1) </math> ( <math>\displaystyle (0) </math> ) takimi, że <math>\displaystyle V_{N}^{1}\cap V_{N}^{2}=\emptyset </math> oraz spełniającymi warunki
| |
| powyższego twierdzenia. Niech <math>\displaystyle L_{i}=L(G_{i}) </math> . Określamy
| |
| gramatykę <math>\displaystyle G </math> odpowiednio typu <math>\displaystyle (1) </math> ( <math>\displaystyle (0) </math> ) generującą
| |
| język <math>\displaystyle L_{1}L_{2} </math> .
| |
| | |
| Jeśli <math>\displaystyle 1\notin L_{1}\cup L_{2} </math> , to przyjmujemy:
| |
| | |
| <center><math>\displaystyle G=(V_{N}^{1}\cup V_{N}^{2}\cup \left\{ v_{0}\right\}
| |
| ,V_{T},v_{0},P_{1}\cup P_{2}\cup \left\{ v_{0}\rightarrow
| |
| v_{0}^{1}v_{0}^{2}\right\} ).</math></center>
| |
| | |
| Jeśli <math>\displaystyle 1\in L_{1}\cup L_{2} </math> , to oznaczamy <math>\displaystyle L_{1}'=L_{1}\setminus \left\{ 1\right\} ,\; \; L_{2}'=L_{2}\setminus
| |
| \left\{ 1\right\} </math> . Wówczas:
| |
| | |
| <center><math>\displaystyle L_{1}L_{2}=\left\{ \begin{array} {lll}
| |
| L_{1}'L_{2}'\cup L_{1}', & gdy & 1\in L_{2},\: 1\notin L_{1},\\
| |
| L_{1}'L_{2}'\cup L_{2}', & gdy & 1\in L_{1},\: 1\notin L_{2},\\
| |
| L_{1}'L_{2}'\cup L_{1}'\cup L_{2}'\cup \left\{ 1\right\}, & gdy &
| |
| 1\in L_{1},\: 1\in L_{2}.
| |
| \end{array} \right. </math></center>
| |
| | |
| Wykorzystując poprzednią konstrukcję i zamkniętość
| |
| ze względu na sumę w każdym z tych przypadków, otrzymujemy gramatykę
| |
| generującą katenację języków <math>\displaystyle L_{1} </math> i <math>\displaystyle L_{2} </math> .
| |
| | |
| [[#pkt.4|4.]] Niech <math>\displaystyle G=(V_{N},V_{T},v_{0},P) </math> będzie
| |
| gramatyką typu <math>\displaystyle (1) </math> (typu <math>\displaystyle (0) </math> ) taką, że symbole
| |
| terminalne nie występują po lewej stronie żadnej produkcji z <math>\displaystyle P
| |
| </math> . Załóżmy też, że <math>\displaystyle 1\notin L=L(G) </math> . Gramatyka
| |
| | |
| <center><math>\displaystyle \overline{G}=(V_{N}\cup \left\{
| |
| \overline{v}_{0},\overline{v}_{1}\right\}
| |
| ,V_{T},\overline{v}_{0},\overline{P}),</math></center>
| |
| | |
| gdzie
| |
| | |
| <center><math>\displaystyle \overline{P}=P\cup \begin{array} [t]{l}
| |
| \left\{ \overline{v}_{0}\rightarrow 1,\: \overline{v}_{0}\rightarrow v_{0},\: \overline{v}_{0}\rightarrow \overline{v}_{1}v_{0}\right\} \cup \\
| |
| \left\{ \overline{v}_{1}a\rightarrow \overline{v}_{1}v_{0}a\, :\, a\in V_{T}\right\} \cup \\
| |
| \left\{ \overline{v}_{1}a\rightarrow v_{0}a\, :\, a\in V_{T}\right\}
| |
| \end{array} </math></center>
| |
| | |
| generuje język <math>\displaystyle L^{*} </math> . Jeśli <math>\displaystyle 1\in L </math> , to usuwamy prawo
| |
| wymazujące <math>\displaystyle v_{0}\rightarrow 1 </math> i dla języka <math>\displaystyle L\setminus
| |
| \left\{ 1\right\} </math> konstruujemy gramatykę <math>\displaystyle \overline{G} </math> . Z
| |
| faktu, że <math>\displaystyle (L\cup \left\{ 1\right\} )^{*}=L^{*} </math> , wynika, że
| |
| również <math>\displaystyle L(\overline{G})=L^{*} </math> .
| |
| | |
| [[#pkt.5|5.]] Jeśli <math>\displaystyle G=(V_{N},V_{T},v_{0},P) </math> jest gramatyką
| |
| typu <math>\displaystyle (1) </math> (typu <math>\displaystyle (0) </math> ) taką, że <math>\displaystyle L(G)=L </math> , to gramatyka
| |
| <math>\displaystyle \overleftarrow{G}=(V_{N},V_{T},v_{0},\overleftarrow{P}) </math> , gdzie
| |
| <math>\displaystyle \overleftarrow{P}=\left\{ \overleftarrow{x}\rightarrow
| |
| \overleftarrow{y}\, :\, x\rightarrow y\in P\right\} </math> generuje
| |
| język <math>\displaystyle \overleftarrow{L} </math> .
| |
| | |
| }}
| |
| | |
| Zauważmy na koniec, że rodzina <math>\displaystyle \mathcal{L}_{0} </math> nie jest
| |
| zamknięta ze względu na uzupełnienie.
| |
| Stwierdzenie to
| |
| wynika z przyjęcia jako obowiązujacej tezy Churcha, która w tym
| |
| wypadku implikuje równość rodziny języków <math>\displaystyle \mathcal{L}_{0} </math> i
| |
| rodziny języków rekurencyjnie przeliczalnych oraz z faktu, iż
| |
| istnieje język rekurencyjnie przeliczalny, którego
| |
| uzupełnienie nie jest rekurencyjnie przeliczalne. Ten ostatni fakt
| |
| podajemy bez dowodu.
| |
| Dodajmy, że własność zamkniętości ze względu na uzupełnienie dla
| |
| rodziny <math>\displaystyle \mathcal{L}_{1} </math> przez długi czas pozostawała problemem otwartym.
| |
| Dopiero w roku 1987 udowodniono, iż własność ta jest spełniona dla
| |
| języków kontekstowych.
| |
| Podsumowanie własności zamkniętości ze względu na działania dla
| |
| różnych klas języków hierarchii Chomsky'ego zawarte jest w poniższej
| |
| tabeli:
| |
| | |
| {| border=1 align=center
| |
| |-
| |
| | || 3 || 2 || 1 || 0
| |
| |-
| |
| | <math>\displaystyle\cup</math> || T || T || T || T
| |
| |-
| |
| | <math>\displaystyle\cdot</math> || T || T || T || T
| |
| |-
| |
| | <math>\displaystyle\star</math> || T || T || T || T
| |
| |-
| |
| | <math>\displaystyle\setminus</math> || T || N || T || N
| |
| |-
| |
| | <math>\displaystyle\cap</math> || T || N || T || T
| |
| |-
| |
| |
| |
| | |
| |}
| |
| | |
| Na koniec podamy
| |
| twierdzenie o wzajemnych relacjach pomiędzy
| |
| rodzinami języków z hierarchii Chomsky'ego. Dowód tego twierdzenia
| |
| wynika w części z definicji typów gramatyk wprowadzonych na wykładzie 2, a w części
| |
| z udowodnionych własności poszczególnych rodzin języków z
| |
| hierarchii Chomsky'ego (zakładając obowiązywanie tezy Churcha).
| |
| | |
| {{twierdzenie|4.3||
| |
| Rodziny języków hierarchii Chomsky'ego spełniają następujące relacje:
| |
| | |
| <center><math>\displaystyle \mathcal{L}_{0}\subseteq \! \! \! \! \! \! _{/}\, \mathcal{L}_{1}
| |
| \subseteq \! \! \! \! \! \! _{/}\, \mathcal{L}_{2}
| |
| \subseteq \! \! \! \! \! \! _{/}\, \mathcal{L}_{3}.
| |
| </math></center>
| |
| | |
| }}
| |
| | |
| ==5. Problemy rozstrzygalne==
| |
| | |
| W poprzednim wykładzie uzasadniliśmy, że dla każdej
| |
| deterministycznej maszyny Turinga jesteśmy w stanie wskazać taką,
| |
| która akceptuje dany język i jednocześnie zatrzymuje się tylko na
| |
| słowach akceptowanych. Wymagało to przejścia przez maszynę
| |
| niedeterministyczną, a następnie jej symulację na maszynie
| |
| deterministycznej. Z tego powodu ograniczamy się w dalszej części
| |
| wykładu tylko do tego typu maszyn Turinga (akceptacja<nowiki>=</nowiki>stop). Jak to
| |
| uzasadniono wcześniej, przy założeniu tezy Churcha, maszyna Turinga
| |
| może być rozpatrywana jako matematycznie ścisła definicja algorytmu.
| |
| | |
| Pojęcie rozstrzygalnego problemu zostało wprowadzone wcześniej, na innym wykładzie, i jest ono znane. Przypomnijmy więc tylko, że rozstrzygalność, czy też nierozstrzygalność, odnosi się do pewnej klasy, którą tworzą określone przypadki ustalonego problemu. Jeśli istnieje algorytm, który rozwiązuje taki problem dla wszystkich przypadków w tej klasy, to mówimy, że problem jest rozstrzygalny (w tej klasie). Zatem taki algorytm jest uniwersalnym sposobem rozwiązywania problemu dla wszystkich danych wejściowych określających poszczególne przypadki w tej klasie. Jak łatwo zauważyć dla ustalenia rozstrzygalności problemu wystarczy się
| |
| opierać na intuicyjnym pojęciu algorytmu. Są jednak
| |
| takie problemy, dla których nie istnieje, w rozważanej klasie
| |
| przypadków, uniwersalny sposób ich rozwiazywania. Takie problemy
| |
| nazywamy nierozstrzygalnymi w danej klasie. Aby wykazać
| |
| nierozstrzygalność jakiegoś problemu, nieodzownym jest sformalizowanie pojęcia algorytmu. Standardowo taką formalizacją jest, o czym wspomniano już wcześniej, maszyna Turinga.
| |
| | |
| Zwróćmy uwagę, że maszyna Turinga akceptuje języki, gdy tymczasem
| |
| przyzwyczajeni jesteśmy, że algorytmy (programy) rozwiązują pewne,
| |
| niekiedy bardzo skomplikowane, problemy (określone przy pomocy list,
| |
| kolejek, grafów itp.). Zwracamy zatem uwagę na fakt, że w przypadku
| |
| maszyny Turinga musimy wykonać wstępne umowne kodowanie naszego
| |
| problemu. W tym przypadku rozważany język określa te spośród
| |
| "sensownych" kodowań, które stanowią rozwiązanie postawionego
| |
| problemu. Z drugiej strony maszyna, akceptując słowo <math>\displaystyle \sharp w_1 \$
| |
| w_2 \sharp</math>, może informować nas o tym, że wynikiem obliczeń
| |
| numerycznych na danych zakodowanych w <math>\displaystyle w_1</math> rzeczywiście jest liczba
| |
| zakodowana w <math>\displaystyle w_2</math> itp.
| |
| | |
| Dla ilustracji powyższych dywagacji rozważmy problem skończoności
| |
| w klasie jezyków regularnych. Problem ten jest rozstrzygalny, bo w
| |
| oparciu o lemat o pompowaniu można skonstruować algorytm,
| |
| który dla dowolnego języka regularnego rozstrzygnie,
| |
| czyli odpowie twierdząco lub przecząco na pytanie o jego
| |
| skończoność. W tym przypadku można np. przyjąć, że jako słowo
| |
| wejściowe podajemy zakodowany opis gramatyki generującej język.
| |
| | |
| Nierozstrzygalność algorytmiczna problemu w ustalonej klasie
| |
| nie oznacza, podkreślmy, niemożliwości rozwiązania konkretnego zadania z tej
| |
| klasy. Nierostrzygalność oznacza niemożliwość rozwiązania za pomocą
| |
| tego samego algorytmu, tej samej metody, wszystkich przypadków tego
| |
| problemu należących do danej klasy.
| |
| | |
| W zamieszczonej poniżej tabeli przedstawiamy najczęściej rozważane pod kątem
| |
| rozstrzygalności problemy z dziedziny
| |
| języków formalnych w ramach hierarchii Chomsky'ego.
| |
| Litera R oznacza rozstrzygalność problemu, N
| |
| nierostrzygalność, a znak - pojawiający się przy problemie
| |
| jednoznaczności oznacza, że problemu tego nie formułuje się dla
| |
| gramatyk kontekstowych i typu '''(0)''':
| |
| | |
| <div align=center>
| |
| {| border=1
| |
| |-
| |
| | '''własność'''
| |
| | '''(3)'''
| |
| | '''(2)'''
| |
| | '''(1)'''
| |
| | '''(0)'''
| |
| |---
| |
| |align="center"| należenie <math>\displaystyle w\in L </math>
| |
| |align="center"| R
| |
| |align="center"| R
| |
| |align="center"| R
| |
| |align="center"| N
| |
| |---
| |
| |align="center"| inkluzja <math>\displaystyle L_{1}\subset L_{2} </math>
| |
| |align="center"| R
| |
| |align="center"| N
| |
| |align="center"| N
| |
| |align="center"| N
| |
| |---
| |
| |align="center"| równoważność
| |
| |align="center"| R
| |
| |align="center"| N
| |
| |align="center"| N
| |
| |align="center"| N
| |
| |---
| |
| |align="center"| pustość <math>\displaystyle L=\emptyset </math>
| |
| |align="center"| R
| |
| |align="center"| R
| |
| |align="center"| N
| |
| |align="center"| N
| |
| |---
| |
| |align="center"| nieskończoność <math>\displaystyle card\, L=\aleph _{0} </math>
| |
| |align="center"| R
| |
| |align="center"| R
| |
| |align="center"| N
| |
| |align="center"| N
| |
| |---
| |
| |align="center"| jednoznaczność gramatyki
| |
| |align="center"| R
| |
| |align="center"| N
| |
| |align="center"| -
| |
| |align="center"| -
| |
| |}
| |
| </div>
| |
| | |
| Najczęściej używaną metodą dowodzenia nierozstrzygalności problemu
| |
| <math>\displaystyle P </math> jest redukcja tego problemu do innego, powiedzmy <math>\displaystyle P'
| |
| </math> , dla którego nierozstrzygalność została ustalona wcześniej.
| |
| Redukcja taka prowadzi do sformułowania implikacji:
| |
| | |
| jeśli <math>\displaystyle P </math> byłby
| |
| rozstrzygalny, to i <math>\displaystyle P' </math> byłby rozstrzygalny.
| |
| | |
| A ponieważ to
| |
| ostatnie (następnik implikacji) nie jest prawdą, więc problem <math>\displaystyle P
| |
| </math> nie jest rozstrzygalny.
| |
| | |
| Należy w tym miejscu podkreślić fakt, że dowody nierozstrzygalności
| |
| problemów uniwersalnych (takich jak problem Posta rozważany dalej)
| |
| wiążą się z konstrukcją odpowiednich maszyn Turinga, kodowaniem
| |
| problemu, a następnie dowodem uzasadniającym, że problem jest
| |
| rzeczywiście nierozstrzygalny. Tematyka ta
| |
| wykracza poza ramy wykładu. Z tego też powodu ograniczymy się tutaj
| |
| do zaprezentowania jednego ze znanych problemów nierozstrzygalnych
| |
| bez dowodu nierozstrzygalności.
| |
| | |
| Najczęściej występującym w literaturze problemem nierozstrzygalnym jest, bez wątpienia,
| |
| problem
| |
| Posta przedstawiony poniżej.
| |
| | |
|
| |
| | |
| '''Problem''' '''Posta'''
| |
| | |
| Dla dowolnego alfabetu <math>\displaystyle A </math> , o co najmniej dwóch elementach ( <math>\displaystyle \sharp A\geqslant 2 </math> ), załóżmy, iż dana jest, tak zwana, lista słów, a dokładniej: par słów ''' <math>\displaystyle \left( u_{1},w_{1}\right) \: \left( u_{2},w_{2}\right) \: \ldots \left( u_{n},w_{n}\right), </math> ''' gdzie <math>\displaystyle u_{i},w_{i}\in A^{+} </math> , <math>\displaystyle n\in \Bbb N </math> . Mówimy, że taka lista ma własność Posta (problem Posta ma rozwiązanie), jeśli istnieje ciąg indeksów <math>\displaystyle i_{1},\ldots ,i_{k}\in \{1,...,n\} </math> taki, że
| |
| | |
| <center><math>\displaystyle u_{i_{1}}\ldots u_{i_{k}}=w_{i_{1}}\ldots w_{i_{k}}.</math></center>
| |
| | |
| Jest to w ogólnym przypadku problem nierozstrzygalny.
| |
| | |
| Problem ten można sformułować równoważnie następująco. Niech <math>\displaystyle A </math> będzie
| |
| alfabetem interpretowanym jako zbiór indeksów, a <math>\displaystyle B
| |
| </math> dowolnym alfabetem. Niech <math>\displaystyle h:A^{*}\longrightarrow
| |
| B^{*},\: g:A^{*}\longrightarrow B^{*} </math> będą dowolnymi
| |
| homomorfizmami. Problem Posta, inaczej sformułowany, polega na odpowiedzi
| |
| na pytanie, czy istnieje słowo <math>\displaystyle x\in A^{+} </math> takie, że <math>\displaystyle h(x)=g(x) </math> .
| |
| | |
| Dwa kolejne przykłady ilustrują technikę redukcji pewnych
| |
| problemów do problemu Posta. W efekcie
| |
| uzyskujemy nierozstrzygalność w sposób opisany powyżej.
| |
| | |
| {{twierdzenie|5.1||
| |
| W klasie gramatyk bezkontekstowych problem
| |
| niejednoznaczności jest nierozstrzygalny.
| |
| | |
| }}
| |
| | |
| {{dowod|||
| |
| Udowodnimy, że problem jest nierozstrzygalny dla gramatyk
| |
| bezkontekstowych generujących języki nad alfabetem
| |
| dwuelementowym <math>\displaystyle A=\{a,b\} </math> . Oznaczmy <math>\displaystyle B=\{d,e\} </math> i
| |
| określmy homomorfizm <math>\displaystyle h:B^{*}\longrightarrow A^{*} </math> ,
| |
| przyjmując <math>\displaystyle h(d)=ba^{2} </math> oraz <math>\displaystyle h(e)=ba^{3} </math> . Niech <math>\displaystyle u </math>
| |
| będzie ciągiem <math>\displaystyle u_{1},...,u_{n}\in B^{+} </math> dowolnie wybranych
| |
| i ustalonych słów. Dla dowolnej liczby naturalnej <math>\displaystyle i>0 </math> niech <math>\displaystyle \overline{i}=de^{i} </math> . Określony poniżej język
| |
| | |
| <center><math>\displaystyle L_{u}=\{h(\overline{i_{1}}).....h(\overline{i_{k}})bah(u_{i_{k}}),...,h(u_{i_{1}})\in
| |
| A^{*}\: :\: k\geqslant 1,\: 1\leqslant i_{j}\leqslant n\}</math></center>
| |
| | |
| jest językiem
| |
| bezkontekstowym, jako generowany przez gramatykę <math>\displaystyle G_{u}=(V_{N},V_{T},v_{0},P_{u}) </math> , dla której
| |
| | |
| <math>\displaystyle V_{N}=\{v_{u}\},\: V_{T}=\{a,b\},\: v_{0}=v_{u} </math> oraz <math>\displaystyle P_{x}=\{v_{u}\rightarrow h(\overline{i})v_{u}h(u_{i}),\:
| |
| v_{u}\rightarrow h(\overline{i})bah(u_{i})\} </math> .
| |
| | |
| Niech teraz <math>\displaystyle u </math> i <math>\displaystyle w </math> oznaczają ciągi dowolnie wybranych i
| |
| ustalonych słów <math>\displaystyle u_{1},...,u_{n}\in B^{+} </math> i <math>\displaystyle w_{1},...,w_{n}\in B^{+} </math> . Tworzą one listę słów ''' <math>\displaystyle \left( u_{1},w_{1}\right) \: \left( u_{2},w_{2}\right) \: \ldots
| |
| \left( u_{n},w_{n}\right), </math> '''. Zatem zasadne jest postawienie
| |
| pytania, czy lista ta ma własność Posta. Niech <math>\displaystyle G_{u} </math> oraz <math>\displaystyle G_{w}
| |
| </math> będą gramatykami bezkontekstowymi określonymi tak jak
| |
| powyżej. Gramatyka <math>\displaystyle G=(\{v_{0},v_{u},v_{w}\},\{a,b\},v_{0},P) </math> ,
| |
| gdzie <math>\displaystyle P=\{v_{0}\rightarrow v_{u},\: v_{0}\rightarrow v_{w}\}\cup
| |
| P_{u}\cup P_{w} </math> jest bezkontekstowa. Gramatyka ta jest
| |
| niejednoznaczna wtedy i tylko wtedy, gdy <math>\displaystyle L_{u}\cap L_{y}\neq
| |
| \emptyset </math> . Ten ostatni warunek równoważny jest istnieniu liczb
| |
| <math>\displaystyle i_{1},...,i_{k}\in \Bbb N </math> takich, że <math>\displaystyle u_{i_{1}}.....u_{i_{k}}=w_{i_{1}}.....w_{i_{k}} </math>, czyli własności
| |
| Posta listy ''' <math>\displaystyle \left( u_{1},w_{1}\right) \: \left(
| |
| u_{2},w_{2}\right) \: \ldots \left( u_{n},w_{n}\right) </math> .'''Ostatecznie więc
| |
| rozstrzygalność problemu niejednoznaczności w klasie
| |
| gramatyk bezkontekstowych prowadziłaby do
| |
| rozstrzygalności własności Posta.
| |
| | |
| }}
| |
| | |
| Dla drugiego przykładu przyjmijmy jako alfabety <math>\displaystyle A_{2}=\left\{ a,b\right\} ,\: A_{3}=\left\{ a,b,c\right\} </math> oraz określmy język
| |
| | |
| <center><math>\displaystyle L=\left\{ v_{1}cv_{2}c\overleftarrow{v}_{2}c\overleftarrow{v}_{1}\,
| |
| :\, v_{1},v_{2}\in A_{2}^{*}\right\}. </math></center>
| |
| | |
| Ustalmy listę Posta ''' <math>\displaystyle \left( u_{1},w_{1}\right) \: \left( u_{2},w_{2}\right) \: \ldots \left( u_{n},w_{n}\right) </math> '''
| |
| nad alfabetem <math>\displaystyle A_{2} </math> , gdzie <math>\displaystyle u_{i},w_{i}\in A_{2}^{+}
| |
| </math> . Wprowadzamy teraz języki <math>\displaystyle L_{u},\: L_{w}\: L_{PP} </math> nad
| |
| alfabetem <math>\displaystyle A_{3} </math>, przyjmując:
| |
| | |
| <center><math>\displaystyle \aligned L_{u} &= \left\{ ba^{i_{k}}b\ldots ba^{i_{1}}cu_{i_{1}}\ldots u_{i_{k}}\, :\, k\geqslant 1,1\leqslant i_{j}\leqslant n\right\} \\
| |
| L_{w} &= \left\{ ba^{i_{k}}b\ldots ba^{i_{1}}cw_{i_{1}}\ldots
| |
| w_{i_{k}}\, :\, k\geqslant 1,1\leqslant i_{j}\leqslant n\right\}
| |
| \endaligned</math></center>
| |
| | |
| oraz definiujemy język
| |
| | |
| <center><math>\displaystyle L_{PP}=L_{u}c\overleftarrow{L}_{w}.</math></center>
| |
| | |
| Określone powyżej języki nad alfabetem <math>\displaystyle A_{3} </math> mają
| |
| własności konieczne do zastosowania lematu, który przytoczymy bez
| |
| dowodu.
| |
| | |
| {{lemat|5.1||
| |
| Języki <math>\displaystyle L,\: L_{PP},\: A_{3}^{*}\setminus L,\: A_{3}^{*}\setminus
| |
| L_{PP} </math> są bezkontekstowe.
| |
| | |
| }}
| |
| | |
| Dla języków <math>\displaystyle L </math> i <math>\displaystyle L_{PP} </math> uzasadnienie ich bezkontekstowości jest proste
| |
| poprzez konstrukcję odpowiednich
| |
| gramatyk. Aby uzyskać bezkontekstowość ich uzupełnień,
| |
| należy
| |
| podzielić rozważane języki na rozłączne podzbiory i konstruować
| |
| gramatyki bezkontekstowe dla tych wyróżnionych
| |
| podzbiorów, a w końcu wykorzystać fakt, że suma języków
| |
| bezkontekstowych jest językiem bezkontekstowym.
| |
| | |
| Zauważmy teraz, że istnienie rozwiązania problemu Posta nad
| |
| alfabetem <math>\displaystyle A_{3} </math> jest równoważne temu, że <math>\displaystyle L_{PP}\cap
| |
| L\neq \emptyset </math> .
| |
| | |
| Jeśli bowiem <math>\displaystyle L_{PP}\cap L\ni ba^{i_{k}}\ldots
| |
| ba^{i_{1}}cu_{i_{1}}\ldots u_{i_{k}}c\overleftarrow{w_{i_{1}}\ldots
| |
| w_{i_{k}}}ca^{i_{1}}b\ldots a^{i_{k}}b </math> , gdzie <math>\displaystyle k\geqslant 1,1\leqslant
| |
| i_{j}\leqslant n </math> , to oczywiście <math>\displaystyle u_{i_{1}}\ldots u_{i_{k}}=w_{i_{1}}\ldots
| |
| w_{i_{k}} </math> . Jeśli ciąg <math>\displaystyle i_{1},\ldots ,i_{k} </math> jest
| |
| rozwiązaniem problemu Posta, to <math>\displaystyle (i_{1},\ldots
| |
| ,i_{k})(i_{1},\ldots ,i_{k}) </math> też. Zatem jeśli <math>\displaystyle L_{PP}\cap L\neq
| |
| \emptyset </math> , to język <math>\displaystyle L_{PP}\cap L </math> jest nieskończony.
| |
|
| |
|
| Wobec nierozstrzygalności problemu Posta wnioskujemy, że
| | Warunek <math>L_1 \propto L_2</math> otrzymujemy w sposób identyczny. Trzeba |
| nierozstrzygalny jest problem pustości i problem nieskończoności
| | tylko wypisać odpowiednią ilość symboli <math>4</math> (a wiemy już, jak |
| przecięcia <math>\displaystyle L_{1}\cap L_{2} </math> w klasie języków
| | konstruować liczbę <math>2n</math>, mając dane <math>n</math>). |
| bezkontekstowych.
| |