extend user object

Help requests on developing Logtalk applications

Moderator: Paulo Moura

Locked
shengcer
Posts: 21
Joined: Wed Aug 14, 2013 7:54 pm

extend user object

Post by shengcer »

Hi, sorry, it is me again.

Using swi-Prolog as the underlying compiler, I made my object extend the "user" object, and then tried to call "concat_atom" inside the object, which failed with

Code: Select all

*     This predicate is called but never defined: concat_atom/3
*       in file /home/shengcer/test/orange.lgt between lines 15-17
*       while compiling object orange
My object def is like this,

Code: Select all

:- object(orange, extends([user])) .
  concat(X, Y, Z) :-
    concat_atom([X, Y], ',', Z) .
:- end_object .
I tried to call user::concat_atom directly in the console, and it worked

Code: Select all

 3 ?- user::concat_atom(['a', 'b'], ',', V) .
V = 'a,b'.
I also noticed inside orange object body, I can call predicates such as findall and call, but not append, exclude or maplist. Also if I replace "concat_atom" with "user::concat_atom" within the object def, i.e.,

Code: Select all

:- object(orange, extends([user])) .
  concat(X, Y, Z) :-
    user::concat_atom([X, Y], ',', Z) .
:- end_object .
it is also working.

why does this happen? How should I properly call the integrated predicate supplied by the underlying prolog engine?

shengcer
Posts: 21
Joined: Wed Aug 14, 2013 7:54 pm

Re: extend user object

Post by shengcer »

New problems,

I am trying to call the built-in predicates directly by referring to "user" predicate,

Code: Select all

public(isfruit/3)
...
user::maplist(fruit::isfruit(X), Hs0, Hs) ,
user::concat_atom(Hs, ',', Value) .
It failed with error

Code: Select all

ERROR: apply:maplist_/3: Undefined procedure: (::)/4
ERROR:   However, there are definitions for:
ERROR:         (::)/2
if I change fruit::isfruit -> isfruit, it ended with this error

Code: Select all

ERROR: apply:maplist_/3: Undefined procedure: isfruit/3
exclude has the similar problem, if a predicate with partially applied argument is referred as an argument.
These code all used to be able to run in SWI-prolog.
Last edited by shengcer on Fri Aug 16, 2013 8:04 pm, edited 1 time in total.

Paulo Moura
Logtalk developer
Posts: 533
Joined: Sat May 05, 2007 8:35 am
Location: Portugal
Contact:

Re: extend user object

Post by Paulo Moura »

"user" is a pseudo-object that basically represents everything that's not encapsulated. Not meant to be used as a parent prototype, i.e to be extend.

The concat_atom/3 is a deprecated SWI-Prolog, available from the "backward_compatibility" library. But you're not making that information available to the Logtalk compiler (hence the warning) using e.g. a use_module/2 directive inside the object. Prefixing its call by "user::" allows it to be compiled as-is (i.e. the Logtalk compiler is bypassed) and the SWI-Prolog auto-loading mechanism to kick in. For append/3, which is also not a built-in predicate, you can use either the SWI-Prolog "lists" library or the Logtalk "list" object. In the first case, you need to add to your object the directive:

Code: Select all

:- use_module(lists, [append/3]).
In the second case, you need to load the "list" library object:

Code: Select all

?- {library(types_loader)}.
and then you can either use:

Code: Select all

..., list::append(...), ...
or:

Code: Select all

:- uses(list, [append/3]).

..., append(...), ...
For meta-predicates such as exclude/3 and maplist/2 you can use the Logtalk library as well:

Code: Select all

?- {library(metapredicates_loader}.

..., meta::map(...), ...
See the compatibility notes on SWI-Prolog ("adapters/NOTES.txt") and the library documentation ("library/docs/index.html") for more information. Also recommended reading is the User Manual section on Prolog integration and migration.
Paulo Moura
Logtalk developer

Paulo Moura
Logtalk developer
Posts: 533
Joined: Sat May 05, 2007 8:35 am
Location: Portugal
Contact:

Re: extend user object

Post by Paulo Moura »

shengcer wrote:New problems,

I am trying to call the built-in predicates directly by referring to "user" predicate,

Code: Select all

public(isfruit/3)
...
user::maplist(fruit::isfruit(X), Hs0, Hs) ,
user::concat_atom(Hs, ',', Value) .
It failed with error

Code: Select all

ERROR: apply:maplist_/3: Undefined procedure: (::)/4
ERROR:   However, there are definitions for:
ERROR:         (::)/2
By prefixing the predicate call by "user::", you're bypassing the Logtalk compiler.
shengcer wrote: if I change fruit::isfruit -> isfruit, it ended with this error

Code: Select all

ERROR: apply:maplist_/3: Undefined procedure: isfruit/3
exclude has the similar problem, if a predicate with partially applied argument is referred as an argument.
These code all used to be able to run in SWI-prolog.
Neither maplist/3 or concat_atom/3 are built-in predicates. Note that you can check the properties of a SWI-Prolog predicate using the built-in predicate predicate_property/2. For example:

Code: Select all

?- predicate_property(concat_atom(_,_,_), Property).
Property = interpreted ;
Property = visible ;
Property = imported_from(backward_compatibility) ;
Property = file('/Users/pmoura/lib/swipl-6.5.1/library/backcomp.pl') ;
Property = line_count(213) ;
Property = number_of_clauses(1) ;
Property = number_of_rules(1) ;
false.
See my previous post on how to properly call predicates such as maplist/3 from within an object.
Paulo Moura
Logtalk developer

shengcer
Posts: 21
Joined: Wed Aug 14, 2013 7:54 pm

Re: extend user object

Post by shengcer »

Thanks a lot! As you suggested, I noticed call, and findall are built-in predicates for logtalk, which is why they can be used in the object body directly. For the others, I have opted to use the logtalk's meta library, and it worked like a charm. One quick question for loading the standard library though -- I can run {library(metapredicates_loader)} in the console, but how can I import them in a loader file? I have tried to put that {library(metapredicates_loader)} inside and outside the :-initialization {...} , but neither works. Also what is the trick that the curly brace does? If I run "library(metapredicates_loader) ." in the console, I got non-existent predicate error.

Please point me to the part of the documentation that I can look for the answers to if you think it might be better this way. I know I have kept throwing questions these days in the forum, and I really appreciate your always quick response and patient explanation :-) I also would like to thank you for inventing this beautiful and powerful language, which I believe all java developers who have an interest developing jpl based application should seriously consider switching their prolog code to.


Paulo Moura wrote:
shengcer wrote:New problems,

I am trying to call the built-in predicates directly by referring to "user" predicate,

Code: Select all

public(isfruit/3)
...
user::maplist(fruit::isfruit(X), Hs0, Hs) ,
user::concat_atom(Hs, ',', Value) .
It failed with error

Code: Select all

ERROR: apply:maplist_/3: Undefined procedure: (::)/4
ERROR:   However, there are definitions for:
ERROR:         (::)/2
By prefixing the predicate call by "user::", you're bypassing the Logtalk compiler.
shengcer wrote: if I change fruit::isfruit -> isfruit, it ended with this error

Code: Select all

ERROR: apply:maplist_/3: Undefined procedure: isfruit/3
exclude has the similar problem, if a predicate with partially applied argument is referred as an argument.
These code all used to be able to run in SWI-prolog.
Neither maplist/3 or concat_atom/3 are built-in predicates. Note that you can check the properties of a SWI-Prolog predicate using the built-in predicate predicate_property/2. For example:

Code: Select all

?- predicate_property(concat_atom(_,_,_), Property).
Property = interpreted ;
Property = visible ;
Property = imported_from(backward_compatibility) ;
Property = file('/Users/pmoura/lib/swipl-6.5.1/library/backcomp.pl') ;
Property = line_count(213) ;
Property = number_of_clauses(1) ;
Property = number_of_rules(1) ;
false.
See my previous post on how to properly call predicates such as maplist/3 from within an object.

Paulo Moura
Logtalk developer
Posts: 533
Joined: Sat May 05, 2007 8:35 am
Location: Portugal
Contact:

Re: extend user object

Post by Paulo Moura »

shengcer wrote: Thanks a lot! As you suggested, I noticed call, and findall are built-in predicates for logtalk, which is why they can be used in the object body directly. For the others, I have opted to use the logtalk's meta library, and it worked like a charm.
That's a good idea for two reasons. First, it helps in making your code portable (to all Logtalk supported backend Prolog compilers). Second, the library includes a compiler that eliminates the overhead of using those meta-predicates. See the "metapredicates" and "metapredicates_compiled" examples in the Logtalk distribution.
shengcer wrote: One quick question for loading the standard library though -- I can run {library(metapredicates_loader)} in the console, but how can I import them in a loader file? I have tried to put that {library(metapredicates_loader)} inside and outside the :-initialization {...} , but neither works. Also what is the trick that the curly brace does? If I run "library(metapredicates_loader) ." in the console, I got non-existent predicate error.
The {...} notation is just a shorthand (defined in the adapter files) for logtalk_load/1, which is handy during interactive development. In a loader file simply write:

Code: Select all

:- initialization((
    ...,
    logtalk_load(library(metapredicates_loader)),
    ...
)).
shengcer wrote: Please point me to the part of the documentation that I can look for the answers to if you think it might be better this way. I know I have kept throwing questions these days in the forum, and I really appreciate your always quick response and patient explanation :-) I also would like to thank you for inventing this beautiful and powerful language, which I believe all java developers who have an interest developing jpl based application should seriously consider switching their prolog code to.
Happy that you're having fun programming in Logtalk :-) Besides the User Manual, I suggest that you take some time to look into the examples. There are many of them but the "examples/NOTES.txt" file gives a brief description of each one. That should help you select the ones that may be more relevant for your application.
Paulo Moura
Logtalk developer

Locked