Einführung in Prolog

Transcrição

Einführung in Prolog
Einführung in Prolog
Martin Gebsera
1. Grundlagen
2. Syntax
3. Unifikation
4. Semantik
5. Eingebaute Konstrukte
a [email protected]
1
Prolog — Programmieren in Logik
Prolog ist eine an die Prädikatenlogik angelehnte
Programmiersprache mit (fast) deklarativer Semantik.
Ein Prolog-Programm ist eine Wissensbasis aus Fakten
(extensionales Wissen) und Regeln (intensionales Wissen).
Ein Prolog-Interpreter beantwortet Anfragen bezüglich seiner
Wissensbasis.
Anfrage
- Interpreter
* H
Y
HH
HH
Wissensbasis1 . . . Wissensbasisn
2
Antwort
Paradigmen: Imperativ versus Deklarativ
Paradigma
Imperativ
Deklarativ
Frage
Wie
Was
wird ein Problem gelöst?
ist eine Problemlösung?
Ablauf
explizit
implizit
Logik
implizit
explizit
3
Extensionales Wissen
Ein Fakt einer Wissensbasis ist eine atomare Formel.
Steffen ist der Vater von Paul:
vater(steffen,paul).
Paul ist der Vater von Maria:
vater(paul,maria).
Jede ganze Zahl ist ohne Rest durch 1 teilbar:
ist teiler(1,Z).
☞ steffen, paul, maria und 1 sind Konstanten.
☞ Z ist eine Variable.
4
Anfragen
Ist Steffen der Vater von Paul?
?- vater(steffen,paul).
Yes
Ist Steffen der Vater von Maria?
?- vater(steffen,maria).
No
Wer ist das Kind von Paul?
?- vater(paul,Kind).
Kind = maria
Wer ist das Kind von Steffen und der Vater von Maria?
?- vater(steffen,X), vater(X,maria).
5
X = paul
Intensionales Wissen (1)
Steffen ist der Großvater von Maria:
grossvater(steffen,maria).
➥ Wenn die Wissensbasis mit
vater(paul,lena).
ergänzt wird, dann muss
grossvater(steffen,lena).
ebenfalls ergänzt werden.
☞ Großväter sollten besser bei Bedarf berechnet werden!
6
Intensionales Wissen (2)
Eine Regel einer Wissensbasis hat die Form Kopf :- Körper.
Ihre Semantik entspricht der Implikation Körper → Kopf.
elternteil(X,Y) :- vater(X,Y).
elternteil(X,Y) :- mutter(X,Y).
grossvater(X,Y) :- vater(X,Z), elternteil(Z,Y).
Beim Hinzufügen von Fakten zur Wissensbasis muss die
grossvater-Relation nicht verändert werden.
☞ Eine Variable wie X, Y oder Z bezeichnet (nur) innerhalb
einer Regel dasselbe Objekt.
7
✔
Eine Prolog-Sitzung (SWI-Prolog)
[gebser@re ~]$ pl
Welcome to SWI-Prolog (Multi-threaded, Version 5.2.13)
Copyright (c) 1990-2003 University of Amsterdam.
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
Please visit http://www.swi-prolog.org for details.
For help, use ?- help(Topic). or ?- apropos(Word).
?- [vorfahre].
% vorfahre compiled 0.00 sec, 2,148 bytes
Yes
?- grossvater(X,Y).
X = steffen
Y = maria ;
X = steffen
Y = lena ;
No
?- halt.
[gebser@re ~]$
8
Prolog-Systeme
Prolog-Systeme am Institut:
System
SWI
ECLiPSe
Aufruf
pl
eclipse
Dateiendungen
pl und swi
pl und ecl
☞ Statt “?- [‘vorfahre.pl’].” reicht “?- [vorfahre].”
Weitere Informationen:
http://www.cs.uni-potsdam.de/wv/prolog/
☞ Alle Prolog-Systeme verwenden dieselbe Syntax und verfügen
(annähernd) über die gleichen eingebauten Prädikate.
9
Übersicht
1. Grundlagen
2. Syntax
3. Unifikation
4. Semantik
5. Eingebaute Konstrukte
10
Konstanten
Bezeichner
• alphanumerische Zeichenfolgen beginnend mit einem
Kleinbuchstaben
[z.B. paul]
• Zeichenfolgen in Hochkommas
• Tokens
[z.B. ‘Paul’]
[z.B. []]
Zahlen
• Ganzzahlen
[z.B. -12345]
☞ Das interne Format von Ganzzahlen ist exakt.
• Gleitkommazahlen
[z.B. 1.234e+5]
11
Variablen
Variablennamen beginnen mit einem Großbuchstaben oder
mit “ ”.
[z.B. Paul, paul und ]
Nach jedem “.” beginnt ein neuer Geltungsbereich.
Innerhalb eines Geltungsbereichs bezeichnen alle Vorkommen
einer Variablen dasselbe Objekt. Die einzige Ausnahme ist .
☞ Jedes Vorkommen von bezeichnet ein eigenes Objekt.
Variablen, deren Namen mit “ ” beginnen, sind anonym.
☞ Warnungen des Prolog-Interpreters werden unterdrückt.
12
Terme
Terme seien induktiv wie folgt definiert:
• Jede Konstante ist ein Term.
[z.B. paul]
• Jede Variable ist ein Term.
[z.B. Paul]
• Wenn t1 , . . . , tn Terme sind und f ein Bezeichner ist, dann
ist f (t1 , . . . , tn ) ein Term.
[z.B. f(paul,f(Paul))]
Für einen Term T = f (t1 , . . . , tn ) sind f /n der Funktor von T
und t1 , . . . , tn die Argumente von T .
☞ Die Funktoren f /0, f /1, f /2, . . . sind paarweise verschieden.
13
Atome
Sei p ein Bezeichner und t1 , . . . , tn Terme.
Der Term p(t1 , . . . , tn ) ist ein Atom des Prädikats p/n.
[z.B. vater(paul,maria)]
☞ Im Gegensatz zu (beliebigen) Termen können Atome
als wahr bzw. falsch interpretiert werden.
14
(Definite) Programme
Seien A, A1 , . . . , An Atome. Dann ist ein Ausdruck der Form
• “A.” ein Fakt.
[z.B. vater(paul,maria).]
• “A :- A1 , . . . ,An .” eine Regel.
[z.B. grossvater(X,Y) :- vater(X,Z), elternteil(Z,Y).]
• “?- A1 , . . . ,An .” eine Anfrage bzw. ein Ziel.
[z.B. ?- grossvater(steffen,X).]
Fakten und Regeln sind (definite) Klauseln.
In einer Klausel ist A der Kopf und A1 , . . . ,An der Körper.
Ein (definites) Programm ist eine Sequenz definiter Klauseln.
☞ Prolog-Programme dürfen auch Ziele enthalten, eingeleitet
durch “:-”. Diese Ziele werden beim Laden ausgewertet.
15
Kommentare
% Dies ist ein Kommentar bis zum Zeilenende.
/*
Dies ist ein
mehrzeiliger Kommentar.
*/
Empfehlung
• Um die Nachvollziehbarkeit eines Programms zu
gewährleisten, sollten Klauseln mit demselben
Prädikat im Kopf direkt aufeinander folgen.
• Die Bedeutung eines jeden Prädikats sollte vor den
Klauseln mit dem Prädikat im Kopf “angemessen” in
Kommentaren beschrieben werden.
16
Übersicht
1. Grundlagen
2. Syntax
3. Unifikation
4. Semantik
5. Eingebaute Konstrukte
17
Substitutionen
Eine Substitution σ ist eine endliche Menge der Form
{V1 = t1 , . . . , Vn = tn }, wobei V1 , . . . , Vn paarweise verschiedene
Variablen und t1 , . . . , tn Terme sind.
Das Ergebnis T σ der Anwendung einer Substitution σ auf
einen Term T ist der Term, der entsteht, wenn für 1 ≤ i ≤ n
jedes Vorkommen einer Variablen Vi in T durch ti ersetzt wird.
T
σ
Tσ
f(X,g(X))
{X = a}
f(a,g(a))
f(X,Y,Z)
{X = Y, Y = g(a)}
f(Y,g(a),Z)
f(g(X),Y,Z)
{X = g(Y), Z = g(Z)}
f(g(g(Y)),Y,g(Z))
18
Unifikatoren
Eine Substitution σ ist ein Unifikator für zwei Terme T1 und
T2 , wenn die Anwendung von σ auf T1 und T2 denselben Term
ergibt, d.h. wenn T1 σ und T2 σ identisch sind.
Zwei Terme sind unifizierbar , wenn es einen Unifikator für sie
gibt.
T1
T2
unifizierbar
σ
zeit(13,30)
zeit(13,X)
ja
{X = 30}
zeit(14,30)
zeit(13,X)
nein
—
zeit(13,30)
zeit(13,30,5)
nein
—
zeit(X,30,5)
zeit(Y,Z,5)
ja
{X = Y, Z = 30}
p(f(X,a),f(a,X))
p(Y,f(a,b))
ja
{X = b, Y = f(b,a)}
X
f(X)
nein
—
19
Varianten und Instanzen
Ein Term T1 ist eine Instanz eines Terms T2 , wenn es eine
Substitution σ gibt, sodass T1 und T2 σ identisch sind.
[z.B. T1 = f(X,X) und T2 = f(Y,Z)]
Zwei Terme T1 und T2 sind Varianten voneinander,
wenn T1 eine Instanz von T2 ist und T2 eine Instanz von T1 .
☞ Bis auf Variablennamen sind T1 und T2 identisch.
[z.B. T1 = f(W,X) und T2 = f(Y,Z),
nicht aber T1 = f(X,X) und T2 = f(Y,Z)]
☞ Eine Variante ist eine Instanz, nicht aber umgekehrt.
20
Allgemeinste Unifikatoren
Ein Unifikator σ1 für zwei Terme T1 und T2 ist ein
allgemeinster Unifikator für T1 und T2 , wenn für jeden
Unifikator σ2 für T1 und T2 gilt, dass T1 σ2 (bzw. T2 σ2 ) eine
Instanz von T1 σ1 (bzw. T2 σ1 ) ist.
[z.B. für T1 = f(W,X) und T2 = f(Y,Z): σ1 = {W = Y, Z = X}
nicht aber: σ2 = {W = a, Y = a, Z = X}, σ3 = {W = Y, X = Y, Z = Y}]
Ein Unifikationsproblem U ist eine Menge von Gleichungen
{t1 = t′1 , . . . , tn = t′n }, wobei t1 , t′1 , . . . , tn , t′n Terme sind.
Für ein Unifikationsproblem U (bzw. eine Substitution σ1 )
bezeichne Uσ2 (bzw. σ1 σ2 ) das Ergebnis der Anwendung einer
Substitution σ2 auf jeden Term in U (bzw. in σ1 ).
21
Berechnung eines Allgemeinsten Unifikators
Eingabe: Zwei Terme T1 und T2 .
Ausgabe: Ein allgemeinster Unifikator σ für T1 und T2 oder “Nein”,
wenn T1 und T2 nicht unifizierbar sind.
1. Setze U := {T1 = T2 } und σ := ∅.
2. Solange U nicht leer ist, wiederhole:
(a) Für eine beliebige Gleichung t = t′ in U, setze U := U \ {t = t′ }.
(b) Unterscheide die folgenden Fälle:
i. Wenn t und t′ identisch sind, dann tue nichts; sonst
ii. Wenn t eine Variable und t′ ein Term ist, sodass t in t′ nicht
vorkommt, setze U := U{t = t′ } und σ := σ{t = t′ } ∪ {t = t′ }; sonst
iii. Wenn t′ eine Variable und t ein Term ist, sodass t′ in t nicht
vorkommt, setze U := U{t′ = t} und σ := σ{t′ = t} ∪ {t′ = t}; sonst
iv. Wenn t = t′ von der Form f (t1 , . . . , tn ) = f (t′1 , . . . , t′n ) ist, setze
U := U ∪ {t1 = t′1 , . . . , tn = t′n }; sonst
v. Gebe “Nein” zurück.
% Fälle i–iv nicht anwendbar
3. Gebe σ zurück.
22
Beispiel
Eingabe: T1 = f(W,g(W,X,Y),Y,b) und T2 = f(a,Z,Y,X)
t = t′
U
σ
—
{f(W,g(W,X,Y),Y,b) = f(a,Z,Y,X)}
∅
f(W,g(W,X,Y),Y,b) = f(a,Z,Y,X) {W = a, g(W,X,Y) = Z, Y = Y, b = X}
∅
W=a
{g(a,X,Y) = Z, Y = Y, b = X}
{W = a}
g(a,X,Y) = Z
{Y = Y, b = X}
{Z = g(a,X,Y), W = a}
Y=Y
{b = X}
{Z = g(a,X,Y), W = a}
b=X
∅
{X = b, Z = g(a,b,Y), W = a}
Ausgabe: σ = {X = b, Z = g(a,b,Y), W = a}
23
Übersicht
1. Grundlagen
2. Syntax
3. Unifikation
4. Semantik
5. Eingebaute Konstrukte
24
Deklarative Semantik
Sei WB eine Wissensbasis.
☞ In jedem Fakt und jeder Regel von WB sind die
vorkommenden Variablen per Konvention allquantifiziert.
Annahme: Alle Fakten und Regeln in WB sind korrekt.
Alle Fakten in WB sind logische Konsequenzen von WB . ✔
Eine Regel der Form “A :- A1 , . . . ,An .” entspricht der
Implikation A1 ∧ · · · ∧ An → A.
Falls für eine Regel in WB und eine Substitution σ die Atome
A1 σ, . . . , An σ logische Konsequenzen von WB sind, dann ist
auch Aσ eine logische Konsequenz von WB . ✔
☞ Die deklarative Semantik von WB ist die Menge der
logischen Konsequenzen von WB .
25
Prozedurale Semantik
Für ein Ziel der Form “?- A1 , . . . ,An .” sucht der
Prolog-Interpreter nach einer Ableitung für A1 , . . . , An .
Dabei werden Atome des Ziels durch Körper von Regeln
ersetzt (Fakt ≡ Regel mit leerem Körper), mit deren Köpfen
sie unifizierbar sind, bis das Ziel leer ist.
Zusammen mit einer (erfolgreichen) Ableitung wird eine
Antwortsubstitution σ berechnet.
☞ Wird eine erfolgreiche Ableitung gefunden, so sind
A1 σ, . . . , An σ logische Konsequenzen der Wissensbasis WB . ✔
☞ Für jede logische Konsequenz von WB existiert eine
erfolgreiche Ableitung. ✔
☞ Erfolgreiche Ableitungen werden nicht immer gefunden. ✘
26
Beweisprozedur
Sei WB eine Wissensbasis, “?- G1 , . . . ,Gm .” ein (initiales) Ziel, Vars die
Menge aller Variablen in G1 , . . . , Gm und σ = ∅.
Prozedur Beweise(Ziel “?- G1 ,G2 , . . . ,Gm .”, Antwortsubstitution σ)
1. Falls m = 0, gebe σ aus; sonst
2. Beginne am Anfang von WB und wiederhole:
(a) Finde den nächsten Fakt “A.” oder die nächste Regel
“A :- A1 , . . . ,An .” in WB, sodass eine Variante A′ von A mit G1
unifizierbar ist. Breche ab, falls das Ende von WB erreicht wird.
(b) Falls ein Fakt bzw. eine Regel gefunden wurde:
i. Bilde eine Variante “A′ .” bzw. “A′ :- A′1 , . . . ,A′n .”, die keine
Variablen aus “?- G1 ,G2 , . . . ,Gm .”, Vars oder σ enthält.
ii. Bestimme einen allgemeinsten Unifikator σ ′ für G1 und A′ und
setze σ := σσ ′ ∪ {(V = t) ∈ σ ′ | V ∈ Vars}.
iii. Für einen Fakt “A′ .” führe
Beweise(“?- G2 σ ′ , . . . ,Gm σ ′ .”, σ)
aus bzw. für eine Regel “A′ :- A′1 , . . . ,A′n .”
Beweise(“?- A′1 σ ′ , . . . ,A′n σ ′ ,G2 σ ′ , . . . ,Gm σ ′ .”, σ).
27
Beispiel
WB :
p(a).
p(b) :- q(b).
p(X) :- q(X).
q(f(X)).
p(X1 ) :- q(X1 ).
p(a).
?- p(X).
@ {X = X}
@ {X = a}
@ 1
@
R
@
R
@
q(f(X2 )).
?- q(X).
?- .
J
J {X = f(X )} p(b) :- q(b).
2
J
HH
JJ
^
HH {X = b} ?- .
HH
j
?- q(b).
28
Backtracking
Die Fakten und Regeln einer Wissensbasis sowie die Atome
innerhalb von Zielen sind geordnet.
Bei der Suche nach erfolgreichen Ableitungen folgt Prolog
einer Tiefensuchstrategie, bei der
• das am weitestenden links stehende Teilziel zuerst
abgearbeitet wird;
• anwendbare Fakten bzw. Regeln von oben nach unten
ausprobiert werden.
Die Suche nach alternativer Fakten bzw. Regeln nach einer
fehlgeschlagenen Ableitung heißt Backtracking.
Für den zuletzt angewendeten Fakt bzw. die zuletzt
angewendete Regel wird zuerst nach Alternativen gesucht.
29
Besonderheiten der Prozeduralen Semantik
Die Ableitungsstrategie von Prolog ist unvollständig, d.h.
erfolgreiche Ableitungen werden, selbst wenn sie existieren,
nicht unbedingt gefunden.
[z.B. WB :
p :- p.
p.]
☞ Die Fakten und Regeln eines Prolog-Programms müssen
“richtig” sortiert sein.
Bei der Abarbeitung von Teilzielen können Seiteneffekte (z.B.
Ein- und Ausgabe) auftreten.
☞ Ein Teilziel muss mit den “richtigen” Argumenten
abgeleitet werden.
In Dokumentationen und Kommentaren findet man oft die
folgenden Angaben für Argumente X:
+X
-X
?X
Eingabevariable (instanziiert)
Ausgabevariable (uninstanziiert)
Ein-/Ausgabevariable
30
Complete Knowledge Assumption
Definite Programme enthalten Fakten und Implikationen.
☞ Das explizite Wissen ist positiv (Was gilt?).
Es gibt keine Möglichkeit der expliziten Repräsentation von
negativem Wissen (Was gilt nicht?). ✘
Wie kann negatives Wissen (implizit) repräsentiert werden?
Annahme: Die Wissensbasis enthält vollständige Information.
Alles, was keine logische Konsequenz ist, ist falsch. ✔
31
Negation als (endlicher) Fehlschlag
Die Ableitung eines negativen Ziels “?- not(G).”
(synonym “?- \+ G.”) ist genau dann erfolgreich, wenn alle
Ableitungen für “?- G.” endlich fehlschlagen.
[z.B. ist “?- not(q).” erfolgreich für WB :
p.
nicht aber für WB :
q :- q.]
☞ Die Einbettung von negativen Teilzielen not(Gi ) in Zielen
“?- G1 , . . . ,not(Gi ), . . . ,Gn .” ist möglich.
Problem: “floundering”
[“?- p(X), not(q(X)).” ist ableitbar für WB : p(a). q(b).
“?- not(q(X)), p(X).” schlägt dagegen fehl.]
☞ Uninstanziierte Variablen in negativen Teilzielen sollten,
wann immer möglich, vermieden werden.
32
Debugging
Die Ableitungsstrategie von Prolog ist festgelegt.
☞ Wenn Anfragen falsch beantwortet werden, dann ist die
Wissensbasis fehlerhaft.
Prolog-Interpreter besitzen einen eingebauten Debugger.
“trace.” schaltet den Debugger ein.
“notrace.” schaltet den Debugger aus.
“spy(p/n).” führt zum Einschalten des Debuggers, wenn ein
Teilziel des Prädikats p/n abgeleitet wird.
“nospy(p/n).” deaktiviert das Einschalten des Debuggers für
Teilziele des Prädikats p/n.
33
Eine Debugging-Session (1)
[gebser@re ~]$ pl
Welcome to SWI-Prolog (Multi-threaded, Version 5.2.13)
Copyright (c) 1990-2003 University of Amsterdam.
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
Please visit http://www.swi-prolog.org for details.
For help, use ?- help(Topic). or ?- apropos(Word).
?- [vorfahre].
% vorfahre compiled 0.00 sec, 2,148 bytes
Yes
?- spy(vater/2).
% Spy point on vater/2
Yes
[debug] ?- trace.
Yes
34
Eine Debugging-Session (2)
[trace] ?- grossvater(steffen,X).
Call: (6) grossvater(steffen, G278) ? leap
Call: (7) vater(steffen, G332) ? creep
Exit: (7) vater(steffen, paul) ? leap
Call: (8) vater(paul, G278) ? creep
Exit: (8) vater(paul, maria) ? creep
Exit: (7) elternteil(paul, maria) ? creep
Exit: (6) grossvater(steffen, maria) ? creep
X = maria ;
Redo: (8) vater(paul, G278) ? creep
Exit: (8) vater(paul, lena) ? leap
X = lena ;
Fail: (8) vater(paul, G278) ? creep
Redo: (7) elternteil(paul, G278) ? leap
Fail: (7) vater(steffen, G332) ? creep
Fail: (6) grossvater(steffen, G278) ? creep
No
35
Eine Debugging-Session (3)
[debug] ?- notrace.
Yes
[debug] ?- nospy(vater/2).
% Spy point removed from vater/2
Yes
[debug] ?- halt.
[gebser@re ~]$
36
Übersicht
1. Grundlagen
2. Syntax
3. Unifikation
4. Semantik
5. Eingebaute Konstrukte
37
Listen
Listen sind Terme, die wie folgt dargestellt werden:
• Erstes Element + Rest einer Liste: [X | L]
• Mehrere Elemente + Rest einer Liste: [X1 ,. . . ,Xn | L]
• Leere Liste & Ende von Listen: []
• Traditioneller Funktor: ./2
[.(X,L) = [X | L]]
Die folgenden (Listen-)Terme sind identisch:
• [a] = [a | []] = .(a,[])
• [1,2,3] = [1 | [2,3]] = [1,2 | [3]] = [1,2,3 | []]
• .(.(a,[]),.(.(b,[]),[])) = [[a],[b]]
38
Einige Listenoperationen
Durchlaufen einer Liste:
durchlaufe([]).
durchlaufe([ | L]) :- durchlaufe(L).
Finden eines Elements (eingebaut als member/2):
element(X,[X | ]).
element(X,[ | L]) :- element(X,L).
Verketten von zwei Listen (eingebaut als append/3):
verkette([],L,L).
verkette([X | L1],L2,[X | L]) :- verkette(L1,L2,L).
☞ Es gibt weitere eingebaute Listenoperationen (z.B. flatten/3).
39
Vergleichen/Unifizieren von Termen
=/2 unifiziert zwei Terme, wenn es möglich ist.
[?- f(X) = f(Y).
X = 123
Y = 123]
\=/2 ist erfolgreich, wenn zwei Terme nicht unifizierbar sind.
[?- f(X) \= g(Y).
X = 123
Y = 321]
==/2 ist erfolgreich, wenn zwei Terme identisch sind.
[?- X == X.
?- X == Y.
X = 123,
No]
\==/2 ist erfolgreich, wenn zwei Terme nicht identisch sind.
[?- X \== Y.
40
X = 123
Y = 321]
Arithmetik
Die Anfrage “?- X = 1+2.” ergibt:
X = 1+2.
☞ Arithmetik muss explizit angestoßen werden.
☞ In arithmetischen Ausdrücken dürfen keine uninstanziierten
Variablen vorkommen.
“?X is +Y” unifiziert das Ergebnis von Y mit X.
Anfrage
Antwort
?- X is 1+2.
X=3
?- 3 is 1+2.
Yes
?- 2+1 is 1+2.
No
?- 3 is 1+X.
ERROR
41
Einige Arithmetische Operatoren
+
Addition
-
Subtraktion
*
Multiplikation
/
Division
>
“größer”-Relation
<
“kleiner”-Relation
>=
“größer-gleich”-Relation
=<
“kleiner-gleich”-Relation
=:= Arithmetische Gleichheit
=\= Arithmetische Ungleichheit
42
Der Cut
Der Cut “!” ist ein spezielles Teilziel zur Manipulation der
prozeduralen Semantik von Regeln und Zielen.
Durch das Setzen von Cuts wird Backtracking unterdrückt.
Der Zweck ist Effizienzgewinn bei der Ableitung von Zielen.
43
Wirkungsweise eines Cut
Eine Regel habe die Form: “A :- A1 ,. . . ,Ai ,!,Ai+1 ,. . . ,An .”
Ausgangssituation:
• Bei der Ableitung eines Ziels A′ wurde die Regel angewendet.
• Die Teilziele A1 , . . . , Ai wurden erfolgreich abgeleitet.
• Die Ableitung von ! ist (immer) erfolgreich.
• Die Ableitung der Teilziele Ai+1 , . . . , An scheitert.
Effekt von !:
• Beim Backtracking wird nicht nach alternativen Ableitungen für
A1 , . . . , Ai gesucht.
• Es werden keine alternativen Fakten bzw. Regeln für A′
angewendet, selbst wenn die Wissensbasis Alternativen enthält.
☞ Die Ableitung des Ziels A′ schlägt fehl.
44
Verwendung von Cuts
Die folgenden Prädikate definieren jeweils das Maximum
zweier Zahlen:
max(X,Y,X) :- X >= Y.
max(X,Y,Y) :- X < Y.
max g(X,Y,X) :- X >= Y, !.
max g(X,Y,Y) :- X < Y.
max r1(X,Y,X) :- X >= Y, !.
max r1(X,Y,Y).
max r2(X,Y,Z) :- X >= Y, !, Z = X.
max r2(X,Y,Y).
Der Cut in max g/3 ist grün: Er verändert die deklarative
Semantik nicht.
Die Cuts in max r1/3 und max r2/3 sind rot: Deklarativ gelten
max r1(X,Y,Y) und max r2(X,Y,Y) für alle Instanzen von X und Y.
In max r2/3 wird die Ausgabeunifikation verzögert.
[Vergleiche: “?- max r1(2,1,1).” und “?- max r2(2,1,1).”]
45
Berechnung aller Antworten
Für ein Ziel G können wahlweise mit bagof(?T,+G,?L),
findall(?T,+G,?L) oder setof(?T,+G,?L) alle Instanzen eines
Terms T berechnet werden, für die G ableitbar ist.
?- bagof(X, member(X,[2,1,3,1,3,2]), L).
L = [2,1,3,1,3,2]
?- findall(X, member(X,[2,1,3,1,3,2]), L).
L = [2,1,3,1,3,2]
?- setof(X, member(X,[2,1,3,1,3,2]), L).
?- bagof(X, member(X,[]), L).
?- findall(X, member(X,[]), L).
?- setof(X, member(X,[]), L).
46
L = [1,2,3]
No
L = []
No
Konstanten
Die Ableitung des Teilziels true ist immer erfolgreich.
A :- A1 ,. . . ,Ai ,true,Ai+1 ,. . . ,An .
m
A :- A1 ,. . . ,Ai ,Ai+1 ,. . . ,An .
Die Ableitung des Teilziels fail schlägt immer fehl.
A :- A1 ,. . . ,Ai ,fail,Ai+1 ,. . . ,An .
m
A :- A1 ,. . . ,Ai ,fail.
Zwecke der Verwendung von fail: Unifikation verhindern,
“Mitnahme” von Seiteneffekten
Besonders “effektive” Kombination: !,fail
47
Der Oder-Operator
Syntax: (Ziel1 ; Ziel2)
Semantik:
A :- A1 , . . . ,Ai−1 ,((Ai , . . . ,Aj ) ; (Aj+1 , . . . ,Ak )),Ak+1 , . . . ,An .
m
A :- A1 , . . . ,Ai−1 ,Ai , . . . ,Aj ,Ak+1 , . . . ,An .
A :- A1 , . . . ,Ai−1 ,Aj+1 , . . . ,Ak ,Ak+1 , . . . ,An .
Beispiel: elternteil(X,Y) :- vater(X,Y) ; mutter(X,Y).
48
Der If-Then-Else-Operator
Syntax: (Bedingung -> Ziel1 ; Ziel2)
Semantik:
A :- A1 , . . . ,Ai−1 ,
((Ai , . . . ,Aj ) -> (Aj+1 , . . . ,Ak ) ; (Ak+1 , . . . ,Al )),
Al+1 , . . . ,An .
m
A :- A1 , . . . ,Ai−1 ,Ai , . . . ,Aj ,!,Aj+1 , . . . ,Ak ,Al+1 , . . . ,An .
A :- A1 , . . . ,Ai−1 ,Ak+1 , . . . ,Al ,Al+1 , . . . ,An .
Beispiel: max(X,Y,Z) :- ((X >= Y) -> (Z = X) ; (Z = Y)).
49
Definieren eigener Operatoren
Benutzereigene Operatoren werden dem Prolog-Interpreter
durch “:- op(+Präzedenz, +Typ, +Name).” bekannt gemacht
und können dann als (spezielle) Funktoren verwendet werden.
Eigene Operatoren werden üblicherweise am Anfang eines
Prolog-Programms bekannt gemacht durch ein Ziel, das beim
Laden ausgeführt wird.
Die Präzendenz ist eine Zahl, die die Bindungskraft des
Operators bestimmt.
Der Typ bestimmt die Art der Benutzung und die
Assoziativität des Operators.
Der Name des Operators ist ein Bezeichner.
50
Typen von Operatoren
Typ
Bedeutung
fx
Präfixoperator, nicht assoziativ
fy
Präfixoperator, rechtsassoziativ
xf
Postfixoperator, nicht assoziativ
yf
Postfixoperator, linksassoziativ
xfx
Infixoperator, nicht assoziativ
xfy
Infixoperator, rechtsassoziativ
yfx
Infixoperator, linksassoziativ
:- op(400, xfx, ist vater von).
steffen ist vater von paul.
?- X ist vater von paul.
51
X = steffen
Analyse und Synthese von Termen
Mit functor(?Term,?Functor,?Arity), arg(?N,+Term,?Argument)
und “?Term =.. ?List” können Terme analysiert bzw.
konstruiert werden.
?- functor(f(1,2),f,2).
Yes
?- functor(f(1,2),F,A).
F = f, A = 2
?- functor(T,f,3).
T = f( 123, 124, 125)
?- functor(T,.,2).
T = [ 123 | 124]
?- functor(f(1,2),f,3).
No
?- arg(2,.(a,b,c),b).
Yes
?- arg(2,f(a,f(a,b)),f(X,Y)).
X = a, Y = b
?- T =.. [vater,steffen,paul].
?- f([1,2,3],X) =.. L.
T = vater(steffen,paul)
X = 123, L = [f,[1,2,3], 123]
52
Den Typ von Termen ermitteln
?- number(X).
Ist X eine Zahl?
?- integer(X).
Ist X eine ganze Zahl?
?- float(X).
Ist X eine Gleitkommazahl?
?- atom(X).
Ist X ein Bezeichner?
?- atomic(X).
Ist X ein Bezeichner oder eine Zahl?
?- compound(X).
Ist X ist ein zusammengesetzter Term?
?- var(X).
Ist X eine uninstanziierte Variable?
?- nonvar(X).
Ist X keine uninstanziierte Variable?
53
Ein- und Ausgabe
Die folgenden Prädikate beziehen sich auf die
Standardeingabe bzw. die Standardausgabe.
Ähnliche Prädikate gibt es auch für Dateien usw.
put(+X)
schreibt ein ASCII-Zeichen X.
get(-X)
liest ein druckbares ASCII-Zeichen und unifiziert es mit X.
get0(-X)
liest ein ASCII-Zeichen und unifiziert es mit X.
nl
schreibt einen Zeilenvorschub.
write(+X) schreibt einen Term X.
read(-X)
liest einen Term und unifiziert ihn mit X.
☞ Eingabe- und Ausgabeprädikate werden beim
Backtracking übersprungen, d.h. nicht alternativ abgeleitet.
54
Ende
Viel Spaß mit Prolog ;-)
55