Objected Oriented Programming in SWI-Prolog

8

Ich habe irgendwo gelesen, dass man sich Module als Objekte in Prolog vorstellen kann. Ich versuche, meinen Kopf dazu zu bringen, und wenn es ein guter Weg zu programmieren ist.

Wenn ich zwei Dateien habe, eine, die einen Klassenhund definiert, und dann eine andere, die diese Klasse benutzt, um zwei Hundeobjekte zu erstellen.

%Vor%

zweite Datei

%Vor%

Dies macht einen Hund-Objekt-Hund, der ein Basset-Hund ist und macht es 5 Mal bellen, Ich mache dann einen anderen Hund Gegenstand Dog2, der ein Bluthund ist und dies auch Rinde machen. Ich verstehe, dass Sie in oop Objekte haben, die Verhalten und Zustand haben. So habe ich jetzt zwei Objekte mit unterschiedlichen Verhaltensweisen, die auf ihren eigenen Zuständen basieren, aber im Moment speichere ich den Zustand der Objekte in den Dog-Variablen, wo sie durch den Code im Hauptprogramm gesehen werden können. Gibt es eine Möglichkeit, den Zustand der Objekte zu verbergen, d. H. Private Variablen zu haben? Zum Beispiel möchte ich vielleicht eine Möglichkeit haben, den Zustand has_barced für jedes Hund-Objekt zu speichern, was wahr wäre, wenn es früher im Programm gebellt wurde, und andernfalls falsch, dann ändere das Verhalten von bark/1 basierend darauf.

Wie würden Sie auch mit Vererbungs- und Überschreibungsmethoden umgehen? Jeder Hinweis auf Lesungen wurde begrüßt. Danke.

    
user27815 26.01.2015, 16:14
quelle

6 Antworten

7

Nur ein Beispiel für eine der möglichen Neuimplementierungen Ihres Beispielcodes in Logtalk. Es verwendet Prototypen zur Vereinfachung, aber es zeigt immer noch einige Schlüsselkonzepte wie Vererbung, Standardprädikatdefinitionen, statische und dynamische Objekte und parametrische Objekte.

%Vor%

Einige Beispielabfragen:

%Vor%

Einige Notizen. ::/2 ist das Steuerungskonstrukt zum Senden von Nachrichten. Das Ziel {Object}::Message beweist einfach Object mit der einfachen Prolog-Datenbank und sendet dann die Nachricht Message an das Ergebnis. Das Ziel [Object::Message] delegiert eine Nachricht an ein Objekt, während der ursprüngliche Absender beibehalten wird.

    
Paulo Moura 27.01.2015, 01:31
quelle
4

Prolog-Module können trivial als Objekte (speziell als Prototypen) interpretiert werden. Prolog-Module können dynamisch erstellt werden, haben einen Namen, der als ihre Identität angesehen werden kann (da sie in einer laufenden Sitzung eindeutig sein muss, da der Modul-Namespace flach ist) und dynamischen Status haben kann (mit lokalen dynamischen Prädikaten). In den meisten Systemen bieten sie jedoch eine schwache Kapselung in dem Sinne, dass Sie jedes Modulprädikat mit expliziter Qualifizierung aufrufen können (das heißt, mindestens ein System, ECLiPSe, ermöglicht es Ihnen, ein Modul zu sperren, um auf diese Weise die Kapselung zu verhindern). Es gibt auch keine Unterstützung für die Trennung der Schnittstelle von der Implementierung oder mehrere Implementierungen der gleichen Schnittstelle (Sie können es irgendwie hacken, abhängig vom Prolog Modulsystem, aber es ist nicht schön).

Logtalk, wie in anderen Antworten erwähnt, ist eine sehr portable objektorientierte Erweiterung von Prolog, die die meisten Systeme unterstützt, einschließlich SWI-Prolog. Logtalk-Objekte subsumieren Prolog-Module, sowohl in konzeptioneller als auch in praktischer Hinsicht. Der Logtalk-Compiler unterstützt einen gemeinsamen Kern von Modulfunktionen. Sie können es z.B. Schreiben von Modulcode in Prolog-Implementierungen ohne ein Modulsystem. Logtalk kann Module als Objekte kompilieren und unterstützt bidirektionale Aufrufe zwischen Objekten und Modulen.

Beachten Sie, dass Objekte in der Logikprogrammierung am besten als Codeverkapselungs- und Codewiederverwendungsmechanismus angesehen werden. Genau wie Module. OO-Konzepte können (und wurden) erfolgreich in anderen Programmierparadigmen angewendet werden, einschließlich Funktion und Logik. Das heißt aber nicht notwendigerweise zwingend / prozedurale Konzepte mitzubringen. Als ein Beispiel können die Beziehungen zwischen einer -Instanz und ihrer -Klasse oder zwischen einem -Prototyp als -Parallel interpretiert werden B. ein Muster der Wiederverwendung von Code angeben , anstatt aus einem dynamischen / Zustandssichtpunkt gesehen zu werden (tatsächlich ist eine Instanz in OOP-Sprachen, die aus Imperativ- / prozeduralen Sprachen abgeleitet sind, wenig mehr als ein verherrlichter dynamische Datenstruktur, deren Spezifikation zwischen ihrer Klasse und ihren Klassenüberklassen verteilt ist.

Wenn Sie Ihren Beispielcode berücksichtigen, können Sie ihn problemlos in Logtalk in der Nähe Ihrer Formulierung rekodieren, aber auch auf andere Weise, wobei die interessantesten davon keine dynamischen Funktionen verwenden. Der Speicherungszustand (wie im dynamischen Zustand) ist manchmal notwendig und kann sogar die beste Lösung für bestimmte Probleme sein (Prolog hat aus gutem Grund dynamische Prädikate!), Sollte aber vorsichtig und nur dann verwendet werden, wenn es wirklich notwendig ist. Die Verwendung von Logtalk ändert das nicht (oder beabsichtigt, es zu ändern).

Ich schlage vor, dass Sie sich die umfangreiche Logtalk-Dokumentation und ihre zahlreichen Programmierbeispiele ansehen. Dort finden Sie, wie z. sauberes Trennen der Schnittstelle von der Implementierung, Verwendung von Komposition, Vererbung, Spezialisierung oder Außerkraftsetzung von übernommenen Prädikaten usw.

    
Paulo Moura 26.01.2015 21:09
quelle
3

Logtalk ist effektiv das prominente objektorientierte Prolog, das heute verfügbar ist. Paulo hat es als Paket zur Verfügung gestellt, daher sollte die Installation sehr einfach sein.

Module sind nicht wirklich für die Objektorientierung geeignet. Sie sind Namespaces ähnlicher, aber ohne Nesting. Auch der ISO-Standard ist ein bisschen kontrovers.

SWI-Prolog v7 führte dicts ein, eine Erweiterung, die zumindest ein historisches Problem von die Sprache und stellen "Felder" namentlich, und eine Syntax für "Methoden" zur Verfügung. Aber immer noch keine Vererbung ...

Bearbeiten

Ich habe hier ein kleines Beispiel für Objektorientierung in SWI-Prolog hinzugefügt. Es ist eine Weiterentwicklung meiner Testanwendung zum Erstellen von Genealogiebäumen.

Vergleichen Sie die genealogy.pl Quellen, Sie können schätzen, wie die neueste Version den Modulbezeichner anstelle der Direktive verwendet: - multifile, und kann dann mit mehreren Bäumen arbeiten.

Sie können sehen, dass das aufrufende Modul den Diagramm-Konstruktionscode übergibt, und haben optionale oder obligatorische Prädikate, die durch Modulqualifizierung aufgerufen werden:

%Vor%

optionale Prädikate müssen wie

aufgerufen werden %Vor%

Beachten Sie, dass Prädikate von den Anwendungsmodulen nicht exportiert werden. Beim Exportieren von ihnen, AFAIK, bricht die Objektorientierung.

==========

Ein anderes, vielleicht trivialeres Beispiel für Objektorientierung ist das Modul pqGraphviz_emu, wo ich einen einfachen Ersatz für Objekte auf Systemebene erstellte.

Ich erkläre: pqGraphviz ist eine winzige Schicht - geschrieben in Qt - über die Graphviz-Bibliothek. Graphviz - wenn auch in C - hat eine objektorientierte Schnittstelle. Tatsächlich ermöglicht die API, relevante Objekte (Graphen, Knoten, Links) zu erstellen und ihnen dann Attribute zuzuweisen. Meine Ebene versucht, die API möglichst originalgetreu zu halten. Zum Beispiel erstellt Graphviz einen Knoten mit

%Vor%

Dann habe ich mit der C ++ - Schnittstelle

geschrieben %Vor%

Wir tauschen Zeiger aus, und ich habe die Qt-Metatyp-Einrichtung eingerichtet, um mit der Typisierung umzugehen ... aber da die Schnittstelle ziemlich niedrig ist, habe ich normalerweise eine winzige mittlere Ebene, die eine anwendungsfreundlichere Ansicht bietet, und es ist diese mittlere Ebene Schnittstelle, die von genealogy.pl aufgerufen wird:

%Vor%

In diesem Snippet sehen Sie ein Beispiel für die SWI-Prolog v7 dicts:

%Vor%

Das Speicherzuordnungsschema wird in allocator.pl behandelt.

    
CapelliC 26.01.2015 18:20
quelle
2

Das PCE-System in SWI-Prolog ist auch eine Option für OOP in Prolog. Es ist normalerweise mit xpce, dem GUI-System, verbunden, aber es ist eigentlich ein universelles klassenbasiertes OO-System.

    
Anniepoo 27.01.2015 21:12
quelle
2

Sehen Sie sich logtalk an. Es ist eine Art objektorientierte Erweiterung von Prolog.

Ссылка

    
schrobe 26.01.2015 16:48
quelle
0

Heutzutage hat SWI Prolog dicts, die mit den Modulen auf eine nette Weise interagieren. Siehe Die SWI-Prolog-Handbuchseite zu Dicts , insbesondere Abschnitt 5.4.1.1: Benutzerdefinierte Funktionen auf Dicts .

Damit können Sie Dinge definieren, die genau wie Methoden aussehen, bis hin zu Rückgabewerten (ungewöhnlich, aber sehr nützlich in Prolog).

Anders als in einigen anderen Antworten besprochen, finde ich persönlich, dass die Logikprogrammierung und die OOP-Paradigmen zueinander orthogonal sind: Es tut definitiv nicht weh, Ihren Logikcode mithilfe der OOP-Modularität strukturieren zu können ...

    
tjltjl 28.07.2017 08:00
quelle

Tags und Links