Terme und Formeln Terme und Unifikation

Werbung
– Regeln
sterblich(X) :- mensch(X).
vernetzt(X) :- verbunden(X,Y), vernetzt(Y).
– Anfragen
|?- sterblich(sokrates).
|?- bruder(jo, X).
...
G. Görz, FAU, Inf.8
12–1
G. Görz, FAU, Inf.8
Terme und Formeln
12–3
Terme und Unifikation
Ein etwas genauerer Blick auf die Sprachelemente von PROLOG:
Beispiel: Axiomatisierung der Addition mit Nachfolgerfunktion
• Terme
Variablen: X, . . .
Anonyme Variable:
Atome: tim, ’hello world’, . . .
Zahlen: 4711, 5.7E-3, . . .
Funktionsterme: f(X), g(h(blah, Y)), . . .
add(0,Y,Y).
add(succ(X),Y,succ(Z)) :- add(X,Y,Z).
Der atomare Term 0 repräsentiert die Zahl 0, der Term succ(0) die 1, etc.
• Formeln
– Fakten
mensch(adam).
liebt(X, eva).
geburtstag(jo, datum(11,november,1980)).
G. Görz, FAU, Inf.8
...
succ ist ein uninterpretiertes Funktionssymbol;
Term succ(0) kann nicht zu dem Term 1 ausgewertet (reduziert) werden.
Die einzige Beziehung zwischen diesen Termen und den Zahlen ist die
Bedeutungsrelation, die der Programmierer “zuschreibt”.
...
12–2
G. Görz, FAU, Inf.8
12–4
Beispielanfragen:
Dieses Ziel ist mit der Einheitsklausel add(0,Y,Y) unifizierbar mit der
Substitution Y 2 = succ(succ(0)), Z 1 = Y 2
?- add(0,succ(0), Result).
Antwort:
Result = succ(0)
yes
und die Ausführung terminiert erfolgreich. Somit:
Result =
=
=
=
?- add(succ(succ(0)),succ(succ(0)),Result).
Result = succ(succ(succ(succ(0))))
yes
succ(Z)
succ(succ(Z_1))
succ(succ(Y_2))
succ(succ(succ(succ(0))))
Ausführung für zweites Beispiel:
Unifikation der Anfrage mit add(succ(X),Y,succ(Z)) ist erfolgreich mit
X = succ(0), Y = succ(succ(0)), Result = succ(Z)
und transformiert beide Formeln in
add(succ(succ(0)),succ(succ(0)),succ(Z)).
Anmerkung : Die in Prolog benutzte Variante der Resolutionsregel
(spezielle Strategie) heisst SLD-Resolution: “Linear resolution for
Definite clauses with Selection function”.
G. Görz, FAU, Inf.8
G. Görz, FAU, Inf.8
12–5
12–7
Unifikation und der “Occurs Check”
succ-Beispiel (Forts.)
Schrittweise:
Wenn eine Variable X mit einem Term T unifiziert werden soll, ist für das
Gelingen der Unifikation entscheidend, dass X nicht in T vorkommt.
Das ursprüngliche Ziel kann nicht mit der ersten, aber mit der zweiten
Klausel unter der genannten Substitution unifiziert werden.
Normalerweise wird in PROLOG dieser Test, der “Occurs Check”, aus
Effizienzgründen weggelassen. Damit: Keine volle Unifikation!
Damit wird der Rumpf der zweiten Klausel zu
add(succ(0),succ(succ(0)),Z).
Beispiel: Der Matcher erlaubt eine Passung von f(X,X) mit f(Y,g(Y))
und bindet X an g(X), ohne die Zirkularität zu bemerken.
Diese kann wiederum mit dem Kopf der zweiten Klausel im Programm
unifiziert werden und ergibt (mit Variablenumbenennung) die Substitution
X 1 = 0, Y 1 = succ(succ(0)), Z = succ(Z 1)
In den meisten PROLOG-Systemen kann der Occurs Check über ein Flag
eingeschaltet und damit die volle Unifikation ermöglicht werden —
allerdings um den Preis einer beträchtlichen Verlangsamung der
Berechnung (Rekursiver Abstieg in Termen!).
Eingesetzt in den Prozedurrumpf: add(0,succ(succ(0)),Z 1).
G. Görz, FAU, Inf.8
12–6
G. Görz, FAU, Inf.8
12–8
Beispiel: Die dreistellige Relation add entspricht einer Axiomatisierung der
Addition durch die Funktion + in einer Logik mit Gleichheit:
Funktionen in PROLOG
Verfügt man über einen Logikkalkül mit Gleichheit zwischen Termen als
Grundbegriff, wird durch die Reduzierbarkeit von Termen auf andere eine
leistungsfähige Technik verfügbar, um Schlüsse über Funktionen
durchzuführen.
Im Logikkalkül wären Gleichheitsaxiome erforderlich, um Beweisprozeduren
für die Gleichheit als Grundlage für funktionale Berechnung nutzen zu
können (analog zu Hornklausel-Beweisprozeduren als Grundlage für
relationale Berechnung).
0 + x = x
succ(x) + y = succ(x + y)
Aber: Von den Gleichheitsaxiomen bleibt (aus Effizienzgründen) in
PROLOG nur die Reflexivität X = X (Standard-Infixoperator).
Konsequenz: Es ist nicht möglich, zu schließen, ob zwei Terme dasselbe
Objekt bezeichnen!
Terme wie f(a) können nicht ausgewertet werden!
Problem: Allgemeine Beweisprozeduren für Logik mit Gleichheit sind nicht
effizient genug für Logikprogrammiersysteme (Kontrollproblem).
Versuch: Repräsentation durch Relationen?
G. Görz, FAU, Inf.8
12–9
G. Görz, FAU, Inf.8
Repräsentation von Funktionen durch Relationen
Die PROLOG-Sicht von Funktionen
Funktionen sind Konstruktoren:
Jeder variablenfreie Term wird als Bezeichnung eines Elements in der
Domäne angesehen. Funktionssymbole dienen zur (notationellen)
Konstruktion neuer Elemente aus gegebenen. (Analogie: cons in Scheme)
Die Beobachtung, dass Funktionen in einer Domäne durch Relationen
repräsentiert werden können, war ein entscheidender Schritt, die
Logikprogrammierung praktikabel zu machen.
Nachteile:
1. Verlust der Eindeutigkeit von Funktionswerten!
In bestimmten Fällen, wenn die relationale Definition einer Funktion nur
ein Ergebnis für jede Eingabe liefert (add), kann Eindeutigkeit erreicht
werden — nur kontingente Eigenschaft.
2. Relationale Syntax erfordert Einführung von Hilfsvariablen
(erschwerte Lesbarkeit).
G. Görz, FAU, Inf.8
12–11
Zusammengesetzte Terme spielen in PROLOG die Rolle von
Record-Strukturen (einzige Datenstrukturen in PROLOG!).
Die Unifikation spielt damit eine doppelte Rolle:
1. Selektion durch Auswahl/ Aufnahme der Argumente von Funktionen;
2. Konstruktion durch Instantiierung von Variablen mit komplexen Termen.
Terme mit Variablen stehen für partiell spezifizierte Datenstrukturen
(Variable als Platzhalter).
12–10
G. Görz, FAU, Inf.8
12–12
Zur Arithmetik in PROLOG
Rekursion und Iteration
Prolog sieht für arithmetische Terme Infix-Notation vor.
Rekursion am Beispiel der Fakultätsfunktion:
Funktionen: N+N , N-N , -N , N*N , N/N , I//I , I rem I ,
I mod I sowie bitweise Operationen
Relationen: =:= , =\= , < , =< , > , >=
fac(0,1).
fac(N,V) :N > 0,
N1 is N-1,
fac(N1,V1),
V is N*V1.
Das is/2-Prädikat (/-Notation: Stelligkeit) ist als arithmetische Funktion
registriert und erzwingt Auswertung arithmetischer Ausdrücke rechts, z.B.
X is 4*2 .
Arithmetische Relationen erzwingen die Auswertung arithmetischer
Ausdrücke auf beiden Seiten.
G. Görz, FAU, Inf.8
[debug]
T Call:
T Call:
T Call:
12–13
Operatoren
Funktionsterme können in Präfix-, Infix- und Postfix-Notation geschrieben
werden.
Festzulegen: Vorrang und Assoziativität der Operatoren
Priorität
500
400
200
200
Assoziativität
yfx
yfx
xfy
fy
Ein Trace:
Operator
+ * /
**
-
?- fact(3,X).
(8) fact(3, _G360)
(9) fact(2, _G363)
(10) fact(1, _G366)
G. Görz, FAU, Inf.8
T
T
T
T
T
Call:
Exit:
Exit:
Exit:
Exit:
X = 6
12–15
(11) fact(0, _G369)
(11) fact(0, 1)
(10) fact(1, 1)
(9) fact(2, 2)
(8) fact(3, 6)
Iterative Variante (Endrekursion! Analog auch für Baumrekursion)
fac_it(N,V) :- fac_it(N, 1, V).
fac_it(0,V,V).
fac_it(N,V0,V) :N > 0,
V1 is V0*N,
N1 is N-1,
fac_it(N1,V1,V).
Benutzerdefinierte Operatoren:
Die Direktive op definiert/modifiziert Operator mit Namen Atom
:- op(Prio, Assoc, Atom).
G. Görz, FAU, Inf.8
12–14
G. Görz, FAU, Inf.8
12–16
Gleichheitsprädikate
Differenzlisten
• = Unifikationsprädikat (Vergleich von Termen)
Erfolg, wenn es seine Argumente unifizieren kann, sonst Scheitern
In manchen Fällen ist es zweckmäßig, die Darstellung durch Differenzlisten
zu verwenden: Sie werden konstruiert durch ein Paar von Listenstrukturen,
in denen die eine ein Suffix der anderen ist.
• \= Negation des Unifikationsprädikats
• Jede Liste in ein suffix von sich selbst.
• == Identitätsprädikat
• Ist die Liste von der Form [Head|Tail], so ist jeder Suffix von Tail
ein Suffix der ganzen Liste.
• \== Negation des Identitätsprädikats
• =:= Arithmetisches Gleichheitsprädikat
Erfolg, wenn seine Argumente zur selben Zahl evaluieren, sonst
Scheitern
D.h., die Beziehung zwischen Listen und ihren Suffixen ist die reflexive
transitive Hülle der Relation zwischen der Liste und ihren Resten.
Konstruktion von Differenzlisten mit dem Infix-Operator “-”:
Eine Differenzliste List-Suffix stellt die Folge der Elemente in List bis
auf jene in Suffix dar.
• =\= Arithmetisches Ungleichheitsprädikat
G. Görz, FAU, Inf.8
12–17
G. Görz, FAU, Inf.8
12–19
Beispiel:
Die Liste [1,2,3] kann durch folgende Differenzlisten dargestellt werden:
[1,2,3,4]-[4], [1,2,3]-[], [1,2,3|X]-X, etc.
Darstellung von Listen in PROLOG
Der Listenkonstruktor: “.” (=
ˆ cons). Listen sind PROLOG-Terme!
Konkatenation wird durch Differenzlisten einfach:
conc dl(Front-Back1, Back1-Back2, Front-Back2)
[] leere Liste
[X|Y] Liste mit Kopf X und Rest Y
Beispiele:
[Head|Tail]
[a,b|X] Liste mit Sequenz a,b, d.h. mit [a,b] als Kopf
Explizite Verwendung des Kontruktors im Beispiel:
.(a,.(b,[])) == [a,b].
PROLOG-Programm, das die induktive Definition von Listen wiedergibt:
list([]).
list([Head|Tail]) :- element(Head), list([Tail]).
G. Görz, FAU, Inf.8
12–18
G. Görz, FAU, Inf.8
12–20
Anwendung:
Beispiele für Rekursion über Listen
Generelle Spezifikation von Sortierung
Element-Relation
sort(Old,New) :- perm(Old,New), ordered(New).
member(X,[X|Xs]).
member(X,[Y|Ys]) :- member(X,Ys).
Old und New mögen Listen bezeichnen.
Trace
Wie kommt man von dieser hohen Abstraktionsebene zu einer konkreten
Spezifikation?
| ?- member(2,[1,2,3]). =>
| ?- member(X,[1,2,3]). =>
| ?- member(2,X).
=>
yes
X = 1; X = 2; X = 3
X = [2|_G822]; X = [_G821,2|_G824];...
Zusammenhängen zweier Listen
Notwendig: Definition der Prädikate perm und ordered.
Wünschenswert: Prozedurale Verzahnung der beiden Prädikate bei der
Ausführung.
append([],Ys,Ys).
append([X|Xs],Ys,[X|Zs]) :- append(Xs,Ys,Zs).
G. Görz, FAU, Inf.8
12–21
G. Görz, FAU, Inf.8
Berechnungen mit partiell definierten Objekten
12–23
Definition des Sortierprogramms
Unterbestimmte Werte werden durch ungebundene Variablen repräsentiert
(“unbound Variable” ist kein Fehler!)
Logik-orientierte Programmierung gestattet die Verarbeitung partieller
“Information”.
delete(X,[X|L],L).
delete(X,[Y|L],[Y|Z]) :- delete(X,L,Z).
Beispiel:
halb1(x) :- X = struct(3,_).
halb2(x) :- X = struct(_,5).
|
A
|
A
ordered([]).
ordered([X]).
ordered([X|[Y|L]]) :- X<Y, ordered([Y|L]).
?- halb1(A).
= struct(3,_G484)
?- halb1(A),halb2(A).
= struct(3,5)
G. Görz, FAU, Inf.8
perm([],[]).
perm(L,[X|Y]) :- delete(X,L,L2), perm(L2,Y).
Hinweis: Als Subjunktionen lesen!
12–22
G. Görz, FAU, Inf.8
12–24
Wegen des inhärenten Nichtdeterminismus können bei der Konstruktion
einer Permutation die Elemente der ursprünglichen Liste in beliebiger
Reihenfolge gelöscht werden. Welches Element gelöscht wird, hängt
jedesmal von der Auswahl einer der beiden delete-Klauseln ab.
Siehe folgende Abbildung:
• Nicht-logische Erweiterungen (⇒ Meta-Programmierung)
Erfüllt man z.B. die Bedingung delete(X,L,L2) durch Verwendung der
ersten Klausel, wird X an den Kopf und L2 an den Rest von L gebunden.
Bei Wahl der zweiten Klausel und danach der ersten würde das
ursprüngliche X an das zweite Element von L gebunden und L2 an den Rest
von L ohne das zweite Element.
G. Görz, FAU, Inf.8
Kontrollkonstrukte und andere Erweiterungen von
PROLOG
12–25
– Kontrollkonstrukte: true , fail , Cond -> Act : Else,
call(G) erzwingt Beweis von G
Cut (!) (s.u.) und weitere
– Negation-as-Failure (“not provable”):
\+ Goal :- call(Goal) -> fail; true.
– “All-Solutions”-Prädikate: setof(Term, Goal, S) u.a.
– Manipulation von Termen: var(X), atomic(X) u.a.,
Term =.. List. ⇒ “programs are data, also in PROLOG”
– Explizite Manipulation der Datenbasis: assert(T), retract(T)
G. Görz, FAU, Inf.8
12–27
• Damit Konstruktion von Meta-Interpretern, z.b. auch zur Einbettung
objekt-orientierter Programmierung
Sortierprogramm (2)
• Spracherweiterungen, z.B. um Modaloperatoren
• Constraint Logic Programming:
Kombination mit einem Constraint Solver zur Lösung von (Un-)
Gleichungssystemen
• Kombination mit anderen Programmierstilen (funktional,
objekt-orientiert) in neuen Programmiersprachen
G. Görz, FAU, Inf.8
12–26
G. Görz, FAU, Inf.8
12–28
Der Cut — Explizite Steuerung des Backtracking
“Rote Cuts”: Eine mangelhafte Programmiertechnik
Wenn Cuts verwendet werden, um explizite Bedingungen wegzulassen,
spricht man von “roten Cuts”.
Der Cut ! in einer allgemeinen Klausel
A ← B1, . . . , Bk , !, Bk+2 . . . , Bn
C
Wenn das aktuelle Ziel G mit dem Kopf von C unifiziert und B1, . . . , Bk
erfolgreich sind, hat der Cut folgenden Effekt:
Schlechtes Beispiel:
minimum(X,Y,X) :- X≤Y, !.
minimum(X,Y,Y).
• Das Programm ist festgelegt auf die Wahl von C zur Reduktion von G;
alternative Klauseln für A, die mit G unfizieren könnten, werden
ignoriert.
Was der Autor ausdrücken wollte: Wenn X ≤ Y, dann ist das Minimum X.
Andernfalls ist das Minimum Y und ein weiterer Vergleich zwischen X und
Y ist überflüssig.
• Falls Bi für i > k scheitert, geht Backtracking nur bis zum ! zurück.
Aber: Obiges Programm ist erfolgreich mit dem Ziel minimum(2,5,5)!
• Andere in der Berechnung von Bi, i ≤ k, verbleibende
Wahlmöglichkeiten werden aus dem Suchbaum eliminiert
(Löschung nutzloser Zweige).
Eine logisch korrekte Definition des minimum-Programms:
minimum(X,Y,X) :- X≤Y, !.
minimum(X,Y,X) :- X>Y, !.
G. Görz, FAU, Inf.8
12–29
G. Görz, FAU, Inf.8
12–31
• Falls Backtracking tatsächlich den Cut erreicht, scheitert der Cut und
die Suche wird fortgesetzt mit der letzten Auswahl, die getroffen wurde,
bevor G das C wählte.
Die “Closed World Assumption” und die Negation in
PROLOG
Cuts, die verwendet werden, um Determinismus auszudrücken — d.h., dass
für jedes anwendbare Ziel nur eine der Klauseln erfolgreich verwendet
werden kann, um es zu beweisen — heissen “grüne Cuts”.
PROLOG benutzt die Closed Word Assumption (CWA). Mit cut und
fail kann eine (eingeschränkte) Form der Negation definiert werden —
nicht die logische Negation, weil deren Axiomatisierung nicht-HORN ist:
⇒ Einsparung von Zeit und Speicherplatz.
not(P) :- call(P), !, fail.
not(P).
D.h.: Es wird ein Beweis von P erzwungen, auf den im Erfolgsfall eine
Cut-Fail-Kombination folgt, die scheitert. Andernfalls ist die zweite Klausel
erfolgreich.
G. Görz, FAU, Inf.8
12–30
G. Görz, FAU, Inf.8
12–32
Zur Negation
“Nicht-Vorkommen der Wahrheit einer Aussage” ist im allgemeinen nicht
dasselbe wie die Wahrheit der negierten Aussage.
Annahme, dass es verschiedene Wissensquellen für den Beweis und die
Zurückweisung einer Behauptung gibt — Inkonsistenzen in grossen
Datenbasen werden nicht ausgeschlossen, weil A+∧ A− kein
Widerspruch (aber möglicherweise eine Warnung!) und A+∨ A− keine
Tautologie ist.
Beispiele:
• Medizinische Diagnose
• Rechtsprechung: Freispruch — Unschuld vs. Mangel an Beweisen
• Telefonbuch: Nicht jeder, der einen Anschluss hat, ist aufgeführt.
Verschiedene Deutungen der “Negation” im Unterschied zur klassischen
Logik:
G. Görz, FAU, Inf.8
12–33
• CWA: Eine Datenbasis D möge ein Modell U beschreiben. Wenn ein
Fakt A nicht aus D folgt, wird ¬A als wahr angesehen.
Gilt nur, wenn D das Modell U vollständig beschreibt. Verbleibende
Probleme: Unentscheidbarkeit und nicht-monotone Schlüsse (s.u.).
12–35
Ist PROLOG nicht-monoton?
Beachte: CWA and NAF.
• NAF: ¬A wird als wahr angesehen, wenn alle Beweisversuche terminiert
haben und A nicht aus D bewiesen werden konnte.
Um ¬A anzunehmen, muss die Unbeweisbarkeit von A bekannt sein: die
Negation von PROLOG.
• Strikte CWA: ¬A ist wahr, wenn das Fakt A nicht in D enthalten ist.
Beispiel: Personen, die nicht im Telefonbuch aufgeführt sind, haben
keinen Anschluss.
• Unabhängige Beschreibungen von “A” und “not A” durch zwei
verschiedene Prädikate A+ and A−. Wird A+ bewiesen, so ist A wahr,
wird A− bewiesen, so ist ¬A wahr.
G. Görz, FAU, Inf.8
G. Görz, FAU, Inf.8
12–34
Beispiel:
Ein Fahrplan enthalte die Abfahrtszeiten p(7). p(8). p(9).
Die Anfrage :- p(8:30). resultiert in der Antwort “no”, was
not(p(8:30)) entspricht.
⇒ Nicht-monotoner Schluss, denn, wenn p(8:30) zur KB hinzugefügt
wird, folgt not(p(8:30)) nicht mehr, sondern stattdessen p(8:30)!
Gegenargument:
Die Logik von PROLOG ist äquivalent zu klassische Logik + CWA
— trifft nicht zu, denn
Angenommen, es gäbe eine weitere Regel, die besagt
G. Görz, FAU, Inf.8
12–36
p(8:30) :- not(p(7:30)).
Wenn wir klassische Logik + CWA annehmen, dann ist die Antwort auf die
Anfrage :- p(8:30). “no”, weil p(8:30). nicht explizit angegeben ist.
Aber PROLOG antwortet “yes” auf die Anfrage :- p(8:30)., weil
p(7:30) scheitert!
G. Görz, FAU, Inf.8
12–37
Verknüpfung logik-orientierter mit funktionaler
Programmierung
Einbettung von PROLOG in SCHEME??
• Funktionale Einbettung : Ein PROLOG-Interpreter wird in Scheme
implementiert. Es kann vorgesehen werden, dass sich PROLOG und
Scheme wechselseitig aktivieren.
Beispiel: Query Language System in Abelson/Sussman, Kap. 4.4
Nichtdeterminismus wird mittels Strömen implementiert
• Umgebungseinbettung : Referenzen von PROLOG-Identifikatoren
beziehen sich auf Identifikatorbindungen in Scheme. Möglich, da
Scheme Closures unterstützt.
• Vollständige Einbettung : Kontrollkontext ist verfügbar und kann
manipuliert werden. Möglich, da Scheme Continuations unterstützt
(Haynes: “Logic Continuations”). Beispiel: SCHELOG (in SLIB)
G. Görz, FAU, Inf.8
12–38
Herunterladen