View source with raw comments or as raw
    1/*  Part of SWI-Prolog
    2
    3    Author:        Jan Wielemaker
    4    E-mail:        J.Wielemaker@vu.nl
    5    WWW:           http://www.swi-prolog.org/projects/xpce/
    6    Copyright (c)  2006-2020, University of Amsterdam
    7                              VU University Amsterdam
    8                              CWI, Amsterdam
    9    All rights reserved.
   10
   11    Redistribution and use in source and binary forms, with or without
   12    modification, are permitted provided that the following conditions
   13    are met:
   14
   15    1. Redistributions of source code must retain the above copyright
   16       notice, this list of conditions and the following disclaimer.
   17
   18    2. Redistributions in binary form must reproduce the above copyright
   19       notice, this list of conditions and the following disclaimer in
   20       the documentation and/or other materials provided with the
   21       distribution.
   22
   23    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   24    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   25    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   26    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   27    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   28    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   29    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   30    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   31    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   33    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   34    POSSIBILITY OF SUCH DAMAGE.
   35*/
   36
   37:- module(prolog_xref,
   38          [ xref_source/1,              % +Source
   39            xref_source/2,              % +Source, +Options
   40            xref_called/3,              % ?Source, ?Callable, ?By
   41            xref_called/4,              % ?Source, ?Callable, ?By, ?Cond
   42            xref_called/5,              % ?Source, ?Callable, ?By, ?Cond, ?Line
   43            xref_defined/3,             % ?Source. ?Callable, -How
   44            xref_definition_line/2,     % +How, -Line
   45            xref_exported/2,            % ?Source, ?Callable
   46            xref_module/2,              % ?Source, ?Module
   47            xref_uses_file/3,           % ?Source, ?Spec, ?Path
   48            xref_op/2,                  % ?Source, ?Op
   49            xref_prolog_flag/4,         % ?Source, ?Flag, ?Value, ?Line
   50            xref_comment/3,             % ?Source, ?Title, ?Comment
   51            xref_comment/4,             % ?Source, ?Head, ?Summary, ?Comment
   52            xref_mode/3,                % ?Source, ?Mode, ?Det
   53            xref_option/2,              % ?Source, ?Option
   54            xref_clean/1,               % +Source
   55            xref_current_source/1,      % ?Source
   56            xref_done/2,                % +Source, -When
   57            xref_built_in/1,            % ?Callable
   58            xref_source_file/3,         % +Spec, -Path, +Source
   59            xref_source_file/4,         % +Spec, -Path, +Source, +Options
   60            xref_public_list/3,         % +File, +Src, +Options
   61            xref_public_list/4,         % +File, -Path, -Export, +Src
   62            xref_public_list/6,         % +File, -Path, -Module, -Export, -Meta, +Src
   63            xref_public_list/7,         % +File, -Path, -Module, -Export, -Public, -Meta, +Src
   64            xref_meta/3,                % +Source, +Goal, -Called
   65            xref_meta/2,                % +Goal, -Called
   66            xref_hook/1,                % ?Callable
   67                                        % XPCE class references
   68            xref_used_class/2,          % ?Source, ?ClassName
   69            xref_defined_class/3        % ?Source, ?ClassName, -How
   70          ]).   71:- autoload(library(apply),[maplist/2,partition/4,maplist/3]).   72:- autoload(library(debug),[debug/3]).   73:- autoload(library(dialect),[expects_dialect/1]).   74:- autoload(library(error),[must_be/2,instantiation_error/1]).   75:- autoload(library(lists),[member/2,append/2,append/3,select/3]).   76:- autoload(library(modules),[in_temporary_module/3]).   77:- autoload(library(operators),[push_op/3]).   78:- autoload(library(option),[option/2,option/3]).   79:- autoload(library(ordsets),[ord_intersect/2,ord_intersection/3]).   80:- autoload(library(prolog_source),
   81	    [ prolog_canonical_source/2,
   82	      prolog_open_source/2,
   83	      prolog_close_source/1,
   84	      prolog_read_source_term/4
   85	    ]).   86:- autoload(library(shlib),[current_foreign_library/2]).   87:- autoload(library(solution_sequences),[distinct/2,limit/2]).   88
   89:- if(exists_source(library(pldoc))).   90:- use_module(library(pldoc), []).      % Must be loaded before doc_process
   91:- use_module(library(pldoc/doc_process)).   92:- endif.   93
   94:- predicate_options(xref_source/2, 2,
   95                     [ silent(boolean),
   96                       module(atom),
   97                       register_called(oneof([all,non_iso,non_built_in])),
   98                       comments(oneof([store,collect,ignore])),
   99                       process_include(boolean)
  100                     ]).  101
  102
  103:- dynamic
  104    called/5,                       % Head, Src, From, Cond, Line
  105    (dynamic)/3,                    % Head, Src, Line
  106    (thread_local)/3,               % Head, Src, Line
  107    (multifile)/3,                  % Head, Src, Line
  108    (public)/3,                     % Head, Src, Line
  109    defined/3,                      % Head, Src, Line
  110    meta_goal/3,                    % Head, Called, Src
  111    foreign/3,                      % Head, Src, Line
  112    constraint/3,                   % Head, Src, Line
  113    imported/3,                     % Head, Src, From
  114    exported/2,                     % Head, Src
  115    xmodule/2,                      % Module, Src
  116    uses_file/3,                    % Spec, Src, Path
  117    xop/2,                          % Src, Op
  118    source/2,                       % Src, Time
  119    used_class/2,                   % Name, Src
  120    defined_class/5,                % Name, Super, Summary, Src, Line
  121    (mode)/2,                       % Mode, Src
  122    xoption/2,                      % Src, Option
  123    xflag/4,                        % Name, Value, Src, Line
  124
  125    module_comment/3,               % Src, Title, Comment
  126    pred_comment/4,                 % Head, Src, Summary, Comment
  127    pred_comment_link/3,            % Head, Src, HeadTo
  128    pred_mode/3.                    % Head, Src, Det
  129
  130:- create_prolog_flag(xref, false, [type(boolean)]).

Prolog cross-referencer data collection

This library collects information on defined and used objects in Prolog source files. Typically these are predicates, but we expect the library to deal with other types of objects in the future. The library is a building block for tools doing dependency tracking in applications. Dependency tracking is useful to reveal the structure of an unknown program or detect missing components at compile time, but also for program transformation or minimising a program saved state by only saving the reachable objects.

The library is exploited by two graphical tools in the SWI-Prolog environment: the XPCE front-end started by gxref/0, and library(prolog_colour), which exploits this library for its syntax highlighting.

For all predicates described below, Source is the source that is processed. This is normally a filename in any notation acceptable to the file loading predicates (see load_files/2). Input handling is done by the library(prolog_source), which may be hooked to process any source that can be translated into a Prolog stream holding Prolog source text. Callable is a callable term (see callable/1). Callables do not carry a module qualifier unless the referred predicate is not in the module defined by Source.

See also
- Where this library analyses source text, library(prolog_codewalk) may be used to analyse loaded code. The library(check) exploits library(prolog_codewalk) to report on e.g., undefined predicates. */
bug
- meta_predicate/1 declarations take the module into consideration. Predicates that are both available as meta-predicate and normal (in different modules) are handled as meta-predicate in all places.
  167:- predicate_options(xref_source_file/4, 4,
  168                     [ file_type(oneof([txt,prolog,directory])),
  169                       silent(boolean)
  170                     ]).  171:- predicate_options(xref_public_list/3, 3,
  172                     [ path(-atom),
  173                       module(-atom),
  174                       exports(-list(any)),
  175                       public(-list(any)),
  176                       meta(-list(any)),
  177                       silent(boolean)
  178                     ]).  179
  180
  181                 /*******************************
  182                 *            HOOKS             *
  183                 *******************************/
 prolog:called_by(+Goal, +Module, +Context, -Called) is semidet
True when Called is a list of callable terms called from Goal, handled by the predicate Module:Goal and executed in the context of the module Context. Elements of Called may be qualified. If not, they are called in the context of the module Context.
 prolog:called_by(+Goal, -ListOfCalled)
If this succeeds, the cross-referencer assumes Goal may call any of the goals in ListOfCalled. If this call fails, default meta-goal analysis is used to determine additional called goals.
deprecated
- New code should use prolog:called_by/4
 prolog:meta_goal(+Goal, -Pattern)
Define meta-predicates. See the examples in this file for details.
 prolog:hook(Goal)
True if Goal is a hook that is called spontaneously (e.g., from foreign code).
  210:- multifile
  211    prolog:called_by/4,             % +Goal, +Module, +Context, -Called
  212    prolog:called_by/2,             % +Goal, -Called
  213    prolog:meta_goal/2,             % +Goal, -Pattern
  214    prolog:hook/1,                  % +Callable
  215    prolog:generated_predicate/1,   % :PI
  216    prolog:no_autoload_module/1.    % Module is not suitable for autoloading.
  217
  218:- meta_predicate
  219    prolog:generated_predicate(:).  220
  221:- dynamic
  222    meta_goal/2.  223
  224:- meta_predicate
  225    process_predicates(2, +, +).  226
  227                 /*******************************
  228                 *           BUILT-INS          *
  229                 *******************************/
 hide_called(:Callable, +Src) is semidet
True when the cross-referencer should not include Callable as being called. This is determined by the option register_called.
  237hide_called(Callable, Src) :-
  238    xoption(Src, register_called(Which)),
  239    !,
  240    mode_hide_called(Which, Callable).
  241hide_called(Callable, _) :-
  242    mode_hide_called(non_built_in, Callable).
  243
  244mode_hide_called(all, _) :- !, fail.
  245mode_hide_called(non_iso, _:Goal) :-
  246    goal_name_arity(Goal, Name, Arity),
  247    current_predicate(system:Name/Arity),
  248    predicate_property(system:Goal, iso).
  249mode_hide_called(non_built_in, _:Goal) :-
  250    goal_name_arity(Goal, Name, Arity),
  251    current_predicate(system:Name/Arity),
  252    predicate_property(system:Goal, built_in).
  253mode_hide_called(non_built_in, M:Goal) :-
  254    goal_name_arity(Goal, Name, Arity),
  255    current_predicate(M:Name/Arity),
  256    predicate_property(M:Goal, built_in).
 built_in_predicate(+Callable)
True if Callable is a built-in
  262system_predicate(Goal) :-
  263    goal_name_arity(Goal, Name, Arity),
  264    current_predicate(system:Name/Arity),   % avoid autoloading
  265    predicate_property(system:Goal, built_in),
  266    !.
  267
  268
  269                /********************************
  270                *            TOPLEVEL           *
  271                ********************************/
  272
  273verbose(Src) :-
  274    \+ xoption(Src, silent(true)).
  275
  276:- thread_local
  277    xref_input/2.                   % File, Stream
 xref_source(+Source) is det
 xref_source(+Source, +Options) is det
Generate the cross-reference data for Source if not already done and the source is not modified. Checking for modifications is only done for files. Options processed:
silent(+Boolean)
If true (default false), emit warning messages.
module(+Module)
Define the initial context module to work in.
register_called(+Which)
Determines which calls are registerd. Which is one of all, non_iso or non_built_in.
comments(+CommentHandling)
How to handle comments. If store, comments are stored into the database as if the file was compiled. If collect, comments are entered to the xref database and made available through xref_mode/2 and xref_comment/4. If ignore, comments are simply ignored. Default is to collect comments.
process_include(+Boolean)
Process the content of included files (default is true).
Arguments:
Source- File specification or XPCE buffer
  305xref_source(Source) :-
  306    xref_source(Source, []).
  307
  308xref_source(Source, Options) :-
  309    prolog_canonical_source(Source, Src),
  310    (   last_modified(Source, Modified)
  311    ->  (   source(Src, Modified)
  312        ->  true
  313        ;   xref_clean(Src),
  314            assert(source(Src, Modified)),
  315            do_xref(Src, Options)
  316        )
  317    ;   xref_clean(Src),
  318        get_time(Now),
  319        assert(source(Src, Now)),
  320        do_xref(Src, Options)
  321    ).
  322
  323do_xref(Src, Options) :-
  324    must_be(list, Options),
  325    setup_call_cleanup(
  326        xref_setup(Src, In, Options, State),
  327        collect(Src, Src, In, Options),
  328        xref_cleanup(State)).
  329
  330last_modified(Source, Modified) :-
  331    prolog:xref_source_time(Source, Modified),
  332    !.
  333last_modified(Source, Modified) :-
  334    atom(Source),
  335    \+ is_global_url(Source),
  336    exists_file(Source),
  337    time_file(Source, Modified).
  338
  339is_global_url(File) :-
  340    sub_atom(File, B, _, _, '://'),
  341    !,
  342    B > 1,
  343    sub_atom(File, 0, B, _, Scheme),
  344    atom_codes(Scheme, Codes),
  345    maplist(between(0'a, 0'z), Codes).
  346
  347xref_setup(Src, In, Options, state(In, Dialect, Xref, [SRef|HRefs])) :-
  348    maplist(assert_option(Src), Options),
  349    assert_default_options(Src),
  350    current_prolog_flag(emulated_dialect, Dialect),
  351    prolog_open_source(Src, In),
  352    set_initial_mode(In, Options),
  353    asserta(xref_input(Src, In), SRef),
  354    set_xref(Xref),
  355    (   verbose(Src)
  356    ->  HRefs = []
  357    ;   asserta(user:thread_message_hook(_,_,_), Ref),
  358        HRefs = [Ref]
  359    ).
  360
  361assert_option(_, Var) :-
  362    var(Var),
  363    !,
  364    instantiation_error(Var).
  365assert_option(Src, silent(Boolean)) :-
  366    !,
  367    must_be(boolean, Boolean),
  368    assert(xoption(Src, silent(Boolean))).
  369assert_option(Src, register_called(Which)) :-
  370    !,
  371    must_be(oneof([all,non_iso,non_built_in]), Which),
  372    assert(xoption(Src, register_called(Which))).
  373assert_option(Src, comments(CommentHandling)) :-
  374    !,
  375    must_be(oneof([store,collect,ignore]), CommentHandling),
  376    assert(xoption(Src, comments(CommentHandling))).
  377assert_option(Src, module(Module)) :-
  378    !,
  379    must_be(atom, Module),
  380    assert(xoption(Src, module(Module))).
  381assert_option(Src, process_include(Boolean)) :-
  382    !,
  383    must_be(boolean, Boolean),
  384    assert(xoption(Src, process_include(Boolean))).
  385
  386assert_default_options(Src) :-
  387    (   xref_option_default(Opt),
  388        generalise_term(Opt, Gen),
  389        (   xoption(Src, Gen)
  390        ->  true
  391        ;   assertz(xoption(Src, Opt))
  392        ),
  393        fail
  394    ;   true
  395    ).
  396
  397xref_option_default(silent(false)).
  398xref_option_default(register_called(non_built_in)).
  399xref_option_default(comments(collect)).
  400xref_option_default(process_include(true)).
 xref_cleanup(+State) is det
Restore processing state according to the saved State.
  406xref_cleanup(state(In, Dialect, Xref, Refs)) :-
  407    prolog_close_source(In),
  408    set_prolog_flag(emulated_dialect, Dialect),
  409    set_prolog_flag(xref, Xref),
  410    maplist(erase, Refs).
  411
  412set_xref(Xref) :-
  413    current_prolog_flag(xref, Xref),
  414    set_prolog_flag(xref, true).
 set_initial_mode(+Stream, +Options) is det
Set the initial mode for processing this file in the cross-referencer. If the file is loaded, we use information from the previous load context, setting the appropriate module and dialect.
  423set_initial_mode(_Stream, Options) :-
  424    option(module(Module), Options),
  425    !,
  426    '$set_source_module'(Module).
  427set_initial_mode(Stream, _) :-
  428    stream_property(Stream, file_name(Path)),
  429    source_file_property(Path, load_context(M, _, Opts)),
  430    !,
  431    '$set_source_module'(M),
  432    (   option(dialect(Dialect), Opts)
  433    ->  expects_dialect(Dialect)
  434    ;   true
  435    ).
  436set_initial_mode(_, _) :-
  437    '$set_source_module'(user).
 xref_input_stream(-Stream) is det
Current input stream for cross-referencer.
  443xref_input_stream(Stream) :-
  444    xref_input(_, Var),
  445    !,
  446    Stream = Var.
 xref_push_op(Source, +Prec, +Type, :Name)
Define operators into the default source module and register them to be undone by pop_operators/0.
  453xref_push_op(Src, P, T, N0) :-
  454    '$current_source_module'(M0),
  455    strip_module(M0:N0, M, N),
  456    (   is_list(N),
  457        N \== []
  458    ->  maplist(push_op(Src, P, T, M), N)
  459    ;   push_op(Src, P, T, M, N)
  460    ).
  461
  462push_op(Src, P, T, M0, N0) :-
  463    strip_module(M0:N0, M, N),
  464    Name = M:N,
  465    valid_op(op(P,T,Name)),
  466    push_op(P, T, Name),
  467    assert_op(Src, op(P,T,Name)),
  468    debug(xref(op), ':- ~w.', [op(P,T,Name)]).
  469
  470valid_op(op(P,T,M:N)) :-
  471    atom(M),
  472    valid_op_name(N),
  473    integer(P),
  474    between(0, 1200, P),
  475    atom(T),
  476    op_type(T).
  477
  478valid_op_name(N) :-
  479    atom(N),
  480    !.
  481valid_op_name(N) :-
  482    N == [].
  483
  484op_type(xf).
  485op_type(yf).
  486op_type(fx).
  487op_type(fy).
  488op_type(xfx).
  489op_type(xfy).
  490op_type(yfx).
 xref_set_prolog_flag(+Flag, +Value, +Src, +Line)
Called when a directive sets a Prolog flag.
  496xref_set_prolog_flag(Flag, Value, Src, Line) :-
  497    atom(Flag),
  498    !,
  499    assertz(xflag(Flag, Value, Src, Line)).
  500xref_set_prolog_flag(_, _, _, _).
 xref_clean(+Source) is det
Reset the database for the given source.
  506xref_clean(Source) :-
  507    prolog_canonical_source(Source, Src),
  508    retractall(called(_, Src, _Origin, _Cond, _Line)),
  509    retractall(dynamic(_, Src, Line)),
  510    retractall(multifile(_, Src, Line)),
  511    retractall(public(_, Src, Line)),
  512    retractall(defined(_, Src, Line)),
  513    retractall(meta_goal(_, _, Src)),
  514    retractall(foreign(_, Src, Line)),
  515    retractall(constraint(_, Src, Line)),
  516    retractall(imported(_, Src, _From)),
  517    retractall(exported(_, Src)),
  518    retractall(uses_file(_, Src, _)),
  519    retractall(xmodule(_, Src)),
  520    retractall(xop(Src, _)),
  521    retractall(xoption(Src, _)),
  522    retractall(xflag(_Name, _Value, Src, Line)),
  523    retractall(source(Src, _)),
  524    retractall(used_class(_, Src)),
  525    retractall(defined_class(_, _, _, Src, _)),
  526    retractall(mode(_, Src)),
  527    retractall(module_comment(Src, _, _)),
  528    retractall(pred_comment(_, Src, _, _)),
  529    retractall(pred_comment_link(_, Src, _)),
  530    retractall(pred_mode(_, Src, _)).
  531
  532
  533                 /*******************************
  534                 *          READ RESULTS        *
  535                 *******************************/
 xref_current_source(?Source)
Check what sources have been analysed.
  541xref_current_source(Source) :-
  542    source(Source, _Time).
 xref_done(+Source, -Time) is det
Cross-reference executed at Time
  549xref_done(Source, Time) :-
  550    prolog_canonical_source(Source, Src),
  551    source(Src, Time).
 xref_called(?Source, ?Called, ?By) is nondet
 xref_called(?Source, ?Called, ?By, ?Cond) is nondet
 xref_called(?Source, ?Called, ?By, ?Cond, ?Line) is nondet
True when By is called from Called in Source. Note that xref_called/3 and xref_called/4 use distinct/2 to return only distinct Called-By pairs. The xref_called/5 version may return duplicate Called-By if Called is called from multiple clauses in By, but at most one call per clause.
Arguments:
By- is a head term or one of the reserved terms '<directive>'(Line) or '<public>'(Line), indicating the call is from an (often initialization/1) directive or there is a public/1 directive that claims the predicate is called from in some untractable way.
Cond- is the (accumulated) condition as defined by :- if(Cond) under which the calling code is compiled.
Line- is the start line of the calling clause.
  573xref_called(Source, Called, By) :-
  574    xref_called(Source, Called, By, _).
  575
  576xref_called(Source, Called, By, Cond) :-
  577    canonical_source(Source, Src),
  578    distinct(Called-By, called(Called, Src, By, Cond, _)).
  579
  580xref_called(Source, Called, By, Cond, Line) :-
  581    canonical_source(Source, Src),
  582    called(Called, Src, By, Cond, Line).
 xref_defined(?Source, +Goal, ?How) is nondet
Test if Goal is accessible in Source. If this is the case, How specifies the reason why the predicate is accessible. Note that this predicate does not deal with built-in or global predicates, just locally defined and imported ones. How is one of of the terms below. Location is one of Line (an integer) or File:Line if the definition comes from an included (using :- include(File)) directive.
  603xref_defined(Source, Called, How) :-
  604    nonvar(Source),
  605    !,
  606    canonical_source(Source, Src),
  607    xref_defined2(How, Src, Called).
  608xref_defined(Source, Called, How) :-
  609    xref_defined2(How, Src, Called),
  610    canonical_source(Source, Src).
  611
  612xref_defined2(dynamic(Line), Src, Called) :-
  613    dynamic(Called, Src, Line).
  614xref_defined2(thread_local(Line), Src, Called) :-
  615    thread_local(Called, Src, Line).
  616xref_defined2(multifile(Line), Src, Called) :-
  617    multifile(Called, Src, Line).
  618xref_defined2(public(Line), Src, Called) :-
  619    public(Called, Src, Line).
  620xref_defined2(local(Line), Src, Called) :-
  621    defined(Called, Src, Line).
  622xref_defined2(foreign(Line), Src, Called) :-
  623    foreign(Called, Src, Line).
  624xref_defined2(constraint(Line), Src, Called) :-
  625    constraint(Called, Src, Line).
  626xref_defined2(imported(From), Src, Called) :-
  627    imported(Called, Src, From).
 xref_definition_line(+How, -Line)
If the 3th argument of xref_defined contains line info, return this in Line.
  635xref_definition_line(local(Line),        Line).
  636xref_definition_line(dynamic(Line),      Line).
  637xref_definition_line(thread_local(Line), Line).
  638xref_definition_line(multifile(Line),    Line).
  639xref_definition_line(public(Line),       Line).
  640xref_definition_line(constraint(Line),   Line).
  641xref_definition_line(foreign(Line),      Line).
 xref_exported(?Source, ?Head) is nondet
True when Source exports Head.
  648xref_exported(Source, Called) :-
  649    prolog_canonical_source(Source, Src),
  650    exported(Called, Src).
 xref_module(?Source, ?Module) is nondet
True if Module is defined in Source.
  656xref_module(Source, Module) :-
  657    nonvar(Source),
  658    !,
  659    prolog_canonical_source(Source, Src),
  660    xmodule(Module, Src).
  661xref_module(Source, Module) :-
  662    xmodule(Module, Src),
  663    prolog_canonical_source(Source, Src).
 xref_uses_file(?Source, ?Spec, ?Path) is nondet
True when Source tries to load a file using Spec.
Arguments:
Spec- is a specification for absolute_file_name/3
Path- is either an absolute file name of the target file or the atom <not_found>.
  673xref_uses_file(Source, Spec, Path) :-
  674    prolog_canonical_source(Source, Src),
  675    uses_file(Spec, Src, Path).
 xref_op(?Source, Op) is nondet
Give the operators active inside the module. This is intended to setup the environment for incremental parsing of a term from the source-file.
Arguments:
Op- Term of the form op(Priority, Type, Name)
  685xref_op(Source, Op) :-
  686    prolog_canonical_source(Source, Src),
  687    xop(Src, Op).
 xref_prolog_flag(?Source, ?Flag, ?Value, ?Line) is nondet
True when Flag is set to Value at Line in Source. This is intended to support incremental parsing of a term from the source-file.
  695xref_prolog_flag(Source, Flag, Value, Line) :-
  696    prolog_canonical_source(Source, Src),
  697    xflag(Flag, Value, Src, Line).
  698
  699xref_built_in(Head) :-
  700    system_predicate(Head).
  701
  702xref_used_class(Source, Class) :-
  703    prolog_canonical_source(Source, Src),
  704    used_class(Class, Src).
  705
  706xref_defined_class(Source, Class, local(Line, Super, Summary)) :-
  707    prolog_canonical_source(Source, Src),
  708    defined_class(Class, Super, Summary, Src, Line),
  709    integer(Line),
  710    !.
  711xref_defined_class(Source, Class, file(File)) :-
  712    prolog_canonical_source(Source, Src),
  713    defined_class(Class, _, _, Src, file(File)).
  714
  715:- thread_local
  716    current_cond/1,
  717    source_line/1.  718
  719current_source_line(Line) :-
  720    source_line(Var),
  721    !,
  722    Line = Var.
 collect(+Source, +File, +Stream, +Options)
Process data from Source. If File \== Source, we are processing an included file. Stream is the stream from shich we read the program.
  730collect(Src, File, In, Options) :-
  731    (   Src == File
  732    ->  SrcSpec = Line
  733    ;   SrcSpec = (File:Line)
  734    ),
  735    option(comments(CommentHandling), Options, collect),
  736    (   CommentHandling == ignore
  737    ->  CommentOptions = [],
  738        Comments = []
  739    ;   CommentHandling == store
  740    ->  CommentOptions = [ process_comment(true) ],
  741        Comments = []
  742    ;   CommentOptions = [ comments(Comments) ]
  743    ),
  744    repeat,
  745        catch(prolog_read_source_term(
  746                  In, Term, Expanded,
  747                  [ term_position(TermPos)
  748                  | CommentOptions
  749                  ]),
  750              E, report_syntax_error(E, Src, [])),
  751        update_condition(Term),
  752        stream_position_data(line_count, TermPos, Line),
  753        setup_call_cleanup(
  754            asserta(source_line(SrcSpec), Ref),
  755            catch(process(Expanded, Comments, Term, TermPos, Src, EOF),
  756                  E, print_message(error, E)),
  757            erase(Ref)),
  758        EOF == true,
  759    !.
  760
  761report_syntax_error(E, _, _) :-
  762    fatal_error(E),
  763    throw(E).
  764report_syntax_error(_, _, Options) :-
  765    option(silent(true), Options),
  766    !,
  767    fail.
  768report_syntax_error(E, Src, _Options) :-
  769    (   verbose(Src)
  770    ->  print_message(error, E)
  771    ;   true
  772    ),
  773    fail.
  774
  775fatal_error(time_limit_exceeded).
  776fatal_error(error(resource_error(_),_)).
 update_condition(+Term) is det
Update the condition under which the current code is compiled.
  782update_condition((:-Directive)) :-
  783    !,
  784    update_cond(Directive).
  785update_condition(_).
  786
  787update_cond(if(Cond)) :-
  788    !,
  789    asserta(current_cond(Cond)).
  790update_cond(else) :-
  791    retract(current_cond(C0)),
  792    !,
  793    assert(current_cond(\+C0)).
  794update_cond(elif(Cond)) :-
  795    retract(current_cond(C0)),
  796    !,
  797    assert(current_cond((\+C0,Cond))).
  798update_cond(endif) :-
  799    retract(current_cond(_)),
  800    !.
  801update_cond(_).
 current_condition(-Condition) is det
Condition is the current compilation condition as defined by the :- if/1 directive and friends.
  808current_condition(Condition) :-
  809    \+ current_cond(_),
  810    !,
  811    Condition = true.
  812current_condition(Condition) :-
  813    findall(C, current_cond(C), List),
  814    list_to_conj(List, Condition).
  815
  816list_to_conj([], true).
  817list_to_conj([C], C) :- !.
  818list_to_conj([H|T], (H,C)) :-
  819    list_to_conj(T, C).
  820
  821
  822                 /*******************************
  823                 *           PROCESS            *
  824                 *******************************/
 process(+Expanded, +Comments, +Term, +TermPos, +Src, -EOF) is det
Process a source term that has been subject to term expansion as well as its optional leading structured comments.
Arguments:
TermPos- is the term position that describes the start of the term. We need this to find leading comments.
EOF- is unified with a boolean to indicate whether or not processing was stopped because end_of_file was processed.
  836process(Expanded, Comments, Term0, TermPos, Src, EOF) :-
  837    is_list(Expanded),                          % term_expansion into list.
  838    !,
  839    (   member(Term, Expanded),
  840        process(Term, Term0, Src),
  841        Term == end_of_file
  842    ->  EOF = true
  843    ;   EOF = false
  844    ),
  845    xref_comments(Comments, TermPos, Src).
  846process(end_of_file, _, _, _, _, true) :-
  847    !.
  848process(Term, Comments, Term0, TermPos, Src, false) :-
  849    process(Term, Term0, Src),
  850    xref_comments(Comments, TermPos, Src).
 process(+Term, +Term0, +Src) is det
  854process(_, Term0, _) :-
  855    ignore_raw_term(Term0),
  856    !.
  857process(Term, _Term0, Src) :-
  858    process(Term, Src).
  859
  860ignore_raw_term((:- predicate_options(_,_,_))).
 process(+Term, +Src) is det
  864process(Var, _) :-
  865    var(Var),
  866    !.                    % Warn?
  867process(end_of_file, _) :- !.
  868process((:- Directive), Src) :-
  869    !,
  870    process_directive(Directive, Src),
  871    !.
  872process((?- Directive), Src) :-
  873    !,
  874    process_directive(Directive, Src),
  875    !.
  876process((Head :- Body), Src) :-
  877    !,
  878    assert_defined(Src, Head),
  879    process_body(Body, Head, Src).
  880process('$source_location'(_File, _Line):Clause, Src) :-
  881    !,
  882    process(Clause, Src).
  883process(Term, Src) :-
  884    process_chr(Term, Src),
  885    !.
  886process(M:(Head :- Body), Src) :-
  887    !,
  888    process((M:Head :- M:Body), Src).
  889process(Head, Src) :-
  890    assert_defined(Src, Head).
  891
  892
  893                 /*******************************
  894                 *            COMMENTS          *
  895                 *******************************/
 xref_comments(+Comments, +FilePos, +Src) is det
  899xref_comments([], _Pos, _Src).
  900:- if(current_predicate(parse_comment/3)).  901xref_comments([Pos-Comment|T], TermPos, Src) :-
  902    (   Pos @> TermPos              % comments inside term
  903    ->  true
  904    ;   stream_position_data(line_count, Pos, Line),
  905        FilePos = Src:Line,
  906        (   parse_comment(Comment, FilePos, Parsed)
  907        ->  assert_comments(Parsed, Src)
  908        ;   true
  909        ),
  910        xref_comments(T, TermPos, Src)
  911    ).
  912
  913assert_comments([], _).
  914assert_comments([H|T], Src) :-
  915    assert_comment(H, Src),
  916    assert_comments(T, Src).
  917
  918assert_comment(section(_Id, Title, Comment), Src) :-
  919    assertz(module_comment(Src, Title, Comment)).
  920assert_comment(predicate(PI, Summary, Comment), Src) :-
  921    pi_to_head(PI, Src, Head),
  922    assertz(pred_comment(Head, Src, Summary, Comment)).
  923assert_comment(link(PI, PITo), Src) :-
  924    pi_to_head(PI, Src, Head),
  925    pi_to_head(PITo, Src, HeadTo),
  926    assertz(pred_comment_link(Head, Src, HeadTo)).
  927assert_comment(mode(Head, Det), Src) :-
  928    assertz(pred_mode(Head, Src, Det)).
  929
  930pi_to_head(PI, Src, Head) :-
  931    pi_to_head(PI, Head0),
  932    (   Head0 = _:_
  933    ->  strip_module(Head0, M, Plain),
  934        (   xmodule(M, Src)
  935        ->  Head = Plain
  936        ;   Head = M:Plain
  937        )
  938    ;   Head = Head0
  939    ).
  940:- endif.
 xref_comment(?Source, ?Title, ?Comment) is nondet
Is true when Source has a section comment with Title and Comment
  946xref_comment(Source, Title, Comment) :-
  947    canonical_source(Source, Src),
  948    module_comment(Src, Title, Comment).
 xref_comment(?Source, ?Head, ?Summary, ?Comment) is nondet
Is true when Head in Source has the given PlDoc comment.
  954xref_comment(Source, Head, Summary, Comment) :-
  955    canonical_source(Source, Src),
  956    (   pred_comment(Head, Src, Summary, Comment)
  957    ;   pred_comment_link(Head, Src, HeadTo),
  958        pred_comment(HeadTo, Src, Summary, Comment)
  959    ).
 xref_mode(?Source, ?Mode, ?Det) is nondet
Is true when Source provides a predicate with Mode and determinism.
  966xref_mode(Source, Mode, Det) :-
  967    canonical_source(Source, Src),
  968    pred_mode(Mode, Src, Det).
 xref_option(?Source, ?Option) is nondet
True when Source was processed using Option. Options are defined with xref_source/2.
  975xref_option(Source, Option) :-
  976    canonical_source(Source, Src),
  977    xoption(Src, Option).
  978
  979
  980                 /********************************
  981                 *           DIRECTIVES         *
  982                 ********************************/
  983
  984process_directive(Var, _) :-
  985    var(Var),
  986    !.                    % error, but that isn't our business
  987process_directive(Dir, _Src) :-
  988    debug(xref(directive), 'Processing :- ~q', [Dir]),
  989    fail.
  990process_directive((A,B), Src) :-       % TBD: what about other control
  991    !,
  992    process_directive(A, Src),      % structures?
  993    process_directive(B, Src).
  994process_directive(List, Src) :-
  995    is_list(List),
  996    !,
  997    process_directive(consult(List), Src).
  998process_directive(use_module(File, Import), Src) :-
  999    process_use_module2(File, Import, Src, false).
 1000process_directive(autoload(File, Import), Src) :-
 1001    process_use_module2(File, Import, Src, false).
 1002process_directive(require(Import), Src) :-
 1003    process_requires(Import, Src).
 1004process_directive(expects_dialect(Dialect), Src) :-
 1005    process_directive(use_module(library(dialect/Dialect)), Src),
 1006    expects_dialect(Dialect).
 1007process_directive(reexport(File, Import), Src) :-
 1008    process_use_module2(File, Import, Src, true).
 1009process_directive(reexport(Modules), Src) :-
 1010    process_use_module(Modules, Src, true).
 1011process_directive(autoload(Modules), Src) :-
 1012    process_use_module(Modules, Src, false).
 1013process_directive(use_module(Modules), Src) :-
 1014    process_use_module(Modules, Src, false).
 1015process_directive(consult(Modules), Src) :-
 1016    process_use_module(Modules, Src, false).
 1017process_directive(ensure_loaded(Modules), Src) :-
 1018    process_use_module(Modules, Src, false).
 1019process_directive(load_files(Files, _Options), Src) :-
 1020    process_use_module(Files, Src, false).
 1021process_directive(include(Files), Src) :-
 1022    process_include(Files, Src).
 1023process_directive(dynamic(Dynamic), Src) :-
 1024    process_predicates(assert_dynamic, Dynamic, Src).
 1025process_directive(dynamic(Dynamic, _Options), Src) :-
 1026    process_predicates(assert_dynamic, Dynamic, Src).
 1027process_directive(thread_local(Dynamic), Src) :-
 1028    process_predicates(assert_thread_local, Dynamic, Src).
 1029process_directive(multifile(Dynamic), Src) :-
 1030    process_predicates(assert_multifile, Dynamic, Src).
 1031process_directive(public(Public), Src) :-
 1032    process_predicates(assert_public, Public, Src).
 1033process_directive(export(Export), Src) :-
 1034    process_predicates(assert_export, Export, Src).
 1035process_directive(import(Import), Src) :-
 1036    process_import(Import, Src).
 1037process_directive(module(Module, Export), Src) :-
 1038    assert_module(Src, Module),
 1039    assert_module_export(Src, Export).
 1040process_directive(module(Module, Export, Import), Src) :-
 1041    assert_module(Src, Module),
 1042    assert_module_export(Src, Export),
 1043    assert_module3(Import, Src).
 1044process_directive('$set_source_module'(system), Src) :-
 1045    assert_module(Src, system).     % hack for handling boot/init.pl
 1046process_directive(pce_begin_class_definition(Name, Meta, Super, Doc), Src) :-
 1047    assert_defined_class(Src, Name, Meta, Super, Doc).
 1048process_directive(pce_autoload(Name, From), Src) :-
 1049    assert_defined_class(Src, Name, imported_from(From)).
 1050
 1051process_directive(op(P, A, N), Src) :-
 1052    xref_push_op(Src, P, A, N).
 1053process_directive(set_prolog_flag(Flag, Value), Src) :-
 1054    (   Flag == character_escapes
 1055    ->  set_prolog_flag(character_escapes, Value)
 1056    ;   true
 1057    ),
 1058    current_source_line(Line),
 1059    xref_set_prolog_flag(Flag, Value, Src, Line).
 1060process_directive(style_check(X), _) :-
 1061    style_check(X).
 1062process_directive(encoding(Enc), _) :-
 1063    (   xref_input_stream(Stream)
 1064    ->  catch(set_stream(Stream, encoding(Enc)), _, true)
 1065    ;   true                        % can this happen?
 1066    ).
 1067process_directive(pce_expansion:push_compile_operators, _) :-
 1068    '$current_source_module'(SM),
 1069    call(pce_expansion:push_compile_operators(SM)). % call to avoid xref
 1070process_directive(pce_expansion:pop_compile_operators, _) :-
 1071    call(pce_expansion:pop_compile_operators).
 1072process_directive(meta_predicate(Meta), Src) :-
 1073    process_meta_predicate(Meta, Src).
 1074process_directive(arithmetic_function(FSpec), Src) :-
 1075    arith_callable(FSpec, Goal),
 1076    !,
 1077    current_source_line(Line),
 1078    assert_called(Src, '<directive>'(Line), Goal, Line).
 1079process_directive(format_predicate(_, Goal), Src) :-
 1080    !,
 1081    current_source_line(Line),
 1082    assert_called(Src, '<directive>'(Line), Goal, Line).
 1083process_directive(if(Cond), Src) :-
 1084    !,
 1085    current_source_line(Line),
 1086    assert_called(Src, '<directive>'(Line), Cond, Line).
 1087process_directive(elif(Cond), Src) :-
 1088    !,
 1089    current_source_line(Line),
 1090    assert_called(Src, '<directive>'(Line), Cond, Line).
 1091process_directive(else, _) :- !.
 1092process_directive(endif, _) :- !.
 1093process_directive(Goal, Src) :-
 1094    current_source_line(Line),
 1095    process_body(Goal, '<directive>'(Line), Src).
 process_meta_predicate(+Decl, +Src)
Create meta_goal/3 facts from the meta-goal declaration.
 1101process_meta_predicate((A,B), Src) :-
 1102    !,
 1103    process_meta_predicate(A, Src),
 1104    process_meta_predicate(B, Src).
 1105process_meta_predicate(Decl, Src) :-
 1106    process_meta_head(Src, Decl).
 1107
 1108process_meta_head(Src, Decl) :-         % swapped arguments for maplist
 1109    compound(Decl),
 1110    compound_name_arity(Decl, Name, Arity),
 1111    compound_name_arity(Head, Name, Arity),
 1112    meta_args(1, Arity, Decl, Head, Meta),
 1113    (   (   prolog:meta_goal(Head, _)
 1114        ;   prolog:called_by(Head, _, _, _)
 1115        ;   prolog:called_by(Head, _)
 1116        ;   meta_goal(Head, _)
 1117        )
 1118    ->  true
 1119    ;   assert(meta_goal(Head, Meta, Src))
 1120    ).
 1121
 1122meta_args(I, Arity, _, _, []) :-
 1123    I > Arity,
 1124    !.
 1125meta_args(I, Arity, Decl, Head, [H|T]) :-               % 0
 1126    arg(I, Decl, 0),
 1127    !,
 1128    arg(I, Head, H),
 1129    I2 is I + 1,
 1130    meta_args(I2, Arity, Decl, Head, T).
 1131meta_args(I, Arity, Decl, Head, [H|T]) :-               % ^
 1132    arg(I, Decl, ^),
 1133    !,
 1134    arg(I, Head, EH),
 1135    setof_goal(EH, H),
 1136    I2 is I + 1,
 1137    meta_args(I2, Arity, Decl, Head, T).
 1138meta_args(I, Arity, Decl, Head, [//(H)|T]) :-
 1139    arg(I, Decl, //),
 1140    !,
 1141    arg(I, Head, H),
 1142    I2 is I + 1,
 1143    meta_args(I2, Arity, Decl, Head, T).
 1144meta_args(I, Arity, Decl, Head, [H+A|T]) :-             % I --> H+I
 1145    arg(I, Decl, A),
 1146    integer(A), A > 0,
 1147    !,
 1148    arg(I, Head, H),
 1149    I2 is I + 1,
 1150    meta_args(I2, Arity, Decl, Head, T).
 1151meta_args(I, Arity, Decl, Head, Meta) :-
 1152    I2 is I + 1,
 1153    meta_args(I2, Arity, Decl, Head, Meta).
 1154
 1155
 1156              /********************************
 1157              *             BODY              *
 1158              ********************************/
 xref_meta(+Source, +Head, -Called) is semidet
True when Head calls Called in Source.
Arguments:
Called- is a list of called terms, terms of the form Term+Extra or terms of the form //(Term).
 1167xref_meta(Source, Head, Called) :-
 1168    canonical_source(Source, Src),
 1169    xref_meta_src(Head, Called, Src).
 xref_meta(+Head, -Called) is semidet
 xref_meta_src(+Head, -Called, +Src) is semidet
True when Called is a list of terms called from Head. Each element in Called can be of the form Term+Int, which means that Term must be extended with Int additional arguments. The variant xref_meta/3 first queries the local context.
deprecated
- New code should use xref_meta/3.
To be done
- Split predifined in several categories. E.g., the ISO predicates cannot be redefined.
- Rely on the meta_predicate property for many predicates.
 1184xref_meta_src(Head, Called, Src) :-
 1185    meta_goal(Head, Called, Src),
 1186    !.
 1187xref_meta_src(Head, Called, _) :-
 1188    xref_meta(Head, Called),
 1189    !.
 1190xref_meta_src(Head, Called, _) :-
 1191    compound(Head),
 1192    compound_name_arity(Head, Name, Arity),
 1193    apply_pred(Name),
 1194    Arity > 5,
 1195    !,
 1196    Extra is Arity - 1,
 1197    arg(1, Head, G),
 1198    Called = [G+Extra].
 1199
 1200apply_pred(call).                               % built-in
 1201apply_pred(maplist).                            % library(apply_macros)
 1202
 1203xref_meta((A, B),               [A, B]).
 1204xref_meta((A; B),               [A, B]).
 1205xref_meta((A| B),               [A, B]).
 1206xref_meta((A -> B),             [A, B]).
 1207xref_meta((A *-> B),            [A, B]).
 1208xref_meta(findall(_V,G,_L),     [G]).
 1209xref_meta(findall(_V,G,_L,_T),  [G]).
 1210xref_meta(findnsols(_N,_V,G,_L),    [G]).
 1211xref_meta(findnsols(_N,_V,G,_L,_T), [G]).
 1212xref_meta(setof(_V, EG, _L),    [G]) :-
 1213    setof_goal(EG, G).
 1214xref_meta(bagof(_V, EG, _L),    [G]) :-
 1215    setof_goal(EG, G).
 1216xref_meta(forall(A, B),         [A, B]).
 1217xref_meta(maplist(G,_),         [G+1]).
 1218xref_meta(maplist(G,_,_),       [G+2]).
 1219xref_meta(maplist(G,_,_,_),     [G+3]).
 1220xref_meta(maplist(G,_,_,_,_),   [G+4]).
 1221xref_meta(map_list_to_pairs(G,_,_), [G+2]).
 1222xref_meta(map_assoc(G, _),      [G+1]).
 1223xref_meta(map_assoc(G, _, _),   [G+2]).
 1224xref_meta(checklist(G, _L),     [G+1]).
 1225xref_meta(sublist(G, _, _),     [G+1]).
 1226xref_meta(include(G, _, _),     [G+1]).
 1227xref_meta(exclude(G, _, _),     [G+1]).
 1228xref_meta(partition(G, _, _, _, _),     [G+2]).
 1229xref_meta(partition(G, _, _, _),[G+1]).
 1230xref_meta(call(G),              [G]).
 1231xref_meta(call(G, _),           [G+1]).
 1232xref_meta(call(G, _, _),        [G+2]).
 1233xref_meta(call(G, _, _, _),     [G+3]).
 1234xref_meta(call(G, _, _, _, _),  [G+4]).
 1235xref_meta(not(G),               [G]).
 1236xref_meta(notrace(G),           [G]).
 1237xref_meta(\+(G),                [G]).
 1238xref_meta(ignore(G),            [G]).
 1239xref_meta(once(G),              [G]).
 1240xref_meta(initialization(G),    [G]).
 1241xref_meta(initialization(G,_),  [G]).
 1242xref_meta(retract(Rule),        [G]) :- head_of(Rule, G).
 1243xref_meta(clause(G, _),         [G]).
 1244xref_meta(clause(G, _, _),      [G]).
 1245xref_meta(phrase(G, _A),        [//(G)]).
 1246xref_meta(phrase(G, _A, _R),    [//(G)]).
 1247xref_meta(call_dcg(G, _A, _R),  [//(G)]).
 1248xref_meta(phrase_from_file(G,_),[//(G)]).
 1249xref_meta(catch(A, _, B),       [A, B]).
 1250xref_meta(catch_with_backtrace(A, _, B), [A, B]).
 1251xref_meta(thread_create(A,_,_), [A]).
 1252xref_meta(thread_create(A,_),   [A]).
 1253xref_meta(thread_signal(_,A),   [A]).
 1254xref_meta(thread_idle(A,_),     [A]).
 1255xref_meta(thread_at_exit(A),    [A]).
 1256xref_meta(thread_initialization(A), [A]).
 1257xref_meta(engine_create(_,A,_), [A]).
 1258xref_meta(engine_create(_,A,_,_), [A]).
 1259xref_meta(transaction(A),       [A]).
 1260xref_meta(transaction(A,B,_),   [A,B]).
 1261xref_meta(snapshot(A),          [A]).
 1262xref_meta(predsort(A,_,_),      [A+3]).
 1263xref_meta(call_cleanup(A, B),   [A, B]).
 1264xref_meta(call_cleanup(A, _, B),[A, B]).
 1265xref_meta(setup_call_cleanup(A, B, C),[A, B, C]).
 1266xref_meta(setup_call_catcher_cleanup(A, B, _, C),[A, B, C]).
 1267xref_meta(call_residue_vars(A,_), [A]).
 1268xref_meta(with_mutex(_,A),      [A]).
 1269xref_meta(assume(G),            [G]).   % library(debug)
 1270xref_meta(assertion(G),         [G]).   % library(debug)
 1271xref_meta(freeze(_, G),         [G]).
 1272xref_meta(when(C, A),           [C, A]).
 1273xref_meta(time(G),              [G]).   % development system
 1274xref_meta(profile(G),           [G]).
 1275xref_meta(at_halt(G),           [G]).
 1276xref_meta(call_with_time_limit(_, G), [G]).
 1277xref_meta(call_with_depth_limit(G, _, _), [G]).
 1278xref_meta(call_with_inference_limit(G, _, _), [G]).
 1279xref_meta(alarm(_, G, _),       [G]).
 1280xref_meta(alarm(_, G, _, _),    [G]).
 1281xref_meta('$add_directive_wic'(G), [G]).
 1282xref_meta(with_output_to(_, G), [G]).
 1283xref_meta(if(G),                [G]).
 1284xref_meta(elif(G),              [G]).
 1285xref_meta(meta_options(G,_,_),  [G+1]).
 1286xref_meta(on_signal(_,_,H),     [H+1]) :- H \== default.
 1287xref_meta(distinct(G),          [G]).   % library(solution_sequences)
 1288xref_meta(distinct(_, G),       [G]).
 1289xref_meta(order_by(_, G),       [G]).
 1290xref_meta(limit(_, G),          [G]).
 1291xref_meta(offset(_, G),         [G]).
 1292xref_meta(reset(G,_,_),         [G]).
 1293xref_meta(prolog_listen(Ev,G),  [G+N]) :- event_xargs(Ev, N).
 1294xref_meta(prolog_listen(Ev,G,_),[G+N]) :- event_xargs(Ev, N).
 1295xref_meta(tnot(G),		[G]).
 1296xref_meta(not_exists(G),	[G]).
 1297
 1298                                        % XPCE meta-predicates
 1299xref_meta(pce_global(_, new(_)), _) :- !, fail.
 1300xref_meta(pce_global(_, B),     [B+1]).
 1301xref_meta(ifmaintainer(G),      [G]).   % used in manual
 1302xref_meta(listen(_, G),         [G]).   % library(broadcast)
 1303xref_meta(listen(_, _, G),      [G]).
 1304xref_meta(in_pce_thread(G),     [G]).
 1305
 1306xref_meta(G, Meta) :-                   % call user extensions
 1307    prolog:meta_goal(G, Meta).
 1308xref_meta(G, Meta) :-                   % Generated from :- meta_predicate
 1309    meta_goal(G, Meta).
 1310
 1311setof_goal(EG, G) :-
 1312    var(EG), !, G = EG.
 1313setof_goal(_^EG, G) :-
 1314    !,
 1315    setof_goal(EG, G).
 1316setof_goal(G, G).
 1317
 1318event_xargs(abort,            0).
 1319event_xargs(erase,            1).
 1320event_xargs(break,            3).
 1321event_xargs(frame_finished,   1).
 1322event_xargs(thread_exit,      1).
 1323event_xargs(this_thread_exit, 0).
 1324event_xargs(PI,               2) :- pi_to_head(PI, _).
 head_of(+Rule, -Head)
Get the head for a retract call.
 1330head_of(Var, _) :-
 1331    var(Var), !, fail.
 1332head_of((Head :- _), Head).
 1333head_of(Head, Head).
 xref_hook(?Callable)
Definition of known hooks. Hooks that can be called in any module are unqualified. Other hooks are qualified with the module where they are called.
 1341xref_hook(Hook) :-
 1342    prolog:hook(Hook).
 1343xref_hook(Hook) :-
 1344    hook(Hook).
 1345
 1346
 1347hook(attr_portray_hook(_,_)).
 1348hook(attr_unify_hook(_,_)).
 1349hook(attribute_goals(_,_,_)).
 1350hook(goal_expansion(_,_)).
 1351hook(term_expansion(_,_)).
 1352hook(resource(_,_,_)).
 1353hook('$pred_option'(_,_,_,_)).
 1354
 1355hook(emacs_prolog_colours:goal_classification(_,_)).
 1356hook(emacs_prolog_colours:term_colours(_,_)).
 1357hook(emacs_prolog_colours:goal_colours(_,_)).
 1358hook(emacs_prolog_colours:style(_,_)).
 1359hook(emacs_prolog_colours:identify(_,_)).
 1360hook(pce_principal:pce_class(_,_,_,_,_,_)).
 1361hook(pce_principal:send_implementation(_,_,_)).
 1362hook(pce_principal:get_implementation(_,_,_,_)).
 1363hook(pce_principal:pce_lazy_get_method(_,_,_)).
 1364hook(pce_principal:pce_lazy_send_method(_,_,_)).
 1365hook(pce_principal:pce_uses_template(_,_)).
 1366hook(prolog:locate_clauses(_,_)).
 1367hook(prolog:message(_,_,_)).
 1368hook(prolog:error_message(_,_,_)).
 1369hook(prolog:message_location(_,_,_)).
 1370hook(prolog:message_context(_,_,_)).
 1371hook(prolog:message_line_element(_,_)).
 1372hook(prolog:debug_control_hook(_)).
 1373hook(prolog:help_hook(_)).
 1374hook(prolog:show_profile_hook(_,_)).
 1375hook(prolog:general_exception(_,_)).
 1376hook(prolog:predicate_summary(_,_)).
 1377hook(prolog:residual_goals(_,_)).
 1378hook(prolog_edit:load).
 1379hook(prolog_edit:locate(_,_,_)).
 1380hook(shlib:unload_all_foreign_libraries).
 1381hook(system:'$foreign_registered'(_, _)).
 1382hook(predicate_options:option_decl(_,_,_)).
 1383hook(user:exception(_,_,_)).
 1384hook(user:file_search_path(_,_)).
 1385hook(user:library_directory(_)).
 1386hook(user:message_hook(_,_,_)).
 1387hook(user:portray(_)).
 1388hook(user:prolog_clause_name(_,_)).
 1389hook(user:prolog_list_goal(_)).
 1390hook(user:prolog_predicate_name(_,_)).
 1391hook(user:prolog_trace_interception(_,_,_,_)).
 1392hook(user:prolog_exception_hook(_,_,_,_)).
 1393hook(sandbox:safe_primitive(_)).
 1394hook(sandbox:safe_meta_predicate(_)).
 1395hook(sandbox:safe_meta(_,_)).
 1396hook(sandbox:safe_global_variable(_)).
 1397hook(sandbox:safe_directive(_)).
 arith_callable(+Spec, -Callable)
Translate argument of arithmetic_function/1 into a callable term
 1404arith_callable(Var, _) :-
 1405    var(Var), !, fail.
 1406arith_callable(Module:Spec, Module:Goal) :-
 1407    !,
 1408    arith_callable(Spec, Goal).
 1409arith_callable(Name/Arity, Goal) :-
 1410    PredArity is Arity + 1,
 1411    functor(Goal, Name, PredArity).
 process_body(+Body, +Origin, +Src) is det
Process a callable body (body of a clause or directive). Origin describes the origin of the call. Partial evaluation may lead to non-determinism, which is why we backtrack over process_goal/3.

We limit the number of explored paths to 100 to avoid getting trapped in this analysis.

 1422process_body(Body, Origin, Src) :-
 1423    forall(limit(100, process_goal(Body, Origin, Src, _Partial)),
 1424           true).
 process_goal(+Goal, +Origin, +Src, ?Partial) is multi
Xref Goal. The argument Partial is bound to true if there was a partial evalation inside Goal that has bound variables.
 1431process_goal(Var, _, _, _) :-
 1432    var(Var),
 1433    !.
 1434process_goal(Goal, Origin, Src, P) :-
 1435    Goal = (_,_),                               % problems
 1436    !,
 1437    phrase(conjunction(Goal), Goals),
 1438    process_conjunction(Goals, Origin, Src, P).
 1439process_goal(Goal, Origin, Src, _) :-           % Final disjunction, no
 1440    Goal = (_;_),                               % problems
 1441    !,
 1442    phrase(disjunction(Goal), Goals),
 1443    forall(member(G, Goals),
 1444           process_body(G, Origin, Src)).
 1445process_goal(Goal, Origin, Src, P) :-
 1446    (   (   xmodule(M, Src)
 1447        ->  true
 1448        ;   M = user
 1449        ),
 1450        (   predicate_property(M:Goal, imported_from(IM))
 1451        ->  true
 1452        ;   IM = M
 1453        ),
 1454        prolog:called_by(Goal, IM, M, Called)
 1455    ;   prolog:called_by(Goal, Called)
 1456    ),
 1457    !,
 1458    must_be(list, Called),
 1459    current_source_line(Here),
 1460    assert_called(Src, Origin, Goal, Here),
 1461    process_called_list(Called, Origin, Src, P).
 1462process_goal(Goal, Origin, Src, _) :-
 1463    process_xpce_goal(Goal, Origin, Src),
 1464    !.
 1465process_goal(load_foreign_library(File), _Origin, Src, _) :-
 1466    process_foreign(File, Src).
 1467process_goal(load_foreign_library(File, _Init), _Origin, Src, _) :-
 1468    process_foreign(File, Src).
 1469process_goal(use_foreign_library(File), _Origin, Src, _) :-
 1470    process_foreign(File, Src).
 1471process_goal(use_foreign_library(File, _Init), _Origin, Src, _) :-
 1472    process_foreign(File, Src).
 1473process_goal(Goal, Origin, Src, P) :-
 1474    xref_meta_src(Goal, Metas, Src),
 1475    !,
 1476    current_source_line(Here),
 1477    assert_called(Src, Origin, Goal, Here),
 1478    process_called_list(Metas, Origin, Src, P).
 1479process_goal(Goal, Origin, Src, _) :-
 1480    asserting_goal(Goal, Rule),
 1481    !,
 1482    current_source_line(Here),
 1483    assert_called(Src, Origin, Goal, Here),
 1484    process_assert(Rule, Origin, Src).
 1485process_goal(Goal, Origin, Src, P) :-
 1486    partial_evaluate(Goal, P),
 1487    current_source_line(Here),
 1488    assert_called(Src, Origin, Goal, Here).
 1489
 1490disjunction(Var)   --> {var(Var), !}, [Var].
 1491disjunction((A;B)) --> !, disjunction(A), disjunction(B).
 1492disjunction(G)     --> [G].
 1493
 1494conjunction(Var)   --> {var(Var), !}, [Var].
 1495conjunction((A,B)) --> !, conjunction(A), conjunction(B).
 1496conjunction(G)     --> [G].
 1497
 1498shares_vars(RVars, T) :-
 1499    term_variables(T, TVars0),
 1500    sort(TVars0, TVars),
 1501    ord_intersect(RVars, TVars).
 1502
 1503process_conjunction([], _, _, _).
 1504process_conjunction([Disj|Rest], Origin, Src, P) :-
 1505    nonvar(Disj),
 1506    Disj = (_;_),
 1507    Rest \== [],
 1508    !,
 1509    phrase(disjunction(Disj), Goals),
 1510    term_variables(Rest, RVars0),
 1511    sort(RVars0, RVars),
 1512    partition(shares_vars(RVars), Goals, Sharing, NonSHaring),
 1513    forall(member(G, NonSHaring),
 1514           process_body(G, Origin, Src)),
 1515    (   Sharing == []
 1516    ->  true
 1517    ;   maplist(term_variables, Sharing, GVars0),
 1518        append(GVars0, GVars1),
 1519        sort(GVars1, GVars),
 1520        ord_intersection(GVars, RVars, SVars),
 1521        VT =.. [v|SVars],
 1522        findall(VT,
 1523                (   member(G, Sharing),
 1524                    process_goal(G, Origin, Src, PS),
 1525                    PS == true
 1526                ),
 1527                Alts0),
 1528        (   Alts0 == []
 1529        ->  true
 1530        ;   (   true
 1531            ;   P = true,
 1532                sort(Alts0, Alts1),
 1533                variants(Alts1, 10, Alts),
 1534                member(VT, Alts)
 1535            )
 1536        )
 1537    ),
 1538    process_conjunction(Rest, Origin, Src, P).
 1539process_conjunction([H|T], Origin, Src, P) :-
 1540    process_goal(H, Origin, Src, P),
 1541    process_conjunction(T, Origin, Src, P).
 1542
 1543
 1544process_called_list([], _, _, _).
 1545process_called_list([H|T], Origin, Src, P) :-
 1546    process_meta(H, Origin, Src, P),
 1547    process_called_list(T, Origin, Src, P).
 1548
 1549process_meta(A+N, Origin, Src, P) :-
 1550    !,
 1551    (   extend(A, N, AX)
 1552    ->  process_goal(AX, Origin, Src, P)
 1553    ;   true
 1554    ).
 1555process_meta(//(A), Origin, Src, P) :-
 1556    !,
 1557    process_dcg_goal(A, Origin, Src, P).
 1558process_meta(G, Origin, Src, P) :-
 1559    process_goal(G, Origin, Src, P).
 process_dcg_goal(+Grammar, +Origin, +Src, ?Partial) is det
Process meta-arguments that are tagged with //, such as phrase/3.
 1566process_dcg_goal(Var, _, _, _) :-
 1567    var(Var),
 1568    !.
 1569process_dcg_goal((A,B), Origin, Src, P) :-
 1570    !,
 1571    process_dcg_goal(A, Origin, Src, P),
 1572    process_dcg_goal(B, Origin, Src, P).
 1573process_dcg_goal((A;B), Origin, Src, P) :-
 1574    !,
 1575    process_dcg_goal(A, Origin, Src, P),
 1576    process_dcg_goal(B, Origin, Src, P).
 1577process_dcg_goal((A|B), Origin, Src, P) :-
 1578    !,
 1579    process_dcg_goal(A, Origin, Src, P),
 1580    process_dcg_goal(B, Origin, Src, P).
 1581process_dcg_goal((A->B), Origin, Src, P) :-
 1582    !,
 1583    process_dcg_goal(A, Origin, Src, P),
 1584    process_dcg_goal(B, Origin, Src, P).
 1585process_dcg_goal((A*->B), Origin, Src, P) :-
 1586    !,
 1587    process_dcg_goal(A, Origin, Src, P),
 1588    process_dcg_goal(B, Origin, Src, P).
 1589process_dcg_goal({Goal}, Origin, Src, P) :-
 1590    !,
 1591    process_goal(Goal, Origin, Src, P).
 1592process_dcg_goal(List, _Origin, _Src, _) :-
 1593    is_list(List),
 1594    !.               % terminal
 1595process_dcg_goal(List, _Origin, _Src, _) :-
 1596    string(List),
 1597    !.                % terminal
 1598process_dcg_goal(Callable, Origin, Src, P) :-
 1599    extend(Callable, 2, Goal),
 1600    !,
 1601    process_goal(Goal, Origin, Src, P).
 1602process_dcg_goal(_, _, _, _).
 1603
 1604
 1605extend(Var, _, _) :-
 1606    var(Var), !, fail.
 1607extend(M:G, N, M:GX) :-
 1608    !,
 1609    callable(G),
 1610    extend(G, N, GX).
 1611extend(G, N, GX) :-
 1612    (   compound(G)
 1613    ->  compound_name_arguments(G, Name, Args),
 1614        length(Rest, N),
 1615        append(Args, Rest, NArgs),
 1616        compound_name_arguments(GX, Name, NArgs)
 1617    ;   atom(G)
 1618    ->  length(NArgs, N),
 1619        compound_name_arguments(GX, G, NArgs)
 1620    ).
 1621
 1622asserting_goal(assert(Rule), Rule).
 1623asserting_goal(asserta(Rule), Rule).
 1624asserting_goal(assertz(Rule), Rule).
 1625asserting_goal(assert(Rule,_), Rule).
 1626asserting_goal(asserta(Rule,_), Rule).
 1627asserting_goal(assertz(Rule,_), Rule).
 1628
 1629process_assert(0, _, _) :- !.           % catch variables
 1630process_assert((_:-Body), Origin, Src) :-
 1631    !,
 1632    process_body(Body, Origin, Src).
 1633process_assert(_, _, _).
 variants(+SortedList, +Max, -Variants) is det
 1637variants([], _, []).
 1638variants([H|T], Max, List) :-
 1639    variants(T, H, Max, List).
 1640
 1641variants([], H, _, [H]).
 1642variants(_, _, 0, []) :- !.
 1643variants([H|T], V, Max, List) :-
 1644    (   H =@= V
 1645    ->  variants(T, V, Max, List)
 1646    ;   List = [V|List2],
 1647        Max1 is Max-1,
 1648        variants(T, H, Max1, List2)
 1649    ).
 partial_evaluate(+Goal, ?Parrial) is det
Perform partial evaluation on Goal to trap cases such as below.
      T = hello(X),
      findall(T, T, List),
To be done
- Make this user extensible? What about non-deterministic bindings?
 1663partial_evaluate(Goal, P) :-
 1664    eval(Goal),
 1665    !,
 1666    P = true.
 1667partial_evaluate(_, _).
 1668
 1669eval(X = Y) :-
 1670    unify_with_occurs_check(X, Y).
 1671
 1672
 1673                 /*******************************
 1674                 *          XPCE STUFF          *
 1675                 *******************************/
 1676
 1677pce_goal(new(_,_), new(-, new)).
 1678pce_goal(send(_,_), send(arg, msg)).
 1679pce_goal(send_class(_,_,_), send_class(arg, arg, msg)).
 1680pce_goal(get(_,_,_), get(arg, msg, -)).
 1681pce_goal(get_class(_,_,_,_), get_class(arg, arg, msg, -)).
 1682pce_goal(get_chain(_,_,_), get_chain(arg, msg, -)).
 1683pce_goal(get_object(_,_,_), get_object(arg, msg, -)).
 1684
 1685process_xpce_goal(G, Origin, Src) :-
 1686    pce_goal(G, Process),
 1687    !,
 1688    current_source_line(Here),
 1689    assert_called(Src, Origin, G, Here),
 1690    (   arg(I, Process, How),
 1691        arg(I, G, Term),
 1692        process_xpce_arg(How, Term, Origin, Src),
 1693        fail
 1694    ;   true
 1695    ).
 1696
 1697process_xpce_arg(new, Term, Origin, Src) :-
 1698    callable(Term),
 1699    process_new(Term, Origin, Src).
 1700process_xpce_arg(arg, Term, Origin, Src) :-
 1701    compound(Term),
 1702    process_new(Term, Origin, Src).
 1703process_xpce_arg(msg, Term, Origin, Src) :-
 1704    compound(Term),
 1705    (   arg(_, Term, Arg),
 1706        process_xpce_arg(arg, Arg, Origin, Src),
 1707        fail
 1708    ;   true
 1709    ).
 1710
 1711process_new(_M:_Term, _, _) :- !.       % TBD: Calls on other modules!
 1712process_new(Term, Origin, Src) :-
 1713    assert_new(Src, Origin, Term),
 1714    (   compound(Term),
 1715        arg(_, Term, Arg),
 1716        process_xpce_arg(arg, Arg, Origin, Src),
 1717        fail
 1718    ;   true
 1719    ).
 1720
 1721assert_new(_, _, Term) :-
 1722    \+ callable(Term),
 1723    !.
 1724assert_new(Src, Origin, Control) :-
 1725    functor_name(Control, Class),
 1726    pce_control_class(Class),
 1727    !,
 1728    forall(arg(_, Control, Arg),
 1729           assert_new(Src, Origin, Arg)).
 1730assert_new(Src, Origin, Term) :-
 1731    compound(Term),
 1732    arg(1, Term, Prolog),
 1733    Prolog == @(prolog),
 1734    (   Term =.. [message, _, Selector | T],
 1735        atom(Selector)
 1736    ->  Called =.. [Selector|T],
 1737        process_body(Called, Origin, Src)
 1738    ;   Term =.. [?, _, Selector | T],
 1739        atom(Selector)
 1740    ->  append(T, [_R], T2),
 1741        Called =.. [Selector|T2],
 1742        process_body(Called, Origin, Src)
 1743    ),
 1744    fail.
 1745assert_new(_, _, @(_)) :- !.
 1746assert_new(Src, _, Term) :-
 1747    functor_name(Term, Name),
 1748    assert_used_class(Src, Name).
 1749
 1750
 1751pce_control_class(and).
 1752pce_control_class(or).
 1753pce_control_class(if).
 1754pce_control_class(not).
 1755
 1756
 1757                /********************************
 1758                *       INCLUDED MODULES        *
 1759                ********************************/
 process_use_module(+Modules, +Src, +Rexport) is det
 1763process_use_module(_Module:_Files, _, _) :- !.  % loaded in another module
 1764process_use_module([], _, _) :- !.
 1765process_use_module([H|T], Src, Reexport) :-
 1766    !,
 1767    process_use_module(H, Src, Reexport),
 1768    process_use_module(T, Src, Reexport).
 1769process_use_module(library(pce), Src, Reexport) :-     % bit special
 1770    !,
 1771    xref_public_list(library(pce), Path, Exports, Src),
 1772    forall(member(Import, Exports),
 1773           process_pce_import(Import, Src, Path, Reexport)).
 1774process_use_module(File, Src, Reexport) :-
 1775    load_module_if_needed(File),
 1776    (   xoption(Src, silent(Silent))
 1777    ->  Extra = [silent(Silent)]
 1778    ;   Extra = [silent(true)]
 1779    ),
 1780    (   xref_public_list(File, Src,
 1781                         [ path(Path),
 1782                           module(M),
 1783                           exports(Exports),
 1784                           public(Public),
 1785                           meta(Meta)
 1786                         | Extra
 1787                         ])
 1788    ->  assert(uses_file(File, Src, Path)),
 1789        assert_import(Src, Exports, _, Path, Reexport),
 1790        assert_xmodule_callable(Exports, M, Src, Path),
 1791        assert_xmodule_callable(Public, M, Src, Path),
 1792        maplist(process_meta_head(Src), Meta),
 1793        (   File = library(chr)     % hacky
 1794        ->  assert(mode(chr, Src))
 1795        ;   true
 1796        )
 1797    ;   assert(uses_file(File, Src, '<not_found>'))
 1798    ).
 1799
 1800process_pce_import(Name/Arity, Src, Path, Reexport) :-
 1801    atom(Name),
 1802    integer(Arity),
 1803    !,
 1804    functor(Term, Name, Arity),
 1805    (   \+ system_predicate(Term),
 1806        \+ Term = pce_error(_)      % hack!?
 1807    ->  assert_import(Src, [Name/Arity], _, Path, Reexport)
 1808    ;   true
 1809    ).
 1810process_pce_import(op(P,T,N), Src, _, _) :-
 1811    xref_push_op(Src, P, T, N).
 process_use_module2(+File, +Import, +Src, +Reexport) is det
Process use_module/2 and reexport/2.
 1817process_use_module2(File, Import, Src, Reexport) :-
 1818    load_module_if_needed(File),
 1819    (   xref_source_file(File, Path, Src)
 1820    ->  assert(uses_file(File, Src, Path)),
 1821        (   catch(public_list(Path, _, Meta, Export, _Public, []), _, fail)
 1822        ->  assert_import(Src, Import, Export, Path, Reexport),
 1823            forall((  member(Head, Meta),
 1824                      imported(Head, _, Path)
 1825                   ),
 1826                   process_meta_head(Src, Head))
 1827        ;   true
 1828        )
 1829    ;   assert(uses_file(File, Src, '<not_found>'))
 1830    ).
 load_module_if_needed(+File)
Load a module explicitly if it is not suitable for autoloading. Typically this is the case if the module provides essential term and/or goal expansion rulses.
 1839load_module_if_needed(File) :-
 1840    prolog:no_autoload_module(File),
 1841    !,
 1842    use_module(File, []).
 1843load_module_if_needed(_).
 1844
 1845prolog:no_autoload_module(library(apply_macros)).
 1846prolog:no_autoload_module(library(arithmetic)).
 1847prolog:no_autoload_module(library(record)).
 1848prolog:no_autoload_module(library(persistency)).
 1849prolog:no_autoload_module(library(pldoc)).
 1850prolog:no_autoload_module(library(settings)).
 1851prolog:no_autoload_module(library(debug)).
 1852prolog:no_autoload_module(library(plunit)).
 process_requires(+Import, +Src)
 1857process_requires(Import, Src) :-
 1858    is_list(Import),
 1859    !,
 1860    require_list(Import, Src).
 1861process_requires(Var, _Src) :-
 1862    var(Var),
 1863    !.
 1864process_requires((A,B), Src) :-
 1865    !,
 1866    process_requires(A, Src),
 1867    process_requires(B, Src).
 1868process_requires(PI, Src) :-
 1869    requires(PI, Src).
 1870
 1871require_list([], _).
 1872require_list([H|T], Src) :-
 1873    requires(H, Src),
 1874    require_list(T, Src).
 1875
 1876requires(PI, _Src) :-
 1877    '$pi_head'(PI, Head),
 1878    '$get_predicate_attribute'(system:Head, defined, 1),
 1879    !.
 1880requires(PI, Src) :-
 1881    '$pi_head'(PI, Head),
 1882    '$pi_head'(Name/Arity, Head),
 1883    '$find_library'(_Module, Name, Arity, _LoadModule, Library),
 1884    (   imported(Head, Src, Library)
 1885    ->  true
 1886    ;   assertz(imported(Head, Src, Library))
 1887    ).
 xref_public_list(+Spec, +Source, +Options) is semidet
Find meta-information about File. This predicate reads all terms upto the first term that is not a directive. It uses the module and meta_predicate directives to assemble the information in Options. Options processed:
path(-Path)
Path is the full path name of the referenced file.
module(-Module)
Module is the module defines in Spec.
exports(-Exports)
Exports is a list of predicate indicators and operators collected from the module/2 term and reexport declarations.
public -Public
Public declarations of the file.
meta(-Meta)
Meta is a list of heads as they appear in meta_predicate/1 declarations.
silent(+Boolean)
Do not print any messages or raise exceptions on errors.

The information collected by this predicate is cached. The cached data is considered valid as long as the modification time of the file does not change.

Arguments:
Source- is the file from which Spec is referenced.
 1918xref_public_list(File, Src, Options) :-
 1919    option(path(Path), Options, _),
 1920    option(module(Module), Options, _),
 1921    option(exports(Exports), Options, _),
 1922    option(public(Public), Options, _),
 1923    option(meta(Meta), Options, _),
 1924    xref_source_file(File, Path, Src, Options),
 1925    public_list(Path, Module, Meta, Exports, Public, Options).
 xref_public_list(+File, -Path, -Export, +Src) is semidet
 xref_public_list(+File, -Path, -Module, -Export, -Meta, +Src) is semidet
 xref_public_list(+File, -Path, -Module, -Export, -Public, -Meta, +Src) is semidet
Find meta-information about File. This predicate reads all terms upto the first term that is not a directive. It uses the module and meta_predicate directives to assemble the information described below.

These predicates fail if File is not a module-file.

Arguments:
Path- is the canonical path to File
Module- is the module defined in Path
Export- is a list of predicate indicators.
Meta- is a list of heads as they appear in meta_predicate/1 declarations.
Src- is the place from which File is referenced.
deprecated
- New code should use xref_public_list/3, which unifies all variations using an option list.
 1947xref_public_list(File, Path, Export, Src) :-
 1948    xref_source_file(File, Path, Src),
 1949    public_list(Path, _, _, Export, _, []).
 1950xref_public_list(File, Path, Module, Export, Meta, Src) :-
 1951    xref_source_file(File, Path, Src),
 1952    public_list(Path, Module, Meta, Export, _, []).
 1953xref_public_list(File, Path, Module, Export, Public, Meta, Src) :-
 1954    xref_source_file(File, Path, Src),
 1955    public_list(Path, Module, Meta, Export, Public, []).
 public_list(+Path, -Module, -Meta, -Export, -Public, +Options)
Read the public information for Path. Options supported are:
silent(+Boolean)
If true, ignore (syntax) errors. If not specified the default is inherited from xref_source/2.
 1965:- dynamic  public_list_cache/6. 1966:- volatile public_list_cache/6. 1967
 1968public_list(Path, Module, Meta, Export, Public, _Options) :-
 1969    public_list_cache(Path, Modified,
 1970                      Module0, Meta0, Export0, Public0),
 1971    time_file(Path, ModifiedNow),
 1972    (   abs(Modified-ModifiedNow) < 0.0001
 1973    ->  !,
 1974        t(Module,Meta,Export,Public) = t(Module0,Meta0,Export0,Public0)
 1975    ;   retractall(public_list_cache(Path, _, _, _, _, _)),
 1976        fail
 1977    ).
 1978public_list(Path, Module, Meta, Export, Public, Options) :-
 1979    public_list_nc(Path, Module0, Meta0, Export0, Public0, Options),
 1980    (   Error = error(_,_),
 1981        catch(time_file(Path, Modified), Error, fail)
 1982    ->  asserta(public_list_cache(Path, Modified,
 1983                                  Module0, Meta0, Export0, Public0))
 1984    ;   true
 1985    ),
 1986    t(Module,Meta,Export,Public) = t(Module0,Meta0,Export0,Public0).
 1987
 1988public_list_nc(Path, Module, Meta, Export, Public, Options) :-
 1989    in_temporary_module(
 1990        TempModule,
 1991        true,
 1992        public_list_diff(TempModule, Path, Module,
 1993                         Meta, [], Export, [], Public, [], Options)).
 1994
 1995
 1996public_list_diff(TempModule,
 1997                 Path, Module, Meta, MT, Export, Rest, Public, PT, Options) :-
 1998    setup_call_cleanup(
 1999        public_list_setup(TempModule, Path, In, State),
 2000        phrase(read_directives(In, Options, [true]), Directives),
 2001        public_list_cleanup(In, State)),
 2002    public_list(Directives, Path, Module, Meta, MT, Export, Rest, Public, PT).
 2003
 2004public_list_setup(TempModule, Path, In, state(OldM, OldXref)) :-
 2005    prolog_open_source(Path, In),
 2006    '$set_source_module'(OldM, TempModule),
 2007    set_xref(OldXref).
 2008
 2009public_list_cleanup(In, state(OldM, OldXref)) :-
 2010    '$set_source_module'(OldM),
 2011    set_prolog_flag(xref, OldXref),
 2012    prolog_close_source(In).
 2013
 2014
 2015read_directives(In, Options, State) -->
 2016    {  repeat,
 2017       catch(prolog_read_source_term(In, Term, Expanded,
 2018                                     [ process_comment(true),
 2019                                       syntax_errors(error)
 2020                                     ]),
 2021             E, report_syntax_error(E, -, Options))
 2022    -> nonvar(Term),
 2023       Term = (:-_)
 2024    },
 2025    !,
 2026    terms(Expanded, State, State1),
 2027    read_directives(In, Options, State1).
 2028read_directives(_, _, _) --> [].
 2029
 2030terms(Var, State, State) --> { var(Var) }, !.
 2031terms([H|T], State0, State) -->
 2032    !,
 2033    terms(H, State0, State1),
 2034    terms(T, State1, State).
 2035terms((:-if(Cond)), State0, [True|State0]) -->
 2036    !,
 2037    { eval_cond(Cond, True) }.
 2038terms((:-elif(Cond)), [True0|State], [True|State]) -->
 2039    !,
 2040    { eval_cond(Cond, True1),
 2041      elif(True0, True1, True)
 2042    }.
 2043terms((:-else), [True0|State], [True|State]) -->
 2044    !,
 2045    { negate(True0, True) }.
 2046terms((:-endif), [_|State], State) -->  !.
 2047terms(H, State, State) -->
 2048    (   {State = [true|_]}
 2049    ->  [H]
 2050    ;   []
 2051    ).
 2052
 2053eval_cond(Cond, true) :-
 2054    catch(Cond, _, fail),
 2055    !.
 2056eval_cond(_, false).
 2057
 2058elif(true,  _,    else_false) :- !.
 2059elif(false, true, true) :- !.
 2060elif(True,  _,    True).
 2061
 2062negate(true,       false).
 2063negate(false,      true).
 2064negate(else_false, else_false).
 2065
 2066public_list([(:- module(Module, Export0))|Decls], Path,
 2067            Module, Meta, MT, Export, Rest, Public, PT) :-
 2068    !,
 2069    append(Export0, Reexport, Export),
 2070    public_list_(Decls, Path, Meta, MT, Reexport, Rest, Public, PT).
 2071public_list([(:- encoding(_))|Decls], Path,
 2072            Module, Meta, MT, Export, Rest, Public, PT) :-
 2073    public_list(Decls, Path, Module, Meta, MT, Export, Rest, Public, PT).
 2074
 2075public_list_([], _, Meta, Meta, Export, Export, Public, Public).
 2076public_list_([(:-(Dir))|T], Path, Meta, MT, Export, Rest, Public, PT) :-
 2077    public_list_1(Dir, Path, Meta, MT0, Export, Rest0, Public, PT0),
 2078    !,
 2079    public_list_(T, Path, MT0, MT, Rest0, Rest, PT0, PT).
 2080public_list_([_|T], Path, Meta, MT, Export, Rest, Public, PT) :-
 2081    public_list_(T, Path, Meta, MT, Export, Rest, Public, PT).
 2082
 2083public_list_1(reexport(Spec), Path, Meta, MT, Reexport, Rest, Public, PT) :-
 2084    reexport_files(Spec, Path, Meta, MT, Reexport, Rest, Public, PT).
 2085public_list_1(reexport(Spec, Import), Path, Meta, Meta, Reexport, Rest, Public, Public) :-
 2086    public_from_import(Import, Spec, Path, Reexport, Rest).
 2087public_list_1(meta_predicate(Decl), _Path, Meta, MT, Export, Export, Public, Public) :-
 2088    phrase(meta_decls(Decl), Meta, MT).
 2089public_list_1(public(Decl), _Path, Meta, Meta, Export, Export, Public, PT) :-
 2090    phrase(public_decls(Decl), Public, PT).
 reexport_files(+Files, +Src, -Meta, ?MetaTail, -Exports, ?ExportsTail, -Public, ?PublicTail)
 2096reexport_files([], _, Meta, Meta, Export, Export, Public, Public) :- !.
 2097reexport_files([H|T], Src, Meta, MT, Export, ET, Public, PT) :-
 2098    !,
 2099    xref_source_file(H, Path, Src),
 2100    public_list(Path, _Module, Meta0, Export0, Public0, []),
 2101    append(Meta0, MT1, Meta),
 2102    append(Export0, ET1, Export),
 2103    append(Public0, PT1, Public),
 2104    reexport_files(T, Src, MT1, MT, ET1, ET, PT1, PT).
 2105reexport_files(Spec, Src, Meta, MT, Export, ET, Public, PT) :-
 2106    xref_source_file(Spec, Path, Src),
 2107    public_list(Path, _Module, Meta0, Export0, Public0, []),
 2108    append(Meta0, MT, Meta),
 2109    append(Export0, ET, Export),
 2110    append(Public0, PT, Public).
 2111
 2112public_from_import(except(Map), Path, Src, Export, Rest) :-
 2113    !,
 2114    xref_public_list(Path, _, AllExports, Src),
 2115    except(Map, AllExports, NewExports),
 2116    append(NewExports, Rest, Export).
 2117public_from_import(Import, _, _, Export, Rest) :-
 2118    import_name_map(Import, Export, Rest).
 except(+Remove, +AllExports, -Exports)
 2123except([], Exports, Exports).
 2124except([PI0 as NewName|Map], Exports0, Exports) :-
 2125    !,
 2126    canonical_pi(PI0, PI),
 2127    map_as(Exports0, PI, NewName, Exports1),
 2128    except(Map, Exports1, Exports).
 2129except([PI0|Map], Exports0, Exports) :-
 2130    canonical_pi(PI0, PI),
 2131    select(PI2, Exports0, Exports1),
 2132    same_pi(PI, PI2),
 2133    !,
 2134    except(Map, Exports1, Exports).
 2135
 2136
 2137map_as([PI|T], Repl, As, [PI2|T])  :-
 2138    same_pi(Repl, PI),
 2139    !,
 2140    pi_as(PI, As, PI2).
 2141map_as([H|T0], Repl, As, [H|T])  :-
 2142    map_as(T0, Repl, As, T).
 2143
 2144pi_as(_/Arity, Name, Name/Arity).
 2145pi_as(_//Arity, Name, Name//Arity).
 2146
 2147import_name_map([], L, L).
 2148import_name_map([_/Arity as NewName|T0], [NewName/Arity|T], Tail) :-
 2149    !,
 2150    import_name_map(T0, T, Tail).
 2151import_name_map([_//Arity as NewName|T0], [NewName//Arity|T], Tail) :-
 2152    !,
 2153    import_name_map(T0, T, Tail).
 2154import_name_map([H|T0], [H|T], Tail) :-
 2155    import_name_map(T0, T, Tail).
 2156
 2157canonical_pi(Name//Arity0, PI) :-
 2158    integer(Arity0),
 2159    !,
 2160    PI = Name/Arity,
 2161    Arity is Arity0 + 2.
 2162canonical_pi(PI, PI).
 2163
 2164same_pi(Canonical, PI2) :-
 2165    canonical_pi(PI2, Canonical).
 2166
 2167meta_decls(Var) -->
 2168    { var(Var) },
 2169    !.
 2170meta_decls((A,B)) -->
 2171    !,
 2172    meta_decls(A),
 2173    meta_decls(B).
 2174meta_decls(A) -->
 2175    [A].
 2176
 2177public_decls(Var) -->
 2178    { var(Var) },
 2179    !.
 2180public_decls((A,B)) -->
 2181    !,
 2182    public_decls(A),
 2183    public_decls(B).
 2184public_decls(A) -->
 2185    [A].
 2186
 2187                 /*******************************
 2188                 *             INCLUDE          *
 2189                 *******************************/
 2190
 2191process_include([], _) :- !.
 2192process_include([H|T], Src) :-
 2193    !,
 2194    process_include(H, Src),
 2195    process_include(T, Src).
 2196process_include(File, Src) :-
 2197    callable(File),
 2198    !,
 2199    (   once(xref_input(ParentSrc, _)),
 2200        xref_source_file(File, Path, ParentSrc)
 2201    ->  (   (   uses_file(_, Src, Path)
 2202            ;   Path == Src
 2203            )
 2204        ->  true
 2205        ;   assert(uses_file(File, Src, Path)),
 2206            (   xoption(Src, process_include(true))
 2207            ->  findall(O, xoption(Src, O), Options),
 2208                setup_call_cleanup(
 2209                    open_include_file(Path, In, Refs),
 2210                    collect(Src, Path, In, Options),
 2211                    close_include(In, Refs))
 2212            ;   true
 2213            )
 2214        )
 2215    ;   assert(uses_file(File, Src, '<not_found>'))
 2216    ).
 2217process_include(_, _).
 open_include_file(+Path, -In, -Refs)
Opens an :- include(File) referenced file. Note that we cannot use prolog_open_source/2 because we should not safe/restore the lexical context.
 2225open_include_file(Path, In, [Ref]) :-
 2226    once(xref_input(_, Parent)),
 2227    stream_property(Parent, encoding(Enc)),
 2228    '$push_input_context'(xref_include),
 2229    catch((   prolog:xref_open_source(Path, In)
 2230          ->  set_stream(In, encoding(Enc))
 2231          ;   include_encoding(Enc, Options),
 2232              open(Path, read, In, Options)
 2233          ), E,
 2234          ( '$pop_input_context', throw(E))),
 2235    catch((   peek_char(In, #)              % Deal with #! script
 2236          ->  skip(In, 10)
 2237          ;   true
 2238          ), E,
 2239          ( close_include(In, []), throw(E))),
 2240    asserta(xref_input(Path, In), Ref).
 2241
 2242include_encoding(wchar_t, []) :- !.
 2243include_encoding(Enc, [encoding(Enc)]).
 2244
 2245
 2246close_include(In, Refs) :-
 2247    maplist(erase, Refs),
 2248    close(In, [force(true)]),
 2249    '$pop_input_context'.
 process_foreign(+Spec, +Src)
Process a load_foreign_library/1 call.
 2255process_foreign(Spec, Src) :-
 2256    ground(Spec),
 2257    current_foreign_library(Spec, Defined),
 2258    !,
 2259    (   xmodule(Module, Src)
 2260    ->  true
 2261    ;   Module = user
 2262    ),
 2263    process_foreign_defined(Defined, Module, Src).
 2264process_foreign(_, _).
 2265
 2266process_foreign_defined([], _, _).
 2267process_foreign_defined([H|T], M, Src) :-
 2268    (   H = M:Head
 2269    ->  assert_foreign(Src, Head)
 2270    ;   assert_foreign(Src, H)
 2271    ),
 2272    process_foreign_defined(T, M, Src).
 2273
 2274
 2275                 /*******************************
 2276                 *          CHR SUPPORT         *
 2277                 *******************************/
 2278
 2279/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 2280This part of the file supports CHR. Our choice is between making special
 2281hooks to make CHR expansion work and  then handle the (complex) expanded
 2282code or process the  CHR  source   directly.  The  latter looks simpler,
 2283though I don't like the idea  of   adding  support for libraries to this
 2284module.  A  file  is  supposed  to  be  a    CHR   file  if  it  uses  a
 2285use_module(library(chr) or contains a :-   constraint/1 directive. As an
 2286extra bonus we get the source-locations right :-)
 2287- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 2288
 2289process_chr(@(_Name, Rule), Src) :-
 2290    mode(chr, Src),
 2291    process_chr(Rule, Src).
 2292process_chr(pragma(Rule, _Pragma), Src) :-
 2293    mode(chr, Src),
 2294    process_chr(Rule, Src).
 2295process_chr(<=>(Head, Body), Src) :-
 2296    mode(chr, Src),
 2297    chr_head(Head, Src, H),
 2298    chr_body(Body, H, Src).
 2299process_chr(==>(Head, Body), Src) :-
 2300    mode(chr, Src),
 2301    chr_head(Head, H, Src),
 2302    chr_body(Body, H, Src).
 2303process_chr((:- chr_constraint(_)), Src) :-
 2304    (   mode(chr, Src)
 2305    ->  true
 2306    ;   assert(mode(chr, Src))
 2307    ).
 2308
 2309chr_head(X, _, _) :-
 2310    var(X),
 2311    !.                      % Illegal.  Warn?
 2312chr_head(\(A,B), Src, H) :-
 2313    chr_head(A, Src, H),
 2314    process_body(B, H, Src).
 2315chr_head((H0,B), Src, H) :-
 2316    chr_defined(H0, Src, H),
 2317    process_body(B, H, Src).
 2318chr_head(H0, Src, H) :-
 2319    chr_defined(H0, Src, H).
 2320
 2321chr_defined(X, _, _) :-
 2322    var(X),
 2323    !.
 2324chr_defined(#(C,_Id), Src, C) :-
 2325    !,
 2326    assert_constraint(Src, C).
 2327chr_defined(A, Src, A) :-
 2328    assert_constraint(Src, A).
 2329
 2330chr_body(X, From, Src) :-
 2331    var(X),
 2332    !,
 2333    process_body(X, From, Src).
 2334chr_body('|'(Guard, Goals), H, Src) :-
 2335    !,
 2336    chr_body(Guard, H, Src),
 2337    chr_body(Goals, H, Src).
 2338chr_body(G, From, Src) :-
 2339    process_body(G, From, Src).
 2340
 2341assert_constraint(_, Head) :-
 2342    var(Head),
 2343    !.
 2344assert_constraint(Src, Head) :-
 2345    constraint(Head, Src, _),
 2346    !.
 2347assert_constraint(Src, Head) :-
 2348    generalise_term(Head, Term),
 2349    current_source_line(Line),
 2350    assert(constraint(Term, Src, Line)).
 2351
 2352
 2353                /********************************
 2354                *       PHASE 1 ASSERTIONS      *
 2355                ********************************/
 assert_called(+Src, +From, +Head, +Line) is det
Assert the fact that Head is called by From in Src. We do not assert called system predicates.
 2362assert_called(_, _, Var, _) :-
 2363    var(Var),
 2364    !.
 2365assert_called(Src, From, Goal, Line) :-
 2366    var(From),
 2367    !,
 2368    assert_called(Src, '<unknown>', Goal, Line).
 2369assert_called(_, _, Goal, _) :-
 2370    expand_hide_called(Goal),
 2371    !.
 2372assert_called(Src, Origin, M:G, Line) :-
 2373    !,
 2374    (   atom(M),
 2375        callable(G)
 2376    ->  current_condition(Cond),
 2377        (   xmodule(M, Src)         % explicit call to own module
 2378        ->  assert_called(Src, Origin, G, Line)
 2379        ;   called(M:G, Src, Origin, Cond, Line) % already registered
 2380        ->  true
 2381        ;   hide_called(M:G, Src)           % not interesting (now)
 2382        ->  true
 2383        ;   generalise(Origin, OTerm),
 2384            generalise(G, GTerm)
 2385        ->  assert(called(M:GTerm, Src, OTerm, Cond, Line))
 2386        ;   true
 2387        )
 2388    ;   true                        % call to variable module
 2389    ).
 2390assert_called(Src, _, Goal, _) :-
 2391    (   xmodule(M, Src)
 2392    ->  M \== system
 2393    ;   M = user
 2394    ),
 2395    hide_called(M:Goal, Src),
 2396    !.
 2397assert_called(Src, Origin, Goal, Line) :-
 2398    current_condition(Cond),
 2399    (   called(Goal, Src, Origin, Cond, Line)
 2400    ->  true
 2401    ;   generalise(Origin, OTerm),
 2402        generalise(Goal, Term)
 2403    ->  assert(called(Term, Src, OTerm, Cond, Line))
 2404    ;   true
 2405    ).
 expand_hide_called(:Callable) is semidet
Goals that should not turn up as being called. Hack. Eventually we should deal with that using an XPCE plugin.
 2413expand_hide_called(pce_principal:send_implementation(_, _, _)).
 2414expand_hide_called(pce_principal:get_implementation(_, _, _, _)).
 2415expand_hide_called(pce_principal:pce_lazy_get_method(_,_,_)).
 2416expand_hide_called(pce_principal:pce_lazy_send_method(_,_,_)).
 2417
 2418assert_defined(Src, Goal) :-
 2419    defined(Goal, Src, _),
 2420    !.
 2421assert_defined(Src, Goal) :-
 2422    generalise(Goal, Term),
 2423    current_source_line(Line),
 2424    assert(defined(Term, Src, Line)).
 2425
 2426assert_foreign(Src, Goal) :-
 2427    foreign(Goal, Src, _),
 2428    !.
 2429assert_foreign(Src, Goal) :-
 2430    generalise(Goal, Term),
 2431    current_source_line(Line),
 2432    assert(foreign(Term, Src, Line)).
 assert_import(+Src, +Import, +ExportList, +From, +Reexport) is det
Asserts imports into Src. Import is the import specification, ExportList is the list of known exported predicates or unbound if this need not be checked and From is the file from which the public predicates come. If Reexport is true, re-export the imported predicates.
To be done
- Tighter type-checking on Import.
 2444assert_import(_, [], _, _, _) :- !.
 2445assert_import(Src, [H|T], Export, From, Reexport) :-
 2446    !,
 2447    assert_import(Src, H, Export, From, Reexport),
 2448    assert_import(Src, T, Export, From, Reexport).
 2449assert_import(Src, except(Except), Export, From, Reexport) :-
 2450    !,
 2451    is_list(Export),
 2452    !,
 2453    except(Except, Export, Import),
 2454    assert_import(Src, Import, _All, From, Reexport).
 2455assert_import(Src, Import as Name, Export, From, Reexport) :-
 2456    !,
 2457    pi_to_head(Import, Term0),
 2458    rename_goal(Term0, Name, Term),
 2459    (   in_export_list(Term0, Export)
 2460    ->  assert(imported(Term, Src, From)),
 2461        assert_reexport(Reexport, Src, Term)
 2462    ;   current_source_line(Line),
 2463        assert_called(Src, '<directive>'(Line), Term0, Line)
 2464    ).
 2465assert_import(Src, Import, Export, From, Reexport) :-
 2466    pi_to_head(Import, Term),
 2467    !,
 2468    (   in_export_list(Term, Export)
 2469    ->  assert(imported(Term, Src, From)),
 2470        assert_reexport(Reexport, Src, Term)
 2471    ;   current_source_line(Line),
 2472        assert_called(Src, '<directive>'(Line), Term, Line)
 2473    ).
 2474assert_import(Src, op(P,T,N), _, _, _) :-
 2475    xref_push_op(Src, P,T,N).
 2476
 2477in_export_list(_Head, Export) :-
 2478    var(Export),
 2479    !.
 2480in_export_list(Head, Export) :-
 2481    member(PI, Export),
 2482    pi_to_head(PI, Head).
 2483
 2484assert_reexport(false, _, _) :- !.
 2485assert_reexport(true, Src, Term) :-
 2486    assert(exported(Term, Src)).
 process_import(:Import, +Src)
Process an import/1 directive
 2492process_import(M:PI, Src) :-
 2493    pi_to_head(PI, Head),
 2494    !,
 2495    (   atom(M),
 2496        current_module(M),
 2497        module_property(M, file(From))
 2498    ->  true
 2499    ;   From = '<unknown>'
 2500    ),
 2501    assert(imported(Head, Src, From)).
 2502process_import(_, _).
 assert_xmodule_callable(PIs, Module, Src, From)
We can call all exports and public predicates of an imported module using Module:Goal.
To be done
- Should we distinguish this from normal imported?
 2511assert_xmodule_callable([], _, _, _).
 2512assert_xmodule_callable([PI|T], M, Src, From) :-
 2513    (   pi_to_head(M:PI, Head)
 2514    ->  assert(imported(Head, Src, From))
 2515    ;   true
 2516    ),
 2517    assert_xmodule_callable(T, M, Src, From).
 assert_op(+Src, +Op) is det
Arguments:
Op- Ground term op(Priority, Type, Name).
 2524assert_op(Src, op(P,T,M:N)) :-
 2525    (   '$current_source_module'(M)
 2526    ->  Name = N
 2527    ;   Name = M:N
 2528    ),
 2529    (   xop(Src, op(P,T,Name))
 2530    ->  true
 2531    ;   assert(xop(Src, op(P,T,Name)))
 2532    ).
 assert_module(+Src, +Module)
Assert we are loading code into Module. This is also used to exploit local term-expansion and other rules.
 2539assert_module(Src, Module) :-
 2540    xmodule(Module, Src),
 2541    !.
 2542assert_module(Src, Module) :-
 2543    '$set_source_module'(Module),
 2544    assert(xmodule(Module, Src)),
 2545    (   module_property(Module, class(system))
 2546    ->  retractall(xoption(Src, register_called(_))),
 2547        assert(xoption(Src, register_called(all)))
 2548    ;   true
 2549    ).
 2550
 2551assert_module_export(_, []) :- !.
 2552assert_module_export(Src, [H|T]) :-
 2553    !,
 2554    assert_module_export(Src, H),
 2555    assert_module_export(Src, T).
 2556assert_module_export(Src, PI) :-
 2557    pi_to_head(PI, Term),
 2558    !,
 2559    assert(exported(Term, Src)).
 2560assert_module_export(Src, op(P, A, N)) :-
 2561    xref_push_op(Src, P, A, N).
 assert_module3(+Import, +Src)
Handle 3th argument of module/3 declaration.
 2567assert_module3([], _) :- !.
 2568assert_module3([H|T], Src) :-
 2569    !,
 2570    assert_module3(H, Src),
 2571    assert_module3(T, Src).
 2572assert_module3(Option, Src) :-
 2573    process_use_module(library(dialect/Option), Src, false).
 process_predicates(:Closure, +Predicates, +Src)
Process areguments of dynamic, etc., using call(Closure, PI, Src). Handles both lists of specifications and (PI,...) specifications.
 2582process_predicates(Closure, Preds, Src) :-
 2583    is_list(Preds),
 2584    !,
 2585    process_predicate_list(Preds, Closure, Src).
 2586process_predicates(Closure, as(Preds, _Options), Src) :-
 2587    !,
 2588    process_predicates(Closure, Preds, Src).
 2589process_predicates(Closure, Preds, Src) :-
 2590    process_predicate_comma(Preds, Closure, Src).
 2591
 2592process_predicate_list([], _, _).
 2593process_predicate_list([H|T], Closure, Src) :-
 2594    (   nonvar(H)
 2595    ->  call(Closure, H, Src)
 2596    ;   true
 2597    ),
 2598    process_predicate_list(T, Closure, Src).
 2599
 2600process_predicate_comma(Var, _, _) :-
 2601    var(Var),
 2602    !.
 2603process_predicate_comma(M:(A,B), Closure, Src) :-
 2604    !,
 2605    process_predicate_comma(M:A, Closure, Src),
 2606    process_predicate_comma(M:B, Closure, Src).
 2607process_predicate_comma((A,B), Closure, Src) :-
 2608    !,
 2609    process_predicate_comma(A, Closure, Src),
 2610    process_predicate_comma(B, Closure, Src).
 2611process_predicate_comma(as(Spec, _Options), Closure, Src) :-
 2612    !,
 2613    process_predicate_comma(Spec, Closure, Src).
 2614process_predicate_comma(A, Closure, Src) :-
 2615    call(Closure, A, Src).
 2616
 2617
 2618assert_dynamic(PI, Src) :-
 2619    pi_to_head(PI, Term),
 2620    (   thread_local(Term, Src, _)  % dynamic after thread_local has
 2621    ->  true                        % no effect
 2622    ;   current_source_line(Line),
 2623        assert(dynamic(Term, Src, Line))
 2624    ).
 2625
 2626assert_thread_local(PI, Src) :-
 2627    pi_to_head(PI, Term),
 2628    current_source_line(Line),
 2629    assert(thread_local(Term, Src, Line)).
 2630
 2631assert_multifile(PI, Src) :-                    % :- multifile(Spec)
 2632    pi_to_head(PI, Term),
 2633    current_source_line(Line),
 2634    assert(multifile(Term, Src, Line)).
 2635
 2636assert_public(PI, Src) :-                       % :- public(Spec)
 2637    pi_to_head(PI, Term),
 2638    current_source_line(Line),
 2639    assert_called(Src, '<public>'(Line), Term, Line),
 2640    assert(public(Term, Src, Line)).
 2641
 2642assert_export(PI, Src) :-                       % :- export(Spec)
 2643    pi_to_head(PI, Term),
 2644    !,
 2645    assert(exported(Term, Src)).
 pi_to_head(+PI, -Head) is semidet
Translate Name/Arity or Name//Arity to a callable term. Fails if PI is not a predicate indicator.
 2652pi_to_head(Var, _) :-
 2653    var(Var), !, fail.
 2654pi_to_head(M:PI, M:Term) :-
 2655    !,
 2656    pi_to_head(PI, Term).
 2657pi_to_head(Name/Arity, Term) :-
 2658    functor(Term, Name, Arity).
 2659pi_to_head(Name//DCGArity, Term) :-
 2660    Arity is DCGArity+2,
 2661    functor(Term, Name, Arity).
 2662
 2663
 2664assert_used_class(Src, Name) :-
 2665    used_class(Name, Src),
 2666    !.
 2667assert_used_class(Src, Name) :-
 2668    assert(used_class(Name, Src)).
 2669
 2670assert_defined_class(Src, Name, _Meta, _Super, _) :-
 2671    defined_class(Name, _, _, Src, _),
 2672    !.
 2673assert_defined_class(_, _, _, -, _) :- !.               % :- pce_extend_class
 2674assert_defined_class(Src, Name, Meta, Super, Summary) :-
 2675    current_source_line(Line),
 2676    (   Summary == @(default)
 2677    ->  Atom = ''
 2678    ;   is_list(Summary)
 2679    ->  atom_codes(Atom, Summary)
 2680    ;   string(Summary)
 2681    ->  atom_concat(Summary, '', Atom)
 2682    ),
 2683    assert(defined_class(Name, Super, Atom, Src, Line)),
 2684    (   Meta = @(_)
 2685    ->  true
 2686    ;   assert_used_class(Src, Meta)
 2687    ),
 2688    assert_used_class(Src, Super).
 2689
 2690assert_defined_class(Src, Name, imported_from(_File)) :-
 2691    defined_class(Name, _, _, Src, _),
 2692    !.
 2693assert_defined_class(Src, Name, imported_from(File)) :-
 2694    assert(defined_class(Name, _, '', Src, file(File))).
 2695
 2696
 2697                /********************************
 2698                *            UTILITIES          *
 2699                ********************************/
 generalise(+Callable, -General)
Generalise a callable term.
 2705generalise(Var, Var) :-
 2706    var(Var),
 2707    !.                    % error?
 2708generalise(pce_principal:send_implementation(Id, _, _),
 2709           pce_principal:send_implementation(Id, _, _)) :-
 2710    atom(Id),
 2711    !.
 2712generalise(pce_principal:get_implementation(Id, _, _, _),
 2713           pce_principal:get_implementation(Id, _, _, _)) :-
 2714    atom(Id),
 2715    !.
 2716generalise('<directive>'(Line), '<directive>'(Line)) :- !.
 2717generalise(Module:Goal0, Module:Goal) :-
 2718    atom(Module),
 2719    !,
 2720    generalise(Goal0, Goal).
 2721generalise(Term0, Term) :-
 2722    callable(Term0),
 2723    generalise_term(Term0, Term).
 2724
 2725
 2726                 /*******************************
 2727                 *      SOURCE MANAGEMENT       *
 2728                 *******************************/
 2729
 2730/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 2731This section of the file contains   hookable  predicates to reason about
 2732sources. The built-in code here  can  only   deal  with  files. The XPCE
 2733library(pce_prolog_xref) provides hooks to deal with XPCE objects, so we
 2734can do cross-referencing on PceEmacs edit   buffers.  Other examples for
 2735hooking can be databases, (HTTP) URIs, etc.
 2736- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 2737
 2738:- multifile
 2739    prolog:xref_source_directory/2, % +Source, -Dir
 2740    prolog:xref_source_file/3.      % +Spec, -Path, +Options
 xref_source_file(+Spec, -File, +Src) is semidet
 xref_source_file(+Spec, -File, +Src, +Options) is semidet
Find named source file from Spec, relative to Src.
 2748xref_source_file(Plain, File, Source) :-
 2749    xref_source_file(Plain, File, Source, []).
 2750
 2751xref_source_file(QSpec, File, Source, Options) :-
 2752    nonvar(QSpec), QSpec = _:Spec,
 2753    !,
 2754    must_be(acyclic, Spec),
 2755    xref_source_file(Spec, File, Source, Options).
 2756xref_source_file(Spec, File, Source, Options) :-
 2757    nonvar(Spec),
 2758    prolog:xref_source_file(Spec, File,
 2759                            [ relative_to(Source)
 2760                            | Options
 2761                            ]),
 2762    !.
 2763xref_source_file(Plain, File, Source, Options) :-
 2764    atom(Plain),
 2765    \+ is_absolute_file_name(Plain),
 2766    (   prolog:xref_source_directory(Source, Dir)
 2767    ->  true
 2768    ;   atom(Source),
 2769        file_directory_name(Source, Dir)
 2770    ),
 2771    atomic_list_concat([Dir, /, Plain], Spec0),
 2772    absolute_file_name(Spec0, Spec),
 2773    do_xref_source_file(Spec, File, Options),
 2774    !.
 2775xref_source_file(Spec, File, Source, Options) :-
 2776    do_xref_source_file(Spec, File,
 2777                        [ relative_to(Source)
 2778                        | Options
 2779                        ]),
 2780    !.
 2781xref_source_file(_, _, _, Options) :-
 2782    option(silent(true), Options),
 2783    !,
 2784    fail.
 2785xref_source_file(Spec, _, Src, _Options) :-
 2786    verbose(Src),
 2787    print_message(warning, error(existence_error(file, Spec), _)),
 2788    fail.
 2789
 2790do_xref_source_file(Spec, File, Options) :-
 2791    nonvar(Spec),
 2792    option(file_type(Type), Options, prolog),
 2793    absolute_file_name(Spec, File,
 2794                       [ file_type(Type),
 2795                         access(read),
 2796                         file_errors(fail)
 2797                       ]),
 2798    !.
 canonical_source(?Source, ?Src) is det
Src is the canonical version of Source if Source is given.
 2804canonical_source(Source, Src) :-
 2805    (   ground(Source)
 2806    ->  prolog_canonical_source(Source, Src)
 2807    ;   Source = Src
 2808    ).
 goal_name_arity(+Goal, -Name, -Arity)
Generalized version of functor/3 that can deal with name() goals.
 2815goal_name_arity(Goal, Name, Arity) :-
 2816    (   compound(Goal)
 2817    ->  compound_name_arity(Goal, Name, Arity)
 2818    ;   atom(Goal)
 2819    ->  Name = Goal, Arity = 0
 2820    ).
 2821
 2822generalise_term(Specific, General) :-
 2823    (   compound(Specific)
 2824    ->  compound_name_arity(Specific, Name, Arity),
 2825        compound_name_arity(General, Name, Arity)
 2826    ;   General = Specific
 2827    ).
 2828
 2829functor_name(Term, Name) :-
 2830    (   compound(Term)
 2831    ->  compound_name_arity(Term, Name, _)
 2832    ;   atom(Term)
 2833    ->  Name = Term
 2834    ).
 2835
 2836rename_goal(Goal0, Name, Goal) :-
 2837    (   compound(Goal0)
 2838    ->  compound_name_arity(Goal0, _, Arity),
 2839        compound_name_arity(Goal, Name, Arity)
 2840    ;   Goal = Name
 2841    )