Was ist Prolog?
Prolog (Programmation en logique, 1972, Alain Colmerauer) ist eine deklarative Sprache: Du beschreibst was gilt (Fakten und Regeln), nicht wie es berechnet wird. Anschließend stellst du Anfragen, und Prolog sucht durch Unifikation und Backtracking alle Lösungen.
Typische Einsatzgebiete: Expertensysteme, natürliche Sprachverarbeitung, Planungs- und Rätselprobleme, Regelwerke, Datenbanken (Datalog) und Teile von IBM Watson. Dieser Kurs nutzt SWI-Prolog.
Ausführen
swipl hallo.pl # interaktiv: ?- main.
swipl -q -g main -t halt hallo.pl # main ausführen und beenden
swipl # leere interaktive Konsole
?- consult('hallo.pl'). % Datei laden (in der Konsole)In der Konsole stellst du Anfragen (?- ...), mit ; fragst du nach weiteren Lösungen. Jeder Satz endet mit einem Punkt.
Das erste Programm
main :-
write('Hallo, Welt!'), nl,
X is 1 + 2,
format("1 + 2 = ~w~n", [X]),
print(42), nl,
format("~a hat ~d Punkte~n", [mia, 17]).Ausgabe
Hallo, Welt! 1 + 2 = 3 42 mia hat 17 Punkte
:- bedeutet „wenn“. , ist „und“. nl schreibt einen Zeilenumbruch, format/2 formatiert mit ~w (beliebig), ~a (Atom), ~d (Ganzzahl), ~n (Zeilenumbruch).
Fakten, Regeln und Anfragen
Der Kern von Prolog: eine Wissensbasis aus Fakten und Regeln.
% Fakten
elternteil(anna, ben).
elternteil(anna, clara).
elternteil(ben, dora).
elternteil(clara, emil).
% Regeln
grosselternteil(G, E) :- elternteil(G, X), elternteil(X, E).
geschwister(A, B) :- elternteil(E, A), elternteil(E, B), A \= B.
main :-
( grosselternteil(anna, dora) -> writeln('anna ist Großelternteil von dora') ; writeln(nein) ),
forall(grosselternteil(anna, E), (write(E), nl)),
findall(K, elternteil(anna, K), Kinder),
writeln(Kinder),
( geschwister(ben, clara) -> writeln('ben und clara sind Geschwister') ; true ).Ausgabe
anna ist Großelternteil von dora dora emil [ben,clara] ben und clara sind Geschwister
Bausteine der Sprache
| Begriff | Beispiel | Bedeutung |
|---|---|---|
| Atom | mia, 'Hallo Welt' | Konstante (klein geschrieben) |
| Zahl | 42, 3.14 | Ganz- oder Fließkommazahl |
| Variable | X, Name, _ | Großbuchstabe oder Unterstrich |
| Struktur | punkt(1, 2) | Funktor mit Argumenten |
| Liste | [1, 2, 3] | Folge von Termen |
| Fakt | vogel(spatz). | wahre Aussage |
| Regel | fliegt(X) :- vogel(X). | Folgerung |
Unifikation
= versucht, zwei Terme gleich zu machen (zu unifizieren):
main :-
X = 5, writeln(X),
punkt(A, B) = punkt(1, 2), writeln(A-B),
[Kopf|Rest] = [a, b, c], writeln(Kopf), writeln(Rest),
( f(a) = f(b) -> writeln(gleich) ; writeln(ungleich) ),
( 1 + 2 =:= 3 -> writeln('rechnerisch gleich') ; true ),
( 1 + 2 = 3 -> true ; writeln('als Terme nicht gleich') ).Ausgabe
5 1-2 a [b,c] ungleich rechnerisch gleich als Terme nicht gleich
So führst du den Code aus: Datei hallo.pl speichern und mit swipl -q -g main -t halt hallo.pl ausführen (SWI-Prolog von swi-prolog.org).
Merke
- Prolog ist deklarativ: Fakten und Regeln beschreiben Wissen, Anfragen suchen Lösungen
- Atome klein, Variablen groß; jeder Satz endet mit einem Punkt
:-heißt „wenn“,,heißt „und“,;heißt „oder“- Unifikation (
=) gleicht Terme an,isrechnet arithmetisch
Aufgabe
Modelliere eine Familie mit mindestens fünf elternteil-Fakten und definiere grosselternteil.