Document

Werbung
Terminierung funktionaler Programme
Obwohl für viele Rekursive Vorschrifften offensichtlich, kann diese für viele Funktionen
nicht unmittelbar abgelesen werden (z.B.: obiges Programm zur Permutation,
Ackermannfunktion). Deshalb wird Formalismus benötigt.
Wir betrachten Rechenvorschrifften der Funktionalität
fct f = (m x)n :E
Sei M die Trägermenge der Sorte m und M- = M \{  }.
Hier verstanden als Ergebniss einer nicht terminierenden Funktion
Dann terminiert die Funktion f xM, wenn xM: f(x) ≠ 
07.05.03
Um die Terminierungseigenschaft einer Fkt. zu zeigen, verwendet man eine sog.
„Abstiegsfunktion“
h: M-  IN0;
h gibt eine Abschätzung für die Anzahl rekursiver Aufrufe bei linearer Rekursion bzw. der
Höhe des Aufrufbaums bei nichtlinearer Rekursion.
Zum Beweis der Terminierung muss folgendes Prädikat gezeigt werden:
P [k  IN 0 , x  M  , h( x)  k  f ( x) ]
Es muss also für alle k gezeigt werden, dass P gilt, bzw. Berechnung der Funktion f umfasst
max. k Schritte für Argument x.
Nachweis durch Induktion:
 Für den IA (k=0) ist zu zeigen: x  M  , wenn h(x) = 0 =>
f ( x)  , d.h. f(x) terminiert.
 IS:
# Ind.annahme: P gilt für alle k’  k
# z.z ist dann, dass aus (h( x)  k  1) die Gültigkeit von f ( x)  folgt.
1. Beispiel: Terminierung der FKT ggT(a,b)
(mit a und b größer gleich 1)
let rec ggT(a,b) = match (a,b) with
|(a,b) when a= b  a
|(a,b) when a<b  ggT(a,b-a)
|(a,b) when a>b  ggT(a-b,b);;
1.Schritt:
Definition einer Ableitungsfunktion
h : INxIN  IN0
für a=b (Erzwinge ‘0’ für Terminierungsfall)
0
h( a, b)  
für (a>b) v (b>a)
a  b
Es geht in diesem Schritt immer darum eine Fkt. zu finden, die in Abhängigkeit der
Argumente des Fkt.aufrufes monoton fällt, und beim Terminierungsfall 0 landen wird.
Induktionsanfang:
h(a,b) = 0
=>
a = b => ggT(a,b) = a  
Induktionsschritt:
- Induktionsannahme: a, b 
Sei also :
: h(a, b)  k  ggT (a, b) 
0  h( a, b)  k  1
 h(a, b)  a  b  k  1
 (a  k )  (b  k ) weil a  1  b  1
Fall I
(a  b)  ggT (a, b)  ggT (a  b, b)
Für (a  b, b) ist jedoch h(a-b,b)= a  k
=> h(a-b,b)  k=>ggT(a-b,b) ≠ 
dann mit Definition der FKT ggT(a,b) terminiert auch ggT(a,b)
Fall II (a<b) analog
Prinzipielle Vorgehensweise
Sei f(x) = E die zu untersuchende Fkt.
1.Schritt:
2.Schritt:
2.Beispiel:
Zeige, dass unter der Voraussetzung h(x)=0 der Ausdruck E zu einem Ergebnis
≠  führt.
(Ind.Schluss) Unter der Voraussetzung h( x)  k  1 forme den Ausdruck E so
um, dass nur noch rekursive Aufrufe vorhanden sind, für die h(x)  k gilt.
Schnelle Berechnung von y = mn, m,n  IN
Naive Implementierung: y  m  m  ...  m
n 1 Multiplikation
Geschicktes Vorgehen:
Rückgriff auf bereits berechneten Teilprodukte, Zwei Fälle:
I.)
y  m  m  ...  m  m  m  ...  m = A  A für geradzahlige n
II.)
y  m  m  ...  m  m  m  ...  m m = A  A  m für geradzahlige n.
A
A
also:
 n  2
 m 2 


y
2
 n21 
 m 


A
A
für gerades n
für ungerades n
Damit fkt.:
1. Variante:
let rec expo (m,n) = match n with
| 0 -> 1
| n when (n mod 2 = 0) -> expo(m,n/2)*expo(m,n/2)
| n -> m * expo (m,(n-1)/2)*expo(m,(n-1)/2);;
2. Variante:
let expo2 m =
let rec aux(n)=match n with
| 0 ->1
| n -> let y = aux(n/2) in
if (n mod 2 = 0) then
y*y else m * y * y
in aux ;;
Für Terminierung :
Mögliche Abstiegsfunktion h(n) = n
Bei jedem rek. Aufruf Integer- Division
 Terminierung bei 0 gewährleistet.
Bemerkung: Häufig lässt sich die Terminierung durch strukturelle Ind. schnell zeigen.
Vorgehen:
- sei f(x) die Fkt. und x  M-;
- wähle für die Argumente der Fkt eine ’geeignete fundierte Ordnung’
- IA: zeige f(x min) ≠ wo x min die minimalen Elemente der Ordnung sind.
- Induktionsschluss: Wenn aus der Gültigkeit von f(z) ≠  für alle z = y die
Gültigkeit von f(y) ≠ folgt, dann ist f(x) ≠ für alle Elemente der Ordnung Fkt.
terminiert
Beispiel 3: Ackermann:
n  1 für m  0

A(m, n)   A(m  1,1) für m  0, n  0

 A(m  1, A(m, n  1)) für m, n  0
-
fundierte Ordnung: lexikographische Ordnung über IN0xIN0 also:
(0,0)<(0,1)<(0,2)< … <(1,0)<(1,1)<…
Damit Beweisführung über geschachtelte Ind.
# über m (äußere Ind)
# über n bei festem m (innere Ind))
a)
b)
Ind. anfang: m= 0
A(0,n)=n+1 ≠
Induktionsschritt:
Voraussetzung äußere Ind.
A(k,n) ≠ für 0  k < m und bel. n
- Innere Ind. über n zum Schluss auf m
o Anfang n = 0: A(m,0) = A(m-1,1)
≠  nach Voraussetzung der äußeren Induktion
o Voraussetzung: A(m,l) ≠  für bestes m und alle l = n
o Schluss auf n:
A(m,n)= A(m-1,A(m,n-1))
A(m,n-1) terminiert nach Voraussetzung und erzeugt k.
also:
A(m -1,k) und dies terminiert nach äußerer Voraussetzung
Also terminiert A(m,n) für alle drei Rekursionsfälle.
Bsp 4: (Klaus Funktion):
Rechenvorschrifft, bei der bis heute nicht bekannt ist, ob sie für alle Eingaben terminiert:
 Ausgehend von a0  IN und a0 > 0 erzeuge Zahlenfolge a0,a1…,an,… in der
folgenden Weise:
Brich ab, falls an=1
Bsp. Aufruf: für a0 = 3  3,10,5,16,8,4,2,1
Es ist offen, ob bei beliebiger Eingabe a0 die Länge der Liste endlich ist
Aufwand von Algorithmen

Speicher – bzw. Berechnungsaufwand eines Algorithmus hängen typischer Weise
empfindlich von den Parametern ab, die den Algorithmus übergeben werden.
Beispielsweise benötigen wir zur Berechnung von fak(n) n rekursive Aufrufe, zur
Berechnung der Permutation einer Sequenz der Länge n ca. n! rekursive Aufrufe.

Um den Aufwand abschätzen
Komplexitätsklassen ein.
Definition:
zu
können
 g (n) | c  0, n0  IN

O( f (n))  mit 0  g (n)  c  f (n)
 für n  n
0

führt
man
sogenannte
O(f(n)) definiert eine Klasse von Funktionen. Eine Funktion g(n) ist element der
Klasse O(f(n)), wenn ab einem bestimmten n0 die Funktion c*f(n) eine andere
Schranke für g(n) bildet.
Also:
g(n) wächst höchstens so schnell wie f(n). Wichtig ist das asymptotische Verhalten für
n -> unendlich
Beispiel:
n2
2
 O(n 2 )
n
 O(n 2 )
n log n  O (n 2 )
n3
 O(n 2 )
Bei der Fakultätsfunktion ist der Berechnungsaufwand proportional zu n => gehört der
Komplexitätsklasse O(n) an.
Herunterladen