Kapitel 4

Transcription

Kapitel 4
Deduktive Datenbanken
4
Sommersemester 2012
Datenstrukturen und Programmstrukturen
für Logikprogramme
2 Es werden einige zentrale Datenstrukturen und Programmstrukturen für
P ROLOG vorgestellt. Diese helfen beim Software Engineering, indem sie die
elegante und kompakte Programmierung unterstützen.
2 Es werden strukturelle Eigenschaften von definiten Logikprogrammen
untersucht. Ein sehr wichtiges Hilfsmittel zur Programmanalyse sind
Abhängigkeitsgraphen.
2 Es werden unterschiedlich starke Formen der Äquivalenz von
Logikprogrammen vorgestellt.
Mittels darauf aufbauender Programmtransformationen werden wir in
Kapitel 5 definite Logikprogramme effizienter auswerten, ohne die
zugrundeliegende Inferenzmaschine ändern zu müssen.
Prof. Dr. Dietmar Seipel
591
Deduktive Datenbanken
4.1
Sommersemester 2012
Datenstrukturen in P ROLOG
allgemeine Strukturen in P ROLOG:
2 Termzerlegung und –aufbau
2 dynamischer Aufbau und Aufruf von Goals
2 Operatoren (Funktoren)
spezielle, interessante Datenstrukturen:
2 Fakten und Regeln
– die clause–Datenbank von P ROLOG
– Fakten und Regeln als Listenargumente
2 die Field Notation zur Repräsentation von X ML–Daten
Prof. Dr. Dietmar Seipel
592
Deduktive Datenbanken
Sommersemester 2012
4.1.1 Terme und Goals
Termzerlegung und –aufbau
Terme können mittels functor/3 und arg/3 in ihre Bestandteile zerlegt
werden, und mittels ” =../2 ” können sie aufgebaut und zerlegt werden:
2 functor(+Term, ?Functor, ?Arity)
functor(?Term, +Functor, +Arity)
2 arg(+N, +Term, ?Argument)
2 +Term =.. [?Functor|?Arguments]
?Term =.. [+Functor|+Arguments]
Dabei ist ” =../2 ” das mächtigste Prädikat; mit ihm können die beiden anderen
simuliert werden.
Prof. Dr. Dietmar Seipel
593
Deduktive Datenbanken
Sommersemester 2012
Das Prädikat functor/3 bestimmt den Funktor und die Stelligkeit eines
Terms; z.B. ist der Listenfunktor ’.’ zweistellig:
?- functor(arc(a, b), Functor, Arity).
Functor = arc, Arity = 2
?- functor([a, b, c], Functor, Arity).
Functor = ’.’, Arity = 2
?- functor(Term, tc, 2).
Term = tc(_G123, _G124)
Prof. Dr. Dietmar Seipel
594
Deduktive Datenbanken
Sommersemester 2012
Das Prädikat arg/3 bestimmt die einzelnen Argumente eines Terms – mittels
findall/3 könnten alle Argumente bestimmt werden:
?- arg(2, arc(a, b), Argument).
Argument = b
?- arg(1, a+b+c, Argument).
Argument = a+b
Offenbar steht der Term a+b+c für +(+(a,b),c).
Prof. Dr. Dietmar Seipel
595
Deduktive Datenbanken
Sommersemester 2012
Das Prädikat ” =../2 ” kann Terme aufbauen bzw. zerlegen.
Der Aufruf ” Term =.. Xs ” baut aus einer gegebenen Liste Xs einen Term
auf:
?- Term =.. [arc, a, b].
Term = arc(a, b)
Derselbe Aufruf ” Term =.. Xs ” bestimmt zu einem gegebenen Term eine
Liste Xs bestehend aus dem Funktor und den Argumenten:
?- a+b+c =.. Xs.
Xs = [+, a+b, c]
Prof. Dr. Dietmar Seipel
596
Deduktive Datenbanken
Sommersemester 2012
functor/3 und arg/3 können mittels ” =../2 ” simuliert werden:
?- functor(Term, Functor, _),
arg(N, Term, Argument).
?- Term =.. [Functor|Arguments],
nth(N, Arguments, Argument).
”=../2 ” kann mittels functor/3 und arg/3 simuliert werden:
?- Term =.. [Functor|Arguments].
?- functor(Term, Functor, _),
findall( Argument,
arg(_, Term, Argument),
Arguments ).
Prof. Dr. Dietmar Seipel
597
Deduktive Datenbanken
Sommersemester 2012
Listen
2 Die []–Notation ist eine intuitive Abkürzung (syntactic sugar) für Listen.
2 Der (binäre) Listenfunktor ist ’.’. Falls X ein Element ist und Xs eine
Liste, so kann man .(X,Xs) kurz als [X|Xs] schreiben.
?- [a, b, c] = .(a, .(b, .(c, []))),
[a, b, c] = [a|[b,c]].
Yes
2 Falls Y keine Liste ist, so ist .(X,Y) immer noch ein erlaubter Term,
der dann allerdings keine Liste mehr repräsentiert:
?- .(a, b) = [a|b].
Yes
Prof. Dr. Dietmar Seipel
598
Deduktive Datenbanken
Sommersemester 2012
Auch Listen können mittels ”=../2” zerlegt werden:
?- [a, b, c] =.. Ys.
Ys = [’.’, a, [b, c]]
Bekanntlich steht die Listennotation [a,b,c] für .(a,.(b,.(c,[]))).
2 Also ist der Funktor ’.’,
2 das erste Argument ist a,
2 und die Restliste ist .(b,.(c,[])), was wiederum als [b,c] angezeigt
wird.
Prof. Dr. Dietmar Seipel
599
Deduktive Datenbanken
Sommersemester 2012
Datenstrukturen für Paare
2 Graph: Kantenmenge als Liste [a-b, a-d, b-c]
2 Multimenge: als Liste [a:2, b:3, c:1]
Graph:
Multimenge:
b
-c
b
a
a
b
R
c
a
d
b
2 Liste von Koordinatenpaaren: [point(1,1), point(2,4)]
Prof. Dr. Dietmar Seipel
600
Deduktive Datenbanken
Sommersemester 2012
Mit pair_lists(Mode, Xs, Ys, Pairs) kann man zwei gleichlange
Listen Xs und Ys zu einer genauso langen Liste Pairs paaren:
/* pair_lists(Mode, Xs, Ys, Pairs) <Mode can be ’[]’, ’,’, ’;’, :, -, pair, ... */
pair_lists(Mode, [X|Xs], [Y|Ys], [Pair|Pairs]) :pair_elements(Mode, X, Y, Pair),
pair_lists(Mode, Xs, Ys, Pairs).
pair_lists(_, [], [], []).
pair_elements(Mode, X, Y, Pair) :( Mode = ’[]’,
Pair = [X, Y]
; Pair =.. [Mode, X, Y] ).
Wenn man pair_elements mit If -> Then ; Else implementiert, dann
funktioniert die Zerlegung von Pairs in Xs und Ys im allgemeinen nicht
(z.B. nicht ohne die Angabe von Mode).
Prof. Dr. Dietmar Seipel
601
Deduktive Datenbanken
Sommersemester 2012
Man könnte pair_lists auch auf der Basis des Meta–Prädikats
maplist/4 implementieren, welches einen Aufruf auf 3 Listen anwendet:
pair_lists(Mode, Xs, Ys, Pairs) :maplist( pair_elements(Mode),
Xs, Ys, Pairs ).
Dies ist äquivalent zur folgenden Implementierung mittels foreach-do:
pair_lists(Mode, Xs, Ys, Pairs) :foreach(X, Xs), foreach(Y, Ys),
foreach(Pair, Pairs) do
pair_elements(Mode, X, Y, Pair).
Prof. Dr. Dietmar Seipel
602
Deduktive Datenbanken
Sommersemester 2012
Für Mode sind beliebige binäre Funktoren erlaubt.
?- Xs = [a, b], Ys = [1, 2],
pair_lists(’[]’, Xs, Ys, Pairs_1),
pair_lists(’,’, Xs, Ys, Pairs_2),
pair_lists(:, Xs, Ys, Pairs_3),
pair_lists(-, Xs, Ys, Pairs_4),
pair_lists(pair, Xs, Ys, Pairs_5).
Pairs_1
Pairs_2
Pairs_3
Pairs_4
Pairs_5
Prof. Dr. Dietmar Seipel
=
=
=
=
=
[[a, 1], [b, 2]],
[(a, 1), (b, 2)],
[a:1, b:2],
[a-1, b-2],
[pair(a, 1), pair(b, 2)]
603
Deduktive Datenbanken
Sommersemester 2012
Das Prädikat pair_lists/4 kann bidirectional verwendet werden:
2 Der Aufruf pair_lists(+Mode, +Xs, +Ys, -Pairs) bestimmt
zu einem vorgegebenen Paarungsmodus und zwei gleichlangen Listen die
Paarliste.
2 Der Aufruf pair_lists(?Mode, -Xs, -Ys, +Pairs) zerlegt
eine vorgegebene Paarliste in zwei gleichlangen Listen, und er bestimmt
gegebenenfalls sogar den Paarungsmodus.
Xs
6
Prof. Dr. Dietmar Seipel
Ys
?
Pairs
6
604
Deduktive Datenbanken
Sommersemester 2012
Man kann eine Paarliste Pairs in zwei gleichlange Listen Xs und Ys zerlegen
und den Paarungsmodus Mode bestimmen.
?- Pairs = [pair(a, 1), pair(b, 2)],
pair_lists(Mode, Xs, Ys, Pairs).
Mode = pair,
Xs = [a, b], Ys = [1, 2]
Der Paarungsmodus Mode muß bei allen Paaren gleich sein; sonst schlägt der
Aufruf fehl:
?- Pairs = [a:1, pair(b, 2)],
pair_lists(Mode, Xs, Ys, Pairs).
No
Prof. Dr. Dietmar Seipel
605
Deduktive Datenbanken
Sommersemester 2012
Operationen auf Graphen
2 Wegesuche, Erreichbarkeit (Bibliothek ugraphs.pl)
2 Bestimmung aller Knoten:
edges_to_vertices(Edges, Vertices) :pair_lists(-, Xs, Ys, Edges),
append(Xs, Ys, Zs), sort(Zs, Vertices).
?- Edges = [a-b, a-d, b-c],
pair_lists(-, Xs, Ys, Edges),
append(Xs, Ys, Zs), sort(Zs, Vertices).
Xs = [a,a,b], Ys = [b,d,c], Zs = [a,a,b,b,d,c],
Vertices = [a,b,c,d].
Prof. Dr. Dietmar Seipel
606
Deduktive Datenbanken
Sommersemester 2012
Operationen auf Multimengen
2 Bestimmung aller Elemente bzw. der Kardinalität
multiset_to_elements_and_cardinality(
Set, Elements, N) :pair_lists(:, Elements, Ns, Set),
add(Ns, N).
?- Set = [a:2, b:3, c:1],
pair_lists(:, Elements, Ns, Set),
add(Ns, N).
Elements = [a, b, c],
Ns = [2, 3, 1],
N = 6.
Prof. Dr. Dietmar Seipel
607
Deduktive Datenbanken
Sommersemester 2012
P ROLOG–Operatoren
Mittels des Aufrufs
current_op(?Precedence, ?Type, ?Name)
kann man die Präzedenz und den Typ von Operatoren ermitteln.
?- current_op(P, T, N).
P = 1200, T = xfx, N = :- ;
P = 1200, T = fx, N = :- ;
P = 600, T = xfy, N = : ;
P = 500, T = yfx, N = + ;
P = 500, T = fx, N = + ;
P = 400, T = yfx, N = * ;
...
Momentan enthält S WI–P ROLOG etwa 60 vordefinierte Operatoren.
Prof. Dr. Dietmar Seipel
608
Deduktive Datenbanken
Sommersemester 2012
Der Regeloperator “:-” ist sowohl binär als auch unär:
2 Direktive (fx, unär):
:- dynamic arc/2.
2 Regel (xfx, binär):
tc(X, Y) :arc(X, Z), tc(Z, Y).
In beiden Fällen hat er die Präzedenz 1200.
Prof. Dr. Dietmar Seipel
609
Deduktive Datenbanken
Sommersemester 2012
Präzedenz
2 Ein Term der Form
a :- b :- c
ist nicht erlaubt, da das “x” in “xfx” besagt, daß beide Argumente eine
kleinere Präzedenz haben müssen als “:-”.
2 Klammerung setzt die Präzedenz auf “0” herab, so daß
a :- (b :- c)
(a :- b) :- c
erlaubte Terme sind.
2 “X = a :- b” ist äquivalent zu “(X = a) :- b”,
denn “=” (Präzedenz 700) bindet stärker als “:-” (Präzedenz 1200).
Prof. Dr. Dietmar Seipel
610
Deduktive Datenbanken
Sommersemester 2012
Konsequenzen:
2 Falls beim Typ das “f” in der Mitte steht, so handelt es sich um einen
Infix–Operator.
2 “x” bedeutet, daß die Präzedenz eines Arguments echt kleiner sein muß
als die Präzedenz des Operators, “y” bedeutet kleiner oder gleich.
2 Die kleinere Präzedenz bindet stärker. Es gilt also Punkt (“*”, 400, yfx)
vor Strich (“+”, 500, yfx), d.h. |{z}
1 + 2|{z}
∗ 3 = 1 + (2 ∗ 3), und nicht
|{z}
∗ |{z}
3 = (1 + 2) ∗ 3. 0 500 400
1| {z
+ 2} |{z}
500
400
0
2 Das “y” faßt zuerst zusammen. Es gilt also a:b:c = a:(b:c), da der
Typ von “:” gleich “xfy” ist.
2 Operatoren können überladen sein. “+” ist z.B. auch ein unärer
Präfix–Operator (“+”, fx).
Prof. Dr. Dietmar Seipel
611
Deduktive Datenbanken
Sommersemester 2012
Seien α und αi , für i = 1, 2, Terme mit den Präzedenzen γi .
2 Konstanten, Variablen und geklammerte Terme (α) haben die Präzedenz 0.
2 Einen binärer Term α1 ⊙ α2 hat dieselbe Präzedenz γ⊙ wie sein Operator ⊙.
Der Typ t1 ft2 erfordert: ti = x =⇒ γi < γ⊙ und ti = y =⇒ γi ≤ γ⊙ .
Z.B. ergibt sich für den Operator + mit der Präzedenz 500 und dem Typ yfx:
2 Der Term 1 + 2 + 3 muß in α1 = 1 + 2 und α2 = 3 zerlegt werden.
Dann ist γ1 = 500 = γ+ und γ2 = 0 < γ+ :
1 + 2 + |{z}
3 .
| {z } |{z}
500
500
0
2 Die Zerlegung in α1 = 1 und α2 = 2 + 3 ist nicht möglich, denn sie würde
γ2 = 500 = γ+ ergeben und somit gegen die Bedingung γ2 < γ+ verstoßen:
1 |{z}
+ 2| {z
+ 3} .
|{z}
0
Prof. Dr. Dietmar Seipel
500
500
612
Deduktive Datenbanken
Sommersemester 2012
Assoziativität:
2 Für die Auswertung von arithmetischen Termen über assoziativen
Operatoren wäre es eigentlich egal wie man zusammenfaßt.
?- X is 1+(2+3), X is (1+2)+3.
X = 6.
2 Die ungeklammerte Fassung 1+2+3 ist äquivalent zu (1+2)+3, aber die
unterschiedlichen Zusammenfassungen unifizieren nicht:
?- 1+2+3 = (1+2)+3.
Yes
?- 1+(2+3) = (1+2)+3.
No
2 Die Division ist nicht assoziativ, denn (16/8)/2 = 1 6= 4 = 16/(8/2).
Prof. Dr. Dietmar Seipel
613
Deduktive Datenbanken
Sommersemester 2012
Mittels des Aufrufs
op(+Precedence, +Type, +Name)
kann man die Präzedenz und den Typ eines neuen Operators definieren.
?- op(900, xfy, likes).
Yes
?- current_op(800, yfx, and).
Yes
?- read_term_to_picture.
|: mary likes george and bill and books.
Yes
Prof. Dr. Dietmar Seipel
614
Deduktive Datenbanken
Sommersemester 2012
Gegenwärtig sind in S WI–P ROLOG keine Standard–Operatoren mit den Typen
xf bzw. yf definiert.
Solche unären Postfix–Operatoren sind aber durchaus möglich:
?- op(500, yf, is_clever).
Yes
?- X = is_clever(mary).
X = mary is_clever.
Dann werden Terme mit dem Operator (hier: is_clever ) in
Postfix–Schreibweise angezeigt, selbst wenn sie in der
Standard–Präfix–Schreibweise mit Klammerung eingegeben wurden.
Prof. Dr. Dietmar Seipel
615
Deduktive Datenbanken
Sommersemester 2012
P ROLOG–intern werden Terme als Listen repräsentiert:
2 arc(a,b) als [arc,a,b] ,
2 +(2,3) als [+,2,3] .
Wie in Lisp ist der Funktor das erste Listenelement, und er wird von den
Argumenten gefolgt.
So gesehen gibt der Operator “ =../2 ” lediglich den Blick auf die interne
Listenrepräsentation frei.
Die externe Präsentation eines Termes hängt vom Typ des Funktors ab:
2 Da zu arc nichts bekannt ist, wird arc(a,b) in Präfixschreibweise
angezeigt.
2 Da + als Infix–Operator bekannt ist, wird +(2,3) in Infixschreibweise
als 2+3 angezeigt.
Prof. Dr. Dietmar Seipel
616
Deduktive Datenbanken
Sommersemester 2012
Dynamischer Aufbau und Aufruf von Goals
Wenn man zur Laufzeit dynamisch Goals aufbauen und aufrufen möchte,
so verwendet man die Prädikate call/n , für n ≥ 1, oder apply/2 :
2 call(+Atom) ,
2 call(+Atom, +Arg1 , ..., Argn−1 ) ,
2 apply(+Atom, +Arguments)
Dabei muß “Atom” ein atomares Goal sein und “Arguments” eine Liste,
was man mit “is_list(Arguments)” testen kann.
Man kann den Parameter a in einem Aufruf call(f(a),X,Y) wie bei einer
mathematischen Funktionenschaar jeweils als fixiert ansehen: vgl. z.B.
Y = fa (X) = a · X 2 . In der Programmierung nennt man diese Parametrisierung
von Prädikaten Currying.
Prof. Dr. Dietmar Seipel
617
Deduktive Datenbanken
Sommersemester 2012
Wenn das Prädikatensymbol eines aufzurufenden Atoms erst zur Laufzeit
berechnet oder eingelesen wird, dann muß man call/n oder apply/2
verwenden:
?- read(P), read(X), read(Y), call(P, X, Y).
|: is.
|: X.
|: 2+3.
P = (is), X = 5, Y = 2+3
Man kann hier nicht P(X,Y) anstelle von call(P,X,Y) schreiben,
da das Prädikatensymbol eines Atoms immer ein P ROLOG–Atom sein muß –
und folglich keine Variable sein kann.
Im Aufruf call(P,X,Y) zum Meta–Prädikat call/3 taucht P dagegen –
in erlaubter Weise – als Argument auf.
Prof. Dr. Dietmar Seipel
618
Deduktive Datenbanken
Sommersemester 2012
?- A =.. [add, 2, 3, Z], call(A).
A = add(2, 3, 5), Z = 5
?- call((add(2, 3, Z), add(Z, 4, Y))).
Z = 5, Y = 9
?- apply(add, [2, 3, Z]).
Z = 5
Äquivalent dazu kann man auch eines der folgenden 3 Goals aufrufen:
apply(add(2), [3,Z]),
apply(add(2,3), [Z]),
apply(add(2,3,Z), []).
Prof. Dr. Dietmar Seipel
619
Deduktive Datenbanken
Sommersemester 2012
Man könnte apply/2 wie folgt implementieren:
apply(A, Xs) :A =.. As,
append(As, Xs, Bs),
B =.. Bs,
call(B).
Zu einem atomaren Goal A und einer Liste Xs von weiteren Argumenten
wird ein neues Goal B aufgebaut und aufgerufen:
A = P(Y1 ,...,Yn ),
Xs = [X1 ,...,Xm ],
B = P(Y1 ,...,Yn ,X1 ,...,Xm ).
Prof. Dr. Dietmar Seipel
620
Deduktive Datenbanken
Sommersemester 2012
Das Meta–Prädikat fold/4 für assoziative Prädikate/Operatoren
fold(Predicate, Acc, [X|Xs], Result) :!,
apply(Predicate, [Acc, X, Acc_2]),
fold(Predicate, Acc_2, Xs, Result).
fold(_, Acc, [], Acc).
Diese Listenrekursion kann nicht direkt mittels der bisher bekannten
Meta–Prädikate ausgedrückt werden. Der Aufruf fold(+P,+I,+Xs,-O)
führt für eine Liste Xs = [X1 ,...,Xn ] zu folgender Berechnung:
2 V1 = I .
2 Vi+1 wird aus Vi und Xi mittels P(Vi ,Xi ,Vi+1 ) bestimmt.
2 O = Vn+1 .
Prof. Dr. Dietmar Seipel
621
Deduktive Datenbanken
Sommersemester 2012
Die Reihenfolge der Regeln wurde aus Effizienzgründen ganz bewußt gewählt:
2 Die erste Regel für nicht–leere Listen [X|Xs] wird für alle Listenelemente
X angewendet.
2 Durch den Cut weiß das System dann, daß die zweite Regel nicht verwendet
werden kann; so kann der Choice Point frühzeitig aufgegeben werden.
2 Erst ganz am Ende der Berechnung wird einmal die zweite Regel auf die
leere Liste [] angewendet.
Wenn die Anfangsliste also n Elemente enthält, dann wird n mal die passende
Regel, nämlich die erste, und nur diese, zuerst probiert.
Nur einmal wird ganz am Ende der Berechnung zuerst die falsche Regel und
dann die passende Regel, nämlich die zweite, probiert.
Prof. Dr. Dietmar Seipel
622
Deduktive Datenbanken
Sommersemester 2012
my_add(Xs, Y) :fold(add, 0, Xs, Y).
add(X, Y, Z) :Z is X + Y.
?- my_add([2,3,4], Y).
Y = 9
Aufrufe von fold/4 :
fold(add, 0, [2,3,4], Y)
U fold(add, 2, [3,4], Y)
U fold(add, 5, [4], Y)
Vi
Xi
U Vi+1
U fold(add, 9, [], Y)
Prof. Dr. Dietmar Seipel
623
Deduktive Datenbanken
Sommersemester 2012
Die Implementierung mittels fold/4 ist kürzer und eleganter als die bereits
bekannte end–rekursive Implementierung mittels Akkumulatoren:
sum(Xs, Sum) :sum(Xs, 0, Sum).
sum([X|Xs], Acc, Sum) :Acc_2 is Acc + X,
sum(Xs, Acc_2, Sum).
sum([], Acc, Acc).
Man kann die Parallelen in den Implementierungen von sum/3 und fold/4
erkennen. Letzteres verwendet anstelle von ”+” ein beliebiges Prädikat als
Parameter.
Prof. Dr. Dietmar Seipel
624
Deduktive Datenbanken
Sommersemester 2012
Die Berechnung startet mit dem neutralen Element (Summe: 0, Produkt: 1).
Darauf werden die Zahlen aus Xs von links beginnend addiert bzw. multipliziert:
my_multiply(Xs, Y) :fold(multiply, 1, Xs, Y).
?- my_multiply([2,3,4], Y).
Y = 24
?- my_multiply([], Y).
Y = 1
Die leere Summe ist 0, das leere Produkt ist 1.
Prof. Dr. Dietmar Seipel
625
Deduktive Datenbanken
Sommersemester 2012
Auch eine Liste von Listen kann man mittels fold/4 aneinander hängen:
append(Lists, List) :fold(append, [], Lists, List).
?- append([[1, 2], [a, b, c], [x, y]], List).
List = [1, 2, a, b, c, x, y]
?- append([], List).
List = []
Für lange Listen wäre hier allerdings eine effizientere Implementierung
vorzuziehen, da man sonst sehr oft an eine immer länger werdende Liste im
Akkumulator hinten anhängt.
Prof. Dr. Dietmar Seipel
626
Deduktive Datenbanken
Sommersemester 2012
4.1.2 Logikprogramme als Klauseln oder als Terme
Mit den folgenden D DK–Prädikaten kann man zwischen der Repräsentation von
Fakten als P ROLOG–Klauseln bzw. als Listen wechseln:
2 assert_facts/1: speichert eine gegebene Liste von Fakten in der
P ROLOG–Datenbank
2 collect_facts/2: sammelt alle Fakten zu einem gegebenen Prädikat
aus der P ROLOG–Datenbank
2 retract_facts/2: sammelt alle Fakten zu einem gegebenen Prädikat
aus der P ROLOG–Datenbank und löscht sie dort gleichzeitig
Prof. Dr. Dietmar Seipel
627
Deduktive Datenbanken
Sommersemester 2012
% assert_facts(+Facts) <assert_facts(Facts) :foreach(A, Facts) do assert(A).
% collect_facts(+Predicate/Arity, -Facts) <collect_facts(Predicate/Arity, Facts) :functor(Fact, Predicate, Arity),
findall( Fact, clause(Fact, true), Facts ).
Prof. Dr. Dietmar Seipel
628
Deduktive Datenbanken
Sommersemester 2012
Man muß in collect_facts/2 den Aufruf clause(Fact, true)
machen, und nicht call(Fact). Sonst würde man das Programm auswerten
anstelle nach Fakten zu suchen.
Der Aufruf collect_facts(a/1, Facts) würde für das Programm
a(1).
a(2) :- b.
b.
z.B. falsche Resultate liefern:
2 mit clause/2: Facts = [a(1)].
2 mit call/1: Facts = [a(1), a(2)].
Prof. Dr. Dietmar Seipel
629
Deduktive Datenbanken
Sommersemester 2012
% retract_facts(+Predicate/Arity, -Facts) <retract_facts(Predicate/Arity) :functor(Fact, Predicate, Arity),
retractall(Fact).
retract_facts(Predicate/Arity, Facts) :functor(Fact, Predicate, Arity),
findall( Fact, retract(Fact), Facts ).
Würde man retract_facts(P/A) mittels retract_facts(P/A, _)
implementieren, so würde die Liste der gelöschten Fakten umsonst berechnet.
Prof. Dr. Dietmar Seipel
630
Deduktive Datenbanken
Sommersemester 2012
?- Facts = [ price(screw, 2),
components(engine, cylinder, 4),
components(engine, valve, 4) ],
assert_facts(Facts).
Yes
?- listing(components/3).
:- dynamic components/3.
components(engine, cylinder, 4).
components(engine, valve, 4).
Yes
?- retract_facts(components/3).
Yes
?- listing(components/3).
:- dynamic components/3.
Yes
Prof. Dr. Dietmar Seipel
631
Deduktive Datenbanken
Sommersemester 2012
Regeln in D IS L OG
2 In D IS L OG können normale Regeln
A ← B1 ∧ . . . ∧ Bm ∧ not C1 ∧ . . . ∧ not Cn
als P ROLOG–Terme
[A]-[B1,...,Bm]-[C1,...,Cn]
repräsentiert werden.
2 Falls n = 0 ist, so können wir auch [A]-[B1,...,Bm] schreiben;
falls n = m = 0 ist, so können wir auch [A] schreiben.
2 Beispiel einer definiten Regel:
[tc(X, Y)]-[arc(X, Z), tc(Z, Y)]
Prof. Dr. Dietmar Seipel
632
Deduktive Datenbanken
Sommersemester 2012
Es wurde die Listennotation für Regelköpfe gewählt um Regeln mit beliebig
vielen Kopfatomen (z.B. auch Goals mit 0 Kopfatomen) repräsentieren zu
können.
2 In D IS L OG können disjunktive Regeln
A1 ∨ . . . ∨ Ak ← B1 ∧ . . . ∧ Bm ∧ not C1 ∧ . . . ∧ not Cn
als P ROLOG–Terme
[A1,...,Ak]-[B1,...,Bm]-[C1,...,Cn]
repräsentiert werden.
Prof. Dr. Dietmar Seipel
633
Deduktive Datenbanken
Sommersemester 2012
Input/Ouput für Files
2 Der Aufruf
dread(+Type, +File, -Rules)
lädt ein Logikprogramm aus einem File in eine Liste von D IS L OG–Regeln
(für Type = lp ) bzw. P ROLOG–Regeln (für Type = pl ).
2 Der Aufruf
dwrite(+Type, +File, +Rules)
schreibt eine Liste von D IS L OG– (für Type = lp ) bzw. P ROLOG–Regeln
(für Type = pl ) in ein File.
2 Falls File = user, so erfolgt die Ausgabe auf der Konsole.
Dann kann man auch einfach dwrite(+Type, +Rules) aufrufen.
Prof. Dr. Dietmar Seipel
634
Deduktive Datenbanken
Sommersemester 2012
?- dread(lp, ’tc.pl’, Program),
tp_iteration(Program, Interpretation).
...
Program = [
[tc(X, Y)]-[arc(X, Y)],
[tc(X, Y)]-[arc(X, Z), tc(Z, Y)],
[arc(a, b)], [arc(b, c)], [arc(c, d)] ]
Interpretation = [
arc(a, b), arc(b, c), arc(c, d),
tc(a, b), tc(a, c), tc(a, d),
tc(b, c), tc(b, d), tc(c, d) ]
Prof. Dr. Dietmar Seipel
635
Deduktive Datenbanken
Sommersemester 2012
?- Program = [
[tc(X, Y)]-[arc(X, Y)],
[tc(X, Y)]-[arc(X, Z), tc(Z, Y)],
[arc(a, b)], [arc(b, c)], [arc(c, d)] ],
dwrite(lp, Program),
dwrite(lp, ’tc_new.pl’, Program).
tc(X1,
tc(X1,
arc(a,
arc(b,
arc(c,
X2) :- arc(X1, X2).
X2) :- arc(X1, X3),tc(X3, X2).
b).
c).
d).
Program = [...]
Prof. Dr. Dietmar Seipel
636
Deduktive Datenbanken
Sommersemester 2012
Konversion
In P ROLOG würde eine D IS L OG–Regel
[A]-[B1,...,Bm]-[C1,...,Cn]
mit atomarem Regelkopf anstelle von Listen im Regelrumpf mit Hilfe von
Komma–Strukturen repräsentiert werden als
A :- (B1,...,Bm,not(C1),...,not(Cn))
2 Die Umformung einer Liste in eine Komma–Struktur erfolgt mittels
list_to_comma_structure(Atoms, Body).
2 Die Umformung einer Komma–Struktur in eine Liste erfolgt mittels
comma_structure_to_list(Body, Atoms).
Prof. Dr. Dietmar Seipel
637
Deduktive Datenbanken
Sommersemester 2012
Das Prädikat dislog_rule_to_prolog_rule/2 überführt eine
D IS L OG–Regel nach P ROLOG:
% dislog_rule_to_prolog_rule(+Rule_1, -Rule_2) <dislog_rule_to_prolog_rule(Rule_1, Rule_2) :parse_dislog_rule(Rule_1, [A], [ ], [ ]),
!,
Rule_2 = A.
dislog_rule_to_prolog_rule(Rule_1, Rule_2) :parse_dislog_rule(Rule_1, [A], Bs, Cs),
( foreach(C, Cs), foreach(D, Ds) do D = not(C) ),
append(Bs, Ds, Atoms),
list_to_comma_structure(Atoms, Body),
Rule_2 = (A :- Body).
Prof. Dr. Dietmar Seipel
638
Deduktive Datenbanken
Sommersemester 2012
Das Prädikat prolog_rule_to_dislog_rule/2 überführt eine
P ROLOG–Regel nach D IS L OG:
% prolog_rule_to_dislog_rule(+Rule_1, -Rule_2) <prolog_rule_to_dislog_rule(Rule_1, Rule_2) :Rule_1 = (A :- Body),
!,
( Body = true ->
Rule_2 = [A]
; comma_structure_to_list(Body, Atoms),
findall( B, ( member(B, Atoms), B \= not(_) ), Bs ),
findall( C, member(not(C), Atoms), Cs ),
Rule_2 = [A]-Bs-Cs ),
!.
prolog_rule_to_dislog_rule(A, [A]).
Prof. Dr. Dietmar Seipel
639
Deduktive Datenbanken
Sommersemester 2012
Die folgenden Bilder zeigen die Regel
tc(X, Y) :arc(X, Z), tc(Z,Y).
als P ROLOG–Term (links) bzw. als D IS L OG–Term (rechts):
Prof. Dr. Dietmar Seipel
640
Deduktive Datenbanken
Sommersemester 2012
% dislog_rules_to_prolog_rules(+Rules_1, -Rules_2) <dislog_rules_to_prolog_rules(Rules_1, Rules_2) :maplist( dislog_rule_to_prolog_rule,
Rules_1, Rules_2 ).
% prolog_rules_to_dislog_rules(+Rules_1, -Rules_2) <prolog_rules_to_dislog_rules(Rules_1, Rules_2) :maplist( prolog_rule_to_dislog_rule,
Rules_1, Rules_2 ).
Prof. Dr. Dietmar Seipel
641
Deduktive Datenbanken
Sommersemester 2012
Einfügen und Löschen in der internen P ROLOG–Datenbank
Mit den folgenden D DK–Prädikaten kann man zwischen der Repräsentation von
Regeln als P ROLOG–Terme (auf Argumentebene) bzw. als P ROLOG–Klauseln (in
der internen P ROLOG–Datenbank) wechseln:
2 assert_rules/1: speichert eine gegebene Liste von P ROLOG–Regeln in
der P ROLOG–Datenbank
2 collect_rules/2: sammelt alle P ROLOG–Regeln zu einem gegebenen
Prädikat aus der P ROLOG–Datenbank
2 retract_rules/2: sammelt alle P ROLOG–Regeln zu einem gegebenen
Prädikat aus der P ROLOG–Datenbank und löscht sie dort gleichzeitig
Es gibt jeweils eine entsprechende Version für D IS L OG–Regeln.
Prof. Dr. Dietmar Seipel
642
Deduktive Datenbanken
Sommersemester 2012
% assert_rules(+Rules) <assert_rules(Rules) :foreach(Rule, Rules) do assert(Rule).
% assert_dislog_rules(+Rules) <assert_dislog_rules(Rules) :dislog_rules_to_prolog_rules(Rules, Rules_2),
assert_rules(Rules_2).
Ein P ROLOG–Fakt A ist dabei äquivalent zu einer Regel A :- true,
und ein D IS L OG–Fakt [A] ist äquivalent zu einer Regel [A]-[].
Prof. Dr. Dietmar Seipel
643
Deduktive Datenbanken
Sommersemester 2012
?- Program = [
[tc(X, Y)]-[arc(X, Y)],
[tc(X, Y)]-[arc(X, Z), tc(Z, Y)],
[arc(a, b)], [arc(b, c)], [arc(c, d)] ],
assert_dislog_rules(Program).
Program = [...]
?- tc(a, Y).
Y = b;
Y = c;
Y = d
Prof. Dr. Dietmar Seipel
644
Deduktive Datenbanken
Sommersemester 2012
% collect_rules(+Predicate/Arity, -Rules) <collect_rules(Predicate/Arity, Rules) :functor(A, Predicate, Arity),
findall( Rule,
( clause(A, As),
( As = true -> Rule = A ; Rule = (A :- As) ) ),
Rules ).
% collect_dislog_rules(+Predicate/Arity, -Rules) <collect_dislog_rules(Predicate/Arity, Rules) :collect_rules(Predicate/Arity, Rules_2),
prolog_rules_to_dislog_rules(Rules_2, Rules).
Prof. Dr. Dietmar Seipel
645
Deduktive Datenbanken
Sommersemester 2012
?- collect_rules(tc/2, Rules).
Rules = [
(tc(X, Y) :- arc(X, Y)),
(tc(X, Y) :- arc(X, Z), tc(Z, Y)) ]
?- collect_dislog_rules(tc/2, Rules).
Rules = [
[tc(X, Y)]-[arc(X, Y)],
[tc(X, Y)]-[arc(X, Z), tc(Z, Y)] ]
Prof. Dr. Dietmar Seipel
646
Deduktive Datenbanken
Sommersemester 2012
% retract_rules(+Predicate/Arity, -Rules) <retract_rules(Predicate/Arity, Rules) :functor(A, Predicate, Arity),
findall( Rule,
( retract(A :- As),
( As = true -> Rule = A ; Rule = (A :- As) ) ),
Rules ).
% retract_dislog_rules(+Predicate/Arity, -Rules) <retract_dislog_rules(Predicate/Arity, Rules) :retract_rules(Predicate/Arity, Rules_2),
prolog_rules_to_dislog_rules(Rules_2, Rules).
Prof. Dr. Dietmar Seipel
647
Deduktive Datenbanken
Sommersemester 2012
Speichern in einem Modul der P ROLOG–Datenbank:
% assert_facts(+Module, +Facts) <assert_facts(Module, Facts) :foreach(A, Facts) do assert(Module:A).
% assert_rules(+Module, +Rules) <assert_rules(Module, Rules) :foreach(Rule, Rules) do Module:assert(Rule).
assert(M:X) ist äquivalent zu M:assert(X) für Fakten und Regeln X.
Als Spezialfälle für M = user ergeben sich die bisherigen Prädikate:
assert_facts(Facts) :- assert_facts(user, Facts).
assert_rules(Rules) :- assert_rules(user, Rules).
Prof. Dr. Dietmar Seipel
648
Deduktive Datenbanken
Sommersemester 2012
4.1.3 Die Field Notation für komplexe Objekte
In einem P ROLOG–Fakt ergibt sich die Bedeutung der Argumente aus ihrer
Position:
person(’Sampras’, 1971, male)
In X ML speichert man dagegen die Attribute mit:
<person name="Sampras" born="1971" sex="male"/>
Äquivalent dazu kann man natürlich auch in einem entsprechenden
P ROLOG–Term die Attribute mitführen:
person:[name:’Sampras’, born:1971, sex:male]:[]
Die leere Liste am Ende des P ROLOG–Terms repräsentiert die leere Liste von
Unterelementen des X ML–Elements.
Prof. Dr. Dietmar Seipel
649
Deduktive Datenbanken
Sommersemester 2012
Assoziationslisten
2 In P ROLOG kann man komplexe Objekte bestehend aus Paaren ai : vi , wobei
ai ein Attributname ist und vi der zugehörige Attributwert, wie folgt als
Listen abspeichern:
[a1 : v1 , . . . , an : vn ].
2 Diese Art der Speicherung nennt man Assoziationsliste. Da jeder
Attributwert von seinem zugehörigen Attributnamen begleitet wird, ist die
Reihenfolge der Listenelemente offensichtlich beliebig.
2 Dabei sind die “ai : vi ” P ROLOG–Terme in Infix–Notation mit dem Funktor
“:” und den zwei Argumenten “ai ” und “vi ”.
2 Die Attributwerte vi können auch selbst wieder komplexe Objekte sein.
Prof. Dr. Dietmar Seipel
650
Deduktive Datenbanken
Sommersemester 2012
Vorteile
2 Man kann sehr komfortabel semistrukturierte Daten (wie z.B. X ML–Daten)
repräsentieren und Anfragen daran stellen.
2 Man kann mit Attributnamen anstelle von Argumentpositionen arbeiten.
Da jeder Attributwert von seinem zugehörigen Attributnamen begleitet wird,
ist die Reihenfolge der Listenelemente beliebig.
2 Fehlende Attributwerte (Nullwerte) kann man einfach weglassen, und man
kann jederzeit ohne Probleme bei beliebigen Objekten Attributwerte zu
weiteren Attributnamen hinzufügen.
2 Dadurch kann man auch jederzeit das zugrundeliegende Datenbankschema
erweitern. In der Objektorientierung wird dieses Problem mit der Vererbung
gelöst.
Prof. Dr. Dietmar Seipel
651
Deduktive Datenbanken
Sommersemester 2012
Das Document Object Model (DOM) für X ML
Auf der Basis von Assoziationslisten werden komplexe Objekte in Field Notation
(FN) definiert, die FN–Tripel:
2 T und C seien P ROLOG–Terme und As eine Assoziationsliste. Dann ist
O = T : As : C ein FN–Tripel mit dem Tag T und dem Inhalt C.
2 Bei einem FN–Tripel O = T : As : C, in dem C = [c1 , . . . , cm ] eine Liste mit
FN–Objekten ist, wird jedes ci als Subelement von O bezeichnet.
2 Wenn As = [a1 : v1 , ..., an : vn ], dann wird jedes ai als Attribut von O und
vi als der dazugehörige Wert bezeichnet.
2 Ist die Attributliste leer, kann man das FN–Tripel zu T : C vereinfachen.
T : C ist also äquivalent zu T : [ ] : C.
Der P ROLOG–Aufruf fn_item_parse(O, T:As:C) zerlegt ein FN–Tripel
in seine Bestandteile. Für O = T : C erhalten wir As = [ ].
Prof. Dr. Dietmar Seipel
652
Deduktive Datenbanken
Sommersemester 2012
Das FN–Tripel a:[b:1]:[c:[2]] zum X ML–Element
<a b="1">
<c>2</c>
</a>
hat folgende Term–Struktur:
Prof. Dr. Dietmar Seipel
653
Deduktive Datenbanken
Sommersemester 2012
Vergleich von S WI und D DK
2 Im DOM von S WI–P ROLOG wird ein X ML–Element als Term der Form
element(T,As,C) repräsentiert. Die Attribut/Wert–Paare werden als
A=V in einer Assoziationsliste As repräsentiert, und die Unterelemente
bilden auch wieder eine Liste C . Hier würde das X ML–Element
<a b="1">
<c>2</c>
</a>
repräsentiert als element(a,[b=’1’],[element(c,[],[’2’])]).
2 Das DOM von S WI–P ROLOG ist offensichtlich äquivalent zu den FN–Tripeln
T:As:C aus dem D DK; letztere sind allerdings etwas kompakter.
Prof. Dr. Dietmar Seipel
654
Deduktive Datenbanken
Sommersemester 2012
Beispiel (X ML vs. Field Notation)
2 Das folgende X ML–Objekt speichert Informationen über die Teile eines
Autos:
<components>
<component name="engine">
<part name="sparkplug" quantity="4"/>
<part name="cylinder" quantity="4"/>
<part name="valve" quantity="4"/> ...
</component>
<component name="valve">
<part name="gasket" quantity="1"/>
<part name="hanger" quantity="1"/>
</component> ...
</components>
Prof. Dr. Dietmar Seipel
655
Deduktive Datenbanken
Sommersemester 2012
2 Repräsentation in Field Notation:
components:[
component:[name:engine]:[
part:[name:sparkplug, quantity:4]:[],
part:[name:cylinder, quantity:4]:[],
part:[name:valve, quantity:4]:[], ... ],
component:[name:valve]:[
part:[name:gasket, quantity:1]:[],
part:[name:hanger, quantity:1]:[] ], ... ]
Leere Listen von Unterelementen muß man aufführen.
Leere Attributlisten – wie bei components:[...] – kann man
weglassen.
Prof. Dr. Dietmar Seipel
656
Deduktive Datenbanken
Sommersemester 2012
Ein– und Ausgabe von X ML–Dateien
2 Das Einlesen X ML–Datei erfolgt mittels
dread(xml, +File, -List) .
Dabei ist List eine Liste, deren letztes Element das FN–Tripel aus der
Datei ist. Mögliche andere Elemente können Processing–Instructions etc.
sein.
2 Das Ausgeben eines FN–Tripels in eine X ML–Datei erfolgt mittels
dwrite(xml, +File, +Fn_Triple) .
Hier wird also keine Liste verwendet.
Das Einlesen basiert intern auf dem Parser und dem X ML–DOM von
S WI–P ROLOG.
Prof. Dr. Dietmar Seipel
657
Deduktive Datenbanken
Sommersemester 2012
Deklarativer Zugriffsoperator im D DK
Der deklarative Zugriffsoperator wurde mit Hilfe eines zweistelligen Prädikats
“ := ” in Infix–Notation realisiert (vgl. is/2 ).
Sei O = T : As : C ein FN–Tripel, X eine Variable und Y ein P ROLOG–Term:
2 Dann liefert X := O/Y in X die Sub–Elemente von O mit dem Tag Y.
2 Dann liefert X := O@Y in X den Attributwert von O zu Y.
2 Dann liefert fn_item_parse(O, X:_:_) in X das Tag T von O.
Der Operator ”/” kann zur Bildung komplexer Pfadausdrücke iteriert werden:
X := O/a/b@c
selektiert z.B. der Reihe nach das a–Sub–Element von O, dann dessen
b–Sub–Element, und dann dessen Attributwert zum Attribut c.
Prof. Dr. Dietmar Seipel
658
Deduktive Datenbanken
Sommersemester 2012
Beispiel (Zugriff auf Field Notation)
2 Die folgende Anfrage liefert die erste Komponente des Motors:
?- C = component:[name:engine]:[
part:[name:sparkplug, quantity:4]:[],
part:[name:cylinder, quantity:4]:[],
part:[name:valve, quantity:4]:[], ... ],
P := C/part.
P = part:[name:sparkplug, quantity:4]:[]
Prof. Dr. Dietmar Seipel
659
Deduktive Datenbanken
Sommersemester 2012
2 Die folgende Anfrage liefert den Namen des ersten Teils des Motors.
Bei Backtracking liefert sie die Namen der weiteren Teile.
?- C = component:[name:engine]:[
part:[name:sparkplug, quantity:4]:[],
part:[name:cylinder, quantity:4]:[],
part:[name:valve, quantity:4]:[], ... ],
N := C/part@name.
N = sparkplug ;
N = cylinder ;
N = valve
Prof. Dr. Dietmar Seipel
660
Deduktive Datenbanken
Sommersemester 2012
Analyse von Spielsequenzen beim Tennis
Es werden Tennis–Matches zusammen mit den entsprechenden
Video–Sequenzen erfaßt.
Die Taktikanalyse soll erfolgreiche Spielzüge identifizieren.
Prof. Dr. Dietmar Seipel
661
Deduktive Datenbanken
Sommersemester 2012
Die Ballwechsel werden in X ML (Field Notation) repräsentiert:
<set id="1">
<game id="1" service="A">
<point id="1" top="B" winner="A">
<hit id="1" hand="forehand" type="ground"
time="00:00:42" x="0.17" y="-12.07"/>
<hit id="2" hand="backhand" type="ground"
time="00:00:44" x="-0.49" y="5.89"/>
<hit id="3" hand="backhand" type="ground"
time="00:00:46" x="-3.92" y="-3.42"/>
<hit id="4" hand="forehand" type="ground"
time="00:00:48" x="3.56" y="2.06"/>
</point>
<point id="2" ...> ... </point> ...
</game> ...
</set>
Prof. Dr. Dietmar Seipel
662
Deduktive Datenbanken
Sommersemester 2012
Die Ballwechsel sind mit Video–Sequenzen hinterlegt:
Es können Anfragen an die Daten gestellt werden, und die Ergebnisse können mit
den entsprechenden Video–Sequenzen illustriert werden.
Prof. Dr. Dietmar Seipel
663
Deduktive Datenbanken
Sommersemester 2012
Beispiel: Anfrage in F N Query
Für ein in X ML (Field Notation) gegebenes Tennis–Match werden nach Sätzen
und Spielen aggregiert die durchschnittlichen Längen (Anzahl der Schläge bzw.
Länge des Ballweges) der Ballwechsel ( point ) berechnet:
average_point_distances(Match, Set, Tuples) :ddbase_aggregate(
[Set, Game, Player, average(L), average(D)],
( Point := Match/set::[@id=Set]/
game::[@id=Game, @service=Service]/point,
Player := Match/player::[@id=Service]@name,
point_to_length_and_distance(Point, L, D) ),
Tuples ).
Auch der aufschlagende Spieler wird mit ausgegeben.
Prof. Dr. Dietmar Seipel
664
Deduktive Datenbanken
Sommersemester 2012
Wir wenden die Anfrage auf den ersten Satz des X ML–Files
2002_sampras_agassi_final.xml an und zeigen die berechneten Tupel
in einer X PCE–Tabelle:
?- File = ’2002_sampras_agassi_final.xml’,
dread(xml, File, [Match]),
Set = ’1’,
average_point_distances(Match, Set, Tuples),
Attributes =
[’Set’, ’Game’, ’Service’, ’Hits’, ’Dist’],
xpce_display_table(Attributes, Tuples).
Prof. Dr. Dietmar Seipel
665
Deduktive Datenbanken
Sommersemester 2012
Wie erwartet zeigt sich, daß bei den Aufschlagspielen von Samprass die
Ballwechsel im Schnitt deutlich kürzer sind. Als Serve&Volley–Spieler rückt er
meist frühzeitig ans Netz auf, um den Ballwechsel zu beenden:
Prof. Dr. Dietmar Seipel
666
Deduktive Datenbanken
Sommersemester 2012
Analyse und Refaktorisierung von Logikprogrammen
Natürlich kann man auch P ROLOG–Regeln in X ML repräsentieren.
Ziele:
2 Programmanalyse hinsichtlich
– Modularsierung,
– Struktureigenschaften (Rekursion, Argumente),
– Design Patterns;
2 Refaktorisierung;
2 Slicing (Extraktion einer Teilfunktion).
Prof. Dr. Dietmar Seipel
667
Deduktive Datenbanken
Sommersemester 2012
P ROLOG–Regeln in X ML:
tc(X, Y) :- arc(X, Y).
tc(X, Y) :- arc(X, Z), tc(Z, Y).
<definition predicate="(user:tc)/2"> ...
<rule file="tc.pl">
<head>
<atom predicate="tc/2">
<var name="X"/> <var name="Y"/> </atom>
</head>
<body>
<atom predicate="arc/2"> ... </atom>
<atom predicate="tc/2"> ... </atom>
</body>
</rule>
</definition>
Prof. Dr. Dietmar Seipel
668
Deduktive Datenbanken
Sommersemester 2012
X ML–Anfrage in F N Query
Bestimme alle Atome in einem Regel–Kopf oder –Rumpf, die eine Variable
namens “ X ” enthalten.
Prof. Dr. Dietmar Seipel
669
Deduktive Datenbanken
4.2
Sommersemester 2012
Kontrollstrukturen und Meta–Prädikate von P ROLOG
2 Finden aller Lösungen: findall/3, bagof/3, setof/3
2 Test bzw. Filter: checklist/2, sublist/2
2 Transformation: maplist/3
2 Schleifen:
– forall(Condition, Action),
– for(I, N, M) do Goal,
– foreach(X, Xs) do Goal
mit dem Prädikatensymbol do/2 (Bibliothek loops.pl von J. Schimpf)
2 Verzweigungen: If -> Then; Else
Prof. Dr. Dietmar Seipel
670
Deduktive Datenbanken
Sommersemester 2012
4.2.1 Finden aller Lösungen
Der Aufruf findall(Y, Goal, Ys) bestimmt die Liste Ys aller
Lösungen Y von Goal. Dabei kommt Y meist in Goal vor, Ys sollte
hingegen nicht darin vorkommen.
Der folgende Aufruf selektiert alle positiven Zahlen aus einer Liste Xs :
?- Xs = [-1,2],
findall( Y, ( member(Y, Xs), Y > 0 ), Ys ).
Ys = [2]
Prof. Dr. Dietmar Seipel
671
Deduktive Datenbanken
Sommersemester 2012
Beim Aufruf
<setof/bagof>(Y, Goal, Ys)
werden alle Variablen aus Goal , die nicht in Y vorkommen, ebenfalls
gebunden, und es wird nach ihnen gruppiert. Sei Xs die Liste dieser freien
Variablen. Für jede Belegung von Xs werden mittels Goal alle Belegungen für
Y berechnet, und sie bilden die Liste Ys :
2 setof/3 berechnet die Liste Ys ohne Wiederholungen.
2 bagof/3 berechnet die Liste Ys mit Wiederholungen.
Nur die Variablen aus Y bleiben unverändert. Über Backtracking kann man die
Lösungen für Xs und Ys durchgehen.
2 findall/3 erzeugt dagegen nur eine Bindung für Ys; die Variablen aus
Y und Xs bleiben unverändert.
Prof. Dr. Dietmar Seipel
672
Deduktive Datenbanken
Sommersemester 2012
Im folgenden ist Y eine Variable, und Xs besteht nur aus der Variablen X :
a(1, 2).
a(1, 3).
a(2, 4).
a(1, 2).
?- setof( Y, a(X, Y), Ys ).
Y = _G281, X = 2, Ys = [4] ;
Y = _G281, X = 1, Ys = [2, 3]
?- bagof( Y, a(X, Y), Ys ).
Y = _G281, X = 2, Ys = [4] ;
Y = _G281, X = 1, Ys = [2, 3, 2]
?- findall( Y, a(X, Y), Ys ).
Y = _G281, X = _G280, Ys = [2, 3, 4, 2]
Prof. Dr. Dietmar Seipel
673
Deduktive Datenbanken
Sommersemester 2012
Die Gruppierung nach X kann unterbunden werden, indem man X^ voranstellt;
dieses ist ein Existenzquantor für X:
a(1, 2).
a(1, 3).
a(2, 4).
a(1, 2).
?- setof( Y, X^a(X, Y), Ys ).
Y = _G281, X = _G280, Ys = [2, 3, 4]
?- bagof( Y, X^a(X, Y), Ys ).
Y = _G281, X = _G280, Ys = [2, 3, 4, 2]
2 Dann verhält sich bagof/3 wie findall/3 ,
und setof/3 liefert eine sortierte Liste Ys ohne Duplikate.
2 Für findall/3 hat der Existenzquantor keinen Effekt.
Prof. Dr. Dietmar Seipel
674
Deduktive Datenbanken
Sommersemester 2012
Wenn Goal im Aufruf
<setof/bagof>(Y, Goal, Ys)
fehlschlägt, dann schlägt der gesamte Aufruf von setof/bagof fehl;
dagegen liefert findall(Y, Goal, Ys) in diesem Fall eine leere Liste Ys
als Resultat:
a(1, 2).
a(1, 3).
a(2, 4).
a(1, 2).
?- setof( Y, a(3, Y), Ys ).
No.
?- bagof( Y, a(3, Y), Ys ).
No.
?- findall( Y, a(3, Y), Ys ).
Ys = [].
Prof. Dr. Dietmar Seipel
675
Deduktive Datenbanken
Sommersemester 2012
Mittels setof/3 kann man multiset_to_elements/2 eleganter
implementieren:
multiset_to_elements(Multiset, Xs) :setof( X, N^member(X:N, Multiset), Xs ).
?- multiset_to_elements([c:1, a:2, b:3, a:4], M).
M = [a, b, c]
Es werden alle ersten Komponenten X der Paare X:N aus Multiset
berechnet und sortiert und ohne Duplikate zurückgegeben.
Prof. Dr. Dietmar Seipel
676
Deduktive Datenbanken
Sommersemester 2012
Mittels bagof/3 kann man multiset_normalize/2 kürzer implementieren:
multiset_normalize(M1, M2) :findall( X:M,
( bagof( N, member(X:N, M1), Ns ),
sum(Ns, M) ),
M3 ),
sort(M3, M2).
?- multiset_normalize([c:1, a:2, b:3, a:4], M).
M = [a:6, b:3, c:1]
bagof(N, member(X:N, M1), Ns) berechnet für jedes X die Liste Ns
der Häufigkeiten N , mit denen X in M1 vorkommt.
Prof. Dr. Dietmar Seipel
677
Deduktive Datenbanken
Sommersemester 2012
Diese Aggregation kann man mittels ddbase_aggregate/3 , welches auf
der Basis von findall/3 realisiert ist, noch eleganter implementieren:
multiset_normalize(M1, M2) :ddbase_aggregate( [X, sum(N)],
member(X:N, M1),
Pairs ),
re_pair_list(:, Pairs, M2).
?- multiset_normalize([c:1, a:2, b:3, a:4], M).
M = [a:6, b:3, c:1]
Die von ddbase_aggregate/3 gelieferte Liste Pairs aus Tupeln [X,
S] muß hinterher mittels re_pair_list/3 zu einer Liste aus Paaren X:S
transformiert werden.
Prof. Dr. Dietmar Seipel
678
Deduktive Datenbanken
Sommersemester 2012
Mittels setof/3 kann man einen Graphen von der Kantendarstellung in die
Adjazenzdarstellung überführen:
edges_to_ugraph(Edges, Ugraph) :findall( V-Ws,
setof( W, member(V-W, Edges), Ws ),
Xs ),
setof( V-[],
( W^member(W-V, Edges),
not(member(V-_, Edges)) ),
Ys ),
append(Xs, Ys, Zs), sort(Zs, Ugraph).
?- edges_to_ugraph([a-b, b-c, a-d], Graph).
Ugraph = [a-[b, d], b-[c], c-[], d-[]]
Prof. Dr. Dietmar Seipel
679
Deduktive Datenbanken
Sommersemester 2012
Auf der Basis von findall/3 kann man die bekannte Mengenkonstruktion im
Rahmen des funktionalen Auswertungsprädikats “ <= ” sehr intuitiv formulieren
(syntactic sugar):
X <= Y :Y = { T | Goal },
!,
findall( T, Goal, X ).
?- Set <= { N | between(1, 5, N), even(N) }.
Set = [2, 4].
In der Mathematik würde man schreiben:
Set := { N | N ∈ IN0 ∧ 1 ≤ N ≤ 5 ∧ even(N ) }.
{z
}
|
between(1 ,5 ,N )
Prof. Dr. Dietmar Seipel
680
Deduktive Datenbanken
Sommersemester 2012
Der P ROLOG–Term zur Mengenkonstruktion hat den folgenden Term–Graphen:
Set <= { N | between(1, 5, N), even(N) }.
Prof. Dr. Dietmar Seipel
681
Deduktive Datenbanken
Sommersemester 2012
4.2.2 Filter und Transformationen
Mittels checklist/2 und sublist/3 kann man testen bzw. filtern
(selektieren).
Die folgenden Aufrufe testen, ob alle Elemente einer Liste positiv sind, bzw.
selektieren die positiven Elemente:
?- Xs = [-1,2],
checklist( <(0), Xs ).
No
?- Xs = [-1,2],
sublist( <(0), Xs, Ys ).
Ys = [2]
<(0) wird mit einem weiteren Argument X , das zur Laufzeit aus der Liste Xs
gespeist wird, zu einem Atom <(0,X) (in Infix–Notation: 0 < X ) aufgefüllt.
Prof. Dr. Dietmar Seipel
682
Deduktive Datenbanken
Sommersemester 2012
Transformationen
maplist/3 transformiert eine Eingabeliste in eine gleichlange Ausgabeliste.
?- Xs = [-1,2],
maplist( abs, Xs, Ys ).
Ys = [1,2]
Der Aufruf maplist(abs, Xs, Ys) erzeugt für jedes Element X aus der
Eingabeliste Xs mittels abs(X,Y) ein neues Element Y für die
Ausgabeliste Ys.
Prof. Dr. Dietmar Seipel
683
Deduktive Datenbanken
Sommersemester 2012
Wenn wir ein geeignetes Additions–Prädikat add/3 definieren, dann können
wir auf alle Elemente einer Liste eine feste Zahl addieren:
add(X, Y, Z) :Z is X + Y.
?- maplist( add(2), [1, 2, 4], Ys ).
Ys = [3, 4, 6]
Der Aufruf maplist(add(2), Xs, Ys) erzeugt für jedes Element X aus
der Eingabeliste Xs mittels add(2,X,Y) ein neues Element Y für die
Ausgabeliste Ys.
Prof. Dr. Dietmar Seipel
684
Deduktive Datenbanken
Sommersemester 2012
Wenn man add/3 geeignet umkehrbar macht, dann kann man auch in
maplist/3 Eingabe und Ausgabe vertauschen:
add(X, Y, Z) :( number(X), number(Y) -> Z is X + Y
; number(X), number(Z) -> Y is Z - X
; number(Y), number(Z) -> X is Z - Y ).
?- maplist( add(2), Xs, [3, 4, 6] ).
Xs = [1, 2, 4]
Außerdem kann es aufgrund der Tests mittels number/1 jetzt auch keine
Typfehler mehr geben.
Prof. Dr. Dietmar Seipel
685
Deduktive Datenbanken
Sommersemester 2012
4.2.3 Schleifen und Verzweigungen
2 Der Aufruf forall(Condition, Action) generiert mittels
Condition über Backtracking Variablenbindungen, die dann beim Aufruf
von Action benutzt werden. Es erfolgt kein Backtracking über Action .
2 Der Aufruf Generator do Action der Prädikats do/2 aus der
Bibliothek loops.pl von J. Schimpf generiert mittels Generator
Variablenbindungen, die dann beim Aufruf von Action benutzt werden.
In Generator können Konstrukte wie for(I, N, M) und
foreach(X, Xs) gemischt werden.
Im Vergleich zu maplist/(n + 1) kann man in Action jeweils flexibler die
generierten Variablenbindungen benutzen. Die fixierten Parameter müssen beim
Aufruf maplist(p(A1 ,...,Am ), Xs1 ,...,Xsn ) – wie wir gesehen
haben – ja an den ersten m Stellen des Prädikats p/(n + m) stehen.
Prof. Dr. Dietmar Seipel
686
Deduktive Datenbanken
Sommersemester 2012
Iteration über eine Liste bzw. einen Zahlenbereich:
?- forall( member(I, [a, b, c, d]),
( write(I), write(’ - ’) ) ).
a - b - c - d Yes
?- for(I, 2, 5) do
( write(I), write(’ - ’) ).
2 - 3 - 4 - 5 Yes
Prof. Dr. Dietmar Seipel
687
Deduktive Datenbanken
Sommersemester 2012
Alternative Implementierung mittels Rekursion:
write_numbers(N, M) :N =< M,
!,
write(N), write(’ - ’),
K is N + 1,
write_numbers(K, M).
write_numbers(_, _).
Das Statement N is N+1 wäre sinnlos, da man den Wert einer bereits belegten
Variablen N nicht verändern kann. Deswegen wird im rekursiven Aufruf eine
frische Variable K mit dem inkrementierten Wert N+1 belegt.
Eleganter ist aber in jedem Fall die Implementierung mittels for-do.
Prof. Dr. Dietmar Seipel
688
Deduktive Datenbanken
Sommersemester 2012
Transformation von Listen (Filter)
Der Aufruf
foreach(X, Xs), foreach(Y, Ys) do p(X, Y)
transformiert eine Liste Xs in eine gleichlange Ergebnisliste Ys:
Xs
X
Prof. Dr. Dietmar Seipel
Ys
-
Y
689
Deduktive Datenbanken
Sommersemester 2012
Multiplikation eines Vektors mit einem Skalar
Multiplikation eines Vektors, der durch eine Liste Xs gegeben ist, mit einem
skalaren Faktor F; das Ergebnis ist wieder eine Liste Ys:
vector_multiply(F, Xs, Ys) :foreach(X, Xs), foreach(Y, Ys) do
Y is F * X.
?- vector_multiply(3, [2, 4], Ys).
Ys = [6, 12]
Prof. Dr. Dietmar Seipel
690
Deduktive Datenbanken
Sommersemester 2012
Die Verwendung von maplist/3 setzt eine geeignete Argumentreihenfolge im
verwendeten Prädikat voraus, bei der die konstanten Parameter zuerst kommen
und die zu transformierenden Argumente nachfolgen.
Um die Multiplikation eines Vektors mittels maplist/3 ausdrücken zu können,
müßte man erst ein geeignetes Hilfsprädikat multiply/3 implementieren:
vector_multiply(F, Xs, Ys) :maplist( multiply(F), Xs, Ys ).
multiply(F, X, Y) :Y is F * X.
Das Prädikat is/2 kann hier nicht direkt herangezogen werden, da es nur
zweistellig ist und eine Eingabe in Produktform erwartet.
Prof. Dr. Dietmar Seipel
691
Deduktive Datenbanken
Sommersemester 2012
Der Aufruf
foreach(X, Xs), foreach(Y, Ys),
foreach(Z, Zs) do p(X, Y, Z)
transformiert zwei gleichlange Listen Xs und Ys in eine genausolange
Ergebnisliste Zs:
Xs
X
Zs
~
>
Z
Y
Ys
Prof. Dr. Dietmar Seipel
692
Deduktive Datenbanken
Sommersemester 2012
Addition von Vektoren
Die Addition zweier gleichlanger Vektoren x = (x1 , . . . , xn ) ∈ IRn und
y = (y1 , . . . , yn ) ∈ IRn ist gegeben durch z = (z1 , . . . , zn ) ∈ IRn , mit
zi = xi + yi .
Man kann die Addition mittels do/2 oder maplist/4 implementieren:
vector_add(Xs, Ys, Zs) :foreach(X, Xs), foreach(Y, Ys),
foreach(Z, Zs) do Z is X + Y.
vector_add(Xs, Ys, Zs) :maplist( add, Xs, Ys, Zs ).
? ? 6
add( X,
Y,
Z )
?- vector_add([1,2], [3,4], Zs).
Zs = [4,6]
Prof. Dr. Dietmar Seipel
693
Deduktive Datenbanken
Sommersemester 2012
Skalarprodukt von Vektoren
Das Skalarprodukt zweier gleichlanger Vektoren x = (x1 , . . . , xn ) ∈ IRn und
Pn
n
y = (y1 , . . . , yn ) ∈ IR ist gegeben durch x · y = i=1 xi · yi .
scalar_product(Xs, Ys, Z) :( foreach(X, Xs), foreach(Y, Ys),
foreach(Z, Zs) do Z is X * Y ),
sum(Zs, Z).
?- scalar_product([1,2], [3,4], Z).
Z = 11
Prof. Dr. Dietmar Seipel
694
Deduktive Datenbanken
Sommersemester 2012
Durch Verknüpfung von for und foreach innerhalb von do/2 kann man
auch die Liste der Fakultäten eleganter berechnen, die wir vorher schon mittels
findall/3 und between/3 berechnet hatten:
?- for(N, 1, 5), foreach(F, Fs) do
factorial(N, F).
Fs = [1, 2, 6, 24, 120]
Dabei generiert for(N, 1, 5) die ganzen Zahlen zwischen 1 und N,
und foreach(F, Fs) sammelt die Fakultäten F in einer Liste Fs auf.
Die Fakultäten werden wieder mittels factorial(N, F) berechnet.
Anders als bei der Berechnung mittels findall/3 ist hier kein Cut in
factorial/2 erforderlich, da kein Backtracking angestoßen wird.
Prof. Dr. Dietmar Seipel
695
Deduktive Datenbanken
Sommersemester 2012
Transformation von Listen mit Variablen
2 Wir haben gesehen, daß man für Listen aus Grundtermen mit findall/3,
maplist/3 und foreach-do dieselben Effekte erzielen kann.
2 Für Listen mit Variablen verhält sich findall/3 aber anders als die
beiden anderen: bei den letzten beiden teilt die Resultatsliste die Bindungen
mit der Ausgangsliste, bei dem ersten nicht.
2 Dies kann man mit dem P ROLOG–Prädikat ==/2 nachweisen.
Der Aufruf X == Y testet, ob X und Y exakt gleich sind.
Dies ist eine stärkere Eigenschaft als die Unifizierbarkeit.
?- X = Y.
Yes
?- X == Y.
No
?- X == X.
Yes
Prof. Dr. Dietmar Seipel
696
Deduktive Datenbanken
Sommersemester 2012
?- Xs = [X1,X2],
maplist( =, Xs, Ys ),
Xs == Ys.
Yes
?- Xs = [X1,X2],
( foreach(X, Xs), foreach(Y, Ys) do Y = X ),
Xs == Ys.
Yes
?- Xs = [X1,X2],
findall( Y, ( member(X, Xs), Y = X ), Ys ),
Xs == Ys.
No
Prof. Dr. Dietmar Seipel
697
Deduktive Datenbanken
Sommersemester 2012
Das Paarungsprädikat pair_lists/4
Zur Implementierung des Paarungsprädikats pair_lists/4 sollten wir
deswegen – wie bereits gezeigt – maplist/3 oder foreach-do verwenden,
aber nicht findall/3. Dann erhalten wir folgendes Verhalten:
pair_lists(Mode, Xs, Ys, Pairs) :foreach(X, Xs), foreach(Y, Ys),
foreach(Pair, Pairs) do
pair_elements(Mode, X, Y, Pair).
?- pair_lists(:, [a, b, c], [X, X, Z], Pairs).
Pairs = [a:X, b:X, c:Z]
Auch wenn man pair_lists/4 mit Listenrekursion implementiert, dann
erhält man das gezeigte – und erwünschte – Verhalten.
Prof. Dr. Dietmar Seipel
698
Deduktive Datenbanken
Sommersemester 2012
Wenn man die Transformation dagegen mit findall/3 implementieren
würde, dann ginge der Bezug zu den ursprünglichen Variablen und der Bezug
innerhalb der Paarliste verloren:
pair_lists(Mode, Xs, Ys, Pairs) :findall( Pair,
( nth(N, Xs, X), nth(N, Ys, Y),
pair_elements(Mode, X, Y, Pair) ),
Pairs ).
?- pair_lists(:, [a, b, c], [X, X, Z], Pairs).
Pairs = [a:_G701, b:_G695, c:_G689]
In der Paarliste enthalten die beiden ersten Paare hier nicht mehr dieselbe
Variable, obwohl die Positionen in der Ausgangsliste gleich sind.
Außerdem könnte die Paarliste aufgrund von Backtracking über
pair_elements/4 eine andere Länge haben als die Ausgangslisten.
Prof. Dr. Dietmar Seipel
699
Deduktive Datenbanken
Sommersemester 2012
If -> Then ; Else
Man kann die Wurzelberechnung wie folgt mit Hilfe von komplexen Zahlen der
Form A+B*i erweitern:
square_root(X, Y) :( X >= 0 -> sqrt(X, Y)
; sqrt(abs(X), Z), Y = Z*i ).
?- square_root(4, Y).
Y = 2
?- square_root(-270400, Y).
Y = 520*i
Prof. Dr. Dietmar Seipel
700
Deduktive Datenbanken
Sommersemester 2012
multiply_complex(X, Y, Z) :normalize_complex(X, A1+B1*i),
normalize_complex(Y, A2+B2*i),
A3 is A1*A2 - B1*B2,
B3 is A1*B2 + A2*B1,
simplify_complex(A3+B3*i, Z).
normalize_complex(X, Y) :( X = A+B*i -> Y = A+B*i
; X =
B*i -> Y = 0+B*i
; X = A
-> Y = A+0*i ).
?- multiply_complex(520*i, 520*i, Z).
Z = -270400
Prof. Dr. Dietmar Seipel
701
Deduktive Datenbanken
Sommersemester 2012
Implementierung in P ROLOG:
2 A->B schlägt fehl, falls A fehlschlägt, und ruft ansonsten B auf.
?- listing(->).
:- module_transparent (->)/2.
A->B :A, !, B.
Yes
2 A->B;C steht für (A->B);C und ist durch eine Regel für “ ; ” definiert.
2 Der Cut unterbindet in jedem Falle das Backtracking über A.
Prof. Dr. Dietmar Seipel
702
Deduktive Datenbanken
Sommersemester 2012
Würde man den Cut anstelle von -> in einem Goal schreiben, so würden auch
vorherige Backtrackpunkte (unten wegen between/3) gelöscht:
?- findall( N,
( between(1, 3, N),
( N > 1, !, write(yes(N)) ; write(no(N)) ) ),
Ns ).
no(1)yes(2)
Ns = [1, 2].
?- findall( N,
( between(1, 3, N),
( N > 1 -> write(yes(N)) ; write(no(N)) ) ),
Ns ).
no(1)yes(2)yes(3)
Ns = [1, 2, 3].
Prof. Dr. Dietmar Seipel
703
Deduktive Datenbanken
Sommersemester 2012
Wenn man den If -> Then; Else –Teil dagegen in eine eigene Regel
auslagert, dann verhalten sich beide Realisierungen gleich:
treat_number(cut, N) :( N > 1, !, write(yes(N)) ; write(no(N)) ).
treat_number(ite, N) :( N > 1 -> write(yes(N)) ; write(no(N)) ).
?- findall( N,
( between(1, 3, N),
treat_number(cut, N) ),
Ns ).
no(1)yes(2)yes(3)
Ns = [1, 2, 3].
Prof. Dr. Dietmar Seipel
?- findall( N,
( between(1, 3, N),
treat_number(ite, N) ),
Ns ).
no(1)yes(2)yes(3)
Ns = [1, 2, 3].
704
Deduktive Datenbanken
4.3
Sommersemester 2012
Struktureigenschaften von Logikprogrammen
Abhängigkeitsgraphen geben an, welche Prädikate welche anderen Prädikate in
einem Logikprogrammen aufrufen.
Sie werden im Software Engineering z.B. für folgende Zwecke benutzt:
2 Analyse von Programmen,
2 Analyse und Verständnis von Softwarepaketen,
2 Refaktorisierung,
2 Slicing.
Prof. Dr. Dietmar Seipel
705
Deduktive Datenbanken
Sommersemester 2012
Definition 4.1 (Abhängigkeitsgraph, Rule–Goal–Graph)
Sei P ein definites Logikprogramm:
2 Der Abhängigkeitsgraph GdP = h ΠP , EPd i von P ist gegeben durch
– ΠP ist die Menge aller Prädikatensymbole in P ,
– EPd = { h pA , pBi i | A ← B1 ∧ . . . ∧ Bm ∈ P, 1 ≤ i ≤ m }.
rg
rg
2 Der Rule–Goal–Graph Grg
=
h
V
,
E
P
P
P i von P ist gegeben durch
– VPrg = ΠP ∪ P ,
– EPrg = { h pA , r i, h r, pBi i | r = A ← B1 ∧ . . . ∧ Bm ∈ P, 1 ≤ i ≤ m }.
Der Abhängigkeitsgraph ergibt sich also aus dem Rule–Goal–Graphen durch
transitive Verbindung der Kopf– und Rumpfprädikatensymbole unter Weglassung
der dazwischen liegenden Regelknoten. Eingeschränkt auf die
Prädikatensymbole haben beide Graphen dieselben Pfade.
Prof. Dr. Dietmar Seipel
706
Deduktive Datenbanken
Sommersemester 2012
Graphen zur Regel r = A ← B1 ∧ . . . ∧ Bm :
GPd :
pA
GPrg :
pA
?
r
pB1
W
. . . pBm
pB1
U
. . . pBm
pA bezeichnet das Prädikatensymbol eines Atoms A.
Prof. Dr. Dietmar Seipel
707
Deduktive Datenbanken
Sommersemester 2012
d
Der Rule–Goal–Graph Grg
P ist genauer als der Abhängigkeitsgraph GP .
Die folgenden Logikprogramme
P1 = { p ← q1 , p ← q2 },
P2 = { p ← q1 ∧ q2 },
haben denselben Abhängigkeitsgraphen GPd , aber unterschiedliche
Rule–Goal–Graphen GPrg1 bzw. GPrg2 :
GPd :
GPrg1 :
p
r1
q1
Prof. Dr. Dietmar Seipel
W
q2
p
U
?
q1
GPrg2 :
?
r
r2
?
q2
p
q1
U
q2
708
Deduktive Datenbanken
Sommersemester 2012
Beispiel (Abhängigkeitsgraph, Rule–Goal–Graph)
Der Abhängigkeitsgraph und der Rule–Goal–Graph für P = { r, s } mit
r = p(X0 , X3 ) ← a(X0 , X2 ) ∧ q(X1 , X2 , X3 ),
s = q(X1 , X2 , X3 ) ← b(X1 , X2 ) ∧ c(X1 , X3 ),
sehen wie folgt aus:
GdP :
Grg
P :
p
p
?
r
a
N
q
R
q
a
?
s
b
Prof. Dr. Dietmar Seipel
N
c
R
c
b
709
Deduktive Datenbanken
Sommersemester 2012
Falls in einem Programm dasselbe Prädikatensymbol mit unterschiedlichen
Stelligkeiten auftritt, so kann man dies in den Graphen unterscheiden:
graph_search(X, Path) :graph_search(X, [X], Path).
...
Grg
P :
graph_search/2
?
r
?
graph_search/3
Prof. Dr. Dietmar Seipel
710
Deduktive Datenbanken
Sommersemester 2012
Für P ROLOG–Regeln, deren Rümpfe “ , ” und “ ; ” enthalten können, muß man
eigentlich extra Knoten einführen, um die Struktur adäquat abzubilden:
tc(X, Y) :( arc(X, Y) ; arc(X, Z),tc(Z, Y) ).
Grg
P :
tc/2
?]
r
?
;
R,
arc/2
Prof. Dr. Dietmar Seipel
711
Deduktive Datenbanken
Sommersemester 2012
Die Infix–Notation des obigen Regelrumpfes ist äquivalent zur Präfix–Notation in
der folgenden Regel. Würde man aber “ ; ” lediglich als binäres
Prädikatensymbol auffassen, so ginge verloren, daß tc/2 sich selbst (Rekursion)
und arc/2 aufruft:
tc(X, Y) :’;’(arc(X, Y), ’,’(arc(X, Z),tc(Z, Y))).
Grg
P :
tc/2
?
r
?
; /2
Prof. Dr. Dietmar Seipel
712
Deduktive Datenbanken
Sommersemester 2012
Wenn wir dagegen die zwei üblichen definiten Regeln für die transitive Hülle
verwenden, die zusammen zur obigen Regel äquivalent sind, dann können die
üblichen Graphen die Struktur adäquat abilden:
tc(X, Y) :- arc(X, Y).
tc(X, Y) :- arc(X, Z), tc(Z, Y).
GPrg :
tc/2
r1
I
R
r2
R
arc/2
Prof. Dr. Dietmar Seipel
713
Deduktive Datenbanken
Sommersemester 2012
?- Program = [
[tc(X, Y)]-[arc(X, Y)],
[tc(X, Y)]-[arc(X, Z), tc(Z, Y)],
[arc(a, b)], [arc(b, c)], [arc(c, d)] ],
program_to_rule_goal_graph(
GPrg :
Program, Vs, Es, Fs).
Vs = [ arc, fact_1, fact_2, fact_3,
rule_1, rule_2, tc ]
Es = [ arc-fact_1, arc-fact_2, arc-fact_3,
tc-rule_1, tc-rule_2,
rule_1-arc, rule_2-arc, rule_2-tc ]
Fs = [ ]
Prof. Dr. Dietmar Seipel
tc/2
r1
I
R
r2
R
arc/2
?R
f1 f2 f3
714
Deduktive Datenbanken
Sommersemester 2012
Für normale Logikprogramme (mit Negation) wie
P = { p ← a ∧ not b }
werden die Kanten zu den Prädikatensymbolen der positiven bzw. negativen
Rumpfatome in separaten Listen zurückgeliefert:
?- Program = [ [p]-[a]-[b] ],
program_to_rule_goal_graph(
Program, Vs, Es, Fs).
Grg
P :
p
?
r
not
Vs = [ a, b, p, rule_1 ]
Es = [ p-rule_1, rule_1-a ]
Fs = [ rule_1-b ]
Prof. Dr. Dietmar Seipel
R
a
b
715
Deduktive Datenbanken
Sommersemester 2012
Abhängigkeitsgraph in DD BASE
Prof. Dr. Dietmar Seipel
716
Deduktive Datenbanken
Sommersemester 2012
Definition 4.2 (Rekursion)
Sei P ein definites Logikprogramm.
2 Ein Prädikatensymbol p ∈ ΠP ist rekursiv, wenn p in einem Zykel von GdP
liegt. Zwei Prädikatensymbole p, q ∈ ΠP sind wechselseitig rekursiv, wenn
p und q zusammen in einem Zykel von GdP liegen.
2 Eine Regel r = A ← B1 ∧ . . . ∧ Bm ∈ P ist rekursiv, wenn mindestens ein
Prädikatensymbol pBi wechselseitig rekursiv zu pA ist. r ist direkt–rekursiv,
wenn mindestens ein Prädikatensymbol pBi gleich pA ist.
2 P ist rekursiv, wenn der Abhängigkeitsgraph GdP von P zyklisch ist.
Ein Programm ist genau dann rekursiv, wenn es eine rekursive Regel enthält.
Es gibt rekursive Programme ohne direkt–rekursive Regeln:
in P = { p ← q, q ← p } sind z.B. p und q wechselseitig rekursiv.
Prof. Dr. Dietmar Seipel
GPrg :
r1
p
K
r2
U
q
717
Deduktive Datenbanken
Sommersemester 2012
Beispiel (Rekursion)
Für das rekursive DATALOG–Programm P = { r1 , r2 , f1 , f2 , f3 } mit
r1 = tc(X , Z ) ← arc(X, Z),
r2 = tc(X , Z ) ← arc(X, Y ) ∧ tc(Y, Z),
f1 = arc(a, b), f2 = arc(b, c), f3 = arc(c, d ),
erhalten wir die folgenden zyklischen Graphen:
GPd :
... .........
tc
........
GPrg :
tc
I
R
r1
r2
?
arc
R
arc
?
R
f1 f2 f3
Prof. Dr. Dietmar Seipel
718
Deduktive Datenbanken
Sommersemester 2012
% predicate_is_recursive(+Program, ?Predicate) <predicate_is_recursive(Program, Predicate) :program_to_rule_goal_graph(Program, Vs, Es, Fs),
ord_union(Es, Fs, Edges),
transitive_closure_edges(Edges, Tc_Edges),
member(Predicate-Predicate, Tc_Edges).
?- Program = [
[tc(X, Y)]-[arc(X, Y)],
[tc(X, Y)]-[arc(X, Z), tc(Z, Y)] ],
predicate_is_recursive(Program, Predicate).
Predicate = tc
Prof. Dr. Dietmar Seipel
719
Deduktive Datenbanken
Sommersemester 2012
Transitive Hülle
Man kann die transitive Hülle eines gerichteten Graphen basierend auf der
Bibliothek ugraphs.pl von S WI–P ROLOG berechen; in dieser werden
Graphen als Adjazenzlisten dargestellt:
?- Graph_1 = [ a-[b], b-[c], c-[b,d] ],
transitive_closure(Graph_1, Graph_2).
Graph_2 = [a-[b, c, d], b-[c, d], c-[b, d]].
Dann ergibt sich transitive_closure_edges/2 daraus über Konversion
von der Kantendarstellung in die Adjazenzlistendarstellung:
transitive_closure_edges(Edges, Tc_Edges) :edges_to_ugraph(Edges, Graph),
transitive_closure(Graph, Tc_Graph),
ugraph_to_edges(Tc_Graph, Tc_Edges).
Prof. Dr. Dietmar Seipel
720
Deduktive Datenbanken
Sommersemester 2012
Transitive Hülle im D DK
Wir können die transitive Hülle eines gerichteten Graphen aber auch basierend
auf tp_iteration/2 berechnen, wenn wir aus der Kantendarstellung eine
geeignete Faktendarstellung erzeugen:
% transitive_closure_edges(+Edges, -Tc_Edges) <transitive_closure_edges(Edges, Tc_Edges) :( foreach(Edge, Edges), foreach(Fact, Facts) do
Edge = X-Y, Fact = [arc(X, Y)] ),
tc_program_generic(tc, arc, Tc_Rules),
append(Facts, Tc_Rules, Tc_Program),
tp_iteration(Tc_Program, Interpretation),
findall( X-Y,
member(tc(X, Y), Interpretation),
Tc_Edges ).
Dies ist insofern interessant als es zeigt, daß wir die Technologie der deduktiven
Datenbanken auch innerhalb der eigenen Domäne anwenden können.
Prof. Dr. Dietmar Seipel
721
Deduktive Datenbanken
Sommersemester 2012
Zu vorgegebenen Pädikatensymbolen Tc und Arc wird ein rechts–rekursives,
lineares DATALOG–Programm erzeugt:
% tc_generic(+Tc, +Arc, -Program) <tc_program_generic(Tc, Arc, Program) :Tc_xy =.. [Tc, X, Y], Arc_xy =.. [Arc, X, Y],
Arc_xz =.. [Arc, X, Z], Tc_zy =.. [Tc, Z, Y],
Program = [
[Tc_xy]-[Arc_xy],
[Tc_xy]-[Arc_xz, Tc_zy] ].
?- tc_program_generic(tc, arc, Program).
Program = [
[tc(X, Y)]-[arc(X, Y)],
[tc(X, Y)]-[arc(X, Z), tc(Z, Y)] ]
Prof. Dr. Dietmar Seipel
722
Deduktive Datenbanken
Sommersemester 2012
Bei der D DK–Implementierung von transitive_closure_edges/2
generiert tp_iteration/2 iterativ die ordinalen Potenzen zur
Faktendarstellung der Kanten des Graphen:
?- transitive_closure_edges([a-b, b-c], Tc_Edges).
[ ]
[arc(a, b), arc(b, c)]
[arc(a, b), arc(b, c), tc(a, b), tc(b, c)]
[arc(a, b), arc(b, c), tc(a, b), tc(a, c), tc(b, c)]
Tc_Edges = [a-b, a-c, b-c]
Der obige Graph ist azyklisch, da keine Kanten der Form V-V berechnet wurden.
Prof. Dr. Dietmar Seipel
723
Deduktive Datenbanken
Sommersemester 2012
Definition 4.3 (Linearität)
Sei P ein definites Logikprogramm:
2 Eine definite Regel r = A ← B1 ∧ . . . ∧ Bm ∈ P ist linear, wenn in P
höchstens ein Prädikatensymbol pBi wechselseitig rekursiv zu pA ist.
2 P ist linear, wenn alle Regeln r ∈ P linear sind.
2 P ist linear–rekursiv, wenn P linear und rekursiv ist.
Ein linear–rekursives definites Logikprogramm P enthält mindestens eine
rekursive Regel. Man nennt es lineares Single–Recursive–Rule–Program (S IRUP),
falls es – neben nicht–rekursiven Regeln – genau eine rekursive Regel enthält.
Wenn P nur eine rekursive Regel r = A ← B1 ∧ . . . ∧ Bm enthält, dann ist
genau ein Prädikatensymbol pBi wechselseitig rekursiv zu pA , und zusätzlich ist
pA = pBi . Offensichtlich ist r dann auch direkt–rekursiv.
Prof. Dr. Dietmar Seipel
724
Deduktive Datenbanken
Sommersemester 2012
Beispiel (Lineare Rekursion)
2 Die Regeln r1 und r2 sind linear. Man nennt sie links– (r1 ) bzw.
rechts–linear (r2 ). r3 ist dagegen nicht linear. Man nennt r3 quadratisch, da
das rekursive Prädikatensymbol tc in zwei Rumpfatomen auftritt.
r1 = tc(X, Z) ← tc(X, Y ) ∧ arc(Y, Z),
r2 = tc(X, Z) ← arc(X, Y ) ∧ tc(Y, Z),
r3 = tc(X, Z) ← tc(X, Y ) ∧ tc(Y, Z).
2 Das Programm P = { r4 , r5 } ist linear–rekursiv.
Das Programm P = { r5 , r6 } ist nicht linear wegen der Regel r6 :
r4 = p(X, Y ) ← q(X, Y ),
r5 = q(X, Y ) ← p(Y, X),
r6 = p(X, Y ) ← p(X, Z) ∧ q(Z, Y ).
Prof. Dr. Dietmar Seipel
725
Deduktive Datenbanken
Sommersemester 2012
Stabilität von Regeln
2 Man kann bei der SLD–Resolution eine ausgefeiltere Selektionsfuntion s als
sl verwenden, welche möglichst Atome auswählt, die schon teilweise
gebunden sind.
2 Analog kann der TP –Operator die Reihenfolge der auszuwertenden
Rumpfatome geeignet wählen.
Entsprechend würde auch ein Optimierer bei der Auswertung von
S QL–Anfragen in relationalen Datenbanksystemen vorgehen, um eine
geeignete Join–Reihenfolge zu bestimmen.
2 Man kann die Auswertung von linear–rekursiven Programmen optimieren,
wenn der rekursive Aufruf im Regelrumpf dasselbe Bindungsmuster hat wie
der Aufruf des Kopfatoms.
Prof. Dr. Dietmar Seipel
726
Deduktive Datenbanken
Sommersemester 2012
Definition 4.4 (Stabilität)
2 Eine Folge h Bi0 , Bi1 , . . . , Bik i von verschiedenen Atomen aus einer
linearen, direkt–rekursiven Regel
r = A ← B1 ∧ . . . ∧ Bm
ist eine Kette in r, wenn gilt:
– Bi0 = A und pBik = pA , und
– Bij und Bij+1 haben (mindestens) eine Variable Xj+1 (Kettvariable)
gemeinsam (0 ≤ j ≤ k − 1).
2 Die Kette heißt stabil, wenn die initiale Variable X1 im Kopf auf derselben
Argumentposition steht wie die finale Variable Xk im Rumpf.
2 r heißt stabil, wenn alle Ketten in r stabil sind.
Die Stabilität ist eine sehr häufige Eigenschaft von rekursiven Regeln.
Prof. Dr. Dietmar Seipel
727
Deduktive Datenbanken
Sommersemester 2012
Beispiel (Stabilität)
2 Die folgende stabile Regel hat zwei stabile Ketten:
p(X1 , Y1 ) ← a(X1 , X2 ) ∧ p(X3 , Y1 ) ∧ b(X2 , X3 )
– Bi0 = p(X1 , Y1 ), Bi1 = a(X1 , X2 ), Bi2 = b(X2 , X3 ), Bi3 = p(X3 , Y1 ),
mit den Kettvariablen X1 , X2 , X3 , und
– Bi0 = p(X1 , Y1 ), Bi1 = p(X3 , Y1 ), mit der Kettvariablen Y1 .
2 Die folgende stabile Regel hat zwei stabile Ketten:
p(X1 , Y1 ) ← up(X1 , X2 ) ∧ p(X2 , Y2 ) ∧ down(Y2 , Y1 ).
– Bi0 = p(X1 , Y1 ), Bi1 = up(X1 , X2 ), Bi2 = p(X2 , Y2 ),
mit den Kettvariablen X1 , X2 , und
– Bi0 = p(X1 , Y1 ), Bi1 = down(Y1 , Y2 ), Bi2 = p(X2 , Y2 ),
mit den Kettvariablen Y1 , Y2 .
Prof. Dr. Dietmar Seipel
728
Deduktive Datenbanken
Sommersemester 2012
2 Die folgende stabile Regel hat ebenfalls zwei stabile Ketten:
sg(X1 , Y1 ) ← par(X1 , X2 ) ∧ sg(X2 , Y2 ) ∧ par(Y1 , Y2 ).
Sie entsteht aus der vorherigen, wenn man
– up(X1 , X2 ) durch par(X1 , X2 ) und
– down(Y2 , Y1 ) durch par(Y1 , Y2 ) ersetzt.
2 Die folgende instabile Regel hat eine stabile und zwei instabile Ketten:
p(X1 , Y1 , Z1 ) ← a(X1 , X2 ) ∧ p(Y1 , X2 , Z1 ),
– stabil: Bi0 = p(X1 , Y1 , Z1 ), Bi1 = p(Y1 , X2 , Z1 ), mit der Kettvariablen Z1 ,
– instabil: Bi0 = p(X1 , Y1 , Z1 ), Bi1 = a(X1 , X2 ), Bi2 = p(Y1 , X2 , Z1 ),
mit den Kettvariablen X1 , X2 , und
– Bi0 = p(X1 , Y1 , Z1 ), Bi1 = p(Y1 , X2 , Z1 ), mit der Kettvariablen Y1 .
Sobald eine Kette nicht stabil ist, ist die Regel nicht stabil.
Prof. Dr. Dietmar Seipel
729
Deduktive Datenbanken
Sommersemester 2012
2 Die folgende instabile Regel hat zwei instabile Ketten:
p(X1 , Y1 ) ← up(X1 , X2 ) ∧ p(Y2 , X2 ) ∧ down(Y2 , Y1 ).
– Bi0 = p(X1 , Y1 ), Bi1 = up(X1 , X2 ), Bi2 = p(Y2 , X2 ),
mit den Kettvariablen X1 , X2 , und
– Bi0 = p(X1 , Y1 ), Bi1 = down(Y1 , Y2 ), Bi2 = p(Y2 , X2 ),
mit den Kettvariablen Y1 , Y2 .
2 Die folgende instabile Regel hat ebenfalls zwei instabile Ketten:
sg(X1 , Y1 ) ← par(X1 , X2 ) ∧ sg(Y2 , X2 ) ∧ par(Y1 , Y2 ).
Sie entsteht aus der vorherigen, wenn man
– up(X1 , X2 ) durch par(X1 , X2 ) und
– down(Y2 , Y1 ) durch par(Y1 , Y2 ) ersetzt.
Prof. Dr. Dietmar Seipel
730
Deduktive Datenbanken
Sommersemester 2012
Eigentlich muß man Tupel von Kettvariablen betrachten:
2 Die folgende stabile Regel hat zwei stabile Ketten:
p(X1 , Y1 , U , V ) ← a(X1 , Y1 , X2 , Y2 ) ∧ p(X2 , Y2 , U, V )
– Bi0 = p(X1 , Y1 , U, V ), Bi1 = a(X1 , Y1 , X2 , Y2 ),
Bi2 = p(X2 , Y2 , U, V ), mit den Tupeln von Kettvariablen
(X1 , Y1 ), (X2 , Y2 ). Falls man nur die einzelnen Kettvariablen X1 , Y2
betrachten würde, so würde die Kette als instabil erscheinen.
– Bi0 = p(X1 , Y1 , U, V ), Bi1 = p(X2 , Y2 , U, V ),
mit dem Tupel von Kettvariablen (U, V ).
Prof. Dr. Dietmar Seipel
731
Deduktive Datenbanken
Sommersemester 2012
Verhalten bei SLD–Resolution
Die SLD–Resolution mit der Selektionsfunktion sl ruft bei der stabilen Same
Generation–Regel sg/2 im Kopf mit demselben Bindungsmuster ( sg(+,-) )
wie im Rumpf auf:
← sg(a, Y )
sg(X1 , Y1 ) ← par(X1 , X2 )
∧ sg(X2 , Y2 ) ∧ par(Y1 , Y2 )
?)
← par(a, X2 ) ∧ sg(X2 , Y2 ) ∧ par(Y, Y2 )
par (a, b)
?)
← sg(b, Y2 ) ∧ par(Y, Y2 )
Dies gilt analog auch wenn man das Bindungsmuster sg(-,+) mit der
Selektionsfunktion sr evaluiert.
Prof. Dr. Dietmar Seipel
732
Deduktive Datenbanken
Sommersemester 2012
Die SLD–Resolution mit der Selektionsfunktion sl ruft bei der instabilen Same
Generation–Regel sg/2 im Kopf mit einem anderen Bindungsmuster
( sg(+,-) ) als im Rumpf ( sg(-,+) ) auf:
← sg(a, Y )
sg(X1 , Y1 ) ← par(X1 , X2 )
∧ sg(Y2 , X2 ) ∧ par(Y1 , Y2 )
?)
← par(a, X2 ) ∧ sg(Y2 , X2 ) ∧ par(Y, Y2 )
par (a, b)
?)
← sg(Y2 , b) ∧ par(Y, Y2 )
Dies gilt analog auch wenn man das Bindungsmuster sg(-,+) mit der
Selektionsfunktion sr evaluiert.
Prof. Dr. Dietmar Seipel
733
Deduktive Datenbanken
Sommersemester 2012
Wenn man das obige Beispiel weiter resolviert, dann landet zuerst die Bindung b
in einem mittleren par –Atom und dann die Bindung c wieder an der ersten
Stelle eines sg–Atoms:
← sg(Y2 , b) ∧ par(Y, Y2 )
sg(X1′ , Y1′ ) ← par(X1′ , X2′ )
∧ sg(Y2′ , X2′ ) ∧ par(Y1′ , Y2′ )
?)
← par(Y2 , X2′ ) ∧ sg(Y2′ , X2′ ) ∧ par(b, Y2′ ) ∧ par(Y, Y2 )
par (b, c)
?)
← par(Y2 , X2′ ) ∧ sg(c, X2′ ) ∧ par(Y, Y2 )
Die bis hierher resolvierten par –Atome par(a, b) und par(b, c) bilden genauso
eine Kette wie die beiden noch verbliebenen par –Atome par(Y2 , X2′ ) und
par(Y, Y2 ).
Prof. Dr. Dietmar Seipel
734
Deduktive Datenbanken
4.4
Sommersemester 2012
Äquivalenz und Transformation von Logikprogrammen
Wir betrachten vier unterschiedlich starke Formen der Äquivalenz.
Sei Q eine Anfrage und Π eine Menge von Prädikatensymbolen.
Zwei Logikprogramme P und P ′ heißen
(≡) äquivalent, falls für alle Herbrandinterpretationen I gilt MP ∪I = MP ′ ∪I .
(≡Π ) äquivalent bezüglich Π, falls für alle Herbrandinterpretationen I über den
Prädikatensymbolen aus Π gilt MP ∪I = MP ′ ∪I .
(≡Q ) äquivalent bezüglich Q, falls für alle Herbrandinterpretationen I gilt
MP ∪I,Q = MP ′ ∪I,Q .
≡
R
≡Q
≡Π
R ≡Π,Q
(≡Π,Q ) äquivalent bezüglich Π und Q, falls für alle Herbrandinterpretationen I
über den Prädikatensymbolen aus Π gilt MP ∪I,Q = MP ′ ∪I,Q .
Prof. Dr. Dietmar Seipel
735
Deduktive Datenbanken
Sommersemester 2012
Offensichtlich ist die erste Form die stärkste, die letzte Form ist die schwächste,
und die beiden mittleren Formen sind unvergleichbar.
Die Einschränkungen auf Π und Q dienen dazu, temporäre Hilfsprädikate für die
Eingabe (Π) bzw. die Ausgabe (Q) auszublenden.
Das Up–Down–Schema: Pup,down
2 Wir verwenden im folgenden wiederholt das zwei–dimensionale, stabile
up–down–Schema Pup,down = { rup,down , eup,down } mit
rup,down = p(X , Y ) ← up(X, X1 ) ∧ p(X1 , Y1 ) ∧ down(Y1 , Y )
eup,down = p(X , Y ) ← f lat(X, Y )
2 In Kapitel 5 werden wir sehen, wie man Pup,down effizient auswerten kann.
Wir werden sogar zeigen, daß sich alle linearen S IRUPs (z.B. anc, tc, sg) auf
Verallgemeinerungen des up–down–Schemas normalisieren lassen.
Prof. Dr. Dietmar Seipel
736
Deduktive Datenbanken
Sommersemester 2012
2 Zur Faktenmenge
up(a1 , a2 ), up(a2 , a3 ), flat(a3 , b3 ), down(b3 , b2 ), down(b2 , b1 ),
leitet Pup,down der Reihe nach folgende Fakten ab:
p(a3 , b3 ), p(a2 , b2 ), p(a1 , b1 ).
a3
up a2
up a1
flat
- b3
U
down
b2
U
down
b1
Ein Fakt p(a, b) kann abgeleitet werden, wenn es eine Brücke gibt, die von a
über k Schritte nach oben (up) geht, dann über flat nach rechts, und dann
ebenfalls über k Schritte nach unten (down) zu b.
Prof. Dr. Dietmar Seipel
737
Deduktive Datenbanken
Sommersemester 2012
Das Fakt p(a1 , b1 ) wird z.B. mit folgendem Beweisbaum abgeleitet:
Man erkennt, daß die verwendeten up–Atome und die verwendeten
down–Atome zwei separate Ketten up(a1 , a2 ), up(a2 , a3 ) und
down(b3 , b2 ), down(b2 , b1 ) bilden.
Prof. Dr. Dietmar Seipel
738
Deduktive Datenbanken
Sommersemester 2012
l
r
q
Ancestor: Panc
, Panc
, Panc
l
l
= { ranc
, eanc } mit
2 Das links–lineare Logikprogramm Panc
l
ranc
= anc(X , Y ) ← anc(X, Z) ∧ par(Z, Y )
eanc = anc(X , Y ) ← par(X, Y )
ist bezüglich Π = { par } äquivalent zum rechts–linearen Logikprogramm
r
r
Panc
= { ranc
, eanc } mit der rechts–rekursiven Regel
r
ranc
= anc(X , Y ) ← par(X, Z) ∧ anc(Z, Y )
l
r
∪ I und Panc
∪I
Für alle Herbrandinterpretationen I über Π haben Panc
sogar dieselben ordinalen Potenzen.
Sie sind auch beide bezüglich Π = { par } äquivalent zum quadratischen
q
q
Logikprogramm Panc
= { ranc
, eanc } mit der rekursiven Regel
q
ranc
= anc(X , Y ) ← anc(X, Z) ∧ anc(Z, Y )
Prof. Dr. Dietmar Seipel
739
Deduktive Datenbanken
Sommersemester 2012
2 Betrachten wir z.B. die Faktenmenge
I = { par (a1 , a2 ), par (a2 , a3 ), par (a3 , a4 ), par (a4 , a5 ) }.
a1
- a2
- a3
- a4
- a5
l
r
Dann erhalten wir sowohl für P = Panc
∪ I als auch für P = Panc
∪ I die
folgenden ordinalen Potenzen und MP = TP ↑ 5 :
TP ↑ 0
=
∅,
TP ↑ 1
=
I,
TP ↑ 2
=
I ∪ { anc(a1 , a2 ), anc(a2 , a3 ), anc(a3 , a4 ), anc(a4 , a5 ) },
TP ↑ 3
=
TP ↑ 2 ∪ { anc(a1 , a3 ), anc(a2 , a4 ), anc(a3 , a5 ) },
TP ↑ 4
=
TP ↑ 3 ∪ { anc(a1 , a4 ), anc(a2 , a5 ) },
TP ↑ n
=
TP ↑ 4 ∪ { anc(a1 , a5 ) }, für n ≥ 5.
Die Fakten anc(ai , ai+k ) zur Pfadlänge k werden also in Iteration k + 1
abgeleitet. Wenn k die maximale Pfadlänge ist, dann sind ab n = k + 1 alle
ordinalen Potenzen gleich.
Prof. Dr. Dietmar Seipel
740
Deduktive Datenbanken
Sommersemester 2012
Das Fakt anc(a1 , a5 ) wird z.B. mit folgendem Beweisbaum abgeleitet:
Der Beweisbaum benutzt an der Wurzel die Regelinstanz
anc(a1 , a5 ) ← anc(a1 , a4 ) ∧ par (a4 , a5 ).
Prof. Dr. Dietmar Seipel
741
Deduktive Datenbanken
Sommersemester 2012
q
Auch für P = Panc
∪ I erhalten wir dasselbe minimale Herbrandmodell
MP = TP ↑ 4, aber schneller und über andere ordinale Potenzen:
TP ↑ 0
=
∅,
TP ↑ 1
=
I,
TP ↑ 2
=
I ∪ { anc(a1 , a2 ), anc(a2 , a3 ), anc(a3 , a4 ), anc(a4 , a5 ) },
TP ↑ 3
=
TP ↑ 2 ∪ { anc(a1 , a3 ), anc(a2 , a4 ), anc(a3 , a5 ) },
TP ↑ n
=
TP ↑ 3 ∪ { anc(a1 , a4 ), anc(a2 , a5 ), anc(a1 , a5 ) }, für n ≥ 4.
Nach n Schritten sind die Pfade der Länge k = 2n−2 durchlaufen. Die Instanz
anc(a1 , a5 ) ← anc(a1 , a3 ) ∧ anc(a3 , a5 )
| {z } | {z }
| {z }
f1,5
f1,3
f3,5
der Regel r leitet z.B. für n = 4 aus den zwei Fakten f1,3 , f3,5 ∈ TP ↑ 3 zur
Pfadlänge 2n−3 = 2 ein Fakt f1,5 ∈ TP ↑ 4 zur Pfadlänge 2n−2 = 4 ab.
Wenn k die maximale Pfadlänge ist, dann sind insgesamt nur
n = ⌈log2 k⌉ + 2 Iterationen erforderlich.
Prof. Dr. Dietmar Seipel
742
Deduktive Datenbanken
Sommersemester 2012
q
l
Für das quadratische Logikprogramm Panc
gibt es – anders als für Panc
r
und Panc
– sogar mehrere Beweisbäume zum Fakt anc(a1 , a5 ):
Dieser Beweisbaum benutzt an der Wurzel die Regelinstanz
anc(a1 , a5 ) ← anc(a1 , a3 ) ∧ anc(a3 , a5 ).
Prof. Dr. Dietmar Seipel
743
Deduktive Datenbanken
Sommersemester 2012
Der folgende Beweisbaum benutzt an der Wurzel die Regelinstanz
anc(a1 , a5 ) ← anc(a1 , a4 ) ∧ anc(a4 , a5 ).
Schließlich gibt es auch einen Beweisbaum, der an der Wurzel die folgende
Regelinstanz benutzt:
anc(a1 , a5 ) ← anc(a1 , a2 ) ∧ anc(a2 , a5 ).
Prof. Dr. Dietmar Seipel
744
Deduktive Datenbanken
Sommersemester 2012
l
r
2 Die linearen Logikprogramme Panc
und Panc
sind bezüglich
Π = { anc, par } nicht äquivalent.
Für I = { anc(a1 , a2 ), par (a2 , a3 ) } unterscheiden sich z.B.
MPanc
l ∪I = I ∪ { anc(a1 , a3 ) } und MP r ∪I = I.
anc
l
r
2 Panc
und Panc
sind bereits bezüglich Π = { anc } nicht äquivalent zum
q
quadratischen Logikprogramm Panc
.
Für I = { anc(a1 , a2 ), anc(a2 , a3 ) } gilt z.B.
MPanc
l ∪I = MP r ∪I = I 6= I ∪ { anc(a1 , a3 ) } = MP q ∪I .
anc
anc
Im allgemeinen gilt für eine Herbrandinterpretation I nur
MPanc
l ∪I ⊆ MP q ∪I und MP r ∪I ⊆ MP q ∪I .
anc
anc
anc
r
l
q
ist im allgemeinen stärker als Panc
und Panc
.
D.h., Panc
Prof. Dr. Dietmar Seipel
745
Deduktive Datenbanken
Sommersemester 2012
l
l
2 Außerdem ist das links–lineare Logikprogramm Panc
= { ranc
, eanc } mit
l
ranc
= anc(X , Y ) ← anc(X, Z) ∧ par(Z, Y )
eanc = anc(X , Y ) ← par(X, Y )
auch bezüglich der Anfrage Q = ← anc(X, Y ) und der Menge Π = { par }
äquivalent zum Logikprogramm
u,d
Panc
= Pup,down ∪ { e1anc , e2anc , e3anc , e4anc }
mit den Regeln
e1anc = anc(X , Y ) ← p(X, Y )
e2anc = up(X , X ) ←
e3anc = down(X , Y ) ← par (X, Y )
e4anc = flat(X , Y ) ← par (X, Y )
Prof. Dr. Dietmar Seipel
746
Deduktive Datenbanken
Sommersemester 2012
Same Generation: Psg
2 Das Logikprogramm Psg = { rsg , esg } mit
rsg = sg(X , Y ) ← par(X, X1 ) ∧ sg(X1 , Y1 ) ∧ par(Y, Y1 )
esg = sg(X , Y ) ← par(X, Z) ∧ par(Y, Z)
ist bezüglich der Anfrage Q = ← sg(X, Y ) und der Menge Π = { par }
äquivalent zum Logikprogramm
Psgu,d = Pup,down ∪ { e1sg , e2sg , e3sg , e4sg }
mit den Regeln
e1sg = sg(X , Y ) ← p(X, Y )
e2sg = up(X , Y ) ← par (X, Y )
e3sg = down(X , Y ) ← par (Y, X)
e4sg = flat(X , Y ) ← par (X, Z) ∧ par (Y, Z)
Prof. Dr. Dietmar Seipel
747
Deduktive Datenbanken
Sommersemester 2012
Man kann also Psg auf der Basis von Pup,down auswerten, indem man die
Eingabe mittels Ppre = { e2sg , e3sg , e4sg } für Pup,down aufbereitet und die
Ausgabe von Pup,down mittels Ppost = { e1sg } in die gewünschte Ausgabe
umsetzt.
6
Psg
Ppost
Postprocessing
6
Pup,down
rekursive Auswertung
6
Ppre
Preprocessing
6
Prof. Dr. Dietmar Seipel
748
Deduktive Datenbanken
Sommersemester 2012
Methodenextraktion und Methodenexpansion
2 Das Logikprogramm Pclone = { r1 , r2 } mit
r1 = p1 (X3 ) ← a(X1 ) ∧ b(X1 , X2 ) ∧ c(X2 , X3 ),
r2 = p2 (X1 , X4 ) ← a(X1 ) ∧ b(X1 , X2 ) ∧ c(X2 , X3 ) ∧ d(X3 , X4 ),
ist bezüglich aller Anfragen Q = ← p(t1 , . . . , tn ) mit p 6= clone und der
Menge Π = { p1 , p2 , a, b, c, d } von Prädikatensymbolen äquivalent zum
ex
= { r1′ , r2′ , r3 } mit den Regeln
Logikprogramm Pclone
r1′ = p1 (X3 ) ← clone(X1 , X3 ),
r2′ = p2 (X1 , X4 ) ← clone(X1 , X3 ) ∧ d(X3 , X4 ),
r3 = clone(X1 , X3 ) ← a(X1 ) ∧ b(X1 , X2 ) ∧ c(X2 , X3 ).
Der gemeinsame Teil der Rümpfe der Regeln r1 und r2 könnte z.B. mit
einem Klonerkennungsverfahren gefunden und in Form der Regel r3
extrahiert worden sein.
Prof. Dr. Dietmar Seipel
749
Deduktive Datenbanken
Sommersemester 2012
Die Methodenextraktion soll den Programm–Code lesbarer machen.
Bei Programm–Transformationen, die Hilfsprädikate einführen, darf man
natürlich keine Anfragen an bzw. Basis–Fakten für die Hilfsprädikate zulassen:
2 Natürlich sind
l
u,d
– Panc
und Panc
bzw.
– Psg und Psgu,d
u,d
nicht äquivalent im stärksten Sinne, da Panc
und Psgu,d Fakten zu den
l
Hilfsprädikaten p, up, down und flat ableiten, welche in Panc
und Psg
überhaupt nicht vorkommen.
2 Ebenso sind aufgrund des Hilfsprädikats clone die beiden obigen
ex
nicht äquivalent im stärksten Sinne.
Logikprogramme Pclone und Pclone
2 Auch die beiden mittleren Formen von Äquivalenz liegen in allen drei Fällen
nicht vor.
Prof. Dr. Dietmar Seipel
750
Deduktive Datenbanken
Sommersemester 2012
Die Methodenexpansion ist invers zur Methodenextraktion.
2 Das Logikprogramm
p(X ) ← q(X) ∧ b(X),
q(X ) ← a(X),
ist bezüglich der Anfrage Q = ← p(X) und Π = { a, b } äquivalent zu
p(X ) ← a(X) ∧ b(X).
2 Im weiteren, allgemeinen Sinne sind die beiden natürlich nicht äquivalent,
– denn das zweite Programm kann keine Anfragen an q/1 beantworten,
– und es ist immun gegen Fakten für q/1 in der Eingabe.
Die Methodenexpansion kann dazu dienen, nicht mehr benötigte Methoden zu
entfernen, indem man die Methodenaufrufe durch die entsprechenden Statements
ersetzt.
Prof. Dr. Dietmar Seipel
751
Deduktive Datenbanken
Sommersemester 2012
Methodenexpansion für rekursive Regeln
Wir betrachten hierzu wieder das links–rekursive Ancestor–Beispiel
l
l
Panc
= { ranc
, eanc } mit
l
ranc
= anc(X , Y ) ← anc(X, Z) ∧ par (Z, Y ),
eanc = anc(X , Y ) ← par (X, Y ),
und die Faktenmenge I = { par (a1 , a2 ), par (a2 , a3 ), par (a3 , a4 ), par (a4 , a5 ) }.
a1
- a2
- a3
- a4
- a5
l
Wenn wir die Variante anc(X , Z ) ← anc(X, Z ′ ) ∧ par (Z ′ , Z) von r = ranc
in
r einsetzen, dann erhalten wir eine neue Regel
r ′′ = anc(X , Y ) ← anc(X, Z ′ ) ∧ par (Z ′ , Z) ∧ par (Z, Y ),
die wir die zweite Iterierte von r nennen, da ihre Anwendung einer zweifachen
Anwendung von r entspricht. r ′′ leitet aus einem anc–Fakt zur Pfadlänge k ein
anc–Fakt zur Pfadlänge k + 2 ab.
Prof. Dr. Dietmar Seipel
752
Deduktive Datenbanken
Sommersemester 2012
Das ebenfalls links–rekursive, definite Logikprogramm P ′′ = { r ′′ , eanc } kann
nur die Fakten zu ungeraden Pfadlängen ableiten. Für P = P ′′ ∪ I erhalten wir:
TP ↑ 0
=
∅,
TP ↑ 1
=
I,
TP ↑ 2
=
I ∪ { anc(a1 , a2 ), anc(a2 , a3 ), anc(a3 , a4 ), anc(a4 , a5 ) },
TP ↑ n
=
TP ↑ 2 ∪ { anc(a1 , a4 ), anc(a2 , a5 ) }, für n ≥ 3.
Nach n Schritten sind die Pfade der ungeraden Längen k ≤ 2 · n − 3 durchlaufen.
Die Instanz
anc(a1 , a4 ) ← anc(a1 , a2 ) ∧ par (a2 , a3 ) ∧ par (a3 , a4 )
| {z } | {z } | {z }
| {z }
f1,4
f1,2
f2,3
f3,4
der Regel r leitet für n = 3 z.B. aus den drei Fakten f1,2 , f2,3 , f3,4 ∈ TP ↑ 2 zur
Pfadlänge 1 ein Fakt f1,4 ∈ TP ↑ 3 zur Pfadlänge 2 · n − 3 = 3 ab.
Wenn k die maximale ungerade Pfadlänge ist, dann sind ab n = ⌈(k + 3)/2⌉ alle
ordinalen Potenzen gleich.
Prof. Dr. Dietmar Seipel
753
Deduktive Datenbanken
Sommersemester 2012
l
P ′′ = { r ′′ , eanc } ist bezüglich Π = { par } also nicht äquivalent zu Panc
. Oben
wurde z.B. das Fakt anc(a1 , a5 ) zur geraden Pfadlänge 4 nicht abgeleitet.
Um auch die Fakten zu den geraden Pfadlängen ableiten zu können, nehmen wir
die Regel e′ = anc(X , Y ) ← par (X, Z) ∧ par (Z, Y ) hinzu.
Das ebenfalls links–rekursive, definite Logikprogramm P ′ = { r ′′ , e′ , eanc } kann
nun die Fakten zu allen Pfadlängen ableiten:
r ′′
= anc(X , Y ) ← anc(X, Z ′ ) ∧ par (Z ′ , Z) ∧ par (Z, Y ),
e′
= anc(X , Y ) ← par (X, Z) ∧ par (Z, Y ),
eanc = anc(X , Y ) ← par (X, Y ).
Die nicht–rekursiven Regeln eanc und e′ leiten offensichtlich anc–Fakten zu den
Pfadlängen 1 und 2 ab. Die rekursive Regel r ′′ kann aus einem anc–Fakt zur
Pfadlänge k und zwei par –Fakten ein anc–Fakt zur Pfadlänge k + 2 ableiten.
l
r
P ′ ist ist bezüglich Π = { par } äquivalent zu Panc
und Panc
.
Prof. Dr. Dietmar Seipel
754
Deduktive Datenbanken
Sommersemester 2012
Das Fakt anc(a1 , a5 ) zur geraden Pfadlänge 4 kann jetzt mit folgendem
Beweisbaum abgeleitet werden:
Dieser Beweisbaum benutzt an der Wurzel die folgende Regelinstanz von r ′′ :
anc(a1 , a5 ) ← anc(a1 , a3 ) ∧ par (a3 , a4 ) ∧ par (a4 , a5 ).
Außerdem werden die Fakten f1 , . . . , f4 und die folgende Instanz von e′ benutzt:
anc(a1 , a3 ) ← par (a1 , a2 ) ∧ par (a2 , a3 ).
Prof. Dr. Dietmar Seipel
755
Deduktive Datenbanken
Sommersemester 2012
Für P = P ′ ∪ I erhalten wir die folgenden ordinalen Potenzen:
TP ↑ 0
=
∅,
TP ↑ 1
=
I,
TP ↑ 2
=
I ∪ { anc(a1 , a2 ), anc(a2 , a3 ), anc(a3 , a4 ), anc(a4 , a5 ),
anc(a1 , a3 ), anc(a2 , a4 ), anc(a3 , a5 ) },
TP ↑ n
=
TP ↑ 2 ∪ { anc(a1 , a4 ), anc(a2 , a5 ), anc(a1 , a5 ) }, für n ≥ 3.
In Iteration 2 werden die anc–Fakten zu den Pfadlängen 1 und 2 berechnet
(z.B. anc(a1 , a2 ) und anc(a1 , a3 )), in Iteration 3 die anc–Fakten zu den
Pfadlängen 3 und 4 (z.B. anc(a1 , a4 ) und anc(a1 , a5 )).
In Iteration n werden die anc–Fakten zu den Pfadlängen k = 2 · n − 3 und
k = 2 · n − 2 neu berechnet.
Nach n Schritten sind alle Pfade der Längen k ≤ 2 · n − 2 durchlaufen.
Wenn k die maximale Pfadlänge ist, dann sind ab n = ⌈(k + 2)/2⌉ also alle
ordinalen Potenzen gleich.
Prof. Dr. Dietmar Seipel
756
Deduktive Datenbanken
Sommersemester 2012
Programm–Transformation
basierend auf der Methodenexpansion – Iteration von Regeln
Auch für das modifizierte up–down–Beispiel P = { r, e } mit
r = p(X , Y ) ← up′ (X, X1 ) ∧ p(Y1 , X1 ) ∧ down ′ (Y1 , Y )
e = p(X , Y ) ← flat ′ (X, Y )
kann man die Variante p(Y1 , X1 ) ← up′ (Y1 , X1′ ) ∧ p(Y1′ , X1′ ) ∧ down ′ (Y1′ , X1 )
der Regel r in r einsetzen (Methodenexpansion) und erhält die Iterierte
r ′′ = p(X , Y ) ←
up′ (X, X1 ) ∧ down ′ (Y1′ , X1 ) ∧ p(Y1′ , X1′ )∧
up′ (Y1 , X1′ ) ∧ down ′ (Y1 , Y ).
Die Anwendung von r ′′ entspricht einer zweifachen Anwendung von r.
Im Gegensatz zu r ist r ′′ stabil.
Prof. Dr. Dietmar Seipel
757
Deduktive Datenbanken
Sommersemester 2012
Zur Faktenmenge
up ′ (a1 , a2 ), down ′ (a3 , a2 ), flat ′ (a3 , b3 ), up ′ (b2 , b3 ), down ′ (b2 , b1 ),
leitet P der Reihe nach folgende Fakten ab:
p(a3 , b3 ), p(b2 , a2 ), p(a1 , b1 ).
a3
down ′ a2
up ′ a1
flat ′
- b3
K up ′
b2
down ′
U
b1
Ein Fakt p(a, b) kann von r′′ zusammen mit e abgeleitet werden, wenn es eine Brücke
gibt, die von a aus 2 · k Schritte unter alternierender Verwendung von up ′ und vom
Inversen von down ′ macht, dann über flat ′ nach rechts geht, und dann 2 · k Schritte unter
alternierender Verwendung vom Inversen von up ′ und von down ′ zu b macht.
Prof. Dr. Dietmar Seipel
758
Deduktive Datenbanken
Sommersemester 2012
Das Fakt p(a1 , b1 ) wird von P mit folgendem Beweisbaum abgeleitet –
wir verwenden im Bild up, down und flat anstelle von up ′ , down ′ und flat ′ :
Man erkennt, daß die verwendeten up ′ –Atome und die verwendeten
down ′ –Atome nun zwei gemischte Ketten up ′ (a1 , a2 ), down ′ (a3 , a2 ) und
up ′ (b2 , b3 ), down ′ (b2 , b1 ) bilden.
Prof. Dr. Dietmar Seipel
759
Deduktive Datenbanken
Sommersemester 2012
Das Fakt p(a1 , b1 ) wird von P ′′ = { r ′′ , e } und der Faktenmenge
up ′ (a1 , a2 ), down ′ (a3 , a2 ), flat ′ (a3 , b3 ), up ′ (b2 , b3 ), down ′ (b2 , b1 ),
mit folgendem Beweisbaum abgeleitet:
Der Beweisbaum für P ′′ ist flacher als der vorherige Beweisbaum für P ,
da die Anwendung der Regel r ′′ der zweifachen Anwendung von r entspricht.
Prof. Dr. Dietmar Seipel
760
Deduktive Datenbanken
Sommersemester 2012
2 Dann gilt für P ′′ = { r ′′ , e } und eine Herbrandinterpretation I:
∆TP ′′ ∪I ↑ n = ∆TP ∪I ↑ 2 · n − 1, für n ≥ 1,
wobei ∆T ↑ n = T ↑ n \ T ↑ n − 1.
2 Die Auswertung der iterierten Regel r ′′ zusammen mit e würde also nur die
ungeraden Potenzen von TP ∪I ↑ ω liefern.
2 Um auch die geraden Potenzen zu erhalten, nehmen wir die Regel e′ hinzu:
e′ = p(X , Y ) ← up′ (X, X1 ) ∧ flat ′ (Y1 , X1 ) ∧ down ′ (Y1 , Y ).
2 Dann ist das Logikprogramm P ′ = { r ′′ , e′ , e } bezüglich der Anfrage
Q = ← p(X, Y ) und Π = { up′ , flat ′ , down′ } äquivalent zu P .
2 Die Regel e′ entspricht der Anwendung von e gefolgt von r, also r ◦ e, und
die Regel r ′′ entspricht der zweifachen Anwendung von r, also r 2 = r ◦ r;
somit entspricht die Umformung von P zu P ′ der folgenden Umformung:
′′ n
′
2·n
n
∞
◦ (r ◦ e ∪ e) = ∪∞
∪∞
n=0 (r ) ◦ (e ∪ e).
n=0 r ◦ e = ∪n=0 r
Prof. Dr. Dietmar Seipel
761
Deduktive Datenbanken
Sommersemester 2012
2 Man kann jetzt r ′′ noch mit zwei Hilfsregeln zu rup,down vereinfachen:
e1 = up(X , Y1′ ) ← up′ (X, X1 ) ∧ down ′ (Y1′ , X1 ),
e2 = down(X1′ , Y ) ← up′ (Y1 , X1′ ) ∧ down ′ (Y1 , Y ).
2 Zusammen mit den Regeln
e3 = flat(X , Y ) ← up′ (X, X1 ) ∧ flat ′ (Y1 , X1 ) ∧ down ′ (Y1 , Y )
e4 = flat(X , Y ) ← flat ′ (X, Y )
kann man ein Logikprogramm P ′′ = Pup,down ∪ { e1 , e2 , e3 , e4 } bilden, das
ebenfalls bezüglich der Anfrage Q und der Menge Π äquivalent zu P ist.
2 P ′′ kann auf der Basis von Pup,down effizient ausgewertet werden.
Die Regeln e1 , e2 , e3 , e4 definieren geeignete Faktenmengen, für up, down
und flat, auf die dann Pup,down angewendet werden kann.
Prof. Dr. Dietmar Seipel
762
Deduktive Datenbanken
Sommersemester 2012
Man erkennt, daß Pup,down und P strukturell sehr unterschiedlich sind:
2 Im stabilen Pup,down verbindet up die erste Argumentposition des p–Atoms
des Kopfes und Rumpfes, und down die zweiten Argumentpositionen.
2 Im instabilen P verbindet up′ die erste Argumentposition des Kopfes mit der
zweiten Argumentposition des Rumpfes, und down′ die zweite des Kopfes
mit der ersten des Rumpfes.
Pup,down :
P:
1
..
....
..
...
.
...
..
...
...
...
...
...
.
...
...
...
...
...
..
..
.
..
...
..
....
.
..
up
Prof. Dr. Dietmar Seipel
2
...
.. .
..
...
.
...
..
...
...
...
...
...
.
2
1
...
...
...
...
...
..
..
.
..
...
..
.. .
.
...
down
.
..
.. .
..
...
.
...
..
...
...
...
...
...
.
o
U
up′
7
...
...
...
...
...
..
..
.
..
...
..
.. .
..
..
down′
763
Deduktive Datenbanken
Sommersemester 2012
Die obigen Graphen nennt man AS–Graphen.
In ihnen unterscheiden sich Pup,down und P essentiell.
Die Rule–Goal–Graphen der beiden Programme sind dagegen strukturell gleich.
GPrgup,down :
p/2
eup,down
flat/2
Prof. Dr. Dietmar Seipel
GPrg :
p/2
I
R
rup,down
up/2
R
down/2
e
flat /2
′
I
R
r
R
′
up /2 down ′ /2
764
Deduktive Datenbanken
Sommersemester 2012
′′
Vergleicht man r ′′ mit der Iterierten rup,down
r ′′
=
p(X , Y ) ←
up′ (X, X1 ) ∧ down′ (Y1′ , X1 ) ∧ p(Y1′ , X1′ ) ∧
up′ (Y1 , X1′ ) ∧ down′ (Y1 , Y ),
′′
rup,down
=
p(X , Y ) ←
up(X, X1 ) ∧ up(X1 , X1′ ) ∧ p(X1′ , Y1′ ) ∧
down(Y1′ , Y1 ) ∧ down(Y1 , Y ),
so erkennt man: in Pup,down liefern die up– bzw. down–Atome unterschiedliche
Ketten, während die up′ – und down′ –Atome in P verschränkt sind.
Durch die Programm–Transformation P ′′ = Pup,down ∪ { e1 , e2 , e3 , e4 } kann
man aber P auf Pup,down zurückführen.
Da es effiziente Auswertungsmethoden für Pup,down gibt, ist das ein Vorteil.
Prof. Dr. Dietmar Seipel
765
Deduktive Datenbanken
Sommersemester 2012
Kettennormalisierung
In Abschnitt 5.3 werden wir zeigen wie beliebige linear–rekursive Regeln auf der
Basis der AS–Graphen normalisiert werden können.
r = p(X1 , X2 , X3 , X4 , X5 , X6 ) ← p(U1 , U2 , U3 , X3 , X5 , U6 ) ∧
a(X1 , U1 ) ∧ b(X2 , U3 ) ∧ c(X4 , U2 ) ∧ d(X6 ).
1
1
..
...
.. .
..
...
..
...
...
...
...
...
.
1
2
...
...
...
...
...
.
1 ....
.
2 ...
.
..
... .
a
Prof. Dr. Dietmar Seipel
2
k
1
2
3
U
b
1 -4
1
2
1
2
c
1
2
5
6
1
2
?
d
766
Deduktive Datenbanken
Sommersemester 2012
Die Normalform kann man sich vereinfacht wie folgt vorstellen:
p(X1 , . . . , Xn ) ← p(U1 , . . . , Un ) ∧ a1 (X1 , U1 ) ∧ . . . ∧ an (Xn , Un ).
1
..
.. .
..
...
...
...
...
...
...
1
2
...
...
...
...
.
1 .....
2 .....
..
..
a1
n
..
.. .
..
...
...
...
...
...
...
···
1
2
...
...
...
...
.
1 ....
2 ....
..
..
an
Wenn wir für n = 2 die Prädikatensymbole a1 = up und a2 = down−1 setzen,
dann erhalten wir als Spezialfall eine Variante
p(X1 , X2 ) ← p(U1 , U2 ) ∧ up(X1 , U1 ) ∧ down(U2 , X2 )
der rekursiven Regel rup,down des Up–Down–Schemas.
Dabei ist das Inverse down−1 durch Vertauschung der beiden
Argumentpositionen definiert.
Prof. Dr. Dietmar Seipel
767
Deduktive Datenbanken
Sommersemester 2012
Programm–Transformation
durch Ausnutzen von Selektionsbedingungen
l
l
Hierzu betrachten wir die Ancestor–Beispiele Panc
= { ranc
, eanc }
r
r
(links–rekursiv) und Panc
= { ranc
, eanc } (rechts–rekursiv) mit
l
= anc(X , Y ) ← anc(X, Z) ∧ par (Z, Y ),
ranc
r
ranc
= anc(X , Y ) ← par(X, Z) ∧ anc(Z, Y ),
eanc = anc(X , Y ) ← par (X, Y ),
und die Anfrage Qa = ← anc(a, Y ).
*d
*a
b
-f
c
-h
je
jg
Prof. Dr. Dietmar Seipel
768
Deduktive Datenbanken
Sommersemester 2012
2 Die naive Bottom–Up–Auswertung berechnet zur Faktenmenge
PAR = { h a, d i, h a, e i, h b, a i, h b, g i, h c, h i, h d, f i }
zuerst die Relation
A NC = PAR ∪ { h a, f i, h b, d i, h b, e i, h b, f i }.
und selektiert erst dann daraus die Resultatrelation
σA NC.1=a (A NC ) = { h a, d i, h a, e i, h a, f i }.
2 Eigentlich müssten die von b und c ausgehenden Kanten nicht bei der
Berechnung der Vorfahren von a berücksichtigt werden.
2 Im folgenden werden wir sehen, wie man das durch geeignete
Programm–Transformationen erreichen kann.
Prof. Dr. Dietmar Seipel
769
Deduktive Datenbanken
Sommersemester 2012
Einsetzen der Selektionsbedingung
2 Eine effizientere Version der Ancestor–Regeln, zugeschnitten auf die
Anfrage, erhält man durch Anwendung der Substitution θ = { X 7→ a } :
l
ranc,a
= anc(a, Y ) ← anc(a, Z) ∧ par(Z, Y )
eanc,a = anc(a, Y ) ← par(a, Y )
Sie berechnet anstelle von A NC nur die sehr viel kleinere Relation
A NC a = { h a, d i, h a, e i, h a, f i }
welche ausschließlich aus Antworttupeln besteht.
Diese Optimierung kann bei großen Faktenbasen entscheident sein.
l
l
l
l
Panc
= { ranc
, eanc } und Panc,a
= { ranc,a
, eanc,a } sind äquivalent
bezüglich der Anfrage Qa = ← anc(a, Y ), aber sie sind natürlich nicht
äquivalent bezüglich der Anfrage Qb = ← anc(b, Y ) mit a 6= b.
Prof. Dr. Dietmar Seipel
770
Deduktive Datenbanken
Sommersemester 2012
l
r
2 Panc
(links–rekursiv) und Panc
(rechts–rekursiv) sind bezüglich Π = { par }
äquivalent (bezüglich beliebiger Anfragen).
2 Das naive Einsetzen der Selektionsbedingung funktioniert nicht immer.
r
r
r
Panc
und Panc,a
= { ranc,a
, eanc,a } sind nicht äquivalent bezüglich der
Anfrage Qa = ← anc(a, Y ) :
r
ranc,a
= anc(a, Y ) ← par(a, Z) ∧ anc(Z, Y )
eanc,a = anc(a, Y ) ← par(a, Y )
denn für I = { par(a, d), par(d, f ) } gilt
r ∪I,Q
MPanc
a
= { anc(a, d), anc(a, f ) },
r
MPanc,a
∪I,Qa = { anc(a, d) }.
Um anc(a, f ) abzuleiten, müßte man vorher anc(d, f ) ableiten, was aber
r
natürlich nicht möglich ist.
mit den Regeln aus Panc,a
Prof. Dr. Dietmar Seipel
771
Deduktive Datenbanken
Sommersemester 2012
Propagieren der Selektionsbedingung
r
Man kann also die Konstante a nicht in die Regeln von Panc
hinein propagieren;
man kann sie aber mittels Hilfsregeln propagieren.
r
2 Aus einer Bindung für “X” im Regelkopf von ranc
kann man mit Hilfe der
folgenden DATALOG–Regel eine Bindung für “Z” im Regelrumpf
berechnen:
ancmagic (Z ) ← ancmagic (X) ∧ par(X, Z).
2 Die Verankerung von ancmagic erfolgt mittels des Fakts
ancmagic (a).
2 Diese beiden Regeln leiten alle Konstanten ab, die bei der
Top–Down–Auswertung (mittels SLD–Resolution) der Anfrage
r
Qa = ← anc(a, Y ) an Panc
in anc–Atomen an der ersten
Argumentposition auftreten.
Prof. Dr. Dietmar Seipel
772
Deduktive Datenbanken
Sommersemester 2012
2 Beispiel:
G0 = ← anc(a, Y ),
G1 = ← par(a, Z) ∧ anc(Z, Y ),
G2 = ← anc(d, Y ).
r
und dann mit dem Fakt par(a, d)
Hier wurde zuerst mit der Regel ranc
resolviert.
r
2 Um ein Fakt anc(a, Y ) mit dem TP –Operator für P = Panc
abzuleiten,
benötigt man eine Grundinstanz ra θ der Regel
ra = anc(a, Y ) ← par(a, Z) ∧ anc(Z, Y ).
Bevor diese Regel feuern kann, muß wiederum das Fakt anc(Z, Y )θ für den
par–Nachfolger Zθ von a mit dem TP –Operator abgeleitet worden sein.
Prof. Dr. Dietmar Seipel
773
Deduktive Datenbanken
Sommersemester 2012
2 Per Induktion kann man zeigen, daß alle Fakten anc(z, y) zu den transitiven
par–Nachfolgern z relevant für die Beantwortung unserer Anfrage
Qa = ← anc(a, Y ) sind.
2 Die transitiven par–Nachfolger im Erreichbarkeitskegel von a werden
mittels der folgenden magischen Regeln berechnet:
a-x-z
ancmagic (Z ) ← ancmagic (X) ∧ par(X, Z),
ancmagic (a).
r
2 Mit dem Filter ancmagic kann die Anwendbarkeit von ranc
und eanc bei der
r
Bottom–Up–Auswertung (mit dem TP –Operator für P = Panc
) geeignet
eingeschränkt werden:
anc(X , Y ) ← ancmagic (X) ∧ par(X, Z) ∧ anc(Z, Y ),
anc(X , Y ) ← ancmagic (X) ∧ par(X, Y ).
Diese Regeln nennen wir modifizierte Regeln.
Prof. Dr. Dietmar Seipel
774
Deduktive Datenbanken
Sommersemester 2012
Für den Stammbaum
*d
*a
b
-f
c
-h
je
jg
wird dann abgeleitet: ancmagic (a), ancmagic (d), ancmagic (e), ancmagic (f ).
Deshalb feuern nur noch folgende Grundinstanzen der modifizierten Regeln:
anc(a, f ) ← ancmagic (a) ∧ par(a, d) ∧ anc(d, f ),
anc(a, d ) ← ancmagic (a) ∧ par(a, d),
anc(a, e) ← ancmagic (a) ∧ par(a, e),
anc(d , f ) ← ancmagic (d) ∧ par(d, f ).
Prof. Dr. Dietmar Seipel
775
Deduktive Datenbanken
Sommersemester 2012
r
Sei weiter P = Panc
. Abgesehen von den magischen Fakten
ancmagic (a), . . . , ancmagic (f )
und den Basisfakten
par(a, d), par(a, e), par(b, a), par(b, g), par(c, h), par(d, f ),
liegt dann die Menge I der abgeleiteten Fakten zwischen MP und
MP,Qa = { anc(a, d), anc(a, e), anc(a, f ) } :
2 I = MP,Qa ∪ { anc(d, f ) }.
2 Das Fakt anc(d, f ) wird nur abgeleitet, da es zur Ableitung von anc(a, f )
benötigt wird.
2 Es werden also nur noch 4 der 10 anc–Fakten aus der naiven
Bottom–Up–Auswertung abgeleitet.
In diesem – relativ einfachen – Beispiel könnte man die Anfrage sogar alleine
aufgrund der abgeleiteten magischen Fakten beantworten.
Prof. Dr. Dietmar Seipel
776
Deduktive Datenbanken
Sommersemester 2012
Für das modifizierte up–down–Beispiel P = { r, e } und die Anfrage
Q = ← p(a, Y ) ist die Situation komplizierter.
Hier erzeugt der Magic Sets–Algorithmus folgendes augmentierte Programm
Magic(P, Q):
h b,f i
p h b,f i (X , Y ) ← pmagic (X) ∧ up′ (X, X1 ) ∧ ph f,b i (Y1 , X1 ) ∧ down′ (Y1 , Y )
h f,b i
p h f ,b i (X , Y ) ← pmagic (Y ) ∧ up′ (X, X1 ) ∧ ph b,f i (Y1 , X1 ) ∧ down′ (Y1 , Y )
h b,f i
p h b,f i (X , Y ) ← pmagic (X) ∧ f lat′ (X, Y )
h f,b i
p h f ,b i (X , Y ) ← pmagic (Y ) ∧ f lat′ (X, Y )
Für r und e werden jeweils zwei modifizierte Regeln mit unterschiedlichen
Augmenten, h b, f i bzw. h b, f i, erzeugt.
Die Kopfprädikatensymbole ph b,f i und ph f,b i der modifizierten Regeln für r
sind wechselseitig rekursiv.
Prof. Dr. Dietmar Seipel
777
Deduktive Datenbanken
Sommersemester 2012
Außerdem gibt es drei magische Regeln zur Berechnung der magischen Atome:
h f ,b i
h b,f i
h b,f i
h f,b i
pmagic (X1 ) ← pmagic (X) ∧ up′ (X, X1 )
pmagic (Y1 ) ← pmagic (Y ) ∧ down′ (Y1 , Y )
h b,f i
pmagic (a).
Die beiden ersten magischen Regeln leiten sich aus r ab, die dritte aus der
Anfrage. Man braucht hier zwei Augmente, da sich bei der SLD–Resolution
abwechselnd Bindungen für die beiden Argumente der p–Atome ergeben:
2 Aus einer Bindung für die erste Variable X des Kopfatoms – vgl.
h b,f i
pmagic (X) – ergibt sich durch den Aufruf von up′ (X, X1 ) eine Bindung für
h f,b i
die zweite Variable X1 des p–Atoms im Rumpf – vgl. pmagic (X1 ).
2 Analog ergibt sich aus einer Bindung für die zweite Variable Y des
h f,b i
Kopfatoms – vgl. pmagic (Y ) – durch den Aufruf von down′ (Y1 , Y ) eine
h b,f i
Bindung für die erste Variable Y1 des p–Atoms im Rumpf – vgl. pmagic (Y1 ).
Prof. Dr. Dietmar Seipel
778