Hi,
As you may be aware, Logtak’s diagrams
tool can generate diagrams for Prolog module libraries and applications (I have a couple of examples online at Tools - Logtalk).
When running on SWI-Prolog, it uses the library(prolog_xref)
for most of the required information on the application modules and predicates. In order to illustrate the issue, consider as an example Anne’s Talespin application:
As typical in SWI-Prolog applications, some module dependencies are explicitly declared while others are omitted with the autoloading mechanism filing the gaps. Take for example this application planner
module with implicit dependencies on the apply
and lists
modules. Let’s generate diagrams for the application plus a predicate cross-diagram for the planner
module:
$ swilgt
...
% load the application
?- [run].
true.
% load Logtalk's diagrams tool
?- {diagrams(loader)}.
...
true.
% generate file loading, file dependency, module xref, ... diagrams
?- diagrams::directory('.').
true.
% generate predicate xref diagram for the planner module
?- xref_diagram::entity(planner).
true.
Converting the generated .dot
file for the planner
module to .svg
:
$ dot -Tsvg planner_module_xref_diagram.dot > planner_module_xref_diagram.svg
you will noticed that predicates such as member/2
or reverse/2
are displayed in the diagram as local predicates. I.e. SWI-Prolog runtime knows that these predicates come from the lists
module but library(prolog_xref)
doesn’t seem to return that information. The diagrams
tool is making the following calls (enumerating callees; here I’m just instantiating the callee argument to member(_,_)
to illustrate the issue):
?- module_property(planner, file(File)), xref_source(File), xref_called(File, member(_,_), Caller).
File = '/Users/pmoura/talespin-annie-master/planner.pl',
Caller = plan(_13422, _13424, _13426, _13428).
?- module_property(planner, file(File)), xref_source(File), xref_called(File, member(_,_), Caller), xref_defined(File, member(_,_), imported(FromFile)).
false.
However, if I modify the planner.pl
file to include the missing directive and reload the application:
:- use_module(library(lists)).
I will now get:
?- module_property(planner, file(File)), xref_source(File), xref_called(File, member(_,_), Caller), xref_defined(File, member(_,_), imported(FromFile)).
File = '/Users/pmoura/talespin-annie-master/planner.pl',
Caller = plan(_26232, _26234, _26236, _26238),
FromFile = '/Users/pmoura/lib/swipl/library/lists.pl'.
which allows the xref diagram (and other diagrams to) correctly show the module dependencies as intended.
This issue, which is not clear to me if it is a library(prolog_xref)
limitation or bug (or something that I’m missing in its usage!), defeats one of the main purpose of generating the diagrams in the first place: to provide a comprehensive view of an application at file, entity, and predicate levels.
Feedback most appreciated.
Thanks,
Paulo