Prolog Florian Kleene - Institut für Wirtschaftsinformatik der WWU ...
Prolog Florian Kleene - Institut für Wirtschaftsinformatik der WWU ...
Prolog Florian Kleene - Institut für Wirtschaftsinformatik der WWU ...
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
Westfälische Wilhelms-Universität Münster<br />
Ausarbeitung<br />
<strong>Prolog</strong><br />
im Rahmen des Seminars Programmiersprachen<br />
Themensteller: Prof. Dr. Herbert Kuchen<br />
<strong>Florian</strong> <strong>Kleene</strong><br />
Betreuer: Dipl.-Medienwiss. Susanne Gruttmann<br />
<strong>Institut</strong> <strong>für</strong> <strong>Wirtschaftsinformatik</strong><br />
Praktische Informatik in <strong>der</strong> Wirtschaft
Inhaltsverzeichnis<br />
1 Einführung in <strong>Prolog</strong> 1<br />
1.1 Entstehung und Geschichte . . . . . . . . . . . . . . . . . . . . . . . . 1<br />
1.2 <strong>Prolog</strong>-Systeme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2<br />
1.3 Anwendungsgebiete . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2<br />
2 Aufbau von <strong>Prolog</strong>-Programmen 3<br />
2.1 Grundsätzliche Struktur . . . . . . . . . . . . . . . . . . . . . . . . . 3<br />
2.2 Fakten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3<br />
2.3 Regeln . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4<br />
2.4 Anfragen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6<br />
2.5 Code-Beispiel: Stammbaum . . . . . . . . . . . . . . . . . . . . . . . 6<br />
3 Funktionsweise des Interpreters 8<br />
3.1 Grundlagen <strong>der</strong> Logik . . . . . . . . . . . . . . . . . . . . . . . . . . 8<br />
3.1.1 Aussagenlogik . . . . . . . . . . . . . . . . . . . . . . . . . . . 8<br />
3.1.2 Prädikatenlogik . . . . . . . . . . . . . . . . . . . . . . . . . . 10<br />
3.2 Unifikation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11<br />
3.3 Resolution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13<br />
3.4 Backtracking und <strong>der</strong> Cut . . . . . . . . . . . . . . . . . . . . . . . . 15<br />
4 <strong>Prolog</strong> in <strong>der</strong> Praxis 17<br />
4.1 Expertensysteme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17<br />
4.2 Code-Beispiel: Send + More = Money . . . . . . . . . . . . . . . . . 19<br />
5 Zusammenfassung und Fazit 20<br />
A Anhang 22<br />
A.1 Code-Beispiel Stammbaum . . . . . . . . . . . . . . . . . . . . . . . . 22<br />
A.2 Wahrheitstabelle zur Resolutionsprüfung . . . . . . . . . . . . . . . . 23<br />
A.3 Abarbeitungsreihenfolge von Anfragen an den <strong>Prolog</strong>-Interpreter (trace) 24<br />
Literaturverzeichnis 25<br />
i
Kapitel 1: Einführung in <strong>Prolog</strong><br />
1 Einführung in <strong>Prolog</strong><br />
1.1 Entstehung und Geschichte<br />
<strong>Prolog</strong> ist die wohl bekannteste logische Programmiersprache. Entwickelt wurde sie<br />
Anfang <strong>der</strong> 1970er Jahre vom französischen Forscher Alain Colmerauer und seinen<br />
Mitarbeitern am Groupe d’Intelligence Artificielle in Marseille. Der Name <strong>Prolog</strong><br />
entstand aus dem französischen ” PROgrammation en LOGigue“, was mit ” Program-<br />
mieren in Logik“ ins Deutsche übersetzt werden muss. Aufbauend auf den Ideen des<br />
Forschers Edgar F. Codd zu relationalen Datenbankmodellen [Bo87, S. 8], J.A. Ro-<br />
binsons Arbeit zum Resolventenprinzip und dem Unifikationsverfahren von Jacques<br />
Herbrand [CL90, S. 2] entwickelte Colmerauer zunächst System-Q. System-Q war<br />
ein Frage-Antwort-System, welches auf Hornklauseln aufbaute und die oben genann-<br />
ten Prinzipien <strong>der</strong> Resolution und Unifikation zur Beweisführung ausnutzte [CL90,<br />
S. 2]. Ausgehend von diesem System entstand mit Unterstützung von P. Roussel<br />
und R. Pasero die Sprache <strong>Prolog</strong>.<br />
Der erste Interpreter <strong>für</strong> <strong>Prolog</strong> wurde 1973 in Fortran geschrieben und um 1975<br />
stand <strong>der</strong> erste Compiler zur Verfügung. Zu dieser Zeit wurde <strong>Prolog</strong> nur von einem<br />
engen Personenkreis <strong>der</strong> Artificial-Intelligence-Forscher genutzt und geschätzt. Erst<br />
als die japanische Regierung 1981 <strong>Prolog</strong> zur Basissprache ihrer ” Rechnersysteme<br />
<strong>der</strong> 5. Generation“ – eine Rechnerarchitektur, die viele parallel arbeitende Prozesso-<br />
ren vorsieht – ernannte, erlangte <strong>Prolog</strong> einen größeren Bekanntheitsgrad. Zwar ist<br />
die Bedeutung <strong>der</strong> Programmiersprache <strong>Prolog</strong> in <strong>der</strong> Folgezeit in den Hintergrund<br />
gerückt und sicher keiner breiten Masse mehr bekannt, doch werden auch heute noch<br />
praktische Anwendung in <strong>Prolog</strong> programmiert. Als Beispiele lassen sich Program-<br />
me zur Fahrplangestaltung bei Zugverspätungen, zur Minimierung von Materialver-<br />
brauch o<strong>der</strong> zur Aufstellung von Schicht- und Stundenplänen anführen [IF08].<br />
Im Gegensatz zu prozeduralen Programmiersprachen ist <strong>der</strong> Programmierer in Pro-<br />
log lediglich aufgefor<strong>der</strong>t das Problem zu beschreiben. Er muss jedoch keinen Lö-<br />
sungsalgorithmus spezifizieren. Insofern ist <strong>Prolog</strong> deklarativ wie beispielsweise die<br />
bekannte Structured Query Language (SQL) <strong>für</strong> Datenbanken und es steht die Fra-<br />
ge nach dem ” Was gelöst werden soll“ im Gegensatz zur Frage nach dem ” Wie es<br />
gelöst werden soll“ bei imperativen o<strong>der</strong> objektorientierten Programmiersprachen<br />
im Vor<strong>der</strong>grund. Dennoch bedient auch <strong>Prolog</strong> sich bei <strong>der</strong> Lösungssuche einiger<br />
prozeduraler Elemente [KS88, S. 13], die im Kapitel 3 aufgezeigt werden.<br />
1
Kapitel 1: Einführung in <strong>Prolog</strong><br />
1.2 <strong>Prolog</strong>-Systeme<br />
Als die Programmiersprache <strong>Prolog</strong> nach <strong>der</strong> ersten Entwicklung durch A. Colmerau-<br />
rer größere Bekanntheit erlangte, entwickelte sich eine Vielzahl von verschiedenen<br />
<strong>Prolog</strong>-Systemen. Bekannte Namen sind in diesem Zusammenhang Arity-<strong>Prolog</strong>,<br />
Micro-<strong>Prolog</strong>, <strong>Prolog</strong> II und III, Turbo-<strong>Prolog</strong>, SWI-<strong>Prolog</strong>, IF/<strong>Prolog</strong> und eine<br />
Vielzahl an<strong>der</strong>er [Be88, S. 275]. Die Systeme unterschieden sich im Hinblick auf die<br />
Anzahl <strong>der</strong> Schnittstellen zu an<strong>der</strong>en Programmiersprachen o<strong>der</strong> die dem Anwen<strong>der</strong><br />
zur Verfügung gestellten Utilities (Interpreter, Compiler, Editor, Bugtracker, usw.).<br />
Außerdem gibt es in den Systemen eine unterschiedliche Syntax und verschiedene<br />
Bezeichnungen und Anzahlen <strong>für</strong> die sog. Built-In-Prädikate – einer Art Grundwort-<br />
schatz bzw. Schlüsselwörter.<br />
Im Laufe <strong>der</strong> Zeit bildeten sich zwei Standards <strong>für</strong> die Syntax heraus. Zum einen<br />
war dies die Marseille-Syntax, wie sie ursprünglich von Alain Colmerauer aufgestellt<br />
wurde, und zum an<strong>der</strong>en die Edinburgh-Syntax [Be88, S. 275 ff.]. Erst im Jahr 1995<br />
wurde bei <strong>der</strong> ISO <strong>der</strong> Standard ISO/IEC 13211-1:1995 [ISO95] und im Jahr 2000<br />
<strong>der</strong> zweite Teil ISO/IEC 13211-2:2000 [ISO00] aufbauend auf <strong>der</strong> Edinburgh-Syntax<br />
festgelegt. Zumindest den ersten Teil des ISO-Standards aus dem Jahr 1995 imple-<br />
mentieren heute die Systeme IF/<strong>Prolog</strong> und SWI-<strong>Prolog</strong>, die in größeren Kreisen<br />
Verbreitung gefunden haben. SWI-<strong>Prolog</strong> wird in <strong>der</strong> Version 5.6.64 im Rahmen<br />
dieser Arbeit verwendet.<br />
1.3 Anwendungsgebiete<br />
Zunächst ist zu sagen, dass es sich bei <strong>Prolog</strong> um eine universelle Programmierspra-<br />
che handelt [CL90, S. 3], die also prinzipiell <strong>für</strong> diverse Gebiete in <strong>der</strong> Informatik<br />
einsetzbar ist. Ursprünglich entwickelt wurde sie jedoch <strong>für</strong> die algorithmische Verar-<br />
beitung natürlicher Sprachen [KS89, S. 9] – also den Bereich <strong>der</strong> Computerlinguistik.<br />
Aus diesem Ursprung heraus ergibt sich, dass <strong>Prolog</strong> insbeson<strong>der</strong>e <strong>für</strong> die verschie-<br />
denen Teilgebiete <strong>der</strong> künstlichen Intelligenz, wie Spracherkennung und Bildverar-<br />
beitung und weniger <strong>für</strong> arithmetische Operationen geeignet ist. Neben dem Gebiet<br />
<strong>der</strong> Computerlinguistik findet <strong>Prolog</strong> seine Anwendung in Expertensystemen, die im<br />
Kapitel 4.1 dieser Arbeit näher erläutert werden, und in <strong>der</strong> Lehre und Forschung<br />
[CL90, S. 3, 4].<br />
2
Kapitel 2: Aufbau von <strong>Prolog</strong>-Programmen<br />
2 Aufbau von <strong>Prolog</strong>-Programmen<br />
2.1 Grundsätzliche Struktur<br />
Ein <strong>Prolog</strong>-Programm besteht aus einer sog. Wissensbasis, die einen Ausschnitt aus<br />
<strong>der</strong> Realwelt darstellt. In <strong>der</strong> Wissensbasis werden Fakten und Regeln, die die Ei-<br />
genschaften <strong>der</strong> Objekte aus <strong>der</strong> Realwelt und <strong>der</strong>en Beziehungen wi<strong>der</strong>spiegeln,<br />
gespeichert. Fakten und Regeln werden durch den Programmierer mit Hilfe eines<br />
Editors in einer Datei gespeichert, von manchen Systemen kompiliert (z. B. Ari-<br />
ty <strong>Prolog</strong> [Be88, S. 277]) und anschließend vom Interpreter, <strong>der</strong> die Aufgabe eines<br />
Theorembeweisers bzw. einer Inferenzmaschine übernimmt, geladen. Um Erkennt-<br />
nisse aus <strong>der</strong> Wissensbasis zu erlangen, ist <strong>der</strong> Nutzer aufgefor<strong>der</strong>t Anfragen an den<br />
Interpreter abzugeben, die dieser versucht durch die Wissensbasis zu beweisen o<strong>der</strong><br />
zu wi<strong>der</strong>legen.<br />
Auch in diesem Aspekt wird ein wesentlicher Unterschied zu den heute mehr ge-<br />
bräuchlichen Programmiersprachen deutlich und man erkennt die Ursprünge des<br />
Frage-Antwort-Systems wie<strong>der</strong>. Der schematische Aufbau eines <strong>Prolog</strong>-Programms,<br />
<strong>der</strong> an die Darstellung aus [KS89, S. 15] angelehnt ist, ist in <strong>der</strong> nachfolgenden<br />
Grafik noch einmal zu erkennen.<br />
2.2 Fakten<br />
Editor<br />
Wissensbasis<br />
(Fakten und Regeln)<br />
Benutzerschnittstelle<br />
(Anfragen)<br />
Interpreter<br />
(Inferenzmaschine)<br />
Abbildung 1: Bestandteile <strong>der</strong> Programmiersprache <strong>Prolog</strong><br />
Fakten in <strong>Prolog</strong> bezeichnen Aussagen über Objekte o<strong>der</strong> die Beziehung zwischen<br />
Objekten, die immer als eindeutig wahr angesehen werden [KS88, S. 16]. Die gene-<br />
relle Struktur eines Fakts lässt in Anlehnung an die Backus-Naur-Form beschreiben<br />
durch:<br />
fakt ::= funktor. | funktor({argument, } ∗ 0 argument).<br />
3
Kapitel 2: Aufbau von <strong>Prolog</strong>-Programmen<br />
Fakten bestehen also entwe<strong>der</strong> aus einem Funktor o<strong>der</strong> aus einem Funktor auf den<br />
in runden Klammern beliebig viele durch Kommata getrennte Argumente folgen<br />
[KS88, S. 76]. Für alle nachfolgenden Quellcodebeispiele sei darauf hingewiesen,<br />
dass Zeilenkommentare in <strong>Prolog</strong> durch ” %“ eingeleitet und Blockkomentare durch<br />
” /* ... */“ eingeschlossen werden. Fakten und Regeln werden am Ende <strong>der</strong> Zeile<br />
durch einen Punkt abgeschlossen.<br />
true . % Nullstelliger Fakt .<br />
student ( philipp ). % Philipp ist ein Student .<br />
vater ( reinhold , florian ). % Reinhold ist <strong>Florian</strong>s Vater .<br />
Zu beachten ist, dass <strong>Prolog</strong> kein tieferes Verständnis von Fakten gewinnt, son<strong>der</strong>n<br />
lediglich Zeichenfolgen verarbeitet. Die Aussage ” Reinhold ist <strong>Florian</strong>s Vater“ aus<br />
dem dritten Fakt entsteht aus <strong>der</strong> Interpretation des Programmieres heraus und<br />
könnte auch durch ” <strong>Florian</strong> ist Reinholds Vater“ festgelegt werden. Die Art und<br />
Weise die Reihenfolge <strong>der</strong> Argumente zu lesen sollte daher einmalig vom Program-<br />
mierer festgelegt werden [CM03, S. 4].<br />
Für die Programmierung von Fakten gilt folgende Syntax [KS88, S. 18]:<br />
1. Der Bezeichner – auch Funktor genannt – eines Fakts beginnt mit einem Klein-<br />
buchstaben. Dadurch wird er vom <strong>Prolog</strong>-Interpreter als Konstante aufgefasst.<br />
2. Auf den Funktor folgen direkt in Klammern die Argumente. Mehrere Argu-<br />
mente werden durch Kommata voneinan<strong>der</strong> abgetrennt.<br />
3. Die Argumente eines Fakts können selbst auch wie<strong>der</strong> Fakten sein. Fakten<br />
o<strong>der</strong> verschachtelte Fakten werden als Struktur bezeichnet.<br />
4. Die Anzahl <strong>der</strong> Argumente, die beliebig groß aber auch Null sein kann, wird<br />
als Stelligkeit bezeichnet. Fakten mit gleichem Funktor und gleicher Stelligkeit<br />
werden unter dem Begriff Prädikat zusammengefasst.<br />
5. Alle Fakten werden mit einem Punkt abgeschlossen.<br />
2.3 Regeln<br />
Regeln ermöglichen es dem <strong>Prolog</strong>-Interpreter Wissen abzuleiten und vereinfachen<br />
es dem Programmierer eine Vielzahl gleich gearteter Fakten in <strong>der</strong> Wissensbasis<br />
darzustellen [KS88, S. 28]. Die allgemeine Struktur einer Regel ist gegeben durch:<br />
regel ::= fakt : − {struktur, } ∗ 1 struktur.<br />
4
Kapitel 2: Aufbau von <strong>Prolog</strong>-Programmen<br />
Angenommen je<strong>der</strong> Student interessiere sich <strong>für</strong> Informatik. Dies ist mit unserer<br />
bisherigen Kenntnis nur möglich, indem jeweils zwei Fakten pro Person in die Wis-<br />
sensbasis aufgenommen werden:<br />
student ( florian ). % <strong>Florian</strong> ist Student .<br />
% <strong>Florian</strong> interessiert sich <strong>für</strong> Informatik .<br />
interesse ( florian , informatik ).<br />
student ( philipp ). % Philipp ist Student .<br />
% Philipp interessiert sich <strong>für</strong> Informatik .<br />
interesse ( philipp , informatik ).<br />
Effizienter ist dies durch eine einzige Regel in <strong>Prolog</strong> ausdrückbar: ” Jemand in-<br />
teressiert sich <strong>für</strong> Informatik, falls er Student ist.“ Mit Hilfe von Regeln wird die<br />
Wissensbasis übersichtlicher und bei vielen gleichartigen Fakten verkürzt sie sich<br />
enorm.<br />
student ( florian ). % <strong>Florian</strong> ist Student .<br />
student ( philipp ). % Philipp ist Student .<br />
% eine einzige Regel<br />
interesse (X, informatik ) :- student (X).<br />
Den linken Teil <strong>der</strong> Regel vor dem ” :-“ bezeichnet man als Kopf, den Teil auf <strong>der</strong><br />
rechten Seite als Rumpf <strong>der</strong> Regel. Regeln sind so zu lesen, dass <strong>der</strong> Kopf <strong>der</strong> Regel<br />
als wahr angesehen werden kann, sofern alle Voraussetzungen im Rumpf erfüllt, d.h.<br />
wahr sind. Das ” :-“ muss somit als umgedrehter Implikationspfeil gelesen werden.<br />
Prinzipiell können auch Fakten in Form von Regeln dargestellt werden. Der Kopf<br />
<strong>der</strong> Regel besteht dann aus dem Fakt selbst und <strong>der</strong> Rumpf aus dem null-stelligen<br />
Prädikat true. Der Fakt mensch(florian). würde also zu <strong>der</strong> Regel mensch(florian<br />
):- true. umgeformt.<br />
Für die Programmierung von Regeln gilt folgende Syntax [KS88, S. 28]:<br />
1. Der Kopf <strong>der</strong> Regel besteht aus genau einem Fakt, <strong>der</strong> als Argumente sowohl<br />
Konstanten als auch Variablen, die in <strong>Prolog</strong> mit einem Großbuchstaben o<strong>der</strong><br />
einem Unterstrich begonnen werden, aufweisen kann.<br />
2. Der Rumpf <strong>der</strong> Regel besteht aus einer o<strong>der</strong> mehreren Strukturen, die durch<br />
Kommata o<strong>der</strong> Semikola voneinan<strong>der</strong> abgetrennt werden. Das Komma in Pro-<br />
log bezeichnet dabei das logische Und, während das Semikolon <strong>für</strong> das logische<br />
O<strong>der</strong> verwendet wird.<br />
5
Kapitel 2: Aufbau von <strong>Prolog</strong>-Programmen<br />
3. Der Geltungsbereich einer Variablen ist auf exakt eine Regel beschränkt, d.h.<br />
Variablen mit <strong>der</strong>selben Bezeichnung in verschiedenen Regeln sind voneinan<strong>der</strong><br />
unabhängig.<br />
4. Jede Regel wird durch einen Punkt abgeschlossen.<br />
Fakten und Regeln, die nach <strong>der</strong> obigen Syntax aufgebaut sind, werden in <strong>Prolog</strong><br />
als Klauseln – genauer als Programmklauseln – bezeichnet.<br />
2.4 Anfragen<br />
Die Benutzung von <strong>Prolog</strong>-Programmen geschieht dadurch, dass <strong>der</strong> Nutzer am<br />
<strong>Prolog</strong>-Prompt, <strong>der</strong> durch ” ?-“ symbolisiert wird, Anfragen abgibt. Anfragen müssen<br />
aus einer o<strong>der</strong> mehreren durch Kommata o<strong>der</strong> Semikola getrennten Strukturen, die<br />
auch Variablen beinhalten können, bestehen. Der Geltungsbereich einer Variablen<br />
ist in diesem Fall auf den Bereich einer einzelnen Anfrage beschränkt. Der Interpreter<br />
versucht die Anfrage aus <strong>der</strong> Wissensbasis abzuleiten und antwortet mit true, false<br />
o<strong>der</strong>, falls die Anfrage Variablen beinhaltete, mit einer Variablenbelegung, die bei<br />
entsprechen<strong>der</strong> Anfrage true liefern würde.<br />
2.5 Code-Beispiel: Stammbaum<br />
Im Folgenden soll <strong>der</strong> Umgang mit Fakten, Regeln und insbeson<strong>der</strong>e Anfragen an-<br />
hand eines Beispielprogramms gezeigt werden. Das Äquivalent zum ” Hello-World-<br />
Programm“ in imperativen Programmiersprachen ist die Implementierung eines<br />
Stammbaumes in logischer Programmierung. Der als Beispiel gewählte Stammbaum<br />
ist in <strong>der</strong> folgenden Grafik zu sehen, wobei die ausgegrauten Personen nur zur opti-<br />
schen Vervollständigung des Stammbaumes eingezeichnet sind. Die zugehörige Wis-<br />
sensbasis, die nach oben beschriebener Syntax aufgebaut ist, befindet sich im Anhang<br />
auf Seite 22 und soll als Code-Grundlage <strong>für</strong> die gesamte Seminararbeit dienen. Sie<br />
enthält neben den offensichtlichen Fakten einige Regeln, die die Verwandtschafts-<br />
verhältnisse beschreiben.<br />
6
Kapitel 2: Aufbau von <strong>Prolog</strong>-Programmen<br />
Hermann + Katharina Tina + Wilhelm<br />
<strong>Florian</strong><br />
Adam + Eva<br />
Reinhold + Doris<br />
Thomas Steffen<br />
Abbildung 2: Darstellung des Staummbaumes<br />
Zunächst werden einige Anfragen gestellt, die sich direkt auf Fakten in <strong>der</strong> Wis-<br />
sensbasis beziehen, also durch einfaches Vergleichen bewiesen o<strong>der</strong> wi<strong>der</strong>legt werden<br />
können.<br />
?- mutter ( doris , thomas ).<br />
true .<br />
?- vater ( hermann , thomas ).<br />
false .<br />
?- mensch ( tobias ).<br />
false .<br />
Wie die letzte Anfrage zeigt, können Anfragen, die sich auf Aussagen beziehen, die<br />
nicht in <strong>der</strong> Wissensbasis abgebildet sind, nicht bewiesen werden. Die Wissensbasis<br />
repräsentiert eine abgeschlossene Welt in <strong>der</strong> alles, was nicht explizit bewiesen wer-<br />
den kann, als falsch angesehen wird. Die Anfrage wird daher vom Interpreter mit<br />
false beantwortet. Für die nachfolgenden Anfragen ist jeweils die Auswertung einer<br />
o<strong>der</strong> mehrerer Regeln nötig. Die Funktionsweise des Interpreters <strong>für</strong> die Schlussfol-<br />
gerungen wird in den kommenden Kapitel ausführlich vorgestellt.<br />
?- elternteil ( doris , florian ). % Beispiel 1<br />
true .<br />
?- vorfahre (X, reinhold ). % Beispiel 2<br />
X = hermann ;<br />
X = katharina ;<br />
false .<br />
?- vorfahre ( doris ,Y). % Beispiel 3<br />
Y = florian ;<br />
Y = thomas ;<br />
false .<br />
7
Kapitel 3: Funktionsweise des Interpreters<br />
Neben Anfragen, die true o<strong>der</strong> false als Ergebnis zurück liefern (Beispiel 1: ?-<br />
elternteil(doris,florian).), können auch Anfragen abgeben werden, die Varia-<br />
blen beinhalten (Beispiele 2 und 3). Derart gestaltete Anfragen beantwortet <strong>der</strong><br />
Interpreter mit Variablenbelegungen, die zum Ergebnis true führen würden. Gibt es<br />
mehrere Lösungen, so ist <strong>der</strong> Nutzer aufgefor<strong>der</strong>t durch Eingabe eines Semikolons<br />
eine weitere Lösung zu verlangen. Der Interpreter gibt solange Lösungen zurück, bis<br />
es keine weiteren mehr gibt und endet dann mit false.<br />
Das dritte Beispiel soll nochmals verdeutlichen, dass <strong>der</strong> <strong>Prolog</strong>-Interpreter sowohl<br />
die Anfragen als auch die Wissensbasis lediglich als Zeichenfolgen verarbeitet. Das<br />
Prädikat vorfahre( , ) ist daher auch dazu geeignet Nachfahren zu bestimmen.<br />
3 Funktionsweise des Interpreters<br />
3.1 Grundlagen <strong>der</strong> Logik<br />
3.1.1 Aussagenlogik<br />
Um die Funktionsweise des <strong>Prolog</strong>-Interpreters verstehen zu können, erscheint es<br />
zunächst sinnvoll, die Grundlagen <strong>der</strong> Logik, die das Fundament <strong>der</strong> Programmier-<br />
sprache bilden, darzustellen. Die Syntax von <strong>Prolog</strong> ist nämlich nicht willkürlich<br />
gewählt, son<strong>der</strong>n lehnt sich stark <strong>der</strong> Prädikatenlogik erster Ordnung an. Zunächst<br />
sei jedoch die Aussagenlogik als Ausgangspunkt <strong>für</strong> die Prädikatenlogik vorgestellt.<br />
Einfache aussagenlogische Formeln bestehen aus durch Und (∧) o<strong>der</strong> O<strong>der</strong> (∨) ver-<br />
knüpften Aussagen (negierte (¬) o<strong>der</strong> nicht-negierte Literale), wobei ein Wahrheits-<br />
wert <strong>für</strong> eine Formel aus den Wahrheitswerten <strong>der</strong> Literale resultiert [Sch00, S. 15].<br />
Die Formel a ∧ (¬b ∨ c) ∧ b ist beispielsweise <strong>für</strong> die Belegung a = 1, b = 1, c = 1<br />
erfüllt, d. h. =1. Die Formel (a ∧ b) ∧ (¬a ∧ b) ist hingegen <strong>für</strong> keine Belegung erfüllt.<br />
Man nennt eine solche Formel Kontradiktion, während Formeln, die <strong>für</strong> alle Bele-<br />
gungen erfüllt sind, Tautologien genannt werden.<br />
<strong>Prolog</strong> arbeitet nicht mit aller Art aussagenlogischer Formeln, die erzeugbar sind. Es<br />
hat sich herausgestellt, dass sich Hornformeln – benannt nach dem amerikanischen<br />
Logiker Alfred Horn – in Kombination mit <strong>der</strong> SLD-Resolutionsregel (Linear reso-<br />
lution with Selected function for Definite clauses) gut maschinell verarbeiten lassen<br />
und gleichzeitig auch viele Praxisprobleme in dieser Form abbildbar sind [KS88,<br />
S. 36]. Die sog. Hornformeln, <strong>der</strong>en Aufbau im Folgenden gezeigt werden soll, stel-<br />
len eine Teilmenge aller aussagenlogischen Formeln dar:<br />
8
Kapitel 3: Funktionsweise des Interpreters<br />
• Hornklausel: Eine Hornklausel ist eine Disjunktion (O<strong>der</strong>-Verkünpfung) von<br />
Literalen, wobei maximal ein Literal in nicht-negierter Form aufritt.<br />
Beispiele: a; (¬a); (¬a ∨ b); (¬a ∨ ¬b ∨ c); (¬a ∨ ¬b ∨ ¬c);<br />
• Hornformel: Eine Hornformel ist eine Konjunktion (Und-Verknüpfung) von<br />
Hornklauseln.<br />
Beispiele: a; (¬a) ∧ (¬a ∨ b); a ∧ (¬a ∨ ¬b ∨ c) ∧ (¬a ∨ ¬b ∨ ¬c);<br />
Eine Hornformel ist also eine Formel in konjunktiver Normalform, d. h. eine Kon-<br />
junktion von Disjunktionstermen, bei <strong>der</strong> je<strong>der</strong> Disjunktionsterm höchstens ein nicht-<br />
negiertes Literal aufweist [Sch00, S. 26, 31].<br />
Den Fakten, Regeln und Anfragen in <strong>Prolog</strong>-Programmen lassen sich charakteris-<br />
tisch drei verschiedene Arten <strong>der</strong> Hornformeln zuordnen:<br />
Ein Fakt ist eine Hornformel, die aus exakt einem nicht-negierten Literal besteht.<br />
Eine Regel enthält ein o<strong>der</strong> mehrere negierte Literale und exakt ein positives Li-<br />
teral und eine Anfrage besteht nur aus negierten Literalen. Um dies ersichtlich zu<br />
machen muss zunächst die Auflösung des umgedrehten Implikationspfeils innerhalb<br />
<strong>der</strong> Anfragen und Regeln vorgenommen werden. Es gilt (a ← b) = (a ∨ ¬b) und<br />
allgemeiner unter Ausnutzung <strong>der</strong> De Morgan’schen Regel a ← (b1 ∧ ... ∧ bn) =<br />
a ∨ ¬(b1 ∧ ... ∧ bn) = a ∨ ¬b1 ∨ ... ∨ ¬bn [Sch00, S. 14, 24]. Wendet man diese Regeln<br />
entsprechend an, so lässt sich folgende Tabelle zusammenstellen:<br />
Darstellung in <strong>Prolog</strong> Codierung durch Auflösung des<br />
Symbole Implikationspfeils<br />
Fakt student(florian). a a<br />
Regel interesse(florian,informatik) c ← a, b, ... c ∨ ¬(a ∧ b ∧ ...)<br />
:- student(florian), ... = c ∨ ¬a ∨ ¬b ∨ ¬...<br />
Anfrage ?- interesse(florian,informatik). ← b ¬b<br />
Tabelle 1: Charakteristika von Fakten, Regeln und Anfragen in Hornklauseln<br />
Fakten und Regeln bezeichnet man, da sie jeweils ein nicht-negiertes Literal enthal-<br />
ten, als Programmklauseln. Anfragen hingegen werden als Zielklauseln bezeichnet.<br />
Um eine Zielklausel beweisen zu können, muss diese unter Ausnutzung <strong>der</strong> Pro-<br />
grammklauseln soweit äquivalent transformiert werden, dass <strong>der</strong> Beweis aus <strong>der</strong> Wis-<br />
sensbasis ersichtlich wird. Dabei kommt dem Schlussfolgern aus <strong>der</strong> Logik die ent-<br />
scheidende Bedeutung zu. Eine Formel lässt sich aus den Ausgangsformeln schluss-<br />
folgern, wenn die neue Formel <strong>für</strong> alle Belegungen, <strong>für</strong> die die Ausgangsformeln wahr<br />
liefern, ebenfalls wahr liefert [KS88, S. 39].<br />
9
Kapitel 3: Funktionsweise des Interpreters<br />
Beispiel: Aus (a ∨ b) ∧ (¬b ∨ c) lässt sich die Formel (a ∨ c) folgern, da<br />
nicht gleichzeitig b und ¬b wahr sein können. Das b kann also eliminiert<br />
werden. Nachvollziehbar wird die Eliminierung sofort, nachdem man die<br />
Ausgangsformel zu (¬a → b) ∧ (b → c) und das Ergebnis zu (¬a → c)<br />
umgeformt hat.<br />
Wendet man diese Regel <strong>der</strong> Eliminierung auf eine Kontradiktion wie z. B.<br />
(¬a∧b)∧(a∧¬b) an, so bleiben keine Literale übrig und es entsteht die leere Klausel<br />
(⊔). Diese Erkenntnis und das Wissen darüber, dass eine Formel genau dann un-<br />
erfüllbar (wi<strong>der</strong>spruchsvoll) ist, wenn ihre Negation eine Tautologie ist, führt zum<br />
Unerfüllbarkeitstest. Fügt man das negierte Literal aus <strong>der</strong> Anfrage dem Programm<br />
hinzu und gelingt es, die leere Klausel herzuleiten, so gibt es einen Wi<strong>der</strong>spruch<br />
[Sch00, S. 37 ff.]. Dies ist äquivalent dazu, dass die unnegierte Anfrage sich aus dem<br />
Programm ableiten lässt, also beweisbar ist.<br />
Beispielsweise existiere eine Wissensbasis {e, c, (d ← e), (b ← c, d), (a ← b)} und<br />
es werde die Anfrage nach ← a gestellt, so muss <strong>für</strong> den Beweis <strong>der</strong> Zielklausel in<br />
Kombination mit dem Programm die leere Klausel erzeugt werden können. Gelingt<br />
dies, so ist a beweisbar. In <strong>der</strong> nachfolgenden Darstellung ist in je<strong>der</strong> Zeile ein Eli-<br />
minierungsschritt (Resolution) ausgeführt worden. Ziel- und Programmklausel sind<br />
innerhalb einer Zeile durch Komma voneinan<strong>der</strong> abgetrennt und ” passen“ deswegen<br />
zu einan<strong>der</strong>, weil die Zielklausel nur negierte Literale und Fakten und Köpfe von<br />
Regeln stets positive Literale sind (vgl. auch obige Tabelle):<br />
(← a), (a ← b)<br />
(← b), (b ← c, d)<br />
(← c, d), c<br />
(← d), (d ← e)<br />
(← e), e<br />
⊔<br />
Die Anfrage ← a ist also aus dem Programm beweisbar. Die zugehörige, vollständige<br />
Wahrheitstabelle findet <strong>der</strong> interessierte Leser im Anhang auf Seite 23.<br />
3.1.2 Prädikatenlogik<br />
Für die vollständige Betrachtung von <strong>Prolog</strong>-Programmen genügt die Aussagenlogik<br />
alleine jedoch noch nicht, da keine Funktoren und keine Variablen, wie sie in <strong>Prolog</strong>-<br />
Programmen enthalten sind, nachgebildet werden können. Die Prädikatenlogik er-<br />
weitert die Aussagenlogik um Quantoren, Funktions- und Prädikatssymbole [Sch00,<br />
S. 50]. Insbeson<strong>der</strong>e die Quantoren ∃ (es existiert ein) und ∀ (<strong>für</strong> alle) sind in diesem<br />
10
Kapitel 3: Funktionsweise des Interpreters<br />
Zusammenhang unabdingbar, da z. B. <strong>der</strong> Aussage vater(X, florian) kein Wahr-<br />
heitswert zugeordnet werden kann, solange die Variable X nicht durch einen Quantor<br />
festgelegt ist. Ist X durch einen Quantor festgelegt, d. h. gebunden, so lässt sich ein<br />
Wahrheitswert <strong>für</strong> ∃X : vater(X, florian) o<strong>der</strong> ∀Y : mutter(Y, florian) in Bezug<br />
auf die Wissensbasis bestimmen.<br />
In <strong>Prolog</strong> sind Variablen in Programmklauseln implizit allquantifiziert, da sie <strong>für</strong><br />
einen Beweis nur einmalig festgelegt werden können. Anfragen hingegen sind impli-<br />
zit existenzquantifiziert, weil es genügt eine Variablenbelegung aufzufinden, die die<br />
Anfrage beweist.<br />
Um die Beweisbarkeit einer Anfrage überprüfen zu können, muss diese daher zunächst<br />
durch Transformationen in eine Form überführt werden, die keine Existenzquanto-<br />
ren mehr enthält. Durch den Vorgang <strong>der</strong> Skolemisierung, benannt nach dem nor-<br />
wegischen Mathematiker Thoralf Skolem, kann dies bewerkstelligt werden [Sch00,<br />
S. 63 f.]. Grundlage dieses Verfahrens ist, dass existenzquantifizierte Variablen durch<br />
eine Skolemkonstante bzw. bei voranstehendem Allquantor durch eine Skolemfunkti-<br />
on ersetzt werden können ohne dass sich <strong>der</strong> Wahrheitswert än<strong>der</strong>t [Sch00, S. 64, 65].<br />
∀Y : ∃X : mann(Y ) → lieben(Y, X) ⇔ ∀Y : mann(Y ) → lieben(Y, fs(Y ))<br />
Die Aussage ” Für alle Männer Y existiert eine Frau X, so dass Y X liebt“ wird<br />
durch den Vorgang <strong>der</strong> Skolemisierung ersetzt durch ” Für alle Männer Y gibt es eine<br />
vom konkreten Mann Y abhängige Frau X, die Y liebt“. Die existenzquantifizierte<br />
Variable X wird also durch die Skolemfunktion fs(Y ) substituiert.<br />
Nachdem alle existenzquantifizierenden Variablen ersetzt worden sind, können die<br />
Allquantoren ohne weitere Beachtung weggelassen werden, da Variablen in Aussagen<br />
– wie bereits oben erwähnt – implizit allquantifizierend sind [KS88, S. 65]. Die<br />
Beweisbarkeit kann jetzt mit Hilfe des gewöhnlichen Unerfüllbarkeitstests, <strong>der</strong> aus<br />
dem vorigen Kapitel bekannt ist, hergeleitet werden.<br />
Im folgenden Kapitel wird die Instanziierung von Variablen und <strong>der</strong> Beweisprozess in<br />
<strong>Prolog</strong> vorgestellt. Das Themengebiet <strong>der</strong> reinen Logik wird verlassen und <strong>der</strong> Focus<br />
auf das Verständnis <strong>der</strong> konkreten Arbeitsweise des <strong>Prolog</strong>-Interpreters gelegt.<br />
3.2 Unifikation<br />
Die Wortbedeutung Unifikation leitet sich aus den lateinischen Wörtern unus (eins)<br />
und facere (machen) ab, so dass sich als Gesamtbedeutung ” zu eins machen“ o<strong>der</strong><br />
” vereinigen“ ergibt [KS89, S. 29]. Ziel ist es mit Hilfe <strong>der</strong> Unifikation die an den<br />
Interpreter gestellten Anfragen aus <strong>der</strong> Wissensbasis abzuleiten. Um eine Anfrage<br />
11
Kapitel 3: Funktionsweise des Interpreters<br />
beantworten zu können, durchsucht <strong>der</strong> Interpreter die Wissensbasis nach einem<br />
Prädikat mit gleichem Funktor und gleicher Stelligkeit. Dieses Prädikat kann sowohl<br />
<strong>der</strong> Kopf einer Regel als auch ein Fakt sein. Damit die Anfrage bewiesen werden<br />
kann, müssen neben Prädikat und Stelligkeit zusätzlich auch die Argumente des<br />
Prädikats unifizieren [KS88, S. 103]. Für die weitere Betrachtung wird aus Gründen<br />
<strong>der</strong> Übersichtlichkeit zwischen den verschiedenen Arten <strong>der</strong> Argumente unterschie-<br />
den. Unifizierbarkeit lässt sich mit Hilfe des internen, zweistelligen <strong>Prolog</strong>-Prädikats<br />
” =( , )“ am Prompt überprüfen.<br />
1. Zwei Konstanten sind unifizierbar, falls ihre Zeichenketten übereinstimmen:<br />
Die Anfrage ?- =(florian,florian). würde also unifizieren, d. h. mit true<br />
beantwortet.<br />
2. Eine (ungebundene) Variable und eine Konstante sind stets dadurch unifizier-<br />
bar, dass die Konstante an die Variable gebunden wird. Man nennt diesen<br />
Vorgang Instanziierung <strong>der</strong> Variablen:<br />
Die Anfrage ?- =(X,florian). würde also dadurch unifizieren, dass an die<br />
Variable X die Konstante florian gebunden würde.<br />
3. Eine (ungebundene) Variable und eine Struktur sind stets dadurch unifizierbar,<br />
dass die Struktur an die Variable gebunden wird:<br />
Die Anfrage ?- =(mensch(florian),X). würde also dadurch unifizieren, dass<br />
an die Variable X die Struktur mensch(florian) gebunden würde.<br />
4. Zwei (ungebundene) Variablen sind stets dadurch unifizierbar, dass sie im An-<br />
schluss <strong>für</strong> den gleichen Wert stehen.<br />
5. Zwei Strukturen sind dann unfizierbar, wenn sie den gleichen Funktor, die<br />
gleiche Stelligkeit haben und jedes Argument auch nach den hier vorgestellten<br />
Regeln unfizierbar ist:<br />
?- =(kind(eltern(X,doris),florian),kind(eltern(reinhold,doris),florian<br />
)). als Anfrage würde also dadurch unifizieren, dass an die Variable X die<br />
Konstante reinhold gebunden würde, da <strong>der</strong> Funktor kind übereinstimmt, die<br />
Stelligkeit jeweils zwei ist und auch die Argumente nach den Regeln 5, 2 und<br />
1 unifizierbar sind.<br />
Bei <strong>der</strong> Unifikation wird von den meisten <strong>Prolog</strong>-Interpretern – so auch von SWI-<br />
<strong>Prolog</strong> – auf den sog. Occurcheck aus Gründen <strong>der</strong> Effizienz verzichtet [KS89, S. 176].<br />
Der Occurcheck stellt einen Kontrollmechanismus bereit, <strong>der</strong> überprüft, ob eine Va-<br />
riable in beiden zu unifizierenden Argumenten auftritt. Das einfachste Beispiel hier-<br />
zu ist die Anfrage ?- =(X,f(X))., die prinzipiell vom Interpreter abgefangen werden<br />
12
Kapitel 3: Funktionsweise des Interpreters<br />
müsste, um eine unendliche Schleife zu verhin<strong>der</strong>n.<br />
Durch die Unifikation lässt sich die Arbeitsweise des Interpreters <strong>für</strong> die Anfrage<br />
nach Fakten in <strong>der</strong> Wissensbasis erklären. Falls jedoch die Auswertung von Regeln<br />
<strong>für</strong> die Beantwortung einer Anfrage hinzugezogen werden muss, so ist ein weiteres<br />
Konzept – nämlich das <strong>der</strong> Resolution – nötig.<br />
3.3 Resolution<br />
Die Resolution bezeichnet einen Schlussfolgerungsmechanismus [CM03, S. 248], <strong>der</strong><br />
bereits im Kapitel zur Aussagenlogik kurz behandelt wurde und dazu verwendet<br />
wird, logische Formeln auf Gültigkeit zu prüfen. Ergebnis <strong>der</strong> Resolution zweier<br />
Klauseln ist eine neue dritte Klausel, die sich als Konsequenz aus den beiden ge-<br />
gebenen Klauseln mit Hilfe <strong>der</strong> Unifikation ergibt. Die Anfrage am Prompt stellt<br />
die zu beweisende Klausel dar. In Kombination mit einer Regel (Resolution) än<strong>der</strong>t<br />
sich die zu beweisende Klausel, so dass ein äquivalentes Problem entsteht, welches<br />
im nächsten Schritt zu beweisen ist.<br />
Nachfolgend ist <strong>der</strong> <strong>für</strong> die Anfrage ?- vorfahre(reinhold,thomas). relevante Aus-<br />
schnitt aus dem Code-Beispiel Stammbaum wie<strong>der</strong>gegeben:<br />
vater ( reinhold , thomas ).<br />
elternteil (X,Y) :- vater (X,Y).<br />
vorfahre (X,Y) :- elternteil (X,Y).<br />
Der <strong>Prolog</strong>-Interpreter ist aufgefor<strong>der</strong>t die Anfrage ?- vorfahre(reinhold,thomas).<br />
zu beweisen. Er durchsucht die Wissensbasis nach einem Prädikat mit dem Funktor<br />
vorfahre und Stelligkeit 2. In <strong>der</strong> dritten Zeile des Code-Ausschnitts wird er fündig.<br />
Die Unifikation bewirkt die Instanziierung <strong>der</strong> Variablen X=reinhold und Y=thomas.<br />
Durch die Resolution verlagert sich das zu beweisende Problem von ?- vorfahre(<br />
reinhold,thomas). zu ?- elternteil(reinhold,thomas)., wobei die instanziierten<br />
Variablen bereits eingesetzt wurden.<br />
In einem nächsten Schritt unifiziert ?- elternteil(reinhold,thomas). mit elternteil<br />
(X,Y):- vater(X,Y).. Wie<strong>der</strong> werden X und Y instanziiert und als Ergebnis <strong>der</strong><br />
Resolution ergibt sich das neu zu beweisende Ziel ?- vater(reinhold,thomas)..<br />
Die Anfrage ?- vater(reinhold,thomas). unifiziert mit dem Fakt vater(reinhold<br />
,thomas). in <strong>der</strong> Wissensbasis. Die Anfrage ist folglich bewiesen, also wahr. Weil<br />
durch die Unifikation und Resolution nur erfüllbarkeitsäquivalente Umformungen<br />
ausgeführt wurden, ist daher auch die Anfrage ?- vorfahre(reinhold,thomas). mit<br />
wahr zu beantworten. Dieses Ergebnis ergibt sich auch aus dem Schaubild des<br />
13
Kapitel 3: Funktionsweise des Interpreters<br />
Stammbaums.<br />
Zum Abschluss dieses Kapitels soll noch auf die prozedurale Arbeitsweise des <strong>Prolog</strong>-<br />
Interpreters, die <strong>Prolog</strong> als Programmiersprache von <strong>der</strong> reinen Logik differenziert<br />
[Be86, S. 101], eingegangen werden. Das prozedurale Vorgehen bei <strong>der</strong> Beweissuche<br />
sollte dem Programmierer bei <strong>der</strong> Zusammenstellung <strong>der</strong> Wissensbasis immer be-<br />
wusst sein, da es sonst leicht zu ungewollten Fehlern und Problemen kommen kann.<br />
<strong>Prolog</strong> durchsucht bei Anfragen die Wissensbasis nach passenden, d. h. unifizierba-<br />
ren Prädikaten, von oben nach unten. Besteht die Anfrage aus mehreren verknüpften<br />
Strukturen, so wird versucht, diese in <strong>der</strong> Reihenfolge von links nach rechts zu bewei-<br />
sen. Ein einfaches Beispiel, das die Wichtigkeit <strong>der</strong> Reihenfolge in <strong>der</strong> Wissensbasis<br />
untermauern soll, ist nachfolgend wie<strong>der</strong>gegeben (vgl. [KS88, S. 71]:<br />
beweisbar (X) :- zirkel (X).<br />
zirkel (Y) :- beweisbar (Y).<br />
beweisbar ( egal ).<br />
Stellt man die Anfrage ?- beweisbar(egal)., so liefert obiges Programm niemals<br />
das Ergebnis true, son<strong>der</strong>n <strong>der</strong> Interpreter gerät in eine unendliche Schleife, obwohl<br />
die Anfrage als Fakt in <strong>der</strong> Wissensbasis vorliegt. Die Begründung liegt in <strong>der</strong> oben<br />
genannten Suchreihenfolge des Interpreters und dem ungünstigen Aufbau <strong>der</strong> Wis-<br />
sensbasis, so dass <strong>der</strong> Interpreter nie die dritte Zeile des Codes erreicht. Aus <strong>der</strong><br />
formalen Logik heraus ist ein solches Verhalten natürlich nicht erwünscht. Die Rei-<br />
henfolge <strong>der</strong> Fakten und Regeln sollte keine Rolle spielen [Be86, S. 101].<br />
Insbeson<strong>der</strong>e <strong>für</strong> rekursiv definierte Prädikate, die im Übrigen die einzige Möglichkeit<br />
darstellen in <strong>Prolog</strong> iterative Schleifen wie z. B. die for-Schleife nachzubilden, ist es<br />
notwendig die Abbruchbedingung <strong>der</strong> Rekursion stets vor dem rekursiv definier-<br />
ten Prädikat selbst in die Wissensbasis aufzunehmen. Als Beispiel hier<strong>für</strong> sei das<br />
Prädikat vorfahre(_,_). aus dem Code-Beispiel genannt:<br />
/* Abbruchbedingung */<br />
vorfahre (X,Y) :- elternteil (X,Y).<br />
/* rekursive Funktionsdefinition von vofahre (_,_).<br />
Nur so sind beliebig weit entfernte Vorfahren<br />
ermittelbar */<br />
vorfahre (X,Y) :- elternteil (Z,Y),vorfahre (X,Z).<br />
Steht das rekursiv definierte Prädikat in <strong>der</strong> Wissensbasis vor <strong>der</strong> zugehörigen Ab-<br />
bruchbedingung, so ist das Prädikat wertlos, da es den Interpreter in eine Schleife<br />
ohne Abbruch zwingt (vgl. oben).<br />
14
Kapitel 3: Funktionsweise des Interpreters<br />
3.4 Backtracking und <strong>der</strong> Cut<br />
Die bisherigen Ausführungen erklären bereits einen großen Teil <strong>der</strong> Vorgehensweise<br />
des <strong>Prolog</strong>-Interpreters. Jedoch ist bislang nicht geklärt worden, wie vorgegangen<br />
wird, wenn <strong>der</strong> <strong>Prolog</strong>-Interpreter durch die Resolution in eine ” Sackgasse“ gerät.<br />
Als Beispiel soll die Anfrage ?- elternteil(doris,florian). dienen. Der relevante<br />
Code-Ausschnitt ist nachfolgend wie<strong>der</strong>gegeben:<br />
mutter ( doris , florian ).<br />
elternteil (X,Y) :- vater (X,Y).<br />
elternteil (X,Y) :- mutter (X,Y).<br />
Wie im Kapitel zur Resolution beschrieben durchsucht <strong>der</strong> <strong>Prolog</strong>-Interpreter die<br />
Wissensbasis von oben nach unten nach unifizierbaren Prädikaten. In diesem Fall<br />
würde die Anfrage also mit <strong>der</strong> in Zeile 2 gezeigten Regel unifizieren. Nach In-<br />
stanziierung <strong>der</strong> Variablen und Resolution verbleibt als neues Ziel <strong>der</strong> Beweis von<br />
?- vater(doris,florian).. Diese Klausel kann in <strong>der</strong> Wissensbasis nicht aufgefun-<br />
den werden, so dass man nach bisheriger Kenntnis davon auszugehen hat, dass <strong>der</strong><br />
<strong>Prolog</strong>-Interpreter mit false antworten würde.<br />
Dies ist jedoch nicht <strong>der</strong> Fall. Der <strong>Prolog</strong>-Interpreter erkennt, dass er in eine ” Sack-<br />
gasse“ geraten ist und geht einen Schritt in seiner Auswertungsreihenfolge zurück<br />
(Backtracking) [KS88, S. 104]. Er überspringt also die Regel in Zeile 2 und wendet<br />
stattdessen die Regel in Zeile 3 an, die sich ebenfalls mit <strong>der</strong> Anfrage unifizieren<br />
lässt. Als neues Ziel verbleibt zu zeigen, dass ?- mutter(doris,florian). gilt. Da<br />
dies ein Fakt <strong>der</strong> Wissensbasis ist, gibt <strong>der</strong> <strong>Prolog</strong>-Interpreter demzufolge true aus.<br />
Die Reihenfolge <strong>der</strong> Abarbeitungen lässt sich in <strong>Prolog</strong> durch das nullstellige Built-<br />
In-Prädikat trace nachvollziehen. Zum besseren Verständnis <strong>der</strong> Abarbeitungsrei-<br />
henfolge kann <strong>der</strong> trace in einem Und-/O<strong>der</strong>-Suchbaum dargestellt werden [Be86,<br />
S. 112]. Die Wurzel dieses Baumes bildet die Anfrage an den Interpreter. Ausgehend<br />
von dieser Wurzel bestimmen sich die Nachfolger dann jeweils als alle möglichen Fak-<br />
ten o<strong>der</strong> Rümpfe von Regeln, die mit <strong>der</strong> Wurzel unifizieren. Die einzelnen Verzwei-<br />
gungen werden, da verschiedene Fakten und Regeln als voneinan<strong>der</strong> unabhängiges<br />
Wissen gesehen werden müssen, mit o<strong>der</strong> verknüpft werden. Hat eine Regel mehr<br />
als eine Voraussetzung im Rumpf, so werden diese im Baum mit und verknüpft. Die<br />
Blätter des Baumes stellen Fakten aus <strong>der</strong> Wissensbasis dar.<br />
Die Beweissuche einer Anfrage geschieht durch Traversierung des Baumes. Um eine<br />
Anfrage zu beweisen, müssen dann alle Nachfolger eines Und-Knotens und einer <strong>der</strong><br />
15
Kapitel 3: Funktionsweise des Interpreters<br />
Nachfolger eines O<strong>der</strong>-Knotens erfolgreich abgearbeitet werden. Scheitert <strong>der</strong> Be-<br />
weis eines Teilziels, so wird zum letzten O<strong>der</strong>-Knoten (Choicepoint), <strong>der</strong> noch nicht<br />
bearbeitete Nachfolger aufweist, zurückgegangen (Backtracking) [Be86, S. 115]. Bei<br />
einem Backtracking-Schritt werden Variableninstanziierungen, die bis zum Choice-<br />
point vorgenommen wurden, rückgängig gemacht.<br />
Der zur Anfrage ?- vorfahre(hermann,florian). gehörende Suchbaum ergibt sich<br />
aus dem trace (vgl. Anhang, Seite 24). In den Knoten des Baumes lassen sich die<br />
jeweils noch zu beweisenden Anfragen erkennen, angewandte Regeln sind durch die<br />
Ziffern an den Kanten dargestellt und die gestrichelte Linie zeigt die Abarbeitungs-<br />
reihenfolge.<br />
X=hermann<br />
Y=florian<br />
vorfahre(hermann,florian)<br />
ODER<br />
3 4<br />
elternteil(hermann,florian)<br />
ODER<br />
UND<br />
Z=reinhold<br />
1<br />
2<br />
vater(hermann,florian) mutter(hermann,florian) elternteil(Z,florian) vorfahre(hermann,reinhold)<br />
Legende zu den Regelnummern:<br />
1: elternteil(X,Y) :- vater(X,Y).<br />
2: elternteil(X,Y) :- mutter(X,Y).<br />
3: vorfahre(X,Y) :- elternteil(X,Y).<br />
4: vorfahre(X,Y) :- elternteil(Z,Y),vorfahre(X,Z).<br />
Legende zu den Symbolen:<br />
fail: Backtracking Schritt<br />
exit: Teilziel erreicht<br />
X=hermann<br />
Y=florian<br />
Z=reinhold<br />
1<br />
ODER<br />
2<br />
3<br />
vater(reinhold,florian) mutter(doris,florian) elternteil(hermann,reinhold)<br />
Z=doris<br />
ODER<br />
1<br />
2<br />
vater(reinhold,florian) mutter(doris,florian)<br />
Abbildung 3: Abarbeitung einer Anfrage dargestellt in einem Suchbaum<br />
Der Suchbaum zeigt, dass die Abarbeitungsreihenfolge <strong>der</strong> Regeln von oben nach<br />
unten und von links nach rechts einer Tiefensuche entspricht. Diese wird in <strong>Prolog</strong> in<br />
Kombination mit Backtracking verwendet. Die Anfrage ist beweisbar, da im rechten<br />
Teilbaum beide durch Und-verknüpfte Teilziele parallel erreicht werden können.<br />
Der sogenannte Cut – ein nullstelliges Built-In-Prädikat mit dem Funktor ! – stellt<br />
dem Programmierer ein Werkzeug zur Seite, das es ihm ermöglicht die Abarbeitungs-<br />
reihenfolge des Interpreters dadurch zu steuern, dass Backtracking gezielt verhin<strong>der</strong>t<br />
wird [KS88, S. 120].<br />
Der Programmierer beschränkt den Suchraum des Interpreters durch gezieltes ” Ab-<br />
schneiden“ irrelevanter Teilbäume und kann somit die Effizienz von Programmen<br />
steigern [Sch00, S. 152]. Eine an<strong>der</strong>e Einsatzform von Cut erlaubt es dem Program-<br />
mierer, nur exakt eine Lösung zu einem Problem ausgeben zu lassen und danach die<br />
16
Kapitel 4: <strong>Prolog</strong> in <strong>der</strong> Praxis<br />
Suche abzubrechen. Letztendlich kann mit Hilfe des Cut sogar das aus prozeduralen<br />
Programmiersprachen bekannte if-then-else nachgebildet werden [Sch00, S. 152].<br />
Aufgrund <strong>der</strong> Eigenschaften des Cut, dass er die Lösungssuche beeinflusst, wird er<br />
in <strong>der</strong> Literatur kontrovers diskutiert. Auf <strong>der</strong> einen Seite ist es mit seiner Hilfe<br />
möglich, die Effizienz <strong>der</strong> Auswertung zu steigern [Sch00, S. 152]. Auf <strong>der</strong> an<strong>der</strong>en<br />
Seite wird er als ” Alptraum jedes Logikers“ [KS89, S. 142] bezeichnet, da er den<br />
Prinzipien <strong>der</strong> logischen Programmierung ” Was statt Wie“ genau entgegenwirkt.<br />
An dieser Stelle wird auf die genauere Darstellung <strong>der</strong> verschiedenen Möglichkeiten<br />
des Cut verzichtet, da es sich nicht um eine <strong>für</strong> <strong>Prolog</strong> wesentliche Komponente<br />
handelt. Es sei hierzu jedoch auf [Be86, S. 103ff.] und [KS88, S. 120 ff.] verwiesen.<br />
4 <strong>Prolog</strong> in <strong>der</strong> Praxis<br />
4.1 Expertensysteme<br />
Nachdem die wesentlichen Aspekte <strong>der</strong> Programmiersprache <strong>Prolog</strong> vorgestellt wur-<br />
den, kann jetzt auf die praktische Anwendung in Expertensystemen eingegangen<br />
werden. Expertensysteme, die auch als wissensbasierte Systeme bezeichnet werden<br />
[KS88, S. 240], sollen in einem gewissen Rahmen den menschlichen Experten erset-<br />
zen können. Dies ist immer dann nötig, wenn es nur eine sehr geringe Anzahl an<br />
Experten in dem entsprechenden Fachgebiet gibt, die Komplexität <strong>der</strong> zu beach-<br />
tenden Vorschriften beson<strong>der</strong>s hoch ist (Beispiel: Behörden) o<strong>der</strong> das Spezialwissen<br />
nur sehr selten benötigt wird (Behandlung von Ausfallsituationen) [Sa89, S. 24 f.].<br />
Aus diesen Umständen ergibt sich, dass ein Expertensystem ähnliche Fähigkeiten<br />
aufweisen muss, die auch ein menschlicher Experte besitzt. Es ist also zunächst ei-<br />
ne genauere Analyse des menschlichen Experten von Nöten, bevor anschließend die<br />
einzelnen Fähigkeiten in Bezug zu <strong>Prolog</strong> gesetzt werden können:<br />
Als Experte wird i. A. eine Person bezeichnet, die umfangreiches Wissen<br />
in einem bestimmten Fachgebiet besitzt und dieses Wissen kompetent<br />
anwenden und auch erläutern kann. Das Wissen wurde durch Talent,<br />
Übung und/o<strong>der</strong> langjährige Erfahrung gesammelt, wobei sich <strong>der</strong> Ex-<br />
perte auch schnell neues Wissen aus externen Quellen aneignen kann. In<br />
Problemsituationen steht <strong>der</strong> Experte in direkter Interaktion mit ande-<br />
ren Menschen. Er erfragt dabei problemrelevante Aspekte, um schließlich<br />
das Problem lösen zu können (vgl. [KS88, S. 240], [Sa89]).<br />
17
Kapitel 4: <strong>Prolog</strong> in <strong>der</strong> Praxis<br />
Fasst man diese Fähigkeiten in einer schematischen Darstellung (vgl. [Be86, S. 26])zu-<br />
sammen, so ergeben sich verschiedene Komponenten, die ein Expertensystem auf-<br />
weisen muss, um den Anfor<strong>der</strong>ungen nach obiger Definition zu genügen:<br />
Erklärungskomponente<br />
Benutzer<br />
Dialogkomponente<br />
(Benutzerschnittstelle)<br />
Problemlösung<br />
(Inferenzmechanismus)<br />
Wissensbasis<br />
(internes, externes, erfragtes Wissen)<br />
Expertensystem<br />
Wissensverän<strong>der</strong>ungskomponente<br />
Abbildung 4: Allgemeine Struktur eines Expertensystems<br />
In <strong>Prolog</strong> kann durch das Konzept <strong>der</strong> Fakten und Regeln ein regelbasiertes Exper-<br />
tensystem aufgebaut werden. Die wichtigste Komponente dieses Systems stellt <strong>der</strong><br />
Inferenzmechanismus dar, da er die verschiedenen an<strong>der</strong>en Komponenten integrieren<br />
und steuern muss. In <strong>Prolog</strong> wird diese Aufgabe durch den Interpreter übernommen,<br />
so dass sich die Arbeitsweise als Tiefensuche in Kombination mit Backtracking cha-<br />
rakterisieren lässt [CL90, S. 170].<br />
Eng verknüpft mit dem Inferenzmechanismus ist die Repräsentation <strong>der</strong> verschiede-<br />
nen Arten des Wissens – in <strong>Prolog</strong> Fakten und Regeln. Wichtig ist es, das erfragte<br />
Wissen, welches erst im Rahmen <strong>der</strong> Interaktion mit dem Benutzer erlangt wird und<br />
sich somit fall-spezifisch unterscheidet, von den zwei an<strong>der</strong>en Wissensarten zu ab-<br />
zugrenzen. Um erfragtes Wissen speichern zu können, unterstützt <strong>Prolog</strong> in diesem<br />
Zusammenhang das dynamische Hinzufügen und Löschen von Fakten und Regeln<br />
in die Wissensbasis zur Laufzeit. Dies wird durch die Built-In-Prädikate asserta( ).<br />
und retract( ). und einige Abwandlungen von diesen realisiert [KS88, S. 179]. Ex-<br />
ternes Wissen erlangt <strong>der</strong> <strong>Prolog</strong>-Interpreter aus an<strong>der</strong>en Programmen, die über<br />
Schnittstellen angebunden sind. Die Schnittstellen sind, wie in <strong>der</strong> Einleitung dar-<br />
gelegt, jedoch zwischen den verschiedenen <strong>Prolog</strong>-Systemen sehr inhomogen und<br />
lassen sich nur <strong>für</strong> den Einzelfall detaillierter beschreiben.<br />
Die Benutzerschnittstelle sollte nach Auffassung von Kleine Büning und Schmittgen<br />
nicht in <strong>Prolog</strong> selbst realisiert werden [KS88, S. 245]. Dies erscheint auch logisch,<br />
da <strong>Prolog</strong> sich nur sehr bedingt dazu eignet grafische Elemente einzubinden, sodass<br />
lediglich eine Interaktion mit dem Benutzer am Prompt verbliebe. Der heutige Nut-<br />
zer ist hingegen grafische Oberflächen gewöhnt und würde eine solche Interaktion<br />
ablehnen. Die Erklärungskomponente muss dem Benutzer über die Benutzerschnitt-<br />
18
Kapitel 4: <strong>Prolog</strong> in <strong>der</strong> Praxis<br />
stelle auf verständliche Art und Weise den Problemlösungsprozess deutlich machen<br />
können, da das Expertensystem ansonsten nur geringe Akzeptanz finden würde.<br />
Aus <strong>der</strong> allgemein gehaltenen Beschreibung <strong>der</strong> verschiedenen Komponenten und<br />
<strong>der</strong> Realisierung geht hervor, dass Benutzerschnittstelle, Inferenzmechanismus und<br />
die Repräsentation des Wissens unabhängig von <strong>der</strong> konkreten Problemstellung im-<br />
plementiert werden können. Die Architektur sieht eine strikte Trennung von Wissen<br />
und Wissensverarbeitung vor. Da die problemspezifische Wissensbasis in solch ein<br />
System eingepflegt werden muss, spricht man daher auch von leeren Schalen o<strong>der</strong><br />
Shells [KS88, S. 243].<br />
Das Produkt TWAICE <strong>der</strong> Firma Nixdorf ist eine solche Expertensystem-Shell,<br />
die auf <strong>Prolog</strong> aufsetzt. Der interessierte Leser findet eine genauere Beschreibung<br />
in [Sa89, S. 135-159]. In [KS88, S. 245-274] findet sich die ausführlich erläuterte,<br />
vollständige Implementierung eines Expertensystems anhand eines Autokauf-Beispiels.<br />
4.2 Code-Beispiel: Send + More = Money<br />
Nachfolgend ist ein Beispielprogramm zur Lösung <strong>der</strong> Gleichung SEND + MORE =<br />
MONEY wie<strong>der</strong>gegeben, um einen Vergleich von <strong>Prolog</strong> mit an<strong>der</strong>en Programmier-<br />
sprachen zu ermöglichen. Je<strong>der</strong> Buchstabe soll dabei durch eine <strong>der</strong> Ziffern {0,...,9}<br />
belegt werden, wobei jede Ziffer nur <strong>für</strong> einen Buchstaben verwendet und <strong>der</strong> Buch-<br />
stabe M nicht durch die Ziffer Null belegt werden sollte.<br />
Das hier vorgestellte <strong>Prolog</strong>-Programm implementiert einen Brute-Force-Algorith-<br />
mus, <strong>der</strong> als Datenstruktur Listen benutzt. Die Liste <strong>der</strong> in <strong>der</strong> Gleichung vorkom-<br />
menden Buchstaben wird mit allen Permutationen <strong>der</strong> Ziffern {0,...,9} instanziiert<br />
(Zeile 5). Die Richtigkeit <strong>der</strong> Gleichung wird in Zeile 6 überprüft und ggf. wird die<br />
Lösung <strong>für</strong> MONEY ausgegeben (Zeile 7).<br />
Es sei darauf hingewiesen, dass die Prädikate perm(_,_). (Zeile 1, 2) und das<br />
da<strong>für</strong> benötigte Prädikat select(_,_,_). (Zeile 3, 4) lediglich aus Gründen <strong>der</strong><br />
Vollständigkeit mit angegeben wurden. In nahezu allen Implementierungen von Pro-<br />
log liegt bereits ein Built-In-Prädikat zur Erzeugung von Permutationen vor.<br />
Es folgt <strong>der</strong> Quellcode zur Wissensbasis:<br />
1 perm ([] ,[]) .<br />
2 perm ( Liste ,[X| Perm ]) :- select (X,Liste , Rest ),perm (Rest , Perm ).<br />
3 select (X ,[X| Rest ], Rest ).<br />
4 select (X ,[ Kopf | Liste ] ,[ Kopf | Rest ]) :- select (X,Liste , Rest ).<br />
5 generiere (S,E,N,D,M,O,R,Y) :- perm ([S,E,N,D,M,O,R,Y,_,_<br />
] ,[1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,0]).<br />
19
Kapitel 5: Zusammenfassung und Fazit<br />
6 gleichung (S,E,N,D,M,O,R,Y) :- (S *1000+ E *100+ N *10+ D *1) + (M<br />
*1000+ O *100+ R *10+ E *1) =:= (M *10000+ O *1000+ N *100+ E *10+ Y *1) .<br />
7 loese :- generiere (S,E,N,D,M,O,R,Y), gleichung (S,E,N,D,M,O,R,<br />
Y),not (M =:=0) ,!, write (M),write (O),write (N),write (E),write<br />
(Y).<br />
Aufgerufen wird das Programm mit <strong>der</strong> Anfrage ?- loese. am Prompt. Der Inter-<br />
preter bestimmt daraufhin ein mögliches Ergebnis und gibt dieses aus:<br />
1 ?- loese .<br />
10652<br />
true .<br />
Aus dem Ergebnis lassen sich die Belegungen <strong>für</strong> die verschiedenen Buchstaben<br />
in MONEY ablesen. Auf Wunsch könnte natürlich auch die Belegung jedes einzelnen<br />
Buchstaben durch Anpassung von Zeile 7 ausgegeben werden.<br />
Es sei an dieser Stelle noch auf den Cut in Zeile 7 hingewiesen. Dieser verhin<strong>der</strong>t,<br />
dass das Ergebnis ein zweites Mal ausgegeben wird. Dieses würde dadurch geschehen,<br />
dass es eine weitere Permutation <strong>der</strong> Ziffern {0,...,9} gibt, die lediglich die Positionen<br />
<strong>der</strong> nicht benötigten Ziffern 3 und 4 än<strong>der</strong>t 1 .<br />
5 Zusammenfassung und Fazit<br />
Nachdem innerhalb dieser Arbeit die Entstehungsgeschichte aus dem Ursprung in<br />
<strong>der</strong> Logik, <strong>der</strong> Aufbau von Programmen und die Funktionsweise des Interpreters <strong>der</strong><br />
Programmiersprache <strong>Prolog</strong> erläutert sowie auch die typischen Anwendungsgebiete<br />
herauskristallisiert wurden, sollen abschließend noch einmal auf Vorteile von <strong>Prolog</strong><br />
eingegangen und schließlich Gründe <strong>für</strong> das bisherige Scheitern identifiziert werden.<br />
Durch die enge Verbindung <strong>der</strong> Programmiersprache zur Logik und damit zur Ma-<br />
thematik lassen sich im Gegensatz zu imperativen Programmiersprachen häufig Kor-<br />
rektheitsbeweise über Programme führen, so dass <strong>für</strong> kritische Anwendung in dieser<br />
Hinsicht ein großer Vorteil besteht. Wie im Kapitel 4.1 zu Expertensystemen auf-<br />
gezeigt, ist es in <strong>Prolog</strong> möglich den Quellcode, d. h. im Rahmen von <strong>Prolog</strong> die<br />
Wissensbasis, dynamisch zur Laufzeit zu verän<strong>der</strong>n, so dass es möglich ist <strong>Prolog</strong>-<br />
Programme lernfähig zu gestalten. Diese Eigenschaft war und ist insbeson<strong>der</strong>e im<br />
Bereich <strong>der</strong> künstlichen Intelligenz eine wünschenswerte Eigenschaft einer Program-<br />
miersprache.<br />
1 Gesamte Gleichung: 9567 + 1085 = 10652, die Ziffern 3 und 4 wurden also nicht benötigt<br />
20
Kapitel 5: Zusammenfassung und Fazit<br />
<strong>Prolog</strong> zeigt seine Stärken in logischen Problemstellungen und ist speziell <strong>für</strong> die<br />
Anwendungsgebiete <strong>der</strong> künstlichen Intelligenz entwickelt worden, jedoch wurde <strong>der</strong><br />
Programmiersprache in den 1970er und 1980er Jahren durch Neuronale Netze ein<br />
starker Konkurrent in diesem Bereich entgegen gestellt. Ein weiterer Punkt, <strong>der</strong> Pro-<br />
log ins Hintertreffen geraten ließ, ist <strong>der</strong> Fakt, dass die Ausführungsgeschwindigkeit<br />
im Vergleich zu Programmen in imperativen Sprachen meist geringer ist. Auch <strong>der</strong><br />
in Kapitel 3.4 vorgestellte Cut zur Effizienzsteigerung kann dieser Tatsache nicht<br />
entscheidend entgegenwirken. Neben den bereits genannten Nachteilen eignet sich<br />
<strong>Prolog</strong> zudem nicht sehr gut, um arithmetische Operationen, die Grundbestandteile<br />
vieler Programme darstellen, auszuführen.<br />
Bedauerlicherweise sind selbst die in Kapitel 1.2 genannten ISO-Standards noch<br />
nicht in allen <strong>Prolog</strong>-Systemen umgesetzt, so dass weiterhin auf eine Konvergenz<br />
zu warten bleibt. Als letzter Punkt seien die lange Zeit zueinan<strong>der</strong> inkompatiblen<br />
<strong>Prolog</strong>-Systeme, die <strong>für</strong> einen größeren Nutzerkreis sicherlich nicht för<strong>der</strong>lich waren,<br />
angeführt.<br />
Alle genannten Gründe leisteten ihren Beitrag dazu, dass das von <strong>der</strong> japanischen<br />
Regierung 1982 mit einem Budget von 400 Millionen Dollar initiierte, international<br />
beachtete Projekt zu den ” Rechnersystemen <strong>der</strong> 5. Generation“ 1992 <strong>für</strong> geschei-<br />
tert erklärt wurde [FG92]. Während alle vorherigen Rechnergenerationen auf eine<br />
Erhöhung <strong>der</strong> Anzahl <strong>der</strong> logischen Bausteine in einer einzelnen CPU setzten, sollten<br />
viele parallel arbeitende Prozessoren in Kombination mit einer logischen Program-<br />
miersprache (<strong>Prolog</strong>) die neue Architektur bestimmen.<br />
Betrachtet man die Entwicklung <strong>der</strong> heutigen Rechnerarchitekturen in Richtung<br />
Parallelität, so mag <strong>der</strong> Satz ” Either it [the Fifth Generation Project] was a failure,<br />
or it was ahead of its time.“ 2 [FG00] zum Nachdenken anregen.<br />
Als Fazit bleibt zu sagen, dass in <strong>Prolog</strong> die Möglichkeit besteht, Probleme aus spe-<br />
ziellen Bereichen schneller, einfacher und eleganter lösen zu können. Es gibt jedoch<br />
auch eine Vielzahl von Problemen, <strong>für</strong> die <strong>Prolog</strong> nur bedingt einsetzbar ist und in<br />
denen an<strong>der</strong>e Programmiersprachen ihre Stärken ausspielen können.<br />
2<br />
” Entwe<strong>der</strong> es [das 5. Generation Projekt] war ein Fehlschlag, o<strong>der</strong> es war seiner Zeit voraus.“<br />
21
Kapitel A: Anhang<br />
A Anhang<br />
A.1 Code-Beispiel Stammbaum<br />
/* Welche Menschen gibt es in unserer " Welt "? */<br />
mensch ( florian ).<br />
mensch ( thomas ).<br />
mensch ( reinhold ).<br />
5 mensch ( doris ).<br />
mensch ( hermann ).<br />
mensch ( katharina ).<br />
/* Die Beziehungen innerhalb <strong>der</strong> Familie väterlicherseits .<br />
vater ( reinhold , florian ) sagt aus : Reinhold ist <strong>der</strong> Vater<br />
von <strong>Florian</strong> . */<br />
10 vater ( reinhold , florian ).<br />
vater ( reinhold , thomas ).<br />
vater ( hermann , reinhold ).<br />
/* Die Beziehungen innerhalb <strong>der</strong> Familie mütterlicherseits .<br />
mutter ( doris , florian ) sagt aus : Doris ist die Mutter von<br />
<strong>Florian</strong> . */<br />
15 mutter ( doris , florian ).<br />
mutter ( doris , thomas ).<br />
mutter ( katharina , reinhold ).<br />
/* Defintion von Eltern : X ist ein Elternteil von Y, wenn es<br />
entwe<strong>der</strong> ein X gibt , sodass X Vater von Y ist o<strong>der</strong> es ein<br />
X gibt , sodass X Mutter von Y ist . */<br />
20 elternteil (X,Y) :- vater (X,Y).<br />
elternteil (X,Y) :- mutter (X,Y).<br />
/* Defintion von Vorfahren : X ist ein Vorfahre von Y, wenn er<br />
entwe<strong>der</strong> ein direkter Elternteil von Y ist , o<strong>der</strong> es gibt<br />
einen Elternteil Z von Y, <strong>der</strong> selbst wi<strong>der</strong>um X als<br />
Vorfahren hat . */<br />
25 vorfahre (X,Y) :- elternteil (X,Y).<br />
vorfahre (X,Y) :- elternteil (Z,Y),vorfahre (X,Z).<br />
22
Kapitel A: Anhang<br />
A.2 Wahrheitstabelle zur Resolutionsprüfung<br />
Wahrheitstabelle zur Formel ¬a ∧ e ∧ c ∧ (d ∨ ¬e) ∧ (b ∨ ¬c ∨ ¬d) ∧ (a ∨ ¬b):<br />
a b c d e ¬a e c (d ∨ ¬e) (b ∨ ¬c ∨ ¬d) (a ∨ ¬b) Gesamt<br />
0 0 0 0 0 1 0 0 1 1 1 0<br />
0 0 0 0 1 1 1 0 0 1 1 0<br />
0 0 0 1 0 1 0 0 1 1 1 0<br />
0 0 0 1 1 1 1 0 1 1 1 0<br />
0 0 1 0 0 1 0 1 1 1 1 0<br />
0 0 1 0 1 1 1 1 0 1 1 0<br />
0 0 1 1 0 1 0 1 1 0 1 0<br />
0 0 1 1 1 1 1 1 1 0 1 0<br />
0 1 0 0 0 1 0 0 1 1 0 0<br />
0 1 0 0 1 1 1 0 0 1 0 0<br />
0 1 0 1 0 1 0 0 1 1 0 0<br />
0 1 0 1 1 1 1 0 1 1 0 0<br />
0 1 1 0 0 1 0 1 1 1 0 0<br />
0 1 1 0 1 1 1 1 0 1 0 0<br />
0 1 1 1 0 1 0 1 1 1 0 0<br />
0 1 1 1 1 1 1 1 1 1 0 0<br />
1 0 0 0 0 0 0 0 1 1 1 0<br />
1 0 0 0 1 0 1 0 0 1 1 0<br />
1 0 0 1 0 0 0 0 1 1 1 0<br />
1 0 0 1 1 0 1 0 1 1 1 0<br />
1 0 1 0 0 0 0 1 1 1 1 0<br />
1 0 1 0 1 0 1 1 0 1 1 0<br />
1 0 1 1 0 0 0 1 1 0 1 0<br />
1 0 1 1 1 0 1 1 1 0 1 0<br />
1 1 0 0 0 0 0 0 1 1 1 0<br />
1 1 0 0 1 0 1 0 0 1 1 0<br />
1 1 0 1 0 0 0 0 1 1 1 0<br />
1 1 0 1 1 0 1 0 1 1 1 0<br />
1 1 1 0 0 0 0 1 1 1 1 0<br />
1 1 1 0 1 0 1 1 0 1 1 0<br />
1 1 1 1 0 0 0 1 1 1 1 0<br />
1 1 1 1 1 0 1 1 1 1 1 0<br />
23
Kapitel A: Anhang<br />
A.3 Abarbeitungsreihenfolge von Anfragen an den <strong>Prolog</strong>-<br />
Interpreter (trace)<br />
Hinweis zu den Angaben Call, Redo, Exit und Fail:<br />
• Call: Beginn eines neuen Teilbeweises.<br />
• Redo: Wie<strong>der</strong>holung eines Teilbeweises mit an<strong>der</strong>er Variableninstanziierung.<br />
• Exit: Erfolgreiches Beenden eines Teilbeweises.<br />
• Fail: Scheitern eines Teilbeweises.<br />
Des Weiteren sei innerhalb des trace auf das _L165, welches die interne Repräsentation<br />
einer Variablen darstellt, und das creep (zu Deutsch: schleichen, kriechen), welches<br />
den Programmfluss wi<strong>der</strong>spiegelt, hingewiesen.<br />
?- trace , vorfahre ( hermann , florian ).<br />
true .<br />
Call : (9) vorfahre ( hermann , florian ) ? creep<br />
Call : (10) elternteil ( hermann , florian ) ? creep<br />
Call : (11) vater ( hermann , florian ) ? creep<br />
Fail : (11) vater ( hermann , florian ) ? creep<br />
Redo : (10) elternteil ( hermann , florian ) ? creep<br />
Call : (11) mutter ( hermann , florian ) ? creep<br />
Fail : (11) mutter ( hermann , florian ) ? creep<br />
Redo : (9) vorfahre ( hermann , florian ) ? creep<br />
Call : (10) elternteil ( _L165 , florian ) ? creep<br />
Call : (11) vater ( _L165 , florian ) ? creep<br />
Exit : (11) vater ( reinhold , florian ) ? creep<br />
Exit : (10) elternteil ( reinhold , florian ) ? creep<br />
Call : (10) vorfahre ( hermann , reinhold ) ? creep<br />
Call : (11) elternteil ( hermann , reinhold ) ? creep<br />
Call : (12) vater ( hermann , reinhold ) ? creep<br />
Exit : (12) vater ( hermann , reinhold ) ? creep<br />
Exit : (11) elternteil ( hermann , reinhold ) ? creep<br />
Exit : (10) vorfahre ( hermann , reinhold ) ? creep<br />
Exit : (9) vorfahre ( hermann , florian ) ? creep<br />
24
Literaturverzeichnis<br />
Literatur<br />
[Be86] F. Belli: Einführung in die logische Programmierung mit <strong>Prolog</strong>, Bibliografi-<br />
sches <strong>Institut</strong> Mannheim, 1986.<br />
[Be88] F. Belli: <strong>Prolog</strong>-Systeme in <strong>der</strong> Praxis, Mannheim, 1988.<br />
[Bo87] Wilhelm Bolkart: Programmiersprachen <strong>der</strong> 4. Und 5. Generation, Hamburg,<br />
1987.<br />
[CM03] William F. Clocksin, Christopher S. Mellish: Programming in <strong>Prolog</strong>, Sprin-<br />
ger, 2003.<br />
[CL90] R. Cordes, R. Kruse, H. Langendörfer, H. Rust: <strong>Prolog</strong>: Eine methodische<br />
Einführung, Vieweg, 1990.<br />
[KS88] Hans Kleine Büning, Stefan Schmittgen: <strong>Prolog</strong>: Grundlagen und Anwen-<br />
dungen, Teubner, 1988.<br />
[KS89] Esther König, Roland Seiffert: Grundkurs <strong>Prolog</strong> fur Linguisten, UTB Lin-<br />
guistik, 1989.<br />
[Sch00] Uwe Schöning: Logik <strong>für</strong> Informatiker, Spektrum, 2000.<br />
[Sa89] Dr. Stuart E. Savory: Expertensysteme: Nutzen <strong>für</strong> Ihr Unternehmen, R.<br />
Oldenbourg Verlag, 1989.<br />
[IF08] Applikationen, die auf IF/<strong>Prolog</strong> basieren<br />
URL: http://www.ifcomputer.de/Consulting/home de.html<br />
Abrufdatum: 04. März 2009.<br />
[ISO95] International Organization for Standardization<br />
URL: http://www.iso.org/iso/iso catalogue/catalogue tc/catalogue-<br />
detail.htm?csnumber=21413<br />
Abrufdatum: 04. März 2009.<br />
Der Originaltext zum ISO Standard ist nicht frei zugänglich.<br />
Einen Überblick von J.P.E. Hodgson über den ISO Standard (<strong>Prolog</strong>: The ISO<br />
Standard Documents) gibt es hier:<br />
URL: http://pauillac.inria.fr/ <strong>der</strong>ansar/prolog/docs.html<br />
Abrufdatum: 04. März 2009.<br />
25
Literaturverzeichnis<br />
[ISO00] International Organization for Standardization<br />
URL: http://www.iso.org/iso/iso catalogue/catalogue tc/catalogue de-<br />
tail.htm?csnumber=20775<br />
Abrufdatum: 04. März 2009.<br />
Der Originaltext zum ISO Standard ist nicht frei zugänglich.<br />
[FG00] Fifth Generation Project<br />
URL: http://encyclopedia.vbxml.net/Fifth Generation Computer<br />
Abrufdatum: 04. März 2009.<br />
[FG92] New York Times, 05.06.1992<br />
URL: http://query.nytimes.com/gst/fullpage.html?res=9E0CE1DB1031-<br />
F936A35755C0A964958260<br />
Abrufdatum: 04. März 2009.<br />
26