Kapitel 2. Berechenbarkeitstheorie 2.1 Intuitiver Berechenbarkeitsbegriff und Churchsche These Eine (partielle) Funktion f : Nk → N wird als berechenbar angesehen, wenn es einen “Algorithmus” gibt, der f berechnet: Bei Eingabe (n1, . . . , nk ) ∈ Nk stoppt der Algorithmus nach endlich vielen Schritten mit der Ausgabe f (n1, . . . , nk ). Ist f (n1, . . . , nk ) undefiniert, so stoppt der Algorithmus bei Eingabe (n1, . . . , nk ) nicht. 124 Beispiel 1: INPUT(n); REPEAT UNTIL FALSE; Dieser Algorithmus berechnet die total undefinierte Funktion Ω : n 7→ “undefiniert”. Beispiel 2: 1 falls n ein Anfangsabschnitt der Dezimalbruchentwicklung von π ist f (n) = 0 sonst ist berechenbar. Beispiel 3: 1 falls n in der Dezimalbruchentwicklung von π vorkommt g(n) = 0 sonst ist möglicherweise nicht berechenbar. 125 Beispiel 4: 1 falls n in der Dezimalbruchentwicklung von π irgendwo mindestens n-mal h(n) = hintereinander eine 7 vorkommt 0 sonst ist berechenbar, denn: 1. Fall: In der Dezimalbruchentwicklung von π treten beliebig lange 7-er Folgen auf. Dann: h(n) = 1 für alle n. 2. Fall: Es gibt eine Zahl n0, sodass die längste 7-er Folge die Länge n0 hat. Dann: h(n) = ( 1 falls 0 ≤ n ≤ n0 0 falls n > n0. Problem: Wir wissen nicht, welcher dieser Fälle gilt. 126 Eine reelle Zahl r ist effektiv approximierbar , wenn die folgende Funktion fr berechenbar ist: fr (n) = 1 falls n ein Anfangsabschnitt der Dezimalbruchentwicklung von r ist 0 sonst R ist überabzählbar, d.h. nicht alle reellen Zahlen sind effektiv approximierbar. Aber : alle rationalen Zahlen sind effektiv approximierbar. 127 Formalisierungen des intuitiven Berechenbarkeitsbegriffs: - Turingmaschinen∗ - Random Access Maschinen - WHILE-Programme∗ - LOOP-Programme∗ - µ-rekursive Funktionen∗ - λ-definierbare Funktionen - Postsche Systeme -... Churchsche These Die durch die formale Definition der Turing-Berechenbarkeit erfasste Klasse von Funktionen stimmt mit der Klasse der im intuitiven Sinne berechenbaren Funktionen überein. 128 2.2 Turing-Berechenbarkeit Stift @ @ a a b c b b b c Lese-/Schreibkopf endliche @ @ @ Mensch Kontrolle Rechenblatt Turingmaschine Definition Eine Funktion f : Σ∗ → Σ∗ heißt Turing-berechenbar , wenn es eine (deterministische) Turingmaschine M gibt, sodass für alle x, y ∈ Σ∗ gilt: f (x) = y gdw. z0x ⊢∗M 2 . . . 2zey2 . . . 2 (ze ∈ E). 129 Definition Eine Funktion f : Nk → N heißt Turing-berechenbar , wenn es eine (deterministische) Turingmaschine M gibt, sodass für alle n1, . . . , nk , m ∈ N gilt: f (n1, . . . , nk ) = m gdw. z0bin(n1)#bin(n2)# . . . #bin(nk ) ⊢∗M 2 . . . 2zebin(m)2 . . . 2 (ze ∈ E). 130 Beispiel: Die Funktion n 7→ n + 1 ist TM-berechenbar. Bezeichnung: Band := Band+1 Beispiel: Die überall undefinierte Funktion Ω ist TM-berechenbar: δ(z0, a) = (z0, a, R) f.a. a ∈ Γ. Beispiel: Sei A ⊆ Σ∗. Definiere χ′A : Σ∗ → {0, 1}: χ′A(w) = ( 1, falls w ∈ A, undefiniert, falls w 6∈ A. A ist vom Typ 0 gdw. χ′A ist TM-berechenbar. 131 Eine Mehrband-Turingmaschine mit k ≥ 1 Bändern: ... a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 . . . ... b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 . . . ... c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 . . . endliche Kontrolle δ : Z × Γk → Z × Γk × {L, R, N }k Satz Zu jeder Mehrband-TM M gibt es eine (Einband-)TM M ′ mit T (M ) = T (M ′) (bzw. M ′ berechnet dieselbe Funktion wie M ). 132 Beweis: ... Einband-TM M ′: a1 a2 a3 a4 a5 a6 a7 a8 a9 ... b4 b5 b6 b7 b8 b9 ... c8 c9 ... * ... b1 b2 b3 * ... c1 c2 c3 c4 c5 c6 c7 * Band mit 2k “Spuren” Arbeitsalphabet: Γ′ := Γ ∪ (Γ ∪ {∗})2k Arbeitsweise von M ′: Startkonfiguration: z0w (w ∈ Σ∗) 1. Phase: w * 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 * 2 * 2. Phase: M ′ simuliert M schrittweise. 3. Phase: Ergebnis von Spur 1 auf das gesamte Band kopieren. 2 133 Ist M eine 1-Band-TM, so ist M (i, k) (i ≤ k) die k-Band-TM, die auf Band i M simuliert, wobei alle anderen Bänder unverändert bleiben. Beispiele: (i) Band := Band + 1(i, k). Schreibweise: Band i := Band i + 1 (ii) Band i := Band i − 1. (iii) Band i := 0. (iv) Band i := Band j. 134 Hintereinanderschalten von TMen Mi = (Zi, Σ, Γi, δi, zi, 2, Ei), i = 1, 2 M : start → M1 → M2 → stop M = (Z1 ∪ Z2, Σ, Γ1 ∪ Γ2, δ, z1, 2, E2) mit δ := δ1∪δ2∪{ (ze, a, z2, a, N ) | ze ∈ E1, a ∈ Γ1 }. Beispiele: (i) start ↓ Band := Band + 1 ↓ Band := Band + 1 ↓ Band := Band + 1 → stop Schreibweise: Band := Band + 3 135 (ii) start / M ze1 / M1 / stop ze2 M2 stop (iii) Band = 0? : Z := {z0, z1, ja,nein}, E = {ja,nein}, δ : (z0, a) 7→ (nein, a, N ) für a 6= 0 (z0, 0) 7→ (z1, 0, R) (z1, a) 7→ (nein, a, L) für a 6= 2 (z1, 2) 7→ (ja, 2, L) Hieraus: Band i=0? (iv) start Band i = 0? ja stop nein M Schreibweise: WHILE Band i 6= 0 DO M . 136 Beobachtung: TMen bilden eine einfache Programmiersprache: - Die Funktionen +c und −c (c ∈ N) sowie f (x1, . . . , xn) = xi (1 ≤ i ≤ n) sind TM-berechenbar. - Diese Sprache enthält einfache Wertzuweisungen. - Sie enthält einfache Abfragen und while-Schleifen. - Das Hintereinanderschalten von Programmen ist möglich. 137 2.3 LOOP- WHILE- und GOTO-Berechenbarkeit Die Programmiersprache LOOP (i) Syntaktische Komponenten: Variable : x0 , x1 , x2 , . . . Konstanten : 0, 1, 2, . . . Trennsymbole : ; := Operationszeichen : + − Schlüsselwörter : LOOP DO END (ii) LOOP-Programme: Wertzuweisung: xi := xj + c (i, j ≥ 0, c ∈ N) xi := xj − c Hintereinanderausführung: P1; P2 Schleife: LOOP xi DO P END (i ≥ 0) (iii) Semantik: xi := xj + c xi := xj − c P1; P2 LOOP xi DO P END “P sooft ausführen, wie dies der Wert von xi zu Beginn angibt.” 138 Definition Eine Funktion f : Nk → N heißt LOOP-berechenbar , wenn es ein LOOP-Programm gibt, das folgendes leistet: Wird P mit den Startwerten n1, . . . , nk in den Variablen x1, . . . , xk gestartet, wobei alle anderen Variablen den Startwert 0 haben, so stoppt P mit dem Wert f (n1, . . . , nk ) in der Variablen x0. Beobachtung: Jedes LOOP-Programm stoppt für jede Eingabe. Also: nur totale Funktionen können LOOP-berechenbar sein. Frage: Gibt es totale Funktionen, die intuitiv berechenbar sind, die aber nicht LOOP-berechenbar sind? 139 Beispiele LOOP-berechenbarer Funktionen: (i) xi := xj (ii) xi := c (iii) IF x = 0 THEN A END : y := 1; LOOP x DO y := 0 END; LOOP y DO A END (iv) Additionsfunktion: x0 := x1; LOOP x2 DO x0 := x0 + 1 END Bezeichnung: x0 := x1 + x2 (v) Multiplikationsfunktion: x0 := 0; LOOP x2 DO x0 := x0 + x1 END (vi) MOD- und DIV-Funktionen Abkürzungen: x := (y DIV z)+(x MOD 5)∗y 140 Die Programmiersprache WHILE (i) Syntaktische Komponenten: wie in LOOP plus Schlüsselwort WHILE und Trennsymbol 6= (ii) WHILE-Programme: wie LOOP-Programme plus WHILE-Schleife: WHILE xi 6= 0 DO P END (iii) Semantik der WHILE-Schleife: “Wiederhole P solange, bis xi den Wert 0 hat” Beachte: LOOP x DO P END ist äquivalent zu y := x; (∗ y neue Variable ∗) WHILE y 6= 0 DO y := y − 1; P END 141 Definition Eine Funktion f : Nk → N heißt WHILE-berechenbar , wenn es ein WHILE-Programm P gibt, das folgendes leistet: Wird P mit den Startwerten n1, . . . , nk in den Variablen x1, . . . , xk gestartet, wobei alle anderen Variablen den Startwert 0 haben, so stoppt P mit dem Wert f (n1, . . . , nk ) in der Variablen x0, falls f (n1, . . . , nk ) definiert ist, andernfalls stoppt P nicht. Satz Turingmaschinen können WHILE-Programme simulieren, d.h. jede WHILE-berechenbare Funktion ist auch Turing-berechenbar. 142