Grundlagen der Informatik I “Programmierung”
Grundlagen der Informatik I “Programmierung”
Grundlagen der Informatik I “Programmierung”
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
4.3.10 Die Verifikation rekursiver Routinen<br />
In den bisherigen Abschnitten haben wir alle Arten von Anweisungen besprochen und Regeln aufgestellt, wie<br />
ihre Korrektheit zu beweisen ist. Bei diesen Betrachtungen haben wir jedoch einen Son<strong>der</strong>fall außer Acht<br />
gelassen, <strong>der</strong> bei <strong>der</strong> Verifikation noch Schwierigkeiten erzeugen kann, nämlich Routinen die sich selbst direkt<br />
o<strong>der</strong> indirekt wie<strong>der</strong> aufrufen. Unser Programmstück zur Berechnung <strong>der</strong> Fakultät (siehe Beispiel 4.3.9 auf<br />
Seite 161) hätten wir zum Beispiel auch durch folgende rekursive Funktion ausdrücken können.<br />
fak berechnung(n:INTEGER):INTEGER is<br />
require n>0<br />
do<br />
if n=1 then Result := 1<br />
else Result := n * fak berechnung(n-1)<br />
end<br />
end<br />
Dies spiegelt einen Gedankengang <strong>der</strong> Mathematik wie<strong>der</strong>, die Fakultätsfunktion statt durch eine Interation<br />
durch zwei Gleichungen 1!=1 ∧ n!=n*(n-1)! auszudrücken, und ist um einiges eleganter (und leichter zu<br />
verifizieren) als die Schleife. Dennoch tauchen rekursive Routinen tauchen in <strong>der</strong> Praxis recht selten auf, da<br />
<strong>der</strong> gleiche Effekt mit Schleifen oft effizienter zu erreichen ist. In manchen Fällen ist dies allerdings recht<br />
schwierig und deshalb kann man auf die Möglichkeit rekursiver Routinenaufrufe nicht sinnvoll verzichten.<br />
So gibt es zum Beispiel Sortierprogramme für Fel<strong>der</strong>, die zunächst einen “Mittelwert” bestimmen, das Feld<br />
in zwei Teile zerlegen, die nur größere bzw. nur kleinere Werte enthalten, und dann in jeden Teil wie<strong>der</strong><br />
nach dem gleichen Verfahren sortieren, bis es nichts mehr zu teilen gibt. Eine rekursive Beschreibung dieses<br />
sehr effizienten Verfahrens (“Quicksort”) ist auf Grundlage dieser Beschreibung sehr leicht zu geben. Ein<br />
Programm, welches dasselbe nur durch Einsatz von Schleifen erreicht, ist dagegen nicht so leicht zu finden.<br />
Darüber hinaus gibt es arithmetische Funktionen, die nur durch rekursive Gleichungen spezifiziert werden<br />
können. Ein beliebtes Beispiel hierfür sind die Fibonaccizahlen, die wie folgt beschrieben sind.<br />
Die erste Fibonaccizahl ist 1, die zweite ebenfalls.<br />
Alle größeren Fibonaccizahlen ergeben sich aus <strong>der</strong> Summe ihrer beiden Vorgänger.<br />
Bezeichnet man die n-te Fibonaccizahl mit fib(n), so kann man dies durch zwei Gleichungen ausdrücken:<br />
fib(1)=fib(2)=1, fib(n+2)=fib(n+1)+fib(n).<br />
Ein rekursives Programm für die Fibonaccizahlen ist leicht zu schreiben. Wir müssen nur jede Eingabe einheitlich<br />
durch den Parameter n beschreiben, die Fälle n=1, n=2 und n>2 unterscheiden und die zweite Gleichung<br />
durch eine Indextransformation n → n-2 umschreiben.<br />
fib(n:INTEGER):INTEGER is<br />
require n>0<br />
do<br />
if n