Primitiv rekursive Funktionen und -rekursive Funktionen:
specific part [[theo2_VergleichModelleBerechenbarkeit]] broad part of [[112.00_anchor_overview]]
Als Motivation wollen wir folgend betrachten: Mit primitiv rekursiven Funktionen und weiter -rekursiven Funktionen betrachten wir ein ganz anderes Berechnungsmodell, denn es fundiert primär auf der Mathematik und entsprang auch in dieser Sparte. Etwa vor 100 Jahren ward dieses System entwickelt - also so 1920er, wo es noch keine Informatiker*innen. Weiterhin gab es zu diesem Zeitpunkt auch noch keine Turingmaschinen!
Primitiv rekursive Funktionen:
Idee :
WIr betrachten folgend Funktionen, die eine feste Anzahl an natürlichen Zahlen als Eingabe erhalten und eine natürliche Zahl als Ausgabe erzeugen können. wir würde also die Abbildungsvorschrift aussehen? #card Wir schreiben also: Eine Funktion mit Eingaben nennt man dann auch eine -stellige Funktion.
Definition:
Die Menge der primitiv rekursiven Funktionen wir induktiv definiert wie folgt: Dabei haben wir im Induktionsanfang drei definierte Funktionen: konstante,nachfolgerfunktion und Projektionsfunktion, was machen diese? #card Induktionsanfang:
- DIe konstante, stellige Funktion ist pirmitiv rekursiv.
- Die Nachfolgerfunktion für successor ist folgend definiert: und ist sie primitiv rekursiv
- Die Projektionsfunktion der folgenden Form: , welche ebenfalls primitiv rekursiv ist.
Induktionsschritt: 4. Die Komposition von primitiv rekursiven Funktionen ist ebenfalls primitiv rekursiv, denn: Seien und diese ist primitiv rekursiv. Weiter ist es dann auc
- Primitive Rekursion: Seien jetzt ist primitiv rekursiv. Dann ist aber auch die folgende Funktion primitiv rekursiv. Betrachten wir dafür: -> wir haben die 0 geskipped! Dann auch:
Beispiel : Addition :
Betrachten wir die Addition wie folgt: ist eine primitiv rekursive Funktion. Warum? wie können wir sie beschreiben? #card schreiben wir sie wie folgt: und weiterhin dann wobei wir mit den Nachfolger bezeichnen wollen.
Intuition ist dann also eine mathematische Schreibweise, wie folgt: -> denn so ist die mathematische Definition der Addition wenn man die natürlichen Zahlen mit Hilfe der Peano-Axiome definiert.
Primitiv rekursive Funktion for:
Das wollen wir ferner zeigen und setzen als Intuition zuerst: welche Schritte werden wir gehen? wir müssen eine Initialisierung und später eine Konvertierung bzw Rekursion aufbauen #card -> Initialisierung : betrachte, dass hier die Eingaben den gleichen Betrag weiterbehalten werden, also die Argumente werden eins zu eins übernommen. weiter dann: –> wobei hier f jetzt das Ergebnis nach Schleifenschritten darstellt. Weiterhin haben wir nach der Anpassung jetzt definiert, was der Berechnung der Schleife basierend auf dem Ergebnis des vorigen Schleifendurchlaufs.
Satz : #card
Die Menge er primitiv rekursiven Funktionen stimmt genau mit der Menge der for-berechenbaren Funktionen überein.
Beweis:
Um dies zu zeigen, müssen wir auch beide Seiten betrachten, also die beidseitige Rekursion zeigen!
Also folgt zuerst die Richtung:
for berechenbar primitiv rekursiv berechenbar.
Dies wird wieder mit einer strukturellen Induktion beweisbar sein. Also jede Variable des for-Programms wird durch eine Variable der Funktion beschrieben.
Induktionsanfang: Wir können einfache Befehle in for-Programmen durch eine primitiv rekursive Funktion beschreiben: Also in etwa folgend: Intuitiv ist dann klar, denn wir haben es bereits gesehen/ wahrgenommen, dass die Addition primitiv rekursiv ist. Das Gleiche gilt für die Subtraktion und eine konstante Funktion –> das haben wir zuvor bereits gezeigt, bzw. kann man eine Subtraktion als Addition darstellen!
Induktionsschritt: Hintereinanderausführung: betrachten wir das for-programm: bedenke es wird als beschrieben. Unsere Induktionsannahme wäre jetzt: wir können die Programm durch zwei Funktionen beschreiben. Können wir das, dann können wir auch die Hintereinandeausführung dieser als Funktion schreiben: wir können sie dann wieder als primitiv rekursiv beschreiben.
Induktionsschritt 2 : for-Schleifen: Betrachten wir jetzt eine For-schleife; for do end: Unter Anwendung der Induktionsvoraussetzung können wir P durch eine Funktion beschreiben. Unter dieser Voraussetzung können wir jetzt also die for-Schleife folgend beschreiben: -> erstmal nur die Initialisierung der Variablen der for-Schleife. Weiter wobei wir mit die Berechnung in der for-Schleife beschreiben.
Somit haben wir die eine Richtung der Äquivalenz bereits gezeigt
primitiv rekursiv for-berechenbar:
Am Ende werden wir sehen, dass die Berechnung für diese Richtung exakt gleich ablaufen wird, man also mit einer Induktion die Schritte beweisen und dann zu einer for-Schleife umformen kann. Daraus folgt also die Äquivalenz!
-rekursive Funktionen:
Wir haben soeben die Äquivalenz zwischen for-Programmen und der rekursiven Funktion gezeigt. Also wissen wir auch, dass diese rekursiven Funktionen nicht turing-äquivalent sind, denn while for!
Wir würden jetzt gerne ein Konstrukt von rekursiven Funktionen bauen, was dennoch Turing-äquivalent ist, also mächtiger als normale rekursive Funktionen. Wir führen hierfür nun einen zweiten Rekursionsoperator ein, die -Rekursion wobei wir symbolisch als Minimum betrachten. #card Dabei ist eine -stellige Funktion gegeben. und wir wollen über ihre erstes Argument ein Minimum bilden: Also am Ende möchten wir folgendes finden:
Definition:
Die Menge der -rekursiven Funktionen wird induktiv folgend definiert. es gibt zwei eindeutige Beschreibung dieser Funktion, welche? #card
- Alle primitiv rekursiven Funktionen sind in enthalten.
- Alle Funktionen sind enthalten, die durch Anwendung des -Operators aus primär rekursiven Funktionen gebaut werden können: Das heißt folgend: Sei eine möglicherweise auch nur partiell definierte Funktion. Dann ist dann folgend definiert: Ist diese folgende Menge leer, dann ist undefiniert.
Partiell definiert heißt in diesem Kontext, :: dass die Funktion nicht terminieren muss und so auch an einer Stelle undefiniert sein kann.
Existenz von partiell definierten Funktionen:
Die -rekursive Funktionen müssen nicht total sein, also sie können auch nur partiell definiert sein. #card Das heißt dann, dass eine Funktion nicht jedem Element ihres Definitionsbereiches einen Wert zuweisen muss. Es kann also Definitionslücken geben.
Konstruktion:
Betrachten wir folgend die Intuition zur Funktion: wir suchen also das kleinste so, dass unser Term mit 0 resultiert. Weiter definieren wir die Menge dann so: Es kann sein, dass die Menge leer ist. In dem Fall ist dann der Funktionswert an dieser Stelle nicht definiert und nur eine partielle Funktion
Unterschied zur primitiven Rekursion:
Worin bestehen die zwei großen Unterschiede zur primitiven Rekursion? #card
- Ein Minimum über eine feste Anzahl von Variablen könnten auch primitiv rekursiv sein
- Der Knackpunkt ist hier, dass wir ein Minimum über die Menge bilden, von der wir vorher gar nicht wissen, wie viele Elemente sie enthalten könnte. –> Also unser Input kann scheinbar unendlich groß sein! Anders, als bei der primitiven Rekursion, wo unsere Anzahl / bzw. Menge begrenzt war.
wir wollen jetzt ferner zeigen, dass while-Programme -rekursiven Funktionen sind!
-rekursive Funktionen while
Die Menge der -rekursiven Funktionen stimmt genau mit der Menge der whhile-berechenbaren Funktionen überein.
Eine mögliche Beweisskizze könnte folgend aussehen: Wir werden wieder eine strukturelle Induktion anwenden Wir wissen bereits: primitiv rekursiv for. Jetzt müssen wir nur noch die Äquivalenz zwischen -Operator und while-Schleife zeigen.
Beweis:
while-Schleife -Operator, Intuition: Betrachte folgende While-Schleife: while do end wobei wir annehmen, dass durch eine -rek. Funktion dargestellt werden kann. ei der Wert der Variable , nachdem die while-Schleife malch durchlaufen wurde. Durch den -Operator können wir anschließend herausfinden, wann die Variable zum ersten Mal 0 entspricht! Dann können wir ab da eine primitiv rekursive Funktion definiere, die genau so oft hintereinander ausgeführt wird!
Beweisen wir die andere Richtung / Implikation : -rekursive while-schleife : hier ist er Beweis ähnlich wie zuvor, jedoch jetzt icht ausgeführt, da nicht relevant.
Resultat der Äquivalenz:
Wir wissen jetzt: was? #card
- primitiv rekursiv for
- -rekursiv while
- for while, aber nicht umgekehrt. Also muss es Funktionen geben die -rekursiv sind, aber nicht primitiv rekursiv!. Ein solches Beispiel wäre die Ackermann-Funktion::