Page 1 of 1
Q on objects
Posted: Mon Jan 28, 2019 12:44 am
by jdoran
I have been lurking for a while, but finally found the time to seriously investigate Logtalk.
I have a project that I'm planning, where I think of the data as frames. The inheritance of Logtalk appeals to me as a good match. This is my motivation for investigating Logtalk.
I have a large project written in SWI Prolog, and decided that I would take parts of the knowledge base and try to express it in terms of protocols/classes/objects. My early experiments are going OK, but I ran into a snag.
If I have an object, similar to:
:- object(rock,
implements(item)).
size(small).
:- end_object.
I can certainly ask questions about a rock. But what if I want a set of objects which are small?
X::size(small). -- nope
I think it would be a good start if I could figure out how to organize a knowledge base so that it can handle queries along this line.
This is a toy example, but illustrates what I'm after -- Give me a set of objects that match some criteria.
What would be a good approach to doing this?
Re: Q on objects
Posted: Mon Jan 28, 2019 2:20 pm
by Paulo Moura
A first approach would be to enumerate the currently defined objects and send to them the size/1 message:
Code: Select all
| ?- current_object(Object), Object::size(small).
But this would result in predicate existence errors for any object that does not understand the size/1 message. To avoid these errors, we could use instead:
Code: Select all
| ?- current_object(Object), Object::(current_predicate(size/1), Object::size(small).
Note that the complexity of this solution is O(n) with n being the number of defined objects. When using protocols, a possible alternative solution is to only consider the objects that conform to a specific protocol (and thus understand a particular message). For example:
Code: Select all
| ?- conforms_to_protocol(Object, phisical_properties), Object::size(small).
This solution is still O(n), however. Other alternatives are possible. For example, keeping track of objects that implement a given protocol. This would require some book-keeping but it would have better performance.
Re: Q on objects
Posted: Mon Jan 28, 2019 11:49 pm
by jdoran
Thanks.
My test already has a protocol in place, so I was able to try both solutions.
conforms_to_protocol() returns classes that implement the protocol. Even when I try something like:
Code: Select all
conforms_to_protocol(Object, item), Object::current_predicate(size/1), Object::size(small)
I get an error: "ERROR: object class-name does not exist"
Here is a little test of what I'm trying to do (with little understanding of Logtalk at the moment).
Code: Select all
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% item
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
:- protocol(item).
:- info([
version is 1.0,
author is 'Jonathon Doran',
date is 2019/1/27,
comment is 'item base class'
]).
:- public([
id/1, % database ID, used as unique identifier
name/1, % printable name
size/1 % small, medium, large
]).
:- end_protocol.
:- protocol(findable).
:- public([
source/1
]).
:- end_protocol.
:- category(weapon,
implements(item)).
:- public([
skill/1
]).
:- end_category.
:- category(food,
implements(item)).
:- public([
edible/0,
meat/0,
grown/0
]).
edible.
meat :- fail.
grown :- fail.
:- end_category.
%%%%%%%%%%%%%%%%%%%%%%%%%%
:- object(dagger,
imports(weapon),
implements(findable)).
id(7001).
name('dagger').
source(quest).
size(small).
skill(edged).
:- end_object.
:- object(egg,
imports(food),
implements(findable)).
id(7).
name('egg').
source(found).
size(small).
edible :- % test of overriding category
fail.
:- end_object.
:- object(bear_meat,
imports(food)).
id(8153).
name('bear meat').
source(found).
meat.
:- end_object.
And some output:
Code: Select all
?- conforms_to_protocol(Object, item), Object::current_predicate(size/1).
Object = dagger ;
Object = egg ;
Object = bear_meat ;
ERROR: object `weapon' does not exist
The "carengines" example is my current inspiration.
Re: Q on objects
Posted: Tue Jan 29, 2019 3:01 am
by Paulo Moura
The conforms_to_protocol/2 predicate returns both objects and categories that conform to a protocol:
https://logtalk.org/manuals/refman/pred ... l_2_3.html
But you can only send messages to objects. You get that error because “weapon” is a category. Try:
Code: Select all
?- current_object(Object), conforms_to_protocol(Object, item), Object::current_predicate(size/1).
Re: Q on objects
Posted: Tue Jan 29, 2019 3:08 am
by jdoran
Thanks, that did the trick.
I'm still learning the basics of Logtalk, and relying heavily on the examples. Trying to figure out what I can and cannot do is my current approach.
Re: Q on objects
Posted: Tue Jan 29, 2019 3:20 am
by Paulo Moura
Are you already using the learning by examples guide?
https://logtalk.org/learning.html
Re: Q on objects
Posted: Tue Jan 29, 2019 6:38 pm
by jdoran
No. Thanks for pointing that out. Somehow I came across the examples without seeing that page. One of my next questions was going to be a request for the order to study new stuff. So I'll go over that list.
I am still happy with some early exposure to objects/protocols/categories as those are central to what I'm thinking about.