Deterministische Turing-Maschinen Um 900 präsentierte David Hilbert auf einem internationalen Mathematikerkongress eine Sammlung offener Fragen, deren Beantwortung er von zentraler Bedeutung für die weitere Entwicklung der Mathematik im 0. Jahrhundert hielt. Eine dieser Fragen befasste sich mit den logischen Grundlagen der Mathematik und lässt sich folgendermaßen formulieren:. Ist die Mathematik vollständig, d.h., kann jede mathematische Aussage bewiesen oder widerlegt werden?. Ist die Mathematik konsistent, d.h., ist es ausgeschlossen, dass sowohl eine Aussage als auch ihr Gegenteil bewiesen werden kann? 3. Ist die Mathematik entscheidbar, d.h., gibt es eine definitive Methode, die für jede mathematische Aussage feststellt, ob diese wahr oder falsch ist? Hilbert war der festen Überzeugung, dass alle diese Fragen positiv beantwortet werden könnten. Im Jahr 93 zeigte allerdings Kurt Gödel 3, dass jede Formalisierung der Arithmetik entweder inkonsistent oder unvollständig sein muss; darüber hinaus bewies er, dass es nicht möglich ist, die Konsistenz der Arithmetik innerhalb dieser selbst zu zeigen. Offen blieb vorerst der dritte Teil der Frage, wenn auch in etwas veränderter Form: 3. Gibt es eine definitive Methode, die für jede mathematische Aussage feststellt, ob diese beweisbar ist oder nicht? Definitive Methode bedeutet hier mechanisches Verfahren oder Algorithmus. Um diese Frage positiv beantworten zu können, genügt es, einen Algorithmus anzugeben, der in der Lage ist, jede Aussage auf Beweisbarkeit zu überprüfen. Eine Verneinung der Frage hingegen verlangt den Nachweis, dass kein einziger Algorithmus dazu in der Lage ist. Dies setzt aber einen exakten Begriff davon voraus, was Algorithmus bzw. mechanisch machbar bedeutet. Zu diesem Zweck führte Alan Turing in seiner Arbeit On computable numbers, with an application to the Entscheidungsproblem (936) ein abstraktes Maschinenmodell (die sogenannte Turing-Maschine) ein, mit dem jedes mechanische Verfahren simuliert werden kann. Turing zeigte in diesem Artikel, dass es keine Turing-Maschine geben kann, die die (Un)Beweisbarkeit jeder beliebigen Aussage feststellt, und beantwortete damit den dritte Teil von Hilbert s Frage negativ. Eine Turing-Maschine besteht aus einem unendlichen Band, das beschrieben und gelesen werden kann, sowie aus einem endlichen Automaten, der das Lesen und Schreiben des Bandes steuert (Abb. ). In der Terminologie realer Computer entspricht der endliche Deutscher Mathematiker, 86 93 Das sogenannte Hilbert-Programm. 3 Österreichischer Mathematiker, geboren 906 in Brünn (Brno, Tschechische Republik), gestorben 978 in der USA Englischer Mathematiker, 9 95
Endlicher Automat Band Schreib-/Lesekopf 3 0 3 Abbildung : Schematische Darstellung einer deterministischen Turing-Maschine Automat dem Prozessor und das Band dem Speicher. Formal lässt sich eine Turing- Maschine folgendermaßen definieren: Definition Eine deterministische Turing-Maschine wird durch ein Siebentupel T = Q, Σ, Γ, δ, q 0,, F beschrieben, wobei wie bei den endlichen Automaten Q eine endliche Menge von Zuständen, q 0 Q der Anfangszustand, F Q eine Menge von Endzuständen und Σ das Eingabealphabet ist. Die Menge Γ heißt Bandalphabet und enthält sowohl das Eingabealphabet als auch das Leersymbol. Letzteres darf nicht im Eingabealphabet vorkommen, d.h., Σ Γ {}. Die Funktion δ: Q Γ Q Γ {L, R} heißt Übergangsfunktion. Als Eingabe für eine Turing-Maschine dient eine Zeichenkette x Σ, die sich in den Feldern bis x des Bandes befindet, wobei jedes Zeichen genau ein Feld belegt. Alle anderen Felder sind zu Beginn mit dem Leersymbol initialisiert. Die Berechnung beginnt im Anfangszustand q 0, der Schreib-/Lesekopf befindet sich über dem Feld mit der Nummer. Die weiteren Schritte erfolgen nun entsprechend der Übergangsfunktion δ. Sei q der momentane Zustand. Falls q ein Endzustand ist, gilt die Eingabe als akzeptiert. Andernfalls wird das Symbol s Γ unter dem Schreib-/Lesekopf gelesen. Ist δ(q, s) = (q, s, ), wechselt die Turing-Maschine vom Zustand q in den Zustand q, das Bandsymbol s wird durch das Symbol s überschrieben, und der Schreib-/Lesekopf rückt ein Feld nach links, falls = L, oder ein Feld nach rechts, falls = R. Die momentane Berechnungssituation einer Turing-Maschine wird vollständig durch den Inhalt des Bandes, die Position des Schreib-/Lesekopfes und den Zustand beschrieben. Diese drei Komponenten werden in der sogenannten Konfiguration zusammengefasst. Diese ist eine Zeichenkette der Form w qw, wobei w, w Γ und q Q. Intuitiv bedeutet w qw, dass sich die Turing-Maschine im Zustand q befindet, das Band mit w w beschriftet ist und der Schreib/Lesekopf über dem ersten Zeichen von w steht. Zusätzlich vereinbaren wir, dass w qw gleichbedeutend mit m w qw n für alle m, n 0 ist, d.h., vor und nach w w können bei Bedarf beliebig viele Leersymbole eingefügt werden. Der Berechnungsvorgang kann nun formal durch die Rechenschrittrelation beschrieben werden:
x R 0 y a/x R a,y b/y R b,z c/z L 3 a,b,y,z R y,z R 5 Abbildung : Turing-Maschine für {a n b n c n n 0} uqav ubq v falls δ(q, a) = (q, b, R) ucqav uq cbv falls δ(q, a) = (q, b, L) wobei u, v Wörter über dem Bandalphabet, a, b, c Symbole des Bandalphabets und q, q Zustände sind. Die reflexive und transitive Hülle von wird mit bezeichnet. Damit lässt sich die von einer Turing-Maschine T akzeptierte Sprache definieren als L(T ) = {w Σ q 0 w uq f v, q f F, u, v Γ } Graphische Darstellung von Turing-Maschinen Turing-Maschinen können als Graphen dargestellt werden. Jeder Knoten des Graphen entspricht einem Zustand aus Q, jede Kante einem möglichen Zustandsübergang. Vom Knoten q führt genau dann eine mit (s, s, ) beschriftete Kante zum Knoten q, wenn δ(q, s) = (q, s, ) gilt: (s, s, ) q q wenn δ(q, s) = (q, s, ). Die graphische Darstellung lässt sich vereinfachen, wenn die Turing-Maschine richtungsgebunden ist, d.h., wenn für jeden Zustand q gilt: jede Kante, die zum Knoten q führt, ist mit derselben Richtungsangabe, L oder R, beschriftet. Diese Angabe kann daher direkt zum Knoten, der q entspricht, geschrieben werden. Da weiters meist das gelesene und das geschriebene Symbol identisch sind, reicht es in diesen Fällen, die Kante lediglich mit einem einzigen Bandsymbol zu beschriften. Wir erhalten damit: q s q wenn δ(q, s) = (q, s, ), und q s/s q wenn δ(q, s) = (q, s, ), wobei s s. Beispiel Abbildung zeigt den Graphen einer Turing-Maschine, die die Sprache {a n b n c n n 0} akzeptiert. In Tupel- und Tabellenschreibweise wird die Turing-Maschine be- 3
R 0 a X R R 5 X a/x R a a/x R X 3 a,x L Abbildung 3: Turing-Maschine für {a n n 0} schrieben durch wobei δ definiert ist durch: {0,,, 3,, 5}, {a, b, c}, {a, b, c, x, y, z, }, δ, 0,, {5} δ a b c x y z 0 (, x, R) (, y, R) (5,, R) (, a, R) (, y, R) (, y, R) (, b, R) (3, z, L) (, z, R) 3 (3, a, L) (3, b, L) (0, x, R) (3, y, L) (3, z, L) (, y, R) (, z, R) (5,, R) Wie schon bei den Automaten lässt sich die Übergangsfunktion zu einer totalen Funktion machen, indem man eine Falle hinzufügt. Beispiel Abbildung 3 zeigt den Graphen einer Turing-Maschine, die die Sprache {a n n 0} akzeptiert. In Tupel- und Tabellenschreibweise wird die Turing-Maschine beschrieben durch {0,,, 3,, 5}, {a}, {, a, X}, δ, 0,, {5} wobei δ definiert ist durch: δ a X 0 (, a, R) (5,, R) (, X, R) (, X, R) (,, L) (3, a, R) (, X, R) 3 (, X, R) (3, X, R) (0,, R) (, a, L) (, X, L) Funktionsweise der Turing-Maschine: n ist genau dann eine Zweierpotenz, wenn entweder n = oder wenn n durch teilbar und n eine Zweierpotenz ist. Entsprechend wird
in jedem Durchlauf durch die Schleife 0, 3 0 die Anzahl der auf dem Band stehenden a s halbiert, indem jedes zweite a durch X ersetzt wird. Ist die Anzahl der a s ungerade, trifft die Turing-Maschine entweder im Zustand oder im Zustand 3 auf ein Leersymbol. In bedeutet dies, dass nur mehr ein einziges a vorhanden ist; damit terminiert die Turing-Maschine im Endzustand 5. In 3 hingegen zeigt das Leersymbol an, dass die Halbierung nicht möglich ist, da die Anzahl der a s zu Beginn des Schleifendurchlaufes ungerade war. Die Turing-Maschine bleibt aufgrund fehlender Übergangsmöglichkeiten daher in diesem Nicht-Endzustand stecken und akzeptiert die Eingabe nicht. Dasselbe gilt, falls das Band zu Beginn der Ausführung ganz leer ist (n = 0). Als Beispiel einer Berechnung zeigen wir, dass das Wort aaaa von der Turing-Maschine akzeptiert wird. Wir nehmen in der Konfigurationsbeschreibung links und rechts der Eingabe noch ein Leersymbol hinzu, da diese Felder während der Abarbeitung inspiziert werden. 0 aaaa a aaa ax aa axa 3 a axax axa X ax ax a XaX axax axax ( ) ( ) 0 axax a XaX ax ax axx X axxx axx X ax XX a XXX axxx axxx ( ) ( ) 0 axxx a XXX ax XX axx X axxx axxx 5 Beispiel Abbildung zeigt den Graphen einer Turing-Maschine, die die Sprache {w {a, b} na(w) = n b (w)} akzeptiert. (n s (w) bezeichnet die Anzahl der Vorkommnisse des Symbols s im Wort w.) In Tupel- und Tabellenschreibweise wird die Turing-Maschine beschrieben durch wobei δ definiert ist durch: {0,,, 3,, 5, 6}, {a, b}, {, a, b, X}, δ, 0,, {6} δ a b X 0 (6,, R) (3, X, R) (, X, R) (0, X, R) (, X, R) (, b, R) (, X, R) (5, X, L) (, b, R) (, X, R) 3 (, X, R) (, X, R) (3, X, R) (, a, R) (5, X, L) (, X, R) 5 (0,, R) (5, a, L) (5, b, L) (5, X, L) 5
b,x b,x R a/x R b/x a/x R L 0 5 b/x a/x b/x R a/x R R 6 3 X a,x Abbildung : Turing-Maschine für {w {a, b} na(w) = n b (w)} Funktionsweise der Turing-Maschine: Das Band wird von links nach rechts gelesen; dabei wird das erste Vorkommnis des Symbols b sowie die ersten beiden Vorkommnisse von a in ein X umgewandelt. Es müssen drei mögliche Anordnungen berücksichtigt werden: ein b gefolgt von zwei a s (entspricht den Zustandsübergängen 0 5), ein a gefolgt von einem b gefolgt von einem a (0 3 5), sowie zwei a s gefolgt von einem b (0 3 5). Anschließend geht der Schreib-/Lesekopf zurück an den Anfang des Bandes, ein neuer Zyklus beginnt. Wird im Zustand 0 ein Leersymbol angetroffen, wurden genau zweimal so viele a s wie b s in ein X umgewandelt, daher erfolgt der Übergang in den Endzustand 6. In den Zuständen q,..., q bedeutet ein hingegen, dass das analysierte Wort nicht in der Sprache liegt, daher gibt es keine entsprechenden Übergänge. Trotz ihrer Einfachheit können Turing-Maschinen jede beliebige Aufgabe lösen, die auch von einem Computer ausgeführt werden kann; sie können etwa dazu verwendet werden, Funktionen zu berechnen. Insbesondere lässt sich mittels Turing-Maschinen auch der Begriff des Algorithmus exakt definieren. Definition Eine Funktion f: D R heißt Turing-berechenbar oder einfach nur berechenbar, wenn es eine Turing-Maschine Q, Σ, Γ, δ, q 0,, F gibt, sodass q 0 d q f f(d) (q f F ) gilt für alle d D. Diese Turing-Maschine wird als Algorithmus zur Berechnung der Funktion bezeichnet. Für mehrstellige Funktionen vereinbart man irgendein beliebiges Symbol, mit dem die einzelnen Argumente auf dem Band voneinander getrennt werden. Beispiel Wir zeigen, dass die Addition natürlicher Zahlen, d.h. die Funktion f(x, y) = x + y für x, y ω, Turing-berechenbar ist. Wir kodieren zunächst jede Zahl n unär als 6
Zeichenkette n und vereinbaren, dass die beiden Argumente der Addition durch das Symbol + getrennt werden. Die folgende Turing-Maschine berechnet f. +/ / R R L L R 0 3 Die Berechnung für f(, 3) sieht folgendermaßen aus: 0 + 0 + 0 + ( ) ( ) 3 3 3 3 3 3 7