22.08.2013 Aufrufe

Grundlagen der Informatik I “Programmierung”

Grundlagen der Informatik I “Programmierung”

Grundlagen der Informatik I “Programmierung”

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

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

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!