Skript in PDF - Theoretische Informatik - Technische Universität ...

Skript in PDF - Theoretische Informatik - Technische Universität ... Skript in PDF - Theoretische Informatik - Technische Universität ...

iti.cs.tu.bs.de
von iti.cs.tu.bs.de Mehr von diesem Publisher
18.09.2013 Aufrufe

114 KAPITEL 4. CHURCHSCHE THESE Bemerkung 3. Nicht jede Turing-berechenbare Funktion ist primitiv-rekursiv. In der Tat sind alle primitiv-rekursiven total (d.h. überall definiert), und es gibt partielle Turing-berechenbare Funktionen. Aber auch alle totalen Turing-berechenbaren Funktionen sind leider nicht primitivrekursiv. Das können wir abstrakt wie folgt zeigen: alle primitiv-rekursiven Funktionen können wir systematisch aufzählen, z.B. setzen wir f0 = K0, f1 = succ, f2 = π 1 1 . Mit den gegebenen Funktionen f0, . . . , fi machen wir alle möglichen Verknüpfungen und primitiven Rekursionen. Dabei entstehen fi+1, . . . , fj, dann ist fj+1 die nächste noch nicht eingenommene Projektion, usw. Diese Aufzählung kann bestimmt eine TM durchführen. Dann ist die Funktion P(n) = 1 + fn(n, n, . . .,n) Turing-berechenbar. Aber P ist nicht primitiv-rekursiv: falls nämlich P = fn, haben wir P(n) = 1 + fn(n) = fn(n) – ein Widerspruch. Es ist U. Ackermann 1928 gelungen, ein viel konkreteres Beispiel einer Funktion anzugeben, die nicht primitiv-rekursiv ist, sich aber mit einem einfachen Algorithmus berechnen läßt. Die Funktion, die man heute Ackermann-Funktion nennt, ist eine von R. Peter und R. M. Robinson später entdeckte Vereinfachung der ursprünglichen Idee: Beispiel 9. Die Ackermann-Funktion A : A(0, m) = m + 1 A(n + 1, 0) = A(n, 1) und A(n + 1, m + 1) = A(n, A(n + 1, m)). Es gilt also A(0, 0) = 1, A(0, 1) = 2, A(1, 0) = A(0, 1) = 2, A(0, 2) = 3, A(1, 1) = A(0, A(1, 0)) = A(0, 2) = 3, A(2, 0) = A(1, 1) = 3, 2 → ist wie folgt definiert: usw. Wir erhalten einen Algorithmus, um jeden Wert A(n, m) zu berechnen: alle möglichen Paare (n, m) werden so aufgezählt, dass der Wert A(n, m) direkt aus den vorigen Werten berechnet wird: (0, 0), (0, 1), (1, 0), (0, 2), (1, 1), (2, 0), . . ., Das können wir durch eine TM realisieren, und wir sehen also, dass die Ackermann-Funktion TM-berechenbar ist. Trotzdem ist sie nicht primitiv-rekursiv! Man kann nämlich beweisen, dass sie schneller wächst, als jede primitiv-rekursive Funktion. Es gilt z.B. folgendes, wie sich leicht durch Induktion über m beweisen lässt: A(1, m) = m + 2 A(2, m) = 2m + 3 A(3, m) = 2 m+3 − 3 A(4, m) = 22..2 − 3, wobei 22..2 Zum Beispiel m + 2 Exponentiationen hat. A(4, 1) = 216 − 3 und A(4, 2) = 2216 − 3 > 101000 . Bemerkung 4. Wir wollen jetzt die Klasse aller primitiv-rekursiven Funktionen durch eine neue Operation ergänzen, um alle berechenbaren Funktionen repräsentieren zu können. Das wird der Minimierungsoperator µ sein, der z.B. jeder 2-stelligen Funktion f(n, m) die 1-stellige Funktion µf(n) = min{m; f(n, m) = 0} zuordnet. Hier müssen wir aber aufpassen: µf ist nicht immer definiert, da es für eine Zahl n geschehen kann, dass f(n, m) = 0 für alle m ∈ . Deshalb arbeiten

4.5. REKURSIVE FUNKTIONEN 115 wir jetzt mit partiellen Funktionen (das ist nicht überraschend, denn die Turingberechenbaren Funktionen sind im allgemeinen auch partiell). Definition. Für jede partielle (k+1)-stellige Funktion f(n1, . . .,nk, nk+1) bezeichnen wir mit µf die folgende partielle k-stellige Funktion: µf(n1, . . . , nk) ist die kleinste Zahl i mit f(n1, . . . , nk, i) = 0; falls keine solche Zahl i existiert, ist µf(n1, . . .,nk) undefiniert. Eine Funktion heißt rekursiv (oder µ-rekursiv), wenn sie durch die Basisfunktionen und endlich viele Anwendungen von 1. Verknüpfung, 2. primitiver Rekursion und 3. Minimierung µ definiert werden kann. Beispiel 10. Diepartielle Vorgängerfunktion n − 1 falls n > 0 pred(n) = undef. für n = 0 ist rekursiv, denn für die Funktion f(n, m) = (succm) ˙− n (siehe Beispiel 8) gilt pred(n) = µ((succm) ˙− n). Beispiel 11. Die Subtraktion n − m falls n ≥ m sub(n, m) = undef. falls n < m ist rekursiv: wir haben sub(n, 0) = n sub(n, m + 1) = pred(sub(n, m)), also ist sub primitiv-rekursiv durch g(n) = π1 1 (n) und h(n, m, i) = pred(i) = pred(π3 3(n, m, i)) definiert (g und h sind rekursiv). Beispiel 12. Die Division k falls n = mk n : m = undef. falls n nicht durch m teilbar ist ist rekursiv. Der erste Versuch wäre, n : m als µ(n − m ∗ k) zu definieren, denn n − m ∗ k = 0 genau dann, wenn k = n : m. Das ergibt leider 0 : 0 = 0. Deswegen müssen wir n − m ∗ k durch n − (succ(pred(m)) ∗ k ersetzen: n : m = µf(n, m) für f(n, m, k) = n − succ(pred(m)) ∗ k = sub(n, mal(succ(pred(m))), k). Jetzt gilt: die Division durch m = 0 ist undefiniert, für m > 0 ist f(n, m, k) = n − m ∗ k und µf(n, m) = n : m genau dann, wenn n : m definiert ist. Satz 2. Jede rekursive Funktion ist Turing-berechenbar. Beweis. Es genügt zu den Punkten 1. - 3. aus Satz 1 einen vierten Punkt hinzuzufügen: 4. Falls f Turing-berechenbar ist, so ist es auch µf.

114 KAPITEL 4. CHURCHSCHE THESE<br />

Bemerkung 3. Nicht jede Tur<strong>in</strong>g-berechenbare Funktion ist primitiv-rekursiv. In<br />

der Tat s<strong>in</strong>d alle primitiv-rekursiven total (d.h. überall def<strong>in</strong>iert), und es gibt partielle<br />

Tur<strong>in</strong>g-berechenbare Funktionen.<br />

Aber auch alle totalen Tur<strong>in</strong>g-berechenbaren Funktionen s<strong>in</strong>d leider nicht primitivrekursiv.<br />

Das können wir abstrakt wie folgt zeigen: alle primitiv-rekursiven Funktionen<br />

können wir systematisch aufzählen, z.B. setzen wir f0 = K0, f1 = succ, f2 = π 1 1 .<br />

Mit den gegebenen Funktionen f0, . . . , fi machen wir alle möglichen Verknüpfungen<br />

und primitiven Rekursionen. Dabei entstehen fi+1, . . . , fj, dann ist fj+1 die nächste<br />

noch nicht e<strong>in</strong>genommene Projektion, usw. Diese Aufzählung kann bestimmt e<strong>in</strong>e<br />

TM durchführen. Dann ist die Funktion<br />

P(n) = 1 + fn(n, n, . . .,n)<br />

Tur<strong>in</strong>g-berechenbar. Aber P ist nicht primitiv-rekursiv: falls nämlich P = fn, haben<br />

wir<br />

P(n) = 1 + fn(n) = fn(n) – e<strong>in</strong> Widerspruch.<br />

Es ist U. Ackermann 1928 gelungen, e<strong>in</strong> viel konkreteres Beispiel e<strong>in</strong>er Funktion anzugeben,<br />

die nicht primitiv-rekursiv ist, sich aber mit e<strong>in</strong>em e<strong>in</strong>fachen Algorithmus<br />

berechnen läßt. Die Funktion, die man heute Ackermann-Funktion nennt, ist e<strong>in</strong>e<br />

von R. Peter und R. M. Rob<strong>in</strong>son später entdeckte Vere<strong>in</strong>fachung der ursprünglichen<br />

Idee:<br />

Beispiel 9. Die Ackermann-Funktion A :<br />

A(0, m) = m + 1<br />

A(n + 1, 0) = A(n, 1) und<br />

A(n + 1, m + 1) = A(n, A(n + 1, m)).<br />

Es gilt also<br />

A(0, 0) = 1,<br />

A(0, 1) = 2,<br />

A(1, 0) = A(0, 1) = 2,<br />

A(0, 2) = 3,<br />

A(1, 1) = A(0, A(1, 0)) = A(0, 2) = 3,<br />

A(2, 0) = A(1, 1) = 3,<br />

2 → ist wie folgt def<strong>in</strong>iert:<br />

usw. Wir erhalten e<strong>in</strong>en Algorithmus, um jeden Wert A(n, m) zu berechnen: alle<br />

möglichen Paare (n, m) werden so aufgezählt, dass der Wert A(n, m) direkt aus den<br />

vorigen Werten berechnet wird:<br />

(0, 0), (0, 1), (1, 0), (0, 2), (1, 1), (2, 0), . . ., Das können wir durch e<strong>in</strong>e TM realisieren,<br />

und wir sehen also, dass die Ackermann-Funktion TM-berechenbar ist.<br />

Trotzdem ist sie nicht primitiv-rekursiv! Man kann nämlich beweisen, dass sie<br />

schneller wächst, als jede primitiv-rekursive Funktion.<br />

Es gilt z.B. folgendes, wie sich leicht durch Induktion über m beweisen lässt:<br />

A(1, m) = m + 2<br />

A(2, m) = 2m + 3<br />

A(3, m) = 2 m+3 − 3<br />

A(4, m) = 22..2 − 3, wobei 22..2 Zum Beispiel<br />

m + 2 Exponentiationen hat.<br />

A(4, 1) = 216 − 3 und A(4, 2) = 2216 − 3 > 101000 .<br />

Bemerkung 4. Wir wollen jetzt die Klasse aller primitiv-rekursiven Funktionen<br />

durch e<strong>in</strong>e neue Operation ergänzen, um alle berechenbaren Funktionen repräsentieren<br />

zu können. Das wird der M<strong>in</strong>imierungsoperator µ se<strong>in</strong>, der z.B. jeder 2-stelligen<br />

Funktion f(n, m) die 1-stellige Funktion<br />

µf(n) = m<strong>in</strong>{m; f(n, m) = 0}<br />

zuordnet. Hier müssen wir aber aufpassen: µf ist nicht immer def<strong>in</strong>iert, da es für<br />

e<strong>in</strong>e Zahl n geschehen kann, dass f(n, m) = 0 für alle m ∈ . Deshalb arbeiten

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!