Skip to content
Snippets Groups Projects
Commit 371cc229 authored by Martin Mareš's avatar Martin Mareš
Browse files

Přepsán důkaz věty o obousměrných automatech

Takhle postupuje mnohem intuitivněji zleva doprava.
parent be0a54dd
No related branches found
No related tags found
No related merge requests found
......@@ -906,87 +906,88 @@ Nyní dokážeme, že to vyjde nastejno -- každý jazyk přijímaný obousměrn
\proof
Připomeňme definici TFA: je to Turingův stroj, který dostane vstup $\|<|\alpha\|>|$
a nemá ho povoleno měnit. Navíc na levé zarážce~$\|<|$ nesmí vykonat pohyb doleva
a na pravé zarážce~$\|>|$ nesmí jít doprava. Aby byl TFA podobnější konečným automatům,
výpočet začíná s~hlavou na prvním znaku slova~$\alpha$. To je ale detail: TFA můžeme snadno upravit,
aby výpočet začínal na~$\|<|$ -- stačí přidat nový počáteční stav, v~němž provedeme jeden pohyb
hlavou doprava a přejdeme do původního počátečního stavu.
a na pravé zarážce~$\|>|$ nesmí jít doprava.
Každý regulární jazyk je určitě přijímán nějakým TFA, který vznikne přímočarým
překladem příslušného DFA. Opačná implikace je méně triviální.
Uvažme TFA rozpoznávající nějaký jazyk~$L$ a jeho výpočet nad nějakým vstupem~$\alpha$
délky~$n$. Do vstupu ještě doplníme zarážky $\alpha[-1] = \|<|$ a $\alpha[n] = \|>|$.
Potřebujeme se nějak vyrovnat s~tím, že automat se může během výpočtu na jedno
políčko vracet opakovaně. Představme si, že se díváme dovnitř výpočtu, hlava zrovna stojí
na $i$-tém políčku slova~$\alpha$, stroj se právě přepíná ze stavu~$s$ do~$s'$ a chystá se
odejít doprava do nějakého suffixu $\alpha[i+1:{}]$.
Jak bude výpočet pokračovat? Jedna možnost je, že se stroj po čase vrátí zprava na $i$-té políčko v~nějakém novém stavu,
přičemž nic kromě stavu stroje se nezměnilo (na pásku nemůžeme zapisovat).
Nebo se předtím stroj stihl zastavit a přijmout/odmítnout.
Případně se stroj zacyklil v~nekonečné smyčce, což rovněž odpovídá odmítnutí vstupu.
Z~této úvahy plyne, že kdybychom znali chování stroje na suffixu $\alpha[i+1:{}]$
(jakému vstupnímu stavu odpovídá jaký výstupní), mohli bychom pomocí něj určit,
co bude stroj dělat na políčku~$\alpha[i]$, aniž bychom se dívali na následující
znaky. Z~toho bychom mohli určit chování na suffixu $\alpha[i:{}]$ a tak dále.
Zkusme to provést.
Chování stroje na suffixu vstupu $\alpha[i:{}]$ popíšeme nějakou funkcí~$f_i(s)$.
Ta dostane počáteční stav~$s\in Q\setminus\{q_+, q_-\}$, v~němž stroj vstoupí
na $\alpha[i]$. Výsledkem funkce je koncový stav~$s'\in Q$, v~němž stroj odchází
ze suffixu doleva. Pokud je $s'=q_+$, stroj se místo odejití doleva zastavil a přijal.
Pokud $s'=q_-$, stroj odmítl zastavením nebo zacyklením se.
Ukážeme, jak sestrojit funkci~$f_i$, pokud už známe~$f_{i+1}$.
Chceme-li stanovit $f(s)$, budeme konstruovat posloupnost stavů $s_0$, $s_1$, $s_2$, \dots{}
Představme si výpočet obousměrného automatu, který právě navštívil znak~$\alpha[i]$.
Pokud se automat pohne doprava, můžeme tento krok provést i~konečným automatem.
Pokud vyčkává na místě, jenom mění stavy, takže DFA může celou posloupnost změn provést
najednou.
Problém nastane, pokud se TFA pohybem doleva vrátí do prefixu $\alpha[{}:i]$,
který už jednou zpracoval. Uvnitř prefixu se může libovolně dlouho toulat, než nastane
jedna ze tří možností: buď prefix opustí doprava v~nějakém novém stavu a~je opět
na znaku~$\alpha[i]$. Anebo se zastaví ve stavu $q_+$ či~$q_-$, případně se zacyklí
(tím také odmítne vstup, takže je to ekvivalentní se zastavením v~$q_-$).
Jelikož TFA nemůže měnit obsah pásky, můžeme jeho chování v~prefixu $\alpha[{}:i]$
jednoznačně popsat nějakou funkcí $f_i: Q\setminus\{q_+, q_-\} \rightarrow Q$.
Ta jako argument dostane stav~$s$, ve kterém stroj začíná na posledním znaku prefixu, tedy
$\alpha[i-1]$. Výsledkem funkce je stav~$s'$, v~němž stroj prefix opustí pohybem vpravo.
Pokud je $s'=q_+$, stroj z~prefixu neodešel, nýbrž se zastavil a přijal.
Je-li $s'=q_-$, stroj odmítl zastavením nebo zacyklením se.
Budeme se snažit sestrojit DFA, který si bude ve stavu udržovat chování prefixu~$f_i$
nalevo od aktuální pozice.
Začněme tou nejzajímavější částí: konstrukcí~$f_{i+1}$ z~$f_i$.
Nechť chceme spočítat $f_{i+1}(s)$. TFA tedy stojí na políčku $\alpha[i]$ ve stavu~$s$.
Jelikož se na toto políčko může vracet, budeme konstruovat posloupnost stavů $s_0$, $s_1$, $s_2$, \dots{}
při jednotlivých návštěvách políčka $\alpha[i]$.
Na počátku položíme $s_0=s$.
Nyní budeme z~libovolného~$s_j$ počítat $s_{j+1}$.
Podíváme se, co stroj provede, přečte-li ve stavu~$s_j$ znak~$\alpha[i]$.
Vyhodnotíme tedy přechodovou funkci $\delta(s_j, \alpha[i])$, čímž získáme instrukci, která
Vyhodnocením přechodové funkce $\delta(s_j, \alpha[i])$ získáme instrukci, která
přechází do nějakého stavu~$s'_j$, zapisuje nezměněný znak~$\alpha[i]$ a možná pohybuje hlavou:
\list{o}
\:Pokud hlava odchází doleva, položíme $f_i(s) = s'_j$ a jsme hotovi.
\:Pokud hlava odchází doprava, položíme $f_{i+1}(s) = s'_j$ a jsme hotovi.
\:Pokud hlava zůstává na místě, položíme $s_{j+1} = s'_j$ a pokračujeme ve vytváření posloupnosti
s~několika výjimkami: Je-li $s'_j$ rovno $q_+$ nebo~$q_-$, položíme $f_i(s) = s'_j$ a skončíme.
s~několika výjimkami: Je-li $s'_j$ rovno $q_+$ nebo~$q_-$, položíme $f_{i+1}(s) = s'_j$ a skončíme.
Je-li $s'_j$ rovno některému z~předešlých~$s_k$ pro $k\le j$, stroj se zacyklil, takže položíme
$f_i(s) = q_-$ a skončíme.
\:Pokud hlava odchází doprava, využijeme známou funkci $f_{i+1}$ popisující chování na suffixu
$\alpha[i+1:{}]$, takže položíme $s_{j+1} = f_{i+1}(s'_j)$. Opět ošetříme případy, kdy je tento
$f_{i+1}(s) = q_-$ a skončíme.
\:Pokud hlava odchází doleva, využijeme známou funkci $f_i$ popisující chování na prefixu
$\alpha[{}:i-1]$. Stačí položit $s_{j+1} = f_i(s'_j)$. Opět ošetříme případy, kdy je tento
stav roven $q_+$, $q_-$, případně některému z~předchozích stavů v~posloupnosti.
\endlist
Všimněte si, že funkce~$f_i$ je jednoznačně určena funkcí~$f_{i+1}$ a znakem $\alpha[i]$.
To nám dává návod na sestrojení konečného automatu, který bude procházet vstupem zprava doleva
a postupně přepočítávat funkci~$f_i$. Stavy automatu odpovídají všem funkcím z~$Q\setminus\{q_+,q_-\}$ do~$Q$,
takže jich je konečně mnoho.
Všimněme si, že funkce~$f_{i+1}$ je jednoznačně určena funkcí~$f_i$ a znakem $\alpha[i]$.
Můžeme tedy sestrojit konečný automat, který bude procházet vstupem zprava doleva
a postupně přepočítávat funkci~$f_i$. Stavy automatu odpovídají všem funkcím z~$Q\setminus\{q_+,q_-\}$ do~$Q$
a~těch je konečně mnoho. Přechody jsou dány konstrukcí~$f_{i+1}$ z~$f_i$.
Po zpracování znaku $\alpha[i]$ se tedy automat nachází ve stavu~$f_{i+1}$.
Zbývá dořešit, jak automat začne a jak skončí.
Ještě je potřeba domyslet, jak automat začne.
Zkusme použít naši konstrukci pro funkci~$f_0$ -- chování TFA na prázdném prefixu.
Hlava TFA tedy stojí na levé zarážce~$\|<|$, odkud se nesmí pohnout doleva.
Konstrukce se proto nikdy nezeptá na neexistující~$f_{-1}$.
Funkce~$f_0$ je tudíž nezávislá na vstupu a může posloužit jako počáteční stav automatu.
Použijeme-li naši konstrukci pro funkci~$f_n$, tedy chování výpočtu na pravé zarážce~\|>|,
nikdy se nezeptá na neexistující~$f_{n+1}$. To proto, že stroj se na pravé zarážce nemůže
pohybovat doprava. Funkce~$f_n$ je tedy nezávislá na vstupu, takže může posloužit jako
počáteční stav automatu.
Máme tedy automat, který po přečtení vstupu $\alpha\|>|$ zná funkci~$f_{n+1}$ --
chování na celém vstupu, stojíme-li na pravé zarážce~$\|>|$.
Až automat přečte levou zarážku~$\|<|$, bude jeho stav roven funkci~$f_{-1}$.
Ta popisuje chování na celém vstupu. Takže do ní chceme dosadit počáteční stav~$q_0$
původního TFA.
Je-li $f_{-1}(q_0)$ rovno~$q_+$, vstup přijmeme.
Pokud je rovno~$q_-$, tak odmítneme.
Nic jiného nemůže funkce vrátit, protože by to znamenalo, že automat z~\|<| odešel doleva, a~to nesmí.
Přijímací stavy tedy odpovídají těm funkcím~$f$, pro něž je $f(q_0)=q_+$.
Teď se nabízí do této funkce dosadit počáteční stav TFA~$q_0$, a~tím zjistit,
jaký výsledek TFA vydá. To ale nemůžeme provést: hlava TFA začíná na levém
okraji vstupu, nikoliv na~$\|>|$. Pomoc je naštěstí snadná: TFA upravíme, aby
začínal na~$\|>|$ v~nějakém novém stavu~$q'_0$. V~něm půjde doleva, dokud nenarazí
na~$\|<|$, načež udělá krok doprava a přepne se do původního počátečního stavu~$q_0$.
Tím jsme sestrojili automat dosvědčující regularitu. Ovšem ne původního jazyka~$L$,
nýbrž jazyka $L' = L\rev\cdot\{\|<|\}$, v~němž jsou slova pozpátku a ukončená zarážkou.
Je-li tedy $f_{n+1}(q'_0)$ rovno~$q_+$, TFA vstup přijal, takže DFA přijme také.
Podobně je-li rovno~$q_-$, tak odmítne.
Nic jiného nemůže funkce vrátit, protože by to znamenalo, že automat z~\|>| odešel doprava, a~to nesmí.
Přijímací stavy tedy odpovídají těm funkcím~$f$, pro něž je $f(q'_0)=q_+$.
Teď si stačí uvědomit, že z~regularity~$L'$ plyne regularita~$L\rev$ a z~ní zase regularita~$L$.
Regularitu $L\rev$ můžeme zdůvodnit cvičením \exref{quotex}, protože $L\rev$ je kvocient $L' / \{\|<|\}$.
Tím jsme sestrojili automat dosvědčující regularitu. Ovšem ne původního jazyka~$L$,
nýbrž jazyka $L' = L\cdot\{\|>|\}$, v~němž jsou slova ukončená zarážkou.
Uvědomíme si, že z~regularity~$L'$ plyne regularita~$L$.
To můžeme zdůvodnit cvičením \exref{quotex}, protože $L$ je kvocient $L' / \{\|>|\}$.
Nebo to lze provést přímo úpravou koncových stavů: za koncové prohlásíme ty stavy, z~nichž vede přechod
před znak~$\|<|$ do některého z~původních koncových stavů.
Regularitu~$L$ dostaneme z~uzavřenosti regulárních jazyků na otočení (cvičení \exref{regrev}).
před znak~$\|>|$ do některého z~původních koncových stavů.
\qed
\exercises
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment