Funktionale vs. logische Programmierung

Werbung
Funktionale vs. logische Programmierung:
Funktionale vs. logische Programmierung:
Vergleich
theoretische Basis der Berechnungen
• funktionale Programme unterscheiden zwischen Eingaben (Argumente
von Funktionen) und Ausgaben (Werte von Funktionen)
• funktionale Programme: Substitution
• relationale Programme in Prolog: Unifikation und Resolution
• relationale Programme treffen diese Unterscheidung nicht notwendigerweise
• was Eingabe und was Ausgabe einer Berechnung mit einem relationalen
Programm sein soll, wird durch die Art der Invokation festgelegt (m.a.W.
höhere Flexibilität)
WS 2006/2007, Programmierkonzepte und Modellierung (PKM), © Prof. Dr. D. Rösner; erstellt: 4. Dezember 2006
225
Funktionale vs. logische Programmierung:
226
Fallbeispiel: Umdrehen einer Liste cont.
Fallbeispiel: Umdrehen einer Liste
• Haskell: mit Pattern matching
• Prolog:
rev :: [a] -> [a]
rev [] = []
rev (x:xs) = rev xs ++ [x]
rev([],[]).
rev([X|Y],Z) :- rev(Y,Z1), append(Z1,[X],Z).
• Haskell: Variante mit Fallunterscheidung
• Scheme:
rev :: Eq a => [a] -> [a]
(define (rev l)
(if (null? l) l
(append (rev (cdr l)) (list (car l)))))
WS 2006/2007, Programmierkonzepte und Modellierung (PKM), © Prof. Dr. D. Rösner; erstellt: 4. Dezember 2006
WS 2006/2007, Programmierkonzepte und Modellierung (PKM), © Prof. Dr. D. Rösner; erstellt: 4. Dezember 2006
rev x = if x == [] then []
else rev (tail x) ++ [head x]
227
WS 2006/2007, Programmierkonzepte und Modellierung (PKM), © Prof. Dr. D. Rösner; erstellt: 4. Dezember 2006
228
Funktionale vs. logische Programmierung:
Fallbeispiel: Mergesort cont.
Fallbeispiel: Mergesort (cf. [Mueller & Page, Ch. 34])
• merge is predefined, redefined as mymerge
• Prolog:
mymerge([], X, X).
mymerge(X, [], X).
mergesort([], []) :- !.
mergesort([X], [X]) :- !.
mymerge([X1|R1], [X2|R2], [X1|R]) :- precedes(X1, X2),
mymerge(R1, [X2|R2], R).
mergesort(X, Sorted) :- split(X, X1, X2),
mergesort(X1, S1),
mergesort(X2, S2),
merge(S1, S2, Sorted).
mymerge([X1|R1], [X2|R2], [X2|R]) :- precedes(X2, X1),
mymerge([X1|R1],R2, R).
• Prolog benötigt Hilfsvariable (hier: S1, S2), um Zwischenergebnisse zu
‘transportieren’
WS 2006/2007, Programmierkonzepte und Modellierung (PKM), © Prof. Dr. D. Rösner; erstellt: 4. Dezember 2006
229
Fallbeispiel: Mergesort cont.
WS 2006/2007, Programmierkonzepte und Modellierung (PKM), © Prof. Dr. D. Rösner; erstellt: 4. Dezember 2006
230
Fallbeispiel: Mergesort (cf. [Mueller & Page, Ch. 34])
• Haskell:
• weitere Hilfsprädikate:
/* split a list of n elements into two near halfes */
sort :: Ord a => [a] -> [a]
/* firstn(X, 0, [], X). */
firstn([X|Y], 1, [X], Y).
firstn([X|Y], N, [X|YN], RN) :- N1 is N-1,
firstn(Y, N1, YN, RN).
sort [] = []
sort [x] = [x]
sort seq = merge (sort a) (sort b)
where (a,b) = split seq
• flexible Kombination von Funktionsaufrufen
split(X, X1, X2) :- length(X,N), N2 is ceiling(N/2),
firstn(X, N2, X1, X2).
• in Verbindung mit Pattern zum Zugriff auf Elemente eines Paares
WS 2006/2007, Programmierkonzepte und Modellierung (PKM), © Prof. Dr. D. Rösner; erstellt: 4. Dezember 2006
231
WS 2006/2007, Programmierkonzepte und Modellierung (PKM), © Prof. Dr. D. Rösner; erstellt: 4. Dezember 2006
232
Fallbeispiel: Mergesort (cf. [Mueller & Page, Ch. 34])
Wichtiger Unterschied
• Hilfsfunktionen:
• Pattern matching in Prolog:
split :: [a] -> ([a],[a])
split [] = ([],[])
split seq = splitAt (div (length seq) 2) seq
all_equal([]).
merge :: Ord a => [a] -> [a] -> [a]
merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys)
| x == y
= x:(merge xs ys)
| x < y
= x:(merge xs (y:ys))
| otherwise
= y:(merge (x:xs) ys)
all_equal([X,X | Y]) :- all_equal([X | Y]).
WS 2006/2007, Programmierkonzepte und Modellierung (PKM), © Prof. Dr. D. Rösner; erstellt: 4. Dezember 2006
all_equal([_]).
233
Wichtiger Unterschied cont.
234
Relationale Programme als ‘Generatoren’
• all_equal als Prädikat
• Pattern matching in Haskell:
?- all_equal([a,a,a,a]).
Yes
allEqual :: Eq a => [a] -> Bool
allEqual [] = True
allEqual [_] = True
allEqual (el1:el2:rest) = if el1 == el2
then allEqual (el2:rest)
else False
• all_equal als ‘Generator’
• Haskell: eine Variable darf in einem Pattern auf der linken Seite einer Definition nur einmal auftauchen
WS 2006/2007, Programmierkonzepte und Modellierung (PKM), © Prof. Dr. D. Rösner; erstellt: 4. Dezember 2006
WS 2006/2007, Programmierkonzepte und Modellierung (PKM), © Prof. Dr. D. Rösner; erstellt: 4. Dezember 2006
235
?- all_equal(X).
X = [] ;
X = [_G205] ;
X = [_G205, _G205] ;
X = [_G205, _G205, _G205] ;
...
WS 2006/2007, Programmierkonzepte und Modellierung (PKM), © Prof. Dr. D. Rösner; erstellt: 4. Dezember 2006
236
Herunterladen