4.4 Ein Schritt weiter: while-Schleifen und $\mu$-Rekursion
4.4 Ein Schritt weiter: while-Schleifen und $\mu$-Rekursion
Primitive Rekursion erlaubt uns Schleifen, allerdings nur in einer sehr restriktiven Form:
Wir müssen anfangs bereits angeben, wie oft wir die Schleife durchlaufen wollen;
wir dürfen nur eine lokale Variable mitführen (und den Iterationsindex).
Der zweite Punkt ist keine echte Beschränkung, wie wir gesehen haben: wenn wir zwei lokale Variablen $a,b$ führen wollen, können wir die via der Bijektion ${\rm pair} : \N^2 \rightarrow \N$ in eine natürliche Zahl codieren. Der erste Punkt allerdings scheint eine echte Beschränkung zu sein: wir wissen schließlich nicht immer, wie oft wir eine Tätigkeit wiederholen müssen, bis wir fertig sind, und ob wir überhaupt jemals fertig werden. Sie kennen vielleicht die Collatz-Vermutung.
Wir definieren eine Funktion $f: \N_+ \rightarrow \N_+$ wie folgt:
Für eine natürliche Zahl $n$ können wir dann die Collatz-Folge definieren: $n, f(n), f(f(n)), ...$. Man sieht leicht, dass diese Folge in einer Schleife landen kann:
Wir beenden die Sequenz daher üblicherweise, wenn wir bei 1 (und somit in dieser Dreierschleife) gelandet sind. Es kann allerdings etwas länger dauern:
Oder noch länger. Wenn wir mit 27 beginnen, dann erhalten wir die Folge
Experimentieren Sie! Ich habe dafür die Html-Seite collatz.html erstellt. Es scheint: egal, wo Sie anfangen, Sie enden immer bei 1. Allerdings wissen wir nicht im Voraus, wie oft wir die Funktion $f$ anwenden müssen. Und wir wissen nicht einmal, ob man immer bei 1 ankommt, ob es andere Zyklen gibt oder ob es Startwerte gibt, für die die Folge einfach nach Unendlich divergiert. Bis zum heutigen Tage (Stand 30. April 2024) hat sich die Collatz-Vermutung zahlreichen Lösungsversuchung widersetzt und demonstriert eindrucksvoll, dass auch mathematische Probleme mit sehr einfacher Formulierung extrem schwierig sein können.
Eine Einschränkung primitiv-rekursiver Funktionen ist
also, dass wir immer vor der Schleife angeben müssen,
wie oft diese durchlaufen werden soll. Es gibt also
keine
while-Schleifen.
Führen wir diese nun ein.
def While (condition, step):
def f(x):
temp = x
while (condition(temp)):
temp = step(temp)
return temp
return f
Übungsaufgabe 4.4.1
Schreiben Sie mit Hilfe von
While,
PrimRec
und
Comp
eine Funktion
collatzList,
die aus einer Zahl
die Collatz-Folge baut, also
>>> collatzList(7) []