Prolog 13.06 =================== 1. Einleitung ************* Prolog (Programming in Logic) ist eine deklarative Programmiersprache, die in den 1970er Jahren von Alain Colmerauer und Robert Kowalski entwickelt wurde. Sie wird hauptsächlich in der künstlichen Intelligenz, insbesondere in der Wissensrepräsentation und der natürlichen Sprachverarbeitung, eingesetzt. Im Gegensatz zu imperativen Programmiersprachen wie C oder Java beschreibt man in Prolog nicht, wie ein Problem zu lösen ist, sondern was das Problem ist. Dies ermöglicht es, logische Zusammenhänge und Beziehungen direkt zu modellieren, weshalb sie auch als wichtigste logische Programmiersprache gilt.([1]_) Prolog basiert auf der mathematischen Logik, insbesondere der Prädikatenlogik erster Stufe. Programme in Prolog bestehen aus einer Menge von Regeln und Fakten, die zusammen eine Wissensbasis bilden. Anfragen an diese Wissensbasis werden als logische Schlussfolgerungen behandelt, und die Prolog-Engine sucht nach Beweisen für diese Anfragen, indem sie die Regeln und Fakten durchsucht. Dies wird als Rückwärtsverkettung (Backward Chaining) bezeichnet, ein Verfahren, bei dem das System versucht, das Ziel zu erreichen, indem es rückwärts von der Schlussfolgerung ausgehend arbeitet. Ein zentrales Konzept in Prolog ist das der Rekursion. Da Prolog keine Schleifenstrukturen wie imperativen Sprachen hat, werden wiederholende Berechnungen durch rekursive Regeln und Fakten abgebildet. Diese Herangehensweise ist besonders nützlich bei der Verarbeitung von Listen und anderen rekursiven Datenstrukturen. Beispiel einer einfachen Prolog-Datenbank: .. code-block:: prolog % Fakten mutter(maria, hans). mutter(anna, sofia). vater(johann, hans). vater(peter, sofia). % Regel elternteil(X, Y) :- mutter(X, Y). elternteil(X, Y) :- vater(X, Y). In diesem Beispiel sind mutter/2 und vater/2 Fakten, die ausdrücken, wer wessen Mutter oder Vater ist. Die Regel elternteil/2 definiert, dass jemand ein Elternteil ist, wenn er entweder Mutter oder Vater der betreffenden Person ist. Eine weitere Stärke von Prolog ist die Fähigkeit, natürliche Sprache zu verarbeiten. Dies ist möglich, weil Prolog einfach Struktur und Bedeutung von Sätzen modellieren kann. Projekte in der Sprachverarbeitung, wie Parsing-Systeme und Sprachdialogsysteme, profitieren von der deklarativen Natur der Sprache. Prolog wird auch in anderen Bereichen der künstlichen Intelligenz verwendet, wie zum Beispiel in Expertensystemen, wo es komplexe Regelbasen handhabt, und in der automatischen Beweisführung. Dank seiner deklarativen Natur ist Prolog besonders gut geeignet, um Probleme zu lösen, bei denen es auf die Beschreibung von Beziehungen und logischen Regeln ankommt. Zu den populären Implementierungen von Prolog gehören SWI-Prolog, GNU Prolog und Sicstus Prolog. Diese Implementierungen bieten Werkzeuge und Bibliotheken, die die Entwicklung von Prolog-Anwendungen unterstützen und die Integration mit anderen Programmiersprachen und Systemen erleichtern. Zusammenfassend lässt sich sagen, dass Prolog eine einzigartige Programmiersprache ist, die sich durch ihre Fähigkeit auszeichnet, logische Probleme und Beziehungen klar und präzise zu modellieren. Ihre Anwendungen in der künstlichen Intelligenz und anderen Bereichen machen sie zu einem wertvollen Werkzeug für Entwickler und Forscher. 2. Grundlagen ************* Prolog Syntax und Konzepte Prolog-Programme bestehen aus Fakten, Regeln und Abfragen: - *Fakten* beschreiben grundlegende Wahrheiten über die Welt. - *Regeln* definieren logische Beziehungen zwischen Fakten. - *Abfragen* werden genutzt, um Informationen aus der Datenbank abzuleiten. **Fakten:** Fakten in Prolog stellen grundlegende Aussagen über die Welt dar. Ein einfaches Beispiel eines Fakts könnte sein: Installation und Ausführung von Prolog: .. code-block:: prolog buch('Der Herr der Ringe'). Dies bedeutet, dass 'Der Herr der Ringe' ein Buch ist. **Regeln:** Regeln verbinden Fakten und beschreiben, wie verschiedene Fakten miteinander in Beziehung stehen. Eine Regel könnte folgendermaßen aussehen: .. code-block:: prolog autor_von(Titel, Autor) :- buch(Titel), geschrieben_von(Titel, Autor). Diese Regel besagt, dass jemand der Autor eines Buches ist, wenn das Buch von dieser Person geschrieben wurde. **Abfragen:** Abfragen werden verwendet, um Informationen aus der Datenbank abzuleiten. Zum Beispiel könnte die Abfrage: .. code-block:: prolog ?- autor_von('Der Herr der Ringe', Wer). Prolog anweisen, nachzusehen, wer der Autor von 'Der Herr der Ringe' ist. **Listen:** Prolog unterstützt auch das Arbeiten mit Listen, was eine wichtige Funktion zur Handhabung von Sequenzen von Elementen ist. Ein Beispiel für eine Liste wäre: .. code-block:: prolog ?- member(X, [apfel, banane, orange]). Dies fragt ab, ob X ein Mitglied der Liste [apfel, banane, orange] ist und gibt nacheinander apfel, banane und orange zurück. **Rekursion:** Ein wesentliches Konzept in Prolog ist die Rekursion, die es ermöglicht, wiederholende Strukturen zu durchlaufen und komplexe Abfragen zu formulieren. Ein Beispiel für eine rekursive Definition wäre: .. code-block:: prolog faktorielle(0, 1). faktorielle(N, Ergebnis) :- N > 0, N1 is N - 1, faktorielle(N1, F1), Ergebnis is N * F1. Diese Regel berechnet die Fakultät einer Zahl. **Unifikation:** Ein weiteres zentrales Konzept in Prolog ist die Unifikation, der Prozess, durch den Variablen mit Werten belegt werden, um Aussagen zu erfüllen. Beispielsweise wird in der Abfrage: .. code-block:: prolog ?- X = 3. die Variable X mit dem Wert 3 belegt. **Backtracking:** Prolog verwendet Backtracking, um alle möglichen Lösungen für eine Abfrage zu finden. Wenn eine bestimmte Lösung nicht funktioniert, geht Prolog zurück und versucht alternative Wege, bis alle Möglichkeiten ausgeschöpft sind. Dies ermöglicht es Prolog, komplexe logische Probleme effizient zu lösen. **Installation und Ausführung von Prolog:** Um Prolog-Dateien auszuführen, muss zuerst 'SWI-Prolog' installiert werden. Dies kann durch Herunterladen und Installieren von der offiziellen SWI-Prolog Webseite erfolgen. [2]_ Nach der Installation können Prolog-Dateien durch das Öffnen der Datei oder durch Eingabe von .. code-block:: prolog consult('Pfadname/Dateiname.pl'). in das SWI-Prolog-Terminal geladen werden. .. image:: img/Prolog-logo.png :scale: 50% ([Abb.1]_): Prolog Logo 3.Versuchsdurchführung *********************** Erklärung der Datei family.pl: Die Datei family.pl definiert eine Familie mit verschiedenen Verwandtschaftsbeziehungen. Zuerst werden einfache Fakten definiert. .. code-block:: prolog % Fakten über Geschlechter: mann(ted). mann(justin). frau(christine). % Fakten über Vater-Kind-Beziehungen: vater_von(christine, ted). vater_von(amelia, ted). % Fakten über Frau-Mann-Beziehungen: frau_von(ted, rosie). frau_von(justin, mia). Aussprache dieser Fakten: - Ted ist ein Mann: mann(ted). - Der Vater von Christine ist Ted: vater_von(christine, ted). - Die Frau von Ted ist Rosie: frau_von(ted, rosie). Zusätzlich zu den Fakten werden Regeln aufgestellt, die die bestehenden Fakten benutzen, um von ihnen Verwandtschaftsbeziehungen abzuleiten. .. code-block:: prolog geschwister(Kind1, Kind2) :- kind_von(Elternteil, Kind1), kind_von(Elternteil, Kind2), Kind1 \= Kind2. Hier werden zunächst die Eltern von 'Kind1' und 'Kind2' verglichen. Sind diese gleich wird noch sichergestellt, dass es sich nicht um die gleiche Person handelt. Ist dies auch der Fall, sind die beiden Personen Geschwister. .. code-block:: prolog bruder_von(Geschwister, Bruder) :- geschwister(Bruder, Geschwister), Bruder \= Geschwister, mann(Bruder). Zuerst wird geprüft, ob 'Bruder' und 'Geschwister' Geschwister sind. Das bedeutet, dass sie mindestens einen gemeinsamen Elternteil haben. Diese Überprüfung verwendet die Regel geschwister/2, die wir zuvor definiert haben. Danach wird sichergestellt, dass 'Bruder' und 'Geschwister' nicht die gleiche Person sind. Schließlich wird überprüft, ob Bruder männlich ist. Dies stellt sicher, dass nur männliche Geschwister als Brüder identifiziert werden. .. code-block:: prolog cousin_von(Person, Cousin) :- kind_von(Elternteil, Person), geschwister(Elternteil, Elternteil2), kind_von(Elternteil2, Cousin), mann(Cousin). Zunächst wird festgestellt, dass Elternteil ein Elternteil von 'Person' ist. Das gleiche gilt für 'Cousin'. Dann wird geprüft, ob 'Elternteil' ein Geschwister von 'Elternteil2' ist. Schließlich wird überprüft, ob 'Cousin' männlich ist. In Prolog dient die Variable 'X' in Abfragen als Platzhalter für unbekannte Werte, die durch die Auswertung der Abfrage ermittelt werden sollen. .. image:: img/Regeln1.png 'X' ermöglicht es, unbekannte Werte zu ermitteln, Bedingungen zu prüfen, Beziehungen zu analysieren und Listen oder Mengen von Ergebnissen zu generieren. Durch die Verwendung von 'X' kann man effizient Informationen aus der Wissensbasis extrahieren und komplexe Anfragen formulieren. Es ist auch möglich, mehrere Abfragen in einem Durchgang zu erfragen. .. image:: img/Regeln2.png Außerdem kann Rekursion in Funktionen eingebaut, um zum Beispiel alle Vorfahren einer Person zu erfragen. .. code-block:: prolog vorfahr_von(Nachkomme, Vorfahr):- kind_von(Vorfahr, Nachkomme). vorfahr_von(Nachkomme, Vorfahr) :- kind_von(ELTERN, Nachkomme), vorfahr_von(ELTERN, Vorfahr). Die erste Klausel definiert den Basisfall: - Sie stellt fest, dass 'Vorfahr' ein direkter Vorfahre (Elternteil) von 'Nachkomme' ist. Wenn 'Nachkomme' das Kind von 'Vorfahr' ist, dann ist 'Vorfahr' ein Vorfahre von 'Nachkomme'. Die zweite Klausel definiert den rekursiven Fall: - Diese Klausel sagt aus, dass 'Vorfahr' ein Vorfahre von 'Nachkomme' ist, wenn 'Eltern' ein Elternteil von 'Nachkomme' ist und 'Vorfahr' ein Vorfahre von 'Eltern' ist. - Hier wird rekursiv geprüft, ob 'Vorfahr' ein Vorfahre der Eltern von 'Nachkomme' ist, wodurch auch entfernte Vorfahren erfasst werden. .. image:: img/Regeln3.png Zum Schluss wurden Abfragen, wie Aufzählen und die Negation von Aussagen ausgetestet. - Wie viele Geschwister hat Sophia? .. code-block:: prolog findall(Geschwister, geschwister(sophia, Geschwister), Liste), length(Liste, AnzahlGeschwister). Erklärung der Funktion: - 'findall/3' ist ein eingebautes Prädikat in Prolog. - 'Geschwister': Eine Variable, die jede mögliche Lösung für die Anfrage 'geschwister(hanna, Geschwister)' aufnimmt. - 'Liste': Eine Liste, in der alle gefundenen Geschwister von 'hanna' gesammelt werden. Diese Liste wird in der 'length/2' Funktion verwendet. - 'length/2' ist ebenfalls ein eingebautes Prädikat in Prolog. - 'Liste': Die Liste der gefundenen Geschwister von 'hanna'. - 'AnzahlGeschwister': Eine Variable, die die Länge der Liste speichert, also die Anzahl der Elemente in der Liste. .. image:: img/Regeln4.png Hier musste man eine eigene Funktion zum Zählen implementieren, da Prolog keine eigene Funktion zum Zählen oder Summieren hat. - Wer ist NICHT Peters Vater? .. code-block:: prolog % Zeichen für Negation: \+ mann(X), \+ vater_von(peter, X). .. image:: img/Regeln5.png Bei dieser Funktion muss darauf geachtet werden, dass Prolog keine 'direkte' Negation von Anfragen unterstützt. Die Negation, die in Prolog einsetzbar ist, kann nur sicherstellen, dass etwas nicht bewiesen werden kann. Das kann zu unvollständigen Ergebnissen führen. 4. Fazit ******** Prolog ist ein mächtiges Werkzeug zur Modellierung logischer Zusammenhänge und Beziehungen. Die Datei family.pl zeigt, wie man eine einfache Familienstruktur und verschiedene Verwandtschaftsbeziehungen modellieren kann. Mit Prolog lassen sich komplexe Abfragen und Regeln formulieren, die in anderen Programmiersprachen schwierig umzusetzen wären. Ein großer Vorteil von Prolog ist, dass man sich auf das "Was" konzentrieren kann, anstatt auf das "Wie". Das bedeutet, dass man in Prolog nur beschreiben muss, was das Problem ist, und nicht, wie man es löst. Dadurch wird es einfacher, komplexe logische Beziehungen darzustellen. Prolog ist besonders gut darin, rekursive Strukturen und Listen zu verarbeiten, was in vielen Anwendungen der künstlichen Intelligenz wichtig ist. In Zukunft könnte das Modell in family.pl erweitert werden, um weitere Verwandtschaftsbeziehungen und komplexere logische Abhängigkeiten darzustellen, wie zum Beispiel Onkel, Tanten oder Cousins. Prolog kann auch in vielen anderen Bereichen der künstlichen Intelligenz eingesetzt werden, wie Expertensystemen oder der Robotik. Zusammenfassend ist Prolog eine einzigartige und leistungsstarke Programmiersprache, die es ermöglicht, logische Probleme auf eine einfache und direkte Weise zu lösen. Mit weiteren Entwicklungen und Anpassungen kann Prolog auch in Zukunft eine wichtige Rolle bei der Lösung komplexer logischer Probleme spielen. 5. Literaturangaben: ******************** .. [1] https://de.wikipedia.org/wiki/Prolog_(Programmiersprache) .. [2] https://www.swi-prolog.org/ Abbildungen: .. [Abb.1] https://dashboard.snapcraft.io/site_media/appmedia/2020/04/Prolog-logo-512.png