\section{Cross-referencer}			\label{sec:xref}

A cross-referencer is a tool that examines the caller-callee relation
between predicates, and, using this information to explicate dependency
relations between source files, finds calls to non-existing predicates
and predicates for which no callers can be found. Cross-referencing is
useful during program development, reorganisation, clean-up, porting and
other program maintenance tasks. The dynamic nature of Prolog makes the
task non-trivial. Goals can be created dynamically using \index{call/1}\predref{call}{1} after
construction of a goal term. Abstract interpretation can find some of
these calls, but they can also come from external
communication, making it impossible to predict the callee.
In other words, the cross-referencer has only partial understanding of
the program, and its results are necessarily incomplete.  Still, it
provides valuable information to the developer.

SWI-Prolog's cross-referencer is split into two parts. The standard
Prolog library \pllib{prolog_xref} is an extensible library for
information gathering described in \secref{lib:prologxref}, and the XPCE
library \pllib{pce_xref} provides a graphical front-end for the
cross-referencer described here. We demonstrate the tool on CHAT80, a
natural language question and answer system by Fernando C.N. Pereira and
David H.D. Warren.

\begin{description}
    \predicate{gxref}{0}{}
Run cross-referencer on all currently loaded files and present a
graphical overview of the result.  As the predicate operates on the
currently loaded application it must be run after loading the
application.
\end{description}

\postscriptfig[width=0.8\linewidth]{xrefchatfile}{File info for
\texttt{chattop.pl}, part of CHAT80}

The \textbf{left window} (see \figref{xrefchatfile}) provides browsers
for loaded files and predicates. To avoid long file paths, the file
hierarchy has three main branches. The first is the current directory
holding the sources. The second is marked \const{alias}, and below it are
the file-search-path aliases (see \index{file_search_path/2}\predref{file_search_path}{2} and
\index{absolute_file_name/3}\predref{absolute_file_name}{3}). Here you find files loaded from the system as
well as modules of the program loaded from other locations using the file
search path. All loaded files that fall outside these categories are
below the last branch called \const{\Sdiv}. Files where the system found
suspicious dependencies are marked with an exclamation mark. This also
holds for directories holding such files. Clicking on a file opens a
\emph{File info} window in the right pane.

The \textbf{File info} window shows a file, its main properties, its
undefined and not-called predicates and its import and export relations
to other files in the project. Both predicates and files can be opened
by clicking on them. The number of callers in a file for a certain
predicate is indicated with a blue underlined number. A left-click will
open a list and allow editing the calling predicate.

The \textbf{Dependencies} (see \figref{xrefchatdep}) window displays
a graphical overview of dependencies between files. Using the background
menu a complete graph of the project can be created. It is also possible
to drag files onto the graph window and use the menu on the nodes to
incrementally expand the graph. The underlined blue text indicates the
number of predicates used in the destination file. Left-clicking opens a
menu to open the definition or select one of the callers.

\postscriptfig[width=0.8\linewidth]{xrefchatdep}{Dependencies between
source files of CHAT80}


\paragraph{Module and non-module files}

The cross-referencer threads module and non-module project files
differently. Module files have explicit import and export relations and
the tool shows the usage and consistency of the relations. Using the
\textsf{Header} menu command, the tool creates a consistent import list
for the module that can be included in the file. The tool computes the
dependency relations between the non-module files.  If the user wishes
to convert the project into a module-based one, the \textsf{Header}
command generates an appropriate module header and import list.  Note
that the cross-referencer may have missed dependencies and does not
deal with meta-predicates defined in one module and called in another.
Such problems must be resolved manually.


\paragraph{Settings}

The following settings can be controlled from the \textsf{settings}
menu:

\begin{description}
    \definition{Warn autoload}
By default disabled.  If enabled, modules that require
predicates to be autoloaded are flagged with a warning and the file
info window of a module shows the required autoload predicates.

    \definition{Warn not called}
If enabled (default), the file overview shows an alert icon for files
that have predicates that are not called.
\end{description}
