Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objected Oriented Programming in SWI-Prolog

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.

like image 289
user27815 Avatar asked Jan 26 '15 16:01

user27815


People also ask

Is Prolog object-oriented?

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.

What is SWI-Prolog programming language?

SWI-Prolog is a free implementation of the programming language Prolog, commonly used for teaching and semantic web applications.

How do I create a SWI file in Prolog?

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.

Is SWI-Prolog open source?

SWI-Prolog offers a comprehensive free Prolog environment.

What is SWI-Prolog?

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.

How can I use Prolog in web programming?

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.

What is the best system for OOP in Prolog?

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.

What is object oriented programming (OOP)?

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.


1 Answers

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.

like image 96
Paulo Moura Avatar answered Sep 30 '22 11:09

Paulo Moura