9.1 Das Zeithierarchietheorem

Das Zeithierarchietheorem besagt, dass es zu jeder "vernünftigen" Komplexitätsfunktion t:NN ein Entscheidungsproblem LΣ gibt, dass man in Zeit t entscheiden kann, aber nicht deutlich schneller. Was "vernünftig" bedeutet, wird weiter unten klar werden. Wir betrachten noch einmal genauer die universelle Turingmaschine aus Kapitel 7.5. Unsere Implementierung hatte insgesamt fünf Bänder verwendet: (1) ein Band, um die Regeln von M zu speichern (also die Funktion δ); (2) ein Band, um den Zustand von M zu speichern; (3) um den akzeptierenden Zustand qyes von M zu speichern; (4) und (5) um das Band von M zu simulieren. Für letzteres hatten wir zwei Bänder verwendet, weil das uns erlaubte, effizient Zeichen einzufügen statt einfach zu überschreiben. Wie wir aber gesehen hatten, können wir (4) und (5) mit einem Band bewältigen, indem wir zu allererst die Codierung enc(M) durchgehen und die Länge l des längsten Bandzeichen bestimmen. Wir verwenden dann auf Band (4) immer Blöcke der Länge l für ein M-Zeichen und separieren diese durch eine Markierung #. Auch das Band (3) können wir uns sparen: den akzeptierenden Zustand von M können wir gleich am Anfang von (1) schreiben, ohne das die Simulation dadurch nennenswert teurer würde. Wir kommen also mit drei Bändern aus. Allerdings hatten wir uns nur überlegt, wie man Einband-Turingmaschinen M simuliert. Es ist aber ziemlich einfach zu sehen, dass man Codierung und Simulation ganz analog für k-Band-Turingmaschinen durchführen kann. Die entsprechende Turingmaschine hat dann allerdings k+2 Bänder: k Arbeitsbänder, eins für den Zustand von M und eins für enc(M). Darüberhinaus hatten wir in Kapitel 7.7 gesehen, dass wir als Codierungsalphabet Σ selbst nehmen können, also enc(M)Σ, solange Σ mindestens zwei Zeichen enthält.

Theorem 9.1.1 Für jedes Alphabet Σ mit mindestens zwei Zeichen und jedes k1 gibt es eine Turingmaschine U mit k+2 Bändern, die folgendes kann: sei M eine beliebige k-Band-Turingmaschine mit Eingabealphabet Σ und sei xΣ. Dann gilt

fU(enc(M)x)=fM(x) .

Weiterhin gilt: wenn M auf x innerhalb von s Schritten terminiert, dann terminiert U auf enc(M)x innerhalb von

C|enc(M)|(|x|+s)

Schritten. Das C ist hier eine absolute Konstante, hängt also weder von M noch von Σ ab.

Dass es so ein U gibt, hatten wir ja schon gesehen. Gehen wir aber noch einmal die Zeitschranke durch. In einer vorbereitenden Phase bestimmt U die Länge l des längsten Bandzeichen von M. Dann schreibt es das Eingabewort x1x2xn als Folge von Blöcken der Länge l auf das Arbeitsband. Zellen in einem Block, die nicht verwendet werden, werden mit einem - gefüllt. Hier ein Beispiel für den Fall l=4:

#x1---#x2---#x3---##xn---#

Diese Vorbereitungsphase benötigt maximal C|enc(M)||x| Schritte. Um nun einen Schritt von M zu simulieren, müssen wir das gerade gelesene M-Zeichen z auf Band 2 schreiben, so dass dann dort enc(q),enc(z) steht. Das braucht l+1 Schritte. Als nächstes müssen wir δM(q,z) bestimmen, müssen wir enc(M) durchgehen und den Eintrag für enc(q),enc(z) suchen, was maximal 2enc(M) Schritte benötigt. Dann müssen wir den Schritt ausführen, also den neuen Zustand auf Band 2 schreiben, das neue Zeichen in den Block auf dem Arbeitsband eintragen und den Kopf bewegen. All das benötigt maximal C|enc(M)| Schritte.

Untere Schranken für Zeitkomplexität

Wir wollen nun eine Sprache definieren, die wir in t(n) Schritten entscheiden können aber nicht deutlich schneller. Wir erinnern uns an HALT, die von der universellen Turingmaschine U akzeptierte Sprache:

HALT:=L(U)={enc(M)w | M akzeptiert w} .

und davon abgeleitete "Diagonalisierungssprache"

NegDiag:={enc(M)Σ | enc(M)enc(M)HALT}

Wir haben gesehen, dass NegDiag nicht entscheidbar ist. Nun wollen wir eine Version von NegDiag, die in t Schritten entscheidbar ist, aber nicht in sehr viel weniger. Dafür definieren wir uns ein Halteproblem mit Zeitbudget.

Definition 9.1.2 (Zeitbudgetiertes Halteproblem). Sei Σ ein endliches Alphabet. Wir definieren die Sprache TIMEDHALT:={enc(M)1b0x | U akzeptiert enc(M)x innerhalb von b Schritten} Mit 1b bezeichnen wir die Folge von n vielen 1en. Des Weiteren ist M eine k-Band-Turingmaschine mit Eingabealphabet Σ und xΣ und U die universelle Turingmaschine, die selbst k+2 Bänder hat. Wir sollten strenggenommen also TIMEDHALTΣ,k definieren, unterlassen dies aber der Lesbarkeit halber.

Bitte erinnern Sie sich daran, dass unsere Codierung enc(M) immer mit dem Sonderzeichen ; endet, oder besser gesagt: mit der Codierung von ;Λ über dem Alphabet Σ selbst. Eine Turingmaschine kann also, gegeben ein Eingabewort enc(M)1b0x, dieses in die Bestandteile enc(M), 1b, 0 und x zerlegen. Die 0 dient dazu, das "Budget" 1b vom "inneren Eingabewort" x abzugrenzen.

Beobachtung 9.1.3 TIMEDHALTTIMEk+3(n).

Beweis. Wir nehmen die universelle Turingmaschine U, die k-Band-Turingmaschinen simulieren kann, und statten sie mit einem Stoppuhrband aus. Sie hat nun also k+3 Bänder. Sei n=|enc(M)|+b+1+|x| die Länge des Eingabewortes. In O(n) Schritten sorgt sie dafür, dass auf dem Eingabeband das Wort enc(M)x steht und auf dem Stoppuhrband das Budget 1b. Nun lassen wir die universelle Turingmaschine U laufen, nur dass wir in jedem Schritt den Kopf auf dem Stoppuhrband nach rechts verschieben. Wenn U hält, dann hält unsere Turingmaschine auch und gibt das gleiche Ergebnis aus. Wenn wir das Ende des Stoppuhrbandes erreicht haben, haben wir unsere b Schritte verbraucht und lehnen ab. Wir brauchen insgesamt O(n+b)=O(n) Schritte.

Sei nun t:NN eine monoton steigende Funktion mit t(n)n. Wir definieren eine Zeitbudgetierte Version der Diagonalisierungssprache:

TimedNegDiag:={enc(M)1m | enc(M)1b0enc(M)1nTIMEDHALT, b=t(|enc(M)|+m)}

Behauptung 9.1.4 (nicht ganz korrekt). TimedNegDiagTIMEk+3(t).

Sei n:=|enc(M)+m| die Länge des Inputwortes. Wir können TimedNegDiag entscheiden, indem wir aus enc(M)1m den String enc(M)1b0enc(M)1m berechnen und dann die Turingmaschine für TIMEDHALT laufen lassen, welche k+3 Bänder hat und selbst O(2|enc(M)|+b+1+m)=O(|enc(M)|+b)=O(b) Schritte braucht. Die Vorbereitungsphase braucht ungefähr so lange, wie wir brauchen, um b=t(|enc(M)+m|)=t(n) zu berechnen. Übliche Zeitschranken t, die uns interessieren, wären zum Beispiel nlogn, n2, 2n, n! oder nn. All diese stellen kein Problem dar. Insgesamt sind wir auf der sicheren Seite, wenn wir die Funktion t selbst in O(t) Schritten berechnen können.

Definition 9.1.5 Eine Funktion t:NN heißt zeitkonstruierbar, wenn es eine Turingmaschine gibt, die aus dem Eingabewort 1n das Ausgabewort 1t(n) berechnet und selbst maximal O(t(n)) Schritte läuft.

Behauptung 9.1.6 (jetzt korrekt). Sei t:NN zeitkonstruierbar, monoton steigend und t(n)n. Dann gilt TimedNegDiagTIMEk+3(t).

So weit, so gut. Wonach wir allerdings aus sind, ist ein Beweis, dass TimedNegDiag nicht signifikant schneller zu berechnen ist.

Lemma 9.1.7 Sei s:NN eine Funktion mit s(n)n und s=o(t), also limns(n)t(n)=0. Dann gilt TimedNegDiagTIMEk(s).

Beweis. Wir nehmen an, es gäbe eine Turingmaschine M, die TimedNegDiag in Zeit s entscheidet und leiten einen Widerspruch her. Sei x:=enc(M). Wir wählen eine natürliche Zahl m, deren genauen Wert wir weiter unten diskutieren und setzen b:=t(|x|+m). Wir fragen uns nun: ist x1mTimedNegDiag?

x1mTimedNegDiagenc(M)1b0x1mTIMEDHALTU lehnt enc(M)x1m innerhalb von b Schritten ab

Langsam nun. Sei n:=|enc(M)|+m die Länge des Wortes x1m. Nach Annahme terminiert M auf dem Eingabewort x1m innerhalb von s(n) Schritten. Wenn U die Maschine M simuliert, braucht sie nach Theorem 8.1.1 höchstens C|enc(M)|(n+s(n)) Schritte. Da s(n)n gilt, sind dies höchstens 2C|enc(M)|s(n)=2C|enc(M)|s(|x|+m) Schritte. Da limns(n)t(n)=0 ist, ist auch

limm2C|enc(M)|s(|x|+m)t(|x|+m)=0 .

Wenn wir also m hinreichend groß wählen, dann ist dieser Bruch kleiner als 1, und die Simulation terminiert also innerhalb von

2C|enc(M)|s(|x|+m)t(|x|+m)=b

Schritten. Das heißt, dass die universelle Turingmaschine U das Wort enc(M)x1m innerhalb von b Schritten ablehnt, wenn sie es überhaupt irgendwann ablehnt. Also schließen wir weiter:

x1mTimedNegDiagenc(M)1b0x1mTIMEDHALTU lehnt enc(M)x1m innerhalb von b Schritten abU lehnt enc(M)x1m abM lehnt x1m ab

und da ist er, der Widerspruch: x1mTimedNegDiagfM(x1m)=reject, entgegen unserer Annahme, dass M die Sprache TimedNegDiag entscheidet.

Zusammenfassend erhalten wir die "Rohversion" des Zeithierarchiesatzes:

Theorem 9.1.8(Zeithierarchiesatz, Rohversion). Seien s,t:NN zeitkonstruierbare Funktionen mit s(n)n und so(t) (also limns(n)/t(n)=0). Dann gilt

TIMEk(s)TIMEk+3(t)

für alle k1.

Zusammen mit der Simulation von k-Band-TMs durch 2-Band-TMs folgt nun

TIME(s)TIME2(slogs)TIME5(tlogt)

oder, alternativ ausgedrückt:

Theorem 9.1.9 (Zeithierarchiesatz). Seien s,t:NN mit s(n)n und slogso(t). Dann gilt TIME(s)TIME(t).

Bitte beachten Sie, dass wir diese Version nicht vollständig bewiesen habe, da ich die effizientere Simulation einer k-Band-Turingmaschine durch eine 2-Band-Turingmaschine, also TIMEk(t)TIME2(tlogt) nicht erklärt habe. Mit der ineffiziten, also TIMEk(t)TIME1(t2), erhalten wir einen Zeithierarchiesatz solange s2o(t) ist.

Übungsaufgabe 9.1.1 Zeigen Sie, dass nn2 und n2n zeitkonstruierbar sind.