Does `yall` clobber the predicate metadata?

I tried (just as an example) (still on SWIPL 8.1.19-37-gc4fb81227):

use_module(library(semweb/turtle)).

And then, predicate_property/2 (I absolutely like this, code as just a database entry with metadata, subject to manipulation, as it should be):

?- predicate_property(rdf_load_turtle/3,imported_from(M)).
yall

?- predicate_property(rdf_load_turtle/3,file(M)).
M = '/usr/local/logic/swipl/lib/swipl/library/yall.pl'.

That sounds wrong.

?- predicate_property(format/3,file(M)).
M = '/usr/local/logic/swipl/lib/swipl/library/yall.pl'.

That sounds wronger.

Maybe it’s a known problem?

1 Like

My guess is you found something related to the autoload changes of recent.

This is not one I plan on digging into today. :slightly_smiling_face:

EDIT

Almost forgot to give you this useful feedback that affirms what you found.

On my system running Windows 10.

Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.24)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit https://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- predicate_property(format/3,file(M)).
M = 'c:/program files/swipl/library/yall.pl'.

?- 

EDIT

OK, I just couldn’t let this one go without a bit more checking.

?- predicate_property(C,file(F)).
C = ansi_format(_2898, _2900, _2902),
F = 'c:/program files/swipl/library/ansi_term.pl' ;
C = library_directory(_3932),
F = 'c:/program files/swipl/boot/parms.pl' ;
C = ignore(_4962),
F = 'c:/program files/swipl/boot/init.pl' ;
C = init_win_menus,
F = 'c:/program files/swipl/library/win_menu.pl' 
Action (h for help) ? abort

% Execution Aborted
?- predicate_property(ignore(_),file(F)).
F = 'c:/program files/swipl/boot/init.pl'.

So trying it all

?- predicate_property(C,file(F)).
C = ansi_format(_8550, _8552, _8554),
F = 'c:/program files/swipl/library/ansi_term.pl' ;
C = library_directory(_9584),
F = 'c:/program files/swipl/boot/parms.pl' ;
C = ignore(_10614),
F = 'c:/program files/swipl/boot/init.pl' ;
C = init_win_menus,
F = 'c:/program files/swipl/library/win_menu.pl' ;
C = file_search_path(_12670, _12672),
F = 'c:/program files/swipl/boot/init.pl' ;
C = prolog_exception_hook(_13702, _13704, _13706, _13708),
F = 'c:/program files/swipl/library/prolog_stack.pl' ;
C = load_files(_60),
F = 'c:/program files/swipl/boot/init.pl' ;
C = _802/_804,
F = 'c:/program files/swipl/library/yall.pl' ;
C = ansi_get_color(_1834, _1836),
F = 'c:/program files/swipl/library/ansi_term.pl' ;
C = prolog_file_type(_2866, _2868),
F = 'c:/program files/swipl/boot/init.pl' ;
false.

reveals a direction, e.g.

C = _802/_804,
F = 'c:/program files/swipl/library/yall.pl' ;
1 Like

No. predicate_property/2 takes a callable term, not a predicate indicator. As x/1 is a callable term referring to the yall predicate (/)/2, that is what you get. Without yall around it would have failed (which might be less confusing).

2 Likes

I was hoping that David would follow up and ask but alas I shall.

Using SWI-Prolog from the command line, given a predicate name/arity is is possible to identify the Prolog source code file it is in? I know not all predicates are pure Prolog, e.g. (PL_ ), but I don’t know if some of the predicates are converted directly into C code during compilation.

Do you mean:

?- predicate_property(length(_,_), file(Filename)).
Filename = '...swipl-devel/build/home/boot/init.pl'.

The docs also say:

A more robust interface can be achieved using nth_clause/3 and clause_property/2.

This doesn’t seem to work for predicates implemented in C. For example:

?- predicate_property(is_list(_), file(Filename)).
false.

To the best of my knowledge, there is no “compilation to C” in SWI-Prolog. Prolog code is compiled to byte code which is run on the virtual machine.

1 Like

Thanks,

I tried some of those predicates noted in the docs but they didn’t find the predicates I was seeking. My guess is it only works on loaded predicates, but now I wonder if autoload needs to be included in checking? :thinking:

Can you give an example?

PS: read the docs. I see:

True when Head refers to a predicate that has property Property. With sufficiently instantiated Head, predicate_property/2 tries to resolve the predicate the same way as calling it would do: if the predicate is not defined it scans the default modules (see default_module/2) and finally tries the autoloader… [and so on]

1 Like

The one I was thinking of was

?- predicate_property(format(_,_,_),file(Filename)).
false.

but as the docs note it is built-in

It would be nice that instead of false it gave some idea of the info found in pl-ext.c

That would indeed be nice, but is a bit of work. Note b.t.w. that pl-ext.c is old school. Most of the predicates are defined using the PRED_IMPL() and PRED_DEF() macros. The others should be
moved as well, but that is a lot of typing. Prolog can give you the address of the function pointer,
but then you need to do some non-portable work to find the shared object and get the source
location of this function. Alternatively you could of course create a table from the sources, but the symbol table version has the advantage that it can also work for user provided extensions, provided they are compiled with debug info …

3 Likes