
SRC Interactive Computing Facility                       Prolog Program Library
SIG Artificial Intelligence                                                XREF



                     Department of Artificial Intelligence
                            University of Edinburgh


                        PROLOG CROSS-REFERENCE PROGRAM

                               Source:    Dave Bowen, Chris Mellish et alia
                       Program Issued:    July 82
                        Documentation:    July 82


1. Description

XREF is a cross-reference program which produces an alphabetically ordered list
of  predicates,  giving the file in which each is defined and a list of all the
predicates which call it (also in alphabetic order).    If  required,  it  also
gives  a  list  of  all  the imports and exports for each file, i.e. the global
predicates used and defined in each file.  If  desired,  this  information  can
also  be  used  to have the public declarations in each of the cross-referenced
files automatically updated, provided that the text editor TEC124 is available.

The user may extend the program by providing a definition file.   This  can  be
used  to  supply  XREF with additional information.  For example it can specify
that certain predicates are built-in, and these  predicates  are  then  omitted
from  the  cross-reference.   Also, it can be used to answer in advance various
questions which would otherwise require user interaction at run time.


2. How to Use the Program

The simplest way to use the program is to type 

            .run XREF:XREF

having first declared the logical path name XREF to point to the area where the
cross-referencer files are stored.  On the Edinburgh DECsystem10 this  is  done
by 

            .path xref: = dskb:[140,143,xref]

Once  the  program is started, the prompt "Next file: " appears and a file name
should be typed in, followed by a carriage-return.  Note: you should not put  a
full  stop  in  unless  it  is  part of the file name.  This is true of all the
questions XREF asks you.  The prompt is repeated so that as many file names  as
desired may be entered.  E.g.  

            Next file: dskb:myfile.ext
            Next file:

When  all  the required files have been entered, this input phase is terminated
by just typing a carriage-return by itself.

The user is subsequently prompted for an output file  name,  and  a  title  and
required  text width for the output.  He is then asked whether lists of imports
and exports are required, and should type the letter "y"  (or  "yes")  if  they
are.    If  the  answer is "n" (or no), the program terminates; otherwise there
follows a request for a file name to which the import/export lists  are  to  be
written,  and  then  another  question asking whether the files which have been
cross-referenced should have their public declarations updated.  If  in  doubt,
answer  no to this question; the implications of answering yes are described in
TECO below.


2.1. Indirect Files

If a number of file names are listed on a file called FOO, say, then  they  can
all  be  entered  at  once simply by typing the file name preceded by an "@" in
response to the prompt "Next file: ", thus:  

            Next file: @FOO

If the file names were listed instead in FOO.CCL, then the "@" could be omitted
since the extension "CCL" is assumed to indicate that the file is  an  indirect
one.  I.e.  

            Next file: FOO.CCL

would have the desired effect.


2.2. Definition Files

The  executable version of XREF, of which the use has been described, makes use
of a set of definitions which may be found in XREF:XREF.DEF.  These define  the
standard  system  (built-in)  predicates,  for  which  cross-referencing is not
required. e.g.  

            system(fail).
            system(length(_,_)).

indicate that fail/0 and length/2 are built-in predicates.

The user may provide his own definition file(s).    A  definition  file  called
MYDEFS can be loaded into XREF by preceding the filename with "*", thus:  

            Next file: *MYDEFS

The asterisk may be omitted if the file has the extension "DEF"; e.g.  

            Next file: MYDEFS.DEF

Apart  from  the  definition of system predicates, several other kinds of terms
are allowed in a definition file:

op(<priority>, <associativity>, <operator symbol list>).
                These terms simply declare  operators  as  in  the  normal  way
                except  that they take the form of assertions rather than goals
                (the preceding ':-' is  omitted).    It  is  not  necessary  to
                declare  operators  in  the  definition  file  unless their use
                precedes their declaration in the files to be processed.

known(<predicate>, <where defined>).
                This  is  useful  for  utility  predicates   for   which   full
                cross-referencing is not required.  It simply tells the program
                where  a  particular  procedure  is  defined, so that it is not
                necessary to process the module which contains  the  definition
                of that procedure.

applies(<term>, <term>).
                This  can be used to indicate that a given predicate takes some
                other predicate as an argument and causes that predicate to  be
                called.  For example, suppose there is a user-defined predicate
                maplist/3  which  takes  a predicate and two lists as arguments
                e.g.  

                            :- maplist(foo,[X1,X2,X3],[Y1,Y2,Y3]).

                and successively applies the predicate to the i-th elements  of
                each of the lists.  I.e. the above goal clause is equivalent to
                

                            :- foo(X1,Y1), foo(X2,Y2), foo(X3,Y3).

                The appropriate entry in the definition file is 

                            applies( maplist(Pred,L1,L2), Pred+2 ).

                This expresses the fact that the first argument of maplist is a
                predicate  and  that  it  is  to  be called with two additional
                arguments, i.e. the above call of maplist/3  results  in  calls
                foo/2.  The '+2' would be omitted if maplist/3 caused foo to be
                called  with  no  additional arguments, i.e. if foo/0 was to be
                referenced.  Note that if maplist is called with a variable  as
                its  first argument, the cross-referencer cannot determine what
                predicate(s) are to be called  and  so  no  special  action  is
                taken.    VERY  IMPORTANT  NOTE: the compound term which is the
                first argument of applies/2 is a skeleton, that is all  of  its
                arguments  MUST be variables as indicated in the example.  This
                term will be matched against the calls in your program, and  if
                you fill it in with random constants it won't unify.

called(<predicate>).
                This  informs  XREF that <predicate> is called.  This is useful
                both for top level routines which are to be called by the user,
                and also for predicates which  are  entered  via  the  built-in
                predicate call/1.  In both cases it avoids the possibility of a
                warning  message claiming that the predicate is not called.  It
                also ensures that the predicate is included in the exports list
                for  the  file,  so  that   automatic   insertion   of   public
                declarations will work properly.

The following can be used to save having to repeatedly type the same answers to
the questions asked by XREF at run time.

cross_ref_file(<file name>).
                This defines the filename for the cross-reference listing.

title(<atom or string>).
                This defines the title for the cross-reference listing.

width(<text width>).
                This   defines   the   text   width   (in  characters)  of  the
                cross-reference listing.

globals_file(<file name>).
                This defines the filename for the imports/exports listings.  If
                it is 'no' then no globals listings will be produced.

update_globals(<yes or no>).
                This determines whether or not it  is  required  to  alter  the
                public  declarations in each file.  It should be set to 'no' if
                TEC124 is not available.


2.3. Automatic Updating of Public Declarations

In order to make  use  of  this  facility  it  is  necessary  to  surround  the
declarations part of each file with special markers like this:  

            %declarations%

            :- public ...<whatever>

            %end%
Everything  between  the two markers will be destroyed, and a new set of public
declarations will be inserted.  Also, a list of all predicates imported by  the
file will be given as comments.

If  there  are  no  public  declarations  in the file to start with, the marker
%here% may be used in place of the pair %declarations% %end%.


2.4. Re-compiling XREF

At times it may be necessary or desirable to create a new executable version of
XREF.  Proceed as follows:  

            .run prolog
            ?- ['xref:xref.pl'].

This compiles the files which  make  up  the  XREF  program.    The  top  level
predicates now available are:

load/1          which  takes  either a list of file names or a single file name
                as its argument.  The files are loaded as definition files.

go/0            which starts the cross-reference program  which  then  runs  as
                described  above.  That is, the prompt "Next file: " appears on
                the screen.

After loading the required definition files the system  may  be  saved  in  the
normal  way  using  plsys(core_image).   For an example of how this is done see
XREF:XREF.MIC.


3. Storage Requirements

The Prolog system requires 30K words. Another 15K  words  suffice  to  run  the
compiled version of XREF on a small program.
