I read somewhere that you can think of modules as objects in Prolog. I am trying to get my head around this, and if it a good way to code.
If I have two files, one defining a class dog and then another one that uses this class to make two dog objects.
:- module(dog,
[ create_dog/4,bark/1 ]).
create_dog(Name,Age,Type,Dog):-
Dog = dog(name(Name),age(Age),type(Type)).
bark(Dog):-
Dog = dog(name(_Name),age(_Age),type(Type)),
Type = bassethound,
woof.
bark(Dog):-
Dog = dog(name(_Name),age(_Age),type(Type)),
Type \= bassethound,
ruff.
woof:-format("woof~n").
ruff:-format("ruff~n").
second file
use_module(library(dog)).
run:-
dog:create_dog('fred',5,bassethound,Dog),
forall(between(1,5,_X),
dog:bark(Dog)
),
dog:create_dog('fido',6,bloodhound,Dog2),
dog:bark(Dog2).
This makes a dog object Dog which is a basset hound and makes it bark 5 times,
I then make another dog object Dog2 which is a bloodhound and make this also bark. I understand that in oop you have objects that have behaviours and state. So I now have two objects with different behaviours based on their own states but at the moment I am storing the state of the objects in the Dog variables where they can be seen by the code in the main program. Is there a way to hide the state of the objects i.e to have private variables?
For example I might want to have a way of storing the state has_barked for each dog object, which would be true if it has barked earlier in the program and false otherwise, then change the behaviour of bark/1
based on this.
Also how would you handle inheritance and overriding methods etc? Any pointer to readings welcomed. Thank you.
Prolog++ Prolog++ is an object-oriented toolkit for the Prolog logic programming language. It allows classes and class hierarchies to be created within Prolog programs.
SWI-Prolog is a free implementation of the programming language Prolog, commonly used for teaching and semantic web applications.
Double-click the Prolog program icon. Use the File menu of the resulting window to create a new file and give it a name, with the extension . pl, making sure you save it at the root level of your M drive. . Enter the text of your file in the file window.
SWI-Prolog offers a comprehensive free Prolog environment.
WIKI SWI-Prolog offers a comprehensive free Prolog environment. Since its start in 1987, SWI-Prolog development has been driven by the needs of real world applications. SWI-Prolog is widely used in research and education as well as commercial applications.
For example, the web programming libraries of SWI Prolog allows one to create REST API interfaces that take a JSON query from outside the Prolog system, and return the result in JSON format. This allows one to make use of Prolog to solve tasks that it is good at, while being able to write the rest of the application using another language.
the PCE system in SWI-Prolog is also an option for OOP in Prolog. It's usually associated with xpce, the GUI system, but it's actually a general purpose class based OO system. Show activity on this post.
Object Oriented programming (OOP) is a programming paradigm that relies on the concept of classes and objects. It is used to structure a software program into simple, reusable pieces of code blueprints (usually called classes), which are used to create individual instances of objects.
Just an example of one of the possible reimplementations of your sample code in Logtalk. It uses prototypes for simplicity but it still illustrates some key concepts including inheritance, default predicate definitions, static and dynamic objects, and parametric objects.
% a generic dog
:- object(dog).
:- public([
create_dog/3, bark/0, name/1, age/1
]).
create_dog(Name, Age, Dog) :-
self(Type),
create_object(Dog, [extends(Type)], [], [name(Name),age(Age)]).
% default definition for all dogs
bark :-
write(ruff), nl.
:- end_object.
:- object(bassethound,
extends(dog)).
% bark different
bark :-
write(woof), nl.
:- end_object.
:- object(bloodhound,
extends(dog)).
:- end_object.
% support representing dogs as plain database facts using a parametric object
:- object(dog(_Name,_Age,_Type),
extends(dog)).
name(Name) :-
parameter(1, Name).
age(Age) :-
parameter(2, Age).
bark :-
parameter(3, Type),
[Type::bark].
:- end_object.
% a couple of (static) dogs as parametric object proxies
dog(fred, 5, bassethound).
dog(fido, 6, bloodhound).
% another static object
:- object(frisbee,
extends(bloodhound)).
name(frisbee).
age(1).
:- end_object.
Some sample queries:
$ swilgt
...
?- {dogs}.
% [ /Users/foo/dogs.lgt loaded ]
% (0 warnings)
true.
?- bassethound::bark.
woof
true.
?- bloodhound::bark.
ruff
true.
?- bassethound::create_dog(boss, 2, Dog).
Dog = o1.
?- o1::bark.
woof
true.
?- {dog(Name, Age, Type)}::bark.
woof
Name = fred,
Age = 5,
Type = bassethound ;
ruff
Name = fido,
Age = 6,
Type = bloodhound.
?- dog(ghost, 78, bloodhound)::(bark, age(Age)).
ruff
Age = 78.
?- forall(between(1,5,_X), {dog(fred,_,_)}::bark).
woof
woof
woof
woof
woof
true.
Some notes. ::/2
is the message sending control construct. The goal {Object}::Message
simply proves Object
using the plain Prolog database and then sends the message Message
to the result. The goal [Object::Message]
delegates a message to an object while keeping the original sender.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With