Algorithmentheorie Skript zur Vorlesung SS 2006 Fassung vom 21.03.2006 Martin Dietzfelbinger Technische Universität Ilmenau Fakultät für Informatik und Automatisierung Fachgebiet Komplexitätsheorie und Effiziente Algorithmen Inhaltsverzeichnis Literaturverzeichnis 1 0 Vorbemerkungen 3 0.1 Fragestellung und Überblick . . . . . . . . . . . . . . . . . . . . . . . . . . 3 0.2 Grundbegriffe: Alphabete, Sprachen und Probleme . . . . . . . . . . . . . . 6 0.3 Mathematische Grundbegriffe . . . . . . . . . . . . . . . . . . . . . . . . . 12 0.3.1 Abzählbarkeit und Überabzählbarkeit . . . . . . . . . . . . . . . . . 12 1 Entscheidbarkeit und Berechenbarkeit 1.1 15 Registermaschinen, Turingmaschinen und Rekursivität . . . . . . . . . . . 15 1.1.1 Registermaschinen . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.1.2 Turingmaschinen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 1.2 Programmiertechniken und Varianten von Turingmaschinen . . . . . . . . . 39 1.3 Nichtdeterministische Turingmaschinenund Chomsky-0-Grammatiken . . . 54 1.3.1 Nichtdeterministische Turingmaschinen . . . . . . . . . . . . . . . . 54 1.3.2 Turingmaschinen und Chomsky-0-Grammatiken . . . . . . . . . . . 66 1.3.3 Linear beschränkte Automaten undChomsky-1-Grammatiken . . . . 71 1.4 Struktur- und Abschlusseigenschaften . . . . . . . . . . . . . . . . . . . . . 76 1.5 Äquivalenz von Turingmaschinen und Registermaschinen . . . . . . . . . . 84 1.6 1.5.1 Simulation von Turingmaschinen auf Registermaschinen . . . . . . . 84 1.5.2 Simulation von Registermaschinen auf Turingmaschinen . . . . . . . 87 1.7 Zur Bezeichnung Rekursive Funktionen“ und Rekursive Mengen“ . . . . . 92 ” ” Die Churchsche These . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 1.8 Universelle Turingmaschinen . . . . . . . . . . . . . . . . . . . . . . . . . . 100 1.9 Unentscheidbare Probleme . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 1.9.1 Existenz von unentscheidbaren Sprachen . . . . . . . . . . . . . . . 105 i 1.9.2 Eine unentscheidbare rekursiv aufzählbare Sprache . . . . . . . . . 106 1.9.3 Die Unentscheidbarkeit des Halteproblems . . . . . . . . . . . . . . 108 1.9.4 Reduzierbarkeit und die Reduktionsmethode . . . . . . . . . . . . . 109 1.10 Unentscheidbarkeit semantischer Fragen . . . . . . . . . . . . . . . . . . . 116 1.10.1 Der Satz von Rice . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 1.10.2 Semantische Fragen über Programme . . . . . . . . . . . . . . . . . 120 1.10.3 Unmöglichkeit von Zertifikaten für Programme . . . . . . . . . . . . 121 1.11 Das Postsche Korrespondenzproblem . . . . . . . . . . . . . . . . . . . . . 125 1.12 Unentscheidbare Fragen bei Grammatiken . . . . . . . . . . . . . . . . . . 132 2 Die Theorie der NP-vollständigen Probleme 139 2.1 Polynomiell zeitbeschränkte Turingmaschinen . . . . . . . . . . . . . . . . 141 2.2 Polynomiell zeitbeschränkte NTMn . . . . . . . . . . . . . . . . . . . . . . 144 2.3 Optimierungsprobleme und Sprachen in NP . . . . . . . . . . . . . . . . . 146 2.4 Polynomialzeitreduktionen und NP-Vollständigkeit . . . . . . . . . . . . . 154 2.5 Der Satz von Cook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 2.6 Einige NP-vollständige Probleme . . . . . . . . . . . . . . . . . . . . . . . 172 ii Literaturverzeichnis Lehrbücher zum Stoff der Vorlesung: 1. A. Asteroth, C. Baier: Theoretische Informatik. Eine Einführung in Berechenbarkeit, Komplexität und formale Sprachen mit 101 Beispielen, Pearson Studium, 2002. 2. N. Blum: Theoretische Informatik — Eine anwendungsorientierte Einführung, 2. Auflage, Oldenbourg, 2001. 3. J. Hopcroft, R. Motwani, J. Ullman: Introduction to Automata Theory, Languages, and Computation, Second Edition, Addison-Wesley, 2001. 4. (Deutsche Fassung) J. Hopcroft, R. Motwani, J. Ullman: Einführung in die Automatentheorie, Formale Sprachen und Komplexitätstheorie, 2., überarbeitete Auflage, Pearson Studium, 2002. 5. U. Schöning: Theoretische Informatik — kurzgefasst, 4. Auflage, Spektrum Akademischer Verlag, 2001. 6. J. Hromkovič, Theoretische Informatik: Berechenbarkeit, Komplexitätstheorie, Algorithmik, Kryptographie. Eine Einführung, 2. Auflage, Teubner, 2004. 7. G. Vossen, K.-U. Witt: Grundkurs Theoretische Informatik, 3., erweiterte Auflage, Vieweg, 2004. 8. K. Wagner: Theoretische Informatik: Eine kompakte Einführung, 2. Auflage, Springer, 2003. 9. I. Wegener: Theoretische Informatik — eine algorithmische Einführung, 2. Auflage, Teubner, 1999. 10. I. Wegener: Kompendium Theoretische Informatik — eine Ideensammlung, Teubner, 1996. 1 Weiterführende, ergänzende Literatur: 1. T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein: Introduction to Algorithms, 2nd Edition, MIT Press, 2001. 2. I. Wegener: Komplexitätstheorie. Grenzen der Effizienz von Algorithmen, Springer, 2003. 3. C. Papadimitriou: Computational Complexity, Addison-Wesley, 1994. 2 Kapitel 0 Vorbemerkungen 0.1 Fragestellung und Überblick Wir skizzieren hier kurz den Stoff der Vorlesung Algorithmentheorie“ (3. Semester) und ” motivieren die behandelten Fragestellungen. Die Vorlesung zerfällt in zwei große Teile: Berechenbarkeitstheorie und Theorie der NPVollständigkeit. Im ersten Teil geht es um die Frage, welche Probleme man mit Rechnern prinzipiell lösen kann und welche nicht. Man beschränkt sich der Einfachheit halber (aber ohne Möglichkeiten für eine tiefe Theorie auszuschließen) auf die Aufgabenstellungen, Funktionen zu berechnen und Entscheidungsprobleme zu lösen. Eine typische, für die Informatik zentrale Art von Entscheidungsproblem ist es z. B., zu einer gegebenen ASCIIDatei prog.pas festzustellen, ob diese ein syntaktisch korrektes Pascal-Programm enthält, das seinen Input aus einer oder mehreren Eingabedateien entnimmt. (Analoge Fragestellungen gibt es für alle anderen Programmiersprachen.) Dies entspricht offenbar dem Problem festzustellen, ob der Inhalt von prog.pas zu der Sprache LPascal aller syntaktisch korrekten Pascal-Programme gehört. Wir wissen, dass jeder Pascal-Compiler diese Aufgabe löst (und noch viel mehr). Eine andere, ebenso interessante Fragestellung wäre, ob das in prog.pas gespeicherte Programm syntaktisch korrekt ist und bei der Ausführung, z. B. mit einer Textdatei daten.txt als externem Input, nach endlicher Zeit anhält und eine Ausgabe liefert. (Diese Frage nennt man das Halteproblem für Pascal-Programme.) Es ist klar, dass es wünschenswert wäre, ein Programm zu haben, das mit prog.pas und daten.txt als Inputdateien diese Frage beantwortet. Es ist ein Ziel der Vorlesung, nachzuweisen, dass es kein solches Programm geben kann — man sagt, das Halteproblem für Pascal-Programme sei unentscheidbar. Ebenso stellen sich andere wichtige Fragestellungen, die sich auf die Semantik von Programmen beziehen, als unentscheidbar heraus, zum Beispiel die Frage nach der Äquivalenz von Programmen ( ist das Ein-/Ausgabeverhalten ” der Programme in prog1.pas und prog2.pas identisch?“) oder nach der Redundanz von Funktionsdefinitionen ( führt die Ausführung des Programms in prog.pas zum Aufruf ” der Funktion mit Namen f?“). 3 Zur Einstimmung geben wir eine Argumentation dafür, dass das Halteproblem für PascalProgramme nicht von Pascal-Programmen gelöst werden kann. Dabei handelt es sich wohlgemerkt nicht um einen mathematisch sinnvollen Beweis, weil wir Eigenschaften von Pascal-Compilern, von Laufzeit- und Dateisystemen in einem gedachten Computer(system) ziemlich freihändig benutzen, ohne sie zu formalisieren. Außerdem wissen wir (einstweilen) nicht, ob es nicht Algorithmen gibt, die nicht als Pascal-Programme formuliert werden können. Wir sagen, ein Pascal-Programm P löst das Halteproblem für Pascal-Programme“, wenn ” P folgendes Ein-/Ausgabeverhalten hat: P erhält zwei (read-only) Textdateien d1.txt und d2.txt als Eingabe und liefert als einzige Ausgabe (auf der Standard-Ausgabe) den Buchstaben J“ (für ja“), wenn d1.txt den Text eines korrekten Pascal-Programmes Q ” ” enthält, das mit d2.txt als einziger Eingabedatei irgendwann anhält; P liefert als Ausgabe den Buchstaben N“ (für nein“), wenn d1.txt kein korrektes Pascal-Programm enthält ” ” oder das in d1.txt gegebene Pascal-Programm mit d2.txt als Eingabe nie anhält. Behauptung: Es gibt kein Pascal-Programm, das das Halteproblem für Pascal-Programme löst. Beweis“: Indirekt. Angenommen, P sei ein Pascal-Programm, das das Halteproblem für ” Pascal-Programme löst. (Wir müssen nun einen Widerspruch herleiten.) Wir stellen uns vor, P sei als Text gegeben, und bauen P ein wenig um, in 2 Schritten. Im ersten Schritt erzeugen wir aus (dem Text von) P ein neues Pascal-Programm P0 mit folgendem Verhalten: P0 erhält eine Textdatei d.txt als Eingabe. Mit Hilfe von StandardLese- und Schreibfunktionen generiert P0 zwei Textdateien d1.txt und d2.txt, die beide denselben Inhalt haben wie d.txt. Dann läuft das Programm P ab, mit Eingabedateien d1.txt und d2.txt. (Ist es sinnvoll“, in die beiden Eingabestellen von P, die ja eigentlich ein Programm und ” einen Eingabetext erwarten, identische Texte einzugeben? Auf den ersten Blick nicht, aber es gibt Programme Q, bei denen ein solches Einsetzen sinnvoll ist — z. B. könnte d.txt einen in Pascal geschriebenen Compiler Q enthalten, den man natürlich auch mit seinem eigenen Programmtext als Eingabe testen könnte. Unbestreitbar ist jedenfalls, dass man P0 leicht aus P gewinnen kann.) Nun erzeugen wir aus P0 durch weiteren Umbau noch ein Programm P00 . Dieses verhält sich so: P00 erhält eine Textdatei d.txt als Eingabe. Es rechnet wie P0 , bis P0 einen Buchstaben auf die Standardausgabe schreibt. Diese Ausgabe wird nicht vorgenommen, sondern abgefangen“, und der geschriebene Buchstabe wird inspiziert. Nach Konstruktion von P0 ” und der Annahme über das Verhalten von P muss dies immer passieren, und der Buchstabe ist J“ oder N“. ” ” Fall J: Die Ausgabe ist J“. Dann geht P00 in eine Endlosschleife“, d. h. ruft eine Prozedur ” ” auf, deren Rumpf begin i:=0; while (i=0) do i:=0 end lautet. Dies hat natürlich den Effekt, dass P00 nie hält. Fall N: Die Ausgabe ist N“. Dann hält P00 an, ohne eine Ausgabe zu erzeugen. ” Es sollte klar sein, dass man aus dem Programmtext für P0 den für P00 leicht erhalten 4 kann. Nun schreiben wir Kopien des Programmtextes von P00 in die Dateien d1.txt und d2.txt und starten (die lauffähige Version von) P mit diesen Dateien als Eingabe. Nach dem angenommenen Verhalten von P gibt es zwei Fälle: 1. Fall : Die Ausgabe ist J“. Nach der Konstruktion von P0 heißt dies, dass P0 mit dem ” Programmtext von P00 in der Eingabedatei d.txt gestartet ebenfalls J“ ausgibt. Dies ” heißt, nach der Konstruktion von P00 , dass P00 auf Eingabe d.txt (mit dem Text von P00 ) in eine Endlosschleife gerät, also nicht hält. — In diesem Falle liefert P also nicht die versprochene Ausgabe. 2. Fall : Die Ausgabe ist N“. Dann gibt P0 mit dem Programmtext von P00 in d.txt ge” startet ebenfalls N“ aus. Nach Konstruktion von P00 hält P00 mit Eingabe d.txt (mit dem ” Text von P00 ) ohne Ausgabe an. — Auch in diesem Falle liefert P nicht die versprochene Ausgabe. Welcher Fall auch immer eintritt: P wird auf der beschriebenen Eingabe (zwei Kopien von P00 ) falsch antworten. Das ist der gewünschte Widerspruch: es kann kein Programm P geben, das das Halteproblem für Pascal-Programme löst. Diese Überlegung sieht wohl gekünstelt und verwickelt aus, aber sie sitzt im Kern aller Unentscheidbarkeitsresultate der Berechenbarkeitstheorie, und ist es daher wert, genauer angesehen zu werden. In diesem Zusammenhang wird auch empfohlen, im Abschnitt Mathematische Grundlagen“ die Anmerkungen zu Diagonalisierung“ zu studieren.1 ” ” Um eine Aussage der Art Für das Entscheidungsproblem P gibt es keinen Algorithmus und kein Com” puterprogamm“ mathematisch präzise formulieren und beweisen zu können, muss man das Konzept Ent” scheidungsproblem“ formalisieren (das ist nicht sehr schwer) und die Idee des Algorith” mus“ mathematisch präzise fassen — das ist etwas schwieriger, was man schon daran sehen kann, dass es einige berühmte Mathematiker (Turing, Gödel, Church, Kleene, Markoff) ziemlich lange beschäftigt hat — und schließlich die Beziehung dieses Algorithmusbegriffs zu Computerprogrammen klären. Wir gehen dazu so vor: Wir besprechen einige mögliche Formalisierungen des Algorithmusbegriffs, manche näher an der Computerstruktur wie wir sie kennen (Registermaschine), manche weiter weg (Turingmaschine, µ-rekursive Funktionen), und stellen ihre Äquivalenz fest. Eine dieser Formalisierungen ist also so gut wie jede andere. Wir wählen dann eine, die technisch gut handhabbar ist, nämlich die Turingmaschinen-Berechenbarkeit, und beweisen mit ihr als technischer Grundlage die Unentscheidbarkeit des Halteproblems. 1 Wenn man das Argument nochmals liest, stellt man fest, dass unser Vorgehen konstruktiv ist in folgendem Sinn: Für jedes Pascal-Programm P, das zwei Textfiles als Input hat, konstruieren wir (durch Diagonalisierung“) ein Programm P00 , das ein Beleg dafür ist, dass P nicht das Halteproblem löst. ” 5 Mit Hilfe des Begriffs der Reduktion zwischen Berechnungsproblemen kann dann die Unentscheidbarkeit vieler weiterer Probleme bewiesen werden, insbesondere aller Probleme, die die Semantik, oder kurz das Ein-/Ausgabeverhalten, von Programmen betreffen. Nebenbei kann man mit Hilfe des Turingmaschinenmodells die Maschinenmodelle identifizieren, die den Stufen 0 und 1 der Chomsky-Hierarchie entspricht (Akzeptierung durch beliebige Turingmaschinen bzw. durch nichtdeterministische Turingmaschinen mit linear beschränktem Speicherplatz). Das Turingmaschinenmodell ist auch eine gute Grundlage für die Untersuchungen im zweiten Teil der Vorlesung. Beim Konzept der prinzipiellen Berechenbarkeit und Entscheidbarkeit spielt die Rechenzeit keine Rolle. Hier wollen wir untersuchen, ob wir Probleme, die Algorithmen mit vernünftigen“ Laufzeiten wie O(n), O(n log n) oder O(n2 ) haben (allge” meiner: polynomielle Laufzeit“), wie etwa das Sortierproblem, unterscheiden können von ” Problemen, die solche Algorithmen nicht haben. Hierzu betrachtet man Entscheidungsprobleme, die auf gewöhnlichen Rechnern in polynomieller Rechenzeit gelöst werden können. Wir diskutieren, wieso Turingmaschinen mit polynomieller Rechenzeit ein gutes abstraktes Modell für alle solchen Verfahren sind. Das Konzept der NP-Vollständigkeit von Entscheidungsproblemen, das wiederum auf der Basis des Turingmaschinenmodells definiert werden kann, indem man Nichtdeterminismus hinzufügt, erlaubt es, eine sehr wichtige Klasse von Entscheidungs- und Berechnungsproblemen zu identifizieren, die vermutlich nicht von gewöhnlichen, deterministischen Polynomialzeit-Turingmaschinen gelöst werden können, und daher vermutlich keinen effizienten Algorithmus haben. Hierzu gehören viele Graphenprobleme (z. B. das in Kap. 0.2 beschriebene Hamiltonkreisproblem oder das berühmte Problem des Handlungsreisenden, auch als TSP-Problem bekannt), Probleme aus dem Gebiet des Schaltungsentwurfs (z. B. das Äquivalenzproblem für Boolesche Schaltungen), oder Probleme aus der Zahlentheorie (die Frage nach der Lösbarkeit von linearen Ungleichungssystemen, wenn die Koeffizienten ganzzahlig sind und die Lösungen aus natürlichen Zahlen bestehen sollen) und vielen anderen Gebieten der Informatik und der Anwendungsgebiete. Eine genauere Untersuchung der Welt der NP-vollständigen Probleme wird in der Vorlesung Komplexitätstheorie“ vorgenommen. ” 0.2 Grundbegriffe: Alphabete, Sprachen und Probleme 0.2.1 Vereinbarung N = {0, 1, 2, . . .} bezeichnet die Menge der natürlichen Zahlen. 0.2.2 Definition Für eine beliebige Menge A, A 6= ∅, bezeichnet Seq(A) die Menge der endlichen Folgen oder Tupel“ in A, d. h. die Menge ” {(a1 , . . . , an ) | n ≥ 0, a1 , . . . , an ∈ A}. 6 Wenn zum Beispiel A = N ist, dann sind (0, 6, 4, 6), (3), und () (die leere Folge) Elemente von Seq(A). Beachte, dass AN = {(ai )i≥0 | ai ∈ A für i ≥ 0} die Menge der unendlichen Folgen in A ist. Wir werden uns insbesondere für Tupel aus natürlichen Zahlen interessieren, also Seq(N). Eines unserer Rechnermodelle (die Registermaschine) wird tatsächlich mit Zahlen und Zahlenfolgen rechnen. Wenn man genau hinsieht, sieht man, dass reale Rechner dies gar nicht tun. Vielmehr operieren sie auf Bitfolgen: der Inhalt des Hauptspeichers etwa ist eine Bitfolge, ebenso Dateiinhalte. Will man mit Zahlen rechnen oder Zeiger benutzen, muss man diese binär kodieren. Auch wir werden andere Rechenmodelle betrachten (insbesondere die Turingmaschine), die nur Zeichenreihen mit Zeichen aus einem endlichen Zeichensatz bearbeiten können. Damit sind wir in der aus der Vorlesung Automaten und ” Formale Sprachen“ bekannten Welt der Alphabete, Wörter, Sprachen und der Funktionen, die Wörter auf Wörter abbilden. Die dort besprochenen Begriffe, die Wörter und Sprachen betreffen, setzen wir als bekannt voraus. Das wichtigste benennen wir hier kurz. 0.2.3 Definition Ein Alphabet Σ ist eine endliche nichtleere Menge. 0.2.4 Beispiel Die Menge {1} oder {|} heißt das unäre Alphabet. Die Menge Σ = {0, 1} heißt das binäre Alphabet. Die Menge {0, 1, #} ist das binäre Alphabet mit Trennzeichen #. Der ASCII-Code gibt eine injektive Abbildung einer Menge von natürlichen“ Buch” staben, Ziffern, und Symbolen (d. h. eines gewissen Alphabets) in {0, 1}8 an. 0.2.5 Definition Σ sei ein Alphabet. Für n ∈ N bezeichnet Σn die Menge aller Folgen w = (a1 , . . . , an ) aus n Buchstaben aus Σ. Statt (a1 , . . . , an ) schreiben wir a1 · · · an , und nennen w ein Wort über Σ (oder einen String über Σ). Die Länge von w, bezeichnet mit |w|, ist n. [ Σ∗ := {Σn | n ∈ N} = Seq(Σ). Ein besonderes Wort ist ε = (), das leere Wort mit Länge 0. 0.2.6 Definition Eine Menge L heißt eine Sprache, wenn es ein Alphabet Σ gibt, so dass L eine Teilmenge von Σ∗ ist. In diesem Fall sagt man auch, L sei eine Sprache über Σ. Sprachen interessieren uns in zweierlei Hinsicht: einerseits, wie in der Vorlesung Auto” maten und Formale Sprachen“ ausführlich besprochen, als Grundkonzept der Theorie der formalen Sprachen; in dieser Vorlesung verwenden wir Sprachen aber viel mehr als Formalisierung des Begriffs eines Berechnungsproblems“ oder Entscheidungsproblems“. Wegen ” ” ihrer fundamentalen Bedeutung wollen wir diese Konzepte noch genauer besprechen. 7 Berechnungsprobleme und Funktionen zwischen Wortmengen. Ein Berechnungsproblem wird beschrieben durch die Angabe zweier Mengen I (die Inputs) und O (die möglichen Outputs) und einer Funktion f : I → O. Die Aufgabe besteht darin, eine Methode anzugeben, mit der man zu jedem x ∈ I den Funktionswert f (x) ∈ O finden kann. Man sollte sorgfältig unterscheiden zwischen dem durch die Funktion f : I → O gegebenen Berechnungsproblem und dem Einzel- Problem“, zu einem gegebenen Input x den ” Wert f (x) zu finden. Das letzte bezeichnet man als Instanz“ des Berechnungsproblems; ” etwas abgekürzt nennt man dann gleich jedes x ∈ I eine Instanz des durch f gegebenen Berechnungsproblems. Beispiele für Berechnungsprobleme: Größter gemeinsamer Teiler : Input/Instanz: Ein Paar (a, b) von natürlichen Zahlen. Output: 0, falls a = b = 0 und c = ggt(a, b) sonst. Multiplikation von Zahlenfolgen: Input/Instanz: Eine Folge (a1 , . . . , an ) von natürlichen Zahlen. Output: Das Produkt a1 · . . . · an (wenn n = 0, ist das Produkt per Definition gleich 1). Zusammenhangskomponenten von Graphen: Input/Instanz: Ein ungerichteter Graph G = (V, E). Output: Die Knotenmengen V1 , . . . , Vr der Zusammenhangskomponenten von G. Wie man an diesen Beispielen sieht, wird bei der Spezifikation von Berechnungsproblemen oft nur eine (allgemein formulierte) Instanz in mathematischer Notation angegeben und der zu findende Funktionswert informal beschrieben. Außerdem kann es passieren (wie im dritten Beispiel), dass die Ausgabe nicht eindeutig ist; die Reihenfolge der Komponenten in der Ausgabe ist nicht festgelegt. Wir formalisieren Berechnungsprobleme mit Hilfe der Terminologie von Alphabeten und Wortmengen. Wenn Σ und ∆ Alphabete sind und A ⊆ Σ∗ und f : A → ∆∗ eine Funktion ist, so ist dadurch natürlich ein Berechnungsproblem definiert (nämlich das, einen Algorithmus zu finden, der f berechnet). Umgekehrt zeigt die Erfahrung, und eine etwas allgemeinere 8 Überlegung, dass man jedes Berechnungsproblem als eine Funktion formulieren kann, die Wörter auf Wörter abbildet. Um ein Problem rechnergerecht“ formulieren zu können, ” muss man die Inputs in einem Format vorgeben, das von einem Rechner bearbeitet werden kann, also digital. (Beispiel für Eingabeformate: eine Textdatei — das ist letztendlich eine Folge von ASCII-Zeichen, also ein Wort über dem ASCII-Alphabet; eine beliebige Datei mit Bilddaten oder intern dargestellten float-Zahlen ist letztendlich ein langes Binärwort; eine Folge von Tastendrücken oder Mausklicks wird ebenfalls binär kodiert. Auch jede Ausgabe, als Text oder als Graphik oder als Klang hat immer eine Zwischendarstellung als (binärer) Text.) Also verlieren wir eigentlich nichts, wenn wir im wesentlichen nur Berechnungsprobleme betrachten, deren Ein- und Ausgabemengen Wortmengen sind. Zwischendurch werden wir auch Berechnungsprobleme betrachten, deren Ein- und Ausgabemengen Teilmengen von Seq(N) sind. Entscheidungsprobleme und Sprachen. Entscheidungsprobleme sind spezielle Berechnungsprobleme. Bei Entscheidungsproblemen sind zu einem Input x nur die Ausgaben Ja“ oder Nein“ möglich; allerdings betrachtet man auch Algorithmen oder Rechenver” ” fahren, die zu manchen Eingaben überhaupt kein Resultat liefern. Beispiele für Entscheidungsprobleme: Teilerfremdheit: Input/Instanz: Ein Paar (a, b) von natürlichen Zahlen. Output: Ja“, falls a und b teilerfremd sind, und Nein“ sonst. ” ” Primzahlproblem: Input/Instanz: Eine natürliche Zahl n. Output: Ja“, falls n eine Primzahl ist, und Nein“ sonst. ” ” Graphzusammenhang: Input/Instanz: Ein ungerichteter Graph G = (V, E). Output: Ja“, falls G zusammenhängend ist, und Nein“ sonst. ” ” Wenn L ⊆ Σ∗ eine Sprache ist, so gehört zu L in ganz natürlicher Weise ein Entscheidungsproblem, nämlich: Wortproblem für L: Input/Instanz: w ∈ Σ∗ Output: Ja“, falls w ∈ L, Nein“ sonst. ” ” Umgekehrt kann man normalerweise Entscheidungsprobleme als Wortprobleme über passenden Sprachen formulieren. Wir geben dazu einige Beispiele. 9 0.2.7 Beispiel (a) Das Problem zu entscheiden, ob eine vorgelegte natürliche Zahl n gerade ist oder nicht, entspricht der Sprache Lgerade = {bin(n) | n ist gerade}. Das Problem zu entscheiden, ob eine vorgelegte natürliche Zahl n eine Primzahl ist oder nicht, entspricht der Sprache Lprim = {bin(n) | n ist Primzahl}. (b) Das Problem zu entscheiden, ob eine vorgelegte Folge a1 , . . . , an von natürlichen Zahlen aus paarweise teilerfremden Zahlen besteht, entspricht der Sprache Lteilerfremd = {bin(a1 )# · · · #bin(an ) | n ∈ N, a1 , . . . , an ∈ N, ∀d > 1, i 6= j : d teilt ai ⇒ d teilt aj nicht} über dem Alphabet {0, 1, #}. Kodierung von Graphproblemen. Als Beispiel für die Formulierung von zu berechnenden Funktionen bzw. von Entscheidungsproblemen als Funktionen Σ∗ → ∆∗ für Alphabete Σ, ∆ bzw. als Wortprobleme für Sprachen formulieren wir hier einige Graphprobleme in dieser Weise. Eine kleine technische Schwierigkeit, die aber mit etwas Gewöhnung nicht schwer zu bewältigen ist, ist die Wahl einer passenden Kodierung für die Objekte in der Ein- und Ausgabemenge. Die hier vorgeschlagene Art der Kodierung ist keineswegs eindeutig, sondern willkürlich. Der Einfachheit halber nehmen wir hier und auch später immer an, dass die Knoten unserer Graphen Zahlen sind. Ein Graph ist also ein Paar (V, E), wo V ⊆ N endlich ist und E ⊆ V × V eine Menge von Paaren ist. Wie in der Graphentheorie üblich, kann man ein solches Paar (V, E) als gerichteten Graphen (kurz Digraphen, von directed graph“) auffassen, indem man ein ” Paar (u, v) ∈ E als geordnetes Paar interpretiert, oder auch als (ungerichteten) Graphen, indem man das Paar (u, v) ∈ E als ungeordnetes Paar auffasst. Wir kodieren Knotennamen durch ihre Binärdarstellung. Eine einfache Methode, einen (Di-)Graphen G als Wort über dem Alphabet {0, 1, #} darzustellen, besteht darin, alle Knoten und alle Kanten in Binärdarstellung aufzulisten. Das heißt, wenn G = (V, E) mit V = {v1 , . . . , vn }, E = {e1 , . . . , em }, wobei ej = (vij , wij ) ∈ V × V ist, dann ist eine Darstellung von G als Wort über {0, 1, #} durch [G] = ###bin(v1 )#bin(v2 )# · · · #bin(vn )## bin(vi1 )#bin(wi1 )## · · · ##bin(vim )#bin(wim )### gegeben. Ein Beispiel: V = {4, 6, 9, 10} E = {(4, 9), (6, 9), (6, 10)} [G] = ###100#110#1001#1010##100#1001##110#1001##110#1010###, ein Wort über Σ = {0,1,#}. Auch seltsame Graphen lassen sich darstellen: Der Graph G = ({0, 3, 7}, ∅) mit drei Knoten und keiner Kante hat die Kodierung ###0#11#111#####. 10 Weil die Knoten- und Kantenordnung nicht vorgegeben ist, hat ein (Di-)Graph normalerweise mehrere verschiedene Kodierungen. Man könnte die Kodierung eindeutig machen, indem man v1 < v2 < · · · < vn fordert und die Kanten lexikographisch anordnet. Wichtig bei dieser Kodierung (und in ähnlichen Situationen) ist der Umstand, dass aus dem Wort [G] der (Di-)Graph G leicht rekonstruiert werden kann und dass Wörter w ∈ {0, 1, #}∗ , die keinen (Di-)Graphen kodieren, leicht zu erkennen sind. Wir geben nun beispielhaft einige Graphprobleme und ihre Formalisierung als Funktionen über Wörtern bzw. als Sprachen an. (i) Das Graphzusammenhangsproblem (für ungerichtete Graphen) wird durch die folgende Sprache über {0, 1, #} dargestellt: Lzush = {[G] | G ist zusammenhängend}. (Das Wortproblem für Lzush ist eine Formalisierung des Graphzusammenhangsproblems.) (ii) Ein (gerichteter) Hamiltonkreis in einem Digraphen G = (V, E) ist eine Anordung der Knoten v1 , . . . , vn so dass zwischen in der Anordnung aufeinanderfolgenden Knoten eine Kante liegt und eine Kante vom letzten zum ersten Knoten führt. Anordnungen beschreibt man bequem durch Permutationen π von {1, . . . , n}: wenn π eine solche Permutation ist, ist vπ(1) , . . . , vπ(n) eine Knotenanordnung; umgekehrt ist jede Knotenanordnung durch eine Permutation darstellbar. (Beispiel: Die Permutation π mit π(1) = 3, π(2) = 4, π(3) = 2, π(4) = 1 gehört zu der Anordnung v3 , v4 , v2 , v1 .) Ein Hamiltonkreis in G = (V, E) ist also eine Permutation π derart dass (vπ(i) , vπ(i+1) ) ∈ E für 1 ≤ i < n und (vπ(n) , vπ(1) ) ∈ E ist. Das Hamiltonkreisproblem ist folgendes Entscheidungsproblem: Input/Instanz: Ein Digraph G = (V, E) mit V = {v1 , . . . , vn }. Output: Ja“, falls G einen Hamiltonkreis besitzt, und Nein“ sonst. ” ” Diesem Problem entspricht die Sprache LHamilton = {[G] | G ist Digraph, G hat einen Hamiltonkreis}. (iii) Kreisfreiheitsproblem: Die Sprache Lazyklisch = {[G] | G ist Digraph, G hat keinen gerichteten Kreis} formalisiert das Problem, zu einem gegebenen Digraphen zu entscheiden, ob dieser kreisfrei (synonym: azyklisch) ist. 11 (iv) Zusammenhangskomponentenproblem: Das Problem, zu einem (ungerichteten) Graphen G seine Zusammenhangskomponenten zu berechnen, kann man zum Beispiel wie folgt als Funktion f : {0, 1, #}∗ → {0, 1, #}∗ kodieren: 0, falls w 6= [G] für alle Graphen G ist; ###bin(v11 )#bin(v12 )# · · · #bin(v1r1 )## bin(v21 )# · · · #bin(v2r2 )## · · · f (w) = bin(vs1 )# · · · #bin(vsrs )###, wo {v , . . . , v1r1 }, . . . , {vs1 , . . . , vsrs } die 11 Zusammenhangskomponenten von G sind, falls w = [G]. Um zu erzwingen, dass zu gegebenem w = [G] der Funktionswert f (w) eindeutig ist, könnte man festlegen, dass in der Ausgabe die Knoten in jeder Zusammenhangskomponente so wie in der Eingabe angeordnet sind und dass die Zusammenhangskomponenten selber so angeordnet sind, dass die Reihenfolge der ersten Elemente v11 , . . . , vsrs dieselbe wie in der Eingabe ist. Man beachte, dass wir syntaktisch falschen Eingaben (Wörtern w, die keinen Graphen kodieren) eine Ausgabe zugeordnet haben, die nicht als Liste missverstanden werden kann. Diese Ausgabe ist als Fehlermeldung zu verstehen. Bemerkung: Nach einer Weile wird es Routine, Entscheidungsprobleme als Sprachen auszudrücken und Berechnungsprobleme als Funktionen. Auch gewöhnt man sich daran, dass alle mathematischen Strukturen irgendwie kodiert werden müssen, und an die Standardverfahren für diese Kodierungen. Der besseren Lesbarkeit halber notiert man dann Entscheidungsprobleme in der Input/Instanz–Output-Formulierung und verzichtet auf die explizite Angabe der Kodierung. So wird es auch in der Literatur gemacht. Zur Übung werden wir in der Vorlesung noch eine Weile die Formulierung von Problemen als Sprachen oder Funktionen mitführen. 0.3 0.3.1 Mathematische Grundbegriffe Abzählbarkeit und Überabzählbarkeit Wir rekapitulieren hier kurz Begriffe aus den Mathematik-Grundvorlesungen (für Informatiker). Alle, denen dies unbekannt vorkommt, mögen auch einführende Mathematikbücher konsultieren. Wir benutzen die Konzepte nur als Hintergrund“ für Untersuchungen in ” Kapitel 1. 0.3.1 Definition Eine Menge A heißt abzählbar (oder abzählbar unendlich), wenn es eine Bijektion f : N ↔ A gibt, das ist eine Aufzählung (f (0), f (1), f (2), f (3), . . .) von A ohne Wiederholung. Ist A unendlich, aber nicht abzählbar, so heißt A überabzählbar. 12 0.3.2 Bemerkung (a) Falls f : N → A surjektiv ist, so ist A endlich oder abzählbar. (b) Falls g : A → N injektiv ist, ist A endlich oder abzählbar. (c) Ist A abzählbar und A0 ⊆ A, so ist A0 endlich oder abzählbar. Die Beweise sind einfache (mathematische) Übungsaufgaben. 0.3.3 Bemerkung Falls A abzählbar ist, gilt: (a) P(A) = {B | B ⊆ A} ist überabzählbar. (b) {0, 1}A = {f | f : A → {0, 1}} ist überabzählbar. (Dasselbe gilt für jede Funktionenmenge ΣA mit |Σ| ≥ 2.) (c) Seq(A) = {(a1 , . . . , an ) | n ∈ N, a1 , . . . , an ∈ A} ist abzählbar. (d) P<∞ (A) = {B | B ⊆ A und A endlich} ist abzählbar. Beweis (a) Wir zeigen mit dem Cantorschen Diagonalverfahren“, dass es keine Bijektion N ↔ ” P(A), also keine Aufzählung aller Elemente von P(A) gibt. Es sei nämlich a = (a0 , a1 , a2 , . . .) eine Aufzählung aller Elemente von A ohne Wiederholung, die nach Voraussetzung existiert, und F = (B0 , B1 , B2 , . . .) eine Aufzählung irgendwelcher Elemente von P(A). Wir zeigen, dass F nicht ganz P(A) enthalten kann. Dies geschieht durch Konstruktion einer Diagonalmenge“, die in F nicht vorkommt: ” D := {ai | i ∈ N, ai ∈ / Bi }. Wir haben nämlich für alle i ∈ N: ai ∈ Bi ⇔ ¬(ai ∈ / Bi ) ⇔ ai ∈ / D, also ist Bi 6= D für alle i ∈ N. (b) Ganz ähnlich wie (a): Es sei a = (a0 , a1 , a2 , . . .) eine Aufzählung von A ohne Wiederholung, und F = (f0 , f1 , f2 , . . .) eine Folge irgendwelcher Funktionen fi : A → {0, 1}. Wir definieren: 1, falls fi (ai ) = 0 , für i ∈ N. fD (ai ) := 0, falls fi (ai ) = 1 Dann gilt für jedes i ∈ N: fD (ai ) = 0 ⇔ fi (ai ) = 1, 13 also jedenfalls fD 6= fi . (Ähnlich argumentiert man, wenn statt {0, 1} eine andere Menge Σ mit |Σ| ≥ 2 als Wertebereich der fi vorliegt.) Um die Bezeichnung Diagonalverfahren“ zu verstehen, stelle man sich die Werte” verläufe von f0 , f1 , f2 , . . . als Zeilen einer (unendlichen) Matrix vor. Der Werteverlauf von fD entsteht durch Kippen der Bits auf der Diagonalen. Dann kann fD natürlich mit keiner der Zeilen übereinstimmen. (c) Es genügt zu zeigen, dass Seq(N) abzählbar ist. Wir betrachten die folgende Funktion Un. ( Un“ steht für Unärdarstellung von Zahlentupeln“.) ” ” Un : Seq(N) \ {()} → {0, 1}∗ (a1 , . . . , an ) 7→ 1a1 01a2 0 · · · 01an . Beispielsweise ist Un((3, 0, 2, 0)) = 11100110 und Un((5)) = 11111. Man überlegt sich leicht, dass Un bijektiv ist. Nach Korollar A.1.12 im AFS-Skript ist {0, 1}∗ abzählbar; dies überträgt sich via Un auch auf Seq(N). (d) Die Abbildung Seq(N) → P<∞ (N), (a1 , . . . , an ) 7→ {a1 , . . . , an } ist offenbar surjektiv. Nach (c) existiert also eine surjektive Abbildung N → P<∞ (N); nach Bemerkung 0.3.2(a) ist dann P<∞ (N) abzählbar. 0.3.4 Bemerkung Es gibt noch eine andere Darstellung des Cantorschen Diagonalverfahrens, das ohne Indizes auskommt. Ein Argument dieser Art wurde in Abschnitt 0.1 benutzt, um die Unentscheidbarkeit des Halteproblems für Pascal-Programme zu demonstrieren. Hier geben wir dieses Beweisverfahren einmal in der puren, mengentheoretischen Formulierung an, um folgendes zu beweisen: Behauptung: Wenn A eine beliebige Menge ist und f : A → P(A) = {B | B ⊆ A} eine Funktion, dann ist f nicht surjektiv. (Insbesondere kann es keine Bijektion zwischen A und P(A) geben.) Beweis: Sei f : A → P(A) beliebig. Wir definieren: D := {a ∈ A | a ∈ / f (a)}. Offenbar ist D eine Teilmenge von A, also D ∈ P(A). Für jedes beliebige a ∈ A gilt nach der Definition von D: a∈D⇔a∈ / f (a), also ist f (a) 6= D. Das heißt, dass D nicht im Bild von f liegt, daher ist f nicht surjektiv.2 2 Man beachte, dass dieser Beweis konstruktiv“ ist in folgendem Sinne: Zu jedem f konstruieren wir ” durch Diagonalisierung“ einen Beleg“ D = Df dafür, dass f nicht surjektiv ist. ” ” 14 Kapitel 1 Entscheidbarkeit und Berechenbarkeit 1.1 Registermaschinen, Turingmaschinen und Rekursivität In diesem Abschnitt stellen wir zwei für das folgende grundlegende Maschinenmodelle bereit: das Modell der Registermaschine (RAM — random access machine — Maschine mit wahlfreiem Speicherzugriff) und das Modell der Turingmaschine (TM, benannt nach Alan Turing, der diese Maschinen 1936 definierte). Beide Modelle sind als Grundlage für echte“ Berechnungen ungeeignet; ihr Wert liegt in ” ihrer einfachen Struktur, die allgemeine Untersuchungen zu Berechenbarkeits- und Komplexitätsfragen erleichtern. Registermaschinen operieren auf natürlichen Zahlen bzw. endlichen Folgen von Zahlen; ihre Struktur stellt sie in die Nähe des von-Neumann-Rechenmodells. Sie haben Programme mit Befehlen, die einem extrem reduzierten Befehlssatz eines gewöhnlichen Rechners entsprechen, und einen Speicher mit Speicherzellen, auf die mit direkter und indirekter Adressierung zugegriffen werden kann. Turingmaschinen dagegen verarbeiten Wörter durch Manipulation von Zeichenreihen, in Verallgemeinerung von endlichen Automaten und Kellerautomaten. 1.1.1 Registermaschinen Eine Registermaschine (RAM) hat einerseits einen Speicher, der aus unendlich vielen Speicherzellen R0 , R1 , R2 , . . . besteht, die man traditionell Register nennt. Jedes Register kann eine natürliche Zahl speichern. hRi i bezeichnet die in Ri gespeicherte Zahl. Wir interessieren uns nur für Speicherzustände, in denen alle bis auf endlich viele Register den Inhalt 0 haben. Wie eine RAM arbeiten soll, wird durch ein Programm festgelegt, 15 das einem Maschinenprogramm in einer simplen Maschinensprache gleicht. Formal ist das Programm eine Folge B0 , B1 , . . . , Bl−1 von l Befehlen, die aus einem Befehlsvorrat stammen, der Speicher- oder Kopierbefehle, arithmetische Befehle und bedingte und unbedingte Sprungbefehle enthält. Bk heißt die k-te Programmzeile“; man stellt sich die ” Befehle also in l Zeilen angeordnet vor. Um die Arbeitsweise der RAM zu beschreiben, geben wir ihr noch ein zusätzliches Register, den Befehlszähler BZ, das ebenfalls natürliche Zahlen speichern kann. Der Inhalt von BZ wird mit hBZi bezeichnet. Schema einer RAM: 0: 1: 2: . . . B0 B1 B2 l −1: B l −1 Steuereinheit 3 R0 5 R1 BZ 0 R2 4 4 R3 0 R4 2 R5 0 R6 Speicher mit Programm und Befehlszähler RAMs mit verschiedenen Programmen werden als verschiedene Maschinen angesehen. Hat man eine RAM M (d. h. ein Programm) und stehen in BZ und R0 , . . . , Rm irgendwelche Zahlen, und in Rm+1 , Rm+2 , . . . Nullen, kann M einen Schritt ausführen: Falls 0 ≤ hBZi < l, wird Befehl BhBZi ausgeführt (dies verändert hBZi und eventuell den Inhalt eines Registers). Ist hBZi ≥ l, passiert nichts: die RAM hält. Dieser Vorgang kann natürlich iteriert werden, bis möglicherweise schließlich ein Befehlszählerinhalt ≥ l erreicht wird. Nun beschreiben wir, in der folgenden Tabelle, den Befehlssatz einer RAM. Es handelt sich um sogenannte Dreiadressbefehle: Operanden werden aus zwei Registern geholt, das Resultat einer Operation in einem dritten Register gespeichert. Nicht-Sprungbefehle führen dazu, dass der Befehlszähler um 1 erhöht wird. In der Tabelle steht das Zeichen := für eine Zuweisung wie in Pascal: Ri := p für einen Index i ∈ N und eine Zahl p ∈ N bewirkt, dass nachher das Register Ri die Zahl p enthält. Analog sind Zuweisungen BZ := m zu interpretieren. Bei der Subtraktion werden negative Resultate durch 0 ersetzt; die Division ist die ganzzahlige Division ohne Rest. Division durch 0 führt zum Anhalten. 16 Befehlszeile Einschränkungen, Beschreibung Speicherbefehle: Ri ← Rj RR i ← Rj Ri ← RR j Arithmetische Ri ← k Ri ← Rj + Rk Ri ← Rj − Rk Ri ← Rj ∗ Rk Ri ← Rj ÷ Rk i, j ∈ N (∗ Register kopieren mit direkter Adressierung ∗) i, j ∈ N (∗ Register kopieren; Ziel indirekt adressiert ∗) i, j ∈ N (∗ Register kopieren; Quelle indirekt adressiert ∗) Befehle: i, k ∈ N (∗ Konstante laden ∗) i, j, k ∈ N (∗ holen, addieren, speichern ∗) i, j, k ∈ N (∗ holen, subtrahieren, speichern; negatives Resultat durch 0 ersetzen ∗) i, j, k ∈ N (∗ holen, multiplizieren, speichern ∗) i, j, k ∈ N (∗ holen, dividieren, speichern ∗) (∗ Fehlerhalt ∗) Sprungbefehle: goto m if (Ri = 0) goto m m∈N (∗ unbedingter Sprung ∗) i, m ∈ N (∗ bedingter Sprung ∗) if (Ri > 0) goto m i, m ∈ N Wirkung Ri := hRj i; BZ := hBZi + 1; RhRi i := hRj i; BZ := hBZi + 1; Ri := hRhRj i i; BZ := hBZi + 1; Ri := k; BZ := hBZi + 1; Ri := hRj i + hRk i; BZ := hBZi + 1; Ri := max{0, hRj i − hRk i}; BZ := hBZi + 1; Ri := hRj i · hRk i; BZ := hBZi + 1; if hRk i > 0 then {Ri := hRj i div hRk i; BZ := hBZi + 1} else BZ := l BZ := m ( m, falls hRi i = 0; BZ := hBZi + 1, sonst. ( m, falls hRi i > 0; BZ := hBZi + 1, sonst. (∗ bedingter Sprung ∗) STOP: (∗ bedingte oder unbedingte Sprünge goto m“ mit Sprungziel m ≥ l ” wirken wie bedingte oder unbedingte STOP-Befehle. Die RAM hält auch, wenn der Befehl in Zeile l − 1 ausgeführt wird und es sich nicht um einen Sprungbefehl handelt. ∗) 17 Mitunter betrachtet man RAMs mit eingeschränktem Befehlsvorrat, z. B. {+, −}-RAMs, bei denen die ∗- und ÷-Befehle fehlen. Da man Multiplikation und Division durch Teilprogramme ersetzen kann, die nur Addition und Subtraktion benutzen, bedeutet dies keine prinzipielle Einschränkung; allerdings kann sich die Anzahl der für eine Berechnung nötigen Schritte erhöhen. Ein-/Ausgabekonventionen: Für die Eingabe benutzen wir folgende Konvention (andere sind möglich): Ist die Eingabe (a0 , . . . , an−1 ) ∈ Nn , so wird anfangs R0 auf n R1 auf a0 R3 auf a1 .. . R2i+1 auf ai , 0 ≤ i < n, gesetzt, alle anderen Registerinhalte sind 0. (Damit hat man die Register R2 , R4 , . . . zur freien Verfügung.) Zudem hat BZ den Inhalt 0. Für die Ausgabe wird die entsprechende (umgekehrte) Konvention benutzt: als Resultat nach dem Anhalten gilt das Zahlentupel (hR1 i, hR3 i, . . . , hR2hR0 i−1 i). Nun können wir erklären, wie eine vollständige Rechnung von M auf einer Eingabe (a0 , . . . , an−1 ) ∈ Seq(N) abläuft. 1 man schreibt a0 , . . . , an−1 gemäß der Eingabekonvention in die Register von M und setzt BZ auf 0. 2 while 0 ≤ hBZi < l do führe Befehl BhBZi aus“ ” (mit der Wirkung wie in der Tabelle angegeben) 3 falls und sobald in 2 eine Situation mit hBZi ≥ l erreicht wird, wird aus den Registerinhalten gemäß der Ausgabekonvention das Resultat abgelesen. 1.1.1 Beispiel Wir wollen aus a0 , . . . , an−1 die Summe a0 + · · · + an−1 und das Produkt a0 · · · an−1 berechnen. Die Register mit geraden Indizes werden verwendet wie folgt: In Register R2 wird von n nach 0 heruntergezählt, in R4 wird die Summe und in R6 das Produkt akkumuliert, R8 enthält den Index des nächsten zu verarbeitenden Inputregisters, in R10 wird der Inhalt dieses Registers zwischengespeichert, R12 enthält die Konstante 1, R14 die Konstante 2. 18 Zeile 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1.1.2 Definition Befehl R12 ← 1 R14 ← 2 R2 ← R0 R4 ← 0 R6 ← 1 R8 ← 1 if (R2 = 0) goto 13 R10 ← RR8 R4 ← R4 + R10 R6 ← R6 ∗ R10 R8 ← R8 + R14 R2 ← R2 − R12 goto 6 R1 ← R4 R3 ← R6 R0 ← 2 Kommentar Konstante laden n ins Zählregister Initialisiere Teilsumme und Teilprodukt Indexregister auf R1 stellen Schleife: Zeilen 6–12 Operanden holen addieren multiplizieren Indexregister um 2 erhöhen Zähler dekrementieren zum Schleifentest Ausgabeformat herstellen: 2 Ausgabewerte Für eine RAM M definieren wir: (a) HM := {(a0 , . . . , an−1 ) ∈ Seq(N) | auf Eingabe (a0 , . . . , an−1 ) angesetzt, hält M nach endlich vielen Schritten} (b) Für a = (a0 , . . . , an−1 ) ∈ Seq(N) sei falls a ∈ / HM ; undefiniert, fM (a) = (b0 , . . . , bm−1 ), falls M auf Eingabe (a0 , . . . , an−1 ) beim Anhalten die Ausgabe (b0 , . . . , bm−1 ) erzeugt. fM heißt die von M berechnete Funktion. (c) Die Menge der RAM-berechenbaren Funktionen ist die Menge aller Funktionen f , die sich als fM oder als die Einschränkung eines fM auf ein Nn , n fest, beschreiben lassen. Bemerkung: (a) Im allgemeinen ist fM eine partielle Funktion“ — die Menge Def(fM ) = ” {x ∈ Seq(N) | fM (x) ist definiert} = HM ist eine Teilmenge von Seq(N), oft verschieden von Seq(N). Z. B. ist es leicht, ein RAM-Programm M mit HM = ∅ anzugeben; in diesem Falle ist fM für keine Eingabe definiert. Es wird sich später herausstellen, dass es bei einer systematischen Behandlung des Berechenbarkeitsbegriffs unvermeidlich ist, auch Funktionen zu betrachten, die nicht für alle Eingaben definiert sind. (b) Oft sind Funktionen f von Interesse, die nur eine feste Anzahl von Inputzahlen haben, z. B. (a, b) 7→ ab oder (a, b) 7→ max{a, b}. Wenn f eine Funktion ist, deren Definitionsbereich eine Teilmenge von Nn ist, sagen wir, dass M f berechnet, wenn f die Einschränkung von fM auf Nn ist, d. h. wenn für alle a ∈ Nn gilt f (a) = fM (a). 19 1.1.3 Beispiel Berechnung von aa01 . Dabei ist nur das Verhalten auf zweistelligen Eingaben (a0 , a1 ) interessant. Idee: a1 -faches Multiplizieren von a0 mit sich selbst. Realisiert wird dies durch eine Schleife, in der R3 in Einerschritten von a1 bis 0 heruntergezählt wird. Programm für M : Zeile 0 1 2 3 4 5 6 7 Befehl Kommentar R2 ← 1 Konstante 1 R4 ← 1 a00 if (R3 = 0) goto 6 Zeilen 2–5: R4 ← R4 ∗ R1 Schleife R3 ← R3 − R2 goto 2 R1 ← R4 Resultatformat R0 ← 1 herstellen Auf der Eingabe (a0 , a1 ) = (6, 3) läuft das Programm wie folgt ab. Die Zeile zu Schritt t repräsentiert dabei den gesamten Zustand (die Konfiguration“ der RAM) nach Schritt ” t = 0, 1, 2, . . .. Schritt 0 entspricht dem Anfangszustand, nach der Initialisierung. Schritt-Nr. R0 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 2 10 2 11 2 12 2 13 2 14 2 15 2 16 2 17 1 R1 R2 R3 6 0 3 6 1 3 6 1 3 6 1 3 6 1 3 6 1 2 6 1 2 6 1 2 6 1 2 6 1 1 6 1 1 6 1 1 6 1 1 6 1 0 6 1 0 6 1 0 216 1 0 216 1 0 R4 hBZi 0 0 0 1 1 2 1 3 6 4 6 5 6 2 6 3 36 4 36 5 36 2 36 3 216 4 216 5 216 2 216 6 216 7 216 8 Wir wollen den Ablauf (des Programms) von M auf einer Eingabe a = (a0 , . . . , an−1 ) die Berechnung von M auf a“ nennen. Als nächstes ordnen wir jeder solchen Berech” nung Kosten“ zu. Die eine Kostenfunktion zählt einfach die Anzahl der ausgeführten ” Rechenschritte, die andere versucht, die Anzahl der benötigten Bitoperationen genauer zu erfassen. 20 1.1.4 Definition (a) Uniformes Kostenmaß/Schrittzahl cM,unif (a) oder cunif (a): Einem RAM-Schritt werden die Kosten 1 zugeordnet. Damit betragen die Kosten cM,unif (a) für die gesamte Rechnung von M auf Eingabe a = (a0 , . . . , an−1 ) ∞ , falls M auf a nicht hält; die Anzahl der Schritte, die M auf a ausführt, falls a ∈ HM . (b) Logarithmisches Kostenmaß oder Bitmaß1 cM,logar (a) oder clogar (a) : Jede in einem ausgeführten Befehl als Registerinhalt oder Operand vorkommende Zahl p trägt |bin(p)| = max{1, dlog2 (p+1)e} (die Anzahl der Bits in der Binärdarstellung bin(p)) zu den Kosten bei, im Zusatz zu Grundkosten 1 für jeden Befehl. (Die Ausführung des Befehls Ri ← Rj hat Kosten 1 + |bin(hRj i)|; die des Befehls RRi ← Rj hat Kosten 1 + |bin(hRj i)| + |bin(hRi i)|; die des Befehls Ri ← RRj hat Kosten 1 + |bin(hRj i)| + |bin(hRhRj i i)|. Der Ladebefehl Ri ← k hat Kosten 1 + |bin(k)|; die anderen arithmetischen Befehle wie Ri ← Rj ∗ Rk haben Kosten 1 + |bin(hRj i)| + |bin(hRk i)|. Der unbedingte Sprung hat Kosten 1; die bedingten Sprünge bezüglich Register Ri haben Kosten 1 + |bin(hRi i)|.) (Beispiel: Die Ausführung des Befehls R3 ← RR8 mit hR8 i = 12, hR12 i = 18 hat logarithmische Kosten 1 + dlog 13e + dlog 19e = 1 + 4 + 5 = 10.) Die logarithmischen Kosten cM,logar (a) der Ausführung eines Programms M auf Eingabe a sind als Summe der Kosten der Einzelschritte definiert. Das uniforme Kostenmaß ist das einfachere und für eine ganze Reihe von Anwendungen geeignet, insbesondere dann, wenn die in der Berechnung als Zwischenergebnisse erzeugten Zahlen nicht sehr viel längere Binärdarstellungen als die Eingabezahlen haben. Das logarithmische Kostenmaß ist angemessen, wenn während der Rechnung sehr lange Zahlen erzeugt werden. Der Zeitaufwand für die Addition und die Subtraktion sehr langer Zahlen in richtigen“ Rechnern mit fixer Operandenbreite in der CPU ist proportional zu ” ihrer Bitlänge, für Multiplikation und Division noch etwas höher. 1.1.5 Beispiel Die RAM aus Beispiel 1.1.3 hat Kosten cunif (a0 , a1 ) = 5 + 4 · a1 im uniformen Kostenmaß. Zur Ermittlung des logarithmischen Kostenmaßes betrachten wir die Zeilen einzeln und überlegen, wie oft sie ausgeführt werden. Zeile 0: einmal ausgeführt, Kosten 1 + dlog 2e = 2. Zeile 1: einmal ausgeführt, Kosten 1 + dlog 2e = 2. 1 Die Idee beim logarithmischen Kostenmaß ist, dass es 1 kostet, ein gespeichertes Bit zu lesen oder sonst zu verwenden. 21 Zeile 2: a1 -mal ausgeführt, Kosten jeweils ≤ 1 + dlog(a1 + 1)e. Gesamtkosten für Zeile 2: ≤ a1 log a1 + O(a1 ). Zeile 3: a1 -mal ausgeführt, Kosten bei der i-ten Durchführung: + 1)e + dlog(a 1 + dlog(ai−1 0 + 1)e = i · log a0 + O(1). 0 P 1 Gesamtkosten für Zeile 3: ai=1 (i · log a0 + O(1)) = O(a21 · log a0 ). Zeile 4: a1 -mal ausgeführt, Kosten jeweils ≤ 1 + dlog(a1 + 1)e + dlog 2e. Gesamtkosten für Zeile 4: ≤ a1 log a1 + O(a1 ), wie bei Zeile 2. Zeile 5: a1 -mal ausgeführt, Kosten a1 . Zeile 6: einmal ausgeführt, Kosten 1 + dlog(aa01 + 1)e = a1 · log a0 + O(1). Zeile 7: einmal ausgeführt, Kosten 2. Wenn wir die Kosten für alle Zeilen aufsummieren, erhalten wir als Kostenschranke cM,logar (a0 , a1 ) = O(a21 log a0 ) + O(a1 log a1 ) + O(1) = O(a21 log a0 ). (Das ist auch intuitiv naheliegend: in den letzten 21 a1 Schleifendurchläufen hat die Zahl in R4 eine Bitlänge von mindestens 21 a1 · log a0 . Allein die Manipulation dieser Zahlen kostet also schon 14 a21 · log a0 im logarithmischen Kostenmaß.) Übungsaufgabe: Es gibt eine viel elegantere Möglichkeit, aa01 auf RAMs zu berechnen, nämlich durch iteriertes Quadrieren. Die Idee ist durch die Rekursionsformel x0 = 1; xb = (xb div 2 )2 , für gerade b > 0 xb = (xb div 2 )2 · x, für ungerade b gegeben. Man setze diese Idee in ein iteratives RAM-Programm um und analysiere die uniformen und logarithmischen Kosten. (Ideale Lösung: uniform O(log a1 ), logarithmisch O(log(aa01 )) = O(a1 · log(a0 )).) 1.1.6 Beispiel Berechne max(a0 , . . . , an−1 ). Idee: Gehe die Zahlen der Reihe nach durch, speichere jeweiliges Maximum in ausgezeichnetem Register. Der Einfachheit halber verwenden wir symbolische Namen für die Programmzeilen; zudem schreiben wir R 0“ ” R 1“ ” R 2“ ” Rmax Rakt Rhilf für R2 für R4 für R6 für R8 für R10 für R12 Konstante 0 Konstante 1 Konstante 2 derzeitiges Maximum Zeiger im Array Hilfsregister 22 Die Übersetzung“ in ein korrektes RAM-Programm ist Routine. ” Marke fertig?: gleich: fertig: Befehl R 0“ ← 0 ” R 1“ ← 1 ” R 2“ ← 2 ” Rmax ← 0 Rakt ← R 2“ · R0 ” Rakt ← Rakt − R 1“ ” if (Rakt = 0) goto fertig Rhilf ← RRakt Rhilf ← Rhilf − Rmax if (Rhilf = 0) goto gleich Rmax ← RRakt Rakt ← Rakt − R 2“ ” goto fertig? R1 ← Rmax R0 ← 1 Kommentar Initialisiere Konstante max(∅) := 0 Zeiger auf R2n−1 stellen for-Schleife Rmax ≥ RRakt Ausgabeformat Auf dieselbe Weise wie im vorhergehenden Beispiel überlegt man sich, dass die Kosten im uniformen Kostenmaß durch 8 + 7 · n beschränkt sind, im logarithmischen Kostenmaß hingegen durch O(n(log n + log(max{ai |0 ≤ i < n})). 1.1.7 Bemerkung Wir betrachten (idealisierte) Programme in einer Standard-Programmiersprache — der Eindeutigkeit halber nehmen wir etwa Pascal. Wir können uns alle Zahltypen wie ganze Zahlen oder reelle Zahlen durch Tupel von natürlichen Zahlen repräsentiert denken, Characters ebenfalls durch Zahlen, Zeiger durch Arrayindizes. Übersetzen wir das Programm mittels eines Compilers in Maschinensprache, ergibt sich ein Programm, das relativ leicht in ein RAM-Programm zu transformieren ist. Wir stellen daher fest: mit Standard-Programmiersprachen berechenbare Funktionen sind auch auf einer RAM berechenbar. — Umgekehrt kann man sich fragen, ob alle RAM-berechenbaren Funktionen von Pascal-Programmen berechnet werden können. Diese Frage ist dann zu verneinen, wenn man die Endlichkeit von Rechnern in Betracht zieht, die dazu führt, dass für jedes auf einer festen Maschine ausführbare Pascal-Programm eine größte darstellbare Zahl und eine Maximalzahl von verwendbaren Registern gegeben ist. Betrachtet man idealisierte“ Programme und Computer ohne solche Einschränkungen, lässt sich ” tatsächlich die Äquivalenz beweisen. Wir geben uns damit zufrieden, im RAM-Modell eine Abstraktion zu erkennen, die auf jeden Fall die Fähigkeiten konkreter Rechner und Programmiersprachen umfasst. 23 1.1.2 Turingmaschinen Wir wenden uns nun unserem zweiten Maschinenmodell zu, der Turingmaschine. Dieses Modell ist noch primitiver als die Registermaschine, unterstützt aber noch besser als diese die prinzipiellen Untersuchungen in dieser Vorlesung. Wir werden (als Hauptergebnis von Kap. 1.5) feststellen, dass sich die Berechnungskraft von RAMs und TMs nicht wesentlich unterscheidet. Im Gegensatz zur Registermaschine, die mit Zahlen als elementaren Objekten umgeht, bearbeiten Turingmaschinen Zeichenreihen, also Wörter.2 Dabei stellen sie eine Verallgemeinerung der aus der AFS-Vorlesung bekannten Modelle des endlichen Automaten (DFAs und NFAs) und des deterministischen oder nichtdeterministischen Kellerautomaten dar. Der Hauptunterschied zum Kellerautomaten besteht darin, dass dieser immer nur am oberen Ende des Kellerwortes lesen und ändern darf, die Turingmaschine dagegen auch irgendwo in der Mitte des auf einem Speicherband geschriebenen Wortes lesen und ändern darf. Wir beginnen mit der deterministischen 1-Band-Turingmaschine, die wir einstweilen kurz Turingmaschine (TM) nennen, und geben eine ausführliche anschauliche Erklärung des Aufbaus und der Funktion. Diese wird nachher in eine präzise mathematische Definition übertragen. Eine TM M hat als Speicher ein zweiseitig unendliches Band, das in Zellen oder Bandfelder eingeteilt ist. (Wenn man will, darf man sich die Zellen mit i ∈ Z durchnumeriert vorstellen, das ist aber nicht Bestandteil der Definition.) Jede Zelle auf dem Band enthält genau einen Buchstaben eines endlichen Alphabetes Γ (des Bandalphabe” tes“). Ein Buchstabe des Bandalphabetes ist als Blankbuchstabe ausgezeichnet. Meistens schreibt man dafür B“, mitunter auch 0“ oder “. Sinnvolle“ Bandinschriften sind ” ” ” ” nur solche, bei denen nur endlich viele Zellen von B verschiedene Buchstaben enthalten. Weiter hat die TM einen (Lese-Schreib-)Kopf, der immer auf einem Bandfeld positioniert ist und der sich in einem Schritt“ immer nur (höchstens) zu einer Nachbarzelle bewe” gen kann. Die Möglichkeit der direkten oder indirekten Adressierung von Zellen und des springenden“ Zugriffs auf Zellen existiert also nicht. ” 2 Will man Zahlen bearbeiten, muss man sie als Zeichenreihen kodieren, z. B. durch ihre Binärdarstellung. 24 ... B B B b a n d i n B B * # − s c h r i f t B B B B B B B Lese−Schreib−Kopf: Schreiben ... Bewegen um 1 Bandfeld Lesen Übergangsfunktion qm q0 Steuereinheit q1 q2 δ q3 gegenwärtiger Zustand q Zustandsmenge Q Abbildung 1.1: Bestandteile einer Turingmaschine M Das Programm als die Vorschrift, wie sich die TM zu verhalten hat, sitzt in einer Steuerein” heit“ 3 . Diese besteht aus einer endlichen Menge Q von Zuständen und einer Vorschrift, was die TM tun soll, wenn sie in einem Zustand q ist, und der Lese-Schreib-Kopf auf einer Zelle steht, die den Buchstaben a ∈ Γ enthält. Diese Vorschrift sagt – welcher Buchstabe zu schreiben ist (in das eben besuchte Feld) (a0 ∈ Γ), – was der neue Zustand ist (q 0 ∈ Q); – in welche Richtung sich der Kopf bewegen soll: D ∈ {L, R, N } (dabei bedeutet L links“, R rechts“ und N gar nicht“). ” ” ” – oder ob eventuell gar nichts passieren soll, also die TM halten soll. Ein Schritt“ der TM besteht in folgendem: ” – Lies das Symbol a ∈ Γ, das in der eben vom Lese-Schreib-Kopf besuchten Zelle steht; – Entscheide aufgrund des gegenwärtigen Zustands q und a, was der neue Zustand q 0 , das neue Symbol a0 , die Bewegungsrichtung D sein soll, und führe die entsprechenden Übergänge aus. 3 engl.: control unit“. Bitte nicht mit Kontrolleinheit“ oder gar mit Kontrolle“ übersetzen. ” ” ” 25 (Dann folgt der nächste Schritt. Einfachere Maschinenzyklen gibt es nicht, oder?) Formal denken wir uns die oben erwähnte Vorschrift“ als Übergangsfunktion δ : Q×Γ → ” Q × Γ × {L, R, N } gegeben. Wir behalten uns aber vor, dass für manche Paare (q, a) die Maschine keinen weiteren Schritt macht, formal, dass δ eine partielle Funktion ist, d. h. dass Def(δ) eine echte Teilmenge von Q × Γ ist. Weil man früher δ als Tabelle (von 5Tupeln (q, a, q 0 , a0 , D) mit δ(q, a) = (q 0 , a0 , D)) aufgefasst hat, wird δ oder eine Darstellung von δ noch oft als Turingtafel bezeichnet. Damit man mit TMn irgendetwas berechnen kann, müssen noch Ein- und Ausgabekonventionen festgelegt werden. Wir wollen entweder Funktionen berechnen, wobei Argumente wie Resultate als endliche Strings gegeben sind, oder Entscheidungsprobleme/Wortprobleme lösen, d. h. es liegt eine Sprache L über Σ vor, und zu x ∈ Σ∗ ist zu entscheiden, ob x ∈ L oder nicht. (Vgl. dazu Abschnitt 0.2.) Die zulässigen Eingaben für eine TM M sind die Wörter x ∈ Σ∗ , wo Σ ⊆ Γ − {B} das Eingabealphabet ist. Die Eingabekonvention besteht darin, dass eine Eingabe x = a1 · · · an ∈ Σ∗ so auf das Band geschrieben wird, dass ai in Zelle i steht, 1 ≤ i ≤ n, und dass der Kopf auf Zelle 1 steht; der Rest des Bandes ist mit dem Blankbuchstaben B“ vorbesetzt: ” ... B B B B B B B B B B B e i n g a b e B B B B B B B B B B ... q 0 Abbildung 1.2: Startkonfiguration für Eingabe x = eingabe (NB: x = ε ⇔ anfangs liest der Kopf ein B.) Weiter soll ein Startzustand q0 ∈ Q festgelegt sein. Die TM führt, startend in dieser Startkonfiguration, einen Schritt nach dem anderen aus, bis sie hält, d. h. bis eine Situation (q, a) auftritt, für die δ(q, a) undefiniert ist. Möglicherweise hält die TM auch überhaupt nicht. Wenn sie hält, wird die Ausgabe wie folgt abgelesen: (i) (Funktionen) Das Resultat ist das Wort, das in den Zellen von der gegenwärtigen Kopfposition (einschließlich) nach rechts bis zum ersten B“ (ausschließlich) auf ” dem Band steht. Ein Beispiel enthält die folgende Abbildung. 26 ... B i r r e l e v a n t r e s u l t a t B B i r r e l e v ... q Abbildung 1.3: TM M hält, wenn δ(q, r) undefiniert ist; Ausgabe: resultat Steht der Kopf auf einer Zelle mit Buchstaben B“, ist das Resultat das leere Wort. ” (ii) (Entscheidungsprobleme) Es gibt eine vorher festgelegte Teilmenge F ⊆ Q, die akzeptierenden (End-)Zustände“. ” Hält die TM im Zustand q, so gilt die Eingabe x als akzeptiert“, falls q ∈ F , ” verworfen“, falls q ∈ Q − F ist. ” 1.1.8 Beispiel Wir beschreiben eine Turingmaschine, die die Wörter der Sprache L = {an bn cn | n ≥ 0} akzeptiert. Damit sehen wir schon, dass Turingmaschinen mehr können“ als Kellerautomaten, da ” wir wissen, dass L nicht kontextfrei ist und daher kein Kellerautomat L akzeptieren kann. Die Idee für das Verfahren ist, mit dem Lese-Schreibkopf mehrere Male über den Bereich des Eingabewortes zu fahren, dabei jedesmal zu überprüfen, in der Manier eines endlichen Automaten, ob die jetzige Bandinschrift aus lauter X besteht (dann akzeptieren wir) oder in der durch den regulären Ausdruck X∗ a(a + X)∗ b(b + X)∗ cc∗ beschriebenen Sprache liegt; dann ersetzen wir jeweils das erste gefundene a, das erste gefundene b und das erste gefundene c durch ein X und beginnen von vorn. Die Eingabe ist offenbar (!) 4 genau dann in L, wenn am Ende ein Wort aus L(X∗ ) auf dem Band steht. Unsere TM M hat die Zustandsmenge Q = {A, C, D, E, H, Y }, der Startzustand ist q0 = A. Das Eingabealphabet ist Σ = {a, b, c}; das Bandalphabet ist Γ = {a, b, c, X, B} mit dem Blankbuchstaben B. Die Zustände dienen folgenden Zwecken: Im Zustand A lesen wir kein, ein oder mehrere X bis zum ersten a. Dieses wird in X umgewandelt und der Zustand wechselt nach C. Finden wir im Zustand A den Buchstaben B, ist das Ziel erreicht; wir wechseln in den Zustand Y . Im Zustand C lesen wir eine beliebige Anzahl von a’s und X’s bis zum ersten b. Dieses wird in X umgewandelt, wir wechseln in den Zustand D. Im Zustand D lesen wir eine beliebige Anzahl von b’s und X’s bis zum ersten c. Dieses wird in X umgewandelt, wir wechseln in den Zustand E. Im Zustand E lesen wir eine beliebige Anzahl von weiteren c’s bis zum ersten B, das einen Wechsel in den Zustand H auslöst. Im Zustand H schließlich fährt der Kopf von 4 Das Zeichen (!)“ heißt, dass man sich die Begründung selbst überlegen sollte. ” 27 rechts nach links zurück über c’s, b’s, a’s und X’s bis zum ersten Feld der Eingabe, der durch das erste gefundene B identifiziert wird; nun beginnt der Zyklus mit Zustand A von vorn. Der Zustand Y wird erreicht, wenn das Eingabewort erfolgreich in lauter X’s transformiert worden ist, bzw. von Anfang an das leere Wort ε gewesen ist; demnach ist F = {Y } zu setzen. Die Übergangsfunktion δ findet sich in der folgenden Tabelle. Wenn ein Übergang δ(q, a) undefiniert ist (in der Tabelle gekennzeichnet durch -“) für q 6= Y , bedeutet dies, dass ” M anhält, ohne zu akzeptieren. a q a b c A (C, X, R) − − C (C, a, R) (D, X, R) − D − (D, b, R) (E, X, R) E − − (E, c, R) H (H, a, L) (H, b, L) (H, c, L) − − − Y X B (A, X, R) (Y, B, N ) (C, X, R) − (D, X, R) − − (H, B, L) (H, X, L) (A, B, R) − − Graphische Darstellung. Wie bei endlichen Automaten und bei Kellerautomaten kann man auch Turingmaschinen durch gerichtete Graphen mit Knoten- und Kantenbeschriftungen darstellen; dies ist oft übersichtlicher als die Turingtafel. Der Graph GM hat einen Knoten vq für jeden Zustand q ∈ Q; dieser ist mit q beschriftet. Startzustand und akzeptierende Zustände werden wie bei Automaten bezeichnet. Wenn δ(q, a) = (q 0 , a0 , D), gibt es eine Kante von vq nach vq0 mit Beschriftung a | a0 , D. Wie üblich zieht man mehrere Kanten von vq nach vq0 zu einer zusammen, mit mehreren Beschriftungen. Die in Beispiel 1.1.8 beschriebene Turingmaschine hat die folgende Darstellung als beschrifteter Graph. 28 X|X , R a|a , R X|X , R A a|X , R C X|X , R b|b , R b|X , R D Start B | B, N Y B | B, R X|X , L a|a , L b|b , L c|c , L c|X , R H B | B, L E c|c , R Abbildung 1.4: Graphdarstellung der TM in Beispiel 1.1.8 1.1.9 Beispiel Als Beispiel für eine Turingmaschine, die eine Ausgabe erzeugt, beschreiben wir eine TM M , die eine sehr einfache Form von binärer Addition vornimmt. Der Input besteht aus zwei n-stelligen Binärzahlen an−1 · · · a0 und bn−1 · · · b0 , mit n ≥ 1. Diese sind in der Eingabe so gegeben, dass ai bi als Bitpaar in einer Bandzelle steht; die Eingabe ist also (an−1 bn−1 , . . . , a0 b0 ).5 Das Eingabealphabet ist Σ = {0, 1}2 . Die Turingmaschine soll die Summe cn · · · c0 oder cn−1 · · · c0 von an−1 · · · a0 und bn−1 · · · b0 berechnen, je nachdem ob ein Übertrag in die (n + 1)te Stelle auftritt oder nicht, und im ersten Falle akzeptieren und sonst verwerfen. Die Arbeitsweise ist sehr einfach: Der Kopf fährt als erstes von links nach rechts über die Eingabe und ermittelt in jeder Eingabeposition die Summe der beiden Eingabebits (Zustand p). Anschließend wird mit der Schulmethode addiert, startend bei den am wenigsten signifikanten Ziffern (also den ganz rechts stehenden). Bei der Addition werden zwei Zustände r0 und r1 benötigt, die das Übertragsbit speichern“. Am Ende stellt man fest, ob eine neue Stelle hinzugefügt werden muss oder ” nicht (Zustände s0 und s1 ). Wenn die Eingabe leer ist, gibt es einen Fehlerhalt im Startzustand p0 . Als Bandalphabet benutzen wir Γ = Σ ∪ {0, 1, 2} ∪ {B}, die Zustandsmenge ist Q = {p0 , p, r0 , r1 , s0 , s1 } mit q0 = p0 und F = {s1 }. — Die Übergangsfunktion δ wird durch die folgende Tabelle gegeben. (Zur Übung male man sich auch die graphische 5 Solche Arrangements werden als Spurtechnik“ später genauer diskutiert. ” 29 Darstellung dieser TM auf.) a q 00 01 10 11 0 1 2 B p0 (p, 0, R) (p, 1, R) (p, 1, R) (p, 2, R) − − − − p (p, 0, R) (p, 1, R) (p, 1, R) (p, 2, R) − − − (r0 , B, L) − − − − (r0 , 0, L) (r0 , 1, L) (r1 , 0, L) (s0 , B, R) r0 − − − − (r0 , 1, L) (r1 , 0, L) (r1 , 1, L) (s1 , 1, N ) r1 s0 , s1 − − − − − − − − Wir verfolgen die Arbeitsweise von M an einer konkreten Eingabe x = (10, 11, 00, 01, 11), entsprechend den zu addierenden Zahlen 11001 und 01011. Die Zeilen in der nachfolgenden Tabelle entsprechen den Situationen nach jeweils einem Schritt. Ein Paar (q, a) ∈ Q × Γ repräsentiert dabei die Bandzelle, auf der der Kopf steht, und den aktuellen Zustand. B B (p0 , 10) 11 00 01 11 B B B 1 (p, 11) 00 01 11 B B B 1 2 (p, 00) 01 11 B B B 1 2 0 (p, 01) 11 B B B 1 2 0 1 (p, 11) B B B 1 2 0 1 2 (p, B) B B 1 2 0 1 (r0 , 2) B B B 1 2 0 (r1 , 1) 0 B B B 1 2 (r1 , 0) 0 0 B B B 1 (r0 , 2) 1 0 0 B B B (r1 , 1) 0 1 0 0 B B (r1 , B) 0 0 1 0 0 B B (s1 , 1) 0 0 1 0 0 B Die Addition wird korrekt durchgeführt (wie man sieht), die Ausgabe lautet 100100, und die Eingabe wird akzeptiert. An dieser Stelle ändern wir die Sichtweise. Haben wir bisher so getan, als wäre durch ein Turingmaschinenprogramm und eine Eingabe ein tatsächlich ablaufender Vorgang gegeben, den man sich anschaulich vorstellt, geben wir nun mathematisch präzise Definitionen an, die den bisher informal eingeführten Konzepten entsprechen. Dadurch wird die von einer TM M berechnete Funktion fM ein präzise definiertes Objekt, ebenso die Menge der von M akzeptierten Wörter. Damit legen wir die Basis für die exakte Untersuchung der 30 Begriffe Berechenbarkeit“ und Entscheidbarkeit“. Zudem ergibt sich die Gelegenheit, ” ” den Ansatz der operationalen Semantik“ kennenzulernen, einer wichtigen Methode, die ” Semantik von Rechensystemen zu beschreiben. 1.1.10 Definition Eine Turingmaschine M besteht aus sieben Komponenten: Q, Σ, Γ, B, q0 , F, δ (formal: M = (Q, Σ, Γ, B, q0 , F, δ)), wobei gilt: (a) Q 6= ∅ ist eine endliche Menge. (Q ist die Menge der Zustände.) (b) Σ 6= ∅ ist eine endliche nichtleere Menge. (Σ ist das Eingabealphabet.) (c) Γ ist eine endliche Menge mit Σ ⊆ Γ. (Γ ist das Bandalphabet.) Dabei ist B ∈ Γ − Σ. (B ist das Blanksymbol.) (d) q0 ∈ Q. (q0 ist der Startzustand.) (e) F ⊆ Q. (F ist die Menge der akzeptierenden Zustände.) (f) δ : Q × Γ → Q × Γ × {R, N, L} ∪ {−} ist die Übergangsfunktion. (Wenn δ(q, a) = −, dann gilt δ(q, a) als undefiniert. δ ist also eine partielle Funktion.) Die Funktionsweise, insbesondere das Ein-/Ausgabeverhalten, einer Turingmaschine M werden gemäß dem Konzept der operationalen Semantik“ beschrieben. Das heißt, wir ” betrachten den Gesamtzustand, wie er durch Bandinhalt, Kopfposition und aktuellen Zustand gegeben ist, und beschreiben, welche Änderung dieser Zustand durch die Ausführung eines Schrittes erfährt. Das Wort Band“ kommt in diese Definition allerdings nicht vor, ” sondern wir benutzen das Konfigurationskonzept wie schon in der Vorlesung Automa” ten und Formale Sprachen“ bei den Kellerautomaten. Obgleich das Band unendlich ist, können nach endlich vielen Schritten der TM nur endlich viele Bandzellen besucht worden sein, also nur endlich viele mit einem von B verschiedenen Buchstaben beschriftet sein. Daher lassen sich Konfigurationen als endliche Texte beschreiben. Bezüglich der Konfigurationsübergänge sind die Verhältnisse einstweilen einfach, da unsere Turingmaschinen deterministisch sind und in jeder Konfiguration maximal ein Schritt ausführbar ist. Die Notation ist aber schon so gestaltet, dass sie leicht auf den später zu besprechenden Fall der nichtdeterministischen Turingmaschinen zu verallgemeinern ist. 1.1.11 Definition Eine TM M = (Q, Σ, Γ, B, q0 , F, δ) sei gegeben. Eine Konfiguration k (engl. instantaneous description“ (Momentaufnahme), technisch: snapshot“) von M ” ” ist ein Wort α1 (q, a)α2 mit q ∈ Q, a ∈ Γ, α1 , α2 ∈ Γ∗ , wobei α1 nicht mit B beginnt und α2 nicht mit B endet. (Für Formelspezialisten: Die Menge KM aller Konfigurationen von M ist einfach (Γ∗ − {B}Γ∗ )(Q × Γ)(Γ∗ − Γ∗ {B}).) Hieraus sieht man sofort, dass die Zahl der Konfigurationen abzählbar unendlich ist.) 31 Eine Konfiguration k entspricht einem möglichen inneren Zustand der Turingmaschine M wie folgt (vgl. Abb. 1.5). ... α1 B B B B α2 a B B B B B B B B ... q Abbildung 1.5: Veranschaulichung einer Konfiguration α1 (q, a)α2 Die Bandinschrift ist α1 aα2 , umrahmt von mit B beschrifteten Feldern; der Zustand ist q und der Kopf steht auf dem Feld mit dem Buchstaben a. Für die Anschauung ist es günstig, sich das q“ nicht neben dem a“, sondern darüber oder darunter vorzustellen. Umgekehrt ” ” entspricht jeder möglichen Kombination von Bandinhalt mit nur endlich vielen von B verschiedenen Buchstaben, Kopfposition und Zustand der TM genau eine Konfiguration.6 1.1.12 Definition (Semantik von TM-Berechnungen) Sei M = (Q, Σ, Γ, B, q0 , F, δ) eine Turingmaschine. (a) k = α1 (q, a)α2 sei Konfiguration von M . Wenn δ(q, a) = − ist, hat k keine Nachfolgekonfiguration; k heißt dann eine Haltekonfiguration. Wenn δ(q, a) = (q 0 , a0 , D) ∈ Q × Γ × {L, R, N }, dann besitzt k genau eine Nachfolgekonfiguration k 0 . Wir schreiben k `M k 0 oder k ` k 0 und lesen k 0 ist (die) direkte Nachfolgekonfiguration von k“. Wie k 0 ” aussieht, ist durch eine längere Fallunterscheidung beschrieben. (Die meisten Fälle kommen durch die Sonderbehandlung von B am Rand der Bandinschrift zustande.) 1. Fall: D = R (∗ Kopfbewegung nach rechts ∗) Standardfall: α2 6= ε. — Wir schreiben α2 = bβ mit b ∈ Γ, β ∈ Γ∗ . Dann ist k = α1 (q, a)bβ `M α1 a0 (q 0 , b)β, falls α1 a0 6= B, k = (q, a)bβ `M (q 0 , b)β, falls α1 = ε und a0 = B. Sonderfall: α2 = ε. — Dann ist k = α1 (q, a) `M α1 a0 (q 0 , B), falls α1 a0 6= B k = (q, a) `M (q 0 , B), falls α1 = ε und a0 = B 6 Die Regel, dass α1 nicht mit B beginnen darf und α2 nicht mit B enden darf, dient dazu, zu verhindern, dass einem inneren Zustand der TM viele äquivalente“ Konfigurationen entsprechen, die durch ” Streichen oder Hinzufügen von Blanks an den Rändern auseinander hervorgehen. 32 2. Fall: D = L (∗ Kopfbewegung nach links ∗) Standardfall: α1 6= ε. — Wir schreiben α1 = βb mit β ∈ Γ∗ , b ∈ Γ. Dann ist k = βb(q, a)α2 `M β(q 0 , b)a0 α2 , falls a0 α2 6= B k = βb(q, a) `M β(q 0 , b), falls a0 = B und α2 = ε Sonderfall: α1 = ε. — Dann ist k = (q, a)α2 `M (q 0 , B)a0 α2 , falls a0 α2 6= B k = (q, a) 3. Fall: D = N Dann ist `M (q 0 , B), falls a0 = B und α2 = ε (∗ Keine Kopfbewegung ∗) k = α1 (q, a)α2 `M α1 (q 0 , a0 )α2 . Elegante Alternative: Zur Verringerung der Anzahl der Fälle kleben wir links und rechts an k jeweils ein Blanksymbol an: Schreibe Bα1 = γ1 c und α2 B = dγ2 für passende c, d ∈ Γ und γ1 , γ2 ∈ Γ∗ . Dann beschreibt k̂ = Bα1 (q, a)α2 B = γ1 c(q, a)dγ2 dieselbe Situation von M wie k, nur mit zwei zusätzlichen Blankzeichen. Wir definieren γ1 (q 0 , c)a0 dγ2 , falls D = L; 0 γ1 ca0 (q 0 , d)γ2 , falls D = R; k̂ := γ1 c(q 0 , a0 )dγ2 , falls D = N . Die Nachfolgekonfiguration k 0 entsteht aus k̂ 0 durch Streichen aller B’s am Beginn und am Ende von k̂ 0 . (Beispiel : In Beispiel 1.1.8 gilt XXaX(C, b)bXcc ` XXaXX(D, b)Xcc und XXaXXbX(D, c)c ` XXaXXbXX(E, c) , aber auch cXcX(D, b) ` cXcXX(D, B), obgleich die Konfigurationen in der letzten Zeile in keiner Berechnung von M auf irgendeinem Input vorkommen. Die Haltekonfiguration XaXb(D, a)c entsteht in der Berechnung mit Input aabbac und bedeutet das nicht-akzeptierende Ende der Berechnung. Die Haltekonfiguration XXX(Y, B) wird auf Input abc erreicht.) 33 (b) Für i ∈ N wird die Relation ( indirekte Nachfolgerelation“) `iM (oder `i ) induktiv ” erklärt durch: k `0 k 0 , falls k = k 0 , und k `i k 0 , falls es eine Konfiguration k 00 gibt mit k `i−1 k 00 und k 00 ` k 0 , für i ≥ 1. Anders ausgedrückt: k `i k 0 , falls i = 0 und k = k 0 gilt oder i ≥ 1 ist und es Konfigurationen k0 , k1 , . . . , ki gibt, mit k = k0 ` k1 ` k2 ` · · · ` ki−1 ` ki = k 0 . (c) k 0 heißt (indirekte) Nachfolgekonfiguration von k, in Zeichen k `∗M k 0 oder k `∗ k 0 , falls k `i k 0 für ein i ∈ N. 1.1.13 Bemerkung Etwas abstrakter betrachtet ist `∗ einfach die reflexive und ” transitive Hülle“ der Relation `. — Wenn R ⊆ A × A eine beliebige zweistellige Relation ist, so ist die reflexive und transitive Hülle A∗ von A die durch die folgende induktive Definition gegebene Relation: (i) Es gilt aR∗ a für jedes a ∈ A; und wenn aRa0 gilt, dann auch aR∗ a0 . (ii) Wenn aR∗ a0 und a0 R∗ a00 , dann ist auch a `∗ a00 . (iii) Sonst stehen keine Paare (a, a0 ) in der Relation R∗ . R∗ ist die kleinste — bzgl. der Mengeninklusion — reflexive und transitive Relation über A, die R enthält. 1.1.14 Definition Sei M = (Q, Σ, Γ, B, q0 , F, δ) eine TM, und k = α1 (q, a)α2 eine Konfiguration von M . (a) k heißt Haltekonfiguration von M , falls δ(q, a) = −. (b) Ist k = α1 (q, a)α2 Haltekonfiguration, so heißt k akzeptierend, falls q ∈ F , verwerfend, falls q ∈ Q − F . (c) Ist n ∈ N und x = a1 · · · an ∈ Σn ein Eingabewort für M , so heißt ( (q0 , a1 )a2 · · · an falls n ≥ 1 init(x) := initM (x) := (q0 , B) falls n = 0 die Startkonfiguration für x auf M . 1.1.15 Definition M = (Q, Σ, Γ, B, q0 , F, δ) sei eine TM, x ∈ Σ∗ sei ein Eingabewort. 34 (a) Zur Startkonfiguration k0 = init(x) gehört eine (eindeutig bestimmte) Folge k0 ` k1 ` · · · von Konfigurationen. Diese heißt die Berechnung von M auf x. Es gibt zwei einander ausschließende Möglichkeiten: (i) Die Berechnung von M auf x ist endlich, d. h. init(x) `∗ k für eine (eindeutig bestimmte) Haltekonfiguration k. In diesem Fall sagen wir, dass M auf x hält. Wenn k akzeptierend ist, sagen wir, dass M x akzeptiert; wenn k verwerfend ist, sagen wir, dass M x verwirft. (ii) Die Berechnung von M auf x ist eine unendliche Folge von Konfigurationen. D. h. es gibt keine Haltekonfiguration k mit init(x) `∗ k. In diesem Fall sagen wir, dass M auf x nicht hält. (b) LM := {x ∈ Σ∗ | M akzeptiert x}. (c) HM := {x ∈ Σ∗ | M hält auf x}. (d) Für x ∈ Σ∗ ist die Ausgabe fM (x) von M auf x folgendermaßen definiert: Falls M auf x nicht hält, ist fM (x) undefiniert. Sonst sei k die (eindeutige) Haltekonfiguration mit init(x) `∗M k, und k = α1 (q, b)α2 , α1 , α2 ∈ Γ∗ , b ∈ Γ, q ∈ Q. Dann ist fM (x) das längste Präfix von bα2 , das den Blankbuchstaben B nicht enthält. (Offenbar gilt fM (x) = ε ⇔ b = B. Beachte: Für die Bestimmung der Ausgabe von M auf x ist es unerheblich, ob M x akzeptiert oder verwirft.) 1.1.16 Definition (a) Eine Sprache L heißt rekursiv aufzählbar (r. a.) (oder TM-akzeptierbar), falls es eine Turingmaschine M gibt, so dass L = LM ist. (b) Eine Sprache L heißt rekursiv (rek.) (oder TM-entscheidbar), falls es eine Turingmaschine M = (Q, Σ, . . .) gibt, die auf allen Eingaben x ∈ Σ∗ hält und für die L = LM gilt. (Man beachte, dass in diesem Fall HM = Σ∗ und {x ∈ Σ∗ | M verwirft x} = Σ∗ − LM gilt.) (c) Eine Funktion f : D → R heißt partiell rekursiv, falls es eine TM M = (Q, Σ, Γ, . . .) gibt derart dass D = HM , R ⊆ (Γ − {B})∗ und f = fM ist. (Andere Bezeichnung: partielle TM-berechenbare Funktion“.)7 ” (d) f heißt total rekursiv ( totale TM-berechenbare Funktion“) oder einfach rekursiv, ” falls f partiell rekursiv und total ist, d. h. falls D = Def(f ) = Σ∗ ist. 7 Die Funktion ist partiell, d. h. sie muss nicht auf allen Inputs in Σ∗ definiert sein. Der Ausdruck partiell rekursiv“ ist grammatisch eine Fehlbezeichnung, denn eigentlich müssten solche Funktionen ” partiell, rekursiv“ heißen; die falsche Zusammenfügung hat sich aber eingebürgert. ” 35 1.1.17 Bemerkung Alle Bezeichnungen aus der vorigen Definition sollten einen Index TM“ tragen. Im Hinblick auf unsere spätere Feststellung, dass der Berechenbarkeitsbe” griff vom Maschinenmodell unabhängig ist, und aus historischen Gründen, knüpfen wir die Standardbezeichnungen rekursiv aufzählbare Menge/Sprache“ und rekursive Men” ” ge/Sprache“ sowie partiell rekursive Funktion“ und (total) rekursive Funktion“ an das ” ” Turingmaschinenmodell. Wir stellen noch fest, dass es für die Definition der r. a. Sprachen keinen Unterschied macht, ob man LM oder HM betrachtet. 1.1.18 Lemma (a) Wenn M eine TM ist, dann gibt es TMn M 0 und M 00 derart dass HM 0 = LM und LM 00 = HM ist. (b) Eine Sprache L ist rekursiv aufzählbar genau dann wenn es eine TM M mit L = HM gibt. Beweis (Konstruktion) Sei M = (Q, Σ, Γ, B, q0 , F, δ). (a) Wir bauen M um zu einer TM M 0 , die zunächst wie M rechnet, aber nicht anhält, wenn M verwerfend hält. Hierzu müssen wir nur die Übergangsfunktion leicht verändern. Also: M 0 = (Q, Σ, Γ, B, q0 , F, δ 0 ), wobei wir für (q, a) ∈ Q × Γ definieren: falls dies definiert ist, δ(q, a), 0 −, falls δ(q, a) = − und q ∈ F , δ (q, a) := (q, a, N ), falls δ(q, a) = − und q ∈ Q − F . Die Form δ 0 (q, a) = (q, a, N )“ bewirkt offenbar, dass M 0 bei Erreichen dieser Situation ” endlos weiterläuft: dies realisiert eine Endlosschleife“. — Ähnlich bauen wir M um zu ” einer TM M 00 , die wie M rechnet, aber immer akzeptiert, wenn M hält. Dazu setzen wir einfach M 00 = (Q, Σ, Γ, B, q0 , F 00 , δ) mit F 00 := Q. (b) Dies folgt unmittelbar aus (a). Mit den Haltemengen HM werden wir uns im weiteren Verlauf der Vorlesung noch beschäftigen. Wir wollen Turingmaschinen für zwei sehr verschiedene Zwecke benutzen. Zunächst sind dies Untersuchungen zur Leistungsfähigkeit des Modells im allgemeinen, zum Vergleich mit anderen Rechenmodellen, zur Konstruktion von universellen Maschinen“, zum Ob” jekt struktureller Untersuchungen, zur Konstruktion nicht rekursiver Sprachen. Für diese Zwecke kommt uns die primitive Struktur dieser Maschinen zupass. Drastisch ausgedrückt ist es sehr angenehm, dass der Befehlssatz von Turingmaschinen so primitiv ist und die Übergangsfunktion keine Struktur hat, um die wir uns kümmern müssen. (Man möge sich im nachhinein Untersuchungen wie die im folgenden angestellten vor Augen halten, die mit einer Maschine hantieren, die auch nur 10 Maschinenbefehle hat, wie z. B. die RAM. Man würde in Fallunterscheidungen ertrinken“.) ” 36 Andererseits kommen wir nicht darum herum, uns davon zu überzeugen, dass gewisse Funktionen von einer TM berechnet werden können, bzw. dass gewisse Sprachen rekursiv aufzählbar oder rekursiv sind. D. h. wir müssen TMn angeben, die gewisse Rechnungen ausführen, also TMn programmieren. Hierfür ist die primitive Struktur des Modells und der primitive Befehlssatz extrem ungünstig. Man möge in frühere Texte zum Thema Berechenbarkeit“ schauen, um den Aufwand zu ermessen, den man treiben muss, um auf ” dem TM-Modell eine einigermaßen handhabbare Programmiermethodik zu entwickeln. Wir werden diese Arbeit nicht durchführen, sondern stattdessen etwa wie folgt vorgehen. Um eine TM anzugeben, die ein bestimmtes Problem löst, dürfen wir den Mengen Q, Σ und Γ eine ganz beliebige und bequeme Struktur geben, solange sie endlich sind. Weiter dürfen wir die Übergangsfunktion δ auf ganz beliebige Weise definieren, z. B. indem wir beschreiben, wie aus dem alten Zustand q und dem gelesenen Zeichen a das Tripel (q 0 , a0 , D) = δ(q, a) berechnet werden kann. Die Funktion δ muss aber keineswegs in irgendeiner Weise effizient oder sonstwie berechenbar“ sein, sondern zur Spezifikation von δ ” sind alle Mittel erlaubt“. Ein extremer Fall einer solchen strukturierten TM-Steuereinheit ” wird im folgenden beschrieben. Einfachere Konstruktionen finden sich im folgenden Abschnitt zu Programmiertechniken“. ” 13 1.1.19 Beispiel Γ = {0, 1}2 = {0, 1}8192 (die Bandsymbole“ sind Blocks von ” 1 kByte), B = 08192 fungiert als Blank. Die Steuereinheit sieht so aus: Band ... ... Programm Puffer Block 1kByte=1 Buchstabe Richtung Daten Befehlszähler Halt? Flagregister Akzeptiere? Abbildung 1.6: Strukturierte Steuereinheit Das Programm“ ist ein Programm in irgendeiner Programmiersprache. Daten“ ist ein ” ” lokaler Speicher mit fester Kapazität (in Bits) und völlig beliebiger Organisation. Insbesondere kann dieser Teil einen Befehlszähler für das Programm“ enthalten. Ein Schritt ” besteht aus folgendem: • Kopiere den Bandblock aus der eben besuchten Zelle in den Puffer. 37 • Das Programm“, startend am im Befehlszähler angegebenen Programmpunkt, be” rechnet aus Daten“ und Puffer“ einen neuen Block Daten0“ und einen neuen ” ” ” Pufferinhalt Puffer0“ sowie eine Richtung D ∈ {L, R, N } (die für diese Berechnung ” benötigte Zeit wird nicht in Betracht gezogen, sie gilt als konstant“). ” 0 • Puffer wird aufs Band geschrieben, Lesekopf wird um einen Block auf dem Band in Richtung D bewegt. • Eventuell wird ein Flag ( Halt?“ und/oder Akzeptiere?“) gesetzt. ” ” • Wenn das Flag Halt?“ gesetzt ist, erfolgt keine weiterer Schritt; das Flag Akzep” ” tiere?“ bestimmt, ob die Eingabe akzeptiert werden soll. Was ist jetzt Q? Q = {w | w möglicher Inhalt von Daten“, Befehlszähler“ und Flagregistern} ” ” Z. B. könnte Daten“ ein binärer Speicher der Kapazität 64 kByte sein, in dem Flagre” gister und Befehlszähler integriert sind. Dann ist Q = {0, 1}64·8·1024 . Es ist aber nicht vorgeschrieben, dass die Steuereinheit einem digitalen Rechner gleichen muss. Sowohl Bandalphabet als auch Speicher können eine ganz beliebige Struktur haben. Wir wollen kurz überlegen, wie aus einer solchen Beschreibung die unstrukturierte“ Be” schreibung gemäß Definition 1.1.2 zu gewinnen ist, z. B. wie eine Wertetabelle für δ zu erzeugen wäre. Sei a ∈ Γ (also ein beliebiger wie auch immer strukturierter) Bandbuchstabe. q sei einer der möglichen inneren Zustände der Steuereinheit. Wir schreiben a in den Puffer, setzen die internen Daten wie von q vorgeschrieben und lassen das Programm“ ” der Steuereinheit rechnen, bis es an eine Stelle kommt, wo der Puffer beschrieben wird. Für diesen Pufferinhalt a0 , den jetzigen internen Zustand q 0 , der Daten und Register, und das Zeichen D aus dem Richtungsregister gilt δ(q, a) = (q 0 , a0 , D). Auf diese (praktisch sehr langwierige) Weise ließe sich eine Wertetabelle für δ aufstellen. Mit dem skizzierten Ansatz lassen sich TM recht leicht programmieren. Oft gehen wir aber noch weiter und begnügen uns damit, eine informale Beschreibung der Aktivitäten der TM zu geben, und uns davon zu überzeugen, dass im Prinzip eine Steuereinheit mit fixem Speicher diese Aktivitäten ausführen kann. Wir müssen bei diesem Vorgehen nur folgendes beachten: – Das Arbeitsbandalphabet ist eine endliche Menge; für jede Turingmaschine ist eine maximale Zahl unterschiedlicher Zelleninhalte vorgegeben. Bei einer festen TM M ist es nicht möglich, in einer Bandzelle beliebig große natürliche Zahlen zu speichern. – die Kapazität des Speichers der Steuereinheit ist fest; er hängt nicht von der Länge der Eingabe ab. – das Programm in der Steuereinheit ist fest, insbesondere von fester Länge. 38 Gravierende Programmierfehler bei TM, die in dieser Art spezifiziert sind, sind folgende: • Die Steuereinheit enthält Integervariable, deren Wertebereich nicht beschränkt ist. Allgemeiner: Datentypen mit unendlich vielen Instanzen kann man nicht in der Steuereinheit halten. • Der Umfang der Daten, die in der Steuereinheit gehalten werden, hängt von der Eingabe ab (z. B. verkettete Strukturen, deren Knotenzahl unbeschränkt ist). Es erfolgen rekursive Aufrufe mit unbeschränkter Tiefe, wobei der Laufzeitkeller in der Steuereinheit gehalten wird. Zum Speichern solcher Daten muss man auf das Band ausweichen. Um natürliche Zahlen zu speichern, benutzt man Binärdarstellung (konstante Zahl von Bits pro Zelle); um Zeiger zu speichern, die Binärdarstellung der Zahlenwerte; ein eventuell nötiger Laufzeitkeller wird auf dem Band organisiert. Bemerkung: Strukturen mit Records / Verbunden / Sätzen sollte man so anlegen, dass jedes Record eine eindeutige Nummer hat, die explizit angegeben ist. 1.2 Programmiertechniken und Varianten von Turingmaschinen In diesem Abschnitt besprechen wir eine Reihe von Methoden, wie man die Zustandsmenge Q und das Bandalphabet Γ strukturieren kann, um die Programmierung von Turingmaschinen übersichtlicher zu gestalten oder unmittelbar einsichtig zu machen, dass eine TM eine bestimmte Berechnungsaufgabe erfüllen kann. Zudem betrachten wir Modellvarianten wie Turingmaschinen mit nur einem einseitig unendlichen Band oder solche mit mehreren Arbeitsbändern und weisen nach, dass solche Einschränkungen oder Erweiterungen unseres ursprünglichen Maschinenmodells ebenso zu den partiell rekursiven Funktionen und den rekursiv aufzählbaren Sprachen führen wie das Standardmodell. 1.2.1 Endlicher Speicher in der Steuereinheit Wir können uns vorstellen, dass die Steuereinheit Speicherplatz für eine beschränkte Anzahl von Bandsymbolen hat (oder Objekte aus einer beliebigen endlichen Menge, also eines Alphabets ∆). Hierzu benutzt man eine Zustandsmenge Q, deren Elemente folgende Struktur aufweisen: (q, a1 , . . . , ak ), wobei q ein Zustand im eigentlichen Sinne ist, der der Ablaufsteuerung dient; a1 , . . . , ak sind die gespeicherten Buchstaben. Als Beispiel betrachten wir die Sprache L = {a1 a2 · · · an−1 an ∈ Σ∗ | n ≥ 2, a1 a2 = an−1 an } 39 der Wörter über Σ, bei denen die beiden Anfangsbuchstaben mit den beiden Endbuchstaben identisch sind.8 Die Idee für eine TM M mit L = LM ist, die beiden ersten Buchstaben in der Steuereinheit zu speichern und nach einer Fahrt mit dem Kopf über das Eingabewort mit den beiden letzten Buchstaben zu vergleichen. Hierzu legen wir δ wie folgt fest: δ(q0 , a) δ((q1 , a), b) δ((q2 , a, b), c) δ((q2 , a, b), B) δ((q3 , a, b), b) δ((q4 , a), a) = = = = = = ((q1 , a), a, R), für a ∈ Σ ((q2 , a, b), b, R), für a, b ∈ Σ ((q2 , a, b), c, R), für a, b, c ∈ Σ ((q3 , a, b), B, L), für a, b, c ∈ Σ ((q4 , a), b, L), für a, b ∈ Σ (q5 , a, N ), für a ∈ Σ Wie üblich sind nicht erwähnte Übergänge undefiniert. Zustand q0 ist der Startzustand; in Zustand (q1 , a) ist a gespeichert; in Zustand (q2 , a, b) sind a und b gespeichert und der Kopf fährt zum Ende der Eingabe; in Zustand (q3 , a, b) wird getestet, ob b gelesen wird (als letzter Eingabebuchstabe); in Zustand (q4 , a) wird getestet, ob a gelesen wird (als vorletzter Buchstabe); q5 schließlich ist der akzeptierende Endzustand. Schließlich definieren wir Q := {q0 , q5 } ∪ {(q1 , a), (q4 , a) | a ∈ Σ} ∪ {(q2 , a, b), (q3 , a, b) | a, b ∈ Σ} und F := {q5 }. Man beachte, wie hier M in Abhängigkeit von Σ festgelegt wird, ohne dass wir Σ explizit kennen müssen. Weiter ist die Anzahl der in einem Zustand gespeicherten Buchstaben je nach Bedarf schwankend. Man darf nur nicht vorsehen, dass unbeschränkt viele Buchstaben in Zuständen gespeichert werden, weil sonst Q nicht mehr endlich ist. In Verallgemeinerung des Speicherns von Buchstaben aus der Eingabe kann man in Zuständen nach Bedarf auch Flagbits oder Register aus Flagbits anlegen, die es erlauben, vorher gesammelte Informationen aufzubewahren. 1.2.2 Spurtechnik Ist ∆ irgendein Alphabet und k ≥ 1, dann kann man sich vorstellen, dass das TM-Band mit k Spuren versehen ist, deren jede in jeder Zelle ein Symbol aus ∆ aufnehmen kann. Spur 1 2 3 4 5 ... ... ... ... ... e B 3 v B i z 3 i B 8 n w 3 e B s e 3 r B B i B 4 5 ... ... ... ... ... Natürlich ist L eine reguläre Sprache, für die man leicht einen DFA ohne weitere TM-Fähigkeiten angeben könnte. 40 Abbildung 1.7: Band mit fünf Spuren Wir realisieren dies dadurch, dass wir ein Bandalphabet Γ benutzen, das alle Elemente (a1 , . . . , ak ) von ∆k enthält. (In Abb. 1.7 sind etwa (e, B, 3, v, B) und (B, i, B, 4, 5) Elemente von Γ.) Gelesen werden immer die Symbole in allen Spuren gleichzeitig. Die Steuereinheit kann für die Verarbeitung einige Spuren ausblenden; dieses kann man z. B. über Flagregister in der Steuereinheit steuern. Anschaulich kann man diese zusammengesetzten Buchstaben auch als Spaltenvektoren schreiben: ( ! ) a.1 .. Γ ⊇ ∆k = : a 1 , . . . , ak ∈ ∆ . ak Wenn man während der Rechnung oder auf verschiedenen Bandabschnitten die Spuranzahl wechseln will, benutzt man einfach Γ mit ∆ ∪ ∆2 ∪ · · · ∪ ∆k ⊆ Γ, für ein festes k, und hat nach Belieben 1 bis k Spuren zur Verfügung. Allerdings ist es ein Programmierfehler, wenn die TM inputabhängig unbeschränkt viele Spuren anlegen soll, da dann die Menge Γ nicht mehr endlich ist. Man kann sich die Spuren auch mit Symbolen verschiedener Spezialalphabete beschriftet denken — das ist nützlich, wenn man Bandzellen markieren will: ... B b a n d # # i n s c h r i f t ... Textspur ... *+ ... Markierung * + Abbildung 1.8: Markierungen auf zweiter Spur Es ist erlaubt, eine feste Anzahl von Markierungen in einer Bandzelle zu halten, ein Programmierfehler ist es aber, wenn unbeschränkt viele Markierungen in einer Zelle vorgesehen sind. 1.2.3 Programmiertechnik: Bandinhalt verschieben Mit der Mehrspurtechnik und der Technik des Speicherns von Buchstaben lässt sich die folgende wichtige Grundaufgabe für Turingmaschinen lösen: Verschieben eines Teils des Bandinhaltes: Auf Spur 1 steht eine Inschrift über dem Alphabet ∆ (mit B ∈ / ∆), auf Spur 2 stehen drei Markierungen: ein /c und (irgendwo rechts davon) ein $ sowie an beliebiger Stelle rechts vom /c ein . Die Aufgabe ist es nun, das Teilwort zwischen der mit /c und der mit $ markierten Stelle so nach rechts zu verschieben, dass der erste Buchstabe des Teilworts in der Bandzelle mit der Markierung steht, und den entstehenden Platz mit B’s aufzufüllen. Anfangs soll der Bandkopf irgendwo links von der Markierung /c stehen. 41 vorher: Spur 1 Spur 2 l i n k s r e c h t s u n d s o w e i t e r B B B c $ zu verschieben nachher: Spur 1 Spur 2 l i n k s B B B B B B B B r e c h t s u n d s o w c $ Hilfsspur r e c h t s u n d s o w Die einfache Idee ist, auf dem Band eine neue (Hilfs-)Spur anzulegen und auf dieser Hilfsspur das zu verschiebende Teilwort so zu speichern, dass es bei der Markierung beginnt. Eine Initialisierung der Hilfsspur ist überflüssig, wenn man vereinbart, dass eine nicht vorhandene dritte Spur in einer Zelle so zu verstehen ist, dass die dritte Spur in dieser Zelle ein B enthält. Ein spezielles Markierungszeichen (z. B. +) wird benutzt, um schon kopierte Zeichen zu markieren. Das Teilwort wird wie folgt Zeichen für Zeichen kopiert. Zu Beginn fährt der Kopf nach rechts bis zum /c. Diese Zelle enthält das erste zu kopierende Zeichen. Zunächst wiederhole folgendes (1.–5.): 1. Speichere den Buchstaben a aus Spur 1 in der Steuereinheit; markiere die Zelle mit +; 2. Fahre den Kopf nach rechts bis zur ersten Zelle nach dem (einschließlich), das in der Hilfsspur ein B enthält; überschreibe dieses B mit dem gespeicherten Buchstaben a; 3. Fahre den Kopf nach links, bis eine mit + markierte Zelle erreicht wird; 4. Wenn dies die $-Zelle ist, ist der Kopiervorgang beendet; gehe zu 6. 5. Sonst bewege den Kopf um eine Zelle nach rechts und mache bei 1. weiter. 6. Fahre den Kopf nach links bis zur /c-Zelle; 7. Fahre den Kopf nach rechts bis zur -Zelle (ausschließlich), überschreibe in jeder dabei besuchten Zelle Spur 1 mit B; 8. von der -Zelle (einschließlich) nach rechts gehend kopiere die Buchstaben von Spur 3 auf dasselbe Feld in Spur 1, lösche dabei gleichzeitig Spur 3, bis zur ersten Zelle (ausschließlich), die in Spur 3 ein B enthält; 9. fahre den Kopf nach links bis zur /c-Zelle. Wenn l die Länge des zu verschiebenden Teilwortes ist und d die Distanz von /c nach , so benötigt das Kopieren O(l · d) Schritte der TM. Wofür kann diese Prozedur dienen? 42 Da jedes Bandfeld nur endliche Kapazität hat, kann es passieren, dass man an einer bestimmten Stelle des Bandes neue Felder einfügen“ möchte, um dort entstehende Daten ” zu speichern. Die Verschiebeprozedur erlaubt dies, ohne dass man das Modell erweitern muss. Ein typischer Fall sind binäre Zähler, die in manchen Rechnungen benutzt werden und deren Umfang (in Bits) mit dem Zählerstand wächst. — Ebenso oft kommt es vor, dass Information, die sich an einer Stelle des Bandes befindet, an einer anderen Stelle gebraucht wird. 1.2.4 Modelleinschränkung: Einseitig unbeschränktes Band Gegeben sei eine beliebige TM M = (Q, Σ, Γ, B, q0 , F, δ). Wir behaupten, dass es eine andere TM M 0 gibt, die dasselbe Ein-/Ausgabeverhalten wie M hat, d. h. LM = LM 0 , HM = HM 0 , und fM = fM 0 erfüllt, und zusätzlich die Eigenschaft hat, dass der Kopf nie ein Feld links der ursprünglichen Position betritt. Turingmaschinen mit einseitig unbeschränktem Band sind als Unterprogramme nützlich, wenn man für die Durchführung des Unterprogramms kein ganzes unbeschriebenes Band verwenden kann, sondern nur ein halbes Band“ rechts von einer Bandinschrift, die nicht ” zerstört werden darf. 0 1 2 3 4 5 i n p u t B B B B B B B ... verboten q0 -3 -2 -1 0 1 2 3 4 5 b a n d + v o n + M + 2 s e i t i g B ... 0 1 2 3 4 5 Band n + M + 2 s e i t i g B B B B B B ... von M’: * o v + d n a b B B B B B B B B B ... -1 -2 -3 Die Idee ist, den Bandanteil links von der ursprünglichen Kopfposition umzuklappen“ ” und in umgekehrter Reihenfolge auf einer zweiten Spur zu speichern. In Spur 2 des ersten Bandfeldes (Kopfposition zu Beginn der Berechnung) wird eine Markierung ∗“ ange” bracht. Die Steuereinheit enthält ein Flagregister, das anzeigt, ob momentan in der oberen 43 Spur (rechte Seite) oder der unteren Spur (linke Seite) gearbeitet wird. Die Steuereinheit der neuen Maschine M 0 sieht anschaulich so aus: Steuereinheit von M e a Puffer oben oben/unten? Abbildung 1.9: Neue Steuereinheit Formal können wir definieren: M 0 = (Q0 , Σ, Γ0 , B 0 , q00 , F 0 , δ 0 ), wobei die Komponenten wie folgt festgelegt sind. Q0 = Q × {u, o} ∪ {q00 }; Γ0 = Γ × (Γ ∪ {∗}) ∪ Σ; B 0 = (B, B) Um die Notation zu vereinfachen, soll das Lesen eines Zeichens a ∈ Σ in δ dasselbe bewirken wie das Lesen von (a, B). Der neue Startzustand q00 dient nur dem Anbringen der ∗-Markierung. Die Übergangsfunktion kann so festgelegt werden (wobei immer a, b, c ∈ Γ, q, p ∈ Q, D ∈ {L, R, N }): δ 0 (q00 , a) δ 0 (q00 , (B, B)) δ 0 ((q, o), (a, c)) δ 0 ((q, u), (c, a)) ((q0 , o), (a, ∗), N ), für a ∈ Σ; ((q0 , o), (B, ∗), N ), (falls der Input ε ist); ((p, o), (b, c), D), für q ∈ Q, δ(q, a) = (p, b, D), c 6= ∗; ((p, u), (c, b), D̄), für q ∈ Q, δ(q, a) = (p, b, D), a 6= ∗, wobei R̄ = L, L̄ = R, N̄ = N ; ((p, u), (b, ∗), R), falls D = L, δ 0 ((q, u), (a, ∗)) ((p, o), (b, ∗), R), falls D = R, = δ 0 ((q, o), (a, ∗)) ((p, o), (b, ∗), N ), falls D = N ; wobei immer δ(q, a) = (p, b, D). = = = = Es sollte klar sein, dass M 0 die Aktionen von M Schritt für Schritt simuliert. Damit gilt schon einmal HM = HM 0 . Um gleiches Akzeptierungsverhalten zu haben, müssen wir noch F 0 := F × {u, o} setzen. Um zu erreichen, dass fM = fM 0 , benötigt man eine Nachverarbeitungsphase, in der nach dem Anhalten von M der Inhalt der beiden Spuren so verschoben wird, dass das Ausgabewort in der oberen Spur in der richtigen Reihenfolge erscheint, und in der schließlich die Doppelbuchstaben durch einfache ersetzt werden. Dies ist mit der in 1.2.3 dargestellten Technik möglich; wir lassen die Details aus. 44 1.2.5 Definition k-Band-Maschine. Wir betrachten Turingmaschinen mit k ≥ 2 Bändern. Die Eingabe steht zu Beginn auf Band 1, jedes Band besitzt einen eigenen Bandkopf. ... B B B e i n g a b e B B B B B ... ... B B B B B B B B B B B B B B B ... ... B B B B B B B B B B B B B B B ... Steuereinheit Abbildung 1.10: 3-Band-Maschine Die Übergangsfunktion δ bildet nun (eine Teilmenge) von Q×Γk nach Q×Γk ×{L, R, N }k ab. Dabei bedeutet δ(q, a1 , . . . , ak ) = (q 0 , a01 , . . . , a0k , D1 , . . . , Dk ), dass, falls im Zustand q auf Band i Buchstabe ai gelesen wird, 1 ≤ i ≤ k, auf Band i Buchstabe a0i gedruckt wird und sich der Kopf in Richtung Di bewegt, für 1 ≤ i ≤ k. Konfigurationen, Akzeptierungsbegriff, Ausgabe werden analog zu 1-Band-TMn definiert. Für die Eingabe und die Ausgabe betrachtet man nur die Inschrift auf Band 1. 1.2.6 Satz Ist M eine k-Band-TM, so gibt es eine 1-Band-TM M 0 , die dasselbe EinAusgabe-Verhalten wie M hat, d. h. die LM = LM 0 , HM 0 = HM und fM = fM 0 erfüllt. Beweis (Konstruktion) Sei M = (Q, Σ, Γ, B, q0 , F, δ). Wir beschreiben, wie die 1-BandTM M 0 aufgebaut ist und wie sie arbeitet. Das Band von M 0 ist mit 2k + 1 Spuren versehen. Dem iten Band von M entsprechen Spuren 2i − 1 und 2i von M 0 . Spur 2i − 1 trägt dabei die Bandinschrift von Band i, (Alphabet Γ), auf Spur 2i gibt es außer Blanks nur eine Markierung ∗“, die die Position des Lese-Schreib-Kopfes von M auf Band i ” markiert (Alphabet {∗, B}). Spur 2k + 1 enthält Markierungen /c und $, die Anfang und Ende des bisher besuchten Abschnittes des Bandes von M 0 markieren. 45 Spur 1 ... B + i n s c h r i f t + b a n d + 1 + B B B B B B B B B ... Spur 2 ... ... Spur 3 ... B B B + i n s c h r i f t Spur 4 ... Spur 5 ... B + + + i n s c h r i f t + + + b a n d + + + 3 + + + B ... Spur 6 ... * ... Spur 7 ... C $ ... * + + b a n d + + 2 + + B B B B ... * d L i N + L Register Richfur Symbole tungsbei "*" register (3 Bänder) ... Steuereinheit von M aktueller Zustand Steuereinheit von M’ M 0 simuliert jeden Schritt von M wie folgt: (i) Zu Beginn steht der Kopf von M 0 auf der Zelle mit /c. (ii) Die Steuereinheit von M 0 speichert den gegenwärtigen Zustand q von M in einem Zustandsregister. (iii) Der Kopf von M 0 durchläuft das Band von /c nach $ und speichert dabei in k ΓRegistern in der Steuereinheit die Buchstaben a1 , . . . , ak , die in den Spuren 1, 3, . . . , 2k− 1 in den mit ∗ markierten Zellen stehen. Dann fährt der Kopf zum /c zurück. (iv) M 0 bestimmt (in der Steuereinheit) δ(q, a1 , . . . , ak ) = (q 0 , a01 , . . . , a0k , D1 , . . . , Dk ), falls dies definiert ist. Damit sind die neuen zu schreibenden Bandsymbole a01 , . . . , a0k , die Richtungen D1 , . . . , Dk ∈ {L, R, N } für die Kopfbewegungen und der neue Zustand q 0 von M gegeben. Wenn δ(q, a1 , . . . , ak ) undefiniert ist, endet die schrittweise Simulation, man springt zur Nachbearbeitung (s. u.). (v) Der Kopf fährt erneut von /c nach $ und zurück. Für jedes i wird in derjenigen Zelle, die in Spur 2i die ∗-Markierung trägt, in Spur 2i − 1 das Zeichen a0i eingetragen. Bei der Links-Rechts-Bewegung werden zudem die ∗-Markierungen in den Spuren 46 2i mit Di = R um eine Zelle nach rechts bewegt; bei der Rechts-Links-Bewegung entsprechend die mit Di = L um eine Zelle nach links. Wird ein ∗ in der /c-Zelle nach links verschoben, wird auch die /c-Markierung mit verschoben, entsprechend bei der $-Markierung rechts. (vi) Schließlich steht Kopf von M 0 wieder auf der /c-Zelle. Beginne wieder mit (i). Vorbearbeitung: Ganz zu Anfang enthält das Band von M 0 die Eingabe x = a1 · · · an , ohne Spurstruktur. M 0 beschreibt die 2k+1 Spuren in einem Schritt mit (a1 , ∗, B, ∗ . . . , B, ∗, {/c, $}), bzw. mit (B, ∗, B, ∗ . . . , B, ∗, {/c, $}), wenn x = ε ist. Wenn während der Simulation eine Zelle betreten wird, die nur einen Inputbuchstaben ai enthält, wird diese so behandelt, als enthielte sie die Inschrift (ai , B, . . . , B). Ende der Rechnung: Falls in (iv) δ(q, a1 , . . . , ak ) undefiniert ist, muss M 0 noch etwas aufräumen. M 0 fährt den Kopf bis zur ∗-Markierung in Spur 2 und von da zum ersten B auf Spur 1 rechts davon, aber auch nicht weiter als bis zur $-Zelle. vorher: b1 b2 b3 br B i r ... r e l e v a n t * 2k+1 nachher: b b b 1 2 3 ... ... . . . ... ... br B i r r e l e v a n .. . t ... Von dort fährt der Kopf zurück zum ∗ in Spur 2, überschreibt dabei Bandzellen mit Eintrag b ∈ Γ auf Spur 1 mit b (ohne Rücksicht auf die Spurstruktur). Sobald die ∗-Markierung erreicht ist, hält M 0 und akzeptiert/verwirft je nachdem ob q ∈ F oder q ∈ / F. Nach Konstruktion hat M 0 dasselbe Ein-/Ausgabeverhalten wie M . Aus Satz 1.2.6 ziehen wir die Konsequenz, dass wir, wenn es bequem ist, auch MehrbandTuringmaschinen benutzen können, wenn wir zeigen wollen, dass Sprachen rekursiv aufzählbar oder rekursiv oder Funktionen (partiell) rekursiv sind. Wie bei Registermaschinen kann man TM-Berechnungen einen Zeitaufwand zuordnen, und zudem einen Platzverbrauch. Wir formulieren diese Konzepte gleich für k-Band-TMn. 1.2.7 Definition (Zeit- bzw. Platzbedarf [ Zeit- bzw. Platzkomplexität“] einer TM) ” Sei M eine k-Band-TM, x ∈ Σ∗ für das Eingabealphabet Σ von M . Wir definieren: 47 Zahl der Schritte, die M auf Eingabe x ausführt ∈ N ∪ {∞} (d. h. das eindeutig bestimmte i mit initM (x) `i k für eine Haltekonfiguration k von M bzw. ∞, falls M auf x nicht hält); sM (x) := Anzahl der verschiedenen Zellen, auf die die Köpfe von M bei Eingabe x schreibend zugreifen, auf allen Bändern zusammen ( ∈ N ∪ {∞}); 9 TM (n) := max{tM (x) | x ∈ Σn } (Zeitbedarf im schlechtesten Fall über alle Eingaben der Länge n: worstcase-Zeitkomplexität); SM (n) := max{sM (x) | x ∈ Σn }. tM (x) := Sei t : N → R+ eine Funktion. M heißt t(n)-zeitbeschränkt, falls TM (n) ≤ t(n) für alle n ∈ N gilt, d. h. falls tM (x) ≤ t(|x|) für alle x ∈ Σ∗ gilt. Sei s : N → R+ eine Funktion. M heißt s(n)-platzbeschränkt, falls SM (n) ≤ s(n) für alle n ∈ N gilt, d. h. falls sM (x) ≤ s(|x|) für alle x ∈ Σ∗ gilt. Man kann z. B. sagen, eine TM M sei 10n2 -zeitbeschränkt, wenn TM (n) ≤ 10n2 für alle n gilt. Der entscheidende Vorteil dieser Sprechweise ist, dass die Funktion TM (n) oft einen sehr unübersichtlichen Verlauf hat, sich eine einfache obere Schranke t(n) aber in vielen Fällen angeben lässt. Man beachte, dass aus M ist t(n)-zeitbeschränkt“ und t(n) ≤ t0 (n) ” folgt, dass M auch t0 (n)-zeitbeschränkt ist. Zur Erinnerung: Für Funktionen f, g : N → R+ schreiben wir g(n) = O(f (n)), wenn es eine Konstante c > 0 gibt, so dass g(n) ≤ c · f (n) gilt, für alle n ∈ N. Offenbar gilt für jede k-Band-Turingmaschine M : wenn M t(n)-zeitbeschränkt ist, dann ist M k · t(n)-platzbeschränkt; die in Satz 1.2.6 beschriebene 1-Band-TM M 0 zu M ist sogar t(n)-platzbeschränkt. 1.2.8 Satz Sei eine t(n)-zeitbeschränkte und s(n)-platzbeschränkte k-Band-TM M gegeben. M 0 sei die in Satz1.2.6 beschriebene 1-Band-TM. Dann gilt: (a) M 0 ist s(n)-platzbeschränkt. (b) M 0 ist O(s(n) · t(n))-zeitbeschränkt. (c) M 0 ist O(t(n)2 )-zeitbeschränkt. Beweis Sei die Eingabe x ∈ Σn . M 0 benutzt nicht mehr Zellen als M . Damit ist die Platzschranke in (a) klar. Für jeden Rechenschritt von M muss der bislang besuchte Teil des Bandes von M 0 viermal überquert werden — das dauert O(s(n)) Schritte. Insgesamt benötigt M 0 also höchstens t(n) · O(s(n)) = O(s(n)t(n)) Schritte. Damit ist (b) gezeigt. (c) folgt aus (b) und der Bemerkung vor dem Satz. 9 Wenn ein Kopf eine Zelle erstmals besucht, aber dieser Besuch in einer Haltekonfiguration stattfindet, gilt dies nicht als schreibender Zugriff und zählt nicht zum Platzbedarf. 48 1.2.9 Definition (Zeitkomplexitätsklassen) Für t : N → R+ definieren wir: DTIME(t(n)) := {LM | M ist k-Band-TM, ∃c > 0 : M ist c · t(n)-zeitbeschränkt} . Die so definierten Sprachenmengen heißen Zeit-Komplexitätsklassen.10 1.2.10 Programmiertechnik: Unterprogramme Ist M eine TM, so können wir bei 0 der Programmierung einer beliebigen anderen TM M die TM M als Unterprogramm“ ” nutzen. D. h., M 0 schreibt während der Rechnung auf ein sonst leeres Band eine Eingabe x für M , startet M durch Umschalten auf den Startzustand von M , und erhält von M nach Beendigung der Rechnung eine Ja/Nein-Entscheidung, je nachdem ob x ∈ LM oder nicht, oder auch den Funktionswert fM (x) geliefert. Mit diesem Ergebnis nimmt M 0 seine Berechnung wieder auf. M selbst kann auch mehrere Bänder benutzen. Ist M wie in Beispiel 1.2.4, genügt auch ein einseitig leeres Band von M 0 , dann benutzt man als Arbeitsbereich für M einen Bandabschnitt rechts von allen beschrifteten Zellen. Es kann sein, dass M von mehreren verschiedenen Programmstellen (Zuständen) von M 0 aus aufrufbar sein soll und mehrere Wiedereinstiegsstellen (Rücksprungadressen) möglich sein sollen. In diesem Falle ist es am einfachsten, die Version von M zu benutzen, die nur 0 1 ein einseitig unbeschränktes Band hat, und M 0 als Eingabe #qrück #qrück #x zu übergeben, 0 1 wo qrück und qrück die Rücksprungadressen im Programm (d. h. der Turingtafel) von M 0 für die Fälle x ∈ LM oder x 6∈ LM sind. Statt zweier Rücksprungadressen kann man auch nur eine oder mehr als zwei angeben. Mit diesen Tricks ist es recht einfach, sogar rekursive Unterprogramme oder sich gegenseitig aufrufende rekursive Unterprogramme auf Turingmaschinen zu realisieren. (Details werden in den Übungen besprochen.) 10 Platz-Komplexitätsklassen werden in der Vorlesung Komplexitätstheorie“ behandelt. ” 49 ... ... Bänder von M’ ... ... ... B B a a a 1 2 3 ... an B B B ... Band von M M’: Programm von M’ ohne M Beschreibung von M endliches Objekt! Abbildung 1.11: TM M als Unterprogramm von TM M 0 1.2.11 Programmiertechnik: Textsuche Eine häufig auftretende Teilaufgabe in Turingmaschinenberechnungen (die sich auch als Unterprogramm realisieren lässt) ist die Suche nach einem Abschnitt einer Bandinschrift (Text) t = b1 · · · bm , der mit einem vorgegebenen Muster (engl. pattern) p = a1 · · · an übereinstimmt. Ist z. B. p = 10010, t = 011010011001001010101, findet sich p in t beginnend bei Position 9 und nochmals beginnend bei Position 12. Wenn ∆ ein Alphabet ist, das # nicht enthält, dann existiert eine 3-Band-TM M = (Q, Σ, Γ, . . .) , die folgendes tut: Auf Eingabe a1 · · · an #b1 · · · bm ∈ ∆∗ {#}∆∗ berechnet M (als Ausgabe auf Band 2) das Binärwort bin(j), wo j minimal ist mit bj bj+1 · · · bj+n−1 = a1 · · · an , falls ein solches j existiert. Zudem steht am Ende der Rechnung der Bandkopf von Band 1 auf der Zelle, die bj enthält. Falls das Teilwort a1 · · · an nicht in b1 · · · bm vorkommt, hält M in einem verwerfenden Zustand. 50 Bandinhalt während der Rechnung : Band 1 ... B a1 a2 a n # b1 b2 ... bj ... bm B B ... * Band 2 Band 3 bin(j) ... B a1 a2 a n B ... Methode: Kopiere a1 · · · an auf Band 3. Initialisiere Band 2 mit 1. Markiere b1 auf ExtraSpur auf Band 1 mit ∗. Wiederhole: Vergleiche den String auf Band 1, startend bei ∗, Zeichen für Zeichen mit a1 · · · an . Falls alle Zeichen gleich: fahre den Bandkopf auf Band 1 nach links zum ∗ und halte. Falls a1 · · · an nicht vollständig gelesen werden kann, halte verwerfend. Sonst rücke ∗ um eine Zelle weiter nach rechts, erhöhe die Binärzahl auf Band 2 um 1. Anwendung: Falls ein Band eine Folge von Records enthält, die durch einen Schlüssel oder Namen identifiziert werden ( identifier“), etwa der Form ” ... feld3 # identifier # feld1 # feld2 # feld3 # identifier ... Binärzahl Binärzahl so findet man den durch einen Zeiger“ (auf einem anderen Band) ” # identifier0 # bezeichneten Record via Textsuche. 1.2.12 Modelleinschränkung: Standardalphabete Σ = {0, 1}, Γ = {0, 1, B}. Wie in der Vorlesung Automaten und Formale Sprachen“ schon bemerkt, kann man jedes ” Alphabet Σ mit |Σ| = b durch das Normalalphabet“ {0, 1, . . . , b − 1} ersetzen. Ebenso ” kann man sich immer vorstellen, die Zustandsmenge Q einer TM sei einfach {0, 1, . . . , |Q|− 1}. Mitunter ist es aber unbequem, Eingabealphabete und Bandalphabete beliebiger Kardinalität zu haben. In diesen Fällen hilft der Ansatz, Bandsymbole binär zu kodieren.11 11 Das ist natürlich ein in der Informatik alltägliches Vorgehen. 51 (a) Eingabealphabet. Sei Σ irgendein Alphabet, |Σ| ≥ 2. Betrachte eine beliebige, aber feste Binärkodierung 1−1 ϕ : Σ → {0, 1}dlog2 |Σ|e für die Buchstaben. Nun kodiert man Wörter binär: ϕ(a1 · · · an ) := ϕ(a1 ) · · · ϕ(an ), für n ∈ N, a1 , . . . , an ∈ Σ. | {z } ∈{0,1}∗ Ebenso kann man dann die Binärkodierung von Sprachen definieren: ϕ(L) = {ϕ(w) | w ∈ L} ⊆ {0, 1}∗ , für L ⊆ Σ∗ . Wenn beispielsweise ϕ : {a, b, c, d, #, $} → {0, 1}3 durch a b c d # $ a ϕ(a) 000 001 010 011 110 111 gegeben ist, so ist ϕ(ab#dc) = 000001110011010 und ϕ({ab#dc, a$d}) = {000001110011010, 000111011}. Ähnlich definiert man die Binärkodierung einer Funktion f : D → Σ∗ mit D ⊆ Σ∗ als f ϕ : φ(D) → {0, 1}∗ , ϕ(w) 7→ ϕ(f (w)). Mit diesen Definitionen gilt: (i) L ist rekursiv ⇔ ϕ(L) ist rekursiv; (ii) L ist rekursiv aufzählbar ⇔ ϕ(L) ist rekursiv aufzählbar; (iii) f ist partiell rekursiv ⇔ f ϕ ist partiell rekursiv. Beweisidee: (i), (ii) ⇒“: Sei L = LM für eine TM M (bei (i): M hält auf allen ” Inputs). Eine neue TM M 0 mit Inputalphabet Σ0 = {0, 1} arbeitet wie folgt: Ein Input w ∈ Σ0∗ wird in Blöcken von jeweils l = dlog2 |Σ|e Bits gelesen und jeder Block wird mittels ϕ−1 , das in der Steuereinheit gespeichert ist, in einen Buchstaben a ∈ Σ umgewandelt und auf Band 2 geschrieben. Falls |w| nicht Vielfaches von l ist, wird die Eingabe verworfen. Danach wird M mit dem nun auf Band 2 stehenden Eingabewort gestartet. — Die Umkehrung in (i) und (ii) zeigt man ähnlich, mit einer vorgeschalteten Übersetzung von Σ∗ in {0, 1}∗ . In (iii) muss man für beide Richtungen ϕ und ϕ−1 verwenden. 52 (b) Bandalphabet. Ist M = (Q, Σ, Γ, B, q0 , F, δ) mit Σ = {0, 1} eine Turingmaschine, so kann das Verhalten von M durch eine TM M 0 = (Q0 , Σ, Γ0 , . . .) mit Bandalphabet Γ0 = {0, 1, B 0 } simuliert werden. Insbesondere gilt also: es existiert eine TM M 0 = (Q0 , {0, 1, B 0 }, {0, 1}, B 0 , . . .) mit LM = LM 0 , HM = HM 0 und fM = fM 0 . Konstruktionsidee: Das Band von M 0 ist in Blöcke der Länge l = dlog2 (|Γ| − 1)e unterteilt. Jeder Block entspricht einer Zelle von M . Die Buchstaben in Γ − {BM } werden durch Binärwörter der Länge l kodiert, das Blanksymbol BM von M durch B l . M 0 hat in seiner Steuereinheit die Kodierungsfunktion ϕ und die Beschreibung der TM M gespeichert. Weiter hat die Steuereinheit l Bitregister und ein Register für den Zustand von M während der Simulation. Um einen Schritt von M zu simulieren, liest und speichert M 0 alle l Zellen des Blocks, in dem gegenwärtig der Kopf steht, und dekodiert das Gelesene mittels ϕ−1 zu einem Buchstaben a ∈ Γ. Gemäß dem gegenwärtigen Zustand q von M bestimmt M 0 nun δ(q, a) = (q 0 , a0 , D), schreibt ϕ(a0 ) in den aktuellen Block, bewegt den Kopf um l Zellen in Richtung D, und stellt den neuen Zustand q 0 ein. Die Sonderfälle, dass B l gelesen wird oder der Übergang nicht definiert ist, sind einfach zu beschreiben. Ebenso liegt die nötige Vorbereitung zu Beginn der Rechnung (die Eingabe muss in das Blockformat umkodiert werden) und die Nachbearbeitung am Ende der Berechnung (Herstellung der Ausgabe aus den Blöcken) auf der Hand. log2(|Γ|) B B B B B B ... 0 1 0 1 1 1 0 0 0 1 1 0 code(B) code(a) code(b) Kopfbewegungen von M’: M’: Puffer: aεΓ Decode Code Programm von M a’ 53 1.3 1.3.1 Nichtdeterministische Turingmaschinen und Chomsky-0-Grammatiken Nichtdeterministische Turingmaschinen Man bezeichnet ein Maschinenmodell (eine Turingmaschine oder ein anderes Maschinenmodell wie z. B. die Registermaschine) als deterministisch, wenn in jeder Konfiguration der nächste auszuführende Schritt und damit auch die Nachfolgekonfiguration eindeutig festgelegt sind. In der Vorlesung Automaten und Formale Sprachen“ haben wir schon ” die Modelle nichtdeterministischer endlicher Automat (NFA) und nichtdeterministischer Kellerautomat (NPDA) kennengelernt, die die Möglichkeit hatten, in manchen Konfigurationen zwischen mehreren möglichen Zügen zu wählen. In diesem Abschnitt beschäftigen wir uns mit der Variante des Turingmaschinenmodells, die durch Hinzufügen dieser Möglichkeit entsteht. Wir sagen, eine solche Maschine akzeptiere eine Eingabe, wenn es eine legale Berechnung gibt, die zu einer akzeptierenden Konfiguration führt. Zwei Bemerkungen vorab: • Nichtdeterministische TMn (oder andere Berechnungsmodelle) sind ausdrücklich nicht als Modelle für realistische Rechner gedacht. Man sollte also nicht an der Frage verzweifeln, wie denn nun eigentlich so eine nichtdeterministische Maschine rechnet“, wo sie doch nicht weiß“, welcher Schritt als nächster auszuführen ist. ” ” Vielmehr sind nichtdeterministische TMn ein abstraktes Hilfsmittel. Oft erleichtern sie die Programmierung von (gewöhnlichen) Turingmaschinen. Andererseits erlauben sie es, nützliche Konzepte wie die Klasse NP der auf nichtdeterministischen TMn in Polynomialzeit akzeptierbaren Sprachen zu definieren — die Grundlage für die Theorie der NP-Vollständigkeit im zweiten Teil der Vorlesung. • Will man die Funktionsweise nichtdeterministischer Maschinen und den Akzeptierungsbegriff intuitiv verstehen, kann man sich etwa vorstellen, dass so eine Maschine eine akzeptierende Berechnung sucht, dabei aber die magische Fähigkeit hat, unterwegs die richtigen Züge, die zum Ziel führen, erraten zu können, wenn sie existieren. 1.3.1 Definition Eine nichtdeterministische (1-Band-)Turingmaschine (NTM) M besteht aus sieben Komponenten: Q, Σ, Γ, B, q0 , F (mit denselben Einschränkungen und Rollen wie in 1.1.2 angegeben) und δ, wobei δ : Q × Γ → P(Q × Γ × {R, N, L}). (P(X) bezeichnet die Potenzmenge der Menge X.) Intuitiv bedeutet diese Art von Übergangsfunktion folgendes: In einer Situation, wo die TM im Zustand q ist und auf dem Band das Zeichen a liest, kann sie einen der in der Menge δ(q, a) ⊆ Q × Γ × {R, N, L} liegenden Züge“ (q 0 , a0 , D) ausführen. Ist also |δ(q, a)| ≥ 2, ” besteht eine Auswahl. 54 1.3.2 Beispiel Wir betrachten folgendes Entscheidungsproblem: Eingeschränktes Rucksackproblem – Exaktes Packen: Input: Eine Folge (a1 , . . . , an , b) von n + 1 natürlichen Zahlen, für ein n ≥ 1. P Output: Ja“, falls es eine Teilfolge (ai )i∈I gibt, so dass die Summe i∈I ai genau b ist, ” und Nein“ sonst. ” (Informal stellt man sich vor, dass eine Menge von verformbaren Gegenständen mit Volumina a1 , . . . , an gegeben ist und fragt, ob man mit einem Teil der Gegenstände einen Rucksack vom Volumen b exakt füllen kann.) Wir können dieses Problem als eine Sprache formalisieren: LRucksack∗ := {bin(a1 )# · · · #bin(an )#bin(b) | n ∈ N, a1 , . . . , an , b ≥ 1 X ∃I ⊆ {1, . . . , n} : ai = b}. i∈I Zum Beispiel gilt: 1010#101#1000#11#1101 ∈ LRucksack∗ ; 110#10#1010#110#1111 ∈ / LRucksack∗ . Wir beschreiben (in den deterministischen Teilen informal) eine NTM M = (Q, Σ, . . .) mit Σ = {0, 1, #}, die genau die Wörter aus LRucksack∗ akzeptiert. Die NTM arbeitet in drei Phasen. Die erste Phase besteht in einer Syntaxprüfung: gehört das Eingabewort zu der regulären Sprache, die zu dem regulären Ausdruck 1(0 + 1)∗ (#1(0 + 1)∗ )+ gehört? Die Syntaxprüfung kann von einem DFA durchgeführt werden; die TM benötigt dazu nur das einmalige Lesen des Inputs von links nach rechts. Ist die Eingabe nicht syntaktisch korrekt, hält M verwerfend, sonst wird der Kopf auf das erste Eingabezeichen zurückgestellt, und es folgt Phase 2. In Phase 2 werden einige der Eingabezahlen nichtdeterministisch ausgewählt. Konkret geschieht das dadurch, dass einige der #-Zeichen durch ∗ ersetzt werden, mit der Idee, dass in Phase 3 die Eingabezahlen ai , die mit · · · bin(ai ) ∗ · · · markiert wurden, gestrichen werden. Phase 2 beginnt in Zustand q2 , der Kopf steht auf dem ersten Eingabebit. In der Turingtafel sieht das nichtdeterministische Markieren so aus: δ(q2 , a) = {(q2 , a, R)}, für a ∈ Σ δ(q2 , #) = {(q2 , ∗, R), (q2 , #, R)}, für a ∈ Σ δ(q2 , B) = {(q3 , B, L)}. In Phase 3 werden die in Phase 2 gewählten Zahlen durch 0 · · · 0 ersetzt. Zustand q3 lässt die Zeichen stehen, Zustand q3∗ löscht. Die letzte Binärzahl, also bin(b), bleibt auf jeden 55 Fall stehen. Am Ende der Phase steht der Kopf auf dem ersten Zeichen der Eingabe. δ(q3 , a) δ(q3∗ , a) δ(q3 , #) = δ(q3∗ , #) δ(q3 , ∗) = δ(q3∗ , ∗) δ(q3 , B) = δ(q3∗ , B) = = = = = {(q3 , a, L)}, für a ∈ Σ {(q3∗ , 0, L)}, für a ∈ Σ {(q3 , #, L)}, {(q3∗ , #, L)}, {(q4 , B, R)}. In Phase 4 werden in der jetzigen Bandinschrift w1 # · · · #wn #wn+1 mit Binärzahlen w1 , . . . , wn , die auch 0 · · · 0 sein dürfen, alle außer der letzten Zahl addiert. Die resultierende Binärzahl u wird Bit für Bit mit wn+1 verglichen. (Techniken für die Addition und den Vergleich von Wörtern werden in der Übung bereitgestellt.) Wenn wn+1 = u, wird akzeptiert, sonst wird verworfen. Wir beobachten die folgenden Eigenschaften der Berechnungen auf der NTM M : Wenn die Eingabe aus n + 1 Zahlen besteht, gibt es genau 2n verschiedene Berechnungen, entsprechend den Möglichkeiten, aus den n #-Zeichen eine Teilmenge in ∗ umzuwandeln. Wenn die Eingabe in LRucksack∗ liegt, gibt es mindestens eine Berechnung, die zum akzeptierenden Halten führt. Wenn die Eingabe nicht in LRucksack∗ liegt, gibt es keine akzeptierende Berechnung.12 Es erscheint sinnvoll festzulegen, zumindest in diesem Beispiel, dass M eine Eingabe x akzeptiert genau dann wenn es für M auf x mindestens eine akzeptierende Berechnung gibt. (Von den vielen nichtakzeptierenden, in denen falsch geraten wurde, lässt man sich nicht stören.) Nun müssen wir den eben angedeuteten Akzeptierungsbegriff formalisieren. Hierzu gehen wir ganz ähnlich wie in Definition 1.1.11 vor. 1.3.3 Definition Eine nichtdeterministische TM M = (Q, Σ, Γ, B, q0 , F, δ) sei gegeben. (a) Die Menge der Konfigurationen von M ist ebenso definiert wie im deterministischen Fall (Def. 1.1.11), ebenso das Konzept der Startkonfiguration initM (x) von M zu x ∈ Σ∗ . (b) (Vgl. Def. 1.1.12) k = α1 (q, a)α2 sei Konfiguration von M . Sei nun (q 0 , a0 , D) ∈ δ(q, a). Dann gibt es zu (q 0 , a0 , D) eine Nachfolgekonfiguration k 0 von k, die im folgenden beschrieben wird. Wir schreiben dafür k `M k 0 oder k ` k 0 . 12 Genauer gesagt entspricht jedem I ⊆ {1, . . . , n} mit nung. 56 P i∈I ai = b genau eine akzeptierende Berech- Schreibe Bα1 = γ1 c und α2 B = dγ2 für passende c, d ∈ Γ und γ1 , γ2 ∈ Γ∗ . Dann beschreibt k̂ = Bα1 (q, a)α2 B = γ1 c(q, a)dγ2 dieselbe Konfiguration wie k, nur mit zwei zusätzlichen Blankzeichen. Wir definieren γ1 (q 0 , c)a0 dγ2 , falls D = L; γ1 ca0 (q 0 , d)γ2 , falls D = R; k̂ 0 := γ1 c(q 0 , a0 )dγ2 , falls D = N . Die Nachfolgekonfiguration k 0 von k für den Zug (q 0 , a0 , D) entsteht aus k̂ 0 durch Streichen aller B’s am Beginn und am Ende von k̂ 0 . Eine Konfiguration α1 (q, a)α2 kann also keine, eine oder mehrere Nachfolgekonfigurationen haben, höchstens jedoch |δ(q, a)| viele. (c) Sind k, k 0 Konfigurationen und ist i ∈ N, so schreiben wir k `iM k 0 oder k `i k 0 , falls i = 0 und k = k 0 oder i ≥ 1 und es Konfigurationen k1 , . . . , ki−1 gibt, so dass k ` k1 ` · · · ` ki−1 ` ki = k 0 gilt. (d) k 0 heißt (indirekte) Nachfolgekonfiguration von k, in Zeichen k `∗M k 0 oder k `∗ k 0 , falls k `iM k 0 für ein i ∈ N. (e) k = α1 (q, a)α2 heißt Haltekonfiguration von M , falls δ(q, a) = ∅ ist. (f) Eine Folge initM (x) = k0 ` k1 ` · · · ` kt mit kt Haltekonfiguration heißt eine haltende Berechnung von M auf x; die Länge oder Schrittzahl dieser Berechnung ist t; eine unendliche Folge initM (x) = k0 ` k1 ` k2 ` · · · ` kt ` · · · heißt eine nicht-haltende Berechnung von M auf x; die Länge einer unendlichen Berechnung ist ∞. (g) Ist k = α1 (q, a)α2 Haltekonfiguration, so heißt k akzeptierend, falls q ∈ F , verwerfend sonst. Entsprechend heißen haltende Berechnungen, die in einer akzeptierenden/verwerfenden Haltekonfiguration enden, selbst akzeptierend/verwerfend. 1.3.4 Definition M = (Q, Σ, Γ, B, q0 , F, δ) sei eine nichtdeterministische TM, x ∈ Σ∗ sei ein Eingabewort. Wir sagen: (a) M akzeptiert x, falls initM (x) `∗M k für eine akzeptierende Haltekonfiguration k gilt, d. h. falls M für x mindestens eine akzeptierende Berechnung besitzt. (b) LM := {x ∈ Σ∗ | M akzeptiert x}. 57 Man beachte, dass in diesen Definitionen nichts weiter über die Situation gesagt wird, wo eine oder mehrere oder alle Berechnungen von M auf x in einer verwerfenden Haltekonfiguration enden. Insbesondere führt man den Begriff Die NTM M verwirft x“ nicht ein, ” nur einzelne Berechnungen können verwerfend enden. Alle Programmiertricks und Modellvarianten aus Abschnitt 1.2 kann man auch für nichtdeterministische Turingmaschinen einsetzen. Hier sei erinnert an die Verwendung der Steuereinheit als endlicher Speicher, an die Spurtechnik, an ein einseitig unbeschränktes Band und an Unterprogramme. Besonders erwähnt werden soll noch das k-Band-Modell. Ebenso wie im deterministischen Fall definiert man nichtdeterministische k-Band-TMn. Die Übergangsfunktion δ bildet Tupel (q, a1 , . . . , ak ) auf Teilmengen von Q × Γk × {L, R, N }k ab. Dabei bedeutet (q 0 , a01 , . . . , a0k , D1 , . . . , Dk ) ∈ δ(q, a1 , . . . , ak ), dass M in der durch (q, a1 , . . . , ak ) beschriebenen Situation den durch (q 0 , a01 , . . . , a0k , D1 , . . . , Dk ) gegebenen Zug ausführen kann. Wieder werden Konfigurationen und Akzeptierungsbegriff ebenso wie bei 1-Band-NTMn definiert. Dieselbe Konstruktion wie in Satz 1.2.6 (das war die Konstruktion mit den 2k + 1 Spuren auf einem Band) und dieselbe Überlegung wie in Satz 1.2.8 liefert folgendes. 1.3.5 Satz M sei eine nichtdeterministische Turingmaschine mit k Bändern. Dann gilt: (a) Es gibt eine 1-Band-NTM M 0 , die LM = LM 0 erfüllt. (b) Wenn jede Berechnung von M auf Inputs x ∈ Σn nach höchstens t(n) Schritten anhält, so kann die NTM M 0 in (a) so konstruiert werden, dass jede Berechnung von M 0 auf Inputs x ∈ Σn nach höchstens O(t(n)2 ) Schritten anhält. Dieser Satz hat zur Folge, dass wir beim Entwurf von NTMn auch solche mit k Bändern benutzen können. Als nächstes geben wir ein Beispiel an, bei dem zwei Bänder sehr nützlich sind. 1.3.6 Beispiel Definition: Ein Wort u = b1 · · · bm heißt Teilfolge eines Wortes x = a1 · · · an , wenn es eine Folge 1 ≤ i1 < · · · < im ≤ n gibt, so dass b1 · · · bm = ai1 · · · aim . Umgekehrt heißt x Oberfolge von u, wenn u Teilfolge von x ist. Zum Beispiel ist 001011001 Oberfolge von 1000, nicht aber 001011101. Wir betrachten das Oberfolgenproblem. Gegeben sei eine beliebige rekursiv aufzählbare Sprache L ⊆ Σ∗ . Wir definieren dann L0 := {x ∈ Σ∗ | ∃w ∈ L : x ist Oberfolge von w}. Weil L rekursiv aufzählbar ist, gibt es eine (deterministische) TM M mit L = LM . Wir entwerfen eine 2-Band-NTM für L0 . Die Berechnung verläuft in zwei Phasen: Phase 1: Lese den Input x auf Band 1 von links nach rechts, wähle nichtdeterministisch Zeichen aus, die auf Band 2 kopiert werden. (Wir sagen: M 0 wählt nichtdeterministisch ” eine Teilfolge von x“ oder M 0 rät eine Teilfolge von x“.) Wenn das Ende der Eingabe ” erreicht ist, fahre den Kopf auf Band 2 zurück zum Bandanfang. 58 Phase 2: Starte M mit Band 2 als seinem einzigen Arbeitsband. Wenn M akzeptiert, akzeptiert auch M 0 . Zur Illustration geben wir die Übergangsfunktion für die erste Phase von M 0 an. In Zustand q0 werden nichtdeterministisch einige Eingabezeichen kopiert. In Zustand q1 fährt der Kopf auf Band 2 zurück zum Beginn der Bandinschrift, der auf Band 1 tut nichts. Der Zustand q0M ist der Startzustand für das Unterprogramm, das das Programm von M auf Band 2 ablaufen lässt. δ(q0 , a, B) δ(q0 , B, B) δ(q1 , B, a) δ(q1 , B, B) = = = = {(q0 , a, a, R, R), (q0 , a, B, R, N )}, für a ∈ Σ; {(q1 , B, B, N, L)}; {(q1 , B, a, N, L)}, für a ∈ Σ; {(q0M , B, B, N, R)}. In Phase 1 werden genau n nichtdeterministische Schritte mit jeweils 2 Alternativen durchgeführt. Es ist klar, dass es dafür 2n verschiedene Abläufe gibt. Nach dem Ende von Phase 1 ist irgendeine der Konfigurationen (a1 · · · an (q0M , B), (q0M , b1 )b2 · · · bm ) erreicht, für eine Teilfolge b1 · · · bm von x = a1 · · · an , oder (a1 · · · an (q0M , B), (q0M , B)), wenn kein Zeichen ausgewählt wurde.13 Beispiel : Ist der Input x = abac, so ist jede Konfiguration mit einer Inschrift auf Band 2 aus der folgenden Liste möglich: abac, aba, abc, ab, aac, aa, ac, a, bac, ba, bc, b, ac, a, c, ε. (In diesem Fall gibt es zwar 16 Abläufe, aber nur 14 verschiedene mögliche Konfigurationen nach Phase 1.) Da in Phase 2 deterministisch gerechnet wird, besitzt M 0 auf a1 · · · an genau 2n viele verschiedene Berechnungen. Es ist klar, dass genau diejenigen dieser Berechnungen akzeptierend halten, bei denen die Bandinschrift b1 · · · bm von Band 2 nach Phase 1 zu L gehört. Daraus folgt: es gibt eine akzeptierende Berechnung auf a1 · · · an genau dann wenn eine Teilfolge b1 · · · bm von a1 · · · an zu L gehört; mit anderen Worten: LM 0 = L0 . Aus den Beispielen sollte man ein Gefühl dafür bekommen haben, was es bedeutet, dass eine NTM auf einem Input x mehrere oder viele verschiedene Berechnungen haben kann. Um dieses Nebeneinander mehrerer Berechnungen zu verdeutlichen und den Akzeptierungsmodus von NTMn zu veranschaulichen, führen wir das Konzept des Berechnungsbaums (zu M und einer Eingabe x) ein. Dieser Baum fasst alle möglichen Berechnungen von M auf Eingabe x zusammen. 1.3.7 Definition Ist M eine nichtdeterministische TM, x ∈ Σ∗ Eingabe für M , so ist der Berechnungsbaum CT (M, x)14 definiert wie folgt. CT (M, x) ist ein endlicher oder unendlicher gerichteter Baum mit Wurzel, dessen Knoten mit Konfigurationen markiert sind, und zwar folgendermaßen: 13 Wir notieren Konfigurationen von k-Band-Maschinen als k-Tupel von 1-Band-Konfigurationen. Es stört nicht weiter, dass dabei der Zustand q k-mal vorkommt. 14 zu engl. computation tree 59 (i) Die Wurzel ist mit initM (x) markiert. (ii) Hat ein Knoten v im Baum Markierung k = α1 (q, a)α2 und ist δ(q, a) = {(q1 , a1 , D1 ), . . . , (qs , as , Ds )}, und sind k1 , . . . , ks die Nachfolgekonfigurationen von k zu den s Zügen in δ(q, a), so hat v Nachfolger v1 , . . . , vs , die mit k1 , . . . , ks markiert sind. . Zeitschritte Wurzel k k’1 . . . 0 init (x) 0 k’’’ 1 1 M k’’1 k’2 k’’2 . . . 2 . . . t k k1 k2 k3 k4 Nachfolge− konfigurationen von k t+1 "verwirf" "akzeptiere" . Die Berechnungen von M auf x kann man sich anhand von CT (M, x) gut anschaulich vorstellen: • einer Berechnung initM (x) = k0 ` k1 ` · · · ` kt ` · · · (endlich oder unendlich) entspricht ein Pfad im Baum, der an der Wurzel beginnt, und umgekehrt; • ein Knoten mit Markierung k ist Blatt, d. h. hat keine Nachfolger, genau dann wenn k Haltekonfiguration ist; • M akzeptiert x genau dann wenn CT (M, x) mindestens ein Blatt hat, das mit einer akzeptierenden Haltekonfiguration markiert ist (ein akzeptierendes Blatt“). ” 60 Interessant ist der Fall, dass CT (M, x) endlich ist, also endlich viele Knoten hat. Man kann sich überlegen, dass ein unendlicher Berechnungsbaum eine nicht abbrechende Berechnung enthalten muss. 1.3.8 Bemerkung Es gilt: CT(M, x) endlich ⇔ jede Berechnung von M auf x endet nach endlich vielen Schritten. Beweis: ⇒“ ist offensichtlich. ” ⇐“: Wir nehmen an, dass CT (M, x) unendlich viele Knoten hat und konstruieren in” duktiv einen unendlichen Weg in CT (M, x). Dieser entspricht einer nichthaltenden Berechnung von M auf x. Basis: Sei v0 die Wurzel. Nach der Annahme ist der Unterbaum mit Wurzel v0 unendlich. Ind.-Schritt: Seien Knoten v0 , . . . , vn−1 schon konstruiert, so dass sie einen Weg in CT (M, x) bilden, und so dass der Unterbaum mit Wurzel vn−1 unendlich ist. Weil vn−1 nur endlich viele direkte Nachfolgeknoten hat, muss es einen geben, wir nennen ihn vn , so dass der Unterbaum mit Wurzel vn unendlich ist. Die so definierte Knotenfolge v0 , v1 , . . . bildet einen unendlichen Weg in CT (M, x). Wegen der vorangegangenen Bemerkung liegt es nahe, für eine NTM M = (Q, Σ, . . .) zu definieren: HM := {x ∈ Σ∗ | CT(M, x) ist endlich }. Es ist etwas komplizierter festzulegen, was es bedeuten soll, dass eine nichtdeterministische TM eine Funktion berechnet. Wir definieren diesen Begriff hier nicht; die Bezeichnung fM ist also für eine nichtdeterministische TM M nicht definiert und darf nicht benutzt werden. Wir wollen nun den Zusammenhang zwischen deterministischen und nichtdeterministischen TMn klären. Die eine Richtung ist einfach. 1.3.9 Bemerkung Man kann deterministische TMn als Spezialfall nichtdeterministischer TMn auffassen: ist M = (Q, Σ, Γ, B, q0 , F, δ) eine deterministische TM, so betrachte δ̂ : Q × Γ → P(Q × Γ × {L, R, N }), das folgendermaßen definiert ist: ( {(q 0 , a0 , D)}, falls δ(q, a) = (q 0 , a0 , D); δ̂(q, a) := ∅, falls δ(q, a) undefiniert. Es ist klar, dass für die nichtdeterministische TM M̂ = (Q, Σ, Γ, B, q0 , F, δ̂) LM̂ = LM und HM̂ = HM gilt. Für jedes x ∈ Σ∗ ist CT (M, x) ein Pfad ohne Verzweigung. Nun wollen wir umgekehrt zeigen, dass Nichtdeterminismus“ die prinzipielle Berech” nungskraft bei Turingmaschinen nicht erhöht. Die Grundidee hierbei ist, dass eine deterministische TM alle möglichen Berechnungen der nichtdeterministischen TM durchpro” bieren“ kann. Wir brauchen dazu eine einfache Hilfs-TM, die zu einem Alphabet ∆ alle Wörter über ∆ aufzählt“, d. h., nacheinander erzeugt. ” 61 1.3.10 Lemma Sei ∆ ein Alphabet. Dann gibt es eine deterministische 1-Band-TM, die, wenn sie mit Eingabe ε gestartet wird, unendlich lange läuft und dabei nacheinander die Konfiguration (qfertig , B) und dann die Konfigurationen (qfertig , a1 )a2 · · · an erreicht, für alle a1 · · · an ∈ ∆+ ; dabei ist qfertig ein Zustand, der sonst nie erreicht wird. Beweis: (Siehe auch Übung.) Schreibe ∆ = {c0 , . . . , cd−1 }. Die Idee ist, ci mit i zu identifizieren, und dann geeignet im d-ären System zu zählen, hierbei aber auch alle Zahldarstellungen mit führenden Nullen zu erzeugen. Der Einfachheit halber nehmen wir ∆ = {0, 1, . . . , d − 1} an, für d ≥ 1.15 Anfangs wird das leere Wort erzeugt: δ(q0 , B) = (qfertig , B, N ); dabei ist q0 der Startzustand. Wenn ein Wort erzeugt worden ist, wird es in der nächsten Runde um 1 inkrementiert (auf das Wort (d − 1)r folgt aber 0r+1 ). Hierzu fährt der Kopf an das rechte Ende; auf dem Weg vom rechten zum linken Ende werden Ziffern d − 1 in Nullen umgewandelt, bis zur ersten Ziffer < d − 1, die um 1 erhöht wird; der Rest wird nicht verändert. Sollte das ganze Wort nur aus Ziffern d − 1 bestanden haben, wird vorne eine 0 angefügt. Realisiert wird dies durch die folgende Übergangsfunktion, wobei Q = {q0 , qfertig , qrechts , qincr , qlinks } die Zustandsmenge ist. δ(qfertig , b) δ(qrechts , a) δ(qrechts , B) δ(qincr , a) δ(qlinks , a) δ(qlinks , B) δ(qincr , d − 1) δ(qincr , B) = = = = = = = = (qrechts , b, N ), für b ∈ ∆ ∪ {B}; (qrechts , a, R), für a ∈ ∆; (qincr , B, L); (qlinks , a + 1, L), für a ∈ ∆ − {d − 1}; (qlinks , a, L), für a ∈ ∆; (qfertig , B, R); (qincr , 0, L); (qfertig , 0, N ). 1.3.11 Satz aufzählbar. Ist L = LM für eine nichtdeterministische TM M , dann ist L rekursiv Beweis: Sei M = (Q, Σ, Γ, B, q0 , F, δ). Wir beschreiben eine deterministische TM M 0 = (Q0 , Σ, Γ0 , B 0 , q00 , F 0 , δ 0 ) mit LM = LM 0 . Die Menge Z := Q × Γ × {L, R, N } aller möglichen Einzelzüge“ von M ist endlich. Jede ” Berechnung k0 ` k1 ` k2 ` . . . (haltend oder nichthaltend) von M entspricht einer Folge 15 Derselbe Ablauf ergibt sich, wenn man Σ = {1, . . . , d} setzt und in der d-adischen Zahldarstellung zählt, die in Anhang A.1.2 des AFS-Skripts beschrieben ist. 62 (z1 , z2 , . . .) in Z (endlich oder unendlich), wobei beim Übergang von kt−1 zu kt gerade Zug zt benutzt wird. Es gibt natürlich auch Zugfolgen, die keiner korrekten Berechnung von M entsprechen. Beispiel : In Beispiel 1.3.2 gibt es in Phase 2 die folgende (Teil-)Berechnung mit zugehöriger Zugfolge: Zug Konfiguration (q0 , 1)1#11#1#100 (q0 , 1, R) ... ... (q2 , 1)1#11#1#100 (q2 , 1, R) 1(q2 , 1)#11#1#100 (q2 , 1, R) 11(q2 , #)11#1#100 (q2 , ∗, R) 11 ∗ (q2 , 1)1#1#10 (q2 , 1, R) 11 ∗ 1(q2 , 1)#1#10 (q2 , 1, R) 11 ∗ 11(q2 , #)1#10 (q2 , #, R) 11 ∗ 11#(q2 , 1)#10 (q2 , 1, R) ... ... (q4 , 0)0#11#1#100 ... ... ... Wegen Satz 1.2.6 dürfen wir uns vorstellen, dass M 0 drei Bänder hat. Band 1 enthält anfangs den Input x ∈ Σ∗ ; diese Inschrift wird nie verändert. Band 2 dient als Arbeitsband von M . Auf Band 3 werden nacheinander alle endlichen Zugfolgen (z1 , z2 , . . . , zr ) ∈ Seq(Z) erzeugt. Die Technik hierfür wurde in Lemma 1.3.10 beschrieben; setze einfach ∆ = Z. Für jede erzeugte Folge (z1 , z2 , . . . , zr ) tut M 0 folgendes: 1. Kopiere x von Band 1 auf Band 2, stelle den Lese-/Schreibkopf auf Band 2 auf den ersten Buchstaben von x. 2. Stelle den Bandkopf auf Band 3 auf z1 . 3. Lasse den Anfang einer Berechnung von M auf Band 2 ablaufen, gesteuert von der Zugfolge auf Band 3, wie folgt: Stelle M auf Zustand q0 . Dann wiederhole die folgenden Schritte: Wenn M in Zustand q ist und der Kopf auf Band 2 Buchstabe a ∈ Γ liest, dann verfahre wie folgt. – wenn δ(q, a) = ∅ ist und q ∈ F , dann hält M 0 akzeptierend; sonst: – wenn der Kopf auf Band 3 den Zug z = (q 0 , a0 , D) sieht“, und (q 0 , a0 , D) ∈ ” δ(q, a), führe Zug z = (q 0 , a0 , D) aus und verschiebe den Kopf auf Band 3 um 1 Feld nach rechts; sonst: – bricht die Berechnung von M mit der gegenwärtigen Zugfolge ab: erzeuge auf Band 3 die nächste Zugfolge, lösche Band 2, und beginne wieder bei 1. 63 Man sieht leicht folgendes ein: Wenn M 0 akzeptierend hält, ist unmittelbar vorher eine akzeptierende Berechnung von M abgelaufen. Dann ist also x ∈ LM . Umgekehrt gilt: wenn x ∈ LM ist, dann existiert eine akzeptierende Berechnung von M auf x. Eine Zugfolge (z1 , z2 , . . . , zr ), die zu einer akzeptierenden Berechnung gehört16 , wird irgendwann einmal erzeugt und führt zur Entdeckung dieser akzeptierenden Berechnung, also akzeptiert M 0 . Wenn CT (M, x) endlich ist, ist nach Bem. 1.3.8 die Menge aller Berechnungen von M auf x endlich. Es wäre gut, wenn auch die simulierende TM M 0 auf Input x anhalten und verwerfen würde, wenn x 6∈ LM . Dies lässt sich durch eine leichte Modifikation von M 0 erreichen: Die TM M 0 beobachtet mit Hilfe eines Flagregisters in der Steuereinheit für jedes r, ob alle M -Berechnungen für Zugfolgen (z1 , . . . , zr ) ∈ Z r vor oder mit Schritt r (nichtakzeptierend) enden. In diesem Fall kann dann auch M 0 (verwerfend) anhalten, weil es sicher keine einzige akzeptierende Berechnung von M auf x gibt. Wenn zudem bekannt ist, dass für x alle Berechnungen nach höchstens t ≥ |x| Schritten enden, dann ist der Zeitbedarf für einen Versuch mit r Schritten O(r + |x|), also insgesamt X |Z|r · O(|x| + r) = O(|Z|t · (|x| + t)) = O(|Z|t · t). 0≤r≤t Für alle t gilt |Z|t · t ≤ 2(log |Z|+1)t . — Diese Überlegung liefert folgendes Resultat: 1.3.12 Korollar (a) Wenn L = LM für eine NTM M ist, die die Eigenschaft hat, dass für jedes x ∈ Σ∗ der Berechnungsbaum CT (M, x) endlich ist, dann ist LM rekursiv. (b) Wenn in der Situation von (a) t : N → R+ eine Funktion ist derart dass für jedes x ∈ Σ∗ jede Berechnung von M auf x höchstens t(|x|) Schritte macht, dann ist die simulierende Turingmaschine M 0 aus Satz 1.3.11 O(2c·t(n) )-zeitbeschränkt, für c = 1 + log |Z|. Satz 1.3.11 und Korollar 1.3.12(a) haben die schöne Konsequenz, dass wir nichtdeterministische Turingmaschinen als eine Art Programmiertechnik einsetzen können, um leichter die Rekursivität oder rekursive Aufzählbarkeit einer Sprache nachzuweisen. Wir demonstrieren dies an einigen Beispielen. 1.3.13 Beispiel (a) Die Sprache LRucksack∗ zum eingeschränkten Rucksackproblem ist rekursiv. Die in Beispiel 1.3.2 angegebene NTM für LRucksack∗ hat die Eigenschaft, dass alle Berechnungen auf einer Eingabe x anhalten; nach Bemerkung 1.3.8 ist CT (M, x) endlich für alle x; nach Korollar 1.3.12 ist die Sprache LRucksack∗ rekursiv. (b) Wenn L rekursiv aufzählbar ist, und L0 = {x ∈ Σ∗ | ∃w ∈ L : x ist Oberfolge von w}, dann ist L0 ebenfalls rekursiv aufzählbar. (In Beispiel 1.3.6 wurde eine NTM M 0 für L0 angegeben.) (c) Wenn L rekursiv ist und L0 ist wie in (b) definiert, ist auch L0 rekursiv. Geht man nämlich in Beispiel 1.3.6 von einer TM M für L aus, die für jede Eingabe hält, dann ist für 16 Ganz genau: die erste, die in der in Lemma 1.3.10 beschriebenen Aufzählung von Seq(Z) auftritt 64 jedes x ∈ Σn jede der 2n möglichen Berechnungen von M 0 auf x endlich, also CT (M, x) endlich. Nach Korollar 1.3.12 ist also L0 rekursiv. Nichtdeterministische TMn sind besonders bequem beim Beweis von Abschlusseigenschaften, wie in den folgenden Beispielen angegeben. Weitere Beispiele werden in den Übungen behandelt. 1.3.14 Beispiel (a) Wenn L1 , L2 ⊆ Σ∗ rekursiv aufzählbar sind, und # ist ein Zeichen, das nicht in Σ vorkommt, dann sind auch die Sprachen L0 = {u#w | u ∈ L1 ∨ w ∈ L2 } und L00 = {u#w | u ∈ L1 ∧ w ∈ L2 } rekursiv aufzählbar. (b) Wenn L1 , L2 aus (a) sogar rekursiv sind, sind L0 und L00 ebenfalls rekursiv. Beweis: (a) Wir gehen von (deterministischen) TMn M1 und M2 mit L1 = LM1 bzw. L2 = LM2 aus. Eine NTM M 0 für L0 arbeitet wie folgt: Eine Eingabe x ∈ (Σ ∪ {#})∗ wird zunächst darauf getestet, ob sie das Format u#w mit u, v ∈ Σ∗ hat. Falls dies nicht so ist, wird sofort verworfen. Sonst wird z. B. ein Zustand q30 erreicht und ein einziger nichtdeterministischer Schritt δ1 (q30 , a) = {(q10 , a, N ), (q20 , a, N )}, für a ∈ Σ ∪ {#} ausgeführt. Im Zustand q10 wird #w gelöscht und M1 auf u gestartet. Im Zustand q20 hingegen wird u# gelöscht und M2 auf w gestartet. — Nach dem Akzeptierungsmodus bei nichtdeterministischen TMn wird x von M 0 akzeptiert genau dann wenn x = u#w mit u ∈ L1 oder w ∈ L2 . Also ist LM 0 = L0 ; nach Satz 1.3.11 ist L0 rekursiv aufzählbar. Eine TM M 00 für L00 arbeitet deterministisch: Sie überprüft ihre Eingabe x zuerst, ob sie das Format u#w hat. Falls dies so ist, wird zuerst (als Unterprogramm, auf einem zweiten Band) M1 mit Eingabe u gestartet. Falls diese Berechnung verwirft, hält M 00 und verwirft. Falls M1 u akzeptiert, wird M2 mit Eingabe w gestartet. Falls diese Berechnung ebenfalls akzeptiert, hält M 00 und akzeptiert. — Es ist klar, dass M 00 die Eingabe x genau dann akzeptiert, wenn x = u#w mit u ∈ L1 und w ∈ L2 . Also ist LM 0 = L0 . Man sollte noch beachten, dass es möglich ist, dass M1 auf u überhaupt nicht hält. Dann wird M2 auf w nicht gestartet und M 00 auf x hält ebenfalls nicht. Dies ist aber in Ordnung, weil u 6∈ L1 , also x 6∈ L00 . (b) Wenn L1 und L2 rekursiv sind, gehen wir vor wie in (a), verwenden aber TMn M1 und M2 , die für alle Eingaben halten. Dann passiert folgendes: Alle Berechnungsbäume CT (M 0 , x) zur NTM M 0 sind endlich. Nach Korollar 1.3.12 ist dann L0 = LM 0 rekursiv. Im Falle von M 00 halten alle Berechnungen der TM M 00 an, demnach ist L00 = LM 00 rekursiv. 65 1.3.2 Turingmaschinen und Chomsky-0-Grammatiken Man erinnere sich an die Definition von Chomsky-0- oder Typ-0-Grammatiken in der Vorlesung Automaten und formale Sprachen“. Dies waren die uneingeschränkten“ Gram” ” matiken G = (V, Σ, S, P ), wo die Menge P aus beliebigen Produktionen der Form l → r, l, r ∈ (V ∪ Σ)∗ , |l| ≥ 1 bestand. 1.3.15 Beispiel und Produktionen Die Grammatik G = (V, Σ, S, P ) mit V = {S, X, B}, Σ = {a, b, c} S X X Bb Bc → → → → → aXbc aXB ε bB bcc ist eine Chomsky-0-Grammatik. Die Sprache L(G) ist folgendermaßen definiert: Für α, β ∈ (V ∪ Σ)∗ schreiben wir α ⇒ β, wenn α = γlδ und β = γrδ für irgendwelche γ, δ ∈ (V ∪ Σ)∗ und eine Regel l → r in P . Dann bilden wir die reflexive und transitive Hülle von ⇒ und schreiben α ⇒∗ β, wenn α = β oder es k ≥ 1 und α0 = α, α1 , . . . , αk−1 , αk = β gibt mit α0 ⇒ α1 ⇒ · · · ⇒ αk . Schließlich definieren wir L(G) := {w ∈ Σ∗ | S ⇒∗ w}. Eine Sprache L gehört zu der Klasse L0 der Chomsky-0-Sprachen oder Typ-0-Sprachen, wenn es eine Typ-0-Grammatik G gibt mit L = L(G). Wenn G eine Typ-0-Grammatik ist, so gehört zu jedem Wort w ∈ L(G) eine (nicht notwendig eindeutig bestimmte) Ableitung S = α0 ⇒ α1 ⇒ · · · ⇒ αk = w, die w aus S erzeugt“. ” In Beispiel 1.3.15 sind folgendes Ableitungen für das Wort aaabbbccc: S ⇒ aXbc ⇒ aaXBbc ⇒ aaaXBBbc ⇒ aaaBBbc ⇒ aaaBbBc ⇒ aaabBBc ⇒ aaabBbcc ⇒ aaabbBcc ⇒ aaabbbccc und S ⇒ aXbc ⇒ aaXBbc ⇒ aaXbBc ⇒ aaXbbcc ⇒ aaaXBbbcc ⇒ aaaXbBbcc ⇒ aaaXbbBcc ⇒ aaaXbbbccc ⇒ aaabbbccc. Ableitungen lassen sich auch sehr gut rückwärts interpretieren. Wenn l → r eine Produktion ist, sagen wir, dass man αrβ durch (Rückwärts-)Anwendung der Regel l → r (oder 66 durch Anwendung der Reduktionsregel r ← l) zu αlβ reduzieren kann, und schreiben αrβ ⇐ αlβ. Dann bilden wir Reduktionsfolgen α1 ⇐ α2 ⇐ · · · ⇐ αk . Offenbar ist w ∈ L(G) genau dann wenn w ∈ Σ∗ und eine Reduktion w ⇐ · · · ⇐ S existiert. Folgendes ist eine Reduktionsfolge in der Grammatik G aus Beispiel 1.3.15: aaabbbccc ⇐ aaaXbbbccc ⇐ aaaXbbBcc ⇐ aaaXbBbcc ⇐ aaaXBbbcc ⇐ aaXbbcc ⇐ aaXbBc ⇐ aaXBbc ⇐ aXbc ⇐ S. Der Reduktionsprozess erinnert etwas an die Arbeitsweise einer nichtdeterministischen Turingmaschine, die von einem Eingabewort x ∈ Σ∗ zu einer Normalform“, nämlich dem ” Startsymbol S, zu gelangen versucht. Tatsächlich gibt es einen engen Zusammenhang. Wir werden beweisen, dass die rekursiv aufzählbaren Sprachen genau die Chomsky-0Sprachen sind, indem wir zeigen, dass Reduktionsfolgen im wesentlichen dasselbe wie NTM-Berechnungen sind. 1.3.16 Satz Sei L ⊆ Σ∗ eine Sprache. Dann gilt: L ist rekursiv aufzählbar ⇔ L ist in L0 . Beweis: Wir führen zwei Konstruktionen durch. ⇒“: Gegeben sei eine nichtdeterministische 1-Band-TM M = (Q, Σ, Γ, B, q0 , F, δ) mit ” L = LM . Wir können annehmen, dass M vor dem Akzeptieren immer das gesamte Arbeitsband mit Blanks überschreibt ( das Band löscht“) und dass M nur einen einzigen ” akzeptierenden Zustand q ∗ besitzt, d. h. dass F = {q ∗ } gilt, und dass δ(q ∗ , B) = ∅. (Wenn dies nicht so ist, können wir M so umbauen, dass die Bedingungen erfüllt sind.) Diese Annahmen führen dazu, dass M nur eine akzeptierende Haltekonfiguration hat, nämlich (q ∗ , B). Wir konstruieren eine Typ-0-Grammatik G = GM mit LM = L(G). Die Grundidee ist, dass eine Ableitung in G im wesentlichen eine Berechnung von M in umgekehrter Reihenfolge sein sollte — das heißt, dass Berechnungen von M sich als Reduktionsfolgen von G wiederfinden. Die Satzformen von G, d. h. die auf S reduzierbaren Wörter über V ∪ Σ, haben die Form /cB · · · BkB · · · B$, wobei k eine Konfiguration von M ist, von der aus man zur akzeptierenden Haltekonfiguration gelangen kann. Hinzu kommen einige spezielle Wörter in der Teilableitung /c initM (w) $ ⇒∗ w. G hat als Terminalzeichenalphabet das Eingabealphabet Σ von M , das Startsymbol S, die Variablenmenge V = (Γ − Σ) ∪ (Q × Γ) ∪ {S, /c, $, #}, und die folgenden Produktionen: Startregel: S → /c(q ∗ , B)$. 67 Damit ist genau die akzeptierende Konfiguration von M ableitbar. In jeder Konfiguration wollen wir an den Rändern beliebig Blankzeichen hinzufügen und streichen können: Blankregeln: /c /cB $ B$ → → → → /cB, /c, B$, $. Nun folgen Regeln, die es erlauben, die Schritte von M rückwärts als Produktionen zu benutzen, d. h. die Schritte von M entsprechen Reduktionsschritten: Schrittregeln: a0 (q 0 , c) → (q, a)c , (q 0 , c)a0 → c(q, a) , (q 0 , a0 ) → (q, a) , für q, q 0 ∈ Q, a, a0 , c ∈ Γ, falls (q 0 , a0 , R) ∈ δ(q, a); für q, q 0 ∈ Q, a, a0 , c ∈ Γ, falls (q 0 , a0 , L) ∈ δ(q, a); für q, q 0 ∈ Q, a, a0 , c ∈ Γ, falls (q 0 , a0 , N ) ∈ δ(q, a). Man sieht ganz leicht ein (formal: durch einen Induktionsbeweis über die Schrittzahl von M bzw. die Länge einer Ableitung mittels der bisher angegebenen Produktionen), dass gilt: S ⇒ /c(q ∗ , B)$ ⇒∗ α mit den bisher angegebenen Produktionen genau dann wenn α = /cB · · · BkB · · · B$ für eine Konfiguration k von M mit k `∗M (q ∗ , B). Uns interessieren nur Startkonfigurationen, d. h. solche α = /c B · · · BkB · · · B $, bei denen k das Format (q0 , B) oder (q0 , a1 )a2 · · · an für ein n ≥ 1 und a1 , . . . , an ∈ Σ hat. Mit einigen Abschlussregeln sorgen wir dafür, dass genau aus solchen α Wörter über Σ abgeleitet werden können. Die Idee ist, (q0 , a) durch a zu ersetzen und damit die Anwendung weiterer Schrittregeln unmöglich zu machen, und dann das Spezialzeichen # von links nach rechts durch das Wort laufen zu lassen und dabei zu überprüfen, dass nur Terminalzeichen vorhanden sind, und schließlich beim Auftreffen des # auf das $-Zeichen am rechten Ende beide Zeichen verschwinden zu lassen. Überflüssige Blankzeichen am rechten Ende kann man mit den Blankregeln entfernen. Abschlussregeln: /c(q0 , B)$ /c(q0 , a) #a #$ → → → → ε; a# , für a ∈ Σ; a# , für a ∈ Σ; ε. 68 Wenn z. B. Σ = {a, b, c}, wird durch die Abschlussregeln die folgende Teilableitung ermöglicht: /c(q0 , a)bcaBB$ ⇒ a#bcaBB$ ⇒ ab#caBB$ ⇒ abc#aBB$ ⇒ abca#BB$. Mit zwei Anwendungen von Blankregeln und der letzten Abschlussregel erhält man: abca#BB$ ⇒ abca#B$ ⇒ abca#$ ⇒ abca. Man sieht“, dass /c- und $-Zeichen nur verschwinden können, wenn das verbleibende Wort ” nur aus Terminalzeichen besteht. Damit ist die Grammatik G = GM vollständig beschrieben. Wir müssen zeigen: LM = L(G). ⊆“: Wenn w ∈ LM , dann gibt es eine Berechnung initM (w) ` · · · ` (q ∗ , B). Nach der ” bisherigen Überlegung gibt es eine Ableitung S ⇒∗ /cB · · · B initM (w) B · · · B$. Mit den Blankregeln erhalten wir S ⇒∗ /c initM (w) $. Wegen der Abschlussregeln gilt /c initM (w) $ ⇒∗ w, also ist w ∈ L(G). ⊇“: Wenn w = a1 · · · an ∈ L(G), gibt es eine Ableitung S ⇒ /c(q ∗ , B)$ ⇒∗ w. Damit ” das /c-Symbol verschwindet, muss einmal eine der /c(q0 , c)-Schlussregeln“ verwen” det werden. Dies eliminiert den Zustandsbuchstaben (q0 , c), also sind danach keine Schrittregeln mehr anwendbar, nur noch Abschlussregeln und die Blankregeln für den $. Wegen der Struktur der Abschlussregeln zerfällt die Ableitung in zwei Phasen: S ⇒ /c (q ∗ , B) $ ⇒∗ /c (q0 , c)a2 · · · an B · · · B $ und /c (q0 , c)a2 · · · an B · · · B $ ⇒∗ w. Dabei eliminiert der erste Schritt von Phase 2 das (q0 , c); falls w = ε, ist c = B, sonst ist und c = a1 . Die erste Phase liefert wegen der Gestalt der Schrittregeln und der Blankregeln, dass initM (w) `∗M (q ∗ , B), also w ∈ LM . ⇐“: Gegeben sei eine Typ-0-Grammatik G = (Σ, V, S, P ). Wir beschreiben die Arbeits” weise einer 1-Band-NTM M = (Q, Σ, Γ, B, q0 , F, δ). Dabei ist Γ so gewählt, dass das Band eine Textspur hat, in der Zeichen aus V ∪ Σ ∪ {B} stehen können, sowie eine Spur für Markierungen. M versucht, zu Eingabewort w = a1 · · · an eine Reduktion in G von w zu S zu finden. Die Menge P der Produktionen ist endlich, also können wir sie in der Übergangsfunktion δ verwenden. Aus Zustand q0 wechselt M in den Zustand p0 . Die Rechnung danach erfolgt in Runden. Zu Beginn einer Runde ist M immer in einer Konfiguration (p0 , x1 )x2 · · · xm ; dann setzen wir α := x1 · · · xm ∈ (V ∪ Σ)+ . Ausnahme: Zu Beginn der ersten Runde kann das Band 69 völlig leer sein, dann ist M in der Konfiguration (p0 , B) und wir setzen α := ε. Spur 2 ist zu Beginn einer Runde leer. Eine Runde besteht aus folgenden Aktionen: 1. Teste, ob α = S. Falls ja, hält M akzeptierend. 2. Sonst markiere nichtdeterministisch Beginn und Ende eines Teilwortes xi · · · xj , 1 ≤ i, j ≤ m, i ≤ j + 1, von α;17 dann 3. wähle nichtdeterministisch eine Produktion l → r aus P . Teste, ob r = xi · · · xj . Falls dies nicht erfüllt ist, halte verwerfend; sonst 4. ersetze auf dem Band das Teilwort xi · · · xj durch l. (Falls |l| = 6 |r|, ist hierzu eine Verschiebung des Teilwortes xj+1 · · · xm um |l| − |r| Zellen nach rechts oder links nötig.) 5. Lösche alle Markierungen, fahre den Kopf auf das erste Feld der Bandinschrift, gehe in Zustand p0 . Nach der Beschreibung ist klar, dass M genau dann in einer Runde von Konfiguration (p0 , x1 )x2 · · · xm in Konfiguration (p0 , y1 )y2 , . . . , ys gelangen kann, wenn y1 · · · ys ⇒ x1 · · · xm . Daraus folgt, dass M genau dann in einer Folge von Runden von (p0 , a1 )a2 · · · an (bzw. (p0 , B), für w = ε) in die Konfiguration (p0 , S) gelangen kann, die zum Akzeptieren führt, wenn S ⇒∗ a1 · · · an . Das bedeutet, dass M die Eingabe w akzeptiert genau dann wenn x ∈ L(G). 1.3.17 Bemerkung Satz 1.3.16 beinhaltet die auf den ersten Blick überraschende Tatsache, dass das Konzept rekursiv aufzählbare Sprache“ eine Charakterisierung ” durch Grammatiken hat, also Regelsysteme zur Erzeugung von Wortmengen. Diese haben auf den ersten Blick überhaupt nichts mit Berechnungen zu tun. Erst der Blick aus der Perspektive der nichtdeterministischen Berechnungen auf TMn zeigt, dass zwischen TM-Berechnungen und Ableitungen bzw. Reduktionen in einer Grammatik gar kein so großer Unterschied besteht. Wo sind hier die partiell rekursiven Funktionen und die rekursiven Sprachen einzuordnen? In der Übung wird gezeigt, dass eine Funktion f : D → Σ∗ mit D ⊆ Σ∗ genau dann partiell rekursiv ist, wenn der Graph“ {x#f (x) | x ∈ D} eine rekursiv aufzählbare Sprache über ” Σ ∪ {#} ist. Das heißt, dass auch die partiell rekursiven Funktionen ohne jeden Bezug auf eine Maschine oder Berechnung definiert werden können. — In Abschnitt 1.4 werden wir sehen, dass L genau dann rekursiv ist, wenn L und L̄ = Σ∗ − L rekursiv aufzählbar sind. Dies führt zu folgender Charakterisierung der rekursiven Sprachen ohne Bezug auf Maschinen, Programme oder Berechnungen: L ist rekursiv ⇔ es gibt Typ-0-Grammatiken G und G0 mit L = L(G) und L̄ = L(G0 ). 17 Wenn i = j + 1, ist xi · · · xj = ε. 70 1.3.3 Linear beschränkte Automaten und Chomsky-1-Grammatiken Mit den Methoden aus dem letzten Abschnitt können wir auch den Maschinentyp beschreiben, der zu den Chomsky-1-Grammatiken gehört. Zur Erinnerung: Eine Grammatik G = (V, Σ, S, P ) hieß vom Typ 1 oder eine Chomsky1-Grammatik, falls alle ihre Produktionen kontextsensitiv“ waren, d. h. von der Form ” αAγ → αβγ, wo A ∈ V , α, β, γ ∈ (Σ ∪ V )∗ und |β| ≥ 1; die einzige Ausnahme ist die Produktion S → ε, die erlaubt ist, wenn S in keiner Produktion auf der rechten Seite vorkommt. Alternativ betrachtet man (wortlängen)monotone“ Grammatiken, die nur monotone ” ” Produktionen“ haben, das sind Produktionen l → r, wo l ∈ (Σ ∪ V )+ , r ∈ (Σ ∪ V )∗ und |l| ≤ |r|; bezüglich der Produktion S → ε gilt dieselbe Ausnahme wie bei den Typ-1-Grammatiken. 1.3.18 Beispiel Die Grammatik aus Beispiel 1.3.15 ist offenbar nicht monoton (wegen der Produktion X → ε). Ebenso ist die im Beweis von Satz 1.3.16 ⇒“ konstruierte ” Grammatik nicht monoton, insbesondere wegen der Blankregeln /cB → /c und B$ → $. Diese Regeln erlauben es, im Verlauf einer Ableitung für x Satzformen α zu benutzen, die viel länger sind als x. Folgendes ist eine monotone Grammatik für die Sprache {an bn cn | n ≥ 0}: G = (V, Σ, S, P ) mit V = {S, X, B}, Σ = {a, b, c} und Produktionen S S S X X Bb Bc → → → → → → → ε abc aXbc aXB aB bB bcc Eine Ableitung für das Wort x = aaabbbccc in dieser Grammatik sieht so aus: S ⇒ aXbc ⇒ aaXBbc ⇒ aaaBBbc ⇒ aaaBbBc ⇒ aaabBBc ⇒ aaabBbcc ⇒ aaabbBcc ⇒ aaabbbccc Man bemerkt, dass natürlich in der Ableitung die Längen der Satzformen nicht abnehmen, d. h. jede Satzform hat ≤ |x| Buchstaben. 71 Schon in der Vorlesung Automaten und Formale Sprachen“ hatten wir bemerkt, dass ” monotone Grammatiken und kontextsensitive Grammatiken dieselben Sprachen erzeugen. 1.3.19 Lemma Für eine Sprache L ⊆ Σ∗ sind äquivalent: (i) L = L(G) für eine monotone Grammatik G. (ii) L = L(G0 ) für eine Typ-1-Grammatik G0 (d. h. L liegt in L1 ). Beweis: Die Implikation (ii) ⇒ (i)“ ist offensichtlich. Wir beweisen (i) ⇒ (ii)“. Gegeben ” ” ist also eine monotone Grammatik G = (V, Σ, S, P ). Wir bauen G zu einer kontextsensitiven Grammatik um. (Zur Vereinfachung nehmen wir an, dass P die Produktion S → ε nicht enthält. Anderenfalls wird diese Produktion beim Umbau unverändert gelassen.) Schritt 1: Separierung. Für jedes a ∈ Σ erfinde eine neue Variable Ca . Ersetze in allen Produktionen in P (auf linken und rechten Seiten) jedes Vorkommen von a ∈ Σ durch Ca , und füge zu P die neuen Produktionen Ca → a hinzu. Die neue Grammatik Gsep = (V 0 , Σ, S, P 0 ) mit V 0 = V ∪ {Ca | a ∈ Σ} erzeugt offensichtlich dieselbe Sprache wie G und ist separiert, d. h. jede Produktion hat die Form A1 · · · Ar → B1 · · · Bs , A → a, 1 ≤ r ≤ s, A1 , . . . , Ar , B1 , . . . , Bs ∈ V 0 ; A ∈ V 0 , a ∈ Σ. Schritt 2: Wir starten mit einer separierten Grammatik G (benenne Gsep aus Schritt 1 wieder in G um). Produktionen der Form A → B1 · · · Bs , s ≥ 1, bleiben unverändert; sie sind schon kontextsensitiv. Für eine Produktion A1 · · · Ar → B1 · · · Bs mit 2 ≤ r ≤ s führen wir r neue Variable Z1 , . . . , Zr ein und ersetzen die Produktion durch die folgende Folge von kontextsensitiven Produktionen: A1 A2 · · · Ar → Z1 A2 · · · Ar , Z1 A2 A3 · · · Ar → Z1 Z2 A3 · · · Ar , .. .. .. . . . Z1 · · · Zr−1 Ar → Z1 · · · Zr−1 Zr ; Z1 Z2 · · · Zr → B1 Z2 · · · Zr ; B1 Z2 Z3 · · · Zr → B1 B2 Z3 · · · Zr ; .. .. .. . . . B1 · · · Br−2 Zr−1 Zr → B1 · · · Br−2 Br−1 Zr B1 · · · Br−1 Zr → B1 · · · Br−1 Br · · · Bs . Man sieht sofort, dass man alle Ableitungen in der Grammatik G in der neuen Grammatik G0 nachbauen kann, d. h. dass L(G) ⊆ L(G0 ) ist. Weil die Änderung an den neuen ZVariablen immer nur im vollen Kontext erfolgen kann, ist es auch nicht schwer einzusehen, 72 dass man aus einer G0 -Ableitung für w auch eine G-Ableitung für w gewinnen kann, so dass also L(G0 ) ⊆ L(G) ist. Wir betrachten nun Turingmaschinen, deren Kopf nie die Felder verlässt, in denen ursprünglich die Eingabe steht. Um der TM die Chance zu geben, das Eingabeende zu erkennen, wird die Eingabekonvention leicht verändert: man markiert“ den letzten Ein” gabebuchstaben. Markierte“ Buchstaben erhält man wie folgt. Zu Σ definiert man ” Σ0 := {(a, 0) | a ∈ Σ} , Σ1 := {(a, 1) | a ∈ Σ} , Σ# := {(a, #) | a ∈ Σ} . Dann schreibt man wieder a für (a, 0) (unmarkierte Version), â für (a, 1) und a# für (a, #). (Die â-Buchstaben werden als Bandbuchstaben benutzt; die #-Buchstaben in einer Grammatik im Beweis des folgenden Satzes.) Für Eingabe x = a1 · · · an ist die Startkonfiguration falls x = ε; (q0 , B), 0 (q0 , â), falls x = a ∈ Σ; initM (x) = (q0 , a1 )a2 · · · an−1 ân , falls x = a1 · · · an ∈ Σn , n ≥ 2. Mit dieser Konvention kann die NTM sicher erkennen, wenn der Kopf die Zelle mit dem letzten Eingabebuchstaben betritt. Die Eingabe ε lässt sich leicht behandeln. Wir können annehmen, dass bei allen betrachteten Maschinen δ(q0 , B) = ∅ ist, dass bei beliebigen Inputs nach dem Start der Rechnung q0 nie mehr betreten wird, und dass q0 akzeptierend ist genau dann wenn ε akzeptiert werden soll. 1.3.20 Definition Eine NTM M heisst linear bandbeschränkt (oder ein linear be” schränkter Automat“, LBA“), wenn auf Eingabe a1 · · · an , n ≥ 1, d. h. mit Konfiguration ” init0M (a1 · · · an ) gestartet, der Kopf von M niemals ein Bandfeld außerhalb der n Eingabefelder betritt. (Auf Eingabe ε hält M an, ohne einen Schritt zu machen.) Der folgende Satz entspricht in Aussage und Beweis Satz 1.3.16 zur Beziehung zwischen nichtdeterministischen Turingmaschinen und Typ-0-Grammatiken. Im Beweis muss man zusätzlich die Monotonie der Grammatik und die Platzschranke der NTM berücksichtigen. 1.3.21 Satz Sei L ⊆ Σ∗ eine Sprache. Dann gilt: L = LM für einen LBA M ⇔ L ist in L1 . Beweis: Wir betrachten wieder zwei Richtungen. ⇒“: Gegeben sei ein LBA M = (Q, Σ, Γ, B, q0 , F, δ) mit L = LM . Wir können annehmen, ” dass M (neben dem Sonderfall q0 im Falle ε ∈ LM ) nur einen akzeptierenden Zustand q ∗ besitzt, und dass M vor dem Übergang nach q ∗ das Feld, auf dem der Kopf stehenbleibt, mit B überschreibt. Damit haben die akzeptierenden Konfigurationen von M die Gestalt α(q ∗ , B)β, für Wörter α, β ∈ Γ∗ . 73 Wir geben eine monotone Grammatik für L an. Diese ähnelt der aus Satz 1.3.16, wieder entsprechen also Turingmaschinenberechnungen den Reduktionsfolgen in G, jedoch muss man mit einem kleinen Trick dafür sorgen, dass nichtmonotone Produktionen vermieden werden. G hat als Terminalzeichenalphabet das Eingabealphabet Σ von M , das Startsymbol S, die Variablenmenge V = (Γ − Σ) ∪ (Q × Γ) ∪ {â, a# | a ∈ Σ} ∪ {S}, und die folgenden Produktionen: Startregeln: S ∗ (q , B) (q ∗ , B) S → → → → (q ∗ , B); X(q ∗ , B), für X ∈ Γ, (q ∗ , B)X, für X ∈ Γ, ε , falls ε ∈ LM . Hiermit sind alle akzeptierenden Konfigurationen von M aus S ableitbar, sowie eventuell ε. Schrittregeln: a0 (q 0 , c) → (q, a)c , (q 0 , c)a0 → c(q, a) , (q 0 , a0 ) → (q, a) , für q, q 0 ∈ Q, a, a0 , c ∈ Γ, falls (q 0 , a0 , R) ∈ δ(q, a); für q, q 0 ∈ Q, a, a0 , c ∈ Γ, falls (q 0 , a0 , L) ∈ δ(q, a); für q, q 0 ∈ Q, a, a0 , c ∈ Γ, falls (q 0 , a0 , N ) ∈ δ(q, a). Wieder ist klar, dass die Schrittregeln es erlauben, Berechnungen von M rückwärts nachzubilden. Nun müssen wir Abschlussregeln so formulieren, dass ein Terminalzeichenwort x ∈ Σ+ nur aus der Startkonfiguration init0M (x) ableitbar ist. Dabei dürfen wir keine Sonderzeichen benutzen, die die Wortlänge verändern. Der simple Trick: Wir integrieren ein Sonderzeichen in die Buchstaben. Hierzu benutzen wir die #-markierten Buchstaben von oben. Abschlussregeln: (q0 , â) (q0 , a) a# b a# b̂ → → → → a , für a ∈ Σ, a# , für a ∈ Σ, ab# , für a, b ∈ Σ, ab , für a, b ∈ Σ. Beispielsweise sieht eine Teilableitung init0M (abaa) ⇒∗ abca mit diesen Abschlussregeln folgendermaßen aus: (q0 , a)bcâ ⇒ a# bcâ ⇒ ab# câ ⇒ abc# â ⇒ abca. 74 Die beschriebene Grammatik G ist offenbar monoton. Dass LM = L(G) ist, zeigt man analog zu dem Argument im Beweis von Satz 1.3.16. ⇐“: Wie in Satz 1.3.16, Beweisteil ⇐“, benutzen wir eine 1-Band-NTM M mit zwei ” ” Spuren, einer Textspur, in der im wesentlichen Zeichen aus V ∪Σ∪{â | a ∈ Σ} stehen, und einer Spur für Markierungen. Der Fall ε wird gesondert behandelt, wie oben beschrieben. Ausgehend von der Startkonfiguration (q0 , a1 )a2 · · · an−1 ân (bzw. (q0 , â1 ) für n = 1) fährt der Kopf einmal hin und her über den gesamten Input, um in die Markierungsspur unter a1 ein /c-Zeichen zu schreiben und in der Zelle, die ân enthält, in die Textspur an und in die Markierungsspur ein $-Zeichen zu schreiben. Die /c- und die $-Markierung werden nie verändert. Ab jetzt arbeitet M genau wie die NTM in Satz 1.3.16, Beweisteil ⇐“, mit den ” folgenden Unterschieden: Der Kopf macht nie von der /c-Zelle aus eine L-Bewegung und nie von der $-Zelle aus eine R-Bewegung. In den Ersetzungsrunden, in denen ein Teilwort r der Inschrift in Spur 1 durch ein Teilwort l ersetzt wird, darf die Produktion S → ε nicht benutzt werden. Weil G monoton ist, gilt für alle anderen Produktionen l → r, dass |l| ≤ |r| ist; daher tritt in den Ersetzungsrunden nie eine Verlängerung der Bandinschrift ein. M hält und akzeptiert genau dann, wenn die Bandinschrift in der Textspur schließlich SB · · · B ist. Man kann den Beweis des vorherigen Satzes etwas ausbauen, um das folgende Ergebnis zu beweisen. 1.3.22 Satz Wenn L eine kontextsensitive Sprache ist, dann ist L rekursiv. Beweisskizze: Gegeben sei eine monotone Grammatik G mit L = L(G). Man bemerkt, dass man wegen der Monotonie der Produktionen eine leicht zu berechnende Funktion g : N → N findet, so dass jedes Wort x ∈ L eine Ableitung einer Länge ≤ g(|x|) hat. Nun kann die im vorherigen Beweis betrachtete NTM M bei ihrer Suche nach einer Ableitung für ein Eingabewort x nach Runde g(|x|) abbrechen. Damit erhalten wir eine NTM für L, die nur endliche Berechnungen hat. Aus den Ergebnissen von Abschnitt 1.3.1 folgt dann, dass L rekursiv ist. Die Details sind Gegenstand einer Übungsaufgabe. 1.3.23 Bemerkung: Die Chomsky-Hierarchie Mit den Erkenntnissen dieses Kapitels können wir die bisherigen Aussagen zur Chomsky-Hierarchie erweitern: (a) L3 ( L2 . (AFS-Vorlesung.) (b) L2 ( L1 . (AFS-Vorlesung.) (c) L1 ⊆ {L | L ist rekursiv}. (Vorhergehender Satz.) (d) {L | L ist rekursiv } ⊆ {L | L ist rekursiv aufzählbar}. (e) {L | L ist rekursiv aufzählbar} = L0 . (Satz 1.3.16.) Die Frage, ob die Inklusionen in (c) und (d) echt sind, wird im weiteren Verlauf der Vorlesung (mit ja“) beantwortet. Damit ergibt sich zusammenfassend: ” 75 Hauptsatz über die Chomsky-Hierarchie: L3 ( L2 ( L1 ( L0 . 1.4 Struktur- und Abschlusseigenschaften In diesem Abschnitt untersuchen wir, unter welchen Operationen die Sprachklassen der rekursiven und der rekursiv aufzählbaren Sprachen abgeschlossen sind. Weiter diskutieren wir das Konzept eines Aufzählers“ (eines deterministischen Erzeugungsverfahrens) für re” kursiv aufzählbare Sprachen. Zu diesem Zweck führen wir weitere Programmiertechniken für Turingmaschinen ein, die dazu dienen, mit dem Problem nichthaltender Berechnungen umzugehen. Im folgenden ist Σ immer ein Alphabet, das Eingabealphabet der vorkommenden TMn, und das den vorkommenden Sprachen zugrundeliegende Alphabet. Zu L ⊆ Σ∗ ist L = Σ∗ − L. Bei den rekursiven Sprachen sind die Verhältnisse einfach. 1.4.1 Satz Es seien L, L1 , L2 ⊆ Σ∗ . Dann gilt: (a) L ist rekursiv ⇒ L ist rekursiv. (b) L1 , L2 sind rekursiv ⇒ L1 ∩ L2 und L1 ∪ L2 sind rekursiv. (c) L ist rekursiv ⇔ cL ist rekursiv, wo cL (x) = ( 1, 0, falls x ∈ L sonst die charakteristische Funktion von L bedeutet. (d) L1 , L2 sind rekursiv ⇒ L1 L2 ist rekursiv. (e) L ist rekursiv ⇒ L∗ ist rekursiv. Beweis: Alle Beweise bestehen darin, dass man gegebene TMn nimmt und in andere umbaut. (a) Gegeben sei eine TM M = (Q, Σ, Γ, B, q0 , F, δ) mit L = LM , die auf allen Inputs hält. Wir benötigen eine TM M̃ mit L = LM̃ , die ebenfalls auf allen Inputs hält. Dafür genügt es, in M die akzeptierenden und die verwerfenden Zustände zu vertauschen, d. h. man setzt M̃ = (Q, Σ, Γ, B, q0 , Q − F, δ). 76 (b) L1 , L2 ⊆ Σ∗ seien rekursiv. M1 und M2 seien TMn mit L1 = LM1 und L2 = LM2 , die auf allen Inputs halten. Eine neue Maschine M 0 geht vor wie folgt: 1. Kopiere Eingabe x ∈ Σ∗ auf ein zweites Band. 2. Lasse M1 auf Band 1 ablaufen. Dann lasse M2 auf Band 2 ablaufen. 3. ∩“: Falls M1 und M2 akzeptierend gehalten haben, akzeptiert M 0 , sonst ver” wirft M 0 . ∪“: Falls M1 oder M2 akzeptierend gehalten hat, akzeptiert M 0 , sonst verwirft ” 0 M. Offenbar gilt LM 0 = L1 ∩ L2 im ∩“-Fall und LM 0 = L1 ∪ L2 im ∪“-Fall, und auch ” ” M 0 hält auf allen Inputs. (c) ⇒“: Sei L = LM für eine TM M , die auf allen Eingaben hält. Die Übergangs” funktion δ von M wird leicht modifiziert, wie folgt: Ist δ(q, a) undefiniert (d. h. M hält), führt die modifizierte TM M 0 noch zwei Schritte aus: Sie schreibt bB“ auf ” das Band, b ∈ {0, 1}, und stellt den Kopf auf das b; dabei ist b = 1, falls q ∈ F , und b = 0, falls q ∈ / F . Nach den Ausgabekonventionen für TMn gilt dann: M 0 hält für jeden Input, und fM 0 = cL . ⇐“: Umgekehrt kann aus einer TM M 0 mit fM 0 = cL leicht eine TM M konstruiert ” werden, die mittels des Endzustandes akzeptiert/verwirft: Wenn M 0 hält, führt M einen weiteren Schritt aus und geht in einen akzeptierenden Zustand, wenn der Kopf eine 1 liest, und in einen verwerfenden, wenn der Kopf eine 0 liest. (d) Übungsaufgabe. (e) Übungsaufgabe. 1.4.2 Satz Wenn L, L1 , L2 ⊆ Σ∗ rekursiv aufzählbare Sprachen sind, dann gilt: (a) L1 ∩ L2 ist rekursiv aufzählbar. (b) L1 ∪ L2 ist rekursiv aufzählbar. (c) L1 L2 ist rekursiv aufzählbar. (d) L∗ ist rekursiv aufzählbar. Beweis: Wieder werden aus gegebenen Turingmaschinen andere konstruiert. Für (a), (b), (c) seien M1 , M2 1-Band-TMn mit L1 = LM1 , L2 = LM2 . (a) Eine 2-Band-TM M mit LM = L1 ∩L2 arbeitet wie folgt: Der Input x wird auf Band 2 kopiert. Dann wird M1 mit Eingabe x auf Band 1 gestartet. Wenn und sobald M1 akzeptierend hält, wird M2 mit Eingabe x auf Band 2 gestartet. Wenn auch diese Berechnung akzeptierend hält, akzeptiert M . — Es ist klar, dass LM = L1 ∩ L2 . Dies gilt, obwohl es passieren kann, dass M1 auf x nicht hält, und M2 auf x gar nicht gestartet wird. Aber weil dann x ∈ / L1 ∩ L2 , ist dies unerheblich. 77 (b) Nun suchen wir eine TM M für L1 ∪ L2 . Der eben benutzte Ansatz, M1 und M2 nacheinander laufen zu lassen, funktioniert hier nicht, denn M muss x auch akzeptieren, wenn M1 nicht hält, aber M2 akzeptiert. Stattdessen lassen wir M1 und M2 parallel ablaufen. 1) Vorbereitung: Kopiere Eingabe x ∈ Σ∗ auf das zweite Band. ... B B B e i n g a b e B B B ... ... B e i n g a b e B B B B B ... M1 M2 AKZ Flagregister 2) Lasse M1 auf Band 1 und M2 auf Band 2 gleichzeitig laufen. Die TM M benutzt dazu die Zustandsmenge Q1 × Q2 und eine Übergangsfunktion δ1 × δ2 , wo Q1 und δ1 für das erste Band und Q2 und δ2 für das zweite Band zuständig sind. 3) Wenn und sobald eine der Teilmaschinen M1 oder M2 akzeptierend gehalten hat, hält M in einem akzeptierenden Zustand. Es ist offensichtlich, dass M eine Eingabe x genau dann akzeptiert, wenn x ∈ L1 ∪L2 ist. (c) Seien M1 , M2 1-Band-TMn mit L1 = LM1 , L2 = LM2 . Eine 2-Band-NTM M für L1 L2 = {x1 x2 | x1 ∈ L1 , x2 ∈ L2 } arbeitet wie folgt: Auf Input x wird ein nichtdeterministisch gewähltes Suffix x2 von Band 1 gelöscht und auf Band 2 geschrieben. Der Rest auf Band 1 heißt x1 . Dann wird M1 auf x1 auf Band 1 gestartet; wenn diese Berechnung akzeptiert, wird M2 auf x2 auf Band 2 gestartet. Wenn auch diese Berechnung akzeptiert, hält M akzeptierend. — Nach dem für NTMn geltenden Akzeptierungsmodus ist klar, dass M x genau dann akzeptiert, wenn man x = x1 x2 mit x1 ∈ L1 und x2 ∈ L2 schreiben kann. Nach Satz 1.3.11 ist damit L1 L2 rekursiv aufzählbar. (d) Sei M eine 1-Band-TM mit L = LM . Eine 2-Band-NTM M 0 für L∗ arbeitet wie folgt auf Input x, der anfänglich auf Band 1 steht: Solange die Inschrift auf Band 1 nicht ε ist, wird folgende Runde wiederholt: 1) Ein nichtdeterministisch gewähltes Präfix z 6= ε der Inschrift y auf Band 1 wird von Band 1 gelöscht und auf Band 2 geschrieben. 78 2) M wird mit Input z auf Band 2 gestartet. Wenn diese Berechnung von M verwerfend hält, hält auch M 0 verwerfend. Wenn M akzeptiert, beginnt eine neue Runde. Sobald nach der Ausführung von r ≥ 0 Runden die Inschrift auf Band 1 ε geworden ist, akzeptiert M 0 . — Es ist klar, dass M 0 x genau dann akzeptiert, wenn man x als z1 · · · zr schreiben kann mit z1 , . . . , zr ∈ LM = L, d. h. wenn x ∈ L∗ ist. Nach Satz 1.3.11 ist damit L∗ rekursiv aufzählbar. 1.4.3 Bemerkung Eine andere Möglichkeit für den Beweis von (b) wäre die Benutzung einer NTM, die sich im ersten Schritt nichtdeterministisch entscheidet, ob M1 oder M2 auf x gestartet wird (vgl. Beispiel 1.3.14). Wir haben direkt eine deterministische 2-Band-TM M 0 für L1 ∪ L2 beschrieben, da die Konstruktion gleich nochmals benötigt wird, in einem Zusammenhang, in dem Nichtdeterminismus nichts nützt. 1.4.4 Satz Für jede Sprache L ⊆ Σ∗ gilt: L ist rekursiv ⇔ L und L sind rekursiv aufzählbar. Beweis: ⇒“: Sei L rekursiv. Nach Satz 1.4.1(a) ist dann auch L rekursiv. Nach Defini” tion 1.1.16 (a) und (b) sind L und L rekursiv aufzählbar. ⇐“: (Durch Konstruktion.) Seien M1 , M2 Turingmaschinen mit L = LM1 , L = LM2 . ” Wir betrachten die Maschine M aus dem Beweis von Satz 1.4.2(b) (sie startet M1 und M2 gleichzeitig auf Eingabe x), nur mit anderem Akzeptierungsverhalten: Sobald M1 hält und akzeptiert, Sobald M2 hält und akzeptiert, hält und akzeptiert M . hält und verwirft M . Wir haben für Eingaben x ∈ Σ∗ : x ∈ L ⇒ M1 hält und akzeptiert ∧ M2 akzeptiert nicht ⇒ M hält und akzeptiert. x ∈ Σ∗ − L ⇒ M1 akzeptiert nicht ∧ M2 hält und akzeptiert ⇒ M hält und verwirft. Also ist L = LM für die TM M , die für alle Eingaben hält; demnach ist L rekursiv. Wir wollen nun noch den Grund für die eigenartige Bezeichnung rekursiv aufzählbar“ ” für die von TMn akzeptierten Sprachen besprechen. Es zeigt sich, dass genau diejenigen Sprachen rekursiv aufzählbar sind, die von einem rekursiven (auf einer TM ablaufenden) Prozess aufgezählt, deren Elemente also nacheinander erzeugt werden können. 79 1.4.5 Definition Eine Mehrband-TM N heißt ein Aufzähler für L ⊆ Σ∗ , falls N auf Eingabe ε auf einem besonderen Ausgabeband eine Zeichenfolge #x1 #x2 #x3 # · · · , x1 , x2 , x3 . . . ∈ Σ∗ , # 6∈ Σ, schreibt, wobei L = {x1 , x2 , x3 , . . .} ist. Im Normalfall hält N nicht an. Für das Ausgabeband gilt die Einschränkung, dass der Kopf sich nicht nach links bewegen darf und einmal geschriebene Symbole a ∈ Σ ∪ {#} nicht mehr verändert werden dürfen. Intuitiv gesprochen stellt ein Aufzähler für L einen Algorithmus zur systematischen Erzeugung aller Wörter in L dar. Im Gegensatz zu dem von einer Grammatik gegebenen Erzeugungsprozess ist das Verfahren aber deterministisch. 1.4.6 Satz L ist rekursiv aufzählbar ⇔ es gibt einen Aufzähler für L. Beweis: Der Beweis besteht aus zwei Konstruktionen. Ein Aufzähler N für L wird in eine TM M mit LM = L umgebaut, und umgekehrt. ⇐“: Sei N ein Aufzähler für L. Wir konstruieren eine TM M mit LM = L. M enthält N ” mit seinen Bändern als Teilmaschine, und besitzt ein weiteres Band, auf dem die Eingabe x steht (und nicht verändert wird). . B B B a 1 a 2 a 3 ... M: an B B B ... Eingabe x für M : N # x1 # x2 # x 3 # Bänder von N a r b e i t s b a n d + v o n + N Auf Eingabe x arbeitet M wie folgt: Lasse N auf der leeren Eingabe ε laufen. Jedesmal wenn N #“ druckt und damit die Ausgabe eines Wortes x0 ∈ L abschließt, wird die ” Berechnung von N unterbrochen und die Eingabe x wird mit dem Wort x0 ∈ Σ∗ verglichen, das vor dem letzten #“ auf dem Ausgabeband von N steht. Falls x = x0 , hält und ” akzeptiert M , sonst wird die Berechnung von N an der Unterbrechungsstelle fortgesetzt. Wir haben: M akzeptiert x ⇔ N zählt x auf ⇔ x ∈ L. Also ist LM = L, und L ist rekursiv aufzählbar. ⇒“: Die andere Richtung des Beweises ist etwas schwieriger. Gegeben ist eine TM ” M = (Q, Σ, Γ, B, q0 , F, δ) mit LM = L. Der naive Ansatz wäre, alle Elemente von Σ∗ 80 aufzuzählen (etwa y0 , y1 , . . .), M nacheinander auf y0 , y1 , . . . zu starten und diejenigen yi auf das Ausgabeband zu schreiben, die von M akzeptiert werden. Das funktioniert aber leider nicht, da M zum Beispiel auf y0 nicht halten könnte und dann die Berechnung auf y1 gar nicht beginnt, obwohl y1 ∈ LM ist. Wir müssen also vorsichtiger vorgehen und es vermeiden, die Berechnung von M auf einem Input y immer weiter laufen zu lassen. Zu diesem Zweck führen wir zwei neue Programmiertechniken ein: Uhr-kontrollierte Be” rechnungen“ und dovetailing“. ” Programmiertechnik: Uhr-kontrollierte Berechnungen. (Engl.: clocked compu” tations“). M sei eine beliebige TM oder NTM. Wir beschreiben eine TM (bzw. NTM) M 0 , die Berechnungen von M bis zu einer durch eine Binärzahl vorgegebene Schrittzahl ausführt. M 0 hat neben den Bändern für M ein zusätzliches Band, das Schrittzählband. M 0 erhält Inputs vom Format x#w, wobei x ∈ Σ∗ der Input von M , w ∈ {1}{0, 1}∗ die Binärdarstellung einer Zeitschranke t = (w)2 und # ∈ / Σ ∪ {0, 1} ein Trennzeichen ist. Mit dieser Eingabe arbeitet M 0 wie folgt: w wird auf das Schrittzählband kopiert und #w wird aus der Eingabe gelöscht. Dann führt M 0 abwechselnd die folgenden Schritte durch: 1. Führe einen Schritt von M aus. Wenn M nun in einer Haltekonfiguration ist, hält auch M 0 ( erfolgreiche Simulation“). ” 2. Reduziere die Binärzahl auf dem Schrittzählband um 1. Falls dort nun 0 steht, hält M 0 an ( erfolglose Simulation“). ” 1.4.7 Lemma Für Eingabe x#w gilt: (a) M 0 führt min{tM (x), (w)2 } Schritte von M aus. (b) M 0 hält erfolgreich genau dann wenn tM (x) ≤ (w)2 . (c) Die Gesamtzahl der Schritte von M 0 während der eigentlichen Simulation (ohne das Kopieren von w) ist O((w)2 ). Beweis: (a) und (b) sind klar; der Beweis von (c) ist eine schöne Übungsaufgabe. Wir beziehen uns auf die Technik der Uhr-kontrollierten Berechnungen, indem wir sagen: M 0 simuliert die Berechnung von M auf x für (w)2 Schritte. Statt einer binären Uhr kann man natürlich auch eine unäre oder eine d-äre zu einer Basis d ≥ 3 benutzen. Programmiertechnik: Quasiparallele Ausführung“. Hier geht es um eine Tech” nik, die es gestattet, auf einer TM M 0 Berechnungen einer TM M auf einer endlichen Menge x1 , . . . , xm von Inputs für M durchzuführen, auch wenn man nicht weiß, welche dieser Berechnungen anhalten. Dabei ist m zwar endlich, aber nicht beschränkt; daher können wir nicht einfach M 0 mit m Bändern versehen und wie im Beweis von Satz 1.4.2(b) auf diesen Bändern parallel arbeiten. Stattdessen muss man zwischen den Berechnungen abwechseln und auf M 0 z. B. den folgenden Ablauf erzeugen: 81 für t := 1, 2, 3, . . . tue für j = 1, . . . , m tue simuliere M auf xj für t Schritte. Technisch lässt man die Eingaben x1 , . . . , xm unverändert auf dem Eingabeband stehen, und erzeugt mit der Methode von Lemma 1.3.10 nacheinander die Binärwörter w ∈ {1}{0, 1}∗ . Für jedes solche w startet man für jedes j ∈ {1, . . . , m} eine Uhrkontrollierte Berechnung von M auf xj #w; nach jeder solchen Berechnung werden die dabei benutzten Bänder wieder gelöscht. Das Verhalten dieses Verfahrens ist klar: Wenn xj ∈ HM , dann wird die Simulation von M auf xj für (w)2 ≥ tM (xj ) erfolgreich sein. Wenn es ein j mit xj ∈ / HM gibt, hält die Prozedur nie an. Wenn M auf allen xj hält, kann auch das Verfahren schließlich halten. Programmiertechnik: Dovetailing“. Man kann die Idee der quasiparallelen Aus” führung noch weiter treiben und auf eine unendliche Folge x1 , x2 , . . . von Inputs anwenden. Das Ziel dabei ist, in einer unendlich lange laufenden Berechnung schließlich alle haltenden Berechnungen von M auf irgendwelchen xj zu finden — oder auch nur ein xj zu finden, auf dem M hält. Es ist klar, dass wir bei einem Berechnungsversuch M auf einem Input xj nur für eine vorgegebene Zahl t von Schritten laufen lassen. Wenn wir sicherstellen, dass für jedes xj eine unbeschränkte Menge von Zeitschranken t probiert wird, gilt: irgendwann wird die haltende Berechnung xj ∈ H M ⇒ von M auf xj gefunden. Eine konkrete Methode, um dies zu erreichen, wäre etwa der folgende Ablauf: für t := 1, 2, 3, . . . tue für j = 1, . . . , t tue simuliere M auf xj für t Schritte. Damit wird für jedes j eine Simulation von M auf xj für t = j, j + 1, j + 2, . . . Schritte durchgeführt, also im Fall xj ∈ HM eine haltende Berechnung von M auf xj gefunden. Dieses verschränkte“ Ausprobieren mehrerer Rechnungen von M (quasi-)gleichzeitig auf ” unendlich vielen Eingaben nennt man dovetailing“. (Das englische Wort heißt wörtlich ” Schwalbenschwanz“ und bezieht sich auf die Technik des Verschränkens mit Nut und ” Feder bei Holzarbeiten.) Dies ist eine sehr wichtige und grundlegende Technik, um mit dem Problem des Nicht-Haltens von TM zurechtzukommen. Wir wenden die Dovetailing-Technik an, um aus einer TM M = (Q, Σ, Γ, . . .) einen Aufzähler N für LM zu konstruieren. Das Zeichen # soll nicht in Σ ∪ {0, 1} vorkommen. N hat zwei Bänder zur Erzeugung von Wörtern: Band 1 für Binärwörter, Band 2 für Wörter aus Σ∗ . Zudem hat N eine Teilmaschine, die Uhr-kontrollierte Berechnungen von M ausführen kann, sowie ein Ausgabeband. N rechnet wie folgt. Auf Band 1 wird 0 geschrieben, auf das Ausgabeband #. Dann wird folgendes wiederholt: 82 1. Erhöhe den Binärzähler auf Band 1 um 1. Die jetzige Inschrift sei w. 2. Erzeuge auf Band 2 mit der Technik von Lemma 1.3.10, erweitert um einen Zähler, der von t = (w)2 nach unten zählt, die ersten t Wörter x1 , . . . , xt in der Aufzählung von Σ∗ . 3. Für jedes Wort xj auf Band 2: Simuliere M auf xj für t = (w)2 Schritte. Falls diese Berechnung akzeptierend hält, füge xj # an die Inschrift auf dem Ausgabeband an. Zu zeigen bleibt: x ∈ L = LM ⇔ N schreibt irgendwann x#. ⇐“: Wenn N das Wort x# schreibt, ist vorher eine akzeptierende Berechnung von M ” auf x gefunden worden. Daher ist x ∈ LM = L. ⇒“: Wenn x ∈ LM , akzeptiert M den Input x nach tM (x) Schritten. In jeder Runde der ” Berechnung von N mit einem w, das (w)2 ≥ tM (x) erfüllt, ist die Simulation von M auf x erfolgreich, also wird x# geschrieben. Damit ist der Beweis von Satz 1.4.6 ⇒“ beendet. ” 1.4.8 Bemerkung (a) Der Aufzähler N aus dem eben geführten Beweis gibt jedes Wort x ∈ L unendlich oft aus. Das ist für manche Anwendungen eine erwünschte Erscheinung. (b) Andererseits gilt: Wenn N irgendein Aufzähler für L ist, konstruiert man folgendermaßen einen Aufzähler N 0 für L, der jedes Wort x ∈ L genau einmal ausgibt: N 0 benutzt N mitsamt den Bändern von N als Teilmaschine und hat ein zusätzliches Ausgabeband. Die von N erzeugte Ausgabe wird gefiltert. Der Kopf auf dem Ausgabeband von N kann auch nach links fahren und Geschriebenes nochmals lesen (aber nichts ändern). Immer wenn N auf seinem Ausgabeband ein #-Zeichen schreibt, wird N unterbrochen. N 0 inspiziert das letzte Wort xi ∈ Σ∗ unmittelbar links vom #-Zeichen und prüft mit Textsuche (Beispiel 1.2.11) auf dem Ausgabeband von N , ob xi unter den vorher erzeugten Wörtern x1 , . . . , xi−1 schon vorkommt. Nur wenn dies nicht so ist, wird xi an die Ausgabe von N 0 angefügt. Man kann die Anforderungen an die Ausgabe von N nicht beliebig erhöhen. Wenn wir für ein Alphabet Σ = {0, 1, . . . , d−1} die kanonische Ordnung <kan auf Σ∗ wie folgt festlegen: x <kan y :⇔ |x| < |y| oder (|x| = |y| ∧ (x)d < (y)d ), 83 könnte man verlangen, dass die Elemente von L in aufsteigender Reihenfolge ausgegeben werden. Dabei gilt jedoch: es existiert ein Aufzähler für L, L ist rekursiv ⇔ der die Wörter x ∈ L in der durch <kan vorgeschriebenen Reihenfolge ausgibt. (Der Beweis ist eine Übungsaufgabe.) — Wir werden bald sehen, dass es rekursiv aufzählbare Sprachen gibt, die nicht rekursiv sind. Diese haben dann zwar einen Aufzähler, aber keinen, der die Elemente in kanonischer Ordnung ausgibt. 1.5 Äquivalenz von Turingmaschinen und Registermaschinen In diesem Abschnitt wollen wir uns klarmachen, dass Turingmaschinen und Registermaschinen dieselbe Berechnungskraft haben. Zunächst zeigen wir, dass man TuringmaschinenBerechnungen auf Registermaschinen (und auf idealisierten Computern ohne Platz- und Zeitbeschränkung) simulieren kann. Danach überlegen wir, wie man die Berechnungen von Registermaschinen auf Turingmaschinen simulieren kann. Da wir uns, zumindest informal, schon überlegt haben, dass auf Registermaschinen alle Maschinenprogramme zu realen Computern ausgeführt werden können, ergibt sich die vielleicht überraschende Konsequenz, dass Turingmaschinen im Prinzip alle Computerprogramme ausführen können. 1.5.1 Simulation von Turingmaschinen auf Registermaschinen In diesem Abschnitt zeigen wir, dass alle von Turingmaschinen berechenbaren Funktionen auch auf Registermaschinen berechenbar sind. Analoges gilt für Entscheidungsprobleme, also Sprachen. Sei also M = (Q, Σ, Γ, B, q0 , F, δ) eine Turingmaschine. Turingmaschinen verarbeiten Wörter über Alphabeten; Registermaschinen verarbeiten Zahlen. Um die TM-Berechnung auf einer RAM ausführen zu können, benennen wir die Elemente des Bandalphabets Γ mit |Γ| = s so in Zahlen um, dass folgende Situation entsteht: Γ = {0, . . . , s − 1}; Σ ⊆ {1, . . . , s − 1}; B = 0. Nach den Konventionen aus Abschnitt 1.1 wird eine Eingabe x = a1 · · · an ∈ Σn bei der Registermaschine anfangs in die Register R1 , R3 , R5 , . . . , R2n−1 geschrieben; R0 enthält n; die anderen Register sind mit 0 vorbesetzt. Als Ausgabe beim Anhalten der Registermaschine gilt der Inhalt der Register R1 , R3 , R5 , . . . , R2k−1 , wobei k = hR0 i ist. Bezüglich der TM M nehmen wir an, dass M ein einseitig unbeschränktes Band hat (s. Beispiel 1.2.4), also nur Bandzellen 1, 2, . . . benutzt, und dass die Ausgabe schließlich in 84 den Bandzellen 1, 2, . . . , k steht. Dies lässt sich durch Umkopieren zum Ende der Rechnung stets erreichen. Eine Akzeptiere/Verwirf-Entscheidung der TM wird nicht über F ⊆ Q, sondern durch den Ausgabewert repräsentiert (etwa 1“ für akzeptiere“ und 2“ für ” ” ” verwirf“, vgl. Satz 1.4.1(c)). ” 1.5.1 Satz M sei eine 1-Band-Turingmaschine. Dann gibt es eine Registermaschine M 0 mit demselben Ein-Ausgabeverhalten wie M , d. h. für jedes x = a1 · · · an ∈ Σ∗ gilt: M hält auf x ⇒ M 0 hält auf x und die Ausgabe von M 0 auf x ist fM (x). M hält nicht auf x ⇒ M 0 hält nicht auf x. Die Zahl der Schritte von M 0 auf x ist O(tM (x)), falls M auf x hält. Die Kosten im logarithmischen Kostenmaß sind O(tM (x) · log(tM (x))). Beweis: M sei wie oben beschrieben. Eine Berechnung von M auf x soll, wie durch die Übergangsfunktion δ gegeben, Schritt für Schritt auf der RAM M 0 simuliert werden. Die Register R1 , R3 , R5 , . . . stellen das einseitig unbeschränkte Band dar. Die Eingabekonventionen sind so abgestimmt, dass die Eingabesymbole a1 , . . . , an anfangs in den richtigen Zellen stehen; die Vereinbarung B = 0 bewirkt, dass alle Zellen ausser den ersten n mit B initialisiert sind. Wir benötigen einige Hilfsregister, die aus R2 , R4 , R6 , . . . ausgewählt werden: Rhead enthält die gegenwärtige Kopfposition Rread enthält den gerade gelesenen Buchstaben R a“ ” enthält die konstante Zahl a ∈ Γ = {0, . . . , s − 1}. Anstelle die Zeilen des RAM-Programms durchzunumerieren, verwenden wir im folgenden für Sprungbefehle im RAM-Programm symbolische Marken. Das RAM-Programm besteht aus: – einem Initialisierungsteil, in dem die Hilfsregister R a“ besetzt werden, und die Be” fehle Rhead ← 1, Rread ← R1 und goto Block q0 ausgeführt werden; – einer Folge von Blöcken Blockq , q ∈ Q, die gleich beschrieben werden; und – einem Nachbearbeitungsteil, in dem die RAM M 0 in einer einfachen Schleife das maximale k mit hR1 i, hR3 i, . . . , hR2k−1 i = 6 0 sucht und k in R0 speichert; danach 0 hält M an. Für q ∈ Q sieht Blockq folgendermaßen aus: Blockq : Eine endliche Kaskade bedingter Sprünge, die folgenden Effekt hat: springe zu Bq,a für a = hRread i ∈ Γ. 85 Bq,0 : ··· Bq,1 : ··· Bq,s−1 : ··· Dabei sieht der mit Bq,a :“ markierte Teilblock je nach dem Wert δ(q, a) in der Turingtafel ” verschieden aus: 1. Fall: δ(q, a) ist undefiniert. Dann Bq,a : goto Nachbearbeitung 2. Fall: δ(q, a) = (q 0 , a0 , D) ∈ Q × Γ × {L, R, N }. Dann Bq,a : RRhead ← R a0“ ” falls D = R : Rhead ← Rhead + R”2“ falls D = L : Rhead ← Rhead − R 2“ ” falls D = N : − Rread ← RRhead goto Block q0 Es sollte klar sein, dass dieses RAM-Programm für jeden beliebigen Input x ∈ Σ∗ die Schritte der TM M auf x nacheinander simuliert und bezüglich Halten und Ausgabe die im Satz angegebenen Eigenschaften hat. Für die Zeitanalyse nehmen wir der Einfachheit halber an, dass M die Eingabe vollständig liest, also tM (x) ≥ |x| ist, und dass die Länge der Ausgabe nicht größer als tM (x) ist. Der Initialisierungsteil macht eine konstante Zahl von Schritten. Für die Simulation eines TMSchrittes wird nur eine konstante Zahl von Schritten der RAM benötigt. (Die Zahl der Schritte, die für die Kaskade bedingter Sprünge zur Unterscheidung der verschiedenen Buchstaben nötig sind, hängt von der Alphabetgröße s ab.) Der Nachbearbeitungsteil erfordert höchstens O(tM (x) + 1) Schritte. Also ist die Gesamtzahl der RAM-Schritte O(tM (x)). Für das logarithmische Kostenmaß ist zusätzlich die Bitlänge der Zahl in Rhead zu berücksichtigen. Alle anderen vorkommenden Zahlen und Registerindizes sind durch eine Konstante beschränkt, haben also Bitlänge O(1). Weil der Kopf von M in tM (x) Schritten keine Zelle jenseits der (tM (x) + 1)-ten erreichen kann, gilt stets hRhead i ≤ 2tM (x) + 1. Also ist die Bitlänge der Zahl in Rhead nicht größer als dlog2 (2tM (x)+2)e = O(log(tM (x))), und die logarithmischen Kosten pro Schritt sind O(log(tM (x))), die Gesamtkosten also O(tM (x) · log(tM (x))). Man beachte noch, dass die Konstruktion des RAM-Programms aus der Beschreibung der Turingmaschine effektiv“ möglich ist, d. h. es gibt einen Algorithmus, der die Transforma” tion für beliebige gegebene TMn durchführen kann. Außerdem sollte klar sein, dass man 86 die beschriebene Methode auch benutzen kann, um Turingmaschinen mit Programmen in Pascal, C oder Java zu simulieren. 1.5.2 Simulation von Registermaschinen auf Turingmaschinen In Abschnitt 1.1 wurde das Registermaschinenmodell eingeführt und erklärt, wie Registermaschinen Funktionen berechnen können. In diesem Abschnitt zeigen wir, dass jede RAM-berechenbare Funktion auch von einer Turingmaschine berechnet werden kann. Registermaschinen berechnen Zahlfunktionen, Turingmaschinen arbeiten auf Wörtern. Also müssen wir erst einmal erkären, wie eine Turingmaschine eine Zahlfunktion berechnen kann. Natürlich geschieht dies über Zahldarstellungen, zum Beispiel mittels der Binärdarstellung von natürlichen Zahlen. 1.5.2 Definition (a) M = (Q, {0, 1, #}, Γ, B, q0 , F, δ) sei eine deterministische Turingmaschine. Die von M berechnete Zahlfunktion f˜M : DM → Seq(N) wird definiert, indem man die Wirkung von M auf Kodierungen von Zahlenfolgen betrachtet. Der Definitionsbereich von f˜M ist DM := {(a1 , . . . , an ) ∈ Seq(N) | w = bin(a1 )# · · · #bin(an ) ∈ HM , ∃(b1 , . . . , bm ) ∈ Seq(N) : fM (w) = bin(b1 )# · · · #bin(bm )}. Für (a1 , . . . , an ) ∈ DM ist f˜M (a1 , . . . , an ) = (b1 , . . . , bm ), wenn fM (bin(a1 )# · · · #bin(an )) = bin(b1 )# · · · #bin(bm ). (Wenn z. B. fM (100#1101#1#0#11) = 10101#110100, dann ist f˜M (4, 13, 1, 0, 3) = (21, 52).) (b) Eine Zahlfunktion f : D → Seq(N), für ein D ⊆ Seq(N), heißt partiell rekursiv, wenn es eine TM M mit f = f˜M gibt. (c) Eine Menge A ⊆ Seq(N) heißt rekursiv aufzählbar, wenn es eine TM M gibt mit A = {(a1 , . . . , an ) ∈ Seq(N) | bin(a1 )# · · · #bin(an ) ∈ LM }. (d) Eine Menge A ⊆ Seq(N) heißt rekursiv, wenn es eine TM M gibt, die auf allen Eingaben hält und A = {(a1 , . . . , an ) ∈ Seq(N) | bin(a1 )# · · · #bin(an ) ∈ LM } erfüllt. 87 1.5.3 Bemerkung Um das Verhalten der TMn auf den Inputs, die nicht das richtige Inputformat bin(a1 )# · · · #bin(an ) für Zahlen a1 , . . . , an haben, sollte man sich keine Sorgen machen. Die Menge der legalen Zahlkodierungen ist regulär, daher kann eine Syntaxprüfung immer in linearer Zeit durchgeführt werden und ein passendes Verhalten der TM (Halten mit Output ε oder (0), Nichthalten, usw.) eingestellt werden. Man macht nichts falsch, wenn man annimmt, dass solche syntaktisch falschen Eingaben gar nicht vorkommen. 1.5.4 Notation: Ist a ∈ N, so ist kak = |bin(a)| = max{1, dlog2 (a + 1)e}. n P kai k die Gesamtbitlänge“ der Binärdar” stellung der Komponenten von a. (Zum Beispiel ist k(5, 9, 16)k = 12.) Ist a = (a1 , . . . , an ) in Seq(N), so ist kak = i=1 1.5.5 Satz Es sei D ⊆ Seq(N) und f : D → Seq(N) eine Funktion. M sei eine RAM, die f berechnet. Dann gilt: (a) Es existiert eine Turingmaschine M 0 mit f = f˜M 0 . (b) Bezeichnet cM,logar (a) die Kosten der Rechnung von M auf a = (a1 , . . . , an ) ∈ D im logarithmischen Kostenmaß (vgl. Definition 1.1.4), so macht M 0 auf Input a O((cM,logar (a) + kak + kbk)3 ) Schritte, wenn b = f˜M (a) ist. Beweis: (Durch Konstruktion einer TM M 0 .) Die Registermaschine M sei durch ein Programm 0 : B0 1 : B1 .. . l − 1 : Bl−1 mit l Programmzeilen aus dem Befehlsvorrat für Registermaschinen gegeben. Die naheliegende Idee für die Simulation ist, die Registerinhalte von M in Binärdarstellung auf einem Band von M 0 zu halten (zum Beispiel auf Band 1). Zur Identifizierung wird dem Registerinhalt der Registerindex in Binärdarstellung vorangestellt. Die Darstellungen der einzelnen Register werden mit ##“ voneinander getrennt. Den Registerinhalten ” (alle anderen Registerinhalte sind 0) hRi1 i = b1 , . . . , hRim i = bm entspricht also die Bandinschrift · · · BB ##bin(i1 )#bin(b1 )##bin(i2 )#bin(b2 )## . . . ##bin(im )#bin(bm )## BB · · · 88 (Beispiel : Wenn hR0 i = 5, hR4 i = 12, hR7 i = 3, und wenn alle anderen Register 0 enthalten, wäre folgendes eine legale Darstellung dieser Registerinhalte: · · · B ##100#1100##11#0##0#101##111#11## B · · · Man bemerkt, dass die Reihenfolge nicht vorgeschrieben ist und dass Register mit Inhalt 0 explizit dargestellt sein können, aber nicht müssen.) Die andere wichtige Information während einer Berechnung von M ist der jeweilige Befehlszählerstand. Dieser stammt aus dem endlichen Bereich {0, 1, . . . , l − 1}, wenn wir Sprungziele ≥ l (die zum Anhalten von M führen) einstweilen ignorieren. Daher kann der Befehlszählerstand in der Steuereinheit von M 0 gespeichert werden. Natürlicherweise hat das Programm von M 0 drei Teile: 1. Initialisierung: Umbau der Eingabe auf das für die Simulation benötigte Format; 2. Schritt-für-Schritt-Simulation; 3. Nachbearbeitung: Umbau der Ausgabe auf das für Turingmaschinen geforderte Format. Initialisierung: Eine Eingabe (a1 , . . . , an ) ∈ Seq(N) für M wird gemäß Definition 1.5.2 der TM M 0 als Wort bin(a1 )# · · · #bin(an ) auf Band 1 präsentiert. Dieser Eingabe entsprechen auf der RAM M die Registerinhalte hR2i−1 i = ai , 1 ≤ i ≤ n, und hR0 i = n; alle anderen Register stehen auf 0. Wir erzeugen eine diesen Registerinhalten entsprechende Bandinschrift, nämlich ##bin(1)#bin(a1 )##bin(3)#bin(a2 )## · · · ##bin(2n−1)#bin(an )##bin(0)#bin(n)## auf Band 1, wie folgt. Wir benutzen zwei Hilfsbänder (Band 2 und 3). Auf Band 3 wird ## geschrieben. Der Kopf auf Band 1 wird auf den Anfang der Inschrift (also zu bin(a1 )) gestellt. Auf Band 2 werden nun nacheinander die Binärdarstellungen bin(0), bin(1), bin(2), . . . erzeugt. (Vgl. Lemma 1.3.10 und Übung.) Jedes zweite Element dieser Folge (also bin(2i−1)) wird an die Inschrift auf Band 3 angefügt, gefolgt von dem Teilstring #bin(ai )##, wobei bin(ai ) von Band 1 kopiert wird. Dies wird fortgeführt, bis der Kopf auf Band 1 das Ende der Bandinschrift erreicht hat. Die letzte benutzte Binärzahl auf Band 2 ist bin(2n − 1). Wir addieren 1 und streichen die letzte 0, um bin(n) zu erhalten, und schreiben schließlich noch 0#bin(n)## auf Band 3. Schließlich wird Band 3 auf Band 1 kopiert, Bänder 2 und 3 mit Blanks überschrieben. Schritt-für-Schritt-Simulation: Für jede Zeile z : Bz , 0 ≤ z < l, des Programms von M , mit einem Befehl Bz aus dem RAM-Befehlsvorrat, besitzt das Programm der TM M 0 ein Teilprogramm TPz , das einfach einem Block von Zeilen in der Turingtafel entspricht. 89 Wir zeigen an zwei Beispielen, wie Befehlszeilen in Teilprogramme umgesetzt werden. Wenn die Ausführung von TPz begonnen wird, sind Bänder 2 und 3 leer, der Kopf auf Band 1 steht auf dem ersten #. 10: Ri ← Rj · Rk Das Teilprogramm TP10 tut folgendes: 1. Suche auf Band 1 das Teilwort uj = ##bin(j)#. (Da j eine feste, von der Eingabe unabhängige Zahl ist, kann man uj in der Steuereinheit speichern.) Falls uj gefunden wird, steht es in einem Zusammenhang ##bin(j)#b1 · · · br ## für ein Binärwort b1 · · · br . Dann kopiere b1 · · · br auf Band 2. Wenn uj nicht gefunden wird, schreibe 0 auf Band 2. 2. Suche auf Band 1 das Teilwort uk = ##bin(k)#. Falls uk gefunden wird, steht es in einem Zusammenhang ##bin(k)#c1 · · · ct ##. Dann kopiere c1 · · · ct auf Band 3. Wenn uk nicht gefunden wird, schreibe 0 auf Band 3. 3. Berechne die Binärdarstellung d1 · · · ds des Produkts der Inhalte b1 · · · br von Band 2 und c1 · · · ct von Band 3. Schreibe das Resultat auf Band 2. 4. Suche auf Band 1 das Teilwort ui = ##bin(i)#. Falls ui gefunden wird, steht es in einem Zusammenhang ##bin(i)#e1 · · · em ##. Kopiere die gesamte Bandinschrift ##y rechts von e1 · · · em auf Band 3, überschreibe e1 · · · em mit d1 · · · ds (von Band 2), und kopiere ##y von Band 3 zurück rechts von d1 · · · ds . — Falls ui auf Band 1 nicht gefunden wird, erzeuge einen neuen Eintrag bin(i)#d1 · · · ds ## rechts der existierenden Bandinschrift auf Band 1. 5. Lösche Bänder 2 und 3, fahre Kopf auf Band 1 auf Ausgangsposition. 6. (Falls l ≥ 12:) Springe zum Teilprogramm TP11 . (Falls l = 11, springe zur Nachbearbeitung.) 15: Ri ← RRj Das Teilprogramm TP15 tut folgendes: 1. Suche auf Band 1 das Teilwort uj = ##bin(j)#. Falls uj gefunden wird, steht es in einem Zusammenhang ##bin(j)#b1 · · · br ## für ein Binärwort b1 · · · br . Dann kopiere b1 · · · br auf Band 3. Wenn uj nicht gefunden wird, schreibe 0 auf Band 3. 90 2. Suche ein Teilwort ##b1 · · · br # (Inschrift Band 3) auf Band 1. (Da die Länge r dieses Teilwortes nicht durch eine nur von M abhängige Konstante zu beschränken ist, sondern inputabhängig beliebig groß sein kann, muss hierzu die Technik Textsuche“ ” aus Abschnitt 1.2.11 benutzt werden.) Falls ##b1 · · · br # gefunden wird, steht es in einem Zusammenhang ##b1 · · · br #c1 · · · ct ## für ein Binärwort c1 · · · ct . Kopiere c1 · · · ct auf Band 2. Wenn ##b1 · · · br # nicht gefunden wird, schreibe 0 auf Band 2. 3. Wie 4. im vorherigen Beispiel. 4. Wie 5. im vorherigen Beispiel. 5. (Falls l ≥ 17:) Springe zum Teilprogramm TP16 . (Falls l = 16, springe zur Nachbearbeitung.) Wenn die Registermaschine M auf Input a anhält, erhält der Befehlszähler schließlich einen Wert ≥ l. In den Teilprogrammen TPz schreibt man an eine solche Stelle einen Sprung zum Beginn der Nachbearbeitung. Die Umsetzung der anderen RAM-Befehle gemäß der Tabelle in Abschnitt 1.1.1 in Turingmaschinen-Teilprogramme seien dem Leser/der Leserin zur Übung überlassen. Die Phase Schritt-für-Schritt-Simulation“ wird begonnen, indem man von der Initialisie” rung zum Teilprogramm TP0 für Programmzeile 0 springt. Nachbearbeitung: Wenn M auf Input a anhält, springt die TM M 0 nach Simulation des letzten Schritts zur Nachbearbeitung. In diesem Teil müssen die Inhalte der auf Band 1 in beliebiger Ordnung aufgeführten Register R1 , R3 , . . ., R2k−1 , mit k = hR0 i in das Ausgabewort bin(hR1 i)#bin(hR3 i)# · · · #bin(hR2k−1 i) umgeformt werden. Hierfür findet man zunächst die Darstellung von R0 und liest den Inhalt k ab. Dann erzeugt man wie in der Initialisierungsphase alle Binärzahlen bin(2i−1), 1 ≤ i ≤ k, und sucht mit Textsuche die Darstellungen der entsprechenden Register auf. Die Registerinhalte werden dann in der richtigen Reihenfolge hintereinandergefügt. Beispiel : Aus der Bandinschrift ##11#101##10#1111##1001#11##110#11101##0#100##101#10##, die den Registerinhalten hR3 i = 5, hR2 i = 15, hR9 i = 3, hR6 i = 29, hR0 i = 4, hR5 i = 2 entspricht, erzeugt die Nachbearbeitung die Ausgabe-Bandinschrift 0#101#10#0, entsprechend der RAM-Ausgabe (0, 5, 2, 0). Wir schätzen nun die Anzahl der für diese Simulation benötigte Anzahl von Schritten der TM M 0 ab. 91 Es sei s die maximal auftretende Länge der gesamten Inschrift auf Band 1, t sei die maximale Bitlänge einer im Verlauf der gesamten Berechnung in einem Register gespeicherten Zahl. Die Suche nach einem Teilwort ##c1 · · · cr # auf Band 1 kann so realisiert werden, dass die benötigte Schrittzahl O(s) ist. Die Simulation eines Schrittes erfordert höchstens 3 solche Suchvorgänge. Das Eintragen des Resultates auf Band 1 erfordert ebenfalls Zeit O(s). Die aufwendigsten arithmetischen Operationen sind Multiplikation und Division; sie erfordern höchstens O(t2 ) Schritte Die Anzahl der zu simulierenden RAM-Schritte ist durch c(a) := cM,logar (a) beschränkt. Daher sind die Gesamtkosten der Schritt-für-SchrittSimulation O(c(a) · (s + t2 )). Wie kann man s abschätzen? Mit der Initialisierung werden die n Eingabezahlen in a durch die Binärdarstellung von n Registernummern erweitert, die alle < 2n sind; man sieht daraus, dass die resultierende Bandinschrift höchstens Länge kak + O(n log n) = O(kak log kak) hat. Eine Verlängerung der Bandinschrift kommt nur durch die Ausführung eines Befehls zustande, in dem Zahlen gelesen und verarbeitet werden. Nach der Definition der logarithmischen Kosten ist die Anzahl der neuen Zeichen in der Bandinschrift durch die logarithmischen Kosten für den Schritt (multipliziert mit einer kleinen Konstanten) beschränkt. Durch Summation über alle Schritte sieht man, dass s = O(kak log kak+c(a)) ist. Mit t ist es einfacher: Offenbar ist t = O(kak + c(a)). — Damit ist die Gesamtzahl der von M 0 in der Initialisierung und der Schritt-für-Schritt-Simulation ausgeführten Schritte O(c(a)) · (O(kak log kak + c(a)) + O((kak + c(a))2 ) = O((kak + c(a))3 ). Ist nun f˜M (a) = (b1 , . . . , bl ), so kann man die Kosten der Nachbearbeitung durch O((s + kbk)2 ) abschätzen. Die Gesamtkosten sind also O((kak + kbk + c(a))3 ). 1.5.6 Bemerkung Für eine polynomielle Laufzeitbeschränkung der simulierenden Turingmaschine ist es notwendig, bei der RAM das logarithmische Kostenmaß zugrundezulegen. Es ist nämlich möglich, auf einer RAM in O(k) Schritten durch iteriertes Quadrieren k die Zahl 22 der Bitlänge 2k zu erzeugen, deren Bearbeitung auf einer TM Zeit Θ(2k ) erfordert. 1.6 Zur Bezeichnung Rekursive Funktionen“ und ” Rekursive Mengen“ ” In den bisherigen Betrachtungen haben wir Rechenmodelle, nämlich Registermaschinen und Turingmaschinen benutzt, um den Begriff berechenbare Funktion“ bzw. entscheid” ” bare Sprache“ präzise zu fassen. Daneben gibt es noch eine ganze Reihe anderer Methoden, mit denen das Konzept intuitiv berechenbare Funktion“ präzise gefasst werden ” kann (Stichworte: λ-Kalkül, Markov-Algorithmen, µ-rekursive Funktionen, Spezifikation in einem Logik-Kalkül, . . .). Eine solche nicht maschinenorientierte Methode wird hier noch kurz skizziert, deren Struktur Anlass für die Namensgebung rekursive Funktion“ ” 92 bzw. rekursive Menge“ gab. Wir arbeiten im Bereich der partiellen Zahlenfunktionen“, ” ” der folgendermaßen erklärt ist: 1.6.1 Definition Für n ≥ 0 sei Fn := {F | F : D → N für ein D ⊆ Nn }. Der Definitionsbereich D von F wird mit DF = Def(F ) bezeichnet.18 Wenn DF = Nn , heißt F total. S F := {Fn | n ≥ 0} ist die Gesamtheit aller partiellen Zahlenfunktionen. Als Abkürzung für (m1 , . . . , mn ) ∈ Nn schreiben wir oft m. ~ Die Stelligkeit muss dann aus dem Zusammenhang hervorgehen. 1.6.2 Definition Die folgenden (totalen) Funktionen heißen Basisfunktionen: (a) Konstante Funktionen: Cn,k ∈ Fn , n, k ≥ 0, wobei Cn,k (m) ~ = k für alle m ~ ∈ Nn . (b) Projektionen: Pn,i ∈ Fn , n ≥ 1, 1 ≤ i ≤ n, wobei Pn,i (m1 , . . . , mn ) = mi für alle (m1 , . . . , mn ) ∈ Nn . (c) Nachfolgerfunktion: S ∈ F1 , wobei S(m) = m + 1, für alle m ∈ N. Es ist klar, dass jede Basisfunktion intuitiv berechenbar ist. (Man überlege zur Übung, wie Pascal-Funktionsprozeduren oder RAM-Programme für die Basisfunktionen aussehen.) Nun betrachten wir drei Methoden ( Schemata“) zur Gewinnung neuer Funktionen aus ” gegebenen. 1.6.3 Definition (Einsetzen) Zu G ∈ Fr , H1 , . . . , Hr ∈ Fn mit r ≥ 1, n ≥ 0, betrachte die Funktion F ∈ Fn , die wie folgt definiert ist: F (m) ~ = G(H1 (m), ~ . . . , Hr (m)), ~ für alle m ~ ∈ DF , wobei ~ . . . , Hr (m)) ~ ∈ DG }. DF = { m ~ ∈ Nn | m ~ ∈ DH1 ∩ . . . ∩ DHr und (H1 (m), Wir sagen, F entsteht aus G, H1 , . . . , Hr durch Einsetzen, und schreiben E(G, H1 , . . . , Hr ) für F . Wir bemerken: Wenn für G und H1 , . . . , Hr Berechnungsverfahren vorliegen, erhält man auch leicht eines für F . 18 Man beachte den Sonderfall n = 0. Hier ist nur DF = {()} sinnvoll, F : {()} → N hat nur einen Wert F (()) ∈ N, entspricht also einer Konstanten. 93 1.6.4 Definition (Primitive Rekursion) Zu G ∈ Fn und H ∈ Fn+2 mit n ≥ 0, betrachte die Funktion F ∈ Fn+1 , die wie folgt definiert ist: F (0, m) ~ = G(m) ~ (definiert falls m ~ ∈ DG ), F (i + 1, m) ~ = H(i, F (i, m), ~ m) ~ (definiert falls F (i, m) ~ definiert und (i, F (i, m), ~ m) ~ ∈ DH ). Wir sagen, F entsteht aus G und H durch primitive Rekursion, und schreiben R(G, H) für F . Wir bemerken, dass man aus Berechnungsverfahren für G und H eines für F gewinnen kann, wie folgt. Angenommen, es soll F (j, m) ~ berechnet werden. Falls j = 0, berechnen wir G für die Eingabe m. ~ Falls dies gelingt, ist G(m) ~ das Resultat. Falls j ≥ 1, berechnen wir (rekursiv) F (j −1, m). ~ Falls dies gelingt, mit Resultat kj−1 , berechnen wir H(j − 1, kj−1 , m). ~ – Man sollte auch bemerken, dass in diesem Verfahren die Rekursion leicht zu eliminieren ist und F auch einfach per Iteration berechnet werden kann. Hierfür genügt eine for-Schleife, z.B. in Pascal-Notation: (* Eingabe: j, m1 ,...,mn : integer *) k := G(m1 ,...,mn ); for i := 1 to j do k := H(i-1, k, m1 ,...,mn ); F := k; (* Resultat: F *) 1.6.5 Definition (µ-Rekursion) Sei G ∈ Fn+1 eine Funktion. Betrachte die Funktion F ∈ Fn , die wie folgt definiert ist: das (eindeutig bestimmte) k ≥ 0 mit ~ ∈ DG für 0 ≤ i ≤ k und (i, m) G(i, m) ~ > 0 für 0 ≤ i ≤ k und F (m) ~ = G(k, m) ~ = 0, falls ein solches k existiert; undefiniert, sonst. Wir sagen, F entstehe aus G durch µ-Rekursion und schreiben (µG) für F . Wieder bemerken wir, dass aus einem Berechnungsverfahren für G eines für F konstruiert werden kann. (* Eingabe: j, m1 ,...,mn : integer *) i := 0; while G(i, m1 ,...,mn ) > 0 do i := i+1; F := i; (* Resultat: F *) Es gibt zwei Möglichkeiten für das Nicht-Terminieren dieses Algorithmus: wenn ein auf” gerufenes“ G(i, m) ~ kein Resultat liefert oder wenn G(i, m) ~ für alle i zwar definiert ist, aber keiner dieser Werte 0 ist. 94 Wieso nennt man diese Regel µ-Rekursion? Man kann sich überlegen, dass F (m) ~ = H(0, m), ~ wo i, falls (i, m) ~ ∈ DG und G(i, m) ~ = 0; H(i + 1, m), ~ falls (i, m) ~ ∈ DG und G(i, m) ~ > 0; H(i, m) ~ = und H(i + 1, m) ~ definiert; undefiniert, sonst. Diese Definition von H stellt eine Rekursion in Aufwärtsrichtung“ dar. ” Nun kommen wir zur entscheidenden Definition. 1.6.6 Definition (a) PR (die Klasse der primitiv rekursiven Funktionen) ist die kleinste Klasse von Funktionen in F, die die Basisfunktionen enthält und unter Einsetzung und primitiver Rekursion abgeschlossen ist, d.h. (i) Die Basisfunktionen sind in PR. (ii) Wenn G ∈ Fr , H1 , . . . , Hr ∈ Fn alle in PR sind, so auch E(G, H1 , . . . , Hr ). (iii) Wenn G ∈ Fn und H ∈ Fn+2 in PR sind, dann auch R(G, H). (iv) Nichts sonst ist in PR. (b) R (die Klasse der µ-rekursiven Funktionen) ist die kleinste Teilklasse von F, die die Basisfunktionen enthält und unter Einsetzung, primitiver Rekursion und µRekursion abgeschlossen ist, d.h. (i)–(iii) wie in (a) mit R statt PR (iv) Wenn G ∈ Fn , n ≥ 1, in R, dann ist auch (µG) in R. (v) Nichts sonst ist in R. Die Beschreibung von R und PR ⊆ R durch induktive Definitionen hat auf den ersten Blick nichts mit Maschinen zu tun. Mit Konstruktionen wie oben angedeutet, kann man aber durch Induktion über den Aufbau von R folgendes zeigen: F ∈ R ⇒ es existiert ein (idealisiertes) Pascal-Programm, das F berechnet. Mit analogen Methoden zeigt man: F ∈ R ⇒ es existiert ein RAM-Programm, das F berechnet. Andererseits kann man zeigen, dass alle RAM-berechenbaren Funktionen in R liegen. Nach unserer Definition und den Resultaten der Abschnitte 1.3 und 1.4 ist also R = Menge der partiell rekursiven Zahlenfunktionen. 95 Die Möglichkeit, die Klasse der RAM- oder Turing-berechenbaren Funktionen mittels des Rekursionsprinzips definieren zu können, hat zu der Namensgebung (partiell) rekursiv“ ” bzw. (total) rekursiv“ für die Funktionen dieser Klasse geführt. Dieser Name übertrug ” sich dann auf die rekursiven Sprachen, das sind die Sprachen, deren charakteristische Funktion (total) rekursiv ist. Zu guter letzt geben wir noch einige Beispiele von Funktionen in PR an, um den Mechanismus der induktiven Definition zu illustrieren. 1.6.7 Beispiel (a) Addition: A(i, m) = i + m. Diese Funktion lässt sich mittels primitiver Rekursion aus Basisfunktionen gewinnen, wie folgt: A(0, m) = m = P1,1 (m), A(i + 1, m) = A(i, m) + 1 = S(A(i, m)). Wenn wir H(k, l, r) = S(P3,2 (k, l, r)) definieren, ist A(i + 1, m) = H(i, A(i, m), m). Also ist A = R(P1,1 , E(S, P3,2 )) primitiv rekursiv. (b) Multiplikation: M (i, m) = i · m. Diese Funktion erhalten wir mittels primitiver Rekursion aus A, wie folgt: M (0, m) = 0 = C1,0 (m), M (i + 1, m) = M (i, m) + m = A(M (i, m), m). Wenn wir H(k, l, r) = A(P3,2 (k, l, r), P3,3 (k, l, r)) setzen, ist M (i+1, m) = H(i, M (i, m), m). Also ist M = R(C1,0 , E(A, P3,2 , P3,3 )) primitiv rekursiv. (c) Vorgängerfunktion: P (i) = 0 i−1 falls i = 0 falls i ≥ 1. Diese kann man wie folgt definieren: P (0) = 0 = C0,0 (()), P (i + 1) = i = P2,1 (i, P (i)), für i ≥ 0. Also ist P = R(C0,0 , P2,1 ) primitiv rekursiv. (d) (Abgeschnittene) Subtraktion: 0 Sub (i, m) = 0 m−i 96 falls i > m sonst. Diese Funktion erhält man wie folgt: Sub0 (0, m) = m = P1,1 (m), Sub0 (i + 1, m) = P (Sub0 (i, m)). Mit H(k, l, r) = P (P3,2 (k, l, r)), also H = E(P, P3,2 ) ist also Sub0 = R(P1,1 , E(P, P3,2 )) primitiv rekursiv. Die gewöhnliche Subtraktion Sub(m1 , m2 ) = m1 −m2 erhält man als Sub0 (P2,2 (m), ~ P2,1 (m)), ~ 0 also Sub = E(Sub , P2,2 , P2,1 ). (e) Signum-Funktion: Die durch sgn(i) = 0 1 falls i = 0 falls i ≥ 1 definierte Funktion ist wegen sgn(0) = 0, sgn(i + 1) = 1, also sgn = R(C0,0 , C3,1 ) primitiv rekursiv. Analog ist auch 1 falls i = 0 sgn(i) = 0 falls i ≥ 1 primitiv rekursiv, wegen sgn(i) = Sub(1, sgn(i)). (f) ≤-Relation: LE(m1 , m2 ) = 1 0 falls m1 ≤ m2 sonst. Es ist klar, dass LE(m1 , m2 ) = sgn(Sub(m1 , m2 )), d.h. LE = E(sgn, Sub), primitiv rekursiv ist. In dieser Art fortfahrend, kann man für viele natürliche Funktionen zeigen, dass sie primitiv rekursiv sind. Beispiele: Teilbarkeitsrelation: DIV BLE(m1 , m2 ) = Primzahlen: PRIM(m) = 1 falls ∃x ∈ N : xm1 = m2 , 0 sonst. 1 falls p ist Primzahl, 0 sonst. 97 1.7 Die Churchsche These Wir erinnern uns aus Abschnitt 0.2 an die Konzepte Berechnungsproblem und Entscheidungsproblem, an die Formulierung von Berechnungsproblemen als Funktionen, die Wörter auf Wörter abbilden, und die Formulierung von Entscheidungsproblemen als Sprachen. Sei f eine partielle Funktion, d. h. f : D → ∆∗ für ein D ⊆ Σ∗ . Wir sagen: f ist (im intuitiven Sinn) berechenbar, wenn es ein mechanisches, algorithmisches Verfahren“ gibt, ” das zu jedem x ∈ D den Funktionswert f (x) bestimmt. Eine Sprache L ⊆ Σ∗ heißt (im intuitiven Sinn) entscheidbar, wenn es ein solches Verfahren gibt, das zu jedem x ∈ Σ∗ eines der Resultate Ja“ und Nein“ berechnet, und zwar Ja“ ” ” ” genau für die x ∈ L. Die Sprache L heißt unentscheidbar, wenn es kein solches Verfahren gibt. Als Churchsche These bezeichnet man die Behauptung, dass das Konzept der partiell rekursiven Funktionen, wie in dieser Vorlesung auf der Basis von Turingmaschinen definiert, die richtige“ Formalisierung des informalen Konzeptes Berechenbare Funktionen“ ” ” ist und dass analog das Konzept der rekursiven Sprachen die richtige“ Formalisierung ” des Konzeptes algorithmisch lösbare Entscheidungsprobleme“ ist. ” Churchsche These: Eine Funktion f : D → ∆∗ , für ein D ⊆ Σ∗ , ist berechenbar genau dann wenn f partiell rekursiv ist. Das Wortproblem für eine Sprache L ⊆ Σ∗ ist entscheidbar genau dann wenn L rekursiv ist. Der Mathematiker Alonzo Church hatte 1936 eine solche Feststellung formuliert. Sie ist prinzipiell nicht beweisbar, denn sie behauptet die Äquivalenz eines intuitiven und nicht präzise fassbaren Konzeptes ( algorithmisch berechenbar“) und einer mathematisch präzi” sen Definition ( es gibt eine TM M mit f = fM “). Die Churchsche These ist aber als ” Basis für Überlegungen zu allem, was mit Algorithmen zu tun hat, etabliert. Welche Argumente gibt es dafür, die TM-Berechenbarkeit als Formalisierung der Idee der algorithmischen Berechenbarkeit“ zu benutzen? In der frühen Zeit der Entwicklung ” der Theorie der Berechenbarkeit wurden viele Versuche unternommen, das Konzept Be” rechenbarkeit“ zu formalisieren. Man definierte µ-rekursive Funktionen, im λ-Kalkül beschreibbare Funktionen, Markov-Algorithmen, spezifizierte Funktionen in Logik-Kalkülen, untersuchte Turingmaschinen, später auch while-Programme und Registermaschinen. Daneben untersuchte man allgemeine Grammatiken. Alle diese Formalismen versuchten, jeder mit einer anderen Terminologie, manche für Wortfunktionen, manche für Zahlenfunktionen, das Konzept algorithmische Berechenbarkeit“ zu formalisieren. Nun stellte sich ” heraus, als mit mathematischen Methoden beweisbare Sätze, dass alle diese Ansätze genau 98 dieselbe Klasse von Funktionen lieferten: nämlich die partiell rekursiven Funktionen. Als Klasse der entscheidbaren Sprachen ergab sich immer die Klasse der rekursiven Sprachen. Wir haben zwei Beispiele für solche Äquivalenzbeweise gesehen: In Abschnitt 1.3 wurde gezeigt, dass der Grammatikformalismus zum Turingmaschinenformalismus äquivalent ist; in Abschnitt 1.5 haben wir gesehen, dass TM-Berechenbarkeit und RAM-Berechenbarkeit äquivalent sind, wenn man zwischen Zahlenmengen und -funktionen und Wortmengen und -funktionen passend übersetzt.19 In späteren Jahren wurden dann sehr viele Programmiersprachen definiert, und damit viele neue Formalismen, mit denen sich Algorithmen als Programme präzise fassen ließen. Auch hier stellte sich heraus, dass man in jeder Programmiersprache ohne künstliche Einschränkungen, sei sie nun imperativ wie Pascal oder C, funktional wie Haskell, Lisp oder ML, oder logisch wie Prolog, bei der Annahme einiger simpler Idealisierungen (keine Zeit- und Speicherplatzbeschränkung) immer Programme genau für die partiell rekursiven Funktionen formulieren konnte. Die partiell rekursiven Funktionen sind also eine sehr natürliche Funktionenmenge, zu der alle bekannten Ansätze führen, das Algorithmenkonzept zu formalisieren. Wir diskutieren nochmals kurz die beiden Richtungen der Churchschen These. ⇒“: Wenn es für ein Entscheidungsproblem, das als Wortproblem für eine Sprache L ” formuliert ist, ein algorithmisches Verfahren oder ein Computerprogramm gibt, so ist L rekursiv; wenn eine Funktion f durch einen Algorithmus berechenbar ist, dann ist f partiell rekursiv. Diese Richtung der Churchschen These wird in zweifacher Weise angewendet: (a) Man spezifiziert einen Algorithmus für eine Funktion f in einem beliebigen Formalismus, einer Programmiersprache oder auch in informaler Weise und schließt ( nach ” der Churchschen These“), dass f partiell rekursiv ist. Bei Entscheidungsproblemen formuliert man ein Entscheidungsverfahren informal oder formal und schließt, dass die entsprechende Sprache rekursiv ist. Damit erspart man sich die mühevolle Beschreibung eines TM-Verfahrens. Meist ist es in diesen Fällen so, dass man sich die Umsetzung des Algorithmus in ein TM-Programm im Prinzip vorstellen kann, mit Hilfe der vielen Programmier- und Simulationstechniken, die wir inzwischen kennen. (b) Wir betrachten Aussagen wie: L ist unentscheidbar, d. h. das Wortproblem für L ist nicht algorithmisch lösbar“ ” oder Die Funktion f ist nicht algorithmisch berechenbar“. ” 19 Weitere Äquivalenzbeweise findet man auch im Buch von Schöning, z. B. zur Äquivalenz der Rekursivität mit den Konzepten berechenbar mit while-Programmen“ und µ-rekursiv“. ” ” 99 Die prinzipielle Schwierigkeit hierbei ist, dass eine Feststellung über alle Algorithmen gemacht werden soll, das Konzept alle Algorithmen“ aber gar nicht formalisiert ” ist, und tatsächlich zum Beispiel mit neuen Programmiersprachen andauernd neue Arten entstehen, Algorithmen aufzuschreiben. Über alle diese, gleichgültig ob schon ausgedacht oder noch nicht, soll eine Aussage gemacht werden. Die Churchsche These sagt nun, dass es genügt, zu zeigen, dass L nicht rekursiv ist bzw. dass die Funktion f nicht partiell rekursiv ist; dann kann man davon ausgehen, dass kein Berechnungsverfahren, das man algorithmisch nennen würde, f berechnet oder L entscheidet. ⇐“: Alle partiell rekursiven Funktionen sind berechenbar; ist L rekursive Sprache, so ist ” das Wortproblem für L algorithmisch entscheidbar. Diese Aussage ist ziemlich offensichtlich korrekt. Wenn M eine TM ist, so stellt das Programm von M zusammen mit unserer Erklärung der Arbeitsweise von Turingmaschinen aus Abschnitt 1.1.2 eine präzise algorithmische Anweisung dar, wie aus x der Wert fM (x) zu berechnen ist, für beliebige x ∈ HM ; wenn M auf allen Inputs hält, stellt M einen Algorithmus dar, um für jedes x ∈ Σ∗ zu entscheiden, ob x ∈ LM ist oder nicht. Eine kleine Warnung ist aber am Platz: Manchmal weiß man, dass eine Funktion rekursiv ist, d. h. dass eine TM existiert, die die Funktion f berechnet, aber man kann keine solche TM explizit angeben, und man kann auch f (x) nicht ausrechnen. Ein Beispiel: 0, falls es unendlich viele Primzahlzwillinge gibt; f (x) := , für x ∈ {0, 1}∗ . 1, sonst. f ist konstant, also rekursiv ( . . . es gibt eine TM M mit f = fM . . .“), aber es ist ein ” offenes mathematisches Problem, herauszufinden, ob f ≡ 0 oder f ≡ 1, also kennt bis heute auch kein Mensch eine Methode, mit der man zum Beispiel f (ε) bestimmen könnte. 1.8 Universelle Turingmaschinen In unseren bisherigen Überlegungen hatten wir special purpose“-Turingmaschinen be” trachtet: zu jeder Funktion f (bzw. zu jeder Sprache L) gab es eine eigene TM M mit f = fM (bzw. L = LM ). Dies entspricht der Situation in der Frühzeit der Computer, wo ganze Rechner zur Lösung eines Problems gebaut wurden (Maschinen für die Grundrechenarten, Maschinen zur Lösung von Differentialgleichungen, Chiffrier-/Dechiffriermaschinen u. ä.). Von einigen Ausnahmen abgesehen, sind reale Rechner schon seit langem general ” purpose“-Maschinen. Man präsentiert dem Rechner ein Programm P in einer Programmiersprache und Eingabedaten. Nun wird P übersetzt, in ein Maschinenprogramm P 0 oder ein interpretierbares Programm P 0 in einer Zwischensprache. Entweder die Hardware oder ein Interpretierprogramm lässt dann P 0 auf den Daten D ablaufen. Pascal- oder Java-Übersetzer und -Interpreter sind recht komplexe Programme. 100 In diesem Abschnitt werden wir feststellen, dass das Turingmaschinenmodell solche gene” ral purpose“-Maschinen schon umfasst. Es gibt also Turingmaschinen, die beliebige TMProgramme (durch M = (Q, Σ, Γ, B, q0 , F, δ) gegeben) auf beliebigen Eingaben x ∈ Σ∗ ablaufen lassen können. Eigentlich sollten solche TM programmierbar“ heissen; sie hei” ßen jedoch aus historischen Gründen universell“. Im Licht der Churchschen These ist die ” Existenz solcher universeller Turingmaschinen keine Überraschung: das in Abschnitt 1.1 beschriebene Verfahren zur Abarbeitung eines TM-Programms auf einer Eingabe x ist sicher ein Algorithmus; also gibt es nach der Churchschen These auch eine TM, die diesen Algorithmus ausführt. Wir werden aber sehen, dass man solche TM recht leicht direkt beschreiben kann. Eine universelle Turingmaschine erhält ihr Programm“, d. h. die Beschreibung der TM, ” die sie ablaufen lassen soll, als Teil des Eingabewortes. Daher ist es nötig, Turingmaschinen durch einen Text über einem festen Alphabet zu beschreiben. Wir wählen eine einfache binäre Kodierung. 1.8.1 Definition (a) Eine TM M = (Q, Σ, Γ, B, q0 , F, δ) heißt normiert, falls gilt: Q = {0, 1, . . . , s − 1} für ein s ≥ 2, q0 = 0, F = {1}, Σ = {0, 1}, Γ = {0, 1, 2}, B = 2. (Bemerkung: Jede TM M kann durch eine normierte TM M 0 simuliert werden. Zur Reduzierung der Eingabe- und Bandalphabete siehe Abschnitt 1.2.12; die Namen der Zustände q spielen für die Arbeit der TM ohnehin keine Rolle; eine leichte Modifikation erlaubt es, mit einem akzeptierenden Zustand auszukommen.) Wir kodieren L, R, N durch 0, 1, 2. (b) Eine normierte TM M = (Q, Σ, Γ, B, q0 , F, δ) sei gegeben; move1 , . . . , mover seien die Elemente von {(q, a, q 0 , a0 , D) | δ(q, a) = (q 0 , a0 , D)} ⊆ Q × Γ × Q × Γ × {0, 1, 2}, aufsteigend sortiert gemäß (q, a). Wir kodieren jedes 5-Tupel wie folgt als Binärwort: 0 0 h(q, a, q 0 , a0 , D)i := 0q+1 1 0a+1 1 0q +1 1 0a +1 1 0D+1 . Schließlich definieren wir hM i := 111 0s+1 111 hmove1 i 11 hmove2 i 11 · · · 11 hmover i 111. hM i heißt die Binärkodierung von M oder auch Gödelnummer von M . (Der Mathematiker Kurt Gödel hatte eine Kodierung von Formeln der Prädikatenlogik durch Zahlen definiert, daher die Bezeichnung Nummer“. Auch unsere Binärkodierung ” M 7→ hM i ordnet jeder normierten TM M eine Nummer“ zu, nämlich die Zahl ” (hM i)2 .) 101 1.8.2 Beispiel Wir betrachten eine normierte TM M mit Q = {q0 , q1 , q2 , q3 } und der folgenden Turingtafel. Der Deutlichkeit halber schreiben wir qi statt i und B statt 2. (Die TM tut etwas einigermaßen Sinnvolles. Was?) a q 0 1 B q0 (q2 , 1, R) (q0 , 0, R) (q1 , 1, N ) q1 − − − q2 (q2 , 0, R) (q2 , 1, R) (q3 , B, L) − − − q3 Die TM hat sechs Züge, nämlich (q0 , 0, q2 , 1, R), (q0 , 1, q0 , 0, R), (q0 , B, q1 , 1, N ), (q2 , 0, q2 , 0, R), (q2 , 1, q2 , 1, R), (q2 , B, q3 , B, L) mit den Kodierungen 0101000100100 , 01001010100 , 010001001001000 , 00010100010100 , 0001001000100100 , 000100010000100010 . Damit erhalten wir folgenden Binärstring als Binärkodierung für M . (Die Lücken dienen nur der besseren Lesbarkeit.) hM i = 111 00000 111 0101000100100 11 01001010100 11 010001001001000 11 00010100010100 11 0001001000100100 11 000100010000100010 111 . Der numerische Wert dieses Strings, als Binärzahl aufgefasst, liefert die Nummer von M . 1.8.3 Bemerkung ( Syntaxcheck“ für TM-Codes) ” Es ist leicht, einen Binärstring w darauf zu testen, ob er ein Präfix der Form hM i hat, also ob w = hM ix für eine normierte TM M und ein x ∈ {0, 1}∗ . M und x sind dann durch w eindeutig bestimmt. Formal halten wir fest: (a) Die Sprache LTM−Code = {hM i | M normierte TM} ⊆ {0, 1}∗ ist rekursiv. (b) Die Sprache D = {hM ix | M normierte TM, x ∈ {0, 1}∗ } ⊆ {0, 1}∗ ist rekursiv. (c) Die Funktion f : D 3 hM ix 7→ hM i#x ist wohldefiniert und partiell rekursiv. (d) Aus hM i kann (leicht) die Übergangsfunktion δ und damit M rekonstruiert werden. 1.8.4 Definition Eine TM U heißt universell, wenn sie bei Eingabe hM ix das Ein/Ausgabeverhalten von M auf x simuliert, d. h. wenn für alle TM-Codes hM i ∈ LTM−Code und alle x ∈ {0, 1}∗ gilt: 102 (a) U hält auf hM ix ⇔ M hält auf x; akzeptiert akzeptiert (b) U hM ix ⇔ M x; verwirft verwirft (c) fU (hM ix) = fM (x). (d) Auf Eingaben, die nicht die Form hM ix haben, hält U nicht an. 1.8.5 Satz Es gibt eine universelle Turingmaschine U mit drei Bändern. Beweis: Wir beschreiben die Arbeitsweise von U auf einer Eingabe w ∈ {0, 1}∗ : Im Gegensatz zu früheren Simulationen zwischen Turingmaschinen verschiedenen Typs muss hier auch der Zustand der simulierten Turingmaschine auf dem Band von U untergebracht werden, da U TMn mit beliebig großen Zustandsmengen simulieren soll und U nur eine feste Anzahl von Zuständen haben darf. Auf eine Kodierung des Bandalphabets von M kann man verzichten, weil M als normiert vorausgesetzt wird. w Band 1 ... B B <M> a 1 ... a n B B B ... Programm Eingabe x für M Band 2 ... B B B a ... 1 a n B B B B B ... Arbeitsband von M Zustand Band 3 1 0 0 1 B B ... Zustand von M ... B B 1 1 0 explizite Konfiguration von M Bandsymbol U A. Initialisierung: Teste (nach Bem. 1.8.3(b)), ob w die Form hM ix für eine normierte TM M hat. Falls ja, kopiere x = a1 · · · an auf Band 2 und stelle den Kopf auf Band 2 auf a1 , sonst geht U in eine Endlosschleife. Schreibe 1101 (entspricht q0 ) auf Band 3. 103 B. Wiederhole (Simulation eines Schrittes von M ): 1. Schreibe 0a+1 1 rechts neben den String 110q+1 1 auf Band 3, wo a ∈ {0, 1, 2} der für den Bandkopf von M auf Band 2 sichtbare Buchstabe ist. 2. Mit Textsuche (s. Beispiel 1.2.11) suche in hM i auf Band 1 das Teilwort u = 110q+1 10a+1 1, das auf Band 3 steht. Falls u nicht gefunden wird: Falls q = 1, halte und akzeptiere, sonst halte und verwirf. Falls u gefunden wird: 0 0 u ist Präfix eines Teilworts 110q+1 10a+1 10q +1 10a +1 10D+1 11 von hM i auf 0 Band 1. Überschreibe Band 3 mit 110q +1 1, schreibe a0 ∈ {0, 1, 2} auf Band 2, bewege Kopf auf Band 2 in Richtung D ∈ {0, 1, 2} = {L, R, N }. Gehe zu 1. Aufgrund der Konstruktion sieht man, dass U die Aktionen von M auf Eingabe x Schritt für Schritt nachahmt. Daher ergibt sich sofort, dass das E/A-Verhalten von U auf Eingabe hM ix dasselbe ist wie das von M auf x. Die Ausgabe fU (hM ix) = fM (x) ist auf Band 2 abzulesen, wenn und sobald U auf hM ix hält. 1.8.6 Bemerkung (a) Falls M auf x hält, gilt für den Rechenzeit- und Speicherplatzbedarf von U : tU (hM ix) = O(|hM i| · tM (x)) sU (hM ix) = O(|hM i| + sM (x)). und (b) Ist M eine feste normierte TM, die s(n)-platzbeschränkt bzw. t(n)-zeitbeschränkt ist, so ist für x ∈ {0, 1}n tU (hM ix) = O(t(n)) sU (hM ix) = O(s(n)). und (Für festes M wird |hM i| als konstant angesehen, für festes k werden also Faktoren |hM i|k in O(. . .) geschluckt“.) ” (c) Es gibt auch eine universelle TM U 0 mit einem Band, für die die Aussage (b) zutrifft. 104 Beweis: (a), (b) Die Simulation eines Schritts von M benötigt Zeit O(|hM i|). Die Abschätzung für den Platzbedarf ist klar. (c) Die Details des Beweises dieser Behauptung lassen wir weg. Die Idee ist, hM i und die Bandinschrift von M auf separaten Spuren des einen Bandes von U 0 zu halten, und während der Simulation bei Kopfbewegungen von M (durch fortwährendes Verschieben um eine Zelle) stets hM i so mitzuführen, dass der erste Buchstabe von hM i in der Zelle steht, auf der momentan der Kopf von M positioniert ist (vgl. das folgende Bild). Spur 1 Spur 2 Spur 3 Spur 4 B B b a n d i n s c h r i f t + v o n + M B Band von M Kopfposition bei M * 1 1 1 0 0 ... 0 1 1 1 <move1> 11 ... 11 <moves> 1 1 1 1 1 0 ... 0 1 0 0 1 <M> (q,a) Abbildung 1.12: Die vier Bandspuren einer universellen 1-Band-TM 1.9 Unentscheidbare Probleme In diesem Abschnitt lernen wir nichtrekursive Sprachen kennen, also Sprachen, die für unentscheidbare Probleme stehen. Im Zentrum steht dabei die Unentscheidbarkeit des Halteproblems für Turingmaschinen. Aus dieser folgt dann die Unentscheidbarkeit vieler anderer Probleme. 1.9.1 Existenz von unentscheidbaren Sprachen Wir zeigen zunächst, dass es Sprachen gibt, deren Wortproblem unentscheidbar ist. 1.9.1 Bemerkung Es gibt Sprachen L ⊆ {0, 1}∗ mit der Eigenschaft, dass weder L noch L rekursiv aufzählbar sind. 105 Beweis: (Vgl. Abschnitt 0.3.1) Die Menge {hM i | M ist normierte Turingmaschine} ⊆ {0, 1}∗ ist abzählbar. Da zu jeder rekursiv aufzählbaren Menge L ⊆ {0, 1}∗ eine normierte Turingmaschine M mit L = LM gehört, ist auch {L ⊆ {0, 1}∗ | L rekursiv aufzählbar} eine abzählbare Menge; dasselbe gilt dann für {L ⊆ {0, 1}∗ | L rekursiv aufzählbar}. Also ist die Vereinigung der beiden Mengen abzählbar. Andererseits ist {L | L ⊆ {0, 1}∗ }, die Menge aller Sprachen, überabzählbar. Also ist {L | L r.a. oder L r.a.} ⊆ {L | L ⊆ 6 ∗ {0, 1} }. Leider genügt dieses abstrakte Argument nicht, um die Existenz von rekursiv aufzählbaren Mengen, die nicht rekursiv sind, nachzuweisen. (Wieso nicht?) Wie wir sehen werden, sind aber gerade diese Sprachen hochinteressant. 1.9.2 Eine unentscheidbare rekursiv aufzählbare Sprache 1.9.2 Definition (a) Erinnerung: Die Haltemenge für eine TM M = (Q, Σ, Γ, . . .) ist folgende Sprache: HM := {x ∈ Σ∗ | M auf x hält}. (b) Die Haltesprache für TMn ist H := {hM ix | M auf x hält}. Dies ist gleich HU für die universelle Turingmaschine U , siehe Definition 1.8.4. Das Wortproblem für H ist eine Formalisierung des folgenden Entscheidungsproblems: Das (allgemeine) Halteproblem für Turingmaschinen: Input: Eine normierte Turingmaschine M und ein x ∈ {0, 1}∗ . Output: Ja“, falls M auf x hält, Nein“ sonst. ” ” (c) Die Selbstanwendungssprache oder Diagonalsprache ist K := {hM i | M ist normierte TM und M hält auf Eingabe hM i}. Das Wortproblem für K ist eine Formalisierung des folgenden Entscheidungsproblems: Das spezielle Halteproblem für Turingmaschinen: Input: x ∈ {0, 1}∗ . Output: Ja“, falls x Binärkodierung einer normierten TM M ist und diese TM M ” auf x hält, Nein“ sonst. ” 106 1.9.3 Behauptung H und K sind rekursiv aufzählbar. Beweis: H ist rekursiv aufzählbar, weil H = HU ist und nach Lemma 1.1.18 für jede TM M die Haltemenge HM rekursiv aufzählbar ist. — Für K betrachte eine TM MK , die auf Eingabe x folgendes tut: 1. Prüfe ob x = hM i für eine TM M . Falls nein, gehe in eine Endlosschleife. 2. Schreibe xx auf Band 1 und starte die TM U (als Unterprogramm) auf dieser Eingabe. Nun gilt: MK hält auf Eingabe x ⇒ x = hM i für eine TM M und U hält auf xx ⇒ x ∈ K; andererseits: x ∈ K ⇒ x = hM i für eine TM M und M hält auf x ⇒ U hält auf hM ix = xx ⇒ MK hält auf Eingabe x. Also ist HMK = K und K ist rekursiv aufzählbar nach Lemma 1.1.18. 1.9.4 Satz (a) K ist nicht rekursiv. (b) K ist nicht rekursiv aufzählbar. Beweis: (a) folgt sofort aus (b) (vgl. Satz 1.4.4). Wir müssen also nur (b) beweisen. Dazu zeigen wir, dass keine rekursiv aufzählbare Sprache mit K übereinstimmen kann. Sei dazu L ⊆ {0, 1}∗ eine beliebige rekursiv aufzählbare Sprache. Nach Lemma 1.1.18 und der Konstruktion in 1.2.12(b) gibt es eine normierte TM M mit L = HM . Nun gilt folgendes: hM i ∈ HM ⇔ M hält auf hM i ⇔ hM i ∈ K ⇔ hM i 6∈ K. (Def.v.K) Also unterscheiden sich L = HM und K auf dem Element hM i ∈ {0, 1}∗ , und es folgt L 6= K. Der formale Beweis ist damit beendet. Er ist kurz, aber vielleicht etwas unanschaulich. (Das Cantorsche Diagonalverfahren wird hier in ähnlich kompakter Weise wie in Bemerkung 0.3.4 angewendet.) Wir beschreiben dieselbe Überlegung nochmals etwas anschaulicher, so dass die Diagonale“ direkt ins Auge fällt. ” Wir numerieren die Wörter in {0, 1}∗ in der bekannten Weise durch (kanonische Anordnung, vgl. das Ende von Abschnitt 1.4): {x1 , x2 , x3 , x4 , x5 , . . .} = {ε, 0, 1, 00, 01, 10, 11, 000, 001, 010, . . .}. Nun stellen wir uns ein Schema in der Art einer unendlichen Matrix vor, deren Zeilen und Spalten Indizes 1, 2, 3, . . . haben. Der Spalte i ist xi als Eingabewort zugeordnet. Der Zeile j ist eine normierte TM Mj zugeordnet, wie folgt: Wenn xj = hM i für eine normierte TM 107 M , dann ist Mj = M ; wenn xj keine TM-Kodierung ist, dann ist Mj = M∅ für eine feste TM M∅ , die auf keiner Eingabe hält. Offensichtlich gilt für jede normierte TM M , dass es ein j mit M = Mj gibt. Eingaben TMCodes x1 x2 x3 x4 <M 1>=x 1 0 0 1 0 <M 2>=x 2 1 1 0 1 <M 3>=x 3 1 1 0 0 <M 4>=x 4 0 1 1 0 ... {0,1}* x i ... x r 1, falls Mj auf x i hält 0 sonst <M >=x j j xi ? K=H M # <M r> r K?? K In das Schema werden wie folgt Nullen und Einsen eingetragen: der Eintrag in Zeile j, Spalte i ist 1, wenn Mj auf xi hält, und 0 sonst. Wir beobachten: (i) Ist L rekursiv aufzählbar, dann gibt es eine Zeile j mit L = HMj . In dieser Zeile j steht die charakteristische Funktion von L. (ii) In der Diagonale findet sich die charakteristische Funktion von K: xi ∈ K gilt genau dann, wenn der Eintrag in Zeile i, Spalte i gleich 1 ist. (iii) Die charakteristische Funktion von K kann nicht als Zeile r vorkommen, denn der Eintrag am Schnittpunkt einer solchen Zeile r mit der Diagonalen (der natürlich in Spalte r liegt) müsste zu K passen (Zeile r) und gleichzeitig zu K (Diagonale). Aus (i) und (iii) folgern wir, dass K nicht rekursiv aufzählbar ist. 1.9.3 Die Unentscheidbarkeit des Halteproblems Nun können wir beweisen, dass das allgemeine Halteproblem für Turingmaschinen unentscheidbar ist. 1.9.5 Satz (a) H ist nicht rekursiv. (b) H ist nicht rekursiv aufzählbar. 108 Beweis: Wie im vorigen Satz folgt (a) aus (b). Wir beweisen (b) indirekt. Annahme: H ist rekursiv aufzählbar. Dann gibt es eine (normierte) TM M 0 mit H = LM 0 . Betrachte nun eine TM M 00 , die auf Eingabe x folgendes tut: 1. Prüfe, ob x Binärkodierung einer normierten TM M ist. Falls nicht, halte. 2. Andernfalls lasse M 0 auf Eingabe xx laufen. Behauptung: HM 00 = K. Beweis der Behauptung: 1. Fall : x ∈ {0, 1}∗ ist nicht Binärkodierung einer TM M . Dann ist x ∈ K nach der Definition von K und x ∈ HM 00 , nach der Konstruktion von M 00 . 2. Fall : x = hM i für eine TM M . Dann gilt: x ∈ HM 00 ⇔ M 0 hält auf hM ix ⇔ hM ix ∈ H ⇔ M hält nicht auf x ⇔ x 6∈ K ⇔ x ∈ K. Die Behauptung ist damit bewiesen. Sie impliziert nach Lemma 1.1.18, dass K rekursiv aufzählbar ist, im Widerspruch zu Satz 1.9.4. Also ist die Annahme falsch, und H ist nicht rekursiv aufzählbar. Anmerkung: Der Beweis ist indirekt formuliert. Aber er kann in eine Konstruktion von Gegenbeispielen umgemünzt werden. Sei dazu M 0 eine beliebige TM. Wie im vorangegangenen Beweis konstruiert man die TM M 00 . Aus dem Beweis von Satz 1.9.4 sieht man, dass sich K und HM 00 im Verhalten auf dem Wort y = hM 00 i unterscheiden. Es gibt zwei Fälle: 1. Fall : y ∈ K ∧ y ∈ HM 00 . — Dann ist yy ∈ H und M 0 hält auf yy. 2. Fall : y ∈ / K ∧y ∈ / HM 00 . — Dann ist yy ∈ / H und M 0 hält auf yy nicht. Also gilt: yy ∈ H ⇔ M 0 hält auf yy. Das Binärwort yy = hM 00 ihM 00 i ist also ein aus M 0 konstruierbarer Beleg dafür, dass HM 0 6= H ist. Wir merken uns als Hauptergebnis dieses Kapitels die informale Version des eben bewiesenen Satzes: Das Halteproblem für Turingmaschinen ist unentscheidbar. 1.9.4 Reduzierbarkeit und die Reduktionsmethode Wir haben im letzten Beweis unser Wissen K ist nicht rekursiv aufzählbar“ benutzt, ” um dasselbe über H zu beweisen. Nun stellen wir eine allgemeine Methode bereit, um in durchsichtiger Weise nachzuweisen, dass weitere Sprachen nicht rekursiv bzw. nicht rekursiv aufzählbar sind. Hierzu führen wir ein neues, wichtiges Konzept ein: die Reduktion einer Sprache auf eine andere. 109 1.9.6 Definition Seien L ⊆ Σ∗ und L0 ⊆ ∆∗ Sprachen. Wir sagen: L ist reduzierbar auf L0 , in Zeichen L ≤ L0 , wenn es eine (totale) rekursive Funktion f : Σ∗ → ∆∗ gibt mit ∀x ∈ Σ∗ : x ∈ L ⇔ f (x) ∈ L0 . Wenn diese Bedingung erfüllt ist, schreibt man auch L ≤ L0 mittels f“ oder L ≤ L0 via ” ” f“. Man kontrolliert anhand der Definitionen leicht nach, dass L ≤ L0 mittels f ⇔ f −1 (L0 ) = L. Ist L reduzierbar auf L0 , so ist das Wortproblem für L0 mindestens so schwer zu ent” scheiden“ wie das für L. Das ≤“-Symbol stellt also schwierigere Wortprobleme auf die ” größer“-Seite. ” Warnung: (a) Viele Studierende haben mit dem Reduktionsbegriff zunächst Probleme. Der erste Schritt zum richtigen Verständnis ist, sich die Definition genau einzuprägen. Es ist wichtig, dass f eine totale Funktion ist und dass die Aussage x ∈ L ⇔ f (x) ∈ L0 für alle x ∈ Σ∗ gilt, nicht etwa nur für die x ∈ L. Weiter ist es nicht genug, zu verlangen, dass ∀x ∈ Σ∗ : x ∈ L ⇒ f (x) ∈ L0 gilt. (Das sieht man schon daran, dass L0 = ∆∗ diese Forderung für jedes beliebige L erfüllt.) (b) Für die Benutzung des Reduktionsbegriffs genügt es nicht, die intuitive Erklärung mindestens so schwer zu entscheiden wie . . .“ zugrundezulegen. Vielmehr muss man direkt ” mit der Definition arbeiten. Wir notieren einige technische Eigenschaften der ≤-Relation. 1.9.7 Lemma (a) (Reflexivität) L ≤ L gilt für jede Sprache L. (b) (Transitivität) Wenn L ≤ L0 und L0 ≤ L00 , dann gilt auch L ≤ L00 . (c) L ≤ L0 mittels f ⇔ L ≤ L0 mittels f . Beweis: (a) Es gilt L ≤ L mittels der Identitätsfunktion id : x 7→ x. (b) Ist L ≤ L0 mittels f : Σ∗ → ∆∗ und L0 ≤ L00 mittels g : ∆∗ → Φ∗ , so ist L ≤ L00 mittels der Hintereinanderausführung g ◦ f , denn für jedes x ∈ Σ∗ gilt: x ∈ L ⇔ f (x) ∈ L0 ⇔ g(f (x)) ∈ L00 ⇔ (g ◦ f )(x) ∈ L00 . Da f und g rekursiv sind, ist auch g ◦ f rekursiv — wenn f = fM1 und g = fM2 , rechnet man zu Input x zunächst mit M1 das Wort y = f (x) aus und dann mit M2 das Wort g(y) = (g ◦ f )(x). 110 (c) Offensichtlich gilt ∀x ∈ Σ∗ : x ∈ L ⇔ f (x) ∈ L0 genau dann wenn ∀x ∈ Σ∗ : x 6∈ L ⇔ f (x) 6∈ L0 gilt. Daraus folgt die Behauptung. Mit dem Reduktionskonzept werden Berechenbarkeitsaussagen zwischen Sprachen übertragen. 1.9.8 Lemma (a) Wenn L0 rekursiv ist und L ≤ L0 gilt, dann ist L ebenfalls rekursiv. (b) Wenn L0 rekursiv aufzählbar ist und L ≤ L0 gilt, dann ist L ebenfalls rekursiv aufzählbar. Beweis: (a) Es gelte L ≤ L0 mittels f . Weil L0 rekursiv ist, gibt es eine TM M 0 mit L0 = LM 0 , die für jeden Input hält. Weil f rekursiv ist, gibt es eine TM M 00 , die auf allen Eingaben hält und f = fM 00 erfüllt. Wir konstruieren eine neue TM M , die auf Eingabe x wie folgt rechnet: Lasse M 00 auf x laufen; das Ergebnis sei y ∈ ∆∗ . Nun lasse M 0 auf Eingabe y laufen. Wenn M 0 akzeptierend hält, hält auch M akzeptierend; wenn M 0 verwerfend hält, verwirft auch M . Offenbar gilt für jedes x: M akzeptiert x ⇔ M 0 akzeptiert y = f (x) ⇔ f (x) ∈ LM 0 = L0 ⇔ x ∈ L. (Die letzte Äquivalenz gilt nach der Definition von ≤“.) Also ist LM = L. Weiter ” ist klar, dass M auf allen Eingaben hält. (b) Die Konstruktion und der Beweis ist identisch zu Teil (a). Nur wird nicht verlangt, dass M 0 auf allen Eingaben hält; dann hält natürlich auch M nicht unbedingt auf allen Eingaben. Wir werden Lemma 1.9.8 praktisch nie benutzen, um zu beweisen, dass eine Sprache rekursiv oder rekursiv aufzählbar ist. Vielmehr benutzen wir die Kontraposition des Lemmas, um zu zeigen, dass Sprachen nicht rekursiv bzw. rekursiv aufzählbar sind. 1.9.9 Korollar (a) Wenn L nicht rekursiv ist und L ≤ L0 gilt, dann ist auch L0 nicht rekursiv. (b) Wenn L nicht rekursiv aufzählbar ist und L ≤ L0 gilt, dann ist auch L0 nicht rekursiv aufzählbar. 111 Rezept: Um zu zeigen, dass L0 nicht rekursiv [nicht rekursiv aufzählbar] ist, wähle eine passende als nicht rekursiv [nicht rekursiv aufzählbar] bekannte Sprache L und definiere eine Funktion f , die L ≤ L0 mittels f erfüllt. Wir benutzen das Rezept zunächst mit K und K an der Stelle von L, um mit der Reduktionsmethode nochmals zu zeigen, dass H nicht rekursiv und H nicht rekursiv aufzählbar ist. Im weiteren Verlauf benutzen wir vorzugsweise H bzw. H an der Stelle von L. Je mehr Sprachen als nicht rekursiv bzw. nicht rekursiv aufzählbar erkannt sind, desto mehr Möglichkeiten hat man bei der Wahl von L. 1.9.10 Beispiel Wir wollen zeigen, dass K ≤ H gilt. Dazu definieren wir eine Funktion f : {0, 1}∗ → {0, 1}∗ durch xx, falls x = hM i für eine TM M f (x) := ε, für alle anderen x ∈ {0, 1}∗ . Nach Bemerkung 1.8.3(a) ist f total rekursiv. Weiter gilt für jedes x ∈ {0, 1}∗ : x ∈ K ⇒ es gibt eine TM M mit x = hM i und M hält auf x ⇒ f (x) = xx ∈ H; weil ε ∈ / H ist, gilt umgekehrt f (x) ∈ H ⇒ f (x) = xx, es gibt eine TM M mit x = hM i und M hält auf x ⇒ x ∈ K. Das bedeutet, dass K ≤ H mittels f gilt. — Mit Lemma 1.9.7(c) folgt, dass auch K ≤ H gilt. Mit Korollar 1.9.9 folgern wir, dass H nicht rekursiv ist und dass H nicht rekursiv aufzählbar ist. Das folgende Beispiel für die Anwendung der Reduktionsmethode ist exemplarisch für viele ähnliche Konstruktionen. Zudem zeigen wir, wie man vorgeht, wenn die rekursive Aufzählbarkeit von Teilmengen von {hM i | M normierte TM} zu beweisen ist. 1.9.11 Beispiel repräsentiert: Es sei Hε die Sprache, die das Halteproblem bei leerem Eingabeband Hε := {hM i | M hält bei Eingabe ε}. (Achtung: Hε ist eine unendliche Menge von Gödelnummern und etwas ganz anderes als Lε = {ε}, eine Menge mit dem einzigen Element ε, das keine Gödelnummer ist.) Wir zeigen: (i) Hε ist rekursiv aufzählbar. 112 (ii) H ε ist nicht rekursiv aufzählbar. (Daraus folgt: Hε ist nicht rekursiv.) Zu (i): (Konstruktion.) Nach der Definition von H gilt hM i ∈ Hε ⇔ hM i = hM iε ∈ H = HU . Dies benutzen wir, um eine TM Mε mit HMε = Hε zu konstruieren. Mε arbeitet auf Eingabe x ∈ {0, 1}∗ folgendermaßen: 1. Teste, ob x eine TM-Kodierung hM i ist. Falls nein, gehe in eine Endlosschleife. 2. Falls ja, starte U als Unterprogramm auf Eingabe x = hM i. Nach dieser Beschreibung haben wir: Mε hält auf x ⇒ x = hM i für eine TM M und U hält auf hM i = hM iε ⇒ M hält auf ε ⇒ x ∈ Hε . Umgekehrt gilt: x ∈ Hε ⇒ x = hM i für eine TM M und M hält auf ε ⇒ U hält auf hM iε = x ⇒ Mε hält auf x. Zu (ii): Wir wollen das Rezept nach Korollar 1.9.9 mit L = H benutzen, also H ≤ H ε zeigen, oder äquivalent H ≤ Hε . Wir brauchen also eine rekursive Funktion f : {0, 1}∗ → {0, 1}∗ , die folgende Eigenschaft hat: (∗) ∀y ∈ {0, 1}∗ : y ∈ H ⇔ f (y) ∈ Hε . Einzig interessant sind Werte f (y), die TM-Kodierungen sind. Wir müssen also zu jedem y eine TM My und ihre Kodierung f (y) = hMy i angeben, so dass ∀y ∈ {0, 1}∗ : y ∈ H ⇔ f (y) = hMy i ∈ Hε oder y ∈ H ⇔ My hält auf Eingabe ε. Wir beschreiben, wie sich My verhält, wenn auf dem Band die Eingabe x steht: (∗ Ignoriere den Input x völlig ∗) 1. Überschreibe den Inhalt x des Bandes mit y (∗ dazu ist y in der Steuereinheit von My gespeichert; die Abhängigkeit von My von y ist also echt ∗) 2. Starte die universelle TM U mit der Bandinschrift y als Eingabe. Wir müssen zwei Eigenschaften überprüfen: 113 (a) f mit f (y) = hMy i für y ∈ {0, 1}∗ ist rekursiv. Dazu überlegen wir, dass die Konstruktion von My aus y, auch im Formalismus der Gödelnummern, bestimmt algorithmisch ausführbar ist; nach der Churchschen These ist f rekursiv. (Es ist instruktiv, sich einen Algorithmus zur Berechnung von hMy i bis zu einem gewissen Detailliertheitsgrad auszudenken. Das Programm der TM My besteht aus einem Vorspann, in dem die Eingabe x gelöscht wird, dann |y| Schritten zum Schreiben von y und |y| Schritten, um den Kopf auf die Startposition zurückzufahren, und aus dem Programm von U . Nur der zweite Teil ist, in einfacher Weise, von y abhängig.) (b) Für y ∈ {0, 1}∗ gilt, nach der Definition von f (y) = hMy i: y ∈ H ⇒ U hält auf y ⇒ My hält auf allen x ⇒ My hält auf ε ⇒ f (y) = hMy i ∈ Hε , und f (y) = hMy i ∈ Hε ⇒ My hält auf ε ⇒ U hält auf y ⇒ y ∈ H. Damit gilt H ≤ Hε mittels f , wie gewünscht. 1.9.12 Bemerkung Wir bemerken, dass die Funktion f aus dem letzten Beispiel für viele andere Sprachen, die aus TM-Kodierungen bestehen, als Reduktionsfunktion dienen kann. Das liegt an der folgenden (offensichtlichen) Eigenschaft von f : für alle y ∈ {0, 1}∗ gilt y ∈ H ⇒ HMy = {0, 1}∗ ; y∈ / H ⇒ HMy = ∅. Beispielsweise sei w ∈ {0, 1}∗ ein beliebiges, festes Wort. Mit Hw bezeichnen wir die Menge der Codes von Turingmaschinen M mit w ∈ HM : Hw := {hM i | M hält auf w}. Ähnlich wie in Teil (i) des vorangegangenen Beispiels zeigt man, dass Hw rekursiv aufzählbar ist (Übung). Mit derselben Argumentation wie in Teil (ii) des Beispiels sieht man (Details: Übung), dass f die folgende Eigenschaft hat: ∀y ∈ {0, 1}∗ : y ∈ H ⇔ f (y) = hMy i ∈ Hw . Daher ist H ≤ Hw , woraus folgt, dass Hw nicht rekursiv und H w nicht rekursiv aufzählbar ist. Es ist also gut, wenn man zunächst einmal mindestens diese eine Reduktionsfunktion in seinem Werkzeugkasten hat. 114 Am Ende dieses Abschnitts wollen wir noch diskutieren, was die bisherigen Resultate mit den Programmen zu tun hat, mit denen man als Informatiker(in) täglich zu tun hat. Als Beispiel-Programmiersprache nehmen wir Pascal; dieselben Überlegungen lassen sich aber für alle anderen Programmiersprachen anstellen. Wir definieren eine Sprache, die das Halteproblem für Pascal-Programme formalisiert. Unsere Programme lesen ihre Eingabe aus einer Eingabedatei, die ASCII-Zeichen enthält. Ascii sei das Alphabet der 128 ASCII-Zeichen. Man erinnert sich, dass jedes PascalProgramm mit end z .“ endet, wobei z eine beliebige Folge von Leerzeichen und Zei” lenvorschüben ist, und dass diese Kombination nirgendwo anders im Programm vorkommen kann. Daher ist bei einer Verkettung Px für ein Pascal-Programm P und ein Wort x ∈ Ascii∗ die Trennstelle zwischen P und x eindeutig zu identifizieren. Die Sprache LPascal := {P ∈ Ascii∗ | P ist syntaktisch korrektes Pascal-Programm} ist rekursiv. Sie ist zwar nicht kontextfrei, aber jeder Pascal-Compiler enthält einen Teil, den Parser, der die Korrektheitsprüfung durchführt. Nun setzen wir LPascal−Halt := {Px | P ∈ LPascal , x ∈ Ascii∗ , P hält auf Input x}. Unser Ziel ist es, zu zeigen, dass die Sprache LPascal−Halt unentscheidbar ist, dass es also keinen Algorithmus gibt, der zu einem Pascal-Programm P mit Input x feststellt, ob P auf x anhält. Das heißt insbesondere, dass es heute und in Zukunft keinen Formalismus geben kann, in dem ein Tool formulierbar ist, das zuverlässig die einfachste semantische Frage über Pascal-Programme beantwortet, die man sich vorstellen kann: hält P mit Input x oder nicht? Man erinnert sich, dass wir dieselbe Frage in der Einleitung bezüglich Pascal-Programmen als Prüfverfahren schon behandelt haben. Mit der Churchschen These kommen wir zu einer viel stärkeren, allgemeinen Aussage über alle algorithmischen Verfahren. Weiterhin können wir die Unentscheidbarkeit von LPascal−Halt nun mathematisch exakt formulieren. 1.9.13 Satz LPascal−Halt ist nicht rekursiv. Beweis: In Abschnitt 1.5.1 haben wir gesehen, wie man beliebige Turingmaschinen auf Registermaschinen simulieren kann. Mit ganz ähnlichen Methoden sieht man, dass es zu jeder TM M mit Inputalphabet {0, 1} ein Pascal-Programm PM gibt, so dass die Ausführung von PM mit einer Eingabedatei, die das binäre Wort x enthält, genau dann hält wenn M auf Eingabe x hält. (Ein Band wird als dynamisches, also längenveränderliches Array oder als doppelt verkettete Liste dargestellt. Die Übergangsfunktion der TM wird in die Struktur von PM übersetzt. Natürlich muss man die übliche Idealisierung vornehmen: der Länge des Arrays bzw. der Liste, die das Band darstellt, sind keine Grenzen gesetzt.) Wir verwenden diese Konstruktion nur für eine einzige TM, nämlich die universelle TM U , und stellen fest, dass es ein Pascal-Programm PU ∈ Ascii∗ gibt, das auf Input w ∈ {0, 1}∗ ⊆ Ascii∗ genau dann hält wenn U auf w hält, d. h. genau dann wenn w ∈ H ist. Das heißt: w ∈ H ⇔ PU w ∈ LPascal−Halt . 115 Wenn wir also definieren: f : {0, 1}∗ → Ascii∗ , f (w) = PU w , dann gilt H ≤ LPascal−Halt mittels f , und der Satz ist bewiesen. Man sieht an diesem Beweis, dass dieselbe Unentscheidbarkeitsaussage für alle Programmiersprachen gilt, in denen man einen Simulator für die universelle Turingmaschine U schreiben kann — und das geht in jeder vernünftigen allgemeinen Programmiersprache. Dass Simulatoren für Turingmaschinen nicht unbedingt die Programme sind, die man jeden Tag schreibt, ändert nichts an der Folgerung, dass es ein Tool zum Überprüfen des Haltens eines beliebigen Programms nicht geben kann. Die Konsequenz ist, dass der Programmdesigner mit seinem Entwurf die Verantwortung dafür trägt, dass keine nichthaltenden Berechnungen auftreten. Ist denn die Unentscheidbarkeit des Halteproblems wirklich ein so großes Hindernis? Niemand will wirklich Programme schreiben, die für manche Inputs nicht anhalten. Natürlich hindert einen die Unentscheidbarkeit von LPascal−Halt nicht daran, nur Programme zu schreiben, die für beliebige Eingaben stets anhalten, und für jedes Programm einen Terminierungsbeweis zu führen. Wir werden aber noch sehen, dass es keinen Algorithmus gibt, der für jedes Programm, das auf allen Eingaben terminiert, einen solchen Terminierungsbeweis liefert. Hier ist also der findige Programmierer gefragt, der für jedes Programm einen spezifischen Terminierungsbeweis führt. — Diese und andere Beobachtungen ergeben sich im nächsten Abschnitt als Ergebnis weiterer Reduktionen. 1.10 Unentscheidbarkeit semantischer Fragen In diesem Abschnitt stellen wir uns die Frage, inwieweit man einem als Text gegebenen (Pascal-)Programm semantische (das heißt sich auf das Ein-/Ausgabeverhalten beziehende) Eigenschaften ansehen kann. Zum Beispiel: (i) Hält ein gegebenes Programm P auf allen Eingaben? (Oder: Hält P auf allen Eingaben aus L0 ? [Dabei ist L0 ⊆ Ascii∗ beliebig.]) (ii) Hält ein gegebenes Programm P auf wenigstens einer Eingabe? (Oder: Hält P auf wenigstens 20 Eingaben? Oder: Hält P auf unendlich vielen Eingaben?) (iii) Berechnen zwei gegebene Programme P1 und P2 dieselbe Funktion? (Oder: Berechnet ein gegebenes Programm P die Funktion g? [Dabei ist g eine beliebige partiell rekursive Funktion.]) 116 (iv) Gegeben sei ein Programm P, das als Eingabe eine natürliche Zahl n erhält, garantiert hält und die Ausgabe fP (n) schreibt. Gilt fP (1) < fP (2) < · · · ? (v) Gegeben sei ein Programm P, das als Eingabe eine natürliche Zahl n erhält, garantiert hält und die Ausgabe fP (n) ∈ {0, 1} schreibt. Gibt es ein n ∈ N mit fP (n) = 1? 1.10.1 Der Satz von Rice Wir werden in diesem Abschnitt eine einheitliche Beweismethode bereitstellen, mit der man für viele Fragen der eben genannten Art die Unentscheidbarkeit nachweisen kann. Wir formulieren unsere Ergebnisse zunächst in der TM-Terminologie. Die Anwendung auf Pascal-Programme wird dann an Beispielen diskutiert. Wir geben Sprachen an, deren Wortprobleme einigen der eben betrachteten semantischen Fragen entsprechen. hM i steht immer für die Kodierung einer normierten TM. 1.10.1 Beispiel (i) {hM i | HM = {0, 1}∗ }. (Oder: {hM i | L0 ⊆ HM }.) (ii) {hM i | |HM | ≥ 1}. (Oder: {hM i | |HM | ≥ 20}. Oder: {hM i | |HM | = ∞}.) (iii) {hM1 ihM2 i | fM1 = fM2 }. (Oder: {hM i | fM = g}.) (iv) {hM i | HM = {bin(n) | n ∈ N} und ∀n ∈ N : (fM (bin(n)))2 < (fM (bin(n + 1)))2 }. (v) {hM i | HM = {0, 1}∗ und ∃x ∈ {0, 1}∗ : fM (x) = 1}. Anstatt nun die Methoden aus Abschnitt 1.9 auf jede dieser Sprachen anzuwenden, stellen wir einen allgemeinen Satz bereit, aus dem leicht folgt, dass alle diese Mengen nicht rekursiv sind. Allen betrachteten Mengen ist folgendes gemeinsam: Es sind Mengen von TM-Kodierungen hM i (oder im Fall (iii) von Paaren von TM-Kodierungen), wobei an hM i nur Bedingungen gestellt werden, die sich auf die Menge HM oder die Funktion fM beziehen — semantische Fragen eben. (Es kommt z. B. nicht die Anzahl der Schritte, die M auf einer Eingabe macht, oder die Anzahl der Zustände von M oder die Anzahl der Bits im Wort hM i vor.) Wir charakterisieren solche Bedingungen wie folgt:20 1.10.2 Definition (a) Eine Eigenschaft von rekursiv aufzählbaren Sprachen über {0, 1} ist eine Teilmenge E von {L ⊆ {0, 1}∗ | L ist rekursiv aufzählbar}. (b) Eine Eigenschaft von partiell rekursiven Funktionen über {0, 1} ist eine Teilmenge F von {f : {0, 1}∗ → {0, 1}∗ | f ist partiell rekursiv}. 20 Hier wird ein in der Mathematik üblicher Trick benutzt: Eine Eigenschaft wird mit der Menge der Objekte identifiziert, die die Eigenschaft haben. 117 Hinter unseren Beispielen stecken folgende Eigenschaften: 1.10.3 Beispiel (i) E = {Σ∗ }. (ii) E = {L | L rekursiv aufzählbar und |L| ≥ 1}. (Oder: E = {L | L rekursiv aufzählbar und |L| ≥ 20}. Oder: E = {L | L rekursiv aufzählbar und |L| = ∞} ). (iii) F = {g}. (iv) F = {f | f ist partiell rekursiv und f ist für alle bin(n), n ∈ N, definiert und (f (bin(n)))2 < (f (bin(n + 1)))2 für alle n ∈ N}. (v) F = {f | f : {0, 1}∗ → {0, 1} ist totale rekursive Funktion und ∃x ∈ {0, 1}∗ : f (x) = 1}. Der Satz von Rice besagt, dass für kein E und kein F anhand von hM i mit einer TM entschieden werden kann, ob HM Eigenschaft E bzw. F hat, außer in völlig trivialen Fällen. Alle oben angegebenen Eigenschaften von Sprachen und Funktionen werden mit diesem Satz erfasst. Mit der Churchschen These interpretiert man ihn so, dass es keine algorithmische Methode gibt, eine TM M anhand ihrer Binärkodierung hM i darauf zu testen, ob HM die Eigenschaft E hat oder nicht; analog für die Funktion fM und F. Von TMn überträgt sich diese Aussage auf alle anderen Programmiersprachen: nichttriviale semantische Eigenschaften von Programmen sind unentscheidbar. 1.10.4 Satz (Satz von Rice) (a) Es sei E eine nichttriviale Eigenschaft von rekursiv aufzählbaren Sprachen, d. h. ∅ 6= E ( {L ⊆ {0, 1}∗ | L ist rekursiv aufzählbar}. Dann gilt: LE := {hM i | HM ∈ E} ist nicht rekursiv. (b) Es sei F eine nichttriviale Eigenschaft von partiell rekursiven Funktionen, d. h. ∅ 6= F ( {f : {0, 1}∗ → {0, 1}∗ | f ist partiell rekursiv}. Dann gilt: LF := {hM i | fM ∈ F} ist nicht rekursiv. Beweis: (a) Wir nehmen zunächst an, dass ∅ ∈ / E. Weil E nichttrivial ist, gibt es eine rekursiv aufzählbare Sprache L1 ∈ E, L1 6= ∅. 21 21 Im folgenden benutzen wir ausschließlich, dass ∅ ∈ / E und L1 ∈ E. Wie E sonst aussieht, ist irrelevant. 118 Wir reduzieren H auf LE . (Dann kann LE nicht rekursiv sein, nach Korollar 1.9.9.) Wir benötigen also eine Reduktionsfunktion g, die ein beliebiges Wort y ∈ {0, 1}∗ in eine TM-Kodierung g(y) = hMy i transformiert, so dass für alle y gilt y ∈ H ⇔ g(y) = hMy i ∈ LE ; d. h. y ∈ H ⇔ HMy ∈ E. Weil ∅ ∈ / E und L1 ∈ E, genügt es, folgendes zu erreichen: y ∈ H ⇒ HMy = L1 ( ∈ E); (∗) y∈ / H ⇒ HMy = ∅ ( ∈ / E). Im Stil von Beispiel 1.9.11 beschreiben wir das Verhalten von My . Wir tun dabei so, als hätte My zwei Bänder. Bevor man hMy i bilden kann, muss man sich noch My in eine normierte 1-Band-TM umgebaut denken. Wir benutzen eine beliebige feste TM M1 mit HM1 = L1 . — Die TM My tut folgendes, auf Eingabe x: 1. Schreibe y auf Band 2; (∗ Dazu ist y in der Steuereinheit von My gespeichert. ∗) 2. Starte U auf der Inschrift y von Band 2. (∗ falls y ∈ / H, hält dies nicht; falls y ∈ H, wird 3. erreicht. ∗) 3. Starte M1 auf der Eingabe x (auf Band 1). (∗ Diese Berechnung hält genau dann, wenn x ∈ L1 . ∗) Es ist klar, dass man aus y die TM My und auch g(y) = hMy i algorithmisch konstruieren kann, dass also g rekursiv ist (Churchsche These). Weiter gilt, nach der Beschreibung von My : y∈ / H ⇒ My hält für keine Eingabe y ∈ H ⇒ My hält genau für Eingaben x ∈ HM1 = L1 . Damit ist (∗) erfüllt; es folgt, dass H ≤ LE mittels g, und damit folgt, dass LE nicht rekursiv ist. Schließlich ist der Fall zu betrachten, dass ∅ ∈ E. Dann wenden wir den obigen Beweis auf die ebenfalls nichttriviale Eigenschaft E = {L | L rekursiv aufzählbar, L ∈ / E} an und erhalten, dass LE nicht rekursiv ist. Weil LE = LE , ist LE ebenfalls nicht rekursiv. (b) Der Beweis verläuft genauso wie der von Teil (a). Man betrachtet zunächst den Fall, dass die leere partielle Funktion f∅ , berechnet von TMn, die auf keiner Eingabe halten, 119 nicht in F liegt. Weil F nichttrivial ist, gibt es eine partiell rekursive Funktion f1 in F. Wir wählen eine TM M1 mit f1 = fM1 . Die Reduktionsfunktion g wird wörtlich so definiert wie in Teil 1. Man erhält: y ∈ H ⇒ fMy = f1 ( ∈ F); y∈ / H ⇒ fMy = f∅ ( ∈ / F). Daraus folgt wiederum, dass H ≤ LF mittels g, also dass LF nicht rekursiv ist. Der Fall f∅ ∈ F wird ebenso wie in (a) durch Betrachten der Komplementeigenschaft behandelt. 1.10.5 Beispiel Alle in Beispiel 1.10.1 angegebenen Mengen von TM-Kodierungen sind nichtrekursiv; die zugehörigen Wortprobleme sind unentscheidbar. Dazu muss man nur beobachten, dass die in Beispiel 1.10.3 angegebenen Eigenschaften alle nichttrivial sind. 1.10.2 Semantische Fragen über Programme Was bedeutet der Satz von Rice für den Informatiker oder die Informatikerin, der/die gerne die Korrektheit oder andere wichtige semantische Eigenschaften von Programmen in seiner/ihrer Lieblingsprogrammiersprache testen möchte, und das möglichst mit einem kommerziell verfügbaren Tool? Er bedeutet schlechte Aussichten: Man kann ein Programm P einer Programmiersprache nicht automatisch darauf testen, (i) ob P auf allen Eingaben hält; (ii) ob P auf mindestens einer Eingabe hält (oder: auf mindestens 20 Eingaben hält; oder: auf unendlich vielen Eingaben hält); (iii) ob P eine vorgegebene (partiell rekursive) Funktion g berechnet; (iv) ob für die von P berechnete Zahlfunktion f : N → N gilt, dass f total ist und f (1) < f (2) < · · · gilt; (v) ob P auf allen Eingaben hält und ein bestimmtes Unterprogramm C, das im Text von P vorkommt, jemals aufgerufen wird (oder: jemals ein Zeichen der Eingabe gelesen wird; oder: die Eingabe komplett gelesen wird; oder: jemals ein Ausgabezeichen erzeugt wird). Die im Beweis des Satzes von Rice verwendete Technik zusammen mit der Beobachtung, dass man in Programmen jeder Programmiersprache die universelle TM U simulieren 120 kann, liefert dies in ziemlich schematischer Weise. Für eine beliebige Pascal-Prozedur B betrachten wir Pascal-Programme einer speziellen Bauart: Jedem Wort y ∈ {0, 1}∗ wird ein Programm Py zugeordnet, das bei Eingabe x ∈ Ascii∗ folgendes tut: 1. Starte eine Simulation der universellen TM U auf y; 2. wenn und sobald die Berechnung in 1. hält: führe B aus; 3. halte an. Py führt B auf Eingabe x aus, wenn y ∈ H ist. Wenn y ∈ / H, hält U auf y nie an und damit auch Py auf x nicht; die Prozedur B wird nicht ausgeführt. Damit haben wir: y ∈ H ⇒ ∀x ∈ Ascii∗ : Bei Aufruf von Py auf x wird B ausgeführt; y∈ / H ⇒ ∀x ∈ Ascii∗ : Bei Aufruf von Py auf x wird B nicht ausgeführt. Um in den eben genannten Beispielen die Nichtrekursivität der Menge der entsprechenden Pascal-Programme zu erhalten, müssen wir nur B passend wählen: (i) B tut nichts. (ii) B tut nichts. (iii) B berechnet g(x) und gibt dies aus. (iv) P erhält als Eingabe eine Zahl n. B gibt die Eingabe n aus. (v) B besteht aus dem Aufruf von C (oder: B liest alle Zeichen der Eingabe ein; oder: B schreibt ein Ausgabezeichen). Für manche(n) Leser(in) ist diese Konstruktion vielleicht unbefriedigend, weil man in der Reduktion direkt das Halteproblem einbaut, und explizit Pascal-Programme benutzt, die nicht halten. Vielleicht kann man semantische Eigenschaften von Programmen wenigstens dann algorithmisch testen, wenn man sich auf Programme konzentriert, die garantiert anhalten? Wir stellen im folgenden Abschnitt und in einer Übungsaufgabe fest, dass auch dies leider nicht zutrifft. 1.10.3 Unmöglichkeit von Zertifikaten für Programme Es sei E bzw. F eine Eigenschaft wie im Abschnitt 1.10.1. Nach dem Satz von Rice kann man nicht algorithmisch entscheiden, ob HM ∈ E bzw. fM ∈ F, man kann also nicht mittels eines Algorithmus gute“ TM-Codes akzeptieren und schlechte“ ablehnen. Eine ” ” bescheidenere Frage ist es, ob es für E bzw. F ein algorithmisches Zertifizierungsverfah” ren“ gibt. Ein solches Verfahren erhält eine TM-Kodierung hM i als Eingabe und liefert o.k.“, falls HM ∈ E bzw. fM ∈ F, und irgendeine andere oder gar keine Ausgabe sonst. ” 121 (Mit einem solchen Verfahren für Pascal-Programme könnte man zumindest positiv nachweisen, dass ein Programm P auf allen Eingaben hält oder eine bestimmte Funktion g berechnet.) Formal ist ein solches Zertifizierungsverfahren eine partiell rekursive Funktion h : D → {0, 1}, D ⊆ {hM i | M TM}, mit 1, falls HM ∈ E bzw. fM ∈ F h(hM i) ist 6= 1 (evtl. auch undefiniert), sonst. Nun kann man sich leicht klarmachen (!), dass E bzw. F ein solches Zertifizierungsverfahren h genau dann besitzt, wenn LE bzw. LF rekursiv aufzählbar ist. Für manche der in Abschnitt 1.10.1 betrachteten Eigenschaften E bzw. F ist LE bzw. LF tatsächlich rekursiv aufzählbar (z. B. für E = {L | L r. a., L 6= ∅} oder F = {f | f partiell rekursiv, f (x) = 0 für alle x mit |x| ≤ 3}). Es gibt aber Eigenschaften E, bei denen weder LE noch LE rekursiv aufzählbar sind. Das heißt, dass weder die guten“ noch die schlechten“ TM-Programme zertifizierbar ” ” sind. Wir betrachten ein typisches Beispiel: die Menge der Codes von TMn, die auf allen Eingaben halten, hat kein Zertifizierungsverfahren, ebensowenig wie die Menge der Codes von TMn, die nicht auf allen Eingaben halten. 1.10.6 Satz Für die Sprache L = {hM i | HM = Σ∗ } gilt, dass weder L noch L rekursiv aufzählbar ist. Beweis: Nach dem Rezept aus Abschnitt 1.9.4 sollten wir H ≤ L und H ≤ L beweisen. Nach Lemma 1.9.7 läuft das darauf hinaus, H ≤ L und H ≤ L zu beweisen. H ≤ L“: Hier können wir die Reduktionsfunktion f : y 7→ hMy i aus Beispiel 1.9.11 ” benutzen. Diese hat, wie in Bemerkung 1.9.12 beobachtet, die Eigenschaft ∀y ∈ {0, 1}∗ : y ∈ H ⇒ HMy = {0, 1}∗ ; y∈ / H ⇒ HMy = ∅ und erfüllt damit ∀y ∈ {0, 1}∗ : y ∈ H ⇔ f (y) = hMy i ∈ L. H ≤ L“: Wir konstruieren eine Reduktionsfunktion g : y 7→ hMy0 i mit folgender Eigen” schaft: ∀y ∈ {0, 1}∗ : y ∈ H ⇒ HMy0 ist endlich; y∈ / H ⇒ HMy0 = {0, 1}∗ . Hierzu benutzen wir einen für Reduktionen neuen Trick: Uhr-kontrollierte Berechnungen, siehe Abschnitt 1.4. Zu y ∈ {0, 1}∗ betrachte die TM My0 , die auf Eingabe x folgendes tut: 122 1. Schreibe y auf Band 2; (∗ Dazu ist y in der Steuereinheit von My0 gespeichert. ∗) 2. Lasse U auf y für |x| Schritte laufen. (∗ Dies hält immer. ∗) 3. Falls die Berechnung in 2. erfolgreich beendet wurde, gehe in eine Endlosschleife; sonst halte an. (∗ Diese Berechnung hält genau dann, wenn |x| < tU (y). ∗) Man kann My0 und hMy0 i leicht aus y bestimmen; nach der Churchschen These ist g : {0, 1}∗ → {hM i | M TM}, g(y) = hMy0 i, rekursiv. Weiter gilt: ∀y ∈ {0, 1}∗ : y ∈ H ⇒ HMy0 = { x | |x| < tU (y)}; y∈ / H ⇒ HMy0 = {0, 1}∗ . Damit gilt für alle y: y ∈ H ⇔ HMy0 = {0, 1}∗ ⇔ g(y) ∈ L , wie gewünscht. Mit der Technik aus Abschnitt 1.10.2 kann man diesen Beweis so umbauen, dass sich ergibt, dass die Menge der Pascal-Programme, die auf allen Eingaben halten, nicht rekursiv aufzählbar ist, also dass die Eigenschaft hält auf allen Eingaben“ von Pascal-Programmen ” nicht zertifizierbar ist. Mit derselben Technik wie im letzten Beweis kann man zeigen, dass man anhand von TM-Kodierungen nicht auf den Verlauf der berechneten Funktionen schließen kann, sogar wenn man sich auf totale Funktionen beschränkt. Das heißt dann, dass man es mit unentscheidbaren Semantikfragen auch dann zu tun bekommen kann, wenn man zuverlässig nur Programme schreibt, die immer halten. Wir betrachten zwei Eigenschaften von partiell rekursiven Funktionen: F0 := {f | ∀x ∈ {0, 1}∗ : f (x) = 0}; F1 := {f | ∀x ∈ {0, 1}∗ : f (x) ∈ {0, 1} ∧ ∃x ∈ {0, 1}∗ : f (x) = 1}. 1.10.7 Satz Es gibt keine partiell rekursive Funktion d : D → {0, 1}∗ für ein D ⊆ {0, 1}∗ , so dass für alle normierten TMn M gilt: (i) fM ∈ F0 ∪ F1 ⇒ hM i ∈ D; (ii) fM ∈ F0 ⇒ d(hM i) = 0; 123 (iii) fM ∈ F1 ⇒ d(hM i) = 1. (Das Verhalten von d auf Eingaben, die nicht zu {hM i | fM ∈ F0 ∪ F1 } gehören, ist völlig beliebig.) Beweis: Indirekt. Annahme: Eine Funktion d wie beschrieben existiert. Wir benutzen nun eine Reduktion ganz ähnlich der im letzten Beweis, mit dem Unterschied, dass alle Turingmaschinen My totale 0-1-wertige Funktionen berechnen, so dass hMy i im Definitionsbereich von d liegt. Zu y ∈ {0, 1}∗ betrachte die TM My , die auf Eingabe x folgendes tut: 1. Schreibe y auf Band 2; 2. Lasse U auf y für |x| Schritte laufen. 3. Falls die Berechnung in 2. erfolgreich beendet wurde, halte mit Ausgabe 1, sonst halte mit Ausgabe 0. (∗ Diese Berechnung liefert 1 genau dann, wenn tU (y) ≤ |x|. ∗) Es ist wieder klar, dass die Funktion h : y 7→ hMy i rekursiv ist. Weiter gilt, dass fMy für jedes y eine totale 0-1-wertige Funktion ist, und: ∀y ∈ {0, 1}∗ : y∈ / H ⇒ fMy ≡ 0, d. h. fMy ∈ F0 ; y ∈ H ⇒ fMy 6≡ 0, d. h. fMy ∈ F1 . Daraus folgt: Die Abbildung d ◦ h : y 7→ d(hMy i) ist total rekursiv und erfüllt y ∈ H ⇔ d ◦ h(y) = 1. Das heißt, dass d ◦ h die charakteristische Funktion von H ist, ein Widerspruch zur Nichtrekursivität von H. In einer Übungsaufgabe wird gezeigt, dass man in derselben Weise Unentscheidbarkeitsresultate für Pascal-Programme erhalten kann, wobei ausschließlich Programme betrachtet werden, die auf jeder Eingabe halten. 124 1.11 Das Postsche Korrespondenzproblem In diesem Abschnitt wird ein unentscheidbares Problem vorgestellt, das nicht auf den ersten Blick Fragen über Turingmaschinen beinhaltet, wie in den bisher betrachteten Situationen. Das Problem ist nach Emil Post benannt, der es 1946 formulierte. Es dient als Basis für viele Unentscheidbarkeitsbeweise für Entscheidungsprobleme in der Mathematik und in anderen Teilen der (theoretischen) Informatik. (Man lasse sich von der in dieser Vorlesung geübten Zurückhaltung nicht täuschen: es gibt sehr viele unentscheidbare Probleme, die mit Maschinen und formalen Sprachen nichts zu tun haben.) 1.11.1 Definition Das Postsche Korrespondenzproblem (PKP )22 ist folgendes Entscheidungsproblem: Eingabe: Eine Folge s = ((x1 , y1 ), (x2 , y2 ), . . . , (xn , yn )) von Paaren von Wörtern über einem Alphabet ∆. Frage: Gibt es eine Folge i1 , . . . , ir in {1, . . . , n} (Wiederholungen erlaubt!) mit r ≥ 1 derart dass xi1 xi2 · · · xir = yi1 yi2 · · · yir ? Eine Indexfolge, die dies erfüllt, heißt Lösungsfolge für s. Man kann sich die Eingabe als eine endliche Menge von zweizeiligen Puzzlesteinen vorstellen, wobei der ite Stein in der oberen Zeile die Inschrift xi , in der unteren die Inschrift yi hat. Die Frage ist, ob man Kopien der Puzzlesteine so nebeneinander hinlegen kann, dass in der oberen Zeile und in der unteren Zeile dasselbe Wort entsteht. Zur Verdeutlichung der Trennstellen zwischen Wortteilen benutzen wir in diesem Abschnitt oft das Zeichen ◦ für die Konkatenation. 1.11.2 Beispiel Die Eingabe besteht aus sechs Paaren von Wörtern über dem Alphabet ∆ = {a, b, c, d, r, !}, nämlich: i xi yi 1 2 3 4 5 6 !a a ada a br c ! rac d ra ab a Diese Instanz des PKP hat verschiedene Lösungsfolgen: Die Indexfolge 1, 5, 4 liefert x1 x5 x4 = !a ◦ br ◦ a = !abra = ! ◦ ab ◦ ra = y1 y5 y4 . 22 Das Wort Korrespondenz“ wird hier im Sinn von Entsprechung“ gebraucht, eine Bedeutung, die ” ” das englische correspondence“ viel stärker hat. ” 125 Die Indexfolge 1, 5, 2, 6, 3, 5, 4 liefert !a ◦ br ◦ a ◦ c ◦ ada ◦ br ◦ a = !abracadabra = ! ◦ ab ◦ rac ◦ a ◦ d ◦ ab ◦ ra 1.11.3 Bemerkung Am Beispiel kann man sich einige andere offensichtliche Eigenschaften des PKP klarmachen: 1. Da die endlichen Folgen von Wortpaaren nur endlich viele Buchstaben enthalten können, muss man das Alphabet ∆ eigentlich nicht explizit benennen; es kann aus der Folge von Paaren abgelesen werden. 2. Wenn i1 , . . . , ir und j1 , . . . , jt Lösungsfolgen für s sind, dann ist auch i1 , . . . , ir , j1 , . . . , jt Lösungsfolge. Im Beispiel sind etwa 1, 5, 4, 1, 5, 4 und 1, 5, 4, 1, 5, 2, 6, 3, 5, 4, 1, 5, 4 weitere Lösungsfolgen. Wenn es also eine Lösungsfolge gibt, dann gibt es sogar unendlich viele verschiedene. 1.11.4 Beispiel Betrachte folgende Eingabe, mit dem Alphabet {0, 1}: i xi yi 1 2 3 10 011 101 101 11 011 Wir versuchen, eine Lösungsfolge zu bauen. Offenbar müssen wir mit (x1 , y1 ) anfangen. Erzwungener Start: 10 101 Nun hat die y-Reihe“ einen Vorsprung von einer 1. Als nächste Elemente kommen nur ” Paare 1 und 3 in Frage, wobei aber Paar 1 nicht passt“. Erzwungene Fortsetzung also: ” 10 ◦ 101 = 10101 101 ◦ 011 = 101011 Wieder hat die y-Reihe“ einen Vorsprung von einer 1. Die einzig mögliche Fortsetzung ” besteht darin, erneut das Paar (x3 , y3 ) anzuhängen. Man sieht, dass dieser Vorgang des Anbauens“ nie zu einem Ende kommt; daher kann es keine Lösungsfolge geben. ” Wir überlegen kurz, dass es genügt, das Standardalphabet {0, 1} zu betrachten. Gegeben sei ein beliebiges Alphabet ∆. Wähle eine feste Binärkodierung für die Buchstaben in ∆ mit Codes fester Länge, d. h. eine injektive Funktion ϕ : ∆ → {0, 1}l , wo l ≥ dlog2 (|∆|)e fest gewählt wird. Durch ϕ wird auch jedes Wort x = a1 · · · am über ∆ binär kodiert, nämlich durch ϕ(x) = ϕ(a1 ) · · · ϕ(am ). In Beispiel 1.11.2 könnte man die Kodierung 126 ! a b c d r 000 001 010 011 100 101 wählen und die folgende kodierte Eingabefolge s0 betrachten: i x0i yi0 1 2 3 4 5 6 000001 001 001100001 001 010101 011 000 101001011 100 101001 001010 001 Man überlegt sich leicht, dass wegen der Kodierung durch Blöcke gleicher Länge für die Eingabe s = ((x1 , y1 ), . . . , (xn , yn )) über ∆ genau dann xi1 · · · xir = yi1 · · · yir gilt, wenn für die binär kodierte Eingabe s0 = ((x01 , y10 ), . . . , (x0n , yn0 )) = ((ϕ(x1 ), ϕ(y1 )), . . . , (ϕ(xn ), ϕ(yn ))) über {0, 1} gilt, dass x0i1 · · · x0ir = yi01 · · · yi0r . Die Menge der Lösungsfolgen für beide Eingaben ist also identisch. Wir benutzen diese Beobachtung so, dass wir größere Alphabete benutzen, wo es bequem ist. Formal hat man sich aber immer die binär kodierten Versionen eingesetzt zu denken. — Nun können wir das PKP als Sprache definieren. 1.11.5 Definition LPKP := {((x1 , y1 ), . . . , (xn , yn )) | n ≥ 1, x1 , y1 , . . . , xn , yn ∈ {0, 1}∗ , ∃r ≥ 1∃i1 , . . . , ir ∈ {1, . . . , n} : xi1 · · · xir = yi1 · · · yir } (Formal gesehen ist LPKP eine Sprache über dem Alphabet {0, 1, (, ), ,“}, wobei das Kom” ma ,“ auch als Buchstabe benutzt wird.) ” Das Wortproblem der Sprache LPKP ist im wesentlichen das Postsche Korrespondenzproblem, bis auf einen trivialen Syntaxcheck, der Eingaben darauf überprüft, ob sie tatsächlich Wortfolgen in der vorgeschriebenen Beschreibung darstellen. 1.11.6 Satz LPKP ist rekursiv aufzählbar, aber nicht rekursiv. Damit hat LPKP bezüglich der Entscheidbarkeit denselben Status wie das Halteproblem für Turingmaschinen. Jedoch erwähnt LPKP Turingmaschinen oder Berechnungen überhaupt nicht. Beweis: Rekursive Aufzählbarkeit“. Dass LPKP rekursiv aufzählbar ist, ist leicht einzuse” hen. Auf Eingabe w ist folgendes zu tun: Überprüfe, ob w das Format ((x1 , y1 ), . . . , (xn , yn )) hat. Falls nein, verwirf die Eingabe. Falls ja, erzeuge die Folgen bin(i1 ), . . . , bin(ir ), r = 127 1, 2, 3, . . ., mit i1 , . . . , ir ∈ {1, . . . , n}, nacheinander. Für jede so erzeugte Folge prüfe, ob xi1 · · · xir = yi1 · · · yir gilt. Wenn und sobald dies der Fall ist, halte und akzeptiere w. Man beachte bei diesem Teil des Beweises, dass es keine Möglichkeit gibt, vorab festzustellen, wie groß das kleinste r ist, so dass eine Lösungsfolge der Länge r existiert. Für den zweiten Teil des Beweises benutzen wir unser Rezept zum Nachweis von Nichtrekursivität und zeigen, dass H ≤ LPKP gilt, wo H die Haltesprache für Turingmaschinen ist. Die Konstruktion dieser Reduktion ist etwas komplizierter, und nimmt den ganzen Rest dieses Abschnittes ein. Hinweis: Der folgende Beweis ist im Wintersemester 2004/05 nicht prüfungsrelevant. Wir benötigen ein Hilfsproblem, das dadurch entsteht, dass man das PKP so modifiziert, dass nur Lösungsfolgen zugelassen werden, die mit dem ersten Paar (x1 , y1 ) beginnen. Dieses Problem heißt MPKP ( modifiziertes PKP“): ” Eingabe: Eine Folge s = ((x1 , y1 ), (x2 , y2 ), . . . , (xn , yn )) von Paaren von Wörtern über einem Alphabet ∆. Frage: Gibt es eine Folge i1 = 1, i2 , . . . , ir in {1, . . . , n} mit r ≥ 1 derart dass x1 xi2 · · · xir = y1 yi2 · · · yir ? Eine Indexfolge 1, i2 , . . . , ir , die dies erfüllt, heißt wieder Lösungsfolge für s. Auch für das MPKP gelten die Bemerkungen zur Binärkodierung, und wir können es als Sprache formulieren: LMPKP := {((x1 , y1 ), . . . , (xn , yn )) | n ≥ 1, x1 , y1 , . . . , xn , yn ∈ {0, 1}∗ , ∃r ≥ 1∃i2 , . . . , ir ∈ {1, . . . , n} : x1 xi2 · · · xir = y1 yi2 · · · yir } 1.11.7 Lemma Das Problem MPKP ist auf PKP reduzierbar, formal: LMPKP ≤ LPKP . Wir schieben den Beweis von Lemma 1.11.7 noch einen Moment auf und notieren, dass wir nur noch (1.1) H ≤ LMPKP beweisen müssen, da dann mit dem Lemma 1.11.7 und der Transitivität der ≤-Relation folgt, dass H ≤ LPKP gilt. Nach Behauptung 1.9.3 ist H rekursiv aufzählbar. Daher genügt es, die folgende Behauptung zu beweisen. 128 1.11.8 Satz Für jede r.a. Sprache L gilt L ≤ LMPKP . Beweis: Sei L ⊆ Σ∗ eine beliebige rekursiv aufzählbare Sprache. Nach Satz 1.3.16 gibt es eine Chomsky-0-Grammatik G = (V, Σ, S, P ) mit L = L(G). Die Idee der Reduktion L ≤ LMPKP ist folgende: Jedem w ∈ Σ∗ wird eine Folge sw = ((x1 , y1 ), . . . , (xn , yn )) von Wortpaaren zugeordnet, so dass eine Ableitung für w in G eine Lösungsfolge für sw induziert, und so dass man umgekehrt aus einer Lösungsfolge für sw relativ leicht eine Ableitungsfolge für w in G ablesen kann. Diese Idee führen wir nun im Detail durch. Für sw benutzen wir das Alphabet ∆ = V ∪ Σ ∪ {#, $} (genauer: eine Binärkodierung dieses Alphabets), wobei natürlich $ und # in V ∪ Σ nicht vorkommen. Das erste Paar in sw ist das Startpaar“ ” (x1 , y1 ) = (#w#, #), die weiteren Paare, in beliebiger Reihenfolge, sind die Produktions-Paare“ ” (l, r), wobei l → r eine Produktion in P ist, die Kopier-Paare“ ” (X, X), für X ∈ V ∪ Σ ∪ {#} , und das Abschlusspaar“ ” ($, S#$). Wir müssen zeigen: w ∈ L = L(G) ⇔ sw ∈ LMPKP , d.h. w besitzt eine Ableitung in G ⇔ sw hat eine MPKP-Lösungsfolge. ⇒“: Es sei w ∈ L(G) und ” S = α0 ⇒G α1 ⇒G · · · ⇒G αt−1 ⇒G αt = w eine Ableitung von w in G. Die Lösungsfolge i1 = 1, i2 , . . . , ir wird nun so gewählt, dass das Lösungswort z die Struktur z = #w#αt−1 #αt−2 # · · · #α1 #S#$ hat, und zwar gegliedert als auf der x-Seite: #w# ◦ αt−1 # ◦ αt−2 # ◦ · · · auf der y-Seite: # ◦ αt # ◦ αt−1 # ◦ · · · 129 ◦ α1 # ◦ S# ◦ $ ◦ α2 # ◦ α1 # ◦ S#$ . Es ist klar, wo das Startpaar und das Abschlusspaar einzusetzen sind. Um zu sehen, dass eine solche Lösungsfolge möglich ist, muss nur noch gezeigt werden, dass es für jedes u eine Indexfolge j1 , . . . , js gibt mit αu−1 # = xj1 · · · xjs und αu # = yj1 · · · yjs . Das ist aber unter Benutzung der Kopier-Paare und der Produktions-Paare offensichtlich möglich. Damit ist ⇒“ bewiesen. ” ⇐“: Es sei i1 = 1, i2 , . . . , ir eine Lösungsfolge für sw , also ” z = x1 xi2 · · · xir = y1 yi2 · · · yir . Wir beobachten zunächst, dass das Startpaar (x1 , y1 ) ein Ungleichgewicht der #-Zeichen erzeugt, das nur ausgeglichen werden kann, wenn irgendwo auch das Abschlusspaar ($, S#$) vorkommt. Es sei t minimal mit (xit , yit ) = ($, S#$). Weil x1 xi2 · · · xit und y1 yi2 · · · yit Präfixe von z sind, und in beiden genau ein $-Zeichen vorkommt, nämlich als letztes Zeichen, gilt x1 xi2 · · · xit = y1 yi2 · · · yit . Also ist schon i1 = 1, i2 , . . . , it Lösungsfolge, und wir können o.B.d.A. t = r annehmen, d.h. dass in z das $-Zeichen genau einmal vorkommt, nämlich als letztes Zeichen. Nach dem bisher Gesagten kommt das #-Zeichen in xi2 · · · xir−1 nur noch in Kopierpaaren (#, #) vor. Wir sondern alle diese Kopierpaare für # aus und können schreiben: (1.2) x-Seite: z = #w# ◦ β1 ◦ # ◦ β2 ◦ # ◦ · · · ◦ # ◦ βp ◦ # ◦ $ y-Seite: z = # ◦ γ1 ◦ # ◦ γ2 ◦ # ◦ · · · ◦ # ◦ γp ◦ # ◦ S#$ , wobei β1 , . . . , βp , γ1 , . . . , γp Wörter über V ∪ Σ sind. Hierbei haben wir die #-Zeichen, die zu einem Kopier-Paar gehören, untereinander plaziert. Jedes Paar von Teilwörtern βu und γu , 1 ≤ u ≤ p, entspricht einem zusammenhängenden Segment in xi2 · · · xir−1 . Da diese Teilfolgen nur Kopier-Paare und Produktions-Paare enthalten, sieht man, dass γu aus βu dadurch entsteht, dass auf disjunkte Teilwörter in γu Produktionen l → r angewendet werden. Indem wir diese Ableitungsschritte nacheinander ausführen, sehen wir, dass (1.3) βu ⇒∗G γu , für 1 ≤ u ≤ p. Andererseits bilden beide Zeilen in (1.2) jeweils dasselbe Wort z. In diesem Wort müssen die vorkommenden #-Zeichen natürlich an denselben Stellen stehen. Dies liefert: w = γ1 ; β1 = γ2 ; β2 = γ3 ; . . . ; βp−1 = γp ; βp = S. Wenn wir dies mit (1.3) kombinieren, erhalten wir S = βp ⇒∗G γp = βp−1 ⇒∗G γp−1 = βp−2 ⇒∗G · · · ⇒∗G γ2 = β1 ⇒∗G γ1 = w. Dies ist die gesuchte Ableitungsfolge für w. Damit ist der Beweis von ⇐“ beendet. ” 130 Es folgt der bisher aufgeschobene Beweis von Lemma 1.11.7. Wir benutzen das Alphabet ∆ = {0, 1, /c, $, #} (genauer gesagt: Binärkodierungen für die Buchstaben dieses Alphabets). Für Wörter z über {0, 1} definieren wir Wörter, die durch Einstreuen von #-Zeichen entstehen, wie folgt: Wenn z = a1 a2 · · · am , dann soll # z = #a1 #a2 · · · #am und z = a1 #a2 # · · · am # # sein. (Beispiel: Für z = 01101 ist z = ε ist # z = z # = ε.) # z = #0#1#1#0#1 und z # = 0#1#1#0#1#. Für Sei s = ((x1 , y1 ), . . . , (xn , yn )) (Eingabe für MPKP) gegeben. Vorab betrachten wir den Sonderfall, dass in s das Paar (ε, ε) vorkommt. Falls (x1 , y1 ) = (ε, ε), ist offenbar (1) eine Lösungsfolge bzgl. des MPKP, und wir wählen mit s0 = ((ε, ε)) eine lösbare Eingabe für das PKP. Falls (x1 , y1 ) 6= (ε, ε), dann lassen wir aus s alle Paare (ε, ε) weg — solche Paare tragen zur Lösbarkeit der Eingabe s im Sinn von MPKP nichts bei. Ab hier können wir also annehmen, dass die Folge s das Paar (ε, ε) nicht enthält. Wir bilden dann zu s die folgende Eingabe s0 für PKP: # # # s0 = ((x# c # ◦ x# c ◦ # y1 ), ($, #$)), 1 , y1 ), . . . , (xn , yn ), (/ 1 ,/ und behaupten: (1.4) s ∈ LMPKP ⇔ s0 ∈ LPKP . (Damit ist die Funktion, die s auf s0 abbildet, eine Reduktionsfunktion.) ⇒“: Sei 1, i2 , . . . , ir eine Lösungsfolge für s, d. h. x1 xi2 · · · xir = y1 yi2 · · · yir . Es ist dann ” klar, dass # # c ◦ # y1 ◦ # yi2 ◦ · · · # yir ◦ #$. /c# ◦ x# 1 ◦ xi2 ◦ · · · ◦ xir ◦ $ = / Damit ist n + 1, i2 , . . . , ir , n + 2 eine Lösungsfolge für s0 . ⇐“: Sei j1 , j2 , . . . , ju eine Lösungsfolge für s0 . Das heißt: ” z = x0j1 x0j2 · · · x0ju = yj0 1 yj0 2 · · · yj0 u . Man könnte nun zeigen, dass die Lösungsfolge j1 , j2 , . . . , ju in disjunkte Blöcke zerfällt, die jeweils mit n + 1 beginnen und mit n + 2 enden, aber im Inneren diese Indizes nicht enthalten, und die auf der x- und auf der y-Seite jeweils denselben Teilwörtern von z entsprechen.23 Für unsere Zwecke genügt es aber, nur einen solchen Block zu finden. Weil s das Paar (ε, ε) nicht enthält, ist z nicht das leere Wort. Wegen der Bauart der Paare in s0 enthält z mindestens ein #-Zeichen. 23 Eine Lösungsfolge für s ergibt sich aus j1 , j2 , . . . , ju , indem man die Vorkommen von n + 2 weglässt und n + 1 durch 1 ersetzt. 131 Behauptung 1: Der Index n + 2 kommt in j1 , . . . , ju vor. [Beweis indirekt. Annahme: n + 2 kommt in j1 , . . . , ju nicht vor. — Dann endet das Wort z = x0j1 · · · x0ju auf # (weil x01 , . . . , x0n+1 leer sind oder auf # enden), andererseits endet 0 leer sind oder auf einen Buchstaben das Wort z = yj0 1 · · · yj0 u nicht auf # (weil y10 , . . . , yn+1 6= # enden). Dies ist der gewünschte Widerspruch.] Es sei t der kleinste Index mit jt = n + 2, also (xjt , yjt ) = ($, #$). Dann enthalten x0j1 · · · x0jt und yj0 1 · · · yj0 t beide genau ein $-Zeichen, und zwar als letztes Zeichen. Diese beiden Wörter sind Anfangsstücke von z, und daher muss das $-Zeichen in beiden Folgen an derselben Stelle in z stehen. Damit haben wir x0j1 · · · x0jt = yj0 1 · · · yj0 t . Behauptung 2: Der Index n + 1 kommt in j1 , . . . , jt−1 vor. [Beweis indirekt. Annahme: n + 1 kommt in j1 , . . . , jt−1 nicht vor. — Wegen der Bauart der Wörter in s0 beginnt das Wort x0j1 · · · x0jt mit einem Zeichen 6= #; dagegen beginnt yj0 1 · · · yj0 t mit #. Das ist unmöglich.] 0 c ◦ # y1 . Es sei p der maximale Index < t mit jp = n + 1, also x0jp = /c# ◦ x# 1 und yjp = / Wie eben sieht man, dass im Wort z das /c-Zeichen aus x0jp und das aus yj0 p an derselben Stelle stehen müssen. Daraus folgt, dass 0 0 x0n+1 x0jp+1 · · · x0jt−1 x0n+2 = yn+1 yj0 p+1 · · · yj0 t−1 yn+2 , und dass jp+1 , . . . , jt−1 ∈ {1, . . . , n}. Wegen der Bauart der Wörter in s0 erhält man x1 xjp+1 · · · xjt−1 = y1 yjp+1 · · · yjt−1 ; mit anderen Worten: 1, jp+1 , . . . , jt−1 ist eine Lösungsfolge für s. Damit ist ⇐“ gezeigt, ” und der Beweis von (1.4) beendet. 1.12 Unentscheidbare Fragen bei Grammatiken Hinweis: Die Beweise dieses Abschnittes sind im Wintersemester 2004/05 nicht prüfungsrelevant. Jedoch sollte man wissen, welche Fragen über kontextfreie Grammatiken unentscheidbar sind. Diese sind aus den Sätzen abzulesen. In der AFS-Vorlesung wurden für eine ganze Reihe von Fragen für kontextfreie Sprachen Algorithmen vorgestellt. Insbesondere ist es möglich, eine kontextfreie Grammatik in einen NPDA für dieselbe Sprache umzubauen, und aus einem NPDA eine äquivalente kontextfreie Grammatik zu gewinnen. Es gibt Algorithmen für das Wortproblem für kontextfreie Sprachen, für das Leerheits- und für das Unendlichkeitsproblem. 132 Für eine Reihe von Problemen hingegen wurden keine Algorithmen angegeben. Zentral hierbei ist eigentlich das Äquivalenzproblem für kontextfreie Sprachen: Eingabe: Kontextfreie Grammatiken G1 , G2 . Frage: Sind G1 , G2 äquivalent, d.h. gilt L(G1 ) = L(G2 )? Wir werden in diesem Abschnitt sehen, dass dieses Problem unentscheidbar ist, es also keinen Algorithmus geben kann, der das Problem entscheidet. In ähnlicher Weise sind eine ganze Reihe anderer Fragen, die zwei kontextfreie Sprachen betreffen, unentscheidbar. Aber auch Fragen zu einzelnen kontextfreien Grammatiken ( Ist L(G) = Σ∗ ?“) stellen ” sich als unentscheidbar heraus. Technisch grundlegend ist das Problem Nichtleerer Durchschnitt“: ” Eingabe: Kontextfreie Grammatiken G1 , G2 . Frage: Gilt L(G1 ) ∩ L(G2 ) 6= ∅? Formal definieren wir: Lnl := {(G1 , G2 ) | G1 , G2 kfG mit L(G1 ) ∩ L(G2 ) 6= ∅}. (Natürlich muss man hierzu kontextfreie Grammatiken geeignet als Wörter kodieren.) Es ist eine nicht allzu schwierige Übungsaufgabe zu zeigen, dass Lnl rekursiv aufzählbar ist. Dass das Nichtleerheitsproblem unentscheidbar ist, folgt dann nach unserem Rezept für den Beweis von Nichtrekursivität aus Satz 1.11.6 und dem folgenden Satz. 1.12.1 Satz LPKP ≤ Lnl . Beweis: Wir konstruieren eine Reduktionsfunktion f , die jeder Eingabefolge s für PKP ein Paar f (s) = (Gs1 , Gs2 ) von kontextfreien Grammatiken zuordnet, derart dass s ∈ LPKP ⇔ L(Gs1 ) ∩ L(Gs2 ) 6= ∅. Sei s = ((x1 , y1 ), . . . , (xn , yn )) gegeben. Dann haben Gs1 und Gs2 beide das Terminalzeichenalphabet Σ = {0, 1, $} ∪ {p1 , p2 , . . . , pn }, wobei p1 , . . . , pn einfach n neue Zeichen sind. (Zum Beispiel könnte man Σ = {0, 1, 2, . . . , n+ 2} verwenden, wobei 2 die Rolle von $ spielt und 3, . . . , n + 2 die Rolle von p1 , . . . , pn spielen.) Wie früher bedeutet xR das Spiegelwort ak · · · a1 des Wortes x = a1 · · · ak . Die Grammatik Gs1 hat Startsymbol S1 , Variablenmenge V1 = {S1 , A, B}, und Produktionen S1 A A B B → → → → → A$B p 1 A x1 | . . . | p n A xn p 1 x1 | . . . | p n xn y1R B p1 | . . . | ynR B pn y1R p1 | . . . | ynR pn 133 Man erkennt leicht, dass in L(Gs1 ) die Wörter des folgenden Formats erzeugt werden können: pir . . . pi1 xi1 . . . xir $ yjRt . . . yjR1 pj1 . . . pjt , (1.5) wo r ≥ 1, i1 , . . . , ir ∈ {1, . . . , n} und t ≥ 1, j1 , . . . , jt ∈ {1, . . . , n}. Man erkennt, dass rechts und links des $-Zeichens voneinander unabhängig Konkatenationen von x- und y-Komponenten von s gebildet werden, und dass die pi -und pj -Folgen dokumentieren, welche dieser Komponenten gewählt worden sind. Die Grammatik Gs2 hat Startsymbol S2 , Variablenmenge V2 = {S2 , T } und Produktionen S2 → p 1 S2 p 1 | . . . | p n S2 p n | T T → 0T 0 | 1T 1 | $ Die Sprache L(Gs2 ) enthält die Wörter des Formats (1.6) uv $ v R uR , u ∈ {p1 , . . . , pn }∗ , v ∈ {0, 1}∗ . 1.12.2 Bemerkung Man kann relativ leicht einsehen, dass sowohl L(Gs1 ) als auch s L(G2 ) von einem deterministischen Kellerautomaten akzeptiert werden. Das heißt, dass L(Gs1 ) und L(Gs2 ) deterministisch kontextfrei sind, und dass die Komplementsprachen L(Gs1 ) und L(Gs2 ) ebenfalls (deterministisch) kontextfrei sind. Man kann dann sogar algorithmisch kontextfreie Grammatiken Gs1 0 und Gs2 0 konstruieren, die L(Gs1 0 ) = L(Gs1 ) und L(Gs2 0 ) = L(Gs2 ) erfüllen. Behauptung: s ∈ LPKP ⇔ L(Gs1 ) ∩ L(Gs2 ) 6= ∅. Beweis der Behauptung: ⇒“: Es sei i1 , . . . , ir eine Lösungsfolge für s, d. h. ” xi1 · · · xir = yi1 · · · yir . Dann erfüllt das Wort zs = pir . . . pi1 xi1 . . . xir $ yiRr . . . yiR1 pi1 . . . pir die in (1.5) und die in (1.6) notierten Bedingungen. Also ist zs ∈ L(Gs1 ) ∩ L(Gs2 ). ⇐“: Es sei z ∈ L(Gs1 ) ∩ L(Gs2 ). Wegen Bedingung (1.6) für L(Gs2 ) gibt es r ≥ 0 und ” pi1 , . . . , pir mit z = pi1 . . . pir v$v R pir . . . pi1 , wobei v ∈ {0, 1}∗ gilt. Wegen Bedingung (1.5) muss weiter r ≥ 1 und v = xir . . . xi1 und v R = yiR1 . . . yiRr gelten. Weil yiR1 . . . yiRr = (yir . . . yi1 )R , heißt das, dass xir . . . xi1 = yir . . . yi1 , also ist ir , . . . , i1 eine Lösungsfolge für s, und s ∈ LPKP . Damit ist die Behauptung bewiesen und der Beweis von Satz 1.12.1 beendet. 134 Wir definieren nun weitere Sprachen, die Entscheidungsproblemen zu Paaren von kontextfreien Sprachen entsprechen. Linfinite Lkfschnitt Lsubset Lequiv := := := := {(G1 , G2 ) | {(G1 , G2 ) | {(G1 , G2 ) | {(G1 , G2 ) | G1 , G2 G1 , G2 G1 , G2 G1 , G2 kfG kfG kfG kfG mit mit mit mit |L(G1 ) ∩ L(G2 )| = ∞}, L(G1 ) ∩ L(G2 ) kontextfrei}, L(G1 ) ⊆ L(G2 )}, L(G1 ) = L(G2 )}. Wir zeigen, dass alle diese Sprachen nichtrekursiv, die entsprechenden Entscheidungsprobleme also unentscheidbar sind. 1.12.3 Satz (a) LPKP ≤ Linfinite . (b) LPKP ≤ Lkfschnitt . (c) LPKP ≤ Lsubset . (d) Lsubset ≤ Lequiv . Beweis: (a) Betrachte die Konstruktion im Beweis von Satz 1.12.1. Gegeben sei eine Eingabe s für PKP. Zu jeder Lösungsfolge i1 , . . . , ir für s finden wir ein Wort zs in L(Gs1 )∩ L(Gs2 ), und alle diese Wörter sind verschieden. Wir erinnern uns nun an Bemerkung 1.11.3, die besagte, dass es zu s entweder keine oder unendlich viele Lösungsfolgen gibt. Das heißt: Wenn s ∈ / LPKP , dann ist L(Gs1 ) ∩ L(Gs2 ) = ∅; wenn s ∈ LPKP , dann ist |L(Gs1 ) ∩ L(Gs2 )| = ∞. Damit ist die Funktion s 7→ (Gs1 , Gs2 ) auch eine Reduktionsfunktion von LPKP auf Linfinite . (b) Wir verwenden nochmals die Reduktionsfunktion s 7→ (Gs1 , Gs2 ). Falls s ∈ / LPKP , ist L(Gs1 ) ∩ L(Gs2 ) = ∅. Sei nun s = ((x1 , y1 ), . . . , (xn , yn )) ∈ LPKP . Zu zeigen ist, dass die Sprache L(Gs1 ) ∩ L(Gs2 ) nicht kontextfrei ist. Hierzu benutzen wir das Pumping-Lemma für kontextfreie Sprachen. (Für die Erklärung des Pumping-Lemmas und das resultierende Muster von Nicht-Kontextfreiheits-Beweisen siehe die AFS-Vorlesung.) Es sei N ≥ 1 beliebig gegeben. Nach Teil (a) ist L(Gs1 ) ∩ L(Gs2 ) unendlich; wir können also ein z = uv$ v R uR , u ∈ {p1 , . . . , pn }∗ , v ∈ {0, 1}∗ in L(Gs1 ) ∩ L(Gs2 ) wählen, mit |u| ≥ N und |v| ≥ N . Dabei ist u = pir · · · pi1 und v = xi1 · · · xir = yi1 · · · yir . Nun betrachte eine beliebige Zerlegung z = z1 z2 z3 z4 z5 mit |z2 z4 | ≥ 1 und |z2 z3 z4 | ≤ N . Wir unterscheiden einige Fälle. 135 1. Fall : z2 z4 enthält das $-Zeichen aus z. — Dann ist z1 z3 z5 = z1 z20 z3 z40 z5 ∈ / L(Gs1 )∩L(Gs2 ). Ab hier nehmen wir an, dass in z2 z4 das $-Zeichen aus z nicht vorkommt. Alle Modifikationen z1 z2i z3 z4i z5 , i ≥ 0, enthalten also genau ein $-Zeichen, so dass man die linke Seite“ ” und die rechte Seite“ unterscheiden kann. ” 2. Fall : z2 enthält ein Zeichen des u-Teils von z. — Dann kann z2 z3 z4 keinen Buchstaben aus dem uR -Teil enthalten. Es folgt, dass in z1 z3 z5 der erste Block aus Zeichen aus p1 , . . . , pn nicht Spiegelbild des letzten Blocks, nämlich uR , ist; damit ist z1 z3 z5 ∈ / L(Gs2 ). 2. Fall : z2 enthält kein Zeichen des u-Teils, aber ein Zeichen des v-Teils von z. — Dann ist in z1 z3 z5 der erste Block aus {0, 1}∗ nicht gemäß den in u festgehaltenen Indizes aus den Wörtern x1 , . . . , xn gebildet, also z1 z3 z5 ∈ / L(Gs1 ). 3. Fall : z2 enthält kein Zeichen des uv-Teils von z. — Dann ist in z1 z3 z5 der Wortteil rechts des $-Zeichens nicht mehr das Spiegelbild des Wortteils links des $-Zeichens, also ist z1 z3 z5 ∈ / L(Gs1 ). In allen Fällen ist z1 z3 z5 ∈ / L(Gs1 ) ∩ L(Gs2 ). Damit ist die nach dem Pumping-Lemma geltende Bedingung verletzt, also kann L(Gs1 ) ∩ L(Gs2 ) nicht kontextfrei sein. (c) In Bemerkung 1.12.2 hatten wir festgestellt, dass L(Gs2 ) deterministisch kontextfrei ist und dass man daher aus s auch eine kontextfreie Grammatik Gs2 0 konstruieren kann, die L(Gs2 0 ) = L(Gs2 ) erfüllt. Damit gilt: s ∈ LPKP ⇔ L(Gs1 ) ∩ L(Gs2 ) 6= ∅ ⇔ L(Gs1 ) 6⊆ L(Gs2 ) = L(Gs2 0 ). Daher ist die Funktion s 7→ (Gs1 , Gs2 0 ) eine Reduktionsfunktion von LPKP auf Lsubset . (d) Zu gegebenen kontextfreien Grammatiken G und G0 können wir eine kontextfreie Grammatik G00 bauen, die L(G00 ) = L(G) ∪ L(G0 ) erfüllt. Offensichtlich gilt: L(G) ⊆ L(G0 ) ⇔ L(G) ∪ L(G0 ) = L(G0 ) ⇔ L(G00 ) = L(G0 ). Damit ist die Funktion (G, G0 ) 7→ (G00 , G0 ) eine Reduktionsfunktion von Lsubset auf Lequiv . Die Reduktionen in den Fällen (a)–(c) arbeiten ausschließlich mit deterministisch kontextfreien Sprachen. Daher erhalten wir, dass die Entscheidungsprobleme leerer Durch” schnitt“, unendlicher Durchschnitt“ und Teilmenge“ schon für deterministisch kontext” ” freie Sprachen (gegeben durch entsprechende Kellerautomaten) unentscheidbar sind. Im Beweis von Teil (d) geht man über die deterministisch kontextfreien Sprachen hinaus, das diese unter der Operation Vereinigung“ nicht abgeschlossen sind. Tatsächlich wurde ” 1997 von G. Sénizergues bewiesen, dass das Äquivalenzproblem für deterministisch kontextfreie Sprachen entscheidbar ist. Nun wollen wir noch weitere Probleme für kontextfreie Sprachen betrachten, die sich als unentscheidbar herausstellen. Für die Definition der Begriffe siehe die AFS-Vorlesung. (a) Totalität: 136 Eingabe: Kontextfreie Grammatik G. Frage: Ist L(G) = Σ∗ ? (b) Komplement kontextfrei? Eingabe: Kontextfreie Grammatik G. Frage: Ist L(G) kontextfrei? (c) Deterministisch kontextfrei? Eingabe: Kontextfreie Grammatik G. Frage: Ist L(G) deterministisch kontextfrei? (d) Regularität: Eingabe: Kontextfreie Grammatik G. Frage: Ist L(G) regulär? (e) Mehrdeutigkeit: Eingabe: Kontextfreie Grammatik G. Frage: Ist G mehrdeutig? 1.12.4 Satz Die in (a)–(e) genannten Entscheidungsprobleme zu kontextfreien Sprachen sind unentscheidbar. Beweis: Wir verzichten darauf, die Formulierungen als Sprachen vorzunehmen, und beschreiben nur die wesentlichen Reduktionen. Wir wissen aus dem Beweis von Satz 1.12.3(b), dass wir aus einer Eingabe s für PKP kontextfreie Grammatiken Gs1 und Gs2 konstruieren können derart, dass (i) s ∈ / LPKP ⇒ L(Gs1 ) ∩ L(Gs2 ) = ∅ (ii) s ∈ LPKP ⇒ L(Gs1 ) ∩ L(Gs2 ) ist nicht kontextfrei. Weiter können wir nach Bemerkung 1.12.2 kontextfreie Grammatiken Gs1 0 und Gs2 0 konstruieren derart dass L(Gs1 0 ) = L(Gs1 ) und L(Gs2 0 ) = L(Gs2 ). Damit können wir auch eine kontextfreie Grammatik Gs3 konstruieren mit L(Gs3 ) = L(Gs1 0 ) ∪ L(Gs2 0 ) = L(Gs1 ) ∩ L(Gs2 ). Aufgrund von (i) und (ii) erhalten wir: (i) s ∈ / LPKP ⇒ L(Gs3 ) = Σ∗ . In diesem Fall ist also L(Gs3 ) auch kontextfrei, deterministisch kontextfrei, und sogar regulär. 137 (ii) s ∈ LPKP ⇒ L(Gs3 ) ist nicht kontextfrei. In diesem Fall ist L(Gs3 ) nicht deterministisch kontextfrei, und auch nicht regulär. Damit gilt für die Funktion s 7→ Gs3 : s ∈ LPKP s ∈ LPKP s ∈ LPKP s ∈ LPKP ⇔ ⇔ ⇔ ⇔ L(Gs3 ) 6= Σ∗ L(Gs3 ) ist nicht kontextfrei L(Gs3 ) ist nicht deterministisch kontextfrei L(Gs3 ) ist nicht regulär Daraus folgt die Unentscheidbarkeit der Entscheidungsprobleme (a), (b), (c) und (d). Zu (e): Betrachte nochmals die Grammatiken Gs1 und Gs2 aus dem Beweis von Satz 1.12.1. Diese sind offensichtlich eindeutig, d. h. jedes Wort in L(Gsi ) besitzt genau einen Ableitungsbaum, für i = 1, 2. Wir bilden nun eine neue Grammatik Gs4 , indem wir die Variablen und die Produktionen von Gs1 und Gs2 vereinigen, und eine neue Startvariable S sowie die Produktionen S → S1 und S → S2 hinzufügen. Die Grammatik Gs4 erzeugt die Sprache L(Gs1 )∪L(Gs2 ). Es ist leicht zu sehen, dass Wörter in L(Gs1 )−L(Gs2 ) und in L(Gs2 )−L(Gs1 ) genau einen Ableitungsbaum besitzen, die Wörter in L(Gs1 ) ∩ L(Gs2 ) hingegen genau zwei (einen für eine Ableitung in Gs1 und einen für eine Ableitung in Gs2 ). Das heißt: Gs4 ist mehrdeutig genau dann wenn L(Gs1 ) ∩ L(Gs2 ) 6= ∅. Damit ergibt sich: s ∈ LPKP ⇔ Gs4 ist mehrdeutig; die Reduktion s 7→ Gs4 zeigt also, dass Problem (e) unentscheidbar ist. Ergänzung: In der Vorlesung wurden noch einige weitere Probleme genannt, die sich als unentscheidbar erwiesen haben: • (Allgemein-)Gültigkeitsproblem für Formeln der Prädikatenlogik • Wahre aussagenlogische Formeln für die Arithmetik (Natürliche Zahlen mit Addition und Multiplikation) • Das 10. Hilbertsche Problem“: Existenz ganzzahliger Nullstellen bei (multivariaten) ” Polynomen mit ganzzahligen Koeffizienten Als schriftliche Unterlage für diese Hinweise sei auf die Folien zur Vorlesung verwiesen. Eine genauere Beschreibung der Probleme und Skizzen der Unentscheidbarkeitsbeweise findet man auch in dem Buch Theoretische Informatik kurzgefasst“ von Uwe Schöning. ” 138 Kapitel 2 Die Theorie der NP-vollständigen Probleme Haben wir im ersten Kapitel die Grenze zwischen algorithmisch behandelbaren (den rekursiven) und denjenigen Problemen kennengelernt, die überhaupt nicht algorithmisch zu behandeln sind, wenden wir uns hier der Frage zu, ob es Probleme gibt, die zwar prinzipiell algorithmisch lösbar sind, aber keinen effizienten Algorithmus besitzen, d. h. keinen, dessen Zeit- und Platzaufwand mit der Eingabelänge erträglich“ langsam wächst. Wir ” greifen dazu aus dem Gebiet der Komplexitätstheorie ein Kapitel heraus, das auch für die Praxis von großer Bedeutung ist: die NP-Vollständigkeits-Theorie. (Die Thematik wird im Hauptstudium in der Vorlesung Komplexitätstheorie“ genauer behandelt.) ” Wie schon im Kapitel 1 kümmern wir uns in erster Linie um Entscheidungsprobleme, die durch Sprachen L ⊆ Σ∗ repräsentiert werden, und um Funktionsberechnungen, repräsentiert durch Funktionen f : Σ∗ → ∆∗ . Für solche Probleme sollen Algorithmen bereitgestellt werden. Wann soll ein Algorithmus effizient heißen? Aus der Programmierungsund der Graphentheorie-Vorlesung weiß man, dass effiziente“ Algorithmen Laufzeiten ” O(n), O(n log n), O(n2 ), O(n3 ), . . . haben, und dass man Algorithmen mit exponentiellen Laufzeiten wie O(2n ) oder O(n!) normalerweise nicht als effizient ansieht. Wir erklären (informal): ein Algorithmus A zur Berechnung einer Funktion f heißt ein Polynomialzeitalgorithmus, falls es ein Polynom p(n) gibt, so dass A auf Eingaben x der Größe“ n ” höchstens p(n) Schritte macht. Beispiele für Polynomialzeitalgorithmen: (a) Für das Sortieren von n Zahlen gibt es Algorithmen mit Schrittzahl O(n log n), also O(n2 ); z. B. Mergesort oder Heapsort. (b) Die Zusammenhangskomponenten eines ungerichteten Graphen G = (V, E), |V | = n, |E| = m, gegeben in Adjazenzlistendarstellung, können in Zeit O(n + m) berechnet werden. Die entsprechenden Algorithmen lernt man unter der Bezeichnung Breitensuche“ oder Tiefensuche“ in der Vorlesung und den Büchern zum Gebiet ” ” Effiziente Algorithmen“ kennen. ” 139 (c) Ein maximaler Fluss in einem Flussnetzwerk mit n Knoten und m Kanten kann in Zeit O(nm2 ) = O(n5 ) berechnet werden. (Siehe Vorlesung Graphentheorie“. Die ” behauptete Laufzeit ergibt sich, wenn man den Ford-Fulkerson-Algorithmus dahin ändert, dass immer flussvergrößernde Wege mit möglichst wenigen Kanten gesucht werden. Der resultierende Algorithmus heißt nach seinen Erfindern Edmonds-Karp” Algorithmus“. Er ist bei weitem nicht der schnellste Flussalgorithmus, aber er hat jedenfalls polynomielle Laufzeit.) Für das weitere legen wir folgende Arbeitshypothese zugrunde: (A) Nur Algorithmen mit polynomieller Laufzeit können effizient sein. Wohlgemerkt heißt das nicht, dass wir behaupten, alle Algorithmen mit polynomieller Laufzeit wären effizient — man denke an Laufzeiten wie O(n1000 ). Um Aussagen wie Problem P besitzt keinen Polynomialzeitalgorithmus“ sinnvoll formulieren zu können, ” benötigen wir eine präzise Formulierung des informalen Konzepts Polynomialzeitalgorith” mus“. Hierfür benutzen wir wie in Kap. 1 das Turingmaschinenmodell.1 Betrachtet man die Simulation zwischen RAMs und TMs (Abschnitt 1.5) genauer, so bemerkt man, dass die Simulation von RAMs mit logarithmischem Kostenmaß, das polynomiell beschränkt ist, auf TMs nur polynomielle Zeit erfordert (Satz 1.5.5) und umgekehrt (Satz 1.5.1). Ähnlich verhält es sich mit anderen Methoden, mit denen man Algorithmen spezifizieren und ihren Zeitbedarf messen kann. Eine gewisse Sorgfalt bei der Kodierung von Inputs ist dabei nötig; für unsere Zwecke genügt die Faustregel, dass eine einfache Binärkodierung für Zahlen und für Graphen und andere Strukturen praktisch immer angemessen ist. Weiter muss man darauf achten, dass bei der Zeitmessung nicht allzu komplexe Operationen, wie z. B. die Addition sehr langer Zahlen, mit Kosten 1 veranschlagt werden. Für unser weiteres Arbeiten legen wir die folgende effiziente Variante der Churchschen These (vgl. Abschnitt 1.7) zugrunde: (B) Eine Sprache L ⊆ Σ∗ (eine Funktion f : Σ∗ → ∆∗ ) kann genau dann von einem Polynomialzeitalgorithmus berechnet werden, wenn es eine polynomiell zeitbeschränkte Turingmaschine M mit L = LM (bzw. f = fM ) gibt. Unsere Aussagen (A) und (B) liefern zusammen ein notwendiges Kriterium für Probleme mit effizienten Algorithmen: (C) Wenn eine Sprache L ein effizientes Entscheidungsverfahren hat, dann ist L = LM für eine polynomiell zeitbeschränkte Turingmaschine. Und analog: Wenn eine Funktion f von einem effizienten Algorithmus berechnet werden kann, dann kann f von einer TM mit polynomieller Zeitschranke berechnet werden. 1 In Abschnitt 2.1 wird genau erklärt, wann eine TM polynomiell zeitbeschränkt heißt. 140 Man beachte wieder, dass nicht behauptet wird, alle polynomiell zeitbeschränkten Turingmaschinen würden effiziente Algorithmen darstellen. Aus (C) erhält man durch Kontraposition: (D) Besitzt eine Sprache keine polynomiell zeitbeschränkte Turingmaschine, so ist L durch keinen effizienten Algorithmus entscheidbar. Analog: Wenn f nicht von einer polynomiell zeitbeschränkten Turingmaschine berechnet werden kann, dann besitzt f keinen effizienten Algorithmus. Das Programm für das vorliegende Kapitel sieht wie folgt aus: Wir untersuchen das Konzept der polynomiell zeitbeschränkten Turingmaschine. Weiter definieren wir die Klasse NP derjenigen Sprachen, die durch Nichtdeterministische Polynomiell zeitbeschränkte ” TM“ entschieden werden können. Innerhalb von NP werden NP-vollständige“ Sprachen ” als die schwierigsten“ identifiziert. Wir sammeln Indizien dafür, dass es zu diesen NP” vollständigen Sprachen vermutlich keine polynomiell zeitbeschränkten Turingmaschinen gibt, also, im Licht von (D), die entsprechenden Entscheidungsprobleme und verwandte Berechnungs- und Optimierungsprobleme keinen effizienten Algorithmus haben. Schließlich besprechen wir eine Reihe von Beispielen für solche NP-vollständigen Probleme. 2.1 Polynomiell zeitbeschränkte Turingmaschinen Vereinbarung: Im Rest des Kapitels meinen wir mit Turingmaschinen“ immer TMn ” mit einer beliebigen festen Anzahl von Bändern. (Vgl. Sätze 1.2.6 und 1.2.8.) Wir nehmen an, dass das Eingabealphabet die Form Σ = {0, . . . , k − 1} für ein k ≥ 2 hat. Meist wird hierbei k = 2 angenommen. (Für die entsprechenden Simulationen siehe Abschnitt 1.2.12.) Erinnerung: (Vergleiche Definition 1.2.7.) Eine Turingmaschine M (auch mit mehreren Bändern) heißt g(n)-zeitbeschränkt (für eine Funktion g : N → R+ ), falls für alle x ∈ Σ∗ gilt, dass M auf Eingabe x höchstens g(|x|) Schritte macht (formal: tM (x) ≤ g(|x|)). Eine TM M (auch mit mehreren Bändern) heißt polynomiell zeitbeschränkt, wenn M p(n)-zeitbeschränkt für ein Polynom p(n) ist. Offenbar gilt für jede g(n)-zeitbeschränkte TM M , dass M auf allen Eingaben hält; d. h. LM ist eine rekursive Sprache und fM ist eine rekursive Funktion. 2.1.1 Definition (a) Für eine Funktion t : N → R+ definieren wir DTIME(t(n)) := {LM | ∃c > 0 : M ist c · t(n)-zeitbeschränkte TM}. (Kommentar : Beachte, dass diese Zeitkomplexitätsklassen“ keinen Unterschied bezüglich ” konstanten Faktoren in den Zeitschranken machen. Für die Frage, ob LM ∈ DTIME(n log n) ist, ist es also gleichgültig, ob M 10n log n-zeitbeschränkt oder 10000n log n-zeitbeschränkt ist.) 141 (b) P ist die Klasse der Sprachen, die von polynomiell zeitbeschränkten Turingmaschinen entschieden werden können, genauer: [ P := {DTIME(nk ) | k ≥ 1} = {LM | ∃c > 0, k ≥ 1 : M ist c · nk -zeitbeschränkte TM}. (c) Für t : N → R+ definieren wir: FDTIME(t(n)) := {fM | ∃c > 0 : M ist c · t(n)-zeitbeschränkte TM}. (d) FP ist die Klasse der Funktionen, die von polynomiell zeitbeschränkten TM berechnet werden können: [ FP := {FDTIME(nk + 1) | k ≥ 1} = {fM | ∃c > 0, k ≥ 1 : M ist c · (nk + 1)-zeitbeschränkte TM}. 2.1.2 Bemerkung In der Definition von P und FP werden Zeitschranken der Form c · nk bzw. c · (nk + 1) benutzt. Diese spezielle Form spielt weiter keine Rolle. Es gilt nämlich: L ∈ P ⇔ es gibt eine TM M und ein Polynom p(n) mit ganzzahligen Koeffizienten, so dass M p(n)-zeitbeschränkt ist und LM = L gilt. Beweis: ⇐“: Es sei L = LM für eine TM M mit tM (x) ≤ p(|x|) für alle x ∈ Σ∗ . Zuerst ” überlegt man, dass man M so umbauen kann, dass M auf Eingabe ε keinen Schritt macht. (Wenn ε ∈ L, ist q0 akzeptierend, sonst verwerfend.) Wenn nun p(n) = ak nk + ak−1 nk−1 + · · · + a1 n + a0 , so ist für c := |ak | + |ak−1 | + · · · + |a1 | + |a0 | stets p(n) ≤ cnk , falls n ≥ 1. Also ist tM (x) ≤ c|x|k für alle x ∈ Σ∗ , also ist L ∈ P. ⇒“ ist trivial. ” Ähnlich zeigt man: f ∈ FP ⇔ es gibt eine TM M und ein Polynom p(n) mit ganzzahligen Koeffizienten, so dass M p(n)-zeitbeschränkt ist und fM = f gilt. Wir haben schon festgestellt, dass jede Sprache in P rekursiv ist und jede Funktion in FP rekursiv ist. Nebenbei sei gesagt, dass sehr viele rekursive Sprachen (Funktionen) nicht in P (bzw. in FP) liegen. Für die folgenden Beispiele brauchen wir eine Kodierung von Graphen als Wörter über einem endlichen Alphabet. Hier gibt es mehrere Möglichkeiten. Eine haben wir in Abschnitt 0.2 vorgestellt. (Diesen Abschnitt sollte man rekapitulieren, bevor man weiterliest.) Dabei konnten die Knotenmengen beliebige Mengen von natürlichen Zahlen sein. 142 Hier werden wir uns nur mit Graphen beschäftigen, die eine Knotenmenge V = {1, . . . , m} für ein m ∈ N haben. Für diesen Fall gibt es noch einfachere Kodierungen, von denen wir zwei nennen wollen. G = (V, E) sei ein (gerichteter oder ungerichteter) Graph mit V = {1, . . . , m} und E = {(v1 , w1 ), . . . , (ve , we )} mit v1 , . . . , ve , w1 , . . . , we ∈ V (geordnete oder ungeordnete Paare). Adjazenzmatrixdarstellung : Die Adjazenzmatrix von G ist bekanntermaßen die Matrix AG = (aij )1≤i,j≤m mit aij = 1 falls (i, j) ∈ E und aij = 0 sonst. Wir können G darstellen, indem wir die Zeilen von AG nebeneinander hinschreiben: hGi := 0m 1a11 · · · a1m · · · am1 · · · amm . Diese Darstellung erfordert exakt m(m + 1) + 1 Bits, gleichgültig wie viele Kanten der Graph hat. Darstellung durch Kantenliste: Man kann auch eine Liste aller Kanten benutzen, um den Graphen darzustellen. Setze l := dlog(m+1)e. Dann besitzt jede Zahl i ∈ {0, 1, . . . , m} eine Darstellung binl (i) als Binärwort mit exakt l Bits (eventuell mit führenden Nullen). Wir setzen hhGii := 0m 10e 1binl (v1 )binl (w1 ) · · · binl (ve )binl (we ), wo E = {(v1 , w1 ), . . . , (ve , we )}. Für diese Darstellung werden genau m + 2 + e(1 + 2l) Bits benötigt. Wenn der Graph nicht allzu viele Kanten hat (deutlich weniger als m2 /2l viele), dann ist diese Darstellung etwas kompakter als die Adjazenzmatrixdarstellung. Um zu erzwingen, dass die Darstellung durch G eindeutig bestimmt ist, kann man verlangen, dass die Kantenliste lexikographisch sortiert ist. Dies ist aber für das folgende nicht wichtig. Man sollte sich kurz klarmachen, dass es leicht ist, auch für eine Turingmaschine in polynomieller Zeit, ein Binärwort darauf zu testen, ob es die Form hGi (oder hhGii) für einen Graphen G hat. Wir werden immer annehmen (und nur manchmal erwähnen), dass TMn, die Graphdarstellungen als Input erwarten, einen solchen Syntaxcheck durchführen. Es ist eine Übungsaufgabe, sich zu überlegen, dass es irrelevant ist, welche der beiden Kodierungen man benutzt, wenn es um die Frage geht, ob eine Sprache von Graphkodierungen, die ein Graphproblem formalisiert, in P liegt oder nicht. Dabei benutzt man die Beobachtung, dass |hhGii| ≤ |hGi|2 und |hGi| = m +1+m2 < (m +1)2 ≤ |hhGii|2 , und dass die beiden Kodierungen leicht ineinander umzurechnen sind. — Eine Verallgemeinerung dieser Kodierungen auf Graphen mit (ganzzahligen oder rationalen) Kantengewichten liegt auf der Hand: Man schreibt diese Gewichte einfach in Binärdarstellung auf. 2.1.3 Beispiel Die folgenden Sprachen sind in P: (a) Lzush = {hGi | G ist zusammenhängender ungerichteter Graph}; (b) Lstark−zush = {hGi | G ist stark zusammenhängender gerichteter Graph}. (G heißt stark zusammenhängend, wenn für jedes Knotenpaar (u, v) in G ein gerichteter Weg von u nach v und ein gerichteter Weg von v nach u existiert.) 143 (c) LMaxGrad ≤d = {hGi | G ist Graph, jeder Knoten in G hat ≤ d Nachbarn}. (d) Lbipartit = {hGi | G ist bipartiter Graph}. (G heißt bipartiter oder paarer Graph, wenn man die Knoten von G so mit 2 Farben färben kann, dass keine zwei benachbarten Knoten dieselbe Farbe haben.) (e) LBaum = {hGi | G ist zusammenhängend und kreisfrei}. Die folgende Funktion ist in FP: (f) fZush−Komp : {0, 1}∗ → {0, 1}∗ , mit der Eigenschaft: fZush−Komp (hGi) = Liste der Zusammenhangskomponenten von G; fZush−Komp (w) = ε, falls w keinen ungerichteten Graphen kodiert. Um TM-Verfahren zu konstruieren, die diese Sprachen bzw. Funktionen berechnen, kann man z. B. Versionen der aus der Graphentheorie-Vorlesung bekannten Algorithmen auf Turingmaschinen umschreiben. Dass dies im Prinzip möglich ist, ohne den Bereich polynomieller Laufzeiten zu verlassen, haben wir oben allgemein festgestellt. 2.2 Polynomiell zeitbeschränkte NTMn In Abschnitt 1.3.1 haben wir uns ausführlich mit nichtdeterministischen Turingmaschinen beschäftigt. Wichtig ist es, sich an den Berechnungsbaum CT (M, x) zur NTM M und einer Eingabe x zu erinnern, der alle möglichen Berechnungen von M auf Eingabe x enthält. Die Anzahl tM (x) der Schritte von M auf x ist die Tiefe von CT (M, x), das heißt die Länge der längsten Berechnung von M auf x. Wieder können unsere TMn eine beliebige Anzahl von Bändern haben. 2.2.1 Definition (Polynomiell zeitbeschränkte NTM) (a) Eine nichtdeterministische TM M heißt t(n)-zeitbeschränkt, wenn für jedes x ∈ Σ∗ die längste Berechnung von M auf x maximal t(|x|) Schritte macht, d. h. wenn CT (M, x) höchstens Tiefe t(|x|) hat. (b) Eine nichtdeterministische TM M heißt polynomiell zeitbeschränkt, wenn M p(n)-zeitbeschränkt für ein Polynom p(n) ist. Es folgt eine der wesentlichen Definitionen dieses Kapitels. 144 2.2.2 Definition (a) Für eine Funktion t : N → R+ definieren wir NTIME(t(n)) := {LM | ∃c > 0 : M ist c · t(n)-zeitbeschränkte NTM}. (b) NP := [ {NTIME(nk ) | k ≥ 1} = {LM | ∃c > 0, k ≥ 1 : M ist c · nk -zeitbeschränkte NTM}. (NP ist die Klasse der Sprachen zu Nichtdeterministischen Polynomiell zeitbeschränkten TM.) (c) co-NP := {L | L ∈ NP} (Komplemente von Sprachen in NP). Wie in Bemerkung 2.1.2 sieht man, dass NP die Menge der Sprachen LM für nichtdeterministische polynomiell zeitbeschränkte NTM M ist. Aus den Definitionen und der Tatsache, dass deterministische TMn nur spezielle NTMn sind, folgt sofort P ⊆ NP. Für die übersichtliche Konstruktion von nichtdeterministischen TMn stellen wir eine Hilfsmaschine bereit. Diese NTM ist nicht wegen ihres Akzeptierungsverhaltens interessant, sondern wegen des produzierten Bandinhalts. 2.2.3 Beispiel (Nichtdeterministisches Schreiben eines Binärstrings: Ratewort-TM“) ” Die Ratewort-TM MRatewort ist eine NTM mit folgendem Verhalten: Eingabe: 0n Ausgabe: Ein Binärwort b1 · · · bn ∈ {0, 1}n . Dabei soll jedes solche Wort als Ausgabe möglich sein, d. h. der Berechnungsbaum hat 2n Blätter. Die Idee ist einfach: man lese das eingegebene Wort von links nach rechts (Zustand q0 ), wandle dabei jede 0 nichtdeterministisch in 0 oder 1 um, stelle den Kopf wieder zurück auf die Ausgangsposition (Zustand q1 ) und halte (Zustand q2 ). Formal: Q = {q0 , q1 , q2 }, Σ = {0}, Γ = {0, 1, B}, δ wie folgt: δ(q0 , 0) δ(q0 , B) δ(q1 , a) δ(q1 , B) = = = = {(q0 , 0, R), (q0 , 1, R)} {(q1 , B, L)} {(q1 , a, L)} für a ∈ {0, 1} {(q2 , B, R)} . Für alle nicht explizit erwähnten Paare (q, a) gilt δ(q, a) = ∅. Auf Eingabe 0n macht MRatewort offenbar 2n+1 Schritte, d. h. sie ist 2n+1-zeitbeschränkt. Natürlich kann man nach demselben Prinzip für jedes Alphabet Σ eine NTM erstellen, die auf Eingabe 0n nichtdeterministisch ein Wort b1 · · · bn ∈ Σn schreibt. 145 2.3 Optimierungsprobleme und Sprachen in NP Viele Berechnungsaufgaben verlangen, dass man eine in einem bestimmten Sinn optimale Struktur findet: • einen kürzesten Weg von Knoten 1 zu Knoten n in einem Graphen G, • einen maximalen Fluss in einem Flussnetzwerk • ein VLSI-Layout für einen Schaltkreis mit möglichst kleiner Fläche • eine Aufteilung von n Jobs mit Bearbeitungszeiten l1 , . . . , ln auf m (gleichartige) Maschinen, so dass die maximale Bearbeitungszeit, über alle Maschinen betrachtet, minimal ist. Solche Optimierungsaufgaben fallen nicht direkt in unsere Kategorien Entscheidungs” probleme“ und Funktionen“. Allerdings findet man meistens eng verwandte Entschei” dungsprobleme und Funktionen, die mit unseren Mitteln klassifiziert werden können. Wir demonstrieren dies am Beispiel des Cliquenproblems. 2.3.1 Beispiel (a) Ist G = (V, E) ein ungerichteter Graph, so heißt V 0 ⊆ V eine Clique in G, falls die Knoten in V 0 einen vollständigen Teilgraphen bilden, d. h. wenn gilt: ∀v, w ∈ V 0 , v 6= w : (v, w) ∈ E. Dabei heißt |V 0 | die Größe der Clique. Beispiel : Im in Abb. 2.1 angegebenen Graphen 1 2 3 4 5 6 7 Abbildung 2.1: Ein Graph mit zwei maximal großen Cliquen bilden die Knotenmengen V 0 = {1, 2, 3, 7} und V 00 = {2, 3, 6, 7} jeweils eine Clique mit vier Knoten. Auch {1, 2} und {1, 2, 3} bilden Cliquen. Dagegen ist V 000 = V 0 ∪ V 00 = {1, 2, 3, 6, 7} keine Clique; überhaupt gibt es in G keine Clique mit fünf oder mehr Knoten. 146 (b) Das Cliquenproblem ist die Aufgabe, in einem gegebenen Graphen eine möglichst große Clique zu finden. Es kann in verschiedenen Formulierungen auftreten. Wir betrachten drei Varianten. (Ähnliche Varianten gibt es für viele Optimierungsprobleme.) Variante 1: (Optimierungsproblem im eigentlichen Sinn; Suche nach einer optimalen Struktur) Gegeben sei ein Graph G = (V, E). Aufgabe: Finde eine Clique V 0 ⊆ V , so dass |V 0 | ≥ |V 00 | für jede Clique V 00 in G. Variante 2: (Parameteroptimierung) Gegeben sei ein Graph G = (V, E). Aufgabe: Bestimme das maximale k ∈ N, so dass G eine Clique der Größe k hat. Variante 3: (Entscheidungsproblem) Gegeben seien G = (V, E) und k ∈ N. Frage: Gibt es in G eine Clique V 0 der Größe |V 0 | ≥ k? Man kann diese Varianten natürlich formalisieren. Dabei werden Parameteroptimierungsprobleme als Funktionen beschrieben, Entscheidungsprobleme als Sprachen. Optimierungsprobleme im eigentlichen Sinn erfordern eine neue Terminologie, hauptsächlich deswegen, weil die Ausgabe durch die Eingabe nicht eindeutig bestimmt ist (zu G kann es ja viele Cliquen maximaler Größe geben). Variante 2: Die Funktion fClique−Size ist folgendermaßen definiert: fClique−Size (hGi) = bin(kG ), wo kG = max{|V 0 | | V 0 ⊆ V ist Clique in G}, für beliebige Graphen G; falls w ∈ {0, 1}∗ keinen Graphen kodiert, ist fClique−Size (w) = ε. Variante 3: LClique := {hGibin(k) | k ≥ 1, G Graph über V = {1, . . . , m}, G hat Clique der Größe k}. LClique ist also eine Sprache über {0, 1}. Variante 1: Um Knotenmengen V 0 ⊆ V = {1, . . . , m} als Binärwörter darzustellen, benutzen wir charakteristische Vektoren“: die Menge V 0 ⊆ V entspricht dem Wort ” y = b1 · · · bm ∈ {0, 1}m mit bi = 1 ⇔ i ∈ V 0 , für 1 ≤ i ≤ m. Zu einem Graphen G = (V, E) mit V = {1, . . . , m} sei Sol(hGi) := {b1 · · · bm ∈ {0, 1}m | V 0 = {i | bi = 1} ist Clique in G}. (Die Menge der zulässigen Lösungen (engl. admissible solution) zum Graphen G ist die Menge aller seiner Cliquen.) Zu b1 · · · bm ∈ Sol(hGi) sei X m(hGi, b1 · · · bm ) := bi 1≤i≤m 147 die Größe der durch b1 · · · bm dargestellten Clique. Berechnet werden soll nun eine Funktion f : {0, 1}∗ → {0, 1}∗ , so dass für alle Graphen G gilt: f (hGi) ∈ Sol(hGi) und m(hGi, f (hGi)) ≥ m(hGi, y), für alle y ∈ Sol(hGi). (Falls w ∈ {0, 1}∗ keinen Graphen kodiert, ist f (w) = ε.) Es ist nicht sinnvoll zu verlangen, dass von f alle Cliquen maximaler Größe ausgegeben werden, da dann normalerweise die (Bit-)Länge der Ausgabe nicht mehr polynomiell in der Länge der Eingabe wäre. 2.3.2 Bemerkung Man sieht sofort die folgenden Implikationen ein: (i) Wenn es eine Funktion f mit den in Variante 1 verlangten Eigenschaften gibt, die durch einen Polynomialzeitalgorithmus berechenbar ist, d. h. mit f ∈ FP, dann ist auch fClique−Size in FP, d. h. die Größe einer maximal großen Clique ist in Polynomialzeit berechenbar. (Man berechnet eine Clique maximaler Größe und zählt, wieviele Knoten sie hat.) (ii) Wenn fClique−Size in FP ist, dann ist die Sprache LClique in P. (Auf Input w = hGibin(k) berechnet man l = fClique−Size (hGi) und akzeptiert genau dann wenn l ≥ k.) (Es sei (ohne Beweis) angemerkt, dass auch die umgekehrte Implikation gilt: (iii) Wenn LClique ∈ P ist, dann hat das eigentliche Optimierungsproblem aus Variante 1 einen Polynomialzeitalgorithmus.) Wir werden im weiteren Verlauf Indizien für die Vermutung angeben, dass LClique nicht in P ist. Mit (ii) und (i) folgt aus dieser Vermutung, dass kein Polynomialzeitalgorithmus existiert, der zu einem Graphen G eine maximal große Clique findet, oder der die maximal mögliche Cliquengröße berechnet. Für viele andere Optimierungsprobleme P geht man ähnlich vor: man findet ein verwandtes Entscheidungsproblem P 0 derart, dass aus jedem Polynomialzeitalgorithmus für P einer für P 0 gewonnen werden kann. Wenn man Grund zu der Annahme hat, dass für P 0 kein solcher Algorithmus existiert, so folgt das auch für (das eigentlich interessante) Optimierungsproblem P. Diese Situation ist der Grund dafür, dass wir in den folgenden Abschnitten anstelle der eigentlichen Optimierungsprobleme die verwandten Entscheidungsprobleme betrachten. 148 2.3.3 Beispiel Wir zeigen nun, dass die Sprache LClique aus dem vorhergehenden Beispiel in NP liegt. Dazu geben wir eine polynomiell zeitbeschränkte, nichtdeterministische NTM M mit LM = LClique an. Sie benutzt die NTM MRatewort aus Beispiel 2.2.3. Verfahren: Auf Eingabe w ∈ {0, 1}∗ tut M folgendes: 0. Prüfe, ob w das Format hGibin(k) hat, wo G ein Graph mit m Knoten 1, . . . , m ist, und 1 ≤ k ≤ m. Falls nicht, halte verwerfend. Sonst: 1. Ermittle m und schreibe 0m auf Band 2 (deterministisch); 2. Lasse MRatewort auf Band 2 ablaufen (nichtdeterministisch); Das auf Band 2 erzeugte Wort sei b1 · · · bm ∈ {0, 1}m . Dieses Binärwort liefert eine Knotenmenge V 0 = {i | 1 ≤ i ≤ m, bi = 1}. 3. Überprüfe (deterministisch): (α) Die Anzahl der Einsen in b1 · · · bm ist ≥ k; (β) V 0 ist Clique in G. Falls (α) und (β) zutreffen, halte akzeptierend, sonst halte verwerfend. Die folgende Skizze gibt die Struktur des resultierenden Berechnungsbaums CT (M, hGibin(k)) für einen Graphen mit m Knoten wieder. Sie repräsentiert auch allgemein die typische Struktur einer nichtdeterministischen Berechnung unter Verwendung von MRatewort . Teil 1 Teil 2 Tiefe m ... ... ... ... Teil 3 ... A V A V V A V V V m 2 Blätter akzeptiere/verwerfe 149 A V V Abbildung 2.2: Berechnungsbaum zu Beispiel 2.3.3 Wieso ist die von M akzeptierte Sprache genau LClique ? Dies lässt sich gut durch einen Blick auf den Berechnungsbaum einsehen. Wir betrachten nur Eingaben mit Format hGibin(k); die anderen werden durch den Syntaxcheck abgefangen. Wenn V 0 ⊆ V eine Clique der Größe k in G ist, dann betrachte das Binärwort b1 · · · bm mit V 0 = {i | 1 ≤ i ≤ m, bi = 1}. Auf einem der 2m Berechnungswege im Berechnungsbaum CT (M, hGibin(k)) erzeugt die Ratewortmaschine genau diesen Binärstring. Die folgende deterministische Überprüfung (Teil 3) endet damit, dass M akzeptierend hält. Also enthält CT (M, hGibin(k)) eine akzeptierende Berechnung; damit ist w ∈ LM . Wenn G keine Clique der Größe k enthält, dann auch keine irgendeiner Größe ≥ k. Daraus folgt aber, dass für jeden Binärstring b1 · · · bm die Überprüfung in Teil 3 der Berechnung von M liefert, dass dieser keine solche Clique beschreibt. Daher enden alle 2m Berechnungswege in CT (M, hGibin(k)) an einem verwerfenden Blatt. Damit ist w ∈ / LM . (Man kann sich überlegen, dass die akzeptierenden Blätter/Wege in CT (M, hGibin(k)) eineindeutig den Cliquen in G mit k oder mehr Knoten entsprechen.) Rechenzeit: Teile 0 und 1: O(m2 ) Schritte genügen für die Syntaxprüfung und die Bestimmung von m. Teil 2: 2m; Teil 3: O((m2 )l ) für eine Konstante l. Also insgesamt O(|w|l ), also polynomiell. Diese Zeitschranke gilt für jede der 2m Berechnungen. Die in Beispiel 2.3.3 konstruierte NTM für die Sprache LClique ist polynomiell zeitbeschränkt, also ist LClique ∈ NP. Hinweis: Man mache sich am einfachen Beispiel dieser NTM die Struktur der Berechnungen einer mit der Ratewortmaschine konstruierten NTM mit polynomieller Laufzeit für eine Sprache in NP klar. Die Laufzeitschranke tM (x) ≤ c|x|l bezieht sich auf die Tiefe des Berechnungsbaums, also die Länge eines längsten Weges. Die Anzahl der Wege und die Anzahl der Knoten im Berechnungsbaum ist hingegen exponentiell groß. Man hat also nicht die Möglichkeit, in polynomieller Zeit alle Berechnungen der NTM durchzu” probieren“, und eine solche NTM liefert keine Möglichkeit, irgendeine praktisch sinnvolle Rechnung in polynomieller Zeit durchzuführen. Vielmehr dient das künstliche Modell der polynomiell zeitbeschränkten NTMn nur dazu, die Klasse NP zu definieren. 2.3.4 Beispiel LRucksack : das Rucksackproblem Informal besteht das Rucksackproblem in folgendem: Gegeben sind ein Rucksack mit Volumen b und m verformbare Gegenstände mit Volumina a1 , . . . , am ∈ N sowie Nutzen” werten“ c1 , . . . , cm ∈ N. Man möchte einige der Gegenstände in den Rucksack packen und dabei den Gesamtnutzen maximieren, ohne die Volumenschranke zu überschreiten. Wir formulieren wieder drei Varianten. Mathematisch beschreibt man eine Auswahl der Gegenstände durch eine Menge I ⊆ {1, . . . , n}. Die Gegenstände i mit i P ∈ I werden eingepackt, die anderen nicht. Die Volumenschranke ist P eingehalten, falls i∈I ai ≤ b. Der Gesamtnutzen der durch I gegebenen Auswahl ist i∈I ci . 150 Variante 1: (Optimierungsproblem im eigentlichen Sinn; Suche nach optimaler Struktur) Gegeben seien b, a1 , . . . , am c1 , . . . , cP m ∈ N. Aufgabe: Finde I ⊆ {1, . . . , m} mit i∈I ai ≤ b, derart dass gilt: ∀J ⊆ {1, . . . , m} : X ai ≤ b i∈J ⇒ X ci ≤ i∈J X ci . i∈I Variante 2: (Parameteroptimierung) Gegeben seien b, a1 , . . . , am , c1 , . . . , cm ∈ N. Bestimme o nX X ci | I ⊆ {1, . . . , m}, ai ≤ b . k = max i∈I i∈I Variante 3: (Entscheidungsproblem) Gegeben seien b, a1 , . . . , am , c1 , . . . ,P cm ∈ N und k ∈P N. Frage: Gibt es I ⊆ {1, . . . , m} mit i∈I ai ≤ b und i∈I ci ≥ k? Die Formalisierung dieser Varianten als Sprachen bzw. Funktionen wird analog zum Cliquenproblem durchgeführt. Als Beispiel geben wir die Formalisierung des Entscheidungsproblems als Sprache an: LRucksack := n bin(a1 )# · · · # bin(am )##bin(c1 )# · · · #bin(cm )#bin(b)#bin(k) m ≥ 1, a1 , . . . , am , c1 , . . . , cm ∈ N, b, k ∈ N, o X X ∃I ⊆ {1, . . . , m} : ai ≤ b ∧ ci ≥ k . i∈I i∈I Mit dieser Formulierung ist LRucksack eine Sprache über {0, 1, #}. Wie üblich kann man die drei Zeichen des Alphabets nochmals über {0, 1} kodieren und so eine äquivalente Sprache über {0, 1} erhalten. Man sieht wieder sofort, dass aus jedem Polynomialzeitalgorithmus für die Optimierungsvariante des Rucksackproblems einer für das Entscheidungsproblem gewonnen werden könnte. Schließlich stellen wir fest: Behauptung: LRucksack ∈ NP. (Die entsprechende NTM benutzt die Ratewort-NTM in naheliegender Weise. Details: Übung.) 151 2.3.5 Beispiel (Das Problem des Handlungsreisenden — Traveling Salesperson Problem — TSP) Anschaulich besteht das TSP-Problem in folgendem: Gegeben sind m Städte, repräsentiert durch die Knoten 1, . . . , m des vollständigen Graphen, und Entfernungen zwischen jeweils zwei Städten, gegeben durch Zahlen aij ∈ N, 1 ≤ i < j ≤ m. (Hier und im folgenden wird für i > j immer aij := aji gesetzt.) Gesucht ist eine Rundreise“, die jede Stadt genau ” einmal besucht, mit minimaler Gesamtweglänge. 2.3.6 Beispiel Im in Abb. 2.3 angegebenen Graphen 1 5 9 2 3 10 9 10 12 6 8 5 4 9 5 Abbildung 2.3: Ein vollständiger Graph mit Kantenkosten bzw. Kantenlängen hat die Rundreise 1, 4, 3, 2, 5, 1 die Weglänge (Kosten) 6+5+10+8+9 = 38, die Rundreise 1, 2, 5, 3, 4, 1 hingegen die Weglänge 5 + 8 + 12 + 5 + 6 = 36. Einen Weg, der jeden Knoten genau einmal besucht, können wir durch eine Permutation π von {1, . . . , m} beschreiben. (Die Knoten werden in der Reihenfolge π(1), π(2), . . . , π(m), π(1) besucht.) Die Gesamtweglänge ist aπ(1)π(2) + · · · + aπ(m−1)π(m) + aπ(m)π(1) ; gesucht ist eine Rundreise, die diese Weglänge minimiert. Wieder können wir drei Varianten formulieren: Variante 1: (Optimierungsproblem im eigentlichen Sinn, Suche nach optimaler Struktur) Gegeben sei eine Zahl m ≥ 1 und m(m−1) Zahlen aij ∈ N, 1 ≤ i < j ≤ m. 2 Gesucht ist eine Permutation π von {1, . . . , m}, die unter allen Permutationen die kleinste Summe aπ(1)π(2) + · · · + aπ(m−1)π(m) + aπ(m)π(1) liefert. 152 Variante 2: (Parameteroptimierung) Die Eingabe ist wie P in Variante 1. Bestimme k = min{ 1≤i<m aπ(i)π(i+1) + aπ(m)π(1) | π Permutation von {1, . . . , m} }. Variante 3: (Entscheidungsproblem) Zahlen aij ∈ N, 1 ≤ i < j ≤ m, sowie eine Gegeben sei eine Zahl m ≥ 1 und m(m−1) 2 Zahl k ∈ N. Entscheide, ob es eine Rundreise mit Gesamtlänge ≤ k gibt, d. h. ob eine Permutation π von {1, . . . , m} existiert, die aπ(1)π(2) + · · · + aπ(m−1)π(m) + aπ(m)π(1) ≤ k erfüllt. Wieder kann man die Problemvarianten formalisieren; wir geben die Formalisierung der Entscheidungsvariante als Sprache an: n LTSP := bin(m)#bin(a12 )#bin(a13 )# · · · #bin(a1m )#bin(a23 )# · · · #bin(a2m )# · · · #bin(am−1,m )#bin(k) m ≥ 1, aij ∈ N, 1 ≤ i < j ≤ m, es existiert eine Permutation π von {1, . . . , m} o X mit aπ(i)π(i+1) + aπ(m)π(1) ≤ k . 1≤i<m Es ist klar, dass man aus einem Polynomialzeitalgorithmus für die Optimierungsvariante einen Polynomialzeitalgorithmus für die Sprache LTSP erhalten kann. Die umgekehrte Richtung (aus einem Polynomialzeitalgorithmus für Variante 3 könnte man einen für das Konstruktionsproblem, Variante 1, gewinnen), trifft ebenfalls zu, ist hier aber keineswegs offensichtlich. Auch die Sprache LTSP liegt in NP. Dies zeigt man durch Angabe einer NTM, die die Ratewort-NTM einsetzt, um nichtdeterministisch eine Permutation auf das Band zu schreiben. Technisch muss man etwas überlegen, wie Permutationen geeignet binär zu kodieren sind. (Details: Übung.) 2.3.7 Bemerkung Bisher haben wir sehr sorgfältig darauf geachtet, dass Elemente von Sprachen Wörter sind und die betrachteten Strukturen (Graphen, Zahlenfolgen) als Zeichenfolgen kodiert. Wir werden uns oft erlauben, diese Kodierung in der Notation zu unterdrücken und zum Beispiel anstelle von hGibin(k) einfach (G, k) und anstelle von bin(a1 )# · · · #bin(am ) einfach (a1 , . . . , am ) schreiben. Nur wenn man im Detail TM-Programme beschreibt, die die Eingaben bearbeiten, muss man sich auf geeignete Kodierungen beziehen. 153 Wir beobachten noch, dass NP nur rekursive Sprachen enthält; diese sind zudem deterministisch in Exponentialzeit berechenbar. 2.3.8 Lemma NP ⊆ [ l {DTIME(2n ) | l ∈ N}. (Insbesondere sind alle Sprachen in NP rekursiv.) Beweis Sei L ∈ NP. Nach der Definition existiert eine nichtdeterministische TM M = (Q, Σ, Γ, B, q0 , F, δ) für L und Konstanten d > 0 und k ∈ N, so dass für x ∈ Σ∗ der Berechnungsbaum CT (M, x) Tiefe höchstens d|x|k hat. Wir können annehmen (nach Satz 1.3.5 und der Version von Satz1.2.8 für NTMn), dass M nur ein Band benutzt. Weil jeder Knoten im Berechnungsbaum höchstens γ := 3|Q| · |Γ| Nachfolger haben kann, ist die Zahl der k Berechnungswege durch γ d|x| +1 beschränkt. In Analogie zur Konstruktion aus 1.3.11 kann man diese Berechnungswege systematisch nacheinander durchprobieren, jedoch braucht man nur eine einzige Zeitschranke d|x|k . Jeder Berechnungsversuch kostet Zeit O(d|x|k ). k 2k Der Gesamtzeitbedarf ist also O(d|x|k · 2(log γ)|x| ) = O(2|x| ). Die Frage, ob die im letzten Lemma angegebene drastische Laufzeiterhöhung beim Übergang von NTMn zu deterministischen TMn wirklich nötig ist, kann man knapp so fassen: Ist P = NP? Offenbar ist P ⊆ NP. Also heißt die Frage präziser: P-NP-Problem: Gibt es für jede Sprache L ∈ NP einen deterministischen polynomialzeitbeschränkten Algorithmus? Oder äquivalent: Gilt P = NP? Diese Frage ist ein — das wohl berühmteste — offene Problem der (Theoretischen) Informatik. Formuliert wurde es in moderner Sprache 1970 (von Edmonds), obgleich vorher schon vielen Forschern das Problem bewusst gewesen zu sein scheint (z. B. Gödel 1936). Die meisten Experten glauben, dass P und NP verschieden sind. Wir diskutieren diese Vermutung ausführlich in den nächsten Abschnitten. 2.4 Polynomialzeitreduktionen und NP-Vollständigkeit Für die folgende Definition vgl. Def. 1.9.6. Zum dortigen Reduktionskonzept fügen wir die Polynomialzeitberechenbarkeit der Reduktionsfunktion hinzu. 2.4.1 Definition Eine Sprache L1 über Σ1 heißt polynomialzeit-reduzierbar auf eine Sprache L2 über Σ2 , in Zeichen, L1 ≤p L2 , wenn L1 ≤ L2 mittels eines f ∈ FP gilt, d. h. wenn es eine in polynomieller Zeit berechenbare Funktion f : Σ∗1 → Σ∗2 gibt mit ∀x ∈ Σ∗1 : x ∈ L1 ⇔ f (x) ∈ L2 . 154 Achtung: Wie bei den Reduktionsfunktionen im Kontext der Berechenbarkeitstheorie ist es wichtig, dass f total ist und dass in der Bedingung an f die Äquivalenz x ∈ L1 ⇔ f (x) ∈ L2 und nicht nur eine Implikation steht. Wichtig ist auch, darauf zu achten, dass die TM, die ein solches f berechnet, deterministisch sein muss. Bevor wir konkrete Reduktionen anschauen, halten wir einige grundlegende Eigenschaften dieses Begriffs fest. 2.4.2 Lemma ≤p ist reflexiv und transitiv, d. h. (a) L ≤p L für beliebige Sprachen L, und (b) L1 ≤p L2 und L2 ≤p L3 impliziert L1 ≤p L3 . Beweis (a) Reflexivität ist klar (die Identitätsfunktion x 7→ x ist polynomialzeitberechenbar). (b) Zur Transitivität: Ist L1 ≤ L2 mittels f ∈ FP und L2 ≤ L3 mittels g ∈ FP, so ist L1 ≤ L3 mittels g ◦ f , denn x ∈ L1 ⇔ f (x) ∈ L2 ⇔ g(f (x)) = (g ◦ f )(x) ∈ L3 , für beliebige Eingaben x. Zu zeigen bleibt also: g ◦ f ∈ FP. Angenommen, f = fM1 und g = fM2 für c(nk + 1)- bzw. d(nl + 1)-zeitbeschränkte deterministische TM M1 bzw. M2 . Eine neue TM M tut folgendes auf Eingabe x: 1. Lasse M1 auf x ablaufen; Resultat y; 2. Lasse M2 auf y ablaufen; Resultat z; 3. Gib z aus. Offenbar gilt fM = g ◦ f . Die Rechenzeit von M wird abgeschätzt wie folgt. Entscheidend ist dabei die Beobachtung, dass |y| = |f (x)| ≤ tM1 (x) ist. tM (x) ≤ tM1 (x) + tM2 (f (x)) ≤ c(|x|k + 1) + d · ((c(|x|k + 1))l + 1) ≤ C · (|x|kl + 1), für eine passend gewählte Konstante C. Also ist M C(nkl + 1)-zeitbeschränkt, also g ◦ f ∈ FP. Anmerkung: Die Aussage der Transitivität sieht unscheinbar aus, aber sie ist für alles weitere extrem wichtig. Man sollte auch den Beweis gut verstanden haben und sich klarmachen, dass hinter ihm hauptsächlich die Eigenschaft steckt, dass das Einsetzen eines Polynoms in ein anderes wieder ein Polynom liefert. Es gibt einfache und komplexe Polynomialzeitreduktionen. Zum Eingewöhnen betrachten wir zwei recht einfache Reduktionen. Dazu definieren wir zwei weitere Graphenprobleme, die sich als mit dem Cliquenproblem eng verwandt erweisen werden. Für die Verfahren kommt es auf die Kodierung nicht an; daher tun wir so, als wären die Elemente unserer Sprachen mathematische Objekte wie Graphen oder Zahlen. Für die Bearbeitung mit Turingmaschinen muss man die Dinge natürlich in geeigneter Weise binär kodieren. 155 2.4.3 Definition (a) G = (V, E) sei ein Graph. Ein Knoten v überdeckt eine Kante (u, w) falls v ∈ {u, w}; eine Knotenmenge V 0 ist eine Knotenüberdeckung von (V, E), falls jede Kante in E von einem Knoten in V 0 überdeckt wird. Das Knotenüberdeckungsproblem ( vertex cover“) besteht darin, zu gegebenem Graphen G eine Knotenüberdeckung ” mit möglichst wenigen Knoten zu finden. Beispiel : G= Abbildung 2.4: Die schwarzen Knoten bilden eine Knotenüberdeckung minimaler Größe Die Entscheidungsvariante des Vertex-Cover-Problems lässt sich folgendermaßen als Sprache formulieren: LVC n := (G, k) | G = (V, E) Graph, k ≥ 1; es gibt V 0 ⊆ V mit |V 0 | ≤ k o und ∀(v, w) ∈ E : v ∈ V 0 ∨ w ∈ V 0 . (b) Wieder sei G = (V, E) ein Graph. Eine Teilmenge V 0 ⊆ V heißt unabhängig (oder stabil“, englisch independent“), wenn es zwischen Knoten von V 0 keine Kanten gibt. ” ” Das Problem Independent Set“ besteht darin, in G eine möglichst große unabhängige ” Menge zu finden. Beispiel: G= Abbildung 2.5: Die schwarzen Knoten bilden eine unabhängige Menge maximaler Kardinalität Die Entscheidungsvariante des Problems ist durch folgende Sprache gegeben: 156 LIS := {(G, k) | G = (V, E) Graph, k ≥ 1; es gibt V 0 ⊆ V mit |V 0 | ≥ k und ∀u, v ∈ V 0 : (u, v) 6∈ E} (c) (Erinnerung) LClique = {(G, k) | G = (V, E) Graph, k ≥ 1, G hat Clique der Größe ≥ k}. Wir zeigen nun, dass es zwischen allen drei genannten Problemen ≤p -Reduktionen gibt. 2.4.4 Satz (a) LClique ≤p LIS und LIS ≤p LClique . (b) LIS ≤p LVC und LVC ≤p LIS . Beweis (a) Zu G = (V, E) betrachte den Komplementgraphen Ḡ := (V, Ē), wo (v, w) ∈ Ē ⇔ (v, w) 6∈ E, für v, w ∈ V . Beispiel: G= G= Abbildung 2.6: schwarz: Clique in G, unabhängige Menge in Ḡ Setze: f ((G, k)) := (Ḡ, k). Man sieht leicht, dass f in Polynomialzeit berechenbar ist, gleichgültig ob die Graphen per Adjazenzmatrix oder über Kantenlisten dargestellt sind. Wir zeigen LClique ≤p LIS mittels f und LIS ≤p LClique mittels f. Zunächst macht man sich leicht folgende Hilfsbehauptung (HB1) klar: Für V 0 ⊆ V gilt: V 0 Clique in (V, E) ⇔ V 0 unabhängig in (V, Ē). Damit erhält man: 157 (G, k) ∈ LClique Def. ⇔ (HB1) G hat Clique der Größe k ⇔ Ḡ hat unabhängige Menge der Größe k Def. f ((G, k)) = (Ḡ, k) ∈ LIS . ⇔ Damit ist gezeigt: LClique ≤p LIS mittels f . Die andere Richtung (LIS ≤p LClique mittels f ) zeigt man genauso. (b) Wir benötigen folgende Hilfsbehauptung (HB2), die den engen Zusammenhang zwischen Knotenüberdeckungen und unabhängigen Mengen auf den Punkt bringt. Für V 0 ⊆ V gilt: V 0 ist unabhängige Menge in (V, E) ⇔ V − V 0 ist Knotenüberdeckung in (V, E). Beispiel: Abbildung 2.7: schwarze Knoten: Knotenüberdeckung, weiße Knoten: unabhängige Menge Man kann HB2 am einfachsten beweisen, indem man die Aussagen negiert: Für V 0 ⊆ V gilt: V 0 ist nicht unabhängig ⇔ V − V 0 ist keine Knotenüberdeckung. Dies ist leicht zu sehen: ∃v, w ∈ V 0 : (v, w) ∈ E ⇔ ∃(v, w) ∈ E : v ∈ V 0 ∧ w ∈ V 0 ⇔ ∃(v, w) ∈ E : v ∈ / V −V0∧w ∈ / V − V 0. Setze g(((V, E), k)) := ((V, E), |V | − k). Es ist leicht zu sehen, dass g in Polynomialzeit berechenbar ist. Weiter erhält man: ((V, E), k) ∈ LIS ⇔ (HB2) ⇔ ⇔ (V, E) hat unabhängige Menge der Größe ≥ k (V, E) hat Knotenüberdeckung der Größe ≤ |V | − k g(((V, E), k)) = ((V, E), |V | − k) ∈ LVC . Damit ist gezeigt: LIS ≤p LVC mittels g. Man zeigt genauso, dass LVC ≤p LIS mittels g. 158 Diese Beispiele sollten gezeigt haben, dass manche Polynomialzeitreduktionen sehr einfach sind. Nun kommen wir zur wichtigsten Definition des ganzen Kapitels. Man zeichnet die Sprachen in NP aus, die bezüglich der Relation ≤p über allen anderen stehen. 2.4.5 Definition (a) Eine Sprache L heißt NP-vollständig (engl. NP-complete“), falls ” (i) L ∈ NP (ii) für alle L0 ∈ NP gilt L0 ≤p L (hierfür sagt man: L ist NP-schwer [ NP-hard“, NP-hart“]). ” ” (b) NPC:= {L | L Sprache, L NP-vollständig}. Wir werden unten feststellen, dass die Sprachen LClique , LVC , LIS NP-vollständig sind. Das gleiche gilt für LRucksack und LTSP (siehe die Komplexitätstheorie-Vorlesung). Das folgende Lemma gibt einfache Beziehungen zwischen dem Reduktionsbegriff ≤p“ und der Klasse ” P an: 2.4.6 Lemma (a) L ∈ P ∧ L0 ≤p L ⇒ L0 ∈ P. (b) L ∈ P ∧ ∅ = 6 L0 6= Σ∗ ⇒ L ≤p L0 . Beweis (a) (Vergleiche Lemma 2.4.2(b).) Es sei L0 ≤p L mittels f ∈ FP. Man wählt eine TM M1 mit f = fM1 , die c(nk + 1)-zeitbeschränkt ist, und eine TM M2 mit L = LM2 , die dnl -zeitbeschränkt ist. Eine neue TM M tut folgendes auf Eingabe x: 1. Lasse M1 auf x ablaufen; Resultat y; 2. Lasse M2 auf y ablaufen; akzeptiere genau dann wenn M2 akzeptiert. Offenbar gilt x ∈ LM ⇔ M2 akzeptiert f (x) für alle x, also LM = L0 . Genau wie im Beweis von Lemma 2.4.2(b) sieht man, dass M O(nkl )-zeitbeschränkt ist. (b) Seien y0 ∈ Σ∗ − L0 und y1 ∈ L0 fest. (Solche Wörter gibt es, weil ∅ 6= L0 6= Σ∗ .) Die Abbildung ( y0 , falls x ∈ /L f : x 7→ y1 , falls x ∈ L ist in FP, da es für die Entscheidung, ob x ∈ L oder nicht, eine Polynomialzeit-TM gibt und weil y0 und y1 feste, von der Eingabe x nicht abhängige Wörter sind. Offensichtlich gilt x ∈ L ⇔ f (x) ∈ L0 , für alle x. Wir haben nun die Hilfsmittel gesammelt, die wir benötigen, um die zentrale strukturelle Aussage über die Klassen P, NP und NPC beweisen zu können. 159 2.4.7 Satz NPC ∩ P = ∅ ⇔ P 6= NP. Beweis Wir beweisen die Äquivalenz der umgekehrten Aussagen, also: NPC ∩ P 6= ∅ ⇔ P = NP. ⇐“ ist ganz einfach: Wenn P = NP ist, dann betrachte irgendein L ∈ P, nur nicht ∅ ” und nicht Σ∗ . Es gilt (i) L ∈ P = NP (klar); (ii) L0 ≤p L für alle L0 ∈ P = NP (nach Lemma 2.4.6(b)). Also ist L ∈ NPC ∩ P. (Man erkennt, dass man hier beweist, dass aus P = NP folgen würde, dass alle Sprachen in P außer ∅ und Σ∗ NP-vollständig sind.) ⇒“: Sei L ∈ NPC ∩ P. Wir zeigen P = NP. Weil P ⊆ NP auf jeden Fall gilt, müssen ” wir nur NP ⊆ P beweisen. Sei also L0 ∈ NP beliebig. Aus L ∈ NPC folgt nach Definition 2.4.5, dass L0 ≤p L gilt; daraus und aus L ∈ P folgt mit Lemma 2.4.6(a), dass L0 ∈ P ist, wie gewünscht. Der Satz macht klar, dass die die Frage Gilt P 6= NP?“ ” der Komplexitätstheorie äquivalent ist zu der für die Algorithmentheorie zentralen Frage Ist es richtig, dass kein NP-vollständiges Problem einen Polynomialzeit” Algorithmus, also einen Algorithmus mit vertretbarem Aufwand, hat?“ Leider ist es so, dass man heute nicht sagen kann, ob die Aussagen, deren Äquivalenz im Satz behauptet wird, beide zutreffen oder beide falsch sind. Die Frage, ob P 6= NP gilt, ist das berühmteste offene Problem der Theoretischen Informatik. Es wurde in dieser Form um 1970 formuliert. Für das Arbeiten im Alltag des Informatikers/der Informatikerin kann man aber den Experten (in Algorithmentheorie wie auch in der Komplexitätstheorie) folgen, die fast alle annehmen, dass P 6= NP ist. Wenn diese Vermutung stimmt, dann sind alle NP-schweren, insbesondere alle NP-vollständigen Probleme algorithmisch schwer ( intractable“) in dem ” Sinn, dass sie keine polynomialzeitbeschränkten Algorithmen besitzen. Für die Praxis bedeutet dies, dass man nicht versuchen sollte, für ein als NP-vollständig oder NP-schwer erkanntes Problem einen effizienten Algorithmus zu finden, sondern dass man besser nach Ausweichmöglichkeiten wie Approximationsalgorithmen oder Abschwächungen des Problems suchen sollte. Man erkennt ein Problem als NP-schwer, indem man es in der langen 160 Liste von bekannten NP-vollständigen und NP-schweren Problemen findet, oder indem man selbst, z. B. mit der bald zu besprechenden Reduktionsmethode, die NP-Vollständigkeit beweist. Folgendes kann als Indiz dafür gelten, dass vermutlich NPC ∩ P = ∅ ist: Wäre P = NP, dann besäßen alle NP-vollständigen Probleme Polynomialzeitalgorithmen. Jedoch wurde bisher noch kein einziges Problem in NPC ∩ P gefunden, trotz größter Anstrengungen von vielen Forschern, die sich mit ganz verschiedenen NP-vollständigen Problemen auseinandergesetzt haben. Als Veranschaulichung für die (vermutete) Situation mag folgendes Diagramm dienen: NP NPC P Sprachen, die effiziente Algorithmen haben 2.5 Der Satz von Cook Wir haben nun schon genau diskutiert, was es bedeutet, dass eine Sprache L NP-vollständig ist. Auch wurden schon eine ganze Reihe von Kandidaten angegeben, die in diese Kategorie fallen. Allerdings fehlt noch der Beweis für diese Behauptung. Dreh- und Angelpunkt der Theorie der NP-vollständigen Probleme ist das Erfüllbarkeitsproblem, das in diesem Abschnitt besprochen wird. In der Vorlesung wird die Definition angegeben und der Satz von Cook formuliert, aber nicht bewiesen. Für Neugierige enthält dieser Abschnitt den vollständigen Beweis. Wir kommen darauf in der Vorlesung Kom” plexitätstheorie“ ausführlich zurück. Obgleich die Terminologie etwas anders ist, ist es zum Verständnis des Folgenden günstig, sich an die Aussagenlogik zu erinnern. (Stichworte: Aussagevariablen A, B, C, . . . , Formeln wie A ∨ ¬A, A → B, (A → B) ↔ (¬B → ¬A), A → (B → C), . . . , Belegungen der Aussagevariablen mit Wahrheitswerten in {falsch, wahr }, {false, true}, oder {0, 1}, und die Auswertung einer Formel unter einer Belegung oder unter allen Belegungen z. B. mittels Wahrheitstafeln oder rekursivem Vorgehen.) Eine Formel ϕ heißt eine Tautologie, wenn sie unter jeder Belegung wahr ist. (Beispielsweise sind A ∨ ¬A und ((A → B) ∧ A) → B) Tautologien.) Klar ist: ϕ ist Tautologie genau dann wenn ¬ϕ nicht erfüllbar ist, d. h. wenn der Wert von ¬ϕ unter jeder Belegung falsch ist. Das Tautologieproblem ist das Problem, zu einer vorgelegten aussagenlogischen Formel ϕ zu entscheiden, ob ϕ eine Tautologie ist. Nach den eben gemachten Bemerkungen ist die 161 Frage, ob eine Formel erfüllbar ist, dazu äquivalent. Im Zentrum der Theorie der NP-Vollständigkeit steht, wenn auch mit etwas anderer Terminologie, eine spezielle Variante des Erfüllbarkeitsproblems. 2.5.1 Definition Wir definieren die syntaktische Struktur von KNF-Formeln. (a) Die Menge {X0 , X1 , X2 , X3 , . . .} heißt die Menge der Booleschen Variablen (≈ Aussagevariablen). (b) Die Menge {X0 , X̄0 , X1 , X̄1 , X2 , X̄2 , . . .} heißt die Menge der Literale. (X̄i , oder synonym ¬Xi , steht für die Negation der Variablen Xi .) (c) Sind l1 , . . . , ls Literale, s ≥ 1, so heißt (l1 ∨ · · · ∨ ls ) eine Klausel. (Eine Klausel ist eine Disjunktion von Literalen.) (d) Sind C1 , . . . , Cr Klauseln, r ≥ 1, so heißt C1 ∧ · · · ∧ Cr eine Formel in konjunktiver Normalform (KNF-Formel ). Beispiele: X1 und X̄1 (bzw. ¬X1 ) sind Literale, nicht aber X̄¯1 (bzw. ¬¬X1 ). (X1 ∨ X3 ∨ X1 ∨ X̄8 ) und (X̄2 ) sind Klauseln, nicht jedoch ((X1 ∧ X̄3 ) ∨ (X4 )). (X0 ) ∧ (X1 ∨ X3 ) ∧ (X̄0 ∨ X̄3 ) ist eine KNF-Formel. Formeln sind Texte und als solche nur syntaktische Objekte. Eine Formel kann nicht wahr oder falsch sein. Erst durch Belegungen erhalten Formeln Wahrheitswerte. Die Zahlen 0 und 1 stehen für die Wahrheitswerte falsch und wahr. 2.5.2 Definition (Belegungen, Wahrheitswerte von KNF-Formeln) (a) Eine Belegung der Booleschen Variablen ist eine Abbildung v : {X0 , X1 , X2 , . . .} → {0, 1}. Im folgenden beschreiben wir, wie eine gegebene Belegung v dazu benutzt wird, Literalen, Klauseln und KNF-Formeln Wahrheitswerte zuzuordnen. Diese werden als Erweiterung von v angesehen; entsprechend schreibt man v(l), v(C), v(ϕ) für diese Wahrheitswerte. (b) Durch die Belegung v erhält jede Boolesche Variable Xi den Wahrheitswert v(Xi ), das entgegengesetzte Literal X̄i den komplementären Wahrheitswert v(X̄i ) := 1 − v(Xi ) ∈ {0, 1}. (c) Wenn v eine Belegung ist, definieren wir für eine Klausel (l1 ∨ · · · ∨ ls ): ( 1, falls es ein j mit v(lj ) = 1 gibt, v(l1 ∨ · · · ∨ ls ) := 0, sonst. (Offenbar drückt dies die Semantik der ODER“-Verknüpfung aus: die Klausel wird ” unter der Belegung v wahr genau dann wenn mindestens eines der Literale darin unter v wahr ist.) 162 (d) Wenn v eine Belegung ist, definieren wir für eine KNF-Formel (C1 ∧ · · · ∧ Cr ): ( 1, falls v(Ci ) = 1 für alle i, v(C1 ∧ · · · ∧ Cr ) := 0, sonst. (Offenbar drückt dies die Semantik des UND“ aus: Die Formel wird wahr unter ” der Belegung v, wenn alle Klauseln unter v wahr sind.) 2.5.3 Beispiel (X0 ), (X1 ∨ X3 ), (X1 ∨ X2 ∨ X̄5 ) sind Klauseln, ϕ = (X0 ) ∧ (X1 ∨ X3 ) ∧ (X1 ∨X2 ∨ X̄5 ) ist KNF-Formel. Die Wahrheitswerte v(X0 ) = v(X1 ) = v(X2 ) = v(X5 ) = 0 und v(X3 ) = 1 machen die erste Klausel falsch, die beiden anderen wahr, daher ist v(ϕ) = 0: diese Belegung macht die Formel falsch. Die Wahrheitswerte v 0 (X0 ) = v 0 (X1 ) = 1 sorgen dafür, dass jede Klausel ein wahres Literal enthält, also wird damit v 0 (ϕ) = 1. Es ist klar, dass für den Wert v(ϕ) nur die Werte v(Xi ) von Bedeutung sind, für die Xi in ϕ vorkommt. Wenn ϕ genau m Variable enthält, dann gibt es genau 2m unterschiedliche Belegungen für diese Variablen. 2.5.4 Definition Eine KNF-Formel ϕ = C1 ∧ · · · ∧ Cr heißt erfüllbar, falls es eine Belegung v gibt, so dass v(ϕ) = 1 ist. 2.5.5 Beispiel Die Formel (X1 ∨X2 )∧(X̄1 ∨ X̄2 ) ist erfüllbar, weil v(X1 ) = 1, v(X2 ) = 0 beide Klauseln wahr macht. Dagegen ist die Formel (X1 ) ∧ (X̄1 ∨ X̄2 ) ∧ (X̄1 ∨ X2 ) nicht erfüllbar, was man z. B. einsieht, indem man alle vier möglichen Belegungen durchprobiert. Man kann auch die Formel (X0 ∨ X̄1 ) ∧ (X1 ∨ X̄2 ) ∧ (X2 ∨ X̄3 ) ∧ · · · (Xk−1 ∨ X̄k ) ∧ (Xk ∨ X̄0 ) ∧ (X0 ) ∧ (X̄k ) betrachten. Die Unerfüllbarkeit dieser Formel lässt sich (für größere k) nicht mehr durch Einsetzen feststellen. Wir definieren (informal): SAT := {ϕ | ϕ KNF-Formel, ϕ erfüllbar}. Die Menge SAT charakterisiert das Erfüllbarkeitsproblem, ist aber keine Sprache, weil kein endliches Alphabet zugrundeliegt, sondern die unendliche Menge {X0 , X1 , X2 , X3 , . . .} ∪ {(, ), ¬, ∧, ∨}. Hier hilft wieder einmal Kodierung. 2.5.6 Bemerkung (a) Man will Formeln über dem Alphabet Σ = {[, ], (,), ∧, ∨, ¬, 0, 1} kodieren. Dazu kodiert man z. B. Xi durch [bin(i)] und X̄i durch ¬[bin(i)], für i ∈ N. Die Formel ϕ = (X1 ∨ X2 ) ∧ (X̄1 ∨ X̄2 ) liest sich dann wie folgt: hϕi = ([1] ∨ [10]) ∧ (¬[1] ∨ ¬[10]). 163 Wir benutzen folgende Konvention: Xi wird als alternative Notation für [bin(i)] aufgefasst, X̄i als Notation für ¬[bin(i)]. Dann kann man die Kodierungsklammern weglassen. Wir bemerken: Die Sprache LKNF = {hϕi | ϕ ist KNF-Formel} über Σ ist regulär. Die Prüfung eines Wortes x ∈ Σ∗ darauf, ob es eine syntaktisch korrekte KNF-Formel darstellt, kann also von einem endlichen Automaten durch einmaliges Lesen von x durchgeführt werden. Wir werden im folgenden eine solche Syntaxüberprüfung meist nicht erwähnen. (b) Oft wird man während der Konstruktion einer Formel die Variablen anders benennen (z. B. unten im Beweis des Satzes von Cook: Xt,p,a , Yt,q , Zt,p ). Wenn eine solche Formel gegeben ist, ist es leicht, die verwendeten Variablen in X0 , X1 , X2 , . . . umzubenennen und wie in (a) als Wort über einem endlichen Alphabet zu schreiben. Eigenschaften wie Erfüllbarkeit ändern sich durch solche Manipulationen nicht. — Wir werden im folgenden meist keinen Unterschied mehr zwischen gewöhnlichen“ Formeln und ihren Kodierungen ” machen. 2.5.7 Definition (Das Erfüllbarkeitsproblem für KNF-Formeln) LSAT := {ϕ | ϕ KNF-Formel , ϕ erfüllbar } (oder ganz formal: {hϕi | ϕ KNF-Formel, ϕ erfüllbar } ). Aus technischen Gründen betrachtet man oft auch das Erfüllbarkeitsproblem für 3” KNF-Formeln“ wie (X2 ∨ X̄4 ∨ X7 ) ∧ (X̄0 ∨ X1 ∨ X4 ) ∧ (X2 ∨ X̄1 ∨ X6 ) ∧ (X̄1 ∨ X̄2 ∨ X4 ), in denen jede Klausel genau drei Literale besitzt. Das entsprechende Erfüllbarkeitsproblem heißt 3-SAT. 2.5.8 Definition (Das Erfüllbarkeitsproblem für 3-KNF-Formeln) L3−SAT := {ϕ ∈ LSAT | jede Klausel von ϕ hat genau 3 Literale }. Das Erfüllbarkeitsproblem ist von großer praktischer Relevanz; z. B. taucht bei der Konstruktion logischer Schaltungen das Teilproblem auf zu entscheiden, ob eine vorgelegte Boolesche Formel, die Teil der Schaltung werden soll, ohnehin immer nur 0“ ausgibt. ” Daneben sind LSAT und L3−SAT aber auch ausgezeichnete NP-vollständige Probleme. Das hat historische Gründe — LSAT war das erste nicht maschinennahe als NP-vollständig erkannte Problem (Cook, 1970) — und auch technische Gründe — LSAT und L3−SAT dienten und dienen als bequemer Anker“ für NP-Vollständigkeitsbeweise mittels der Redukti” onsmethode, siehe den folgenden Abschnitt. 164 2.5.9 Satz von Cook LSAT ist NP-vollständig. Beweis: Wir müssen die beiden Eigenschaften aus Definition 2.4.5 überprüfen: (i) LSAT ∈ NP, und (ii) LSAT ist NP-schwer, d. h. für alle L0 ∈ NP gilt L0 ≤p LSAT . (i) LSAT ∈ NP“: ” Wir beschreiben eine NTM M für LSAT . M tut folgendes auf Input x: (1) Prüfe, ob x = ϕ (genauer: x = hϕi) für eine KNF-Formel ϕ. Falls nicht: halte und verwerfe. (Dies ist von einem endlichen Automaten durchführbar.) (2) Schreibe auf Band 2: #[bin(i1 )]#[bin(i2 )]# · · · #[bin(im )], wobei [bin(i1 )], . . . , [bin(im )] genau die in ϕ vorkommenden Variablen (Kodierungen) sind, in beliebiger Reihenfolge, aber ohne Wiederholung. Hierzu schreibt man die Variablen von Band 1 ab und benutzt Textsuche, um Wiederholungen zu erkennen. (3) Schreibe 0m auf Band 3. (4) Lasse MRatewort auf Band 3 ablaufen. Resultat: b1 · · · bm ∈ {0, 1}m . (5) Ändere Band 2 zu b1 [bin(i1 )]b2 [bin(i2 )] · · · bm [bin(im )]. (6) Ersetze auf Band 1 jedes Teilwort [bin(ir )] durch br · · · br und jedes Teilwort ¬[bin(ir )] durch b̄r · · · b̄r . (Hierzu wird wieder Textsuche verwendet.) (7) Teste, ob auf Band 1 in jedem Paar von runden Klammern mindestens eine 1 vorkommt. (Diese Aufgabe kann durch einen endlichen Automaten gelöst werden.) Falls ja, akzeptiere, falls nein, verwerfe. Man sieht leicht, dass für jedes x gilt: x ∈ LSAT ⇔ x = ϕ für eine erfüllbare KNF-Formel ϕ ⇔ es existiert eine Belegung v (interessant nur die m Werte für die in ϕ vorkommenden Variablen) mit v(ϕ) = 1 ⇔ es gibt ein Binärwort b1 · · · bm , das in Schritten (5)–(7) dazu führt, dass M akzeptiert ⇔ es gibt eine akzeptierende Berechnung von M auf x. (Dabei entspricht die in einer akzeptierenden Berechnung geschriebene Bitfolge b1 · · · bm einer erfüllenden Belegung für die in x = ϕ vorkommenden Variablen.) Außerdem: M hat polynomielle Laufzeit. (ii) LSAT ist NP-schwer“: Dies ist viel schwieriger als Teil (i). ” Sei L ∈ NP beliebig, aber fest gewählt. Wir wollen zeigen, dass L ≤p LSAT gilt. Dazu gehen wir aus von einer polynomiell zeitbeschränkten NTM M 0 für L und bauen gemäß Satz 1.2.8 und Beispiel 1.2.4 M 0 zu M = (Q, Σ, Γ, B, q0 , F, δ) um mit: 165 • M hat ein Band • M betritt nie Zellen links der Eingabe • Anstatt zu halten, mit δ(q, a) = ∅, verharrt M in derselben Konfiguration, es gilt also δ(q, a) = {(q, a, N )}. Eine Konfiguration α1 (q, a)α2 ist also eine akzeptierende Haltekonfiguration“ genau dann wenn δ(q, a) = {(q, a, N )} und q ∈ F . ” • M hat polynomielle Laufzeit: tM (x) ≤ c|x|k für alle x ∈ Σ∗ , für gewisse Konstanten c, k ∈ N, c, k ≥ 1. Für x ∈ Σ∗ gilt: x ∈ L = LM ⇔ es existiert eine Berechnung initM (x) = k0 ` k1 ` · · · ` kT mit T = c|x|k , wobei kT einen Zustand q ∈ F enthält. Wenn wir uns die Bandzellen von M mit 1, 2, 3,. . . numeriert denken, ist klar, dass in jeder Berechnung von M auf x, |x| = n, der Kopf keine Zelle mit einer Nummer > T + 1 erreichen kann. Im folgenden beschreiben wir eine Reduktionsfunktion Φ, so dass L ≤p LSAT mittels Φ gilt. Es soll also gelten: Φ : Σ∗ → {ϕ | ϕ KNF-Formel}, x 7→ ϕx mit Φ ∈ FP, und ∀x ∈ Σ∗ : x ∈ L ⇔ ϕx hat eine erfüllende Belegung. Dazu bauen wir ϕx so auf, dass gilt: ∃ akzeptierende Berechnung von M auf x ⇔ ∃v : v(ϕx ) = 1. Der Rest des Beweises ist nicht prüfungsrelevant. Als Bausteine für ϕx führen wir drei Familien von Variablen ein. (a) Xt,p,a mit 0 ≤ t ≤ T , 1 ≤ p ≤ T + 1 und a ∈ Γ. Ein solches Xt,p,a symbolisiert die Aussage nach Schritt t steht in Zelle p das Zeichen ” a“. (b) Yt,q mit 0 ≤ t ≤ T und q ∈ Q. Ein solches Yt,q symbolisiert die Aussage nach Schritt t ist M im Zustand q“. ” (c) Zt,p mit 0 ≤ t ≤ T und 1 ≤ p ≤ T + 1. Ein solches Zt,p symbolisiert die Aussage nach Schritt t befindet sich der Kopf von ” M in Zelle p“. 166 Eine Belegung v für diese Variablen liefert dann Aussagen über eine Berechnung von M . Z. B. wird v(X3,5,# ) = 1 gelesen als nach Schritt 3 steht in Zelle 5 das Zeichen #“; ” v(Y4,q ) = 0 wird gelesen als nach Schritt 4 ist M nicht in Zustand q“. Natürlich gibt es ” jede Menge Belegungen, die zu widersprüchlichen Aussagen führen. (Zum Beispiel spricht eine Belegung v mit v(Z1,4 ) = 1 nie über eine korrekte Berechnung von M , weil nach Schritt 1 der Kopf nicht in Zelle 4 sein kann.) Uns interessieren Belegungen, die korrekte akzeptierende Berechnungen von M beschreiben. Die Formel ϕx ist als Konjunktion aus vielen Teilen aufgebaut, die folgendes erzwingen sollen: v ist erfüllende Belegung für ϕx ⇔ v beschreibt“ eine korrekte akzeptierende ” Berechnung von M . Für die Konstruktion von ϕx benutzen wir die folgenden Abkürzungen: ^ Sind C1 , . . . , Cr Klauseln, so steht Cu für die KNF-Formel C1 ∧ · · · ∧ Cr . 1≤u≤r Sind l1 , . . . , ls Literale, so steht _ lu für die Klausel (l1 ∨ · · · ∨ ls ). 1≤u≤s Nun geben wir die acht Teilformeln von ϕx an: (1) Genau ein Symbol pro Zelle und Schritt ϕ1 = ^ ^ 0≤t≤T 1≤p≤T +1 ^ _ Xt,p,a ∧ a,a0 ∈Γ a6=a0 a∈Γ X̄t,p,a ∨ X̄t,p,a0 Dabei sorgt der linke Ausdruck in der großen Klammer dafür, dass nur solche Belegungen ϕ1 erfüllen können, bei denen mindestens ein Symbol a pro Zelle und Schritt vorhanden ist. Der rechte Ausdruck sorgt dafür, dass nicht mehrere Zeichen pro Zelle und Schritt vorhanden sein können. Genauer macht man sich folgendes klar: v(ϕ1 ) = 1 ⇔ Für jedes Paar (t, p) existiert genau ein a ∈ Γ mit v(Xt,p,a ) = 1. (2) Genau ein Zustand pro Schritt ϕ2 = ^ _ Yt,q 0≤t≤T q∈Q ! ∧ ^ q,q 0 ∈Q q6=q 0 Ȳt,q ∨ Ȳt,q0 Man überlegt sich: v(ϕ2 ) = 1 ⇔ Für jedes t existiert genau ein q ∈ Q mit v(Yt,q ) = 1. 167 (3) Genau eine Kopfposition zu jedem Zeitpunkt ! ^ ^ _ ϕ3 = ∧ Z t,p 0≤t≤T 1≤p,p0 ≤T +1 p6=p0 1≤p≤T +1 Z̄t,p ∨ Z̄t,p0 Man überlegt sich: v(ϕ3 ) = 1 ⇔ für jedes t gibt es genau ein p, 1 ≤ p ≤ T + 1, mit v(Zt,p ) = 1. (4) Startkonfiguration ^ ϕ4 = (X0,p,ap ) ∧ 1≤p≤n ^ (X0,p,B ) ∧ (Y0,q0 ) ∧ (Z0,1 ) n+1≤p≤T Man überlegt sich: v(ϕ4 ) = 1 ⇔ die in v beschriebene Bandinschrift in Schritt 0 hat die Form a1 · · · an B · · · B; der Kopf steht auf Zelle 1; der Zustand ist q0 . (5) Endkonfiguration ϕ5 = _ YT,q q∈F Hier ist klar: v(ϕ5 ) = 1 ⇔ Es existiert ein q ∈ F mit v(YT,q ) = 1. (6) Wo der Kopf nicht ist, bleibt die alte Bandinschrift erhalten ^ ^ ^ ϕ6 = Zt−1,p ∨ X̄t−1,p,a ∨ Xt,p,a 1≤t≤T 1≤p≤T +1 a∈Γ Klar: v(ϕ6 ) = 1 gilt genau dann wenn [v(Zt−1,p ) = 0 ∧ v(Xt−1,p,a ) = 1 ⇒ v(Xt,p,a ) = 1], für alle t, p und a. Für (7) und (8) führen wir neue Hilfsvariablen ein: Ut,q,a,q0 ,a0 ,D mit 1 ≤ t ≤ T, q, q 0 ∈ Q, a, a0 ∈ Γ, D ∈ {L, R, N } und (q 0 , a0 , D) ∈ δ(q, a) Abkürzung: Ut,r für r = (q, a, q 0 , a0 , D). Ein solches Ut,r symbolisiert die Aussage in Schritt t wird die durch (q 0 , a0 , D) ∈ ” δ(q, a) gegebene Regel benutzt“. 168 (7) Genau ein Übergang ϕ7 = ^ 1≤t≤T _ r Regel Ut,r ! ∧ ^ r,r̄ Regeln r6=r̄ Ūt,r ∨ Ūt,r̄ Man zeigt: v(ϕ7 ) = 1 gilt genau dann wenn es für jeden Schritt 1 ≤ t ≤ T genau eine Regel r gibt, für die v(Ut,r ) = 1 ist. (8) Der in Schritt t benutzte Übergang ist legal (bzgl. Konfiguration kt−1 ) und hat bzgl. Kopfposition, Zelleninhalt und Zustand den vorgeschriebenen Effekt. ^ ^ ^ Ūt,r ∨ Z̄t−1,p ∨ Xt−1,p,a ∧ ϕ8 = 0 0 1≤t≤T 1≤p≤T +1 r=(q,a,q ,a ,D) Ūt,r ∨ Yt−1,q ∧ Regel 0 Ūt,r ∨ Z̄t−1,p ∨ X ∧ t,p,a Ūt,r ∨ Yt,q0 ∧ Ūt,r ∨ Z̄t−1,p ∨ Zt,p+d(D) , −1 0 wobei d(D) = 1 für D = L für D = N die Richtung der Kopfbewegung beschreibt. für D = R ϕx ergibt sich nun zu: ϕx = ϕ1 ∧ ϕ2 ∧ · · · ∧ ϕ8 . Nun müssen wir nur noch die X-, Y -, Z- und U -Variablen in die Standard-Variablenmenge {X0 , X1 , . . .} übersetzen. Hier arbeitet man am besten direkt mit den Binärdarstellungen der Indizes, z.B. durch Xt,p,a = [100 bin(t) bin(p) bin(a)], Yt,q = [101 bin(t) bin(q)], Zt,p = [110 bin(t) bin(p)], Ut,q,a,q0 ,a0 ,D = [111 bin(t) bin(q) bin(a) bin(q 0 ) bin(a0 ) bin(d(D))]. Dabei werden bin(t), bin(p) mit dlog(T + 2)e Bits und die Elemente von Q, Γ und D mit einer festen Bitzahl dargestellt. Auf die Erfüllbarkeit hat eine solche Umbenennung der Variablen keinen Einfluss. 169 Wir stellen fest: Durch Inspektion der acht Formelteile sieht man, dass jeder O(T 2 ) oder O(T 3 ) (Fall (3)) Literale und Verknüpfungszeichen enthält. Jedes Literal hat O(log T ) = O(log n) Zeichen. Zudem ist T = O(|x|k ), also log T = O(log |x|). Daraus folgt: |ϕx | = O(|x|3k+1 ). Weiter sieht man leicht ein, dass ϕx aus x in Polynomialzeit berechenbar ist. Zentrale Feststellung: x ∈ L ⇔ ϕx ∈ LSAT , für beliebiges x ∈ Σ∗ . Beweis: ⇒“: Sei x ∈ L, |x| = n. Dann existiert eine akzeptierende Berechnung mit cnk Schritten ” von M auf x. Wir belegen die Variablen genau entsprechend dem Ablauf dieser Berechnung, wie folgt: 1 nach Schritt t steht in Zelle p Buchstabe a v(Xt,p,a ) = 0 sonst. 1 nach Schritt t ist M in Zustand q v(Yt,q ) = 0 sonst. 1 nach Schritt t steht der Kopf in Zelle p v(Zt,p ) = 0 sonst. 1 in Schritt t wird Regel r = (q, a, q 0 , a0 , D) benutzt v(Ut,r ) = 0 sonst. Es ist nun eine langwierige, aber einfache Routineaufgabe, zu überprüfen, dass v die Formel ϕx = ϕ1 ∧ ϕ2 ∧ · · · ∧ ϕ8 erfüllt. Wir betrachten als Beispiel ϕ8 . Seien t, p und r = (q, a, q 0 , a0 , D) beliebig. Wir betrachten die fünf Klauseln, die sich auf t, p, r beziehen. 1. Fall: In Schritt t wird nicht Regel r benutzt. Dann ist v(Ūt,r ) = 1, also enthalten alle Klauseln ein wahres Literal. 2. Fall: In Schritt t wird Regel r benutzt. Dann ist M nach Schritt t − 1 in Zustand q und nach Schritt t in Zustand q 0 , also gilt v(Yt−1,q ) = v(Yt,q0 ) = 1. Also enthalten die Klauseln 2 und 4 zu t, p, r je ein wahres Literal. Fall 2a: Vor Schritt t ist der Kopf nicht in Zelle p. Dann ist v(Z̄t−1,p ) = 1, also enthalten die Klauseln 1, 3 und 5 zu t, p, r je ein wahres Literal. Fall 2b: Vor Schritt t ist der Kopf in Zelle p. Weil wir von einer korrekten Rechnung ausgehen, steht vor Schritt t in Zelle p der Buchstabe a, nachher der Buchstabe a0 , und nach Schritt t ist der Kopf bei Zelle p + d(D). Also v(Xt−1,p,a ) = v(Xt,p,a0 ) = v(Zt,p+d(D) ) = 1, und wieder enthalten die Klauseln 1, 3 und 5 je ein wahres Literal. 170 Schr. t 0 1 2 3 4 .. . Zust. q q0 q5 q8 q6 q10 .. . Kopfp. p 1 2 3 3 2 .. . Regel r — (q0 , a1 , q5 , d, R) (q5 , a2 , q8 , e, R) (q8 , a3 , q6 , b, N ) (q6 , b, q10 , m, L) .. . t−1 t .. . q q0 .. . p0 p0 + 1 .. . ··· (q, a, q 0 , a0 , R) .. . T qh ph ··· 1 a1 d d d d 2 a2 a2 e e e 3 a3 a3 a3 b m ··· ··· ··· ··· ··· ··· n an an an an an Band n+1 B B B B B .. . ··· ··· ··· ··· ··· ··· ··· ··· p0 B B B B B a a0 ··· ··· ··· ··· ··· ··· T B B B B B ··· ··· .. . ··· Tabelle 2.1: Berechnung einer NTM ⇐“: Sei ϕx ∈ LSAT . Dann hat ϕx eine erfüllende Belegung v. Offenbar gilt dann v(ϕ1 ) = ” · · · = v(ϕ8 ) = 1. Wir konstruieren aus v eine akzeptierende Berechnung von M auf x. Betrachte dazu das Schema in Tabelle 2.1. Es hat T + 1 Zeilen für die Schritte t = 0, . . . , T und Spalten für Zustand, Kopfposition und die Inschriften der Bandzellen 1, . . . , T + 1 in Schritten t = 0, . . . , T , sowie für die verwendete Regel r in Schritten t = 1, . . . , T . Wir lesen aus v eine Beschriftung für dieses Schema ab: in Zeile t, Spalte Zust.“ steht das q mit v(Yt,q ) = 1, ” Spalte Kopfp.“ steht das p mit v(Zt,p ) = 1, ” Spalte Regel“ steht das r mit v(Ut,r ) = 1, ” Spalte p im Teil Band“ steht das a mit v(Xt,p,a ) = 1. ” Es folgt direkt aus v(ϕ1 ) = v(ϕ2 ) = v(ϕ3 ) = v(ϕ7 ) = 1, dass diese Eintragungen stets konfliktfrei möglich sind. Die Eigenschaft v(ϕ4 ) = 1 garantiert, dass in Zeile 0 die Startkonfiguration von M zu x steht. Die Eigenschaft v(ϕ5 ) = 1 garantiert, dass in Zeile T eine akzeptierende Konfiguration von M steht. Die Eigenschaften v(ϕ6 ) = v(ϕ8 ) = 1 führen dazu, dass im Übergang von Zeile t − 1 zu Zeile t genau der zur Regel r gehörende Zug der TM M ausgeführt wird. Damit repräsentiert die Schemabeschriftung eine legale Berechnung von M . Weil M auf x höchstens T Schritte macht, steht in Zeile T eine (akzeptierende) Haltekonfiguration, also enthält das Schema eine akzeptierende Berechnung von M auf x. UFF! Dieser Beweis ist zugegebenermaßen sehr umfangreich. Man sollte ihn sich aber so lange durch den Kopf gehen lassen, bis man zumindest die Grundidee einleuchtend und einfach findet. 171 T +1 B B B B B Müssen wir für jeden NP-Vollständigkeitsbeweis diesen Aufwand treiben? Nein, zum Glück hilft das Konzept der Polynomialzeitreduktion, von LSAT ausgehend viel einfachere Beweise zu führen. 2.6 Einige NP-vollständige Probleme Wir haben im letzten Abschnitt festgestellt, dass LSAT NP-vollständig ist, durch direkte Reduktion einer beliebigen NP-Sprache L auf LSAT . Wenn man immer, für jedes Sprache L0 , diese Reduktion ausführen müsste, also Berechnungen von NTMn in das Problem L0 hineinkodieren, um zu zeigen dass L0 NP-vollständig ist, wäre wahrscheinlich der Theorie der NP-Vollständigkeit kein solcher Erfolg beschieden gewesen wie er sich in den letzten 35 Jahren eingestellt hat. Zum Glück geht es viel einfacher, zumindest in den meisten Fällen. Die Schlüsselmethode ist wieder Reduktion, wie bei den Unentscheidbarkeitsbeweisen. Sie hat es ermöglicht, für mehrere tausend Entscheidungsprobleme die NP-Vollständigkeit nachzuweisen. Aus Zeitgründen können wir in dieser Vorlesung nur einige wenige Beispiele für NP-Vollständigkeits-Beweise mit der Reduktionsmethode behandeln. Herausragendes Beispiel ist dabei das Cliquenproblem. Für Beweise für die NP-Vollständigkeit anderer wichtiger Probleme (insbesondere das TSP-Problem, das Rucksackproblem, Graphfärbbarkeitsprobleme, Hamilton-Kreis) sei auf die Vorlesung Komplexitätstheorie“ verwiesen. ” 2.6.1 Lemma (Reduktionsmethode) Wenn für eine Sprache L gilt: (i) L ∈ NP und (ii)∗ L0 ≤p L für ein L0 ∈ NPC, dann ist L NP-vollständig. Beweis Wir müssen die Bedingungen (i) und (ii) der Definition 2.4.5 nachprüfen. Offenbar ist nur (ii) zu zeigen, d. h. dass L00 ≤p L für jedes L00 ∈ NP. Weil nach Voraussetzung (ii)∗ L0 ∈ NPC ist, haben wir L00 ≤p L0 für jedes L00 ∈ NP, weiter ist nach Voraussetzung (ii)∗ L0 ≤p L. Daraus folgt mit 2.4.2(b) (Transitivität von ≤p ), dass L00 ≤p L für jedes L00 ∈ NP, was zu zeigen war. Wir wollen die Reduktionsmethode noch einmal als Handlungsanweisung formulieren: 172 Sei L eine Sprache. Um zu zeigen, dass L NP-vollständig ist, gehe folgendermaßen vor: (i) Zeige, dass L ∈ NP ist. (ii) Wähle eine geeignete als NP-vollständig bekannte Sprache L0 und zeige (durch Konstruktion der Reduktionsfunktion), dass L0 ≤p L. Oft spielt LSAT oder auch L3−SAT die Rolle von L0 . In der Praxis kann man auch ein beliebiges der vielen als NP-vollständig bekannten Probleme aus der Literatur nehmen und die Rolle von L0 spielen lassen. Damit es gerechtfertigt ist, in solchen Beweisen L3−SAT zu verwenden, das eine angenehmere Struktur als LSAT hat, benötigen wir folgenden Satz. 2.6.2 Satz L3−SAT ist NP-vollständig. Beweis Nach unserem Rezept zeigen wir zunächst L3−SAT ∈ NP. Hier können wir dasselbe Verfahren wie für LSAT benutzen (Beweis von Satz 2.5.9), nur muss der Syntaxcheck hier prüfen, ob die Eingabe eine 3-KNF-Formel ist. Nun bleibt zu zeigen: LSAT ≤p L3−SAT . Hierfür müssen wir eine Reduktionsfunktion definieren, die eine KNF-Formel ϕ in eine 3-KNF-Formel ϕ∗ transformiert derart, dass ϕ ist erfüllbar ⇔ ϕ∗ ist erfüllbar gilt. Bei der Beschreibung der Reduktionsfunktion ignorieren wir Kodierungen und das eher nebensächliche Problem, dass Inputs eventuell keine KNF-Formeln darstellen. (Ein einfacher Syntaxcheck ermittelt solche Inputs und bildet sie auf eine 3-KNF-Formel ab, die nicht erfüllbar ist.) Sei eine KNF-Formel ϕ = C1 ∧ · · · ∧ Cr gegeben. Wir bilden zu jeder Klausel Cj eine Formel ϕ∗j in 3-KNF-Form, um dann ϕ∗ = ϕ∗1 ∧ · · · ∧ ϕ∗r zu definieren. Sei dazu vorläufig j fest. Wie wird ϕ∗j aus Cj gebildet? Es gibt Literale l1 , . . . , ls mit Cj = (l1 ∨ · · · ∨ ls ). 1. Fall : s = 1. — Dann wähle zwei neue Variable Z1 und Z2 , die sonst nirgends vorkommen (insbesondere nicht in anderen Teilformeln ϕ∗j 0 , j 0 6= j) und definiere ϕ∗j = (l1 ∨ Z1 ∨ Z2 ) ∧ (l1 ∨ Z1 ∨ Z̄2 ) ∧ (l1 ∨ Z̄1 ∨ Z2 ) ∧ (l1 ∨ Z̄1 ∨ Z̄2 ). 173 2. Fall : s = 2. — Dann wähle eine neue Variable Z1 und definiere ϕ∗j = (l1 ∨ l2 ∨ Z1 ) ∧ (l1 ∨ l2 ∨ Z̄1 ). 3. Fall : s = 3. — Dann definiere ϕ∗j = (l1 ∨ l2 ∨ l3 ) = Cj . 4. Fall : s ≥ 4. — Dann wähle s − 3 neue Variable Z3 , Z4 , . . . , Zs−1 und definiere ϕ∗j = (l1 ∨ l2 ∨ Z3 ) ∧ (Z̄3 ∨ l3 ∨ Z4 ) ∧ (Z̄4 ∨ l4 ∨ Z5 ) .. . ∧ (Z̄s−2 ∨ ls−2 ∨ Zs−1 ) ∧ (Z̄s−1 ∨ ls−1 ∨ ls ) . Beispielsweise ergibt sich aus der Klausel Cj = (X2 ∨ X4 ∨ X̄5 ∨ X̄7 ∨ X8 ∨ X̄10 ) die Teilformel ϕ∗j = (X2 ∨ X4 ∨ Z3 ) ∧ (Z̄3 ∨ X̄5 ∨ Z4 ) ∧ (Z̄4 ∨ X̄7 ∨ Z5 ) ∧ (Z̄5 ∨ X8 ∨ X̄10 ). Wir stellen zunächst fest, dass die Transformation ϕ 7→ ϕ∗ so einfach ist, dass sie sicher in Polynomialzeit berechnet werden kann. Zu zeigen bleibt: Behauptung: ϕ ist erfüllbar ⇔ ϕ∗ ist erfüllbar. Man beachte, dass ϕ∗ mehr Variablen enthält als ϕ und daher die beiden Formeln nicht äquivalent“ sein können. Dennoch sind sie erfüllungsäquivalent“. ” ” Beweis der Behauptung: ⇒“: Eine Belegung v mit v(ϕ) = 1 sei gegeben. Wir definieren ” eine Belegung v ∗ für die Variablen in ϕ∗ , und prüfen, dass durch v ∗ alle Klauseln in ϕ∗ den Wert 1 bekommen, wie folgt. Zuerst setzen wir v ∗ (Xi ) = v(Xi ) für alle Xi , die in ϕ vorkommen. Für jedes j erhalten die neuen Variablen in ϕ∗j ihre Belegung anhand der Fälle für die Definition von ϕ∗j aus Cj = (l1 ∨ · · · ∨ ls ). 1. Fall : s = 1. Wenn Z1 , Z2 die neuen Variablen in ϕ∗j sind, dann setze v ∗ (Z1 ) = v ∗ (Z2 ) = 0. — Weil v(Cj ) = 1, muss v(l1 ) = 1 sein. Damit gilt auch v ∗ (l1 ) = 1, und alle vier Klauseln in ϕ∗j erhalten unter v ∗ den Wahrheitswert 1. 2. Fall : s = 2. Wenn Z1 die neue Variable in ϕ∗j ist, dann setze v ∗ (Z1 ) = 0. — Weil v(Cj ) = 1, muss einer der Werte v(l1 ) oder v(l1 ) gleich 1 sein. Damit ist auch v ∗ (l1 ) = 1 oder v ∗ (l2 ) = 1, und beide Klauseln in ϕ∗j erhalten unter v ∗ den Wahrheitswert 1. 174 3. Fall : s = 3. Dann ist ϕ∗j = Cj und v ∗ (ϕ∗j ) = v(Cj ) = 1. 4. Fall : s ≥ 4. Wenn Z3 , . . . , Zs−1 die neuen Variablen in ϕ∗j sind, dann verfahre wie folgt: Weil v(ϕ) = 1, ist auch v(Cj ) = 1, also gibt es ein k mit v(lk ) = 1. Für 3 ≤ h ≤ s − 1 setze ( 1 , falls h ≤ k, v ∗ (Zh ) = 0 , falls h > k. Dann erhalten unter v ∗ alle Klauseln in ϕ∗j den Wert 1, was man wie folgt einsieht: Die Klausel, die lk enthält, hat unter v ∗ den Wert 1, weil v ∗ (lk ) = v(lk ) = 1. Die vorangehenden Klauseln enthalten eine Variable Zh mit einem h ≤ k, und erhalten daher unter v ∗ den Wert 1; die darauffolgenden Klauseln enthalten ein Literal Z̄h mit einem h > k, und erhalten daher unter v ∗ ebenfalls den Wert 1. ⇐“: Nun sei eine Belegung v ∗ für die Variablen in ϕ∗ gegeben, die v ∗ (ϕ∗ ) = 1 erfüllt. Wir ” wollen zeigen, dass auch v ∗ (ϕ) = 1 gilt. Dazu ist zu zeigen, dass alle Klauseln von ϕ unter v ∗ den Wert 1 erhalten. Wir betrachten dazu eine beliebige Klausel Cj = (l1 ∨ · · · ∨ ls ). Wir wissen, dass v ∗ (ϕ∗j ) = 1 ist. 1. Fall : s = 1. — Dann ist ϕ∗j = (l1 ∨ Z1 ∨ Z2 ) ∧ (l1 ∨ Z1 ∨ Z̄2 ) ∧ (l1 ∨ Z̄1 ∨ Z2 ) ∧ (l1 ∨ Z̄1 ∨ Z̄2 ) mit zwei neuen Variablen Z1 , Z2 . In einer der vier Klauseln haben beide Literale zu Z1 und Z2 den Wahrheitswert 0; daher muss v ∗ (l1 ) = 1 sein. 2. Fall : s = 2. — Dann ist ϕ∗j = (l1 ∨ l2 ∨ Z1 ) ∧ (l1 ∨ l2 ∨ Z̄1 ) für eine neue Variable Z1 . In einer der beiden Klauseln erhält das Z1 -Literal unter v ∗ den Wahrheitswert 0; daher muss v ∗ (l1 ) = 1 oder v ∗ (l2 ) = 1 sein. 3. Fall : s = 3. — Dann ist ϕ∗j = Cj und daher v ∗ (Cj ) = 1. 4. Fall : s ≥ 4. — Dann ist ϕ∗j = (l1 ∨ l2 ∨ Z3 ) ∧ (Z̄3 ∨ l3 ∨ Z4 ) ∧ · · · ∧ (Z̄s−2 ∨ ls−2 ∨ Zs−1 ) ∧ (Z̄s−1 ∨ ls−1 ∨ ls ) mit s − 3 neuen Variablen Z3 , . . . , Zs−1 . Alle s − 2 Klauseln erhalten unter v ∗ den Wahrheitswert 1. Falls v ∗ (Z3 ) = 0 ist, muss v ∗ (l1 ∨ l2 ) = 1 sein und damit v ∗ (Cj ) = 1. Falls v ∗ (Zs−1 ) = 1 ist, muss v ∗ (ls−1 ∨ ls ) = 1 sein und wieder v ∗ (Cj ) = 1. Es bleibt der Fall v ∗ (Z3 ) = 1 und v ∗ (Zs−1 ) = 0. Das heißt: Die 0-1-Folge v ∗ (Z3 ), . . . , v ∗ (Zs−1 ) beginnt mit 1 und endet mit 0. Daher muss es ein k geben, 3 ≤ k ≤ s − 2, mit v ∗ (Zk ) = 1 und v ∗ (Zk+1 ) = 0. Weil v ∗ (Z̄k ∨ lk ∨ Zk+1 ) = 1, folgt v ∗ (lk ) = 1. Also enthält Cj ein Literal, das unter v ∗ den Wahrheitswert 1 erhält, wie gewünscht. Bemerkung: Falls ϕ die Eigenschaft hat, dass keine Klausel ein Literal zweimal enthält, dann gilt dies auch für ϕ∗ . Diese Eigenschaft ist für manche Reduktionen wichtig, die von dem Problem 3-SAT ausgehen. Exemplarisch zeigen wir nun, wie man mit der Reduktionsmethode beweist, dass LClique NP-vollständig ist. 175 2.6.3 Satz LClique ist NP-vollständig. 2.6.4 Korollar LVC und LIS sind NP-vollständig. Beweis von Korollar 2.6.4: Wir wenden die Reduktionsmethode an und verwenden als bekannte Sprache aus NPC die Sprache LClique . (i) Dass LVC und LIS in NP sind, zeigt man analog zur Konstruktion in Beispiel 2.3.3. (ii) Mit Satz 2.4.4 und Lemma 2.4.2(b) folgt LClique ≤p LIS und LClique ≤p LVC . Beweis von Satz 2.6.3: Wieder wird die Reduktionsmethode angewendet. (i) Dass LClique ∈ NP ist, haben wir schon in Beispiel 2.3.3 gesehen. (ii) Wir zeigen: L3−SAT ≤p LClique . Wir müssen also eine Funktion f definieren, die eine Eingabe ϕ für L3−SAT (also ϕ = C1 ∧ · · · ∧ Cr mit Cj Klausel mit 3 Literalen für 1 ≤ j ≤ r) abbildet auf eine Eingabe f (ϕ) = (Gϕ , kϕ ) für das Problem LClique . Dabei soll gelten: • f ∈ FP, d. h. f ist polynomialzeitberechenbar, und • Für jede 3-KNF-Formel ϕ gilt: ϕ ∈ L3−SAT ⇔ f (ϕ) = (Gϕ , kϕ ) ∈ LClique . (Für Puristen: damit f total ist, muss man noch z. B. f (x) := ε 6∈ LClique definieren für Eingaben x für L3−SAT , die nicht eine 3-KNF-Formel darstellen.) Wir betrachten nun eine feste Eingabe ϕ = C1 ∧ · · · ∧ Cr für L3−SAT , wobei Cj = (lj1 ∨ lj2 ∨ lj3 ), 1 ≤ j ≤ r, für Literale ljs , 1 ≤ j ≤ r, 1 ≤ s ≤ 3, und definieren den ungerichteten Graphen Gϕ = (Vϕ , Eϕ ) und die Zahl kϕ . Der Graph Gϕ hat 3r Knoten vjs , 1 ≤ j ≤ r, 1 ≤ s ≤ 3. Jeder Literalposition“ ljs ” entspricht ein Knoten. Anschaulich kann man sich die Knoten in r Spalten zu je drei Knoten angeordnet denken, eine Spalte für jede Klausel. Auch kann man Knoten vjs mit ljs beschriften, allerdings gibt es eventuell mehrere Knoten mit derselben Beschriftung. Innerhalb einer Spalte gibt es keine Kanten. Andere Knoten sind genau dann miteinander verbunden, wenn sie nicht zu entgegengesetzten Literalen Xi und X̄i gehören. Formal: Vϕ := {vjs | 1 ≤ j ≤ r, 1 ≤ s ≤ 3} und Eϕ := {(vjs , vj 0 s0 ) | 1 ≤ j 6= j 0 ≤ r, ljs , lj 0 s0 sind nicht entgegengesetzte Literale }. Zuletzt definieren wir Gϕ := (Vϕ , Eϕ ) und kϕ := r. 176 Beispiel : Eingabe für L3−SAT : ϕ = (X1 ∨ X̄2 ∨ X̄4 ) ∧ (X2 ∨ X1 ∨ X3 ) ∧ (X̄1 ∨ X̄2 ∨ X4 ). v v 11 X X 1 v 21 X 2 31 1 v 12 v v X 2 22 X X 1 32 2 v v 13 X 4 X X 3 v 33 4 23 Abbildung 2.8: Ein Graph Gϕ zu einer 3-KNF-Formel ϕ Der Graph Gϕ hat neun Knoten v11 , v12 , v13 , v21 , v22 , v23 , v31 , v32 , v33 . Die Kantenmenge besteht aus allen ungeordneten Paaren (vjs , vj 0 s0 ) mit j 6= j 0 außer den Paaren (v11 , v31 ), (v22 , v31 ) (Literale X1 und X̄1 ), (v12 , v21 ) (Literale X̄2 und X2 ), (v21 , v32 ) (Literale X2 und X̄2 ), (v13 , v33 ) (Literale X̄4 und X4 ). Man sieht leicht ein, dass die Funktion f , die durch f (ϕ) := (Gϕ , kϕ ) gegeben ist, polynomialzeitberechenbar ist. Wir müssen also noch zeigen: ϕ ∈ L3−SAT ⇔ f (ϕ) ∈ LClique , d. h. ϕ erfüllbar ⇔ (Gϕ , kϕ ) ∈ LClique , oder in Worten: Es gibt eine Belegung v, so dass jede Klausel von ϕ ein wahres Literal enthält ⇔ Gϕ hat eine Clique der Größe r. Beweis dazu: ⇒“: Sei v eine Belegung, die in jeder Klausel Cj , 1 ≤ j ≤ r, ein Literal ” wahr macht. Für jedes j wählen wir ein sj ∈ {1, 2, 3} mit v(lj,sj ) = 1. Dann ist die Menge V 0 := {vj,sj | 1 ≤ j ≤ r} eine Clique in Gϕ . Ist nämlich j 6= j 0 , so kann es wegen v(lj,sj ) = v(lj 0 ,sj 0 ) = 1 nicht sein, dass lj,sj und lj 0 ,sj 0 entgegengesetzte Literale sind. Also ist (vj,sj , vj 0 ,sj 0 ) eine Kante in Gϕ . — Dass |V 0 | = r ist, ist offensichtlich. ⇐“: Sei V 0 ⊆ Vϕ eine Clique in Gϕ mit r Knoten. Weil die Knoten, die zu einer Klausel ” Cj gehören, nicht miteinander verbunden sind, gehören die r Knoten zu unterschiedlichen 177 Klauseln. Also gibt es für jedes j, 1 ≤ j ≤ r, genau ein sj ∈ {1, 2, 3}, so dass V 0 = {vj,sj | 1 ≤ j ≤ r} ist. Wir definieren eine Belegung v folgendermaßen: ( 1 falls Xi = lj,sj für ein j, v(Xi ) := 0 sonst. Diese Belegung erfüllt jede Klausel Cj , denn: 1. Fall : lj,sj ist eine Variable Xi . — Dann gilt v(Xi ) = 1 nach der Definition von v, also enthält Cj ein wahres Literal. 2. Fall : lj,sj ist eine negierte Variable X̄i . — Weil V 0 eine Clique in Gϕ ist, kann kein Literal lj 0 ,sj 0 , j 0 6= j, gleich Xi sein. Also ist v(Xi ) = 0, nach der Definition von v; daraus folgt v(X̄i ) = 1 und v(Cj ) = 1. 178