20.02.2013 Aufrufe

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 ...

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!