Iteration und Rekursion Unter einer Iteration versteht man einen Algorithmus mit der Eigenschaft, einen Eingabewert x (zuerst einen Anfangswertes x(0) ) gemäß einer Funktion f(x) in einen Ausgabewert y umzuwandeln und diesen stets wieder als nächsten input einzugeben. Mit Bezug auf die Abbildung könnte man also ganz einfach sagen: Alles, was aus dem (gelben) Block als output herauskommt, wird sogleich wieder als nächster input in ihn eingegeben. Für x kann man deshalb auch x(n) schreiben und für y jeweils x(n+1). Die einzelnen Schritte dieses Prozesses nennt man gleichfalls Iterationen. So würde etwa bei der fünften Iteration der Eingabewert x(5) in den Ausgabewert x(5+1) umgewandelt, der dann als x(6) wieder eingegeben wird. Der Iterationsprozess kann entweder unendlich weiter laufen oder beendet werden, entweder wenn eine vorgegebene Schrittzahl n bzw. ein vorgegebener Wert x(max) erreicht wurde oder wenn die Funktion f nicht mehr ausgeführt werden kann (zum Beispiel weil dies eine Division durch Null bedeutet würde). Rekursion ist demgegenüber etwa ganz anderes. Eine Funktion F (oder ein entsprechender Algorithmus) heißt rekursiv, wenn sie sich zu ihrer Durchführung ein Mal oder mehrfach selbst aufruft. Das klingt kompliziert, ist aber nicht allzu schwer zu verstehen. Wenn man zum Beispiel ein Computerprogramm für einen Algorithmus schreiben will, der eine eingegebene Zahl Z auf Primeigenschaft prüft (also entscheidet, ob die Eingabezahl Z eine Primzahl ist oder nicht), so kann man den Rechner natürlich anweisen, der Reihe nach für jede natürliche Zahl N – angefangen mit 2 bis hin zur Hälfte von Z – zu prüfen, ob Z durch das jeweilige N teilbar ist. Aber dies wäre viel zu umständlich und würde unnötig lange dauern, denn wenn zum Beispiel Z nicht durch 2 teilbar war, dann brauchte das Programm nicht mehr zu prüfen, ob Z durch irgendeine andere gerade Zahl teilbar ist. Hat es festgestellt, dass Z nicht ohne Rest durch 3 teilbar ist, dann steht damit auch fest, dass Z auch nicht durch irgendeine Zahl N, die ein Vielfaches von 3 ist, geteilt werden kann. Eine erhebliche Vereinfachung des Programms liefe also darauf hinaus, nur die Teilbarkeit von Z durch Zahlen zu prüfen, die selber Primzahlen sind. Also müsste der Algorithmus, der ja eine Zahl auf Primeigenschaft prüfen soll, jeden in Betracht gezogenen Teiler selbst erst auf Primeigenschaft prüfen, das heißt sich selbst – rekursiv – darauf anwenden. Bei den Fibonacci-Zahlen (siehe Materialien zur 1. Vorlesung) verhält es sich ganz ähnlich: In der nachstehenden Abbildung sieht man zwei Grundmuster (oder Diagramme), bezeichnet als (a) und (c): ein Algorithmus, der ein geometrisches Muster wie (a) mit den entsprechenden Linien und Knoten erzeugt, ist leicht zu programmieren. (Vgl. hierzu die Ausführungen über Turtle-Grafiken und L-Systeme in den Materialien 2 zur 4. Vorlesung) Dort, wo in der Abb. (a) ein G steht, soll der Algorithmus eine genaue Kopie des Musters (a) anfügen, also ein Muster, zu dessen Erzeugung er sich selbst aufrufen muss: Auf diese Weise stellt er das Muster (b) her. Bei diesem könnte jetzt wiederum überall dort, wo ein G steht, das Gleiche geschehen. (Das Muster (c) illustriert das gleiche, nur für eine andere Ausgangsfigur). Die vorstehende Abbildung (aus HOFSTADTER 1985) zeigt, wie sich aus dem Anfangsmuster (a) durch die beschriebenen Erweiterungen ein sog. Baum erzeugen lässt, der, wenn man die Knoten von unten nach oben durchnumeriert, an seinem rechten Rand die Fibonacci-Zahlen aufführt. Demzufolge müssten sich die Fibonacci-Zahlen gleichfalls durch einen rekursiven Algorithmus – hier als RTN (für Rekursives Transitions-Netzwerk oder recursive transition network) erzeugen lassen. Das RTN-Diagramm von HOFSTADTER (seine Abb. 31) zeigt, wie dies geschehen kann. (Links einzugeben ist FIBO(n) ) Etwas ganz Ähnliches zeigt – auf der vorstehenden Seite – die sogenannte HILBERT-Kurve. Das unvollständige Quadrat oben links ist die Hilbert-Kurve 1. Ordnung, also die Grundfigur, genannt das Axiom X. Die Figur oben rechts (die Kurve 2. Ordnung) entsteht aus vier (verkleinerten) Kopien dieser Grundfigur, die jedoch noch durch eine zusätzliche Linie (Y) verbunden und nach dem zugrundeliegenden Algorithmus auf bestimmte Weise in der Ebene gedreht werden (–). Wer die Ausführungen über L-Systeme gelesen hat (in denen bereits ähnliche Kurven, z.B. die Koch-, die Drachen- oder die Sierpinski-Kurve gezeigt wurden), sollte verstehen können, wie die Anweisung (die unter den Kurven 5. und 6. Ordnung steht) aufzufassen und auszuführen ist. Der Ausdruck „Kurve“ könnte hier etwas verwirren: die Hilbert-Kurve zeigt ja keinerlei „Krümmung“; stattdessen füllt sie zunehmend die Ebene aus, je höher ihre Ordnung ist, was zu der Frage führt, ob sie ein eindimensionales Gebilde ist – wie normale Kurven sonst – oder schon eher ein zweidimensionales. Tatsächlich ist ihre Dimension eine gebrochene Zahl (engl. fraction), weshalb es sich hier um ein Gebilde der sog. fraktalen Geometrie handelt. Die Kurven vieler rekursiven Funktionen weisen oft noch ganz andere verblüffende Eigenschaften auf. Als Beispiel diene der Graph (die Kurve) der von Hostadter (a.a.O., p. 150) erörterten Funktion INT(x): Diese diskontinuierliche – und fraktale – Kurve besteht bis in ihre unendliche Tiefe hinein nur aus Kopien ihrer selbst. Man könnte ein beliebiges Teilstück davon, sei es auch noch so winzig, herausvergrößern (zoomen) und erhielte eine vollständige Kopie des Bildes, das man oben vor sich sieht. In der fraktalen Geometrie bezeichnet man diese Eigenschaft als Selbstähnlichkeit. Diese ist uns übrigens auch von Blumenkohl oder Broccoli bekannt: bricht man aus einem Kopf Blumenkohl ein Röschen heraus, so gleicht dessen Gestalt weitgehend dem Ganzen. Diese Eigenschaft weist auch die Graphik auf der folgenden Seite auf: sie stellt eine sog. Julia-Menge dar, die einer spezifischen Koordinate der Mandelbrot-Menge (weithin inzwischen auch als „Apfelmännchen bekannt) entspricht. Auf der folgenden Seite sieht man den Auszug aus einem BASIC-Programm zur Erzeugung der Hilbert-Kurve: Hier kann man besonders gut erkennen, wie der Algorithmus gewissermaßen ineinander verschachtelt wird und die Berechnung für jede Ordnungsstufe durch den Befehl GOSUB auf die Berechnung der nächstniederen zurückgreift. In der Mengentheorie, in der mathematischen Logik und in der Automatentheorie hat der Ausdruck rekursiv jedoch noch eine andere Bedeutung, die mit der zuvor erläuterten nicht verwandt ist. Um die Eigenschaften eines logischen Systems, also eines Kalküls, zu untersuchen, ist es besonders beliebt, die Theoreme dieses Kalküls (das könnten Sätze sein oder auch nur Zeichenfolgen – strings –, wie sie hier bereits früher betrachtet wurden) sozusagen einfach zu nummerieren, genauer: sie eineindeutig (also eins zu eins) auf die Menge N der natürlichen Zahlen abzubilden (wobei die Einzelheiten der Zuordnung hier nicht von Bedeutung sind) und hernach die gewünschten strukturellen Untersuchungen an den Beziehungen zwischen den jeweiligen Zahlen durchzuführen. Der Vorteil besteht darin, dass die Strukturen der natürlichen Zahlen außerordentlich gut bekannt und übersichtlich sind. Vor allem aber können die natürlichen Zahlen ebenso wie die Elemente vieler ihrer Teilmengen – z.B. die geraden Zahlen, die Primzahlen usw. – stets durch einen Algorithmus (oder, wenn man lieber will; durch eine „Maschine“) erzeugt werden. Eine Menge P, die sich durch einen Algorithmus erzeugen lässt, welcher die Elemente von P eines um das andere (vielleicht mit Wiederholungen) generiert, bezeichnet man als rekursiv aufzählbar (recursively enumarable) * Die Menge N der natürlichen Zahlen ist rekursiv aufzählbar, ebenso – als Teilmengen davon – die Menge der geraden Zahlen : die Menge der Quadratzahlen: die Menge der Primzahlen: die Menge der Fibonacci-Zahlen 0, 2, 4, 6, 8, 10, ..... 0, 1, 4, 9, 16, 32 .... 2, 3, 5, 7, 11, 13.... 1, 1, 2, 3, 5, 8, 13, .. usw. Auch die Komplementärmengen dazu, welche alle in der jeweiligen Teilmenge nicht enthaltenen Elemente enthalten, sind rekursiv aufzählbar, z. B. für die ersten beiden Fälle 1, 3, 5, 7, 9, 11.... als Komplementärmenge der geraden Zahlen (= also die der ungeraden) oder 2, 3, 5, 6, 7, 8, 10.. als Komplementärmenge der Quadratzahlen, weil auch zur Erzeugung dieser Elemente ein Algorithmus existiert. Für die Menge N der natürlichen Zahlen kann man sogar einen Algorithmus angeben, der entscheidet, ob ein vorgegebenes Element z. B. zur Teilmenge der Primzahlen, der Kubikzahlen usw. oder zur jeweiligen Komplementärmenge gehört. Eine Menge R mit der Eigenschaft, dass sowohl sie selbst als auch ihre Komplementärmenge rekursiv aufzählbar sind, heißt eine rekursive Menge. Die Komplementärmenge einer rekursiven Menge ist gleichfalls eine rekursive Menge. Nun stellt sich ein scheinbar ganz exotisches Problem: Gibt es Mengen, die rekursiv aufzählbar, aber nicht rekursiv sind? Als wir (siehe Materialien 1 zur 4. Vorlesung) erläutert haben, was ein Kalkül ist, haben wir auch den Unterschied zwischen einem Theorem und einem Non-Theorem erklärt: ein * „Aufzählbar“ (enumerable) ist nicht das Gleiche wie „abzählbar“ (coutable)! Mathematiker sind da sehr pingelig, aber der Unterschied ist hier nicht von Belang. Theorem eines bestimmten Kalküls lässt sich nach den für ihn definierten generativen Regeln aus seinen Axiomen ableiten (oder erzeugen), ein Non-Theorem – etwa irgendein string, in dem die für den Kalkül eingeführten Basale (Zeichen) vorkommen – dagegen nicht. Die Theoreme eines Kalküls, der (mathematische oder semantische) Aussagen verknüpft, nennt man auch (seine) wahren Aussagen, die Non-Theoreme heißen dagegen falsch. Man hat sich nun lange vorgestellt, die Menge der falschen Aussagen eines Kalküls sei die Komplementärmenge zu der seiner wahren Aussagen, sodass das Ganze ungefähr so aussähe: Würde man zum Beispiel die Menge W aller wahren Sätze des Kalküls (oder der Theorie) im oben erläuterten Sinne auf die – beweisbar rekursiv aufzählbare – Menge der geraden Zahlen abbilden und die Komplementärmenge der falschen Sätze auf die der ungeraden, die ja gleichfalls rekursiv aufzählbar ist, so sollte es doch, da wir ja einen EntscheidungsAlgorithmus haben, der feststellen kann, ob irgendeine Zahl zur Teilmenge der geraden oder der der ungeraden gehört, ebenso möglich sein, für eine beliebige Aussage, der ja eine bestimmte Zahl aus N korrespondieren muss, zu entscheiden, ob sie zur Menge der wahren Aussagen (oben weiß) oder der der falschen (oben schwarz) gehört. Aber dem ist nicht so !! Nehmen wir an, wir haben einen Kandidaten k: eine Aussage, von der wir wissen wollen, ob sie eine gültige Aussage eines bestimmten Kalküls, also wahr ist oder ob sie in der Menge der wahren Aussagen des Kalküls gar nicht enthalten, mithin falsch ist. Da die Menge aller wahren Aussagen des Kalküls rekursiv aufzählbar ist, existiert ein Algorithmus, der alle ihre Elemente der Reihe nach erzeugt. Wir brauchten also nur die Ableitungsregeln (Generatoren) des Kalküls „in Betrieb zu setzen“, um ihn, angefangen mit den Axiomen, alle seine Theoreme erzeugen zu lassen, bis eines auftaucht, das mit dem „Kandidaten“ übereinstimmt. (Damit hätten wir übrigens k bewiesen). Natürlich könnte dieser Prozess, wenn k gar nicht zur Menge der Theoreme des Kalküls gehört, unendlich lange dauern. Aber wir könnten ja, parallel dazu, einen zweiten Algorithmus die Elemente der Komplementärmenge dazu (die Non-Theoreme) erzeugen lassen und abwarten, ob der Kandidat k dort auftaucht: wenn ja, hätten wir ihn widerlegt. Nur hat die Sache einen Haken: die letztere Prozedur funktioniert nur dann, wenn die Gesamtmenge aus Theoremen und Non-Theoremen (in der Abbildung oben: der ganze Kreis) rekursiv ist. Das ist sie wiederum nur dann, wenn auch die Komplementärmenge (also die der Non-Theoreme) rekursiv aufzählbar wäre. Aber das ist sie nicht! Es gibt zwar Non-Theoreme des Kalküls, aber keinen Algorithmus, der diese NonTheoreme der Reihe nach erzeugen könnte! Die Menge W (der wahren Aussagen des Kalküls) ist mithin zwar rekursiv aufzählbar, aber nicht rekursiv (weil ihre Komplementärmenge nicht rekursiv aufzählbar ist). Dies ist der Kern des GÖDEL’schen Theorems: es gibt keinen Algorithmus, mit dem sich stets entscheiden ließe, ob eine Aussage in Bezug auf einen bestimmten Kalkül wahr oder falsch ist. Als „rekursive Mathematik“ bezeichnet man deswegen Untersuchungen, die sich mit den Konsequenzen dieses erschütternden Sachverhalts befassen. (näheres hierzu bei PENROSE 1991, p. 117 ff.)