¤§¨­°´¸Ý FI MUFakulta informatiky Masarykova univerzita Automaty a formální jazyky I Ivana Černá Mojmír Křetínský Antonín Kučera Učební text FI MU verze 1.3 Copyright c­2002, FI MU únor 2002 Obsah 1 Jazyk a jeho konečná reprezentace 1 1.1 Abeceda a jazyk 1 1.1.1 Operace nad jazyky 2 1.2 Konečná reprezentace jazyka 3 1.2.1 Pojem gramatiky 4 1.2.2 Chomského hierarchie gramatik a jazyků 5 2 Regulární jazyky a konečné automaty 9 2.1 Konečné automaty 9 2.1.1 Konstrukce konečných automatů 15 2.1.2 Lemma o vkládání pro regulární jazyky 18 2.1.3 Myhillova-Nerodova věta 21 2.1.4 Minimální konečný automat 25 2.1.5 Minimalizace konečných automatů 26 2.2 Konservativní rozšíření modelu konečných automatů 31 2.2.1 Nedeterministické konečné automaty 31 2.2.2 Automaty s -kroky 36 2.2.3 Uzávěrové vlastnosti regulárních jazyků ­ část I 39 2.2.4 Regulární výrazy 41 2.3 Vlastnosti regulárních jazyků 47 2.3.1 Uzávěrové vlastnosti regulárních jazyků ­ část II 47 2.3.2 Ekvivalence konečných automatů a regulárních gramatik 48 2.3.3 Rozhodnutelné problémy pro třídu regulárních jazyků 51 2.4 Aplikace regulárních jazyků a konečných automatů 54 3 Bezkontextové jazyky a zásobníkové automaty 57 3.1 Bezkontextové gramatiky 57 3.1.1 Derivační stromy 57 3.1.2 Transformace bezkontextových gramatik 61 3.1.3 Chomského normální forma, lemma o vkládání 66 3.1.4 Greibachové normální forma 71 3.2 Zásobníkové automaty 76 3.2.1 Definice PDA 77 3.2.2 Zásobníkové automaty a bezkontextové jazyky 83 3.3 Vlastnosti bezkontextových jazyků 92 3.3.1 Uzávěrové vlastnosti 92 3.3.2 Rozhodnutelné vlastnosti a regularita 95 3.4 Deterministické zásobníkové automaty 98 3.4.1 Definice DPDA a jejich základní vlastnosti 98 3.4.2 Uzávěrové vlastnosti deterministických jazyků 100 4 Turingovy stroje a jazyky typu 0 105 4.1 Turingův stroj: model a jeho definice 105 4.2 Metody konstrukce Turingových strojů 110 4.3 Modifikace Turingových strojů 112 4.4 Vlastnosti rekursivních a rekursivně spočetných jazyků 120 4.5 Turingovy stroje a jazyky typu 0 123 4.6 Lineárně ohraničené automaty a jazyky typu 1 125 5 Nerozhodnutelnost 129 5.1 Churchova teze 129 5.2 Kódování TM a univerzální TM 130 5.3 Diagonalizace 132 5.4 Redukce 136 5.5 Další rozhodnutelné a nerozhodnutelné problémy pro TM 139 5.6 Postův korespondenční problém 143 5.7 Nerozhodnutelné problémy z teorie formálních jazyků 150 Kapitola 1 Jazyk a jeho konečná reprezentace V této kapitole budou zavedeny základní pojmy, které jsou předmětem zkoumání teorie formálních jazyků. 1.1 Abeceda a jazyk Abecedou se rozumí libovolná konečná množina , jejíž prvky nazýváme znaky (případně také písmena nebo symboly) abecedy. Příkladem abecedy je třeba množina {a, b}, množina číslic {0, 1, . . . , 9}, nebo prázdná množina . Slovo (též řetězec) v nad abecedou je libovolná konečná posloupnost znaků této abecedy (např. aabb je slovo nad abecedou {a, b}). Počet členů této posloupnosti v značíme |v| a nazýváme délkou slova, počet výskytů znaku a ve slově v značíme #a(v) (např. #b(abaaba) = 2). Prázdné posloupnosti znaků odpovídá tzv. prázdné slovo, označované , které má nulovou délku. Množinu všech slov nad abecedou značíme , množinu všech neprázdných slov +. Platí např. {a} = {, a, aa, aaa, aaaa, . . . } {a}+ = {a} \ {} {0, 1} = {, 0, 1, 00, 01, 10, 11, 000, 001, 010, 011, . . . } Definitoricky dále klademe = {} a + = . Na každá dvě slova u, v lze aplikovat binární operaci zřetězení, označovanou ,,.", která je definována předpisem u.v = uv. Např. zřetězením slov abba a bba obdržíme slovo abbabba. Operace zřetězení je asociativní, tj. u.(v.w) = (u.v).w pro libovolná slova u, v, w. Dále se chová jako jednotkový prvek, tj. u. = .u = u pro libovolné slovo u. V dalším textu budeme znak ,,." v zápisu zřetězení obvykle vynechávat. Každé (neprázdné) slovo nad abecedou lze získat zřetězením (nenulového počtu) symbolů této abecedy ­ odtud ,,řetězec" jako ekvivalent pojmu slovo. Pro snadnější specifikaci jazyků je výhodné zavést unární operaci i-té mocniny slova, která je definovaná induktivně pro každé i 0 takto: necht' je libovolná abeceda, u libovolné slovo. Pak ˇ u0 = ˇ ui+1 = u.ui Např. (abc)3 = abcabcabc (kulaté závorky slouží jako metasymboly; nejsou součástí slova, pouze pomáhají vymezit argument operace). Slovo u je podslovem slova v, jestliže existují slova x, y taková, že v = xuy. Pokud navíc x = , říkáme že slovo u je předponou (nebo také prefixem) slova v, což značíme u v ( je tedy částečným uspořádáním na ); je-li v tomto případě ještě navíc u = v (tj. y = ), pak klademe u v. Je-li y = (nyní již bez omezujících požadavků na x), nazveme u příponou (sufixem) slova v. Například aa je předponou aabab, zatímco 11 není ani podslovem slova 01010. Konečně pro každé k 1 celé a slovo v značíme zápisem k v předponu slova v délky (nejvýše) k a dejinujeme k v = u, pokud existuje w takové, že v = uw a |u| = k; v opačném případě klademe k v = v. Zejména tedy pro neprázdné slovo v zápis 1 u znamená první znak slova v. Jazyk nad abecedou je libovolná množina slov nad (jazyky nad jsou tedy právě podmnožiny ). Např. {10, 1, 011101} je jazyk nad abecedou {0, 1}, prázdná množina je jazyk nad libovolnou abecedou, atd. Jazyky mohou ovšem být i nekonečné, např. {w {a, b} | #a(w) = #b(w)} je jazyk nad abecedou {a, b} obsahující všechna slova, ve kterých se a i b vyskytují ve stejném počtu (tedy např. aababb, jsou prvky tohoto jazyka, zatímco a, abbaa nikoliv). 1.1.1 Operace nad jazyky V této části zavedeme některé operace nad jazyky, které se v dalších kapitolách ukáží jako velmi důležité. Je třeba důsledně rozlišovat mezi operacemi nad slovy a operacemi nad jazyky, i když se některé z nich (jako třeba zřetězení nebo mocnina) značí v obou případech stejně. Na základě ,,typu" parametrů bude vždy jasné, zda se jedná o operaci nad slovy nebo jazyky. Necht' L je libovolný jazyk nad abecedou a K libovolný jazyk nad abecedou . Jelikož L i K jsou množiny, můžeme aplikovat standardní množinové operace sjednocení, průnik a rozdíl. Výsledkem je vždy jazyk nad abecedou . Dále definujeme: ˇ Zřetězením jazyků K a L je jazyk K.L = {uv | u K, v L} nad abecedou . Podle definice zejména platí .M = M. = a {}.M = M.{} = M pro libovolný jazyk M. Operace zřetězení jazyků je také zřejmě asociativní. ˇ i-tá mocnina jazyka L je definována induktivně pro každé i 0: 1. L0 = {} 2. Li+1 = L.Li Zejména tedy 0 = {}, i = pro libovolné i a {}j = {} pro libovolné j 0. ˇ Iterace jazyka L je jazyk L = i=0 Li . ˇ Pozitivní iterace jazyka L je jazyk L+ = i=1 Li . Obecně není pravda, že L+ = L \ {}; tato rovnost platí právě tehdy, když L neobsahuje . ˇ Doplněk jazyka L je jazyk co­L = \ L. ˇ Zrcadlovým obrazem (též reverzí) slova x = a1 . . . an nazýváme slovo wR = an . . . a1 (R = ). Zrcadlový obraz jazyka L definujeme jako L R = {wR|w L}. ˇ Substituce f je zobrazení abecedy do podmnožin množiny , tj. f přiřazuje každému a jazyk f (a) . Zobrazení f je rozšířeno na slova takto: 1. f () = 2. f (xa) = f (x) f (a). f rozšíříme na jazyky tak, že pro každé L klademe f (L) = xL f (x). Substituci f nazveme nevypouštějící jestliže žádné z f (a), a neobsahuje . ˇ Speciálním případem substituce je homomorfismus h, který definujeme jako substi- tuci, u níž h(a) obsahuje jediné slovo pro každé a . V tomto případě obvykle h(a) považujeme za slovo a nikoli jednoprvkovou množinu obsahující toto slovo. Je-li navíc h(a) = pro všechna a , říkáme, že h je nevypouštějící (též -free). ˇ Je-li h homomorfismus, pak definujeme inverzní homomorfní obraz jazyka L jako h-1(L) = {x|h(x) L} a pro slova definujeme inverzní homomorfismus jako h-1(w) = {x|h(x) = w}. V souvislosti s operací iterace je dobré si povšimnout, že symbolem jsme v předchozí části označili množinu všech slov nad abecedou . Jelikož samotné je možné chápat jako jazyk nad (obsahující právě všechna slova délky jedna), lze zápis interpretovat také jako iteraci jazyka . Tato nejednoznačnost však není na závadu; snadno se vidí, že iterací obdržíme právě jazyk obsahující všechna slova nad . Ze stejného důvodu je nezávadná dvojznačnost zápisu +. Necht'Ä je třída jazyků a o je n-ární operace na jazycích. Ř ekneme, že Äje uzavřená na o, pokud pro libovolné jazyky L1, . . . , Ln patřící do Äplatí, že také jazyk o(L1, . . . , Ln) patří do Ä. Příklad 1.1. Necht'Ä je množina tvořená jazyky Li = {ai }, kde i 0. Pak Äje uzavřena na zřetězení a mocninu, ale není uzavřena na doplněk, sjednocení, průnik, rozdíl a iteraci . Příklady subbstitucí a homomorfismů budou uvedeny v relevantních partiích tohoto textu. 1.2 Konečná reprezentace jazyka Většina jazuků, kterými se budeme zabývat v tomto textu, bude obsahovat nekonečný počet slov. V této souvislosti velmi přirozeně vyvstávají některé důležité otázky. Jedna z nich se nabízí okamžitě ­ jak konečným způsobem reprezentovat (obecně nekonečný) jazyk, tj. specifikovat množinu všech jeho slov (tzv. problém konečné repre- zentace). Pokud by jazyk byl konečný (tj. obsahoval pouze konečně mnoho slov), pak vystačíme s výčtem všech jeho slov. V případě jazyka nekonečného je problém jeho ko- nečné reprezentace velice podstatný. Konečná reprezentace by měla být (formálně vzato) opět řetězcem symbolů (nad jistou abecedou), který budeme vhodně interpretovat tak, aby danému jazyku odpovídala nějaká (ne nutně jediná) konkrétní konečná reprezentace; ob- ráceně pak, aby každé konkrétní konečné reprezentaci odpovídal jediný konkrétní jazyk. Takovými reprezentacemi pro nás v dalším textu budou zejména tzv. gramatiky, které zavedeme v této kapitole a automaty, které budeme definovat později. V návaznosti na právě řečené vystává další otázka, a to zda pro každý jazyk existuje jeho konečná reprezentace. Zde lze po krátkém zamyšlení očekávat negativní odpověd': množina všech řetězců nad libovolnou abecedou je spočetně nekonečná, ale systém všech podmnožin spočetně nekonečné množiny je množina nespočetná. Jelikož bychom měli být schopni zapsat jakoukoli definici konečné reprezentace jako nějaký řetězec symbolů, lze (alespoň na intuitivní úrovni) očekávat, že dostaneme jen spočetně mnoho konečných reprezentací, a tedy že existuje mnohem víc jazyků, než konečných reprezentací (formálněji jsou tyto úvahy formulovány a dokázány až po definici pojmu gramatiky v tvrzení 1.4). Konečně si lze položit otázku, jaká je struktura, vlastnosti, . . . těch tříd jazyků pro něž existují konečné reprezentace (a to v souvislosti s ,,typem" této reprezentace), jak lze tyto třídy charakterizovat atp. Těmto problémům je věnována převžná část tohoto učebního textu. 1.2.1 Pojem gramatiky Definice 1.2. Gramatika je čtveřice (N, , P, S), kde ˇ N je neprázdná konečná množina neterminálních symbolů (stručněji: neterminálů). ˇ je konečná množina terminálních symbolů (terminálů) taková, že N = . Sjednocením N a obdržíme množinu všech symbolů gramatiky, kterou obvykle označujeme symbolem V . ˇ P V NV ×V je konečná množina pravidel. Pravidlo (, ) obvykle zapisujeme ve tvaru (a čteme jako ,, přepiš na "). ˇ S N je speciální počáteční neterminál (nazývaný také kořen gramatiky). Podmínka kladená na tvar pravidel pouze požaduje, aby (tzv. levá strana pravidla) obsahovala alespoň jeden neterminál; na (pravou stranu pravidla) nejsou obecně kladeny žádné požadavky ­ specielně, může být i prázdným slovem . Každá gramatika = (N, , P, S) určuje binární relaci přímého odvození na množině V definovanou takto: právě když existuje pravidlo P a slova , V taková, že = a = . V dalších kapitolách budeme rovněž potřebovat tyto relace na V : ˇ relaci odvození v k krocích (k-násobné složení relace ) značíme k a definujeme pro každé k 0 induktivně takto: ­ 0 je identická relace ­ k+1 = k ˇ relaci odvození v nejvýše k krocích, kterou značíme k a definujeme pro každé k 0 předpisem k = k i=0 i ˇ relaci odvození, ktrerou značíme a definujeme předpisem = i=0 i Tedy je reflexivní a tranzitivní uzávěr . ˇ Relace netriviálního odvození, kterou značíme + , je definována takto: + = i=1 i Relace + je tedy tranzitivní uzávěr relace . V dalším textu budeme index u výše uvedených relací obvykle vynechávat, bude-li z kontextu patrné, o kterou gramatiku se jedná. Prvky množiny V , které lze odvodit z počátečního neterminálu, nazýváme větnými formami gramatiky . Přesněji, V je větná forma právě když S . Větná forma, která neobsahuje žádné neterminály, se nazývá věta. Množina všech vět tvoří jazyk generovaný gramatikou , označovaný jako L( ): L( ) = {w | S w} Gramatiky 1 a 2 nazveme jazykově ekvivalentní (dále jen ekvivaletní), právě když gene- rují tentýž jazyk, tj. L( 1) = L( 2). Příklad 1.3. Necht' = ({S, A, B}, {a, b}, P, S), kde P = { S ABS, S , AB B A, B A AB, A a, B b } Pak např. AaB AbBS je větná forma , zatímco ABb nikoliv. Jazyk L( ) vypadá takto: L( ) = {u {a, b} | #a(u) = #b(u)}. V následujícím textu budeme dodržovat tyto konvence týkající se značení: ˇ Kořen gramatiky obvykle značíme symbolem S. ˇ Neterminální symboly jsou označovány velkými písmeny (obvykle ze začátku) la- tinské abecedy (A, B, C, . . . ) ˇ Terminální symboly obvykle značíme malými písmeny ze začátku latinské abecedy (a, b, c, . . . ). ˇ Ř etězce, které jsou složeny výhradně z terminálních symbolů (tzv. terminálnířetězce) obvykle značíme malými písmeny z konce latinské abecedy (. . . , x, y, z) ˇ Ř etězce, které mohou být složené z terminálních i neterminálních symbolů, jako např. větné formy, značíme malými řeckými písmeny (, , , . . . ). ˇ Pravidla , se stejnou levou stranou často zapisujeme stručněji jako | . Uvedené konvence platí, pokud v textu není výslovně uvedeno jinak. 1.2.2 Chomského hierarchie gramatik a jazyků Lingvista Noam Chomsky rozdělil gramatiky do čtyř skupin (typů) na základě různých omezení na tvar pravidel. Jeho práce (z konce 50. let) byla původně motivována úvahami o struktuře přirozeného jazyka, z dnešního pohledu má však především význam jako zá- kladní (a neobyčejně výhodné) rozdělení gramatik podle jejich popisné síly. Chomského hierarchie rozlišuje tyto čtyři (základní) typy gramatik: typ 0 Libovolná gramatika je gramatikou typu 0; na tvar pravidel se nekladou žádné omezující požadavky. Někdy též se takové gramatiky označují jako gramatiky bez omezení či frázové gramatiky (phrase grammars). typ 1 Gramatika je typu 1 (nebo též kontextová1, Context-Sensitive, CSG, méně často též monotónní), jestliže pro každé její pravidlo platí || || s eventuelní výjimkou pravidla S , pokud se S nevyskytuje na pravé straně žádného pravidla. typ 2 Gramatika je typu 2 (též bezkontextová, Context-Free, CFG), jestliže každé její pravidlo je tvaru A , kde || 1 s eventuelní výjimkou pravidla S , pokud se S nevyskytuje na pravé straně žádného pravidla. typ 3 Gramatika je typu 3 (též regulární či pravolineární2), jestliže každé její pravidlo je tvaru A aB nebo A a s eventuelní výjimkou pravidla S , pokud se S nevyskytuje na pravé straně žádného pravidla. 3 V dalším textu bude ukázáno, že ke každé gramatice typu 2 s pravidly A , kde || 0, lze sestrojit ekvivaletnígramatiku typu 2 splňujícípožadavek || 1 s eventuelnívýjimkou o S . Z toho okamžitě plyne i analogické tvrzení pro typ 3, pokud bychom povolili pravidla tvaru A . Hierarchie gramatik také určuje příslušnou hierarchii jazyků. Jazyk L je regulární (resp. bezkontextový, kontextový, typu 0) pokud existuje regulární (resp. bezkontextová, kontextová, typu 0) gramatika taková, že L( ) = L. Nyní je již zřejmý smysl ,,výjimky" týkající se pravidla S ; kdybychom ji nepovolili, stal by se z libovolného (třeba i regulárního) jazyka po přidání prázdného slova jazyk typu 0, který nelze popsat ani kontextovou gramatikou. To by bylo značně nepřirozené ­ přidáním jediného slova se ,,charakter" obecně (a též i obvykle) nekonečného jazyka příliš nezmění. Z definice je patrné, že každý nový typ gramatiky v Chomského hierarchii je spe- cifikován zavedením dalších omezujících podmínek na typ předchozí ­ například každá regulární gramatika je také gramatikou bezkontextovou, kontextovou i typu 0. Naopak to ovšem neplatí. V této souvislosti se rovněž nabízí přirozená otázka, zda existuje jazyk, který není typu 0, tj. jazyk, který nelze generovat žádnou gramatikou, či ekvivaletně jazyk, pro nějž neexistuje konečná reprezentace (pomocí gramatiky). Odpověd'podává tato věta: Tvrzení 1.4. Nad abecedou {a} existuje jazyk, který není typu 0. Důkaz: Množina všech slov nad abecedou {a} je spočetně nekonečná. Množina všech jazyků nad touto abecedou má proto mohutnost 20 , což je mohutnost kontinua (zejména je 1. Název ,,kontextová" je odvozen z toho, že uvedenou podmínku je možné ekvivalentně zformulovat také tak, že každé pravidlo je tvaru A , kde || 1 (tj. neterminál A se přepíše na tehdy, je-li obklopen kontextem a ). ,,Ekvivalentní formulací" myslíme to, že třída všech jazyků, které lze generovat kontextovými gramatikami, se nezmění. 2. Analogicky lze definovat gramatiky levolineární s pravidly tvaru A Ba nebo A a. I tyto gramatiky se nazývají regulární. 3. U tohoto typu gramatik bývá někdy v uvedené definici povoleno a {}; třída jazyků generovaných těmito gramatikami se nezmění oproti standardnímu případu. tedy nespočetná). Ukážeme, že jazyků typu 0 nad abecedou {a} je pouze spočetně mnoho. Bud' M libovolná, ale pro další úvahy pevně zvolená spočetná množina. Ke každé gramatice s množinou neterminálů N existuje ekvivalentní gramatika jejíž množina neterminálů je podmnožinou M (stačí ,,přejmenovat" prvky N vhodně zvolenými prvky množiny M). Lze proto bez újmy na obecnosti předpokládat, že každá gramatika s množinou terminálů {a} má neterminály z množiny M. Ukážeme, že všech takových gramatik je pouze spočetně mnoho. K tomu si stačí uvědomit, že zápis každé takové gramatiky je vlastně slovo nad spočetnou abecedou M {a, , (, ), {, }, ,} Podtržítka mají jen pomocnou úlohu ­ naznačují, že se má podtržený znak chápat jako prvek množiny a ne jako metasymbol. Všech slov délky i nad touto abecedou je i 0 = 0 pro libovolné i . Všech slov nad touto abecedou je proto spočetně mnoho, nebot' sjednocením spočetně mnoha spočetných množin je spočetná množina. Uvažovaných gramatik je proto rovněž spočetně mnoho. Z důkazu předchozí věty je patrné, že gramatikami lze ve skutečnosti popsat jen ,,velmi malou" třídu jazyků. Z uvedeného není ovšem jasné, jakého ,,druhu" jsou jazyky, které nejsou typu 0 ­ jak uvidíme později, spadají sem i některé velmi přirozeně definované jazyky. Pozorného čtenáře jistě napadne i další otázka ­ existuje nějaký mocnější aparát pro popis jazyků než gramatiky? Uvědomme si, že základní požadavek na každý takový aparát je, aby jazyky byly popsány konečným způsobem. Jazyky tedy budou v každém případě specifikovány konečnou posloupností matematických symbolů. Jelikož matematika vystačí se spočetně mnoha symboly, lze aplikovat argument předchozího důkazu; každá konečná reprezentace (popisný aparát) proto dokáže popsat nejvýše spočetnou množinu jazyků. Toto základníomezenínelze překonat. Nenívšak možné předem vyloučit existenci aparátu, který interpretuje zápis jazyka takovým způsobem, že lze konečně zapsat i jazyky, které nejsou typu 0. Toto je základní omezení, kterým je ovlivněna celá informatika. I program (nebo libovolný jiný zápis algoritmu) je totiž konečná posloupnost znaků a je jich proto spočetně mnoho. Jak uvidíme, lze problémy formálně specifikovat jako jazyky. Všech problémů je tedy nespočetně mnoho. Z toho okamžitě plyne, že jsou i takové problémy, na jejichž řešení neexistuje algoritmus. Mezi nimi se najdou i takové problémy, kde by existence algoritmu byla velmi užitečná (ale bohužel tomu tak není). Patří k nim například ˇ problém, zda libovolný daný program ukončí svůj výpočet pro (jeden) libovolný daný vstup (vstupní data), resp. pro každý daný vstup (tj. zda program pro zadaný bude cyklit, resp. pro žádný vstup nikdy cyklit nebude), ˇ problém, zda dva libovolné dané programy jsou ekvivalentní v tom smyslu, že pro stejné vstupy dávají tytéž výsledky (například prototyp nějakého systému či jeho proveditelná specifikace jako jeden program a efektivní implementace téhož systému jako program druhý), ˇ problém, zda dvě libovolné bezkontextové gramatiky (tj. užitečný nástroj pro spe- cifikaci syntaxe programovacích jazyků) jsou ekvivaletní (jedna z gramatik definuje syntaxi jazyka vhodnou pro uživatele ­ programátora, je však nevhodná pro jeho implementaci; tvůrce překladače musí najít jinou vhodnou gramatiku, ale neexistuje algoritmus, který by ověřil, zda tyto gramatiky jsou ekvivalentní) ˇ a řada dalších. Touto problematikou se budeme zabývat v kapitole 5, tj. až po studiu jazyků gene- rovatelných gramatikami v Chomského hierarchii. Detailněji se těmito otázkami zabývá teorie vyčíslitelnosti. Kapitola 2 Regulární jazyky a konečné automaty V této kapitole se budeme zabývat vlastnostmi regulárních jazyků. Ukážeme si alternativní způsoby jejich formální reprezentace, které jsou na první pohled velmi odlišné od regu- lárních gramatik ­ nejprve zavedeme pojem konečného automatu, který je matematickým modelem jednoduchého výpočetního zařízení s konečnou pamětí, schopného rozpoznávat určitý jazyk. Dokážeme, že třída jazyků, které lze rozpoznat konečnými automaty, je přesně třída regulárních jazyků; tento poznatek také přinese zajímavé výsledky o jejich struktuře a vlastnostech. Další způsob formální reprezentace regulárních jazyků představují tzv. regulární výrazy, kterými se budeme rovněž zabývat. Umožňují popsat libovolný regulárníjazyk jako výsledek kompozice několika jednoduchých operací nad jazyky (jde tedy o nerekurzivní popis, na rozdíl od gramatik a konečných automatů). V závěru kapitoly se také zmíníme o praktickém uplatnění prezentovaných teoretic- kých poznatků; možnosti jsou velmi široké a pečlivé studium tohoto textu proto rozhodně není ztrátou času. 2.1 Konečné automaty V každodenním životě se často setkáváme se zařízeními, která provádějí jistý druh čin- nosti na základě poměrně komplikované komunikace s okolím. Dobrým příkladem je třeba automat na kávu ­ představme si stroj, který je vybaven dvoumístným displejem (je tedy schopen přijmout hotovost až do výše 99 korun), dále otvorem pro mince, několika tlačítky pro výběr nápoje a samozřejmě výdejním systémem. Komunikace s automatem probíhá po- mocí uvedených komponent. Jedinou výjimkou je v tomto směru displej; ten se komunikace přímo neúčastní, pouze signalizuje množství peněz, které byly do automatu vhozeny. To je také jediná veličina, která ovlivňuje další chování přístroje (pro jednoduchost neuvažujeme množství surovin, které v automatu zbývá). Určuje, které tlačítko pro volbu nápoje lze použít, zda je ještě možné vhodit další minci (pokud by výsledná částka přesáhla 99 korun, je mince odmítnuta), případně kolik peněz má automat po stisku speciálního tlačítka vrátit. Hodnota na displeji tedy přesně a úplně vystihuje momentálnístav automatu. Ten se měnína základě komunikace s okolím podle předem stanoveného protokolu ­ vhozením další mince nebo stiskem tlačítka se stav automatu příslušným způsobem upraví. Odebrání nápoje pří- stroj nijak nezaznamená, nemá tudíž na stav žádný vliv (čtenář se může snadno přesvědčit, že tento předpoklad je celkem realistický). Vnitřní protokol automatu musí přesně vystih- nout, která posloupnost akcí je pro automat přijatelná a která nikoliv. Jestliže bílá káva stojí 8 korun a objednává se tlačítkem X, je např. posloupnost akcí 2Kč, 5Kč, 1Kč, X pro automat přijatelná, zatímco sekvence 1Kč, 1Kč, X nikoliv. Jelikož další činnost automatu je úplně určena jeho momentálním stavem, kterých je konečně mnoho (přesně 100), je možné zmíněný protokol specifikovat tak, že pro každý stav uvedeme seznam akcí, na které je automat schopen reagovat spolu se stavem, do kterého se po dané akci dostane. Existuje mnoho systémů, jejichž chování lze definovat pomocíkonečně mnoha stavů, akcí a přechodů mezi stavy. Nemusí se vždy jednat zrovna o řídící jednotky ­ i některé společenské hry jako třeba šachy lze tímto způsobem chápat a přesně popsat; stavy jsou v tomto případě všechna možná rozložení figur na šachovnici (jelikož máme konečný počet figur i polí, je možných rozložení také konečně mnoho), akce jsou všechny možné tahy (např. ,,bílá věž z B2 na B6") a v každém stavu lze provést pouze ty akce, které neodporují danému rozložení figur a pravidlům šachu. Pokud se zajímáme například o výherní strategii hráče s bílými figurami, můžeme stavy ve kterých dává bílý mat označit za koncové. Ověřit, zda bílý má v daném stavu šanci na výhru pak znamenená zjistit, zda z daného stavu existuje posloupnost akcí, která vede do některého z koncových stavů. Ne každá hra se ovšem dá popsat jako systém s konečným počtem stavů (dále jen stručněji: konečně stavový systém). Příkladem jsou tzv. ,,piškvorky" ­ hrací pole je potenciálně nekonečné a hra má tudíž nekonečně mnoho možných konfigurací. I počítače jsou konečně stavové systémy, nebot'mají sice velkou, ale přece jen koneč- nou pamět, která tudíž může nabýt pouze konečně mnoha stavů (počítáme sem samozřejmě i disky, vyrovnávací paměti, velkokapacitní záznamová média sdílená po síti a podobně). Akce a přechody mezi stavy paměti nelze v tomto případě popsat nějak jednoduše ­ závisí na konstrukci počítače a samozřejmě i na samotném obsazení paměti (jaký program se provádí, jaká má data atd.). Zároveň je však třeba poznamenat, že omezení na velikost paměti je poněkud umělé. V praxi nepředstavuje zásadní problém a v abstraktních úvahách je proto účelné tento limit zcela pominout. Získané teoretické výsledky pak mnohem lépe odvídají realitě, nebot' přesněji vystihují ,,výpočetní sílu" reálných počítačů, jak ostatně uvidíme v kapitole 5. Abstraktním modelem konečně stavových systémů jsou tzv. konečné automaty. Ko- nečný automat je vybaven konečně stavovou řídící jednotkou (tj. konečnou pamětí), čtecí hlavou a páskou, na které je zapsané vstupní slovo ­ viz obrázek 2.1. Na začátku výpočtu je hlava umístěna na nejlevějším políčku pásky. Automat na základě přečteného symbolu a momentálního stavu svůj stav změní a posune čtecí hlavu o jedno políčko vpravo. Vý- počet končí, pokud se automat ,,zablokuje", nebo přečte celé vstupní slovo. Slovo zapsané na pásce je automatem akceptováno, pokud je celé přečteno a výsledný stav je některý z předem určených koncových stavů. Množina všech slov, která daný konečný automat akceptuje, tvoří jazyk akceptovaný automatem .Formální definice vypadá takto: Definice 2.1. Konečný automat (Finite Automaton, FA) je pětice (Q, , , q0, F), kde a a b a b b b a konečně stavová řídící jednotka čtecí hlava vstupní páska Obrázek 2.1: Konečný automat ˇ Q je neprázdná konečná množina stavů. ˇ je konečná množina vstupních symbolů, nazývaná také vstupní abeceda. ˇ Q × Q je parciální přechodová funkce. ˇ q0 Q je počáteční stav. ˇ F Q je množina koncových stavů. Abychom mohli definovat jazyk přijímaný daným FA , zavedeme rozšířenou přecho- dovou funkci ^ Q × Q, definovanou induktivně vzhledem k délce slova ze : ˇ ^(q, ) = q pro každý stav q Q. ˇ ^(q, wa) = (^(q, w), a) je-li ^(q, w) i (^(q, w), a) definováno, jinak. Symbol značí, že funkce není definovaná. Zápis ^(q, w) = p znamená, že automat přejde ze stavu q ,,pod slovem" w (tj. postupným přečtením slova w znak po znaku zleva doprava) do stavu p. Jazyk přijímaný (akceptovaný, rozpoznávaný) konečným automatem ,označovaný L(), je tvořen právě všemi takovými slovy, pod kterými automat přejde z počátečního stavu do některého z koncových stavů: L() = {w | ^(q0, w) F} Jazyk, který je rozpoznatelný (nějakým) konečným automatem, nazveme regulární (viz však poznámka 2.2. Ekvivalenci konečných automatů definujeme podobně jako v případě gramatik ­ konečné automaty a jsou ekvivalentní, pokud L() = L( ). Poznámka 2.2. V části 1.2.2 jsme přívlastkem ,,regulární" označili jazyk generovatelný regulární gramatikou; jak uvidíme, jsou třídy jazyků, které lze generovat regulárními gra- matikami, resp. rozpoznat konečnými automaty, ve skutečnosti stejné. Než toto dokážeme, bude slovo ,,regulární" zkratkou pro ,,rozpoznatelný konečným automatem". Příklad 2.3. Necht' = ({q0, q1, q2}, {a, b}, , q0, {q2}) je FA, kde (q0, a) = q1 (q0, b) = q2 (q1, a) = q2 (q1, b) = q0 (q2, a) = q0 (q2, b) = q1 Pak L() = {w {a, b} | (#a(w) - #b(w)) mod 3 = 2}. Ú plná definice konkrétního automatu musí zahrnovat popis všech složek pětice z defi- nice 2.1. Není však nutné tyto složky vždy reprezentovat standardní množinovou symboli- kou (tj. výčtem prvků). V praxi se často používají i jiné (přehlednější) způsoby reprezentace konečných automatů. Předvedeme si dva z nich na automatu z předchozího příkladu. Automat je možné reprezentovat pomocí tabulky přechodové funkce takto: a b q0 q1 q2 q1 q2 q0 q2 q0 q1 Stavy automatu jsou vypsány v záhlaví řádků, vstupní symboly v záhlaví sloupců, pře- chodová funkce je určena obsahem vnitřních polí tabulky (pokud je pro některé dvojice nedefinována, uvádí se v příslušném místě tabulky znak ,,­"), počáteční stav je označen znakem a koncové stavy znakem . Ještě přehlednější, a proto nejčastěji používaná, je reprezentace pomocí přechodo- vého grafu (též přechodového systému s návěštími ze ), který pro automat vypadá takto: GGWVUTPQRSq0 a GG GF ED b WVUTPQRSq1 a GG b oo WVUTPQRSONMLHIJKq2 b oo BC@A a yy Stavy odpovídají uzlům, přechodová funkce je znázorněna ohodnocenými hranami, vstupní abeceda je tvořena symboly, kterými jsou hrany ohodnoceny, počáteční stav je označen šipkou a koncové stavy jsou dvojitě zakroužkovány. Nakonec ještě zmiňme reprezentaci výpočetním (či též stavovým) stromem. Kořen stromu odpovídá počátečnímu stavu (a není tedy nutné jej nějak označovat jako počáteční). Z každého uzlu, který není listem vychází ­ dle definice přechodové funkce ­ právě tolik hran ohodnocených symboly vstupní abecedy, kolik má odpovídající stav následníků (je-li tedy totální, pak právě tolik hran, kolik symbolů má vstupní abeceda). Jestliže nějaký stav odpovídá více uzlům, pak hrany vycházejí jen z jednoho z těchto uzlů. Výpočetním stromem lze reprezentovat jen ty automaty, kde každý stav je tzv. dosažitelný z počátečního stavu (viz definice 2.18) ­ z hlediska schopnosti rozpoznávat daný jazyk, není přítomnost či nepřítomnost nedosažitelných stavů podstatná (viz lemma 2.19). Výpočetní strom pro daný automat není (obecně) určen jednoznačně ­ může se lišit dle toho, zda jej konstruujeme způsobem, který odpovídá například procházení do hloubky, nebo do šířky, či dalším možnostem. Pokud však ve výpočetním stromu ztotožníme uzly označené stejným stavem, obržíme přechodový graf (v němž však musíme vyznačit stav počáteční). Výpočetní strom pro automat může tedy mít například tyto tvary: ?>=<89:;q0 a b 11ddddd ?>=<89:;q0 a b 11ddddd ?>=<89:;q1 a b 11ddddd ?>=<89:;76540123q2 ?>=<89:;q1 a b ?>=<89:;76540123q2 a b 11ddddd ?>=<89:;76540123q2 a b 11ddddd ?>=<89:;q0 ?>=<89:;76540123q2 ?>=<89:;q0 ?>=<89:;q0 ?>=<89:;q1 ?>=<89:;q0 ?>=<89:;q1 Příklad 2.4. Pro ilustraci nyní uvedeme rovněž důkaz faktu, že konečný automat z příkladu 2.3 skutečně rozpoznává jazyk L() = {w {a, b} | (#a(w)-#b(w)) mod 3 = 2}. Důkaz: Dokážeme, že pro každé slovo v {a, b} platí, že ^(q0, v) = qi , kde i = (#a(v) - #b(v)) mod 3. Indukcí k délce slova v: |v| = 0: Pak v = a ^(q0, ) = q0 podle definice rozšířené přechodové funkce. Zřejmě (#a() - #b()) mod 3 = 0. Indukčníkrok: Necht'v = ux, kde u {a, b} a x {a, b}. Podle indukčního předpokladu platí ^(q0, u) = qi , kde i = (#a(u) - #b(u)) mod 3. Necht' např. x = a (případ kdy x = b se vyšetří stejným způsobem). Přechodová funkce byla definována tak, že pro každé k {0, 1, 2} platí (qk, a) = ql , kde l = (k + 1) mod 3. Proto také ^(q0, ua) = (^(q0, u), a) = (qi , a) = qj , kde j = (i + 1) mod 3 = (#a(u) - #b(u) + 1) mod 3 = (#a(ua) - #b(ua)) mod 3, což bylo dokázat. Jelikož koncovým stavem je pouze q2, platí L() = {w {a, b} | ^(q0, w) = q2} = {w {a, b} | (#a(w) - #b(w)) mod 3 = 2}. Podobným způsobem lze postupovat i v jiných případech. Jediný problém (a tedy jádro důkazu) je postihnout vztah mezi slovy ze a stavy daného automatu. Přechodová funkce byla v definici 2.1 zavedena jako parciální, což umožňuje snadnější návrh a stručnější prezentaci konečných automatů ­ můžeme se soustředit jen na ,,důležité" přechody z daného stavu. Příklad 2.5. Navrhneme konečný automat, rozpoznávající řetězcové konstanty podle (zjed- nodušené) konvence jazyka C ­ řetězec začíná uvozovkami, následuje posloupnost libovol- ných znaků s ASCII kódem 32­127 a na konci jsou zase uvozovky, před kterými ovšem nesmí být znak obráceného lomítka. Množinu znaků s ASCII kódem 32­127 označíme symbolem (hrana s tímto návěštím tedy reprezentuje, formálně vzato, množinu hran ­ pro každý z uvažovaných symbolů právě jedna hrana): GGWVUTPQRSq0 " GGWVUTPQRSq1 " GG \ @G cc FED -{",\} )) WVUTPQRSONMLHIJKq3 WVUTPQRSq2 yy Parcialita přechodové funkce nemá podstatný vliv na výpočetní sílu konečných automatů, jak dokládá následující pomocné tvrzení: Lemma 2.6. Ke každému FA existuje ekvivalentní FA s totální přechodovou funkcí. Důkaz: Necht' = (Q, , , q0, F). Automat sestrojíme tak, že ke stavům automatu přidáme nový nekoncový stav p a chybějící přechody do něj ,,nasměrujeme". Tedy = (Q {p}, , , q0, F), kde p Q a je definována takto: (q, a) = (q, a) je-li (q, a) definováno, p jinak. Zejména (p, a) = p pro každé a . Indukcí k délce slova se snadno ověří, že pro každé q Q a w platí ^ (q, w) = ^(q, w) je-li ^(q, w) definováno, p jinak. Jelikož p F, platí L() = L( ). Jazyk akceptovaný konečným automatem je možné definovat také pomocí pojmů konfi- gurace a krok výpočtu. Jak uvidíme, tento způsob je obecnější ­ lze ho aplikovat i na složitější modely, než jakými jsou konečné automaty. Proto tuto (alternativní) možnost rovněž uvedeme. Konfigurace konečného automatu = (Q, , , q0, F) je každá dvojice (q, w) Q × . Na množině všech konfigurací automatu zavedemebinární relaci krok výpočtu, označovanou , pomocí předpisu (q, aw) (p, w) def (q, a) = p Reflexivní a tranzitivní uzávěr relace kroku výpočtu značíme . Jazyk akceptovaný auto- matem pak můžeme definovat také takto: L() = {w | (q0, w) (q, ), kde q F} Konfigurace konečného automatu přesně popisuje momentální stav výpočtu, který na daném slově provádí. Obsahuje úplnou informaci, která je potřebná pro jeho další pokračování. ,,Programem" pro tento výpočet je samozřejmě přechodová funkce. Důkaz faktu, že obě uvedené definice jazyka L() jsou ekvivalentní, lze přenechat čtenáři jako jednoduché cvičení ­ stačí ukázat platnost ekvivalence ^(q, w) = p (q, w) (p, ) což se dá jednoduše provést indukcí vzhledem k délce slova w. 2.1.1 Konstrukce konečných automatů Konstrukce konečného automatu, který rozpoznává daný jazyk, je obecně netriviální úkol. V této části si ukážeme některé metody, s jejichž pomocí je možné vyřešit řadu konkrétních úloh. Základním trikem, který dokáže zjednodušit návrh konečného automatu, je zavedení jisté pomocné struktury na stavech. Uvědomme si, že stavy konečného automatu představují konečnou pamět', do níž je možné ukládat informace o dosud přečtené části vstupního slova. Informaci, která je spojená s daným stavem, je účelné zachytit v jeho označení. Příklad 2.7. Máme za úkol sestrojit automat rozpoznávající jazyk L = {w {a, b} | w obsahuje podslovo abaa} Označení stavů automatu zvolíme tak, aby bylo patrné, jaká část požadovaného podslova abaa již byla automatem přečtena: GGWVUTPQRSq a GG @G cc FEDb )) WVUTPQRSqa b GG @G cc FED a )) WVUTPQRSqab a GG BC@A b yy WVUTPQRSqaba a GG b oo WVUTPQRSONMLHIJKqabaa @G cc FED a,b )) Vhodná volba množniny stavů (,,struktury na stavech") dokáže konstrikci automatu zjed- nodušit a výsledný automat zpřehlednit. V některých případech je její zavedení dokonce nevyhnutelné, má-li být definice technicky zvládnutelná. Příklad 2.8. Sestrojme automat rozpoznávající jazyk L = {w {a, b} | #a(w) mod 1997 = 483 #b(w) mod 1998 = 645} Ve stavech automatu je třeba zachytit informaci o počtu dosud přečtených symbolů ,,a" modulo 1997 a o počtu dosud přečtených symbolů ,,b" modulo 1998. Celkem tedy bude zapotřebí 1997.1998 = 3990006 stavů. Reprezentovat takovýto automat pomocí přecho- dového grafu není příliš rozumné (i když stále možné). Místo toho zavedeme jednoduchou strukturu na stavech, která umožní zapsat celou definici na několik (krátkých) řádků. Necht' = (Q, {a, b}, , q0,0, {q483,645}), kde Q = {qi, j | 0 i 1996 0 j 1997} a přechodová funkce je definována takto: ˇ (qi, j , a) = qi+1, j pro každé 0 i 1995, 0 j 1997 ˇ (q1996, j , a) = q0, j pro každé 0 j 1997 ˇ (qi, j , b) = qi, j+1 pro každé 0 i 1996, 0 j 1996 ˇ (qi,1997, b) = qi,0 pro každé 0 i 1996 Další často používanou technikou je synchronní paralelní kompozice automatů. Pro dané automaty 1 a 2 umožňuje snadno sestrojit automat rozpoznávající průnik (případně také sjednocení nebo rozdíl) jazyků L(1) a L(2). Intuitivně si lze celou konstrukci představit tak, že automaty 1 a 2 necháme běžet paralelně na stejném vstupním slově. Jejich běh je synchronní, tj. 1 a 2 provádějí kroky výpočtu vždy ve stejném okamžiku. Má-li slovo w patřit do sjednocení L(1) a L(2), musí být alespoň jeden z automatů po zpracování slova w v koncovém stavu. Formálně je tato myšlenka zachycena v níže uvedené definici. Definice 2.9. Pro dané FA 1 = (Q1, , 1, q1, F1), 2 = (Q2, , 2, q2, F2), je- jichž přechodové funkce jsou totální, definujeme konečný automat 1 2 = (Q1 × Q2, , , (q1, q2), F), kde ˇ F = {(p, q) | p F1 q F2} = (F1 × Q2) (Q1 × F2) ˇ ((p, q), a) = (1(p, a), 2(q, a)). Předpoklad, že přechodové funkce 1, 2 jsou totální sice není omezující (viz lemma 2.6), avšak pro ,,správné" fungovaní synchronní paralelní kompozice 1 2 nezbytný; není pak totiž možné, aby se jedna z komponent na daném slově ,,zablokovala", zatímco druhá měla možnost ve výpočtu pokračovat. Věta 2.10. Necht'1 = (Q1, , 1, q1, F1) a 2 = (Q2, , 2, q2, F2) jsou konečné automaty s totálními přechodovými funkcemi. Pak L(1 2) = L(1) L(2). Důkaz: Nejprve dokážeme toto tvrzení: ^((q1, q2), w) = (p, q) ^1(q1, w) = p ^2(q2, w) = q (2.1) Důkaz se provede indukcí vzhledem k |w|. ˇ |w| = 0: Platí ^((q1, q2), ) = (q1, q2), ^1(q1, ) = q1, ^2(q2, ) = q2. Pro w = tedy obě strany ekvivalence, kterou je třeba dokázat, platí (přímo z definice rozšířené přechodové funkce). Samotná ekvivalence je proto rovněž platná. ˇ Indukční krok: Necht' w = va, kde v , a . Platí ^((q1, q2), va) = (p, q) ^((q1, q2), v) = (r, s) ((r, s), a) = (p, q) ^1(q1, v) = r ^2(q2, v) = s (indukční předpoklad) 1(r, a) = p 2(s, a) = q (dle definice ) ^1(q1, va) = p ^2(q2, va) = q Nyní již lze snadno dokázat vlastní tvrzení věty: w L(1 2) ^((q1, q2), w) = (p, q) kde p F1 nebo q F2 ^1(q1, w) = p ^2(q2, w) = q w L(1) L(2). Poznámka 2.11. Podobným způsobem lze pro automaty 1 = (Q1, , 1, q1, F1) a 2 = (Q2, , 2, q2, F2) s totálními přechodovými funkcemi sestrojit automat 1 2, resp. 1 2, rozpoznávající jazyk L(1) L(2), resp. L(1) - L(2). Jediný rozdíl je v definici množiny koncových stavů; ta je v případě 1 2 rovna F1 × F2 a v případě 1 2 je definována jako {(p, q) | p F1 q F2} = F1 - F2. Důkazy, že L(1 2) = L(1) L(2) a L(1 2) = L(1) - L(2) jsou snadné; použije se vztah (2.1). Pro úplnost ještě poznamenejme, že pro automat = (Q, , , q0, F) s totální přechodovou funkcí lze také lehce sestrojit automat rozpoznávající jazyk co­L() ­ stačí položit = (Q, , , q0, Q - F). Zřejmě w L() w L(), tedy L() = - L() (předpoklad, že je totální, je opět zcela nezbytný). Příklad 2.12. Necht'L {0, 1} je jazyk, obsahující všechna slova w, která vyhovují těmto podmínkám: 1. w je binární zápis čísla dělitelného třemi ( chápeme jako jiný zápis čísla 0) a 2. w obsahuje lichý počet výskytů znaku ,,0" Prvky L jsou například slova 000, 011, 1011010. Konečný automat rozpoznávající jazyk L sestrojíme jako paralelní kompozici dvou jednodušších automatů, které rozpoznávají slova vyhovující podmínce 1 resp. 2. Automat 1 rozpoznávající jazyk L1 = {w {0, 1} | w je binární zápis čísla dělitelného třemi} vypadá takto: GGWVUTPQRSONMLHIJKq0 1 GG @G cc FED0 )) WVUTPQRSq1 0 GG 1 oo WVUTPQRSq2 0 oo @G cc FED1 )) Indexy stavů odpovídají zbytkovým třídám modulo 3 (je třeba si uvědomit, že připsáním znaku ,,0" na konec binárního čísla se zdvojnásobíjeho hodnota; připsáním ,,1" dosáhneme zdvojnásobení a přičtení jedničky. V obou případech se snadno zjistí, jak se změní zbytek při dělení třemi.) Automat 2 rozpoznávající jazyk L2 = {w {0, 1} | #0(w) mod 2 = 1} je jednoduchý: GGWVUTPQRSqs 0 GG @G cc FED1 )) WVUTPQRSONMLHIJKql 0 oo @G cc FED1 )) Výsledný automat 1 2 vypadá následovně: GGWVUTPQRSq0,s 1 GG 0 WVUTPQRSq1,s 0 11cccccccccc 1 oo WVUTPQRSq2,s 0 @G cc FED1 )) WVUTPQRSONMLHIJKq0,l 1 GG 0 yy WVUTPQRSq1,l 0 cc 1 oo WVUTPQRSq2,l 0 cccccccccc @G ABC 1 33 Výčet metod a triků, které lze při návrhu konečných automatů použít, není zdaleka úplný. V části 2.2 se seznámíme s některými rozšířeními základního modelu konečných auto- matů, které sice nemají vliv na výpočetní sílu (ukážeme, že tyto ,,obecnější" stroje lze ve skutečnosti vždy simulovat konečným automatem), avšak jejich konstrukce je často velmi přímočará. Otevírá se tak další strategie pro návrh konečných automatů ­ nejprve navrhneme ,,rozšířený" stroj a ten pak transformujeme na ekvivalentní konečný automat. 2.1.2 Lemma o vkládání pro regulární jazyky O tom, že nějaký jazyk je regulární, se můžeme (více či méně) snadno přesvědčit konstrukcí příslušného automatu. V případě, že se nám takový automat zkonstruovat nepodaří, může to mimo jiné znamenat, že neexistuje. Jak to však dokážeme? Základními nástroji, které pro tento účel mohou posloužit, jsou tzv. lemma o vkládání (též známé jako ,,pumping lemma") pro regulární jazyky, které je nutnou (nikoli však postačující) podmínkou pro regularitu jazyka a tzv. Myhillova-Nerodova věta (viz odstavec 2.1.3, která představuje podmínku nutnou a postačující. Lemma 2.13 (o vkládání). Necht' L je regulární jazyk. Pak existuje n takové, že libovolné slovo w L, jehož délka je alespoň n, lze psát ve tvaru w = xyz, kde |xy| n, y = a xyi z L pro každé i 0. (Číslo n se neformálně nazývá pumpovací konstanta.) Důkaz: Jelikož L je regulární, existuje deterministický FA = (Q, , , q0, F) rozpo- znávající jazyk L. Položme n = card(Q). Ukažme, že pro libovolné slovo w L délky alespoň n (tj. w = a1 . . . am, m n) platí, že automat projde při akceptování slova w (alespoň) dvakrát stejným stavem: provede výpočet (q0, a1 . . . am) (q1, a2 . . . am) . . . (qm, ), kde qm F při němž projde m + 1, tj. více než n konfiguracemi. Podle Dirichletova principu se tedy alespoň dvě z konfigurací musí shodovat ve svých prvních komponentách ­ stavech (těch je jen n). Jinak řečeno, existují indexy i, j takové, že 0 i < j n a qi = qj = p. Schématicky: WVUTPQRSq0 x GG/o/o/o WVUTPQRSp y GG/o/o/o WVUTPQRSp z GG/o/o/o WVUTPQRSONMLHIJKqm Slovo w se tedy rozpadne na tři části ­ w = xyz, kde x = a1 . . . ai , y = ai+1 . . . aj , z = aj+1 . . . am a kde y = . Jinak řečeno ^(q0, x) = p, ^(p, y) = p a ^(p, z) = qm. Je zřejmé, že ke zopakování nějakého stavu dojde nejpozději po zpracování prvních n znaků 1 slova w, a tedy dostáváme |xy| n. Dále ^(p, yi ) = p pro libovolné i 0, proto také ^(q0, xyi z) = qm, tj. xyi z L() pro každé i 0. Je užitečné si uvědomit, že PL (díky alternování universálních a existenčních kvan- tifikátorů) lze zapsat takto : 1. bez uvážení tohoto faktu bychom obrželi o něco slabší variantu lemmatu: Necht' L je regulární jazyk. Pak existuje n takové, že libovolné slovo w L, jehož délka je alespoň n, lze psát ve tvaru w = xyz, kde 1 |y| n a xyiz L pro každé i 0 . (Necht') L je regulární n . w L. |w| n . x, y, z. w = xyz y = |xy| n . i 0. xyi z L Zdůrazněme, že lemma o vkládání (na rozdíl od Myhillovy-Nerodovy věty, kterou zformu- lujeme a dokážeme v následujícím odstavci ­ viz 2.1.3) poskytuje podmínku, která je pouze nutná, ale nikoliv postačující pro to, aby daný jazyk byl regulární. Lze tedy pomocí něho dokázat, že nějaký jazyk regulární není (tím, že prokážeme jeho nesplnění), ale v žádném případě ne to, že regulární je. Pumping lemma (PL) je tvrzení tvaru implikace L je regulární Q. Při dokazo- vání, že L neníregulárnípoužijeme kontrapositivníformu PL, tj. Q L není regulární, či ekvivaletně důkaz sporem: L je regulární Q Q. V každém případě jde však o dokázání Q. Obecně tedy můžeme postupovat takto: (pro dosažení sporu s PL předpo- kládejme, že L je regulární; pak musí splňovat podmínky pumping lemmatua ukážeme, že tomu tak není) tedy ukážeme platnost Q, tj. že ˇ pro libovolné n (pumpovací konstantu) ˇ vždy existuje takové slovo w L, které má délku alepoň n, a pro které platí, že ˇ při libovolném rozdělení slova w na takové tři části x, y, z, že |xy| n a y = ˇ vždy existuje alespoň jedno i 0 takové, že xyi z L. Pak z PL plyne, že L není regulární. Znovu si tedy uvědomme, že při použití PL k důkazu, že jazyk není regulární, volíme slovo w a počet pumpování i (viz výše podtržené existenční kvantifikátory). Nevolíme ani pumpovací konstantu n, ani rozdělení na podslova x, y, z. Příklad 2.14. Ukážeme, že L = {a p | p je prvočíslo} nad abecedou {a} není regulární. Důkaz: Pro dosažení sporu předpokládejme, že L je regulární. Bud' n N libovolné (pumpovací konstanta z PL). Jelikož prvočísel je nekonečně mnoho, existuje prvočíslo p, které je větší nebo rovno n; zvolme w = a p patřící do L. Při jakémkoli rozdělení w na podslova x, y, z musí být y = ak, k 1. Napumpujeme-li y p + 1-krát, dostaneme: xyp+1z = xyypz = xyzyp = apakp = ap(k+1), což je jistě slovo, které nepatří do jazyka L, protože p(k + 1) není prvočíslo ­ dostáváme tedy spor s naším předpokladem, že L je regulární. Podle PL tedy L regulární není. Příklad 2.15. Jazyk L = {ai bi | i } nad abecedou {a, b} není regulární. Důkaz: Nyní již poněkud stručněji: bud'n libovolné. Slovo anbn jistě patří do L; pokud ho jakkoli rozdělíme na tři části x, y, z tak, že |xy| n a |y| 1, nutně x = ak, y = al a z = an-k-lbn, kde k +l n. Pak např. pro i = 2 dostáváme aka2.lan-k-lbn L, nebot'k + 2l + n - k - l = n + l = n. Obdobně bychom ke sporu dospěli volbou i = 0 (volba i = 1 by byla jen naše ,,nedostatečnost"). Formule s alternujícími kvantifikátory a hra 2 hráčů. Pro porozumění formuli s větším počtem kvantifikátorů je možné na ni nahlížet jako na hru dvou hráčů , kde universálnímu kvantifikátoru odpovídá hráč Al a existečníkvantifikátor je reprezentován hráčem Ex. Al a Ex hrají proti sobě (jsou na tahu) v tom pořadí, které odpovídá výskytu kvantifikátorů ve formuli (čteno zleva doprava). Je-li na tahu Al, se snaží snažíse formuli tvaru u.p(u) vyvrátit: je-li u.p(u) pravda, pak Al nemůže vyhrát; je-li u.p(u) nepravda, pak existuje aspoň jedna hodnota u, která vyvrací (u) a Al může vyhrát tak, že pro u zvolí právě tuto hodnotu. Je-li na tahu Ex, snaží se formuli tvaru u.p(u) učinit pravdivou: je-li u.p(u) pravda, Ex může vyhrát volbou hodnoty pro u takovou, že p(u) je pravda. Je-li u.p(u) nepravda, nemůže se mu toto podařit a hru prohrává. Vrat'me se nyní zpět k pumping lemmatu; to tvrdí, že pokud L je regulární jazyk, pak 1. n 2. w L takové, že |w| n 3. x, y, z taková, že w = xyz y = |xy| n 4. i 0 xyi z L Toto tvrzení obsahuje 4 kvantifikátory a podmínky za nimi uvedené budou ve hře 2 hráčů přestavovat omezení na možnosti volby, které každý z hráčů bude během hry činit. Zvolme nějaký regulární jazyk L; hra pro L probíhá takto: 1. Ex zvolí přirozené číslo n, 2. Al zvolí w, a to tak, že w L a |w| n, 3. Ex zvolí x, y, z taková, že w = xyz a y = a |xy| n 4. Al zvolíi 0, přičemž se snaží volbu provést tak, aby vyhrál, tj. snaží se o xyi z / L. Demonstrovat vyhrávající strategii pro hráče Ex značí (de facto) znovu provést důkaz pumping lemmatu, tentokrát ovšem v pojmech hry: necht'tedy L je nějaký regulární (tj. nějakým konečným automatem akceptovaný) jazyk. 1. Ex zvolí n = card(Q), kde Q je množina stavů automatu . 2. Al zvolí slovo w takové, že w L a |w| n. (Pokud takové slovo neexistuje, pak Al prohrává: v tomto případě druhý kvantifikátor říká, že všechny prvky prázdné množiny mají jistou vlastnost, což je (bez ohledu na to o jakou vlastnost se jedná) triviálně pravda ­ Al nemůže formuli vyvrátit). 3. Nyní Ex najde v akceptující výpočet pro w (ten jistě existuje, protože w L) a zaznamená si posloupnost p stavů řídicí jednotky, kterými se při akceptování w projde. Jelikož |w| n, je těchto ,,průběžných" stavů alespoň n + 1, ale Q má jen n stavů, a tedy v p (akceptující posloupnosti stavů) se musí alespoň jeden ze stavů vyskytovat alespoň dvakrát (podle Dirichletova principu). Necht'q je první výskyt nějakého opakujícího se stavu v p. Ex rozdělí výpočet na 3 části (bude korespondovat postupnému přečtení řetězců x, y a z), a to podle prvních dvou výskytů konfigurací majících v 1. komponentě stav q. Výpočet pro vstupní slovo w = xyz lze zapsat jako (q0, xyz) (q, yz) + (q, z) (q f , ), kde x je přečteno dříve, než se poprvé vejde do stavu q, po následném přečtení y se (poprvé) vrátíme do q (tj. druhý výskyt q) a z je zbytkem vstupního slova. Jistě tedy platí, že x, y, z jsou taková, že w = xyz a y = a |xy| n. Ex tedy splnil podmínky volby. 4. At'Al nyní zvolí jakékoli i 0, bude výpočet v pro slovo xyi z vždy tvaru (q0, xyi z) (q, yi z) + . . . + i krát přečte y (q, z) (q f , ), což je ale akceptující výpočet v ,tj. xyi z L, a tedy Al prohrává, Ex vítězí. Zopakujme tedy, že použití pumping lemmatu k důkazu (sporem) neregularity něja- kého jazyka L tedy v termínech hry probíhá takto: 1. Ex zvolí přirozené číslo n, 2. Al zvolí w, a to tak, že w L a |w| n, 3. Ex zvolí x, y, z taková, že w = xyz a y = a |xy| n 4. Al zvolí i 0, přičemž se snaží volbu provést tak, aby vyhrál, tj. snaží se o xyi z / L. Příklad 2.16. Necht'L obsahuje právě všechna ta slova nad abecedou {a}, jejichž délky jsou druhými mocninami přirozených čísel, tj. L = {an2 | n }. Ukažme, že L není regulární, a to tak, že presentujeme vyhrávající strategii Al-a: 1. Ex zvolí přirozené číslo n. 2. Al zvolí z L a |z| n2 (to vždy lze, protože L je nekonečný). 3. Ex zvolí u, v a w taková, že z = uvw a v = a |uv| n. 4. Al zvolí i = 2, Protože z L, platí |z| = m2 pro nějaké přirozené m. Al volil z tak, že platí m > n. Máme tedy 0 < |v| n a označme k = |v|. Pak m2 < m2 + k = |uv2 w| m2 + n < m2 + m < (m + 1)2 . Délka slova uv2w tedy padne mezi druhé mocniny dvou po sobě jdoucích přirozených čísel (m a m + 1), takže uv2w / L, a tedy Al vyhrává. Jelikož Al má vyhrávající strategii, bez ohledu na to, jak Ex hraje, L nemůže být regulární. Fakt, že lemma o vkládání neudává postačující podmínku pro regularitu jazyka, lze názorně demonstrovat tímto příkladem: Příklad 2.17. Jazyk L = {a, b} {cj ai bi | i, j } nad abecedou {a, b, c} splňuje podmínky lemmatu o vkládání, přitom však není regulární (jak lze snadno dokázat užitím Myhillovy-Nerodovy věty). 2.1.3 Myhillova-Nerodova věta V tomto odstavci zformulujeme a dokážeme velice důležité tvrzení,tzv. Myhillovu-Nerodovu větu, která představuje algebraickou charakterizaci třídy regulárních jazyků a má četné dů- ležité důsledky. Abychom ji mohli zformulovat, potřebujeme několik pomocných pojmů. Definice 2.18. Necht' = (Q, , , q0, F) je konečný automat. Stav q Q nazveme dosažitelný, pokud existuje w takové, že ^(q0, w) = q. Stav je nedosažitelný, pokud není dosažitelný. Je zřejmé, že vypustíme-li z daného automatu nedosažitelné stavy, jazyk L() se nezmění. Tuto transformaci lze navíc provést algoritmicky, jak dokládá toto lemma: Lemma 2.19. Existuje algoritmus, který pro každý konečný automat = (Q, , , q0, F) sestrojí ekvivalentní konečný automat bez nedosažitelných stavů. Důkaz: Nejprve dokážeme, že množinu Q = {q Q | q je dosažitelný} lze algoritmicky zkonstruovat. Uvědomme si, že do každého dosažitelného stavu vede v přechodovém grafu automatu konečná cesta z počátečního stavu q0. Označíme-li pro každé i 0 symbolem Si množinu stavů, do kterých se lze z q0 dostat cestou o délce nejvýše i (tj. použitím nejvýše i přechodů), platí: Q = i=0 Si (2.2) Do stavu q0 se vždy lze dostat cestou délky 0 ­ pro každý konečný automat tedy platí S0 = {q0}. Hodnoty Si pro i 1 již závisí na tom, jak je definován. Můžeme je však snadno vypočítat podle následujícího induktivního předpisu: ˇ S0 = {q0} ˇ Si+1 = Si {q | p Si , a (p, a) = q} Indukcí vzhledem k i se snadno ověří, že každé Si obsahuje pouze dosažitelné stavy. Dále pro každé i 0 platí, že Si Q a Si Si+1. Označme n = card(Q). Vzhledem k tomu, že množina Q je konečná, nemohou se množiny Si pro rostoucí i neustále zvětšovat ­ existuje tedy k n takové, že Sk = Sk+1. Z definice množin Si nyní vyplývá, že dokonce pro každé j 0 platí Sk = Sk+ j. Proto můžeme množinu Q všech dosažitelných stavů, tj. vztah 2.2 vyjádřit také jako Q = k i=0 Si = Sk (2.3) Tato rovnost podává přesný návod na to, jak množinu Q vypočítat. Formálně je tím dokázána správnost i konečnost algoritmu 2.1. Hledaný automat je pak (Q , , /Q , q0, F Q ), kde symbol /Q značí zobrazení zúžené na Q . Přitom platí, že pokud je totální, je i /Q totální. Fakt, že L() = L( ), je zřejmý. Způsob, jakým jsme v algoritmu 2.1 zkonstruovali množinu všech dosažitelných stavů konečného automatu ,je velmi speciální aplikací Knasterovy-Tarského věty o pevném bodě a Kleeneovy věty o rekurzi. Tento princip použijeme ještě mnohokrát. Definice 2.20. Necht' je abeceda a necht' je ekvivalence na . Ř ekneme, že je zprava invariantní (pravá kongruence), pokud pro každé u, v, w platí u v uw vw. Index ekvivalence je počet tříd rozkladu / (pokud je těchto tříd nekonečně mnoho, klademe index roven ). Poznámka 2.21. Snadno se nahlédne, že ekvivalence na je pravá kongruence právě když pro každé u, v , a platí u v ua va. (Z jedné strany triviální, obrácená implikace se snadno ukáže indukcí k délce zprava přiřetězeného slova w.) Algoritmus 2.1 Eliminace nedosažitelných stavů konečného automatu. Vstup: Konečný automat = (Q, , , q0, F). Výstup: Ekvivalentní konečný automat bez nedosažitelných stavů. i = 0; Si = ; repeat Si+1 = Si {q0} {q | p Si , a (p, a) = q}; i = i + 1; until Si = Si-1 Q = Si ; = (Q , , /Q , q0, F Q ); Konečné automaty a pravé kongruence s konečným indexem spolu velmi úzce souvisejí, jak ukazuje následující věta (a zejména její důkaz). Věta 2.22. (Nerodova). Necht'L je jazyk nad . Pak tato dvě tvrzení jsou ekvivalentní: 1. L je rozpoznatelný konečným automatem. 2. L je sjednocením některých tříd rozkladu určeného pravou kongruencí na s ko- nečným indexem. Důkaz: (1 2) Necht' = (Q, , , q0, F) je FA, který rozpoznává L. Bez újmy na obecnosti předpokládejme, že je bez nedosažitelných stavů (viz lemma 2.19) a je totální (viz lemma 2.6); pak také ^ je totální. Na definujme binární relaci takto: u v def ^(q0, u) = ^(q0, v) Relace je ekvivalence, která sdružuje taková slova, pro která automat přejde do stejného stavu. Třídy rozkladu určeného relací tedy odpovídajístavům automatu ,proto relace má konečný index. Ukážeme, že je pravá kongruence. Necht'u v a a . Pak ^(q0, ua) = (^(q0, u), a) = (^(q0, v), a) = ^(q0, va), tedy ua va, což bylo dokázat. Jazyk L() je sjednocením těch tříd rozkladu určeného relací , které odpovídají koncovým stavům automatu ­ označíme-li symbolem q třídu, která odpovídá stavu q, platí u L (q0, u) = q, kde q F u q , kde q F. (2 1) Necht'L je sjednocením některých tříd rozkladu určeného pravou kongruencí na s konečným indexem. Prvek faktorové množiny / (tj. třídu rozkladu) obsahující prvek u budeme značit u. Dále definujme konečný automat = (Q, , , q0, F), kde ˇ Q = /, tj. stavy jsou třídy rozkladu na určeného ekvivalencí . Jelikož má konečný index, je těchto tříd konečně mnoho. ˇ je definována pomocí reprezentantů: (u, a) = ua. Tato definice je korektní, tj. nezávisí na volbě konkrétního reprezentanta2, nebot' je zprava invariantní. ˇ q0 = . 2. Nezávislost na volbě reprezentantů v tomto případě znamená, že pro každé u, v , a platí u v ua va ˇ F obsahuje právě ty prvky /, jejichž sjednocením obdržíme jazyk L. Indukcí k délce slova v se snadno ukáže, že ^(, v) = v pro každé v . Zřejmě L = L(), nebot'v L v F ^(, v) F. Poznámka 2.23. Každý konečný automat tedy jednoznačně určuje jistou pravou kongru- enci s konečným indexem a obráceně. Omezíme-li se pouze na automaty, které jsou bez nedosažitelných stavů a s totální přechodovou funkcí, jsou obě uvedená přiřazení navzájem inverzní až na označení stavů automatu. Předchozí věta rovněž udává podmínku, která je nutná a postačující k tomu, aby daný jazyk byl regulární. Lze tedy pomocí ní dokázat i to, že nějaký jazyk regulární není. Příklad 2.24. Dokážeme, že jazyk L = {ai bi | i } nad abecedou {a, b} není rozpozna- telný žádným konečným automatem. (O tomto jazyku jsme již dokázali, že regulární není ­ viz příklad 2.15; tímto důkazem ,,jen" ilustrujeme techniku obsaženou ve větě 2.22 Důkaz: Předpokládejme, že L je regulární. Pak podle věty 2.22 existuje pravá kongruence na {a, b} s konečným indexem taková, že L je sjednocením některých tříd rozkladu {a, b}/. Ukážeme, že to není možné; za tímto účelem stačí nalézt dvě slova u, v, která prokazatelně leží ve stejné třídě rozkladu {a, b}/ a přitom u L a v L. Bud'k index ekvivalence . Uvažme slova ab, aab, aaab, . . . , ak+1b. Jelikož roz- klad {a, b}/ má právě k tříd, musí ve výše uvedeném seznamu existovat dvě různá slova, která patří do stejné třídy ­ tedy ai b a j b pro nějaké 1 i < j k + 1. Protože je zprava invariantní, platí rovněž ai bbi-1 a j bbi-1. Tedy slova u = ai bi a v = a j bi patří do stejné třídy rozkladu {a, b}/, přitom u náleží do jazyka L, zatímco v nikoliv. Poslední pojem, který budeme k formulaci Myhillovy-Nerodovy věty potřebovat, je obsa- žen v následující definici: Definice 2.25. Necht'L je libovolný (ne nutně regulární)jazyk nad abecedou . Na množině definujeme relaci L zvanou prefixová ekvivalence pro L takto: u L v def w uw L vw L Tedy L obsahuje právě ty dvojice (u, v), které majítu vlastnost, že po připojenílibovolného w vzniklá slova uw, vw budou do jazyka L patřit bud'obě, nebo ani jedno z nich. Lemma 2.26. Necht'L je libovolný jazyk nad . Pak relace L je pravá kongruence a L lze vyjádřit jako sjednocení některých (ne nutně konečně mnoha) tříd rozkladu /L . Důkaz: Zřejmě L je ekvivalence. Dokážeme, že L je pravá kongruence. Necht'u L v a a . Platí ua L va, nebot'pro libovolné slovo w je uaw L vaw L (vyplývá to z toho, že aw je rovněž slovo nad a u L v ­ viz definice 2.25). Zbývá dokázat, že L je sjednocením některých tříd rozkladu /L . K tomu stačí ukázat, že pro libovolná u, v platí u L v (u L v L), tedy že slova v každé třídě patří do L bud'všechna, nebo tam nepatří žádné z nich. Necht'tedy u L v. Podle definice 2.25 pak pro každé w platí uw L vw L. Zvolíme-li za w prázdné slovo , obržíme u = u L v = v L, což bylo dokázat. Každý jazyk nad abecedou lze podle předchozího lemmatu vyjádřit jako sjednocení některých tříd rozkladu určeného jistou pravou kongruencí na (těchto tříd však obecně nemusí být konečně mnoho). Pozorný čtenář patrně namítne, že za účelem konstatování tohoto faktu nebylo nutné zavádět relaci L, protože např. také identická relace id je pravá kongruence a každý jazyk lze vyjádřit jako sjednocení jistých tříd rozkladu /id. Relace L však přece jen je něčím zvláštní: Lemma 2.27. Necht'L je jazyk nad abecedou . Pro libovolnou pravou kongruenci na takovou, že L je sjednocením některých tříd rozkladu / platí, že L (tj. L je největší pravá kongruence s touto vlastností). Důkaz: Necht'u v. Ukážeme, že pak také u L v, tj. pro libovolné slovo w platí uw L vw L. K tomu si stačí uvědomit, že uw vw (viz definice 2.20); jelikož L je sjednocením některých tříd /, platí uw L vw L. Věta 2.28 (Myhillova-Nerodova). Necht'L je jazyk nad , pak tato tvrzení jsou ekviva- lentní: 1. L je rozpoznatelný konečným automatem. 2. L je sjednocením některých tříd rozkladu určeného pravou kongruencí na s ko- nečným indexem. 3. Relace L má konečný index. Důkaz: (1 2) Viz věta 2.22 (ve směru 2.22­1 2.22­2). (2 3) Necht' je libovolná pravá kongruence na s konečným indexem taková, že L je sjednocením některých tříd rozkladu /. Protože je zjemněním L (viz lemma 2.27), má rozklad /L nejvýše tolik tříd jako /. (3 1) Dle lemmatu 2.26 je L sjednocením některých tříd rozkladu /L a L je pravá kongruence. Jelikož L má konečný index, lze opět použít větu 2.22 (tentokrát ve směru 2.22­2 2.22­1), resp. druhou část důkazu 2.22. 2.1.4 Minimální konečný automat Konečné automaty nacházejí velmi široké uplatnění v technické praxi (viz část 2.4). Z hle- diska efektivity a nákladnosti implementace je důležité, aby počet stavů byl pokud možno co nejmenší. Přirozeným problémem je proto konstrukce minimálního automatu (tj. auto- matu s nejmenším počtem stavů), který rozpoznává daný regulární jazyk L. V této části ukážeme, že minimální automat lze sestrojit poměrně jednoduchým způsobem -- stačí mít k dispozici nějaký konečný automat, který rozpoznává L. Minimální automat pak obdržíme ztotožněním některých jeho stavů. Pozorný čtenář jistě postřehl, že tvrzení o existenci minimálního automatu a do jisté míry i návod k jeho konstrukci, jsou skryty v Myhillově-Nerodově větě (specielně viz důkaz implikace (3 1) v 2.28, tj. konstrukce z druhé části důkazu věty 2.22 aplikované na L). Myhillovu-Neorovu větu můžeme totiž reformulovat takto: Věta 2.29 (Myhillova-Nerodova, 2. varianta). Počet stavů libovolného minimálního au- tomatu rozpoznávajícího jazyk L je roven indexu prefixové ekvivalence L. (Takový konečný automat existuje právě když index L je konečný.) Důkaz: Víme, že každý konečný automat (a bez újmy na obecnosti bez nedosažitelných stavů) určuje jistou pravou kongruenci s konečným indexem a obráceně (viz věta 2.22). Je-li jazyk L regulární, pak relace L je největší pravá kongruence s konečným indexem taková, že L je sjednocením některých tříd příslušného rozkladu (viz lemma 2.27). Konečný automat, který odpovídá relaci L, je tedy minimální automat rozpoznávající jazyk L a získáme jej tak, že aplikujeme postup uvedený v druhé části důkazu věty 2.22, tentokrát však nikoli pro , ale pro L. Jen pro zopakování připomeňme princip konstrukce: má-li L konečný index k, konstruujeme FA s k stavy. si ve své konečné množině stavů uchovává informaci o tom, do které třídy ekvivalence dosud přečtená část vstupu patří. Při značení jako v důkazu 2.22 má tedy množinu stavů {u | u } o právě k prvcích (kde u = {u | u L u}). Stav u je koncový, je-li u L, jinak není koncový. Přechodová fuknce je definována jako (u, a) = ua. Důkaz korektnosti této konstrukce ­ viz 2.22. Příklad 2.30. Myhillovu-Nerodovu větu lze, tak jako větu 2.22, použít k důkazu, že jazyk je či není akceptovatelný nějakým FA. Pro srovnání dokažme o témže jazyku jako v příkladu 2.15 a v příkladu 2.24, tj. L = {ai bi | i 0}, že není regulární, a to pomocí 2.29 (tj. opět ,,jen" ilustrujeme důkazovou techniku implikovanou tvrzením této věty; čtenáři doporučujeme tyto techniky vzájemně porovnat). Žádné řetězy , a, a2, . . . nejsou ekvivaletní vzhledem k L, protože ai bi L, ale a j bi / L pro i = j. Tedy L má nekonečně mnoho různých tříd (nekonečný index); jinak řečeno L nemůže být rozpoznáván žádným konečným automatem, což jsme měli dokázat. Tvrzení o existenci minimálního konečného automatu můžeme tedy explicitněji zformulovat (jako bezprostřední důsledek Myhillovy-Nerodovy věty) takto: Důsledek 2.31. Minimální konečný automat akceptující jazyk L je určen jednoznačně až na isomorfismus (tj. přejmenování stavů). 2.1.5 Minimalizace konečných automatů Věnujme se nyní problému, jak k danému automatu algoritmicky nalézt ekvivaletní mini- málníautomat. Zopakujme, že máme-li k dispozici nějaký konečný automat rozpoznáva- jící L, je příslušná pravá kongruence zjemněním relace L. Rozklad /L tedy vznikne z / sjednocením některých tříd. Jelikož třídy /L odpovídají stavům minimálního automatu a třídy / odpovídají stavům , můžeme také říci, že stavy minimálního automatu vzniknou ztotožněním některých stavů automatu .Zbývá zjistit, jak uvedené ztotožnění provést, a to samozřejmě beze změny akceptovaného jazyka. Jistě nelze ztotožnit nějaký koncový stav p s nekoncovým stavem q. Pokud totiž p = ^(q0, x) a q = ^(q0, y), pak x musí být akceptován a y zamítnut, a to i po ztotožnění p a q. Není však způsob, jak zajistit, že ,,ztotožněný" stav má někdy akceptovat a někdy zamítat. Dále, pokud bychom ztotožnili nějaké p a q, pak bychom měli ztotožnit i jejich následníky (p, a) a (q, a), abychom dodrželi funkcionalitu (tzv. determinismus) : pro daný stav a symbol je jednoznačně určen následník. Z těchto dvou úvah plyne, že nemůžeme ztotožnit p a q, pokud ^(p, x) F a současně ^(q, x) / F pro nějaké x. Ukazuje se, že tato podmínka je nutná i postačující pro rozhodování, kdy dva stavy ztotožnit, tj. pokud pro nějaké x ^(p, x) F a současně ^(q, x) / F, pak stavy nemůžeme ztotožnit; pokud žádné takové x neexistuje, pak je ztotožnit můžeme. Tyto úvahy lze formalizovat takto: Definice 2.32. Necht' = (Q, , , q0, F) je FA bez nedosažitelných stavů, jehož pře- chodová funkce je totální. Pro každý stav q definujeme jazyk L(q) předpisem L(q) = {x | ^(q, x) F} . Stavy p, q nazveme jazykově ekvivalentní, psáno p q, pokud L(p) = L(q), tj. p q x (^(p, x) F ^(q, x) F) L(q) je tedy jazyk přijímaný automatem q, který vznikne z tak, že za počáteční stav prohlásíme q. Zřejmě je ekvivalence na Q. Intuitivně je jasné, že ztotožněním jazykově ekvivalentních stavů se přijímaný jazyk nezmění. K přesné formulaci tohoto faktu nejprve potřebujeme vědět, co se přesně myslí ,,ztotožněním stavů". (Čtenář, kterému je alespoň intuitivně jasné, jak by zkonstruoval ekvivalentní automat s množinou stavů Q/, pokud by byla dána , a že takto získaný automat / je minimální, může při prvním čtení přeskočit text až za důkaz věty 2.37, kde se věnujeme problému, jak spočítat .) Lemma 2.33. Necht' = (Q, , , q0, F) je FA bez nedosažitelných stavů s totální přechodovou funkcí. Jestliže p q, pak pro každé a platí (p, a) (q, a). Důkaz: Označme r = (p, a), s = (q, a). Potřebujeme dokázat, že L(r) = L(s), tj. že pro libovolné slovo w platí ^(r, w) F ^(s, w) F. K tomu si stačí uvědomit, že ^(r, w) = ^((p, a), w) = ^(p, aw) a podobně ^(s, w) = ^((q, a), w) = ^(q, aw). Zřejmě ^(p, aw) ^(q, aw), nebot' p q. Definice 2.34. Necht' = (Q, , , q0, F) je FA bez nedosažitelných stavů s totální přechodovou funkcí. Reduktem (též podílovým či faktor automatem) automatu nazveme konečný automat / = (Q/, , , q0, F/), tj. automat, kde ˇ Stavy jsou třídy rozkladu Q/ (třídu obsahující stav q značíme q). ˇ Přechodová funkce je definována pomocí reprezentantů. Je to nejmenší funkce splňující: p, q Q, a (q, a) = p (q, a) = p . Aby tato definice byla korektní, nesmí záviset na volbě reprezentantů ­ pro každé dva stavy q, q a každé a musí platit, že pokud q q , pak také (q, a) (q , a). To je však splněno podle lemmatu 2.33. ˇ Počáteční stav je třída rozkladu Q/, obsahující stav q0. ˇ Koncové stavy jsou právě ty třídy rozkladu Q/, obsahující alespoň jeden koncový stav (jednoduchým důsledkem definice 2.32 je, že v každé třídě jsou koncové bud' všechny stavy, nebo ani jeden z nich ­ tento fakt ospravedlňuje použité značení F/). Vztah mezi přechodovou funkcí automatu a přechodovou funkcí automatu / si zasluhuje bližší pozornosti: Lemma 2.35. Necht' = (Q, , , q0, F) je konečný automat bez nedosažitelných stavů s totální přechodovou funkcí a / = (Q/, , , q0, F/) jeho redukt. Pro každé u, v, w platí: 1. ^(q0, w) = q ^(q0, w) = p, kde p q a 2. ^(q0, u) ^(q0, v) ^(q0, u) = ^(q0, v) Důkaz: (1): Indukcí k délce slova w: ˇ |w| = 0: Zřejmě ^(q0, ) = q0 a platí ^(q0, ) = q q q0. Dokazovaná ekvivalence je tedy pravdivá. ˇ Indukční krok: Necht' w = va, kde v , a . Platí ^(q0, va) = q ^(q0, v) = r a (r, a) = q ^(q0, v) = s kde s r (indukční předpoklad) a (s, a) = p, kde p q (uvědomme si, že nezávisí na volbě reprezentantů; jelikož s r a (r, a) q, musí také platit (s, a) q) ^(q0, va) = p, kde p q. (2): Plyne přímo z tvrzení 1 tohoto lemmatu a definice množiny stavů automatu /. Následující věta formálně vyjadřuje, že ztotožnění jazykově ekvivalentních stavů nezmění přijímaný jazyk: Věta 2.36. Necht' = (Q, , , q0, F) je konečný automat bez nedosažitelných stavů s totální přechodovou funkcí. Pak L() = L(/). Důkaz: Podle první části lemmatu 2.35 platí ^(q0, w) F ^(q0, w) F/, proto L() = L(/). Nyní již lze dokázat hlavní výsledek této části: Věta 2.37. Necht' = (Q, , , q0, F) je konečný automat bez nedosažitelných stavů s totální přechodovou funkcí, rozpoznávající jazyk L. Pak / je minimální automat rozpoznávající jazyk L. Důkaz: Dokážeme, že pravá kongruence určená automatem / ve smyslu věty 2.22 je přesně relace L. Pro libovolná u, v platí: u v ^(q0, u) = ^(q0, v) dle algoritmu z Nerodovy věty ^(q0, u) ^(q0, v) dle lemmatu 2.35 (w ^(^(q0, u), w) F ^(^(q0, v), w) F) dle definice (w ^(q0, uw) F ^(q0, vw) F) (w uw L vw L) u L v dle definice L , a tedy = L , což bylo dokázat. Předchozí věta sice říká, jak pro daný konečný automat vypadá ekvivalentní minimální automat, ale nepodává algoritmus pro jeho konstrukci ­ není totiž na první pohled jasné, jakým způsobem lze zkonstruovat relaci . Tímto problémem se budeme nyní zabývat. Definice 2.32 říká, že p q pokud pro každé slovo w platí, že ^(p, w) F ^(q, w) F. Relaci lze tedy velmi přirozeně aproximovat tak, že položíme omezení na délku slova w: Definice 2.38. Necht' = (Q, , , q0, F) je konečný automat bez nedosažitelných stavů, jehož přechodová funkce je totální. Pro každé i 0 definujeme binární relaci i na Q předpisem (srv. s definicí relace v 2.32) p i q def w .|w| i (^(p, w) F ^(q, w) F) Pokud p i q, znamená to, že stavy p a q nelze ,,rozlišit" ve smyslu definice 2.32 žádným slovem délky nejvýše i. Tedy p q právě když p i q pro každé i 0. Množinovou symbolikou to lze vyjádřit takto: = i=0 i (2.4) Zřejmě každá z relací i je ekvivalence na Q a navíc i+1 je zjemněním i pro každé i 0. Následující lemma obsahuje návod, jak relace i počítat. Jedná se de facto o re- kursivní definici, resp. induktivní definici vzhledem k délce rozlišujících slov. Musíme též ukázat její korektnost vůči 2.38. Lemma 2.39. Pro relace i platí: 1. 0 = {(p, q) | p F q F} 2. i+1 = {(p, q) | p i q a (p, a) i (q, a)} Důkaz: Tvrzení dokážeme indukcí vzhledem k i. Báze (případ i = 0) zřejmě platí, nebot' slovem lze ve smyslu definice 2.38 rozlišit pouze koncové a nekoncové stavy. Předpokládejme nyní, že 2 platí pro nějaké i a ukažme platnost 2 pro i + 1. Zřejmě p i+1 q (tj. nejsou rozlišitelné žádným slovem délky nejvýše i + 1) (i) p i q (tj. nejsou rozlišitelné žádným slovem délky nejvýše i) a (ii) w.|w| = i + 1 platí ^(p, w) F ^(q, w) F (tj. a nejsou rozlišitelné ani žádným slovem délky i + 1). Podmínku (ii) lze formálně zapsat jako: w i+1.(^(p, w) F ^(q, w) F) , která platí a .v i .(^(p, av) F ^(q, av) F) a .v i .(^((p, a), v) F ^((q, a), v) F) a .((p, a) i (q, a)). Tedy p i+1 q p i q a .((p, a) i (q, a)), což bylo dokázat. Označme n počet stavů automatu .Připomeňme že, každá i je relací evivalence a navíc i+1 je zjemněním i pro každé i 0, tj. i+1 má alespoň tolik tříd rozkladu jako i . Jelikož libovolná ekvivalence na n-prvkové množině může mít nejvýše n tříd a 0 má aspoň jednu třídu, pak nutně (podle Dirichletova principu) platí, že musí existovat nějaké k n - 1 takové, že k a k+1 mají stejný počet tříd, což (opět díky faktu o zjemnění) dává k = k+1. To ovšem znamená, že dokonce k = k+ j pro libovolné j 0, nebot' relace i+1 závisí pouze na relaci i . Vztah (2.4) je tedy možné přepsat jako = k i=0 i = k (2.5) Tím je formálně dokázána správnost i konečnost algoritmu 2.2 pro minimalizaci konečného automatu. Po inicializaci (i = 0) iterativně počítáme i , i = 1, 2, . . . a skončíme pro i = k takové, že platí k = k-1. Algoritmus 2.2 Minimalizace konečného automatu. Vstup: Konečný automat = (Q, , , q0, F) bez nedosažitelných stavů s totální přechodovou funkcí. Výstup: Redukt /. i = 0; 0 = {(p, q) | p F q F}; repeat i+1 = {(p, q) | p i q a (p, a) i (q, a)}; i = i + 1; until i = i-1 = i ; / = (Q/, , , q0, F/); Příklad 2.40. Mějme konečný automat daný níže uvedenou tabulkou. Při konstrukci minimálního automatu je nejprve třeba odstranit nedosažitelné stavy a zúplnit přechodovou funkci. Obdržíme tak automat (stav 7 byl nedosažitelný, za účelem zúplnění přechodové funkce byl dále přidán nový stav N): a b 1 2 - 2 3 4 3 6 5 4 3 2 5 6 3 6 2 - 7 6 1 a b 1 2 N 2 3 4 3 6 5 4 3 2 5 6 3 6 2 N N N N Nyní již lze přistoupit ke konstrukci relací i . Technicky to lze provést například tak, že v tabulce přechodové funkce sdružíme řádky odpovídající stavům, které jsou v relaci i a jednotlivé skupiny (třídy rozkladu Q/i ) označíme římskými číslicemi. Aby bylo možné snadno určit následující relaci i+1, doplníme do každého políčka (q, x) číslo třídy, do níž patří stav (q, x) (dvojice (q, x) označuje políčko na řádku q ve sloupci x). Třídy rozkladu určeného i+1 pak lze získat tak, že existující skupiny dále rozdělíme ­ v rámci každé skupiny sdružíme stavy, které mají řádky vyplněné stejným způsobem. Pokud dojde k tomu, že v každé skupině mají všechny stavy řádky vyplněné stejně, není již důvod něco rozdělovat; nalezli jsme relaci . 0 a b I 1 I I 2 II I 4 II I N I I II 3 II II 5 II II 6 I I 1 a b I 1 II I N I I II 2 III II 4 III II III 3 IV III 5 IV III IV 6 II I 2 a b I 1 III II II N II II III 2 IV III 4 IV III IV 3 V IV 5 V IV V 6 III II Relace je tedy v tomto případě rovna relaci 2. Minimální automat pro jazyk L() vypadá takto: / a b I III II II II II III IV III IV V IV V III II 2.2 Konservativní rozšíření modelu konečných automatů V této části si ukážeme některé způsoby, jak lze základní model konečného automatu dále rozšířit či zobecnit bez toho, aby se změnila výpočetní síla ­ tj. ke každému rozšíře- nému modelu (akceptujícímu nějaký jazyk) bude existovat model základní s ním jazykově ekvivaletní (akceptující týž jazyk). Takovéto rozšíření se nazývá konservativní. 2.2.1 Nedeterministické konečné automaty Nedeterministický konečný automat je zařízení, které je velmi podobné konečnému auto- matu z definice 2.1. Jediný rozdíl je v tom, že nedeterministický automat nemusí mít pro daný stav a vstupní symbol určen následující stav jednoznačně (na přechodových grafech si to lze představit tak, že z jednoho uzlu může vycházet více hran se stejným návěštím). Není tedy předem jasné, do jakého stavu se automat dostane po zpracování daného slova w, nebot'automat si během výpočtu může ,,vybírat" jeden z možných následujících stavů. Slovo w bude akceptováno, pokud alespoň jeden z možných výpočtů nad slovem w skončí v koncovém stavu. Poznámka 2.41. V dalším textu budeme označovat konečné automaty z definice 2.1 pří- vlastkem deterministické, zkráceně DFA, abychom předešli nedorozumění. Definice 2.42. Nedeterministický konečný automat, zkráceně NFA, je = (Q, , , q0, F), kde význam všech složek je stejný jako v definici 2.1 s výjimkou přechodové funkce . Ta je definována jako (totální) zobrazení Q × 2Q. Na deterministické automaty tedy můžeme pohlížet jako na speciální případ nedeterminis- tických automatů, kdy pro každé q Q a a je množina (q, a) nejvýše jednoprvková. Podobně jako v případě deterministických automatů zavedeme rozšířenou přecho- dovou funkci ^ Q × 2Q: ˇ ^(q, ) = {q} ˇ ^(q, wa) = p^(q,w) (p, a) Jazyk přijímaný nedeterministickým konečným automatem je definován takto: L() = {w | ^(q0, w) F = } Nedeterministické konečné automaty a jsou ekvivalentní, pokud L() = L( ). Stejně jako v případě deterministických konečných automatů je také možné definovat jazyk L() pomocí pojmů konfigurace a krok výpočtu; jediná změna je v definici relace kroku výpočtu: (q, aw) (p, w) def p (q, a) Nedeterminismus je velmi silný popisný aparát, který často umožňuje zachytit strukturu jazyka elegantním a přirozeným způsobem. Uvažme např. jazyk L = {w {a, b} | w obsahuje podslovo abba nebo bab} Navrhnout deterministický automat, který rozpoznává L, není zcela triviální. Naopak ne- deterministický automat lze zkonstruovat snadno: WVUTPQRS2 b GGWVUTPQRS3 b GGWVUTPQRS4 a 33ggggggg GGWVUTPQRS1 a aa{{{{{{{ b 99yyyyyyyyyyyyy @G cc FED a,b )) WVUTPQRSONMLHIJK5 CD GFE a,b 33 WVUTPQRS7 a GGWVUTPQRS6 b UUooooooooooooo Struktura automatu velmi přímočaře odráží fakt, že L je složen ze slov, která začínají nějakým řetězcem symbolů a, b, pak následuje jedno z podslov abba, bab a na konci je zase nějaký řetězec složený z a, b. Nedeterminismus lze dobře využít jako popisný prostředek, nemá však vliv na vý- početní sílu konečných automatů. Ke každému nedeterministickému konečnému automatu totiž ve skutečnosti existuje ekvivalentní deterministický automat, který lze dokonce al- goritmicky zkonstruovat. Důkaz tohoto faktu se opírá o zajímavou techniku, které se říká podmnožinová konstrukce: Věta 2.43. Pro každý NFA = (Q, , , q0, F) existuje ekvivalentní DFA. Důkaz: Necht' = (Q , , , {q0}, F ) je deterministický konečný automat, kde: ˇ Q = 2Q, tj. stavy automatu jsou všechny podmnožiny Q. ˇ Přechodová funkce je definována předpisem (P, a) = qP (q, a) ˇ Množina koncových stavů F je tvořena právě těmi podmnožinami Q, které obsahují alespoň jeden prvek množiny F. Zřejmě je deterministický konečný automat (dokonce s totální přechodovou funkcí). Nejprve ukažme, že pro každé w platí ^(q0, w) = ^ ({q0}, w). Indukcí k délce w: ˇ |w| = 0: Platí ^(q0, ) = {q0} = ^ ({q0}, ). ˇ Indukčníkrok: Necht'w = va(v , a ), pak ^(q0, va) = p^(q0,v) (p, a) = (^(q0, v), a) (viz definice ) = (^ (q0, v), a) (indukčnípředpoklad) = ^ (q0, va). Nyní se již snadno vidí, že L() = L( ), nebot'w L() ^(q0, w) F = ^ ({q0}, w) F = ^ ({q0}, w) F w L( ). Algoritmus 2.3 Transformace NFA na ekvivalentní DFA. Vstup: Nedeterministický konečný automat = (Q, , , q0, F). Výstup: Ekvivalentní deterministický konečný automat = (Q , , , {q0}, F ) bez nedosažitelných stavů s totální přechodovou funkcí. Q = {{q0}}; = ; F = ; Done = ; while (Q - Done) = do M = libovolný prvek množiny Q - Done; if M F = then F = F {M}; end if for all a do N = pM (p, a); Q = Q {N}; = {((M, a), N)}; end for Done = Done {M}; end while = (Q , , , {q0}, F ); Uvedený důkaz je konstruktivní (podává návod na sestrojení automatu ). Nevý- hodou prezentovaného algoritmu však je, že automat může obsahovat mnoho nedosa- žitelných stavů. Tento nedostatek lze odstranit jednoduše ­ iterativní konstrukcí množiny dosažitelných stavů a přechodové funkce. Obdržíme tak algoritmus 2.3. Aplikujeme-li algoritmus 2.3 na dříve uvedený nedeterministický automat, rozpo- znávající jazyk L = {w {a, b} | w obsahuje podslovo abba nebo bab}, dostaneme tento výstup: WVUTPQRS12 b GG @G cc FED a )) WVUTPQRS137 b &&SSSSSSSSSSSSSS a WVUTPQRSONMLHIJK1357 b GG a &&SSSSSSSSSSSSSS WVUTPQRSONMLHIJK1457 a b &&SSSSSSSSSSSSSS WVUTPQRSONMLHIJK125 CD GFE a 33E ccccc F b GGWVUTPQRS1 a YYwwwwwwww b 55qqqqqqqq WVUTPQRS17 a GG @G ABC b 33 WVUTPQRS126 a SSSSSSSSSSSSSS b hh WVUTPQRS147 a GG B A b ccccc WVUTPQRSONMLHIJK1256 a hh b SSSSSSSSSSSSSS WVUTPQRSONMLHIJK157a oo CD cc @AB b xx )) Tento příklad také demonstruje, že výstupem algoritmu 2.3 nemusí být minimální automat; ten totiž pro jazyk L vypadá takto: WVUTPQRSq1 b GG @G cc FED a )) WVUTPQRSq2 b &&SSSSSSSSSSSSSS a WVUTPQRSONMLHIJKq3 CD GFE a,b 33 GGWVUTPQRSq0 a YYwwwwwwww b 55qqqqqqqq WVUTPQRSq6 a GG @G ABC b 33 WVUTPQRSq5 a SSSSSSSSSSSSSS b hh WVUTPQRSq4 a yy B A b ccccc Čtenář se nyní může pokusit zjistit, jaká informace o přečtené části vstupního slova je spojena s jednotlivými stavy. Podmnožinová konstrukce je na první pohled značně neefektivní ­ nárůst počtu stavů při přechodu od nedeterministického konečného automatu k deterministickému je ex- ponenciální. To je z technického hlediska nepříjemné. Nabízí se proto otázka, zda použitím ,,pomocných" technik (odstranění nedosažitelných stavů, minimalizace) je obecně možné dosáhnout lepšího výsledku. Následující věta říká, že nikoliv. Věta 2.44. Pro každé n existuje NFA o n stavech takový, že ekvivalentní DFA má i po minimalizaci 2n stavů. Důkaz: Necht'n N je libovolné přirozené číslo. Zkonstruujeme nedeterministický ko- nečný automat o n stavech, který má požadovanou vlastnost. Necht' = (Q, , , 1, {1}), kde: ˇ Q = {1, . . . , n} ˇ = {a, b} WVUTPQRS2 a GG b ÓÓÖÖÖÖÖÖÖÖÖÖÖÖ @G cc FEDb )) WVUTPQRS3 a ''VVVVVVVVVVVV b wwooooooooooooooooooooooooo CD GFE b 33 GGWVUTPQRSONMLHIJK1 a ggÖÖÖÖÖÖÖÖÖÖÖÖ WVUTPQRS4 boo a ÓÓÖÖÖÖÖÖÖÖÖÖÖÖ CD GFE b 33 WVUTPQRS6 a VVVVVVVVVVVV b VVVVVVVVVVVV @G ABC b 33 WVUTPQRS5 b ggyyyyyyyyyyyyyyyyyyyyyyyyy a oo CD cc @AB b xx )) Obrázek 2.2: Automat z důkazu věty 2.44 pro n = 6. ˇ je nejmenší funkce splňující: ­ (i, a) = {i + 1} pro 1 i n - 1 ­ (n, a) = {1} ­ (i, b) = {1, i} pro 2 i n Na obrázku 2.2 je znázorněn automat pron = 6. Dokážeme, že deterministický konečný automat , který je výstupem algoritmu 2.3, má právě 2n stavů a je minimální. To, že má právě 2n stavů vyplývá z toho, že libovolná podmnožina Q je do- sažitelným stavem automatu ­ prázdná množina je zřejmě dosažitelný stav, nebot' ^ (1, b) = . Necht'tedy {k1, . . . , kl } Q je neprázdná podmnožina. Předpokládejme, že ki < kj pro i < j a označme di = ki+1 - ki pro 1 i < l. Pak stav {k1, . . . , kl } je v automatu dosažitelný pod slovem adl-1 badl-2 badl-3 . . . ad1 bak1-1 (tedy např. stav {2, 4, 5} je v automatu na obrázku 2.2 dosažitelný pod slovem abaaba). Tento fakt lze lehce ověřit indukcí vzhledem k l. Zbývá dokázat, že je minimální. K tomu stačí ověřit, že pro každé dva různé stavy U, V automatu platíU V (viz definice 2.32). Jelikož U = V , existuje k {1, . . . , n}, které patří do U ale nepatří do V , nebo obráceně. Slovem, kterým lze stavy U a V rozlišit ve smyslu definice 2.32, je an-k+1. Tedy i pro poměrně ,,malý" nedeterministický konečný automat může být ekvivalentní deterministický automat ,,velmi velký" i po minimalizaci. V praxi je velikost stavového prostoru samozřejmě omezená použitou technologií. Znamená to tedy, že nedeterminis- tické konečné automaty obecně nelze efektivně implementovat? Naštěstí tomu tak není; technický ,,trik", kterým lze exponenciální nárůst počtu stavů obejít, je skryt v samotné podmnožinové konstrukci: Necht' Q = {q1, . . . , qn} je množina stavů nedeterministic- kého konečného automatu .Libovolnou podmnožinu X Q pak můžeme jednoznačně zakódovat bitovým řetězcem délky n takto: i-tý prvek = 1 pokud qi X, 0 jinak. Libovolný stav deterministického automatu , který je výstupem podmnožinové kon- strukce aplikované na , můžeme tedy reprezentovat n-bitovým řetězcem. Technická implementace automatu pak spočívá v realizaci dvou funkcí: Ó ÜË ´× Ë Ó ¸ ×Ý Ó Ö Ë Ó Tato funkce má dva parametry: × je stav automatu , zakódovaný jako n- bitový řetězec (bitové řetězce jsou implementovány pomocídatovéhotypuË Ó ). Druhý parametr ×Ý Ó je vstupní symbol. Funkce vrací kód stavu (q, ×Ý Ó), kde q je stav s kódem × . Ó Á× ´× Ë Ó ÓÓ Funkce má jeden parametr, kterým je stav automatu , zakódovaný jako n-bitový řetězec. Vrací Ö pokud je stav s kódem × koncový, jinak × . Jedinou datovou strukturou, která je potřebná pro implementaci těchto funkcí, je tabulka přechodové funkce původního nedeterministického automatu s vyznačenými koncovými stavy. Funkce ÜË na základě svých parametrů a tabulky pro snadno určí kód výsledného stavu (i-tý bit výsledku bude nastaven na 1, právě když qi (qj , ×Ý Ó) pro nějaké j takové, že j-tý bit prvního parametru je nastaven na 1). Podobně funkce Á× vrátí hodnotu Ö , pokud existuje i takové, že qi F a i-tý bit parametru je 1. Není tedy zapotřebí implementovat tabulku přechodové funkce , ani není nutné explicitně reprezentovat stavy automatu . Na nedeterministický automat proto můžeme pohlížet jako na symbolickou re- prezentaci automatu , která dokáže popsat stavy i přechodovou funkci podstatně hutnější (úspornější) syntaxí. 2.2.2 Automaty s -kroky Model nedeterministického konečného automatu je možné dále rozšířit o tzv. -kroky. Automat pak může svůj stav za určitých okolností změnit samovolně, tj. bez přečtení vstupního symbolu. Tato schopnost je formálně popsána pomocí -kroků, které si lze na přechodových grafech představit jako hrany, jejichž návěštím je prázdné slovo. Přes tyto hrany může automat během výpočtu na slově w měnit svůj stav bez toho, aby ze vstupu cokoliv přečetl ­ mezi přečtením dvou po sobě jdoucích symbolů z wmůže provést libovolné konečné množství -přechodů. Příklad 2.45. Následující automat s -kroky rozpoznává právě ta slova w {0, 1}, která jsou tvaru 01k1 01k2 . . . 01kn , kde n 1 a ki 1 pro každé 1 i n: GGWVUTPQRSq0 0 GGWVUTPQRSq1 1 GGWVUTPQRSONMLHIJKq2 oo BC@A yy Definice 2.46. Nedeterministický konečný automat s -kroky je pětice = (Q, , , q0, F), kde význam všech složek je stejný jako v definici 2.42 s výjimkou přechodové funkce . Ta je definována jako totální zobrazení Q × ( {}) 2Q. Rozšířenou přechodovou funkci ^ ovšem musíme definovat odlišným způsobem; nejprve zavedeme funkci D Q 2Q, která pro daný stav p vrací množinu stavů, kterých může dosáhnout z p bez toho, aby četl vstup. Pro dané p Q je D(p) nejmenší množina X Q taková, že platí: ˇ p X ˇ Pokud q X a r (q, ), pak také r X. Např. pro automat z příkladu 2.45 platí D(q0) = {q0}, D(q1) = {q1}, D(q2) = {q0, q1, q2}. Funkci D je možné přirozeně rozšířit na množiny stavů; je-li Y Q, položíme D(Y) = qY D(q) Nyní již můžeme definovat rozšířenou přechodovou funkci ^ Q × 2Q takto: ˇ ^(q, ) = D(q), ˇ ^(q, wa) = p^(q,w) D((p, a)). Pro automat z příkladu 2.45 mimo jiné platí ^(q2, 1) = {q0, q1, q2}, ^(q1, 1) = {q0, q1, q2} a ^(q2, 0) = {q1}. Jazyk přijímaný automatem s -kroky je definován stejně jako v případě nedeter- ministických automatů, tj. L() = {w | ^(q0, w) F = } Není obtížné dokázat, že ke každému automatu s -kroky existuje ekvivalentní nedeter- ministický automat ; v principu je třeba v přechodovém grafu automatu přidat hranu p1 a qn pro každou cestu tvaru p1 . . . pm a q1 . . . qn kde m, n 1, a . Pak lze -hrany z přechodového grafu bez problémů odstranit. Nejprve dokážeme jedno pomocné tvrzení: Lemma 2.47. Necht' = (Q, , , q0, F) je automat s -kroky. V přechodovém grafu automatu existuje cesta p1 . . . pm a q1 . . . qn, kde m, n 1, a , právě když qn ^(p1, a). Důkaz: Nejprve si uvědomme, že podle definice ^ platí ^(p1, a) = rD(p1) D((r, a)) (2.6) ( ) Jelikož p1 . . . pm, platí pm D(p1). Dále pm a q1, tedy q1 (pm, a). Konečně q1 . . . qn, proto qn D(q1). Celkem qn ^(p1, a) podle vztahu (2.6). ( ) Necht' qn ^(p1, a). Podle vztahu (2.6) pak musí existovat stav r D(p1) takový, že qn D((r, a)). Jelikož r D(p1), existuje v přechodovém grafu cesta p1 . . . r. Protože qn D((r, a)), musí existovat stav s (r, a) takový, že qn D(s). V přechodovém grafu proto existuje hrana r a s a cesta s . . . qn. Celkem p1 . . . r a s . . . qn, což bylo dokázat. Věta 2.48. Ke každému NFA s -kroky existuje ekvivalentní NFA (bez -kroků). Důkaz: Necht' = (Q, , , q0, F) je libovolný NFA s -kroky a sestrojme ekvivaletní NFA = (Q, , , q0, G) bez -kroků. Položme (q, a) = ^(q, a) pro každé q Q, a a množinu G definujme takto: G = F pokud D(q0) F = , F {q0} jinak. Nejprve dokážeme, že pro libovolné p Q, w + platí ^(p, w) = ^ (p, w), tj. q ^(p, w) q ^ (p, w). V této souvislosti je třeba si uvědomit, že funkce ^, ^ jsou definovány na základě funkcí , odlišným způsobem ­ ^ je rozšířenou přechodovou funkcí nedeterministického konečného automatu , je tedy určena předpisem uvedeným za definicí 2.42, zatímco ^ je určena předpisem za definicí 2.46 (pro w = tedy uvedená ekvivalence platit nemusí). Důkaz provedeme indukcí k délce slova w. ˇ |w| = 1: Pak w = a pro nějaké a a ^(p, a) = (p, a) = ^ (p, a) podle definic a ^ . ˇ Indukční krok: Necht' w = va, kde v + a a . Platí q ^(p, w) existují stavy r, s takové, že r ^(p, v), s (r, a) a q D(s) (existuje tedy cesta r a s . . . q) r ^ (p, v) (s využitím indukčního předpokladu), q ^(r, a) (lemma 2.47) r ^ (p, v) a q (r, a) (podle definice ) q ^ (p, va). Pro libovolné w + tedy platí ^(q0, w) = ^ (q0, w), tj. w L() w L( ). Dále L() D(q0) F = q0 G L( ). Tedy celkem L() = L( ). Předchozí věta podává algoritmus pro transformaci automatu s -kroky na ekvivalentní nedeterministický automat (bez -kroků). Pokud jej aplikujeme na automat z příkladu 2.45, pak dostaneme GGWVUTPQRSq0 0 GGWVUTPQRSq1 1 GG 1 oo @G cc FED1 )) WVUTPQRSONMLHIJKq2 0,1 oo BC@A 1 yy @G cc FED1 )) 2.2.3 Uzávěrové vlastnosti regulárních jazyků ­ část I V této části dokážeme, že třída regulárních jazyků je uzavřená na některé operace nad jazyky definované v části 1.1.1. Důležitost uzávěrových vlastností spočívá nejen ve zkoumání vlastnostídané třídy jazyků, ale má i řadu praktických aspektů. Daný jazyk lze často vyjádřit pomocí několika jazyků jednodušších, pro každý z nich navrhnout konečný automat a na jejich základě sestrojit žádaný výsledný automat ­ tento postup byl již ilustrován v příkladu 2.12. Uzávěrových vlastností lze často využít i ke zjednodušení důkazu, že nějaký jazyk je (viz opět 2.12) či (a to zejména) není regulární ­ viz příklad 2.50 níže. Uvědomme si, že již na počátku této kapitoly (přesněji v 2.9 ­ 2.11) jsme de facto ukázali, že třída regulárních jazyků je uzavřená na základní množinové operace sjednocení, průniku a komplementu. Věta 2.49. Třída regulárních jazyků je uzavřená na sjednocení, průnik a rozdíl. Důkaz: Necht'L1 a L2 jsou regulární jazyky rozpoznávané deterministickými konečnými automaty 1 a 2 s totálními přechodovými funkcemi. Bez újmy na obecnosti přitom můžeme předpokládat, že L1 i L2 jsou jazyky nad stejnou abecedou (v opačném pří- padě provedeme sjednocení abeced a dodefinujeme přechodové funkce automatů ­ viz lemma 2.6). Pak jazyky L1 L2, L1 L2 a L1 - L2 jsou rozpoznávané po řadě auto- maty 1 2, 1 2 a 1 2 (viz definice 2.9 a poznámka 2.11), jsou tedy regulární. Příklad 2.50. Ukažme, že jazyk L = {w a, b | #a(w) = #b(w)} není regulární. Důkaz lze samozřejmě provést pomocí Myhillovy-Nerodovy věty (viz 2.28) či lemmatu o vkládání 2.13. Jestliže však již víme, že L1 = {ai bi | i 0} není regulární, stačí uvážit, že L1 = L ab. Kdyby totiž byl L regulární, pak by díky regularitě ab a uzavřenosti regulárních jazyků na průnik musel být regulární i L1, což ale není. Věta 2.51. Třída regulárních jazyků je uzavřená na komplement. Důkaz: Důkaz okamžitě plyne z předchozí věty 2.49 a De Morganových pravidel. Al- ternativně lze též uvést konstruktivní důkaz: necht' L je regulární jazyk nad abecedou , rozpoznávaný deterministickým konečným automatem = (Q, , , q0, F) s to- tální přechodovou funkcí. Pak jazyk co­L je rozpoznávaný konečným automatem M = (Q, , , q0, Q - F) (viz poznámka 2.11). Věta 2.52. Třída regulárních jazyků je uzavřená na zřetězení. Důkaz: Necht'L1 a L2 jsou regulární jazyky, rozpoznávané nedeterministickými koneč- nými automaty 1 = (Q1, 1, 1, q1, F1) a 2 = (Q2, 2, 2, q2, F2), kde Q1Q2 = (předpoklad, že oba automaty jsou nedeterministické, není podstatný; umožní nám však elegantně zapsat definici přechodové funkce níže uvedeného automatu). Pak L1.L2 je roz- poznávaný automatem 1 2 = (Q1 Q2, 1 2, , q1, F2) s -kroky, kde = 1 2 {((p, ), {q2}) | p F1} Jinými slovy, automat 1 2 vznikne ,,napojením" automatů 1 a 2 pomocí - hran, které vedou z koncových stavů 1 do počátečního stavu 2. Zřejmě L(1 2) = L1.L2, nebot' w L(1 2) w = uv, kde u L(1) a v L(2) uv L1.L2. Věta 2.53. Třída regulárních jazyků je uzavřená na iteraci. Důkaz: Necht' L je regulární jazyk, rozpoznávaný nedeterministickým konečným auto- matem = (Q, , , q0, F) (předpoklad, že je nedeterministický, má stejný vý- znam jako v důkazu předchozí věty). Pak jazyk L je rozpoznávaný automatem = (Q {p}, , , p, {p}) s -kroky, kde p Q a = {((p, ), {q0}} {((q, ), {p}) | q F} V automatu tedy přibyl nový počátečnístav p, který je také jediným koncovým stavem, dále -hrana ze stavu p do původního počátečního stavu q0 a konečně -hrany z původních koncových stavů do stavu p. Zřejmě L() = L. Poznámka 2.54. Zavedení nového počátečního stavu p v automatu z předchozího důkazu je nutné ­ kdybychom tak neučinili a prohlásili za koncový přímo stav q0 (počáteční stav automatu který rozpoznává L musíbýt nutně koncový, nebot'L vždy obsahuje prázdné slovo), do kterého bychom přidali -hrany z původních koncových stavů, mohl by vzniklý automat přijímat vlastní nadmnožinu jazyka L ­ dojít k tomu může tehdy, když v existuje alespoň jeden přechod do stavu q0 a přitom q0 není v automatu koncovým stavem. Ukážeme si konkrétní příklad ­ necht' je automat: GGWVUTPQRSq0 b GG @G cc FED a )) WVUTPQRSONMLHIJKq1 Kdybychom nyní přidali -hranu ze stavu q1 do q0 a stav q0 prohlásili za koncový, bude vzniklý automat akceptovat např. i slovo aa, které do iterace jazyka L() nepatří. Věta 2.55. Třída regulárních jazyků je uzavřena vůči operaci zrcadlového obrazu (reverzi). Důkaz: Necht'L je regulární jazyk, který je rozpoznáván nějakým konečným automatem a sestrojme s ním ekvivaletní NFA s -kroky. obržíme tak, že (neformálně řečeno) v přechodovém grafu obrátíme orientaci hran, přidáme nový počáteční stav, z něhož povedeme -přechody do všech koncových stavů automatu a počáteční stav bude koncovým stavem v . Formální definici a důkaz ekvivalence L() = L( ) ponecháváme čtenáři. Důsledek 2.56. Libovolný jazyk L je regulární L R je regulární. Důkaz: Díky 2.55 zbývá ukázat implikaci L R regulární L je regulární. Jelikož platí (LR)R = L, pak dle 2.55 dostáváme L R regulární (L R)R = L je regulární. Uzavřenost na další operace bude ukázána v části 2.3.1, kde s výhodou využijeme dalšího konservativního rozšíření základního modelu. 2.2.4 Regulární výrazy V této části zavedeme formalismus, který je rovněž užitečným prostředkem pro popis (spe- cifikaci) a návrh konečných automatů. Jen zopakujme, že zatím jsme pojem regulární jazyk používali jako (syntaktickou) zkratku pro pojem jazyk přijímaný konečným automatem a též pro pojem jazyk generovaný gramatikou typu 3. Tvrzení, že se jedná o tutéž třídu jazyků bude ukázáno v následující části. V této části budeme definovat regulární jazyky tak, jak byly historicky originálně (pod tímto názvem) zavedeny, uvedeme formalismus pro jejich specifikaci a konečně ukážeme, že takto definovaná třída jazyků je identická s třídou jazyků rozpoznávaných konečnými automaty. Definice 2.57. Třída regulárních jazyků nad abecedou , označovaná jako R( ), je defi- nována induktivně takto: 1. , {} a {a} pro každé a je regulární jazyk nad . 2. Jsou-li L1, L2 regulární jazyky nad , jsou také, L1.L2, L1 L2 a L 1 regulární jazyky3 nad . 3. Každý regulární jazyk vznikne po konečném počtu aplikací kroků 1 a 2. Jinými slovy R( ) je nejmenší třída jazyků nad splňující podmínky 1 a 2. Jazyky uvedené ad 1 se nazývají elementární, operace nad jazyky uvedené ad 2 se nazývají regu- lární. Je tedy vidět, že každý regulární jazyk lze popsat určením elementárních jazyků a předpisu, který určuje jak na tyto jazyky aplikovat regulární operace. Taková specifikace je cílem následující definice. Definice 2.58. Množina regulárních výrazů (regular expressions) nad abecedou , ozna- čovaná RE( ), je definována induktivně takto: 1. , aaaa pro každé a jsou regulárnívýrazy nad (tzv. základní regulárnívýrazy). 2. Jsou-li E, F regulární výrazy nad , jsou také, (E.F), (E + F) a (E) regulární výrazy nad . 3. Každý regulární výraz vznikne po konečném počtu aplikací kroků 1­2. Základníregulárnívýrazy se podobajísymbolům, se kterými jsme se v textu běžně setkávali. Tučně jsou zapsány proto, že je třeba je chápat jako symboly zcela nové; tyto ,,dvojníky" jsme zavedli proto, abychom mohli vždy snadno rozlišit mezi syntaxí a sémantikou re- gulárních výrazů (předchozí definice popisuje pouze syntaxi). V regulárních výrazech se 3. je zřejmé, že požadavek ,,{} je regulární . . . " v 1 je nadbytečný, protože {} = . Je uveden čistě z pedagogických důvodů. mohou vyskytovat také kulaté závorky jako metasymboly, které pomáhají vymezit rozsah operátorů. Abychom jejich použití omezili na minimum, přijmeme konvenci týkající se priority operátorů: Největší prioritu má ,,", pak ,,." a nakonec ,,+", přičemž ,,nadbytečné" závorky lze vypouštět. Výraz aaa + bbb.ccc tedy odpovídá výrazu (aaa + (bbb.(ccc))). Každý regulární výraz E nad abecedou popisuje (jednoznačně určuje) jazyk L(E) nad abecedou (jazyk L(E) je sémantikou regulárního výrazu E) podle těchto pravidel: L() def = {} L() def = L(aaa) def = {a} pro každé a L(E.F) def = L(E).L(F) L(E + F) def = L(E) L(F) L(E ) def = L(E) Na levé straně definujících rovnic se vyskytují regulární výrazy; na pravé straně je třeba symboly ,,", ,,", atd. chápat v jejich původním významu ­ tj. jazyk určený regulárním výrazem obsahuje pouze prázdné slovo, jazyk určený výrazem je prázdný, atd. Tečka se v zápisu regulárních výrazů často vynechává. Například tedy platí: L((aaa + bbb) (ababab + bbbbbb)(aaa + bbb) ) = {w (a, b) | w obsahuje podslovo ab nebo bb} L((aaaaaa + ababab + bababa + bbbbbb) ) = {w {a, b} | w má sudou délku} L((000 111 222 ) ) = {0, 1, 2} Poznámka 2.59. Z výše řečeného se okamžitě nahlédne fakt, že jazyk je regulární nad právě když je popsatelný nějakým regulárním výrazem nad . Na rozdíl od regulárních gramatik neobsahují regulární výrazy žádnou formu rekurze; aby bylo jasné, oč se jedná, uvažme např. gramatiku = ({S, A}, {a, b}, P, S), kde P obsahuje pravidla S aA | a A bS | b Neterminály S a A přirozeným způsobem určují jazyky L(S) a L(A): L(S) = {w {a, b} | S w} L(A) = {w {a, b} | A w} Platí tedy L( ) = L(S). Pravidla gramatiky lze přirozeným způsobem transformovat na systém vzájemně rekurzivních rovnic: XS = {a}.X A {a} X A = {b}.XS {b} Proměnné XS a XA zastupují jazyky nad abecedou {a, b}. První rovnice říká, že jazyk X S dostaneme sjednocením zřetězení jazyků {a} a X A s jazykem {a}. Význam druhé rovnice je obdobný ­ jazyk X A je definován v závislosti na jazyku XS. Dosadíme-li za XS jazyk L(S) a za X A jazyk L(A), obě rovnice platí. Není obtížné dokázat (čtenář se o to může pokusit), že L(S) a L(A) jsou také jediným řešením uvedených rovnic. Tento fakt má obecnou platnost, tj. jazyk generovaný libovolnou regulární gramati- kou lze tímto způsobem vyjádřit jako řešeníjistého systému rekurzivních rovnic. Podobná forma rekurze se objevuje také u konečných automatů; v definici 2.32 jsme pro každý stav q konečného automatu zavedli jazyk L(q). Přechodová funkce popisuje závislost mezi jazyky L(q) podobným způsobem, jako množina pravidel v případě gramatik. Rekurze je z hlediska popisné síly velmi důležitá ­ pokud definující rovnice určené pravidly regulární gramatiky neobsahují žádnou rekurzivní (tj. ,,cyklickou") závislost mezi proměnnými, je jazyk L( ) nutně konečný. Příkladem takové gramatiky je třeba ({S, A, B}, {a, b, c}, P, S), kde P obsahuje pravidla S a | bA A c | aB B b | c V případě regulárních výrazů, kde se rekurze v žádné podobě neobjevuje, se snadno vidí, že jediný prostředek umožňující definovat nekonečný jazyk je iterace. Výsledek o ekvivalenci regulárních výrazů a regulárních gramatik, který v této části dokážeme, lze tedy také interpretovat jako ekvivalenci popisné síly iterace a rekurze ve speciálním typu rovnic. Věta 2.60. Necht'E je regulární výraz. Pak existuje konečný automat rozpoznávající L(E). Důkaz: Pro libovolnou (konečnou) abecedu lze zkonstruovat FA, které rozpoznávají elementární jazyky, tj. , {} a {a} pro každé a . Tvrzení věty pak okamžitě plyne z uzavřenosti jazyků rozpoznatelných konečnými automaty vůči regulárním operacím, tj. sjednocení (viz věta 2.49), zřetězení(viz věta 2.52) a iteraci (viz věta 2.53). Čtenáře, který očekával přímočařejší algoritmus, jak k danému regulárnímu výrazu sestrojit ekvivalentníkonečný automat, nezklameme a odkazujeme jej na pojem regulárního přechodového grafu a větu 2.65, které jsou uvedeny v závěru této části. Poznámka 2.61. Výše uvedená věta 2.60 tedy říká, že třída jazyků, která obsahuje všechny konečné množiny (každá z nich jistě rozpoznatelná nějakým FA) a která je uzavřena na sjed- nocení, zřetězení a iteraci je podtřídou třídy jazyků rozpoznatelných konečnými automaty. Následující věta ukazuje, že platí i obrácená inkluse, což spolu s 2.60 říká, že třída jazyků rozpoznatelných konečnými automaty je nejmenší třída, která obsahuje všechny konečné množiny a je uzavřena na sjednocení, zřetězení a iteraci ­ srovnej s formulací tzv. Kleene-ho věty (věta 2.63). Věta 2.62. Necht'L je akceptovaný nějakým (libovolným) DFA, pak L je popsatelný nějakým regulárním výrazem. Důkaz: Necht' = ({q1, . . . , qn}, , , q1, F) je DFA, který akceptuje L. Pro všechna i, j 1 i, j n definujme množiny slov Ri j def = {w | ^(qi , w) = qj } tj. množiny slov převádějících ze stavu qi do stavu qj . Je vhodné si uvědomit, že platí: L = L( ) = qj F R1 j (*) Stačí tedy ukázat, že každá R1 j je regulární (definice regulárního jazyka v sobě obsahuje uzavřenost na sjednocení), a tedy je popsatelná nějakým regulárním výrazem. Abychom dokázali regularitu R1 j , dokažme, že každá Ri j je regulární (žádané dosta- neme specializací pro i = 1). Za tímto účelem definujme množiny slov Rk i j , k = 0, . . . , n, kde každá z nich bude množinou všech slov, která převádějí automat ze stavu qi do stavu qj (jako u Ri j ), ale při tomto výpočtu není povoleno projít žádným (mezi)stavem qm, který by měl index m větší než k. Formálně zapsáno: Rk i j def = {x | ^(qi , x) = qj ((^(qi , y) = qm y x) m k)} Zřejmě pak platí Ri j = Rn i j (a ukážeme-li regularitu všech Rk i j , stačí položit k = n). Nyní si uvědomme, že Rk i j lze definovat induktivně, a tedy následně využít k doka- zování regularity Rk i j indukci. Navíc můžeme takovou definici využít k jejich výpočtu (at' už k rekursivnímu či iterativnímu). Definujme tedy: 1. R0 i j def = {a | (qi , a) = qj } je-li i = j {a | (qi , a) = qj } {} je-li i = j 2. Rk+1 i j def = Rk i,k+1(Rk k+1,k+1) Rk k+1, j Rk i j pro všechna k = 0, . . . , n - 1 (**) Neformálně lze tuto definici vysvětlit takto: bod 1 představuje bázi výše uvedené definice. Bod 2 říká, že vstup, který automat převede z qi do qj bez průchodu mezistavem o indexu větším než k + 1, je bud' ˇ z množiny Rk i j (2. sčítanec v 2), tj. množiny slov odpovídající cestám z qi do qj , kdy není použit žádný mezistav ,,vyšší" než qk, nebo ˇ z množiny slov, která reprezentuje průchod stavem ,,vyšším" než qk, tj. qk+1 (1. sčí- tanec v 2): lze ji získat tak, že 1. nejprve vezmeme všechna slova, která převedou z qi poprvé do qk+1 (tj. 1. či- nitel Rk i,k+1), 2. následovaná (zřetězená se) všemi slovy, která převedou z qk+1 zpět do qk+1, aniž by se prošlo nějakým vyšším stavem než qk. Pokud je množina těchto slov neprázdná, pak reprezentuje cyklus z qk+1 zpět do qk+1, a proto tedy u 2. činitele (Rk k+1,k+1) je operace iterace. Množina těchto slov může být i prázdná (taková cesta neexistuje) ­ uvědomme si, že definice je korektní i v tomto případě, protože {} = {}. 3. Konečně ke slovům získaným ve dvou výše uvedených bodech připojíme (zře- tězením) všechna slova, která převedou z qk+1 do cílového qj bez průchodu stavem qk+1 nebo vyšším, což je reprezentováno 3. činitelem Rk k+1, j. Nyní se indukcí snadno ukáže, že každá Rk i j je regulární, a tedy popsatená nějakým regu- lárním výrazem. I když z hlediska důkazu není nutno tyto výrazy specifikovat, uvedeme je (v komentářových závorkách `(*' a `*)' ), nebot'tak de facto specifikujeme algoritmus pro konstrukci hledaného výrazu. Báze indukce, k = 0. Pro libovolná i, j je R0 i j {}, a tedy regulární ­ obsahuje totiž jen elementární jazyky. (*Odpovídající regulární výraz, značený r 0 i j , lze zapsat jako a1 + . . . + ap (resp. a1 + . . . + ap + , pokud i = j), kde {a1, . . . , ap} je množina všech symbolů a takových, že (qi , a) = qj . Jetliže žádné takové a neexistuje, pak r0 i j = (resp. r0 i j = , pokud i = j).*) Indukční krok. (IP): předpokládejme , že pro jisté k, 0 k < n a všechna i, j jsou Rk i j regulární a ukažme, že pak i Rk+1 i j je regulární. To se však snadno nahlédne: Rk+1 i j je definována ­ viz (**) ­ pomocí Rk i j (dle IP jsou regulární) a pomocí regulárních operací sjednocení, zřetězení a iterace, a tedy (viz definice regulárního jazyka) je regulární i Rk+1 i j . (*IP je ekvivalentní tomu, že pro všechna l, m existují regulární výrazy r k lm takové, že L(rk lm) = Rk lm. Hledaný výraz rk+1 i j je tedy roven rk i,k+1(rk k+1,k+1)rk k+1, j rk i j .*) Tímto je důkaz ukončen (zopakujme: všechna Rk i j jsou regulární, specielně Rn i j jsou regulární a Rn i j = Ri j , a tedy i R1 j je regulární a tedy dle (*) L( ) = qj F R1 j je regulární). (*Tedy L( ) je popisován výrazem rn 1 j1 + . . . + rn 1 jp , kde F = {qj1 , . . . qjp }.*) Obě předchozí věty 2.60 a 2.62 lze shrnout do tvrzení známého jako Kleeneho věta: Věta 2.63. (Kleene). Libovolný jazyk je popsatelný regulárním výrazem právě když je rozpoznatelný konečným automatem. V této části jsme dosud zavedli jistá rozšíření deterministických konečných automatů definovaných v části 2.1 a ukázali jejich vzájemnou ekvivalenci. Strukturu těchto výsledků (mimo průběžně uváděné uzávěrové vlastnosti) lze znázornit takto: 76 54 01 23DFA 76 54 01 23NFA V ta 2.43oooo 76 54 01 23NFA s kroky V ta 2.48oooo 76 5401 23RE V ta 2.60oooo ECD @GF V ta 2.62 Důkaz věty 2.62 ­ viz definice (**) ­ podává i návod, jak napsat algoritmus převádějící libovolný konečný automat na ekvivaletní regulární výraz. 1. Zmíněnou definici lze považovat za specifikaci rekursivní procedury ´ ¸ ¸ , která má (při značení jako v důkazu věty 2.62) vypočítat r k i j , přičemž rekursivní smyčka končí pro k = 0. Uvědomme si však, že takový algoritmus by byl značně neefektivní - pro řadu konkrétních hodnot parametrů i, j, k by (v obecném případě) opakovaně počítal již v některém předchozím rekursivní volání vypočtené r k i j . 2. Výše uvedenou neefektivitu lze odstranit (na úkor nárůstu pamět'ových nároků) tak, že bychom navíc deklarovali pole ¸¸ a Î ¸¸ , kde bychom inicializovali ¸ ¸ pro všechna i, j, k a kde nastavení ¸ ¸ by udávalo, že výraz rk i j již byl (některou z předchozích aktivací procedury ´ ¸ ¸ ) vypočítán a jeho hodnota by byla uložena ve Î ¸ ¸ . 3. Dále si uvědomme, že výše uvedenou rekursi lze v tomto konkrétním případě, převést na iteraci. Její inicializace spočívá ve výpočtu r0 i j pro všechna i, j. Vlastní iterace postupně počítá (opět pro všechna i, j) výrazy r 1 i j , . . . ,rn i j . Další možné vylepšení (týkající se nyní nároků pamět'ových) spočívá v uvědomění si, že k výpočtu r k+1 i j nepotřebujeme znát všechny dosud určené hodnoty rm i j , 0m k, ale stačí uchovávat jen hodnoty rk i j . Implementační detaily ponecháváme čtenáři s tím, že je vhodné si uvědomit, že pracnost implementace (i v tomto jednoduchém případě) je zřejmě nejnižší ad 1 (lze ji uvažovat jako vhodný prototyp) a nejvyšší ad 3. Na druhé straně asi ani jeden z nastíněných algoritmů není vhodný pro ,,ruční" zpracování (stylem papír a tužka). Uvedeme proto ještě další nástroj, který umožní ,,ruční" převody od konečného automatu k regulárnímu výrazu a obráceně. Mělo by býti zřejmé (nicméně bude dokázáno), že se opět jedná o konservativní rozšíření modelu konečného automatu. Definice 2.64. Regulární přechodový graf je pětice (Q, , , I, F), kde ˇ Q je neprázdná konečná množina stavů. ˇ je vstupní abeceda. ˇ Q × Q RE( ) je parciální přechodová funkce. ˇ I Q je množina počátečních stavů. ˇ F Q je množina koncových stavů. Regulární přechodové grafy tedy představují další zobecnění automatů s -kroky. Hrany mohou být nyní ohodnoceny nejen prvky {}, ale dokonce libovolným regulárním výrazem nad (mezi libovolnými dvěma uzly je však nejvýše jedna hrana, což však není omezení podstatné ­ viz operátor +). Každý automat s -kroky lze považovat za regulární přechodový graf s jedním počátečním stavem, jehož hrany jsou ohodnoceny regulárními výrazy tvaru a1a1a1 + + ananan, kde n a každé aiaiai patří do {}. Slovo w je grafem akceptováno, právě když existuje posloupnost stavů q0, . . . , qn, kde n 1, q0 I, qn F a (qi-1, qi ) je definováno pro každé 0 < i n taková, že w lze rozdělit na n částí w = v1 . . . vn tak, že vi L((qi-1, qi )) pro každé 0 < i n. Navíc je akceptováno také tehdy, je-li I F = . Věta 2.65. Pro libovolný regulární přechodový graf = (Q, , , I, F) existuje ekviva- lentní NFA s -kroky. Důkaz: Přechodový graf automatu s -kroky vznikne transformací regulárního pře- chodového grafu (tento důkazový postup je korektní, nebot'každý automat s -kroky lze jednoznačně reprezentovat jeho přechodovým grafem a obráceně). Nejprve přidáme ke grafu nový stav q0 a hranu q0 q pro každé q I. Stav q0 bude (jediným) počátečním stavem automatu , prvky F jeho koncovými stavy. Další postup transformace spočívá v opakované realizaci dvou kroků (viz obrázek 2.3): 1. Odstraň všechny hrany, které jsou ohodnoceny symbolem . 2. Vyber libovolnou hranu p E q, kde E {}, odstraň ji a proved'následující: ˇ Pokud E = F + G, přidej hrany p F q a p G q. ˇ Pokud E = F.G, přidej ke Q nový stav s a hrany p F s a s G q. ˇ Pokud E = F, přidej ke Q nový stav s a hrany p s, s F s a s q. Tyto dva kroky se provádí tak dlouho, dokud přechodový graf obsahuje alespoň jednu hranu ohodnocenou symbolem, který nepatří do {}. Fakt, že popsaná transformace skončí, vyplývá z toho, že obsahuje pouze konečně mnoho hran a každý regulární výraz vznikne aplikací pravidel 1­2 z definice 2.58 v konečně mnoha krocích. Výsledný graf je přechodovým grafem automatu s -kroky. Snadno se ověří, že kroky 1 a 2 popsaného transformačního algoritmu zachovávají ekvivalenci automatů, proto L() = L( ). Věta 2.66. Pro každý regulárnípřechodový graf = (Q, , , I, F) existuje ekvivalentní regulární přechodový graf = ({x, y}, , , {x}, {y}), kde je definováno pouze pro GFED@ABCp F+G GGGFED@ABCq GFED@ABCp F GG G GGGFED@ABCq GFED@ABCp F.G GGGFED@ABCq GFED@ABCp F GGGFED@ABCs G GGGFED@ABCq GFED@ABCp F GGGFED@ABCq GFED@ABCp GGGFED@ABCs GG 34 765 F 33 GFED@ABCq Obrázek 2.3: Pravidla pro transformaci regulárního přechodového grafu na ekvivalentní NFA s -kroky dvojici (x, y). Důkaz: Popíšeme způsob, kterým lze transformovat graf nagraf . Nejprve přidáme ke grafu nový počáteční stav x a nový koncový stav y. Přidáme také hrany x q pro každé q I a r y pro každé r F. Tato úprava jistě nezmění přijímaný jazyk. Každý stav p různý od x a y nyní odstraníme spolu s jeho incidentními hranami (tj. hranami, které do p vcházejí nebo z p vycházejí) takto (viz obrázek 2.4): Necht'{E1, . . . , En} je množina všech regulárních výrazů E takových, že p E p je hrana v upravovaném přechodovém grafu. Pro každou dvojici hran r F p, kde r = p a p G q, kde p = q, přidáme hranu z r do q s ohodnocením F.(E1 + + En + ).G. Pak lze stav p spolu s incidentními hranami odstranit bez toho, aby se změnil přijímaný jazyk ( bylo k množině {E1, . . . , En} přidáno pro případ, že uvedená množina je prázdná; připomeňme {} = {}). Pokud má stav p tu vlastnost, že do něj žádná hrana nevchází, resp. z něj žádná hrana nevychází, je p z počátečního stavu x nedosažitelný, resp. nelze z něj dosáhnout koncového stavu y. V takovém případě můžeme p odstranit aniž bychom nějaké hrany přidávali ­ tato úprava přijímaný jazyk nezmění. Po odstranění všech stavů různých od x a y zůstanou tyto dva stavy spolu s konečně mnoha hranami z x do y (hrana z x do x, nebo z y do y pomocí výše uvedené transformace vzniknout nemůže). Necht' {E1, . . . , Em} je množina všech regulárních výrazů, které se na těchto hranách vyskytují. Všechny hrany pak můžeme odstranit a přidat jedinou hranu s ohodnocením E1 + + Em +. Tato úprava přijímaný jazyk rovněž nezmění. Obdržíme tak přechodový graf se dvěma stavy a jedinou hranou. Shrnutí obou předchozích vět by bylo jen zopakováním Kleeneho věty ­ viz 2.63. 2.3 Vlastnosti regulárních jazyků 2.3.1 Uzávěrové vlastnosti regulárních jazyků ­ část II Již dříve jsme ukázali, že třída regulární jazyků je uzavřena vůči sjednocení, průniku, komplementu, zřetězení a iteraci (viz část 2.2.3). Díky Kleeneho větě lze velmi snadno GFED@ABCr1 F1 99xxxxxxxxx GFED@ABCq1 GFED@ABCp G1 UUppppppppp G2 99xxxxxxxxx 34 765 E1 33 34 bb 012 E2 xx )) GFED@ABCr2 F2 UUppppppppp GFED@ABCq2 GFED@ABCr1 F1.(E1+E2+).G1 GG F1.(E1+E2+).G2 88wwwwwwwwwwwwwwwwwwwww GFED@ABCq1 GFED@ABCr2 F2.(E1+E2+).G2 GG F2.(E1+E2+).G1 VVqqqqqqqqqqqqqqqqqqqqq GFED@ABCq2 Obrázek 2.4: Eliminace stavu regulárního přechodového grafu. ukázat, že třída regulárních jazyků je uzavřena vůči operaci (regulární) substituce. Věta 2.67. Necht' je konečná abeceda a f substituce taková, že f (a) je regulární jazyk nad pro každé a . Pak pro každý regulární jazyk L je též f (L) regulárním jazykem. Důkaz: Necht' E je regulární výraz takový, že L(E) = L a Ea jsou regulární výrazy takové, že L(Ea) = f (a) pro každé a . Pokud pro každé a dosadíme do E za každý výskyt symbolu a odpovídající regulární výraz Ea, získáme opět regulární výraz, řekněmě F, a to takový, že L(F) = f (L). Formální důkaz korektnosti těchto dosazení lze provést indukcí vzhledem k počtu operátorů v regulárním výrazu, přičemž bychom vzali v potaz, že f (L1 L2) = f (L1) f (L2) a analogicky pro zřetězení a iteraci. Věta 2.68. Třída regulárních jazyků je uzavřena vůči homomorfismu a inversnímu homo- morfismu. Důkaz: Uzavřenost vůči homomorfismu okamžitě plyne z uzavřenosti vůči substituci: každý homomorfismus h je substitucí, kde každé h(a), a , je jednoprvkový jazyk. Abychom ukázali uzavřenost vůči inversnímu homomorfismu, mějme DFA = (Q, , , q0, F) takový, že L = L() a homomorfismus h z do . Zkonstruujme DFA akceptující h-1(L) tak, že čte symbol a a simuluje činnost nad h(a). Formálně = (Q, , , q0, F), kde pro všechna a a q Q definujeme (q, a) = ^(q, h(a)). Poznamenejme, že h(a) je slovo (dokonce může být i prázdné), avšak ^ jako rozšířená přechodová funkce je definována pro všechna slova. Indukcí vzhledem k délce slova x lze snadno ukázat, že ^ (q0, x) = ^(q0, h(x)), a tedy akceptuje x právě když akceptuje h(x), tj. L( ) = h-1(L()). 2.3.2 Ekvivalence konečných automatů a regulárních gramatik Na začátku této kapitoly již byla zmínka o tom, že pojem regulárního jazyka byl vlastně definován dvakrát ­ nejprve pomocí regulární gramatiky (viz část 1.2.2) a pak ještě jednou pomocí konečného automatu. V této části dokážeme, že tato nejednoznačnost je nezávadná, nebot'třídy jazyků, které lze generovat regulárními gramatikami, resp. rozpoznat konečnými automaty, jsou stejné. Začneme tím, že ukážeme, jak lze k dané regulární gramatice sestrojit ekvivalentní nedeterministický konečný automat (uvědomme si, že není podstatné, jestli jde o auto- mat deterministický, nedeterministický, nebo dokonce s -kroky, protože všechny uvedené modely jsou navzájem ekvivalentní ve smyslu vět 2.43 a 2.48). Myšlenka důkazu je jedno- duchá ­ stavy automatu budou odpovídat neterminálům gramatiky, tj. pro každý neterminál A bude existovat stav A. Pro každé pravidlo A aB přidáme do (A, a) stav B. Abychom se mohli vypořádat také s pravidly tvaru C a, zavedeme speciální koncový stav q f , který přidáme do (C, a). Počáteční stav bude S, koncový stav q f a případně také S, pokud gramatika obsahuje pravidlo S . Lemma 2.69. Ke každé regulární gramatice = (N, , P, S) existuje nedeterministický konečný automat = (Q, , , q0, F) takový, že L( ) = L(). Důkaz: Položme ˇ Q = {A | A N} {q f }, kde q f N. ˇ q0 = S. ˇ je nejmenší funkce Q × 2Q splňující: ­ Pokud A aB je pravidlo v P, pak B (A, a). ­ Pokud A a je pravidlo v P, kde a = , pak q f (A, a) ˇ F = {S, q f } pokud S je pravidlo v P, {q f } jinak. Nejprve dokážeme vztah mezi větnými formami a rozšířenou přechodovou funkcí ^: S a1 . . . ak B, kde a1, . . . , ak , B N B ^(S, a1 . . . ak), kde B = q f Důkaz provedeme indukcí vzhledem ke k: ˇ k = 0: Pak nutně B = S, B = S a obě strany dokazované ekvivalence (a tedy i ekvivalence samotná) platí. ˇ Indukční krok: Platí S a1 . . . ak+1 B S a1 . . . akC a1 . . . ak+1 B (tedy C ak+1B P) C ^(S, a1 . . . ak) (indukční předpoklad), B (C, ak+1) B ^(S, a1 . . . ak+1). Nyní lze již snadno ukázat, že w L( ) w L(). Pokud w = , platí L( ) S P S F L(). Necht'tedy w = , tj. w = va, kde v , a . Platí va L( ) S vB va (tedy B a P) B ^(S, v), q f (B, a) q f ^(S, va) va L(). Je dobré si uvědomit, že poslední ekvivalence platí proto, že nemůže akceptovat neprázdné slovo pomocí stavu S ­ pokud S F, obsahuje P pravidlo S , a tedy S se nevyskytuje na pravé straně žádného pravidla; v automatu pak do stavu S nevedou žádné přechody. Příklad 2.70. Necht' = ({S, A, B, C, D}, {a, b, c, d}, P, S), kde P obsahuje pravidla S aA | bB | C aA | cD A bC | b D aC | bB B d D | a Ekvivalentní nedeterministický konečný automat má tento tvar: WVUTPQRSA b GG b 11cccccc WVUTPQRSC a oo c GGWVUTPQRSONMLHIJKS a cc b 11cccccc WVUTPQRSONMLHIJKq f WVUTPQRSB a GG a cc WVUTPQRSD b oo d yy Způsob, kterým lze naopak ke každému konečnému automatu sestrojit ekvivalentní regu- lární gramatiku, je do určité míry ,,inverzní" ke konstrukci použité v důkazu předchozího lemmatu. Neterminály budou odpovídat stavům, pravidla budou simulovat přechodovou funkci. Je tu však jeden problém ­ pokud automat přijímá prázdné slovo (tj. počáteční stav je koncovým stavem), musí každá ekvivalentní gramatika nutně obsahovat pravidlo S , kde S je kořen. Pak se ale S nesmí vyskytovat na pravé straně žádného pravidla (viz část 1.2.2). Přitom je ale možné, že některé přechody automatu končí v počátečním stavu a mají být simulovány pravidly, které mají na pravé straně S, což by vedlo ke konfliktu s požadavkem pravostranných výsktů S. Tento problém vyřešíme tak, že ke zkonstruované gramatice (mající jak S , tak i pravostranné výskyty S) lehce nalezneme ekvivaletní gramatiku splňující (jak vidno, v případě typu 3 čistě formálních) požadavky definice z 1.2.2. Lemma 2.71. Pro každý konečný automat = (Q, , , q0, F) existuje regulární gra- matika = (N, , P, S) taková, že L() = L( ). Důkaz: Bez újmy na obecnosti předpokládejme, že je nedeterministický. Necht' ˇ N = {q | q Q}. ˇ P je nejmenší množina pravidel splňující: ­ Pokud p (q, a), je q a p pravidlo v P . ­ Pokud p (q, a) a p F, je q a pravidlo v P . Gramatika = (N , , P , q0) je zřejmě regulární, protože pravidla jsou předepsaného tvaru. Podobně jako v předchozím důkaze, tentokrát však jen pro neprázdná slova (problém s v případě q0 F vyřešíme posléze) ukažme platnost tvrzení: ^(q0, a1 . . . ak) F = , kde k 1, a1, . . . , ak q0 a1 . . . ak Indukcí vzhledem k délce akceptovaného slova, tj. ke k: ˇ k = 1: pro p F, p ^(q0, a) q0 a je pravidlo v P q0 a. ˇ Indukční krok: pro p F, platí p ^(q0, a1 . . . ak+1) existuje stav q takový, že q ^(q0, a1 . . . ak) a p (q, ak+1) q0 a1 . . . akq (podle indukčního předpokladu) a q ak+1 je pravidlo v P q0 a1 . . . ak+1. Tedy pro každé w = platí w L() w L( ). (*) Je-li q0 F, pak L(); v tomto případě L( ) = L() \ {}. Abychom obdrželi hledanou = (N, , P, S) položme N = N {S}, kde S Q a P = P {S } {S | q0 }. Přidali jsme tedy nový neterminál (je nyní kořenem) a zajistili, aby jej bylo možné přepsat na cokoliv, na co se přepisoval kořen q0 (viz poslední sčítanec v definici P). Konečně do množiny pravidel jsme přidali kýžené S . Jelikož S je nově přidaný symbol, zcela jistě se nevyskytuje na žádné pravé straně v P. Zřejmě L( ) = L( ) {} = L(). Je-li q0 / F, tj. / L(), pak stačí položit N = N , P = P a S = q0. Požadované L( ) = L() je nyní jen jiným zápisem již dokázaného tvrzení (*). Příklad 2.72. Mějme automat GGWVUTPQRSONMLHIJKq0 a GGWVUTPQRSq1 b GG a oo WVUTPQRSONMLHIJKq2 b oo Použitím algoritmu z předchozího důkazu obdržíme ekvivalentní regulární gramatiku = ({S, q0, q1, q2}, {a, b}, P, S), kde P obsahuje pravidla S aq1 | q1 aq0 | bq2 | a | b q0 aq1 q2 bq1 Okamžitým důsledkem lemmat 2.69 a 2.71 je: Věta 2.73. Třídy jazyků, které lze generovat regulárními gramatikami, resp. rozpoznat konečnými automaty, jsou si rovny. 2.3.3 Rozhodnutelné problémy pro třídu regulárních jazyků Studujeme-li nějakou třídu jazyků (generovanou jistým typem gramatik či automatů), pak je zajímavé ptát se na existenci algoritmů (tzv. rozhodnutelnost či algoritmickou řešitel- nost) jistých přirozených problémů. Máme-li dány dvě libovolné gramatiky (alternativně automaty) a uvažovaného typu, pak nejtypičtějšími obvykle jsou tyto problémy: 1. ekvivalence: jsou a ekvivaletní? Přesněji řečeno: existuje algoritmus, který pro dvě libovolné dané gramatiky a (z uvažované třídy) rozhoduje, zda jsou ekvi- valetní? Poznamejme, že obecně se nemusí jednat pouze o jazykovou ekvivalenci, tj. rovnost jazyků. 2. inkluse (jazyka): platí L( ) L( ) ? (opět ve výše uvedeném smyslu existence algoritmu ­ podobně i u všech dále uvedených problémů). Obecněji se jedná o problém tzv. simulace vzhledem k danému uspořádání. 3. příslušnost (slova k jazyku): je-li dáno libovolné slovo w , platí w L( ) ? 4. prázdnost (jazyka): je L( ) = ? 5. universalita (jazyka): je L( ) = ? ( je terminální abeceda ) 6. konečnost (jazyka): je L( ) konečný jazyk? 7. regularita (jazyka): je L( ) regulární jazyk?4 (či obecněji ­ srv. s poznámkou o ekvi- valeci v 1: existuje ke ekvivaletní regulární gramatika nebo konečný automat?) V předchozím textu jsme se již setkali s celou řadou algoritmů, které sloužili převážně pro transformaci (tj. ,,překlad") mezi různými typy popisných formalismů. Samotný pojem 4. pro regulární jazyky je tento problém rozhodnutelný triviálně, což pro ostatní třídy neplatí ,,algoritmus" ovšem nebyl nijak blíže vysvětlen ani definován; spoléhali jsme (a spoléháme) se na to, že je intuitivně jasný. Z ryze matematického hlediska je takový postup samozřejmě nepřípustný. Vše uvedeme na pravou míru v kapitole 5, kde je problematika formální definice algoritmu podrobněji rozebrána. V této části budeme přitom předpokládat, že regulární jazyky jsou reprezentovány deterministickými konečnými automaty. Věta 2.74. Problém, zda libovolný daný regulární jazyk L nad abecedou je prázdný, resp. roven , je rozhodnutelný. Důkaz: Necht' = (Q, , , q0, F) je deterministický konečný automat s totální pře- chodovou funkcí, rozpoznávající jazyk L. Zřejmě L je prázdný, právě když mezi dosažitel- nými stavy automatu není žádný prvek F; tuto podmínku lze algoritmicky ověřit, nebot' množinu dosažitelných stavů lze zkonstruovat užitím algoritmu 2.1. Dále L = , právě když co­L = . Jak již víme, je třída regulárních jazyků uzavřena na komplement: jazyk co­L je rozpoznávaný deterministickým automatem ­ viz poznámka 2.11. Stačí tedy výše uvedeným způsobem otestovat prázdnost jazyka L(). Poznámka 2.75. Tvrzení předchozí věty lze též dokázat tak, že ukážeme platnost tvrzení: Jazyk rozpoznávaný konečným automatem o n stavech je neprázdný, právě když akceptuje alespoň jedno slovo délky menší než n. K důkazu lze využít přímo lemma o vkládání, resp. úvahy uvedené v jeho důkazu. Věta 2.76. Problém, zda libovolný daný regulární jazyk L je konečný, resp. nekonečný, je rozhodnutelný. Důkaz: Necht' = (Q, , , q0, F) je deterministický konečný automat, rozpoznávající jazyk L. Označme n = card(Q). Dokážeme, že L je nekonečný, právě když akceptuje alespoň jedno slovo w s vlastností n |w| < 2n: ( ) Je-li L nekonečný, nutně obsahuje alespoň jedno slovo u délky alespoň n (de facto je takových slov samozřejmě nekonečně mnoho). Je-li |u| 2n, jsme hotovi. V opačném případě lze slovo u rozdělit na tři části u = xyz tak, že 1 |y| n a xz L (viz lemma 2.13 o vkládání). Pokud je délka slova xz stále větší než 2n, celý postup opakujeme; po konečném počtu opakování dostaneme slovo w požadovaných vlastností. ( ) Jelikož |w| n, musí automat při akceptování slova w projít dvakrát stejným stavem; slovo w lze tedy rozdělit na tři části w = xyz tak, že |y| 1 a platí xyi z L pro každé i 0 (viz důkaz lemmatu 2.13 o vkládání), tedy L je nekonečný. To, zda akceptuje alespoň jedno slovo w takové, že n |w| 2n, lze algoritmicky ověřit ­ těchto slov je konečně mnoho, můžeme tedy ,,vyzkoušet" každé z nich. Věta 2.77. Problém rovnosti libovolných daných regulárních jazyků je rozhodnutelný. Důkaz: Pro libovolné L1, L2 platí: (L1 = L2) (L1 co­L2) (co­L1 L2) = . Pro L1, L2 regulárnílze všechny uvedené operace algoritmicky realizovat (viz 2.11). Zbytek plyne z rozhodnutelnosti problému prázdnosti regulárního jazyka ( 2.74). Uvedený důkaz obsahuje i návod na konstrukci algoritmu pro rozhodování problému, zda L1 = L2. Necht' L1, L2 jsou po řadě rozpoznávány DFA 1 = (Q1, , 1, q1, F1) a 2 = (Q2, , 2, q2, F2) s totálními přechodovými funkcemi (je důležité, že oba automaty mají stejnou vstupní abecedu; tento předpoklad je bez újmy na obecnosti, nebot'v opačném případě lze abecedy sjednotit a přechodové funkce znovu zúplnit). Položme = (1 2) (1 2). Pak L1 = L2 L() = . Uvažme však, že není nutné postupovat ,,otrocky" po struktuře, jak je konstruován . Zřejmě L() = (L1 = L2) w (L1 co­L2) (co­L1 L2). Hledejme tedy množinu R dosažitelných stavů synchronního paralelního spojení automatů 1 a 2 (viz poznámka 2.11). R bude obsahovat aspoň jednu dvojici (p, q) z množiny F1 × (Q2 - F2) (Q1 - F1) × F2 právě když w (L1 co­L2) (co­L1 L2) (L1 = L2). Tedy definujme množinu R Q1 × Q2 takto: R = {(r, s) | w r = ^1(q1, w) s = ^2(q2, w)} Právě jsme tedy ukázali, že L(1) = L(2) právě když R obsahuje alespoň jednu dvojici stavů z (F1 × (Q2 - F2)) ((Q1 - F1) × F2), či ekvivaletně vyjádřeno: Lemma 2.78. L(1) = L(2) právě když R obsahuje pouze takové dvojice, ve kterých jsou obě komponenty současně bud'koncové nebo nekoncové stavy. Důkaz: Důkaz uvádíme jen pro snazší čtenářovu orientaci. Ukažme (srovnej s poznámkou 2.11 a s konstrukcí dosažitelných stavů v důkazu lemmatu 2.19), jak lze množinu R algoritmicky zkonstruovat; vyjdeme z toho, že R lze přirozeně aproximovat tak, že v její definici položíme omezení na délku slova w. Obdržíme tak systém množin Ri , kde i 0, definovaný takto: Ri = {(r, s) | w |w| i r = ^1(q1, w) s = ^2(q2, w)} Platí tedy R = i=0 Ri (2.7) Každou z množin Ri lze ovšem snadno zkonstruovat na základě induktivního předpisu: ˇ R0 = {(q1, q2)} ˇ Ri+1 = Ri {(1(r, a), 2(s, a)) | (r, s) Ri a } Označme n = card(Q1 × Q2). Jelikož Ri Ri+1 a každá z množin Ri je podmnožinou Q1 × Q2, nutně existuje k n takové, že Rk = Rk+1. Z induktivního předpisu pro Ri je vidět, že množina Rk+1 závisí pouze na množině Rk ­ proto dokonce platí Rk = Rk+ j pro libovolné j 0. Vztah 2.7 lze tedy přepsat do tvaru R = k i=0 Ri = Rk (2.8) Tím je formálně dokázána správnost i konečnost algoritmu 2.4. Algoritmus 2.4 Test rovnosti regulárních jazyků. Vstup: DFA j = (Q j , , j , qj , Fj ), j = 1, 2 s totálními j . Výstup: YES jestliže L(1) = L(2), NO jinak. i = 0; R0 = {(q1, q2)}; repeat Ri+1 = Ri {(1(r, a), 2(s, a)) | (r, s) Ri a }; if Ri+1 obsahuje dvojici (p, q), kde p F1 q F2 then return NO; end if i = i + 1; until Ri = Ri-1 return YES; Algoritmus 2.4 je ve skutečnosti mírně zoptimalizovaný; test, zda R obsahuje ,,nedovolené" dvojice, se provádí po každé iteraci a pokud uspěje, algoritmus se ihned ukončí. Alternativně lze větu 2.77 (i s implicitně obsaženým algoritmem) dokázat takto: necht'L1 a L2 jsou regulární jazyky, po řadě rozpoznávané DFA 1 a 2. Ke každému z nich lze sestrojit minimální DFA 1, resp. 2. Pak L1 = L2 právě když 1 a 2 jsou isomorfní (liší se jen pojmenováním stavů). Ověření tohoto isomorfismu, jako isomorfismu dvou přechodových grafů s konečně mnoha stavy (uzly), je jistě algoritmicky realizovatelné, či jinak řečeno rozhodnutelné. Tím je důkaz ukončen. Abychom však výše zmíněný isomorfismus nemuseli ověřovat zkoumáním všech možností, je vhodné si uvědomit, že každý automat (a tedy i 1 a 2 z výše uvedeného důkazu) lze převést do jistého standardizovaného (tzv. kanonického) tvaru. Můžeme totálně uspořádat vstupní abecedu = {a1, . . . am}, ai =<89:;E zzuuuuuuu 66sssssss ?>=<89:;E ?>=<89:;+ ?>=<89:;T ?>=<89:;T ?>=<89:;F ?>=<89:;F ?>=<89:;i ?>=<89:;i reprezentuje deset vzájemně ekvivalentních derivací, například 1. E E + T T + T F + T i + T i + F i + i nebo 2. E E + T E + F E + i T + i F + i i + i a též 3. E E + T T + T T + F F + F F + i i + i a další. Všimněme si, že 1 je levá, kdežto 2 je pravá derivace. Věta 3.3. Necht' = (N, , P, S) je CFG. Pak pro libovolné (N ) platí S právě když v existuje derivační strom s výsledkem . Důkaz: Je-li = (N, , P, S) CFG a A N, definujmeme A def = (N, , P, A), tj. gra- matiku s týmiž pravidly jako , která však má kořen A. Důkaz povedeme tak, že nejprve ukážeme silnější tvrzení: A N. (A v A existuje derivační strom s výsledkem ). (*) Tvrzení věty pak obdržíme specializací A = S. I. ( ) Předpokládejme, že je výsledkem derivačního stromu, který má k vnitřích uzlů a indukcí vzhledem ke k ukažme, že pak A . 1. k = 1. Existuje-li ve stromu jediný vnitřní uzel, A xxrrrrrrr 88vvvvvvv X1 . . . Xn pak pro = X1 . . . Xn z definice derivačního stromu plyne, že A P. 2. k > 1. Předpokládejme (IP), že dokazované tvrzení platí pro stromy, které mají nanejvýš k - 1 vnitřních uzlů. Necht' je výsledkem stromu s k vnitřními uzly. Následníci kořene (označme je 1, . . . n) nejsou jen samé listy (mimo kořen zde musí být jestě aspoň jeden vnitřní uzel, protože k > 1) a necht'jejich návěští jsou v uspořádání zleva po řadě X 1 . . . Xn. Pak jistě A X1 . . . Xn P. Nyní: (a) Je-li i vnitřím uzlem, pak je současně kořenem nějakého podstromu Ti a Xi N. Ti mající nejvýše k - 1 vnitřních uzlů je stromem v Xi a jeho výsledkem je i . Dle IP je Xi i . (b) Je-li i listem, pak Xi = i (tedy triviálně Xi i ). Zřejmě = 1 . . . n, a tedy celkem dostáváme A X1 X2 . . . Xn 1 X2 . . . Xn ( dle IP, je-li X1 N; triv. pro X1 ) ... 12 . . . n-1 Xn ( dtto ) 12 . . . n = tj.A A rrddddddddddddddddddddddddddddddddddddddddd sshhhhhhhhhhhhhhhhhhhhhhhhhhh @@ X1 X2 00aaaaaaaa . . . . . . Xn-1 Xn ~~~~~~~~~ 11ddddddddd T2 Tn-1 II. ( ) Předpokládejme, že A a máme ukázat,že v A existuje derivační strom s výsledkem . Tentokrát použijeme indukci vzhledem k délce odvození A . 1. Je-li A , tj. v jednom kroku, pak A P a z definice derivačního stromu dostáváme existenci stromu s výsledkem . 2. Předpokládejme (IP), že je-li A v méně než k krocích, pak v A existuje derivační strom s výsledkem (IP). Necht'tedy A v k krocích a necht'1. krok je tvaru A X1 . . . Xn. Zřejmě každý symbol v je bud'některé z X1 . . . Xn nebo je symbolem v řetězu odvoditelného z některého z nich, a to v méně než k krocích (dle IP platí pro něj dokazované tvrzení). Dále, ta část , která je odvoditelná z Xi leží vlevo od té části , která je odvoditelná z X j pro i < j. Můžeme tedy psát = 1 . . . n, kde Xi i a označme takový podstrom Ti . Hledaný derivační strom nyní zkonstruujeme takto: začneme s konstrukcí odpovída- jící prvnímu kroku odvození, tj. A X1 . . . Xn a dostaneme A xxrrrrrrr 88vvvvvvv X1 . . . Xn a dále každé Xi nahradíme stromem Ti (je-li Xi terminál, je náhrada triviální ­ nic nena- hrazujeme). Výsledkem takto vzniklého stromu je zřejmě . Tím jsme dokázali tvrzení (*); tvzení věty obdržíme (specializací) tak, že v (*) položíme A = S ( S = ). Specielně tedy pro terminální řetěz w platí, že w L( ) právě když v existuje derivační strom s výsledkem w. Není těžké ukázat, že každému derivačnímu stromu v CFG odpovídá jediná levá derivace a obráceně, každé levé derivaci odpovídá jediný derivační strom. (Například v důkazu předchozí věty byla k derivačnímu stromu s kořenem A a výsledkem nalezena levá derivace větné formy z A za předpokladu, že každá z Xi i byla levou derivací.) Analogické tvrzení platí o vzájemně jednoznačné korespondenci mezi derivačními stromy a pravými derivacemi (a tedy i mezi levými a pravými derivacemi). Každý, kdo programuje v jazyce Pascal, jistě ví, že existují CF gramatiky, v nichž má jedna věta či větná forma několik různých derivačních stromů. Příklad 3.4. Mějme gramatiku s pravidly S if b then S else S | if b then S | a Pak například věta if b then if b then a else a má dva různé derivační stromy, které odpovídají interpretaci if b then (if b then a) else a resp. if b then (if b then a else a). Zkonstruujte oba stromy! Definice 3.5. CFG se nazývá víceznačná (nejednoznačná) právě když existuje w L( ) majícíalespoň dva různé derivačnístromy. V opačném případě říkáme, že je jednoznačná. Jazyk L se nazývá vnitřně (inherentně) víceznačný právě když každá gramatika, která jej generuje, je víceznačná. Příklad 3.6. Gramatika 1 s pravidly E E + E | E E | (E) | i , která je ekvivaltní s gramatikou 0 z příkladu 3.2, je víceznačná; například proto, že věta i + i + i má dvě různé levé derivace a jim odpovídající dva různé derivační stromy: E yyssssss 77uuuuuu E yyssssss 77uuuuuu E yyssssss 77uuuuuu + E E + E yyssssss 77uuuuuu E + E i i E + E i i i i Nejednoznačnost gramatiky může v některých praktických aplikacích působit jisté obtíže: pokud nalezení derivačního stromu věty (například zdrojového textu programu) je základem pro stanovení významu věty, vznikl by v případě nejednoznačné gramatiky problém, který z těchto významů zvolit (nehledě k nárůstu časové i pamět'ové složitosti spojené s hledáním všech derivačních stromů). Ke gramatice 1 z příkladu 3.6 lze zkonstruovat ekvivaletní jednoznačnou gramatiku 2 s pravidly například E E + T | E T | T ; T (E) | i . Všimněme si však, že 0 z příkladu 3.2, na rozdíl od 2, umožňuje postihnout (již na syntaktické úrovni) asociativitu tak, aby reflektovala i obvyklou prioritu operátorů, tj. že váže silněji než +; věta i + i i by v 2 byla asociována zleva jako (i + i) i. Poznamejme, že ne vždy lze k dané gramatice (resp. jazyku) nalézt ekvivaletní gramatiku, která by byla jednoznačná. Takovým vnitřně víceznačným jazykem je například L = {ai bj ck| i = j nebo j = k}. Intiutivně řečeno, každá gramatika generující L musí být schopna vytvářet jistou sadou pravidel jak slova spňující i = j, tak i jinou sadou pravidel slova s j = k, a tudíž nelze zabránit tomu, aby aspoň některá ze slov ai bi ci , tj. i = j = k nebyla generovatelná oběma různými způsoby. Jak ukážeme později, bohužel ani pro problém, zda libovolná daná CFG je (ne)jednoznačná neexistuje algoritmus. 3.1.2 Transformace bezkontextových gramatik Jak jsme již naznačili v závěru minulé sekce, bývá často výhodné modifikovat danou gra- matiku tak, aby vytvářela takovou stukturu vět z L( ), která by zajistila splněníněkterých kýžených vlastností jazyka či gramatiky. Mimo již zmíněné asociativity a jednoznačnosti je těchto vlastností (a jim korespondujících transformací) gramatik celá řada. Definice 3.7. Ř ekneme, že symbol X N je nepoužitelný v CFG = (N, , P, S) právě když v neexistuje derivace tvaru S wXy wxy pro nějaká w, x, y . Ř ekneme, že je redukovaná, jestliže neobsahuje žádné nepoužitelné symboly. Poznámka 3.8. Povšimněme si, že výše uvedená definice postihuje nepoužitelnost dvojího druhu: neexistence první části uvedené derivace říká, že symbol X N se nevyskuje v žádné větné formě (jedná se o tvz. nedosažitelný symbol), kdežto neexistence druhé části zmíněné derivace vyjadřuje skutečnost, že z neterminálu X nelze vyderivovat žádný terminální řetěz (tzv. nenormovaný, někdy též redundatní neterminál 1). Poznamejme ještě, že existence obou zmíněných derivací ještě není postačující podmínkou pro použitelnost symbolu: X se může totiž objevit jen v takové větné formě, která obsahuje nenormovaný neterminál. Pokud z nepoužitelné symboly vypustíme, pak se L( ) zřejmě nezmění. Ř ešme nejprve druhý z těchto problémů, tj. zda {w |A w} = . Pokud pro tento problém nalezneme algoritmus, pak jeho existence implikuje (položením A = S) existenci algoritmu pro problém zda L( ) = , či nikoli. Věta 3.9. Algoritmus 3.1 "Je L( ) neprázdný?" vrací "ANO" w . S w. 1. Normou neterminálu A obvykle rozumíme délku nejkratšího terminálního řetězu odvoditelného z A, pokud taková derivace existuje Algoritmus 3.1 Je L( ) neprázdný? Vstup: CFG = (N, , P, S). Výstup: "ANO" je-li L( ) = ; "NE" v ostatních případech Dle následujících kroků konstruuj induktivně množiny N0, N1, . . . takto: i = 0; N0 = ; (* inicializace *) (1) repeat i = i + 1; (* iterace *) (2) Ni = Ni-1 {A|A P, (Ni-1 )} (3) until Ni = Ni-1; (* test ukončení *) (4) Ne = Ni ; (5) if S Ne then output("ANO") else output("NE"). (6) Důkaz: Poznamejme, že každá Ni je definována jako množina neterminálů, které lze v nejvýše i krocích přepsat na řetěz terminální. Dokažme nejprve (opět) obecnější tvrzení: A Ne w .A w. (*) I.( ) A Ne i. A Ni . Indukcí dokažme tvrzení: i. A Ni w . A w 1. i = 0 : platí triviálně, protože N0 = . (viz řádek (1) v Algoritmu 3.1) 2. i > 0 (IP): Předpokládejme, že dokazované tvrzení platí pro i. Necht'nyní A Ni+1: ˇ je-li A rovněž prvkem z Ni , pak tvrzení plyne přímo z (IP). ˇ je-li A Ni+1 \ Ni , pak existuje A X1 . . . Xk P, kde každé X j (1 j k) je bud'terminál, nebo neterminál patřící do Ni (viz řádek (3)). Tedy existují w j tak, že X j wj pro všechna j 1, k , wj (je-li X j , pak wj = X j , jinak existence wj plyne z (IP)). Tedy celkem A X1 . . . Xk w1 X2 . . . Xk . . . w1 . . . wk, w1 . . . wk II. ( ) Definice množin Ni zajišt'uje, že pokud nastane Ni = Ni-1, pak platí Ni = Ni+1 = . Máme ukázat, že pokud A w pro nějaké w , pak A Ne, přičemž na základě předchozí poznámky stačí ukázat, že A Ni pro nějaké i. Tedy indukcí dokažme: A n w, w A Ni pro nějaké i 1. n = 1, tj. A w, w okamžitě dává i = 1 (viz řádek (3) v Algoritmu 3.1). 2. n > 1 (IP): Předpokládejme, že dokazované tvrzení platí pro všechna n a necht'nyní A n+1 w. Pak zřejmě tuto derivaci lze rozepsat do tvaru A X1 . . . Xk n w, kde w = w1 . . . wk takové, že X j n j wj pro všechna j a kde n j n. Pak dle (IP) je-li X j N, potom X j Ni j pro nějaké i j . Je-li X j , necht'i j = 0. Položme i = 1 + max{i1, . . . , ik}. Pak zřejmě A Ni , čímž je důkaz indukcí ukončen. Položíme-li A = S v právě dokázaném tvrzení (*), dostáváme tvrzení věty. Poznamejme, že jsme právě dokázali, že pokud algoritmus 3.1 zastaví, pak dává koretkní odpověd. Důkaz, že algoritmus musí skončit, a to nejpozději po n + 1 iteracích (pro n = card(N)), plyne okamžitě z faktu, že Ne N ­ viz monotonie Ni vzhledem k inklusi (během iterace platí Ni-1 Ni ) a tvaru testu ukončení. Celkem tedy máme: Důsledek 3.10. Existuje algoritmus, který pro libovolnou danou CFG rozhoduje, zda L( ) = . K eliminaci nepoužitelných symbolů musíme ještě umět odstranit nedosažitelné symboly (viz Poznámka 3.8). Tuto činnost provádí Algoritmus 3.2. Algoritmus 3.2 Eliminace nedosažitelných symbolů Vstup: CFG = (N, , P, S). Výstup: CFG = (N , , P , S) bez nedosažitelných symbolů: L( ) = L( ) Dle následujících kroků konstruuj induktivně množiny V0, V1, . . . takto: i = 0; Vi = {S}; (* inicializace *) (1) repeat i = i + 1; Vi = Vi-1 {X|A.(A X P A Vi-1)} (* iterace *) (2) until Vi = Vi-1; (* test ukončení *) (3) N = N Vi ; = Vi ; P = P (Vi × V i ) (4) Ke korektnosti algoritmu 3.2 zbývá uvážit, že jeho ukončení je implikováno faktem, že Vi N , a tedy iteraci (2) ­ (3) lze provést jen konečně mnohokrát. Důkaz, že při skončení neobsahuje nedosažitelné symboly spočívá v ukázání, že S X i. X Vi (indukcí vzhledek k i). Formální důkaz je ponechán čtenáři jako cvičení. Nyní jsme v situaci, kdy můžeme prezentovat algoritmus 3.3, který odstraňuje z CFG nepoužitelné symboly. Algoritmus 3.3 Eliminace nepoužitelných symbolů Vstup: CFG = (N, , P, S) taková, že L( ) = . Výstup: CFG = (N , , P , S) bez nepoužitelných symbolů: L( ) = L( ) Použij algoritmus 3.1 se vstupem a s výstupem Ne; (1) Polož 1 = (N Ne, , P1, S), kde P1 = P (Ne × (Ne )); Použij algoritmus 3.2 se vstupem 1; výstupem je = (N , , P , S) (2) Krok (1) algoritmu 3.3 odstraňuje z všechny neterminály, které nemohou vygene- rovat terminální řetěz, krok (2) odstraní nedosažitelné symboly, tj. každý X N se musí vyskytnout alespoň jednou v nějaké derivaci tvaru S wXy wxy. Konečně poznamenejme, že záměna pořadí kroků (1) a (2) obecně nevede k cíli (proč?). Věta 3.11. Každý neprázdný CFL je generován nějakou redukovanou CFG (tj. CFG bez nepoužitelných symbolů). Důkaz: Necht'L = L( ) je neprázdný CFL a necht' 1 a jsou, jak uvedeno v algoritmu 3.3. Zřejmě L( ) = L( ) (kompozice transformací zachovávajích ekvivalenci). Předpokládejme, že má nepoužitelný symbol X. Pak ovšem v existuje derivace S X (viz krok (2)). Jelikož všechny symboly z jsou též v 1, pak (viz krok (1)) pro nějaký terminální řetěz platí S X w, a tedy žádný symbol z derivace X w není krokem (2) eliminován. Tedy z X lze v odvodit terminální řetěz, což vede ke sporu s předpokladem, že X je nepoužitelný. Příklad 3.12. Necht' má pravidla {S a|A, A AB, B b} a aplikujme na ni algoritmus 3.3. Po kroku (1) máme Ne = {S, B}, takže 1 = ({S, B}, {a, b}, {S a, B b}, S); po kroku (2) obdržíme V2 = V1 = {S, a}, a tedy = ({S}, {a}, {S a}, S}. Poznamenejme, že pokud bychom na použili nejprve krok (2), tj. algoritmus 3.2, shledali bychom, že všechny symboly jsou dosažitelné ­ by se vůbec nezměnila. Následná aplikace kroku (1) by dala Ne = {S, B}, a tudíž bychom celkem dostali 1 a nikoli . Nyní se budeme zabývat eliminací pravidel tvaru A , tzv. -pravidly. Pokud však L( ) obsahuje , pak zřejmě nelze eliminovat z všechna -pravidla. Definice 3.13. Ř ekneme, že CFG = (N, , P, S) je bez -pravidel def bud' 1. P neobsahuje žádné -pravidlo (tj. pravidlo tvaru A ) nebo 2. v P existuje právě jedno -pravidlo S a S se nevyskytuje na pravé straně žádného pravidla z P. Algoritmus 3.4 Eliminace -pravidel Vstup: CFG = (N, , P, S) Výstup: CFG = (N , , P , S ) bez -pravidel: L( ) = L( ) Zkonstruuj N = {A N|A } (* analogicky jako Ne z algoritmu 3.1 *); (1) Množinu pravidel P zkonstruuj takto: for all A X1 . . . Xn P do přidej do P všechna pravidla tvaru A 1 . . . n z P splňující tyto podmínky: (2) (a) pokud Xi / N (*tj. Xi *), pak i = Xi ; (3) (b) pokud Xi N (*tj. Xi *), pak i je bud'Xi , nebo ; (4) (c) ne všechna i jsou ; (* tj. nepřidávej pravidlo A *) (5) end for if S N (6) then přidej do P pravidla S S| (S / N ); N = N {S } (7) else N = N; S = S (8) Věta 3.14. Výstupní CFG z algoritmu 3.4 je bez -pravidel a L( ) = L( ) . Důkaz: Snadno se nahlédne, že je bez -pravidel ­ viz řádek (5). Abychom ukázali, že L( ) = L( ) , lze ukázat, že A w v w = A w v Důkaz, který je ponechán čtenáři do cvičení, se vede indukcí vzhledem k délce derivace A i w v pro část ` '; analogicky pro obrácenou implikaci. Požadovanou jazykovou ekvivalenci pro neprázdná slova obdržíme položením A = S ve výše uvedeném tvrzení; fakt, že L( ) L( ) je zřejmý z řádků (6) ­ (8). Další užitečnou transformací může být odstranění pravidel A B, (A, B N), která nazýváme jednoduchá pravidla. Algoritmus 3.5 Eliminace jednoduchých pravidel Vstup: CFG = (N, , P, S) bez -pravidel Výstup: CFG = (N, , P , S) bez jednoduchých a -pravidel: L( ) = L( ) for all A N do zkonstruuj NA = {B N|A B} takto (* opět: srv. s V0, V1, . . . z alg. 3.2*): i = 0; Ni = {A}; (* inicializace: reflexivita *) (1) repeat i = i + 1; (* iterace: transitivita *) (2) Ni = Ni-1 {C|B C P, B Ni-1} (3) until Ni = Ni-1; (* test ukončení *) (4) NA = Ni ; (5) end for Množinu pravidel P konstruuj takto: for all B P, které není jednoduché do přidej do P pravidla A pro všechna A taková, že B NA (6) end for Příklad 3.15. Mějme gramatiku 0 z příkladu 3.2 s pravidly: E E + T | T T T F | F F (E) | i Po skončení 1. cyklu (řádky (1) ­ (5)) dostaneme NE = {E, T, F}, NT = {T, F}, NF = {F}, což po skončení 2. cyklu (ř. (6)) dává výstupní gramatiku bez jednoduchých pravidel: E E + T | T F | (E) | i T T F | (E) | i F (E) | i Věta 3.16. Gramatika z algoritmu 3.5 je bez jednoduchých pravidel a L( ) = L( ) . Důkaz: Množina pravidel P je evidentně konstruována tak, že neobsahuje jednoduchá pravidla ­ viz řádek (6). Nejprve ukažme, že L( ) L( ). Mějme tedy w L( ) , tedy v existuje derivace S = 0 1 . . . n = w. Bylo-li při kroku i i+1 použito v pravidlo A , pak existuje nějaké B NA (s možností A = B) takové, že v je A B a B , a tedy i A a i i+1 v . Odtud již snadno dostaneme, že v existuje derivace S w, tj. w L( ). Abychom ukázali platnost obrácené inkluse, tj. L( ) L( ) , zvolme libovolné w L( ). Pak v existuje levá derivace S = 0 1 . . . n = w. Pak lze nalézt posloupnost indexů i1, . . . , ik složenou výhradně z j takových, že v j-1 j nebylo použito jednoduchého pravidla (zejména derivace věty nemůže končit jednoduchým pravidlem, a proto ik = n). Protože se jedná o levou derivaci, pak opakované použití jednoduchých pravidel nahrazuje neterminály na téže pozici v uvažované levé větné formě. Odtud vidíme, že v je možná derivace S = 0 i1 . . . ik = w, tj. w L( ) . Celkem tedy máme žádané L( ) L( ). Definice 3.17. CFG = (N, , P, S) se nazývá necyklická, právě když neexistuje A N takový, že A + A. se nazývá vlastní, právě když je bez nepoužitelných symbolů, bez -pravidel a necyklická. A-pravidlem nazveme každé pravidlo tvaru A . Věta 3.18. Ke každému CFL existuje vlastní CFG, která jej generuje. Důkaz: Použitím výše uvedených algoritmů 3.3, 3.4 a 3.5 a odpovídajích tvrzení o jejich korektnosti. V dalším textu předpokládáme, že každá CFG je bez nepoužitelných symbolů a pokud nebude řečeno jinak, pak i vlastní. 3.1.3 Chomského normální forma, lemma o vkládání V této části nejprve ukážeme, že ke každé CFG existuje ekvivalení CFG v jistém speciálním tvaru, který je charakterizován zejména tím, že na pravých stranách pravidel vystačíme se dvěma výskyty neterminálů (přesná definice viz 3.19). Na základě tohoto tvrzení budeme schopni dokázat tzv. lemma o vkládání (obecně též známé jako pumping lemma) pro CFL, které nám umožní v některých případech dokázat, že daný jazyk není CFL. Definice 3.19. Ř ekneme, že CFG = (N, , P, S) je v Chomského normální formě (CNF) def je bez -pravidel (viz def. 3.13) a každé pravidlo z P má jeden z těchto tvarů: 1. A BC, B, C N nebo 2. A a, a K důkazu tvrzení, že každý CFL je generovatelný nějakou CFG v CNF použijeme algoritmu 3.6; k důkazu jeho korektnosti využijeme následující lemma o substituci. Lemma 3.20. (o substituci) Necht' = (N, , P, S) je CFG. Necht'A 1 B2 P je pravidlo a B 1 | . . . |r jsou všechna B-pravidla z P. Necht'dále 1 = (N, , P1, S), kde P1 = (P \ {A 1 B2}) {A 112 | . . . |1r 2}. Pak L( ) = L( )1. Důkaz: Zřejmě L( )1 L( ), protože pokud je v derivaci v 1 použito nějaké pravidlo A 1i 2, pak v lze použít A 1 B2 1i 2. K důkazu L( ) L( )1 stačí uvědomit si, že A 1 B2 je jediné pravidlo, které je v a není v 1. Tedy kdykoli je v nějaké derivaci věty v toto pravidlo použito, pak neterminál B musí být přepsán Algoritmus 3.6 Transformace do CNF Vstup: Vlastní CFG = (N, , P, S) bez jednoduchých pravidel Výstup: CFG = (N , , P , S) v CNF: L( ) = L( ) P je tvořena takto: P = ; for all p P do if pravidlo p je tvaru A a nebo A BC nebo S then přidej p do P ; (1) if p = A X1 X2, kde aspoň jedno z Xi (i = 1, 2) je terminál then (2) polož Xi def = Xi , je-li Xi N nový neterminál, je-li Xi (3) a do P přidej pravidlo A X1 X2 ; (4) if p = A X1 . . . Xk, k > 2 then (5) polož Xi def = Xi , je-li Xi N nový neterminál, je-li Xi (1 i k) (6) a do P přidej pravidla A X1 X2 . . . Xk X2 . . . Xk X2 X3 . . . Xk ... Xk-2 . . . Xk Xk-2 Xk-1 Xk Xk-1Xk Xk-1 Xk (7) kde každé Xi . . . Xk je nový neterminál end for for all neterminál tvaru a nově zavedený v ř. (3) nebo (6) do do P přidej pravidla a a (8) end for N = N {všechny nově zavedené neterminály tvaru a nebo tvaru Xi . . . Xk } (9) v některém z pozdějších kroků derivace v 1 pomocí nějakého B-pravidla, tj. B i . Tyto dva kroky odvození v lze v gramatice 1 nahradit jedním krokem A 1i 2. Věta 3.21. Necht'L je CFL. Pak L = L( ) pro nějakou CFG v CNF. Důkaz: Bez újmy na obecnosti předpokládejme, že L je generován nějakou CFG , která je vlastní a bez jednoduchých pravidel, a tedy splňuje požadavky kladené na vstupní gramatiku algoritmu 3.6. Inspekcí tohoto algoritmu snadno zjistíme, že výstupní gramatika splňuje požadavky CNF. Zbývá tedy ukázat, že L( ) = L( ). Opakovaně použijme lemma o substituci (viz 3.20) nejprve na každé pravidlo v obsahující nově zavedený neterminál a a následně též na každé pravidlo s neterminálem tvaru Xi . . . Xk . Takto obdržíme původní gramatiku . Vzhledem k tomu, že jsme opakovaně použili pouze lemma o substituci, které zachovává ekvivalenci gramatik, pak tedy i a jsou ekvivaletní. Příklad 3.22. Mějme s pravidly S aAB | B A A BBB | a B aS | AS | b Do množiny pravidel P hledané gramatiky v CNF nejprve přidáme pravidla, která již požadavky CNF splňují, tj. S B A, A a, B AS | b (viz řádek (1) v algoritmu 3.6) V dalším kroku (viz ř. (2)) procházíme pravidla s pravou stranou délky 2 obsahující alespoň jeden terminál: do P tedy přidáme B a S, kde a je nový neterminál. Po tomto kroku máme zpracována všechna pravidla s délkou pravé strany nejvýše 2. Následující krok (viz řádky (5) ­ (7)) prochází pravidla s délkami pravých stran vět- šími než 2 a do P tedy díky pravidlu S aAB postupně přidáme S a AB , AB AB a díky pravidlu A BBB přidáme A B BB , BB BB. Konečně v kroku (8) do P přidáme pro všechny nově zavedené "čárkované" neter- minály pravidla, která je přepisují na původní terminály, tj. do P přidáme a a. Poznámka 3.23. (O derivačních stromech gramatik v CNF) Uvědomme si, že (i) z každého uzlu derivačního stromu gramatiky v CNF vychází nejvýše 2 hrany a (ii) z uzlu vychází jedna hrana právě když tato vchází do listu ­ pokud bychom z takového stromu odstranili listy (a hrany do nich vcházející), obdrželi bychom binární strom, v němž platí, že pokud každá cesta má délku (tj. počet hran na této cestě) rovnu j, pak strom má 2 j listů. Pro stromy odvození v CNF je však počet listů roven počtu jejich přímých předchůdců ­ viz (ii). Pokud tedy strom v CNF nemá žádnou cestu delší než j, pak má nejvýše 2 j-1 listů. Věta 3.24. (Lemma o vkládání, pumping lemma pro CFL) Necht'L je CFL. Pak existují přirozená čísla p, q (závisející na L) taková, že každé slovo z L, |z| > p lze psát ve tvaru z = uvwxy, kde ˇ alespoň jedno ze slov v, x je neprázdné (tj. vx = ), ˇ |vwx| q a ˇ uvi wxi y L pro všechna i 0. Idea důkazu: Mějme v CNF. Díky poznámce 3.23 víme, že pokud zvolíme slovo z "dostatečně dlouhé", pak v derivačním stromu musí být "dost dlouhá" cesta. Zvolme tedy z tak dlouhé, aby v jeho derivačním stromu byla tak dlouhá cesta, že se na ní některý (tj. alespoň jeden) neterminál, řekněme A, musívyskytnout alespoň dvakrát (viz též obrázek 3.1). Tedy A se musí (díky výskytu, který je zmíněné cestě blíže k listu) přepsat na nějaký terminální řetěz, řekněme w (tj. A w). Rovněž však se A musí (díky výskytu, který je téže cestě blíže ke kořenu) přepsat na řetěz opět obsahující sebe sama, řekněme vAx (tj. A vAx); toto přepisování můžeme libovolněkrát opakovat (též i 0-krát). Vždy obdržíme korektní odvození nějakého slova z L( ). Neprázdnost alespoň jednoho z v či x je zajištěna tím, že CFG v CNF nemá -pravidla. Konečně si uvědomme, že na dosti dlouhé cestě se může vyskytnout celá řada několikrát se opakujících neterminálů. Můžeme však A zvolit tak, aby oba jeho výše zmíněné výskyty nebyly "příliš daleko" od listu, tj. tak, aby úsek vwx nebyl příliš dlouhý. Důkaz: Necht' L je generován nějakou CFG = (N, , P, S), která je (bez újmy na obecnosti) v CNF. Označme k = card(N) a položme p = 2k-1, q = 2k. Je-li z L, |z| > p, pak v libovolném derivačním stromu slova z existuje cesta délky větší než k ­ viz poznámka 3.23 o derivačních stromech gramatik v CNF. Zvolme pevně jeden takový derivační strom T a v něm (libovolnou) nejdelší cestu C, která má jistě délku větší než k. Na této cestě C lze zvolit tři uzly u1, u2, u3 s těmito vlastnostmi: 1. uzly u1, u2 jsou označeny týmž neterminálem, řekněme A, 2. u1 leží blíže ke kořenu než u2, 3. u3 je list a 4. cesta z u1 do u3 má délku nejvýše k + 1. Uzel u1 určuje v T podstrom T1 s kořenem u1, tedy výsledek podstromu T1 je podslovem v z, které je výsledkem stromu T ; tj. existuje derivace S uAy pro nějaká u, y (1) a podobně u2 určuje v T podstrom T2 s kořenem u2, přičemž T2 je podstromem stromu T1 ­ viz obrázek 3.1. S A A u1 u2 u v w x y u3 Obrázek 3.1: Derivační strom s cestou C se dvěma výskyty neterminálu A Strom T1 odpovídá (levé) derivaci nějakého slova z1, přičemž z1 má délku nejvýše 2k (viz vlastnost 4 a pozn.3.23 ­ každá cesta v T1 má délku nejvýše k + 1: kdyby v T1 existovala od u1 k nějakému u4 cesta delší, pak by i v T byla cesta delší než je zvolená C, a to by byl spor s předpokladem o volbě C jako cesty s největší délkou). Jistě tedy platí |z1| 2k = q. Strom T2 též odpovídá derivaci nějakého slova, označme jej w. Jelikož T2 je pod- stromem ve stromu T1, musí být w podslovem slova z1, tj. existují řetězy v, x takové, že lze psát z1 = vwx, což spolu s již ukázaným |z1| 2k = q dává žádané |vwx| q. Dále si uvědomme, že u1 je vnitřním uzlem, a tedy mu odpovídá aplikace pravidla tvaru A BC, a tedy alespoň jedno ze slov v, x je neprázdné (CFG v CNF je bez -pravidel), tj. vx = . Současně jsme též ukázali, že A vAx a (2) A w (3) Nyní použijme jedenkrát derivaci (1), pak i-krát (i 0) derivaci (2) a nakonec derivaci (3), tj. S uAy uvi Axi y uvi wxi y tedy uvi wxi y L( ). Všimněme si, že derivace ad (2) umožňuje náhradu, kdy v T místo podstromu T2 opakovaně (i-krát) vložíme podstrom T1 s kořenem označeným týmž A ­ takto získáme opět korektní derivační strom; derivace (3) umožňuje (mimo jiné) místo T1 použít přímo T2 ­ odpovídá situaci pro i = 0. Explicitněji (z hlediska kvantifikace) lze tvrzení lemmatu 3.24 přepsat takto: (Necht') L je CFL p, q . z L. |z| > p . u, v, w, x, y. z = uvwxy vx = |vwx| q . i 0. uvi wxi y L Uvědomme si, že lemma o vkládání je (opět) pouze podmínkou nutnou k tomu, aby L byl CFL. Zopakujme, že i toto lemma je ­ stejně jako PL pro regulární jazyky ­ tvaru implikace P Q, kde P je nyní výrok, že L je CFL a Q jsou uvedené vlastnosti; této implikace (resp. v kontrapositivní formě ekvivaletní implikace Q P), lze použít k důkazu, že nějaký jazyk L není CFL, nikoli však obráceně, tj. k důkazu, že L je CFL. Čtenáři doporučejeme, aby si Q explicitně vyjádřil. Poznámka 3.25. Všimněme si, že pokud ve výše uvedeném lemmatu 3.24 namísto konstant p, q budeme všude psát jen (jedinou) pumpovací konstantu n, tvrzení zůstane v platnosti: v důkazu stačí položit p = q = 2k, kde k = card(N). Příklad 3.26. Ukažme, že jazyk L = {ai bi ci | i 1} není CFL. Náš postup bude tento: předpokládejme opak, tj. P L je CFL a dokazujme Q P. 1. Necht'n je libovolná konstanta z poznámky 3.25 (či první konstanta z lemmatu 3.24 a p = q = n). 2. Zvolme nyní slovo z (v závislosti na n ­ pro každé n musí existovat takové z) a 3. uvážíme všechny možnosti, jak jej zapsat jako z = uvwxy tak, aby splňovalo pod- mínky lemmatu (vx = , |vwx| n); 4. následně pak ukažme, že pro každé takové rozdělení z na u, v, w, x, y lze nalézt (existuje) takové i, že napumpováním získáme uvi wxi y L. Dle 1 necht'n je libovolné; zvolme (viz 2) z = anbncn a dále postupujeme podle 3 a 4. Pokud by v obsahovalo kladný počet symbolů a a kladný počet symbolů b, pak napumpované uv2wx2 y L, protože po nějakém výskytu b by následoval výskyt a, tj. uv2wx2 y abc. Podobně postupujeme ve všech ostatních případech, kdy v nebo x obsahují nenulový počet výskytů (alespoň) 2 různých znaků. Uvažme proto zbývající možnosti, kdy v patří do a nebo b nebo c a též x obsahuje jen samé stejné znaky, přičemž alespoň jedno ze slov v, x je neprázdné. Je-li v a+ a x b, pak uv2wx2 y obsahuje více symbolů a než symbolů c, tj. uv2wx2 y L. Podobně dojdeme ke sporu při všech ostatních možných volbách: protože vx obsahuje aspoň jeden výskyt symbolu d s možností výskytu jiného symbolu e, nezbývá žádná možnost pro výskyt třetího symbolu f (pro d, e, f {a, b, c} vzájemně různé ), a tedy uv2wx2 y bude mít vždy více výskytů symbolu d než výskytů symbolu f . Jak již víme, pro porozumění formuli s větším počtem kvantifikátorů je vhodné na ni nahlížet jako na hru dvou hráčů (viz též pumping lemma pro regulární jazyky), kde kvantifikátoru odpovídá hráč Al a je reprezentován hráčem Ex. Necht'tedy L je jazyk, pak hra (ve variantě p = n = q) probíhá takto: ˇ Ex zvolí přirozené číslo n ˇ Al zvolí z L takové, že |z| n ˇ Ex zvolí u, v, w, x, y tak, aby platilo z = uvwxy, |vwx| n a vx = ˇ Al zvolí i Pokud Al zvolí i tak, že uvi wxi y L, pak vyhrává Al. Pokud Al může vždy vyhrát bez ohledu na to, jak hraje Ex (má vyhrávající strategii), pak L není CFL. Pokud však Al prohraje (at' už vždy či jen někdy), pak z pumping lemmatu nelze o L odvodit nic korektního. Příklad 3.27. Jiným příkladem jazyka, který není CFL, je L = {ai bj ci d j | i, j 0}. Abychom to ukázali, předpokládejme, že L je CFL. Jelikož chceme dospět ke sporu, hrajeme roli hráče Al. ˇ Hráč Ex zvolí libovolnou pumpovací konstantu n; ˇ dále Al zvolí nějaké z = anbncndn. ˇ Dle pumping lemmatu tedy mají existovat u, v, w, x, y tak, že z = uvwxy, |vwx| n a v nebo x je neprázdné (volí Ex). ˇ Má platit uvi wxi y L pro všechna i 0. Al tedy má ukázat, že pro každou Ex-ovu volbu vyvrátí predikát i. uvi wxi y L): Jelikož |vwx| n, vwx musí být tvaru ab nebo bc nebo cd. Pro jakoukoli z těchto voleb však "pumpování" musívyústit v řetěz nepatřícído L (např. vwx ab značí, že uwy má méně symbolů a a b,1 než symbolů c a d). K důkazu, že například L = {ai bj ck| i = j a j = k} nebo L = {ai bj ck| i = j a j = k} není CFL je nutno použít některou ze silnějších variant Pumping lemmatu pro CFL, například tzv. Ogdenovo lemma, resp. jeho důsledky. Dokonce existuje též nutná a postačující podmínka pro to, aby jazyk byl CFL. Čtenáře odkažme na seznam literatury uvedený v závěru. 3.1.4 Greibachové normální forma Naším cílem je nyní prezentovat další, tzv. Greibachové normálníformu (GNF), v níž každá pravá strana každého pravidla v CFG začíná terminálním symbolem (za nímž případně následují neterminály). Abychom mohli dokázat tvrzení o existenci ekvivaletní gramatiky v GNF, potřebujeme ukázat několik lemmat o modifikacích pravidel v CFG. Definice 3.28. Neterminál A v CFG = (N, , P, S) se nazývá rekursivní jestliže exis- tuje derivace A + A pro nějaká , . Je-li = (resp. = ), pak A se navývá levorekursivní (resp. pravorekursivní). CFG bez levorekursivních neterminálů se nazývá nelevorekursivní. Poznamenejme, že pojem rekursivity neterminálu je diametrálně odlišný od pojmu rekursivity gramatiky, tj. existence algoritmu pro rozhodování problému zda w L( ). Pro transformaci CFG do GNF bude nutné z gramatiky odstranit levou rekursi: pokud v gramatice nebudou levorekursivní neterminály, budeme moci na nejlevější neterminály na pravých stranách pravidel aplikovat lemma o substituci. Schopnost eliminovat levou rekursi se ukáže jako velmi užitečná též v řadě prakticky orientovaných aplikací. Lemma 3.29. (O eliminaci bezprostřední levé rekurze). Necht' = (N, , P, S) je CFG, v níž všechna A-pravidla jsou tvaru A A1 | . . . | Am | 1 | . . . | n, kde 1 i = A pro všechna 1 i n. (*) Necht' = (N {A }, , P , S), kde P obdržíme z P tak, že všechna pravidla označená (*) nahradíme pravidly A 1 | . . . | n| 1 A | . . . | n A , A 1 | . . . | m | 1 A | . . . | m A . (**) Pak L( ) = L( ). Důkaz: Neformálně řečeno jsme levou rekursi v A-pravidlech, která generujířetězce tvaru (1 + . . . + n)(1 + . . . + m), nahradili nově zavedeným pravorekursivním A , který (spolu s A) generuje tutéž množinu. Formální důkaz možno vést například takto: V libovolné nejlevější derivaci nějaké věty v musí posloupnost použití pravidel typu A Ai být ukončena použitím nějakého pravidla A j . Tedy místo derivace A Ai1 Ai2 i1 . . . Aip . . . i2 i1 j ip . . . i2 i1 v , lze v gramatice použít derivaci A j A j ip A . . . j ip . . . i2 A j ip . . . i2 i1 . Jelikož výše uvedená úvaha platíi v obráceném směru (po jisté posloupnosti použitípravidel tvaru A i A musí být použito A i ), dostáváme žádané L( ) = L( ). Příklad 3.30. Mějme 0 s pravidly: E E +T | T T T F | F F (E) | i Pak 0 má pravidla: E T | T E E +T | +T E T F | FT T F | FT F (E) | i Poznámka 3.31. Jestliže z lemmatu 3.29 je bez -pravidel, pak i ekvivaletní má tuto vlastnost. Pravidla (*) lze též nahradit namísto pravidel (**) pravidly: A 1 A | . . . | n A , A 1 A | . . . | m A | . (***) Tato náhrada však zavádí -pravidla: ke 0 z příkladu 3.30 bychom obrželi 0 s pravidly: E T E E +T E | T FT T FT | F (E) | i Lemma 3.29 nedává návod jak postupovat, když v existuje levorekursivní smyčka A + A délky větší než 1. Tento problém řeší algoritmus 3.7. Algoritmus 3.7 Eliminace levé rekurze Vstup: Vlastní CFG = (N, , P, S) Výstup: CFG = (N , , P , S) L( ) = L( ) a je nelevorekurzivní 1: Uspořádej libovolně N, N = {A1, . . . , An} 2: for i = 1 to n do 3: for j = 1 to i - 1 do 4: for all pravidlo tvaru Ai A j (*tj. zde platí j < i *) do 5: přidej Ai 1| . . . |k, kde A j 1| . . . |k jsou všechna A j -pravidla; 6: vypust'pravidlo Ai A j (* = aplikace lemmatu o substituci *) 7: end for 8: end for 9: (* dále následuje použití eliminace bezprostřední levé rekurze pro Ai -pravidla: *) 10: for all pravidlo tvaru Ai Ai do 11: přidej Ai Ai | ; (* tj. použití pravidel (***); variantu (**) lze též použít *) 12: vypust'pravidlo Ai Ai 13: end for 14: přidej Ai 1 Ai | . . . |l Ai , kde Ai 1| . . . |l jsou vš. Ai -pravidla pro něž platí, že 1 k = Ai ; 15: end for Věta 3.32. Každý CFL je generovatelný nelevorekursivní CFG. Důkaz: Necht' je vlastní CFG generující L. Jelikož algoritmus 3.7 používá jen trans- formace uvedené v lemmatu o substituci (3.20) a lemmatu o eliminaci bezprostřední levé rekurze (3.29), které zachovávají ekvivalenci gramatik, pak použití tohoto algoritmu na dává ekvivaletní CFG . Zbývá tedy ukázat, že výsledná je bez levé rekurze. Indukcí ukažme platnost následujících dvou tvrzení: 1. po skončení i-té iterace vnějšího cyklu (začínajícího na řádku 2) platí, že všechna Ai -pravidla začínají bud'terminálem nebo neterminálem Ak, k > i 2. po skončení j-té iterace vnitřního cyklu (začínajícího na řádku 3) a dané i platí, že Ai -pravidla začínají bud'terminálem nebo neterminálem Ak, k > j. Tuto indukci povedeme vzhledem k hodnotě s = n i + j, kde i 0, n , j 0, i - 1 . Báze indukce je pro s = n, tj. i = 1, j = 0 a odpovídá provedení eliminace levé rekurze pro A1 (cyklus pro j se vůbec neprovedl); žádné 1, . . . , l nezačíná A1. Tedy pro i = 1 tvrzení 1 platí; tvrzení 2 platí triviálně. Indukční krok: předpokládejme, že tvrzení 1 a 2 platí pro všechny hodnoty menší než s a necht'nyní jsou i, j taková, že 0 j < i n a n i + j = s. Dokažme nejprve 2. Na základě indukčního předpokladu o tvrzení 1 máme, že všechna A j -pravidla začínají bud'terminálem nebo neterminálem Ak, k > j (je-li totiž j > 1, pak instance 2 pro i a j - 1 má hodnotu menší než s; případ j = 1 plyne z 1). Tvrzení 2 pro parametry i a j tak okamžitě plyne z tvaru nově přidaných pravidel. Induktivní krok pro tvrzení 1 a hodnotu s (tj. n i = s, j = 0) je ponechán čtenáři. Z právě dokázaného tvrzení 1 plyne, že žádné z A1, . . . An nemůže být levorekur- sivní: kdyby totiž bylo Ai + Ai pro nějaké , pak by musely existovat neterminály A j a Ak, k j takové, že Ai A j Ak Ai . Zbývá ukázat, že žádný z Ai není levorekursivní, což však plyne z předpokladu, že je vlastní CFG ­ tj. žádné z řádku 10 není , a tedy Ai nemůže nikdy být nejlevějším symbolem na pravé straně přidávaného pravidla Ai Ai (viz řádek 14). Definice 3.33. Necht' = (N, , P, S) je CFG. Ř ekneme, že je v Greibachové normální formě (GNF) právě když je bez -pravidel (viz def. 3.13) a každé pravidlo z P je tvaru A a (a , N). Algoritmus 3.8 Transformace do GNF Vstup: Nelevorekursivní, vlastní CFG = (N, , P, S) Výstup: CFG v GNF: L( ) = L( ) 1: Zkonstruuj na N lineární uspořádání takové, že je-li A B P, pak A B. Označme N = {A1, . . . , An| Ai-1 Ai , 0 < i n} 2: for i = n - 1 downto 1 do 3: for all pravidlo tvaru Ai A j , j > i do 4: přidej Ai 1| . . . |k, kde A j 1| . . . |k jsou vš. A j -pravidla; 5: vypust'pravidlo Ai A j (* = aplikace lemmatu o substituci *) 6: end for 7: end for 8: for all pravidlo tvaru Ai aX1 . . . Xk, X j .1 j k X j do 9: v pravidle Ai aX1 . . . Xk nahrad'všechny ty X j , které jsou terminály, novými neterminály X j (přidej je do množiny neterminálů) a přidej pravidla X j X j . 10: end for Věta 3.34. Necht'L je CFL. Pak L = L( ) pro nějakou CFG v GNF. Důkaz: Bez újmy na obecnosti lze předpokládat, že L je generován CFG 1 splňující vstupní předpoklady algoritmu 3.8 (aby 1 byla vlatní, tj. specielně bez -pravidel, stačí v algoritmu 3.7 uvažovat na řádku 11 variantu (**) - viz též poznámka 3.31). Lineárníuspořádání požadované v řádku 1 algoritmu 3.8 lze zkonstruovat například takto: na množině neterminálů definujme relaci R A, B R def A + B pro nějaké . Pak díky tomu, že 1 není levorekursivní, je R částečným uspořádáním na množině neterminálů N, a tedy N lze lineárně douspořádat tak, aby platilo R . Nyní ukažme, že po skončení cyklu, který začíná na řádku 2, pro hodnotu i musí platit, že všechna Ai -pravidla začínají terminálem. Toto se snadno ukáže indukcí pro hodnotu k = n - i, i = 0, . . . , n - 1 (stručně zvanou zpětná indukce pro i od n po 1). Báze indukce je pro k = n, tj. i = 0. Pravé strany An-pravidel jistě začínají termi- nálem (viz definice ), což je též důvodem, proč se cyklus 2: pro i = n vůbec neprovádí. Indukční krok: jestliže dokazovanou vlastnost mají všechna A j -pravidla pro i < j n, pak evidentně pro provedení řádků 4 a 5 mají tuto vlastnost i všechna Ai -pravidla. Tedy po úplném skončení cyklu na řádcích 2­7 začínají všechna pravidla terminálem. Konečně uvažme, že algoritmus používá jen transformace zachovávající ekvivalenci gramatik, a tedy dostáváme žádané. Příklad 3.35. Mějme 0 z příkladu 3.30 s pravidly: E T | T E E +T | +T E T F | FT T F | FT F (E) | i Požadované lineární uspořádání (jedno z možných) je například: E E T T F. Další práce algoritmu 3.8 na řádcích 2 ­ 7 vypadá takto: ˇ V množině pravidel hledané gramatiky v GNF zůstanou beze změny obě F-pravidla (F je největším prvkem vzhledem k a cyklem pro i nejsou vůbec zpracovávány ­ pravé strany F-pravidel totiž už terminálem začínají). ˇ Při průchodu cyklem pro neterminál T pravidla T F | FT nahradíme pravidly T (E) | i | (E)T | iT . ˇ V dalším průchodu (pro T ) neprovádíme žádné změny. ˇ Při zpracování E nahradíme existující E-pravidla novými pravidly E (E) | i | (E)T | iT | (E)E | i E | (E)T E | iT E ; ˇ pro E opět žádné náhrady neprovádíme. Konečně (viz řádky 8 ­ 10) ve všech takto získaných pravidlech nahradíme na jejich pravých stranách všechny výskyty terminálu ")" novým neterminálem ") " a přidáme pravidlo ) ). Poznamenejme, že výše uvedená metoda převodu libovolné CFG do GNF není jediná možná ­ další metody lze nalézt v publikacích uvedených v seznamu literatury. Námi uvedená metoda byla zvolena zejména z toho důvodu, že explicitně obsahuje algoritmus na odstranění levé rekurze, jejíž přítomnost může činit jisté problémy v některých praktických aplikacích. Mimo uvedenou GNF (viz definice 3.33) existují i její další varianty. Ř ekneme, že je v k-GNF právě když je v GNF a žádná pravá strana v pravidlech gramatiky nemá délku větší než k, k 3, tj. neobsahuje více než k - 1 výskytů neterminálů (na intuitivní úrovni se jedná o GNF beroucí v potaz fakt, že díky CNF vystačíme v CFG na pravých stranách s (nejvýše) dvěma neterminály). Další variantou je tzv. zdvojená GNF, kdy všechny pravé strany pravidel jsou ze N , tj. začínajíi končíterminálem. Konečně je ve zdvojené k-GNF jestliže je ve zdvojené GNF a každé pravidlo má délku nejvýše k, k 4. Například tedy 3-GNF či zdvojená 4-GNF neobsahují na pravých stranách pravidel více než 2 výskyty neterminálů. Algoritmy převodu libovolné CFG do každé z výše uvedených normálních forem lze nalézt v obsažnějších monografiích o bezkontextových jazycích. Na závěr zmiňme ještě tzv. operátorovou normální formu, kdy na pravých stra- nách pravidel spolu nesmí sousedit žádné dva neterminály, tj. všechny pravé strany jsou ze N + . . . + N . Algoritmus převodu libovolné CFG (či bez újmy na obecnosti CFG v CNF) spočívá v zavedení nových neterminálů X, a pro každou dvojici X N, a s tím, že X, a má generovat množinu slov u takových, že X generuje slova ua. Tedy každý jazyk L(X) je přesně sjednocením (přes a ) všech jazyků L( X, a ).a, případně doplněném o {}, pokud L(X) obsahuje prázdné slovo. Tedy na pravých stranách pravidel lze každý neterminál X nahradit zřetězením X, a .a; přidáním pravidel tvaru X, a pro každé X a, získáme ekvivaletní gramatiku v požadovaném tvaru. Detaily algoritmu i důkazu jeho korektnosti ponecháváme čtenáři jako cvičení. Použití normálních forem pro další zkoumání vlastností CFL bylo již částečně ilu- strováno v této části (viz CNF a její využití v důkazu pumping lemmatu pro CFL); s dalšími aplikacemi se setkáme v části 3.3. 3.2 Zásobníkové automaty Tak jako k regulárním gramatikám existují konečné automaty, které rozpoznávají právě jazyky generované těmito gramatikami, tak i ke gramatikám bezkontextovým existují ve výše uvedeném smyslu ekvivaletní automaty ­ tzv. zásobníkové automaty (push-down automata ­ PDA). PDA si lze představit jako (nedeterministický) konečný automat s tím, že navíc obsahuje (pomocnou) pamět'(a díky ní i další zdroj nedeterminismu), která pracuje jako zásobník (push-down store) a jejíž velikost není shora omezena ­ je tzv. potenciálně nekonečná v následujícím smyslu: v každém okamžiku (konečného) výpočtu je sice konečná (tj. v zásobníku je uloženo jen konečně mnoho symbolů), ale kdykoli ji můžeme rozšířit o další konečný počet pamět'ových míst (přidat další symboly na zásobník). a a b a b b b a konečně stavová řídící jednotka Z a A čtecí hlava vstupní páska zásobník Obrázek 3.2: Zásobníkový automat Ze vstupní pásky, na níž je zapsáno slovo nad jistou vstupní abecedou, lze pouze číst a čtecí hlava se pohybuje jen vpravo. Automat může na vrchol zásobníku ukládat symboly (opět z jisté abecedy) a takto uložené symboly může následně číst s tím, že smí číst pouze z vrcholu zásobníku: přečtený symbol je z vrcholu odstraněn (tj. systém LIFO ­ Last In First Out). Jinými slovy, nelze číst do hloubi zásobníku, aniž by přečtené symboly nebyly odstraněny ­ zásobník, u něhož naopak toto "nedestruktivní" čtení lze realizovat se v angličtině nazývá stack, na rozdíl od našeho push-down store s desktruktivním čtením. Takto intuitivně popsané zařízení nyní formalizujme. 3.2.1 Definice PDA Definice 3.36. Nedeterministický zásobníkový automat (PDA) je sedmice = (Q, , , , q0, Z0, F), kde ˇ Q je konečná množina, jejíž prvky nazýváme stavy, ˇ je konečná množina, tzv. vstupní abeceda, ˇ je konečná množina, tzv. zásobníková abeceda, ˇ Q × ( {}) × ) Fin(Q × ), tzv. (parciální) přechodová funkce2 , ˇ q0 Q je počáteční stav, ˇ Z0 je počáteční symbol v zásobníku, ˇ F Q je množina koncových stavů. Je-li (p, a, Z) definováno, pak zápis (p, a, Z) = {(qi , i )| 1 i n} intuitivně interpretujeme tak, že PDA může ze stavu p po přečtení symbolu a ze vstupní pásky a symbolu Z z vrcholu zásobníku (Z se při tomto čtení z vrcholu odstraní) přejít do jednoho ze stavů qi a na vrchol zásobníku zapíše řetěz i (přičemž na vrcholu zásobníku je nyní nejlevější symbol z i ). Čtecí hlava se na vstupní pásce posune o jeden symbol vpravo. Obdobně interpretujeme (pokud je definováno) (p, , Z) s tím rozdílem, že pozice čtecí hlavy na vstupní pásce se nemění. Tuto intuitivní představu o jednom kroku výpočtu budeme formalizovat (obdobně jako u konečných automatů) zavedením pojmu konfigurace, popisujícím celkovou situaci automatu. U konečných automatů byla konfigurace dána popisem situace na vstupní pásce (tj. specifikací dosud nepřečtené části vstupního slova) a vnitřní situací automatu (tj. speci- fikací jednoho, momentálního stavu, který reflektoval změny v automatu dané zpracováním již přečtené části vstupu počínaje počátečním stavem q0). Co se týče vstupu, je situace u PDA identická, avšak zpracování již přečtené části vstupu se ve vnitřní situaci projeví nejen změnou stavu q0, ale i tím, co si automat zapamatoval v zásobníku. Konfigurace by tedy měla opět popisovat jak vnitřní situaci jako dvojici (stav, obsah zásobníku), tak i dosud nepřečtenou část vstupního slova. Krok výpočtu pak bude definovat vztah mezi dvěma konfiguracemi ­ situací před provedením kroku výpočtu a situací po provedení tohoto kroku. Automat bude akceptovat vstupní slovo, jestliže bude existovat posloupnost kroků výpočtu začínající v jisté počáteční konfiguraci, která skončí v nějaké finální, akceptující konfiguraci. 2. zápis Fin(Q × ) značí množinu všech konečných podmnožin množiny Q × Definice 3.37. Necht' = (Q, , , , q0, Z0, F) je PDA. Vnitřní konfigurací (též to- tálním stavem) nazveme libovolný prvek (q, ) Q × (kde q je momentální stav PDA a je celý obsah zásobníku s vrcholem psaným vlevo). Konfigurací nazveme libovolný prvek (p, w, ) z Q × × (udávající mimo totální stav navíc i w ­ dosud nepřečtenou část vstupního řetězu). Na množině všech konfiguracíautomatu definujeme binární relaci | (krok výpočtu) takto: (p, aw, Z) | (q, w, ) def (q, ) (p, a, Z) pro a {} Reflexivní a tranzitivní uzávěr relace kroku výpočtu značíme | , její k-násobný součin značíme | k . Je-li zřejmý z kontextu, píšeme stručněji pouze | , resp. | , resp. | k . Jazyk akceptovaný (též rozpoznávaný) PDA koncovým stavem definujeme jako L() = {w | (q0, w, Z0) | (q f , , ), kde q f F, } a jazyk akceptovaný (též rozpoznávaný) PDA prázdným zásobníkem definujeme jako Le() = {w | (q0, w, Z0) | (q, , ), kde q Q} Každý výpočet pro vstupní slovo w tedy začíná v konfiguraci (q0, w, Z0), tj. ve vnitřní konfiguraci (q0, Z0) a dosud nečteným vstupem. Způsobů akceptování je obecně více: každá akceptující (finální) konfigurace je charakterizována zcela přečteným vstupním slovem, tj. (q, , ), vzájemně se však tyto způsoby liší tím, co prohlásíme za akceptující totálnístav (vnitřníkonfiguraci). Ve výše uvedené definici 3.37 jsou to po řadě totálnístavy z F × , resp. Q×{}. Další způsoby akceptování lze definovat tak, že za akceptující vnitřní konfigurace prohlásíme např. prvky z F × {} (akceptování koncovým stavem a prázdným zásobníkem, resp. prvky z Q × pro nějakou (akceptování vrcholovými symboly v zásobníku). Formální definice jsou ponechány čtenáři. Poznámka 3.38. 1. U takto definovaného PDA se opět jedná o nedeterministický automat, který akceptuje vstup, jestliže existuje alespoň jeden výpočet, který vede z konfigurace počátečnído konfigurace akceptující(při možnosti volby tedy PDA "hádá správně", protože nesprávná volba sama o sobě nemůže způsobit zamítnutí vstupu ­ ten může být zamítnut jedině tedy, pokud žádná správná volba neexistuje). 2. Dále si povšimněme jedné důležité vlastnosti zásobníkových automatů, kterou lze parafrázovat takto: to, co se děje na vrcholu zásobníku (ve výše definovaném smyslu push-down store, nikoli však obecnějším stack), děje se zcela nezávisle na tom, co je pod jeho vrcholem. Přesněji: pokud (q, w, A) | n (q , , ), pak (q, w, A) | n (q , , ) pro všechna A , . Tento fakt se velmi snadno dokáže indukcí vzhledem k n. Věta 3.39. Jazyk L = Le() pro nějaký PDA L = L() pro nějaký PDA . Idea důkazu: 1. : k danému zkonstruujeme simulující jeho činnost. Kdykoli vejde do koncového stavu, bude mít možnost volby, zda pokračovat v simulaci automatu nebo přejít do svého, nově přidaného stavu qe, v němž vyprázdní svůj zásobník. Musíme však uvážit možnou komplikaci: může projít takovou posloupností kroků, kdy jeho vstup způsobí vymazání zásobníku a není v koncovém stavu, tedy zamítá vstup. Musíme zabránit tomu, aby v tomto bodě vstup (prázdným zásobníkem) akceptoval. Ř ešení spočívá v tom, že ještě před zahájením simulace bude u na dně zásobníku nový symbol, který nedovolíme odstranit jinde, než v koncovém stavu q F nebo ve stavu qe. 2. : simuluje činnost a má opět nově přidaný symbol jako své dno zásob- níku. Jakmile je schopen číst tento symbol (tj. zásobník automatu je prázdný), pak přejde do nově přidaného stavu q f , který je koncovým stavem. Důkaz: 1. : Necht' = (Q, , , , q0, Z0, F) je PDA takový, že L = L(). Se- strojme takový, že L = Le(). Položme = (Q {q0, qe}, , {Z }, , q0, Z , ) , kde Z / a q0, qe / Q a kde je definována takto: 1. (q0, , Z ) = {(q0, Z0 Z )} , 2. jestliže (q, a, Z) obsahuje (r, ), pak (q, a, Z) obsahuje (r, ) pro všechna q Q, a {} a Z , 3. q F.Z {Z } (q, , Z) obsahuje (q, ) , 4. Z {Z } (q, , Z) = {(q, )} . Pak zřejmě (q0, w, Z ) | (q0, w, Z0 Z ) -dle 1 | n (q, , Y1 . . . Yr ) -dle 2 | (q, , Y2 . . . Yr ) -dle 3 | r - 1 (q, , ) -dle 4 ( kde Yr = Z ) právě když (q0, w, Z0) | n (q, , Y1 . . . Yr-1), pro nějaké q F. 2. : Necht' = (Q, , , , q0, Z0, ) je PDA takový, že L = Le(). Sestroj- me takový, že L = L(). Položme = (Q {q0, q f }, , {Z }, , q0, Z , {q f }) kde je definována takto: 1. (q0, , Z ) = {(q0, Z0 Z )} 2. jestliže (q, a, Z) obsahuje (r, ), pak (q, a, Z) obsahuje (r, ) pro všechna q Q, a {} a Z 3. q Q (q, , Z ) = {(q f , )} Požadovaný důkaz, že Le() = L() je obdobný jako v části 1 a je ponechán čtenáři. Poznámka 3.40. Ve výše uvedeném důkazu je prezentována technika zavedení nového sym- bolu Z označující dno zásobníku simulujícího automatu, která umožnuje de facto testovat prázdnost zásobníku simulovaného automatu. Jestliže též požadujeme (srv. odstranění Z pouze v q), aby každá vnitřní konfigurace (s eventuelní výjimkou finální při akceptování prázdným zásobníkem) byla tvaru p, Z , budeme říkat, že takový PDA umožnuje test dna zásobníku. Pokud tedy PDA čte dno Z , musí jej též znovu na dno zapsat, tj. pokud obsa- huje jako argument Z , pak je tvaru (p, a, Z ) = {(q1, 1 Z ), . . . , (qn, n Z )}. Je zřejmé, že ke každému PDA lze setrojit PDA s testem dna zásobníku akceptující tentýž jazyk. Poznamejme, že obdobně lze ukázat i ekvivalenci (ve smyslu výše uvedené věty 3.39) mezi akceptováním koncovým stavem a akceptováním koncovým stavem a (současně) prázdným zásobníkem či akceptováním vrcholovými symboly v zásobníku. Příklad 3.41. Mějme PDA = ({p, q,r}, {0, 1}, {Z, 0}, , p, Z, {p}), kde je definována takto: (p, 0, Z) = {(q, 0Z)} (q, 0, 0) = {(q, 00)} (r, 1, 0) = {(r, )} (q, 1, 0) = {(r, )} (r, , Z) = {(p, )} Automat pracuje tak, že nejprve ze vstupu načte do zásobníku všechny symboly `0' a následně s každým čteným (vstupním) symbolem `1' odstraní jeden symbol `0' z vrcholu zásobníku. Navíc se kontroluje, zda žádná `1' není před `0' (tím, že pro tyto situace je nedefinována, a tedy není definován krok výpočtu pro žádnou takovou situaci). Možná posloupnost (v obecném, nikoli však v tomto případě, pouze jedna z možných posloupností) konfigurací automatu pro vstupní slovo například 0011 může být (p, 0011, Z) | (q, 011, 0Z) | (q, 11, 00Z) | (r, 1, 0Z) | (r, , Z) | (p, , ) Lze ukázat, že akcetuje koncovým stavem jazyk L = {0n1n| n 0}. Snadno se nahlédne, že L L(): pro n 1 lze po jediném přechodu z p do q (přečtení `0' a jeho uložení do zásobníku ­ viz 1. přechod výše) provést n1 přechodů z q do q (opět čtení `0'a uložení do zásobníku ­ viz 2. přechod). Následně lze při čtení prvního symbolu `1' provést jediný přechod z q do r následovaný n1 přechody z r do r po nichž zůstane v zásobníku pouze Z; následuje přechod do koncového stavu p. Případ n = 0 je triviální. Ukázat obrácenou inklusi (tj., že neakcetuje jiná slova než 0n1n) je obecně těžší úkol. Abychom to ukázali, uvědomme si, že při libovolném výpočtu nad neprázdným slovem musí automat procházet (s případnými cykly) postupně stavy p, q,r a skončí v p. Je-li (p, w, Z) | i (q, , ), i 1, pak w =0i a =0i Z. Podobně, je-li (r, w, ) | i (r, , ), i 1, pak w = 1i a = 0i . Dále přechod (q, w, ) | (r, , ) nastane jedině tehdy, pokud w = 1 a = 0; podobně (r, w, Z) | (p, , ), pokud w = . Tedy celkem, je-li (p, w, Z) | i (p, , ), i 0, pak bud'w = a i = 0 nebo w = 0i 1i , i = 2n + 1 a = . Tedy L L(). Zdůrazněme, že tak, jak byl PDA definován, může dělat () kroky i po přečtení celého vstupu; PDA nemůže udělat žádný krok, pokud je zásobník prázdný. Poznámka 3.42. O přechodových grafech (`stavových' diagramech) PDA. Na stavové dia- gramy konečných automatů lze nahlížet tak, že jsme grafově znázornili vzájemné závislosti (dané přechodovou funkcí) mezi vnitřními konfiguracemi (tj. stavy) automatu. Podobně můžeme postupovat i v případě PDA = (N, , , , q0, Z, F). Uzly přechodového grafu (stavového diagramu) budou označeny vnitřními konfiguracemi uvažovaného PDA (pro jednoduchost pišme vnitřní konfiguraci p, Q × ve tvaru p Q ). Analogicky jako u definice kroku výpočtu ved'me z uzlu pZ hranu s návěštím a (a {}) do uzlu q právě když (p, a, Z) obsahuje (q, ), což zapisujme jako pZ a q . Poznamenejme, že stavový diagram PDA má obecně nekonečně mnoho uzlů (proto je PDA prvním příkladem "nekonečného" automatu). Část stavového diagramu pro z příkladu 3.41 má tento tvar pZ 0 GG q0Z 0 GG 1 q00Z 0 GG 1 q000Z 0 GG 1 . . . 0 GG q0i Z 0 GG 1 . . . p r Z oo r0Z 1oo r00Z 1oo . . .1oo q0i-1 Z 1oo . . .1oo kde koncovými totálními stavy jsou pZ a p, v diagramu pro názornost zapsaný jako p. Povšimněme si, že ve výše uvedeném stavovém diagramu automatu jsou uvedeny pouze tzv. dosažitelné totální stavy, tj. ty ke kterým existuje cesta z počátečního uzlu (zde pZ) končící v uzlu daném; ostatní nazveme nedosažitelné a obvykle je ve stavovém diagramu neuvádíme (ve výše uvedeném diagramu to jsou např. qZ Z, qZ0Z a další). V souladu s právě zavedenou notací můžeme též při specifikaci funkce místo (p, a, Z) = {(q1, 1), . . . , (qn, n)} psát pZ a q11 | . . . | qnn. Relaci a můžeme zřejmým způsobem rozšířit ze symbolů ze na řetězy nad touto abecedou ( aw def = a w ); značení w , w lze chápat jako zobecněnou přechodovou funkci pro PDA). V dalším textu budeme rovněž používat následující značení. Je-li p nějaká vnitřní konfigurace PDA = (Q, , , , q0, Z0, F), pak definujme L()(p) def = {w | p w q, q F} a Le()(p) def = {w | p w q, q Q}. Zřejmě tedy L() = L()(q0 Z0) a Le() = Le()(q0 Z0). Bude-li zřejmý z kontextu, budeme stručněji psát pouze L(p) resp. Le(p). Příklad 3.43. Necht'L = {wwR| w {0, 1}}. Pak PDA rozpoznávající L prázdným zá- sobníkem je například = ({p, q}, {0, 1}, {R, G, B}, , p, R, ) (tj. množina koncových stavů nehraje žádnou roli), kde je definována (ve výše zavedené notaci) takto: (1) pR 0 pBR (2) pR 1 pGR (3) pB 0 pBB | q (4) pG 0 pBG (5) pB 1 pGB (6) pG 1 pGG | q (7) qB 0 q (8) qG 1 q (9) pR q (10) qR q Pravidla (1) až (6) ukládají vstup na zásobník s tím, že pravidlech (3) a (6) je možnost alternativní volby: jestliže uhodne, že bylo dosaženo středu vstupního slova, volí dru- hou alternativu; v ní pak přejde do stavu q, v němž postupně porovnává zbytek vstupního slova s obsahem zásobníku. Pokud hádal správně a slovo bylo tvaru wwR, pak dojde k přečtení celého slova a vyprázdnění zásobníku ­ vstupní slovo bylo akceptováno. Pokud by hádal chybně a slovo bylo tvaru wwR, pak by akceptující konfigurace nedosáhl, což ovšem neznamená zamítnutí vstupního slova ­ viz též pozn. 3.38. Uvedený příklad ilustruje nedeterminismus PDA, avšak u PDA z př. 3.41 se možnosti volby způsobující nedeterminismus nevyskytly ­ v každé (vnitřní) konfiguraci je další krok určen jednoznačně. Definice 3.44. Rozšířeným PDA nazveme = (Q, , , , q0, Z0, F), kde všechny sym- boly mají tentýž význam jako v definici PDA s výjimkou , která je zobrazením z konečné podmnožiny množiny Q × ( {}) × do konečných podmnožin množiny Q × . Pojmy konfigurace, kroku výpočtu, výpočtu a akceptovaného jazyka (koncovým stavem, prázdným zásobníkem) zůstávají rovněž beze změny. Povšimněme si, že rozšířený PDA činí rozhodnutí o dalším kroku nikoli na základě jen jednoho (vrcholového) symbolu na zásobníku, ale na základě řetězu (konečné délky!), který je tvořen nejhornějšími symboly na zásobníku. Zápis p a q (resp. (p, a, ) obsahuje (q, )) interpretujeme tak, že pokud má automat ve stavu p na vrcholu zásobníku , pak po přečtenísymbolu a ze vstupnípásky (analogicky pro -krok) vymaže ze zásobníku řetěz symbolů , zapíše na něj řetěz symbolů a změní svůj stav na q. Specielně může rozšířený PDA učinit krok bez ohledu na zásobník (uvažuje řetěz ), a tedy obecně je schopen dělat kroky i v situaci, kdy zásobník je prázdný. Lemma 3.45. Necht' je rozšířený PDA. Pak existuje PDA takový, že L() = L(). Idea důkazu: Pro daný = (Q, , , , q0, Z0, F) označme m maximální délku řetězu symbolů na vrcholu zásobníku, který používá k rozhodnutí o dalším kroku výpočtu (tj. m = max{||; (q, a, ) = , pro nějaká q Q, a {}}). Budeme simulovat tak, že k rozhodování o dalším kroku potřebných m symbolů, které má k dispozici na zásobníku, si bude simulující PDA uchovávat (a aktualizovat) ve "vyrovnávací paměti" (konečné) délky m (tu bude mít ve své konečně stavové řídící jednotce ­ stavy automatu budou tedy dvojice stav simulovaného ,stav vyrovnávací paměti). Tedy bude vědět před provedením každého kroku, kterých m symbolů má na vrcholu zásobníku. Zmíněná aktualizace probíhá takto: je-li v nahrazeno k vrcholových symbolů, řekněme , l symboly, řekněme , pak v paměti PDA nahradíme též těchto k symbolů týmiž l symboly; Je-li l < k, pak udělá navíc k - l aktualizačních kroků, při nichž postupně přenáší symboly z vrcholu zásobníku do paměti. Je-li l > k, je zapotřebí (ještě před náhradou za ) "nadbytečných" l - k symbolů z konečné vyrovnávací paměti postupně přesunout na zásobník. V obou případech tak bude vyrovnávací pamět'automatu opět obsahovat přesně m symbolů, které má momentálně na vrcholu na zásobníku. Důkaz: Necht' = (Q, , , , q0, Z0, F) je rozšířený PDA a označme m = max{||; (q, a, ) = , pro nějaká q Q, a {}}). Nyní definujme PDA = (Q1, , 1, 1, q1, Z1, F1), kde 1. Q1 = {q, | q Q, 1, 0 || m} , 2. 1 = {Z1}, kde Z1 je nový symbol, 3. 1 je definována takto: (a) Necht'(q, a, X1 . . . Xk) obsahuje (r, Y1 . . . Yl). Pak i. je-li l k, pak pro všechna Z 1 a 1 taková, že || = m - k, klademe 1(q, X1 . . . Xk, a, Z) obsahuje (r, , Z), kde = Y1 . . . Yl a || = m; ii. je-li l < k, pak pro všechna Z 1 a 1 taková, že || = m - k, klademe 1(q, X1 . . . Xk, a, Z) obsahuje (r, Y1 . . . YlZ, ). (b) pro všechna q Q, Z 1 a 1 taková, že || < m, klademe 1(q, , , Z) = {(q, Z, )} 4. q1 = q0, Z0 Zm-1 1 5. F1 = {q, | q F, 1} . Na základě takto definované 1 není obtížné ověřit, že (q, aw, X1 . . . Xk Xk+1 . . . Xn) | (r, w, Y1 . . . Yl Xk+1 . . . Xn) (q, , aw, ) | + (r, , w, ), kde 1. = X1 . . . Xn Zm 1 , 2. = Y1 . . . Yl Xk+1 . . . Xn Zm 1 , 3. || = | | = m a 4. mezi dvěma výše uvedenými konfiguracemi PDA neexistuje taková konfigurace, kde druhá komponenta stavu (tj. pamět') by měla délku m. Odtud pak okamžitě plyne, že (q0, w, Z0) | (q, , ) pro nějaká q F a právě když (q0, Z0 Zm-1 1 , w, Z1) | (q, , , ), kde || = m a = Zm 1 . Tedy L() = L(). Poznámka 3.46. Poznamenejme, že i pro rozšířené PDA platí tvrzení věty 3.39 o ekvi- valenci rozpoznávání prázdným zásobníkem a koncovým stavem. Toto tvrzení se dokáže naprosto stejně jako u zmíněné věty. 3.2.2 Zásobníkové automaty a bezkontextové jazyky V této části ukážeme fundamentální výsledek, že třída jazyků rozpoznávaných zásobníko- vými automaty tvoří právě třídu bezkontextových jazyků. Věta 3.47. (O nedeterministické syntaktické analýze shora dolů) Necht' je libovolná CFG. Pak lze sestrojit PDA takový, že L( ) = Le(). Idea důkazu: Ke zkonstruujeme (jednostavový) PDA tak, aby ve svém zásobníku byl schopen simulovat levé derivace v , přičemž budeme požadovat, aby v každé konfiguraci platilo: z konfigurace s obsahem zásobníku a zbytkem vstupu w akceptuje prázdným zásobníkem v lze derivovat w (*) V je v jednom kroku odvození nahrazen (nejlevější) neterminál A (naráz, celou) pravou stranou X1 . . . Xn, kdežto v bude této situaci odpovídat (1): náhrada neterminálu A na vrcholu zásobníku toutéž pravou stranou následovaná (2): postupným (symbol po symbolu) zpracováním této, na vrchol zásobníku přidané, pravé strany: necht'se má zpracovat (tj. je na vrcholu zásobníku) Xi . Je-li Xi neterminál, postup ad (1) opakujeme, je-li (2) Xi terminál, pak zkontrolujeme (tj. ověřuje se korektnost nedeterministické volby v kroku typu (1)) zda Xi je stejný jako první, dosud nečtený terminálem na vstupu; pokud ano, pak terminál z vrcholu zásobníku odstraníme (a čtecí hlava se posune o jeden symbol vpravo). Korektnost uvedeného postupu spočívá v důkazu, že v jeho průběhu platí tvrzení (*). Odstartujeme-li v situaci, kdy v zásobníku je pouze kořen (a na vstupu slovo z L( )), pak (*) platí. Dále se (indukcí) ověří, že operace (1) a (2) zachovávají platnost (*). Pro pochopení činnosti je vhodné si uvědomit, že (*) implikuje tuto (opět v celém procesu invariantní) vlastnost: dosud přečtená část vstupu zřetězena s obsahem zásobníku v je odpovídající levou větnou formou v (a obráceně) (**) (tedy vstupní slovo je z L( ), právě když celý proces skončí v akceptující konfiguraci s celým přečteným vstupem a prázdným zásobníkem). Důkaz: Necht' = (N, , P, S). Definujme akceptující prázdným zásobníkem jako = ({q}, , N , , q, S, ), kde je definována takto: (1) q A q , je-li A P (tj. (q, , A) obs. (q, ) (2) qa a q , pro všechna a (tj. (q, a, a) = {(q, )}) Abychom ukázali L( ) = Le(), ukažme, že pro nějaká m, n 1 platí: A m w (q, w, A) | n (q, , ) (tj. q A w q v n krocích) (*1) 1. : Mějme A m w a ukažme, že (q, w, A) | (q, , ) (tj. q A w q): (a) je-li m = 1 a w = a1 . . . ak, (k 0), pak zřejmě A w P, a tedy (q, a1 . . . ak, A) | (q, a1 . . . ak, a1 . . . ak) | k (q, , ) (b) Přepokládejme, že (*1) platí pro všechna m < m a necht'A m w pro m > 1. Pak 1. krok derivace je tvaru A X1 X2 . . . Xk, kde Xi mi xi , 0 mi < m, což dle definice , bodu (1) dává (q, w, A) | (q, w, X1 X2 . . . Xk). (1.1) Je-li Xi N, pak dle indukčního předpokladu máme (q, xi , Xi ) | (q, , ). (1.2) Je-li Xi (tj. Xi =xi ), pak dle definice , bodu (2) máme (q, xi , xi ) | (q, , ). (1.3) Kompozicí přechodů (1.1) ­ (1.3) tedy dostáváme (q, w, A) | + (q, , ). 2. : Předpokládejme, že (q, w, A) | n (q, , ) a ukažme, že A + w: (a) n = 1 implikuje q A q , a tedy w = a A P. (b) Předpokládejme, že dokazované tvrzení platí pro všechna n < n. Pak 1. krok je tvaru (q, w, A) | (q, w, X1 X2 . . . Xk), tj. A X1 X2 . . . Xk P (2.1) Dále (q, xi , Xi ) | ni (q, , ), kde ni < n, 1 i k a kde w = x1x2 . . . xk je takové, že je-li Xi N, pak dle indukčního předpokladu máme Xi + xi , (2.2) je-li Xi , pak Xi 0 xi . (2.3) Vhodnou kompozicí (2.1) ­ (2.3) tedy obdržíme A X1 X2 . . . Xk x1 X2 . . . Xk ... x1 . . . xk = w , což je (korektní) levá derivace slova w v gramatice . Položíme-li A = S v právě dokázaném tvrzení (*1), okamžitě dostáváme žádané S + w (q, w, S) | + (q, , ), tj. qS w q . Poznámka 3.48. Poznamenejme, že uvedený důkaz lze modifikovat tak, že (bez újmy na obecnosti) předpokládáme, že daná CFG je v GNF. Pak body (1) a (2) v definici přechodové funkce lze nahradit jediným, a to q A a q , je-li A a. Princip důkazu ovšem zů- stává beze změny. (Přechodový graf takto vzniklého PDA k dané CFG , resp. k ekvivalentní CFG v GNF, nazveme rovněž přechodovým grafem CFG .) Prezentovaná varianta byla zvolena proto, že (dle našeho názoru) zřetelněji artikuluje nedetermininismus vznikající právě v bodu (1) definice (viz též poznámka 3.50) a nevyžaduje převod do GNF. Příklad 3.49. Mějme gramatiku 0 = ({E, T, F}, {+, , (, ), i}, P, E) s pravidly P da- nými takto: E E +T | T T T F | F F (E) | i Pak PDA sestrojený dle konstrukce z důkazu věty 3.47 je = ({q}, {+, , (, ), i}, {E, T, F, +, , (, ), i}, , q, E, ), kde je definována takto: qE qE +T | qT dle bodu (1) qT qT F | qF dle bodu (1) qF q(E) | qi dle bodu (1) qa a q pro všechna a {+, , (, ), i} dle bodu (2) Akceptující výpočet automatu pro vstupní slovo i +i i je uveden na obrázku 3.3. Jelikož je jednostavový, nebudeme stav v konfiguracích uvádět; tyto jsou tedy dvojicemi tvaru (vstup, obsah zásobníku). Doporučujeme ověřit si platnost vlastnosti (*) a (**) spefikované v idei důkazu věty 3.47. krok odpovídající pravidlo z 0 (i + i i, E) | ( i + i i, E + T ) E E + T | ( i + i i, T + T ) E T | ( i + i i, F + T ) T F | ( i + i i, i + T ) F i | i ( +i i, +T ) | + ( i i, T ) | ( i i, T F) T T F | ( i i, F F) T F | ( i i, i F) F i | i ( i, F) | ( i, F) | ( i, i) F i | i ( , ) Obrázek 3.3: Výpočet automatu z příkladu 3.49 pro vstupní slovo i + i i Poznámka 3.50. Jestliže PDA nejen koretně rozhoduje zda w L( ), ale při kladné odpovědi je navíc schopen určit derivační strom vstupní věty, říkáme, že PDA provádí syn- taktickou analýzu. Ve výše uvedeném příkladu 3.49 je posloupnost odpovídajících pravidel z 0 použitých při výpočtu v posloupností pravidel použitých při levé derivaci vstupní věty. Pokud bychom na základě této posloupnosti postupně konstruovali odpovídající de- rivační strom, povšimneme si, že konstrukce začíná u jeho kořene a jde směrem k listům; odtud název této techniky ­ nedeterministická syntaktická analýza shora dolů. Nedetermi- nismus se objevuje jen v konfiguracích, kdy PDA má na vrcholu neterminál a volí, kterou z odpovídajích pravých stran jej nahradit. Věta 3.51. Ke každému PDA lze sestrojit CFG takovou, že Le() = L( ). Idea důkazu: Nejprve si uvědomme, že pokud by PDA byl jednostavový, pak nalezení ekvivaletní CFG by bylo velmi snadné ­ konstrukce z důkazu věty 3.47 resp. poznámky 3.48 (tj. k CFG sestrojit ekvivalentní PDA) je plně reversibilní. V podstatě tedy půjde o tento cíl: (***) nalézt k danému PDA ekvivaletní PDA s jedním stavem (označeným např. symbo- lem `*') takový, že levé odvození v hledané má být simulací práce (tj. neterminály, které se vyskytují v libovolném kroku levé derivace v , odpovídajísymbolům v zásobníku automatu v době, kdy tento již přečetl ze vstupu to, co nalevo od nejlevějšího neter- minálu vygenerovala (srovnej s vlastnosti (*) resp. (**) uvedenými v idei důkazu zmíněné věty). Klíčovým úkolem důkazu je tedy ukázat, jak simulovat libovolný PDA jednosta- vovým PDA ­ oba dva akceptující prázdným zásobníkem. Informaci o stavu simu- lovaného PDA nelze v simulujícím jednostavovém PDA umístit jinam než na zásobník, tj. "vhodným způsobem" ji na zásobník přidat. Je-li w Le(), pak q0 Z0 w q do nějakého q Q, jinak řečeno odstartován v q0 Z0 přečetl w a skončil vymazáním Z0 v nějakém q. Pak v souladu s naším cílem (***) je přirozené požadovat dostupnost přesně této informace v zásobníku jednostavového PDA: požadujme po , aby odstartován s informací tvaru q0 Z0q jako jediným symbolem v zásobníku byl schopen přečíst vstup w a akceptovat jej prázdným zásobníkem, tj. mít v hledané gramatice neterminál tvaru q0 Z0q takový, aby q0 Z0q w. Uvědomme si, že v průběhu celého výpočtu zásobník neklesl ­ s výjimkou poslední konfigurace ­ pod hladinu danou vrcholovým symbolem Z0 v počátečním totálním stavu q0 Z0. Původní PDA ovšem prochází při svém (výše naznačeném) výpočtu celou po- sloupností kroků, a proto je přirozené zjemnit informaci q0 Z0 w q (resp. q0 Z0q w) tak, že jednostavový PDA bude mít v zásobníku symboly tvaru pAq z Q Q takové, aby platilo: odstartován s pAq jako jediným symbolem ve svém zásobníku akcep- tuje vstup x prázdným zásobníkem právě když odstartován ve vnitřní konfiguraci pA akceptuje x prázdným zásobníkem ve stavu q, tj. (připomeňme, že symbol `*' reprezentuje jediný stav PDA ): * pAq x v pA x q v . Nyní zbývá definovat přechody v . S každým přechodem pA a q1 B1 . . . Bn (a {}) v přidejme do všechny přechody tvaru pAq a q1 B1q2 q2 B2q3 . . . qn Bnqn+1 pro všechny možné volby q2, . . . , qn+1 takové, že qn+1 = q. V případě n = 0, tedy pA a q v ,přidáme do přechod pAq a . Intuitivně řečeno, simuluje tak, že nedeterministicky hádá, v kterých stavech se ve svém budoucím výpočtu ocitne: uloží si tato hádání na zásobník s tím, že posléze kontroluje korektnost svého nedeterministického hádání. V následujícím důkazu explicitníkonstrukci vypustíme a budeme pracovat přímo s hledanou , protože je zřejmé, že každému přechodu pAq a q1 B1q2 q2 B2q3 . . . qn Bnqn+1 v odpovídá v gramatice přímo pravidlo pAq a q1 B1q2 q2 B2q3 . . . qn Bnqn+1 . Navíc, protože gramatika může mít jen jeden kořen (resp. PDA jen jeden počáteční symbol v zásobníku), kdežto symbolů tvaru q0 Z0q je obecně více, přidáme i pravidla S q0 Z0q pro všechna q Q (pro platí Le() = {w | q0 Z0 w q, q Q}). Důkaz: Necht'PDA =(Q, , , , q0, Z0, ) a necht' =(N, , P, S) je CFG, kde ˇ N = {S} { pAq | p, q Q, A , kde S Q je nový symbol ˇ P obsahuje pravidla: 1. S q0 Z0q pro všechna q Q 2. pAq a q1 B1q2 q2 B2q3 . . . qn Bnqn+1 pro qn+1 =q, a {}, A, Bi (1i n) , qi Q, je-li pA a q1 B1 B2 . . . Bn ; je-li n = 0, klademe q1 = q a pAq a P. Abychom ukázali, že L( ) = Le(), tj. S q0 Z0q w q0 Z0 w q, dokaž- me: pAq x pA x q (1) 1. : Dokazujme, že (p, x, A) | i (q, , ) implikuje pAq x, a to indukcí vzhledem k i (vzhledem k čemu ještě by šlo indukci vést?). (a) Je-li i = 1, pak jistě pA a q (a {}), a tedy pAq a je pravidlo z P. (b) Necht'i > 1 a necht'x = ay a (p, ay, A) | (q1, y, B1 B2 . . . Bn) | i - 1 (q, , ). (1.1) Ř etěz y lze zapsat ve tvaru y = y1y2 . . . yn takovém, že přečtení yi způsobí odstranění Bi ze zásobníku (posloupností kroků, kdy zásobník může ještě vzrůst, ale nikdy neklesne pod úroveň, na níž je Bi ). Jinak řečeno, y1 je takovou předponou slova y, že po jejím přečtení se zásobník poprvé zkrátí na úroveň (hloubku) n - 1 (bude obsahovat B2 . . . Bn); y2 je takový řetěz, že následuje za y1 a po přečtení y2 se poprvé zásobník zkrátí na úroveň n-2 atd. Podstatné je, že během zpracování yi se žádné z Bi+1 . . . Bn neobjevilo na vrcholu zásobníku, a tudíž nemohlo ovlivnit průběh této části výpočtu, tj. B j zůstává na zásobníku bez vlivu na výpočet nad y1 . . . yj-1 ­ viz obrázek 3.4. Tedy existují stavy q2, q3, . . . , qn+1 (kde qn+1 =q) takové, že výpočet (qj , yj , Bj ) | (qj+1, , ) proběhne v méně než i krocích (q j je stav, do kterého se automat dostal, když se zásobník poprvé zkrátil na úroveň n - j + 1). Podle indukčního pžedpokladu tedy dostáváme qj Bj qj+1 yj pro všechna 1 j n (1.2) Protože první krok celého výpočtu (1.1) nad x = ay byl (p, ay, A) | (q1, y, B1 B2 . . . Bn) (tj. pA a q1 B1 B2 . . . Bn ), máme též 0 1 n-2 n-1 n y1 y2 y3 yn q1 B1. . .Bn q2 B2. . .Bn q3 B3. . .Bn qn Bn přečtený vstup q výška zásobníku (q = qn+1) Obrázek 3.4: Výška zásobníku jako funkce přečteného vstupu ­ k důkazu Věty 3.51 pAq a q1 B1q2 q2 B2q3 . . . qn Bnqn+1 , což spolu s (1.2) dává žádané pAq ay1y2 . . . yn = x. 2. : Nyní předpokládejme, že pAq i x a indukcí vzhledem k i ukažme, že pak (p, x, A) | (q, , ). (a) Je-li i = 1, pak pAq x je pravidlo v , což značí, že pA x q (x {}). (b) Necht'i > 1. Derivaci pAq i x lze zapsat jako pAq a q1 B1q2 q2 B2q3 . . . qn Bnqn+1 i-1 x, kde qn+1 = q (2.1). Pak x lze zapsat ve tvaru x = ax1x2 . . . xn takovém, že pro každé j(1 j n) platí qj Bjqj+1 x j , kde každá tato derivace má méně než i kroků. Tedy dle indukčního předpokladu platí (q j , x j , Bj ) | (qj+1, , ) pro všechna j(1 j n). Pokud v každé této posloupnosti konfigurací vložíme na dno zásobníku řetěz B j+1 . . . Bn, obdržíme (qj , x j , Bj Bj+1 . . . Bn) | (qj+1, , Bj+1 . . . Bn). (2.2) Z prvního kroku derivace (2.1) máme, že (pA a q1 B1 B2 . . . Bn) , tj. (p, x, A) | (q1, x1x2 . . . xn, B1 B2 . . . Bn) je korektní krok, což spolu s (2.2) pro j = 1, 2, . . . , n dává žádané (p, x, A) | (q, , ). Jestliže v právě dokázaném tvrzení (1) položíme p = q0 a A = Z0, dostáváme q0 Z0q x q0 Z0 x q, což spolu s pravidlem 1. pro konstrukci množiny P pravidel gramatiky dává S x q0 Z0 x q pro nějaký stav q Q, tj. x L( ) x Le(), což jsme měli dokázat. Sumarizujme dosud dosažené výsledky o rozpoznávání CFL pomocí PDA. Důsledek 3.52. 1. L = L( ) pro nějakou CFG 2. L = L() pro nějaký PDA 3. L = Le() pro nějaký PDA 4. L = L() pro nějaký rozšířený PDA . Důkaz: 3 1 (dle 3.47); 1 3 (3.47); 4 2 (3.45); 2 4 (triviální); 2 3 (3.39). Příklad 3.53. Mějme dán PDA = ({q0, q1}, {a, b}, {X, Z0}, , q0, Z0, ), kde je definována takto: q0 Z0 a q0 X Z0 q1 X b q1 q0 X a q0 X X q1 X q1 q0 X b q1 q1 Z0 q1 a konstruujme CFG = (N, , P, S) tak, aby generovala Le(). Zřejmě = {a, b} a N = {S} { qi Xqj |i, j 0, 1 } { qi Z0qj |i, j 0, 1 }. Při konstrukci množiny pravidel P lze postupovat systematicky tak, že začneme s ko- řenovými S-pravidly a další pravidla přidáváme jen pro ty neterminály . . . , které se již vyskytly na některé pravé straně do P již přidaného pravidla (proč?). Tedy S-pravidla jsou S q0 Z0q0 | q0 Z0q1 Nyní přidávejme pravidla pro q0 Z0q0 a q0 Z0q1 . Díky q0 Z0 a q0 X Z0 přidáme q0 Z0q0 a q0 Xq0 q0 Z0q0 | a q0 Xq1 q1 Z0q0 , q0 Z0q1 a q0 Xq0 q0 Z0q1 | a q0 Xq1 q1 Z0q1 . Opakováním tohoto postupu pro nově vznikající neterminály celkem ještě přidáme q0 Xq0 a q0 Xq0 q0 Xq0 | a q0 Xq1 q1 Xq0 , a též q0 Xq1 a q0 Xq0 q0 Xq1 | a q0 Xq1 q1 Xq1 , protože q0 X a q0 X X , q0 Xq1 b, protože q0 X b q1 q1 Z0q1 , protože q1 Z0 q1 , q1 Xq1 | b, protože q1 X q1, q1 X b q1 . Poznamenejme, že neexistují žádná pravidla pro q1 Xq0 a q1 Z0q0 ; tyto se ovšem na pravých stranách v P vyskytují, tedy tato pravidla nemohou vygenerovat žádný terminální řetěz, tj. i příslušné levostranné neterminály q0 Xq0 a q0 Z0q0 jsou nenormované (ne- použitelné). Pak ekvivalentní reduková gramatika má těchto sedm pravidel: 1. S q0 Z0q1 2. q0 Z0q1 a q0 Xq1 q1 Z0q1 5. q1 Z0q1 3., 4. q0 Xq1 a q0 Xq1 q1 Xq1 | b 6., 7. q1 Xq1 | b Příklad 3.54. Necht'je dán PDA = ({p, q,r, s}, {a, b, c, d}, {X}, , p, X, ), kde je dána takto: pX a pX X, pX b r, pX c q, qX d sX, sX d q, r X d r. Pro zkonstruujte část přechodového grafu (např. z pX alespoň dva a-přechody vedoucí postupně do pX X a pX X X a všechny b, c, d-přechody (a totální stavy) vedoucí postupně do akceptujících q,r). Nalezněte ekvivaletní CFG a zkonstruujte její přechodový graf. Na závěr této části uved'me ještě jedno tvrzení, které je sice již obsaženo v dů- sledku 3.52, avšak v jeho důkazu bude uvedena přímočará a velmi důležitá konstrukce, která (mimo jiné) ozřejmí, proč jsme definovali rozšířený PDA. Lemma 3.55. (O nedeterministické syntaktické analýze zdola nahoru) Necht' je libovolná CFG, pak lze zkonstruovat rozšířený PDA takový, že L( ) = L(). Idea důkazu: Z důvodů čitelnosti (viz dále) budeme nyní vrchol zásobníku psát (v definici i v konfiguracích) vždy vpravo. bude opět de facto jednostavový (druhý stav bude sloužit jen jako koncový). Na rozdíl od důkazu analogického tvrzení pro obyčejný PDA (viz věta 3.47), budeme konstruovat rozšířený PDA tak, aby simuloval pravé odvození vstupní věty, přesněji řečeno reverzi tohoto odvození: práci začne nad vstupní větou (a ­ v pricipu ­ s prázdným zásobníkem) a skončí s prázným vstupem a v zásobníku bude kořen gramatiky (odtud název analýza zdola nahoru. Pravou větnou formu Ay bude mít k dispozici tak, že A (jako výsledek dosavadní práce nad x ­ již přečtenou částí vstupu) je obsah zásobníku (s A na vrcholu) a y je dosud nepřečtená (nezpracovaná) část vstupu. Tedy invarintem výpočtu bude vlastnost: obsah zásobníku zřetězen se zbytkem vstupu v = pravá větná forma v (*) či přesněji řečeno, začne-li pracovat nad vstupem, který je větou z L( ), pak: Ay je obsah zásobníku zřetězen se zbytkem vstupu <=> Ay je pravá větná forma. (**) Rozšířený PDA má kroky dvojího typu: (1) může kdykoli číst do zásobníku vstupní symbol, (2) je-li na vrcholu zásobníku řetěz tvořící pravou stranu nějakého pravidla v , může nahradit v zásobníku tuto pravou stranu odpovídajícím levostranným neterminálem; ze vstupu nic nečte. Krok typu (2) nazveme redukcí podle příslušného pravidla. Automat bude tedy (opět) nedeterministický, tj. bude hádat, kdy (postupně) číst symboly ze vstupu a kdy a jak redukovat podřetězy v pravých větných formách (vrcholové řetězy v zásobníku), a to počínaje vstupním slovem tak, aby bylo dosaženo kořene gramatiky, právě když vstup je větou v . Důkaz: Necht' = (N, , P, S) a položme = ({q,r}, , N {}, , q, , {r}), kde je nově přidaný symbol a kde je definována takto: 1. (q, a, ) = {(q, a)} pro všechna a , 2. je-li A , pak (q, , ) obsahuje (q, A) , 3. (q, , S) = {(r, )}. Ú mluva: každé níže uvedené odvození je pravým odvozením. Nyní zformulujme a dokažme implikaci "" v (**). Indukcí vzhledem k n tedy ukažme tvrzení (všimněme si, že jen říká, že Ay je pravá větná forma ­ viz úmluva): S Ay n xy (q, xy, ) | (q, y, A) (1) Báze, tj. n = 0 je triviální ­ neudělá žádný krok. Předpokládejme, že (1) platí pro všechna n < n. Pak můžeme psát Ay y n-1 xy. Mohou nastat 2 případy: Je-li , pak = x a (q, xy, ) | (q, y, ) | (q, y, A). Je-li , pak lze psát = Bz, kde B je nejpravější neterminál. Podle indukčního předpokladu máme, že S Bzy n-1 xy implikuje (q, xy, ) | (q, zy, B). Jelikož (q, zy, B) | (q, y, Bz) je možná posloupnost kroků (čtení do zásobníku), dostáváme celkem, že (1) platí. Konečně (q, , S) | (r, , ), a tedy L( ) L(). Abychom ukázali obrácenou inklusi (tj. implikaci "" v (**)), dokažme indukcí vzhledem k n tvrzení (q, xy, ) | n (q, y, A) Ay xy (2) Báze indukce, n = 0, platí triviálně. Pro indukční krok předpokládejme, že (2) platí pro všechna n < m. Pokud symbol na vrcholu zásobníku je neterminál, pak jistě musel být poslední krok proveden na základě pravidla redukce (viz bod 2 v definici automatu ) ­ na vstupu neterminály nejsou. Můžeme tedy psát (q, xy, ) | m - 1 (q, y, ) | (q, y, A), kde A je pravidlo z P. Pokud se v řetězu vyskytuje nějaký neterminál, pak dle indukčního předpokladu máme y xy. Celkem tedy dostáváme Ay y xy, čímž je (2) dokázána. Nyní specializací (2) dostaneme, že (q, w, ) | (q, , S) implikuje S w. Jelikož akceptuje w jen pokud (q, w, ) | (q, , S) | (r, , ), dostáváme, že L() L( ), a tedy celkem L() = L( ), čímž je důkaz ukončen. Příklad 3.56. Mějme 0 s pravidly E E +T | T, T T F | F, F (E) | i. Pak rozšířený PDA z lemmatu 3.55 je = ({q,r}, {+, , (, ), i}, {E, T, F, +, , (, ), i, }, , q, , {r}), kde je definována takto (připomeňme, že vrchol zásobníku píšeme vpravo): q a qa a {+, , (, ), i} dle bodu 1 qE +T qE dle bodu 2 qT qE dle bodu 2 qT F qT dle bodu 2 qF qT dle bodu 2 q(E) qF dle bodu 2 qi qF dle bodu 2 qE r dle bodu 3 Všimněme si, že pokud bychom nepřijali konvenci, že vrchol zásobníku píšeme vpravo, museli bychom ve výše uvedené definici funkce místo pravé strany pravidla z P psát méně přehledný zrcadlový obraz , tj. R. Z těchže důvodů jsou v akceptujícím výpočtu pro vstupní slovo i + i i (viz obrázek 3.5) konfigurace psány ve tvaru trojic (stav, obsah zásobníku, vstup) s vrcholem zásobníku vpravo (a to i pro názornost ověření podmínky (*) z úvodu k důkazu lemmatu 3.55). Poznámka 3.57. Na obrázku 3.5 si všimněme, že posloupnost odpovídajících pravidel z 0 použitých při výpočtu v je reverzí posloupnosti pravidel použitých při pravé derivaci vstupní věty v 0. Pokud bychom na základě této posloupnosti postupně konstruovali odpovídající derivační strom, povšimneme si, že konstrukce začíná u jeho (levých) listů a jde směrem ke kořenu; odtud název této techniky ­ nedeterministická syntaktická analýza krok výpočtu odpovídající pravidlo z 0 pro následující krok (q, , i + i i) | i (q, i, +i i) F i | (q, F, +i i) T F | (q, T, +i i) E T | (q, E, +i i) | + (q, E+, i i) | i (q, E + i, i) F i | (q, E + F, i) T F | (q, E + T, i) | (q, E + T, i) | i (q, E + T i, ) F i | (q, E + T F, ) T T F | (q, E + T, ) E E + T | (q, E, ) | (r, ) Obrázek 3.5: Výpočet automatu z příkladu 3.56 pro vstupní slovo i + i i zdola nahoru. Nedeterminismus se objevuje v těchto dvou základních variantách: (1) v konfiguracích, kdy PDA má na vrcholu pravou stranu nějakého pravidla a volí zda redukovat tuto pravou stranu na odpovídající neterminál nebo zda číst ze vstupu ­ viz výše např. (q, E + T, i), kde lze nejen provést uvedené čtení symbolu `*', ale též redukci dle E E +T). Tuto situaci nazýváme konfliktem typu čtení versus redukce; (2) v konfiguracích, kdy PDA má na vrcholu takový řetěz, že jsou možné alespoň dvě různé redukce (tj. redukce podle různých pravidel); jako příklad může opět sloužit výše uvedená (q, E + T, i), kde lze redukovat jak E +T na E, tak i příponu tohoto řetězu, tj. T , na (shodou okolností opět) E. Tuto situaci nazývýme konfliktem typu redukce versus redukce. Variantu (1) lze obecně charakterizovat existencí jak pravidla A , tak i B (spolu s existencí například S Az a S Bz), kdežto pro (2) je typická existence pravidel A a B (spolu například s S Az a S Bz). Současný výskyt obou typů konfliktů je samozřejmě v konfiguraci PDA též možný. Co se nedeterminismu týče, je tedy vidět, že zatímco u analýzy shora dolů se omezuje na případ, kdy máme volit, kterou z pravých stran nahradit neterminál na vrcholu zásobníku, je u analýzy zdola nahoru jeho povaha poněkud košatější. 3.3 Vlastnosti bezkontextových jazyků 3.3.1 Uzávěrové vlastnosti V této části uvedeme některé uzávěrové vlastnosti CFL a ukážeme, jak je lze použít k důkazu, že nějaký jazyk je, nebo není CFL. Díky vztahu CFG a PDA (viz část 3.2) lze v níže uvedených důkazech použít jak bezkontextových gramatik, tak i zásobníkových automatů. V dalším textu Ä2 značí třídu všech bezkontextových jazyků a připomeňme, že pokud není řečeno jinak, vždy předpokládáme, že gramtika je redukovaná. Věta 3.58. Ä2 je uzavřena vzhledem k operaci (1) sjednocení, (2) zřetězení, (3) iteraci a (4) pozitivní iteraci. Důkaz: Necht'CFL Li , i = 1, 2 je generován CFG i = (Ni , i , Pi , Si ), tj. Li = L( i ). Bez újmy na obecnosti můžeme předpokládat, že N1 N2 = (v opačném případě lze například k N2 vytvořit abecedu dvojníků N2 = {A | A N2}). (1) Jazyk L = L1 L2 je generován gramatikou = (N1 N2 {S}, 1 2, P1 P2 {S S1, S S2}, S), kde S je nový symbol. Pak každá derivace v musízačínat použitím bud'S S1 nebo S S2, přičemž podmínka N1 N2 = zaručuje, že při použití S S1 (resp. S S2) lze v dalším derivování používat jen pravidla z P1 (resp. P2). Formální důkaz, že L( ) = L( )1 L( )2 (tj. obě inkluse) je ponechán čtenáři. (2) Jazyk L = L1.L2 je generován gramatikou = (N1 N2 {S}, 1 2, P1 P2 {S S1S2}, S), kde S je nový symbol. (3) Jazyk L = L 1 je generován gramatikou = (N1 {S}, 1, P1 {S SS1 | }, S), kde S je nový symbol. (4) Jazyk L = L+ 1 je generován gramatikou = (N1 {S}, 1, P1 {S SS1 | S1}, S), kde S je nový symbol. Formální důkazy ad (2) ­ (4) jsou opět ponechány čtenáři. Příklad 3.59. Ukažme, že jazyk L1 = {am1 bm1 . . . amn bmn | n 0, mi 0, 1 i n} je CFL. Stačí si uvědomit, že L1 lze obdržet iterací jazyka L = {ambm | m 0}, který je CFL, tj. L1 = L. Věta 3.60. Ä2 není uzavřena vzhledem k operacím (1) průniku a (2) doplňku. Důkaz: (1) Mějme jazyky L1 = {anbncm | m, n 1} a L2 = {ambncm | m, n 1}. Oba tyto jazyky jsou CFL (například L1 je generován CFG s pravidly S S1C, S1 aS1b | ab, C Cc | c ). Kbyby Ä2 byla uzavřena vzhledem k operaci průniku, pak i L1 L2 = {anbncn | n 1} musel být bezkontextový, což však není ­ viz příklad 3.26. (2) Neuzavřenost Ä2 vůči doplňku plyne okamžitě z její uzavřenosti na sjednocení, neuzavřenosti na průnik a z De Morganových pravidel: pro libovolné L1, L2 platí L1 L2 = (L1 L2), tj., kdyby Ä2 byla uzavřena na doplněk, musela by být uzavřena i na průnik ­ spor. Věta 3.61. Ä2 je uzavřena vzhledem k průniku s regulárním jazykem. Důkaz: L Ä2 značí, že existuje PDA = (Q1, , , 1, q1 0 , Z0, F1), takový, že L = L() a R regulární značí, že existuje (bez újmy na obecnosti deterministický) konečný automat = (Q2, , 2, q2 0 , F2), takový, že R = L( ). Abychom ukázali, že L = L R Ä2, sestrojme PDA , takový, že L = L( ). Položme = (Q , , , , q0, Z0, F ), kde 1. Q = Q1 × Q2, 2. q0 = q1 0 , q2 0 3. F = F1 × F2 a 4. ( p, q , a, Z) obsahuje ( p , q , ) def 1(p, a, Z) obsahuje (p , ) a 2(q, a) = q Zřejmě platí w L( ) w L() L(). Příklad 3.62. Ukažme, že L = {w {a, b, c} | w obsahuje stejný počet symbolů a, b, c} není CFL. K tomu stačí uvážit, že L abc = {anbncn | n 0} není CFL, a tedy ani L není CFL. Věta 3.63. Ä2 je uzavřena vzhledem k substituci. Důkaz: Necht' L je CFL a taková substituce, že pro každé a platí, že (a) = La je CFL. Necht' L = L( ) a La = L( a) pro každé a . Bez újmy na obecnosti předpokládejme, že abecedy neterminálů všech uvedených CFG jsou vzájemně po dvou disjunktní a konstruujme gramatiku takto: 1. neterminály gramatiky jsou sjednocením neterminálů gramatiky a neterminálů všech a, 2. terminály v jsou sjednocením terminálů všech a, 3. pravidla v jsou sjednocením pravidel všech a spolu s pravidly, která vzniknou takto: ke každému A v vytvoříme nové pravidlo, které vznikne tak, že v každý výskyt terminálu a nahradíme neterminálem Sa ­ kořenem gramatiky a a 4. kořenem je kořen . Formální důkaz je opět ponechán čtenáři. Příklad 3.64. Necht'L je množina slov, která obsahují stejný počet výskytů symbolu a a b. Necht'dále La = {0n1n| n 1} a Lb = {wwR| w (0 + 2)}. L lze generovat CFG s pravidly S aSbS | bSaS | , La lze generovat CFG a s pravidly Sa 0Sa1 | 01 a Lb lze generovat CFG b s pravidly Sb 0Sb0 | 2Sb2 | . Je-li f taková substituce, že f (a) = La a f (b) = Lb, pak f (L) lze generovat CFG s pravidly S Sa SSbS | SbSSaS | Sa 0Sa1 | 01 Sb 0Sb0 | 2Sb2 | . Jelikož {a, b}, {ab}, a a a+ jsou CFL, pak uzavřenost Ä2 na substituci implikuje uzavřenost na sjednocení, zřetězení a (pozitivní) iteraci: sjednocení La Lb je substitucí La a Lb do {a, b}, podobně zřetězení La.Lb je substitucí La a Lb do {ab} a L a je substitucí La do a. Tvrzení věty 3.58 bylo tedy možné prezentovat jako důsledek věty 3.63. Důsledek 3.65. Ä2 je uzavřena vůči (1) homomorfismu a (2) inverznímu homomorfismu. Důkaz: (1) Homomorfismus je speciálním případem substituce, vůči níž je Ä2 uzavřena. (2) Důkaz na inverzníhomomorfismus plyne z uzavřenosti Ä2 na substituci, homomorfismus a průnik s regulárním jazykem takto: Mějme libovolný homomorfismus h a k definujme abecedu dvojníků . Dále definujme: 1. substituci (c) = c pro každé c , 2. regulární jazyk L1 = {aw | a , w , h(a) = w} a 3. homomorfismus h1 ( ) takto: h1(a) = a pro všechna a h1(c) = pro všechna c . Zřejmě platí, že h1((L) L 1) = h-1(L). Současně však z uzavřenosti třídy Ä2 vzhledem k výše zmíněným operacím (a faktu, že též jazyk L 1 je regulární) plyne, že pro každý jazyk L Ä2 platí h1((L) L 1) Ä2. Celkem tedy dostáváme h-1(L) Ä2, což jsme měli dokázat. Příklad 3.66. Mějme jazyk L = {ww | w {a, b}} a ukažme, že L není CFL. Před- pokládejme, že L je CFL. Pak ovšem L1 = L a+b+a+b+ by byl též CFL, ale L1 = {ai bj ai bj | i, j 1}, což je jazyk velmi podobný jazyku L2 = {ai bj ci d j | i, j 1} z příkladu 3.27 o němž jsme pomocí pumping lemmatu ukázali, že není CFL ­ pomocí obdobných argumentů lze totéž dokázat i o L1. Pokud bychom k důkazu, že L1 není CFL nechtěli použít pumping lemma, lze L1 re- dukovat přímo na L2 = {ai bj ci d j | i, j 1} takto: Necht'h je homomorfismus definovaný takto: h(a) = h(c) = a a h(b) = h(d) = b. Pak h-1(L1) se skládá ze všech slov tvaru x1x2x3x4 takových, že x1 a x3 jsou z {a, c}+ a mají stejnou délku a podobně x2 a x4 jsou z {b, d}+ a mají stejnou délku. Pak ovšem h-1(L1) abcd = L2, a tedy kdyby L1 byl CFL, musel by L2 být rovněž CFL, což (jak víme z příkladu 3.27) není, tudíž ani L1 nemůže být CFL. Příklad 3.67. Na základě příkladu 3.66 lze ukázat, že jazyk fragmentů pascalských pro- gramů L = {begin var w integer; w = 0; end | w {a, b}+ } není bezkontextový. Necht' h je homomorfismus takový, že h(a) = a, h(b) = b a h(X) = v ostatních případech. Pak h(L) = {ww | w {a, b}+}, a tedy L není CFL. V kompilátorech je tato situace řešena tak, že před vlastní syntaktickou analýzou je text zpracován lexikálním analyzátorem, který identifikátory, jejichž délka není v definici jazyka shora omezena, zpracovává tak, že je redukuje na dvojici fixní délky, kde první komponenta (kterou bere v potaz syntaktický analyzátor) udává, že se jedná o syntaktickou kategorii ,,identifikátor"; druhá komponenta obsahuje odkaz do tabulky, kde je skutečný textový tvar identifikátoru uložen. 3.3.2 Rozhodnutelné vlastnosti a regularita Již v předchozích částech jsme ukázali, že existuje algoritmus, který pro libovolnou danou CFG rozhoduje, zda L( ) = či nikoliv (tzv. problém prázdnosti jazyka je pro CFLs tedy algoritmicky řešitelný ­ rozhodnutelný). Další důležitou vlastnost jsme ukázali tím, že (opět) k libovolné dané CFG lze sestrojit (jazykově) ekvivaletní PDA; jinak řečeno, máme k dispozici (nedeterministický) algoritmus, který rozhoduje problém zda w L( ) či nikoliv (tzv. problém příslušnosti slova je v třídě CFLs rozhodnutelný). Některé další vlastnosti CFL jsme již též ukázali v předchozích částech, mimo jiné i tzv. Pumping lemma pro CFL, které nám v některých případech (spolu s eventuelním využitím uzávěrových vlastností) umožní dokázat, že daný jazyk není bezkontextový. I následující věty jsou de facto důsledkem Pumping lemmatu pro CFL. Věta 3.68. Ke každé CFG lze sestrojit čísla m, n taková, že L( ) je nekonečný právě když existuje slovo z L( ) takové, že m < |z| n. Důkaz: Předpokládejme, že je v CNF. Pak dle Pumping lemmatu pro CFL (viz 3.24) existují čísla p, q s vlastnostmi popsanými v tomto lemmatu. Položme m = p a n = p +q. 1. : Jestliže z L( ) je takové slovo, že p < |z| p + q, pak lze psát z = uvwxy (vx = ) a uvi wxi y L( ) pro všechna i 0. Tedy L( ) obsahuje nekonečně mnoho slov tvaru uvi wxi y, je tedy nekonečný. 2. : Necht'L( ) je nekonečný. Pak obsahuje i nekonečně mnoho slov délky větší než p ­ tuto množinu slov označme M. Zvolme z M libovolné takové slovo z, které má minimální délku a ukažme, že musí platit p < |z| p + q. Kdyby |z| > p + q, pak (opět dle Pumping lemmatu pro CFL) lze z psát ve tvaru z = uvwxy, kde vx = , |vwx| q a uvi wxi y L( ) pro všechna i 0. Tedy specielně pro i = 0 máme, že uwy L( ) a současně |uwy| < |uvwxy|. Přitom však (díky |uvwxy| > p + q a |vwx| q) platí, že |uwy| > (p + q) - q = p; tedy uwy M, což je spor s volbou z jako slova z M s minimálnídélkou. Celkem tedy musíbýt |z| p+q. Poznámka 3.69. Naše dosavadní poznatky o (ne)prázdnosti a (ne)konečnosti CFL lze sumarizovat takto: existují algoritmy, které pro libovolný daný CFL L určí, zda L je (a) prázdný, (b) konečný, nebo (c) nekonečný. Algoritmus pro problém ad (a) byl podán v 3.9. Problém ad (b) resp. ad (c) lze rozhodovat tak, že postupně pro všechna slova w taková, že p < |w| p + q (a těch je jen konečně mnoho nad konečnou abecedou ) testujeme, zda w L( ) či nikoliv (pomocí ekvivaletního PDA). Pokud nalezme w takové, že w L( ), pak L( ) je nekonečný, v opačném případě je konečný. Následující vlastnost charakterizuje ty CFL, které nejsou regulární a po ní uvedené tvrzení ilustruje jednu z aplikací GNF. Definice 3.70. Necht' = (N, , P, S) je CFG. Ř ekneme, že má vlastnost sebevlo- žení, jestliže existují A N a u, v + taková, že A + uAv. CFL L má vlastnost sebevložení, jestliže každá gramatika, která jej generuje, má vlastnost sebevložení. Věta 3.71. CFL L má vlastnost sebevložení, právě když L není regulární. Důkaz: 1. ( P Q ukazujeme jako Q P): Je-li L regulární, pak jej lze generovat regulární gramatikou a žádná regulární gramatika vlastnost sebevložení nemá. 2. (opět P Q ukazujeme jako Q P): Necht' L je generovatelný nějakou CFG, která nemá vlastnost sebevložení a ukažme, že pak L musí být regulární. Zmíněnou CFG lze převést na gramatiku = (N, , P, S) v GNF, která opět nemá vlastnost sebevložení a L = L( ). Označme n = card(N) a d = max{||; A a P, A N}. Nyní ukažme platnost tohoto tvrzení: v žádné levé větné formě v nemůže být více než n d výskytů neterminálů. (*) S X X jeden krok odvození d-1 cesta délky větší než n (od koře- ne k nejlevějšímu neterminálu) terminály neterminály (>n.d) nejlevější neterminál větné formy Obrázek 3.6: Derivační strom větné formy ­ gramatika v GNF Abychom to ukázali, předpokládejme opak, tj. existuje takové, S je levá derivace v a obsahuje více než n d výskytů neterminálů. Při každém odvozovacím kroku se zvýší počet výskytů neterminálů nejvýše o d - 1, což pro naše značí, že v derivačním stromu pro (viz obrázek 3.6) má cesta od kořene k nejlevějšímu listu označenému neterminálem (tj. k nejlevějšímu neterminálu v ) délku větší než n. To však znamená, že alespoň dva z vrcholů na této cestě musí být označeny týmž neterminálem, řekněmě A. To ovšem značí, že A + uAv, kde u i v jsou neprázdná, což je však spor s tím, že nemá vlastnost sebevložení. Tím jsme dokázali tvrzení (*). Jestliže se v libovolné levé větné formě v vyskytuje nejvýše n d neterminálů, pak L( ) lze generovat regulární gramatikou = (N , , P , S ), kde ˇ N = { | N, || n d}, ˇ S = S a ˇ je-li A a P, a , N, pak A a P pro každé takové, že || n d. Je zřejmé, že L( ) = L( ) a je regulární gramatika. Zdůrazněme, že existence tvrzení o vlastnosti sebevložení charakterizující ty CFLs, které nejsou regulární, rozhodně neimplikuje existenci algoritmu, který by uměl pro libo- volný daný CFL jazyk L rozhodovat, zda L tuto vlastnost má, či nemá; v dalším textu bude ukázáno, že neexistuje takový algoritmus, který by pro L rozhodoval, zda existuje regulární jazyk R takový, že L = R (dokonce neexistuje ani algoritmus, který by rozhodoval, zda L = ). 3.4 Deterministické zásobníkové automaty 3.4.1 Definice DPDA a jejich základní vlastnosti Definice 3.72. Ř ekneme, že PDA =(Q, , , , q0, Z0, F) je deterministický (DPDA), jestliže jsou splněny tyto podmínky: 1. pro všechna q Q a Z platí: kdykoliv (q, , Z) = , pak (q, a, Z) = pro všechna a ; 2. pro žádné q Q, Z a a {} neobsahuje (q, a, Z) více než jeden prvek. Ř ekneme, že L je deterministický bezkontextový jazyk (DCFL, stručněji též deterministický jazyk), právě když existuje DPDA takový, že L = L(). Podmínka 1 vylučuje možnost volby mezi krokem nezávislým na vstupním symbolu (-krokem) a krokem, kdy se ze vstupu čte. Podmínka 2 říká, že jak v případě čtecího kroku, tak i pro -krok, neexistuje více než jedna varianta, jak dále pokračovat. Lemma 3.73. Ke každému DPDA lze sestrojit DPDA takový, že Le() = L() Důkaz: Tvrzení se dokáže stejně jako analogické tvrzení věty 3.39, část 2. ( ). Z uvedené konstrukce je okamžitě vidět, že je-li daný deterministický, pak i simulující jeho činnost je deterministický. Poznámka 3.74. Poznamenejme, že obrácené tvrzeník tvrzení3.73 obecně neplatí(důvody, jak uvidíme, jsou čistě technického, formálního charakteru). Po vyprázdnění zásobníku nemůže totiž žádný PDA (a tedy i DPDA) pokračovat ve výpočtu. Máme-li tedy dán takový jazyk L, že existuje slovo u L a též uv L, v = , pak každý DPDA akceptující prázdným zásobníkem musí po přečtení u akceptovat zastavením s prázdným zásobníkem. Tatáž situace však nastane, dáme-li automatu na vstup slovo uv: pak toto slovo nemůže dočíst do konce, a tedy neakceptuje uv, tedy nerozpoznává L. Příkladem takového jazyka je dokonce konečný (tedy v Chomského hierarchii regulární) jazyk {a, aa}. Pokud naopak L výše uvedenou vlastnost nemá (tj. neexistuje slovo u L takové, že rovněž uv L, v = ), pak říkáme, že L je bezprefixový; z tohoto důvodu tedy DPDA akceptující prázdným zásobníkem nemohou rozpoznávat jazyky, které nejsou bezprefixové. Poznamenejme, že {anbn| n 1} je příkladem bezprefixového CFL ­ tedy rozpoznatelný DPDA prázdným zásobníkem. Zkonstruujte jej! (srv. příklad 3.41) Je zřejmé, že ani technika "testu dna zásobníku" problém v případě DPDA neřeší ­ determinismus neumožňuje hádat, zda byl již přečen poslednísymbol ze vstupu. Povšimněme si však, že pro každý L a je jazyk L.{ } bezprefixový (symbol hraje roli eof, pokud vstup chápeme jako soubor ­ file). V dalším textu tedy budeme u každého DPDA předpokládat, pokud nebude řečeno jinak, že ke konci vstupního slova je přidán znak (tzv. pravá koncová značka) . Formální definici DPDA s pravou koncovou značkou (na vstupu) přenecháváme čtenáři jako cvičení. Definice 3.75. Ř ekneme, že rozšířený PDA = (Q, , , , q0, Z0, F) je determinis- tický (DPDA) jestliže jsou splněny tyto podmínky: 1. Pro žádná q Q, a {} a neplatí card((q, a, )) > 1. 2. Je-li (q, a, ) = , (q, a, ) = a = , pak ani není předponou ani není předponou . 3. Je-li (q, a, ) = , (q, , ) = a = , pak ani není předponou ani není předponou . Poznamenejme, že podmínky 2 a 3 jsou formulovány vzhledem ke konvenci, že v konfiguracích píšeme vrchol zásobníku vlevo, tj. , jsou vrcholové řetězy v zásobníku. Při konvenci s vrcholem zásobníku vpravo bychom museli v podmínkách 2 a 3 místo "předpona" použít "přípona". Z definice 3.75 je vidět, že ve speciálním případě, kdy rozšířený PDA je "obyčejným" PDA, uvedená definice souhlasí s definicí 3.72. Poznamenejme též, že pokud je konstrukce z důkazu lemmatu 3.45 aplikována na rozšířený PDA ,pak výsledkem bude DPDA když a jen když je rozšířeným DPDA. Definice 3.76. (normální forma (D)PDA) Ř ekneme, že DPDA = (Q, , , , q0, Z0, F) je v normální formě jestliže platí: je-li (q, a, X) = (p, ), pak bud'(a) = nebo (b) = X nebo (c) = Y X pro nějaké Y . Identicky lze definovat normální formu i pro (nedeterministický) PDA. Uvedená normálníforma tedy požaduje, aby jediné povolené operace nad zásobníkem byly odstranění vrcholového symbolu ze zásobníku (viz podmínka (a)) nebo přidání jednoho symbolu na vrchol zásobníku (viz podmínka (c)); podmínka (b) povoluje změnit pouze vnitřní stav, a to bez změny zásobníku. Následujícídvě lemmata dokazují, že k libovolnému DPDA (resp. i PDA) lze sestrojit ekvivaletníDPDA (resp. PDA) v normálníformě (důkazy pro PDA jsou kopiemi důkazů pro DPDA a nejsou tedy uvedeny). Prvnílemma říká, že v žádném kroku DPDA nemusí ukládat na zásobník více než jeden symbol, protože namísto uložení řetězu symbolů je možné tento řetěz uložit na zásobník postupně, symbol po symbolu, a to pomocí -kroků. Navazující druhé lemma již konstruuje DPDA v normální formě, tj. ukazuje navíc, že DPDA nikdy nemění vrcholový symbol ­ nanejvýš nad něj jeden symbol přidá (tedy pokud vrcholový symbol není přímo odstraněn). Těmto změnám vrcholového symbolu se vyhneme tím, že DPDA si bude pamatovat vrcholový symbol v konečně stavové řídicíjednotce a požadované změny se budou odehrávat pouze v ní. Lemma 3.77. Ke každému DPDA = (Q, , , , q0, Z0, F) existuje s ním ekvivaletní DPDA = (Q , , , , q0, Z0, F) takový, že je-li (q, a, X) = (p, ), pak | | 2. Důkaz: Je-li (q, aX) = (p, ) takové, že | | 2, označme = Y1 . . . Yn, pro nějaké n 3. Přidejme nové nekoncové stavy p1, . . . , pn-2 a položme (q, a, X) = (p1, Yn-1Yn), (pi , , Yn-i ) = (pi+1, Yn-i-1, Yn-i ) pro 1 i n - 3 a (pn-2, , Y2) = (r, Y1Y2) Automaty a jsou evidentně ekvivaletní ­ jediný rozdíl je v tom, že pokud je ve stavu q a má při čtení symbolu a nahradit vrcholové X řetězem = Y1 . . . Yn a nabýt stavu r, pak to neučiní v jednom kroku, ale v n - 1 krocích. Lemma 3.78. Ke každému DCFL L existuje DPDA = (Q, , , , q0, Z0, F) v nor- mální formě takový, že L = L(). Důkaz: Necht'L = L( ) pro nějaký DPDA = (Q , , , , q0, X0, F ) splňující podmínky kladené na automat lemmatu 3.77. Sestrojíme , který bude simulovat činnost tak, že vrcholový symbol automatu se bude uchovávat v množině stavů automatu . Položme Q = Q × , q0 = q0, X0, F = F × , = {Z0}, kde Z0 je nový symbol a definujme takto: 1. je-li (q, a, X) = (p, ), pak Y položme (q, X, a, Y) = (p, Y, ), 2. je-li (q, a, X) = (p, Y), pak Z položme (q, X, a, Z) = (p, Y, Z), 3. je-li (q, a, X) = (p, Y Z), pak W položme (q, X, a, W) = (p, Y, ZW). Bod 1 říká, že pokud odstraní vrcholový symbol, pak též odstraní vrcholový symbol s tím, že nový vrchol si zapamatuje ve své množině stavů. Bod 2 říká, že pokud změní svůj vrcholový symbol, pak zaznamenává tuto změnu pouze v množině stavů. Konečně 3 říká, že pokud zásobník u roste, pak si odloží příslušný symbol na svůj zásobník. Nyní se snadno ověří (indukcí vzhledem k počtu kroků automatu), že platí: (q0, w, X0) | (q, , X1 X2 . . . Xn) (q0, X0, w, Z0) | (q, X1, , X2 X3 . . . Xn Z0). Tedy L() = L( ). 3.4.2 Uzávěrové vlastnosti deterministických jazyků V řadě (i praktických) aplikací je třeba zjistit, zda daný jazyk L je (anebo není) DCFL. K důkazu, že je DCFL stačí nalézt odpovídající DPDA (alternativně lze zkonstruovat něja- kou tzv. L R gramatiku, kterými se zde však nezabýváme). Obrácená situace, kdy chceme ukázat, že L není DCFL, může být složitější. Pokud by L nebyl ani CFL, můžeme pou- žít pumping lemma, ale často L může být CFL, ale ne DCFL. Jelikož není známo žádné pumping lemma, které by platilo specielně pro DCFL, musíme se spolehnout jen na uzávě- rové vlastnosti. Naštěstí DCFL jsou uzavřeny na některé operace, například vůči doplňku, na něž CFL obecně uzavřeny nejsou. V dalším textu se na třídu všech deterministických bezkontextových jazyků odvoláváme jako na "třídu DCFL". Věta 3.79. Třída DCFL je uzavřena vzhledem k průniku s regulárním jazykem. Důkaz: Konstrukce DPDA akceptujícího průnik CFL L a regulárního jazyka R je iden- tická s konstrukcíz důkazu věty o uzavřenosti třídy CFL vůči průniku s regulárním jazykem (viz 3.61) ­ je-li rozpoznávající L deterministický, je též determistickým i konstruovaný zásobníkový automat rozpoznávající L R. Věta 3.80. Třída DCFL není uzavřena vzhledem k operaci průniku. Důkaz: Snadno se nahlédne, že jazyky L1 a L2 v části (1) důkazu věty 3.60 o neuzavřenosti CFL vůči průniku jsou deterministické. Nyní budeme chtít ukázat, že třída všech DCFL je uzavřena vůči operaci doplňku. V důkazu téže vlastnosti pro regulárníjazyky jsme jednoduše záměnili koncové a nekoncové stavy v odpovídajícím deterministickém konečném automatu. Avšak u DPDA tato technika není takto přímočaře použitelná, a to hned ze dvou důvodů. 1. DPDA nemusí vždy dočíst vstupní slovo až do konce, a to z těchto důvodů: (a) se dostane do takové konfigurace, že další krok není definován nebo (b) se dostane do nekonečného cyklu -kroků, kdy pouze pracuje s (konečným) obsahem zásobníku, aniž by četl ze vstupní pásky. Jinak řečeno, dělá pouze -kroky, přičemž bud' i. jeho zásobník neomezeně roste nebo ii. zásobník neroste neomezeně, ale jeho obsah "cyklí", tj. po jistém počtu kroků se jeho obsah opakuje. Pokud nedočte slovo až do konce, pak toto slovo neníakceptováno a potíž v těchto případech spočívá v tom, že po pouhé záměně koncových a nekoncových stavů by takto modifikovaný DPDA opět slovo nedočetl, tj. nepřijal. 2. DPDA sicedočte slovo až do konce, ale pak může ještě provést jistou posloupnost -kroků, při které prochází jak nekoncovými, tak i koncovými stavy. Zde je problém v tom, že pokud takto akceptuje, pak po záměně koncových a nekoncových stavů by modifikovaný DPDA opět slovo akceptoval. Následující lemma 3.81 odstraňuje problémy typu 1, problém 2 je řešen ve větě 3.82. Lemma 3.81. Ke každému DPDA existuje ekvivalentní DPDA ',který přečte každé vstupní slovo až do konce. Důkaz: Potíž ad 1a odstraníme celkem snadno. Pokud by nedočetl slovo proto, že vyprázdní svůj zásobník, použijeme techniku "test dna zásobníku" (viz důkaz věty 3.39 a poznámka 3.40), tj. 'bude mít své vlastní dno Z0 nad nějž si uloží dno Z0 simulovaného automatu. Jestliže vyprázdní svůj zásobník, ' je schopen číst své lokální dno Z0 a na základě toho přejde do nově přidaného (nekoncového) stavu d, v němž dočte vstup až do konce. Rovněž pro každou kombinaci stavu, vstupního symbolu (včetně ) a vrcholu zásobníku, pro kterou není definován další krok, dodefinujeme tento krok přechodem do stavu d. Problémy ad 1b vyžadujíponěkud více úsilí.Označme s = card(Q), t = card( ) a r = max{| |; (p, , Z) = (p , ), p, p Q, Z } - 1. Tedy r udává maximum, o kolik symbolů se může zásobník zvětšit při jednom -kroku. Nyní ukažme platnost tohoto tvrzení: zásobník neomezeně roste při -krocích (*) během nějaké posloupnosti -kroků se jeho délka zvětší o více než r.s.t (*) : evidentní (roste-li zásobník nade všechny meze, pak vzroste i o více než r.s.t). (*) : jestliže během nějaké posloupnosti -kroků zásobník povyroste o více než r.s.t, pak lze z této posloupnosti konfigurací vybrat (pod)posloupnost všech konfigurací tako- vých, že při přechodu od i-té k i + 1-ní konfiguraci zásobník vzroste nad úroveň, kterou měl v i-té konfiguraci (rostoucí posloupnost vzhledem k délce zásobníku). Tato vybraná posloupnost má jistě délku větší než s.t (viz význam konstant r, s, t). . . . . . . . . . . . . .. . . k1 k2 výška zásobníku -kroky >r.s.t Obrázek 3.7: Vybraná podposloupnost konfigurací při -krocích To ovšem značí, že mezi vybranými konfiguracemi existují alespoň dvě konfigurace k1 a k2, které se shodují svým stavem a svým vrcholovým symbolem, přičemž délka zásobníku je v k2 větší než v k1 ­ viz obrázek 3.7. Jelikož je deterministický, pak posloupnost kroků, kterou prováděl mezi k1 a k2, bude dělat i nadále, a to ad infinitum. Tedy zásobník poroste nade všechny meze, čímž jsme dokázali tvrzení (*). K detekci chování typu 1(b)i stačí tedy kontrolovat, zda se během nějaké nepřetržité posloupnosti -kroků nezvětší délka zásobníku o více než r.s.t. Tuto kontrolu zabezpečíme tak, že do konečně stavové řídicí jednotky přidáme čítač c1, který může nabývat (konečně mnoha) hodnot z intervalu 0,r.s.t a s nímž simulující pracuje takto: ˇ kdykoli se přečte symbol ze vstupu, c1 se nastaví na 0; ˇ při každém -kroku se c1 zvětší/zmenší o hodnotu, o kterou se zvětšila/zmenšila délka zásobníku; ˇ místo záporných čísel c1 nabývá hodnoty 0; ˇ pokud by měl c1 nabýt hodnoty větší než r.s.t, pak simulující přejde do "záchyt- ného stavu d (nově přidaný nekoncový stav ­ viz tento důkaz, část ad 1a), v němž dočte vstup až do konce. Tím je tedy odstraněn problém ad 1(b)i. Nyní se zabývejme možnostmi detekce situací ad 1(b)ii, tj. když během nekonečné posloupnosti -kroků zásobník neroste neomezeně. Jinak řečeno, jeho délka nepřesáhne určitou mez. V průběhu této posloupnosti zásobník nemůže vzrůst o více než r.s.t, jinak by totiž rost nade všechny meze ­ viz tvrzení (*). Necht'tedy při této posloupnosti -kroků zásobník nikdy neklesne pod úroveň h, a tedy nikdy nevzroste nah úroveň h + r.s.t. To však značí, že nejpozději za s.(t + 1)r.s.t kroků se musí dostat do alespoň dvou konfigurací, které se shodují svým stavem i (celým) obsahem zásobníku nad hranicí h. Pro detekci chování typu 1(b)ii tedy přidáme další čítač c2, který může nabývat hodnot z intervalu 0, s.(t + 1)r.s.t a který bude uchovávat počet provedených -kroků: jestliže bude vynulován čítač c1, nastavíme na 0 i čítač c2 a při každém -kroku zvětšíme c2 o jedničku. Pokud by mělo dojít k přetečení c2, přejde simulující DPDA opět do záchytného stavu d, v němž dočte vstup až do konce. Formální popis simulujícího rozšířeného oproti o možnost testu dna (tj. nový počáteční stav, nové dno zásobníku Z0 a záchytný stav d) a o čítače c1 a c2 je vynechán a lze jej nalézt v doporučené literatuře. Věta 3.82. Třída deterministických bezkontextových jazyků je uzavřena vůči doplňku. Důkaz: Mějme libovolný DCFL L a bez újmy na obecnosti předpokládejme, že L = L(), pro nějaký DPDA = (Q, , , , q0, Z0, F) splňující podmínky lemmatu 3.81. Sestrojme DPDA , který má rozpoznávat doplněk jazyka L. Idea konstrukce: bude simulovat činnost ,přičemž musíme mít na zřeteli problém 2 uvedený v diskusi před lemmatem 3.81. Stavy budou nyní dvojice z Q × {p, n, f }, kde smyslem druhé komponenty ve stavu q, je zaznamenat mezi dvěma čtecími kroky (které mohou být proloženy posloupností -kroků), zda prošel či neprošel koncovým stavem. Pokud prošel od posledního čtení vstupního symbolu koncovým stavem, pak = p, v opačném případě = n (neprošel koncovým stavem). Je-li druhá komponenta p a čte vstupní symbol, pak simuluje krok automatu a v závislosti na tom, zda se tímto krokem dostal do koncového či nekoncového stavu, aktualizuje svoji druhou komponentu na p či n. Je-li druhá komponenta n, pak nejprve změnín na f a pak simuluje krok automatu a opět aktualizuje svoji druhou komponentu na p či n v závislosti na tom, zda nový stav je či není koncový. Formálně definujme DPDA = (Q , , , , q0, Z0, F ), kde 1. Q = { q, | q Q, {p, n, f } } , 2. q0 = q0, p je-li q0 F, q0, n je-li q0 F, 3. F = { q, f | q Q} , 4. je pro všechna q, q Q a a definována takto: (a) je-li (q, , Z) = (q , ), pak (q, p, , Z) = (q , p, ) a (q, n, , Z) = (q , p, ) je-li q F, (q , n, ) je-li q F, (b) je-li (q, a, Z) = (q , ), a , pak (q, n, , Z) = (q, f , Z) a (q, p, a, Z) = (q, f , a, Z) = (q , p, ) je-li q F, (q , n, ) je-li q F. Ukažme nyní, že L( ) je doplňkem L(). Necht'a1a2 . . . an L(). Pak vejde do koncového stavu (někdy) po přečtení an. V tomto případě bude druhá komponenta nastavena na p (a to předtím, než by mohl číst nějaký vstup za an). Tedy nebude akceptovat, tj. schopen vejít do stavu s druhou komponentou f (pokud an je posledním vstupním symbolem). Je-li naopak a1a2 . . . an L(), pak (dle lemmatu 3.81) po přečtení an musí po jisté době přestat dělat -kroky a chtít číst další vstupní symbol. V této situaci je však druhá komponenta rovna n, protože a1a2 . . . an L(). Na základě pravidla 4b v definici bude akceptovat (a to před eventuelním pokusem o čtení dalšího vstupního symbolu). Celkem tedy L( ) = L(). Důsledek 3.83. Každý DCFL je akceptován nějakým DPDA, který v koncovém stavu nedělá žádné -kroky. Důkaz: Tvrzení je implicitně obsaženo v důkazu výše uvedené věty 3.82 ­ v žádném koncovém stavu (tj. s druhou komponentou rovnou f ) není možný žádný -krok ( není pro tento případ definována). Důsledek 3.84. Třída DCFL není uzavřena vzhledem ke sjednocení. Důkaz: Plyne okamžitě z uzavřenosti DCFL vůči doplňku (viz věta 3.82), neuzavřenosti vůči průniku (viz věta 3.80) a De Morganových pravidel. Příklad 3.85. Uzavřenosti DCFL vůči doplňku lze někdy využít k důkazu, že daný CFL není deterministický. Ukažme, L = {anbncn | n 1} není DCFL. Rozborem po případech, kdy w {anbncn | n 1}, se snadno nahlédne, že L je CFL: případ w abc je popsatelný pomocí regulárního jazyka ­ ty jsou uzavřeny vzhledem ke doplňku; případy typu, kdy w abc, ale počet symbolů a je různý od počtu symbolů b atd jsou popsatelné pomocí CFL/PDA. Díky uzavřenosti CFL na sjednocení dostáváme, že L je CFL. L však nemůže být DCFL: kdyby tomu tak bylo, pak by (díky uzavřenosti na doplněk) musel být DCFL i jazyk L = {anbncn | n 1}, který však není ani CFL. Podobně lze ukázat, že například {ww | w {a, b}} je CFL (sestrojte nedetermi- nistický PDA), který však není DCFL. Důsledek 3.86. Třída DCFL tvoří vlastní podtřídu třídy bezkontextových jazyků. Důkaz: Viz L = {anbncn | n 1} z právě uvedeného příkladu 3.85. Kapitola 4 Turingovy stroje a jazyky typu 0 Cílem této kapitoly je definovat a prozkoumat vlastnosti nejsilnějšího z doposud uvažo- vaných výpočetních modelů -- Turingova stroje. Je pojmenován podle matematika Alana Turinga, který ho v roce 1936 definoval. Turingův stroj dokáže realizovat libovolný proces, který lze intuitivně nazvat algoritmem. Ve skutečnosti, jak ukážeme později, je smysluplné definovat pojem algoritmicky řešitelný právě jako řešitelný Turingovým strojem. 4.1 Turingův stroj: model a jeho definice Neformální popis Turingův stroj byl navržen dlouho předtím, než se objevil první počítač. Motivací pro jeho definici byla snaha přesně rozlišit co je a co není vyčíslitelné, tj. co lze a co nelze efektivně vypočítat. Z toho vyplynuly základní požadavky: zaprvé, každý výpočet se musí dát reprezentovat konečným způsobem. Zadruhé, výpočet se má skládat z diskrétních kroků, přičemž každý z nich je mechanicky realizovatelný. Turingův stroj (anglicky Turing machine, zkráceně TM) má konečnou množinu stavů Q, pásku, která je rozdělena na jednotlivá políčka, a hlavu, která se může po pásce pohybovat doleva a doprava, číst a zapisovat symboly. Na každém políčku pásky je zapsán právě jeden z konečně mnoha páskových (pracovních) symbolů. Páska je jednosměrně nekonečná. Na nejlevějším (nultém) políčku je zapsán speciální symbol ,označující levý konec pásky. Na začátku výpočtu je na prvním až n-tém, n 0, políčku pásky zapsán vstupní řetěz (vstupem tedy může být i prázdný řetěz). Ostatních nekonečně mnoho políček napravo od vstupu je prázdných -- tuto skutečnost vyjádříme pomocí speciálního znaku . Výpočet začíná v počátečním stavu q0, přičemž hlava snímá nulté políčko obsa- hující levou koncovou značku . Krok výpočtu spočívá v tom, že stroj v závislosti na momentálním stavu a symbolu snímaném hlavou 1. změní svůj stav (či přesněji může změnit), 2. zapíše symbol na políčko snímané hlavou (čímž přepíše symbol, který tam byl zapsán předtím) a 3. posune hlavu o jedno políčko doprava, nebo doleva. a b a b b . . . konečně stavová řídící jednotka čtecí/zápisová hlava nekonečná vstupní páska Obrázek 4.1: Turingův stroj Způsob, jakým se má změnit stav, přepsat symbol a posunout hlava, předepisuje přechodová funkce . Stroj akceptuje vstupní řetěz, právě když přejde do speciálního akceptujícího stavu qaccept . Stroj zamítá právě když přejde do speciálního zamítajícího stavu qreject. Na některých vstupech může výpočet běžet nekonečně dlouho, aniž by stroj vstupní slovo akceptoval, nebo zamítnul. V takovém případě říkáme, že stroj pro daný vstup cyklí. Formální definice Turingova stroje Formálně, Turingův stroj (TM) je 9-tice = (Q, , , , , , q0, qaccept , qreject ) kde: ˇ Q je konečná množina stavů; ˇ je konečná množina vstupních symbolů; ˇ je konečná množina páskových (pracovních) symbolů, obsahující jakou svou pod- množinu abecedu ; ˇ \ je levá koncová značka; ˇ \ je symbol označující prázdné políčko; ˇ (Q \ {qaccept , qreject}) × Q × × {L, R} je totální přechodová funkce; ˇ q0 Q je počáteční stav; ˇ qaccept Q je akceptující stav; ˇ qreject Q je zamítající stav; Navíc požadujeme, aby Turingův stroj nikdy nepřepsal levou koncovou značku jiným symbolem a aby nikdy neposunul svou hlavu vlevo od políčka obsahujícího levou koncovou značku. Formálně, požadujeme aby pro každé q Q existoval stav p Q takový, že (q, ) = (p, , R). Množina stavů spolu s přechodovou funkcí se někdy souhrnně označuje jako řídící jednotka Turingova stroje. Konfigurace a výpočet Abychom mohli přesně definovat pojem výpočtu, potřebujeme, podobně jako u zásob- níkových resp. konečných automatů, definovat nejdříve pojem konfigurace. Konfigurace obsahuje kompletní informaci o momentálním stavu výpočtu Turingova stroje, tj. o stavu řídící jednotky, o poloze hlavy na pásce a o obsahu pásky. V libovolném okamžiku výpočtu je na pásce zapsán řetěz tvaru y , kde y (má konečnou délku!) a symbol značí nekonečný řetěz . . . I když páska Turingova stroje je nekonečná, dokážeme vždy její obsah jednoznačně popsat konečným řetězem: stačí totiž specifikovat obsah neprázdných políček (a těch je konečně mnoho). Formálně, konfigurace je prvek množiny Q × {y | y } × 0. Konfigurace (q, z, n) specifikuje, že Turingův stroj je ve stavu q, obsah pásky je z a hlava snímá n-té políčko zleva, n 0. Počáteční konfigurace stroje pro vstup w je konfigurace (q0, w , 0). Akceptující konfigurace je každá konfigurace tvaru (qaccept , z, n), kde z , n 0. Podobně zamítající konfigurace je každá konfigurace tvaru (qreject, z, n). Na množině všech konfigurací Turingova stroje definujeme binární relaci krok výpočtu, označujeme | . Pro libovolný řetěz z (i nekonečný) nad abecedou , necht'zn označuje n-tý symbol řetězu z (z0 označuje nejlevější symbol řetězu z). Dále necht'sn b (z) označuje řetěz, který získáme tak, že v z nahradíme symbol zn symbolem b. Pak relace | je definována předpisem (p, z, n) | (q, sn b (z), n + 1) pro (p, zn) = (q, b, R) (q, sn b (z), n - 1) pro (p, zn) = (q, b, L). Analogicky jako v 3.37 definujeme | a | k , resp. | a | k . Výpočet Turingova stroje na vstupu w je posloupnost konfigurací K0, K1, K2 . . . taková, že ˇ K0 je počáteční konfigurace stroje pro vstup w a ˇ Ki | Ki+1 pro všechna i 0. Výpočet může být konečný ale i nekonečný. Stroj akceptuje vstupní řetěz w právě když výpočet na w je konečný a poslední konfigurace výpočtu je akceptující, tj. právě když (q0, w , 0) | (qaccept , z, n). Stroj zamítá vstupní řetěz w právě když výpočet na w je konečný a poslední konfigurace výpočtu je zamítající, tj. právě když (q0, w , 0) | (qreject, z, n). Stroj se zastaví na vstupu w právě když výpočet na w je konečný, tj. právě když akceptuje anebo zamítá w. Samozřejmě, může nastat situace, kdy výpočet na w je nekonečný, tj. stroj vstupní řetěz ani neakceptuje, ani nezamítá. V takovém případě říkáme, že stroj pro vstup w cyklí. Turingův stroj se nazývá úplný, právě když se pro každý vstup zastaví. Jazyk akceptovaný Turingovým strojem označujeme L() a definujeme jej jako množinu řetězů, které akceptuje, tj. L() = {w | akceptuje w}. Speciálně, jestliže je úplný, pak říkáme, že jazyk L() je rozhodovaný strojem nebo že stroj rozhoduje jazyk L(). Příklad 4.1. Navrhněme Turingův stroj rozhodující jazyk L = {anbncn | n 0}, který není bezkontextový. Stroj nejdříve posouvá svou hlavu až na konec vstupního řetězu a kontroluje, zda řetěz zapsaný na pásce je tvaru abc. Přitom vůbec nemění obsah pásky (formálně: zapíše vždy ten symbol, který přečetl). Poté, co hlava přečte první prázdné políčko (formálně: políčko obsahující symbol ), začne se posouvat doleva až na levý konec pásky. Následuje cyklus, ve kterém hlava ,,vymaže" (přepíše symbolem X) jeden symbol a, jeden b, jeden c a vrátí se na levý konec pásky. Pokud vstupní řetěz patří do jazyka L, stroj nakonec vymaže na pásce všechny symboly a, b, c a akceptuje. V opačném případě vstup zamítne. Necht' = (Q, , , , , , q0, qa, qr ), kde Q = {q0, q1, q2, q3, q4, q5, q6, qa, qr }, = {a, b, c}, = {, , X}. Přechodová funkce je určena touto tabulkou: a b c X q0 (q0, , R) (q0, a, R) (q1, b, R) (q2, c, R) (q3, , L) - q1 - (qr , -, -) (q1, b, R) (q2, c, R) (q3, , L) - q2 - (qr , -, -) (qr , -, -) (q2, c, R) (q3, , L) - q3 (q4, , R) (q3, a, L) (q3, b, L) (q3, c, L) (q3, , L) (q3, X, L) q4 - (q5, X, R) (qr , -, -) (qr , -, -) (qa, -, -) (q4, X, R) q5 - (q5, a, R) (q6, X, R) (qr , -, -) (qr , -, -) (q5, X, R) q6 - - (q6, b, R) (q3, X, L) (qr , -, -) (q6, X, R) Symbol "­" v tabulce vyjadřuje, že není podstatné, co se zapíše na uvedené místo (můžeme tam doplnit cokoli vyhovující definici). Výpočet stroje na vstupu a2b2c2 je (q0, aabbcc , 0) | 1 (q0, aabbcc , 1) | 1 (q0, aabbcc , 2) | 1 (q0, aabbcc , 3) | 1 (q1, aabbcc , 4) | 3 (q2, aabbcc , 7) | 1 (q3, aabbcc , 6) | 7 (q4, aabbcc , 1) | 1 (q5, Xabbcc , 2) | 2 (q6, XaXbcc , 4) | 2 (q3, XaXbXc , 4) | 5 (q4, XaXbXc , 1) | 2 (q5, XX XbXc , 3) | 2 (q6, XX X X Xc , 5) | 2 (q3, XX X X X X , 5) | 6 (q4, XX X X X X , 1) | 6 (q4, XX X X X X , 7) | 1 (qa, XX X X X X , 7) Rekursivní a rekursivně spočetné jazyky Jazyk L nazýváme rekursivně spočetný (Recursively enumerable, RE) právě když L = L() pro nějaký Turingův stroj ; rekursivní (Recursive, Rec) právě když L = L() pro nějaký úplný TM . Ke každému rekursivnímu jazyku L existuje Turingův stroj, který ho rozhoduje, tj. výpočet na každém vstupním slovu je konečný. Rekursivně spočetný jazyk musí splňovat slabší podmínku: musí pro něj existovat Turingův stroj, který ho akceptuje, tj. akceptuje každé slovo z L, ale výpočet na slovu nepatřícím do L může být bud'zamítající, nebo nekonečný. Rozhodnutelné, nerozhodnutelné a částečně rozhodnutelné problémy Problém, kdy se má určit, zda řetěz w má vlastnost P, nazýváme rozhodnutelný právě když množina všech řetězů majících vlastnost P je rekursivní, tj. existuje úplný Turingův stroj ,který akceptuje každý řetěz mající vlastnost P a zamítne každý řetěz, který tuto vlastnost nemá ( rozhoduje jazyk obsahující právě všechna ta slova, která mají vlastnost P); nerozhodnutelný právě když není rozhodnutelný; částečně rozhodnutelný (semirozhodnutelný) právě když množina všech řetězů majících vlastnost P je rekursivně spočetná, tj. existuje Turingův stroj, který akceptuje každý řetěz mající vlastnost P (a zamítá anebo cyklí pro řetěz nemající vlastnost P). Namísto ,,problém určit, zda řetěz w má vlastnost P je rozhodnutelný (částečně roz- hodnutelný)" zkráceně říkáme, že vlastnost P je rozhodnutelná resp. že problém P je rozhodnutelný (částečně rozhodnutelný). Ačkoli vlastnost rekursivní resp. rekursivně spočetný vypovídá o množinách, zatímco rozhodnutelnost resp. semirozhodnutelnost je vlastnost problémů, jsou oba pojmy úzce spjaty. Platí mezi nimi tato ekvivalence: P je rozhodnutelný jazyk {w | w má vlastnost P} je rekursivní L je rekursivní problém ,,w ? L" je rozhodnutelný P je semirozhodnutelný jazyk {w | w má vlastnost P} je rekursivně spočetný L je rekursivně spočetný problém ,,w ? L" je semirozhodnutelný Turingovy stroje a funkce Na Turingovy stroje můžeme nahlížet nejen jako na automaty, které akceptují jazyky, ale i jako na zařízení počítající (vyčíslující) funkce na množině řetězů (slov) nad nějakou abecedou, případně též i na množině přirozených čísel. Pro jednoduchost předpokládejme, že přirozená čísla budeme reprezentovat v unární číselné soustavě, tj. číslo i 0 zapíšeme jako řetěz 0i (nulu reprezentujeme prázdným řetězem). Uvažujme funkci arity k; jejich k argumentů i1, i2, . . . , ik můžeme jednoznačně reprezentovat řetězem 0i1 10i2 1 . . . 10ik . Turingův stroj počítá funkci f k 0 0 právě když akceptuje vstupní řetěz 0i1 10i2 1 . . . 10ik a obsah jeho pásky v akceptující konfiguraci je 0m , kde m = f (i1, i2, . . . , ik). Nevylučujeme možnost existence vstupu tvaru 0i1 1 . . . 10ik , který TM zamítne anebo pro který cyklí, resp. který akceptuje, ale nevypočte žádnou hodnotu (obsah pásky není požadovaného tvaru). Podotýkáme, že jeden Turingův stroj může počítat funkci jedné proměnné, jinou funkci dvou proměnných atd. Funkce f k 0 0 se nazývá částečně rekursivní právě když existuje Turingův stroj počítající funkci f ; rekursivní právě když existuje Turingův stroj počítající funkci f a navíc funkce f je totální. Hodnota částečně rekursivní funkce nemusí být definována pro všechny vstupní argu- menty. Všechny běžné aritmetické funkce, jako například součet, násobení, faktoriál, jsou rekursivní. Přirozeným způsobem lze definici rozšířit i pro funkce nad libovolným ji- ným definičným oborem a oborem hodnot. Zejména tedy můžeme definovat fuknce typu × . . . × - nad řetězci (slovy) nad nějakou abecedou , které můžeme považo- vat za (jednosměrné) seznamy znaků abecedy. Takto lze snadno definovat obvyklé funkce zřetězení (slov, seznamů) a další standardní funkce pro práci nad seznamy, jako například heah, tail, cons, append a další. 4.2 Metody konstrukce Turingových strojů Turingův stroj můžeme programovat podobně jako počítač. Tím, že určujeme přechodovou funkci Turingova stroje, píšeme pro něj vlastně program. Abychom byli schopni napro- gramovat i komplikované Turingovy stroje, uvádíme několik triků resp. konceptuálních pojmů, které mohou tento úkol učinit snadnějším. Zapamatování v řídící jednotce Prostřednictvím stavu si Turingův stroj může zapamatovat konečně mnoho různých infor- mací. V takovém případě je vhodné zapisovat (pojmenovat) stav jako uspořádanou dvojici. Hodnota v první složce řídí činnost stroje; ve druhé složce je uložena informace, kterou si stroj potřebuje zapamatovat. Definice Turingova stroje zůstává nezměněna, stav jako uspořádaná dvojice je jenom naše vlastní interpretace (označení). Příklad 4.2. Mějme jazyk L slov nad {a, b}, které začínají a končí stejným symbolem, tj.: L = {xux | x {a, b}, u {a, b} } {a, b}. Turingův stroj přečte první symbol vstupního řetězu a zapamatuje si ho ve svém stavu -- změní stav na q1, a resp. q1, b. Dále posouvá hlavu doprava, dokud nenarazí na prázdné políčko. Posune hlavu o jednu pozici doleva a akceptuje právě když symbol zapsaný na snímaném políčku je shodný se symbolem, který si zapamatoval ve svém stavu. Formálně, = (Q, , , , , , s, qaccept , qreject ), kde Q = {s, qaccept , qreject, q1, a, q2, a, q1, b, q2, b}, = {a, b}, = {, }. Přechodová funkce je určena tabulkou: a b s (s, , R) (q1, a, a, R) (q1, b, b, R) (qreject, -, -) q1, a - (q1, a, a, R) (q1, a, b, R) (q2, a, , L) q1, b - (q1, b, a, R) (q1, b, b, R) (q2, b, , L) q2, a - (qaccept , -, -) (qreject, -, -) - q2, b - (qreject, -, -) (qaccept , -, -) - Označování symbolů Označování symbolů je užitečný trik, který najde uplatnění především v situacích, kdy potřebujeme porovnat jisté skupiny symbolů. Použití techniky ilustruje příklad 4.1. V něm se symbol, který už byl ,,započten", označil (tj. přepsal symbolem X). Jiný způsob užití této techniky ilustruje následující příklad. Příklad 4.3. Necht' L = {w | w {a}, |w| = 2n, n 1}. Turingův stroj akceptující jazyk L může postupovat tak, že označí polovinu symbolů na pásce a druhou polovinu nechá neoznačenu. Realizace je taková, že prochází slovo zleva doprava a každý druhý symbol a přepíše symbolem A. Pak posune hlavu na začátek pásky. V dalším průchodu se stroj znovu snaží přepsat polovinu doposud neoznačených symbolů a atd. Pokud je délka vstupního slova mocninou 2, stroj dojde do situace, kdy na pásce je jenom jeden symbol a a akceptuje. V opačném případě nastane někdy během výpočtu situace, ve které se stroj snaží rozdělit na dvě stejné poloviny řetězec liché délky; stroj zamítne. Formálně, = (Q, , , , , , s, qaccept , qreject ), kde Q = {s,l, n, qaccept , qreject}, = {a}, = {, , A}. Přechodová funkce je určena tabulkou: a A s (s, , R) (l, a, R) (s, A, R) (n, , L) l - (s, A, R) (l, A, R) (k, , L) n (s, , R) (n, a, L) (n, A, L) - k - (k, a, L) (k, A, L) - k (qaccept , -, -) (qreject, -, -) (k, A, L) - Otázka 4.4. Modifikujte stroj tak, aby rozhodoval jazyk L. Násobné stopy Představme si, že Turingův stroj má ,,širokou" pásku, která je rozdělena na k stop, pro libovolné konečné k. Situace pro k = 3 je naznačena na obrázku 4.2. Pracovníabeceda stroje obsahuje k-tice symbolů, jeden znak pro každou stopu. Pro lepší názornost je na obrázku k-tice symbolů zapsána ve svislé poloze a jednotlivé položky jsou odděleny vodorovnou čárou. 1 0 1 1 1 1 1 0 1 1 0 0 1 0 1 Obrázek 4.2: Páska se 3 stopami Příklad 4.5. Sestrojme Turingův stroj, který jako vstup dostane přirozené číslo zapsané v binární soustavě. Akceptuje právě když vstup je prvočíslem. Stroj ,,rozdělí" svou pásku na tři stopy tak, že svou hlavu posouvá doprava a symbol 1 (0) přepíše symbolem 1, , (0, , ). Na druhou stopu postupně píše binárně čísla 2, 3, 4,. . . Pro každé číslo i zapsané na druhé stopě testuje, zda i dělí vstup. Provádí to tak, že od vstupu opakovaně na třetí stopě odečítá i. Na obrázku 4.2 je zachycena situace, kdy TM testuje, zda-li číslo 47 je prvočíslem. Na druhé stopě je zapsáno číslo 5, které už dva krát odečetl od 47 a proto na třetí stopě je zapsáno 37. Podprogramy Podobně jako v programování, je i při konstrukci Turingova stroje výhodné použít ,,mo- dulární" přístup, tedy přístup shora dolů. Turingův stroj dokáže simulovat libovolný typ procedury, s jakou se můžeme setkat v běžných programovacích jazycích, včetně rekursiv- ních procedur a různých způsobů předávání parametrů. Trik je v tom, že můžeme napsat program Turingova stroje, který budeme využívat jako proceduru. Program má specifiko- vaný počáteční a koncový stav. Pro koncový stav není zatím definován žádný přechod. Když Turingův stroj chce zavolat tuto proceduru, udělá to tak, že přejde do jejího počá- tečního stavu. Samozřejmě předpokládáme, že stavy procedury jsou disjunktní se stavy Turingova stroje. Návrat z procedury se realizuje přechodem z koncového stavu procedury do určeného stavu Turingova stroje, který byl například zapsán na pásku jako ,,návratová adresa". 4.3 Modifikace Turingových strojů Jedním z argumentů pro to, aby Turingův stroj byl považován za obecný model výpočtu, je jeho robustnost. Mnohé modifikace TM, které se na první pohled zdají býti silnějšími nebo naopak slabšími, jsou ve skutečnosti výpočtově ekvivalentními, tj. akceptují (i rozhodují) stejnou třídu jazyků. Turingův stroj s obousměrně nekonečnou páskou Jedním z nejjednodušších rozšíření Turingova stroje je obousměrně nekonečná páska. Jak vyplývá z jeho názvu, páska je nekonečná jak směrem doprava, tak i doleva. Jeho výpočtová síla je stejná ve srovnání se základním modelem TM. Turingův stroj simulující TM s obou- směrně nekonečnou páskou bude mít dvě stopy: jedna bude reprezentovat políčka vpravo od políčka, které se čte na začátku výpočtu (včetně tohoto políčka), druhá bude v obráce- ném pořadí reprezentovat políčka vlevo od počátečního políčka. Vztah mezi oběma stroji je naznačen na obrázku 4.3. Políčko, na které ukazuje šipka, bylo čteno na začátku výpočtu. c a b a c c c a b c c c c c a b c c a b a c Obrázek 4.3: Simulace obousměrně nekonečné pásky jednosměrně nekonečnou páskou. Turingův stroj s více páskami Vícepáskový Turingův stroj se skládá z řídící jednotky, která má k hlav na k (jednosměrně nekonečných) páskách; k je pevně dané přirozené číslo. Na začátku výpočtu je vstupní řetěz zapsán na první pásce. Ostatní pásky mají na nejlevějším políčku zapsán symbol (levá koncová značka) a zbylé políčka jsou prázdné (obsahují symbol ). V jednom kroku výpočtu stroj přečte k symbolů zapsaných na políčkách snímaných k hlavami. Na základě této informace, a v závislosti na svém stavu, stroj zapíše nový symbol na každé snímané políčko, změní svůj stav a každou z k hlav bud' posune (doprava nebo doleva) anebo nezmění její pozici. Přechodová funkce k-páskového TM je zobrazení množiny (Q\{qaccept , qreject})× k do množiny Q× k ×{L, R, S}k (symbol S vyjadruje skutečnost, že pozice hlavy se nemění). Příklad 4.6. Sestrojíme dvoupáskový Turingův stroj rozhodující jazyk L = {an bn2 | n 0} . Jazyk L obsahuje slova nad abecedou {a, b} taková, že počet symbolů b je druhou mocninou počtu symbolů a. Výpočet Turingova stroje na vstupu w bude sledovat následové schema: 1. Současně posouvá obě hlavy doprava a na druhou pásku zapisuje symbol A, dokud na první pásce nenarazí na první symbol b (stav q). Druhou hlavu posune na začátek pásky (stav n). 2. Druhá hlava hledá symbol A (stav hA); když ho najde, přepíše ho symbolem B (stav nA) a přesune se na začátek pásky. 3. Obě hlavy se současně posouvají směrem doprava (stav o), dokud druhá hlava nenarazí na první symbol . 4. Druhá hlava se posune na začátek pásky (stav n) a výpočet pokračuje bodem 2. 5. K akceptování dojde, když jsou současně splněny tyto podmínky: (a) obě hlavy současně přečetly symbol a (b) všechny symboly A na druhé pásce byly přepsány symbolem B (toto se ověří ve stavu k). Formálně, = (Q, , , , , , s, qaccept , qreject), kde Q = {q, n, hA, nA, o, k, qaccept , qreject }, = {a, b}, = {, , A, B}. Přechodová funkce je určena takto: (q, ,) = (q, ,, R, R) (nA, b, B) = (nA, b, B, S, L) (q, a, ) = (q, a, A, R, R) (nA, b, ) = (o, b, ,S, R) (q, b, ) = (n, b, , S, L) (o, b, B) = (o, b, B, R, R) (n, b, A) = (n, b, A, S, L) (o, b, A) = (o, b, A, R, R) (n, b, B) = (n, b, B, S, L) (o, b, ) = (n, b, , S, L) (n, b, ) = (hA, b, ,S, R) (o, , ) = (k, , , S, L) (hA, b, B) = (hA, b, B, S, R) (k, , B) = (k, , B, S, L) (hA, b, A) = (nA, b, B, S, L) (k, , ) = (qaccept , , ,S, S) Pro všechny ostatní kombinace (stav, čtené symboly) definujeme hodnotu funkce jako přechod do zamítajícího stavu qreject . Necht' je k-páskový TM. Ukážeme, jak je možno sestrojit (jednopáskový) TM Â,který simuluje výpočet stroje .Páska stroje  bude rozdělena na k stop. Každá stopa reprezentuje obsah jedné pásky stroje .Navíc, každá stopa obsahuje právě jeden speciálně označený symbol indikující, které políčko právě snímá zodpovídající hlava stroje . Na začátku výpočtu si  upraví odpovídajícím způsobem svou pásku. Pro vstup a1a2 . . . an bude mít upravená páska podobu zachycenou na obrázku 4.4. ˇ a1 a2 an ˇ ˇ ˇ Obrázek 4.4: Simulace 4 pásek pomocí jedné. Aby stroj  odsimuloval jeden krok stroje , musí  postupně přečíst každé políčko označené speciální značkou ˇ a označené symboly si zapamatovat ve svém stavu. Formálně,  prochází svou pásku zleva doprava, dokud nenajde všech k značek a ve svém stavu si pamatuje uspořádanou k-tici symbolů. Hlava se vrátí na levou koncovou značku. Po shromáždění všech potřebných údajů  zjistí, který krok by vykonal stroj a realizuje ho tím, že znovu prochází svou pásku. Vždy, když narazí na speciální značku, změní patřičným způsobem obsah políčka a posune značku doleva anebo doprava. Nakonec  opět posune svou hlavu na levou koncovou značku a začíná simulovat další krok stroje . Na rozdíl od předcházející simulace (obousměrně nekonečná - jednosměrně nekonečná páska), je v tomto případě na simulaci jednoho kroku původního stroje potřebných více kroků. Otázka 4.7. Navrhněte TM se třemi páskami, akceptující jazyk z příkladu 4.1. Srovnejte počet kroků, které musí udělat stroj z příkladu 4.1, než akceptuje vstup délky n, a které musí udělat Vámi navržený stroj. Nedeterministický Turingův stroj Rozdíl oproti původnímu (deterministickému) Turingovu stroji spočívá v tom, že pro daný stav a snímaný symbol má nedeterministický stroj obecně několik možností pro následující krok. Každá možnost zahrnuje nový stav, symbol, který se má zapsat na pásku a směr, kterým se má posunout hlava. Nedeterministický stroj akceptuje právě když existuje výpočet (tj. nějaká posloupnost výběru kroků) vedoucí do akceptující konfigurace. Definice 4.8. Nedeterministický Turingův stroj je 9-tice = (Q, , , , , , q0,qaccept , qreject), kde význam všech složek je stejný jako v definici 4.1, s výjimkou přechodové funkce. Ta je definována jako (totální) zobrazení (Q \ {qaccept , qreject}) × 2Q× ×{L,R}. Stejně jako v případě deterministických TM, je možné definovat jazyk pomocí pojmů konfigurace a krok výpočtu; jediná změna je v definice relace krok výpočtu: relace | je definována předpisem (p, z, n) | (q, sn b (z), n + 1) právě když (q, b, R) (p, zn) (q, sn b (z), n - 1) právě když (q, b, L) (p, zn) Výpočet TM na vstupu w si můžeme pro názornost představit jako strom (tzv. výpo- čtový strom), jehož vrcholy jsou konfigurace (kořen je počáteční konfigurace na w) a jednotlivé cesty odpovídají různým výpočtům na w. Stroj akceptuje vstup w právě když ve výpočtovém stromu existuje cesta z kořena do listu odpovídajícímu akceptující konfiguraci. I v tomto případě, i když je to možná poněkud překvapující, se dá navrhnout simulace (deterministickým) Turingovým strojem. Věta 4.9. Pro každý nedeterministický Turingův stroj existuje ekvivalentní deterministický Turingův stroj. Důkaz: Necht' = (Q, , , , , , q0, qaccept , qreject) je nedeterministický TM. Na- vrhneme deterministický TM simulující nedeterministický stroj . Simulace je založena na tom, že stroj prozkoumá všechny výpočty stroje a zjistí, jestli některý z nich obsahuje akcetpující konfiguraci. Když si výpočty stroje na vstupu w představíme jako výpočtový strom, tak prohledání výpočtů znamená vlastně prohledání stromu. Je třeba si ale uvědomit, že z dvou možných způsobů, které přicházejí do úvahy -- prohledávání do hloubky a do šířky -- je jen jeden korektní. Protože výpočtový strom může být nekonečný, můžeme se při prohledávání do hloubky dostat do situace, kdy sledujeme jednu konkrétní, nekonečnou cestu a nikdy se nedostaneme k prozkoumání ostatních cest, z nichž některá může vést do akceptující konfigurace. Stroj bude mít 3 pásky. Prvnípáska obsahuje vstupní řetěz a jejíobsah se v průběhu výpočtu nemění. Na druhé pásce simuluje výpočet stroje .Na třetí pásce si uchovává informaci určující, který vrchol výpočtového stromu právě prohledává. Specifikujeme nejdříve, jakým způsobem stroj reprezentuje informaci na třetí pásce. Každý vrchol výpočtového stromu má nejvýše b následníků, kde b je maximální kardinalita množiny (q, a), b = max{|(q, a)| | q Q, a } . Každý vrchol stromu označíme řetězem nad abecedou b = {1, 2, . . . , b}. Například řetězem 314 označíme vrchol (konfiguraci), do kterého se dostaneme z kořenu (počáteční konfigurace) když si v prvním kroku výpočtu vybereme třetího následníka, v druhém kroku prvního a v třetím kroku čtvrtého následníka (obr. 4.5). Každý symbol v řetězu určuje, kterého následníka si máme vybrat při simulaci dalšího kroku výpočtu. Může nastat situace, kdy symbolu neodpovídá žádný následník ­ v takovém příapdě je řetěz kódem neplatného výpočtu. Kořen stromu je označen řetězem . Informace na třetí pásce stroje je reprezentována právě jako řetěz nad abecedou b. ˇ yysssssssss ,, ˇ1 ˇ2 ˇ3 ttjjjjjjjjjjjjjjjjj $$rrrrrrrr ˇ11 ˇ31 zzuuuuuuuu $$ssssssss ** ˇ32 ˇ111 ˇ311 ˇ312 ˇ313 ˇ314 ˇ1111 Obrázek 4.5: Výpočtový strom a jeho značení Ted'již jsme připraveni popsat výpočet stroje . 1. Na začátku obsahuje první páska vstup w; druhá a třetí páska jsou prázdné. 2. Zkopíruje obsah první pásky na druhou pásku. 3. Na druhé pásce simuluje výpočet na vstupu w, přičemž v každém kroku se rozhoduje podle následujícího symbolu z třetí pásky, kterým směrem pokračovat v simulaci. Když všechny symboly z třetí pásky byly přečteny, nebo řetěz na třetí pásce je kódem neplatného výpočtu, nebo simulovaný výpočet se dostal do zamítající konfigurace, tak pokračuje bodem 4. Když se simulovaný výpočet dostane do akceptující konfigurace, tak akceptuje. 4. Ř etěz na třetí pásce nahradí řetězem, který za ním následuje v lexikografickém uspořádání. Pokračuje bodem 2. (tj. simulací dalšího výpočtu stroje ). Je tedy vidět, že jazyky akceptované strojem a strojem jsou si rovny, což jsme měli dokázat. Poznamejme, že pokud stroj z právě uvedeného důkazu neakceptuje a zamítá, pak simulující stroj může cyklit, což však na akceptovaný jazyk nemá vliv. Důsledek 4.10. Jazyk je rekursivně spočetný právě když je akceptován nějakým nedeter- ministickým Turingovým strojem. Konečně poznamenejme, že tvrzení analogické větě 4.9 by platilo i pro úplný nede- termistický TM a rozhodování jazyků (definici tohoto stroje ponecháváme čtenáři; zejména by v libovolném výpočetním stromu takového stroje neexistovaly žádné nekonečné cesty). Simulující deterministický stroj by pak bylo možno zkonstruovat tak, aby byl rovněž úplný. Turingův stroj s oddělenou vstupní páskou Jedná se o model, ve kterém má stroj dvě pásky: vstupní a pracovní. Vstupní řetězec je zapsán na vstupní pásce, z níž může stroj jen číst (nesmí měnit její obsah). V závislosti na tom, zda se hlava na vstupní pásce může pohybovat jenom doprava resp. oběma směry, hovoříme o on-line resp. off-line Turingových strojích. Zřejmě tato modifikace neovlivní výpočetní sílu TM. Všechny doposud uvažované modifikace byly rozšířeními základního modelu. Následující modely by na první pohled mohly mít méně výpočetních možností než Turingovy stroje; o všech však prokážeme, že jejich výpočetní síla je stejná jako u Turingových strojů. Stroj se dvěma zásobníky Jedná se o Turingův stroj se vstupní páskou, který má místo pracovní pásky dva zásob- níky. Výpočet (jednopáskového) TM dokáže stroj se dvěma zásobníky simulovat takto: do prvního zásobníku si uloží tu část pásky TM, která je vlevo od políčka právě snímaného hlavou, přičemž na vrcholu zásobníku je symbol bezprostředně vlevo od snímaného sym- bolu. Zbývající část pásky si uloží do druhého zásobníku tak, že právě čtený symbol je na vrcholu zásobníku. Pohyb hlavy doleva (doprava) je simulován přesunem vrcholového symbolu prvního (druhého) zásobníku na vrchol druhého (prvního) zásobníku. Například páska (pozice hlavy je naznačena šipkou) a a c a b a c c c a b je simulována zásobníky b a c a a a c c c a b Všimněme si ještě, jakým způsobem stroj manipuluje se zásobníkem. V každém kroku zjišt'uje, jaký symbol je uložen na vrcholu zásobníku a následně bud' tento symbol ze zásobníku odstraní, nebo na vrchol přidá nový symbol. Stroj s dvěma počitadly Obecně, k-počitadlový stroj je Turingův stroj se vstupní páskou a s k pracovními páskami, který navíc splňuje tyto požadavky: ˇ na každou z pracovních pásek může stroj zapisovat jenom jeden ze dvou symbolů: (levá koncová značka) a (symbol pro prázdné políčko), ˇ symbol je na začátku zapsán na levém krajním políčku pracovní pásky a nikdy se nesmí objevit na jiném políčku. Když hlava snímá i-té políčko pracovní pásky, můžeme to interpretovat jako fakt, že stroj má uloženo v paměti celé nezáporné číslo i. Přitom v každém kroku výpočtu stroj testuje, zda číslo uložené na pásce je rovno nule (čte se symbol ) nebo různé od 0 (čte se symbol ). V každém kroku může stroj hodnotu zapamatovaného čísla zvětšit anebo zmenšit (to v případě, že je nenulové) o jedničku tím, že svou hlavu posune doprava nebo doleva. Namísto termínu počitadlo se lze často setkat s termínem čítač (anglicky counter). Mírná modifikace (rozdíl se týká jen způsobu zápisu) počitadlového stroje je známá jako Minského stroj (dle matematika Marvina Minskeho). Formálně lze tento stroj (s k počitadly) definovat jako konečnou posloupnost instrukcí s návěštími (program) tvaru: l0 příkaz0, . . . ,ln-1 příkazn-1,ln stop, kde každá z instrukcí lI příkazi , i 0, n - 1 je tvaru bud' lp ci := ci + 1; goto lq 1 i k, nebo lp if ci = 0 then goto lq else ci := ci - 1; goto lr 1 i k . Počáteční konfigurace , pokud není řečeno jinak, je definována tak, že čítač instrukcí je nastaven na l0, hodnoty počitadel c1, . . . , ck kódují požadovaný vstup. V literatuře je možno se setkat i s dalšími modifikacemi. Všechny mají společné to, že stroj si může do paměti uložit (několik) libovolně velkých čísel, přičemž o každém z nich je schopen zjistit jenom to, jestli je rovno 0 anebo různé od 0. Navíc, v jednom kroku výpočtu může změnit hodnotu každého z čísel maximálně o 1, či jinou, předem danou celočíselnou konstantu. Nás bude zajímat vztah počitadlových a Turingovych strojů. Nejdříve ukážeme, že dvě počitadla se dají simulovat jedním zásobníkem. Jak už víme, Turingův stroj se dá simulovat strojem s dvěma zásobníky. Spojení obou poznatků nám umožní dokázat ekvivalenci Turingovych strojů a strojů s 4 počitadly. Lemma 4.11. Stroj s jedním zásobníkem se dá simulovat strojem s dvěma počitadly. Důkaz: Necht' je stroj s jedním zásobníkem, jehož pracovní abeceda sestává ze sym- bolů Z1, . . . , Zk-1 (tj. stroj má k pracovních symbolů). Předpokládejme, že obsah zásob- níku stroje jeZi1 Zim (vrchol zásobníku je vpravo). Chceme ukázat, jakým způsobem je možné tutéž informaci uložit do jednoho počitadla. K tomu si stačí uvědomit, že na řetěz Zi1 Zim můžeme nahlížet jako na pozičnízápis číslai1km-1+i2km-2+ +im-1k+im v k-adické soustavě. Na druhé straně, v počitadle si stroj pamatuje číslo zapsané v unární soustavě. Proto zásobník Zi1 Zim se dá jednoznačně reprezentovat v počitadle jako číslo j = im + k im-1 + k2 im-2 + + km-1 i1. Dále potřebujeme ukázat, jak stroj s počitadly dokáže simulovat operace nad zásob- níkem, tj. přidání a odebrání symbolu ze zásobníku a přečtení symbolu z vrcholu zásobníku (srovnej s přecházejícím odstavcem). ˇ Přidání symbolu do zásobníku Předpokládejme, že na vrchol zásobníku je přidán symbol Zr . Pak číslo reprezentující tento nový obsah zásobníku je právě j k + r. To znamená, že potřebujeme vynásobit předešlý obsah počitadla číslem k a připočíst k němu r. Proto opakovaně (předpokládáme, že číslo j je uloženo v 1. počitadle a 2. počitadlo je prázdné) ­ 1. počitadlo posune svou hlavu o 1 políčko doleva zatímco ­ 2. počitadlo posune svou hlavu o k políček doprava. Jakmile 1. počitadlo je na dně (čte se symbol ),pak 2. počitadlo obsahuje číslo k j, k němuž lehce (pomocí konečně stavové řídící jednotky, bez manipulace s počitadly) připočteme r (r 1, k - 1 ). ˇ Odebrání symbolu ze zásobníku Z vrcholu je odebrán zymbol Zim a číslo reprezen- tujícízměněný zásobník je j div k. Abychom dosáhli odpovídajícísituaci v počitadle, opakovaně ­ 1. počitadlo posune svou hlavu o k políček doleva a ­ 2. počitadlo posune svou hlavu o 1 políčko doprava. Jakmile 1. počitadlo dosáhne dna, je ve 2. počitadle číslo j div k. ˇ Přečtení symbolu na vrcholu zásobníku V 1. počitadle je uloženo číslo j a na zjištění, který symbol je na vrcholu zásobníku musíme vypočítat j mod k. Toho dosáhneme tak, že kopírujeme obsah 1. počitadla do 2. počitadla a ve stavové jednotce přitom počítáme j mod k. Důsledek 4.12. Každý Turingův stroj lze simulovat strojem s 4 počitadly. Nyní ukážeme, že právě navrženou simulaci je možné ještě zoptimalizovat. Věta 4.13. Každý Turingův stroj lze simulovat strojem s 2 počitadly. Důkaz: Potřebujeme ukázat, že stroj s 4 počitadly se dá simulovat strojem s 2 počitadly. Necht' 4 simulovaná počitadla mají pořadě hodnoty i, j, k,l. Jedno simulující počitadlo může reprezentovat všechny 4 výše uvedené počitadla číslem n = 2i 3j 5k7l (2, 3, 5, 7 jsou prvočísla, a tedy z n lze jednoznačně určit hodnoty i, j, k,l). Nyní zvýšit číslo i, j, k nebo l o 1 znamená násobit číslem 2, 3, 5 nebo 7. K tomu využijeme 2. počitadlo, které nastavíme na nulu a opakovaně ˇ 1. počitadlo posune svou hlavu o 1 políčko doleva zatímco ˇ 2. počitadlo posune svou hlavu o 2 (resp. 3, resp. 5, resp. 7) políček doprava. Jakmile 1. počitadlo je na nule, 2. počitadlo obsahuje číslo 2n (resp. 3n, resp. 5n, resp. 7n). Analogicky snížit i, j, k nebo l o 1 znamená dělit číslem 2, 3, 5 nebo 7. K dokončení zbývá ukázat, jak se provede test na nulu (tzn. jak se zjistí, zda obsah konkrétního počítadla je roven nule nebo různý od nuly). K tomu se obsah 1. počitadla (n) zkopíruje do 2. počitadla a přitom se testuje, zda n mod 2 (resp. n mod 3, resp. n mod 5, resp. n mod 7) je rovno nule. Důsledek 4.14. Libovolný stroj s k počitadlami lze simulovat strojem s 2 počitadly. Upozorněme, že simulace jednoho kroku TM si vyžaduje obrovský počet kroků stroje se 2 počitadly. Stroj s jedním počitadlem je slabší než TM ­ de facto se jedná o speciální případ PDA se zásobníkovou abecedou {Z0, I}, kde Z0 smí označovat pouze dno zásobníku (takto je umožněn test na nulu) a počet symbolů I na zásobníku odpovídá hodnotě počitadla. Jazyky akceptovaných těmito stroji s jedním čítačem se v anglické literatuře nazývají one- counter languages. Konečně upozorněme, že pro vlastní převod libovolného vstupního slova Turingova stroje do počáteční konfigurace stroje s počitadly potřebujeme 3 počitadla; konstrukci zde neuvádíme a lze ji nalézt v literatuře. 4.4 Vlastnosti rekursivních a rekursivně spočetných jazyků Cílem je prozkoumat uzavřenost vůči elementárním operacím , , , a komplementu. V případě prvních čtyř budou důkazové techniky podobné těm, které byly použity při zkoumání uzávěrových vlastností regulárních a bezkontextových jazyků. Věta 4.15. Třídy rekursivních a rekursivně spočetných jazyků jsou uzavřeny vzhledem k operacím , , , a . Důkaz: Necht' L1, L2 jsou jazyky akceptovány Turingovými stroji 1, 2. Bez újmy na obecnosti můžeme předpokládat, že 1 a 2 mají disjunktní množiny stavů. Nedeterministický stroj , akceptující L1 L2, dostaneme sjednocením strojů 1 a 2 (obr. 4.6). Stroj bude mít navíc nový počáteční stav. V prvním kroku výpočtu nedeterministicky přejde bud'do počátečního stavu stroje 1, nebo do počátečního stavu stroje 2. V dalším simuluje výpočet zvoleného stroje. ACCE PT//ACCE PT 11 RE J ECT ,, 1 RE J ECT// w // w 66nnnnnnnnnnnnnnn w ** ACCE PT//ACCE PT 11 RE J ECT ,, 2 RE J ECT// '& %$ ! "# ?> =< 89 :; ?> =< 89 :; Obrázek 4.6: Konstrukce TM pro sjednocení dvou jazyků Stroj , akceptující L1 L2 (obr. 4.7), bude mít pásku se třemi stopami. Na první stopě je zapsán vstupní řetěz a její obsah se v průběhu výpočtu nemění. Stroj okopíruje svůj vstup w na druhou stopu a na ní simuluje výpočet 1 na w. V případě, že 1 akceptoval, okopíruje vstup w na třetí stopu a na ní pak simuluje výpočet 2 na w. Jestliže 2 akceptoval, pak též akceptuje. w // w // ACCE PT // XXXXXXXXXXXXX RE J ECT // ACCE PT// RE J ECT ##qqqqqqqqqqqqqqqq ACCE PT // 1 2 RE J ECT // '& %$ ! "# ?> =< 89 :; ?> =< 89 :; Obrázek 4.7: Konstrukce TM pro průnik dvou jazyků Nedeterministický stroj , akceptující L1 L2, bude mít pásku se třemi stopami. Na první stopě je zapsáno vstupní slovo. Stroj překopíruje nějaký (může být i prázdný) prefix vstupního slova na druhou stopu -- délku prefixu určí nedeterministicky. Symboly, které byly okopírovány se na první stopě označkují. Na druhé stopě pak simuluje výpočet 1. V případě, že simulovaný výpočet skončí v akceptující konfiguraci, tak překopíruje na třetí stopu zbylou (neoznačkovanou) část vstupu a simuluje výpočet 2 na řetězu zapsaném na třetí stopě. akceptuje právě když 2 akceptuje. Nedeterministický stroj , akceptující L 1 je zobecněním stroje . Za předpokladu, že stroje 1 a 2 jsou úplné, budou i stroje , , a úplné. To dokazuje platnost věty i v případě rekursivních jazyků. Poslední elementární operací nad jazyky je komplement (doplněk). Vzhledem k této operaci se třídy rekursivních a rekursivně spočetných jazyků chovají rozdílně. Zatímco komplement rekursivního jazyka je vždy rekursivní jazyk, komplement rekursivně spočet- ného jazyka nemusí být rekursivně spočetný. Věta 4.16. Třída rekursivních jazyků je uzavřena vzhledem k operaci komplementu. Důkaz: Necht' L je jazyk akceptovaný úplným deterministickým Turingovym strojem = (Q, , , , , , q0, t,r). Stroj co­, akceptující jazyk co­L = - L, získáme tak, že všude v definici přechodové funkce zaměníme navzájem akceptující stav qaccept a zamítající stav qreject (obr. 4.8). Protože je úplný, bude i co­ úplný. RE J ECT // w // w // ACCE PT 11 RE J ECT -- ACCE PT // co­ '& %$ ! "# _^ ]\ XY Z[ Obrázek 4.8: Konstrukce TM pro komplement rekursivního jazyka Poznamenejme, že pokud stroj z předchozího důkazu není úplný, pak jazyk L(co­) nemusí být roven co­L. Stačí uvážit slovo w, na kterém cyklí. Pak i co­ na w cyklí, a tedy w L(co­). Současně však w co­L. Z uvedené úvahy samozřejmě ještě nevyplývá, že třída rekursivně spočetných jazyků není uzavřena vůči komplementu. Věta 4.17. Necht'jazyk L i jeho komplement co­L jsou rekursivně spočetné. Pak jazyky L a co­L jsou rekursivní. Důkaz: Předpokládejme, že 1 a 2 jsou Turingovy stroje akceptující pořadě jazyky L a co­L. Sestrojíme Turingův stroj , který bude na vstupu w současně simulovat výpočet 1 na w i výpočet 2 na w. Formálně, stroj bude mít dvě stopy, jednu pro každý simulovaný výpočet. střídavě simuluje jeden krok výpočtu stroje 1 (na první stopě) a jeden krok výpočtu stroje 2 (na druhé stopě). akceptuje vstup, právě když ho akceptuje 1 a zamítá vstup, právě když ho akceptuje 2. Protože každý řetěz w patří bud'do jazyka L anebo do jazyka co­L, výpočet se pro každý vstup zastaví. Proto L je rekursivní. Rekursivita jazyka co­L plyne z věty 4.16. Poznamejme, že výše uvedená věta je známa jako Postova věta a je též uváděna jako tvrzení: L je rekursivní L a co­L jsou rekursivní. Platnost tohoto tvrzení je vzhledem k právě dokázané větě 4.17 a větě 4.16 zřejmá. Důsledkem uzavřenosti třídy rekursivně spočetných jazyků k operaci komplementu by byla rovnost tříd rekursivních a rekursivně spočetných jazyků. V následující kapitole (věta 5.6) ukážeme, že tyto dvě třídy nejsou stejné, a proto třída rekursivně spočetných jazyků není uzavřena na komplement. Věty 4.16 a 4.17 mají i další zajímavé důsledky. Například, že pro jazyk L a jeho komplement co­L může nastat jen jedna z těchto tří možností: 1. oba jazyky L a co­L jsou rekursivní; 2. žádný z jazyků L a co­L není rekursivně spočetný a 3. jeden z jazyků L a co­L je rekursivně spočetný ale není rekursivní, druhý není rekursivně spočetný. 4.5 Turingovy stroje a jazyky typu 0 Cílem této části je ukázat, že gramatiky typu 0 (též známé jako frázové gramatiky) jsou výpočetně ekvivalentní Turingovým strojům. Jinými slovy, že třída jazyků generovaných gramatikami typu 0 je právě třída rekursivně spočetných jazyků. I když oba formalismy jsou stejně expresivní, rozdíl mezi nimi je ve způsobu, jakým popisují uvedenou třídu jazyků. Zatímco TM je ve své podstatě návodem, jak rozpoznat, zda dané slovo patří do jazyka, tak formální gramatika je návodem, jak vytvořit slovo patřící do jazyka. První z následujících dvou lemmat prokazuje, že každá gramatika typu 0 generuje rekursivně spočetný jazyk; druhá pak opačnou implikaci. Lemma 4.18. Necht'L je jazyk generovaný gramatikou typu 0. Pak L je rekursivně spo- četný. Důkaz: Necht' L je jazyk generovaný gramatikou = (N, , P, S) typu 0. Sestrojíme nedeterministický Turingův stroj akceptující jazyk L. Stroj bude mít dvě stopy. Na první stopě je zapsán vstupní řetěz a její obsah se v průběhu výpočtu nemění. Na druhé stopě simuluje odvození v a je na ní zapsána (do daného okamžiku vygenerovaná) větná forma gramatiky . inicializuje obsah druhé stopy na S a pak opakovaně provádí tyto kroky: 1. Nedeterministicky vybere pozici i v řetězu zapsaném na druhé stopě. Přesněji, počí- naje nejlevějším políčkem pásky, bud'posune hlavu doprava anebo zvolí momentální pozici. 2. Nedeterministicky zvolí pravidlo gramatiky . 3. Je-li podřetězem řetězu , začínajícím na pozici i, pak nahradí řetězem . V případě, že | | < ||, ,,přisune" zbývající část řetězu tak, aby nově vytvořený řetěz byl zapsán na za sebou následujících políčkách. V situaci | | > || je naopak zapotřebí zbývající část řetězu ,,odsunout", aby vznikl prostor pro zapsání celého řetězu . 4. Porovná vstupní řetěz, zapsaný na prvé stopě, s nově vytvořeným řetězem na druhé stopě. V případě rovnosti akceptuje, v případě neshody pokračuje bodem 1. Lehce se prokáže, že každý řetěz vytvořený na druhé stopě je větnou formou gramatiky a naopak, že každou větnou formu gramatiky je možno popsaným způsobem vytvořit. Proto L( ) = L() = L. Lemma 4.19. Necht'L je rekursivně spočetný jazyk. Pak L je generován gramatikou typu 0. Důkaz: Předpokládejme, že L je akceptován deterministickým Turingovym strojem = (Q, , , , , , q0, qaccept , qreject ). Naším cílem je zkonstruovat gramatiku takovou, že slovo w se dá odvodit v , právě když w je akceptováno strojem . Proto odvození v gramatice musí nějakým způsobem simulovat výpočet stroje. Simulace je založena na tom, že v gramatice vygenerujeme dvě kopie slova w nad abecedou a nad druhou z nich v každém kroku odvození simulujeme jeden krok výpočtu stroje .Pokud stroj neakceptuje, odvození nikdy nepovede k terminálnímu řetězu. Formálně je = (N, , P, S), kde N = {S, S , K} Q (( {})× ). Pro lepší názornost rozdělíme množinu pravidel do 3 skupin podle toho, ve které fázi odvozování je možno tato pravidla aplikovat. I Na začátku odvození potřebujeme vygenerovat nějaké slovo w a jeho kopii (nad kterou se pak bude simulovat výpočet stroje ).Proto budeme jako neterminály používat uspořádané dvojice x, y, podobně jako tomu bylo u TM s více stopami. Posloup- nost takových neterminálů můžeme pak chápat jako dva řetězy zapsané nad sebou. Abychom mohli se spodním řetězem pracovat jako s konfigurací TM, přidáme neter- minály odpovídající počátečnímu stavu stroje a levé koncové značce. Dále, abychom měli možnost rozpoznat, který symbol je poslední, přidáme na konec neterminál K. 1. S q0, S 2. S a, aS pro každé a 3. S K. Aplikací pravidel 1-3 dokážeme v vygenerovat z počátečního neterminálu S řetěz (pro lepší pochopení jsou uspořádané dvojice zapsány svisle) q0 a1 a1 a2 a2 an an K II Větná forma odvozena aplikací pravidel 1-3 obsahuje dvě informace. Na horní stopě je zapsáno slovo w . Obsah dolní stopy spolu se symbolem q0 určují počá- teční konfiguraci výpočtu na w (hlava snímá políčko bezprostředně vpravo od neterminálu určujícího stav). Druhá skupina pravidel umožní simulovat výpočet na w. Přesněji, jestliže | je krok výpočtu stroje a () je větná forma obsahující na spodní stopě konfiguraci (), pak pravidla z druhé skupiny umožní odvození . 4. px, a x, b q pro každé x {}; a, b ; p, q Q takové, že (p, a) = (q, b, R) 5. y, cpx, a qy, cx, b pro každé x, y {}; a, b, c ; p, q Q takové, že (p, a) = (q, b, L) 6. pK , bqK pro každé b ; p, q Q takové, že (p, ) = (q, b, R) 7. y, cpK qy, c, bK pro každé y {}; b, c ; p, q Q takové, že (p, ) = (q, b, L) Jestliže akceptuje vstup a1 an, pak (q0, w , 0) | (qaccept , Z1 . . . Zs , i) Použitím pravidel 4-7 můžeme v gramatice odvodit q0 a1 a1 a2 a2 an an K a1 Z1 ai-1 Zi-1 qaccept ai Zi as Zs K kde an+1 = . . . = as = . III Aplikací pravidel z prvních dvou skupin se dá v odvodit řetěz obsahující neterminál qaccept právě když akceptuje slovo w zapsané na první stopě řetězu . Třetí skupina pravidel umožní odvodit z terminální řetěz. Přesněji, neterminály určující stav a konec (K) přepíšeme na . Neterminál -- uspořádanou dvojici -- přepíšeme na symbol z první komponenty dvojice. 8. Zqaccept qaccept Z pro všechna Z N 9. qaccept a, x aqaccept pro všechna a , x 10. qaccept , x qaccept pro všechna x 11. qaccept K Množina pravidel gramatiky je tvořena právě pravidly 1-11. Věta 4.20. Třídy jazyků, které lze generovat gramatikami typu 0, resp. akceptovat Turin- govymi stroji, jsou si rovny a tvoří právě třídu rekursivně spočetních jazyků. Pozorný čtenář si jistě v důkazu věty 4.19 povšimne, že libovolný rekursivně spočetný jazyk je tedy generovatelný gramatikou, která obsahuje právě jedno-pravidlo ­viz pravidlo 11 (nejedná se však o pravidlo typu S , kde S se nevyskytuje na žádné pravé straně v pravidlech gramatiky ­ srv. definicí pojmu je bez -pravidel). 4.6 Lineárně ohraničené automaty a jazyky typu 1 Výsledky prezentované v předchozí části ukazují, že rekursivně spočetné jazyky je možné popsat dvěma formalismy: prostřednictvím Turingových strojů a gramatik typu 0. Z vý- sledků předcházejících kapitol víme, že podobnou možnost máme i pro regulární jazyky (konečné automaty a regulárnígramatiky) a bezkontextové jazyky (zásobníkové automaty a bezkontextové gramatiky). Zbývá najít protějšek kontextových gramatik. Ukážeme, že jím jsou Turingovy stroje se speciálním omezením na velikost pásky -- tzv. lineárně ohraničené automaty. Lineárně ohraničený automat (anglicky Linear Bounded Automaton), zkráceně LBA, je jednopáskový nedeterministický TM, který nikdy neopustí ta políčka, na kterých byl umístěn vstup. Formálně, lineárně ohraničený automat je 10-tice = (Q, , , ,, , , q0, qaccept , qreject ) kde symboly Q, , , , , , q0, qaccept , qreject mají stejný význam jako u nedetermi- nistického TM. \ je pravá koncová značka. Podobně jako u TM požadujeme, aby LBA nikdy nepřepsal levou (pravou) koncovou značku jiným symbolem a aby nikdy neposunul svou hlavu vlevo (vpravo) od políčka obsahujícího levou (pravou) koncovou značku. Definice konfigurace, relace kroku výpočtu a jazyka L() zůstávají stejné jako u nedeterministického TM. Název LBA je odvozen z následujícího faktu. Uvažme ty nedeterministické TM , pro které existuje taková konstanta k , že pro každý vstupní řetěz w je pozice hlavy v každé konfiguraci každého výpočtu na w nanejvýš k |w|. Zřejmě každý LBA spl- ňuje uvedenou vlastnost. Naopak, ke každému TM uvedené vlastnosti se dá (technikou podobnou té, kterou jsme použili při simulaci k-páskového Turingova stroje jednopásko- vým) skonstruovat ekvivalentní LBA. Alternativně tedy možno definovat LBA jako TM s lineárně ohraničeným prostorem. O LBA říkáme, že je deterministický, právě když pro každé q Q a a je množina (q, a) jednoprvková. Není známé, zda třída jazyků akceptovaných deterministickými LBA je vlastní podtřídou třídy jazyků akceptovaných lineárně ohraničenými automaty. Víme, že každý jazyk akceptovaný nedeterminickým lineárně ohraničeným automatem se dá akceptovat deterministickým Turingovým strojem. Velikost pásky, kterou potřebuje takovýto Turingův stroj však může být až exponenciální funkcí délky vstupního slova a ne jenom lineární (viz konstrukce v 4.3). Náš zájem o LBA byl dán skutečností, že akceptují právě třídu kontextových jazyků. Důkaz tohoto tvrzení je podobný jako důkaz tvrzení, že gramatiky typu 0 akceptují právě třídu rekursivně spočetných jazyků. Lemma 4.21. Necht'L je jazyk generovaný kontextovou gramatikou. Pak L je akceptován nějakým lineárně ohraničeným automatem . Důkaz: Automat konstruujeme podobně jako v důkazu lemmatu 4.18 s tím rozdílem, že nepovolíme, aby délka řetězu na druhé stopě někdy přesáhla délku vstupního řetězu. Korektnost konstrukce plyne z faktu, že pokud S = w0 w1 w2 wn , tak pro každé i = 1, . . . , n je |wi-1| |wi |. Stroj má proto dostatek prostoru na to, aby odvození vstupního řetězu, pokud existuje, našel. Lemma 4.22. Necht' je lineárně ohraničený automat. Pak existuje kontextová gramatika generující jazyk L(). Důkaz: Důkaz tohoto tvrzení je nepatrnou modifikací důkazu lemmatu 4.19. Modifikace je nutná proto, že pravidla 10 a 11 nejsou kontextová. Změny doznajípravidla skupiny I, kdy první a poslední neterminál generovaného řetězu v sobě ponesou informaci o tom, že jsou prvním resp. posledním neterminálem. Neterminál, určující stav odpovídající konfigurace LBA, se stane součástí neterminálu pro obsah políčka. Věta 4.23. Třídy jazyků, které lze generovat kontextovými gramatikami, resp. rozhodovat lineárně ohraničenými automaty, jsou si rovny. Důležitou vlastností lineárně ohraničených automatů je, že každý LBA můžeme transformovat na ekvivalentní úplný Turingův stroj. Věta 4.24. Každý kontextový jazyk je rekursivní. Důkaz: Necht'L je jazyk akceptovaný lineárně ohraničeným automatem = (Q, , , ,, , , q0, qaccept , qreject ). Zkonstruujeme úplný LBA takový, že L() = L. Tím dokážeme tvrzení věty. Konstrukce je založena na pozorování, že počet různých konfigurací, které se mohou vyskytnout ve výpočtu na vstupu w je konečný a jejich počet závisí jenom na délce slova w a na definici stroje .Když tedy stroj slovo w akceptuje, pak nutně existuje akceptujícívýpočet naw,jehož délka nepřesáhne počet různých konfigurací(v opačném případě se v něm nutně musí objevit dvě stejné konfigurace a vynecháním úseku mezi nimi skonstruujeme kratší akceptující výpočet). Proto stroji postačuje simulovat výpočet stroje jenom do délky rovné počtu různých konfigurací. Konfigurace stroje v sobě nese informaci o stavu stroje, o obsahu pásky a o pozici hlavy. Počet různých konfigurací, které se mohou vyskytnout ve výpočtu na vstupu w délky n, je proto |Q| | |n (n + 2) . Dále platí, že funkci |Q|| |n (n +2) můžeme zhora ostře ohraničit funkcí cn pro vhodně zvolené přirozené číslo c. Počet symbolů, které potřebujeme na zápis libovolného čísla z intervalu 0, . . . , cn - 1 v c-ární číselné soustavě, nikdy nepřesáhne n. LBA bude na vstupu w pracovat takto. Svoji pásku rozdělí na dvě stopy. Na horní stopě zůstane zapsán vstup w, na druhou zapíše číslo 0 (v c-ární číselné soustavě). Pak na horní stopě simuluje výpočet na w, přičemž za každý odsimulovaný krok připočte k číslu, zapsanému na spodní stopě, jedničku (stále v c-ární číselné soustavě). Pokud akceptuje (zamítne) vstup w, pak i akceptuje (zamítne). Když dojde k ,,přeplnění" spodní stopy, tak zamítne. Výpočet LBA na libovolném vstupu w se zastaví bud' proto, že simulovaný výpočet dosáhl akceptující resp. zamítající konfiguraci, nebo proto, že délka simulovaného výpočtu přesáhla hranici c|w|. Jestliže tedy akceptuje, pak existuje výpočet na w takový, že jeho simulace přivede k akceptování. Naopak, jestliže w ,pak žádný výpočet na w nemůže být akceptující. LBA je úplný, a proto jazyk L je rekursivní. V následujícíkapitole prezentujeme důkazovou techniku (tzv. metodu diagonalizace), která dovoluje dokázat, že ne každý rekursivní jazyk je nutně kontextový. V podstatě všechny jazyky, které považujeme za ,,přirozeně definované", jsou kontextové. Pro úplnost ještě uved'me, jaké jsou uzávěrové vlastnosti třídy kontextových jazyků. Věta 4.25. Třída kontextových jazyků je uzavřena vzhledem k operacím , , , a kom- plementu. Důkaz: Platnost tvrzení pro operace průniku, sjednocení, zřetězení a iterace se dokáže úplně stejným způsobem jako pro rekursivní jazyky (věta 4.15). Důkaz pro komplement není tak přímočarý. Techniku použitou v důkazu věty 4.15 nemůžeme na LBA aplikovat. Problém je v tom, že LBA je definován jako nedetermi- nistické výpočetní zařízení, a tedy pouhou záměnou akceptujícího a zamítajícího stavu bychom nezískali automat pro komplement jazyka (viz podobnou argumentaci pro nedeter- ministické konečné resp. zásobníkové automaty). Ve skutečnosti je důkaz uzavřenosti třídy kontextových jazyků na komplement dosti komplikovaný, a proto jej zde neuvádíme. Kapitola 5 Nerozhodnutelnost Cílem této kapitoly je poskytnout odpověd'na následující otázky: 1. Existuje jazyk (problém), který není rekursivně spočetný (částečně rozhodnutelný)? 2. Existuje jazyk (problém), který je rekursivně spočetný (částečně rozhodnutelný), ale není rekursivní (rozhodnutelný)? Ukážeme, že odpověd'na obě otázky je kladná. Z toho pak plyne další otázka: 3. Které problémy, týkající se jazyků Chomského hierarchie, jsou resp. nejsou rozhod- nutelné? Než začneme s úvahami o (ne)rozhodnutelnosti, projdeme dva okruhy problémů. Churchova teze ozřejmuje význam našich úvah o nerozhodnutelnosti. Na jejím základě můžeme totiž tvrzení o nerozhodnutelnosti konkrétního problému interpretovat jako tvrzení o neexistenci algoritmu řešícího uvažovaný problém. Podkapitola pojednávající o kódování TM je spíše technická a využijeme ji v následujících konstrukcích. Univerzální Turingův stroj je pro nás zajímavý hned ze dvou hledisek. Jednak jako technický nástroj, který můžeme využít tehdy, když potřebujeme, aby TM simuloval nějaký jiný TM. Z druhé strany, univerzální TM zdůrazňuje tu skutečnost, že Turingův stroj může být, podobně jako reálný počítač, programován. 5.1 Churchova teze Cílem A. Turinga v době, kdy definoval svůj model (později nazvaný na jeho počest Tu- ringův stroj), bylo rozlišit, co je a co není efektivní procedura, respektive jak bychom to řekli dnes, co je a co není algoritmus. Intuitivně, algoritmus je množina pravidel, které jednoznačně předepisují, co máme dělat pro to, abychom po konečném počtu kroků ob- drželi požadovaný výsledek. Problém exaktní a jednoznačné definice pojmu algoritmus se stává klíčovým v okamžiku, když chceme dokázat, že neexistuje žádný algoritmus pro řešení konkrétního problému. Otázku existence resp. neexistence algoritmu si matematici kladli dávno (vzpomeňme alespoň problém kvadratury kruhu). Zvláště aktuální se stala v souvislosti s formulací známého Hilbertova programu začátkem našeho století. To vedlo k několika definicím pojmu algoritmus, z nichž jedna vychází právě z TM. Je známá pod názvem Churchova teze1 (či též jako Church-Turingova teze): Každý proces, který lze intuitivně nazvat algoritmem, se dá realizovat na Turingově stroji. Obsahem Churchovy teze je tedy ztotožnění pojmů ,,algoritmicky řešitelný" a ,,řešitelný Turingovym strojem". Protože pojem algoritmicky řešitelný je jenom intuitivním pojmem, nemůže být obsah Churchovy téze formálně dokázán. Existuje však celá řada argumentů podporujících platnost teze, z nich uved'me například tyto: 1. Kromě TM bylo navrženo i mnoho jiných formalizmů; zmiňme alespoň ˇ Postovy systémy ˇ Minského stroje ˇ -rekursivní funkce ˇ -kalkul ˇ while programy. Důležité je, že všechny se ukázaly, co se jejich výpočtové sily týče, jako vzájemně ekvivalentní. 2. Třída jazyků akceptovaných TM a třída funkcí počítaných TM jsou velice robustní. Různá omezení resp. rozšíření základního modelu nemají žádný vliv na tyto třídy (viz předcházející kapitola). 3. Doposud není znám žádný algoritmus, který by se nedal realizovat na Turingově stroji. Více podrobností může čtenář najít literatuře věnované teorii vyčíslitelnosti. Z pohledu Churovy teze je tedy problém2 algoritmicky řešitelný, právě když je rozhodnutelný. V dalším textu budeme i nadále pracovat s Turingovými stroji, avšak budeme na ně nazírat především jako na algoritmy. 5.2 Kódování TM a univerzální TM Základní vlastnost, ze které budeme v následujících úvahách vycházet, je schopnost Turin- gových strojů simulovat jiné Turingovy stroje, jejichž popis obdrží jako část svého vstupu. První problém, na který při simulaci narazíme, je otázka vhodného kódování (zápisu) Turingových strojů. Požadujeme, aby pro každý stroj (a případně i slovo nad nímž má pracovat) byl definován jeho kód (jako slovo nad nějakou abecedou) a aby z kódu stroje (a případně i slova nad nímž má pracovat) byla jednoznačně dekódovatelná informace o jeho stavech, symbolech, přechodové funkci, . . . (a případně i slovo nad nímž má pracovat). Kódování Turingových strojů Necht' = (Q, , , , , , q0, qaccept , qreject). Bez ztráty na obecnosti můžeme před- pokládat, že množina stavů Q = {q0, q1, q2, . . . , qn}, přičemž q1 = qaccept je akceptující 1. Alonzo Church byl americký matematik 2. Jak je zřejmé již z kontextu, pod pojmem problém zde máme na mysli úlohu, kde řešením je bud 'ANO, nebo NE. Jakékoliv jiné úlohy, tj. takové, kde možných řešení je víc než jenom 2, můžeme nahlížet jako funkce a aplikovat na ně pojmy rekursivní resp. rekursivně spočetný. a q2 = qreject zamítající stav. Podobně = {X0, . . . , Xz}, přičemž X0 = je levá koncová značka a X1 = je symbol pro prázdné políčko. Symbolům pro směr pohybu můžeme též přiřadit synonyma L = S1 a R = S2. Pak hodnotu přechodové funkce (qi , X j ) = (qk, Xl , Sm) můžeme jednoznačně kódovat binárním řetězem 0i 10j 10k 10l 10m . (5.1) Binárním kódem Turingova stroje je řetěz 111 kód1 11 kód2 11 11 kódr 111 , kde kódi je řetězec tvaru 5.1 a kód1, . . . , kódr jednoznačně popisují celou přechodovou funkci stroje 3. Kód stroje budeme označovat . Každý binární řetězec je kódem nanejvýš jednoho Turingova stroje. Některé řetězy nejsou kódem žádného stroje; v takovém případě interpretujeme řetězec jako kód stroje přijímajícího prázdný jazyk. Podobným způsobem můžeme kódovat i vstupní slova stroje -- slovu Xi1 Xik přiřadíme kód 0i1 1 10ik 1. Prázdnému slovu přiřadíme kód . Kód slova w označujeme w . Příklad 5.1. Mějme = ({q0, q1, q2, q3}, {0, 1}, {, , 0, 1, A, B}, , , , q0, q1, q2) s přechodovou funkcí (q0, ) = (q3, , R) (q3, 0) = (q3, A, R) (q3, 1) = (q3, B, L) (q3, A) = (q1, A, L) (q3, ) = (q2, , R) Kódem stroje je = 1111100011001100010010001000010011000100010001000001011 000100001010000101100011001100111 Kódem slova 001101 je 001101 = 00100100010001001000. Univerzální Turingův stroj Zavedené kódování strojů a jejich vstupů nám umožňuje zkonstruovat univerzální Turingův stroj Í takový, že Í akceptuje w def akceptuje w, to jest: L(Í) = { w | akceptuje w }. Jinými slovy, jestliže stroj Í dostane na vstup kód stroje a kód jeho vstupu w (vzájemně odděleny symbolem ), pak akceptuje, právě když akceptuje w. Stroj Í pracuje takto: 3. Poznamenejme, že neklademe žádné podmínky na uspořádání, a proto jeden TM může mít více různých kódů. 1. nejdříve ověří, zda jeho vstup je tvaru {0, 1}{ }{0, 1}. Když není, tak zastaví a zamítne. 2. Í simuluje krok po kroku výpočet stroje na w. Páska stroje Í je rozdělena na tři stopy. Na první stopě si stroj Í udržuje kód simulovaného stroje .Na druhé stopě má zaznamenán aktuální obsah pásky stroje s vyznačenou pozicí hlavy. Třetí stopa slouží na zapamatování aktuálního stavu stroje . Simulace jednoho kroku znamená, že stroj srovnává obsah třetí a relevantní části druhé stopy s obsahem první stopy aby zjistil, jaká akce je předepsána pro aktuální stav a snímaný symbol stroje .Předepsanou akci odsimuluje: změní kód stavu na třetí stopě, přepíše snímaný symbol a posune značku pro pozici hlavy. 3. Í akceptuje (zamítá) právě když se na třetí stopě objeví kód akceptujícího (zamíta- jícího) stavu. Pokud na vstupu w cyklí, pak i Í na vstupu w cyklí. Poznámka 5.2. Na tomto místě (jako i na mnoha jiných v dalším textu) stavíme na Chur- chově tezi. Místo toho, abychom přesně definovali univerzální Turingův stroj (tj. specifiko- vali jeho množinu stavů, přechodovou funkci atd.), popsali jsme jeho činnost jen ,,slovně". Důvod je zřejmý: tento popis je mnohem přehlednější a srozumitelnější, než kdybychom měli k dispozici popis přechodové funkce o délce několika (desítek) stran. 5.3 Diagonalizace Hlavním cílem této kapitoly je prozkoumat, které problémy, vztahující se k formálním jazykům a automatům, jsou resp. nejsou algoritmicky řešitelné. Popíšeme dvě matematické metody, které umožňují o problému dokázat, že není (částečně) rozhodnutelný -- metodu diagonalizace a metodu redukce. Jaký typ problémů je nerozhodnutelný, tj. algoritmicky neřešitelný? Jsou tyto pro- blémy jen ,,teoretické", nebo se s nimi můžeme běžně setkat? První z problémů, který prozkoumáme je formulován takto: máme daný program a přesnou specifikaci, co by tento program měl dělat (např. násobit dvě matice). Potřebujeme verifikovat, zda program sku- tečně dělá to, co od něj očekáváme. Jelikož jak program, tak i specifikace, jsou matematicky přesně definované objekty, přáli bychom si, aby proces verifikace byl pokud možno auto- matizován. Ukážeme, že právě toto je typ problému, který (obecně) není rozhodnutelný, a tedy řešitelný počítačem. Přesněji formulováno, budeme se zabývat problémem příslušnosti pro Turinovy stroje. Pro daný Turingův stroj a slovo w chceme určit, zda slovo w akceptuje, nebo neakceptuje (tj. zamítá w nebo na w cyklí). Jinými slovy, chceme určit, zda slovo w bud'přísluší, nebo nepřísluší jazyku L(). Univerzální Turingův stroj a technika diago- nalizace jsou nástroje, které nám umožní dokázat, že problém příslušnosti pro Turingovy stroje je nerozhodnutelný. Jinak řečeno, dokážeme, že jazyk P P def = { w | stroj akceptuje w} není rekursivní. První idea, jak problém řešit, je použít univerzální stroj Í,kterému na vstup dáme řetěz w . Í simuluje výpočet na w a následně ˇ zastaví a akceptuje právě když se zastaví a akceptuje ˇ zastaví a zamítne právě když se zastaví a zamítne ˇ cyklí právě když cyklí. Lehce ověříme, že L(Í) = P P. Problém příslušnoti je tedy částečně rozhodnu- telný. Protože však stroj Í není úplný, neplyne z jeho existence rozhodnutelnost problému příslušnosti. Na místě je tedy otázka, zda existuje nějaká jiná metoda, která na základě popisu Turingova stroje a jeho vstupu umožní vždy rozhodnout, jak dopadne výpočet stroje na daném vstupu. Ve skutečnosti takováto metoda neexistuje. Pro konkrétní TM a slovo se nám může podařit problém rozhodnout aplikací nějakého heuristického (ad hoc) přístupu, ale obecná metoda, která by poskytla řešení pro libovolnou dvojici stroj, slovo neexistuje. Věta 5.3. Problém příslušnosti pro Turingovy stroje je částečně rozhodnutelný, ale není rozhodnutelný. Částečnou rozhodnutelnost jsme již dokázali. Tvrzení o nerozhodnutelnosti doká- žeme pomocí Cantorovy diagonalizační metody. Tuto metodu poprvé použil matematik Georg Cantor v roce 1873, když se zabýval problémem měření mohutnosti nekonečných množin. Diagonalizací prokázal, že množiny přirozených a reálných čísel mají různou mo- hutnost. Analogickým způsobem můžeme prokázat, že existuje jazyk, který neníakceptován žádným Turingovým strojem. Lemma 5.4. Existuje jazyk, který není rekursivně spočetný. Důkaz: Z předcházejícího víme, že každý řetězec nad abecedou {0, 1} můžeme chápat jako kód nějakého Turingova stroje resp. jako kód nějakého slova. Pro každé x {0, 1} označme x Turingův stroj s kódem x. Podobně wx je slovo, jehož kód je právě x. Rostoucí uspořádání slov4 nad abecedou {0, 1} určuje uspořádání Turingových strojů , 0, 1, 00, 01, 10, 11, 000, . . . a uspořádání slov w, w0, w1, w00, w01, w10, w11, w000, . . . . Snadno nahlédneme, že uvedené uspořádání je natolik jednoduché, že se dá zkonstruovat TM, který pro dané přirozené číslo m vypočte kód m-tého Turingova stroje resp. m-tého slova. Uvažme nyní nekonečnou dvojrozměrnou tabulku (obr. 5.1). Ř ádky tabulky jsou označeny Turingovými stroji v zavedeném uspořádání. Sloupce jsou označeny slovy v zavedeném uspořádání. Na průsečíkui-tého řádku a j-tého sloupce obsahuje tabulka symbol 1, právě když i-tý Turingův stroje akceptuje j-té slovo. Jestliže stroj vstup neakceptuje, pak na uvažované pozici tabulka obsahuje symbol 0. 4. V rostoucím uspořádání slovo menší délky předchází slovu větší délky. Pokud a = a 1 am a b = b1 bm mají stejnou délku, pak a předchází b právě když existuje i takové, že a 1 = b1, . . . , ai-1 = bi-1 a ai < bi . w w0 w1 w00 w01 w10 w11 w000 w001 1 0 1 1 0 1 0 1 1 0 0 1 1 1 0 1 0 0 1 1 1 1 1 0 1 1 0 1 0 00 0 0 0 0 0 1 0 1 1 01 1 0 0 1 0 0 1 1 1 10 0 0 0 1 1 1 0 1 1 11 1 1 0 1 0 1 0 1 0 000 0 1 1 0 0 1 1 1 1 001 1 1 1 1 1 0 0 1 0 ... ... ... Obrázek 5.1: Tabulka obsahující informace o výpočtech Turingových strojů (symboly 1 a 0 jsou rozmístěny náhodně, čistě pro ilustraci.) Zkonstruujeme jazyk D (tzv. diagonální jazyk) nad abecedou {0, 1} využitím prvků, které v tabulce ležína diagonále. Abychom zabezpečili, že jazyk D neníakceptován žádným Turingovým strojem, požadujeme, aby slovo d patřilo do jazyka D tehdy a jen tehdy, když stroj d neakceptuje slovo wd, tj. na průsečíku řádku d a sloupce wd obsahuje tabulka symbol 0. Lehce přijdeme ke sporu: předpokládejme, že existuje nějaký stroj x akceptující jazyk D. Jestliže slovo x patří do jazyka D, pak tabulka obsahuje na pozici (x, wx ) symbol 0 a nemůže být L(x) = D. Naopak, jestliže slovo x nepatří do jazyka D, pak tabulka obsahuje na pozici (x , wx ) symbol 1, a tedy opět nemůže platit L(x) = D. Proto neexistuje žádný TM, který by akceptoval jazyk D. Nyní jsme již připraveni dokázat větu 5.3 o nerozhodnutelnosti problému příslušnosti. Důkaz: věty 5.3 Důkaz věty provedeme sporem. Předpokládejme, že existuje úplný stroj akceptující jazyk P P. Nad vstupním slovem M w stroj pracuje takto: ˇ se zastaví a akceptuje právě když se zastaví a akceptuje w ˇ se zastaví a zamítne právě když se zastaví a zamítne anebo když cyklí na w. Zkonstruujeme nový Turingův stroj (viz obr. 5.2), který pro vstup x {0, 1} 1. zapíše na svou pásku řetěz x x, 2. simuluje výpočet stroje na vstupu x x, 3. akceptuje vstup x, právě když zamítne vstup x x. zamítne vstup x, právě když akceptuje vstup x x. Při konstrukci stroje jsme využili existenci univerzálního TM. Konkrétně, v bodě 2. předepisujeme, aby stroj simuloval jiný stroj, jehož popis dostal jako součást vstupu ­ to ale znamená, že se chová jako univerzální stroj. Pro každé slovo x {0, 1} akceptuje x zamítá vstup x x (podle definice ) RE J ECT // x // x x // ACCE PT 11dddddddddddddddd RE J ECT -- ACCE PT // '& %$ ! "# _^ ]\ XY Z[ Obrázek 5.2: Konstrukce stroje stroj s kódem x zamítá anebo cyklí na vstupu s kódem x (podle předpokladu o ) Speciálně nás zajímá výpočet stroje na vstupu , tj. na vstupu, který je kódem stroje .Tedy dostáváme akceptuje zamítá vstup stroj s kódem zamítá anebo cyklí na vstupu s kódem neakceptuje To je zřejmý spor, a proto náš předpoklad o existenci úplného Turingova stroje musel být chybný. Ještě jednou zopakujme, jakým způsobem jsme dokázali nerozhodnutelnost problému pří- slušnosti. Předpokládali jsme existenci stroje rozhodujícího tento problém. Zkonstruovali jsme stroj (který využíval ) takový, že když dostal na vstup x, tak ho akceptoval jedině tehdy, když stroj s kódem x neakceptoval vstup s kódem x. Nakonec jsme spustili stroj na vstupu . Chování stroje popisuje řádek w w0 w1 w00 w01 w10 w11 w000 w001 ... ... 0 0 0 1 1 0 1 0 1 ... ... ... který vznikl ,,negací" diagonály z tabulky 5.1. Srovnáme-li stroj s libovolným Turingo- vym strojem x , tak vidíme, že jejich chování na vstupu s kódem x se liší: když jeden ze strojů akceptuje, tak druhý neakceptuje a naopak. Problém příslušnosti pro Turingovy stroje je příkladem problému, který je částečně rozhodnutelný, ale není rozhodnutelný. Přirozenou je otázka, zda existuje problém, který není ani částečně rozhodnutelný. Příkladem takového problému je komplement problému příslušnosti. Věta 5.5. Jazyk co­P P def = { w | neakceptuje w} není rekursivně spočetný. Důkaz: Předpokládejme, že jazyk co­P P je rekursivně spočetný. Pak podle věty 4.17 je jazyk P P rekursivní, což je spor. 5.4 Redukce S problémem příslušnosti pro TM úzce souvisí problém zastavení pro TM. Pro libovolný daný TM a libovolné dané slovo w se ptáme, zda výpočet na w je konečný či nikoli. Opět nás zajímá, zda je tento problém rozhodnutelný, tj. zda jazyk P Z def = { w | výpočet na w je konečný } je rekursivní. Věta 5.6. Problém zastavení pro Turingovy stroje není rozhodnutelný. Důkaz: Důkaz provedeme sporem. Předpokládejme, že problém je rozhodnutelný. Pak existuje úplný Turingův stroj akceptující jazyk P Z. Ukážeme, jak s pomocí stroje , můžeme sestrojit úplný Turingův stroj akceptující jazyk P P. Jelikož však jazyk P P není rekursivní, tak předpoklad o rozhodnutelnosti problému zastavení vede ke sporu. Ú kolem stroje je pro daný stroj a slovo w rozhodnout, zda akceptuje w. Stroj pro vstup w pracuje takto (obr. 5.3): 1. simuluje výpočet stroje na vstupu w , 2. v případě, že akceptuje w , tak výpočet na w je konečný. Proto může simulovat výpočet na w a akceptuje právě když akceptuje w, 3. v případě, že zamítá w , tak na w cyklí. Proto zamítne svůj vstup. ACCE PT //ACCE PT 22fffffffffffff RE J ECT ++ RE J ECT // w // // ACCE PT 55llllllllllllllllll RE J ECT )) RE J ECT // '& %$ ! "# 76 54 01 23 76 54 01 23 Obrázek 5.3: Konstrukce stroje Stroj je úplný, protože stroj je úplný a simuluje jen konečné výpočty stroje . Stroj akceptuje jazyk P P, protože platí: akceptuje w stroj akceptuje w a akceptuje w. Metoda, kterou jsme použili v důkazu věty 5.6 je založena na tzv. redukci: problém příslušnosti jsme převedli (redukovali) na problém zastavení tak, že kdybychom měli k dispozici algoritmus řešící problém zastavení (stroj ), pak bychom dokázali sestrojit i algoritmus rozhodující problém příslušnosti (stroj ).Z předcházejícího víme, že takový algoritmus existovat nemůže, a tedy nemůže existovat ani algoritmus rozhodující problém zastavení. Jelikož úplně stejný postup můžeme použít i pro jiné problémy, zformulujeme metodu redukce a její použitelnost obecně. Definice 5.7. Necht'A, B jsou jazyky, A , B . Redukce jazyka A na jazyk B je rekursivní funkce taková, že w A (w) B . V případě existence redukce jazyka A na jazyk B říkáme, že A je redukovatelný (se redukuje) na B a značíme A B. S ohledem na známý vztah mezi pojmy jazyk a rozhodovací problém, můžeme aplikovat pojem redukce i na problémy. Zdůrazněme ještě jednou dvě klíčové vlastnosti redukce: 1. existence úplného Turingova stroje (algoritmu), který pro každé slovo w nad abece- dou vypočte jeho obraz, tj. slovo (w) nad abecedou ; 2. redukce zachovává příslušnost do jazyka (slovo z jazyka A se zobrazí na slovo z jazyka B, slovo nepatřícíjazyku A se zobrazína slovo nepatřícíjazyku B) (obr. 5.4). ˇ ** ˇ ˇ ** ˇ A B ~ }| xy z{ _^ ]\ XY Z[ ~ }| xy z{ _^ ]\ XY Z[ Obrázek 5.4: Redukce Způsob, jakým lze pojem redukce využít při důkazu o (ne)rozhodnutelnosti nějakého pro- blému, je vyjádřen v následující větě. Věta 5.8. Necht'A B. (i) Není-li jazyk A rekursivně spočetný, pak ani jazyk B není rekursivně spočetný. (ii) Není-li jazyk A rekursivní, pak ani jazyk B není rekursivní. Alternativní (a ekvivalentní) formulace věty 5.8 je Necht' A B. (i) Je-li jazyk B rekursivně spočetný, pak i jazyk A je rekursivně spočetný. (ii) Je-li jazyk B rekursivní, pak i jazyk A je rekursivní. Důkaz: (i) Dokážeme alternativu (i). Tvrzení (i) dostaneme kontrapozicí implikace. Předpokládejme, že A B a že B je rekursivně spočetný. Necht' je úplný TM počítající redukci jazyka A na jazyk B. Dále necht'B je TM akceptující jazyk B. Sestrojíme nový TM A akceptující jazyk A a tím dokážeme, že A je rekursivně spočetný. Stroj A pro vstup w (viz obr. 5.5) pracuje takto: 1. simuluje výpočet stroje na vstupu w. Výsledkem simulace je řetěz (w); 2. simuluje výpočet stroje B na vstupu (w); 3. pokud stroj B zastaví a akceptuje (zamítne), pak i A zastaví a akceptuje (zamítne). Když B cyklí, pak i A cyklí. Tedy platí: A akceptuje w B akceptuje (w) (w) B w A (ii) Analogicky jako v předcházejícím případě. Protože však B je rekursivní, existuje úplný TM B, který ho akceptuje. Pak ale i stroj A bude úplný, a tedy jazyk A rekursivní. ACCE PT // w // w // (w) // ACCE PT 22fffffffffffff RE J ECT ++ B RE J ECT // A '& %$ ! "# ?> =< 89 :; ?> =< 89 :; Obrázek 5.5: Konstrukce stroje A Důkaz nerozhodnutelnosti problému P metodou redukce se skládá ze dvou kroků. 1. Zvolíme nějaký problém N, o kterém už bylo dokázáno, že je nerozhodnutelný. 2. Prokážeme, že N P. Nerozhodnutelnost problému P je pak důsledkem věty 5.8. Redukci můžeme, samozřejmě, využít i k důkazu rozhodnutelnosti nějakého problému P. V takovém případě 1. Zvolíme nějaký problém R, o kterém už bylo dokázáno, že je rozhodnutelný. 2. Prokážeme, že P R. Rozhodnutelnost problému P je pak opět důsledkem věty 5.8. Konstrukce redukce A B se skládá z následujících kroků. Necht' A , B . 1. Definujeme funkci . 2. Ověříme, že funkce je rekursivní (například tak, že zkonstruujeme úplný Turingův stroj (tj. algoritmus), který pro každé w vypočte (w)). 3. Ověříme platnost ekvivalence w A (w) B . Otázka 5.9. Který z jazyků P P, P Z hraje v důkazu věty 5.6 roli jazyka A a který roli jazyka B. Jak je definována redukce A na B? Otázka 5.10. Ukažte, že redukovatelnost je tranzitivní, tj. když A B a B C, pak A C. Je redukovatelnost symetrická, tj. plyne z A B platnost B A? 5.5 Další rozhodnutelné a nerozhodnutelné problémy pro TM Doposud jsme se setkali se třemi nerozhodnutelnými problémy, z nichž dva (problém za- stavení a příslušnosti pro TM) byly částečně rozhodnutelné a třetí (komplement problému zastavení) nebyl ani částečně rozhodnutelný. Dále jsme ukázali princip, jak lze pomocí redukce dokázat (částečnou) rozhodnutelnost či nerozhodnutelnost jiných problémů. Apli- kujme nyní tyto poznatky a prozkoumejme další problémy týkající se TM (rekursivně spočetných jazyků). Věta 5.11 (Rozhodnutelné problémy). Následující problémy jsou rozhodnutelné. Pro libovolný daný Turingův stroj rozhodnout, zda (a) má alespoň 1998 stavů, (b) výpočet stroje nad vstupním slovem a1998 je delší než 1998, (c) existuje slovo w takové, že výpočet stroje nad vstupním slovem w je delší než 1998. Věta 5.12 (Semirozhodnutelné problémy). Následující problémy nejsou rozhodnutelné, ale jsou částečně rozhodnutelné. Pro libovolný daný Turingův stroj rozhodnout, zda (a) jazyk L() je neprázdný, (b) jazyk L() obsahuje alespoň 1998 slov. Věta 5.13 (Nerozhodnutelné problémy). Následující problémy nejsou (ani) částečně roz- hodnutelné. Pro libovolný daný Turingův stroj rozhodnout, zda (a) jazyk L() je prázdný, (b) jazyk L() obsahuje nanejvýš 1998 slov, (c) jazyk L() je konečný, (d) jazyk L() = R pro libovolný daný regulární jazyk R, (e) jazyk L() je regulární (tj. zda existuje regulární jazyk R takový, že L() = R), (f) jazyk L() je rekursivní (tj. zda existuje rekursivní jazyk L takový, že L() = L, tj. problém, zda je úplný TM). Důkaz: věty 5.11 Rozhodnutelnost všech uvedených problémů prokážeme tak, že zkonstruujeme úplný TM akceptující právě kódy Turingových strojů majících požadovanou vlastnost. (a) Stroj prochází vstup a testuje, zdali je na některé z pozic příslušejících stavům (viz kódování TM) řetěz tvaru 019980. (b) Stroj má tři pásky. Na třetí pásce si na počátku výpočtu označí 1999 políček. Na druhou pásku zapíše řetěz a1998. Pak na druhé pásce simuluje krok po kroku výpočet stroje s kódem x (x je vstup stroje ) na vstupu a1998. Za každý odsimulovaný krok označí jeden symbol na třetí pásce. Když simulovaný výpočet skončil dříve, než byly označeny všechny symboly na třetí pásce, tak zamítá. Pokud označil všechny symboly, tak akceptuje. (c) Naším cílem je zkonstruovat TM , který pro dané rozhodne, zdali existuje slovo w takové, že výpočet stroje na vstupu w je delší než 1998. Stroj bere postupně slova nad vstupní abecedou stroje v rostoucím uspořádání až do délky 1999. Pro každé slovo simuluje výpočet stroje nad tímto slovem, přičemž si pamatuje počet už odsimulovaných kroků výpočtu. Když délka simulovaného výpočtu přesáhne 1998, tak se zastaví a akceptuje. Když délka výpočtu na žádném z uvažovaných slov nepřesáhne 1998, tak se zastaví a vstup zamítne. Zůstává prokázat korektnost navrženého postupu. Tvrdíme, že když jsme hledané slovo nenašli mezi slovy délky maximálně 1999, tak skutečně neexistuje. Víme, že délka výpočtu na žádném ze slov délky 1999 nepřesáhla hodnotu 1998. To zna- mená, že stroj nikdy nečetl poslední symbol vstupu (na to by potřeboval alespoň 1999 kroků). Průběh výpočtu je tedy jednoznačně určen prefixem délky 1998 a není ovlivněn symboly za tímto prefixem. Důkaz: věty 5.12 (a) Nejdříve dokážeme, že problém neprázdnosti není rozhodnutelný. Navrhneme redukci jazyka P Z (který není rozhodnutelný -- věta 5.6) na jazyk P N def = { | L() = }. Nerozhodnutelnost problému neprázdnosti plyne z věty 5.8. Protože P Z {0, 1, }, P N {0, 1}, tak hledaná redukce je funkce z {0, 1, } do {0, 1}. Slovu x {0, 1, } přiřadí slovo x , přičemž x je kód takto definovaného Turingova stroje. Stroj x pro vstup w {0, 1} pracuje následovně. 1. Jestliže slovo x nepatří do {0, 1}{ }{0, 1}, tak x vstup w zamítne. 2. V opačném případě smaže obsah své pásky a zapíše na ní slovo x. Necht' x = x1 x2. 3. Stroj x simuluje výpočet stroje s kódem x1 na vstupu s kódem x2. 4. Jestliže simulovaný výpočet je konečný, tak x akceptuje. Pokud simulovaný výpočet je nekonečný, tak i výpočet x je nekonečný. Funkce je úplná a je vyčíslitelná (vypočítatelná) Turingovým strojem, což znamená, že je rekursivní. Je důležité si uvědomit, že jazyk akceptovaný strojem x je L(x) = když stroj s kódem x1 na vstupu s kódem x2 cyklí, resp. v případě že x nepatří do {0, 1}{ }{0, 1} {0, 1} když výpočet stroje s kódem x1 na vstupu s kódem x2 je konečný. Funkce zachovává příslušnost do jazyka, protože x P N L(x ) = {0, 1} x = x1 x2, x1, x2 {0, 1} a výpočet stroje s kódem x1 na vstupu s kódem x2 je konečný x P Z Zůstává dokázat, že jazyk P N je rekursivně spočetný. Zkonstruujeme Turingův stroj akceptující jazyk P N. Nabízí se vcelku přímočaré řešení. Chceme-li zjistit, zda daný stroj akceptuje vůbec nějaké slovo, stačí brát všechna možná vstupní slova a simulovat postupně výpočet stroje na každém z nich. Pokud akceptuje nějaké slovo, určitě na něj dříve nebo později narazíme. Potíž je v tom, že dříve než dojde na toto slovo, které by stroj akceptoval, tak se může zkoušet i slovo, na němž cyklí ­ k hledanému slovu se tak nikdy nedostaneme. Potíž můžeme obejít využitím ,,paralelismu". Namísto toho, aby se simuloval vždy jen jeden výpočet stroje , bude stroj simulovat několik výpočtů stroje najednou. Provedeme to tak, že vždy odsimuluje krok jednoho výpočtu, pak krok dalšího výpočtu atd. Předpokládejme libovolné, ale fixní uspořádání slov nad vstupní abecedou stroje . Pracovní páska stroje bude rozdělena na několik úseků oddělených speciálním symbolem $ . V každém úseku je aktuální konfigurace jednoho simulovaného výpočtu. Na počátku má jen jeden úsek a na něm počáteční (nultou) konfiguraci na prvním vstupu stroje .Jeden cyklus spočívá v tom, že prochází svoji pracovní pásku zleva doprava. V každém úseku přepíše konfiguraci jejím následovníkem. Když dojde za poslední úsek, napíše tam počáteční konfiguraci výpočtu na dalším, ještě neprozkoumaném slově. Obsah pracovní pásku stroje po pátém opakování cyklu je schematicky naznačen na obrázku 5.6 (symbol Konfigi j značí j-tou kon- figuraci výpočtu stroje na i-tém vstupu). Pokud se v některém z úseků objeví Konfig1 4 $ Konfig2 3 $ Konfig3 2 $ Konfig4 1 $ Konfig5 0 $ . . . Obrázek 5.6: Paralelní simulace výpočtů akceptující konfigurace (což nastane, právě když jazyk L() je neprázdný), pak stroj akceptuje. Pro vstup takový, že L() = , stroj cyklí. (b) Tvrzení dokážeme nepatrnou modifikací předcházejícího důkazu. Pro nerozhodnutel- nost stačí vzít v úvahu, že jazyk L() obsahuje alespoň 1998 slov tehdy a jenom tehdy, když L(x) = {0, 1}. Pro semirozhodnutelnost stačí modifikovat stroj tak, aby akceptoval až po objevení se 1998 akceptujících konfigurací. Důkaz: věty 5.13 (a) Nerozhodnutelnost problému prázdnosti (anglicky emptiness) dokážeme redukcíjazyka co­P Z (který není rekursivně spočetný -- dokažte!) na jazyk P E, kde P E def = { | L() = }. Redukce je definována podobným způsobem, jako v důkazu nerozhodnutelnosti případu neprázdnosti (věta 5.12, případ (a)). Jediná změna se týká bodu 1.: pokud slovo x nepatří do {0, 1}{ }{0, 1}, pak x vstup w akceptuje. Opět platí, že jazyk L(x ) je bud'prázdný (v případě, že stroj s kódem x1 na vstupu s kódem x2 cyklí) , nebo stroj x akceptuje každé vstupní slovo (to v případě, že výpočet stroje s kódem x1 na vstupu s kódem x2 je konečný, resp. v případě že x nepatří do {0, 1}{ }{0, 1}). Funkce zachovává příslušnost do jazyka, protože x P E L(x) = x = x1 x2, x1, x2 {0, 1} a stroj s kódem x1 na vstupu s kódem x2 cyklí x co­P Z (b),(c) Stejně jako předcházející případ. Jazyk L(x) je bud' prázdný, a tedy obsahuje nanejvýš 1998 slov, resp. je konečný, nebo je nekonečný. (d) Předpokládejme, že problém, zda daný TM a konečný automat akceptujístejný jazyk, je částečně rozhodnutelný. Pak za konečný automat můžeme zvolit automat akceptující prázdný jazyk a dostáváme, že i problém prázdnosti pro Turingovy stroje je částečně rozhodnutelný -- spor. (e) Zvolme jazyk L, který je bezkontextový a není regulárný. Necht' je zásobníkový automat akceptující jazyk L. Chceme dokázat, že jazyk P R def = { | L() je regulární }. není rekursivně spočetný. Důkaz provedeme redukcí jazyka co­P Z na jazyk P R. Hledaná redukce slovu x {0, 1, } přiřadíslovo x , přičemž x je kód takto definovaného Turingova stroje. Stroj x pro vstup w {0, 1} pracuje následovně. 1. Jestliže slovo x nepatří do {0, 1}{ }{0, 1}, tak x pokračuje bodem 4. 2. V opačném případě změní svou pásku na třístopou. Na druhou stopu zapíše slovo x. Necht'x = x1 x2. 3. Stroj x simuluje na své třetístopě výpočet stroje s kódem x1 na vstupu s kódem x2. Jestliže simulovaný výpočet je konečný, tak x pokračuje bodem 4. Pokud simulovaný výpočet stroje s kódem x1 na vstupu s kódem x2 je nekonečný, tak i výpočet x je nekonečný. 4. x simuluje výpočet zásobníkového automatu na vstupu w. 5. Jestliže automat slovo w akceptuje, tak i stroj x svůj vstup w akceptuje. Pokud zamítne, tak i x zamítá. Funkce je úplná a je vyčíslitelná Turingovým strojem, což znamená, že je rekur- sivní. Jazyk akceptovaný strojem x je L(x) = L jestliže výpočet stroje s kódem x1 na vstupu s kódem x2 je konečný resp. v případě že x nepatří do {0, 1}{ }{0, 1}) jestliže stroj s kódem x1 na vstupu s kódem x2 cyklí Funkce zachovává příslušnost do jazyka, protože x P R L(x ) = x = x1 x2, x1, x2 {0, 1} a stroj s kódem x1 na vstupu s kódem x2 cyklí x co­P Z (f) Analogicky jako v případě (e) s tím rozdílem, že jako jazyk L zvolíme jazyk, který je rekursivně spočetný a není rekursivní. 5.6 Postův korespondenční problém V předchozí části jsme zkoumali rozhodnutelnost různých problémů týkajících se Turin- gových strojů. Poznali jsme, že až na několik málo velice jednoduchých problémů, jsou nerozhodnutelné. Přirozenou je proto otázka, co se stane, když v uvedených problémech zaměníme TM nějakým výpočtově slabším zařízením. Překvapujícím(?) je zjištění, že po- kud chceme, aby se problém stal rozhodnutelným, pak ho musíme většinou (až na několik málo již ukázaných výjimek) formulovat pro velice omezenou třídu jazyků: pro determi- nistické bezkontextové, resp. v některých případech až pro regulární jazyky. Shrnutí všech uvažovaných problémů najde čtenář na konci této kapitoly. V předchozí části byl klíčovým důkaz nerozhodnutelnosti problému příslušnosti (věta 5.3). Nerozhodnutelnost všech ostatních problémů byla dokázána redukcí. Obdobnou klíčovou roli v této části sehraje tzv. Postův korespondečníproblém. Postův problém je úzce spjat s problémem zastavení, avšak jeho formulace je pro naše cíle mnohem vhodnější. Formulace Postův korespondenční problém (anglicky Post Correspondence Problem), zkráceně PKP (PCP), lze formulovat takto: jsou dány dva seznamy, A = x1, . . . , xn a B = y1, . . . , yn, neprázdných slov nad abecedou . Seznamy A, B nazýváme instancí (případem) PKP a označujeme A, B . Daná instance PKP má řešení, právě když existuje konečná posloupnost přirozených čísel i1, i2, . . . ik, k 1, taková, že xi1 xi2 xik = yi1 yi2 yik . Posloupnost i1, i2, . . . ik se nazývá řešením PKP. Postův korespondenční problém je formu- lován jako třída problémů rozhodnout pro libovolnou danou instanci PKP, zda má řešení. Příklad 5.14. Necht'A, B jsou seznamy nad abecedou {a, b, c}, A = (b, cbb, ab, c) B = (bbc, b, a, bc). Pro lepší představu si instanci PKP můžeme znázornit jako kostky domina A B = b bbc , cbb b , ab a , c bc Řešením uvedené instance PKP je posloupnost 3,1,2,1,2,4 protože x3x1x2x1x2x4 = y3y1y2y1y2y4 = abbcbbbcbbc. Opět pro lepší představu uvádíme i grafickou prezentaci 3 1 2 1 2 4 | a b | vvvvvv b | rrrrrr c b b | vvvvvv b | rrrrrr c b b | vvvvvv c | | a | b b c | b | b b c | b | b c | Uvedená posloupnost není jediným řešením daného případu; jsou jím např. i posloupnosti 3,1,2,1,2,1,2,4 a 3,1,2,1,2,4,3,1,2,1,2,4 a další. Otázka 5.15. Kolik řešení má instance PKP z předcházejícího problému? Příklad 5.16. Mějme instanci PKP, danou seznamy A, B nad abecedou {0, 1} takto: A = (01, 001, 11) B = (10, 00, 011). Hledané řešení by muselo začínat indexem 2, protože dvojice x1, y1 a též x3, y3 se liší v již prvním symbolu (přesněji: v žádné z těchto dvojic není jedno ze slov předponou druhého). Tím máme | 0 0 1 | zzzzz | 0 0 | Ze seznamu B musíme nyní vybrat slovo, které začíná symbolem 1. Jedinou možností je slovo 10. Dostáváme | 0 0 1 | xxxxx 0 1 | zzzzz | 0 0 | 1 0 | a to je situace shodná s předcházející. Proto tato instantce PKP nemá řešení (neexistuje konečná posloupnost čísel požadovaných vlastností). Jsme tedy schopni pro některé konkrétní případy rozhodnout, zda mají řešení. Jak ovšem uvidíme, nelze napsat algoritmus, který by pro libovolnou instanci PKP rozhodoval, zda má či nemá řešení. Iniciální Postův korespondeční problém Našim cílem je dokázat, že Postův korespondenční problém není rozhodnutelný. Použijeme metodu redukce a sestrojíme redukci problému příslušnosti pro TM (věta 5.3) na PKP. Protože sestrojit hledanou redukci přímo je poměrně (technicky) náročné, zjednodušíme si celý problém následovně. Definujeme iniciální Postův korespondenční problém (zkráceně inPKP) a prokážeme, že pokud je inPKP nerozhodnutelný, tak i PKP je nerozhodnutelný. Pak dokážeme, že inPKP je nerozhodnutelný. Rozdíl ve formulaci inPKP a PKP je v tom, že u iniciálního Postova problému se pro danou instanci A, B ptáme, zda má řešení začínající číslem 1. Přesněji, instance A, B iniciálního Postova korespondečního problému má řešení právě když existuje posloupnost přirozených čísel i1, i2, . . . ik, k 0, taková, že x1xi1 xi2 xik = y1yi1 yi2 yik . Příklad 5.17. Iniciální Postův korespondeční problém pro seznamy A, B z příkladu 5.14 má řešení 122, protože x1x1x2x2 = y1y1y2y2 = bbcbbcbb. Lemma 5.18. Z nerozhodnutelnosti iniciálního Postova korespondečního problému plyne nerozhodnutelnost Postova korespondečního problému. Důkaz: Předpokládejme, že PKP je rozhodnutelný. Dané instanci A, B inPKP přiřadíme instanci C, D PKP tak, že A, B má řešení právě když C, D má řešení. Z rozhodnu- telnosti PKP by tedy plynula i rozhodnutelnost inPKP. Necht'tedy seznamy A = x1, . . . , xn a B = y1, . . . , yn nad abecedou jsou instancí iniciálního Postova problému. Dále necht'$, jsou dva symboly nepatřící do abecedy . Zavedeme homomorfismy hL , hR {$, } definované předpisem: hL (a) def = a, hR(a) def = a pro všechna a (s přirozeným rozšířením ze na ). Položme X1 = hR(x1) Y1 = hL(y1) Xi+1 = hR(xi ) Yi+1 = hL (yi ) pro 1 i n Xn+2 = $ Yn+2 = $ Seznamy C a D nyní vytvoříme takto: C = (X1, . . . , Xn+2) D = (Y1, . . . , Yn+2). Ověřme, že instance C, D PKP má řešení, právě když instance A, B inPKP má řešení: 1. : Necht'řešením instance A, B inPKP je posloupnost i1, i2, . . . ik. Protože hR(x1xi1 xik )$ = hL(y1yi1 yik )$, je posloupnost 1, (i1 + 1), . . . (ik + 1), n + 2 řešením instance C, D PKP. 2. : Necht'řešením instance C, D PKP je posloupnost j1, j2, . . . , jk. Pak nutně musí být j1 = 1 a jk = n + 2. Ř ešením instance A, B inPKP pak bude například posloupnost ( j2 - 1), . . . , ( jl - 1), kde l je nejmenší takové číslo, že jl+1 = n + 2. Nutnost volby l je dána faktem, že dvojice Xn+2, Yn+2 nemá v A, B žádný vzor. Příklad 5.19. Redukcí instance A, B iniciálního PKP A B = ba b , b bb , b abb , bab a dostaneme instanci C, D PKP C D = ba b , ba b , b bb , b abb , bab a , $ $ Řešení 3,4,2 instance A, B odpovídá například řešení 1,4,5,3,6 instance C, D . Poznámka 5.20. Jiná formulace tvrzení uvedeného v lemmatu 5.18 je, že inPKP PKP. Dokažte, že platí i opačné tvrzení, tj. že PKP inPKP. Nerozhodnutelnost Postova korespondenčního problému Věta 5.21. Postův korespondenční problém je nerozhodnutelný. Důkaz: Vzhledem k tvrzení lemmatu 5.18 stačí dokázat nerozhodnutelnost iniciálního Postova problému. Sestrojíme redukci problému příslušnosti pro TM (věta 5.3) na iniciální Postův problém: dvojici Turingův stroj a slovo w tato redukce přiřadí dva seznamy A a B tak, že instance A, B inPKP má řešení, právě když stroj akceptuje slovo w. Necht' = (Q, , , , , , q0, qaccept , qreject), w . Dále předpokládejme, že Q = a že / Q (nový symbol). Každou konfiguraci (q, z,r) stroje můžeme jednoznačně reprezentovat řetězcem z1qz2, kde z1z2 = z a |z1| = r. V této reprezentaci je pozice hlavy určena umístěním symbolu stavu v řetězci z. Základní idea konstrukce je přiřadit dvojici , w takovou instanci iniciálního Postova problému, že její řešení (posloupnost čísel) určuje slovo q0w 1q11 kqaccept k takové, že jeho předpona je zápisem akceptujícího výpočtu na w (za podmínky, že existuje). Seznam A Seznam B I q0 w II Z Z pro všechna Z III pro všechna q Q \ {qaccept }, p Q, X, Y, Z qX Y p jestliže (q, X) = (p, Y, R) ZqX pZY jestliže (q, X) = (p, Y, L) q Y p jestliže (q, ) = (p, Y, R) Zq pZY jestliže (q, ) = (p, Y, L) IV Zqaccept qaccept pro všechna Z qaccept Z qaccept pro všechna Z V qaccept Obrázek 5.7: Redukce problému příslušnosti pro TM na inPKP Seznamy A, B jsou tvořeny slovy nad abecedou { } tak, jak je uvedeno v tabulce 5.7. Pro lepší pochopení jsou slova seskupena do menších celků. S výjimkou první dvojice (skupina I), která musí být v seznamech na prvním místě, uspořádání zbylých dvojic může být libovolné. Konstrukci nejdříve ilustrujeme na příkladu a až pak prokážeme její korektnost. Příklad 5.22. Prezentovanou redukci ilustrujeme na příkladu stroje = ({q0, q1}, {a, b}, {, , a, b, A}, , , , q0, qaccept , qreject ) ( je dána tabulkou 5.1) a slova w = aa. a A q0 (q0, , R) (q1, A, R) (q1, A, L) (qaccept , A, R) q1 (qreject, , R) (q0, A, R) (q0, A, L) (q0, , L) Tabulka 5.1: Přechodová funkce stroje Dvojici a w přiřadíme případ A, B iniciálního PKP popsaný v tabulce 5.8. Pokusíme se najít řešení této instance PKP. Jako první musíme vzít ze seznamu A slovo a ze seznamu B k němu odpovídající slovo q0 aa (plyne z definice iniciálního PKP). | | | q0 a a | Ze seznamu A musíme dále vybírat tak, abycom vytvořili řetěz q0 aa . K dispozici máme slova z druhé a třetí skupiny. | | q0 | a | a | | | q0 a a | q0 | a | a | | Všimněme si, že zatímco prvníslovo jsme prodloužili o řetěz q0aa (počátečníkonfigurace na w), k druhému slovu jsme přidali řetěz q0aa , což je konfigurace, do které přejde z počáteční konfigurace v jednom kroku výpočtu. Opět tedy musíme k prvnímu slovu přidat q0aa . | | q0 | a | a | | | q0 a | a | | | q0 a a | q0 | a | a | | | A q1 | a | | Podobně postupujeme, dokud nenastane situace . . . . . . | | . . . . . . A A A qaccept | | Symbol qaccept ve spodním slově ukazuje, že stroj by slovo aa akceptoval. Proto bychom měli být schopni najít řešení dané instance iniciálního PKP. Skutečně, dvojice ze 4. a 5. Seznam A Seznam B q0aa a a b b A A q0 q0 protože (q0, ) = (q0, , R) q0a Aq1 protože (q0, a) = (q1, A, R) q0 A q1 A protože (q0, A) = (q1, A, L) aq0 A q1aA Aq0 A q1 AA q0 A q1 A q0 Aqaccept protože (q0, ) = (qaccept , A, R) q0 Aqaccept q1 qreject protože (q1, ) = (qreject, , R) q1a Aq0 protože (q1, a) = (q0, A, R) q1 A q0 A protože (q1, A) = (q0, A, L) aq1 A q0aA Aq1 A q1 AA q1 A q1 A q1 q0 protože (q1, ) = (q0, , L) aq1 q0a Aq1 q0 A q1 q0 q1 q0 aq1 q0a Aq1 q0 A q1 q0 qaccept qaccept aqaccept qaccept Aqaccept qaccept qaccept qaccept qaccept qaccept qaccept a qaccept qaccept A qaccept qaccept qaccept qaccept Obrázek 5.8: Seznamy A a B skupiny nám umožní, aby se obě slova ,,srovnala": . . . . . . | | | A | A | A qaccept | | . . . . . . A A A qaccept | | | A | A | qaccept | | Podobně postupujeme až do úspěšného konce . . . . . . | yyyyyyyyyyyyyyy | xxxxxxxxxxxxxx qaccept | tttttttttttt | uuuuuuuuuuuuqaccept | . . . . . . qaccept | | qaccept | | | Pokračování důkazu věty 5.21 Máme dokázat, že navržená transformace je redukcí. Rekursivita je zřejmá. Zůstává ověřit, že Turingův stroj akceptuje slovo w tehdy a jen tehdy, když k němu přirazená instance iniciálního PKP má řešení. Je-li (x1, . . . , xn), (y1, . . . , yn) instance iniciálního PKP, pak posloupnost indexů i1, . . . , im nazveme částečným řešením této instance, právě když slovo x = x1xi1 xim je prefixem slova y = y1yi1 yim . O slovech x a y říkáme, že jsou definovány částečným řešením i1, . . . , im. Necht'q0 w u1q1v1 u2q2v2 ukqkvk je výpočet stroje na vstupu w a necht'qk {qaccept , qreject}. Tvrdíme, že pak existuje částečné řešení instance A, B definující dvojici slov (x, y), x = q0 w u1q1v1 uk-1qk-1vk-1 y = q0 w u1q1v1 uk-1qk-1vk-1 ukqkvk a navíc, že neexistuje žádné jiné řešení definující dvojici slov (c, y) pro žádné c. Uvedené tvrzení lehce dokážeme indukcí vzhledem ke k. Pro k = 0 je tvrzení triviální: jedině prázdná posloupnost čísel definuje dvojici slov ( , q0w). Předpokládejme, že tvrzení platí pro nějaké k a že qk {qaccept , qreject}. Dokážeme, že pak platí i pro k + 1. Protože y = xz, kde z = ukqkvk , tak ze seznamu A musíme vybrat slova tvořící z. Pro symboly Z můžeme použít jedině slova ze skupiny II. Pro symbol qk a symbol bezprostředně za ním následující resp. předcházející je ve skupině III jediné slovo. Toto slovo spolu se svým protějškem ze seznamu B přirozeným způsobem prezentují krok výpočtu stroje . Žádný jiný výběr neumožňuje vytvoření slova z. Tímto dostáváme nové častečné řešení definující dvojici slov (y, yuk+1qk+1vk+1 ). Lehce nahlédneme, že ukqkvk uk+1qk+1vk+1. Navíc, jestliže qk+1 = qaccept , tak jedno- duchým způsobem získáme (použitím slov ze skupin IV a V) z tohoto částečného řešení řešení instance A, B . Tedy existuje-li akceptující výpočet stroje na vstupu w, pak instance A, B iniciálního PKP má řešení. Pokud slovo w neakceptuje, pak A, B může mít částečná řešení, která ale definujídvojice slov nestejné délky a nenímožné je prodloužit nařešení. 5.7 Nerozhodnutelné problémy z teorie formálních jazyků Nerozhodnutelnost Postova korespondenčního problému využijeme v následujících úva- hách o (ne)rozhodnutelnosti některých problémů týkajících se gramatik Chomského hie- rarchie. Poznamenáváme jenom, že vzhledem ke známým vztahům mezi gramatikami a automaty, všechna uvedená tvrzení platí stejně i pro odpovídající typ automatů. Problém prázdnosti Je formulován jako úloha pro libovolnou danou gramatiku rozhodnout, zda L( ) = . Věta 5.23. Problém prázdnosti pro třídu bezkontextových gramatik je rozhodnutelný. Důkaz: Je obsažen v důkazu věty 3.9. Důsledek 5.24. Problém prázdnosti pro třídu regulárních gramatik je rozhodnutelný. Důkaz: Protože každá regulární gramatika je současně bezkontextovou, na rozhodování problému můžeme použít algoritmus navržený pro bezkontextové gramatiky. Ú vahu použitou v důkazu důsledku 5.24 můžeme lehce zobecnit. Necht'P je problém a S množina jeho instancí. Pak z rozhodnutelnosti problému P pro množinu instnacíS plyne rozhodnutelnost tohoto problému pro každou množinu instancí S , kde S S. Tvrzení nemusí platit pro množinu S S, což dokazuje následující věta. Věta 5.25. Problém prázdnosti pro třídu kontextových gramatik je nerozhodnutelný. Důkaz: Navrhneme redukci komplementu Postova korespondenčního problému na pro- blém prázdnosti pro kontextové gramatiky. Komplement PKP není rozhodnutelný (kdyby byl, tak podle věty 4.16 i PKP by byl rozhodnutelný). Redukce přiřadí seznamům A, B kontextovou gramatiku takovou, že instance A, B nemá řešení tehdy a jen tehdy, když gramatika generuje prázdný jazyk. Vyjdeme z poznatku, že daná instance A = (x1, . . . , xn), B = (y1, . . . , yn) PKP nad abecedou bud'nemá žádné řešení, nebo jich má nekonečně mnoho. Uvažme jazyky L A a LB nad abecedou { , 1, . . . , n} (předpokládáme { , 1, . . . , n} = ); L A def = { xi1 xik ik i1 | 1 i j n pro j = 1, . . . , k} LB def = { yi1 yik ik i1 | 1 i j n pro j = 1, . . . , k}. Průnik těchto dvou jazyků L A LB obsahuje právě ta slova u v, pro která v = ik i1 a posloupnost i1, . . . , ik je řešením instance A, B Postova problému. Lehce ověříme, že jazyky L A a LB jsou kontextové (jsou dokonce determininistické bezkontextové), a tedy i jejich průnik L A LB je kontextový jazyk (věta 4.25). Necht' je kontextová gramatika generující jazyk L A LB. Hledaná redukce přiřadí instanci A, B gramatiku . Důsledek 5.26. Problém prázdnosti pro třídu gramatik typu 0 je nerozhodnutelný. Důkaz: Z rozhodnutelnosti problému pro třídu gramatik typu 0 by plynula i rozhodnutel- nost problému pro třídu kontextových gramatik, což je spor. Použitou úvahu můžeme opět formulovat obecně: z nerozhodnutelnosti problému P pro množinu instancí S plyne nerozhodnutelnost tohoto problému pro každou množinu instancí S , kde S S. Problém příslušnosti Je formulován jako úloha rozhodnout pro libovolnou danou gramatiku a libovolné dané slovo w, zda w L( ). S tímto problémem jsme se setkali již jednou (věta 5.3) a víme tedy, že pro gramatiky typu 0 je nerozhodnutelný. Z lemmatu 4.21 plyne, že ke každé kontextové gramatice je možné zkonstruovat ekvivalentní úplný Turingův stroj, a proto problém příslušnosti pro kontextové gramatiky je rozhodnutelný. Problém konečnosti Je formulován jako úloha pro libovolnou danou gramatiku rozhodnout, zda jazyk L( ) je konečný. Věta 5.27. Problém konečnosti pro bezkontextové gramatiky je rozhodnutelný. Důkaz: Tvrzení je důsledkem lemmatu o vkládáni pro CFL (věta 3.24). Jazyk L( ) je nekonečný tehdy a jen tehdy, když obsahuje slovo z délky p < |z| p + q. Věta 5.28. Problém konečnosti pro kontextové gramatiky je nerozhodnutelný. Důkaz: Důkaz tvrzení je obsažen v důkazu věty 5.25. Stačí si uvědomit, že jazyk L A LB obsahuje právě slova odpovídající řešením PKP, a tedy je bud'prázdný (PKP nemá řešení), nebo nekonečný (PKP má řešení, tedy jich má nekonečně mnoho). Další nerozhodnutelné problémy Nerozhodnutelnost budeme opět dokazovat redukcí z PKP resp. komplementu PKP. Vy- užijeme označení zavedené v důkazu věty 5.25, tj. seznamy A = (x1, . . . , xn), B = (y1, . . . , yn) nad abecedou tvoří instanci PKP, { , 1, . . . , n} = . K nim jsou přiřa- zeny jazyky L A def = { xi1 xik ik i1 | 1 i j n pro j = 1, . . . , k} LB def = { yi1 yik ik i1 | 1 i j n pro j = 1, . . . , k}. jejichž průnik je neprázdný, právě když instance A, B má řešení. Navíc definujeme jazyky L A,B a S předpisem L A,B def = L A { } LR B S def = { u v vR uR | u , v {1, . . . , n} }. Otázka 5.29. Sestrojte deterministické zásobníkové automaty akceptující jazyky L A,B a S. Vlastnosti definovaných jazyků popisují následující tři lemmata. Lemma 5.30. Instance A, B Postova problému má řešení, právě když L A,B S = . Důkaz: Předpokládejme, že posloupnost čísel i1, . . . , ik je řešením instance A, B . Tato posloupnost určuje slova u S a v L A,B, přičemž u = xi1 xik ik i1 i1 ik xik xi1 v = xi1 xik ik i1 i1 ik yik yi1. Protože i1, . . . , ik je řešením instance A, B , je xi1 xik = yi1 yik a následně u = v. Jazyk L A,B S je tedy neprázdný. Opačná implikace se dokáže analogicky. Lemma 5.31. Jazyk co­(L A,B S) je bezkontextový. Důkaz: Vyjděme ze vztahu co­(L A,B S) = co­L A,B co­S. Protože jazyk L A,B je deterministický bezkontextový (5.29), je i jazyk co­(L A,B) deterministický bezkon- textový (věta 3.82). Analogicky pro jazyk S. Tvrzení lemmatu plyne z uzavřenosti třídy bezkontextových jazyků vůči operaci sjednocení (věta 3.58). Lemma 5.32. Jazyk LA,B S je bezkontextový tehdy a jen tehdy, když je prázdný. Důkaz: Pro danou instanci A, B Postova problému obsahuje (podle lemmatu 5.30) jazyk L A,B S právě slova odpovídající řešením instance A, B . Protože každá instance PKP bud'nemá žádné řešení nebo jich má nekonečně mnoho, tak i jazyk L A,B S je bud'prázdný anebo nekonečný. Pokud L A,B S je prázdný, tak je triviálně bezkontextový (ba dokonce regulární). Abychom ukázali obrácenou implikaci, předpokládejme, že L A,B S je neprázdný a že je bezkontextový. Pro každý bezkontextový jazyk platí lemma o vkládání (věta 3.24). Tedy i pro L A,B S musíexistovat dvě konstanty p, q takové, že každé slovo z (L A,B S) délky větší než p lze napumpovávat (existence takovéhoto slova plyne z nekonečnosti jazyka L A,B S). Zvolme slovo z L, z = xi1 xik ik i1 i1 ik yik yi1, kde k q. Toto se musí se dát rozdělit na pět částí u, v, w, x, y tak, aby vx = a |vwx| q. Pro žádné z možných rozdělení však neplatí uv2wx2 y (L A,B S), což je spor. Jazyk L A,B S je tedy bezkontextový jedině tehdy, když je prázdný. Jako přímý důsledek právě uvedených tří lemmat dostáváme toto tvrzení: Věta 5.33. Pro libovolnou danou bezkontextovou gramatiku a libovolnou danou regu- lární množinu R je nerozhodnutelné určit, zda (a) L( ) = R (b) L( ) R Důkaz: (a) Stačí za R zvolit ( { } {1, . . . , n}) a za bezkontextovou gramatiku generující jazyk co­(L A,B S). Podle lemmatu 5.30 je co­(L A,B S) = R právě když instance A, B PKP nemá řešení. (b) Ukážeme, že inkluze L( ) R je snadno rozhodnutelná. Kdyby byla rozhodnutelná i inkluze uvedená v (b), pak bychom uměli rozhodovat i rovnost, což je spor s bodem (a). K rozhodnutelnosti inkluze L( ) R si stačí uvědomit, že L( ) R L( ) co­R = a jazyk L( ) co­R je bezkontextový. Důsledek 5.34. (a) Pro libovolnou danou bezkontextovou gramatiku s terminální abe- cedou je nerozhodnutelné určit, zda L( ) = . (b) Pro dvě libovolné dané bezkontextové gramatiky 1 a 1 je nerozhodnutelné určit, zda L( 1) = L( 2) resp. zda L( 1) L( 2). Věta 5.35. Pro dvě libovolné dané bezkontextové gramatiky 1 a 2 je nerozhodnutelné určit, zda (a) L( 1) L( 2) je bezkontextový jazyk, (b) co­L( 1) je bezkontextový jazyk, (c) L( 1) je regulární jazyk (či ekvivaletně: jazyk L( 1) nemá vlastnost sebevložení). Důkaz: (a) Stačí zvolit bezkontextové gramatiky 1 a 2 tak, aby L( 1) = L A,B a L( 2) = S a aplikovat lemma 5.32. (b) Zvolme bezkontextovou gramatiku 1 tak, aby L( 1) = co­(L A,B S). Tvrzení je pak důsledkem lemmatu 5.32. (c) Provedeme volbu jako v předcházejícím případě. Jazyk L( 1) je regulární, právě když je roven ( { } {1, . . . , n}). Jazyk co­(L A,B S) je regulární, právě když L A,B S je regulární, a to je (podle lemmatu 5.32) tehdy a jen tehdy, když instance A, B PKP nemá řešení. Věta 5.36. Pro libovolnou danou bezkontextovou gramatiku je nerozhodnutelné určit, zda je víceznačná. Důkaz: Necht' A, B je instance Postova korespondenčního problému nad , A = (x1, . . . , xn), B = (y1, . . . , yn). Bez újmy na obecnosti můžeme předpokládat, že {1, . . . , n} = a / . K této instanci nyní sestrojíme bezkontextovou gramatiku = (N, {1, . . . , n} { }, P, S) s množinou pravidel P S S1 | S2 S1 xi S1i | pro všechna 1 i n S2 yi S2i | pro všechna 1 i n Zřejmě gramatika je víceznačná tehdy a jen tehdy, když instance A, B Postova kore- spondečního problému má řešení. Věta 5.37. Pro libovolnou danou bezkontextovou gramatiku je nerozhodnutelné určit, zda je víceznačná. Důkaz: Necht' A, B je instance Postova korespondenčního problému nad , A = (x1, . . . , xn), B = (y1, . . . , yn). Bez újmy na obecnosti můžeme předpokládat, že {1, . . . , n} = a / . K této instanci nyní sestrojíme bezkontextovou gramatiku = (N, {1, . . . , n} { }, P, S) s množinou pravidel P S S1 | S2 S1 xi S1i | pro všechna 1 i n S2 yi S2i | pro všechna 1 i n Zřejmě gramatika je víceznačná tehdy a jen tehdy, když instance A, B Postova kore- spondečního problému má řešení. Přehled rozhodnutelných a nerozhodnutelných problémů týkajících se tříd jazyků Chomského hierarchie je obsažen v následující tabulce5. Symbol R (resp. N) značí, že problém je rozhodnutelný (resp. nerozhodnutelný). V případě, že vlastnost je splněna pro všechny instance problému, je na odpovídajícím místě v tabulce ano. R DCF CF CS Rec RE Je L( ) prázdný? konečný? R R R N N N Je L( ) = ? R R N N N N Je L( ) = R? (R je regulární množina) R R N N N N Je L( 1) = L( 2)? R R N N N N Je L( 1) L( 2)? R N N N N N Je L( ) regulární jazyk? ano R N N N N Je průnik dvou jazyků jazyk téhož typu? ano N N ano ano ano Je sjednocení dvou jazyků jazyk téhož typu? ano N ano ano ano ano Je komplement jazyka jazyk téhož typu? ano ano N ano ano N Je zřetězení dvou jazyků jazyk téhož typu? ano N ano ano ano ano Je gramatika víceznačná? R N N N N N 5. Ne všechny výsledky jsou dokázány v tomto učebním textu.