Handout

Werbung
Listenverarbeitung bisher
Verschachtelte Listen,
Differenzlisten, Graphen
member/2
append/3
delete/3
reverse/2
reverse/3
permute/2
sort/2
qs/2
partition/4
Prolog Grundkurs WS 99/00
Christof Rumpf
[email protected]
29.11.99
deleteall/3
Listenelemente finden
Listen konkatenieren
Listenelemente löschen/einfügen
Liste umkehren (naiv)
Liste umkehren (mit Akkumulator)
Liste permutieren (n!)
Liste permutationssortieren (n!)
Liste mit Quicksort sortieren (n log n)
Liste in Teillisten partitionieren
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
2
makeset/3
% deleteall(Term,Liste1,Liste2)
deleteall(_,[],[]).
Termination
deleteall(X,[X|T1],L):Lösche X aus Kopf
deleteall(X,T1,L).
Lösche X aus Rest T1
deleteall(X,[H|T1],[H|T2]):Behalte Kopf H,
X \= H,
falls H ≠ X
deleteall(X,T1,T2).
Lösche X aus Rest T1
% makeset(Liste1,Liste2)
makeset([],[]).
makeset([H|T1],[H|T2]):deleteall(H,T1,L),
makeset(L,T2).
Termination.
Behalte Kopf H.
Löschen aller H aus T1 liefert L.
Entferne alle Duplikate aus L.
makeset/2 entfernt mit Hilfe von deleteall/3 alle
Duplikate aus Liste1 und liefert Liste2 als Ergebnis.
deleteall/3 löscht alle Vorkommen eines Terms aus einer
Liste, während delete/3 genau ein Vorkommen eines Terms
löscht und scheitert, wenn der Term nicht vorkommt.
29.11.99
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
3
29.11.99
Verschachtelte Listen
Das Prädikat flatten/2 wandelt eine
verschachtelte Liste in flache Liste um.
[1,2,3,[a,b,[x,y],c],4,5,[],6]
?- flatten([1,2,3,[a,b,[x,y],c],4,5,[],6],L).
L = [1,2,3,a,b,x,y,c,4,5,6]
yes
Die Verarbeitung von Listen von Listen erfordert
häufig doppelte Rekursion, sodaß bei einer
Zerlegung nicht nur der Rest, sondern auch der
Kopf rekursiv weiterverarbeitet wird.
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
4
Verflachen von Listen
Als Listenelemente können beliebige Terme
auftreten, also auch Listen.
29.11.99
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
5
29.11.99
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
6
1
Effizienz von flatten/2
flatten/2
%flatten(VerschachtelteListe, FlacheListe)
flatten([],[]).
Leere Liste ist schon flach.
flatten([H|T],FL):flatten(H,FH),
flatten(T,FT),
append(FH,FT,FL).
flatten/2 hat nach dem zweiten rekursiven
Aufruf einen Aufruf von append/3. Dies drückt
die Performance ähnlich nach unten, wie wir es
schon beim naiven reverse/2 gesehen haben.
Zerlege verschachtelte Liste.
Verflache Kopf.
Verflache Rest.
Konkateniere verflachten Kopf
und Rest zu Ergebnis.
Verbesserung: flatten/3 mit Akkumulator!
flatten(X,[X]):Term in flache Liste packen,
X \= [], X \= [_|_]. falls Term keine Liste ist.
29.11.99
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
7
29.11.99
flatten/3
flatten(VL,FL):flatten(VL,[],FL).
flatten([],[],[]).
flatten([],[H|Acc],FL):flatten(H,Acc,FL).
flatten([H|T],Acc,FL):is_list(H),
flatten(H,[T|Acc],FL).
flatten([H|T1],Acc,[H|T2]):not is_list(H),
flatten(T1,Acc,T2).
29.11.99
(2)
(5)
(8)
(11)
(13)
(16)
(19)
(21)
(24)
(27)
(30)
(34)
(35)
(38)
(40)
(41)
(44)
(47)
(47)
(44)
(41)
(40)
(38)
(35)
(34)
(31)
(30)
(27)
(24)
(21)
(19)
(16)
(13)
(11)
(8)
(5)
(2)
CALL:
CALL:
CALL:
CALL:
CALL:
CALL:
CALL:
CALL:
CALL:
CALL:
CALL:
CALL:
CALL:
CALL:
CALL:
CALL:
CALL:
CALL:
EXIT(N):
EXIT(N):
EXIT(N):
EXIT(N):
EXIT(N):
EXIT(N):
EXIT(N):
EXIT(N):
EXIT(N):
EXIT(N):
EXIT(N):
EXIT(N):
EXIT(N):
EXIT(N):
EXIT(N):
EXIT(N):
EXIT(N):
EXIT(N):
EXIT(N):
29.11.99
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
8
is_list/1
flatten/2 ruft flatten/3 auf.
Initialisierung des Akkumulators.
Termination.
Falls verschachtelte Liste leer,
verflache Kopf des Akkumulators.
Falls Kopf von VL nichtleere Liste,
nimm Rest von VL in Akkumulator
und verflache H.
Falls Kopf von VL keine Liste ist,
übernimm den Kopf in flache Liste
und verflache Rest von VL.
flatten([1,2,3,[a,b,[x,y,z],c],4,[],5,6],
[],
_0098)
flatten( [2,3,[a,b,[x,y,z],c],4,[],5,6],
[],
_0AB8)
flatten(
[3,[a,b,[x,y,z],c],4,[],5,6],
[],
_0C14)
flatten(
[[a,b,[x,y,z],c],4,[],5,6],
[],
_0D70)
flatten(
[a,b,[x,y,z],c],
[[4,[],5,6]],
_0D70)
flatten(
[b,[x,y,z],c],
[[4,[],5,6]],
_11E4)
flatten(
[[x,y,z],c],
[[4,[],5,6]],
_1340)
flatten(
[x,y,z],
[[c],[4,[],5,6]],
_1340)
flatten(
[y,z],
[[c],[4,[],5,6]],
_17B4)
flatten(
[z],
[[c],[4,[],5,6]],
_1910)
flatten(
[],
[[c],[4,[],5,6]],
_1A6C)
flatten(
[],
[[4,[],5,6]],
_1D00)
flatten(
[4,[],5,6],
[],
_1D00)
flatten(
[[],5,6],
[],
_1F94)
flatten(
[],
[[5,6]],
_1F94)
flatten(
[5,6],
[],
_1F94)
flatten(
[6],
[],
_2540)
flatten(
[],
[],
_269C)
flatten(
[],
[],
[])
flatten(
[6],
[],
[6])
flatten(
[5,6],
[],
[5,6])
flatten(
[],
[[5,6]],
[5,6])
flatten(
[[],5,6],
[],
[5,6])
flatten(
[4,[],5,6],
[],
[4,5,6])
flatten(
[],
[[4,[],5,6]],
[4,5,6])
flatten(
[c],
[[4,[],5,6]],
[c,4,5,6])
flatten(
[],
[[c],[4,[],5,6]],
[c,4,5,6])
flatten(
[z],
[[c],[4,[],5,6]],
[z,c,4,5,6])
flatten(
[y,z],
[[c],[4,[],5,6]],
[y,z,c,4,5,6])
flatten(
[x,y,z],
[[c],[4,[],5,6]],
[x,y,z,c,4,5,6])
flatten(
[[x,y,z],c],
[[4,[],5,6]],
[x,y,z,c,4,5,6])
flatten(
[b,[x,y,z],c],
[[4,[],5,6]],
[b,x,y,z,c,4,5,6])
flatten(
[a,b,[x,y,z],c],
[[4,[],5,6]],
[a,b,x,y,z,c,4,5,6])
flatten(
[[a,b,[x,y,z],c],4,[],5,6],
[],
[a,b,x,y,z,c,4,5,6])
flatten(
[3,[a,b,[x,y,z],c],4,[],5,6],
[],
[3,a,b,x,y,z,c,4,5,6])
flatten( [2,3,[a,b,[x,y,z],c],4,[],5,6],
[], [2,3,a,b,x,y,z,c,4,5,6])
flatten([1,2,3,[a,b,[x,y,z],c],4,[],5,6],
[],[1,2,3,a,b,x,y,z,c,4,5,6])
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
9
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
11
Das Prädikat is_list/1 ist beweisbar, wenn
das Argument eine leere oder nichtleere Liste ist.
is_list([]).
is_list([_|_]).
Aus Effizienzgründen verzichten wir auf
Korrektheit für is_list/1 , indem wir auf den
rekursiven is_list/1 -Beweis für Restlisten
nichtleerer Listen verzichten.
29.11.99
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
10
Graphen
Viele Probleme lassen sich graphentheoretisch
modellieren. Ein Graph ist ein mathematisches
Objekt mit klar definierten Eigenschaften und
Methoden.
Bäume sind Graphen mit speziellen
Eigenschaften. Wir nähern uns jetzt Bäumen an,
indem wir von gerichteten Graphen über DAGs zu
geordneten Bäumen kommen.
29.11.99
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
12
2
Gerichteter Graph
Prolog-Repräsentation: Graph
Ein gerichteter Graph G ist ein Tupel <N, E>, wobei
N(odes) eine Menge von Knoten und E(dges) eine
Menge E ⊆ N × N von Kanten ist.
a
G1 = <{a,b,c,d,e},
{<a,b>,<a,c>,
<b,d>,<d,c>,
<d,e>,<d,a>}>
29.11.99
b
c
d
als Fakten:
als Struktur:
node(a).
...
node(e).
edge(a,b).
...
edge(d,a).
([a,b,c,d,e],
[(a,b),(a,c),
(b,d),(d,c),
(d,e),(d,a)])
e
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
13
29.11.99
Transitive Hülle
Transitive Hülle für Faktenrepräsentation:
closure(X,Y):- edge(X,Y).
closure(X,Y):- edge(X,Z), closure(Z,Y)
1. E ⊆ H(G)
2. <x, y> ∈ H(G) ∧ <y, z> ∈ H(G)
⇒ <x, z> ∈ H(G)
Transitive Hülle für Listenrepräsentation:
Die transitive Hülle liefert uns alle Verbindungen,
die zwischen Knoten bestehen.
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
14
Berechnung in Prolog
Die transitive Hülle eines Graphen G= <N, E> ist
die Menge H(G) ⊆ N × N, sodaß gilt:
29.11.99
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
15
closure(X,Y,E):- member((X,Y),E).
closure(X,Y,E):- member((X,Z),E),
closure(Z,Y,E).
% E = [(N1,N2),...,(Ni,Nk)]
29.11.99
DAG
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
16
Bäume
Ein gerichteter azyklischer Graph
(DirectedAcyclicGraph) G = <N, E> ist ein Graph, für
den gilt:
Ein DAG G = <N, E> ist ein Baum, wenn gilt:
∀x,y,z ∈ N: <x, z> ∈ E ∧ <y, z> ∈ E ⇒ x = y
∀<x, y> ∈ H(G): x ≠ y
Jeder Knoten in einem Baum hat maximal einen
Vorgänger.
Kein Knoten ist in H(G) mit sich selbst
verbunden.
29.11.99
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
17
29.11.99
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
18
3
Geordnete Bäume
Beispiel Syntaxbaum
Ein geordneter Baum G = <N, E, O> ist ein Baum
mit einer totalen Ordnungsrelation O ⊆ N × N,
sodaß gilt:
∀x,y,z ∈ N: <x, y> ∈ E ∧ <x, z> ∈ E ∧ y ≠ z
⇒ <y, z> ∈ O ∨ <z, y> ∈ O
Zwei Relationen:
S
NP
Det
unmittelbare Dominanz
zwischen Mutter- und
Tochterknoten
VP
N
V
NP
lineare Präzedenz
zwischen Tocherknoten
Jeder Mann liebt Det N
Die unmittelbaren Nachfolger eines Knotens
stehen in einer linearen Ordnung.
29.11.99
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
eine Frau
19
29.11.99
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
Lineare Repräsentation in Prolog
als Struktur:
?- det(ein) =.. L.
L = [det,ein], yes
?- S =.. [det,ein].
S = det(ein), yes
als Liste:
[s, [np, [det, [jeder]], [n, [mann]]],
[vp, [v, [liebt]],
[np, [det, [eine]], [n, [frau]]]]]
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
Univ
Strukturen und Listen können ineinander überführt
werden. Prolog stellt dazu das eingebaute Prädikat
=.. (Univ) zur Verfügung.
s(np(det(jeder),n(mann)),
vp(v(liebt),np(det(eine),n(frau))))
29.11.99
21
29.11.99
Listen vs. Strukturen
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
?- np(det(ein),n(mann)) =.. L.
L = [np,det(ein),n(mann)]
Allgemein:
p(A1 ,...An ) =.. [p,A1 ,...An ]
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
22
Pretty Printing
?- pp(s(np(det(jeder),n(mann)),
vp(v(liebt),np(det(eine),n(frau)))))
s
np
det
jeder
Ein Pretty-Printer für Bäume ist
n
ein Programm, das die lineare
mann
vp
Repräsentation eines Baumes als
v
eingerückten Baum auf den
liebt
np
Bildschirm ausgeben kann.
det
eine
n
frau
Strukturen sind zwar für das menschliche Auge
leichter zu überblicken, dafür sind Listenrepräsentationen allerdings flexibler zu verarbeiten.
– Strukturen: Zugriff auf Argumente nur bei
bekanntem Funktor und bekannter Stelligkeit
möglich.
– Listen: Zerlegung in Kopf und Rest für jede
nichtleere Liste in gleicher Weise.
29.11.99
20
23
29.11.99
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
24
4
Handwerkszeug zum Drucken
pprint/1
Wir benötigen ein paar eingebaute Prädikate, um
einen Pretty-Printer implementieren zu können:
write(Term)
nl
tab(Integer)
Number is Expr
Schreibt Term auf den Bildschirm.
Bewirkt einen Zeilenvorschub.
Schreibt 0-n Leerzeichen.
Führt Berechnungen durch.
pprint(Term):- pprint(Term,0).
Initialisierung.
pprint(Term,N):Term =.. [Atom|[]],
Termination.
Term ist Blatt im Baum.
tab(N), write(Atom), nl.
pprint(Term,N):-
Ausgabe des Blatts.
Rekursion
Term =.. [F|Args],
Args \= [],
Term ist Mutterknoten
mit Töchtern.
tab(N), write(F), nl,
N1 is N+3,
Ausgabe des Knotens.
Tabulator erhöhen.
pprintl(Args,N1).
pprintl([H|T],N):pprint(H,N),
pprintl(T,N).
pprintl([],_).
29.11.99
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
25
29.11.99
Eine Differenzliste ist ein Paar von Listen (L1,L2),
wobei L2 ein Suffix von L1 repräsentiert. Die
Elemente einer Differenzliste sind die nach Abzug
von Suffix L2 verbleibenden Elemente in L1.
Differenzliste
gewöhnliche Liste
([E1,...,En|T],T)
[E1,...,En]
(L,[])
L
(L,L)
[]
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
27
26
[1,2,3] ⇔
⇔
⇔
⇔
29.11.99
([1,2,3],[])
([1,2,3,4,5],[4,5])
([1,2,3,a,b|T],[a,b|T])
([1,2,3|T],T)
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
28
append_dl/3
Differenzlisten haben einen entscheidenden
Vorteil gegenüber gewöhnlichen Listen: Man
kann sie in konstanter Zeit konkatenieren.
Genauer: in einem Schritt.
?- D1 = ([1,2,3|T1],T1),
D2 =([4,5,6|T2],T2),
append_dl(D1,D2,D3).
D3 = ([1,2,3,4,5,6|T2],T2), yes
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
Termination.
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
Für jede gewöhnliche Liste gibt es unendlich viele
Darstellungen als Differenzliste, weil es beliebige
Suffixe geben kann.
Konkatenation von Diff-Listen
29.11.99
Drucke eine Schwester.
Drucke die anderen Schwestern.
[1,2,3] als Differenzliste
Differenzlisten
29.11.99
Unterbäume drucken.
Schwesterknoten drucken.
append_dl((A,B),(B,C),(A,C)).
29
29.11.99
GK Prolog - Verschachtelte Listen, Differenzlisten, Graphen
30
5
Herunterladen