Generating xref info with term expansions?

It appears that library(prolog_xref) doesn’t do term expansion (at least when I ran it, it didn’t find any of the predicates that had been created by term expansion). Is there a way to do cross-referencing of term-expanded files?

If not, I could use current_predicate/1 and listing/1 to output the predicates (or read_term/2 and expand_term/2) because I want to find dead code: xref_defined(_, Pred, _), \+ xref_called(_, Pred, _). But it’d be nice if there’s a better way of doing this.

You may be able to use Logtalk’s dead_code_scanner tool.

The xref library does use term expansion, unless you blocked it by testing for the Prolog flag xref. Also, it doesn’t define the term_expansion rules, so you must make sure they are available. You can use gxref/0 after loading your program (requires gui).

The other library to use is library(prolog_codewalk) which runs over all or part of the loaded program and does a callback on all or a selection of the call edges, possibly providing source location information. Using this you can easily record what is called. Next you enumerate what is defined using predicate property and you are done. list_undefined/0, used by make is built on top of this library.

The codewalk library, working on the loaded program, is more precise than the xref library. It is still not complete of course as it cannot find dynamically constructed and called goals.

I couldn’t figure out how to use it – I’ve been able to use the instructions at Linter but what argument should I give to dead_code_scanner::entity? (I also tried directory and file but they didn’t detect anything.)

Sorry, I was pressed on time when I mentioned the tool. Ideally, you would be able to compile your Prolog modules as objects and then use the dead_code_scanner::entity/1 predicate taking as argument a name of a module (that was compiled as an object). For example, assuming a module named foo something like:

$ swilgt
...

?- set_logtalk_flag(optimize, on).
true.

?- {dead_code_scanner(loader)}.
...
true.

?- {foo).
...
true

?- dead_code_scanner::entity(foo).

This would likely give you some or several false positives, specially depending if you use use_module/2 vs use_module/1 to declare module dependencies.

Feel free to DM me with more details on your code and any issues found while trying the steps.

I’ve figured out why term expansion didn’t happen … I’m using EDCG, which uses edcg:pred_info/2 facts to trigger it; and of course the xref library doesn’t load those facts, so term expansion doesn’t happen. Multifile requires_library/2 might be a way around this, but I’ll have to study the source in library(prolog_source) a bit more to figure out how to use it.

BTW, gxref uses a tiny font … is there any way to make it bigger? (And I might have something misconfigured with X11 – the “drag” functionality of gxref doesn’t seem to work.)

It is a bit of an old mess with too many hacks, I’m afraid :frowning: You can simply preload such libraries though. Probably best is to simply load the entire program before xreffing the files.

Start ?- emacs., go to Edit/Edit editor preferences and uncomment and set font.scale. Then quit and restart Prolog. This is a general scaling factor that increases/reduces all fonts.

Peter,

I am thinking this should be in the category Help; would that be wrong?

Yes.

Also, the tidbit about setting font size should go somewhere (which I had forgotten about when I recently used tspy). The generated file is ~/.config/swi-prolog/xpce/Defaults, BTW.

Be aware though that the old names are still used by the stable branch …