8.1 Formale Definition

Eine Turingmaschine besteht aus einem Band, das in Zellen unterteilt ist und in beide Richtungen unbegrenzt ist, und einem Schreib-Lese-Kopf. Dieser befindet sich in jedem Schritt auf einer Zelle. Wie auch der endliche Automat oder der Kellerautomat hat die Turingmaschine einen internen Zustand. In jedem Schritt liest die Maschine das Zeichen, das sich in der aktuellen Zelle des Bandes befindet (dort, wo der Kopf steht). Abhängig vom gelesenen Zeichen s und dem internen Zustand q schreibt die Turingmaschine ein neues Symbol s in die Zelle, wechselt in einen neuen Zustand q und bewegt den Kopf um maximal eine Zelle, also nach link, rechts, oder gar nicht.

Sie können sich das Band auch als Magnetband vorstellen, das nach vorn oder nach hinten gespult wird, anstatt dass der Kopf sich bewegt. Am Anfang steht auf dem Band das Eingabewort und der Kopf auf dem ersten Symbol dieses Wortes. Die Turingmaschine wendet nun ihre Regeln an, bis Sie einen Endzustand erreicht. Bei Entscheidungsproblemen, wo uns nur eine Ja/Nein-Antwort interessiert, wird die Antwort durch den Entzustand angegeben: der Zustand qyes entspricht einem Ja, der Zustand qno entspricht einem Nein. Diese zwei Endzustände reichen im Allgemeinen aus. Wenn wir von der Maschine eine komplexere Ausgabe als Ja/Nein erwarten, so betrachten wir als Ausgabe der Turingmaschine den Inhalt des Bandes zu dem Zeitpunkt, da die Maschine den Zustand qyes erreicht. Was brauchen wir also, um so eine Turingmaschine und ihre Arbeitsweise zu beschreiben?

Definition 8.1.1(Turingmaschine). Eine Turingmaschine besteht aus folgenden Elementen:

  1. Einem endlichen Eingabe-Alphabet Σ. Dies sind die Symbole, die für das Eingabewort in Frage kommen.
  2. Einem endlichen Bandalphabet Γ; das sind die Symbole, die auf dem Band stehen dürfen. Offensichtlich muss ΣΓ gelten. Jede Zelle kann genau ein Zeichen aus Γ enthalten. Darüberhinaus gibt es noch das sogenannte Blanksymbol ΓΣ. Dies zeigt an, dass die Zelle im Moment leer ist. Im obigen Beispiel ist die Zelle links vom ersten a beispielsweise leer. Am Anfang steht auf dem Band also ein Eingabewort wΣ und rechts und links davon unendlich viele -Symbole.
  3. Einer endliche Menge Q an inneren Zuständen. Dies entspricht in etwa den Prozessor-Registern eines Computers. Ein Zustand startQ ist der Startzustand, in welchem sich die Maschine zu Beginn befindet.
  4. Einer Zustandsübergangsfunktion δ, die sagt, was die Turingmaschine tun soll, wenn Sie im Zustand q ist und Zeichen s liest. Formal: δ:Q×ΓQ×Γ×{L,S,R} , wobei L für gehe eine Zelle nach links steht, R für rechts und S für stay, also die Anweisung, den Kopf nicht zu bewegen.
  5. Zwei besonderen Zuständen qyes und qno.

Für die Turingmaschine in dem obigen Beispiel haben wir zwei Regeln gesehen: δ(q2,b)=(q3,a,R)δ(q3,#)=(q4,b,L)

Was macht eine Turingmaschine?

Sie haben nun wohl bereits eine vage Vorstellung, was eine Turingmaschine macht. Versuchen wir, es noch weiter zu formalisieren. Um den Gesamtzustand der Turingmaschine zu beschreiben, also eine vollständige Momentaufnahme, reicht nicht der aktuelle innere Zustand q; wir brauchen auch den Bandinhalt und insbesondere die Position, an der sich der Kopf befindet. Das alles zusammen nennt man die Konfiguration der Turingmaschine. Wir wollen sie mit uns bereits bekannten mathematischen Begriffen beschreiben.
Definition 8.1.2 Die Konfiguration einer Turingmaschine ist ein Element in Γ×Q×Γ, also C=uqv wobei uvΓ der Bandinhalt ist, der Schreib-Lese-Kopf auf dem ersten Zeichen von v steht und q der innere Zustand der Turingmaschine ist. Das q in C kennzeichnet also sowohl die Position des Schreib-Lese-Kopfes auf dem Band sowie den inneren Zustand Die Menge aller Konfigurationen ist C:=Γ×Q×Γ Der Zustand einer Konfiguration C=uqv ist q, also der innere Zustand, in dem sich die Maschine gerade befindet. Wir bezeichnen mit state(C). Formal: state:CQuqvq . Eine Konfiguration C ist eine akzeptierende Endkonfiguration wenn state(C)=qyes ist; eine ablehnende Endkonfiguration , wenn state(C)=qno ist. In beiden Fällen ist C eine Endkonfiguration.

Wenn also das Eingabewort wΣ und qstart der Startzustand ist, dann ist Cstart=qstartw die Startkonfiguration.

Die Rolle des -Symbols. Das Band der Turingmaschine ist ja unendlich. Um eine Momentaufnahme dennoch als endliches Objekt beschreiben zu können, lassen wir die -Symbole links und rechts vom "eigentlichen" Bandinhalt weg. Bei einer Konfiguration uqv stehen also links vom u und rechts vom v unendlich viele -Symbole auf dem Band. Nach der formalen Definition uqvΓ×Q×Γ ist es nicht verboten, dass u auch mit einem -Symbol beginnt oder v mit einem aufhört. Allerdings wären die Konfiguration uqv und uqv genauso gut mit uqv beschrieben. Wir können uns also auf die Konvention einigen, dass nie am Rande einer Konfiguration uqv steht. Beachten Sie auch, dass die Zellen nicht "numeriert" sind. Die beiden folgenden Momentaufnahmen
können also beide mit der Konfiguration aAAaq#ba beschrieben werden, obwohl die Zellen nun andere Inhalte haben, weil die Turingmaschine es irgendwie geschafft hat, den ganzen Bandinhalt um eins nach rechts zu kopieren. Es sollte klar sein, dass die Turingmaschine keine Möglichkeit hat, die obere von der unteren Situation zu unterscheiden, und dass es somit nur recht und billig ist, beide als eine identische Konfiguration aufzufassen.

All diese Schwierigkeiten verschwinden, wenn wir uns den Speicher einer Turingmaschine nicht als unendliches Band vorstellen, sondern als zwei Stapel, einer links vom Kopf und einer rechts vom Kopf. Allerdings hat sich die Vorstellung vom Band irgendwie als Standard durchgesetzt. Hier sehen Sie die gleiche Konfiguration in dem Modell mit zwei Stapeln:

Alternativ können wir auch der Turingmaschine verbieten, das Blank-Symbol jemals zu schreiben. Dann wäre also δ:Q×ΓQ×(Γ{})×{L,S,R}. All diese Betrachtungsweisen unterscheiden sich nicht wesentlich. Wir bleiben bei unserem "alten" δ, erlauben also, zu schreiben, und leben damit, dass uqv und uqv formal zwei verschiedene Konfigurationen sind, auch wenn beide irgendwie das selbe beschreiben.

Formal definiert δ nun auch eine Funktion auf der Menge der Konfigurationen:

Definition 8.1.3 (erweiterte Zustandsübergangsfunktion) Die erweiterte Zustandsübergangsfunktion einer Turingmaschine ist δ^:CC  Sie beschreibt für eine Konfiguration C, welches die Konfiguration im nächsten Schritt ist. Per Konvention legen wir fest, dass δ^(C)=C gilt, wenn C eine Endkonfiguration ist.
Unsere obige Turingmaschine hat beispielsweise die Regeln δ(q2,b)=(q3,a,R) und δ(q3,#)=(q4,b,L), und somit würden δ^(aaAq2b#ba)=aaAaq3#baδ^(aaAaq3#ba)=aaAq4abbaδ^(abAq2bba#)=abAaq3ba# gelten. Sie sehen: Die Definition von δ^ ist nichts wirklich Tiefgründiges, sondern einfach eine Implementierung der Turingmaschinen-Momentaufnahme mit uns bereits geläufigen mathematischen "Datenstrukturen" (hier: der Menge Γ×Q×Γ). Stellen Sie sich einfach vor, Sie müssten eine Turingmaschine in Java implementieren. Dann würden Sie es wahrscheilich irgendwie so ähnlich machen.

Ausgabekonfiguration einer Turingmaschine

Die Funktion δ^ bildet aus einer Konfiguration die Folgekonfiguration. Wir definieren nun δ^(i)(C):=δ^(δ^((δ^i mal(C)))) also die Konfiguration, die die Turingmaschine nach i Rechenschritten erreicht hat. Weiterhin definieren wir δ^(C) als die Endkonfiguration, die bei wiederholter Anwendung von δ^ schlussendlich erreicht wird. Hier taucht ein Problem auf: es ist nicht gesagt, dass die Turingmaschine, von Konfiguration C beginnend, überhaupt irgendwann in einer Endkonfiguration landen wird. Daher kann δ^ auch undefined sein: δ^(C):={δ^(i)(C) wenn es ein i gibt, so dass δ^(i)(C) eine Endkonfiguration istundefinedsonst.

Nochmal zur Verdeutlichung: wenn δ(i)(C) eine Endkonfiguration ist, dann ist auch δ(j)(C) eine, für jedes ji, weil wir δ^(C)=C für jede Endkonfiguration C definiert haben. Es spielt also in der obigen Formulierung wenn es ein i gibt keine Rolle, welches solche i wir wählen.

Für ein Eingabewort xΣ können wir nun das Ergebnis der Berechnung von Turingmaschine M auf x=x1xn definieren: M^(x):=δ^(qstartx1x2x3xn) . Wir beginnen also mit der Startkonfiguration und lassen die Turingmaschine dann laufen, bis sie einen Endzustand erreicht. Die erreichte Konfiguration bezeichnen wir mit M^(x). Falls nie ein Endzustand erreicht wird (die Turingmaschine also endlos läuft), ist M^(x) undefined.

Sprachen entscheiden

Ein Entscheidungsproblem ist eine Funktion P:Σ{true,false}, beispielsweise: gegeben ein Wort, stellt dieses Wort ein korrektes Java-Programm dar? oder gegeben eine Zahl in Dezimalschreibweise, ist dies eine Primzahl? Eine äquivalente Sichtweise ist die eines Entscheidungsproblems als Sprache LΣ. Wir identifizieren L hier mit der Menge aller Wörter x mit P(x)=true. Wenn wir es mit einem Entscheidungsproblem zu tun haben und dieses mit einer Turingmaschine lösen wollen, so interessiert uns am Endergebnis M^(x) (also der erreichten Endkonfiguration) nicht der Bandinhalt, sondern nur, ob der Zustand accept oder reject ist. Wir definieren daher fM(x)={accept falls state(M^(x))=qyes, wenn also M^(x) eine akzeptierende Endkonfiguration ist, reject falls state(M^(x))=qno ,undefined falls M^(x)=undefined 

Definition 8.1.4 (Turingmaschine entscheidet eine Sprache) Eine Turingmaschine M entscheidet die Sprache LΣ wenn
  1. fM(x)=accept für alle xL,
  2. fM(x)=reject für alle xΣL.
Insbesondere heißt das, dass M auf jedem Eingabewort terminiert.

Eine Sprache L heißt entscheidbar, wenn es eine Turingmaschine gibt, die sie entscheidet.

Definition 8.1.5 (Turingmaschine akzeptiert eine Sprache) Eine Turingmaschine M akzeptiert die Sprache LΣ wenn xLfM(x)=accept für alle xΣ gilt. Das heißt, dass M für xΣ entweder irgendwann den Endzustand qno erreicht oder nie einen Endzustand erreicht.

Eine Sprache LΣ heißt semi-entscheidbar, wenn es eine Turingmaschine M gibt, die L akzeptiert.

In beiden Definition verlangen wir natürlich, dass Σ das Eingabealphabet der Turingmaschine ist.

Funktionen berechnen

Oft wollen wir nicht nur eine Sprache LΣ entscheiden, sondern eine Funktion g:Σ1Σ2 berechnen. Mit einer Turingmaschine heißt das einfach, dass bei Eingabe xΣ1 die Turingmaschine in einer akzeptierenden Endkonfiguration C landet, und in C steht dann g(x) auf dem Band. Formal müssen wir noch klären, was g(x) steht auf dem Band bedeutet.

Definition 8.1.6 (Turingmaschine berechnet eine Funktion) Seien Σ1,Σ2 zwei endliche Alphabete und g:Σ1Σ2 eine Funktion. Eine Turingmaschine M berechnet die Funktion g, wenn
  1. Σ1 das Eingabealphabet von M ist,
  2. Σ1Σ2Γ gilt und Γ(Σ1Σ2); das Blank-Symbol ist also weder Teil das Eingabealphabets noch des Ausgabealphabets.
  3. M terminiert für jedes xΣ.
  4. In der Endkonfiguration M^(x) steht auf dem Arbeitsband das Wort g(x)Σ2 und der Kopf steht ganz links, also M^(x)=qyesg(x).

Turingmaschinen und formale Grammatiken

Da Turingmaschinen sowohl in dem Kurs Berechenbarkeit und Kreativität als auch Theoretische Informatik vorkommen, teilen sich die beiden Kurse diese Seiten. Für Berechenbarkeit und Kreativität ist der Rest dieses Teilkapitels allerdings weniger relevant, da formale Grammatiken nicht Teil des Kurses waren.

Theorem 8.1.7 Sei M eine Turingmaschine und L(M) die von ihr akzeptierte Sprache. Dann gibt es eine formale Grammatik G mit L(G)=L(M). In anderen Worten: formale Grammatiken sind mindestens so mächtig wie Turingmaschinen.
Beweis. Die Idee ist, dass wir eine Grammatik G schreiben, die "in umgekehrter Reihenfolge" läuft, also $qstartw.S ableiten kann genau dann, wenn wS gilt. Wir brauchen $ und . als Randmarkierungen. Wir lassen hier temporär zu, dass die linke Seite ausschließlich aus Terminalsymbolen bestehen kann.

Hierfür definieren wir für jede Regel der Turingmaschine eine Grammatik-Regel: δ(q,x)=(r,y,S)wird zur Produktionqxryδ(q,x)=(y,r,R)wird zur Produktionenqxyrδ(q,x)=(y,r,L)wird zu den Produktionenaqxray für alle aΓ Die Asymmetrie zwischen den Regeln, die den Kopf nach rechts verschieben und denen, die ihn nach links verschieben, ergibt sich aus unserer Konvention, die Konfigurationen uqv so zu interpretieren, dass der Kopf auf dem ersten Symbol von v und nicht etwa auf dem letzten von u steht. Ein Problem ergibt sich, wenn q am Rand steht. Hierfür erlauben wir, an den Rändern der Konfiguration -Symbole zu erzeugen: $$..  Wenn der Kopf also vor dem . stehen sollte, dann können wir $uq.$uq. anwenden und dann die Produktion, die der Regel von δ(q,) entspricht. Es sollte nun klar sein, dass folgendes gilt:

Beobachtung 8.1.8 Wenn δ^(i)(uqv)=uqv gilt, die Turingmaschine also in i Schritten von Konfiguration uqv nach uqv übergeht, dann gilt in der gerade entwickelten Grammatik auch $uqv.$uqv.
Als nächstes definieren wir Aufräumregeln: wenn q=accept, dann können wir jedes Zeichen löschen: accept xacceptx acceptaccept wobei accept ein Nichtterminal der Grammatik ist. Und somit gilt auch $u accept v.$ accept . Als letzte Regel definieren wir:  accept .S Wir haben nun eine Grammatik mit den folgenden Eigenschaften: M(x1x2xn)=accept genau dann, wenn $startx1x2xn.S Wir bauen nun eine weitere Grammatik G, in der wir jede Produktion αβ umdrehen, also durch βα ersetzen. Zusätzlich definieren wir Abschlussregeln $ϵ.ϵstartϵ die die Randmarkierungen ersetzen. In dieser Grammatik gilt nun für alle Wörter xΣ: xL(M)SG:Sx und somit gilt L(G)=L(M). Zusammenfassend besitzt G also die Produktionen S1$ accept .(für jedes xΓ)accept2x accept | accept x(wenn δ(q,x)=(r,y,S))ry3qx(wenn δ(q,x)=(r,y,R))yr4qx(wenn δ(q,x)=(r,y,L), für jedes aΓ)ray5aqx$6$.7.$8ϵ.9ϵstart10ϵ Um also ein Wort xL(M) abzuleiten, müssen wir die akzeptierende Endkonfiguration C von M(x) "erraten" und dann per Produktionen 1 und 2 die Wortform $C. ableiten. Von da an verwenden wir die Produktionen 3, 4, 5, 6, 7, um die Berechnung der Turingmaschine M(x) von hinten nach vorne zu simulieren, bis wir bei $start x. angelangt sind. Dann lassen wir $,start,. mit den Produktionen 8, 9, 10 verschwinden und haben x abgeleitet.