Ubuntu 12.04 „Precise Pangolin“
Prolog ist eine logische Programmiersprache, die Anfang der 1970er Jahre vom Franzosen Alan Colmerauer entwickelt wurde. Der Name des Programmes ergibt sich aus dem Französischen "Programmation en Logique" (Programmieren in Logik). Prolog dient der deklarativen Programmierung, d.h. dass hierbei die Problembeschreibung im Vordergrund steht und das Programm die Problemlösung selbstständig findet.
Prolog baut auf Wissensbasen auf. Wissenbasen sind einfache Textdokumente, die in einem Texteditor erstellt werden. Hierin werden Fakten und Regeln festgehalten. Um Regeln formulieren und verstehen zu können, sollten Kenntnisse in derPrädikatenlogik vorhanden sein. Die Datei muss als .pl gespeichert werden, wodurch unter Umständen Verwechslungsmöglichkeiten mit Perl-Skripten auftreten können.
Dieser Artikel befasst sich vor allem mit der Prolog-Implementierung durch SWI . Das GNU-Projekt bietet aber auch Prolog-Pakete an: GNU Prolog
(welches auch über die offiziellen Paketquellen installierbar ist).
Leider gibt es keinen einheitlichen Prolog-Standard, sondern verschiedene Dialekte, die nicht 100% zueinander kompatibel sind.
Um SWI-Prolog nutzen zu können, muss das folgende Paket mit seinen Abhängigkeiten installiert [1] werden:
swi-prolog (universe)
mit apturl
Paketliste zum Kopieren:
sudo apt-get install swi-prolog
sudo aptitude install swi-prolog
Am Besten navigiert man direkt in den Ordner, in dem sich die Wissensbasen befinden und startet hier Prolog auf der Kommandozeile [3]:
swipl
Das Programm öffnet sich nun in der Konsole und lässt sich hierin bedienen. Zum Stoppen des Programms muss der Befehl halt.
eingegeben werden.
Bei Prolog werden Befehle immer mit einem Punkt (.
) abgeschlossen. Fehlt dieser wird der Befehl nicht ausgeführt. Das ist eine häufige Fehlerquelle. Das Programm besitzt ähnliche Merkmale wie die Bash, so kann durch Betätigen der Pfeiltasten durch die eingegebenen Befehle navigiert werden und durch die Tab-Taste
Tab ⇆ Dateinamen vervollständigt werden.
Prolog kennt drei unterschiedliche Zustände: den Start- bzw. Normalzustand, "trace" - hierbei zeigt Prolog die einzelnen Schritte, die es ausführt an - und "debug" - der Modus zur Fehlerbehebung. Diese Zustände können durch die Eingabe des Wortes aufgerufen werden. Beendet werden sie mit einem no
vor dem jeweiligen Wort, bspw. notrace
oder nodebug
.
Prädikate besitzen in Prolog eine Stelligkeit. Sie wird beispielsweise durch NAME/1
gekennzeichnet, d.h. das Prädikat NAME
ist einstellig.
Hier ist eine unvollständige Auflistung der Befehle, die Prolog von Haus aus kennt.
Übersicht | |
Befehl | Beschreibung |
[DATEINAME]. | Lädt die aktuelle Wissensbasis ein, wenn man Prolog im richtigen Verzeichnis gestartet hat. Der Dateiname muss ohne .pl eingegeben werden und darf nur kleingeschrieben werden. |
['/PFAD/ZU/DATEINAME.pl']. | Lädt die aktuelle Wissensbasis ein, ohne im gleichen Verzeichnis zu sein. |
, | Konjunktion (Logischs Und) |
; | Disjunktion (Logisches Oder) |
:- | Implikation (Wenn, dann) |
\= | Negation (Logische Verneinung) |
[H|T]. bzw. [X,Y,Z] bzw. [1,2,3] | Listennotation, | ist der Trenner für Kopf (H) und Rest der Liste (T). |
_ | Meint eine anonyme Variable (hier ist der Wert, den die Variable einnimmt, nicht von Interesse). |
! | cut, Der Cut kann in einem komplexen Term eingebracht werden. Wenn Prolog bei der Abarbeitung der Klauseln hinter die Stelle des Cuts gelangt, ist es für das Programm nicht mehr möglich, davor zu gelangen. |
\+ | schwache Negation, Durch die Resolution kann der Satz nicht als wahr belegt werden, so dass davon ausgegangen wird, dass der Satz unwahr ist. |
listing. | Zeigt den Inhalt der aktuellen Wissensbasis an. |
listing(TERM). | Prüft, ob ein bestimmter Term in der Wissensbasis ist. |
trace. bzw. notrace. | Startet und beendet den Tracemodus. |
'ATOMNAME' | Einfache Anführungszeichen oben kennzeichnen ein Atom. |
asserta() | Fügt einen Term oder einen Fakt an den Anfang die aktuelle Wissensbasis an. |
assaertz() | Fügt einen Term oder einen Fakt ans Ende der aktuellen Wissensbasis an. |
append/3 | Definition:append([],L,L). (Abbruchbedingung)append([H|T],L2,[H|L3]):- append(T,L2,L3). fügt zwei Listen zusammen und ist ein dreistelliger Term |
prefix/2 | Baut auf append auf und gibt die Prefixe einer Liste an:prefix(P,L):- append(P,_,L). |
suffix/2 | Baut ebenfalls auf append/3 auf; gibt aber das Ende einer Liste aus.suffix(S,L):- append(_,S,L). |
Die folgenden Beispiele sind angelehnt an den Onlinekurs Learn Prolog Now .
Gegeben sei eine Straße mit drei Häusern, die alle eine andere Farbe (rot, blau und grün), von anderen Nationalitäten bewohnt werden und alle ein anderes Haustier haben. Zudem weiß man, dass:
Der Australier im roten Haus wohnt.
Der Tiger bei der italienischen Familie lebt.
Der Chinese rechts vom Eidechsenbesitzer wohnt.
Der Eidechsenbesitzer links vom blauen Haus wohnt.
Die Frage ist nun, wo wohnt das Nilpferd? Natürlich kann man die Antwort logisch erschließen, aber Aufgabe ist, es ein Prädikat zu definieren, dass diese Aufgabe übernimmt. Das Prädikat heißt nilpferd
und ist einstellig.
1 2 3 4 5 6 7 8 9 10 | nilpferd(N):- Street=[Haus1,Haus2,Haus3], mitglied(haus(rot,_,_),Street), mitglied(haus(blau,_,_),Street), mitglied(haus,(grün,_,_),Street), mitglied(haus(rot,australier,_),Street), mitglied(haus(_,italiener,tiger),Street), sublist(haus(_,_,eidechse),haus(_,chinese,_),Street), sublist(haus(blau,_,_),haus (_,_,eidechse),Street) mitglied(haus(_,N,nilpferd);Street). |
Gegeben ist folgende Wissenbasis:
1 2 3 4 5 6 7 | direktZug(saarbruecken,dudweiler). direktZug(forbach,saarbruecken). direktZug(freyming,forbach). direktZug(stAvold,freyming). direktZug(fahlquemont,stAvold). direktZug(metz,fahlquemont). direktZug(nancy,metz). |
Nun soll ein Prädikat definiert werden, dass reiseVonZu/2
heißt. Das Prädikat ist zweistellig und muss rekursiv definiert werden.
1 | reiseVonZu(X,Z):- direktZug(X,Y), reiseVonZu(Z,Y). |
Die neue Wissensbasis würde so aussehen:
1 2 3 4 5 6 7 8 9 | direktZug(saarbruecken,dudweiler). direktZug(forbach,saarbruecken). direktZug(freyming,forbach). direktZug(stAvold,freyming). direktZug(fahlquemont,stAvold). direktZug(metz,fahlquemont). direktZug(nancy,metz). reiseVonZu(X,Z):- direktZug(X,Y), reiseVonZu(Z,Y). |
Nun kann Prolog nicht nur die direkten Verbindungen feststellen, sondern auch Verbindungen, die Zwischenstationen in anderen Städten haben.