Teoretická informatika TIN Studijní opora M. Češka, T. Vojnar, A. Smrčka 1. září 2011 Tento učební text vznikl za podpory projektu ” Zvýšení konkurenceschopnosti IT odborníků – absolventů pro Evropský trh práce“, reg. č. CZ.04.1.03/3.2.15.1/0003. Tento projekt je spolufinancován Evropským sociálním fondem a státním rozpočtem České republiky. Obsah 1 Úvod 5 1.1 Obsahové a metodické informace o předmětu Teoretická informatika 6 1.1.1 Cíle předmětu . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.1.2 Anotace předmětu . . . . . . . . . . . . . . . . . . . . . . . 6 1.1.3 Požadované prerekvizitní znalosti a dovednosti . . . . . . . 6 1.1.4 Osnova přednášek a přiřazení ke kapitolám opory . . . . . . 6 2 Jazyky, gramatiky a jejich klasifikace 8 2.1 Jazyky . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.2 Gramatika . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.3 Chomského klasifikace gramatik . . . . . . . . . . . . . . . . . . . . 16 2.3.1 Typ 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 2.3.2 Typ 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 2.3.3 Typ 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.3.4 Typ 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.4 Cvičení . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3 Regulární jazyky 21 3.1 Jazyky přijímané konečnými automaty a deterministický konečný automat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.1.1 Nedeterministický konečný automat . . . . . . . . . . . . . 21 3.1.2 Lineární a regulární gramatiky . . . . . . . . . . . . . . . . 24 3.1.3 Ekvivalence třídy L3 a třídy jazyků přijímaných konečnými automaty . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 3.2 Minimalizace deterministického konečného automatu . . . . . . . . 33 3.3 Regulární množiny a regulární výrazy . . . . . . . . . . . . . . . . 36 3.3.1 Regulární množiny . . . . . . . . . . . . . . . . . . . . . . . 36 3.3.2 Regulární výrazy . . . . . . . . . . . . . . . . . . . . . . . . 38 3.3.3 Rovnice nad regulárními výrazy . . . . . . . . . . . . . . . . 40 3.3.4 Soustavy rovnic nad regulárními výrazy . . . . . . . . . . . 41 3.4 Převod regulárních výrazů na konečné automaty . . . . . . . . . . 43 3.5 Vlastnosti regulárních jazyků . . . . . . . . . . . . . . . . . . . . . 47 3.5.1 Strukturální vlastnosti regulárních jazyků . . . . . . . . . . 47 3.5.2 Myhill-Nerodova věta . . . . . . . . . . . . . . . . . . . . . 49 3.5.3 Uzávěrové vlastnosti regulárních jazyků . . . . . . . . . . . 51 3.5.4 Rozhodnutelné problémy regulárních jazyků . . . . . . . . . 52 3.6 Cvičení . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 1 OBSAH 2 4 Bezkontextové jazyky a zásobníkové automaty 55 4.1 Derivační strom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 4.2 Fráze větné formy . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 4.3 Víceznačnost gramatik . . . . . . . . . . . . . . . . . . . . . . . . . 60 4.4 Rozklad věty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 4.5 Transformace bezkontextových gramatik . . . . . . . . . . . . . . . 66 4.6 Chomského normální forma . . . . . . . . . . . . . . . . . . . . . . 74 4.7 Greibachové normální forma . . . . . . . . . . . . . . . . . . . . . . 76 4.8 Cvičení . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 4.9 Základní definice zásobníkového automatu . . . . . . . . . . . . . . 80 4.10 Varianty zásobníkových automatů . . . . . . . . . . . . . . . . . . 83 4.11 Ekvivalence bezkontextových jazyků a jazyků přijímaných zásobníkovými automaty . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 4.12 Deterministický zásobníkový automat . . . . . . . . . . . . . . . . 92 4.13 Vlastnosti bezkontextových jazyků . . . . . . . . . . . . . . . . . . 94 4.13.1 Strukturální vlastnosti . . . . . . . . . . . . . . . . . . . . . 94 4.13.2 Uzávěrové vlastnosti . . . . . . . . . . . . . . . . . . . . . . 95 4.13.3 Rozhodnutelné a nerozhodnutelné problémy pro bezkontextové jazyky . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 4.13.4 Uzávěrové vlastnosti jazyků deterministických bezkontextových jazyků . . . . . . . . . . . . . . . . . . . . . . . . . . . 99 4.13.5 Některé další zajímavé vlastnosti bezkontextových jazyků . 99 4.14 Cvičení . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 5 Turingovy stroje 102 5.1 Základní koncepce Turingových strojů . . . . . . . . . . . . . . . . 102 5.1.1 Churchova teze . . . . . . . . . . . . . . . . . . . . . . . . . 102 5.1.2 Turingův stroj . . . . . . . . . . . . . . . . . . . . . . . . . 102 5.1.3 Konfigurace Turingova stroje . . . . . . . . . . . . . . . . . 103 5.1.4 Přechodová relace TS . . . . . . . . . . . . . . . . . . . . . 103 5.1.5 Výpočet TS . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 5.1.6 Poznámka – alternativní definice TS . . . . . . . . . . . . . 104 5.1.7 Grafická reprezentace TS . . . . . . . . . . . . . . . . . . . 104 5.1.8 Modulární konstrukce TS . . . . . . . . . . . . . . . . . . . 105 5.1.9 Kompozitní diagram TS . . . . . . . . . . . . . . . . . . . . 105 5.1.10 Základní stavební bloky TS . . . . . . . . . . . . . . . . . . 107 5.1.11 Příklady TS . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 5.2 Turingovy stroje jako akceptory jazyků . . . . . . . . . . . . . . . . 109 5.2.1 Jazyk přijímaný TS . . . . . . . . . . . . . . . . . . . . . . 109 5.3 Modifikace TS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 5.3.1 Přijímání zvláštních konfigurací pásky . . . . . . . . . . . . 110 5.3.2 Vícepáskové Turingovy stroje . . . . . . . . . . . . . . . . . 111 5.3.3 Nedeterministické Turingovy stroje . . . . . . . . . . . . . . 113 5.4 Jazyky rekurzivně vyčíslitelné a jazyky rekurzivní . . . . . . . . . . 115 5.4.1 Rekurzivní vyčíslitelnost a rekurzivnost . . . . . . . . . . . 115 5.4.2 Rozhodovací problémy . . . . . . . . . . . . . . . . . . . . . 116 5.4.3 Rozhodování problémů TS . . . . . . . . . . . . . . . . . . . 116 5.5 TS a jazyky typu 0 . . . . . . . . . . . . . . . . . . . . . . . . . . . 116 5.5.1 Jazyky přijímané TS jsou typu 0 . . . . . . . . . . . . . . . 117 5.5.2 Jazyky typu 0 jsou přijímány TS . . . . . . . . . . . . . . . 118 5.5.3 Jazyky typu 0 = jazyky přijímané TS . . . . . . . . . . . . 118 5.6 Vlastnosti jazyků rekurzívních a rekurzívně vyčíslitelných . . . . . 118 OBSAH 3 5.6.1 Uzavřenost vůči ∪, ∩, . a ∗ . . . . . . . . . . . . . . . . . . 119 5.6.2 (Ne)uzavřenost vůči komplementu . . . . . . . . . . . . . . 120 5.7 Lineárně omezené automaty . . . . . . . . . . . . . . . . . . . . . . 121 5.7.1 Lineárně omezené automaty . . . . . . . . . . . . . . . . . . 121 5.7.2 LOA a kontextové jazyky . . . . . . . . . . . . . . . . . . . 121 5.7.3 Kontextové a rekurzívní jazyky . . . . . . . . . . . . . . . . 122 5.7.4 Vlastnosti kontextových jazyků . . . . . . . . . . . . . . . . 122 5.8 Cvičení . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 6 Meze rozhodnutelnosti 124 6.1 Jazyky mimo třídu 0 . . . . . . . . . . . . . . . . . . . . . . . . . . 124 6.1.1 Existence jazyků mimo třídu 0 . . . . . . . . . . . . . . . . 124 6.2 Problém zastavení . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 6.2.1 Kódování TS . . . . . . . . . . . . . . . . . . . . . . . . . . 125 6.2.2 Univerzální TS . . . . . . . . . . . . . . . . . . . . . . . . . 126 6.2.3 Problém zastavení TS . . . . . . . . . . . . . . . . . . . . . 126 6.3 Redukce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 6.3.1 Důkaz nerozhodnutelnosti redukcí . . . . . . . . . . . . . . 128 6.4 Problém náležitosti a další problémy . . . . . . . . . . . . . . . . . 129 6.4.1 Problém náležitosti pro L0 . . . . . . . . . . . . . . . . . . 129 6.4.2 Příklady dalších problémů pro TS . . . . . . . . . . . . . . 130 6.5 Postův korespondenční problém . . . . . . . . . . . . . . . . . . . . 130 6.5.1 Postův korespondenční problém . . . . . . . . . . . . . . . . 131 6.5.2 Nerozhodnutelnost PCP . . . . . . . . . . . . . . . . . . . . 131 6.5.3 Nerozhodnutelnost redukcí z PCP . . . . . . . . . . . . . . 132 6.5.4 Souhrn některých vlastností jazyků . . . . . . . . . . . . . . 132 6.6 Riceova věta . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 6.6.1 Riceova věta – první část . . . . . . . . . . . . . . . . . . . 133 6.6.2 Důkaz 1. části Riceovy věty . . . . . . . . . . . . . . . . . . 134 6.6.3 Riceova věta – druhá část . . . . . . . . . . . . . . . . . . . 134 6.7 Alternativy Turingova stroje . . . . . . . . . . . . . . . . . . . . . . 135 6.8 Vyčíslitelné funkce . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 6.8.1 Základy teorie rekurzivních funkcí . . . . . . . . . . . . . . 135 6.8.2 Počáteční funkce . . . . . . . . . . . . . . . . . . . . . . . . 136 6.8.3 Primitivně rekurzivní funkce . . . . . . . . . . . . . . . . . 136 6.8.4 Příklady primitivně rekurzivních funkcí . . . . . . . . . . . 138 6.8.5 Funkce mimo primitivně rekurzivní funkce . . . . . . . . . . 140 6.8.6 Parciálně rekurzivní funkce . . . . . . . . . . . . . . . . . . 140 6.9 Vztah vyčíslitelných funkcí a Turingových strojů . . . . . . . . . . 141 6.9.1 Turingovsky vyčíslitelné funkce . . . . . . . . . . . . . . . . 141 6.9.2 Turingovská vyčíslitelnost parciálně rekurzivních funkcí . . 142 6.9.3 Reprezentace Turingova stroje parciálně rekurzivními funkcemi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 6.10 Cvičení . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145 7 Složitost 147 7.1 Základní pojmy složitosti . . . . . . . . . . . . . . . . . . . . . . . 147 7.1.1 Složitost algoritmů . . . . . . . . . . . . . . . . . . . . . . . 147 7.1.2 Různé případy při analýze složitosti . . . . . . . . . . . . . 147 7.1.3 Složitost výpočtů TS . . . . . . . . . . . . . . . . . . . . . . 148 7.1.4 Složitost a cena atomických operací . . . . . . . . . . . . . 149 7.1.5 Složitost výpočtů na TS a v jiných prostředích . . . . . . . 149 OBSAH 4 7.1.6 Asymptotická omezení složitosti . . . . . . . . . . . . . . . 151 7.2 Třídy složitosti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 7.2.1 Složitost problémů . . . . . . . . . . . . . . . . . . . . . . . 152 7.2.2 Třídy složitosti . . . . . . . . . . . . . . . . . . . . . . . . . 153 7.2.3 Časově/prostorově konstruovatelné funkce . . . . . . . . . . 153 7.2.4 Nejběžněji užívané třídy složitosti . . . . . . . . . . . . . . 154 7.2.5 Třídy pod a nad polynomiální složitostí . . . . . . . . . . . 154 7.2.6 Třídy nad exponenciální složitostí . . . . . . . . . . . . . . 155 7.2.7 Vrchol hierarchie tříd složitosti . . . . . . . . . . . . . . . . 155 7.3 Vlastnosti tříd složitosti . . . . . . . . . . . . . . . . . . . . . . . . 155 7.3.1 Vícepáskové stroje . . . . . . . . . . . . . . . . . . . . . . . 155 7.3.2 Determinismus a nedeterminismus . . . . . . . . . . . . . . 156 7.3.3 Prostor kontra čas . . . . . . . . . . . . . . . . . . . . . . . 158 7.3.4 Uzavřenost vůči doplňku . . . . . . . . . . . . . . . . . . . . 158 7.3.5 Ostrost hierarchie tříd . . . . . . . . . . . . . . . . . . . . . 159 7.3.6 Některé další zajímavé výsledky . . . . . . . . . . . . . . . . 159 7.3.7 R redukce, jazyky C-těžké a C-úplné . . . . . . . . . . . . . 160 7.3.8 Nejběžnější typy R redukce a úplnosti . . . . . . . . . . . . 160 7.4 Příklady složitosti problémů . . . . . . . . . . . . . . . . . . . . . . 161 7.5 SAT-problém . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 7.5.1 Polynomiální redukce . . . . . . . . . . . . . . . . . . . . . 162 7.5.2 Problém splnitelnosti - SAT problém . . . . . . . . . . . . . 163 7.5.3 NP-úplné jazyky . . . . . . . . . . . . . . . . . . . . . . . . 164 7.5.4 Význačné NP-úplné problémy . . . . . . . . . . . . . . . . . 164 7.5.5 Použití redukcí k důkazu úplnosti . . . . . . . . . . . . . . . 165 7.6 Cvičení . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 Literatura 167 Kapitola 1 Úvod 0:20 Teorie formálních jazyků a vyčíslitelnost představují klasické a velmi důležité oblasti teoretické informatiky. Základy novodobé historie těchto disciplín položil v roce 1956 americký matematik Noam Chomsky, který v souvislosti se studiem přirozených jazyků vytvořil matematický model gramatiky jazyka. Realizace původních představ, formalizovat popis přirozeného jazyka takovým způsobem, aby mohl být automatizován překlad z jednoho přirozeného jazyka do druhého nebo aby přirozený jazyk sloužil jako prostředek komunikace člověka s počítačem, se ukázala velmi obtížnou a teprve současné výsledky můžeme považovat alespoň za slibné. Začala se však vyvíjet vlastní teorie jazyků, která nyní obsahuje bohaté výsledky v podobě matematicky dokázaných tvrzení – teorémů. Tato teorie pracuje se dvěma duálními matematickými entitami, s gramatikou a s automatem, představující abstraktní matematický stroj. Zatímco gramatika umožňuje vetšinou snáze popsat strukturu vět formálního jazyka, automat dovede tuto strukturu snaze identifikovat a zpracovávat. Poznatky teorie formálních jazyků mají význam nejen ve všech oblastech informatiky a informačních technologií, ale jejich aplikace zasahují do téměř nespočetné řady technických i netechnických oborů. Dodávají algoritmy, jež jsou podkladem pro konstrukci reálných programů či zařízení zpracovávajících informaci ve tvaru vět formálního jazyka. Stanovují však také možnosti a omezení algoritmických postupů řešení problémů; odhalují problémy, které jsou algoritmicky nerozhodnutelné, tj. problémy, jejichž řešení nelze dosáhnout v konečném čase. Teorie formálních jazyků našla doposud největší uplatnění v oblasti programovacích jazyků. Krátce po Chomského definici gramatiky formálního jazyka a klasifikaci formálních jazyků (Chomského hierarchii formálních jazyků), Backus a Nauer použili základních objektů gramatiky pro definici syntaxe programovacího jazyka Algol 60 (ve tvaru formalismu, jež se nazývá Backus-Nauerova forma). Další vývoj pak přímočaře vedl k aplikacím teorie jazyků v oblasti překladačů programovacích jazyků. Stanovení principů syntaxí řízeného překladu a generátorů překladačů (programovacích systémů, které na základě formálního popisu syntaxe a sémantiky programovacího jazyka vytvoří jeho překladač) představuje kvalitativní skok při konstrukci překladačů umožňující automatizovat náročnou programátorskou práci spojenou s implementací programovacích jazyků. V současné době je teorie formálních jazyků spolu s matematickou logikou základem ambiciozních výzkumných programů zaměřených na formální verifikace technických i programových prostředků, vedoucí k větší spolehlivosti a bezpečnosti počítačových aplikací. . 5 KAPITOLA 1. ÚVOD 6 Čas potřebný pro studium Otázka, příklad k řešení Cíl Počítačové cvičení, příklad Definice Příklad Důležitá část Reference Rozšiřující látka Správné řešení Souhrn Obtížná část Slovo tutora, komentář Zajímavé místo Tabulka 1.1: Význam používaných piktogramů 1.1 Obsahové a metodické informace o předmětu Teoretická informatika 1.1.1 Cíle předmětu Rozšíření znalostí teorie formálních jazyků a osvojení základů teorie vyčíslitelnosti a základních pojmů výpočetní složitosti. 1.1.2 Anotace předmětu Aplikace teorie formálních jazyků v informatice a informačních technologiích (překladače, modelování a analýza systémů, lingvistika, biologie atd.), modelovací a rozhodovací síla formálního modelu, regulární jazyky a jejich vlastnosti, minimalizace konečného automatu, bezkontextové jazyky a jejich vlastnosti, Turingovy stroje, vlastnosti rekurzivních a rekurzivně vyčíslitelných jazyků, vyčíslitelné funkce, nerozhodnutelnost, nerozhodnutelné problémy teorie formálních jazyků, úvod do výpočetní složitosti. 1.1.3 Požadované prerekvizitní znalosti a dovednosti Základní znalosti z binárních relací, teorie grafů a formálních jazyků včetně konečných a zásobníkových automatů a pojmů algoritmické složitosti. 1.1.4 Osnova přednášek a přiřazení ke kapitolám opory Kapitola 2 Úvod, aplikace teorie formálních jazyků, modelovací a rozhodovací síla formálního modelu, operace nad jazyky. KAPITOLA 1. ÚVOD 7 Kapitola 3 Regulární jazyky a jejich vlastnosti, Kleenova věta, Nerodova věta, věta o vkládání (Pumping theorem). Minimalizace konečného automatu, relace nerozlišitelnosti stavů, konstrukce redukovaného konečného automatu. Uzávěrové vlastnosti regulárních jazyků, regulární jazyky jako množinová Booleova algebra, rozhodnutelné problémy regulárních jazyků. Kapitola 4 Bezkontextové jazyky a jejich vlastnosti. Normální tvary bezkontextových gramatik, jednoznačné a deterministické bezkontextové jazyky, věta o vkládání pro bezkontextové jazyky. Zásobníkové automaty, varianty zásobníkových automatů, ekvivalence bezkontextových jazyků a jazyků přijímaných zásobníkovými automaty, deterministický zásobníkový automat. Uzávěrové vlastnosti bezkontextových jazyků, uzavřenost vzhledem k substituci, důsledky, rozhodnutelné problémy bezkontextových jazyků. Kapitola 5 Turingovy stroje (TS), definice TS a jazyka přijímaného TS, rekurzivně vyčíslitelné a rekurzivní jazyky a problémy, TS a funkce, metody konstrukce TS. Modifikace TS, TS s obousměrně nekonečnou páskou, s více páskami, nedeterministický TS, stroj se dvěma zásobníky, stroje s čitači. TS a jazyky typu 0, diagonalizace, vlastnosti rekurzivních a rekurzivně vyčíslitelných jazyků, lineárně ohraničené automaty a jazyky typu 1. Vyčíslitelné funkce, počáteční funkce, primitivně rekurzivní funkce, mí-rekurzivní funkce, vztah vyčíslitelných funkcí a Turingových strojů. Church-Turingova téze, univerzální TS, nerozhodnutelnost, problém zastavení TS, redukce, Postův korespondenční problém. Kapitola 6 Nerozhodnutelné problémy teorie formálních jazyků. Kapitola 7 Úvod do výpočetní složitosti, Turingovská složitost, třída P a NP problémů. Kapitola 2 Jazyky, gramatiky a jejich klasifikace 10:00 Cílem této kapitoly je pochopení pojmu formální jazyk, jeho matematické explikace (popisu) a universality a základních algebraických operací nad formálními jazyky, které nacházejí praktické uplatnění v praktických aplikacích. Dále pak pochopení základního způsobu specifikace formálního jazyka gramatikou a způsobu klasifikace formálních jazyků, založeného na klasifikaci gramatik. 2.1 Jazyky Jedním ze základních pojmů pro vymezení jazyka jsou pojmy abeceda a řetězec. Definice 2.1 Abecedou rozumíme neprázdnou množinu prvků, které nazýváme symboly abecedy. V některých teoretických případech je účelné pracovat i s abecedami nekonečnými, v našich aplikacích se však omezíme na abecedy konečné. Příklad 2.1 Jako příklady abeced můžeme uvést latinskou abecedu obsahující 52 symbolů, které reprezentují velká a malá písmena, řeckou abecedu, dvouprvkovou binární abecedu reprezentovanou množinou {0, 1} resp. {true, false} nebo abecedy programovacích jazyků. Definice 2.2 Řetězcem (také slovem nebo větou) nad danou abecedou rozumíme každou konečnou posloupnost symbolů abecedy. Prázdnou posloupnost symbolů, tj. posloupnost, která neobsahuje žádný symbol, nazýváme prázdný řetězec. Prázdný řetězec budeme označovat písmenem . Formálně lze definovat řetězec nad abecedou Σ takto: (1) prázdný řetězec je řetězec nad abecedou Σ, (2) je-li x řetězec nad Σ a a ∈ Σ, pak xa je řetězec nad Σ, (3) y je řetězec nad Σ, když a jen když lze y získat aplikací pravidel 1 a 2. Příklad 2.2 Je-li A = {a, b, +} abeceda, pak a b + aa a + b + ab jsou některé řetězce nad abecedou A. Pořadí symbolů v řetězci je významné; řetězce a + b, +ab jsou různé. Symbol b, například, je řetězec nad A, poněvadž b = b (pravidlo (2)). Konvence 2.1 Budeme-li pracovat s obecnými abecedami, symboly, či řetězci, pak pro jejich značení použijeme: 8 KAPITOLA 2. JAZYKY, GRAMATIKY A JEJICH KLASIFIKACE 9 • velká řecká písmena pro abecedy, • malá latinská písmena a, b, c, d, f, . . . pro symboly, • malá latinská písmena t, u, v, w, . . . pro řetězce. Nyní uvedeme některé důležité operace nad řetězci. Definice 2.3 Nechť x a y jsou řetězce nad abecedou Σ. Konkatenací (zřetězením) řetězce x s řetězcem y vznikne řetězec xy připojením řetězce y za řetězec x. Operace konkatenace je zřejmě asociativní, tj. x(yz) = (xy)z, ne však komutativní, xy = yx. Příklad 2.3 Je-li x = ab, y = ba, pak xy = abba, yx = baab, x = x = ab, kde je prázdný řetězec. Definice 2.4 Nechť x = a1a2 . . . an je řetězec nad abecedou Σ, ai ∈ Σ pro i = 1, . . . , n. Reverzí (zrcadlovým obrazem) řetězce x rozumíme řetězec xR = anan−1 . . . a2a1; tj. symboly řetězce xR jsou vzhledem k řetězci x zapsány v opačném pořadí. Příklad 2.4 Je-li x = abbc, pak xR = cbba. Zřejmě R = . Definice 2.5 Nechť w je řetězec nad abecedou Σ. Řetězec z se nazývá podřetězcem řetězce w, jestliže existují řetězce x a y takové, že w = xzy. Řetězec x1 se nazývá prefixem (předponou) řetězce w, jestliže existuje řetězec y1 takový, že w = x1y1. Analogicky, řetězec y2 se nazývá sufixem (příponou) řetězce w, jestliže existuje řetězec x2 takový, že w = x2y2. Je-li y1 = , resp. x2 = , pak x1 je vlastní prefix, resp. y2 je vlastní sufix řetězce w. Příklad 2.5 Je-li w = abbc, pak a ab abb abbc jsou všechny prefixy řetězce w (první čtyři jsou vlastní), c bc bbc abbc jsou všechny sufixy řetězce w (první čtyři jsou vlastní) a a bb abb jsou některé podřetězce řetězce w. Zřejmě, prefix i sufix jsou podřetězce řetězce w, prázdný řetězec je podřetězcem, prefixem i sufixem každého řetězce. Definice 2.6 Délka řetězce je nezáporné celé číslo udávající počet symbolů řetězce. Délku řetězce x značíme symbolicky |x|. Je-li x = a1a2 . . . an, ai ∈ Σ pro i = 1, . . . n, pak |x| = n. Délka prázdného řetězce je nulová, tj. | | = 0. Konvence 2.2 Řetězec nebo podřetězec, který sestává právě z k výskytů symbolu a budeme symbolicky značit ak . Např. a3 = aaa, b2 = bb, a0 = . KAPITOLA 2. JAZYKY, GRAMATIKY A JEJICH KLASIFIKACE 10 Definice 2.7 Nechť Σ je abeceda. Označme symbolem Σ∗ množinu všech řetězců nad abecedou Σ včetně řetězce prázdného, symbolem Σ+ množinu všech řetězců nad Σ vyjma řetězce prázdného, tj. Σ∗ = Σ+ ∪ { }. Množinu L, pro níž platí L ⊆ Σ∗ (případně L ⊆ Σ+ , pokud /∈ L), nazýváme jazykem L nad abecedou Σ. Jazykem tedy může být libovolná podmnožina řetězců nad danou abecedou. Řetězec x, x ∈ L, nazýváme větou (také někdy slovem) jazyka L. Příklad 2.6 Nechť Σ je abeceda. Potenční množina 2Σ∗ reprezetuje všechny možné jazyky nad abecedou Σ. Nechť jazyky L1 a L2 jsou definovány nad binární abecedou, tj. L1, L2 ⊆ {0, 1}∗ , takto: L1 = {0n 1n | n ≥ 0} tj. L1 = { , 01, 0011, 000111, . . . } L2 = xxR | x ∈ {0, 1} + tj. L2 = {00, 11, 0000, 0110, 1001, 1111, . . . } Příklad 2.7 Uvažujeme abecedu programovacího jazyka Pascal. Jazyk Pascal je nekonečná množina řetězců (programů) nad jeho abecedou, které lze odvodit z grafů syntaxe jazyka Pascal (viz. [6]). Např. řetězec program P; begin end. je větou jazyka Pascal (přestože nepopisuje žádnou akci), kdežto řetězec procedure S; begin a := a mod b end nepatří do jazyka Pascal, protože reprezentuje pouze úsek možného programu (podřetězec nějaké věty). Povšimněme si nyní operací, které lze definovat nad jazyky. Tyto operace lze rozdělit do dvou skupin. Jednu skupinu představují obvyklé množinové operace plynoucí ze skutečnosti, že jazyk je množina. Má tedy smysl mluvit o sjednocení, průniku, rozdílu a komplementu jazyků. Je-li např. L1 jazyk nad abecedou Σ, pak jeho komplement (doplněk) L2 je jazyk, jenž je dán rozdílem L2 = Σ∗ \ L1. Druhá skupina operací respektuje specifikum množin tvořících jazyky, tj. skutečnost, že jejich prvky jsou řetězce. Z této skupiny definujeme operaci součinu a iterace jazyků. Definice 2.8 Nechť L1 je jazyk nad abecedou Σ1, L2 jazyk nad abecedou Σ2. Součinem (konkatenací) jazyků L1 a L2 je jazyk L1 · L2 nad abecedou Σ1 ∪ Σ2, jenž je definován takto: L1 · L2 = {xy | x ∈ L1, y ∈ L2} Operace součin jazyků je definována prostřednictvím konkatenace řetězců a má stejné vlastnosti jako konkatenace řetězců – je asociativní a nekomutativní. Příklad 2.8 Nechť: P = {A, B, . . . , Z, a, b, . . . , z}, C = {0, 1, . . . , 9} jsou abecedy L1 = P, L2 = (P ∪ C)∗ jsou jazyky KAPITOLA 2. JAZYKY, GRAMATIKY A JEJICH KLASIFIKACE 11 Součinem jazyků L1 · L2 je jazyk, který obsahuje všechny identifikátory, tak jak jsou obvykle definovány v programovacích jazycích. Prostřednictvím součinu jazyka se sebou samým (mocniny jazyka) můžeme definovat důležitou operaci nad jazykem – iteraci jazyka. Definice 2.9 Nechť L je jazyk nad abecedou Σ. Iteraci L∗ jazyka L a pozitivní iteraci L+ jazyka L definujeme takto: L0 = { } (1) Ln = L · Ln−1 pro n ≥ 1 (2) L∗ = n≥0 Ln (3) L+ = n≥1 Ln (4) Věta 2.1 Je-li L jazyk, pak platí: L∗ = L+ ∪ { } a (1) L+ = L · L∗ = L∗ · L (2) Důkaz: Tvrzení 1 plyne z definice iterace a pozitivní iterace: L∗ = L0 ∪ L1 ∪ L2 ∪ . . . , L+ = L1 ∪ L2 ∪ . . . L∗ = L0 ∪ L+ = L+ ∪ L0 = L+ ∪ { } Tvrzení 2 dostaneme provedením součinu L · L∗ resp. L∗ · L: L · L∗ = L · (L0 ∪ L1 ∪ L2 ∪ . . . ) = L1 ∪ L2 ∪ L3 ∪ · · · = L+ , s použitím distributivního zákona L1(L2∪L3) = L1L2∪L1L3. Podobně, s využitím ekvivalentní definice mocniny Ln = Ln−1 L, n ≥ 0 obdržíme L∗ · L = L+ . 2 Příklad 2.9 Je-li L1 = {(p}, L2 = {, p}, L3 = {)} potom jazyk L1 · L∗ 2 · L3 obsahuje řetězce: (p) (p, p) (p, p, p) (p, p, p, p) . . . Definice 2.10 Algebraická struktura A, +, ·, 0, 1 se nazývá polokruh s aditivním jednotkovým prvkem 0 a multiplikativním jednotkovým prvkem 1, jestliže (1) A, +, 0 je komutativní monoid (2) A, ·, 1 je monoid (3) pro operaci · platí distributivní zákon vzhledem k +: a · (b + c) = a · b + a · c pro a, b, c ∈ A. Věta 2.2 Algebra jazyků 2Σ∗ , ∪, ·, ∅, { } , kde ∪ je sjednocení a · konkatenace jazyků tvoří polokruh. KAPITOLA 2. JAZYKY, GRAMATIKY A JEJICH KLASIFIKACE 12 Důkaz: 1. 2Σ∗ , ∪, ∅ je komutativní monoid (∪ je komutativní a asociativní operace a L ∪ ∅ = ∅ ∪ L = L pro všechna L ∈ 2Σ∗ ). 2. 2Σ∗ , ·, { } je monoid: L · { } = { } · L = L pro všechna L ∈ 2Σ∗ . 3. Pro všechny L1, L2, L3 ∈ 2Σ∗ : L1(L2 ∪ L3) = {xy | (x ∈ L1) ∧ (y ∈ L2 ∨ y ∈ L3)} = = {xy | (x ∈ L1 ∧ y ∈ L2) ∨ (x ∈ L1 ∧ y ∈ L3)} = = {xy | x ∈ L1 ∧ y ∈ L2} ∪ {xy | x ∈ L1 ∧ y ∈ L3} = = L1L2 ∪ L1L3. 2 Příklad 2.10 Nechť L1 = {xy, z, x}, L2 = {a, bc} jsou jazyky. Specifikujte jazyky L1L2, L2 2, L∗ 2. Řešení: (1) L1L2 = {xy, z, x} · {a, bc} = {xya, xybc, za, zbc, xa, xbc} (2) L2 2 = L2 · L2 = {aa, abc, bca, bcbc} (3) L∗ 2 = {w | w je prázdný řetězec nebo řetězec nad abecedou {a, b, c} v němž každému výskytu symbolu c bezprotředně předchází výskyt symbolu b a za každým výskytem symbolu b bezprostředně následuje symbol c}. 2.2 Gramatika Pojem gramatika souvisí velmi úzce s problémem reprezentace jazyka. Triviální způsob reprezentace – výčet všech vět jazyka – je nepoužitelný nejen pro jazyky nekonečné, ale prakticky i pro rozsáhlé konečné jazyky. Také obvyklé matematické prostředky (použité v předchozích příkladech) jsou použitelné pouze pro reprezentaci jazyků s velmi jednoduchou strukturou. Gramatika, jako nejznámější prostředek pro reprezentaci jazyků, splňuje základní požadavek kladený na reprezentaci konečných i nekonečných jazyků, požadavek konečnosti reprezentace. Používá dvou konečných disjunktních abeced: 1. množiny N nonterminálních symbolů 2. množiny Σ terminálních symbolů Nonterminální symboly, krátce nonterminály, mají roli pomocných proměnných označujících určité syntaktické celky – syntaktické kategorie. Množina terminálních symbolů, krátce terminálů, je identická s abecedou, nad níž je definován jazyk. Sjednocení obou množin, tj. N ∪ Σ, nazýváme slovníkem gramatiky. Konvence 2.3 Pro zápis terminálních a nonterminálních symbolů a řetězců tvořených těmito symboly budeme používat této konvence: 1. a, b, c, d reprezentují terminální symboly 2. A, B, C, D, S reprezentují nonterminální symboly 3. U, V, . . . , Z reprezentují terminální nebo nonterminální symboly KAPITOLA 2. JAZYKY, GRAMATIKY A JEJICH KLASIFIKACE 13 4. α, β, . . . , ω reprezentují řetězce terminálních a nonterminálních symbolů 5. u, v, . . . , z reprezentují řetězce pouze terminálních symbolů 6. řetězec uzavřený v úhlových závorkách , reprezentuje nonterminální symbol (konvence používaná v BNF). Příklad 2.11 Slovník gramatiky pro definici jazyka identifikátorů může mít tvar: N = { identifikátor , písmeno , číslice } Σ = {A, B, . . . , Z, a, b, . . . , z, 0, 1, . . . , 9} Obsahuje tedy 65 symbolů. Gramatika představuje generativní systém, ve kterém lze z jistého vyznačeného nonterminálu generovat, aplikací tzv. přepisovacích pravidel, řetězce tvořené neterminálními a terminálními symboly, které nazýváme větnými formami. Větné formy, které jsou tvořeny pouze terminálními symboly, reprezentují věty gramatikou definovaného jazyka. Může se přitom samozřejmě stát, že gramatika negeneruje žádnou větu a reprezentuje pak prázdný jazyk. Jádrem gramatiky je tak konečná množina P přepisovacích pravidel (nazývaných také produkce). Každé přepisovací pravidlo má tvar uspořádané dvojice (α, β) řetězců; stanovuje možnou substitucí řetězce β namísto řetězce α, který se vyskytuje jako podřetězec generovaného řetězce. Řetězec α obsahuje alespoň jeden nonterminální symbol, řetězec β je prvek množiny (N ∪Σ)∗ . Formálně vyjádřeno, množina P přepisovacích pravidel je podmnožinou kartézského součinu: P ⊆ (N ∪ Σ)∗ N(N ∪ Σ)∗ × (N ∪ Σ)∗ Příklad 2.12 Uvažujme, že např. dvojice (AB, CDE) je jedním z přepisovacích pravidel gramatiky a předpokládejme, že řetězec x = FGABH byl získán aplikací jiných pravidel gramatiky. Aplikujeme-li nyní na řetězec x pravidlo (AB, CDE), obdržíme řetězec y = FGCDEH (nahrazením podřetězce AB řetězce x řetězcem CDE). Říkáme, že jsme řetězec y odvodili (derivovali) z řetězce x podle přepisovacího pravidla (AB, CDE). Přistoupíme nyní k úplné definici gramatiky a formální definici pojmů, jejichž prostřednictvím lze definovat jazyk generovaný gramatikou. Definice 2.11 Gramatika G je čtveřice G = (N, Σ, P, S), kde • N je konečná množina nonterminálních symbolů • Σ je konečná množina terminálních symbolů, N ∩ Σ = ∅ • P je konečná podmnožina kartézského součinu (N∪Σ)∗ N(N∪Σ)∗ ×(N∪Σ)∗ , • S ∈ N je výchozí (také počáteční) symbol gramatiky Prvek (α, β) množiny P nazýváme přepisovacím pravidlem (krátce pravidlem) a budeme jej zapisovat ve tvaru α → β. Řetězec α resp. β nazýváme levou resp. pravou stranou přepisovacího pravidla. Příklad 2.13 G = ({A, S}, {0, 1}, P, S) P = {S → 0A1, 0A → 00A1, A → } KAPITOLA 2. JAZYKY, GRAMATIKY A JEJICH KLASIFIKACE 14 Příklad 2.14 Gramatika definující jazyk identifikátorů může mít tvar: G = (N, Σ, P, S), kde N = { identifikátor , písmeno , číslice } Σ = {A, B, . . . , Z, a, b, . . . , z, 0, 1, . . . , 9} P = { identifikátor → písmeno , identifikátor → identifikátor písmeno , identifikátor → identifikátor číslice , písmeno → A, ... písmeno → Z, číslice → 0, ... číslice → 9} S = identifikátor Množina P obsahuje 65 přepisovacích pravidel. Konvence 2.4 Obsahuje-li množina pravidel P přepisovací pravidla tvaru α → β1, α → β2, . . . , α → βn, pak pro zkrácení lze použít zápisu α → β1 | β2 | . . . | βn. Definice 2.12 Nechť G = (N, Σ, P, S) je gramatika a nechť λ a µ jsou řetězce z (N ∪ Σ)∗ . Mezi řetězci λ a µ platí binární relace ⇒ G , nazývaná přímá derivace, jestliže můžeme řetězce λ a µ vyjádřit ve tvaru λ = γαδ µ = γβδ kde γ a δ jsou libovolné řetězce z (N ∪Σ)∗ a α → β je nějaké přepisovací pravidlo z P. Platí-li mezi řetězci λ a µ relace přímé derivace, pak píšeme λ ⇒ G µ a říkáme, že řetězec µ lze přímo generovat z řetězce λ v gramatice G. Je-li z kontextu zřejmé, že jde o derivaci v gramatice G, pak nemusíme specifikaci gramatiky pod symbolem ⇒ uvádět. Příklad 2.15 Uvažujme gramatiku z příkladu 2.13 a řetězce λ = 000A111 a µ = 0000A1111. Položíme-li λ = 00 γ 0A α 111 δ µ = 00 γ 00A1 β 111 δ vidíme, že platí 000A111 ⇒ 0000A1111, protože 0A → 00A1 je pravidlem v této gramatice. KAPITOLA 2. JAZYKY, GRAMATIKY A JEJICH KLASIFIKACE 15 Příklad 2.16 Je-li α → β pravidlo v gramatice G, pak v této gramatice platí α ⇒ β, jak plyne z definice 2.12, položíme-li γ = δ = . Definice 2.13 Nechť G = (N, Σ, P, S) je gramatika a λ a µ jsou řetězce z (N ∪ Σ)∗ . Mezi řetězci λ a µ platí relace ⇒+ nazývaná derivace, jestliže existuje posloupnost přímých derivací νi−1 ⇒ νi i = 1, . . . , n, n ≥ 1 taková, že platí: λ = ν0 ⇒ ν1 ⇒ . . . ⇒ νn−1 ⇒ νn = µ Tuto posloupnost nazýváme derivací délky n. Platí-li λ ⇒+ µ, pak říkáme, že řetězec µ lze generovat z řetězce λ v gramatice G. Relace ⇒+ je zřejmě tranzitivním uzávěrem relace přímé derivace ⇒ . Symbolem ⇒n značíme n-tou mocninu relace ⇒. Příklad 2.17 V gramatice z příkladu 2.13 platí (v důsledku pravidla 0A → 00A1, viz příklad 2.15) relace 0n A1n ⇒ 0n+1 A1n+1 n > 0 a tudíž také 0A1 ⇒+ 0n A1n pro libovolné n > 1. Definice 2.14 Jestliže v gramatice G platí pro řetězce λ a µ relace λ ⇒+ µ nebo identita λ = µ, pak píšeme λ ⇒∗ µ. Relace ⇒∗ je tranzitivním a reflexivním uzávěrem relace přímé derivace ⇒. Příklad 2.18 Relaci 0A1 ⇒+ 0n A1n , n > 1 z příkladu 2.17 lze rozšířit na relaci 0A1 ⇒∗ 0n A1n , n > 0 Poznámka 2.1 Dojdeme-li v posloupnosti přímých derivací k řetězci, který obsahuje pouze terminální symboly, pak již nelze aplikovat žádné přepisovací pravidlo a proces generování končí. Z této skutečnosti, jež vyplývá z definice pravidla, je odvozen název množiny Σ jako množiny terminálních symbolů. Definice 2.15 Nechť G = (N, Σ, P, S) je gramatika. Řetězec α ∈ (N ∪ Σ)∗ nazýváme větnou formou, jestliže platí S ⇒∗ α, tj. řetězec α je generovatelný z výchozího symbolu S. Větná forma, která obsahuje pouze terminální symboly, se nazývá věta. Jazyk L(G), generovaný gramatikou G, je definován množinou všech vět L(G) = {w | S ⇒∗ w ∧ w ∈ Σ∗ } Příklad 2.19 Jazyk generovaný gramatikou G z příkladu 2.13 je množina L(G) = {0n 1n | n > 0}, protože platí S ⇒ 0A1 S ⇒∗ 0n A1n n > 0 (viz příklad 2.17 a 2.18) S ⇒∗ 0n 1n n > 0 (po aplikaci pravidla A → ) KAPITOLA 2. JAZYKY, GRAMATIKY A JEJICH KLASIFIKACE 16 2.3 Chomského klasifikace gramatik Chomského klasifikace gramatik (a jazyků), známá také pod názvem Chomského hierarchie jazyků, vymezuje čtyři typy gramatik, podle tvaru přepisovacích pravidel, jež obsahuje množina přepisovacích pravidel P. Tyto typy se označují jako typ 0, typ 1. typ 2 a typ 3. 2.3.1 Typ 0 Gramatika typu 0 obsahuje pravidla v nejobecnějším tvaru, shodným s definicí 2.11 gramatiky: α → β, α ∈ (N ∪ Σ)∗ N(N ∪ Σ)∗ , β ∈ (N ∪ Σ)∗ . Z tohoto důvodu se gramatiky typu 0 nazývají také gramatikami neomezenými. Příklad 2.20 Příklad neomezené gramatiky: G = ({A, B}, {a, b}, P, A) s pravidly A → AbB | a AbB → baB | BAbB B → b | 2.3.2 Typ 1 Gramatika typu 1 obsahuje pravidla tvaru: αAβ → αγβ, A ∈ N, α, β ∈ (N ∪ Σ)∗ , γ ∈ (N ∪ Σ)+ nebo S → , pokud se S neobjevuje na pravé straně žádného pravidla. Gramatiky typu 1 se nazývají také gramatikami kontextovými, poněvadž tvar pravidla této gramatiky implikuje, že nonterminál A může být nahrazen řetězcem γ pouze tehdy, je-li jeho pravým kontextem řetězec β a levým kontextem řetězec α. Kontextové gramatiky neobsahují pravidla tvaru αAβ → αβ, tj. nepřipouštějí, aby byl nonterminál nahrazen prázdným řetězcem. Jedinou přípustnou výjimkou je pravidlo S → , a to jen za předpokladu, že se S, tj. výchozí symbol gramatiky, neobjevuje na pravé straně žádného pravidla. Připadné použití pravidla S → umožňuje popsat příslušnost prázdného řetězce k jazyku, který je danou gramatikou generován. V důsledku této vlastnosti pravidel gramatiky typu 1 nemůže při generování věty dojít ke zkrácení generovaných řetězců, tj. platí-li λ ⇒ µ, pak |λ| ≤ |µ| (s výjimkou S ⇒ ). Příklad 2.21 Příklad kontextové gramatiky: G = ({A, S}, {0, 1}, P, S) s pravidly S → 0A | 0A → 00A1 (α = 0, β = , γ = 0A1) A → 1 Dodejme, že v literatuře je možné se setkat s alternativní definicí gramatik typu 1, která definuje stejnou třídu jazyků. V této definici se připouští pouze pravidla tvaru α → β, kde |α| ≤ |β|, nebo S → , pokud se S neobjevuje na pravé straně žádného pravidla. KAPITOLA 2. JAZYKY, GRAMATIKY A JEJICH KLASIFIKACE 17 2.3.3 Typ 2 Gramatika typu 2 obsahuje pravidla tvaru: A → γ, A ∈ N, γ ∈ (N ∪ Σ)∗ . Gramatiky typu 2 se nazývají také bezkontextovými gramatikami, protože substituci pravé strany γ pravidla za nonterminál A lze provádět bez ohledu na kontext, ve kterém je nonterminál A uložen. Na rozdíl od kontextových gramatik, bezkontextové gramatiky smí obsahovat pravidla tvaru A → . V kapitole 4 však ukážeme, že každou bezkontextovou gramatiku lze transformovat, aniž by se změnil jazyk generovaný touto gramatikou tak, že obsahuje nejvýše jedno pravidlo s prázdným řetězcem na pravé straně tvaru S → . V takovém případě, stejně jako v případě kontextových gramatik, nesmí se výchozí symbol S objevit v žádné pravé straně přepisovacího pravidla gramatiky. Příklad 2.22 Příklad bezkontextové gramatiky: G = ({S}, {0, 1}, P, S) s pravidly S → 0S1 | Poznamenejme, že jazyk generovaný touto gramatikou je stejný jako jazyk generovaný kontextovou gramatikou z příkladu 2.21: L(G) = {0n 1n }, n ≥ 0 2.3.4 Typ 3 Gramatika typu 3 obsahuje pravidla tvaru: A → xB nebo A → x; A, B ∈ N, x ∈ Σ∗ . Gramatika s tímto tvarem pravidel se nazývá pravá lineární gramatika (jediný možný nonterminál pravé strany pravidla stojí úplně napravo). V následující kapitole ukážeme, že k uvedené gramatice lze sestrojit ekvivalentní speciální pravou lineární gramatiku s pravidly tvaru A → aB nebo A → a, kde A, B ∈ N, a ∈ Σ nebo S → , pokud se S neobjevuje na pravé straně žádného pravidla. Tuto gramatiku budeme nazývat regulární gramatikou, přesněji pravou regulární gramatikou. Příklad 2.23 Příklady gramatiky typu 3: G = ({A, B}, {a, b, c}, P, A) s pravidly A → aaB | ccB B → bB | KAPITOLA 2. JAZYKY, GRAMATIKY A JEJICH KLASIFIKACE 18 Definice 2.16 Jazyk generovaný gramatikou typu i, i = 0, 1, 2, 3, nazýváme jazykem typu i. Podle názvů gramatik mluvíme také o jazycích rekurzivně vyčíslitelných (i = 0) a analogicky ke gramatikám jazycích kontextových (i = 1), bezkontextových (i = 2) a regulárních (i = 3)1 . Věta 2.3 Nechť Li, i = 0, 1, 2, 3 značí třídu všech jazyků typu i. Pak platí L0 ⊇ L1 ⊇ L2 ⊇ L3. Důkaz: Z definice gramatiky typu i plyne, že každá gramatika typu 1 je zároveň gramatikou typu 0 a každá gramatika typu 3 je zároveň bezkontextovou gramatikou. Inkluze L1 ⊇ L2 plyne ze skutečnosti, že každá bezkontextová gramatika může být převedena na bezkontextovou gramatiku, jež neobsahuje, s výjimkou pravidla S → (S je výchozí symbol), žádné pravidlo s pravou stranou totožnou s prázdným řetězcem . 2 K základním poznatkům teorie formálních jazyků patří další tvrzení, jež je zesílením věty 2.3 a jež definuje Chomského hierarchii formálních jazyků. Toto tvrzení uvádíme nyní bez důkazu. Věta 2.4 Nechť Li, i = 0, 1, 2, 3 jsou třídy jazyků typu i. Pak platí L0 ⊃ L1 ⊃ L2 ⊃ L3. Formální jazyk je univerzálním prostředkem pro kódování informace a popis objektů řady aplikací, které lze reprezentovat a zpracovávat počítačovými programy. Algebraický charakter operací nad formálními jazyky umožňuje kompozitní řešení složitých problémů jejich rozkladem a skládáním výsledného řešení. Chomského hierarchie gramatik a formálních jazyků je referenčním schématem klasifikace aplikací teorie formálních jazyků a prostředkem vymezujícím popisnou a rozhodovací sílu dané třídy formálních modelů. 2.4 Cvičení Cvičení 2.4.1 Uspořádejte (podle množinové inkluse) tyto jazyky (a) {a, b}∗ (b) a∗ b∗ c∗ (c) {w | w ∈ {a, b}∗ a počet výskytů symbolů a a b je roven } Cvičení 2.4.2 Na základě Chomského klasifikace gramatik a jazyků rozhodněte typ dané gramatiky. Uvádíme pouze pravidla gramatiky; velká písmena značí nonterminální symboly (S je výchozí symbol) a malá písmena nebo číslice značí terminální symboly. 1Toto označení vychází z ekvivalence vyjadřovací síly gramatik typu 3 a gramatik regulárních. KAPITOLA 2. JAZYKY, GRAMATIKY A JEJICH KLASIFIKACE 19 (a) S → bSS | a (b) S → 00S1 | (c) S → bA A → eB B → gC C → iD D → n (d) S → sur A S → in A S → bi A S → pro A A → jekce (e) S → SZ1 Y1Z3 → Y Z3 ZZ1 → Z2Z1 S → X1Z1 Y Z3 → Y Z Z2Z1 → Z2Z X1 → aY1 Y1Y → Y1Z2 Z2Z → Z1Z X1 → aX1Y1 Y1Y2 → Y Y2 Y → b Y1Z1 → Y1Z3 Y Y2 → Y Y1 Z → c (f) S → Y XY ZY → XXY Y X → Y Z X → a ZX → XXZ Y → V gramatikách (a)–(f) vytvořte derivace terminálních řetězců a stanovte jazyky L(G), které tyto gramatiky specifikují. Cvičení 2.4.3 Při popisu syntaxe programovacích jazyků se často používají určité konvence, které zkracují zápisy syntaktických definic. Hranaté závorky označují volitelnost řetězců, např. statement → if expr then statement else [ statement ] složené závorky pak iteraci řetězce včetně 0 − násobné iterace jako v příkladu definice složeného příkazu: statement → begin statement {; statement } end . Stanovte ekvivalentní zápisy pravidly bezkontextové gramatiky pro (1) A → α [β] γ (2) A → α {β} γ Cvičení 2.4.4 Vytvořte gramatiku typu 3, která generuje identifikátory jež mohou mít maximálně 6 znaků a začínají písmenem I, J, K, L, M nebo N(celočíselné proměnné v jazyce Fortran). Cvičení 2.4.5 Vytvořte gramatiku typu 3, která generuje čísla jazyka Pascal. Cvičení 2.4.6 Vytvořte bezkontextovou gramatiku, která generuje všechny řetězce nul a jedniček takové, že počet nul je v každém řetězci shodný s počtem jedniček. Cvičení 2.4.7 Ukažte, že neomezená gramatika G = ({S, B, C}, {a, b, c}, P, S), kde P obsahuje pravidla S → SaBC, Ca → aC, S → aBC, BC → CB, aB → Ba, CB → BC, Ba → aB, B → b, aC → Ca, C → c generuje věty ve kterých je počet výskytů symbolů a, b, c navzájem roven. Cvičení 2.4.8 Nechť je N množina neterminálních symbolů a Σ množina terminálů. Ukažte, že pravidla tvaru A → r, kde A ∈ N a r je regulární výraz nad abecedou (N ∪ Σ) lze převést na pravidla bezkontextové gramatiky. KAPITOLA 2. JAZYKY, GRAMATIKY A JEJICH KLASIFIKACE 20 Podle navrženého postupu převeďte na ekvivalentní pravidla bezkontextové gramatiky pravidlo A → a (C + D), kde symboly ∗ , + , (, ) jsou metasymboly regulárního výrazu. Cvičení 2.4.9 Sestrojte gramatiky, které generují tyto jazyky: (a) L = {wwR | w ∈ {a, b}∗ } (b) L = {wcwR | w ∈ {a, b}+ } (c) jazyk aritmetických výrazů s operátory +, ∗, / a − ve významu unárního i binárního operátoru. (d) jazyk identifikátorů (vytvořte gramatiky s levou rekurzí, s pravou rekurzí a s minimálním počtem pravidel). Kapitola 3 Regulární jazyky 20:00 Cílem této kapitoly je důkladné pochopení alternativních prostředků specifikace regulárních jazyků, důkazových technik, které verifikují jejich ekvivalenci a formálních algoritmů zápisů jejich vzájemných převodů. Vede dále k pochopení základních vlastností regulárních jazyků, jež činí tuto třídu nejvíce aplikovatelnou v řadě technických i netechnických oblasí. Kapitola stanovuje rámce teorie, které jsou využívány i v následujících částech učebního textu. 3.1 Jazyky přijímané konečnými automaty a deterministický konečný automat 3.1.1 Nedeterministický konečný automat Definice 3.1 Nedeterministický konečný automat (NKA) je 5-tice M = (Q, Σ, δ, q0, F), kde (1) Q je konečná množina stavů, (2) Σ je konečná vstupní abeceda, (3) δ je zobrazení Q × Σ → 2Q , které nazýváme funkcí přechodu (2Q je množina podmnožin množiny Q), (4) q0 ∈ Q je počáteční stav, (5) F ⊆ Q je množina koncových stavů. Deterministický konečný automat definujeme analogicky jako nedeterministický s tím, že přechodová funkce má tvar δ : Q × Σ → Q ∪ {nedef}, nedef ∈ Q. Činnost konečného automatu M je dána posloupností přechodů; přechod z jednoho stavu do druhého je řízen funkcí přechodu δ, která na základě přítomného stavu qi a právě přečteného symbolu a ∈ Σ vstupního řetězce předepisuje budoucí stav qj automatu. Je-li M deterministický konečný automat, δ předepisuje vždy jediný budoucí stav qj ∈ Q, nebo nedef, což znamená, že přechod není možný1 ; v případě nedeterministického konečného automatu δ předepisuje množinu budoucích stavů Qj, Qj ∈ 2Q . Definice 3.2 Je-li M = (Q, Σ, δ, q0, F) konečný automat, pak dvojici C = (q, w) z Q×Σ∗ nazýváme konfigurací automatu M. Konfigurace tvaru (q0, w) je počáteční konfigurace, konfigurace tvaru (q, ), q ∈ F je koncová konfigurace. Přechod automatu M je reprezentován binární relací M na množině konfigurací C. Pro všechna q, q ∈ Q a w, w ∈ Σ∗ definujeme, že platí (q, w) M (q , w ), tehdy a jen tehdy, když w = aw pro nějaké a ∈ Σ a q ∈ δ(q, a) (tj. δ(q, a) = Qj, Qj ∈ 2Q , q ∈ Qj). Označíme symbolem k M , k ≥ 0, k-tou mocninu (C 0 C právě když C = C ), 1Alternativou je použít parciální přechodovou funkci Q × Σ → Q. 21 KAPITOLA 3. REGULÁRNÍ JAZYKY 22 δ z c · e q0 q8 q7 q6 q4 q1 q2 q2 q1 q3 q2 q4 q3 q2 q5 q5 q4 q1 q6 q5 q7 q7 q6 q4 q1 q8 q7 q6 q4 Tabulka 3.1: Funkce přechodů automatu M symbolem + M tranzitivní uzávěr a symbolem ∗ M tranzitivní a reflexivní uzávěr relace M . Bude-li zřejmé, že jde o automat M, pak uvedené relace zapíšeme pouze ve tvaru , k , + , ∗ . Definice 3.3 Říkáme, že vstupní řetězec w je přijímán konečným automatem M, jestliže (q0, w) ∗ (q, ), q ∈ F. Jazyk přijímaný konečným automatem M označujeme symbolem L(M) a definujeme ho jako množinu všech řetězců přijímaných automatem M: L(M) = {w | (q0, w) ∗ (q, ) ∧ q ∈ F} Příklad 3.1 Konečný deterministický automat M = ({g0, q1, q3, q4, q5, q6, q7, q8}, {c, z,10 , ·, }, δ, q0, {q1}), jehož funkce přechodu δ je definována tabulkou 3.1, přijímá jazyk zápisů čísel, jak ho známe z některých programovacích jazyků. Symbolem c značíme prvek množiny {0, 1, . . . , 9}, symbolem z prvek množiny {+, −}; znak ukončuje zápis čísla. Např. vstupnímu řetězci zc.cezc (např. číslu +3.1e − 5) bude odpovídat tato posloupnost konfigurací: (q0, zc.cezc ) (q8, c.cezc ) (q7, .cezc ) (q6, cezc ) (q5, ezc ) (q4, zc ) (q3, c ) (q2, ) (q1, ) Poněvadž (q0, zc.cezc ) ∗ (q1, ), patří zc.cezc do L(M). Příklad 3.2 Nedeterministický konečný automat (NKA) M1 = ({q0, q1, q2, qF }, {0, 1}, δ, q0, {qF }) má přechodovou funkci definovanou takto: KAPITOLA 3. REGULÁRNÍ JAZYKY 23 δ : δ(q0, 0) = {q0, q1} δ(q0, 1) = {q0, q2} δ(q1, 0) = {q1, qF } δ(q1, 1) = {q1} δ(q2, 0) = {q2} δ(q2, 1) = {q2, qF } δ(qF , 0) = ∅ δ(qF , 1) = ∅ Alternativními způsoby reprezentace funkce δ může být 1. matice přechodů nebo 2. diagram přechodů. 1. matice (přechodů) 2. diagram přechodů 0 1 q0 {q0, q1} {q0, q2} q1 {q1, qF } {q1} q2 {q2} {q2, qF } qF ∅ ∅ Příklad 3.3 Uvažujme NKA M1 z příkladu 1.5. Platí: (q0, 1010) (q0, 010) (q1, 10) (q1, 0) (qf , ) a tedy: (q0, 1010) ∗ (qf , ) Neplatí například (q0, ) ∗ (qf , ) Vyjádření jazyka L(M1): L(M1) = {w | w ∈ {0, 1}∗ ∧w končí symbolem, který je již v řetězci w obsažen}. Vztah mezi nedeterministickými a deterministickými konečnými automaty patří k základním poznatkům teorie formálních jazyků. Věta 3.1 Každý nedeterministický konečný automat M lze převést na deterministický konečný automat M tak, že L(M) = L(M ). Důkaz: 1. Nejprve nalezneme algoritmus převodu M → M : Algoritmus 3.1 Převod nedeterministického konečného automatu na ekvivalentní deterministický konečný automat. Vstup: Nedeterministický konečný automat M = (Q, Σ, δ, q0, F) Výstup: Deterministický konečný automat M = (Q , Σ, δ , q0, F ) Metoda: 1. Polož Q = 2Q \ {∅}. 2. Polož q0 = {q0}. 3. Polož F = {S | S ∈ 2Q ∧ S ∩ F = ∅}. 4. Pro všechna S ∈ 2Q \ {∅} a pro všechna a ∈ Σ polož: • δ (S, a) = q∈S δ(q, a), je-li q∈S δ(q, a) = ∅. • Jinak δ (S, a) = nedef. KAPITOLA 3. REGULÁRNÍ JAZYKY 24 2. Nyní je třeba ukázat, že L(M) = L(M ) tj. že platí: (a) L(M) ⊆ L(M ) a současně, (b) L(M ) ⊆ L(M). Tuto část důkazu ponecháme jako cvičení. 2 Příklad 3.4 Uvažujme nedeterministický konečný automat M2 = ({S, A, B, C}, {a, b, c}, δ, S, {A}), δ : δ(S, a) = {A}, δ(S, c) = {B}, δ(B, b) = {B, C}, δ(C, a) = {B}, δ(C, c) = {A}. K nalezení funkce δ příslušného DKA aplikujeme zkrácený postup, využívající skutečnosti, že řada stavů z 2Q může být nedostupných: 1. Počáteční stav: {S} 2. δ ({S}, a) = {A} — koncový stav δ ({S}, c) = {B} 3. δ ({B}, b) = {B, C} 4. δ ({B, C}, a) = δ(B, a) ∪ δ(C, a) = {B} δ ({B, C}, b) = {B, C} δ ({B, C}, c) = {A} 3.1.2 Lineární a regulární gramatiky Dříve, než přistoupíme k důkazu ekvivalence třídy L3 a třídy jazyků přijímaných konečnými automaty, ukážeme, že každý jazyk typu 3 může být generován speciálním typem gramatiky, než je pravá lineární gramatika. Definice 3.4 • Gramatika G = (N, Σ, P, S) s pravidly tvaru: A → xB A, B ∈ N, x ∈ Σ∗ nebo A → x x ∈ Σ∗ , resp. tvaru: A → Bx A, B ∈ N nebo A → x x ∈ Σ∗ se nazývá pravá lineární, resp. levá lineární, gramatika. KAPITOLA 3. REGULÁRNÍ JAZYKY 25 • Gramatika G = (N, Σ, P, S) s pravidly tvaru: A → aB A, B ∈ N, a ∈ Σ, A → a a ∈ Σ, případně S → pokud se S neobjevuje na pravé straně žádného pravidla resp. s pravidly tvaru: A → Ba A, B ∈ N, a ∈ Σ, A → a a ∈ Σ, případně S → pokud se S neobjevuje na pravé straně žádného pravidla se nazývá pravá regulární, resp. levá regulární, gramatika. Gramatiky pravé regulární i levé regulární můžeme též označit souhrnně jako regulární. Poznámka 3.1 Gramatika G = (N, Σ, P, S) s pravidly tvaru A → xBy nebo A → x, kde A, B ∈ N a x, y ∈ Σ∗ se nazývá lineární gramatika. Označme: • LP L – všechny jazyky generované pravými lineárními gramatikami, • LLL – všechny jazyky generované levými lineárními gramatikami, • LL – všechny jazyky generované lineárními gramatikami. Platí: LP L = LLL a LP L ⊂ LL. Věta 3.2 Každá pravá lineární gramatika G = (N, Σ.P, S), tj. gramatika obsahující pouze pravidla typu A → xB nebo A → x, kde A, B ∈ N, x ∈ Σ∗ , může být transformována na gramatiku G = (N , Σ, P , S ), která obsahuje pouze pravidla tvaru A → aB nebo A → , přičemž L(G) = L(G ). Důkaz: Množinu přepisovacích pravidel P gramatiky G konstruujeme takto: (1) všechna pravidla z P tvaru A → aB a A → kde A, B ∈ N, a ∈ Σ zařadíme do množiny P (2) každé pravidlo tvaru A → a1a2 . . . anB; A, B ∈ N, ai ∈ Σ, n ≥ 2 z množiny P nahradíme v množině P soustavou pravidel: A → a1A1 A1 → a2A2 ... An−1 → anB Nově zavedené nonterminály A1, . . . , An−1 přidáme k množině N . Derivaci A ⇒ G a1 . . . anB zřejmě odpovídá právě derivace A ⇒ G n a1a2 . . . anB. KAPITOLA 3. REGULÁRNÍ JAZYKY 26 (3) Každé pravidlo tvaru A → a1 . . . an, ai ∈ Σ, n ≥ 2 z množiny P nahradíme v množině P soustavou pravidel: A → a1A1 A1 → a2A2 ... An−1 → anAn An → Derivaci A ⇒ G a1a2 . . . an zřejmě odpovídá právě derivace A ⇒ G n+1 a1a2 . . . an. (4) zbývající, tzv. jednoduchá pravidla tvaru A → B, A, B ∈ N, nahradíme takto: (a) Pro každé A ∈ N sestrojíme množinu NA = {B | A ⇒∗ B}. (b) Množinu pravidel P rozšíříme takto: Jesliže B → α je v P a není jednoduchým pravidlem, pak pro všechna A, pro něž B ∈ NA, přidáme k P pravidla A → α. Bod 4b aplikuje obecný algoritmus odstranění jednoduchých pravidel bezkontextové gramatiky, který je uveden a dokázán v kapitole 4 (algoritmus 4.5). Jeho součástí je také výpočet množiny NA. 2 Příklad 3.5 Na základě předchozí věty budeme transformovat pravou lineární gramatiku G = ({X, Y }, {a, b, c}, P, X), kde P obsahuje pravidla: X → abc | Y | Y → aY | cbX Podle 1 budou v P pravidla: X → , Y → aY Podle 2 nahradíme pravidlo Y → cbX pravidly Y → cZ, Z → bX Podle 3 nahradíme pravidlo X → abc pravidly X → aU, U → bV, V → cW, W → Podle 4 nahradíme pravidlo X → Y . Protože NX = {X, Y } přidáme k P pravidla X → aY, X → cZ Výsledná gramatika má pak tvar G = ({X, Y, Z, U, V, W}, {a, b, c}, P , X) kde P obsahuje pravidla: X → | aY | cZ | aU Y → aY | cZ Z → bX U → bV V → cW W → KAPITOLA 3. REGULÁRNÍ JAZYKY 27 Věta 3.3 Každý jazyk typu 3 lze generovat pravou regulární gramatikou. Důkaz: Pravou regulární gramatiku získáme z gramatiky zkonstruované podle věty 3.2 odstraněním pravidel s prázdným řetězcem na pravé straně. Systematicky tento postup popisuje algoritmus 4.4 v kapitole 4 (níže jej ilustrujeme na příkladě). 2 Příklad 3.6 Gramatiku z příkladu 3.5 převedeme na pravou regulární odstraněním pravidla W → (vznikne pravidlo V → c) a pravidla X → (vznikne pravidlo Z → b). Protože ∈ L(G) a X je na pravé straně pravidla Z → bX, musíme zavést nový výchozí symbol X a odstranit jednoduché pravidlo X → X. Výsledná gramatika bude mít tvar: G = ({X , X, Y, Z, U, V }, {a, b, c}, P , X ), P obsahuje pravidla: X → | aY | cZ | aU Y → aY | cZ Z → bX | b X → aY | cZ | aU U → bV V → c Věta 3.4 Každý jazyk typu 3 může být generován levou lineární gramatikou. Důkaz: Úplný důkaz ponecháme na cvičení. Lze postupovat tak, že nejprve z definice regulární množiny dokážeme tvrzení: je-li L regulární množina, pak LR je také regulární množina. Dále ukážeme: je-li G = (N, Σ, P, S) pravá lineární gramatika, pak levá lineární gramatika G , jejíž množina pravidel má tvar P = {A → αR | A → α je v P}, generuje jazyk (L(G))R . 2 Příklad 3.7 Gramatika G = ({X, Y }, {a, b, c}, P , X), kde P obsahuje pravidla X → cba | Y | Y → Y a | Xbc je levá lineární gramatika, pro kterou L(G ) = (L(G))R a G je pravá lineární gramatika z příkladu 3.5. Věta 3.5 Každý jazyk typu 3 lze generovat levou regulární gramatikou. Důkaz: Konstrukce levé regulární gramatiky k dané levé lineární gramatice je zcela analogická konstrukci pravé regulární gramatiky k dané pravé lineární gramatice, a je proto ponechána na čtenáři (ilustraci poskytuje následující příklad). 2 Příklad 3.8 Uvažujme gramatiku z příkladu 3.7, jež má pravidla: X → cba | Y | Y → Y a | Xbc KAPITOLA 3. REGULÁRNÍ JAZYKY 28 1. krok zavádí pouze pravidla typu A → Ba nebo A → : X → Ua | Y a | Zc | Y → Y a | Zc U → V b V → Wc W → Z → Xb 2. krok odstraňuje pravidla typu A → a upravuje gramatiku na konečný tvar: X → Ua | Y a | Zc | Y → Y a | Zc U → V b V → c Z → Xb | b X → Ua | Y a | Zc Povšimněme si, v čem se liší pravidla této gramatiky od pravidel pravé regulární gramatiky z příkladu 3.6, jež byla získána z pravé lineární gramatiky (příklad 3.5). 3.1.3 Ekvivalence třídy L3 a třídy jazyků přijímaných konečnými automaty Označíme LM třídu jazyků přijímaných konečnými automaty a ukážeme, že L3 = LM . Věta 3.6 Nechť L je jazyk typu 3. Pak existuje konečný automat M takový, že L = L(M), tj. L3 ⊆ LM . Důkaz: Podle věty 3.2 můžeme jazyk L generovat gramatikou G = (N, Σ, P, S) typu 3, jejíž pravidla mají tvar A → aB nebo A → (A, B ∈ N, a ∈ Σ). Sestrojme konečný (nedeterministický) automat M = (Q, Σ, δ, q0, F), kde: (1) Q = N, (2) Σ = Σ, (3) δ : δ(A, a) obsahuje B pro každé pravidlo A → aB z P, (4) q0 = S, (5) F = {A | A → je pravidlo z P}. Ukážeme, že L(G) = L(M). Důkaz provedeme indukcí. Dokazovaná induktivní hypotéza nechť má tvar: pro každé A ∈ N platí A ⇒ G i+1 w, w ∈ Σ∗ , právě když (A, w) i M (C, ) pro nějaké C ∈ F. KAPITOLA 3. REGULÁRNÍ JAZYKY 29 Nejdříve dokážeme tuto hypotézu pro i = 0. Zřejmě platí A ⇒ , právě když (A, ) 0 (A, ) pro A ∈ F. Nyní předpokládejme, že dokazovaná hypotéza platí pro i > 0 a položíme w = ax, a ∈ Σ, |x| = i − 1. Pak platí A ⇒i+1 w, právě když A ⇒ aB ⇒i x. Podle definice funkce δ pak δ(A, a) obsahuje B (v důsledku přímé derivace A ⇒ aB). Na základě induktivní hypotézy platí B ⇒i x, právě když (B, x) i−1 (C, ), C ∈ F. Shrneme-li tyto skutečnosti, platí: A ⇒ aB ⇒i ax = w, právě když (A, ax) (B, x) i−1 (C, ), C ∈ F tj. A ⇒i+1 w, právě když (A, w) i (C, ), C ∈ F; tím jsme platnost induktivního předpokladu dokázali pro všechna i ≥ 0. Speciálně pak platí S ⇒∗ w, právě když (S, w) ∗ (C, ), C ∈ F a tedy L(G) = L(M). 2 Příklad 3.9 Ke gramatice G = ({X, Y, Z, U, V, W}, {a, b, c}, P, X), kde P obsahuje pravidla X → | aY | cZ | aU Y → aY | cZ Z → bX U → bV V → cW W → sestrojíme konečný automat, který přijímá jazyk L(G). Budeme postupovat podle věty 3.6. Funkci přechodů δ reprezentujeme diagramem přechodů (obr. 3.1), v němž koncové stavy jsou vyznačeny dvojitým kroužkem a počáteční stav malou šipkou bez výstupního vrcholu. M = (Q, Σ, δ, q0, F) kde Q = {X, Y, Z, U, V, W} Σ = {a, b, c} δ : viz obr. 3.1 q0 = X F = {X, W} Věta 3.7 Nechť L = L(M) pro nějaký konečný automat M. Pak existuje gramatika G typu 3 taková, že L = L(G), tj. LM ⊆ L3. KAPITOLA 3. REGULÁRNÍ JAZYKY 30 Obrázek 3.1: Diagram přechodů automatu M Důkaz: Nechť M = (Q, Σ, δ, q0, F). Protože každý nedeterministický automat může být převeden na deterministický automat přijímající stejný jazyk, předpokládejme, že M je deterministický automat. Nechť G je gramatika typu 3, G = (Q, Σ, P, q0), jejíž množina P přepisovacích pravidel je definována takto: (1) je-li δ(q, a) = r, pak P obsahuje pravidlo q → ar (2) je-li p ∈ F, pak P obsahuje pravidlo p → V další části probíhá důkaz zcela analogicky důkazu věty 3.6. 2 Příklad 3.10 Na základě příkladu 3.1 sestrojíme gramatiku typu 3, která generuje jazyk zápisů čísel. Přechodová funkce deterministického konečného automatu, který přijímá tento jazyk, je v tabulce 3.1. Výsledná gramatika bude tvaru: G = ({q0, q1, q2, q3, q4, q5, q6, q7, q8}, {c, z, e, ., }, P, q0) P obsahuje pravidla q0 → zq8 | cq7 | ·q6 | eq4 q1 → q2 → cq2 | q1 q3 → cq2 q4 → zq3 | cq2 q5 → cq5 | eq4 | q1 q6 → cq5 q7 → cq7 | ·q6 | eq4 | q1 q8 → cq7 | ·q6 | eq4 Poznamenejme, že převod této gramatiky na gramatiku regulární je velice snadný, stačí dosadit za q1 prázdný řetězec a odstranit pravidlo q1 → . Věta 3.8 Třída jazyků, jež jsou přijímány konečnými automaty, je totožná s třídou jazyků typu 3 Chomského hierarchie. Důkaz: Tvrzení bezprostředně plyne z vět 3.6 a 3.7. 2 KAPITOLA 3. REGULÁRNÍ JAZYKY 31 Algoritmus konstrukce nedeterministického konečného automatu z důkazu věty 3.6 může být snadno modifikován pro převod pravé regulární gramatiky na ekvivalentní nedeterministický konečný automat. Algoritmus 3.2 Konstrukce nedeterministického konečného automatu k pravé regulární gramatice. Vstup: Pravá regulární gramatika G = (N, Σ, P, S), jejíž pravidla mají tvar A → aB a A → a, kde A, B ∈ N a a ∈ Σ, případně S → za předpokladu, že S se nevyskytuje na pravé straně žádného pravidla. Výstup: Nedeterministický konečný automat M = (Q, Σ, δ, q0, F), pro který je L(M) = L(G). Metoda: (1) Položíme Q = N ∪ {qF }, kde qF reprezentuje koncový stav. (2) Množina vstupních symbolů automatu M je identická s množinou terminálů gramatiky G. (3) Funkci přechodů δ definujeme takto: (a) Je-li A → aB pravidlo z P, pak δ(A, a) obsahuje stav B. (b) Je-li A → a pravidlo z P, pak δ(A, a) obsahuje qF . (4) q0 = S (5) Je-li S → pravidlo z P, pak F = {S, qF }, v opačném případě F = {qF }. Věta 3.9 Nechť G je pravá regulární gramatika a M konečný automat z algoritmu 3.2. Pak L(M) = L(G). Důkaz: Důkaz této věty je modifikací důkazu věty 3.6; přenecháme ho jako cvičení. 2 Příklad 3.11 Uvažujeme gramatiku G = ({S, B}, {0, 1}, P, S) s pravidly S → 0B | B → 0B | 1B | 0 Diagram přechodů automatu přijímajícího jazyk L(G) má, na základě konstrukce podle algoritmu 3.2, tvar: S B qF 0 0,1 0 Obrázek 3.2: Diagram přechodů KAPITOLA 3. REGULÁRNÍ JAZYKY 32 Algoritmus 3.3 Konstrukce nedeterministického konečného automatu k levé regulární gramatice. Vstup: Levá regulární gramatika G = (N, Σ, P, S) jejíž pravidla mají tvar A → Ba a A → a kde A, B ∈ N a a ∈ Σ, případně S → , je-li ∈ L(G). Výstup: Nedeterministický konečný automat M = (Q, Σ, δ, q0, F), pro který je L(M) = L(G). Metoda: (1) Položíme Q = N ∪ {q0} (2) Množina vstupních symbolů automatu M je identická s terminální abecedou gramatiky G. (3) Funkci přechodu δ definujeme takto: (a) Je-li A → Ba pravidlo z P, pak δ(B, a) obsahuje stav A. (b) Je-li A → a, pak δ(q0, a) obsahuje stav A. (4) q0 je počáteční stav automatu M (5) Je-li S → pravidlo z P pak F = {S, q0}, v opačném případě F = {S} Věta 3.10 Nechť G je levá lineární gramatika a M konečný automat z algoritmu 3.3. Pak L(M) = L(G). Důkaz: Nejprve dokážeme, že ∈ L(G), právě když ∈ L(M). Podle konstrukce automatu M, q0 ∈ F právě když v P je pravidlo S → a tedy S ⇒ , právě když (q0, ) 0 (q0, ), q0 ∈ F Nyní dokážeme, že pro libovolné w ∈ Σ+ platí S ⇒+ w, právě když (q0, w) + (S, ), S ∈ F Položme w = ax, a ∈ Σ, x ∈ Σ∗ . Induktivní hypotéza nechť má tvar: S ⇒i Ax ⇒ ax, právě když (q0, ax) (A, x) i (S, ), A ∈ N, S ∈ F, |x| = i Pro i = 0 dostaneme: S ⇒ a, právě když (q0, a) (S, ), což plyne přímo z definice funkce přechodů automatu M (δ(q0, a) obsahuje S, právě když S → a je v P). Pro i ≥ 1 je třeba dokázat: (a) Ax ⇒ ax, právě když (q0, ax) (A, x) (b) S ⇒i Ax právě když (A, x) i (S, ) Důkaz tvrzení (a) a (b) ponecháme jako cvičení. 2 KAPITOLA 3. REGULÁRNÍ JAZYKY 33 Příklad 3.12 Uvažujme gramatiku G = ({S, I, N}, {c, p, }, P, S) s pravidly: S → I | N I → p | Ip | Ic N → c | Nc Značí-li c arabskou číslici a p písmeno, pak L(G) je jazyk identifikátorů (nonterminál I) a celých čísel bez znaménka (nonterminál N). Každá věta jazyka L(G) končí koncovým znakem . Diagram přechodů automatu, který přijímá jazyk L(G), má na základě algoritmu 3.3 tvar: Obrázek 3.3: Diagram přechodů 3.2 Minimalizace deterministického konečného au- tomatu Postup převodu deterministického konečného automatu na minimální deterministický konečný automat se skládá z několika kroků, ve kterých eliminujeme nedosažitelné stavy, automat převedeme na úplně definovaný DKA, následně na redukovaný DKA a pokud se v tomto redukovaném DKA vyskytuje tzv. ” sink“ stav, tj. nekoncový stav, z něhož lze poračovat jen do něj samého, pak ho odstra- níme. Definice 3.5 Deterministický konečný automat M = (Q, Σ, δ, q0, F) nazýváme úplný deterministický konečný automat, pokud pro všechna q ∈ Q a všechna a ∈ Σ platí, že δ(q, a) ∈ Q, tj. δ je totální funkcí na Q × Σ. Definice 3.6 Nechť M = (Q, Σ, δ, q0, F) je konečný automat. Stav q ∈ Q nazveme dosažitelný, pokud existuje w ∈ Σ∗ takové, že (q0, w) ∗ M (q, ε). Stav je nedosažitelný, pokud není dosažitelný. Algoritmus 3.4 Eliminace nedosažitelných stavů Vstup: Deterministický konečný automat M = (Q, Σ, δ, q0, F). Výstup: Deterministický konečný automat M bez nedosažitelných stavů, L(M) = L(M ). KAPITOLA 3. REGULÁRNÍ JAZYKY 34 Metoda: 1. i := 0 2. Si := {q0} 3. repeat 4. Si+1 := Si ∪ {q | ∃p ∈ Si ∃a ∈ Σ : δ(p, a) = q} 5. i := i + 1 6. until Si = Si−1 7. M := (Si, Σ, δ|Si , q0, F ∩ Si) Základem algoritmu minimalizace deterministického konečného automatu je koncept nerozlišitelných stavů. Definice 3.7 Nechť M = (Q, Σ, δ, q0, F) je úplný DKA. Říkáme, že řetězec w ∈ Σ∗ rozlišuje stavy z Q, jestliže (q1, w) ∗ M (q3, ε) ∧ (q2, w) ∗ M (q4, ε) pro nějaké q3, q4 a právě jeden ze stavů q3, q4 je v F. Říkáme, že stavy q1, q2 ∈ Q jsou k-nerozlišitelné a píšeme q1 k ≡ q2, právě když neexistuje w ∈ Σ∗ , |w| ≤ k, který rozlišuje q1 a q2. Stavy q1, q2 jsou nerozlišitelné, značíme q1 ≡ q2, jsou-li pro každé k ≥ 0 k-nerozlišitelné. Dá se snadno dokázat, že ≡ je relací ekvivalence na Q, tj. relací, která je reflexivní, symetrická a tranzitivní. Definice 3.8 Úplně definovaný DKA M nazýváme redukovaný, jestliže žádný stav Q není nedostupný a žádné dva stavy nejsou nerozlišitelné. Věta 3.11 Nechť M = (Q, Σ, δ, q0, F) je úplný DKA a |Q| = n, n ≥ 2. Platí ∀q1, q2 ∈ Q : q1 ≡ q2 ⇔ q1 n−2 ≡ q2. Důkaz: Část ⇒ důkazu je triviální, plyne přímo z definice. Část ⇐: 1. Jestliže |F| = 0 nebo |F| = n, pak vzájemně platí q1 n−2 ≡ q2 ⇒ q1 ≡ q2 (všechny stavy jsou koncové, nebo všechny stavy jsou nekoncové). 2. Nechť |F| > 0 ∧ |F| < n. Ukážeme, že platí ≡ = n−2 ≡ ⊆ n−3 ≡ ⊆ ... ⊆ 1 ≡ ⊆ 0 ≡: • Zřejmě platí: (a) ∀q1, q2 ∈ Q : q1 0 ≡ q2 ⇔ (q1 ∈ F ∧ q2 ∈ F) ∨ (q1 ∈ F ∧ q2 ∈ F). (b) ∀q1, q2 ∈ Q ∀k ≥ 1 : q1 k ≡ q2 ⇔ (q1 k−1 ≡ q2 ∧ ∀a ∈ Σ : δ(q1, a) k−1 ≡ δ(q2, a)). • Relace 0 ≡ je ekvivalencí určující rozklad {F, Q \ F}. • Je-li k+1 ≡ = k ≡, pak k+1 ≡ je vlastním zjemněním k ≡, tj. obsahuje alespoň o jednu třídu více než rozklad k ≡. • Jestliže pro nějaké k platí k+1 ≡ = k ≡, pak také k+1 ≡ = k+2 ≡ = k+3 ≡ = ... podle (b) a tedy k ≡ je hledaná ekvivalence. KAPITOLA 3. REGULÁRNÍ JAZYKY 35 • Protože F nebo Q \ F obsahuje nejvýše n − 1 prvků, získáme relaci ≡ po nejvýše n − 2 zjemněních 0 ≡. 2 Algoritmus 3.5 Převod na redukovaný deterministický konečný automat. Vstup: Úplně definovaný DKA M = (Q, Σ, δ, q0, F). Výstup: Redukovaný DKA M = (Q , Σ, δ , q0, F ), L(M) = L(M ). Metoda: 1. Odstraň nedosažitelné stavy s využitím algoritmu 3.4. 2. i := 0 3. 0 ≡ := {(p, q) | p ∈ F ⇐⇒ q ∈ F} 4. repeat 5. i+1 ≡ := {(p, q) | p i ≡ q ∧ ∀a ∈ Σ : δ(p, a) i ≡ δ(q, a)} 6. i := i + 1 7. until i ≡ = i−1 ≡ 8. Q := Q/ i ≡ 9. ∀p, q ∈ Q ∀a ∈ Σ : δ ([p], a) = [q] ⇔ δ(p, a) = q 10. q0 = [q0] 11. F = {[q] | q ∈ F} Poznámka 3.2 Výraz [x] značí ekvivalenční třídu určenou prvkem x. Příklad 3.13 Převeďte níže uvedený deterministický konečný automat (zadaný diagram přechodů) na odpovídající redukovaný deterministický konečný automat. a b b b a a a a b b b a A D B F E C Řešení: V řešení příkladu si ukážeme, jak vypadájí stavy na jednotlivých řádcích algoritmu 3.5. KAPITOLA 3. REGULÁRNÍ JAZYKY 36 1. Neobsahuje nedostupné stavy. 3. 0 ≡ = {{A, F}, {B, C, D, E}} 5.1. 1 ≡ = {{A, F}, {B, E}, {C, D}} 0 ≡ δ a b I: A FI BII F AI EII II: B EII DII C CII FI D DII AI E BII CII 5.2. 2 ≡ = {{A, F}, {B, E}, {C, D}} = 1 ≡ = ≡ 1 ≡ δ a b I: A FI BII F AI EII II: B EII DIII E BII CIII III: C CIII FI D DIII AI 8. Q = {[A], [B], [C]}, kde [A] = {A, F}, [B] = {B, E}, [C] = {C, D} 9–11. [A] [B] [C] a a a b b b 3.3 Regulární množiny a regulární výrazy 3.3.1 Regulární množiny Definice 3.9 Nechť Σ je konečná abeceda. Regulární množinu nad abecedou Σ definujeme rekurzívně takto: (1) ∅ (prázdná množina) je regulární množina nad Σ (2) { } (množina obsahující pouze prázdny řetězec) je regulární množina nad Σ (3) {a} pro všechna a ∈ Σ je regulární množina nad Σ (4) jsou-li P a Q regulární množiny nad Σ, pak také P ∪ Q, P · Q a P∗ jsou regulární množiny nad Σ (5) regulárními množinami jsou právě ty množiny, které lze získat aplikací 1–4. Třída regulárních množin je tedy nejmenší třída jazyků, která obsahuje ∅, { }, {a} pro všechny symboly a a je uzavřena vzhledem k operacím sjednocení, součinu a iterace. Příklad 3.14 L = ({a} ∪ {d}) · ({b}∗ ) · {c} je regulární množina nad Σ = {a, b, c, d}. Ukážeme, že třída regulárních množin tvoří právě třídu L3, tj. třídu jazyka typu 3 Chomského hierarchie. KAPITOLA 3. REGULÁRNÍ JAZYKY 37 Věta 3.12 Nechť Σ je konečná abeceda. Pak ∅ (1) { } (2) {a} pro všechna a ∈ Σ (3) jsou jazyky typu 3 nad abecedou Σ. Důkaz: (1) G = ({S}, Σ, ∅, S) je gramatika typu 3 pro kterou L(G) = ∅ (2) G = ({S}, Σ, {S → }, S) je gramatika typu 3 pro kterou L(G) = { } (3) Ga = ({S}, Σ, {S → a}, S) je gramatika typu 3, pro kterou L(Ga) = {a} 2 Věta 3.13 Nechť L1 a L2 jsou jazyky typu 3 nad abecedou Σ. Pak L1 ∪ L2 (1) L1 · L2 (2) L∗ 1 (3) jsou jazyky typu 3 nad abecedou Σ. Důkaz: Protože L1 a L2 jsou jazyky typu 3, můžeme předpokládat existenci gramatik G1 = (N1, Σ, P1, S1) a G2 = (N2, Σ, P2, S2) typu 3 takových, že L(G1) = L1 a L(G2) = L2. Bez újmy na obecnosti dále předpokládejme, že množiny N1 a N2 jsou disjunktní. (1) Nechť G3 = (N1∪N2∪{S3}, Σ, P1∪P2∪{S3 → S1, S3 → S2}, S3) je gramatika typu 3, kde S3 je nový nonterminál, S3 /∈ N1, S3 /∈ N2. Zřejmě L(G3) = L(G1)∪L(G2), poněvadž pro každou derivaci S3 ⇒ G3 + w existuje buď derivace S1 ⇒ G1 + w, nebo S2 ⇒ G2 + w a naopak. Protože G3 je gramatika typu 3, je L(G3) jazyk typu 3. (2) Nechť G4 = (N1 ∪ N2, Σ, P4, S1) je gramatika typu 3, jejíž množina přepisovacích pravidel P4 je definována takto: (a) je-li A → xB v P1, pak A → xB je v P4 (b) je-li A → x v P1, pak A → xS2 je v P4 (c) všechna pravidla z P2 jsou v P4. Nyní, jestliže S1 ⇒ G1 + w, pak S1 ⇒ G4 + wS2. Je-li dále S2 ⇒ G2 + x, pak S2 ⇒ G4 + x a tedy S1 ⇒ G4 + wx pro libovolné w a x. Z toho plyne L(G1) · L(G2) ⊆ L(G4). Předpokládejme, že platí S1 ⇒ G4 + w. Protože v P4 nejsou žádná pravidla tvaru A → x z množiny P1, můžeme tuto derivaci zapsat ve tvaru S1 ⇒ G4 + x S2 ⇒ G4 + xy, kde w = xy, přičemž všechna pravidla použitá v derivaci S1 ⇒ G4 + xS2 byla odvozena podle (a) a (b). Pak ale musí existovat derivace S1 ⇒ G1 + x a S2 ⇒ G2 + y a tudíž L(G4) ⊆ L(G1) · L(G2). Z toho však plyne L(G4) = L(G1) · L(G2). KAPITOLA 3. REGULÁRNÍ JAZYKY 38 (3) Nechť G5 = {N1 ∪ {S5}, Σ, P5, S5}, S5 /∈ N1 a množina P5 je konstruována takto: (a) je-li A → xB v P1, pak A → xB je v P5 (b) je-li A → x v P1, pak A → xS5 a A → x jsou v P5 (c) S5 → S1 a S5 → jsou v P5. Nyní je třeba dokázat tvrzení: Derivace S5 ⇒ G5 + x1S5 ⇒ G5 + x1x2S5 ⇒ G5 + . . . ⇒ G5 + x1x2 . . . xn−1S5 ⇒ G5 + x1x2 . . . xn−1xn existuje tehdy a jen tehdy, když existují derivace S1 ⇒ G1 + x1, S1 ⇒ G1 + x2, . . . , S1 ⇒ G1 + xn. Z tohoto tvrzení, jehož důkaz ponecháme jako cvičení, bezprostředně plyne L(G5) = (L(G1))∗ . Protože G5 je gramatika typu 3, je i jazyk L(G5) typu 3. 2 3.3.2 Regulární výrazy Obvyklou notací pro reprezentaci regulárních množin jsou regulární výrazy. Definice 3.10 Regulární výrazy nad Σ a regulární množiny, které označují, jsou rekurzívně definovány takto: (1) ∅ je regulární výraz označující regulární množinu ∅, (2) ε je regulární výraz označující regulární množinu {ε}, (3) a je regulární výraz označující regulární množinu {a} pro všechny a ∈ Σ, (4) jsou-li p, q regulární výrazy označující regulární množiny P a Q, pak (a) (p + q) je regulární výraz označující regulární množinu P ∪ Q, (b) (pq) je regulární výraz označující regulární množinu P · Q, (c) (p∗ ) je regulární výraz označující regulární množinu P∗ . (5) Žádné jiné regulární výrazy nad Σ neexistují. Konvence 3.1 Při používání regulárních výrazů stanovujeme následující kon- vence. 1. Regulární výraz p+ značí regulární výraz pp∗ . 2. Abychom minimalizovali počet používaných závorek, stanovujeme priority operátorů: ∗ a + (iterace – nejvyšší priorita), · (konkatenace), + (alterna- tiva). Příklad 3.15 1. 01 odpovídá {01}. 2. 0∗ odpovídá {0}∗ . 3. (0 + 1)∗ odpovídá {0, 1}∗ . KAPITOLA 3. REGULÁRNÍ JAZYKY 39 4. (0 + 1)∗ 011 značí množinu řetězců nad {0, 1} končících 011. 5. (a + b)(a + b + 0 + 1)∗ značí množinu řetězců nad {a, b, 0, 1} začínající symbolem a nebo b. Nyní jsme si definovali regulární výrazy. K tomu, abychom byli schopni odvodit všechny rovnice nad regulárními výrazy, potřebujeme sadu axiomů. Takovou sadou je Kleeneho algebra. Definice 3.11 Kleeneho algebra sestává z neprázdné množiny se dvěma význačnými konstantami 0 a 1, dvěma binárními operacemi + a · a unární operací ∗ , které splňují následující axiomy: a + (b + c) = (a + b) + c asociativita + [A.1] a + b = b + a komutativita + [A.2] a + a = a idempotence + [A.3] a + 0 = a 0 je identitou pro + [A.4] a(bc) = (ab)c asociativita · [A.5] a1 = 1a = a 1 je identitou pro · [A.6] a0 = 0a = 0 0 je anihilátorem pro · [A.7] a(b + c) = ab + ac distributivita zleva [A.8] (a + b)c = ac + bc distributivita zprava [A.9] 1 + aa∗ = a∗ [A.10] 1 + a∗ a = a∗ [A.11] b + ac ≤ c ⇒ a∗ b ≤ c [A.12] b + ca ≤ c ⇒ ba∗ ≤ c [A.13] V A.12 a A13 reprezentuje ≤ uspořádání definované takto: a ≤ b def ⇐⇒ a+b = b. Příklad 3.16 Příklady Kleeneho algeber (1) Třída 2Σ∗ všech podmnožin Σ∗ s konstantami ∅ a {ε} a operacemi ∪, . a ∗. (2) Třída všech regulárních podmnožin Σ∗ s konstantami ∅ a {ε} a operacemi ∪, . a ∗. (3) Třída všech binárních relací nad množinou X s konstantami v podobě prázdné relace a identity a ∪, kompozicí relací a reflexivním tranzitivním uzávěrem kompozice jako operacemi. (4) Kleeneho algebry matic. Poznámka 3.3 Axiomy A.12 a A.13 lze nahradit následujícími ekvivalentními vztahy (důkaz viz [3]): ac ≤ c ⇒ a∗ c ≤ c [A.14] ca ≤ c ⇒ ca∗ ≤ c [A.15] Některé užitečné teorémy Kleeneho algebry, které lze odvodit z jejich axiómů jsou následující: (1) 0∗ = 1 (2) 1 + a∗ = a∗ (3) a∗ = a + a∗ (4) a∗ a∗ = a∗ (5) a∗∗ = a∗ (6) (a∗ b)∗ a∗ = (a + b)∗ pravidlo ” vynořování“ [R.16] (7) a(ba)∗ = (ab)∗ a pravidlo posuvu [R.17] (8) a∗ = (aa)∗ + a(aa)∗ KAPITOLA 3. REGULÁRNÍ JAZYKY 40 Důkaz: Pro stručnost uvádíme pouze důkazy prvních dvou teorémů, ostatní viz [3]. (1) 0∗ = 1: 0∗ A.10 = 1 + 00∗ A.7 = 1 + 0 A.4 = 1. (2) 1 + a∗ = a∗ – pro stručnost neuvádíme použití A.1, A.2: (a) 1 + a∗ ≤ a∗ : i. A.10: a∗ = 1 + aa∗ ii. A.3: a∗ + a∗ = 1 + aa∗ iii. A.10: 1 + aa∗ + a∗ = 1 + aa∗ iv. A.3: 1+1+aa∗ +a∗ = 1+aa∗ , neboli 1+a∗ +1+aa∗ = 1+aa∗ v. def. ≤: 1 + a∗ ≤ 1 + aa∗ vi. A.10: 1 + a∗ ≤ a∗ (b) a∗ ≤ 1 + a∗ : i. 1 + a∗ = 1 + a∗ ii. A.3: 1 + a∗ + a∗ = 1 + a∗ iii. def. ≤: a∗ ≤ 1 + a∗ (c) antisymetrie ≤. 2 Příklad 3.17 Nechť p, resp. q, označují regulární množiny P, resp. Q. Pak p + q označuje P ∪Q a q+p označuje Q∪P. P ∪Q = Q∪P (komutativita množinového sjednocení) ⇒ p + q = q + p. Různé vlastnosti Kleeneho algeber se někdy snáze dokazují pro jednotlivé konkrétní příklady těchto algeber, např. pro Kleeneho algebru regulárních výrazů, kde lze např. využít vazby na teorii množin. 3.3.3 Rovnice nad regulárními výrazy Definice 3.12 Rovnice, jejímiž složkami jsou koeficienty a neznámé, které reprezentují (dané a hledané) regulární výrazy, nazýváme rovnicemi nad regulárními výrazy. Příklad 3.18 Uvažujme rovnici nad regulárními výrazy nad abecedou {a, b} X = aX + b Jejím řešením je regulární výraz X = a∗ b. Důkaz: LS = a∗ b, PS = a(a∗ b) + b = a+ b + b = (a+ + )b = a∗ b. Ne vždy však existuje jediné řešení rovnice nad regulárními výrazy. 2 Příklad 3.19 Nechť X = pX +q je rovnice nad regulárními výrazy, kde p, q jsou regulární výrazy a p označuje regulární množinu P takovou, že ∈ P. Pak X = p∗ (q + r) je řešením této rovnice pro libovolné r (kterému nemusí ani odpovídat regulární množina, ale případně i obecnější jazyk). KAPITOLA 3. REGULÁRNÍ JAZYKY 41 Důkaz: LS = p∗ (q + r), PS = p(p∗ (q + r)) + q = pp∗ (q + r) + q = p∗ (q + r) + q = p∗ (q + r). Je třeba si uvědomit, že ∈ P. 2 Obvykle ale hledáme ” nejmenší řešení“, tzv. nejmenší pevný bod, dané rovnice. Věta 3.14 Nejmenším pevným bodem rovnice X = pX + q je: X = p∗ q Důkaz: LS = p∗ q, PS = pp∗ q + q = (pp∗ + )q = p∗ q 2 3.3.4 Soustavy rovnic nad regulárními výrazy Příklad 3.20 Budiž dána soustava rovnic X = a1X + a2Y + a3 Y = b1X + b2Y + b3 Její řešení je: X = (a1 + a2b∗ 2b1)∗ (a3 + a2b∗ 2b3) Y = (b2 + b1a∗ 1a2)∗ (b3 + b1a∗ 1a3) Důkaz: Cvičení. 2 Definice 3.13 Soustava rovnic nad regulárními výrazy je ve standardním tvaru vzhledem k neznámým ∆ = {X1, X2, ..., Xn}, má-li soustava tvar i∈{1,...,n} Xi = αi0 + αi1X1 + αi2X2 + ... + αinXn kde αij jsou regulární výrazy nad nějakou abecedou Σ, Σ ∩ ∆ = ∅. Věta 3.15 Je-li soustava rovnic nad regulárními výrazy ve standardním tvaru, pak existuje její minimální pevný bod a algoritmus jeho nalezení. Důkaz: Vyjadřujeme hodnotu jednotlivých proměnných pomocí řešení rovnice X = pX +q jako regulární výraz s proměnnými, jejichž počet se postupně snižuje: Z rovnice pro Xn vyjádříme např. Xn jako regulární výraz nad Σ a X1, ..., Xn−1. Dosadíme za Xn do rovnice pro Xn−1 a postup opakujeme. Jsou přitom možné (ale ne nutné) různé optimalizace tohoto pořadí. 2 Příklad 3.21 Vyřešte soustavu rovnic nad regulárními výrazy: (1) X1 = (01∗ + 1)X1 + X2 (2) X2 = 11 + 1X1 + 00X3 (3) X3 = ε + X1 + X2 Řešení: KAPITOLA 3. REGULÁRNÍ JAZYKY 42 1. Výraz pro X3 dosadíme z (3) do (2). Dostaneme soustavu: (4) X1 = (01∗ + 1)X1 + X2 (5) X2 = 11 + 1X1 + 00(ε + X1 + X2) = 00 + 11 + (1 + 00)X1 + 00X2 2. Ze (4) vyjádříme X1 s využitím řešení rovnice X = pX + q (věta 3.14): (6) X1 = (01∗ + 1)∗ X2 = (0 + 1)∗ X2 3. Dosazením do (5): (7) X2 = 00 + 11 + (1 + 00)(0 + 1)∗ X2 + 00X2 = = 00 + 11 + (1 + 00)(0 + 1)∗ X2 4. Vypočtením X2 jako řešení rovnice X = pX + q dostaneme: (8) X2 = ((1 + 00)(0 + 1)∗ )∗ (00 + 11) 5. Dosazením do (6) dostaneme: (9) X1 = (0 + 1)∗ ((1 + 00)(0 + 1)∗ )∗ (00 + 11) = (0 + 1)∗ (00 + 11) 6. Dosazením do (3) dostaneme: (10) X3 = ε + (0 + 1)∗ (00 + 11) + ((1 + 00)(0 + 1)∗ )∗ (00 + 11) = = ε + ((0 + 1)∗ + ((1 + 00)(0 + 1)∗ )∗ )(00 + 11) = = ε + (0 + 1)∗ (00 + 11) Věta 3.16 Každý jazyk generovaný gramatikou typu 3 je regulární množinou: L3 ⊆ LR Důkaz: 1. Nechť L ∈ L3 je libovolný jazyk typu 3. Již víme, že ho můžeme popsat konečným automatem M = (Q, Σ, δ, q0, F). Nechť Q = {q0, q1, ..., qn}. 2. Vytvoříme soustavu rovnic na regulární výrazy s proměnnými X0, X1, ..., Xn ve standardním tvaru. Rovnice pro Xi popisuje množinu řetězců přijímaných ze stavu Qi. 3. Řešením této soustavy získáme regulární výraz pro proměnnou X0, který reprezentuje jazyk L. 2 Příklad 3.22 Jazyk L popisuje regulární výraz, který je řešením této soustavy pro proměnnou X1. a 1 a 3 2 a b a a b X1 = ε + aX1 + aX2 + bX3 X2 = bX1 + aX3 X3 = ε + aX2 + aX3 KAPITOLA 3. REGULÁRNÍ JAZYKY 43 Poznámka 3.4 Jiný převod KA na RV Regulární přechodový graf je zobecnění konečného automatu, které umožňuje množinu počátečních stavů a regulární výrazy na hranách. Každý regulární přechodový graf je možné převést na regulární přechodový graf s jediným přechodem, ze kterého odečteme hledaný regulární výraz. Zavedeme nový počáteční a koncový stav, které propojíme s původními počátečními a koncovými stavy přechody. Pak postupně odstraňujeme všechny původní stavy následujícím způsobem: R1 R2 S1 S2 T1 T2 R1(S1+S2+ε)*T1 R2(S1+S2+ε)*T2 R2(S1+S2+ε)*T1 R1(S1+S2+ε)*T2 3.4 Převod regulárních výrazů na konečné auto- maty Nyní si ukážeme přímý převod regulárního výrazu na deterministický konečný automat. Regulární výrazy budeme převádět nejprve na tzv. rozšířené konečné automaty a ty pak na deterministické konečné automaty. Definice 3.14 Rozšířený konečný automat (RKA) je pětice M = (Q, Σ, δ, q0, F), kde (a) Q je konečná množina stavů, (b) Σ je konečná vstupní abeceda, (c) δ je zobrazení Q × (Σ ∪ {ε}) → 2Q , (d) q0 ∈ Q je počáteční stav, (e) F ⊆ Q je množina koncových stavů. Příklad 3.23 M = ({0, 1, 2, 3, 4}, {a, b}, δ, 0, {2, 4}) 0 1 2 3 4 a b a b ε ε L(M) = aa∗ + bb∗ = a+ + b+ Definice 3.15 Klíčovou funkci v algoritmu převodu RKA na DKA má výpočet funkce, která k danému stavu určí množinu všech stavů, jež jsou dostupné po ε hranách diagramu přechodů funkce δ. Označme tuto funkci jako ε-uzávěr: ε-uzávěr(q) = {p | ∃w ∈ Σ∗ : (q, w) ∗ (p, w)} KAPITOLA 3. REGULÁRNÍ JAZYKY 44 Funkci ε-uzávěr zobecníme tak, aby argumentem mohla být množina T ⊆ Q: ε-uzávěr(T) = s∈T ε-uzávěr(s) Příklad 3.24 q r a ε ε ε p s t ε-uzávěr({q, r, s}) = {p, q, r, s, t} Pro popis výpočtu ε-uzávěru si zavedeme relaci ε −→ v množině Q takto: ∀q1, q2 ∈ Q : q1 ε −→ q2 def ⇐⇒ q2 ∈ δ(q1, ε) Pak ε-uzávěr(p) = {q ∈ Q | p ε −→ ∗ q}. K výpočtu ε-uzávěru pak použijeme Warshallův algoritmus, doplníme diagonálu jedničkami a z příslušného řádku matice výsledné relace vyčteme ε-uzávěr. Příklad 3.25 ε ε ε ε ε ε ε a b ε 0 1 2 3 4 5 6 7 a b b 8 9 10 ε-uzávěr(3) = {3, 6, 7, 1, 2, 4} ε-uzávěr({1, 0}) = {0, 1, 2, 4, 7} Algoritmus 3.6 Převod rozšířeného konečného automatu na deterministický konečný automat. Vstup: Rozšířený konečný automat M = (Q, Σ, δ, q0, F). Výstup: Deterministický konečný automat M = (Q , Σ, δ , q0, F ), L(M) = L(M ). Metoda: 1. Q := 2Q \ {∅}. 2. q0 := ε-uzávěr(q0). 3. δ : Q × Σ → Q ∪ {nedef} je vypočtena takto: • Nechť ∀T ∈ Q , a ∈ Σ : δ(T, a) = q∈T δ(q, a). • Pak pro každé T ∈ Q , a ∈ Σ: (a) pokud δ(T, a) = ∅, pak δ (T, a) = ε-uzávěr(δ(T, a)), (b) jinak δ (T, a) = nedef. KAPITOLA 3. REGULÁRNÍ JAZYKY 45 4. F := {S | S ∈ Q ∧ S ∩ F = ∅}. Příklad 3.26 Aplikujte algoritmus 3.6 na automat z příkladu 3.25 1. Počáteční stav, označíme ho A, je A = ε-uzávěr(0) = {0, 1, 2, 4, 7}. 2. δ (A, a) = ε-uzávěr({3, 8}) = {1, 2, 3, 4, 6, 7, 8} = B. 3. δ (A, b) = ε-uzávěr({5}) = {1, 2, 4, 5, 6, 7} = C. 4. δ (B, a) = ε-uzávěr({3, 8}) = B. 5. δ (B, b) = ε-uzávěr({5, 9} = {1, 2, 4, 5, 6, 7, 9} = D. 6. δ (C, a) = ε-uzávěr({3, 8}) = B. 7. δ (C, b) = ε-uzávěr({5}) = C. 8. δ (D, a) = ε-uzávěr({3, 8}) = B. 9. δ (D, b) = ε-uzávěr({5, 10} = {1, 2, 4, 5, 6, 7, 10} = E. 10. δ (E, a) = ε-uzávěr({3, 8}) = B. 11. δ (E, b) = ε-uzávěr({5}) = C. 12. Množina koncových stavů F = {E}. Algoritmus 3.7 Převod regulárního výrazu na rozšířený konečný automat. Vstup: Regulární výraz r popisující regulární množinu R nad Σ. Výstup: Rozšířený konečný automat M takový, že L(M) = R. Metoda: 1. Rozložíme r na jeho primitivní složky podle rekurzivní definice regulární množiny/výrazu. 2. (a) Pro výraz ε zkonstruujeme automat: εs f (b) Pro výraz a, a ∈ Σ zkonstruujeme automat: a s f (c) Pro výraz ∅ zkonstruujeme automat: s f (d) Nechť N1 je automat přijímající jazyk specifikovaný výrazem r1 a nechť N2 je automat přijímající jazyk specifikovaný výrazem r2. i. Pro výraz r1 + r2 zkonstruujeme automat: s f N1 N2 ε ε ε ε ii. Pro výraz r1r2 zkonstruujeme automat: N1 N2 KAPITOLA 3. REGULÁRNÍ JAZYKY 46 iii. Pro výraz r∗ 1 zkonstruujeme automat: N1s ε f ε ε ε Příklad 3.27 Vytvořme rozšířený konečný automat pro regulární výraz (a + b)∗ abb: 1. Rozklad regulárního výrazu vyjádříme stromem: r11 a r9 r8r7 r6r5 r4 r3 r1 r2 r10 a b b b ( ) + * . . . 2. (a) Regulárnímu výrazu r1 = a přísluší automat N1: a2 3 (b) Regulárnímu výrazu r2 = b přísluší automat N2: b4 5 (c) Regulárnímu výrazu r1 + r2 přísluší automat N3: ε ε ε ε a b 1 2 3 4 5 6 (d) Automat N4 pro r4 = (r3) je stejný jako N3, zkonstruujeme tedy rovnou N5 pro výraz r5 = r∗ 4 = (a + b)∗ : ε ε ε ε ε ε ε a b ε 0 1 2 3 4 5 6 7 (e) Regulárnímu výrazu r6 = a přísluší automat N6: a 7 8 (f) Regulárnímu výrazu r7 = r5r6 přísluší automat N7: ε ε ε ε ε ε ε a b ε 0 1 2 3 4 5 6 7 a 8 KAPITOLA 3. REGULÁRNÍ JAZYKY 47 (. . . ) Pokračujeme, až do získání automatu z příkladu 3.25. Převod RV na RKA zavádí mnoho vnitřních stavů a je proto obvykle následován použitím algoritmu minimalizace DKA (algoritmus 3.5). Příklad 3.28 Ověřte, zda deterministický konečný automat z příkladu 3.26 je či není minimální. Pro porovnávání regulárních gramatik, konečných automatů a regulárních výrazů můžeme shrnout, že 1. gramatiky typu 3 (pravé/levé regulární gramatiky, pravé/levé lineární gra- matiky), 2. (rozšířené/nedeterministické/deterministické) konečné automaty a 3. regulární výrazy mají ekvivalentní vyjadřovací sílu. regulární výrazy gramatiky typu 3 konečné automaty 3.5 Vlastnosti regulárních jazyků Podobně jako u dalších tříd jazyků budeme nyní zkoumat následující vlastnosti regulárních jazyků: (1) vlastnosti strukturální, (2) vlastnosti uzávěrové a (3) rozhodnutelné problémy pro regulární jazyky. 3.5.1 Strukturální vlastnosti regulárních jazyků Věta 3.17 Každý konečný jazyk je regulární. Důkaz: Nechť L = {w1, w2, . . . , wn}, wi ∈ Σ. Pak L = L(G), kde G = ({S}, Σ, {S → w1, S → w2, . . . , S → wn}, S). G je zřejmě gramatika typu 3. 2 Opak věty 3.17 zjevně neplatí: Příklad 3.29 Sestrojte gramatiku typu 3 generující jazyk {0, 1}∗ . Řešení: ⇒ G = ({S}, {0, 1}, {S → ε, S → 0S, S → 1S}, S) KAPITOLA 3. REGULÁRNÍ JAZYKY 48 Pumping lemma Pokud se zajímáme o vlastnost, zda jazyk spadá do dané třídy jazyků, je užitečné tzv. Pumping lemma. Neformálně řečeno Pumping lemma tvrdí, že v každé dostatečně dlouhé větě každého regulárního jazyka jsme schopni najít poměrně krátkou sekvenci, kterou je možné vypustit, resp. zopakovat libovolný počet krát, přičemž dostáváme stále věty daného jazyka. Věta 3.18 Nechť L je nekonečný regulární jazyk. Pak existuje celočíselná konstanta p > 0 taková, že platí: w ∈ L ∧ |w| ≥ p ⇒ w = x y z ∧ 0 < |y| ≤ p ∧ x yi z ∈ L pro i ≥ 0. Důkaz: Nechť L = L(M), M = (Q, Σ, δ, q0, F) je konečný automat, kde |Q| = n > 0. Položme p = n. Je-li w ∈ L a |w| ≥ n, pak M přijme větu w ” průchodem“ alespoň n + 1 konfiguracemi a tudíž alespoň dvě z nich obsahují stejný stav, tedy: (q0, w) = (q0, xyz) ∗ (r, yz) k (r, z) ∗ (qF , ε), qF ∈ F pro nějaký stav r ∈ Q a k takové, že 0 < k ≤ n. Pak ale existuje posloupnost konfigurací: (q0, xyi z) ∗ (r, yi z) + (r, yi−1 z) ... + (r, z) ∗ (qF , ε) 2 To ovšem znamená, že xyi z ∈ L(M), a to nejen pro i > 0, ale i pro případ i = 0: (q0, xz) ∗ (r, z) ∗ (qF , ), qF ∈ F. Věty 3.18 se často používá k důkazu, že daný jazyk není regulární. Příklad 3.30 Dokažte, že jazyk L = {0n 1n | n ≥ 1} není regulární. Důkaz: Předpokládejme, že L je regulární. Pak podle věty 3.18 může být věta 0k 1k pro dostatečně velké k zapsána ve tvaru xyz = 0k 1k , 0 < |y| ≤ k, a platí xyi z ∈ L pro i ≥ 0. Při hledání podřetězce y mohou nastat 3 možnosti: 0 0 0 . . y . 0 1 1 y 1 . . . y 1 y ∈ {0}+ pak ale xyi z /∈ L — nesouhlasí počet 0 a 1 y ∈ {1}+ pak ale xyi z /∈ L — nesouhlasí počet 0 a 1 y ∈ {0}+ · {1}+ pak ale xyi z /∈ L (všechny 0 nepředcházejí všechny 1) Řetězec tudíž nelze vybrat, a proto L /∈ L3. 2 KAPITOLA 3. REGULÁRNÍ JAZYKY 49 Příklad 3.31 Dokažte, že jazyk L = {aq | q je prvočíslo } není regulární. Důkaz: Předpokládejme, že L je regulární. Pak podle věty 3.18 existuje p > 0 takové, že každá věta aq ∈ L, kde q ≥ p, může být zapsána ve tvaru aq = xyz, 0 < |y| ≤ p, a platí xyi z ∈ L pro i ≥ 0. Zvolme r prvočíslo větší než p. ar ∈ L a |ar | = r ≥ p, což implikuje ar = xyz, 0 < |y| ≤ p, a platí xyi z ∈ L pro i ≥ 0. Nechť |y| = k a zvolme i = r + 1. Pak ale |xyr+1 z| = |xyz| + |yr | = r + r.k = r.(k + 1), což však není prvočíslo, a tedy xyi z ∈ L. Spor. 2 3.5.2 Myhill-Nerodova věta Myhill-Nerodova věta charakterizuje některé zásadní vztahy mezi konečnými automaty nad abecedou Σ a jistými ekvivalenčními relacemi nad řetězci ze Σ∗ . Dále slouží k popisu některých z nutných a postačujících podmínek pro to, aby daný jazyk byl jazykem regulárním (používá se často k důkazu neregularity jazyka). Poskytuje také formální bázi pro elegantní důkaz existence unikátního (až na isomorfismus) minimálního DKA k danému regulárnímu jazyku. Pravá kongruence a prefixová ekvivalence Pro zopakování: ekvivalence ∼ je binární relace, která je reflexivní, symetrická a tranzitivní. Index ekvivalence ∼ je počet tříd rozkladu Σ∗ / ∼. Je-li těchto tříd nekonečně mnoho, definujeme index jako ∞. Definice 3.16 Nechť Σ je abeceda a ∼ je ekvivalence na Σ∗ . Ekvivalence ∼ je pravou kongruencí (je zprava invariantní), pokud pro každé u, v, w ∈ Σ∗ platí u ∼ v =⇒ uw ∼ vw Věta 3.19 Ekvivalence ∼ na Σ∗ je pravá kongruence právě tehdy, když pro každé u, v ∈ Σ∗ , a ∈ Σ platí u ∼ v =⇒ ua ∼ va. Důkaz: ” ⇒“ je triviální, ” ⇐“ lze snadno ukázat indukcí nad délkou w. 2 Definice 3.17 Nechť 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 Věta 3.20 Nechť L je jazyk nad Σ. Pak následující tvrzení jsou ekvivalentní: Myhill- Nerodova věta 1. L je jazyk přijímaný deterministickým konečným automatem. 2. L je sjednocením některých tříd rozkladu určeného pravou kongruencí na Σ∗ s konečným indexem. 3. Relace ∼L má konečný index. Důkaz: Dokážeme následující implikace: (a) 1 ⇒ 2 KAPITOLA 3. REGULÁRNÍ JAZYKY 50 (b) 2 ⇒ 3 (c) 3 ⇒ 1 Z definice ekvivalence (a ⇔ b def ⇐⇒ a ⇒ b ∧ b ⇒ a) a ze základní tautologie výrokové logiky (a ⇒ b ∧ b ⇒ c) ⇒ (a ⇒ c) plyne tvrzení věty. (a) Důkaz implikace 1 ⇒ 2 Je-li L přijímán DKA, pak L je sjednocením některých tříd rozkladu určeného pravou kongruencí na Σ∗ s konečným indexem. Pro DKA M = (Q, Σ, δ, q0, F) zaveďme zobecněnou přechodovou funkci ˆδ : Q × Σ∗ → Q tak, že ∀q1, q2 ∈ Q, w ∈ Σ∗ : ˆδ(q1, w) = q2 ⇔ (q1, w) ∗ M (q2, ε). Pro daný L přijímaný konečným automatem M zkonstruujeme ∼ s potřebnými vlastnostmi: (1) Nechť M = (Q, Σ, δ, q0, F) a δ je totální. (2) Zvolíme ∼ jako binární relaci na Σ∗ takovou, že u ∼ v ⇐⇒ ˆδ(q0, u) = ˆδ(q0, v). (3) Ukážeme, že ∼ má potřebné vlastnosti: i. ∼ je ekvivalence: je reflexivní, symetrická a tranzitivní. ii. ∼ má konečný index: třídy rozkladu odpovídají stavům automatu. iii. ∼ je pravá kongruence: Nechť u ∼ v a a ∈ Σ. Pak ˆδ(q0, ua) = δ(ˆδ(q0, u), a) = δ(ˆδ(q0, v), a) = ˆδ(q0, va) a tedy ua ∼ va. iv. L je sjednocením některých tříd Σ∗ \ ∼: těch, které odpovídají F. (b) Důkaz implikace 2 ⇒ 3 Existuje-li relace ∼ splňující podmínku 2, pak ∼L má konečný index. Pro všechny u, v ∈ Σ∗ takové, že u ∼ v, platí u ∼L v: Nechť u ∼ v. Ukážeme, že také u ∼L v, tj. ∀w ∈ Σ∗ : uw ∈ L ⇔ vw ∈ L. Víme, že uw ∼ vw a protože L je sjednocením některých tříd rozkladu Σ∗ \∼, platí též uw ∈ L ⇔ vw ∈ L. Víme tedy, že ∼⊆∼L (tj. ∼L je největší pravá kongruence s danými vlastnostmi). Každá třída ∼ je obsažena v nějaké třídě ∼L. Index ∼L nemůže být větší než index ∼. ∼ má konečný index a tedy i ∼L má konečný index. (c) Důkaz implikace 3 ⇒ 1 Má-li ∼L konečný index, pak L je přijímán nějakým konečným automatem. Zkonstruujeme M = (Q, Σ, δ, q0, F) přijímající L: (1) Q = Σ∗ \∼ (stavy jsou třídy rozkladu Σ∗ relací ∼), (2) ∀u ∈ Σ∗ , u ∈ Σ : δ([u], a) = [ua], (3) q0 = [ε], (4) F = {[x] | x ∈ L}. KAPITOLA 3. REGULÁRNÍ JAZYKY 51 Uvedená konstrukce je korektní, tj. L = L(M): indukcí nad délkou slova v ukážeme, že ∀v ∈ Σ∗ : ˆδ([ε], v) = [v]. Navíc v ∈ L ⇐⇒ [v] ∈ F ⇐⇒ ˆδ([ε], v) ∈ F. 2 Jak bylo řečeno dříve, Myhill-Nerodova věta také slouží pro elegantní dokázání, zda je daný jazyk regulární (resp. není regulární). Následující příklad ukazuje toto využití. Příklad 3.32 Dokažte, že jazyk L = {an bn | n ≥ 0} není regulární. Důkaz: Žádné řetězce ε, a, a2 , a3 , ... nejsou ∼L-ekvivalentní, protože ai bi ∈ L, ale ai bj ∈ L pro i = j. Relace ∼L má tedy nekonečně mnoho tříd (neboli nekonečný index). Dle Myhill-Nerodovy věty tudíž nemůže být L přijímán žádným konečným automatem. 2 Další využití Myhill-Nerodovy věty je pro elegantní důkaz existence minimálního deterministického konečného automatu k danému regulárnímu výrazu. Věta 3.21 (2. varianta Myhill-Nerodovy věty) Počet stavů libovolného mi- nimálního DKA přijímajícího L je roven indexu ∼L. (Takový DKA existuje právě tehdy, když je index ∼L konečný.) Důkaz: Každý DKA (můžeme uvažovat DKA bez nedosažitelných stavů) určuje jistou pravou kongruenci s konečným indexem a naopak. Je-li L regulární, je ∼L největší pravou kongruencí s konečným indexem takovou, že L je sjednocením některých tříd příslušného rozkladu. Konečný automat, který odpovídá ∼L (viz důkaz 3 ⇒ 1 Myhill-Nerodovy věty), je tedy minimální konečný automat přijímající L. 2 3.5.3 Uzávěrové vlastnosti regulárních jazyků Věta 3.22 Třída regulárních jazyků je uzavřena (mimo jiné) vzhledem k operacím ∪ (sjednocení), · (konkatenace) a ∗ (iterace). Důkaz: Plyne z definice regulárních množin a ekvivalence regulárních množin a regulárních jazyků. 2 Věta 3.23 Třída regulárních jazyků tvoří množinovou Booleovu algebru. Důkaz: Označme L3 třídu všech regulárních jazyků abecedou Σ. Ukážeme, že algebraická struktura < L3, ∪, ∩, , Σ∗ , ∅ > je Booleova algebra. 1. Protože Σ∗ ∈ L3 i ∅ ∈ L3, jsou tyto jazyky zřejmě ” jedničkou“, resp. ” nulou“ uvažované algebry. Dále je zřejmá uzavřenost vůči ∪. 2. Dokážeme uzavřenost vzhledem ke komplementu nad abecedou ∆, ∆ ⊆ Σ. K jazyku L sestrojíme úplně definovaný KA M. M = (Q, ∆, δ, q0, F) takový, že L = L(M). Pak KA M KAPITOLA 3. REGULÁRNÍ JAZYKY 52 M = (Q, ∆, δ, q0, Q \ F) zřejmě přijímá jazyk ∆∗ \ L (komplement L v ∆∗ ). Komplement vzhledem k Σ∗ : L = L(M ) ∪ Σ∗ (Σ \ ∆)Σ∗ což je podle věty 3.19 regulární jazyk. 3. Uzavřenost vzhledem k průniku plyne z de Morganových zákonů: L1 ∩ L2 = L1 ∩ L2 = L1 ∪ L2 a tedy L1, L2 ∈ L3 ⇒ L1 ∩ L2 ∈ L3. 2 Věta 3.24 Nechť L ∈ L3 a nechť LR = {wR | w ∈ L}. Pak LR ∈ L3. Důkaz: Nechť M je konečný automat takový, že L = L(M). Lze sestrojit M takový, aby L(M ) = LR . Konstrukce automatu M se ponechává na čtenáři jako cvičení. 2 3.5.4 Rozhodnutelné problémy regulárních jazyků Tato podkapitola se zabývá těmito základními rozhodnutelnými problémy regulárních jazyků: problém neprázdnosti: L = ∅ ?, problém náležitosti: w ∈ L ? a problém ekvivalence: L(G1) = L(G2) ? Věta 3.25 Ve třídě L3 je rozhodnutelný problém neprázdnosti jazyka i problém náležitosti řetězce (do jazyka). Důkaz: K jazyku L ∈ L3 sestrojíme deterministický konečný automat M, L = L(M): M = (Q, Σ, δ, q0, F) neprázdnost: L(M) = ∅ ⇐⇒ ∃q ∈ Q : (q ∈ F ∧ q je dostupný z q0) náležitost: w ∈ L ⇔ (q0, w) ∗ (q, ε) ∧ q ∈ F 2 Věta 3.26 Nechť L1 = L(G1) a L2 = L(G2) jsou dva jazyky generované regulárními gramatikami G1 a G2. Pak je rozhodnutelný problém ekvivalence, tj. L(G1) = L(G2) nebo L(G1) = L(G2). Důkaz: Nechť M1 = (Q1, Σ1, δ1, q1 0, F1), resp. M2 = (Q2, Σ2, δ2, q2 0, F2) jsou KA přijímající jazyky L1, resp. L2 takové, že Q1 ∩ Q2 = ∅. Vytvoříme konečný automat M takto: M = (Q1 ∪ Q2, Σ1 ∪ Σ2, δ1 ∪ δ2, q1 0, F1 ∪ F2) a vypočítáme relaci ≡ nerozlišitelnosti stavů z Q1 ∪ Q2 pro automat M. Pak L(G1) = L(G2) ⇐⇒ q1 0 ≡ q2 0 KAPITOLA 3. REGULÁRNÍ JAZYKY 53 2 Regulární jazyky, zahrnující všechny konečné jazyky, představují třídu formálních jazyků s velmi výrazným počtem aplikací zvláště pak pro jejich mimořádnou rozhodovací sílu. K nejrozšířenějším prostředkům jejich specifikace patří, vedle gramatik typu 3 a nedeterministických a deterministických konečných jazyků také regulární výrazy. Regulární jazyky tvoří jednu z instancí Kleenovy algebry, která umožňuje řešit standartizované soustavy rovnic nad regulárními výrazy. Algoritmy převodů mezi ekvivalentními specifikačními prostředky jsou základem speciálních jazykových procesorů, např konstruktorů lexikálních analyzátorů překladačů. 3.6 Cvičení Cvičení 3.6.1 Ke konečnému nedeterministickému automatu M = ({q0, q1, q2, q3, qF }, {1, 2, 3}, δ, q0, {qF }), kde zobrazení δ je definováno touto tabulkou . Σ Q 1 2 3 q0 {q0, q1} {q0, q2} {q0, q3} q1 {q1, qF } {q1} {q1} q2 {q2} {q2, qF } {q1} q3 {q3} {q3} {q3, qF } qF ∅ ∅ ∅ sestrojte deterministický automat M , pro který platí L(M ) = L(M). Cvičení 3.6.2 Nechť L1 = L(M1) a L2 = L(M2) jsou jazyky přijímané konečnými automaty M1 = (Q1, Σ1, δ1, q1 0, F1) a M2 = (Q2, Σ2, δ2, q2 0, F2). Analogicky větě 3.13 ukažte konstrukci automatů M3, M4 a M5, pro které platí: L(M3) = L1 ∪ L2, L(M4) = L1 · L2 a L(M5) = L∗ 1. Cvičení 3.6.3 K pravé lineární gramatice, která osahuje pravidla A → B | C B → 0B | 1B | 011 C → 0D | 1C | D → 0C | 1D vytvořte pravou lineární gramatiku, jež generuje stejný jazyk. Nonterminál A je výchozím symbolem gramatiky. Cvičení 3.6.4 Vytvořte pravou regulární gramatiku, která generuje jazyk přijímaný automatem M ze cvičení 3.6.1. Cvičení 3.6.5 Vytvořte konečný automat, který přijímá jazyk generovaný gramatikou ze cvičení 3.6.3. Cvičení 3.6.6 Na základě algoritmu, jenž je ” inverzní“ k algoritmu 3.3, sestrojte levou regulární gramatiku pro jazyk reálných čísel pro programovací jazyky. Automat přijímající tento jazyk je uveden v příkladě 3.1. KAPITOLA 3. REGULÁRNÍ JAZYKY 54 Cvičení 3.6.7 Na základě gramatiky ze cvičení 2.4.5 vytvořte konečný deterministický automat, který přijímá jazyk čísel programovacího jazyka Pascal. Cvičení 3.6.8 Gramatika G = ({S, An, An−1, . . . , A0}, {a, b}, P, S) s pravidly S → An An → An−1An−1 An−1 → An−2An−2 ... A2 → A1A1 A1 → A0A0 A0 → a | b popisuje pro n ≥ 0 regulární jazyk nad abecedou {a, b}. (a) Specifikujte jazyk L(G) gramatikou typu 3. (b) Převeďte tuto gramatiku na pravou regulární gramatiku. (c) Převeďte tuto gramatiku na ekevivalentní NKA a DKA. (d) Popište jazyk specifikovaný gramatikou G ve tvaru regulárního výrazu. (e) K získanému regulárnímu výrazu vytvořte ekvivalentní rozšířený konečný automat a deterministický konečný automat. (f) Srovnejte DKA, které jste získali v (c) a (e). Ukažte, že automat přijímající jazyk L(G) nepotřebuje více než 2n + 1 stavů. Kapitola 4 Bezkontextové jazyky a zásobníkové automaty 25:00 Prvním cílem této kapitoly je důkladné zvládnutí pojmů a poznatků teorie bezkontextových gramatik, jež jsou základem moderních aplikací v překladačích programovacích jazyků či při formální specifikaci a verifikaci (nejen) počítačových systémů. Kapitola vymezuje základní transformace bezkontextových gramatik zachovávající ekvivalenci bezkontextových jazyků a vede k algoritmizaci a důkazu těchto transformací. Druhým cílem této kapitoly je osvojení prostředků a metod alternativních popisů bezkontextových jazyků různými variantami zásobníkových automatů. Dokazuje se vztah mezi bezkontextovými gramatikami a nedeterministickými a deterministickými zásobníkovými automaty. Konečně třetím cílem je vést čtenáře k rigoroznímu pochopení základních vlastností bezkontextových jazyků a seznámit ho, méně formálně, i s některými pokročilejšími užitečnými poznatky teorie bezkontextových jazyků. Definice 4.1 Bezkontextová gramatika G je čtveřice G = (N, Σ, P, S) (1) N je konečná množina nonterminálních symbolů (2) Σ je konečná množina terminálních symbolů (3) P je konečná množina přepisovacích pravidel (pravidel) tvaru A → α, A ∈ N a α ∈ (N ∪ Σ)∗ (4) S ∈ N je výchozí symbol gramatiky. Dále budeme gramatikou bez další specifikace rozumět bezkontextovou grama- tiku. Příklad 4.1 Gramatika G = ({S, A, B}, {a, b, c, d}, P, S), kde P obsahuje pra- vidla S → AB A → aAb | ab B → cBd | cd generuje bezkontextový jazyk L(G) = {an bn cm dm | n ≥ 1, m ≥ 1} Jazyk L(G) je součinem dvou bezkontextových jazyků generovaných gramati- kami G1 = ({A}, {a, b}, {A → aAb, A → ab}, A) G2 = ({B}, {c, d}, {B → cBd, B → cd}, B) Poznamenejme, že jazyk L(G1) = {an bn | n ≥ 1} a tudíž ani jazyk L(G) není jazykem regulárním, protože konečný automat nemůže pro libovolné n ” počítat“ stejný počet výskytů symbolů a a b. Na druhé straně, jazyk {an bn cn dn | n ≥ 1}, dokonce ani jazyk {an bn cn | n ≥ 0} není jazykem bezkontextovým. 55 KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY56 4.1 Derivační strom Důležitým prostředkem pro grafické vyjádření struktury věty (její derivace) je kořenový, uzlově ohodnocený strom, který se nazývá derivačním nebo syntaktickým stromem. Připomeňme, že strom je orientovaný acyklický graf s těmito vlastnostmi: (1) Existuje jediný uzel, tzv. kořen stromu, do něhož nevstupuje žádná hrana. (2) Do všech ostatních uzlů grafu vstupuje právě jedna hrana. Uzly, z nichž žádná hrana nevystupuje, se nazývají koncové uzly stromu (listy). Při kreslení stromu je obyčejně dodržována tato konvence: kořen leží nejvýše, všechny hrany jsou orientovány směrem dolů. Budeme-li tuto konvenci dodržovat, pak můžeme vynechat šipky, které označují orientaci hran. Kořenem stromu na Obrázek 4.1: Příklad stromu 4.1 je uzel 1, uzly 2, 4, 5, 6 jsou koncovými uzly stromu. Definice 4.2 Nechť δ je věta nebo větná forma generovaná v gramatice G = (N, Σ, P, S) a nechť S = ν0 ⇒ ν1 ⇒ ν2 . . . ⇒ νk = δ její derivace v G. Derivační strom příslušející této derivaci je strom s těmito vlastnostmi: (1) Uzly derivačního stromu jsou (ohodnoceny) symboly z množiny N ∪ Σ; kořen stromu je označen výchozím symbolem S. (2) Přímé derivaci νi−1 ⇒ νi, i = 0, 1, . . . , k, kde νi−1 = µAλ, µ, λ ∈ (N ∪ Σ)∗ , A ∈ N νi = µαλ a A → α, α = X1 . . . Xn je pravidlo z P, odpovídá právě n hran (A, Xj), j = 1, . . . , n vycházejících z uzlu A jež jsou uspořádány zleva doprava v pořadí (A, X1), (A, X2), . . . (A, Xn). (3) Označení koncových uzlů derivačního stromu vytváří zleva doprava větnou formu nebo větu δ (plyne z (1) a (2)). Příklad 4.2 V Gramatice z příkladu 4.1 můžeme generovat řetězec aabbcd např. derivací: S ⇒ AB ⇒ aAbB ⇒ aabbB ⇒ aabbcd Derivační strom odpovídající této derivaci je na obrázku 4.2. Po stranách jsou uvedena použitá pravidla. Poznámka 4.1 Uzel derivačního stromu, který je označen terminálním symbolem, musí být zřejmě koncovým uzlem derivačního stromu. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY57 Obrázek 4.2: Derivační strom s s s s s s s                    d d d d d d d d dd         d d d d ¡ ¡ ¡ ¡ d d d d ™ ™ ™ ™™     l l l l l l l l l l l                                 µ A S S A λ λµ . . . X1 XnX2 µAλ µX1X2 . . . Xnλ=⇒ −→ Obrázek 4.3: Konstrukce derivačního stromu Při konstrukci derivačního stromu k dané derivaci opakovaně aplikujeme bod (2) z definice 4.2. Tuto aplikaci ilustruje obr. 4.3. Příklad 4.3 Uvažujme gramatiku G = ({ výraz , term , faktor }, {+, −, ∗, /, (, ), i}, P, výraz ), které se často používá pro popis aritmetického výrazu s binárními operacemi +, −, ∗, /. Terminální symbol i odpovídá identifikátoru. Množina P obsahuje tato přepisovací pravidla: výraz → term | výraz + term | výraz − term term → faktor | term ∗ faktor | term / faktor faktor → ( výraz ) | i Jak lze snadno ukázat, větami jazyka L(G) jsou například řetězce i, (i), i ∗ i, i ∗ i + i, i ∗ (i + i). Předpokládejme, že máme zkonstruovat derivační strom pro větnou formu výraz + term ∗ faktor . Nejprve ukažme, že tento řetězec je skutečně větnou formou: výraz ⇒ výraz + term ⇒ výraz + term ∗ faktor Derivační strom začínáme vytvářet od výchozího symbolu: výraz u První přímé derivaci odpovídá konstrukce: KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY58 výraz 222222–––––– u u u u výraz + term Po znázornění druhé přímé derivace obdržíme výsledný derivační strom. výraz 222222––––––  €€€€ u u u u výraz + term u u u faktor∗term Je-li tedy dána derivace větné formy, pak této derivaci přísluší právě jeden derivační strom. Důkaz vyplývá z konstrukce derivačního stromu. Podívejme se nyní, zda uvedené tvrzení platí také obráceně: K derivačnímu stromu větné formy přísluší pouze jedna derivace. Uvažujme gramatiku G z příkladu 4.1. S → A B A → aAb | ab B → cBd | cd Na obr. 4.2 jsme znázornili derivační strom k derivaci S ⇒ AB ⇒ aAbB ⇒ aabbB ⇒ aabbcd Ukážeme nyní, že existují i jiné derivace věty aabbcd. S ⇒ AB ⇒ Acd ⇒ aAbcd ⇒ aabbcd nebo S ⇒ AB ⇒ aAbB ⇒ aAbcd ⇒ aabbcd Uvedené derivace věty aabbcd se liší v pořadí, v němž byly vybírány nonterminály pro přímé derivace. Toto pořadí však ve výsledném derivačním stromě není postiženo, a proto budou derivační stromy příslušející k 2. a 3. z uvedených derivací věty aabbcd totožné s derivačním stromem na obr. 4.2. Neplatí tedy tvrzení, že k derivačnímu stromu přísluší pouze jedna derivace. Poznamenejme, že jiné derivace věty aabbcd v gramatice z příkladu 4.2 neexistují. V první a druhé z uvedených derivací byla přepisovací pravidla aplikována určitým kanonickým způsobem, který je charakteristický pro nejužívanější syntaktické analyzátory překladačů programovacích jazyků. Zavedeme si pro tyto speciální derivace vlastní označení. Definice 4.3 Nechť S = α1 ⇒ α2 ⇒ . . . ⇒ αn = α je derivace větné formy α. Jestliže byl v každém řetězci αi, i = 1, . . . , n − 1 přepsán nejlevější (nejpravější) nonterminál, pak tuto derivaci nazýváme levou (pravou) derivací větné formy α. První derivace věty aabbcd je tedy derivací levou, druhá je derivací pravou. Je-li S = α0 ⇒ α1 ⇒ . . . ⇒ αn = w levá derivace věty w, pak je každé αi, i = 0, 1, . . . , n − 1 tvaru xiAiβi, kde xi ∈ Σ∗ , Ai ∈ N a βi ∈ (N ∪ Σ∗ ). K získání větné formy αi+1 bude přepsán nonterminál Ai. Obrácená situace platí pro pravou derivaci. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY59 4.2 Fráze větné formy Definice 4.4 Nechť G = (N, Σ, P, S) je gramatika a nechť řetězec λ = αβγ je větná forma. Podřetězec β se nazývá frází větné formy λ vzhledem k nonterminálu A z N, jestliže platí: S ⇒∗ αAγ A ⇒+ β Podřetězec β je jednoduchou frází větné formy λ, jestliže platí: S ⇒∗ αAγ A ⇒ β Příklad 4.4 Máme nalézt všechny fráze a všechny jednoduché větné formy výraz + term ∗ faktor v gramatice, která popisuje aritmetický výraz. Jak již bylo uvedeno, derivace této větné formy má tvar: výraz ⇒ výraz + term ⇒ výraz + term ∗ faktor Protože platí výraz ⇒∗ výraz + term a term ⇒ term ∗ faktor je řetězec term ∗ faktor jednoduchou frází větné formy výraz + term ∗ faktor vzhledem k nonterminálu term . Dále je: výraz ⇒∗ výraz výraz ⇒+ výraz + term ∗ faktor a z toho vyplývá, že větná forma výraz + term ∗ faktor je frází sama k sobě vzhledem k výchozímu symbolu. Tato skutečnost je důsledkem triviálního případu v definici fráze, kdy jsou řetězce α a γ prázdné. Jiné fráze větné formy výraz + term ∗ faktor neexistují. Pojem fráze je stěžejním pojmem pro syntaktickou analýzu. Celá třída syntaktických analyzátorů je postavena na metodách hledání nejlevější jednoduché fráze větné formy (věty). Protože dále budeme pojmu nejlevější jednoduchá fráze často používat, zavedeme pro něj speciální označení, l-fráze. Ve větné formě výraz + term ∗ faktor je jediná jednoduchá fráze: term ∗ faktor . Tato fráze je tedy zároveň l-frází. S pojmem fráze větné formy je velmi úzce svázán pojem podstrom příslušného derivačního stromu. Podstromem derivačního stromu budeme rozumět tu část tohoto stromu, která je vymezena jistým uzlem, tzv. kořenem podstromu, spolu se všemi uzly, které jsou z kořene podstromu dostupné prostřednictvím příslušných hran, včetně těchto hran. Příklad 4.5 Podstromy derivačního stromu věty aabbcd z obr. 4.2 jsou stromy z obr. 4.4. Předpokládejme nyní, že nonterminál A je kořenem podstromu derivačního stromu. Je-li β řetězec koncových uzlů tohoto podstromu, pak jistě platí A ⇒+ β. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY60 Obrázek 4.4: Podstromy derivačního stromu Nechť α je řetězec koncových uzlů vlevo, γ řetězec koncových uzlů derivačního stromu vpravo od β. Pak platí S ⇒∗ αβγ; S je kořenem derivačního stromu. To ovšem znamená, že β je frází větné formy αβγ vzhledem k nonterminálu A. Situaci ilustruje obr. 4.5. Obrázek 4.5: Fráze větné formy Podstrom derivačního stromu tedy odpovídá frázi příslušné větné formy. Fráze je tvořena koncovými uzly podstromu. Jednoduchá fráze odpovídá podstromu, jenž je výsledkem přímé derivace A ⇒ β. Příklad 4.6 V gramatice z příkladu 4.1 nalezněte fráze věty a2 b2 c2 d2 . Nejdříve sestavíme derivační strom. Pro jeho konstrukci vytvořme (např.) levou derivaci této věty: S ⇒ AB ⇒ aAbB ⇒ aabbB ⇒ aabbcBd ⇒ aabbccdd Vyznačené podstromy odpovídají dále uvedeným frázím definovaným k příslušným nonterminálům. Horní indexy slouží k rozlišení výskytu téhož nonterminálu (viz 4.6) Fráze Nonterminál aabbccdd S aabb A1 ab A2 ccdd B1 cd B2 Fráze ab a cd jsou jednoduché, ab je l-fráze. 4.3 Víceznačnost gramatik Definice 4.5 Nechť G je gramatika. Říkáme, že věta w generovaná gramatikou KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY61 Obrázek 4.6: Podstromy derivačního stromu G je víceznačná, existují-li alespoň dva různé derivační stromy s koncovými uzly tvořícími větu w. Gramatika G je víceznačná, jestliže generuje alespoň jednu víceznačnou větu. V opačném případě mluvíme o jednoznačné gramatice. Povšimněte si, že definujeme víceznačnou gramatiku, nikoli víceznačný jazyk. V mnoha případech lze vhodnými transformacemi víceznačné gramatiky odstranit víceznačnost vět, aniž se samozřejmě změní jazyk generovaný získanou jednoznačnou gramatikou. Existují však jazyky, které nelze generovat jednoznačnou gramatikou. Takové jazyky jsou pak nazývány jazyky s inherentní víceznačností. Příklad 4.7 Uvažujme gramatiku G = ({E}, {+, −, ∗, /, (, ), i}, P, E), kde P je množina pravidel E := E + E | E − E | E ∗ E | E / E | ( E ) | i Jazyk L(G) je totožný s jazykem generovaným gramatikou z příkladu 4.3 a je tvořen aritmetickými výrazy s binárními operacemi. Tato gramatika je na rozdíl od gramatiky z příkladu 4.3 víceznačná. Vezměme například větu i + i ∗ i a uvažujme všechny možné derivační stromy příslušející k této větě (viz obr. 4.7). Existence dvou různých derivačních stromů k větě i+i∗i dokazuje, že gramatika G je víceznačná. Označuje-li se + sečítání a ∗ násobení, pak není jasné, zda první operací bude násobení (první derivační strom), a nebo sečítání (druhý derivační strom). Jednoznačná gramatika z příkladu 4.3 na druhé straně respektuje obvyklou prioritou operací (násobení má přednost před sečítáním), jak je patrno z jediného derivačního stromu věty i + i ∗ i na obr. 4.8 Pro bezkontextové gramatiky bylo dokázáno, že problém, zda daná gramatika je a nebo není víceznačná, je nerozhodnutelný, tj. neexistuje algoritmus, který by v konečném čase odhalil víceznačnost každé bezkontextové gramatiky. Příklad 4.8 Gramatika obsahující pravidlo tvaru A → A je zřejmě víceznačná. Toto pravidlo můžeme vypustit, aniž změníme jazyk generovaný takto zredukovanou gramatikou. Poznámka 4.2 Víceznačnost gramatiky, pokud negeneruje jazyk s inherentní víceznačností, je obecně pokládána za negativní rys, poněvadž vede k větám, KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY62 Obrázek 4.7: Derivační stromy věty i + i ∗ i Obrázek 4.8: Derivační strom věty i + i ∗ i v G2 jež mají několik interpretací. Na druhé straně však víceznačná gramatika může být jednodušší, než odpovídající jednoznačná gramatika (viz příklad 4.7). Této skutečnosti se někdy využívá při konstrukci překladačů takovým způsobem, že se použije víceznačné gramatiky a nežádoucí interpretace víceznačné věty se vyloučí dodatečným sémantickým pravidlem. Příklad 4.9 Jedním z nejznámějších příkladů víceznačnosti v programovacích jazycích jsou konstrukce s then a else. Skutečně, přepisovací pravidla S → if b then S else S S → if b then S S → p kde b značí booleovský výraz a p jiný, než podmíněný příkaz, vedou k víceznačné interpretaci podmíněného příkazu. Např. k větě if b then if b then p else p KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY63 existují dva různé derivační stromy. Zatímco Algol 60 tuto konstrukci nedovoloval (za then musel být složený příkaz), jazyk Pascal uvedenou víceznačnost řeší sémantickým pravidlem: ” k danému else se vztahuje nejbližší předchozí then“. Poznamenejme, že i toto pravidlo lze postihnout také syntakticky: S1 → if b then S1 | if b then S2 else S1 | p S2 → if b then S2 else S2 | p S použitím těchto přepisovacích pravidel obdržíme pro větu if b then if b then p else p jediný derivační strom na obr. 4.9. Obrázek 4.9: Derivační strom podmíněného příkazu Příklad 4.10 Nalezněte bezkontextovou gramatiku, která generuje správně vytvořené regulární výrazy nad abecedou {a, b}. Řešení: Velmi jednoduché řešení tohoto příkladu nabízí rekurzivní definice regulární množiny 3.9 G0 RV = ({E}, {a, b, , +, ∗ , (, )}, P, E), kde E je jediný nonterminál popisující syntaktickou kategorii regulární výraz značí prázdný řetězec jako součást výrazu + odpovídá operaci sjednocení regulárních množin ∗ odpovídá operaci iterace regulární množiny Konkatenace se explicitně nevyznačuje. Pravidla tvořící množinu P pak vytváříme na základě definice regulární množiny: E → a | b | | E + E | EE | E∗ | (E) Sestrojená gramatika G0 RV je jednoduchá, má však vlastnost, která je obvykle nežádoucí – víceznačnost. Abychom vytvořili jednoznačnou gramatiku, budeme využívat analogií s gramatikou pro aritmetický výraz. Kromě nejvyšší syntaktické kategorie R popisující celý regulární výraz, zavedeme další nonterminály: K pro podvýrazy tvořené operací konkatenace KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY64 I pro podvýrazy tvořené operací iterace P pro primitivní regulární výrazy Výsledná gramatika pak může mít tvar GRV = ({R, K, I, P}, {a, b, , +, ∗ , (, )}, PP, R), kde množina PP přepisovacích pravidel obsahuje pravidla R → R + K | K K → KI | I I → I∗ | P P → a | b | | (R) 4.4 Rozklad věty Konstrukci derivace či derivačního stromu pro danou větu nebo větnou formu nazýváme rozkladem nebo syntaktickou analýzou této věty nebo větné formy. Program, který provádí rozklad vět určitého jazyka, se nazývá syntaktický analyzátor (anglicky také parser, to parse = rozložit). Algoritmy syntaktické analýzy lze rozdělit podle způsobu, kterým je konstruována derivace věty, tj. vytvářen derivační strom, do těchto dvou základních skupin: - syntaktická analýza shora dolů - syntaktická analýza zdola nahoru Při syntaktické analýze shora dolů začínáme derivační strom budovat od výchozího symbolu (kořene derivačního stromu) a postupnými přímými derivacemi dojdeme k terminálním symbolům, které tvoří analyzovanou větu (koncovým uzlům derivačního stromu). Problém spočívá ve správnosti volby přímých derivací, tj. pořadí používání přepisovacích pravidel. Při syntaktické analýze zdola nahoru začínáme derivační strom budovat od koncových uzlů a postupnými přímými redukcemi dojdeme ke kořenu (výchozímu symbolu gramatiky). Základním problémem této třídy syntaktických analyzátorů je hledání prvního podřetězce věty (v dalších krocích větných forem), který může být redukován k jistému nonterminálu – kořenu podstromu derivačního stromu. Tento podřetězec, jak již víme, se nazývá l-fráze. Příklad 4.11 Odlišnost obou typů syntaktické analýzy ilustrujeme na příkladě gramatiky, která generuje jazyk L = {an bm cm dn | n ≥ 1, m ≥ 1}. Tato gramatika má pravidla S → aSd | aAd A → bAc | bc kde S je výchozí symbol. Na obr. 4.10 je uvedena konstrukce derivačního stromu metodou shora dolů spolu s odpovídající levou derivací věty abbccd. Na obr. 4.11 je znázorněna konstrukce derivačního stromu metodou zdola nahoru. Odpovídající pravá derivace je zapsána zprava doleva. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY65 Obrázek 4.10: Syntaktická analýza shora dolů Vraťme se opět k základním problémům syntaktické analýzy. Při analýze shora dolů konstruujeme levou derivaci věty. Předpokládejme, že v jistém kroku analýzy je A nejlevějším nonterminálem, který má být přepsán. Dále předpokládejme, že gramatika obsahuje n pravidel s levou stranou A: A → α1 | α2 | . . . | αn Jak poznáme, kterým řetězcem αi je třeba nahradit nonterminál A? Podobně při Obrázek 4.11: Syntaktická analýza zdola nahoru analýze zdola nahoru, kdy je v každém kroku redukována l-fráze větné formy, spočívá hlavní problém v určení začátku a konce l-fráze. Jedním z řešení těchto problémů je náhodný výběr některé z možných alternativ. Ukáže-li se později, že zvolená alternativa nebyla správná, je třeba proces rozkladu ” vrátit“ a uvažovat jinou alternativu. (Při syntaktické analýze shora dolů se například pokoušíme přepisovat A řetězci α1, α2 . . . tak, aby se prefix získané levé derivace, který obsahuje pouze terminální symboly, shodoval s prefixem analyzované věty). Tento typ analýzy se nazývá syntaktická analýza s návratem (Syntax analysis with backup). I když počet návratů je omezený, je patrné, že analýza s návratem je časově náročná. Kromě toho jsou návraty zdrojem komplikací při sémantickém vyhodnocování překládaného programu. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY66 Praktickým řešením problémů syntaktické analýzy programovacích jazyků jsou tzv. deterministické gramatiky (kapitola 6.), které umožňují na základě kontextu zpracovávaného podřetězce větné formy, určit správnou alternativu v každém kroku analýzy. Tento typ syntaktické analýzy se nazývá deterministická syntaktická analýza (deterministický rozklad) nebo syntaktická analýza bez návratu. Pro ilustraci role kontextu uvažujme větu i + i ∗ i v gramatice z příkladu 4.3. Po zpracování podřetězce i + i nám kontext reprezentovaný terminálem ∗ pomůže určit frázi, kterou není i + i, ale podřetězec i ∗ i. 4.5 Transformace bezkontextových gramatik Obecně neexistuje algoritmická metoda, která by umožňovala sestrojit gramatiku generující jazyk s libovolnou strukturou. Teorie vyčíslitelnosti dokonce ukazuje, že nekonečně mnoho formálních jazyků nelze popsat žáným konečným formálním systémem, tudíž ani gramatikou. Existuje však celá řada užitečných transformací gramatik, které dovolují modifikovat gramatiku, aniž by byl porušen generovaný jazyk. V tomto odstavci popíšeme některé z těchto transformací formou matematických zápisů příslušných algoritmů. Definice 4.6 Říkáme, že gramatiky G1 a G2 jsou ekvivalentní, jestliže platí L(G1) = L(G2), tj. jestliže jimi generované jazyky jsou totožné. V některých případech se může stát, že sestrojená gramatika obsahuje zbytečné symboly a nadbytečná přepisovací pravidla. Nehledě k tomu, že tato skutečnost může být důsledkem chyby v konstrukci gramatiky, je velmi pravděpodobné, že syntaktická analýza bude probíhat méně efektivně. Je proto důležité odstranit z gramatiky zbytečné symboly a nadbytečná pravidla. Uvažujme například gramatiku G = ({S, A}, {a, b}, P, S), kde P = {S → a, A → b}. Je zřejmé, že nonterminál A a terminál b se nemohou objevit v žádné větné formě. Proto je můžeme z gramatiky G odstranit spolu s nadbytečným pravidlem A → b, aniž se změní jazyk L(G). Definice 4.7 Nechť G = (N, Σ, P, S) je gramatika. Říkáme, že symbol X ∈ (N ∪ Σ) je v gramatice G zbytečný, jestliže neexistuje derivace tvaru S ⇒∗ wXy ⇒∗ wxy. Řetězce w, x, y jsou v Σ∗ . Abychom zjistili, zda nonterminál A je zbytečný, popíšeme algoritmus určující, může-li se z nonterminálu A generovat řetězec terminálních symbolů, tj. zjišťujeme, zda {w | A ⇒∗ w, w ∈ Σ∗ } = ∅ Tento algoritmus lze rozšířit na algoritmus, který zjišťuje, je-li jazyk, generovaný bezkontextovou gramatikou, neprázdný. Algoritmus 4.1 Je L(G) neprázdný? Vstup: gramatika G = (N, Σ, P, S). Výstup: ANO je-li L(G) = ∅, NE v opačném případě. Metoda: Sestrojíme množiny N0, N1, . . . rekurzivně takto (1) N0 = ∅, i = 1 (2) Ni = {A | A → α je v P ∧ α ∈ (Ni−1 ∪ Σ)∗ } (3) Je-li Ni = Ni−1, polož i = i + 1 a vrať se ke kroku 2. Je-li Ni = Ni−1, polož Nt = Ni (4) Jestliže výchozí symbol S je v Nt, pak je výstup ANO, jinak NE. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY67 Poznámka 4.3 Jestliže množina nonterminálů N má n prvků, pak, protože Nt ⊆ N, musí algoritmus 4.1 skončit maximálně po n + 1 iteracích kroku 2. Věta 4.1 Algoritmus 4.1 má výstup ANO, právě když S ⇒∗ w pro nějaké w ∈ Σ∗ Důkaz: Nejprve dokážeme indukcí pro i implikaci: Jestliže platí A ∈ Ni, pak A ⇒∗ w pro nějaké w ∈ Σ∗ (1) Pro i = 0 implikace platí, protože N0 = ∅. Předpokládejme, že (1) platí pro i, a že A je prvkem množiny Ni+1. Je-li zároveň A ∈ Ni, pak je induktivní krok triviální. Jestliže A leží v Ni+1 − Ni, pak existuje pravidlo A → X1 . . . Xk, kde Xj je buď terminální symbol, nebo Xj ∈ Ni, j = 1, . . . , k. Pro každé j tedy existuje řetězec wj ∈ Σ∗ takový, že Xj ⇒∗ wj a platí tak A ⇒ X1 . . . Xk ⇒∗ w1X2 . . . Xk ⇒∗ . . . ⇒∗ w1 . . . wk = w Opačnou implikaci: Jestliže A ⇒n w, pak A ∈ Ni pro nějaké i (2) dokážeme opět indukcí. Je-li n = 1, pak zřejmě i = 1. Předpokládejme, že (2) platí pro n, a že A ⇒n+1 w . Pak můžeme psát A ⇒ X1 . . . Xk ⇒n w, kde w = w1 . . . wk a Xj ⇒nj wj pro j = 1, . . . , k, nj ≤ n. (Podřetězce wj jsou fráze řetězce w vzhledem k nonterminálům Xj v případě, že Xj ∈ N, pak Xj ∈ Nij pro nějaké ij. Položme ij = 0, jestliže Xj ∈ Σ. Nechť i = 1+max(i1, . . . , ik). Pak, podle definice, A ∈ Ni. Položíme-li nyní A = S v implikacích (1) a (2), dostáváme důkaz věty 4.1. 2 Definice 4.8 Říkáme, že symbol X ∈ (N ∪ Σ) je nedostupný v gramatice G = (N, Σ, P, S), jestliže X se nemůže objevit v žádné větné formě. Algoritmus 4.2 Odstranění nedostupných symbolů Vstup: Gramatika G = (N, Σ, P, S). Výstup: Gramatika G = (N , Σ , P , S), pro kterou platí (i) L(G ) = L(G) (ii) Pro všechna X z (N ∪ Σ ) existují řetězce α a β z (N ∪ Σ )∗ tak, že S ⇒∗ αXβ v gramatice G . Metoda: (1) Položíme V0 = {S} a i = 1 (2) Konstruujeme Vi = {X | A → αXβ ∈ P ∧ A ∈ Vi−1} ∪ Vi−1 (3) Je-li Vi = Vi−1, polož i = i + 1 a vrať se ke kroku 2. Je-li Vi = Vi−1, pak N = Vi ∩ N Σ = Vi ∩ Σ P ⊆ P obsahuje ta pravidla, která jsou tvořena pouze symboly z Vi. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY68 Algoritmus 4.2 je podobný algoritmu 4.1. Protože je Vi ⊂ N∪Σ, je počet opakování bodu (2) algoritmu 4.2 konečný. Důkaz algoritmu se provede indukcí pro i této ekvivalence: S ⇒∗ αXβ, právě když X ∈ Vi pro nějaké i. Nyní zformulujeme algoritmus pro odstranění zbytečných symbolů. Algoritmus 4.3 Odstranění zbytečných symbolů. Vstup: Gramatika G = (N, Σ, P, S) generující neprázdný jazyk. Výstup: Gramatika G = (N , Σ , P , S), pro kterou platí: (i) L(G) = L(G ) (ii) Žádný symbol v N ∪ Σ’ není zbytečný Metoda: (1) Na gramatiku G aplikuj algoritmus 4.1 s cílem získat množinu Nt. Polož G = (Nt ∪{S}, Σ, P1, S), kde P1 obsahuje pravidla tvořená pouze symboly z Nt ∪ Σ. (2) Algoritmus 4.2 aplikuj na gramatiku G. Výsledkem je gramatika G = (N , Σ , P , S), která neobsahuje zbytečné symboly. V kroku (1) algoritmu 4.3 jsou z G odstraněny všechny nonterminály, které nemohou generovat terminální řetězce. V kroku (2) jsou pak odstraněny všechny symboly, které jsou nedostupné. Pořadí použití algoritmů 4.1 a 4.2 je podstatné, obrácené pořadí nemusí vždy vést ke gramatice bez zbytečných symbolů. Věta 4.2 Gramatika G z algoritmu 4.3 je ekvivalentní gramatice G a nemá zbytečné symboly. Důkaz: Dokážeme sporem, že gramatika G nemá zbytečné symboly. Předpokládejme, že A ∈ N je zbytečný symbol. Podle definice zbytečných symbolů musíme uvažovat dva případy: 1. Neplatí S ⇒ G ∗ αAβ pro všechna α a β. V tomto případě se však dostáváme do sporu s krokem (2) algoritmu 4.3. 2. Platí S ⇒ G ∗ αAβ pro nějaká α a β, avšak neplatí A ⇒ G ∗ w, w ∈ Σ ∗ . Pak A nebude odstraněn v kroku (2) algoritmu 4.3 a navíc, platí-li A ⇒ G ∗ γBδ, pak ani B nebude odstraněn v kroku (2). Platí-li však A ⇒ G ∗ w, pak také platí A ⇒ G ∗ w a tedy neplatí-li A ⇒ G ∗ w, pak neplatí ani A ⇒ G ∗ w, což je spor s krokem (1) algoritmu 4.3. Důkaz, že G neobsahuje ani zbytečný terminál se provede obdobně. 2 Příklad 4.12 Uvažujme gramatiku G = ({S, A, B}, {a, b}, P, S), kde P obsahuje pravidla: S → a | A A → AB B → b KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY69 Aplikujeme-li na G algoritmus 4.3, pak v kroku 1 získáme Nt = {S, B}, takže G = ({S, B}, {a, b}, {S → a, B → b}, S}). Po aplikování algoritmu 4.2 na G obdržíme V2 = V1 = {S, a}. Výsledkem je tedy ekvivalentní gramatika G = ({S}, {a}, {S → a}, S). Kdybychom jako první aplikovali algoritmus 4.2, zjistíme, že všechny symboly v G jsou dostupné a algoritmus 4.2 tedy gramatiku G nezmění. Po aplikování algoritmu 4.1 získáme Nt = {S, B}, takže výsledná gramatika bude G a ne G . Další důležitou transformací, kterou nyní popíšeme, je transformace odstraňující z gramatiky pravidla tvaru A → ( je prázdný řetězec), tzv. -pravidla. Jestliže ovšem L(G) má obsahovat také prázdný řetězec, pak není možné aby G neobsahovala žádné -pravidlo. Následující definice gramatiky bez -pravidla respektuje tuto skutečnost. Definice 4.9 Říkáme, že gramatika G = (N, Σ, P, S) je gramatikou bez -pravidel, jestliže buď P neobsahuje žádné -pravidlo, nebo, v případě ∈ L(G), existuje jediné -pravidlo tvaru S → a výchozí symbol S se nevyskytuje na pravé straně žádného pravidla z P. Algoritmus 4.4 Transformace na gramatiku bez -pravidel. Vstup: Gramatika G = (N, Σ, P, S) Výstup: Ekvivalentní gramatika G = (N , Σ , P , S ) bez -pravidel. Metoda: (1) Sestroj N = {A | A ∈ N a A ⇒∗ }. Konstrukce množiny N je analogická konstrukci Nt z 4.1. (2) Nechť P je množina pravidel, kterou konstruujeme takto: a) Jestliže A → α0B1α1B2 . . . Bkαk je v P, k ≥ 0 a každé Bi je v N , 1 ≤ i ≤ k, avšak žádný ze symbolů řetězců αj není v N , 0 ≤ j ≤ k, pak k P přidej všechna nová pravidla tvaru A → α0X1α1X2 . . . Xkαk kde Xi je buď Bi nebo . Nepřidávej -pravidlo A → , které se objeví, jsou-li všechna αi = . b) Jestliže S ∈ N pak k P přidej pravidla S → | S S je nový výchozí symbol. Polož N = N ∪ {S } Jestliže S /∈ N , pak N = N a S = S (3) Výsledná gramatika má tvar G = (N , Σ , P , S ) Příklad 4.13 Uvažujme gramatiku G = ({S}, {a, b}, P, S), kde P obsahuje pravidla S → aSbS | bSaS | . Po aplikování algoritmu 4.4 získáme gramatiku G bez -pravidel. G = ({S , S}, {a, b}, P , S ), kde P obsahuje pravidla S → S | S → aSbS | abS | aSb | ab | bSaS | baS | bSa | ba KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY70 Věta 4.3 Algoritmus 4.3 převádí vstupní gramatiku G na ekvivalentní gramatiku G bez -pravidel Důkaz: G zřejmě neobsahuje -pravidla kromě případného pravidla S → , je-li ∈ L(G). Důkaz, že L(G) = L(G ) se provede indukcí pro délku řetězce w v ekvivalenci A ⇒ G ∗ w právě když w = ∧ A ⇒ G ∗ w Jinou užitečnou transformací je odstranění pravidel tvaru A → B. 2 Definice 4.10 Přepisovací pravidlo tvaru A → B, A, B ∈ N se nazývá jednoduché pravidlo. Algoritmus 4.5 Odstranění jednoduchých pravidel. Vstup: Gramatika G bez -pravidel. Výstup: Ekvivalentní gramatika G bez jednoduchých pravidel. Metoda: (1) Pro každé A ∈ N sestroj množinu NA = {B | A ⇒∗ B} takto: a) N0 = {A}, i = 1 b) Ni = {C | B → C je v P a B ∈ Ni−1} ∪ Ni−1 c) Jestliže Ni = Ni−1, polož i = i + 1 a opakuj krok b). V opačném případě je NA = Ni. (2) Sestroj P takto: Jestliže B → α je v P a není jednoduchým pravidlem, pak pro všechna A, pro něž B ∈ NA, přidej k P pravidla A → α (3) Výsledná gramatika je G = (N, Σ, P , S) Příklad 4.14 Uvažujme gramatiku s přepisovacími pravidly: E → E + T | T T → T ∗ F | F F → (E) | i Tato gramatika se liší od gramatiky z příkladu 4.3 pouze jiným značením nonterminálu a generuje tudíž stejný jazyk aritmetických výrazů Po aplikování algoritmu 4.5 bude NE = {E, T, F} NT = {T, F} NF = {F} a výsledná množina přepisovacích pravidel, neobsahující jednoduchá pravidla, bude: E → E + T | T ∗ F | (E) | i T → T ∗ F | (E) | i F → (E) | i Věta 4.4 Algoritmus 4.4 převádí vstupní gramatiku G na ekvivalentní gramatiku G bez jednoduchých pravidel. Důkaz: Gramatika G zřejmě neobsahuje jednoduchá pravidla. Abychom ukázali, že L(G) = L(G ), dokážeme že platí L(G ) ⊆ L(G) a také L(G) ⊆ L(G ). KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY71 1. L(G ) ⊆ L(G) Nechť w ∈ L(G ). Pak existuje v G derivace S = α0 ⇒ α1 ⇒ . . . ⇒ αn = w. Jestliže k derivaci αi ⇒ G αi+1 bylo použito pravidla A → β, pak existuje nonterminál B (A = B případně) takový, že A ⇒ G ∗ B a B ⇒ G β a tedy A ⇒ G ∗ β a αi ⇒ G ∗ αi+1. Z toho plyne, že platí S ⇒ G ∗ w a w je tudíž v L(G). 2. L(G) ⊆ L(G ) Nechť w ∈ L(G) a S = α0 ⇒ α1 ⇒ . . . ⇒ αn = w je levá derivace řetězce w v gramatice G. Nechť i1, i2, . . . ik je posloupnost indexů tvořená pouze těmi j, pro které v levé derivaci αj−1 ⇒ αj nebylo použito jednoduchého pravidla. Speciálně ik = n, protože poslední aplikované pravidlo v derivaci řetězce w nemůže být jednoduché. Derivace řetězce w v G je levou derivací, a proto aplikací jednoduchých pravidel nahrazujeme pouze nejlevější nonterminál jiným nonterminálem (reprezentuje levou stranu pravidla v G ). Platí tedy S ⇒ G αi1 ⇒ G . . . ⇒ G αi1 = w a tudíž w ∈ L(G ). Dokázali jsme tak ekvivalenci gramatik G a G . 2 Definice 4.11 Říkáme, že G je gramatika bez cyklu, jestliže v ní neexistuje derivace tvaru A ⇒+ A pro žádné A z N. Jestliže G je gramatika bez cyklu a bez -pravidel a nemá žádné zbytečné symboly, pak říkáme, že G je vlastní gramatika. Věta 4.5 Je-li L bezkontextový jazyk, pak existuje vlastní gramatika G taková, že L = L(G). Důkaz: Vyplývá z algoritmů 4.1–4.5. Gramatika, jež neobsahuje -pravidla a jednoduchá pravidla, je zřejmě gramatikou bez cyklu. 2 Poznámka 4.4 Gramatika, která obsahuje cykly, je víceznačná a nemůže být napr. použita pro konstrukci deterministického syntaktického analyzátoru. Existence -pravidel a jednoduchých pravidel, na druhé straně, neimplikuje existenci cyklu (tj. derivace tvaru A ⇒+ A pro nějaké A ∈ N). Další transformací, kterou uvedeme, je odstranění levé rekurze. Tato transformace je důležitá pro použití analýzy typu shora-dolů. Definice 4.12 Nechť G = (N, Σ, P, S). Přepisovací pravidlo z P se nazývá rekurzivní zleva (rekurzivní zprava), jestliže je tvaru A → Aα(A → αA), A ∈ N, α ∈ (N ∪Σ)∗ . Jestliže v G existuje derivace A ⇒+ αAβ, pro nějaké A ∈ N, říkáme, že gramatika G je rekurzivní. Je-li α = , pak mluvíme o gramatice rekurzivní zleva, je-li β = , pak říkáme, že G je rekurzivní zprava. Poznamenejme, že je-li jazyk L(G) nekonečný, pak G musí být rekurzivní. Dříve, než zformujeme algoritmus eliminující levou rekurzi, ukážeme, jakým způsobem lze odstranit přepisovací pravidla rekurzivní zleva. Definice 4.13 Pravidlo A → α , s levou stranou tvořenou nonterminálem A, budeme nazývat A-pravidlo (Neplést s -pravidlem.) KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY72 Věta 4.6 Nechť G = (N, Σ, P, S) je gramatika a nechť A → Aα1 | Aα2 | . . . | Aαm | β1 | β2 | . . . | βn jsou všechna A-pravidla. Žádný z řetězců βi nezačíná nonterminálem A. Gramatika G = (N ∪{A }, Σ, P , S), kde P obsahující namísto uvedených pravidel pravidla A → β1 | β2 | . . . | βn | β1A | β2A | . . . | βnA A → α1 | α2 | . . . | αm | α1A | α2A | . . . | αmA je ekvivalentní s gramatikou G, tj. L(G) = L(G ). Důkaz: Uvedena transformace nahrazuje pravidla rekurzivní zleva pravidly, která jsou rekurzivní zprava. Označíme-li jazyky L1 = {β1, β2, . . . , βn} a L2 = {α1, α2, . . . , αm} vidíme, že v G lze z nonterminálu A derivovat řetězce tvořící jazyk L1L∗ 2. Právě tyto řetězce můžeme však derivovat z A také v gramatice G . Efekt popisované transformace ilustruje obrázek 4.12. 2 s s         d d d d A A αi1 s s         d d d d A αi2 s s         d d d d A s s s         d d d d         A A αiκ β . . . ss s ss ss ss d d d d         d d d d d d d d         d d d d         d d d d         A Aαi2 αi1 . . . A Aβ Aαiκ A Obrázek 4.12: Odstranění levé rekurze: nalevo část stromu v G, napravo část stromu v G Příklad 4.15 Uvažujme gramatiku G z předcházejícího příkladu s pravidly E → E + T | T T → T ∗ F | F F → (E) | i Po odstranění pravidel rekurzivních zleva získáme ekvivalentní gramatiku G s pravidly E → T | TE E → +T | +TE T → F | FT T → ∗F | ∗FT F → (E) | i KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY73 Věta 4.7 Nechť G = (N, Σ, P, S) je gramatika. A → αBβ, B ∈ N; α, β ∈ (N ∪ Σ)∗ je pravidlo z P a B → γ1 | γ2 | . . . | γn jsou všechna B-pravidla v P. Nechť G = (N, Σ, P , S), kde P = P − {A → αBβ} ∪ {A → αγ1β | αγ2β | . . . | αγnβ}. Pak L(G) = L(G ). Důkaz: Výsledkem této transformace je odstranění pravidla A → αBβ z gramatiky G tím způsobem, že za nonterminál B ” dosadíme“ všechny pravé strany B-pravidel. Formálně se důkaz provede tak, že se ukáže platnost konjunkce L(G) ⊆ L(G)∧L(G ) ⊆ L(G). Efekt této transformace ilustruje obr. 4.13, jenž znázorňuje derivační stromy řetězce aabbb v gramatice G resp. G . Gramatika G obsahuje pravidlo A → aAA a dvě A-pravidla A → aAA | b. Položíme-li α = a, B = A, β = A, můžeme eliminovat pravidlo A → aAA zavedením těchto A-pravidel v gramatice G : A → aaAAA | abA | b 2 Obrázek 4.13: Derivační stromy věty aabbb v G resp. G Algoritmus 4.6 Odstranění levé rekurze. Vstup: Vlastní gramatika G = (N, Σ, P, S) Výstup: Gramatika G bez levé rekurze. Metoda: (1) Nechť N = {A1, A2, . . . , An}. Gramatiku budeme transformovat tak, že je-li Ai → α pravidlo, pak α začíná buď terminálem, nebo nonterminálem Aj, j > i. K tomu účelu položme i = 1. (2) Nechť Ai → Aiα1 | . . . | Aiαm | β1 | . . . | βp jsou všechna Ai-pravidla a nechť žádné βi nezačíná nonterminálem Ak, je-li k ≤ i. Nahraď všechna Ai-pravidla těmito pravidly: Ai → β1 | . . . | βp | β1Ai | . . . | βpAi Ai → α1 | . . . | αm | α1Ai | . . . | αmAi kde Ai je nový nonterminál. Takto všechna Ai-pravidla začínají buď terminálem, nebo nonterminálem Ak, k > i. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY74 (3) Je-li i = n, pak jsme získali výslednou gramatiku G . V opačném případě polož i = i + 1 a j = 1. (4) Každé pravidlo tvaru Ai → Ajα nahraď pravidly Ai → β1α | . . . | βpα kde Aj → β1 | . . . | βp jsou všechna Aj-pravidla. Po této transformaci budou všechna Aj-pravidla začínat buď terminálem, nebo nonterminálem Ak, k > j, takže také všechna Ai-pravidla budou mít tuto vlastnost. (5) Je-li j = i − 1, pak přejdi ke kroku (2). Jinak j = j + 1 a opakuj krok (4). Věta 4.8 Každý bezkontextový jazyk lze generovat gramatikou bez levé rekurze. Důkaz: Nechť G je vlastní gramatika. Algoritmus 4.6 používá pouze transformací z vět 4.6 a 4.7 a tudíž je L(G) = L(G ). Dále musíme dokázat, že G není gramatikou rekurzivní zleva. Formální důkaz nebudeme provádět (viz [1]). Uvědomíme si však, že krok (2) odstraňuje pravidla rekurzivní zleva. Stejně tak pravidla vzniklá aplikací kroku (4) nejsou rekurzivní zleva. Protože krok (2) je aplikován na všechny nonterminální symboly, nemůže výsledná gramatika obsahovat pravidla rekurzivní zleva. 2 Příklad 4.16 Nechť G je gramatika s pravidly: A → BC | a B → CA | Ab C → AB | CC | a Položme A1 = A, A2 = B a A3 = C. V každém kroku uvedeme pouze nová pravidla pro ty nonterminály, jejichž pravidla se mění. krok (2), i=1, beze změny krok (4), i=2, j=1, B → CA | BCb | ab krok (2), i=2, B → CA | ab | CAB | abB B → CbB | Cb krok (4), i=3, j=1, C → BCB | aB | CC | a krok (4), i=3, j=2, C → CACB | abCB | CAB CB | abB CB | aB | CC | a krok (2), i=3, C → abCB | abB CB | aB | a | abCBC | abB CBC C → aBC | aC C → ACBC | AB CBC | CC | ACB | AB CB | C 4.6 Chomského normální forma Definice 4.14 Gramatika G = (N, Σ, P, S) je v Chomského normální formě (CNF), jestliže každé pravidlo z P má jeden z těchto tvarů: (1) A → BC, A, B, C ∈ N nebo (2) A → a, a ∈ Σ nebo (3) Je-li ∈ L(G), pak S → je pravidlo z P a výchozí symbol S se neobjeví na pravé straně žádného pravidla. Chomského normální forma gramatiky je prostředkem zjednodušujícím tvar reprezentace bezkontextového jazyka. Nyní popíšeme algoritmus převodu obecné bezkontextové gramatiky do Chomského normální formy. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY75 Algoritmus 4.7 Převod do Chomského normální formy. Vstup: Vlastní gramatika G = (N, Σ, P, S) bez jednoduchých pravidel. Výstup: Gramatika G = (N , Σ, P , S ) v CNF taková, že L(G) = L(G ) Metoda: Z gramatiky G získáme ekvivalentní gramatiku G v CNF takto: (1) Množina pravidel P obsahuje všechna pravidla tvaru A → a z P (2) Množina pravidel P obsahuje všechna pravidla tvaru A → BC z P (3) Je-li pravidlo S → v P, pak S → je také v P (4) Pro každé pravidlo tvaru A → X1 . . . Xk, kde k > 2 z P přidej k P tuto množinu pravidel. Symbolem Xi značíme nonterminál Xi, je-li Xi ∈ N, nebo nový nonterminál, je-li Xi ∈ Σ: A → X1 X2 . . . Xk X2 . . . Xk → X2 X3 . . . Xk ... Xk−1Xk → Xk−1Xk kde každý symbol Xi . . . Xk značí nový nonterminální symbol. (5) Pro každé pravidlo tvaru A → X1X2, kde některý ze symbolů X1 nebo X2 leží v Σ přidej k P pravidlo A → X1X2, kde Xi značíme nonterminál Xi, je-li Xi ∈ N, nebo nový nonterminál, je-li Xi ∈ Σ. (6) Pro každý nový nonterminál tvaru a přidej k P pravidlo a → a. Výsledná gramatika je G = (N , Σ, P , S ); množina N obsahuje všechny nonterminály tvaru Xi . . . Xk a a . Věta 4.9 Nechť L je bezkontextový jazyk. Pak existuje bezkontextová gramatika G v CNF taková, že L = L(G). Důkaz: Podle věty 4.5 má jazyk L vlastní gramatiku G. Stačí tedy dokázat, že výsledkem algoritmu 4.7 je ekvivalentní gramatika G tj. L(G) = L(G ). Tato ekvivalence však plyne bezprostředně z aplikace věty 4.7 na každé pravidlo z P , které má nonterminály tvaru a a Xi...Xj . Výsledkem bude gramatika G . 2 Příklad 4.17 Nechť G je gramatika s pravidly S → aAB | BA A → BBB | a B → AS | b Chomského normální forma G = (N , {a, b}, P , S) má pravidla: S → a AB | BA A → B BB | a B → AS | b AB → AB BB → BB a → a Nová množina nonterminálů je tedy N = {S, A, B, AB , BB , a } KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY76 Příklad 4.18 Předpokládejme, že gramatika G je v CNF, a že řetězci w ∈ L(G) přísluší derivace v G délky p. Jaká je délka věty w? Řešení: Nechť |w| = n. Pak pro odvození věty bylo třeba n-krát aplikovat pravidlo tvaru A → a a (n-1)-krát pravidlo tvaru A → BC. Dostáváme tedy vztah p = n + n − 1 = 2n − 1 a vidíme, že p je vždy liché. Řešení příkladu je tedy |w| = p + 1 2 4.7 Greibachové normální forma Definice 4.15 Gramatika G = (N, Σ, P, S) je v Greibachové normální formě (GNF), je-li G gramatikou bez -pravidel a jestliže každé pravidlo (s výjimkou případného pravidla S → ) má tvar A → aα kde a ∈ Σ a α ∈ N∗ . Lemma 4.1 Nechť G = (N, Σ, P, S) je gramatika bez levé rekurze. Pak existuje lineární uspořádání < definované na množině nonterminálních symbolů N takové, že je-li A → Bα v P, pak A < B. Důkaz: Nechť R je relace na množině N taková, že ARB platí právě když A ⇒+ Bα pro nějaké α ∈ (N ∪ Σ)∗ . Z definice levé rekurze plyne, že R je částečné uspořádání (R je tranzitivní). Každé částečné uspořádání pak lze rozšířit na lineární uspořádání. 2 Nyní zformulujeme algoritmus převodu gramatiky G do Greibachové normální formy. Algoritmus 4.8 Převod do Greibachové normální formy. Vstup: Vlastní gramatika bez levé rekurze G = (N, Σ, P, S) Výstup: Ekvivalentní gramatika G v GNF Metoda: (1) Podle lemmy 4.1 vytvoř lineární uspořádání < na N takové, že každé A-pravidlo začíná buď terminálem, nebo nějakým nonterminálem B takovým, že A < B. Nechť N = {A1, A2, . . . , An} a A1 < A2 < · · · < An. (2) Polož i = n − 1. (3) Je-li i = 0 přejdi k bodu (5), je-li i = 0 nahraď každé pravidlo tvaru Ai → Ajα, kde j > i pravidly Ai → β1α | . . . | βmα, kde Aj → β1 | . . . | βm jsou všechna Aj-pravidla. (Každý z řetězců β1 . . . βm začíná terminálem.) (4) Polož i = i − 1 a opakuj krok (3). (5) V tomto okamžiku všechna pravidla (s vyjímkou pravidla S → ) začínají terminálním symbolem. V každém pravidle A → aX1 . . . Xk nahraď ty symboly Xj, které jsou terminálnímy symboly, novým nonterminálem Xj. (6) Pro všechna Xj z bodu (5) přidej pravidla Xj → Xj. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY77 Věta 4.10 Nechť L je bezkontextový jazyk. Pak existuje gramatika G v GNF taková, že L = L(G). Důkaz: Z definice uspořádání < vyplývá, že všechna An-pravidla začínají terminály, a že po opakovaném provádění kroku (3) algoritmu 4.8 budou všechna Ai-pravidla pro i = 1, . . . , n − 1 začínat také terminálními symboly. Krok (5) a (6) převádí nepočáteční terminální symboly pravých stran na nonterminály, aniž se mění generovaný jazyk. 2 Příklad 4.19 Převeďme gramatiku G s pravidly E → T | TE E → +T | +TE T → F | FT T → ∗F | ∗FT F → (E) | i do GNF. Řešení: Podle lemmy 4.1 je E < T < F. Jako lineární uspořádání na množině nonterminálů vezměme uspořádání E < E < T < T < F Všechna F-pravidla začínají terminálem (důsledek skutečnosti, že F je největší prvek v uspořádání < ). Předcházející symbol T má pravidla T → F | FT a po aplikaci kroku (3) dostáváme pravidla T → (E) | i | (E)T | iT . Výsledná gramatika v GNF má pravidla: E → (E) | i | (E) T | iT | (E) E | iE | (E) T E | iT E E → +T | +TE T → (E) | i | (E) T | iT T → ∗F | ∗FT F → (E) | i ) → ) Nevýhodou algoritmu 4.8 je velké množství nových pravidel. Existuje alternativní algoritmus převodu do GNF, [1], který nezvětšuje tak výrazně počet pravidel gramatiky, avšak zavádí zase více nonterminálů. Bezkontextové gramatiky umožňují popisovat většinu rysů současných vyšších programovacích jazyků. Způsob získání derivačního stromu věty v dané bezkontextové gramatice je základem syntaktické analýzy a klasifikace syntaktických analyzátorů překladačů a jazykových procesorů. Řada transformací bezkontextových gramatik a existence normálních forem bezkontextových gramatik umožňuje odstraňování některých atributů gramatiky nebo derivaci v této gramatice, jež se využívá v praktických aplikacích i v rámci důkazových technik. 4.8 Cvičení Cvičení 4.8.1 Modifikujte gramatiku GRV z příkladu 4.10 tak, aby zápisy regulárních výrazů rovněž připouštěly: (a) explicitní použití operátoru · konkatenace (např. a · b) KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY78 (b) použití operátoru + ve významu r+ = rr∗ Cvičení 4.8.2 Gramatika G = ({ deklarace , options , option , mode , scale , precision , base }, {declare, id, real, complex, fixed, floating, single, double, binary, decimal}, P, deklarace ) s pravidly P deklarace → declare id options options → option options | option → mode | scale | precision | base mode → real | complex scale → fixed floating precision → single | double base → binary | decimal popisuje deklaraci jednoduché proměnné. Tato gramatika však dovoluje vytvářet deklarace, které obsahují redundantní nebo rozporné informace, např. declare X real fixed real floating Zapište gramatiku, která připouští pouze deklarace bez redundancí a rozporů. Uvažte, zda je vhodné takový problém řešit prostředky definice syntaxe jazyka. Cvičení 4.8.3 Pro výpočet tranzitivního uzávěru binární relace definované na konečné množině (např. slovníku gramatiky) se velmi často používá reprezentace relace prostřednictvím booleovské matice a operací nad touto maticí. Je-li A booleovská matice reprezentující binární relaci R na množině M (tj. A[p, q] = true, je-li (p, q) ∈ R a A[p, q] = false, je-li (p, q) /∈ R, p, q ∈ M a A[p, q] je prvek matice A v řádku označeném p a sloupci označeném q), pak tranzitivní uzávěr relace R je relace R+ , jenž je reprezentován maticí A+ : A+ = A + A2 + . . . + An , (3) kde n = min(|M| − 1, |R|) a operace sečítání, resp. násobení jsou interpretovány jako disjunkce, resp. konjunkce. Pro výpočet tranzitivního uzávěru existuje efektivnější postup než podle 3, nazývaný, podle autora, Warshallův algoritmus. Algoritmus 4.9 Warshallův algoritmus pro výpočet tranzitivního uzávěru binární relace. Vstup: Booleovská matice A reprezentující binární relaci R. Výstup: Booleovská matice B reprezentující binární relaci R+ . Metoda: (1) Polož B = A a i = 1. (2) Pro všechna j, jestliže B[j, i] = true, pak pro k = 1, . . . , n polož B[j, k] = B[j, k] + B[i, k]. (3) Polož i = i + 1. (4) Je-li i ≤ n, vrať se ke kroku (2); v opačném případě je B výsledná matice. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY79 Ukažte, že algoritmus 4.9 počítá skutečně tranzitivní uzávěr binární relace. Cvičení 4.8.4 V gramatice z příkladu 4.3 vytvořte levou a pravou derivaci a derivační strom věty i ∗ (i + i − i). Nalezněte všechny fráze, jednoduché fráze a l-frázi této věty. Cvičení 4.8.5 Nechť G = (N, Σ, P, S) je gramatika a α1, α2 řetězce α1, α2 ∈ (N ∪ Σ)∗ . Navrhněte algoritmus, který zjišťuje, zda platí α1 ⇒ G ∗ α2. Cvičení 4.8.6 Je dána gramatika G = ({S, A, B}, {a, b}, P, S), která má pra- vidla S → bA | aB A → a | aS | bAA B → b | bS | aBB Ukažte, že tato gramatika je víceznačná (uvažujte např. větu aabbab). Pokuste se nalézt ekvivalentní jednoznačnou gramatiku. Cvičení 4.8.7 Gramatiku s pravidly S → A | B A → aB | bS | b B → AB | Ba C → AS | b transformujte na ekvivalentní gramatiku bez zbytečných symbolů. Cvičení 4.8.8 Nalezněte gramatiku bez -pravidel, jež je ekvivalencí s gramati- kou S → ABC A → BB | B → CC | a C → AA | b Cvičení 4.8.9 Ke gramatice S → A | B A → C | D B → D | E C → S | a | D → S | b E → S | c | nalezněte ekvivalentní vlastní gramatiku. Cvičení 4.8.10 Formulujte algoritmus, který testuje, zda gramatika G je a nebo není gramatikou bez cyklu. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY80 Cvičení 4.8.11 V gramatice S → AB A → BS | b B → SA | a odstraňte levou rekurzi. Cvičení 4.8.12 Do Chomského normální formy převeďte gramatiku G = ({S, T, L}, {a, b, +, −, ∗, /, [, ]}, P, S) kde P obsahuje pravidla S → T + S | T − S | T T → L ∗ T | L/T | L L → [S] | a | b Cvičení 4.8.13 Gramatiku G = ({S, A, B}, {a, b}, P, S) s pravidly S → Ba | Ab A → Sa | AAb | a B → Sb | BBa | b převeďte do Greibachové normální formy. 4.9 Základní definice zásobníkového automatu Zásobníkový automat je jednocestný nedeterministický automat, jenž je opatřen zásobníkem reprezentujícím nekonečnou paměť. Schéma zásobníkového automatu je uvedeno na obr. 4.14. T a1 ana2 Z1 Z2 Zm Řídicí Zásobník . . . ... jednotka Vstupní páska Čtecí hlava Obrázek 4.14: Schéma zásobníkového automatu Vstupní páska je rozdělena na jednotkové záznamy, každý záznam obsahuje právě jeden vstupní symbol. Obsah jednotkového záznamu může být čten čtecí KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY81 hlavou, nemůže však být přepsán (read only input tape). V určitém časovém okamžiku může čtecí hlava zůstat na daném záznamu, nebo se posune o jeden záznam doprava (jednocestný automat). Konečná řídící jednotka realizuje operace posuvu čtecí hlavy a ukládání informace do zásobníku prostřednictvím funkce přechodů definované nad vstupní abecedou, množinou stavů řídící jednotky a vrcholem zásobníku. Definice 4.16 Zásobníkový automat P je sedmice P = (Q, Σ, Γ, δ, q0, Z0, F), kde (1) Q je konečná množina stavových symbolů reprezentujících vnitřní stavy řídicí jednotky, (2) Σ je konečná vstupní abeceda; jejími prvky jsou vstupní symboly, (3) Γ je konečná abeceda zásobníkových symbolů, (4) δ je zobrazení z množiny Q × (Σ ∪ { }) × Γ do konečné množiny podmnožin množiny Q × Γ∗ popisující funkci přechodů, (5) q0 ∈ Q je počáteční stav řídicí jednotky, (6) Z0 ∈ Γ je symbol, který je na počátku uložen do zásobníku – tzn. startovací symbol zásobníku, (7) F ⊆ Q je množina koncových stavů. Definice 4.17 Konfigurací zásobníkového automatu P nazveme trojici (q, w, α) ∈ Q × Σ∗ × Γ∗ kde (1) q je přítomný stav řídící jednotky (2) w je doposud nepřečtená část vstupního řetězce; první symbol řetězce w je pod čtecí hlavou. Je-li w = , pak byly všechny symboly ze vstupní pásky přečteny. (3) α je obsah zásobníku. Pokud nebude uvedeno jinak, budeme zásobník reprezentovat řetězcem, jehož nejlevější symbol koresponduje s vrcholem zásobníku. Je-li α = , pak je zásobník prázdný. Definice 4.18 Přechod zásobníkového automatu P budeme reprezentovat binární relací P (nebo bude-li zřejmé, že jde o automat P), která je definována na množině konfigurací zásobníkového automatu P. Relace (q, w, β) (q , w , β ) platí pro q, q ∈ Q, w, w ∈ Σ∗ , β, β ∈ Γ∗ , jestliže w = aw pro nějaké a ∈ (Σ∪{ }), β = Zα a β = γα pro nějaké Z ∈ Γ, α, γ ∈ Γ∗ a δ(q, a, Z) obsahuje prvek (q , γ). KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY82 Relaci P interpretujeme tímto způsobem. Nachází-li se zásobníkový automat P ve stavu q a na vrcholu zásobníku je uložen symbol Z, pak po přečtení vstupního symbolu a = může automat přejít do stavu q , přičemž se čtecí hlava posune doprava a na vrchol zásobníku se uloží, po odstranění symbolu Z, řetězec γ. Je-li γ = , pak je pouze odstraněn vrchol zásobníku. Je-li a = , neposouvá se čtecí hlava, což znamená, že přechod do nového stavu a nový obsah zásobníku není určován příštím vstupním symbolem. Tento typ přechodu budeme nazývat -přechodem. Poznamenejme, že -přechod může nastat i tehdy, když byly přečteny všechny vstupní symboly. Relace i , + , ∗ jsou definovány obvyklým způsobem. Relace + resp. ∗ je tranzitivní, resp. tranzitivní a reflexivní uzávěr relace , i je i-tá mocnina relace , i ≥ 0. Počáteční konfigurace zásobníkového automatu má tvar (q0, w, Z0) pro w ∈ Σ∗ , tj. automat je v počátečním stavu q0, na vstupní pásce je řetězec w a v zásobníku je startovací symbol Z0. Koncová konfigurace má tvar (q, , α), kde q ∈ F je koncový stav a α ∈ Γ∗ . Definice 4.19 Platí-li pro řetězec w ∈ Σ∗ relace (q0, w, Z0) ∗ (q, , α) pro nějaké q ∈ F a α ∈ Γ∗ , pak říkáme, že řetězec w je přijímán zásobníkovým automatem P. Množinu L(P) všech řetězců přijímaných zásobníkovým automatem P, který nazýváme jazykem přijímaným zásobníkovým automatem. Příklad 4.20 Uvažujme jazyk L = {0n 1n | n ≥ 0}. Zásobníkový automat P, který přijímá jazyk L, má tvar P = ({q0, q1, q2}, {0, 1}, {Z, 0}, δ, q0, Z, {q0}) kde δ(q0, 0, Z) = {(q1, 0Z)} δ(q1, 0, 0) = {(q1, 00)} δ(q1, 1, 0) = {(q2, )} δ(q2, 1, 0) = {(q2, )} δ(q2, , Z) = {(q0, )} a pracuje tak, že kopíruje všechny nuly ze vstupního řetězce do zásobníku. Objevíli se na vstupu symbol 1, pak odstraňuje jednu nulu ze zásobníku. Kromě toho požaduje, aby všechny nuly předcházely všechny jedničky. Například pro vstupní řetězec 0011 realizuje automat P tyto přechody: (q0, 0011, Z) (q1, 011, 0Z) (q1, 11, 00Z) (q2, 1, 0Z) (q2, , Z) (q0, , ) Ukažme, že skutečně platí L(P) = L. Z definice funkce přechodů δ a relace plyne (q0, , Z) 0 (q0, , Z) a tedy ∈ L(P). Dále platí (q0, 0, Z) (q1, , 0Z) (q1, 0i , 0Z) i (q1, , 0i+1 Z) (q1, 1, 0i+1 Z) (q2, , 0i Z) (q2, 1i , 0i Z) i (q2, , Z) (q2, , Z) (q0, , ) KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY83 což dohromady implikuje (q0, 0n 1n , Z) 2n+1 (q0, , ) pro n ≥ 1 a tedy L ⊆ L(P). Dokázat opačnou inkluzi L(P) ⊆ L, tj. dokázat, že zásobníkový automat nepřijímá jiné řetězce, než 0n 1n , n ≥ 1, je obtížnější. Příjme-li zásobníkový automat P vstupní řetězec, pak musí projít posloupností stavů q0, q1, q2, q0. Jestliže platí (q0, w, Z) i (q1, , α), pak w = 0i a α = 0i Z. Podobně, jestliže (q2, w, α) i (q2, , β) pak w = 1i a α = 0i β. To však znamená, že relace (q1, w, α) (q2, , β) platí, právě když w = 1 a α = 0β a relace (q2, w, Z) ∗ (q0, , ) platí, právě když w = . Tedy, jestliže platí (q0, w, Z) i (q0, , α) pro nějaké i > 0, pak w = 0n 1n , i = 2n + 1 a α = , tj. L(P) ⊆ L. Poznámka 4.5 Zásobníkové automaty lze také popisovat přechodovými diagramy. Jejich podoba je ilustrována níže na zásobníkovém automatu z příkladu 4.20. q0 q1 q2 Z 0,Z/0Z 0,0/00 1,0/ε 1,0/ε ε,Z/ε Všimněte si, že označení počátečního stavu je spojeno s definicí startovacího symbolu zásobníku. Přechody mezi stavy – řekněme q a q – jsou označeny výrazy a, Z/γ, kde a ∈ Σ ∪ {ε}, Z ∈ Γ a γ ∈ Γ∗ a specifikují, že (q , γ) ∈ δ(q, a, Z). 4.10 Varianty zásobníkových automatů V tomto odstavci uvedeme dvě varianty základní definice zásobníkového automatu, které nám usnadní objasnit vztah mezi zásobníkovými automaty a bezkontextovými jazyky. Definice 4.20 Rozšířeným zásobníkovým automatem rozumíme sedmici P = (Q, Σ, Γ, δ, q0, Z0, F) kde δ je zobrazení z konečné podmnožiny Q×(Σ∪{ })×Γ∗ do množiny podmnožin množiny Q×Γ∗ . Ostatní symboly mají stejný význam jako v základní definici 4.16. Podobně jako u běžných ZA je relace přechodu definována jako nejmenší relace taková, že (q, aw, αγ) (q , w, βγ) platí, jestliže δ(q, a, α) obsahuje (q , β) pro q, q ∈ Q, a ∈ Σ ∪ { } a α, β, γ ∈ Γ∗ . Tato relace odpovídá přechodu, v němž je vrcholový řetězec zásobníku odstraněn a nahrazen řetězcem β. (Připomeňme, že v základní definici je α ∈ Γ nikoliv α ∈ Γ∗ ). Jazyk definovaný automatem P je L(P) = {w | (q0, w, Z0) ∗ (q, , α), q ∈ F, α ∈ Γ∗ } Rozšířený zásobníkový automat může, na rozdíl od základní definice provádět přechody i v případě, že je zásobník prázdný. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY84 Příklad 4.21 Uvažujme rozšířený zásobníkový automat P, který přijímá jazyk L = {wwR | w ∈ {a, b}∗ }, P = ({q, p}, {a, b}, {a, b, S, Z}, δ, q, Z, {p}) kde zobrazení δ je definováno takto: δ(q, a, ) = {(q, a)} δ(q, b, ) = {(q, b)} δ(q, , ) = {(q, S)} δ(q, , aSa) = {(q, S)} δ(q, , bSb) = {(q, S)} δ(q, , SZ) = {(p, )} Pro vstupní řetězec aabbaa realizuje automat P tyto přechody: (q, aabbaa, Z) (q, abbaa, aZ) (q, bbaa, aaZ) (q, baa, baaZ) (q, baa, SbaaZ) (q, aa, bSbaaZ) (q, aa, SaaZ) (q, a, aSaaZ) (q, a, SaZ) (q, , aSaZ) (q, , SZ) (q, , ) Vidíme, že automat P pracuje tak, že nejdříve ukládá do zásobníku prefix vstupního řetězce, pak na vrchol zásobníku uloží znak S značící střed; pak vrcholový řetězec aSa nebo bSb nahrazuje symbolem S. Tento příklad ilustruje také nedeterministickou povahu zásobníkového automatu, protože zobrazením není určeno, zda má být přečten vstupní symbol a uložen na vrchol zásobníku (δ(q, x, ) = (q, x), x ∈ {a, b}), nebo zda má být proveden -přechod, který uloží na vrchol zásobníku středový symbol S, (δ(q, , ) = (q, S)). Z definice rozšířeného zásobníkového automatu vyplývá, že je-li jazyk L přijímán zásobníkovým automatem, pak je také přijímán rozšířeným zásobníkovým automatem. Ukažme nyní, že platí i opačná implikace. Věta 4.11 Nechť P = (Q, Σ, Γ, δ, q0, Z0, F) je rozšířený zásobníkový automat. Ekvivalence RZA a ZA Pak existuje zásobníkový automat P1 takový, že L(P1) = L(P). Důkaz: Položme m = max{|α| | δ(q, a, α) = ∅ pro nějaké q ∈ Q, a ∈ Σ∪{ } a α ∈ Γ∗ }. Zásobníkový automat P1 budeme konstruovat tak, aby simuloval automat P. Protože automat P neurčuje přechody podle vrcholu zásobníku, ale podle vrcholového řetězce zásobníku, bude automat P1 ukládat m vrcholových symbolů v jakési ” vyrovnávací paměti“ řídící jednotky tak, aby na počátku každého přechodu věděl, jakých m vrcholových symbolů je v zásobníku automatu P. Nahrazuje-li automat P k vrcholových symbolů řetězcem délky l, pak se totéž provede ve vyrovnávací KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY85 paměti automatu P1. Jestliže l < k, pak P1 realizuje k − l -přechodů, které přesouvají k−l symbolů z vrcholu zásobníku do vyrovnávací paměti. Automat P1 pak může simulovat další přechod automatu P. Je-li l ≥ k, pak se symboly přesouvají z vyrovnávací paměti do zásobníku. Formálně můžeme konstrukci zásobníkového automatu P1 popsat takto: P1 = (Q1, Σ1, Γ1, δ1, q1, Z1, F1) kde (1) Q1 = {[q, α] | q ∈ Q, α ∈ Γ∗ 1 a 0 ≤ |α| ≤ m} (2) Γ1 = Γ ∪ {Z1} (3) Zobrazení δ1 je definováno takto: a) Předpokládejme, že δ(q, a, X1 . . . Xk) obsahuje (r, Y1 . . . Yl). (i) Jestliže l ≥ k, pak pro všechna Z ∈ Γ1 a α ∈ Γ∗ 1 taková, že |α| = m−k δ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 δ1([q, X1 . . . Xkα], a, Z) obsahuje ([r, Y1 . . . YlαZ], ) b) Pro všechna q ∈ Q, Z ∈ Γ1 a α ∈ Γ∗ 1 taková, že |α| < m δ1([q, α], , Z) = {([q, α, Z], )} Tato pravidla vedou k naplnění vyrovnávací paměti (obsahuje m symbolů). (4) q1 = [q0, Z0, Zm−1 1 ]. Vyrovnávací paměť obsahuje na počátku symbol Z0 na vrcholu a m − 1 symbolů Z1 na dalších místech. Symboly Z1 jsou speciální znaky pro označení dna zásobníku. (5) F1 = {[q, α] | q ∈ F, α ∈ Γ∗ 1} Lze ukázat, že (q, aw, X1 . . . XkXk+1 . . . Xn) P (r, w, Y1 . . . YlXk+1 . . . Xn) platí, právě když ([q, α], aw, β) + P1 ([r, α ], w, β ) kde αβ = X1 . . . XnZm 1 α β = Y1 . . . YlXk+1 . . . XnZm 1 |α| = |α | = m a mezi těmito dvěma konfiguracemi automatu P1 není žádná konfigurace, ve které by druhý člen stavu (vyrovnávací paměť) měl délku m. Tedy relace (g0, w, Z0) P (q, , α) pro q ∈ F, α ∈ Γ∗ platí, právě když ([q0, Z0, Zm−1 1 ], w, Z1) ∗ P1 ([q, β], , γ) kde |β| = m a βγ = αZm 1 . Tedy L(P) = L(P1). 2 KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY86 Definice 4.21 Nechť P = (Q, Σ, Γ, δ, q0, Z0, F) je zásobníkový nebo rozšířený zásobníkový automat. Řetězec w je přijímán s vyprázdněním zásobníku, jestliže platí (q0, w, Z0) + (q, , ), q ∈ Q. Označme L (P) množinu všech řetězců, které jsou přijímány zásobníkovým automatem P s vyprázdněním zásobníku. Věta 4.12 Nechť L je jazyk přijímaný zásobníkovým automatem P = (Q, Σ, Γ, δ, q0, Z0, F), L = L(P). Lze zkonstruovat zásobníkový automat P takový, že L (P ) = L. Důkaz: Opět budeme konstruovat automat P tak, aby simuloval automat P. Kdykoli automat P dospěje do koncového stavu, přejde do speciálního stavu q , který způsobí vyprázdnění zásobníku. Musíme však uvážit situaci, kdy automat P je v konfiguraci s prázdným zásobníkem, nikoliv však v koncovém stavu. Abychom zabránili případům, že automat P přijímá řetězec, který nemá být přijat, přidáme k zásobníkové abecedě automatu P znak, jenž bude označovat dno zásobníku a může být vybrán pouze tehdy, je-li automat P ve stavu q . Formálně vyjádřeno, nechť P = (Q ∪ {q , q }, Σ, Γ ∪ {Z }, δ , q , Z , ∅), kde symbolem ∅ vyznačujeme, že P přijímá řetězec s vyprázdněním zásobníku. Zobrazení δ nyní definujeme takto: (1) Jestliže δ(q, a, Z) obsahuje (r, γ), pak δ (q, a, Z) obsahuje (r, γ) pro všechna q ∈ Q, a ∈ Σ ∪ { } a Z ∈ Γ. (2) δ(q , , Z ) = {(q0, Z0Z )}. První přechod zásobníkového automatu P uloží do zásobníku řetězec Z0Z , kde Z je speciální znak označující dno zásobníku, a přejde do počátečního stavu automatu P. (3) Pro všechna q ∈ F a Z ∈ Γ ∪ {Z } obsahuje δ (q, , Z) prvek (q , ). (4) Pro všechna Z ∈ Γ ∪ {Z } je δ(q , , Z) = {(q , )}. Nyní zřejmě platí (q , w, Z ) P (q0, w, Z0Z ) n P (q, , Y1 . . . Yr) P (q , , Y2 . . . Yr) r−1 P (q , , ) kde Yr = Z , právě když (q0, w, Z0) n P (q, , Y1 . . . Yr−1) pro q ∈ F a Y1 . . . Yr−1 ∈ Γ∗ . Tudíž L (P ) = L(P). Předchozí věta platí také obráceně 2 Věta 4.13 Nechť P = (q, Σ, Γ, δ, q0, Z0, ∅) je zásobníkový automat přijímající vyprázdněním zásobníku. Lze zkonstruovat zásobníkový automat P takový, že L(P ) = L (P). Důkaz: Zásobníkový automat P konstruujeme tak, že má speciální symbol Z na dně zásobníku. Jakmile je tento symbol ze zásobníku odstraněn, přechází automat P do nového koncového stavu qf : F = {qf }. Formální konstrukci automatu P nebudeme provádět. 2 KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY87 4.11 Ekvivalence bezkontextových jazyků a jazyků přijímaných zásobníkovými automaty L2 = LP Nejdříve ukážeme, jak lze zkonstruovat nedeterministický syntaktický analyzátor jazyka generovaného bezkontextovou gramatikou, který pracuje metodou shora– dolů. L2 ⊆ LP Věta 4.14 Nechť G = (N, Σ, P, S) je bezkontextová gramatika. Z gramatiky G můžeme zkonstruovat zásobníkový automat R takový, že L (R) = L(G). Důkaz: Zásobníkový automat R konstruujeme tak, aby vytvářel levou derivaci vstupního řetězce v gramatice G. Nechť R = ({q}, Σ, N ∪ Σ, δ, S, ∅), kde δ je definováno takto: (1) Je-li A → α pravidlo z P, pak δ(q, , A) obsahuje (q, α). (2) δ(q, a, a) = {(q, )} pro všechna a ∈ Σ. Nyní ukážeme, že A ⇒m w, právě když a jen když (q, w, ) n (q, , ) pro nějaké m, n ≥ 1. Část ” jen když“ dokážeme indukcí pro m. Předpokládejme, že A ⇒m w. Je-li m = 1 a w = a1 . . . ak, k ≥ 0 pak (q, a1 . . . ak, A) (q, a1 . . . ak) k (q, , ) Předpokládejme nyní, že platí A ⇒m w pro m > 1. První krok této derivace musí mít tvar A ⇒ X1X2 . . . Xk, přičemž Xi ⇒mi xi pro mi < m, 1 ≤ i ≤ k a x1x2 . . . xk = w. Tedy (q, w, A) (q, w, X1 . . . Xk) Je-li Xi ∈ N, pak podle induktivního předpokladu (q, xi, Xi) ∗ (q, , ) Je-li Xi = xi, xi ∈ Σ, pak (q, xi, Xi) (q, , ) Nyní již vidíme, že levé derivaci A ⇒ X1 . . . Xk ⇒m1 x1X2 . . . Xk ⇒m2 . . . ⇒mk x1x2 . . . xk = w odpovídá tato posloupnost přechodů: (q, x1 . . . xk, A) (q, x1 . . . xk, X1 . . . Xk) ∗ (q, x2 . . . xk, X2 . . . Xk) . . . ∗ (q, , ) Část ” když“, tj. je-li (q, w, A) n (q, , ), pak ⇒+ w dokážeme indukcí pro n. Pro n = 1, w = a A → je pravidlo v P. Předpokládejme, že dokazovaná relace platí pro všechna n < n. Pak první přechod automatu R musí mít tvar (q, w, A) (q, w, X1 . . . Xk) a (q, xi, Xi) ni (q, , ) pro 1 ≤ i ≤ k, kde w = x1 . . . xk. Pak A → X1 . . . Xk je pravidlo z P a derivace Xi ⇒+ xi plyne z induktivního předpokladu. Je-li Xi ∈ Σ pak Xi ⇒0 xi. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY88 Tedy A ⇒ X1 . . . Xk ⇒∗ x1X2 . . . Xk ⇒∗ . . . ⇒∗ x1 . . . xk−1Xk ⇒∗ x1 . . . xk−1xk = w je levá derivace řetězce w z A. Vezmeme-li S = A jako speciální případ, dostaneme S ⇒+ w, právě když (q, w, s) + (q, , ) a tedy L (R) = L(G). 2 Příklad 4.22 Ke gramatice G s pravidly E → E + T | T T → T ∗ F | F F → (E) | i sestrojme zásobníkový automat P takový, že L (P) = L(G) Řešení: P = ({q}, {+, ∗, (, ), i}, {+, ∗, (, ), i, E, T, F}, δ, q, E, ∅) kde δ je zobrazení δ(q, , E) = {(q, E + T), (q, T)} δ(q, , T) = {(q, T ∗ F), (q, F)} δ(q, , F) = {(q, (E)), (q, i)} δ(q, a, a) = {(q, )} pro všechna a ∈ {+, ∗, (, ), i} Pro vstupní řetězec i+i∗i může zásobníkový automat P realizovat tuto posloupnost přechodů: (q, i + i ∗ i, E) (q, i + i ∗ i, E + T) (q, i + i ∗ i, T + T) (q, i + i ∗ i, F + T) (q, i + i ∗ i, i + T) (q, +i ∗ i, +T) (q, i ∗ i, T) (q, i ∗ i, T ∗ F) (q, i ∗ i, F ∗ F) (q, i ∗ i, i ∗ F) (q, ∗i, ∗F) (q, i, F) (q, i, i) (q, , ) Nyní ukážeme, jakým způsobem lze k bezkontextové gramatice G definovat rozšířený zásobníkový automat reprezentující syntaktický analyzátor zdola–nahoru. Věta 4.15 Nechť G = (N, Σ, P, S) je bezkontextová gramatika. Rozšířený zásobníkový automat R = ({q, r}, Σ, N ∪ Σ ∪ {/S}, δ, q, /S, {r}), kde zobrazení δ je definováno takto: (1) δ(q, a, ) = {(q, a)} pro všechna a ∈ Σ. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY89 (2) Je-li A → α pravidlo z P, pak δ(q, , α) obsahuje (q, A). (3) δ(q, , S/S) = {(r, )}, přijímá jazyk L(G), tj. L(R) = L(G). Důkaz: Ukážeme, že automat R pracuje tak, že vytváří pravou derivaci postupnými redukcemi l-fráze počínaje terminálním řetězcem (umístěným na vstupní pásce) a konče výchozím symbolem S. Jinými slovy automat R realizuje syntaktickou analýzu zdola–nahoru. Změna konvence: Vrchol zásobníku budeme nyní uvádět vpravo. Induktivní hypotéza, kterou dokážeme indukcí pro n má tvar: S ⇒ rm ∗ αAy ⇒ rm n xy implikuje (q, xy, /S) ∗ (q, y, /SαA), ⇒ rm značí pravou derivaci. Pro n = 0 tato hypotéza platí, protože αA = x a tudíž automat R provádí přechody podle δ(q, a, ) = {(q, a)}, a ∈ Σ, přesouvající řetězec x do zásobníku. Nyní předpokládejme, že induktivní hypotéza platí pro všechny derivace, kratší než n. Můžeme psát αAγ ⇒ rm αβy ⇒ rm n−1 xy Je-li řetězec αβ tvořen pouze terminálními symboly, pak αβ = x a (q, xy, /S) ∗ (q, y, /Sαβ) (q, y, /SαA). Není-li αβ ∈ Σ∗ , pak můžeme psát αβ = γBz, kde B je nejpravější nonterminál a podle induktivní hypotézy S ⇒ rm ∗ γBzy ⇒ rm n−1 xy implikuje (q, xy, /S) ∗ (q, zy, /SγB). Platí tedy (q, zy, /SγB) ∗ (q, y, /SγBz) (q, y, /SαA) a tudíž jsme dokázali induktivní hypotézu. Protože (q, , /SS) (r, , ) dostáváme L(G) ⊆ L(R). Abychom dokázali, že L(R) ⊆ L(G), ukažme, že platí implikace: Jestliže (q, xy, /S) n (q, y, /SαA), pak αAy ⇒∗ xy Pro n = 0 tato implikace platí. Předpokládejme, že platí také pro všechny posloupnosti přechodů kratší než n. Protože vrchol zásobníku je nonterminální symbol, prováděl se poslední přechod podle předpisu (2) v zobrazení δ a můžeme psát: (q, xy, /S) n−1 (q, y, /Sαβ) (q, y, /SαA) kde A → β je pravidlo z P. Existuje tedy derivace αAy ⇒ αβy ⇒∗ xy. Jako speciální případ uvažujme implikaci: je-li (q, w, /S) ∗ (q, , /SS), pak S ⇒∗ w Protože však platí (q, w, /S) ∗ (q, , /SS) (r, , ) je L(R) ⊆ L(G) a společně s první částí důkazu dostáváme L(G) = L(R). 2 Poznamenejme, že automat R skutečně představuje model syntaktického analyzátoru, který vytváří pravou derivaci vstupního řetězce postupnými redukcemi l-fráze větných forem (počáteční větná forma je vstupní řetězec, koncová větná forma je výchozí symbol gramatiky). Bezprostředně po přechodu automatu je KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY90 pravá větná forma αAx reprezentována obsahem zásobníku (řetězec αA) a nezpracovanou částí vstupního řetězce (řetězec x). Následující činností automatu je přesunutí prefixu řetězce x na vrchol zásobníku a redukce l-fráze dané vrcholovým řetězcem zásobníku. Tento typ syntaktické analýzy se, jak již víme, nazývá syntaktická analýza zdola–nahoru. Příklad 4.23 Sestrojme syntaktický analyzátor R zdola–nahoru pro gramatiku s pravidly E → E + T | T T → T ∗ F | F F → (E) | i Nechť R je rozšířený zásobníkový automat R = ({q, r}, {+, ∗, (, ), i}, {/S, E, T, F, +, ∗, (, ), i}, δ, q, /S, {r}) kde δ je zobrazení (1) δ(q, a, ) = {(q, a)} pro všechna a ∈ {i, +, ∗, (, )}. (2) δ(q, , E + T) = {(q, E)} δ(q, , T) = {(q, E)} δ(q, , T ∗ F) = {(q, T)} δ(q, , F) = {(q, T)} δ(q, , (E)) = {(q, F)} δ(q, , i) = {(q, F)} (3) δ(q, , /SE) = {(r, )} Pro vstupní řetězec i + i ∗ i může rozšířený zásobníkový automat R provést tuto posloupnost přechodů: (q, i + i ∗ i, /S) (q, +i ∗ i, /Si) (q, +i ∗ i, /SF) (q, +i ∗ i, /ST) (q, +i ∗ i, /SE) (q, i ∗ i, /SE+) (q, ∗i, /SE + i) (q, ∗i, /SE + F) (q, ∗i, /SE + T) (q, i, /SE + T∗) (q, , /SE + T ∗ i) (q, , /SE + T ∗ F) (q, , /SE + T) (q, , /SE) (r, , ) KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY91 Na závěr tohoto odstavce ukážeme , že bezkontextové jazyky jsou ekvivalentní jazykům přijímaným zásobníkovými automaty, tj., že lze také ke každému zásobníkovému automatu R vytvořit bezkontextovou gramatiku G takovou, že L(R) = L(G). Věta 4.16 Nechť R = (Q, Σ, Γ, δ, q0, Z0, F) je zásobníkový automat. Pak existuje LP ⊆ L2 bezkontextová gramatika G, pro kterou platí L(G) = L(R). Důkaz: Gramatiku G budeme konstruovat tak, aby levá derivace terminálního řetězce w přímo korespondovala s posloupností přechodů automatu R. Budeme používat nonterminální symboly tvaru [qZr] kde q, r ∈ Q, Z ∈ Γ. Vrchol zásobníku uvádíme opět vlevo. Nechť gramatika G = (N, Σ, P, S) je formálně definována takto: (1) N = {[qZr] | q, r ∈ Q, Z ∈ Γ} ∪ {S} (2) Jestliže δ(q, a, Z) obsahuje (r, X1 . . . Xk) k ≥ 1, pak k množině přepisovacích pravidel P přidej všechna pravidla tvaru [qZsk] → a[rX1s1][s1X2s2] . . . [sk−1Xksk] pro každou posloupnost s1, s2, . . . , sk stavů z množiny Q. (3) Jestliže δ(q, a, Z) obsahuje (r, ), pak k P přidej pravidlo [qZr] → a. (4) Pro každý stav q ∈ Q přidej k P pravidlo S → [q0Z0q]. Indukcí lze opět dokázat, že pro všechna q, r ∈ Q a Z ∈ Γ platí [qZr] ⇒m w, právě když (q, w, Z) n (r, , ). Speciální případ této ekvivalence je S ⇒ [q0Z0q] ⇒+ w, právě když (q0, w, Z0) + (q, , ), q ∈ F. To však znamená, že L (R) = L(G). 2 Příklad 4.24 Nechť P = ({q0, q1}, {0, 1}, {X, Z0}, δ, q0, Z0, ∅) kde zobrazení δ je dáno takto: δ(q0, 0, Z0) = {(q0, XZ0)} δ(q0, 0, X) = {(q0, XX)} δ(q0, 1, X) = {(q1, )} δ(q1, 1, X) = {(q1, )} δ(q1, , X) = {(q1, )} δ(q1, , Z0) = {(q1, )} Zkonstruujme gramatiku G = (N, Σ, P, S) takovou, že L(P) = L(G). Množiny nonterminálů a terminálů mají tvar: N = {S, [q0Xq0], [q0Xq1], [q1Xq0], [q1Xq1], [q0Z0q0], [q0Z0q1], [q1Z0q0], [q1Z0q1]} Σ = {0, 1} Množina N obsahuje některé nonterminály, které jsou v gramatice G nedostupné. Abychom je nemuseli dodatečně odstraňovat, začneme konstruovat pravidla gramatiky G počínaje S-pravidly a přidávejme pouze ty nonterminály, které se objevují na pravých stranách konstruovaných pravidel. Podle bodu (4) sestrojíme S-pravidla: S → [q0Z0q0] S → [q0Z0q1] KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY92 Nyní přidáme pravidla pro nonterminál [q0Z0q0] [q0Z0q0] → 0[q0Xq0][q0Z0q0] [q0Z0q0] → 0[q0Xq1][q1Z0q0] vyplývající z δ(q0, 0, Z0) = {(q0, XZ0)}. Pravidla pro nonterminál [q0Z0q1] [q0Z0q1] → 0[q0Xq0][q0Z0q1] [q0Z0q1] → 0[q0Xq1][q1Z0q1] jsou požadována zobrazením δ(q0, 0, Z0) = {(q0, XZ0)}. Pravidla pro zbývající nonterminály jsou: [q0Xq0] → 0[q0Xq0][q0Xq0] [q0Xq0] → 0[q0Xq1][q1Xq0] [q0Xq1] → 0[q0Xq0][q0Xq1] [q0Xq1] → 0[q0Xq1][q1Xq1] protože, δ(q0, 0, X) = {(q0, XX)}; [q0Xq1] → 1, protože δ(q0, 1, X) = {(q1, )} [q1Z0q1] → , protože δ(q1, , Z0) = {(q1, )} [q1Xq1] → , protože δ(q1, , X) = {(q1, )} [q1Xq1] → 1, protože δ(q1, 1, X) = {(q1, )}. Povšimněme si nyní, že pro nonterminály [q1Xq0] a [q1Z0q0] nejsou definována žádná pravidla, a proto ani z nonterminálu [q0Z0q0] ani z [q0Xq0] nemohou být derivovány terminální řetězce. Odstraníme-li tedy pravidla obsahující některý z uvedených čtyř nonterminálů, dostaneme ekvivalentní gramatiku generující jazyk L(P): S → [q0Z0q1] [q0Z0q1] → 0[q0Xq1][q1Z0q1] [q0Xq1] → 0[q0Xq1][q1Xq1] [q1Z0q1] → [q0Xq1] → 1 [q1Xq1] → [q1Xq1] → 1 4.12 Deterministický zásobníkový automat V předchozím odstavci jsme ukázali, že ke každé bezkontextové gramatice lze sestrojit zásobníkový automat, který reprezentuje syntaktický analyzátor pro věty generované danou gramatikou. Tento analyzátor je obecně nedeterministický. Z hlediska aplikací teorie formálních jazyků v překladačích jsou důležité tzv. deterministické bezkontextové jazyky, které lze analyzovat deterministickými syntaktickými analyzátory. V tomto odstavci definujeme třídu zásobníkových automatů, které v každém okamžiku mohou přijít pouze do jediné konfigurace, tzv. deterministické zásobníkové automaty, a jim odpovídající deterministické jazyky. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY93 Definice 4.22 Zásobníkový automat P = (Q, Σ, Γ, δ, q0, Z0, F) nazýváme deterministickým zásobníkovým automatem, jestliže pro každé q ∈ Q a Z ∈ Γ platí buď pro každé a ∈ Σ obsahuje δ(q, a, Z) nanejvýš jeden prvek a δ(q, , Z) = ∅, nebo δ(q, a, Z) = ∅ pro všechna a ∈ Σ a δ(q, , Z) obsahuje nejvýše jeden prvek. Protože zobrazení δ(q, a, Z) obsahuje nejvýše jeden prvek, budeme místo δ(q, a, Z) = {(r, γ)} psát δ(q, a, Z) = (r, γ). Příklad 4.25 Deterministický zásobníkový automat, který přijímá jazyk L = {wcwR | w ∈ {a, b}+ }, má tvar: P = ({q0, q1, q2}, {a, b, c}, {Z, a, b}, δ, q0, Z, {q2}) kde zobrazení δ je definováno takto: δ(q0, X, Y ) = (q0, XY ) pro všechna X ∈ {a, b} a Y ∈ {Z, a, b} δ(q0, c, Y ) = (q1, Y ) pro všechna Y ∈ {a, b} δ(q1, X, X) = (q1, ) pro všechna X ∈ {a, b} δ(q1, , Z) = (q2, ) Automat P pracuje tak, že dokud nepřečte středový symbol c, ukládá symboly vstupního řetězce do zásobníku. Potom přejde do stavu q1 a srovnává další vstupní symboly se symboly zásobníku. Mezi zásobníkovým automatem a deterministickým zásobníkovým automatem bohužel neplatí vztah jako mezi nedeterministickým a deterministickým konečným automatem, tzn., že ne každý jazyk přijímaný zásobníkovým automatem může být přijímán deterministickým zásobníkovým automatem. Definice 4.23 Jazyk L se nazývá deterministický bezkontextový jazyk, jestliže existuje deterministický zásobníkový automat P takový, že L(P) = L. Definici deterministického zásobníkového automatu můžeme rozšířit tak, aby zahrnovala rozšířené zásobníkové automaty. Definice 4.24 Rozšířený zásobníkový automat P = (Q, Σ, Γ, δ, q0, z0, F) nazýváme deterministický RZA (DRZA), jestliže platí: 1. ∀q ∈ Q ∀a ∈ Σ ∪ {ε} ∀γ ∈ Γ∗ : |δ(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, α) = ∅ a δ(q, ε, β) = ∅, pak ani α není předponou β, ani β není předponou α. Pozor na použití α = β v bodě 2 ve výše uvedené definici a nepoužití této podmínky v bodě 3: V bodě 2 dostáváme pro α = β tutéž trojici (q, a, α) = (q, a, β) a nedochází tedy k nedeterminismu na rozdíl od bodu 3, kde vznikají dvě různé dvojice (q, a, α) = (q, a, β) a (q, ε, α) = (q, ε, β). Věta 4.17 Deterministické rozšířené zásobníkové automaty mají ekvivalentní vyjadřovací sílu jako deterministické zásobníkové automaty. Věta 4.18 Deterministické zásobníkové automaty mají striktně menší vyjadřovací sílu než nedeterministické zásobníkové automaty. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY94 Důkaz: i (z důvodu zjednodušení je zde uvedena pouze idea důkazu) Bezkontextový jazyk L = {wwR | w ∈ Σ+ } nelze přijímat žádným DZA. Neformálně řečeno, DZA nemá možnost uhádnout, kdy končí w a začíná wR . 2 Poznámka 4.6 Jiná možnost důkazu věty 4.18 je přes následně uvedenou uzavřenost jazyků DZA vůči doplňku a přes uvážení, že {anbncn|n ≥ 1} je bezkontextový jazyk. Problém, zda daný bezkontextový jazyk je jazykem nějakého DZA, není obecně rozhodnutelný (podobně jako není rozhodnutelná víceznačnost). 4.13 Vlastnosti bezkontextových jazyků V této podkapitole se budeme zabývat některými vlastnostmi bezkontextových jazyků v podobné podobě jako v případě regulárních jazyků. 4.13.1 Strukturální vlastnosti Pumping lemma Věta 4.19 Nechť L je bezkontextový jazyk. Pak existuje konstanta k > 0 taková, že je-li z ∈ L a |z| ≥ k, pak lze z napsat ve tvaru: z = u v w x y, vx = ε, |vwx| ≤ k a pro všechna i ≥ 0 je uvi wxi y ∈ L. Důkaz: Nechť L = L(G) a nechť G = (N, Σ, P, S) je gramatika v CNF. 1. Nejprve dokážeme implikaci: Jestliže A ⇒+ w pro nějaké A ∈ N, w ∈ Σ∗ , pak |w| ≤ 2m−2 , kde m je počet vrcholů nejdelší cesty v odpovídajícím derivačním stromu. Tato implikace platí, protože |w| je rovno počtu přímých předchůdců listů příslušného derivačního stromu, který je maximálně roven počtu listů plného binárního stromu, jehož všechny větve obsahují m − 1 uzlů, což je právě 2m−2 . Skutečně: • Plný binární strom s větvemi o n uzlech, má 2n−1 listů, což se snadno ukáže indukcí: – Plný binární strom s (jedinou) větví o n = 1 uzlu, má 1 = 20 = 2n−1 listů. – Plný binární strom s větvemi délky n = n + 1 uzlů, kde n ≥ 1, má 2n −1 + 2n −1 = 2.2n −1 = 21+n −1 = 2n = 2n−1 listů. • Postačí tedy volit n = m−1, přičemž případ neplných binárních stromů není třeba uvažovat, neboť se zajímáme o stromy s maximálním počtem listů při dané maximální délce větví. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY95 2. Položme k = 2|N| > 0 a uvažujme libovolnou větu z takovou, že |z| ≥ k. Označíme-li m počet vrcholů nejdelší cesty v odpovídajícím derivačním stromu, pak 2|N| ≤ 2m−2 a taková cesta pak obsahuje alespoň |N| + 2 vrcholů (|N| + 2 ≤ m). Z těchto |N| + 2 vrcholů je jeden terminál a nutně alespoň dva jsou označeny stejným nonterminálem, řekněme A. Viz obrázek vpravo. S A A w x yu v Řetězce v, x nemohou být prázdné, protože aplikované pravidlo mělo tvar A → BC. Nyní uvažujme derivaci řetězce z tvaru: S ⇒∗ uAy ⇒+ uvAxy ⇒+ uvwxy = z To pak ovšem znamená, že v G existuje rovněž derivace: S ⇒∗ uAy ⇒+ uvAxy ⇒+ uvvAxxy ⇒+ uv2 wx2 y, protože A ⇒+ w, a tedy derivace S ⇒∗ uvi wxi y pro libovolné i > 0, což je dokazované tvrzení. 2 Lemma 4.2 Jazyk L = {an bn cn | n ≥ 1} není bezkontextovým jazykem. Důkaz: Důkaz provedeme aplikací pumping teorému: Nelze zvolit řetězce v a x tak, aby jejich iterací zůstával stejný počet symbolů a, b, c a současně pořadí symbolů a, b, c zůstalo nezměněno. 2 Poznámka 4.7 Jazyk L = {an bn cn | n ≥ 1} je typickým kontextovým jazykem. 4.13.2 Uzávěrové vlastnosti Substituce jazyků Definice 4.25 Nechť L je třída jazyků a nechť L ⊆ Σ∗ je jazykem třídy L. Dále nechť Σ = {a1, a2, ..., an} pro nějaké n ∈ N a nechť jazyky označené La1 , La2 , ..., Lan jsou rovněž jazyky třídy L. Říkáme, že třída L je uzavřena vzhledem k substituci, jestliže pro každý výběr jazyků L, La1 , La2 , ..., Lan je také jazyk σLa1 ,La2 ,...,Lan (L) σLa1 ,La2 ,...,Lan (L) = {x1x2...xm | b1b2...bm ∈ L ∧ ∀i ∈ {1, ..., m} : xi ∈ Lbi } ve třídě L. Příklad 4.26 Nechť L = {0n 1n | n ≥ 1}, L0 = {a}, L1 = {bm cm | m ≥ 1}. Substitucí jazyků L0 a L1 do L dostaneme jazyk L = {an bm1 cm1 bm2 cm2 ...bmn cmn | n ≥ 1 ∧ ∀i ∈ {1, ..., n} : mi ≥ 1} Morfismus jazyků Definice 4.26 Nechť Σ a ∆ jsou abecedy a L ⊆ Σ∗ je jazyk nad abecedou Σ. Zobrazení h : Σ∗ → ∆∗ nazveme morfismem nad slovy, platí-li ∀w = a1a2...an ∈ Σ∗ : h(w) = h(a1)h(a2)...h(an). Morfismus jazyka h(L) pak definujeme jako h(L) = {h(w) | w ∈ L}. Morfismus jazyků je zvláštní případ substituce, kde každý substituovaný jazyk má právě jednu větu. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY96 Uzavřenost vůči substituci Věta 4.20 Třída bezkontextových jazyků je uzavřena vůči substituci. Důkaz: 1. Ve shodě s definicí substituce nechť Σ = {a1, a2, ..., an} je abeceda bezkontextového jazyka L a La pro a ∈ Σ libovolné bezkontextové jazyky. Nechť G = (N, Σ, P, S) a Ga = (Na, Σa, Pa, Sa) pro a ∈ Σ jsou gramatiky, pro které L = L(G) a La = L(Ga) pro a ∈ Σ. 2. Předpokládejme, že N ∩ Na = ∅ a Na ∩ Nb = ∅ pro každé a, b ∈ Σ, a = b. Sestrojme gramatiku G = (N , Σ , P , S) takto: (a) N = N ∪ a∈Σ Na. (b) Σ = a∈Σ Σa. (c) Nechť h je morfismus na N ∪ Σ takový, že i. h(A) = A pro A ∈ N a ii. h(a) = Sa pro a ∈ Σ a nechť P = {A → h(α) | (A → α) ∈ P} ∪ a∈Σ Pa. 3. Uvažujme libovolnou větu ai1 ai2 ...aim ∈ L a věty xj ∈ Laj , 1 ≤ j ≤ m. Pak S ∗ ⇒ G Sai1 Sai2 ....Saim ∗ ⇒ G x1Sai2 ....Saim ∗ ⇒ G ... ∗ ⇒ G x1x2...xm a tedy L ⊆ L(G ). Podobně L(G ) ⊆ L . 2 Uzavřenost L2 vůči různým jazykovým operacím Věta 4.21 Bezkontextové jazyky jsou uzavřeny vzhledem k: 1. sjednocení, 2. konkatenaci, 3. iteraci, 4. pozitivní iteraci, 5. morfismu. Důkaz: Nechť La a Lb jsou bezkontextové jazyky. 1. Uzavřenost vůči ∪ plyne ze substituce La, Lb do jazyka {a, b}. 2. Uzavřenost vůči · plyne ze substituce La, Lb do jazyka {ab}. 3. Uzavřenost vůči ∗ plyne ze substituce La do jazyka {a}∗ . 4. Uzavřenost vůči + plyne ze substituce La do jazyka {a}+ . 5. Nechť h je daný morfismus a La = {h(a)} pro a ∈ Σ. Substitucí jazyků La do jazyka L získáme jazyk h(L). 2 Věta 4.22 Bezkontextové jazyky jsou uzavřeny vzhledem k průniku s regulárními jazyky. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY97 Důkaz: Snadno zkonstruujeme zásobníkový automat přijímající příslušný průnik – konstruujeme průnik na konečném řízení, zásobníkové operace zůstávají. 2 Definice 4.27 Je-li h : Σ∗ → ∆∗ morfismus, pak definujeme inverzní morfismus nad slovy z ∆∗ jako h−1 (w) = {x ∈ Σ∗ | h(x) = w} a inverzní morfismus jazyka L nad ∆ jako h−1 (L) = {x ∈ Σ∗ | h(x) ∈ L}. Věta 4.23 Bezkontextové jazyky jsou uzavřeny vzhledem k inverznímu mor- fismu. Důkaz: Mějme libovolný morfismus h : Σ∗ → ∆∗ . Zaveďme pomocnou abecedu Σ, jež ke každému a ∈ Σ obsahuje a takové, že a ∈ Σ. Uzavřenost L2 vůči inverznímu morfismu plyne z uzavřenosti vůči substituci, průniku s regulárním jazykem a morfismu: h−1 (L) = h1(σ(L) ∩ L∗ 1), kde: 1. σ je substituce taková, že ∀c ∈ ∆ : Lc = Σ ∗ cΣ ∗ , 2. L1 = {aw | a ∈ Σ ∧ w ∈ ∆∗ ∧ h(a) = w} je regulární jazyk a 3. h1 : (Σ ∪ ∆)∗ → Σ∗ je morfismus takový, že (1) ∀a ∈ Σ : h1(a) = a a (2) ∀c ∈ ∆ : h1(c) = ε. 2 Neuzavřenost L2 vůči průniku a doplňku Věta 4.24 Bezkontextové jazyky nejsou uzavřeny vůči průniku a doplňku. Důkaz: 1. Neuzavřenost vůči ∩: Uvažujme jazyky L1 = {am bm cn | n, m ≥ 1} a L2 = {am bn cn | m, n ≥ 1}, které jsou oba bezkontextové. Ovšem L1 ∩ L2 = {an bn cn | n ≥ 1}, což není bezkontextový jazyk (lze ukázat např. pomocí Pumping lemmatu). 2. Neuzavřenost vůči doplňku: Předpokládejme, že bezk. jazyky jsou uzavřeny vůči doplňku. Z De Morganových zákonů (a z uzavřenosti vůči sjednocení) pak ovšem plyne uzavřenost vůči průniku L1 ∩L2 = L1 ∩ L2 = L1 ∪ L2, což je spor. 2 4.13.3 Rozhodnutelné a nerozhodnutelné problémy pro bezkontextové jazyky Věta 4.25 Následující problémy jsou rozhodnutelné, tj. jsou algoritmicky řeši- telné: 1. problém neprázdnosti jazyka L(G) pro libovolnou bezkontextovou gramatiku G, 2. problém příslušnosti řetězce w ∈ Σ∗ do jazyka L(G) pro libovolnou bezkontextovou gramatiku G, KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY98 3. problém konečnosti jazyka L(G) pro libovolnou bezkontextovou gramatiku G. Důkaz: 1. K rozhodování neprázdnosti lze využít algoritmus iterativně určující množinu Nt nonterminálů generujících terminální řetězce uvedený v přednášce 4. Pak L(G) = ∅ ⇔ S ∈ Nt. 2. U problému příslušnosti řetězce můžeme např. určit průnik NZA s KA přijímajícím právě řetězec w a pak ověřit neprázdnost. 3. Problém konečnosti můžeme rozhodovat na základě platnosti Pumping lemma pro bezkontextové jazyky: (a) Dle Pumping lemma pro bezkontextové jazyky existuje pro každý bezkontextový jazyk L konstanta k ∈ N taková, že každou větu w ∈ L, |w| ≥ k, můžeme rozepsat jako uvwxy, kde vx = ε a |vwx| ≤ k, a ∀i ∈ N : uvi wxi y ∈ L. (b) Pro testování konečnosti tedy postačí ověřit, že žádný řetězec ze Σ∗ o délce mezi k a 2k − 1 nepatří do daného jazyka: Pokud takový řetězec existuje, může být ” napumpován“ a dostáváme nekonečně mnoho řetězců patřících do daného jazyka. Jestliže takový řetězec neexistuje, k − 1 je horní limit délky řetězců L. Pokud by existoval řetězec délky 2k nebo větší patřící do L, můžeme v něm podle Pumping lemma najít vwx a vypustit vx. Vzhledem k tomu, že 0 < |vx| ≤ k, postupným opakováním vypouštění bychom se dostali k nutné existenci řetězce z L o délce mezi k a 2k − 1. (c) K určení konstanty k postačí reprezentovat L pomocí bezkontextové gramatiky v CNF s n nonterminály a zvolit k = 2n (viz důkaz Pumping lemma). 2 Nerozhodnutelné problémy pro L2 Věta 4.26 Následující problémy jsou nerozhodnutelné, tj. nejsou algoritmicky řešitelné: 1. problém ekvivalence jazyků bezkontextových gramatik, tj. otázka, zda L(G1) = L(G2) pro dvě bezkontextové gramatiky G1, G2, 2. problém inkluze jazyků bezkontextových gramatik, tj. otázka, zda L(G1) ⊆ L(G2) pro dvě bezkontextové gramatiky G1, G2. Důkaz: Využívá redukci z nerozhodnutelného Postova korespondenčního problému – viz dále. Z nerozhodnutelnosti ekvivalence plyne nerozhodnutelnost inkluze (A = B ⇔ A ⊆ B ∧ B ⊆ A). 2 V následujících kapitolách zmíníme i některé další nerozhodnutelné problémy pro L2, mezi něž patří univerzalita (L(G) ? = Σ∗ ), regularita apod. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY99 4.13.4 Uzávěrové vlastnosti jazyků deterministických bezkontextových jazyků Věta 4.27 Deterministické bezkontextové jazyky jsou uzavřeny vůči průniku s regulárními jazyky a doplňku. Důkaz: (idea) Bod 1 dokážeme podobně jako v případě jazyků přijímaných nedeterministickými zásobníkovými automaty. U bodu 2 postupujeme podobně jako u deterministického konečného automatu – použijeme záměnu koncových a nekoncových stavů, musíme ale navíc řešit dva okruhy problémů: (a) DZA nemusí vždy dočíst vstupní slovo až do konce (buď se dostane do konfigurace, z níž nemůže pokračovat, nebo cyklí přes ε-kroky) a (b) DZA slovo dočte do konce, ale pak ještě provede posloupnost ε-kroků jdoucích přes koncové i nekoncové stavy. Popis řešení těchto problémů je možno nalézt v doporučené literatuře. 2 Věta 4.28 Deterministické bezkontextové jazyky nejsou uzavřeny vůči průniku a sjednocení. Důkaz: U bodu 1 použijeme stejný postup jako u NZA (uvědomíme si, že {am bm cn | n, m ≥ 1} a {am bn cn | n, m ≥ 1} lze přijímat DZA). Bod 2 plyne z De Morganových zákonů. 2 Věta 4.29 Deterministické bezkontextové jazyky nejsou uzavřeny vůči konkatenaci a iteraci. Důkaz: (idea) Vyjdeme z toho, že zatímco jazyky L1 = {am bm cn | m, n ≥ 1} a L2 = {am bn cn | m, n ≥ 1} jsou deterministické bezkontextové, jazyk L1 ∪ L2 ne. (Intuitivně DZA nemůže odhadnout, zda má kontrolovat první nebo druhou rovnost, a tedy, zda na zásobník ukládat symboly a nebo b.) 1. Neuzavřenost vůči konkatenaci. Jazyk L3 = 0L1 ∪ L2 je zřejmě deterministický bezkontextový. Jazyk 0∗ je také deterministický bezkontextový (dokonce regulární), ovšem není těžké nahlédnout, že 0∗ L3 není deterministický bezkontextový. Stačí uvážit, že 0a∗ b∗ c∗ je deterministický bezkontextový (dokonce regulární) jazyk a 0∗ L3 ∩ 0a∗ b∗ c∗ = 0L1 ∪ 0L2 = 0(L1 ∪ L2). 2. Neuzavřenost vůči iteraci. Uvážíme ({0} ∪ L3)∗ ∩ 0a+ b+ c+ = 0(L1 ∪ L2). 2 4.13.5 Některé další zajímavé vlastnosti bezkontextových jazyků Definice 4.28 Bezkontextová gramatika G = (N, Σ, P, S) má vlastnost sebevlo- regularita žení, jestliže existují A ∈ N a u, v ∈ Σ+ takové, že A ⇒+ uAv a A není zbytečný nonterminál. Bezkontextový jazyk má vlastnost sebevložení, jestliže každá gramatika, která jej generuje, má vlastnost sebevložení. Věta 4.30 Bezkontextový jazyk má vlastnost sebevložení právě tehdy, když není regulární. KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY100 Důkaz: Můžeme využít Greibachovu normální formu (definice 4.15). 2 Uvedená věta může být užitečná při dokazování, že určitá gramatika negeneruje regulární jazyk. Zopakujme ale, že problém, zda daná bezkontextová gramatika generuje regulární jazyk, není algoritmicky rozhodnutelný. Teorém Chomského a Schützenbergera. Tento teorém postihuje úzkou vazbu bezkontextových jazyků na závorkování. Definice 4.29 Označme ZAVn pro n ≥ 0 jazyky sestávající ze všech vyvážených řetězců závorek n typů. Tyto jazyky – označované též jako Dyckovy jazyky – jsou generovány gramatikami s pravidly tvaru: S → [1 S ]1 | [2 S ]2 | · · · | [n S ]n | SS | ε Věta 4.31 (Chomsky-Schützenberger) Každý bezkontextový jazyk je morfismem průniku nějakého jazyka závorek a nějaké regulární množiny. Jinými slovy, pro každý L ∈ L2 existují n ≥ 0, regulární množina R a morfismus h takový, že L = h(ZAVn ∩ R) Důkaz: Viz doporučená literatura. 2 Parikhův teorém. Tento teorém opět postihuje strukturu bezkontextových jazyků – zabývá se tím, co dostaneme, pokud ve větách odhlédneme od pořadí jednotlivých symbolů a zkoumáme pouze počet jejich opakování (tj. zahrneme vlastně libovolné přeházení znaků v řetězci). Definice 4.30 Mějme abecedu Σ = {a1, ..., ak}. Parikhova funkce je funkce ψ : Σ∗ → Nk definovaná pro w ∈ Σ∗ jako ψ(w) = (#a1(w), ..., #ak(w)), kde #ai(w) udává počet výskytů symbolu ai ve w. Definice 4.31 Podmnožinu množiny vektorů Nk nazveme lineární množinou, jeli dána bází u0 ∈ Nk a periodami u1, ..., um ∈ Nk jako {u0 + a1u1 + ... + amum | a1, ..., am ∈ N}. Podmnožinu Nk nazveme semilineární množinou, je-li sjednocením konečného počtu lineárních množin. Věta 4.32 (Parikh) Pro libovolný bezkontextový jazyk L, ψ(L) je semilineární množina. Důkaz: Viz doporučená literatura. 2 Ke každé semilineární množině S můžeme najít regulární množinu R ⊆ Σ∗ takovou, že ψ(R) = S. Proto bývá Parikhův teorém někdy formulován takto: Komutativní obraz každého bezkontextového jazyka odpovídá nějakému regulárnímu jazyku. Semilineární množiny se navíc dají reprezentovat konečnými automaty přímo jako množiny číselných vektorů v binárním kódování (tzv. NDDs – number decision diagrams). KAPITOLA 4. BEZKONTEXTOVÉ JAZYKY A ZÁSOBNÍKOVÉ AUTOMATY101 Ekvivalentním specifikačním prostředkem pro libovolný bezkontextový jazyk je nedeterministický zásobníkový automat. Existují ekvivalentní varianty těchto automatů, které se, mimo jiné, využívají jako modely různých typů syntaktických analyzátorů. Třída jazyků přijímaných deterministickými zásobníkovými automaty (tzv deterministické bezkontextové jazyky) je vlastní podtřídou třídy bezkontextových jazyků. K uzávěrovým vlastnostem bezkontextových jazyků nepatří průnik a doplněk, není rovněž rozhodnutelný problém ekvivalence dvou bezkontextových gramatik. K rozhodnutí nepříslušnosti formálního jazyka do třídy bezkontextových jazyků se používá pumpping lema, která rovněž charakterizuje základní atribut vět nekonečného bezkontextového jazyka. 4.14 Cvičení Cvičení 4.14.1 Sestrojte zásobníkový automat, který přijímá jazyk L = {an bm | n ≤ m ≤ 2n} Cvičení 4.14.2 Pro gramatiky (a) S → aSb | (b) S → AS | b A → SA | a (c) S → SS | A A → 0A1 | S | 01 sestrojte zásobníkové automaty modelující syntaktickou analýzu shora–dolů a zdola–nahoru. Cvičení 4.14.3 Nalezněte gramatiku, která generuje jazyk L(P), kde P = ({q0, q1, q2}, {a, b}, {Z0, A}, δ, q0, Z0, {q2}); zobrazení δ má tvar: δ(q0, a, Z0) = (q1, AZ0) δ(q0, a, A) = (q1, AA) δ(q1, a, A) = (q0, AA) δ(q1, , A) = (q2, A) δ(q2, b, A) = (q2, ) Kapitola 5 Turingovy stroje 15:00 Cílem kapitoly je formální vymezení Turingova stroje, stanovení pravidel a konvencí pro kompozitní vytváření Turingových strojů, pochopení mechanismu definice jazyka přijímaného a rozhodovaného Turingovým strojem a dokázání ekvivalence třídy jazyků typu 0 s třídou jazyků přijímaných Turingovými stroji. Cílem této kapitoly je také analýza vlastností příslušných jazyků a důležitá modifikace Turingova stroje specifikující kontextové jazyky. 5.1 Základní koncepce Turingových strojů 5.1.1 Churchova teze Churchova (Church-Turingova) teze: Turingovy stroje (a jim ekvivalentní systémy) definují svou výpočetní silou to, co intuitivně považujeme za efektivně vyčíslitelné. Churchova teze není teorém, nemůžeme formálně dokazovat, že něco odpovídá našim intuitivním představám, nicméně je podpořena řadou argumentů: • Turingovy stroje jsou velmi robustní – uvidíme, že jejich různé úpravy nemění jejich výpočetní sílu (determinismus x nedeterminismus, počet pásek, ...). • Byla navržena řada zcela odlišných výpočetních modelů (λ-kalkul, parciálně rekurzívní funkce, Minského stroje, ...), jejichž síla odpovídá Turingovým strojům. • Není znám žádný výpočetní proces, který bychom označili za efektivně vyčíslitelný a který by nebylo možné realizovat na Turingově stroji.1 5.1.2 Turingův stroj Turingův stroj se skládá z konečně stavové řídící jednotky, jednosměrně neohraničené pásky a čtecí/zapisovací hlavy. V jednom kroku výpočtu Turingův stroj nejprve přečte symbol pod hlavou. Následně v závislosti na čteném symbolu a stavu řídící jednotky může čtený symbol přepsat, změnit stav a posunout hlavu o jedno pole doprava nebo doleva. To vše podle konečné série pravidel – přechodové relace, která je součástí řídící jednotky. Výpočet je pak navazující sérií výpočetních kroků vycházející z počáteční konfigurace stroje, t.j. stavu řídící jednotky, obsahu pásky a pozice hlavy. 1Existují formalizované výpočetní procesy realizovatelné např. na TS s orákulem (nápovědou), rozhodujícím atomicky nějaký Turingovsky nerozhodnutelný problém (např. problém zastavení), které ale nepovažujeme za efektivní výpočetní procesy. 102 KAPITOLA 5. TURINGOVY STROJE 103 páska: čtecí/zápisová hlava q0 q1 . . .. . . . stavové řízení x y z ∆ Definice 5.1.1 Turingův stroj (TS) je šestice tvaru M = (Q, Σ, Γ, δ, q0, qF ), kde: • Q je konečná množina vnitřních (řídicích) stavů, • Σ je konečná množina symbolů nazývaná vstupní abeceda, ∆ ∈ Σ, • Γ je konečná množina symbolů, Σ ⊂ Γ, ∆ ∈ Γ, nazývaná pásková abeceda, • parciální funkce δ : (Q \ {qF }) × Γ → Q × (Γ ∪ {L, R}), kde L, R ∈ Γ, je přechodová funkce, • q0 je počáteční stav, q0 ∈ Q a • qF je koncový stav, qF ∈ Q. 5.1.3 Konfigurace Turingova stroje Symbol ∆ značí tzv. blank (prázdný symbol), který se vyskytuje na místech pásky, která nebyla ještě použita (může ale být na pásku zapsán i později). Konfigurace pásky je dvojice sestávající z nekonečného řetězce reprezentujícího obsah pásky a pozice hlavy na tomto řetězci – přesněji jde o prvek množiny {γ∆ω | γ ∈ Γ∗ }×N.2 Konfiguraci pásky zapisujeme jako ∆xyzz∆x∆∆... (podtržení značí pozici hlavy). Konfigurace stroje je pak dána stavem řízení a konfigurací pásky – formálně se jedná o prvek množiny Q × {γ∆ω | γ ∈ Γ∗ } × N. 5.1.4 Přechodová relace TS Pro libovolný řetězec γ ∈ Γω a číslo n ∈ N označme γn n-tý symbol daného řetězce a označme sn b (γ) řetězec, který vznikne z γ záměnou γn za b. Krok výpočtu TS M definujeme jako nejmenší binární relaci M takovou, že ∀q1, q2 ∈ Q ∀γ ∈ Γω ∀n ∈ N ∀b ∈ Γ: • (q1, γ, n) M (q2, γ, n + 1) pro δ(q1, γn) = (q2, R) – operace posuvu doprava při γn pod hlavou, • (q1, γ, n) M (q2, γ, n − 1) pro δ(q1, γn) = (q2, L) a n > 0 – operace posuvu doleva při γn pod hlavou a • (q1, γ, n) M (q2, sn b (γ), n) pro δ(q1, γn) = (q2, b) – operace zápisu b při γn pod hlavou. 2Pro libovolnou abecedu Σ je Σω množina všech nekonečných řetězců nad Σ, tj. nekonečných posloupností symbolů ze Σ. Pro připomenutí: Σ∗ je množina všech konečných řetězců nad Σ. KAPITOLA 5. TURINGOVY STROJE 104 5.1.5 Výpočet TS Výpočet TS M začínající z konfigurace K0 je posloupnost konfigurací K0, K1, K2, ..., ve které Ki M Ki+1 pro všechna i ≥ 0 taková, že Ki+1 je v dané posloupnosti, a která je buď • nekonečná, a nebo • konečná s koncovou konfigurací (q, γ, n), přičemž rozlišujeme následující typy zastavení TS: 1. normální – přechodem do koncového stavu, tj. q = qF , a 2. abnormální : (a) pro (q, γn) není δ definována, nebo (b) hlava je na nejlevější pozici pásky a dojde k posunu doleva, tj. δ(q, γn) = (q , L) pro nějaké q ∈ Q. 5.1.6 Poznámka – alternativní definice TS Používají se i některé alternativní definice TS, u kterých se dá snadno ukázat vzájemná převoditelnost: • namísto jediného qF je povolena množina koncových stavů, • namísto qF je zavedena dvojice qaccept a qreject, • na prvním políčku pásky je ” napevno“ zapsán symbol konce pásky, z něhož není možný posun doleva, • při zavedení obou předchozích bodů je δ obvykle definovaná jako totální funkce, • přepis a posuv hlavy jsou spojeny do jedné operace • apod. 5.1.7 Grafická reprezentace TS Grafická reprezentace přechodu (x – co se čte, s – zápis/L/R): p q x/s Grafická reprezentace počátečního a koncového stavu: p qF Příklad 5.1.1 TS, který posouvá hlavu doprava na první ∆ počínaje aktuální pozicí (např. ∆aab∆... −→ ∆aab∆...): p q∆/∆ a/R b/R KAPITOLA 5. TURINGOVY STROJE 105 5.1.8 Modulární konstrukce TS Podobně jako program je možné vytvořit kompozicí jednodušších podprogramů, procedur a funkcí, tak i Turingův stroj lze konstruovat modulárně spojováním (kombinací) jednodušších TS ve složitější celky. Příklad 5.1.2 Uvažme tři následující komponenty: • M1 přesune hlavu o jeden symbol doprava: s ∆/R x/R y/R tM1: (R) • M2 nalezne první výskyt symbolu x vpravo (od aktuální pozice hlavy): l ∆/R x/R y/R m nx/x y/R ∆/R M2: (Rx) • M3 nalezne první výskyt symbolu y vpravo: p ∆/R x/R y/R q r y/y x/R ∆/R M3: (Ry) Následující kombinací M1, M2 a M3 vznikne TS M, který nalezne druhý výskyt (neblankového) symbolu od počáteční pozice. V pravé části obrázku je M zapsán v podobě tzv. kompozitního diagramu – konstrukce takových diagramů je podrobněji diskutována níže. l m n x/x y/R ∆/R p q r y/y x/R ∆/R s ∆/R x/R y/R t x/R y/R x/x ∆/∆ y/y x/x y/y ∆/∆ M: M1 x y M2 M3 ∆/∆ 5.1.9 Kompozitní diagram TS Při konstrukci TS pomocí kompozitních diagramů předpokládáme, že všechny komponenty mají stejnou vstupní abecedu Σ i páskovou abecedu Γ. První konstrukcí, kterou při kompozitní konstrukci používáme, je bezpodmínečné předání řízení z koncového stavu jedné komponenty do počátečního stavu druhé komponenty. Graficky značíme tuto konstrukci jednoduchou šipkou mezi příslušnými komponentami. Například pro TS A a B konstrukce A B znamená KAPITOLA 5. TURINGOVY STROJE 106 předání řízení z koncového stavu qA F stroje A do počátečního stavu qB 0 stroje B. Formálně to znamená, že ve výsledném TS, který zahrnuje všechny stavy a přechody obou komponent, stav qA F ztrácí status koncového stavu, qB 0 ztrácí status počátečního stavu a jsou doplněny přechody tak, že ∀x ∈ Γ. δ(qA F , x) = (qB 0 , x). S ohledem na determinismus přitom platí, že z jedné komponenty může být řízení bezpodmínečně předáno nanejvýše jedné komponentě. Sekvenci strojů A B C často zkracujeme na ABC. Povolujeme přitom, aby příchozí šipky označující předání řízení směřovaly ke kterémukoliv ze strojů v dané sekvenci. Řízení se pak předává tomu stroji v dané sekvenci, ke kterému šipka směřuje (bude-li příchozí šipka směřovat u našeho příkladu k A, předává se řízení sekvenci ABC; bude-li ovšem příchozí šipka směřovat k B, předává se řízení sekvenci BC). Na druhou stranu šipka znázorňující odchozí předání řízení musí být spojena s poslední komponentou v sekvenci (tj. v našem případě s C). Další konstrukcí často používanou při kompozitní konstrukci TS je podmíněné předání řízení, umožňující na úrovni kompozitního diagramu dosáhnout větvení výpočtu, jak jsme viděli již v příkladu na konci předchozí podsekce. Graficky je podmíněné předání řízení značeno šipkou mezi komponentami podobně jako u nepodmíněného předání řízení – příslušná šipka je ovšem spojena se seznamem čárkou oddělených symbolů z páskové abecedy Γ. Řízení se pak předává v případě, že se pod čtecí hlavou vyskytuje některý z těchto symbolů. Kombinovat podmíněné a nepodmíněné předání řízení není u deterministických TS možné. Jedna komponenta může ale mít více odchozích podmíněných předání řízení, ovšem pouze tehdy, jsou-li množiny symbolů vyskytujících se v seznamech s nimi spojených disjunktní. Množiny symbolů, které se vyskytují na odchozích šipkách podmíněného předání řízení přitom nemusí pokrývat celou abecedu Γ. Vyskytne-li se pak pod čtecí hlavou symbol, pro který není předání řízení explicitně stanoveno, výsledný TS automaticky přejde do koncového stavu, tj. přijme (!). Formálněji můžeme výše uvedenou konstrukci popsat takto. Předpokládejme, že z komponenty A máme m ≥ 1 odchozích šipek předávajících podmíněně řízení strojům B1, ..., Bm s množinami stavů Q1, ..., Qm, které jsou disjunktní navzájem a disjunktní s množinou stavů stroje A. Každý z těchto přechodů je označen seznamem symbolů xi 1, ..., xi ni ∈ Γ, ni ≥ 1, 1 ≤ i ≤ m. Výsledný TS zahrne všechny stavy a přechody původních strojů a navíc nový koncový stav qF . Počáteční a koncové stavy qi 0 a qi F strojů Bi , 1 ≤ i ≤ m, a koncový stav qA F stroje A ztrácejí svůj původní status. Navíc jsou přidány následující přechody: • Pro všechna 1 ≤ i ≤ m, 1 ≤ j ≤ ni, y ∈ Γ ∪ {L, R}, q ∈ Qi, je-li v Bi přechod qi 0 xi j /y −→ q, pak dodáme v kompozici přechod qA F xi j /y −→ q. • Pro každé x ∈ Γ \ {x1 1, ..., x1 n1 , ..., xm 1 , ..., xm nm } dodáme přechod qA F x/x −→ qF . • Pro všechna 1 ≤ i ≤ m a x ∈ Γ dodáme přechod qi F x/x −→ qF . Při podmíněném předání řízení je možné užít také větve pokrývající všechny ostatní symboly, jež nejsou pokryty běžným podmíněným předáním řízení. K tomu účelu použijeme šipku která obsahuje seznam všech symbolů, přes které se podmíněně předává řízení z dané komponenty, uvozený symbolem negace ¬. Jednoduchý příklad této konstrukce je uveden níže: KAPITOLA 5. TURINGOVY STROJE 107 x M1 x M2 M3 Pokud bychom chtěli dodat takové předání řízení ke kompozici strojů A, B1, ..., Bm uvažované výše, byla by příslušná šipka označena ¬x1 1, ..., x1 n1 , ..., xm 1 , ..., xm nm . Předání řízení přes takovou šipku je ekvilentní předání řízení přes šipku označenou seznamem obsahujícím symboly Γ \ {x1 1, ..., x1 n1 , ..., xm 1 , ..., xm nm }. Pro zjednodušení konstrukce strojů, ve kterých se stejným způsobem zpracovává několik různých symbolů, se používá tzv. parametrová konvence. Jedná se o podmíněné předání řízení zapsané jako x1, ..., xn ω , kde x1, ..., xn ∈ Γ, n ≥ 2, ω ∈ Γ ∪ {L, R}. Při předání řízení tímto způsobem nabývá ω hodnoty toho symbolu z množiny x1, ..., xn, který je aktuálně pod čtecí hlavou. Parametrová konvence je vlastně jakousi analogií použití maker, jak ilustruje níže uvedený příklad. Příklad 5.1.3 Turingův stroj x,y ω M1 M2 ω je ekvivalentní Turingovu stroji: xM1 M2 M2 x y y 5.1.10 Základní stavební bloky TS Uvažujme Γ = {x, y, ∆}, mezi základní stavební bloky TS obvykle patří následující stroje (lze je snadno upravit pro libovolnou jinou Γ): 1. Stroje L, R, x: ∆/L x/L y/L L: doleva ∆/R x/R y/R R: doprava ∆/x x/x y/x x: na aktuální pozici zapiš x Příklad 5.1.4 Stroj R y L neboli RyL transformuje pásku ∆xyxyx∆∆... na ∆xyxyxy∆... 2. Stroje Lx, Rx, L¬x a R¬x: L y ∆ Lx: R y ∆ Rx: L x L x: R x R x: KAPITOLA 5. TURINGOVY STROJE 108 3. Stroje SR a SL pro posuv (shift) obsahu pásky: Stroj SR posune řetězec neblankových symbolů nacházejících se vlevo od aktuální pozice hlavy o jeden symbol doprava. Stroj SL funguje podobně. x,y ω ∆L L ∆ R ∆ R∆R∆ω x,y σ RσLSR: Příklad 5.1.5 Činnost strojů SR a SL si můžeme přiblížit na následujících příkladech: • ∆xyyxx∆∆... SR −→ ∆∆xyyx∆∆... • ∆yxy∆∆xxy∆... SR −→ ∆∆yxy∆xxy∆... • xy∆yx∆∆... SR −→ xy∆∆x∆∆... • ∆yyxx∆∆... SL −→ ∆yxx∆∆∆... 5.1.11 Příklady TS Příklad 5.1.6 Kopírovací stroj – transformuje ∆w∆ na ∆w∆w∆: x,y ω R∆R∆L∆L∆ R ∆R∆R∆ωR∆L∆L∆ω Příklad 5.1.7 Generování řetězců: • Následující stroj generuje postupně všechny řetězce nad {x, y, z} v uspořádání ε, x, y, z, xx, yx, zx, xy, yy, zy, xz, yz, zz, xxx, yxx, .... • Předpokládáme, že stroj začíná s konfigurací pásky ∆w∆..., kde w je řetězec uvedené posloupnosti, od kterého generování započne. x L∆R y x z ∆ y z x Příklad 5.1.8 Stroj dekrementující kladné číslo zapsané ve dvojkové soustavě: 1 0L∆R SL ∆R∆ L 1 0 0 0L 0 1 1 KAPITOLA 5. TURINGOVY STROJE 109 5.2 Turingovy stroje jako akceptory jazyků 5.2.1 Jazyk přijímaný TS Turingův stroj normálně (přechodem do stavu qF ) zastaví jen pro některá slova množiny Σ∗ zapsaná na pásce v počáteční konfiguraci. Každý stroj tedy jednoznačně vymezuje množinu slov ze Σ∗ , se kterými na pásce v počáteční konfiguraci normálně zastaví – jde o jazyk přijímaný Turingovým strojem. Výpočetní problémy je možno nahlížet jako jazyky. Třída jazyků, pro které existuje Turingův stroj, který je přijímá, vlastně reprezentuje třídu všech vypočítatelných problémů. Definice 5.2.1 1. Řetězec w ∈ Σ∗ je přijat TS M = (Q, Σ, Γ, δ, q0, qF ), jestliže M při aktivaci z počáteční konfigurace pásky ∆w∆... a počátečního stavu q0 zastaví přechodem do koncového stavu qF , tj. (q0, ∆w∆ω , 0) ∗ M (qF , γ, n) pro nějaké γ ∈ Γ∗ a n ∈ N. 2. Množinu L(M) = {w | w je přijat TS M} ⊆ Σ∗ nazýváme jazyk přijímaný TS M. Příklad 5.2.1 Pro níže uvedený TS M platí L(M) = {xn yn zn | n ≥ 0}: x SL# R y SL z SL R x x y R y y z ∆ L z R y,z # ∆,z ∆,z ∆,x ∆,x x,y L# Stroj pracuje takto: xn yn zn → xn−1 yn zn → xn−1 yn−1 zn → ...ε. Stroj akceptující stejný jazyk, jehož přechodová relace je definována tabulkou: M = (Q, Σ, Γ, δ, q0, qF ) Q = {q0, q1, q2, q3, qF } Σ = {x, y, z} Γ = {x, y, z, ×, ∆} δ ∆ x y z × q0 q1, R q1 qF q2, × q1, R q2 g3, × q2, R q3 q4, × q3, R q4 q1, R q1, L q1, L q1, L q1, L Stroj si postupně škrtá (symbolem ×) po jednom od každého ze symbolů x, y, z. Ve stavu q1 hledá x, poté ve stavu q2 y, a následně ve stavu q3 z. Ve stavu q4 se vrací na začátek slova, kde začne vyškrtával další trojici. Akceptuje, jen pokud je slovo prázdné nebo pokud se mu podařilo jej po trojicích symbolů celé proškrtat. KAPITOLA 5. TURINGOVY STROJE 110 5.3 Modifikace TS Prozkoumáme několik způsobů rozšíření možností Turingova stroje. Protože je ale původní TS velmi robustní, ani zdánlivě obecnější modifikace nás nedovedou k mechanismům s větší výpočetní silou – třída jazyků akceptovaných následujícími modifikovanými Turingovými stroji zůstane stejná. 5.3.1 Přijímání zvláštních konfigurací pásky Někdy může být vhodné, aby Turingův Stroj oznámil korektní ukončení výpočtu jinak, a to např. zapsáním informace o výsledku výpočtu na pásku. Můžeme přijetí řetězce TS definovat tak, že TS začíná s konfigurací pásky ∆w∆... a zastaví s konfigurací pásky ∆Y ∆..., Y ∈ Γ \ Σ, (Y značí Yes). Věta 5.3.1 Máme-li TS M, který přijímá L(M) přechodem do qF , můžeme vždy sestrojit stroj M , který bude přijímat L(M) zastavením s konfigurací pásky ∆Y ∆.... Důkaz. (Idea) R∆SRR*L∆L#R M’ ∆L ∆RYL # # R*M’’: • M začíná s páskou #∆w ∗ ∆.... • M sestrojíme doplněním M s množinou stavů Q o přechody, které řeší nájezd na ∗ a #: 1. ∀q ∈ Q : δ(q, #) = (q, L) – ” zajištění přepadnutí“ (abnormálního ukončení), ke kterému by původně došlo. 2. Při čtení symbolu ∗ je třeba (potenciálně) zvětšit pracovní prostor – aktivujeme podstroj ∆R ∗ L. 2 Snadno lze přejít i opačně od přijímání konfigurací pásky ∆Y ∆... k přijímání přes qF . Poznámka 5.3.1 • Uvědomme si, že na TS lze také nahlížet jako na výpočetní mechanismy implementující funkce Σ∗ → Γ∗ tím, že transformují počáteční neblankový prefix své pásky na jiný neblankový prefix při přechodu do koncového stavu. • Vzhledem k tomu, že TS nemusí každý svůj vstup přijmout, jsou funkce jimi implementované obecně parciální. • Blíže se budeme vyčíslováním funkcí TS zabývat dále. KAPITOLA 5. TURINGOVY STROJE 111 5.3.2 Vícepáskové Turingovy stroje Přímočarou cestou k zesílení Turingova stroje je zapojení ne jedné, ale několika pásek. Vícepáskový TS disponuje k jednosměrně nekonečnými páskami, z nichž každá je vybavena vlastní čtecí/zapisovací hlavou a je připojena ke společné konečně stavové jednotce. V jednom kroku stroj nejdříve na každé pásce zvlášť přečte symbol, posune hlavu nebo přepíše symbol a poté v závislosti na čtených symbolech změní stav řídící jednotky. Formálněji – uvažujme TS, který má k pásek s páskovými abecedami Γ1, Γ2, ..., Γk a k odpovídajících hlav s přechodovou funkcí tvaru δ : (Q \ {qF }) × Γ1 × Γ2 × ... × Γk −→ Q × i∈{1,...,k} {i} × (Γi ∪ {L, R}), kde i značí pásku, na kterou se zapisuje (na které se posouvá hlava). Příklad 5.3.1 Sestrojíme dvoupáskový stroj, který bude akceptovat již známý jazyk xn yn zn . Výhoda druhé pásky se zde projeví efektivitou stroje. Budeme předpokládat, že v počáteční konfiguraci mají pásky tvary: – první páska: ∆w∆∆ . . . – druhá páska: ∆∆ . . .. Stroj bude vypadat takto: M = {Q, Σ, Γ1, Γ2, δ, q0, qF } kde: Q = {q0, q1, q2, q3, qF } Σ = {x, y, z} Γ1 = {x, y, z, ∆} Γ2 = {X, Y ∆} δ ∆, ∆ x, ∆ x, X y, ∆ y, X y, Y z, ∆ z, Y q0 q1, R, R q1 qF q1, x, X q1, R, R q2, y, L q2 q2, y, Y q2, R, L q3, z, R q3 qF q3, R, R Stroj slovo na první (vstupní) pásce přečte jen jednou zleva doprava. Přitom na druhé pásce kontroluje jeho tvar takto: Nejdříve zápisem symbolu X na druhou pásku zaznamenává na vstupu přečtená x. Poté za každé y přečtené na vstupu přepíše jeden symbol X na druhé pásce symbolem Y (skončí na začátku druhé pásky). Nakonec za každé přečtené z na vstupu posune hlavu druhé pásky doprava. Slovo akceptuje, pokud hlavu druhé pásky takto posune přesně za všechna Y . Vícepáskové stroje lze rovněž popisovat pomocí komponentních diagramů. Při podmíněném předání řízení pak používáme u příslušných symbolů horní indexy k označení toho, ze které pásky jsou čteny. Je možné i podmíněné předání řízení na základě určitých kombinací symbolů čtených z různých pásek. Chceme-li např. uskutečnit podmíněné předání řízení, je-li pod čtecí hlavou na první pásce symbol x a na druhé pásce symbol y, použijeme zápis x1 ∧ y2 , nebo jednoduše x1 y2 . Šipka označená x1 y2 , u1 v2 pak znamená předání řízení, je-li pod čtecí hlavou na první pásce symbol x a na druhé pásce symbol y, nebo je-li pod čtecí hlavou na první pásce symbol u a na druhé pásce symbol v. Chceme-li při konstrukci vícepáskových strojů užít základní stavební komponenty navržené původně pro jednopáskové stroje (např. stroje R, L apod.), pak označení těchto strojů spojíme s horním indexem určujícím, se kterou páskou má příslušný stroj pracovat. KAPITOLA 5. TURINGOVY STROJE 112 Příklad 5.3.2 TS akceptující stejný jazyk jako v přechozím příkladě, zapsaný diagramem: R1R2 X2R1R2 x1 L1 y1 L2 y1, z1 z1, ∆1 R1L2 y1x2 R1R2 x1 R2 z1∆2 x1, y1, z1∆2, ∆1x2 x1, ∆1, y1∆2, z1x2 z1x2 Příklad 5.3.3 Navrhněte vícepáskový TS pro převod binárního zápisu čísla na unární. Věta 5.3.2 Pro každý k-páskový TS M existuje jednopáskový TS M takový, že L(M) = L(M ). Důkaz. (idea) x y x x x y y y y y x x x y x x x y y y y y x x ∆ ∆ 1 ∆ ∆ ∆ ∆ 1 1 ∆ ∆ ∆ Nový páskový symbol Důkaz provedeme tak, že ukážeme algoritmus převodu na ekvivalentní jednopáskový TS: • Předpokládáme, že přijímaný řetězec je u k-páskového stroje na počátku zapsán na první pásce, všechny ostatní pásky jsou prázdné a všechny hlavy jsou na nejlevější pozici. • Původních k pásek simulujeme rozšířením páskové abecedy o 2k-tice, v nichž vždy i-tá složka pro liché i reprezentuje obsah (i+1 2 )-ní pásky a na pozici i + 1 je ∆ nebo 1 podle toho, zda se na ní nachází příslušná hlava či nikoliv. • Počet načítaných kombinací symbolů v původním automatu je konečný a tudíž si výše uvedené rozšíření můžeme skutečně dovolit. • Při simulaci k-páskového TS pak nejprve převedeme původní obsah první pásky na ekvivalentní obsah zakódovaný v 2k-ticích a pak každý krok simulujeme několika kroky. KAPITOLA 5. TURINGOVY STROJE 113 • Při simulaci využíváme stavy ve formě (k + 1)-tic, kde první složka je stav původního TS a ostatní složky jsou aktuálně čtené symboly. • Při rozhodování o dalším kroku pak bereme na zřetel především tento stav, aktuální načítaný symbol není důležitý a vždy se při čtení přemístíme na speciální pozici nalevo od užitečného obsahu pásky. • Po rozhodnutí o dalším kroku ” najedeme“ doprava na pozici, na které je simulovaná hlava pásky, která se má modifikovat, provedeme příslušnou změnu a vrátíme se zpět doleva. • Za nový aktuální stav považujeme (k + 1)-tici danou novým stavem simulovaného TS a k-ticí převzatou z původního stavu nového TS modifikovanou na místě modifikované pásky. • Navíc je nutné korektně simulovat ” přepadnutí“ hlavy na kterékoliv pásce a převod dosud nevyužitých míst pásky s ∆ na odpovídající 2k-tici blank symbolů. • Při řádné formalizaci popsaného algoritmu pak není těžké ukázat, že výsledný TS skutečně simuluje původní TS. 2 Závěr: Zvětšení paměťových možností TS nerozšiřuje jejich schopnosti přijímat jazyky! Příklad 5.3.4 Využijte možností vícepáskového stroje k návrhu TS akceptujícího jazyk xn yn zn . 5.3.3 Nedeterministické Turingovy stroje Definovaný deterministický Turingův stroj se o příštím kroku rozhodoval vždy jednoznačně na základě čteného symbolu a stavu. Nedeterministický TS si naproti tomu v dané konfiguraci vybírá z konečného počtu možností. Pro jednu vstupní konfiguraci tedy existuje více možných výpočtů a slovo je nedeterministický strojem akceptováno, právě když alespoň jeden z možných výpočtů na něm je akceptující.3 Definice 5.3.1 Nedeterministický TS je šestice M = (Q, Σ, Γ, δ, q0, qF ), kde význam jednotlivých složek je shodný s deterministickým TS až na δ, jež má tvar: δ : (Q \ {qF }) × Γ −→ 2Q×(Γ∪{L,R}) Definice 5.3.2 Jazyk L(M) NTS M = (Q, Σ, Γ, δ, q0, qF ) je množina řetězců w ∈ Σ∗ takových, že M při aktivaci z q0 při počátečním obsahu pásky ∆w∆... může zastavit přechodem do qF . 3Jakoby stroj ” hádal“, který z možných kroků (jestli nějaký) vede do koncového stavu. KAPITOLA 5. TURINGOVY STROJE 114 Příklad 5.3.5 Sestrojíme dvoupáskový nedeterministický stroj, který bude akceptovat jazyk L = {wwR | kde w ∈ {x, y}∗ }. Nedeterminismus zde využijeme k ” uhádnutí“ poloviny vstupního slova. To znamená, že stroj nejprve čte slovo na první pásce a přečtené symboly zapisuje na druhou pásku. V určitém okamžiku stroj nedeterministicky přejde do stavu, kdy začne porovnávat obsah druhé pásky s dosud nepřečteným vstupem na první pásce (na druhé pásce se pohybuje zprava doleva). Budeme předpokládat, že v počáteční konfiguraci mají pásky tvary: – první páska: ∆w∆∆ . . . – druhá páska: ∆∆ . . . Jelikož stroj je nedeterministický, jeho přechodová funkce δ vrací množinu stavů. To znamená, že v jednotlivých poličkách tabulky pro přechodovou funkci může být víc než jedna položka. Stroj bude vypadat takto: M = {Q, Σ, Γ1, Γ2, δ, q0, qF } kde: Q = {q0, q1, q2, qF } Σ = {x, y} Γ1 = {x, y, ∆} Γ2 = {x, y, ∆} δ ∆, ∆ x, ∆ x, x y, ∆ y, y x, y y, x ∆, x ∆, y q0 q1, R, R q1 q0, R, R q1, x, x q1, R, R q2, R, x q1, y, y q1, R, R q2, R, y q2 qF q0, x, ∆ q2, R, L q0, y, ∆ q2, R, L q0, x, y q0, y, x q0, ∆, x q0, ∆, y Pro popis NTS je opět možno užít kompozitních diagramů. Jejich použití je podobné jako v případě DTS, odpadají zde ale některá omezení vyskytující se u DTS. U NTS je možné podmíněné předání řízení přes stejný symbol více strojům, šipky doplňkového podmíněného předání řízení (s využitím symbolu ¬) nemusí být označeny seznamem symbolů vytvářejícím přesný doplněk množiny symbolů vyskytujících se v ostatních podmíněných předáních řízení a je možná i kombinace podmíněného a nepodmíněného předání řízení. Je-li kombinováno podmíněné a nepodmíněné předání řízení, nedoplňují se implicitní přechody do nového koncového stavu přes symboly nepokryté podmíněným předáním řízení. Příklad 5.3.6 Navrhněte vícepáskový nedeterministický TS akceptující jazyk {ap | kde p není prvočíslo}. Věta 5.3.3 Pro každý NTS M existuje DTS M takový, že L(M) = L(M ). Důkaz. (idea) • NTS M budeme simulovat třípáskovým DTS. Význam jednotlivých pásek tohoto stroje je následující: – Páska 1 obsahuje přijímaný vstupní řetězec. – Páska 2 je pracovní páska. Obsahuje kopii pásky 1 ohraničenou vhodnými speciálními značkami. Po neúspěšném pokusu o přijetí je její obsah smazán a obnoven z první pásky. KAPITOLA 5. TURINGOVY STROJE 115 – Páska 3 obsahuje kódovanou volbu posloupností přechodů; při neúspěchu bude její obsah nahrazen jinou posloupností. • Zvolená posloupnost přechodů je kódována posloupností čísel přiřazených přechodům simulovaného stoje. • Jednotlivé posloupnosti přechodů na pásce 3 je možno generovat modifikovaným TS pro generování posloupnosti řetězců ε, x, y, z, xx, .... • Vlastní simulace probíhá takto: 1. Okopíruj obsah pásky 1 na pásku 2. 2. Generuj příští posloupnost přechodů na pásce 3. 3. Simuluj provedení posloupnosti z pásky 3 na obsahu pásky 2. 4. Vede-li zkoumaná posloupnost do qF simulovaného stroje, zastav – vstupní řetězec je přijat. V opačném případě smaž pásku 2 a vrať se k bodu 1. • Není obtížné nahlédnout, že jazyk přijímaný takto vytvořeným strojem odpovídá jazyku přijímaným původním NTS. 2 Závěr: Zavedením nedeterminismu do TS se nezvyšují jejich schopnosti přijímat jazyky! 5.4 Jazyky rekurzivně vyčíslitelné a jazyky re- kurzivní Zavedeme klasifikaci jazyků (problémů) vzhledem k jejich akceptovatelnosti Turingovými stroji (řešitelnosti). Dojdeme k základním třem třídám jazyků, které reprezentují problémy řešitelné, problémy řešitelné jen částečně a problémy algoritmicky neřešitelné. 5.4.1 Rekurzivní vyčíslitelnost a rekurzivnost Turingův stroj se nazývá úplný (total), právě když pro každý vstup zastaví. Definice 5.4.1 Jazyk L ⊆ Σ∗ se nazývá • rekurzívně vyčíslitelný, jestliže L = L(M) pro nějaký TS M, • rekurzívní, jestliže L = L(M) pro nějaký úplný TS M. Je-li M úplný Turingův stroj, pak říkáme, že M rozhoduje jazyk L(M). Ke každému rekurzívnímu jazyku existuje TS, který ho rozhoduje, tj. zastaví pro každé vstupní slovo – tento TS lze samozřejmě upravit tak, aby pro každý řetězec z daného jazyka zastavil s páskou ∆Y ∆∆..., a jinak zastavil s páskou ∆N∆∆.... TS přijímající rekurzívně vyčíslitelný jazyk L zastaví pro každé w ∈ L, ovšem pro w ∈ L může zastavit, ale také může donekonečna cyklit. KAPITOLA 5. TURINGOVY STROJE 116 5.4.2 Rozhodovací problémy Rozhodovací problém (decision problem) P může být chápán jako funkce fP s oborem hodnot {true, false}4 . Rozhodovací problém je obvykle specifikován: • definičním oborem AP reprezentujícím množinu možných instancí problému (možných vstupů) a • podmnožinou BP ⊆ AP , BP = {p | fP (p) = true} instancí, pro které je hodnota fP rovna true. V teorii formálních jazyků používáme ke kódování jednotlivých instancí problémů řetězce nad vhodnou abecedou Σ. Pak je rozhodovací problém P přirozeně specifikován jazykem Lp = {w ∈ Σ∗ | w = code(p), p ∈ BP }, kde code : AP → Σ∗ je injektivní funkce, která přiřazuje instancím problému příslušný řetězec (nezávisle na fP ). Příklad 5.4.1 Příklady rozhodovacích problémů: • P1 – orientovaný graf je silně souvislý. • P2 – dvě bezkontextové gramatiky jsou ekvivalentní. • P3 – n je prvočíslo. Poznámka: Dále budeme o rozhodovacích problémech hovořit jednoduše jako o problémech. 5.4.3 Rozhodování problémů TS Definice 5.4.2 Nechť P je problém specifikovaný jazykem LP nad Σ. Problém P nazveme: • rozhodnutelný, pokud LP je rekurzívní jazyk, tj. existuje TS, který LP rozhoduje (přijme každý řetězec w ∈ LP a zamítne každý řetězec w ∈ Σ∗ \ LP ), • nerozhodnutelný, když není rozhodnutelný, a • částečně rozhodnutelný, jestliže LP je rekurzívně vyčíslitelný jazyk, tj. existuje TS, který přijme každý řetězec w ∈ LP a každý řetězec w ∈ Σ∗ \ LP zamítne, nebo je jeho výpočet na něm nekonečný. Poznámka: Z definice 8.2 plyne, že každý rozhodnutelný problém je současně částečně rozhodnutelný. Některé nerozhodnutelné problémy nejsou ale ani částečně rozhodnutelné. 5.5 TS a jazyky typu 0 Odvodíme důležitou korespondenci mezi gramatikami typu 0 a Turingovými stroji. Jazyky generované gramatikami typu 0 jsou totiž právě jazyky akceptované Turingovými stroji (rekurzivně vyčíslitelné). Ukážeme, jak pro každý TS sestrojit gramatiku typu 0, která generuje jazyk jím akceptovaný, a naopak jak pro každou gramatiku typu 0 strojit TS akceptující jazyk jí generovaný. 4Otázka s možnou odpovědí ano/ne. KAPITOLA 5. TURINGOVY STROJE 117 5.5.1 Jazyky přijímané TS jsou typu 0 Konfigurace TS je dána (1) stavem řízení, (2) obsahem pásky a (3) pozicí hlavy. Pro zápis konfigurace TS v řídícím stavu q a s konfigurací pásky ∆xyz∆... zavedeme konvenci [∆xqyz∆...]. Příklad 5.5.1 TS přijímající jazyk {xm yn | m ≥ 0, n > 0} konfigurací pásky ∆Y ∆ při počáteční konfiguraci pásky ∆w∆: q0 qF ∆/R x/R p q r t u y/R y/R ∆/L s x/∆ ∆/Ly/∆ ∆/R ∆/Y Y/L Posloupnost konfigurací při příjetí xxy: 1. [q0∆xxy∆...] 2. [∆pxxy∆...] 3. [∆xpxy∆...] 4. [∆xxpy∆...] 5. [∆xxyq∆...] 6. [∆xxry∆...] 7. [∆xxs∆∆...] 8. [∆xrx∆∆...] 9. [∆xs∆∆∆...] 10. [∆rx∆∆∆...] 11. [∆s∆∆∆∆...] 12. [r∆∆∆∆∆...] 13. [∆t∆∆∆∆...] 14. [∆uY ∆∆∆...] 15. [qF ∆Y ∆∆∆...] Věta 5.5.1 Každý jazyk přijímaný TS (tj. každý rekurzívně vyčíslitelný jazyk) je jazykem typu 0. Důkaz. Nechť L = L(M) pro nějaký TS M = (Q, Σ, Γ, δ, q0, qF ). Sestrojíme gramatiku G = (N, Σ, P, S) typu 0 takovou, že L(G) = L(M). Gramatika G bude umožňovat vytvářet právě derivace odpovídající inverzi posloupnosti konfigurací TS M při přijetí libovolného řetězce w ∈ L(M): 1. N = {S} ∪ Q ∪ (Γ \ Σ) ∪ {[, ]} (předpokládáme, že všechny zde sjednocené množiny jsou po dvou disjunktní). 2. P je nejmenší množina obsahující následující pravidla: (a) S → [qf ∆Y ∆], (b) ∆] → ∆∆] – doplnění ∆, (c) qy → px, jestliže δ(p, x) = (q, y), (d) xq → px, jestliže δ(p, x) = (q, R), (e) qyx → ypx pro každé y ∈ Γ, jestliže δ(p, x) = (q, L), (f) [q0∆ → ε, ∆∆] → ∆], ∆] → ε – zajištění [q0∆w∆...∆] + ⇒ G w. Snadno se nyní nahlédne, že w ∈ L(M) právě tehdy, když existuje derivace S ⇒G [qF ∆Y ∆] ⇒G ... ⇒G [q0∆w∆...] ⇒G ... ⇒G w, a že L(G) = L(M). 2 KAPITOLA 5. TURINGOVY STROJE 118 5.5.2 Jazyky typu 0 jsou přijímány TS Věta 5.5.2 Každý jazyk typu 0 je přijímán nějakým TS (tj. je rekurzívně vyčís- litelný). Důkaz. Nechť L = L(G) pro G = (N, Σ, P, S) je jazykem typu 0. Sestrojíme nedeterministický dvoupáskový TS M takový, že L(G) = L(M): • 1. páska obsahuje přijímaný vstupní řetězec w. • Na 2. pásce se M pokouší pomocí simulace použití přepisovacích pravidel (α → β) ∈ P vytvořit derivaci w: w S ⊥ ⊥ w ⊥ ⊥ α w β w ⊥ ⊥ wα ⊥ ⊥ α 1. Stroj nejprve umístí na 2. pásku symbol S. 2. Stroj opakovaně simuluje na 2. pásce provádění pravidel (α → β) ∈ P. Nedeterministicky zvolí pravidlo a také výskyt α na pásce. Při přepisu α na β, |α| = |β|, může využít posuv části užitečného obsahu pásky vlevo či vpravo. 3. Stroj srovná finální obsah 2. pásky s 1. páskou. Shodují-li se, zastaví přechodem do qF . Jinak posouvá hlavu doleva až do abnormálního zastavení. Snadno se nyní nahlédne, že skutečně L(G) = L(M). Navíc lze M, podobně jako u vícepáskových DTS, převést na jednopáskový NTS a ten dále na jednopáskový DTS. 2 5.5.3 Jazyky typu 0 = jazyky přijímané TS Věta 5.5.3 Třída jazyků přijímaných TS (neboli jazyků rekurzívně vyčíslitelných) je shodná se třídou jazyků typu 0. Důkaz. Důsledek dvou předchozích vět. 2 5.6 Vlastnosti jazyků rekurzívních a rekurzívně vyčíslitelných ” Příjemnou“ vlastností rekurzivních a rekurzivně spočetných jazyků je jejich uzavřenost vůči operacím průniku, sjednocení a zřetězení. Třída rekurzívních jazyků je navíc uzavřena i vůči doplňku. KAPITOLA 5. TURINGOVY STROJE 119 5.6.1 Uzavřenost vůči ∪, ∩, . a ∗ Věta 5.6.1 Třídy rekurzívních a rekurzívně vyčíslitelných jazyků jsou uzavřeny vůči operacím ∪, ∩, . a ∗. Důkaz. Nechť L1, L2 jsou jazyky přijímané TS M1, M2. Zřejmě můžeme předpokládat, že množiny stavů TS M1, M2 jsou disjunktní. • NTS ML1∪L2 , L(ML1∪L2 ) = L1 ∪ L2, sestrojíme tak, že sjednotíme po složkách stroje M1 a M2, zavedeme nový počáteční stav, z něj nedeterministické přechody přes ∆/∆ do obou původních počátečních stavů a sloučíme původní koncové stavy do jediného nového koncového stavu. w∆ ∆∆... M1 M2 v • Třípáskový TS ML1∩L2 , L(ML1∩L2 ) = L1 ∩ L2, okopíruje vstup z první pásky na druhou, na ní simuluje stroj M1, pokud ten přijme, okopíruje vstup z první pásky na třetí, na ní simuluje stroj M2, pokud i ten přijme, přijme i stroj ML1∩L2 . w∆ ∆∆... w∆ ∆∆... M1 w∆ ∆∆... M2 v • Třípáskový NTS ML1.L2 , L(ML1.L2 ) = L1.L2, okopíruje nedeterministicky zvolený prefix vstupu z první pásky na druhou, na ní simuluje stroj M1, pokud ten přijme, okopíruje zbytek vstupu z první pásky na třetí, na ní simuluje stroj M2, pokud i ten přijme, přijme vstup i stroj ML1.L2 . w ∆ ∆∆... w’∆ ∆∆... M1 w’’∆ ∆∆... M2 vw’ w’’ • Dvoupáskový NTS ML∗ 1 , L(ML∗ 1 ) = L∗ 1, je zobecněním předchozího stroje: po částech kopíruje vstup z první pásky na druhou a na ní simuluje opakovaně stroj M1. Obsah druhé pásky má ohraničený speciálními značkami a po každé simulaci stroje M1 ho smaže. Umožňuje samozřejmě posuv pravé značky dále doprava při nedostatku místa. KAPITOLA 5. TURINGOVY STROJE 120 Jsou-li stroje M1 a M2 úplné, je možné vybudovat stroje podle výše uvedených pravidel také jako úplné (u ML1∪L2 , ML1∩L2 , ML1.L2 je to okamžité, u ML∗ 1 nepřipustíme načítání prázdného podřetězce vstupu z 1. na 2. pásku – pouze umožníme jednorázově přijmout prázdný vstup). To dokazuje uzavřenost vůči uvedeným operacím také u rekurzívních jazyků. 2 5.6.2 (Ne)uzavřenost vůči komplementu Věta 5.6.2 Třída rekurzívních jazyků je uzavřena vůči komplementu. Důkaz. TS M přijímající rekurzívní jazyk L vždy zastaví. Snadno upravíme M na M , který při nepřijetí řetězce vždy přejde do unikátního stavu qreject. TS M, L(M) = L, snadno dostaneme z M záměnou qF a qreject. 2 Třída rekurzívně vyčíslitelných jazyků není uzavřena vůči komplementu! • Výše uvedené konstrukce nelze užít – cyklení zůstane zachováno. • Důkaz neuzavřenosti bude uveden v dalších přednáškách. Věta 5.6.3 Jsou-li jazyky L i L rekurzívně vyčíslitelné, pak jsou oba rekurzívní. Důkaz. Mějme M, L(M) = L, a M, L(M) = L. Úplný TS přijímající L sestrojíme takto: • Použijeme dvě pásky. Na jedné budeme simulovat M, na druhé M. Simulace se bude provádět proloženě krok po kroku: krok M, krok M, krok M, ... • Přijmeme, právě když by přijal M, zamítneme abnormálním zastavením, právě když by přijal M. Jedna z těchto situací určitě nastane v konečném počtu kroků. w∆ ∆∆... M w∆ ∆∆... M YES NO Existence úplného TS pro L plyne z uzavřenosti rekurzívních jazyků vůči komplementu. 2 Důsledkem výše uvedených vět je mj. to, že pro L a L musí vždy nastat jedna z následujících situací: • L i L jsou rekurzívní, • L ani L nejsou rekurzívně vyčíslitelné, • jeden z těchto jazyků je rekurzívně vyčíslitelný, ale ne rekurzívní, druhý není rekurzívně vyčíslitelný. KAPITOLA 5. TURINGOVY STROJE 121 5.7 Lineárně omezené automaty Poslední třídou Chomského hierarchie, ke které jsme zatím nepoznali protějšek ve formě výpočetního stroje5 , jsou gramatiky typu 1 – kontextové gramatiky. Nyní se seznámíme s mírně omezenou formou Turingových strojů, která tuto mezeru vyplňuje. 5.7.1 Lineárně omezené automaty Lineárně omezený automat (LOA) je nedeterministický TS, který nikdy neopustí tu část pásky, na níž je zapsán jeho vstup. Formálně můžeme LOA definovat jako NTS, jehož pásková abeceda obsahuje speciální symbol, kterým unikátně označujeme pravý konec vstupu na pásce, přičemž tento symbol není možné přepsat, ani z něj provést posun doprava. Deterministický LOA můžeme přirozeně definovat jako (deterministický) TS, který nikdy neopustí část pásky se zapsaným vstupem. Není známo, zda deterministický LOA je či není striktně slabší než LOA. 5.7.2 LOA a kontextové jazyky Věta 5.7.1 Třída jazyků, kterou lze generovat kontextovými gramatikami, odpovídá třídě jazyků, které lze přijímat LOA. Důkaz. • Uvážíme definici bezkontextových gramatik jako gramatik s pravidly v podobě α → β, kde |α| ≤ |β|, nebo S → ε. • LOA −→ G1: – Použijeme podobnou konstrukci jako u TS −→ G0. – Na počátku vygenerujeme příslušný pracovní prostor, který se pak již nebude měnit: odpadá nekontextové pravidlo ∆∆] → ∆]. – Užití nekontextových pravidel [q0∆ → ε a ∆] → ε obejdeme (1) zavedením zvláštních koncových neterminálů integrujících původní informaci a příznak, že se jedná o první/poslední symbol, a (2) integrací symbolu reprezentujícího řídící stav a pozici hlavy s následujícím páskovým symbolem. • G1 −→ LOA: – Použijeme podobnou konstrukci jako u G0 −→ TS s tím, že nepovolíme, aby rozsah druhé pásky někdy překročil rozsah první pásky. 2 5Regulárním gramatikám odpovídají konečné automaty, bezkontextovým gramatikám zásobníkové automaty a gramatikám typu 0 Turingovy stroje. KAPITOLA 5. TURINGOVY STROJE 122 5.7.3 Kontextové a rekurzívní jazyky Věta 5.7.2 Každý kontextový jazyk je rekurzívní. Důkaz. • Počet konfigurací, které se mohou objevit při přijímání w příslušným LOA M je vzhledem k nemožnosti zvětšovat pracovní prostor pásky konečný: lze shora ohraničit funkcí cn pro vhodnou konstantu c – exponenciála plyne z nutnosti uvažovat výskyt všech možných symbolů na všech místech pásky. • Pro zápis libovolného čísla z intervalu 0, ..., cn − 1 nikdy nebude třeba více než n symbolů, užijeme-li c-ární soustavu. • Můžeme zkonstruovat úplný LOA ekvivalentní s M, který bude mít každý symbol na pásce strukturovaný jako dvojici: – S využitím 1. složek těchto dvojic simulujeme M. – V 2. složkách počítáme počet kroků; dojde-li k přetečení, odmítneme vstup. 2 Věta 5.7.3 Ne každý rekurzívní jazyk je kontextový. Důkaz. (Idea) Lze užít techniku diagonalizace prezentovanou dále. 2 5.7.4 Vlastnosti kontextových jazyků Věta 5.7.4 Třída kontextových jazyků je uzavřena vůči operacím ∪, ∩, ., ∗ a komplementu. Důkaz. • Uzavřenost vůči ∪, ∩, . a ∗ lze ukázat stejně jako u rekurzívně spočetných jazyků. • Důkaz uzavřenosti vůči komplementu je značně komplikovaný (všimněme si, že LOA je nedeterministický a nelze tudíž užít konstrukce použité u rekurzívních jazyků) – zájemci naleznou důkaz v doporučené literatuře. 2 Poznamenejme, že již víme, že u kontextových jazyků • lze rozhodovat členství věty do jazyka (rekurzivnost) a • nelze rozhodovat inkluzi jazyků (neplatí ani pro bezkontextové jazyky). KAPITOLA 5. TURINGOVY STROJE 123 Dále lze ukázat, že pro kontextové jazyky nelze rozhodovat prázdnost jazyka (užije se redukce z Postova problému přiřazení – viz další kapitoly). Turingův stroj je ekvivalentním specifikačním prostředkem pro libovolný jazyk typu 0 a v souladu s Churchovou tezí nejmocnějším formálním prostředkem (spolu s řadou dalších) pro specifikaci formálních jazyků. Představuje robustní matematický nástroj popisu jazyků a algoritmů, jehož modelovací síla není ovlivněna ani nedeterminismem či determinismem stroje, ani jeho paměťovými prostředky (více páskami). Významná podtřída Turingových strojů, lineárně omezené automaty, vymezují třídu kontextových jazyků. 5.8 Cvičení Příklad 5.8.1 1. Vysvětlete význam Churchovy teze. 2. Definujte pojmy Turingův stroj a jazyků přijímaných Turingovými stroji. 3. Definujte pojmy vícepáskový a nedeterministický Turingův stroj a rozhodněte, zda tato rozšíření zvyšují schopnost přijímat jazyky. 4. Vysvětlete rozdíl mezi úplnými a neúplnými Turingovy stroji a uveďte třídy jazyků, které jsou schopny přijímat. 5. Jaký je vztah mezi třídou jazyků přijímanou Turingovými stroji a jazyky typu 0. 6. Rozhodněte, pro které jazykové operace jsou uzavřeny třídy rekurzivních a rekurzivně vyčíslitelných jazyků. 7. Definujte lineárně omezené automaty a rozhodněte, jaký je vztah mezi třídou jazyků přijímaných lineárně omezenými automaty a třídou jazyků typu 1. Kapitola 6 Meze rozhodnutelnosti 15:00 Podle Churchovy teze třídu algoritmicky řešitelných – vyčíslitelných problémů vymezují Turingovy stroje. Zavedli jsme pomocí nich základní rozdělení problémů na rozhodnutelné, částečně rozhodnutelné a nerozhodnutelné. Nyní budeme chtít blíže prozkoumat vlastnosti jednotlivých tříd a problémů v nich ležících a najít odpověď na otázky jako: – Existují jazyky (problémy), jež nejsou rekurzivně vyčíslitelné (částečně roz- hodnutelné)? – Které jazyky (problémy) nejsou rekurzívní (rozhodnutelné)? – Jak poznat, ve které ze tříd leží konkrétní jazyk (problém)? Bude také zaveden prostředek specifikace jazyků (algoritmů) ekvivalentní Turingovým strojům – parciálně rekurzívní funkce. 6.1 Jazyky mimo třídu 0 Jazyky mimo třídu 0 (algoritmicky neřešitelné problémy) nejen existují, ale dokonce se dá říci, že částečná rozhodnutelnost (algoritmická řešitelnost) je mezi jazyky (problémy) výjimkou. 6.1.1 Existence jazyků mimo třídu 0 Věta 6.1.1 Pro každou abecedu Σ existuje jazyk nad Σ, který není typu 0. Důkaz. 1. Libovolný jazyk typu 0 nad Σ může být přijat TS s Γ = Σ ∪ {∆}: Pokud M používá více symbolů, můžeme je zakódovat jako jisté posloupnosti symbolů ze Σ ∪ {∆} a sestrojit TS M , který simuluje M. 2. Nyní můžeme snadno systematicky vypisovat všechny TS s Γ = Σ ∪ {∆}. Začneme stroji se dvěma stavy, pak se třemi stavy, atd. Závěr: Množina všech takových strojů a tedy i jazyků typu 0 je spočetná. 3. Množina Σ∗ ale obsahuje nekonečně mnoho řetězců a proto je množina 2Σ∗ , zahrnující všechny jazyky, nespočetná – důkaz viz následující lemma. 4. Z rozdílnosti mohutností spočetných a nespočetných množin plyne platnost uvedené věty. 2 Lemma 6.1.1 Pro neprázdnou a konečnou množinu Σ je množina 2Σ∗ nespo- četná. 124 KAPITOLA 6. MEZE ROZHODNUTELNOSTI 125 Důkaz. Důkaz provedeme tzv. diagonalizací (poprvé použitou Cantorem při důkazu rozdílné mohutnosti N a R). • Předpokládejme, že 2Σ∗ je spočetná. Pak dle definice spočetnosti existuje bijekce f : N ←→ 2Σ∗ . • Uspořádejme Σ∗ do nějaké posloupnosti w1, w2, w3, ..., např. ε, x, y, xx, xy, yx, yy, xxx, ... pro Σ = {x, y}. Nyní můžeme f zobrazit nekonečnou maticí : w0 w1 w2 ... wi ... L0 = f(0) a00 a01 a02 ... a0i ... L1 = f(1) a10 a11 a12 ... a1i ... L2 = f(2) a20 a21 a22 ... a2i ... ... , kde aij = 0, jestližewj ∈ Li, 1, jestližewj ∈ Li. • Uvažujme jazyk L = {wi | aii = 0}. L se liší od každého jazyka Li = f(i), i ∈ N: – je-li aii = 0, pak wi patří do jazyka, – je-li aii = 1, pak wi nepatří do jazyka. • Současně ale L ∈ 2Σ∗ , f tudíž není surjektivní, což je spor. 2 6.2 Problém zastavení Problém, zda výpočet daného TS zastaví, je prvním problémem, jehož nerekurzívnost ukážeme. Za tím účelem zavedeme (s pomocí vhodného kódování TS) univerzální Turingův stroj, což je TS schopný simulovat výpočet kteréhokoli jiného stroje z jakékoliv počáteční konfigurace (stroj a konfigurace jsou vstupem univerzálního stroje). Ten bude dále důležitý nejen v důkazu nerozhodnutelnosti problému zastavení. 6.2.1 Kódování TS Kódovací systém pro TS zahrnuje (1) kódování stavů (tak, aby byly odlišeny všechny stavy včetně q0 a qF ), (2) symbolů z Γ a (3) přechodové funkce δ. Kódování stavů: Množinu stavů Q uspořádáme do posloupnosti q0, qF , q, p, ..., t. Stav qj zakódujeme jako 0j , přičemž indexujeme (např.) od nuly. Kódování symbolů a příkazů L/R: Předpokládejme, že Γ = Σ ∪ {∆}. Uspořádáme Σ do posloupnosti a1, a2, ..., an a zvolíme tyto kódy: ∆ → ε, L → 0, R → 00, ai → 0i+2 . Přechod δ(p, x) = (q, y), kde y ∈ Γ∪{L, R}, reprezentujeme čtveřicí (p, x, q, y) a kódujeme zřetězením kódů p, x, q, y při použití 1 jako oddělovače, tj. jako p 1 x 1 q 1 y , kde _ značí kód _. Celý TS kódujeme jako posloupnost kódů přechodů oddělených a ohraničených 1. Příklad 6.2.1 q0 ∆/x x/R qF kód: 1110100010100011001 KAPITOLA 6. MEZE ROZHODNUTELNOSTI 126 6.2.2 Univerzální TS Zavádí koncept ” programovatelného“ stroje, který umožňuje ve vstupním řetězci specifikovat konkrétní TS (tj. program) i data, nad nimiž má tento stroj pracovat. TS, který má být simulován, budeme kódovat, jak bylo uvedeno výše, vstupní řetězec budeme kódovat jako posloupnost příslušných kódů symbolů oddělených a ohraničených 1. Kód stroje a vstupního řetězce oddělíme např. #. Příklad 6.2.2 TS z předchozí strany mající na vstupu xxx: 1110100010100011001#1000100010001 Univerzální TS, který zpracuje toto zadání, můžeme navrhnout jako třípáskový stroj, který • má na 1. pásce zadání (a později výstup), • 2. pásku používá k simulaci pracovní pásky původního stroje a • na 3. pásce má zaznamenán aktuální stav simulovaného stroje a aktuální pozici hlavy (pozice hlavy i je kódována jako 0i ). Univerzální stroj pracuje takto: 1. Stroj zkontroluje, zda vstup odpovídá zadání. Pokud ne, abnormálně za- staví. 2. Přepíše w na 2. pásku, na 3. pásku umístí kód q0 a za něj poznačí, že hlava se nachází na levém okraji pásky. 3. Na 2. pásce vyhledá aktuální symbol pod hlavou simulovaného stroje a na 1. pásce vyhledá přechod proveditelný ze stavu zapsaného na začátku 3. pásky pro tento vstupní symbol. Pokud žádný přechod možný není, stroj abnormálně zastaví. 4. Stroj provede na 2. a 3. pásce změny odpovídající simulovanému přechodu (přepis aktuálního symbolu, změna pozice hlavy, změna řídícího stavu). 5. Pokud nebyl dosažen stav qF simulovaného stroje, přejdeme na bod 3. Jinak stroj vymaže 1. pásku, umístí na ní obsah 2. pásky a zastaví normálně (přechodem do koncového stavu). Víme, že výše uvedený stroj můžeme převést na jednopáskový univerzální TS, který budeme v dalším značit jako TU . 6.2.3 Problém zastavení TS Věta 6.2.1 Problém zastavení TS (Halting Problem), kdy nás zajímá, zda daný TS M pro daný vstupní řetězec w zastaví, není rozhodnutelný, ale je částečně rozhodnutelný. Důkaz. • Problému zastavení odpovídá rozhodování jazyka HP = { M # w | M zastaví při w}, kde M je kód TS M a w je kód w. KAPITOLA 6. MEZE ROZHODNUTELNOSTI 127 • Částečnou rozhodnutelnost ukážeme snadno použitím modifikovaného TU , který zastaví přijetím vstupu M # w právě tehdy, když M zastaví při w – modifikace spočívá v převedení abnormálního zastavení při simulaci na zastavení přechodem do qF . • Nerozhodnutelnost ukážeme pomocí diagonalizace: 1. Pro x ∈ {0, 1}∗ , nechť Mx je TS s kódem x, je-li x legální kód TS. Jinak ztotožníme Mx s pevně zvoleným TS, např. s TS, který pro libovolný vstup okamžitě zastaví. 2. Můžeme nyní sestavit posloupnost Mε, M0, M1, M00, M01, M10, M11, M000, ... zahrnující všechny TS nad Σ = {0, 1} indexované řetězci z {0, 1}∗ . 3. Uvažme nekonečnou matici ε 0 1 00 01 10 ... Mε HMε,ε HMε,0 HMε,1 HMε,00 HMε,01 ... M0 HM0,ε HM0,0 HM0,1 HM0,00 HM0,01 ... M1 HM1,ε HM1,0 HM1,1 HM1,00 HM1,01 ... M00 HM00,ε HM00,0 HM00,1 HM00,00 HM00,01 ... M01 HM01,ε HM01,0 HM01,1 HM01,00 HM01,01 ... ... kde HMx,y = C, jestližeMx cyklí na y, Z, jestližeMx zastaví na y. 4. Předpokládejme, že existuje úplný TS K přijímající jazyk HP. Pak K pro vstup M # w • zastaví normálně (přijme) právě tehdy, když M zastaví na w, • zastaví abnormálně (odmítne) právě tehdy, když M cyklí na w. 5. Sestavíme TS N, který pro vstup x ∈ {0, 1}∗ : • Sestaví Mx z x a zapíše Mx #x na svou pásku. • Simuluje K na Mx #x, přijme, pokud K odmítne, a přejde do nekonečného cyklu, pokud K přijme. Všimněme si, že N v podstatě komplementuje diagonálu uvedené matice: ε 0 1 00 01 10 ... Mε HMε,ε HMε,0 HMε,1 HMε,00 HMε,01 ... M0 HM0,ε HM0,0 HM0,1 HM0,00 HM0,01 ... M1 HM1,ε HM1,0 HM1,1 HM1,00 HM1,01 ... M00 HM00,ε HM00,0 HM00,1 HM00,00 HM00,01 ... M01 HM01,ε HM01,0 HM01,1 HM01,00 HM01,01 ... ... 6. Dostáváme, že N zastaví na x ⇔ K odmítne Mx # x (definice N) ⇔ Mx cyklí na x (předpoklad o K). 7. To ale znamená, že N se liší od každého Mx alespoň na jednom řetězci – konkrétně na x. To je ovšem spor s tím, že posloupnost Mε, M0, M1, M00, M01, M10, M11, M000, ... zahrnuje všechny TS nad Σ = {0, 1}. Tento spor plyne z předpokladu, že existuje TS K, který pro daný TS M a daný vstup x určí (rozhodne), zda M zastaví na x, či nikoliv. KAPITOLA 6. MEZE ROZHODNUTELNOSTI 128 2 Ukázali jsme, že jazyk HP je rekurzívně vyčíslitelný ale není rekurzívní, a tedy že problém zastavení TS je jen částečně rozhodnutelný. Z věty 5.6.3 pak plyne, že komplement problému zastavení není ani částečně rozhodnutelný a jazyk co-HP = { M # w | M nezastaví při w} je příkladem jazyka, jenž není ani rekurzívně vyčíslitelný. S dalším příkladem takového jazyka se seznámíme v následujcích kapitolách. 6.3 Redukce Redukce je základní technikou klasifikace problémů z hlediska vyčíslitelnosti. Jedná se o algoritmický převod problému na jiný problém, tedy neformálně o vyčíslitelnou redukční funkci f, která každé instanci I problému P přiřadí instanci f(I) problému Q tak, že řešení f(I) je právě řešením I1 . 6.3.1 Důkaz nerozhodnutelnosti redukcí Technika redukce patří spolu s diagonalizací k nejpoužívanějším technikám důkazu, že problém není rozhodnutelný (částečně rozhodnutelný), neboli že jazyk není rekurzívní (rekurzívně vyčíslitelný): • víme, že jazyk A není rekurzívní (rekurzívně vyčíslitelný), • zkoumáme jazyk B, • ukážeme, že A lze úplným TS převést (redukovat) na B, • to ale znamená, že B rovněž není rekurzívní (rekurzívně vyčíslitelný) – jinak by šlo použít úplný TS (ne-úplný TS) přijímající B a příslušné redukce k sestavení úplného TS (ne-úplného TS) přijímajícího A, což by byl spor. Argumentace výše samozřejmě ukazuje, že redukci lze použít i při dokazování, že určitý problém je rekurzívní (částečně rekurzívní). Definice 6.3.1 Nechť A, B jsou jazyky, A ⊆ Σ∗ , B ⊆ Ψ∗ . Redukce jazyka A na jazyk B je rekurzívně vyčíslitelná funkce σ : Σ∗ → Ψ∗ taková, že w ∈ A ⇔ σ(w) ∈ B. A Σ* B Ψ* σ σ Existuje-li redukce jazyka A na B, říkáme, že A je redukovatelný na B, což značíme A ≤ B. 1P a Q jsou rozhodovací problémy. KAPITOLA 6. MEZE ROZHODNUTELNOSTI 129 Věta 6.3.1 Nechť A ≤ B. 1. Není-li jazyk A rekurzívně vyčíslitelný, pak ani jazyk B není rekurzívně vy- číslitelný. 2. Není-li jazyk A rekurzívní, pak ani jazyk B není rekurzívní. 1. Je-li jazyk B rekurzívně vyčíslitelný, pak i jazyk A je rekurzívně vyčíslitelný. 2. Je-li jazyk B rekurzívní, pak i jazyk A je rekurzívní. Důkaz. Dokážeme, že pokud A ≤ B, pak (1) je-li jazyk B rekurzívně vyčíslitelný, pak i jazyk A je rekurzívně vyčíslitelný: • Nechť MR je úplný TS počítající redukci σ z A na B a MB je TS přijímající B. • Sestrojíme MA přijímající A: 1. MA simuluje MR se vstupem w, čímž transformuje obsah pásky na σ(w). 2. MA simuluje výpočet MB na σ(w). 3. Pokud MB zastaví a přijme, MA rovněž zastaví a přijme, jinak MA zastaví abnormálně nebo cyklí. • Zřejmě platí: MA přijme w ⇔ MB přijme σ(w) ⇔ σ(w) ∈ B ⇔ w ∈ A (definice redukce). Tvrzení (1) je kontrapozicí (1); tvrzení (2) dokážeme podobně jako (1) při použití úplného TS MB; tvrzení (2) je kontrapozicí2 (2). 2 6.4 Problém náležitosti a další problémy Redukce z problému zastavení přináší množství ” špatných zpráv“ o nerozhodnutelnosti významných problémů, jako je např. problém příslušnosti slova do daného jazyka. 6.4.1 Problém náležitosti pro L0 Věta 6.4.1 Problém náležitosti (Membership Problem) řetězce w do jazyka L typu 0 není rozhodnutelný, ale je částečně rozhodnutelný. Důkaz. Částečná rozhodnutelnost je zřejmá: jednoduše použijeme TU , který bude simulovat TS M, L(M) = L, nad daným řetězcem w. Nerozhodnutelnost ukážeme redukcí z problému zastavení : 2Kontrapozice: p → q ⇔ ¬q → ¬p (Modus tollens). KAPITOLA 6. MEZE ROZHODNUTELNOSTI 130 • Libovolný TS M můžeme snadno upravit na M , který přijme w právě tehdy, když M zastaví (jakkoli) na vstupu w: postačí dodat veškeré ” chybějící“ přechody jejich svedením do qF , dodat počáteční poznačení levého okraje unikátním symbolem a přechod do qF , který bude použit, kdykoliv se hlava posune na tento symbol. • Uvedenou transformaci lze zřejmě snadno realizovat na úrovni kódů Turingových strojů úplným TS – ten tak bude implementovat redukci jazyka HP na jazyk MP = { M # w | w ∈ L(M)}. • Jsme tedy schopni redukovat HP úplným TS na MP a současně víme, že HP není rekurzívní. Dle věty 10.3 (2) tedy máme, že MP není rekurzívní, a tedy problém náležitosti pro jazyky typu 0 není rozhodnutelný. 2 Podobně jako u problému zastavení nyní z věty 5.6.3 plyne, že • komplement problému náležitosti není ani částečně rozhodnutelný a • jazyk co-MP = { M # w | w ∈ L(M)} je dalším příkladem jazyka, jenž není ani rekurzívně vyčíslitelný. 6.4.2 Příklady dalších problémů pro TS Konstrukcí příslušného úplného TS (a v případě složitější konstrukce důkazem její korektnosti) lze ukázat, že např. následující problémy jsou rozhodnutelné: • Daný TS má alespoň 2005 stavů. • Daný TS učiní více než 2005 kroků na vstupu ε. • Daný TS učiní více než 2005 kroků na nějakém vstupu. Konstrukcí příslušného (ne-úplného) TS a důkazem nerekurzivnosti redukcí lze ukázat, že např. následující problémy jsou právě částečně rozhodnutelné: • Jazyk daného TS je neprázdný. • Jazyk daného TS obsahuje alespoň 2005 slov. Důkazem redukcí lze ukázat, že jazyky odpovídající následujícím problémům nejsou ani parciálně rekurzívní – následující problémy nejsou ani částečně rozhod- nutelné: • Jazyk daného TS je prázdný. • Jazyk daného TS obsahuje nanejvýš 2005 slov. • Jazyk daného TS je konečný (regulární, bezkontextový, kontextový, rekur- zívní). 6.5 Postův korespondenční problém Podobně jako problém zastavení je Postův korespondenční problém důležitý jako východisko redukce při dokazování nerozhodnutelnosti mnoha problémů. KAPITOLA 6. MEZE ROZHODNUTELNOSTI 131 6.5.1 Postův korespondenční problém Definice 6.5.1 • Postův systém nad abecedou Σ je dán neprázdným seznamem S dvojic neprázdných řetězců nad Σ, S = (α1, β1), ..., (αk, βk) , αi, βi ∈ Σ+ , k ≥ 1. • Řešením Postova systému je každá neprázdná posloupnost přirozených čísel I = i1, i2, ..., im , 1 ≤ ij ≤ k, m ≥ 1, taková, že: αi1 αi2 ...αim = βi1 βi2 ...βim (Pozor: m není omezené a indexy se mohou opakovat!) • Postův problém (PCP) zní: Existuje pro daný Postův systém řešení? Příklad 6.5.1 • Uvažujme Postův systém S1 = {(b, bbb), (babbb, ba), (ba, a)} nad Σ = {a, b}. Tento systém má řešení I = 2, 1, 1, 3 : babbb b b ba = ba bbb bbb a. • Naopak Postův systém S2 = {(ab, abb), (a, ba), (b, bb)} nad Σ = {a, b} nemá řešení, protože |αi| < |βi| pro i = 1, 2, 3. 6.5.2 Nerozhodnutelnost PCP Věta 6.5.1 Postův korespondenční problém je nerozhodnutelný. Důkaz. (Idea) Dá se ukázat, že nerozhodnutelnost PCP plyne z nerozhodnutelnosti tzv. iniciálního PCP, u kterého požadujeme, aby řešení začínalo vždy jedničkou. Nerozhodnutelnost iniciálního PCP se dá ukázat redukcí z problému náležitosti pro TS: • Konfiguraci výpočtu TS lze zakódovat do řetězce: použitý obsah pásky ohraničíme speciálními značkami (a jen ten si pamatujeme), řídicí stav poznačíme speciálním symbolem před symbol pásky nacházející se aktuálně pod hlavou (kódujeme tak i pozici hlavy). • Posloupnost konfigurací TS při přijetí řetězce budeme reprezentovat jako konkatenaci řetězců, která vzniká řešením PCP. • Jedna z uvažovaných konkatenací bude celou dobu (až na poslední fázi) delší: na začátku bude obsahovat počáteční konfiguraci a pak bude vždy o krok napřed. V posledním fázi výpočtu konkatenace ” zarovnáme“ (bude-li možné výpočet simulovaného TS ukončit přijetím). • Výpočet TS budeme modelovat tak, že vždy jednu konkatenaci postupně prodloužíme o aktuální konfiguraci simulovaného TS a současně v druhé konkatenaci vygenerujeme novou konfiguraci TS. • Jednotlivé dvojice PCP budou modelovat následující kroky: KAPITOLA 6. MEZE ROZHODNUTELNOSTI 132 – Vložení počáteční konfigurace simulovaného TS do jedné z konkatenací, např. pravostranné (#, #počáteční_konfigurace), # ∈ Γ používáme jako oddělovač konfigurací. – Kopírování symbolů na pásce před a po aktuální pozici hlavy (z, z) pro každé z ∈ Γ ∪ {#, <, >}, kde <, > ohraničují použitou část pásky. – Základní změna konfigurace: přepis δ(q1, a) = (q2, b): (q1a, q2b), posuv doprava δ(q1, a) = (q2, R): (q1a, aq2), posuv doleva δ(q1, b) = (q2, L): (aq1b, q2ab) pro každé a ∈ Γ ∪ {<}. Navíc je zapotřebí ošetřit nájezd na >: čtení ∆, rozšiřování použité části pásky. – Pravidla pro ” zarovnání“ obou konkatenací při přijetí: na levé straně umožníme přidat symbol v okolí qF , aniž bychom ho přidali na pravé straně. • Simulace výpočtu TS, který načte a, posune hlavu doprava, přepíše a na b a zastaví, by pak na vstupu aa vypadala takto: # < q0 a a > # < a q1 a > # < a qF b > # < qF b > # < qF > # qF > # qF # # # < q0 a a > # < a q1 a > # < a qF b > # < qF b > # < qF > # qF > # qF # # • Obecná korektnost konstrukce se dá dokázat indukcí k délce výpočtu. 2 6.5.3 Nerozhodnutelnost redukcí z PCP Redukce z PCP (resp. jeho doplňku) se velmi často používají k důkazům, že určitý problém není rozhodnutelný (resp. není ani částečně rozhodnutelný). Jako příklad uvedeme důkaz faktu, že problém prázdnosti jazyka dané kontextové gramatiky není ani částečně rozhodnutelný: • Použijeme redukci z komplementu PCP. Redukce přiřadí seznamu S = (α1, β1), ..., (αk, βk), definujícímu instanci PCP, kontextovou gramatiku G takovou, že PCP založený na S nemá řešení právě tehdy, když L(G) = ∅. • Uvažme jazyky Lα, Lβ nad Σ ∪ {#, 1, ..., k} (předp. Σ ∩ {#, 1, ..., k} = ∅): – Lα = {αi1 ...αim #im...i1 | 1 ≤ ij ≤ k, j = 1, ..., m, m ≥ 1}, – Lβ = {βi1 ...βim #im...i1 | 1 ≤ ij ≤ k, j = 1, ..., m, m ≥ 1}. • Je zřejmé, že Lα, Lβ jsou kontextové (dokonce deterministické bezkontextové), tudíž Lα ∩ Lβ je také kontextový (věta 8.10) a můžeme tedy efektivně sestavit gramatiku G, která tento jazyk generuje (např. konstrukcí přes LOA). • Lα ∩ Lβ zřejmě obsahuje právě řetězce u#v, kde v odpovídá inverzi řešení dané instance PCP. • Hledaná redukce tedy přiřadí dané instanci PCP gramatiku G. 2 6.5.4 Souhrn některých vlastností jazyků Uvedeme nyní souhrn některých důležitých vlastností probraných tříd jazyků; některé jsme dokázali, důkazy jiných lze nalézt v literatuře3 (u otázek nerozhod- 3Např. I. Černá, M. Křetínský, A. Kučera. Automaty a formální jazyky I. FI MU, 1999. KAPITOLA 6. MEZE ROZHODNUTELNOSTI 133 nutelnosti se často užívá redukce z PCP):4 Reg DCF CF CS Rec RE w ∈ L(G)? R R R R R N L(G) prázdný? konečný? R R R N N N L(G) = Σ∗ ? R R N N N N L(G) = R, R ∈ L3? R R N N N N L(G1) = L(G2)? R R N N N N L(G1) ⊆ L(G2)? R N N N N N L(G1) ∈ L3? A R N N N N L(G1) ∩ L(G2) je stejného typu? A N N A A A L(G1) ∪ L(G2) je stejného typu? A N A A A A Komplement L(G) je stejného typu? A A N A A N L(G1).L(G2) je stejného typu? A N A A A A L(G)∗ je stejného typu? A N A A A A Je G víceznačná? R N N N N N 6.6 Riceova věta Riceova věta je důležitým nástrojem vyčíslitelnostní klasifikace jazyků (založeným na redukci z HP a co − HP). Znovu se ukazuje, že rozhodnutelnost je výjimkou, která potvrzuje pravidlo. 6.6.1 Riceova věta – první část Věta 6.6.1 Každá netriviální vlastnost rekurzívně vyčíslitelných jazyků je nerozhodnutelná. Definice 6.6.1 Budiž dána abeceda Σ. Vlastnost rekurzívně vyčíslitelných množin je zobrazení P : { rekurzívně vyčíslitelné podmnožiny množiny Σ∗ } → {⊥, }, kde resp. ⊥ reprezentují pravdu resp. nepravdu. Příklad 6.6.1 Vlastnost prázdnosti můžeme reprezentovat jako zobrazení P(A) = , jestliže A = ∅, ⊥, jestliže A = ∅. Zdůrazněme, že nyní mluvíme o vlastnostech rekurzívně vyčíslitelných množin, nikoliv o vlastnostech TS, které je přijímají. Následující vlastnosti tedy nejsou vlastnostmi r.v. množin: • TS M má alespoň 2005 stavů. • TS M zastaví na všech vstupech. Definice 6.6.2 Vlastnost rekurzívně vyčíslitelných množin je netriviální, pokud není vždy (pro všechny r.v. možiny) pravdivá ani vždy nepravdivá. 4R = rozhodnutelný, N = nerozhodnutelný, A = vždy splněno KAPITOLA 6. MEZE ROZHODNUTELNOSTI 134 6.6.2 Důkaz 1. části Riceovy věty Důkaz. • Nechť P je netriviální vlastnost r.v. množin. Předpokládejme beze ztráty obecnosti, že P(∅) = ⊥, pro P(∅) = můžeme postupovat analogicky. • Jelikož P je netriviální vlastnost, existuje r.v. množina A taková, že P(A) = . Nechť K je TS přijímající A. • Redukujeme HP na { M | P(L(M)) = }. Z M # w sestrojíme σ( M # w ) = M , kde M je 2-páskový TS, který na vstupu x: 1. Uloží x na 2. pásku. 2. Zapíše na 1. pásku w – w je ” uložen“ v řízení M . 3. Odsimuluje na 1. pásce M – M je rovněž ” uložen“ v řízení M . 4. Pokud M zastaví na w, odsimuluje K na x a přijme, právě když K přijme. • Dostáváme: – M zastaví na w ⇒ L(M ) = A ⇒ P(L(M )) = P(A) = , – M cyklí na w ⇒ L(M ) = ∅ ⇒ P(L(M )) = P(∅) = ⊥, Máme tedy skutečně redukci HP na { M | P(L(M)) = }. Protože HP není rekurzívní, není rekurzívní ani P(L(M)), a tudíž není rozhodnutelné, zda L(M) splňuje vlastnost P. 2 6.6.3 Riceova věta – druhá část Definice 6.6.3 Vlastnost P r.v. množin nazveme monotónní, pokud pro každé dvě r.v. množiny A, B takové, že A ⊆ B, platí P(A) ⇒ P(B). Příklad 6.6.2 Mezi monotónní vlastnosti patří např.: • A je nekonečné. • A = Σ∗ . Naopak mezi nemonotónní vlastnosti patří např.: • A je konečné. • A = ∅. Věta 6.6.2 Každá netriviální nemonotónní vlastnost rekurzívně vyčíslitelných jazyků není ani částečně rozhodnutelná. Důkaz. Redukcí z co-HP – viz např. D. Kozen. Automata and Computability.2 KAPITOLA 6. MEZE ROZHODNUTELNOSTI 135 6.7 Alternativy Turingova stroje Mezi výpočetní mechanismy mající ekvivalentní výpočetní sílu jako TS patří např. automaty s (jednou) frontou: • Uvažme stroj s konečným řízením, (neomezenou) FIFO frontou a přechody, které dovolují načíst ze začátku fronty a zapsat na konec fronty symboly z frontové abecedy Γ. • Pomocí ” rotace“ fronty je zřejmě možné simulovat pásku TS. Ekvivalentní výpočetní sílu jako TS mají také zásobníkové automaty se dvěma (a více) zásobníky: • Intuitivně: obsah pásky simulovaného TS máme v jednom zásobníku; chcemeli ho změnit (obecně nejen na vrcholu), přesuneme část do druhého zásobníku, abychom se dostali na potřebné místo, provedeme patřičnou změnu a vrátíme zpět odloženou část zásobníku. • Poznámka: rovněž víme, že pomocí dvou zásobníků můžeme implementovat frontu. Jiným výpočetním modelem s plnou Turingovskou silou jsou automaty s čítači (pro dva a více čítačů) a operacemi +1, −1 a test na 0: • Zmíněné automaty mají konečné řízení a k čítačů, přičemž v každém kroku je možné tyto čítače nezávisle inkrementovat, dekrementovat a testovat na nulu (přechod je podmíněn tím, že jistý čítač obsahuje nulu). • Pomocí čtyř čítačů je snadné simulovat dva zásobníky: – U ZA postačí mít Γ = {0, 1}: různé symboly můžeme kódovat určitým počtem 0 oddělených 1. Obsah zásobníku má pak charakter binárně zapsaného čísla. Vložení 0 odpovídá vynásobení 2, odebrání 0, vydělení 2. Podobně je tomu s vložením/odebráním 1. – Binární zásobník můžeme simulovat dvěma čítači: při násobení/dělení 2 odečítáme 1 (resp. 2) z jednoho čítače a přičítáme 2 (resp. 1) k druhému. • Postačí ovšem i čítače dva: – Obsah čtyř čítačů i, j, k, l je možné zakódovat jako 2i 3j 5k 7l . – Přičtení/odečtení je pak možné realizovat násobením/dělením 2, 3, 5, či 7. Mezi další Turingovsky úplné výpočetní mechanismy pak patří např. λ-kalkul či parciálně-rekurzívní funkce (viz následující kapitola). 6.8 Vyčíslitelné funkce 6.8.1 Základy teorie rekurzivních funkcí Budeme se snažit identifikovat takové funkce, které jsou ” spočitatelné“, tj. vyčíslitelné v obecném smyslu (bez ohledu na konkrétní výpočetní systém). Abychom snížili extrémní velikost třídy těchto funkcí, která je dána také varietou definičních oborů a oborů hodnot, omezíme se, uvažujíce možnost kódování, na funkce tvaru: KAPITOLA 6. MEZE ROZHODNUTELNOSTI 136 f : Nm → Nn kde N = {0, 1, 2, . . .}, m, n ∈ N. Konvence: n-tici (x1, x2, . . . , xn) ∈ Nn budeme označovat jako x Klasifikace parciálních funkcí: • Totální funkce nad množinou X5 – definičním oborem je celá X • Striktně parciální funkce nad množinou X – alespoň pro jeden prvek x ∈ X není definována funkční hodnota Příklad 6.8.1 Totální funkce plus plus : N × N → N plus(x, y) = x + y N × N plus N Příklad 6.8.2 Striktně parciální funkce div div : N × N → N div(x, y) = celá část x/y, je-li y = 0 N × N div { | y=0} N 6.8.2 Počáteční funkce Hierarchie vyčíslitelných funkcí je založena na dostatečně elementárních tzv. počátečních funkcích, které tvoří ” stavební kameny“ vyšších funkcí. Jsou to tyto funkce: 1. Nulová funkce (zero function): ξ() = 0 zobrazuje ” prázdnou n-tici“ → 0 2. Funkce následníka (successor function): σ : N → N σ(x) = x + 1 3. Projekce (projection): πn k : Nn → N Vybírá z n-tice k-tou složku, např.: π3 2(7, 6, 4) = 6 a π2 1(5, 17) = 5 Speciální případ: πn 0 : Nn → N0 , tj. např. π3 0(1, 2, 3) = () 6.8.3 Primitivně rekurzivní funkce Nyní definujme tři způsoby vytváření nových, složitějších funkcí. Primitivně rekurzivní funkce pak budou takto tvořeny z funkcí počátečních. 1. Kombinace: Kombinací dvou funkcí f : Nk → Nm a g : Nk → Nn získáme funkci, pro kterou: f × g : Nk → Nm+n f × g(x) = (f(x), g(x)), x ∈ Nk 5V dalším bude množinou X obvykle Nk. KAPITOLA 6. MEZE ROZHODNUTELNOSTI 137 Např.: π3 1 × π3 3(4, 12, 8) = (4, 8) 2. Kompozice: Kompozice dvou funkcí f : Nk → Nm a g : Nm → Nn je funkce, pro kterou: g ◦ f : Nk → Nn g ◦ f(x) = g(f(x)), x ∈ Nk Např.: σ ◦ ξ() = 1 σ ◦ σ ◦ ξ() = 2 3. Primitivní rekurze je technika, která umožňuje vytvořit funkci f : Nk+1 → Nm na základě jiných dvou funkcí g : Nk → Nm a h : Nk+m+1 → Nm rovnicemi: f(x, 0) = g(x) f(x, y + 1) = h(x, y, f(x, y)), x ∈ Nk Ilustrace schématu vyčíslení (pro y = 3): f(x,3)=h(x,2,f(x,2)) f(x,2)=h(x,1,f(x,1)) f(x,1)=h(x,0,f(x,0)) f(x,0)=g(x) Příklad 6.8.3 Předpokládejme, že chceme definovat funkci f : N2 → N, jejíž hodnoty f(x, y) udávají počet vrcholů x-árního stromu hloubky y, který je pravidelný (úplný): x x x Zřejmě: 1. f(x, 0) = 1 2. strom hloubky y má xy listů. Zvětšením hloubky o jedničku na y +1 musíme přidat xy+1 = xy · x vrcholů Takže funkci f můžeme definovat následujícím předpisem: f(x, 0) = x0 , f(x, y+ 1) = f(x, y) + xy · x. Např.: f(3, 2) = f(3, 1) + 31 · 3 = f(3, 0) + 30 · 3 + 31 · 3 = 1 + 3 + 9 = 13 KAPITOLA 6. MEZE ROZHODNUTELNOSTI 138 Příklad 6.8.4 Uvažujme funkci plus : N2 → N. Může být definována pomocí primitivní rekurze takto: plus(x, 0) = π1 1(x) plus(x, y + 1) = σ ◦ π3 3(x, y, plus(x, y)) což vyjadřuje: 1. x + 0 = x 2. x + (y + 1) = (x + y) + 1 = σ(x + y) Definice 6.8.1 Třída primitivních rekurzivních funkcí obsahuje všechny funkce, které mohou být z počátečních funkcí vytvořeny: 1. kombinací, 2. kompozicí a 3. primitivní rekurzí. Věta 6.8.1 Každá primitivní rekurzivní funkce je totální funkcí. Důkaz. Počáteční funkce jsou totální. Aplikací kombinace, kompozice a primitivní rekurze na totální funkce dostaneme totální funkce. 2 6.8.4 Příklady primitivně rekurzivních funkcí Třída primitivně rekurzivních funkcí zahrnuje většinu funkcí typických v aplikacích počítačů. Ukážeme, jak je definovat z počátečních pomocí kombinace, kompozice a primitivní rekurze. Konvence: Namísto funkcionálních zápisů typu h ≡ plus◦(π3 1 ×π3 3) budeme někdy používat zápis h(x, y, z) = plus(x, z) nebo h(x, y, z) = x + z. Konstantní funkce: Zavedeme funkci κn m, která libovolné n-tici x ∈ Nn přiřadí konstantní hodnotu m ∈ N κ0 m ≡ σ ◦ σ ◦ . . . ◦ σ m−krát ξ Také pro n > 0 je κn m funkce rekurzivně primitivní: κn m(x, 0) = κn−1 m (x) κn m(x, y + 1) = πn+1 n+1(x, y, κn m(x, y)) Např.: κ2 3(1, 1) = π3 3(1, 0, κ2 3(1, 0)) = κ2 3(1, 0) = κ1 3(1) = κ1 3(0) = κ0 3() = 3 Kombinací funkcí κn m dostáváme konstanty z Nn , n > 1. Např.: κ3 2 × κ3 5(x, y, z) = (2, 5) Funkce násobení : mult(x, 0) = κ1 0(x) mult(x, y + 1) = plus(x, mult(x, y)) KAPITOLA 6. MEZE ROZHODNUTELNOSTI 139 Funkce umocňování : exp : N2 → N - analogicky - viz cvičení. Funkce předchůdce: pred(0) = ξ() pred(y + 1) = π2 1(y, pred(y)) Poznámka: pred je totální funkcí: pred(0) = 0 Funkce monus: monus(x, 0) = π1 1(x) monus(x, y + 1) = pred(monus(x, y)) Význam: monus(x, y) = x − y je-li x ≥ y 0 jinak Notace: monus(x, y) ≡ x ˙−y Funkce eq (equal): eg(x, y) = 1 je-li x = y 0 je-li x = y Definice 6.8.2 eq(x, y) = 1 ˙−((y ˙−x) + (x ˙−y)) nebo formálněji eq ≡ monus ◦ (κ2 1 × (plus ◦ ((monus ◦ (π2 2 × π2 1)) × monus ◦ (π2 1 × π2 2)))) Příklad 6.8.5 eq(5, 3) = 1 ˙−((3 ˙−5) + (5 ˙−3)) = 1 ˙−(0 + 2) = 1 ˙−2 = 0 Funkce ¬ eq: ¬eq ≡ monus ◦ (κ2 1 × eq) (≡ 1 ˙−eq) Tabulární funkce: Uvažujme funkce typu: f(x) =    3 je-li x = 0 5 je-li x = 4 2 v ostatních případech které bývají zadávány tabulkou. Tyto funkce lze tvořit pomocí charakteristické funkce ϕi(x) = 1 je-li x = i 0 jinak která může být vyjádřena jako monus(Ii, Ii−1), kde Ii(x) = eq(x ˙−i, 0) Ii 1 2 i- i 1 I 1 2 i- i 1 I i 1 2 i- i 1 i- i-I. 1 1 1 11 Tabulární funkce mohou být nyní tvořeny konečným součtem násobků konstant a funkcí ϕi a ¬ϕi. Např.: nahoře uvedená funkce f(x) je vyjádřitelná ve tvaru: f ≡ mult(3, ϕ0) + mult(5, ϕ4) + mult(2, mult(¬ϕ0, ¬ϕ4)) KAPITOLA 6. MEZE ROZHODNUTELNOSTI 140 Funkce quo (quotient): quo(x, y) = celá část podílu x/y je-li y = 0 0 je-li y = 0 Tato funkce může být definována primitivní rekurzí: quo(0, y) = 0 quo(x + 1, y) = quo(x, y) + eq(x + 1, mult(quo(x, y), y) + y) 6.8.5 Funkce mimo primitivně rekurzivní funkce Existují funkce, které jsou vyčíslitelné a nejsou primitivně rekurzivními funkcemi. Jsou to všechny striktně parciální funkce (jako div), ale i totální funkce. Taková totální funkce byla prezentována W. Ackermannem (1928) a nazývá se Ackermannova funkce. Je dána rovnicemi: A(0, y) = y + 1 A(x + 1, 0) = A(x, 1) A(x + 1, y + 1) = A(x, A(x + 1, y)) Věta 6.8.2 Existuje totální funkce z N do N, která není primitivně rekurzivní. Důkaz. Definice funkcí, které jsou primitivně rekurzivní budeme chápat jako řetězce a můžeme je uspořádat v lexikografickém pořadí s označením f1, f2, . . . , fn, . . . Definujeme nyní funkci f : N → N tak, že f(n) = fn(n)+1 pro ∀n ∈ N\{0}. f je jasně totální a vyčíslitelná. f však není primitivně rekurzivní (kdyby byla, pak f ≡ fm pro nějaké m ∈ N. Pak ale f(m) = fm(m) a ne fm(m) + 1, jak vyžaduje definice funkce f). 2 Definice 6.8.3 Třída totálních vyčíslitelných funkcí se nazývá µ-rekurzivní funkce. Dostáváme následující klasifikaci funkcí: -rekurzivní funkce vycíslitelné funkce primitivne rekurzivní funkce pocátecní funkce 6.8.6 Parciálně rekurzivní funkce K rozšíření třídy vyčíslitelných funkcí za totální vyčíslitelné funkce zavedeme techniku známou pod názvem minimalizace. Tato technika umožňuje vytvořit funkci f : Nn → N z jiné funkce g : Nn+1 → N předpisem, v němž f(x) je nejmenší y takové, že: 1. g(x, y) = 0 2. g(x, z) je definována pro ∀z < y, z ∈ N KAPITOLA 6. MEZE ROZHODNUTELNOSTI 141 Tuto konstrukci zapisujeme notací: f(x) = µy[g(x, y) = 0] Příklad 6.8.6 f(x) = µy[plus(x, y) = 0] tj. f(x) = 0 pro x = 0 nedef. jinak Příklad 6.8.7 div(x, y) = µt[((x + 1) ˙−(mult(t, y) + y)) = 0] Příklad 6.8.8 i(x) = µy[monus(x, y) = 0] tj. identická funkce Funkce definovaná minimalizací je skutečně vyčíslitelná. Výpočet hodnoty f(x) zahrnuje výpočet g(x, 0), g(x, 1), . . . tak dlouho, pokud nedostaneme: • g(x, y) = 0 (f(x) = y), • g(x, z) je nedefinována (f(x) je nedefinována). Definice 6.8.4 Třída parciálně rekurzivních funkcí je třída parciálních funkcí, které mohou být vytvořeny z počátečních funkcí aplikací: • kombinace, • kompozice, • primitivní rekurze a • minimalizace. 6.9 Vztah vyčíslitelných funkcí a Turingových strojů Turingův stroj můžeme ” upravit“ tak, aby byl schopen počítat funkce. Navrhneme jej tak, aby z počáteční konfigurace se vstupními parametry funkce na pásce zapsal výsledek výpočtu (požadovanou funkční hodnotu) na vstup, a jen tehdy normálně zastavil. Ukážeme, že rekurzivní funkce a Turingovy stroje vymezují pojem vyčíslitelnost funkcí stejně, t.j. funkce počítatelné Turingovými stroji jsou právě rekurzivní funkce 6.9.1 Turingovsky vyčíslitelné funkce Definice 6.9.1 Turingův stroj M = (Q, Σ, Γ, δ, q0, qF ) vyčísluje (počítá) parciální funkci f : Σ∗m → Σ∗n 1 , Σ1 ⊆ Γ, ∆ /∈ Σ1, jestliže pro každé (w1, w2, . . . , wm) ∈ Σ∗m a odpovídající počáteční konfiguraci ∆w1∆w2∆ . . . ∆wm∆∆∆ stroj M: 1. v případě, že f(w1, . . . , wm) je definována, pak M zastaví a páska obsahuje ∆v1∆v2∆ . . . ∆vn∆∆∆, kde (v1, v2, . . . , vn) = f(w1, . . . , wm) 2. v případě, že f(w1, . . . , wm) není definována, M cykluje (nikdy nezastaví) nebo zastaví abnormálně. Parciální funkce, kterou může počítat nějaký Turingův stroj se nazývá funkcí Turingovsky vyčíslitelnou. Příklad 6.9.1 Turingův stroj, který počítá funkci f(w1, w2, w3) = (w1, w3). KAPITOLA 6. MEZE ROZHODNUTELNOSTI 142 R R SLL Příklad 6.9.2 Nechť L je libovolný jazyk. Funkce f(w) = |w| jestliže w ∈ L 0 jestliže w /∈ L není Turingovsky vyčíslitelná. Poznámka 6.9.1 Definice výpočtu funkce Turingovým strojem nepředpokládala speciální pozici hlavy v koncové konfiguraci. Bez újmy na obecnosti můžeme předpokládat, že M končí v konfiguraci ∆v1∆ . . . ∆vn∆∆∆. 6.9.2 Turingovská vyčíslitelnost parciálně rekurzivních funkcí Budeme uvažovat Turingův stroj s abecedou Σ = {0, 1} a parciální funkce tvaru f : Nm → Nn , m-tice a n-tice budeme kódovat podle vzoru: ∆11∆10∆100∆∆ reprezentuje trojici (3, 2, 4) Věta 6.9.1 Každá parciálně rekurzivní funkce je Turingovsky vyčíslitelná. Důkaz. 1. Nejprve je třeba nalézt Turingovy stroje, které vyčíslují počáteční funkce ξ, σ, π. (a) ξ : → R0L (b) (c) viz cvičení 2. Dále popíšeme konstrukci Turingových strojů pro aplikaci kombinace, kompozice, primitivní rekurze a minimalizace: (a) Kombinace: Nechť Turingův stroj M1, resp. M2 vyčísluje parciální funkci g1, resp. g2. Stroj M, který vyčísluje g1 × g2 bude 3-páskový Turingův stroj, který začne duplikováním vstupu na 2. a 3. pásku. Pak M simuluje M1 s využitím pásky 2 a M2 s použitím pásky 3. Skončí-li M1 i M2 řádně, M vyčistí pásku 1 a okopíruje na ní obsah pásek 2 a 3 (oddělených blankem) a zastaví. (b) Kompozice: Funkci g1 ◦ g2 realizuje stroj → M2M1. (c) Primitivní rekurze: Uvažujme: f(x, 0) = g(x) f(x, y + 1) = h(x, y, f(x, y)) kde g je parciální funkce, kterou vyčísluje stroj M1 a h parciální funkce, kterou vyčísluje stroj M2. Funkci f vyčísluje Turingův stroj, který pracuje takto: i. Je-li poslední složka vstupu 0, pak vymaže tuto složku, vrátí hlavu na začátek a simuluje stroj M1. ii. Není-li poslední složkou vstupu 0, pak páska musí obsahovat sekvenci ∆x∆y + 1∆∆∆ pro nějaké y + 1 > 0 . Potom: KAPITOLA 6. MEZE ROZHODNUTELNOSTI 143 A. S využitím strojů pro kopírování a dekrement transformuj obsah pásky na sekvenci ∆x∆y∆x∆y−1∆ . . . ∆x∆0∆x∆∆. Pak přesuň hlavu bezprostředně za 0 a simuluj stroj M1. B. Nyní je obsahem pásky ∆x∆y∆x∆y−1∆ . . . ∆x∆0∆g(x)∆∆, což je ekvivalentní s ∆x∆y∆x∆y − 1∆ . . . ∆x∆0∆f(x, 0)∆∆. Přesuň hlavu před poslední x a simuluj stroj M2. To vede k ∆x∆y∆x∆y − 1∆ . . . ∆x∆1∆h(x, 0, f(x, 0))∆∆, což je ekvivalentní s ∆x∆y∆x∆y − 1∆ . . . ∆x∆1∆f(x, 1)∆∆. C. Pokračuj v aplikaci stroje M2 na zbytek pásky až je M2 aplikován na ∆x∆y∆f(x, y) a páska je zredukována do tvaru ∆h(x, y, f(x, y))∆∆, což je ekvivalentní žádanému výstupu ∆f(x, y + 1)∆∆. (d) Minimalizace: Uvažujme funkci µy[g(x, y) = 0], kde parciální funkci g vyčísluje stroj M1. Zkonstruujeme 3-páskový stroj M, který pracuje takto: i. Zapíše 0 na pásku 2. ii. Zkopíruje obsah pásky 1 a následně pásky 2 na pásku 3. iii. Simuluje stroj M1 na pásce 3. iv. Jestliže páska 3 obsahuje 0, vymaže pásku 1, okopíruje pásku 2 na pásku 1 a zastaví. Jinak inkrementuje obsah na pásce 2, vymaže pásku 3 a pokračuje krokem (2). 2 6.9.3 Reprezentace Turingova stroje parciálně rekurzivními funkcemi Abychom dokázali, že Turingova a Churchova teze jsou ekvivalentní, zbývá ukázat, že výpočetní síla Turingových strojů je omezena na možnost vyčíslovat parciálně rekurzivní funkce. K tomu účelu uvažujme Turingův stroj M = (Q, Σ, Γ, δ, q0, qF ) a položme b = |Γ|. Nyní budeme obsah pásky interpretovat jako v opačném pořadí zapsané nezáporné celé číslo při základu b. Například: Bude-li Γ = {x, y, ∆} a interpretujeme-li x ≈ 1, y ≈ 2, ∆ ≈ 0, pak páska obsahující ∆yx∆∆y∆∆ . . . je ekvivalentní s 02100200 . . ., což po inverzi reprezentuje číslo . . . 00200120 při základu 3 a tedy 501. S touto interpretací můžeme činnost každého Turingova stroje chápat jako výpočet funkce f : N → N, která číslu odpovídajícímu počátečnímu obsahu pásky ” přiřazuje“ číslo odpovídající obsahu pásky po zastavení stroje. Charakter funkce f specifikuje následující věta. Věta 6.9.2 Každý výpočetní proces prováděný Turingovým strojem je procesem vyčíslení nějaké parciálně rekurzivní funkce. Důkaz. Budeme vycházet z právě zavedené interpretace činnosti Turingova stroje M, tj. pro každé n ∈ N, f(n) je definována obsahem pásky při zastavení stroje M. Dále provedeme zakódování stavů: 1 ≈ q0, 0 ≈ qF , ostatní stavy čísly 2, 3, . . . , k−1 za předpokladu |Q| = k. Tedy jak stavy, tak symboly mají přiřazené numerické hodnoty a můžeme definovat funkce, které sumarizují diagram přechodů stroje M (M je zakódovaný stroj M): KAPITOLA 6. MEZE ROZHODNUTELNOSTI 144 mov(p, x) =    2 jestliže δ(p, x) = (∗, R) 1 jestliže δ(p, x) = (∗, L) 0 jinak sym(p, x) = y jestliže δ(p, x) = (∗, y) x jinak state(p, x) = q jestliže δ(p, x) = (q, ∗) k jestliže p = 0 nebo δ(p, x) není definována Funkce sym, mov a state jsou tabulární funkce (totální) a jsou tedy primitivně rekurzivní. Nyní uvažujme konfiguraci Turingova stroje M ve tvaru trojice (w, p, n), kde w je obsah pásky, p přítomný stav, n pozice hlavy (n ≥ 1, nejlevější pozice je rovna 1). Z informace obsažené v konfiguraci může být vypočítán symbol, který se nachází pod hlavou, primitivně rekurzivní funkcí cursym: cursym(w, p, n) = quo(w, bn−1 ) ˙−mult(b, quo(w, bn )) Příklad 6.9.3 Nalezení n-té číslice řetězce w = 1120121 pro n = 5 a b = 3: 112w=1120121 deleno b n-1 110 11w=1120121 deleno b n násobeno b 2 . 112 = quo(w, bn−1 ) 110 = mult(b, quo(w, bn )) Další funkce, které definujeme na množině konfigurací jsou: nexthead(w, p, n) = n ˙−eq(mov(p, cursym(w, p, n)), 1) +eq(mov(p, cursym(w, p, n)), 2) určující příští pozici hlavy (0 indikuje abnormální posuv z 1. pozice vlevo) nextstate(w, p, n) = state(p, cursym(w, p, n)) + mult(k, ¬nexthead(w, p, n)) (normálně je 2. sčítanec roven 0; při abnormálním posuvu tato funkce vyčíslí nelegální stav větší než k − 1) a konečně funkce nexttape(w, p, n) = (w ˙−mult(bn−1 , cursym(w, p, n))) +mult(bn−1 , sym(p, cursym(w, p, n))) která vyčísluje celé číslo reprezentující nový obsah pásky, po provedení přechodu z konfigurace (w, p, n). Kombinací tří předchozích funkcí dostaneme funkci step, která modeluje 1. krok Turingova stroje, tj. přechod do nové konfigurace: step = nexttape × nextstate × nexthead Nyní definujme funkci run : N4 → N3 ; run(w, p, n, t) realizující t přechodů z konfigurace (w, p, n). Opět užijeme primitivní rekurze: run(w, p, n, 0) = (w, p, n) run(w, p, n, t + 1) = step(run(w, p, n, t)) KAPITOLA 6. MEZE ROZHODNUTELNOSTI 145 Výsledná funkce vyčíslovaná strojem M (při vstupu w) je hodnota pásky po dosažení koncového stavu (stavu 0). Počet požadovaných kroků stroje M je dán funkcí stoptime stoptime(w) = µt[π3 2(run(w, 1, 1, t)) = 0] Na závěr tedy, je-li f : N → N parciální funkce počítaná strojem M, pak f(w) = π3 1(run(w, 1, 1, stoptime(w))) z její konstrukce plyne, že f je parciálně rekurzivní funkce. 2 Shrňme v obrázku získané informace: Turingovsky vycíslitelné funkce parciálne rekurzivní funkce= vsechny funkce pocátecní funkce primitivne rekurzivní funkce -rekurzivní funkce Existuje nespočetně mnoho formálních jazyků, které nelze popsat Turingovým strojem a leží tudíž mimo třídu rekurzivně vyčíslitelných jazyků. K těmto jazykům patří jazyky, které jsou striktně nerozhodnutelné jazyky a komplementy částečně rozhodnutelných jazyků. Mnohé z nich popisují problémy, které tudíž nelze algoritmicky řešit. Jejich obecnou, často využívanou reprezentací pro redukce je problém zastavení Turingova stroje a Postův korespondenční problém. Mezi řadou alternativních, Turingovým strojům ekvivalentních formálních systémů jsou důležitým prostředkem popisu a analýzy parciální rekurzivní funkce, které mají velmi úzký vztah k funkcionálnímu programování. 6.10 Cvičení Příklad 6.10.1 1. Definujte, kdy je problém rozhodnutelný, nerozhodnutelný a částečně rozhod- nutelný. 2. Uveďte problémy, které jsou rozhodnutelné, částečně rozhodnutelné a problémy které nejsou ani částečně rozhodnutelné. 3. Definujte Postův korespondenční problém a rozhodněte, zda je rozhodnutelný nebo aspoň částečně rozhodnutelný. Dále uveďte příklad Postova systému, který má řešení resp. nemá řešení. KAPITOLA 6. MEZE ROZHODNUTELNOSTI 146 4. Definujte pojem redukce a vysvětlete na příkladu jeho použití. 5. Uveďte 1. a 2. Riceova větu a jejich možné použití. 6. Uveďte příklady dalších výpočetních modelů, které mají ekvivalentní výpočtovou sílu jako Turingovy stroje. 7. Vysvětlete pojmy počáteční funkce, primitivně rekurzivní funkce a parciálně vyčíslitelná funkce. 8. Existuje primitivně rekurzivní funkce, která není totální. Své rozhodnutí zdů- vodněte. 9. Uveďte příklady funkcí, které vznikly kombinací, kompozicí, primitivní rekurzí a minimalizací. 10. Uveďte vztah parciálně vyčíslitelných funkcí a Turingových strojů. Kapitola 7 Složitost 8:00 Cílem této kapitoly je pochopení aplikace Turingových strojů pro popis a klasifikaci časové a paměťové složitosti problémů a vymezení složitostních tříd těsně spjatých s otázkami časové a paměťové efektivity výpočtů a reálnosti realizovat řešení problémů na počítačích. 7.1 Základní pojmy složitosti 7.1.1 Složitost algoritmů Základní teoretický přístup a volba Turingova stroje jako výpočetního modelu vychází z Church-Turingovy teze: Každý algoritmus je implementovatelný jistým TS. Zavedení TS nám umožňuje klasifikovat problémy (resp. funkce) do dvou tříd: 1. problémy, jež nejsou algoritmicky ani částečně rozhodnutelné (resp. funkce algoritmicky nevyčíslitelné) 2. problémy algoritmicky alespoň částečně rozhodnutelné (resp. funkce algoritmicky vyčíslitelné). Nyní se budeme zabývat třídou algoritmicky (částečně) rozhodnutelných problémů (vyčíslitelných funkcí) v souvislosti s otázkou složitosti jejich rozhodování (vyčíslování). Analýzu složitosti algoritmu budeme chápat jako analýzu složitosti výpočtů příslušného TS, jejímž cílem je vyjádřit (kvantifikovat) požadované zdroje (čas, prostor) jako funkci závisející na délce vstupního řetězce. 7.1.2 Různé případy při analýze složitosti Nejdříve je třeba určit cenu jednoho konkrétního výpočtu konkrétního TS (paměť, čas výpočtu). Mějme TS M. Složitost bude tedy funkcí ComplM : N → N1 . Je více možností její definice podle toho, který z možných výpočtů na vstupu příslušné délky (a jeho cenu) si vybereme jako určující: 1. analýza složitosti nejhoršího případu, 2. analýza složitosti nejlepšího případu, 3. analýza složitosti průměrného případu. 1pro dané n vrací míru složitosti výpočtu M na řetězcích délky n 147 KAPITOLA 7. SLOŽITOST 148 Průměrná složitost algoritmu je definována následovně: Jestliže algoritmus (TS) vede k m různým výpočtům (případům) s cenou c1, c2, ..., cm, jež nastávají s pravděpodobností p1, p2, ..., pm, pak průměrná složitost algoritmu je dána jako Σn i=1pici. Obvykle (alespoň na teoretické úrovni) se věnuje největší pozornost složitosti nejhoršího případu. 7.1.3 Složitost výpočtů TS Na cenu výpočtu se budeme dívat z hledisek času výpočtu a paměťové náročnosti. • Časová složitost – počet kroků (přechodů) TS provedený od počátku do konce výpočtu. • Prostorová (paměťová) složitost – počet ” buněk“ pásky TS požadovaný pro daný výpočet. Příklad 7.1.1 Uvažme následující TS M: ∆/R x/R x/L ∆/x M: ∆/∆ Pro vstup w = ∆xxx∆∆... je: • časová složitost výpočtu M na w rovna 10, • prostorová složitost výpočtu M na w rovna 5. Lemma 7.1.1 Je-li časová složitost výpočtu prováděného TS rovna n, pak prostorová složitost tohoto výpočtu není větší než n + 1. Důkaz. Tvrzení je jednoduchou implikací plynoucí z definice časové a prostorové složitosti. 2 Nyní budeme definovat funkce udávající složitost TS v závislosti na čase výpočtu (počtu kroků TS) a použitém prostoru (počtu použitých políček pásky). Bude se jednat o analýzu nejhoršího případu: Definice 7.1.1 Řekneme, že k-páskový DTS (resp. NTS) M přijímá jazyk L nad abecedou Σ v čase TM : N → N, jestliže L = L(M) a M přijme (resp. může přijmout) každé w ∈ L v nanejvýš TM (|w|) krocích. Definice 7.1.2 Řekneme, že k-páskový DTS (resp. NTS) M přijímá jazyk L nad abecedou Σ v prostoru SM : N → N, jestliže L = L(M) a M přijme (resp. může přijmout) každé w ∈ L při použití nanejvýš SM (|w|) buněk pásky. Poznámka 7.1.1 Do prostorové složitosti nepočítáme buňky pásky, na nichž je zapsán vstup, pokud nebudou během vypočtu přepsány. Zcela analogicky můžeme definovat vyčíslování určité funkce daným TS v určitém čase, resp. prostoru. KAPITOLA 7. SLOŽITOST 149 7.1.4 Složitost a cena atomických operací Pro případ TS předpokládáme, že každý jeho výpočetní krok je stejně náročný. Používáme tedy takzvané uniformní cenové kritérium, kdy každé operaci přiřadíme stejnou cenu. V jiném výpočetním prostředí, než jsou TS, tomu tak ale být nemusí. Používá se ale např. také tzv. logaritmické cenové kritérium, kdy operaci manipulující operand o velikosti i, i > 0, přiřadíme cenu lg i + 1. Zohledňujeme to, že s rostoucí velikostí operandů roste cena operací – logaritmus odráží růst velikosti s ohledem na binární kódování (v n bitech zakódujeme 2n hodnot). Analýza složitosti za takových předpokladů není zcela přesná, důležité ale obvykle je to, aby se zachovala informace o tom, jak rychle roste čas/prostor potřebný k výpočtu v závislosti na velikosti vstupu.2 Význam srovnávání rychlosti růstu složitosti výpočtů si snad nejlépe ilustrujeme na příkladu: Příklad 7.1.2 Srovnání polynomiální (přesněji kvadratické – n2 ) a exponenciální (2n ) časové složitosti: délka vstupu časová složitost časová složitost n c1.n2 , c1 = 10−6 c2.2n , c2 . = 9.766.10−8 10 0.0001 s 0.0001 s 20 0.0004 s 0.1024 s 30 0.0009 s 1.75 min 40 0.0016 s 1.24 dne 50 0.0025 s 3.48 roku 60 0.0036 s 35.68 století 70 0.0049 s 3.65 mil. roků 7.1.5 Složitost výpočtů na TS a v jiných prostředích Pro rozumná cenová kritéria se ukazuje, že výpočetní složitost je pro různé modely výpočtu blízké běžným počítačům (RAM, RASP stroje) polynomiálně vázaná se složitostí výpočtu na TS (viz dále) a tudíž složitost výpočtu na TS není ” příliš“ rozdílná oproti výpočtům na běžných počítačích. • RAM stroje mají paměť s náhodným přístupem (jedna buňka obsahuje libovolné přirozené číslo), instrukce typu LOAD, STORE, ADD, SUB, MULT, DIV (akumulátor a konstanta/přímá adresa/nepřímá adresa), vstup/výstup, nepodmíněný skok a podmíněný skok (test akumulátoru na nulu), HALT. U RAM stroje je program součástí řízení stroje (okamžitě dostupný), u RASP je uložen v paměti stejně jako operandy. • Funkce f1(n), f2(n) : N → N jsou polynomiálně vázané, existují-li polynomy p1(x) a p2(x) takové, že pro všechny hodnoty n je f1(n) ≤ p1(f2(n)) a f2(n) ≤ p2(f1(n)). • Logaritmické cenové kritérium se uplatní, uvažujeme-li možnost násobení dvou čísel. Jednoduchým cyklem typu Ai+1 = Ai ∗Ai (A0 = 2) jsme schopni počítat 22n , což TS s omezenou abecedou není schopen provést v polynomiálním čase (pro uložení/načtení potřebuje projít 2n buněk při použití binárního kódování). KAPITOLA 7. SLOŽITOST 150 Ilustrujme si nyní určení složitosti v prostředí mimo TS: Příklad 7.1.3 Uvažme následující implementaci porovnávání řetězců. int str_cmp (int n, string a, string b) { int i; i = 0; while (i= 0) && (a[j] > value)) { a[j+1] = a[j]; j = j - 1; } a[j+1] = value; } } • Pro určení složitosti aplikujme uniformní cenové kritérium např. tak, že budeme považovat složitost každého řádku programu (mimo deklarace) za jednotku. (Předpokládáme, že žádný cyklus není zapsán na jediném řádku.) • Složitost lze pak určit jako 2n2 + 4n + 1: – vnitřní cyklus má 4 kroky, provede se 0, 1, ..., n − 1 krát, tj. 4(0 + 1 + ... + n − 1) = 4n 2 (0 + n − 1) = 2n2 − 2n kroků, – vnější cyklus má mimo vnitřní cyklus 6 kroků (včetně testu ukončujícího vnitřní cyklus) a provede se n krát, tj. 6n kroků, – jeden krok připadá na ukončení vnějšího cyklu. 2Algoritmus A1, jehož nároky rostou pomaleji než u jiného algoritmu A2, nemusí být výhodnější než A2 pro řešení malých instancí. KAPITOLA 7. SLOŽITOST 151 7.1.6 Asymptotická omezení složitosti Přesná informace o složitosti algoritmu je pro nás většinou zbytečná, o skutečném čase (prostoru) výpočtu vypovídá málo: • různé aditivní a multiplikativní konstanty vzniknou velmi snadno ” drobnými“ úpravami uvažovaných algoritmů, • např. srovnávání dvou řetězců je možné donekonečna zrychlovat tak, že budeme porovnávat současně 2, 3, 4, ... za sebou jdoucích znaků, • tyto úpravy ovšem nemají zásadní vliv na rychlost nárůstu časové složitosti (ve výše uvedeném případě nárůst zůstane kvadratický), • navíc při analýze složitosti mimo prostředí TS se dopouštíme jisté nepřesnosti již zavedením různých cenových kritérií. Zajímá nás tedy jen ” důležitá“ část informace o složitosti (porovnání řetězců – čas roste lineárně, insert-sort – čas roste kvadraticky). Proto se často složitost popisuje pomocí tzv. asymptotických odhadů složitosti: Definice 7.1.3 Nechť F je množina funkcí f : N → N. Pro danou funkci f ∈ F definujeme množiny funkcí O(f(n)), Ω(f(n)) a Θ(f(n)) takto: • Asymptotické horní omezení funkce f(n) je množina O(f(n)) = {g(n) ∈ F | ∃c ∈ R+ , ∃n0 ∈ N ∀n ∈ N : n ≥ n0 ⇒ 0 ≤ g(n) ≤ c.f(n)}. • Asymptotické dolní omezení funkce f(n) je množina Ω(f(n)) = {g(n) ∈ F | ∃c ∈ R+ , ∃n0 ∈ N ∀n ∈ N : n ≥ n0 ⇒ 0 ≤ c.f(n) ≤ g(n)}. • Asymptotické oboustranné omezení funkce f(n) je množina Θ(f(n)) = {g(n) ∈ F | ∃c1, c2 ∈ R+ , ∃n0 ∈ N ∀n ∈ N : n ≥ n0 ⇒ 0 ≤ c1.f(n) ≤ g(n) ≤ c2.f(n)}. c.f(n) c’.f’(n) g1 g2 n0 n f(n) Příklad 7.1.5 S využitím asymptotických odhadů složitosti můžeme říci, že složitost našeho srovnání řetězců patří do O(n) a složitost insert-sort do O(n2 ). Příklad 7.1.6 • Ukážeme, že platí 2 · n ∈ O(n). Dle definice zvolme c = 3 a n0 = 1. Pak skutečně platí, že ∀n ≥ 1 je 2 · n ≤ 3 · n • Ukážeme, že platí n2 ∈ O(n). Důkaz provedeme sporem. Nechť dle definice ∃c ∈ R+ , ∃n0 ∈ N takové, že ∀n ≥ n0 platí n2 ≤ c·n. Pak také ale platí, že ∀n ≥ n0 je n ≤ c, což je spor. KAPITOLA 7. SLOŽITOST 152 Poznámka 7.1.2 Používá se i zobecnění O-notace, kdy se operátor O může vyskytovat na různých místech aritmetických výrazů. Například výraz 2O(f(n)) označuje množinu funkcí 2g(n) , kde g(n) ∈ O(f(n)). Všimněme si přitom, že 2O(f(n)) = O(2f(n) ): • 2O(f(n)) je množina všech funkcí, jejichž hodnota zůstává pro všechna n větší než nějaké n0 pod 2a.f(n)+b , neboli vlastně pod c a.f(n)+b d , kde a, b, c, d jsou libovolné konstanty takové, že c = 2d , tj. jedná se o exponenciály s libovolným základem. • Naproti tomu O(2f(n) ) zahrnuje jen funkce, jejichž hodnota zůstává pro všechna n větší než nějaké n0 pod a.2f(n) + b pro nějaké konstanty a, b – základem exponenciály je zde vždy 2. Podobně třeba výraz n2 + O(n) označuje množinu polynomů {n2 + g(n) | g(n) ∈ O(n)}. Lze užít i výrazy jako O(f(n))O(g(n)) .O(h(n)), kde se O vyskytuje vícekrát. V uvedeném příkladu se jedná konkrétně o množinu funkcí k(n)l(n) .m(n), kde k(n) ∈ O(f(n)), l(n) ∈ O(g(n)) a m(n) ∈ O(h(n)). Příklad 7.1.7 Rozhodněte a zdůvodněte, zda platí: • n · log(n) ∈ O(n2 ) • n · log(n) ∈ O(n) • 3n ∈ 2O(n) • 6 · n3 + 50 · n2 + 6 ∈ O(n3 − 8 · n2 − n − 5) 7.2 Třídy složitosti 7.2.1 Složitost problémů Přejdeme nyní od složitosti konkrétních algoritmů (Turingových strojů) ke složitost problémů. Třídy složitosti zavádíme jako prostředek ke kategorizaci (vytvoření hierarchie) problémů dle jejich složitosti, tedy dle toho, jak dalece efektivní algoritmy můžeme nahradit pro jejich rozhodování (u funkcí můžeme analogicky mluvit o složitosti jejich vyčíslování). Podobně jako u určování typu jazyka se budeme snažit zařadit problém do co nejnižší třídy složitosti – tedy určit složitost problému jako složitost jeho nejlepšího možného řešení. Poznámka 7.2.1 Omezením této snahy je to, že (jak uvidíme) existují problémy, jejichž řešení je možné do nekonečna významně zrychlovat. Zařazení různých problémů do téže třídy složitosti může odhalit různé vnitřní podobnosti těchto problémů a může umožnit řešení jednoho převodem na druhý (a pragmatické využití např. různých již vyvinutých nástrojů). KAPITOLA 7. SLOŽITOST 153 7.2.2 Třídy složitosti Definice 7.2.1 Mějme dány funkce t, s : N → N a nechť TM , resp. SM , značí časovou, resp. prostorovou, složitost TS M. Definujeme následující časové a prostorové třídy složitosti deterministických a nedeterministických TS: • DTime[t(n)] = {L | ∃ k-páskový DTS M : L = L(M) a TM ∈ O(t(n))}. • NTime[t(n)] = {L | ∃ k-páskový NTS M : L = L(M) a TM ∈ O(t(n))}. • DSpace[s(n)] = {L | ∃ k-páskový DTS M : L = L(M) a SM ∈ O(s(n))}. • NSpace[s(n)] = {L | ∃ k-páskový NTS M : L = L(M) a SM ∈ O(s(n))}. Definici tříd složitosti pak přímočaře zobecňujeme tak, aby mohly být založeny na množině funkcí, nejen na jedné konkrétní funkci. Poznámka 7.2.2 Dále ukážeme, že použití více pásek přináší jen polynomiální zrychlení. Na druhou stranu ukážeme, že zatímco nedeterminismus nepřináší nic podstatného z hlediska vyčíslitelnosti, může přinášet mnoho z hlediska složitosti. Poznámka 7.2.3 Výše uvedené definice tříd jsou třídami výpočetní složitosti rozhodovacích problémů. Studují se však také např. třídy tzv. optimalizačních problémů, u kterých se neptáme, zda daná instance je či není řešením, ale hledáme v určitém smyslu optimální řešení (např. se neptáme, zda daný graf má kliku určité velikosti, ale ptáme se, klika jaké největší velikosti v grafu existuje). Problémy pak mohou být také dále klasifikovány do tříd dle aproximovatelnosti jejich optimálního řešení, existují rovněž pravděpodobnostní třídy složitosti (pro řešení problémů pravděpodobnostními algoritmy) atd (viz např. [9]). Tyto třídy jsou však mimo rozsah tohoto textu. 7.2.3 Časově/prostorově konstruovatelné funkce Třídy složitosti obvykle budujeme nad tzv. časově/prostorově konstruovatelnými funkcemi: • Důvodem zavedení časově/prostorově konstruovatelných funkcí je dosáhnout intuitivní hierarchické struktury tříd složitosti – např. odlišení tříd f(n) a 2f(n) , což, jak uvidíme, pro třídy založené na obecných rekurzívních funkcích nelze. Definice 7.2.2 Funkci t : N → N nazveme časově konstruovatelnou (time constructible), jestliže existuje vícepáskový TS, jenž pro libovolný vstup w zastaví po přesně t(|w|) krocích. Definice 7.2.3 Funkci s : N → N nazveme prostorově konstruovatelnou (space constructible), jestliže existuje vícepáskový TS, jenž pro libovolný vstup w zastaví s využitím přesně s(|w|) buněk pásky. Příklad 7.2.1 Uveďme některé • časově konstruovatelné funkce: f(n) = n log(n), f(n) = n √ n, KAPITOLA 7. SLOŽITOST 154 • časově nekonstruovatelné funkce: f(n) = c, f(n) = log(n), f(n) = n3 , • prostorově konstruovatelné funkce: f(n) = log(n), f(n) = n2 , • prostorově nekonstruovatelné funkce: f(n) = c, f(n) = log log n. Poznámka 7.2.4 Pokud je jazyk L nad Σ přijímán strojem v čase/prostoru omezeném časově/prostorově konstruovatelnou funkcí, pak je také přijímán strojem, který pro každé w ∈ Σ∗ vždy zastaví: • U časového omezení t(n) si stačí předem spočíst, jaký je potřebný počet kroků a zastavit po jeho vyčerpání. • U prostorového omezení spočteme z s(n), |Q|, |∆| maximální počet konfigurací, které můžeme vidět a z toho také plyne maximální počet kroků, které můžeme udělat, aniž bychom cyklili. 7.2.4 Nejběžněji užívané třídy složitosti Deterministický/nedeterministický polynomiální čas: P = ∞ k=0 DTime(nk ) NP = ∞ k=0 NTime(nk ) Deterministický/nedeterministický polynomiální prostor: PSPACE = ∞ k=0 DSpace(nk ) ≡ NPSPACE = ∞ k=0 NSpace(nk ) Poznámka 7.2.5 P je zvlášť důležitou třídou. Vymezuje všechny prakticky dobře řešitelné problémy. Poznámka 7.2.6 Problémy ze třídy PSPACE se často ve skutečnosti neřeší v polynomiálním prostoru – zvyšují se prostorové nároky výměnou za alespoň částečné (např. z O(2n2 ) na O(2n )) snížení časových nároků. 7.2.5 Třídy pod a nad polynomiální složitostí Deterministický/nedeterministický logaritmický prostor: LOGSPACE = ∞ k=0 DSpace(k lg n) NLOGSPACE = ∞ k=0 NSpace(k lg n) Deterministický/nedeterministický exponenciální čas: EXP = ∞ k=0 DTime(2nk ) NEXP = ∞ k=0 NTime(2nk ) Deterministický/nedeterministický exponenciální prostor: EXPSPACE = ∞ k=0 DSpace(2nk ) ≡ NEXPSPACE = ∞ k=0 NSpace(2nk ) 3Funkce f(n) = n není časově zkonstruovatelná, protože úvodní blank nepočítáme jako součást vstupu (někdy se v literatuře můžeme setkat i s jinými přístupy). KAPITOLA 7. SLOŽITOST 155 7.2.6 Třídy nad exponenciální složitostí Det./nedet. k-exponenciální čas/prostor založený na věži exponenciál 22 ... 2 o výšce k: k-EXP = ∞ l=0 DTime(22 ... 2nl ) k-NEXP = ∞ l=0 NTime(22 ... 2nl ) k-EXPSPACE = ∞ l=0 DSpace(22 ... 2nl ) ≡ k-NEXPSPACE = ∞ l=0 NSpace(22 ... 2nl ) ELEMENTARY = ∞ k=0 k-EXP 7.2.7 Vrchol hierarchie tříd složitosti Na vrcholu hierarchie tříd složitosti se pak hovoří o obecných třídách jazyků (funkcí), se kterými jsme se již setkali: • třída primitivně-rekurzívních funkcí PR (implementovatelných pomocí zanořených cyklů s pevným počtem opakování – for i=... to ...), • třída µ−rekurzívních funkcí (rekurzívních jazyků) R (implementovatelných pomocí cyklů s předem neurčeným počtem opakování – while ...) a • třída rekurzívně vyčíslitelných funkcí (rekurzívně vyčíslitelných jazyků) RE. 7.3 Vlastnosti tříd složitosti Prozkoumáme nyní vztahy a vlastnosti zadefinovaných složitostních tříd. 7.3.1 Vícepáskové stroje Zavedení vícepáskového stroje nemělo vliv na vyčíslitelnost. Ani v teorii složitosti nepřinese mnoho nového. Ukážeme, že ke každému vícepáskovému stroji existuje ekvivalentní jednopáskový, jehož výpočty jsou maximálně polynomiálně časově náročnější. Věta 7.3.1 Je-li jazyk L přijímán nějakým k-páskovým DTS Mk v čase t(n), pak je také přijímán nějakým jednopáskovým DTS M1 v čase O(t(n)2 ). Důkaz. (idea)Ukážeme, jak může Mk simulovat M1 v uvedeném čase: • Na pásku stroje M1 zapíšeme zřetězení obsahu pásek stroje Mk. Dále si stroj M1 musí uchovávat informaci o aktuální pozici hlav stroje Mk (například symboly na pásce které jsou čteny hlavami stroje Mk budou podtrženy) a informaci o konci jednotlivých pásek stroje Mk (speciální oddělovače). KAPITOLA 7. SLOŽITOST 156 • V první fázi simulace výpočtu stroje Mk strojem M1 si stroj M1 upraví svoji pásku do požadovaného tvaru. • K simulaci jednoho kroku stroje Mk musí stroj M1 dvakrát přečíst svoji pásku. V prvním průchodu shromáždí informace o symbolech, které byly čteny jednotlivými hlavami stroje Mk. V druhém průchodu patřičně upraví svoji pásku. • Problém nastává, pokud při simulaci stroj Mk zapsal nějaký symbol na do teď prázdné políčko své pásky. V tom případě musí stroj M1 posunout zbytek řetězce na pásce o jedno políčko doprava, aby uvolnil potřebné místo pro nový symbol. • Stroj Mk nemůže mít na žádné pásce víc než t(n) symbolů kde n je délka vstupního řetězce. Tudíž stroj M1 nemůže mít víc než k · t(n) symbolů. Simulace jednoho kroku stroje Mk zabere 4 · k · (t(n)) kroků (dva průchody páskou tam a zpět) plus nanejvýš k · (t(n)) kroků (vytvoření prázdného políčka). Dohromady tedy počet kroků stroje M1 bude v O(k2 ·t(n)2 ). Jelikož k je konstanta nezávislá na vstupu, celková časová složitost stroje M1 je v O(t(n)2 ). 2 Příklad 7.3.1 Ukažte, že L = {w ∈ Σ∗ | w je palindrom } ∈ P. 7.3.2 Determinismus a nedeterminismus Zatímco z hlediska vyčíslitelnosti nepřináší zavedení nedeterminismu nic nového, pro složitost je situace jiná. Ačkoli skutečné vztahy deterministických a nedeterministických tříd nebyly dosud dokázány, zdá se, že nedeterminismus výrazně snižuje zejména časové nároky výpočtu. Jeho sílu dobře ilustruje například následující pohled na výpočet nedeterministického stroje: • Zatímco klasický deterministický stroj krok za krokem výsledek počítá, nedeterministický stroj je prostě může uhodnout, zapsat a po té jen ověřit jeho správnost. Nedeterministický TS dokážeme simulovat strojem deterministickým, avšak jen za cenu exponenciálního nárůstu času: Věta 7.3.2 Je-li jazyk L přijímán nějakým NTS Mn v čase t(n), pak je také přijímán nějakým DTS Md v čase 2O(t(n)) . Důkaz. (idea) Ukážeme, jak může Md simulovat Mn v uvedeném čase: • Očíslujeme si přechody Mn jako 1, 2, ..., k. • Md bude postupně simulovat veškeré možné posloupnosti přechodů Mn (obsah vstupní pásky si uloží na pomocnou pásku, aby ho mohl vždy obnovit; na jinou pásku si vygeneruje posloupnost přechodů z {1, 2, ..., k}∗ a tu si- muluje). KAPITOLA 7. SLOŽITOST 157 • Vzhledem k možnosti nekonečných výpočtů Mn nelze procházet jeho možné výpočty do hloubky – budeme-li je ale procházet do šířky (tj. nejdřív všechny řetězce z {1, 2, ..., k}∗ délky 1, pak 2, pak 3, ...), určitě nalezneme nejkratší přijímající posloupnost přechodů pro Mn, existuje-li. • Takto projdeme nanejvýš O(kt(n) ) cest, simulace každé z nich je v O(t(n)) a tudíž celkem využijeme nanejvýš čas O(kt(n) )O(t(n)) = 2O(t(n)) . 2 Příklad 7.3.2 Ukažte že L = {φ| φ je splnitelné formule v CNF} ∈ NP Vztah determinismu a nedeterminismu je jedním z nejslavnějších otevřených problémů informatiky. Zejména o problému ekvivalence polynomiálních časových tříd P = NP bylo řečeno mnoho. Jeho řešení se však zatím zdá být za hranicemi dnešních možností. Komplikovanost problému naznačují například výsledky, které říkají, že pokud P=NP, nemůže tento vztah být dokázán simulací4 a naopak, pokud P=NP, nemůže být tento výsledek dokázán diagonalizací. Zatímco se zdá, že nedeterminismus přináší značnou výhodu z hlediska časové složitosti výpočtů, v případě prostorové složitosti je situace jiná: Věta 7.3.3 (Savitchův teorém) NSpace[s(n)] ⊆ DSpace[s2 (n)] pro každou prostorově konstruovatelnou funkci s(n) ≥ lg n. Důkaz. Uvažme NTS M = (Q, Σ, Γ, δ, q0, qF ) rozhodující L(M) v prostoru s(n): • Existuje k ∈ N závislé jen na |Q| a |Γ| takové, že pro libovolný vstup w, M projde nanejvýš ks(n) konfigurací o délce max. s(n). • To implikuje, že M provede pro w nanejvýš ks(n) = 2s(n)lg k kroků. • Pomocí DTS můžeme snadno implementovat proceduru test(c, c , i), která otestuje, zda je možné v M dojít z konfigurace c do c v 2i krocích: procedure test(c, c , i) if (i = 0) then return ((c = c ) ∨ (c M c )) else for all configurations c such that |c | ≤ s(n) do if (test(c, c , i − 1) ∧ test(c , c , i − 1)) then return true return false • Všimněme si, že rekurzivním vyvoláváním test vzniká strom o výšce i simulující posloupností svých listů posloupnost 2i výpočetních kroků. • Nyní k deterministické simulaci M postačí projít všechny akceptující konfigurace cF takové, že |cF | ≤ s(n), a ověřit, zda test(co, cf , s(n)lg k ), kde c0 je počáteční konfigurace. • Každé vyvolání test zabere prostor O(s(n)), hloubka rekurze je s(n)lg k = O(s(n)) a tedy celkově deterministicky simulujeme M v prostoru O(s2 (n)). • Dodejme, že s(n) může být zkonstruováno v prostoru O(s(n)) (jedná se o prostorově konstruovatelnou funkci) a tudíž neovlivňuje výše uvedené úvahy. 4nemůže existovat polynomiálně časově ohraničený DTS simulující každý polynomiální NTS KAPITOLA 7. SLOŽITOST 158 2 Důsledkem Savitchova teorému jsou již dříve uvedené rovnosti: • PSPACE ≡ NPSPACE, • k-EXPSPACE ≡ k-NEXPSPACE. 7.3.3 Prostor kontra čas Intuitivně můžeme říci, že zatímco prostor může růst relativně pomalu, čas může růst výrazně rychleji, neboť můžeme opakovaně procházet týmiž buňkami pásky – opačně tomu být zřejmě nemůže (nemá smysl mít nevyužitý prostor). Věta 7.3.4 NSpace[t(n)] ⊆ DTime[O(1)t(n) ] pro každou časově konstruovatelnou funkci t(n) ≥ lg n. Důkaz. Dá se použít do jisté míry podobná konstrukce jako u Savitchova teorému – blíže viz literatura. 2 7.3.4 Uzavřenost vůči doplňku Doplňkem třídy rozumíme třídu jazyků, které jsou doplňkem jazyků dané třídy. Tedy označíme-li doplněk třídy C jako co-C, pak L ∈ C ⇔ L ∈ co-C. U rozhodování problémů toto znamená rozhodování komplementárního problému (prázdnost x neprázdnost apod.). Prostorové třídy jsou obvykle uzavřeny vůči doplňku: Věta 7.3.5 Jestliže s(n) ≥ lg n, pak NSpace(s(n)) = co-NSpace(s(n)). Důkaz. Jedná se o teorém Immermana a Szelepcsényiho – důkaz viz literatura.2 Pro časové třídy je situace jiná: • Některé třídy jako P či EXP jsou uzavřeny vůči doplňku. • U jiných významných tříd zůstává otázka uzavřenosti vůči doplňku otevřená. Proto má smysl hovořit např. i o třídách jako: – co-NP či – co-NEXP. Věta 7.3.6 Třída P je uzavřena vůči doplňku. Důkaz. (idea) Základem je to, že ukážeme, že jestliže jazyk L nad Σ může být přijat DTS M v polynomiálním čase, pak také existuje DTS M , který L rozhoduje v polynomiálním čase, tj. L = L(M ) a existuje k ∈ N takové, že pro každé w ∈ Σ∗ M zastaví v čase O(|w|k ): • M na začátku výpočtu určí délku vstupu w a vypočte p(|w|), kde p(n) je polynom určující složitost přijímání strojem M. Na speciální dodatečnou pásku uloží p(|w|) symbolů. KAPITOLA 7. SLOŽITOST 159 • Následně M simuluje M, přičemž za každý krok umaže jeden symbol z dodatečné pásky. Pokud odebere z této pásky všechny symboly a M by mezitím nepřijal, M abnormálně ukončí výpočet (odmítne). • M evidentně přijme všechny řetězce, které přijme M na to mu stačí p(n) simulovaných kroků a nepřijme všechny řetězce, které by M nepřijal – pokud M nepřijme v p(n) krocích, nepřijme vůbec. M však vždy zastaví v O(p(n)) krocích. 2 7.3.5 Ostrost hierarchie tříd Z dosavadního můžeme shrnout, že platí následující: • LOGSPACE ⊆ NLOGSPACE ⊆ P ⊆ NP • NP ⊆ PSPACE = NPSPACE ⊆ EXP ⊆ NEXP • NEXP ⊆ EXPSPACE = NEXPSPACE ⊆ 2-EXP ⊆ 2-NEXP ⊆ ... • ... ⊂ ELEMENTARY ⊂ PR ⊂ R ⊂ RE5 Řada otázek ostrosti uvedených vztahů pak zůstává otevřená, nicméně z tzv. teorému hierarchie (nebudeme ho zde přesně uvádět, neboť je velmi technický – zájemci je naleznou v literatuře) plyne, že exponenciální ” mezery“ mezi třídami jsou ” ostré“: • LOGSPACE, NLOGSPACE ⊂ PSPACE, • P ⊂ EXP, • NP ⊂ NEXP, • PSPACE ⊂ NEXPSPACE, • EXP ⊂ 2-EXP, ... 7.3.6 Některé další zajímavé výsledky Věta 7.3.7 (Blumův teorém) Pro každou totální vyčíslitelnou funkci f : N → N existuje problém, jehož každé řešení s nějakou složitostí t(n) může být zlepšeno tak, že nové řešení má složitost f(t(n)) pro skoro každé n ∈ N. Důkaz. Viz literatura. 2 V důsledku Blumova teorému tedy existují problémy jejichž řešení se složitostí t(n) je možné donekonečna zrychlovat na lg t(n), lg lg t(n), lg lg lg t(n), ... Nutnost pracovat s časově konstruovatelnými funkcemi, abychom se vyhnuli např. tomu, že DTime[f(n)] = DTime[2f(n) ] pro nějaké f(n), vyjadřuje následující teorém: Věta 7.3.8 (Gap Theorem) Ke každé rekurzívní funkci φ(n) > n existuje rekurzívní funkce f(n) taková, že DTime[φ(f(n))] = DTime[f(n)]. 5Bez důkazu jsme doplnili, že ELEMENTARY ⊂ PR. KAPITOLA 7. SLOŽITOST 160 Důkaz. Viz literatura – založeno na konstrukci funkce f takové, že žádný TS nezastaví pro vstup délky n počtem kroků mezi f(n) a φ(f(n)). 2 7.3.7 R redukce, jazyky C-těžké a C-úplné Až doposud jsme třídy používali jako horní omezení složitosti problémů. Všimněme si nyní omezení dolního – to zavedeme pomocí redukovatelnosti třídy problémů na daný problém. R redukce je (podobně jako v kapitole o vyčíslitelnosti) funkcí, která převádí problém na problém jiný. V teorii složitosti je ale potřeba, aby vyhovovala i jiným požadavkům, než je prostá vyčíslitelnost: Definice 7.3.1 Nechť R je třída funkcí. Jazyk L1 ⊆ Σ∗ 1 je R redukovatelný (přesněji R many-to-one reducible) na jazyk L2 ⊆ Σ∗ 2, což zapisujeme L1 ≤m R L2, jestliže existuje funkce f z R taková, že w ∈ L1 ⇔ f(w) ∈ L2. Pokud se všechny problémy nějaké třídy R redukují na jistý problém, pak je tento problém v oné třídě úplný vzhledem k R redukci (alespoň tak těžký, jako kterýkoliv jiný problém této třídy): Definice 7.3.2 Nechť R je třída funkcí a C třída jazyků. Jazyk L0 je C-těžký (C-hard) vzhledem k R redukovatelnosti, jestliže ∀L ∈ C : L ≤m R L0. Pokud problém těžký pro třídu vzhledem k R redukci navíc do této třídy patří, pak je pro ni úplný (nejtěžší z této třídy): Definice 7.3.3 Nechť R je třída funkcí a C třída jazyků. Jazyk L0 nazveme Cúplný (C-complete) vzhledem k R redukovatelnosti, jestliže L0 ∈ C a L0 je C-těžký (C-hard) vzhledem k R redukovatelnosti. Pro třídy C1 ⊆ C2 a jazyk L, jenž je C2 úplný vůči R redukovatelnosti, platí, že buď C2 je celá R redukovatelná na C1 nebo L ∈ C2 \ C1. 7.3.8 Nejběžnější typy R redukce a úplnosti Uveďme nejběžněji používané typy úplnosti – všimněme si, že je použita redukovatelnost dostatečně silná na to, aby bylo možné najít úplné problémy vůči ní a na druhou stranu nebyly příslušné třídy triviálně redukovány na jejich (možné) podtřídy: • NP, PSPACE, EXP úplnost je definována vůči polynomiální redukovatelnosti (tj. redukovatelnosti pomocí DTS pracujících v polynomiálním čase), • P, NLOGSPACE úplnost definujeme vůči redukovatelnosti v deterministickém logaritmickém prostoru, • NEXP úplnost definujeme vůči exponenciální redukovatelnosti (tj. redukovatelnosti pomocí DTS pracujících v exponenciálním čase). Zvláště důležitá je polynomiální redukce, protože podobně jako třída P vymezuje prakticky řešitelné problémy, polynomiální redukovatelnost odpovídá realizovatelné převoditelnosti problémů. KAPITOLA 7. SLOŽITOST 161 7.4 Příklady složitosti problémů Příklady LOGSPACE problémů: • existence cesty mezi dvěma uzly v neorientovaném grafu. Příklady NLOGSPACE-úplných problémů: • existence cesty mezi dvěma uzly v orientovaném grafu, • 2-SAT (SATisfiability), tj. splnitelnost výrokových formulí tvaru konjunkce disjunkcí dvou literálů (literál je výroková proměnná nebo její negace), např. (x1 ∨ ¬x3) ∧ (¬x2 ∨ x3). Příklady P-úplných problémů: • splnitelnost Hornových klauzulí (p∧q∧...∧t) ⇒ u, kde p, q, ... jsou atomické formule predikátové logiky, • náležitost řetězce do jazyka bezkontextové gramatiky, • následnost uzlů při průchodu grafem do hloubky (pro dané řazení přímých následníků). Příklady NP-úplných problémů: • 3-SAT a obecný SAT – viz dále, • řada grafových problémů, např.: – existence kliky dané velikosti, – existence Hamiltonovské kružnice v neorientovaném grafu, – existence orientované Hamiltonovské kružnice v orientovaném grafu, – barvitelnost: lze daný neorientovaný graf obarvit jistým počtem barev?, – uzlové pokrytí neorientovaného grafu množinou uzlů o určité velikosti (tj. množinou uzlů, se kterou souvisí všechny hrany), – ... • problém obchodního cestujícího, • knapsack – máme položky s cenou a hodnotou, maximalizujeme hodnotu tak, aby cena nepřekročila určitou mez. Příklady co-NP-úplných problémů: • ekvivalence regulárních výrazů bez iterace. Příklady PSPACE-úplných problémů: • ekvivalence regulárních výrazů, • náležitost řetězce do jazyka kontextové gramatiky, • model checking formulí lineární temporální logiky (LTL – výroková logika doplněná o temporální operátory until, always, eventually, next-time) s ohledem na velikost formule, • nejlepší tah ve hře Sokoban. KAPITOLA 7. SLOŽITOST 162 Příklady EXP-úplných problémů: • nejlepší tah v šachu (zobecněno na šachovnici n × n), • model checking procesů s neomezeným zásobníkem (rekurzí) vůči zafixované formuli logiky větvícího se času (CTL) – tj. EXP ve velikosti procesu. • inkluze pro tzv. visibly push-down jazyky (operace push/pop, které provádí přijímající automat jsou součástí vstupního řetězce). Příklady EXPSPACE-úplných problémů: • ekvivalence regulárních výrazů doplněných o operaci kvadrát (tj. r2 ). k-EXP / k-EXPSPACE: • rozhodování splnitelnosti formulí Presburgerovy aritmetiky – tj. celočíselné aritmetiky se sčítáním, porovnáváním (ne násobením – to vede na tzv. Peanovu aritmetiku, která je již nerozhodnutelná) a kvantifikací prvního řádu (např. ∀x, y : x ≤ x + y) je problém, který je v 3-EXP (2-EXPSPACE- úplný). Problémy mimo ELEMENTARY: • ekvivalence regulárních výrazů doplněných o negaci, • rozhodování splnitelnosti formulí logiky WS1S – celočíselná aritmetika s operací +1 a kvantifikací prvního a druhého řádu (tj. pro každou/existuje hodnota, resp. množina hodnot, taková, že ...), • verifikace dosažitelnosti v tzv. Lossy Channel Systems – procesy komunikující přes neomezenou, ale ztrátovou frontu (cokoliv se může kdykoliv ztratit). 7.5 SAT-problém SAT-problém (problém splnitelnosti booleovských formulí) byl prvním problémem, jehož NP-úplnost vzhledem k polynomiální redukci se podařilo dokázat. V mnoha případech jej lze s úspěchem použít k důkazu NP-těžkosti. 7.5.1 Polynomiální redukce Definice 7.5.1 Polynomiální redukce jazyka L1 nad abecedou Σ1 na jazyk L2 nad abecedou Σ2 je funkce f : Σ∗ 1 → Σ∗ 2, pro kterou platí: 1. ∀w ∈ Σ∗ 1 : w ∈ L1 ⇔ f(w) ∈ L2 2. f je Turingovsky vyčíslitelná v polynomiálním čase Existuje-li polynomiální redukce jazyka L1 na L2, říkáme, že L1 se redukuje na L2 a píšeme L1 ≤m P L2. Věta 7.5.1 Je-li L1 ≤m P L2 a L2 je ve třídě P, pak L1 je ve třídě P. Důkaz. Nechť Mf je Turingův stroj, který provádí redukci f jazyka L1 na L2 a nechť p(x) je jeho časová složitost. Pro libovolné w ∈ L1 výpočet f(w) vyžaduje nanejvýš p(|w|) kroků a produkuje výstup maximální délky p(|w|) + |w|. Nechť KAPITOLA 7. SLOŽITOST 163 M2 přijímá jazyk L2 v polynomiálním čase daném polynomem q(x). Uvažujme Turingův stroj, který vznikne kompozicí → Mf M2. Tento stroj přijímá jazyk L1 tak, že pro každé w ∈ L1 udělá stroj → Mf M2 maximálně p(|w|)+q(p(|w|)+|w|) kroků, což je polynomem ve |w| a tedy L1 leží ve třídě P. 2 Příklad 7.5.1 Funkce f : {x, y}∗ → {x, y, z}∗ definována jako f(v) = vzv je polynomiální redukcí jazyka L1 = {w|w je palindrom nad {x, y}} na jazyk L2 = {wzwR |w ∈ {x, y}∗ }. Předchozí věta nám dává praktickou možnost jak ukázat, že určitý jazyk je ve třídě P. Navíc, přeformulujeme-li tuto větu takto: ” Jestliže platí L1 ≤m P L2 a L1 neleží v P, pak L2 také neleží v P“, můžeme dokazovat, že určitý jazyk neleží v P. 7.5.2 Problém splnitelnosti - SAT problém Nechť V = {v1, v2, . . . , vn} je konečná množina Booleovských proměnných (prvotních formulí výrokového počtu). Literálem nazveme každou proměnnou vi nebo její negaci vi. Klauzulí nazveme výrokovou formuli obsahující pouze literály spojené výrokovou spojkou ∨ (nebo). Příklady klauzulí: v1 ∨ v2, v2 ∨ v3, v1 ∨ v3 ∨ v2. SAT-problém lze formulovat takto: Je dána množina proměnných V a množina klauzulí nad V . Je tato množina klauzulí splnitelná? Každý konkrétní SAT-problém můžeme zakódovat jediným řetězcem takto: Nechť V = {v1, v2, . . . , vn}, každý literál vi zakódujeme řetězcem délky m, který obsahuje samé 0 s výjimkou i-té pozice, která obsahuje symbol p, jde-li o literál vi, nebo n, jde-li o literál vi. Klauzuli reprezentujeme seznamem zakódovaných literálů oddělených symbolem /. SAT-problém bude seznam klauzulí uzavřených v aritmetických závorkách. Příklad 7.5.2 SAT-problém obsahuje proměnné v1, v2, v3 a klauzule v1 ∨v2, v2 ∨ v3, v1 ∨ v3 ∨ v2 bude reprezentována řetězcem: (p00/0n0)(0p0/00p)(n00/00n/0p0) Označme LSAT jazyk obsahující řetězce tohoto typu, které reprezentují splnitelné množiny klauzulí. Řetězec (p00/0n0)(0p0/00p)(n00/00n/0p0) je prvkem LSAT (v1 = F, v2 = F, v3 = T), na rozdíl od řetězce (p00/0p0)(n00/0p0)(p00/0n0) (n00/0n0), který je kódem nesplnitelné množiny klauzulí v1 ∨ v2, v1 ∨ v2, v1 ∨ v2, v1 ∨ v2. Přiřazení pravdivostních hodnot budeme reprezentovat řetězcem z {p, n}+ , kde p v i-té pozici představuje přiřazení vi ≈ true a n v i-té pozici představuje přiřazení vi ≈ false. Pak test, zda určité hodnocení je modelem množiny klauzulí (množina klauzulí je pro toto hodnocení splněna), je velmi jednoduchý a ilustruje ho obrázek: v =true v =false v =false 1 2 3 n n p n n pn n pn n p (p00/0n0) (0p0/00p) (n00/00n/0p0) KAPITOLA 7. SLOŽITOST 164 Na uvedeném principu můžeme zkonstruovat nedeterministický Turingův stroj, který přijímá jazyk LSAT v polynomiálním čase. Zvolíme 2-páskový Turingův stroj, který: 1. začíná kontrolou, zda vstup reprezentuje množinu klauzulí, 2. na 2. pásku vygeneruje řetězec z {n, p}m nedeterministickým způsobem, 3. posouvá hlavu na 1. pásce a testuje, zda pro dané ohodnocení (na 2. pásce) je množina klauzulí splnitelná. Tento proces může být snadno implementován s polynomiální složitostí přijetí v závislosti na délce vstupního řetězce a tedy LSAT ∈ NP. Věta 7.5.2 Cookův teorém: Je-li L libovolný jazyk z NP, pak L ≤m P LSAT . Důkaz. Protože L ∈ NP, existuje nedeterministický Turingův stroj M a polynom p(x) tak, že pro každé w ∈ L stroj M přijímá w v maximálně p(|w|) krocích. Jádro důkazu tvoří konstrukce polynomiální redukce f z L na LSAT : Pro každý řetězec w ∈ L bude f(w) množina klauzulí, které jsou splnitelné, právě když M přijímá w. 2 Věta 7.5.3 SAT je NP-úplný vzhledem k polynomiální redukci. Důkaz. Přímo z předchozího. 2 7.5.3 NP-úplné jazyky Po objevení Cookova teorému se ukázalo, že mnoho dalších NP jazyků má vlastnost podobnou jako LSAT , t.j. jsou polynomiálními redukcemi ostatních NP ja- zyků. Tyto jazyky se – jak již víme – nazývají NP-úplné (NP-complete) jazyky. Kdyby se ukázalo, že libovolný z těchto jazyků je v P, pak by muselo platit P = NP; naopak důkaz, že některý z nich leží mimo P by znamenalo P ⊂ NP. 7.5.4 Význačné NP-úplné problémy • Satisfiability: Je boolovský výraz splnitelný? • Clique: Obsahuje neorientovaný graf kliku velikosti k? • Vertex cover: Má neorientovaný graf dominantní množinu mohutnosti k? • Hamilton circuit: Má neorientovaný graf Hamiltonovskou kružnici? • Colorability: Má neorientovaný graf chromatické číslo k? • Directed Hamilton circuit: Má neorientovaný graf Hamiltonovský cyklus? • Set cover: Je dána třída množin S1, S2, . . . , Sn. Existuje podtřída k množin Si1 , Si2 , . . . , Sik taková, že k j=1 Sij = n j=1 Sj ? • Exact cover: Je dána třída množin S1, S2, . . . , Sn. Existuje množinové pokrytí (set cover) tvořené podtřídou po dvojicích disjunktních množin? KAPITOLA 7. SLOŽITOST 165 7.5.5 Použití redukcí k důkazu úplnosti Příklad 7.5.3 Dokážeme, že problém 3SAT ={φ| splnitelné formule φ v CNF obsahující v každé klauzuli nanejvýš 3 literály } je NP-úplný. Musíme ukázat: • a) 3SAT ∈ NP NTS si nedeterministicky zvolí přiřazení jednotlivým proměnným v 3SAT formuli a v polynomiálním čase ověří, zda jde o splňující přiřazení. • b) SAT ≤p 3SAT Zkonstruujeme polynomiálně vyčíslitelnou funkci f, pro kterou platí: A ∈ SAT ⇔ f(A) ∈ 3SAT Funkce f pracuje následovně: Nechť K = (a1, a2, a3, ....an) je klauzule v SAT která má víc než 3 literály. Klauzuli K nahradíme klauzulemi K1 = (a1, a2, b) a K2 = (¬b, a3, ..., an), kde literál b se nevyskytuje v původní formuli. Je zřejmé, že platí: K1 ∪ K2 je splnitelná ⇔ K je splnitelná a navíc klauzule K2 má o jeden literál méně než původní klauzule K. Analogicky postupujeme, dokud formule obsahuje klauzule obsahující více než 3 literály. Je zřejmé, že funkce f je polynomiálně vyčíslitelná a navíc pro ni platí výše uvedený vztah. Příklad 7.5.4 Dokážeme, že problém KLIKA = {(G, k)| G obsahuje úplný podgraf tvořený k vrcholy} je NP-úplný Musíme ukázat: • a) KLIKA ∈ NP NTS si nedeterministicky zvolí k vrcholů a v polynomiálním čase ověří zda tvoří úplný podgraf. • b) SAT ≤p KLIKA Zkonstruujeme polynomiálně vyčíslitelnou funkci f, pro kterou platí: A ∈ SAT ⇔ f(A) ∈ KLIKA Funkce f vytvoří z formule φ v CNF graf G a číslo k takové, že formule φ je splnitelná, právě tehdy když graf G obsahuje úplný podgraf tvořený k vrcholy. Číslo k odpovídá počtu klauzulí ve formuli. Vrcholy grafu G odpovídají literálům vyskytujícím se ve formuli. Hrana v G mezi dvěma vrcholy, které odpovídají dvěma literálům, existuje právě tehdy, když tyto literály nejsou komplementární a nacházejí se ve dvou různých klauzulích. ⇐: Předpokládejme, že formule φ je splnitelná a funkce H : {x1, . . . , xn} → {0, 1} je přiřazení, které splňuje φ. Při tomto přiřazení existuje v každé klauzuli aspoň jeden literál, který má po tomto přiřazení hodnotu 1. Mezi každými dvěma vrcholy odpovídajícími těmto literálům existuje hrana, jelikož nejsou komplementární a nacházejí se v různých klauzulích. Tudíž vzniklý graf patří do KLIKY . KAPITOLA 7. SLOŽITOST 166 ⇒: Předpokládejme že vrcholy k1, . . . , kk jsou vrcholy grafu, které tvoří úplný podgraf. Jelikož mezi každými dvěma vrcholy je hrana, musí být odpovídající literály v navzájem různých klauzulích a zároveň nemohou být komplementární. Tudíž těmto literálům můžeme přiřadit hodnotu 1 a dostaneme splňující přiřazení pro φ. Turingovy stroje jsou často používány také pro popis a klasifikaci časové a paměťové složitosti složitosti problémů (algoritmů). K nejdůležitějším složitostním třídám problémů (jazyků) patří třídy P, NP a NPC, avšak i ostatní třídy mají význam pro charakterizaci obtížnosti výpočtu. Reprezentativním problémem třídy NPC je SAT problém. 7.6 Cvičení Příklad 7.6.1 1. Dokažte, že problém DoubleSat = {φ| formule φ v CNF která má dvě splnitelné přiřazení } je NP-úplný. 2. Dokažte, že problém rozhodnout, zda existuje obarvení neorientovaného grafu třemi barvami, tak aby každé dva sousední vrcholy měly různou barvu je NP- úplný. 3. Uvažme problém 2SAT. Rozhodněte, zda je NP úplný nebo leží v P. Příklad 7.6.2 1. Definujte časovou a prostorovou složitost výpočtu Turingova stroje nad daným jazykem. 2. Proč se zavádí asymptotické omezení složitosti? Pro danou funkci f definujte množinu funkcí O(f(n)), Ω(f(n)) a Θ(f(n)). 3. Definujte následující složitostní třídy P, NP, PSPACE, LOGSPACE, NLOGSPACE a uveďte příklady problémů patřící do výše uvedených tříd. 4. Uveďte jaký vliv má použití vícepáskových TS a nedeterministických TS na složitost výpočtů. 5. Vysvětlete Savitchův teorém a jeho význam. 6. Uveďte hierarchii složitostních tříd a zamyslete se na ostrostí jednotlivých inkluzí. 7. Definujte obecně pojmy redukce, těžkost a úplnost. Dále definujte polynomiální redukci a vysvětlete na příkladu její použití. 8. Definujte pojem NP-úplnost a uveďte příklady problémů, které jsou NP- úplné. Literatura [1] Aho, A. V, Ullman, J. D.: The theory of parsing, translation and compiling, EngelWood Cliffs, New Jersey, Prentice-Hall 1972. [2] Kolář, J.: Algebra a grafy, Skriptum ES ČVUT, Praha, 1982. [3] Kozen, D. C.: A Completeness Theorem for KleeneAlgebras and the Algebra of Regular Events, Technical Report TR 90–1123, 1990. [4] Kozen, D. C.: Automata and Computability, Springer-Verlag, New York, Inc, 1997. ISBN 0-387-94907-0 [5] Rábová, Z., Češka, M.: Základy systémového programování I., Učební texty vysokých škol. Ediční středisko VUT Brno, 1979. [6] Rábová, Z., Češka, M., Honzík, J. M., Hruška, T.: Programovací techniky, Učební texty vysokých škol. Ediční středisko VUT Brno, 1985. [7] Černá, I., Křetínský, M., Kučera, A.: Automaty a formální jazyky I, učební text FI MU, Brno, 1999. [8] Hopcroft, J.E., Motwani, R., Ullman, J.D.: Introduction to Automata Theory, Languages, and Computation, Addison Wesley, 2. vydání, 2000. ISBN 0-201- 44124-1 [9] Gruska, J.: Foundations of Computing, International Thomson Computer Press, 1997. ISBN 1-85032-243-0 [10] Bovet, D.P., Crescenzi, P.: Introduction to the Theory of Complexity, Prentice Hall Europe, Pearson Education Limited, 1994. ISBN 0-13-915380-2 167