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