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(, , ). 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(, ). 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(, ). 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(). This informs XREF that 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(). This defines the filename for the cross-reference listing. title(). This defines the title for the cross-reference listing. width(). This defines the text width (in characters) of the cross-reference listing. globals_file(). This defines the filename for the imports/exports listings. If it is 'no' then no globals listings will be produced. update_globals(). 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 ... %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.