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((Left => Body), Src) :-
  881    !,
  882    (   nonvar(Left),
  883        Left = (Head, Guard)
  884    ->  assert_defined(Src, Head),
  885        process_body(Guard, Head, Src),
  886        process_body(Body, Head, Src)
  887    ;   assert_defined(Src, Left),
  888        process_body(Body, Left, Src)
  889    ).
  890process(?=>(Head, Body), Src) :-
  891    !,
  892    assert_defined(Src, Head),
  893    process_body(Body, Head, Src).
  894process('$source_location'(_File, _Line):Clause, Src) :-
  895    !,
  896    process(Clause, Src).
  897process(Term, Src) :-
  898    process_chr(Term, Src),
  899    !.
  900process(M:(Head :- Body), Src) :-
  901    !,
  902    process((M:Head :- M:Body), Src).
  903process(Head, Src) :-
  904    assert_defined(Src, Head).
  905
  906
  907                 /*******************************
  908                 *            COMMENTS          *
  909                 *******************************/
 xref_comments(+Comments, +FilePos, +Src) is det
  913xref_comments([], _Pos, _Src).
  914:- if(current_predicate(parse_comment/3)).  915xref_comments([Pos-Comment|T], TermPos, Src) :-
  916    (   Pos @> TermPos              % comments inside term
  917    ->  true
  918    ;   stream_position_data(line_count, Pos, Line),
  919        FilePos = Src:Line,
  920        (   parse_comment(Comment, FilePos, Parsed)
  921        ->  assert_comments(Parsed, Src)
  922        ;   true
  923        ),
  924        xref_comments(T, TermPos, Src)
  925    ).
  926
  927assert_comments([], _).
  928assert_comments([H|T], Src) :-
  929    assert_comment(H, Src),
  930    assert_comments(T, Src).
  931
  932assert_comment(section(_Id, Title, Comment), Src) :-
  933    assertz(module_comment(Src, Title, Comment)).
  934assert_comment(predicate(PI, Summary, Comment), Src) :-
  935    pi_to_head(PI, Src, Head),
  936    assertz(pred_comment(Head, Src, Summary, Comment)).
  937assert_comment(link(PI, PITo), Src) :-
  938    pi_to_head(PI, Src, Head),
  939    pi_to_head(PITo, Src, HeadTo),
  940    assertz(pred_comment_link(Head, Src, HeadTo)).
  941assert_comment(mode(Head, Det), Src) :-
  942    assertz(pred_mode(Head, Src, Det)).
  943
  944pi_to_head(PI, Src, Head) :-
  945    pi_to_head(PI, Head0),
  946    (   Head0 = _:_
  947    ->  strip_module(Head0, M, Plain),
  948        (   xmodule(M, Src)
  949        ->  Head = Plain
  950        ;   Head = M:Plain
  951        )
  952    ;   Head = Head0
  953    ).
  954:- endif.
 xref_comment(?Source, ?Title, ?Comment) is nondet
Is true when Source has a section comment with Title and Comment
  960xref_comment(Source, Title, Comment) :-
  961    canonical_source(Source, Src),
  962    module_comment(Src, Title, Comment).
 xref_comment(?Source, ?Head, ?Summary, ?Comment) is nondet
Is true when Head in Source has the given PlDoc comment.
  968xref_comment(Source, Head, Summary, Comment) :-
  969    canonical_source(Source, Src),
  970    (   pred_comment(Head, Src, Summary, Comment)
  971    ;   pred_comment_link(Head, Src, HeadTo),
  972        pred_comment(HeadTo, Src, Summary, Comment)
  973    ).
 xref_mode(?Source, ?Mode, ?Det) is nondet
Is true when Source provides a predicate with Mode and determinism.
  980xref_mode(Source, Mode, Det) :-
  981    canonical_source(Source, Src),
  982    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.
  989xref_option(Source, Option) :-
  990    canonical_source(Source, Src),
  991    xoption(Src, Option).
  992
  993
  994                 /********************************
  995                 *           DIRECTIVES         *
  996                 ********************************/
  997
  998process_directive(Var, _) :-
  999    var(Var),
 1000    !.                    % error, but that isn't our business
 1001process_directive(Dir, _Src) :-
 1002    debug(xref(directive), 'Processing :- ~q', [Dir]),
 1003    fail.
 1004process_directive((A,B), Src) :-       % TBD: what about other control
 1005    !,
 1006    process_directive(A, Src),      % structures?
 1007    process_directive(B, Src).
 1008process_directive(List, Src) :-
 1009    is_list(List),
 1010    !,
 1011    process_directive(consult(List), Src).
 1012process_directive(use_module(File, Import), Src) :-
 1013    process_use_module2(File, Import, Src, false).
 1014process_directive(autoload(File, Import), Src) :-
 1015    process_use_module2(File, Import, Src, false).
 1016process_directive(require(Import), Src) :-
 1017    process_requires(Import, Src).
 1018process_directive(expects_dialect(Dialect), Src) :-
 1019    process_directive(use_module(library(dialect/Dialect)), Src),
 1020    expects_dialect(Dialect).
 1021process_directive(reexport(File, Import), Src) :-
 1022    process_use_module2(File, Import, Src, true).
 1023process_directive(reexport(Modules), Src) :-
 1024    process_use_module(Modules, Src, true).
 1025process_directive(autoload(Modules), Src) :-
 1026    process_use_module(Modules, Src, false).
 1027process_directive(use_module(Modules), Src) :-
 1028    process_use_module(Modules, Src, false).
 1029process_directive(consult(Modules), Src) :-
 1030    process_use_module(Modules, Src, false).
 1031process_directive(ensure_loaded(Modules), Src) :-
 1032    process_use_module(Modules, Src, false).
 1033process_directive(load_files(Files, _Options), Src) :-
 1034    process_use_module(Files, Src, false).
 1035process_directive(include(Files), Src) :-
 1036    process_include(Files, Src).
 1037process_directive(dynamic(Dynamic), Src) :-
 1038    process_predicates(assert_dynamic, Dynamic, Src).
 1039process_directive(dynamic(Dynamic, _Options), Src) :-
 1040    process_predicates(assert_dynamic, Dynamic, Src).
 1041process_directive(thread_local(Dynamic), Src) :-
 1042    process_predicates(assert_thread_local, Dynamic, Src).
 1043process_directive(multifile(Dynamic), Src) :-
 1044    process_predicates(assert_multifile, Dynamic, Src).
 1045process_directive(public(Public), Src) :-
 1046    process_predicates(assert_public, Public, Src).
 1047process_directive(export(Export), Src) :-
 1048    process_predicates(assert_export, Export, Src).
 1049process_directive(import(Import), Src) :-
 1050    process_import(Import, Src).
 1051process_directive(module(Module, Export), Src) :-
 1052    assert_module(Src, Module),
 1053    assert_module_export(Src, Export).
 1054process_directive(module(Module, Export, Import), Src) :-
 1055    assert_module(Src, Module),
 1056    assert_module_export(Src, Export),
 1057    assert_module3(Import, Src).
 1058process_directive('$set_source_module'(system), Src) :-
 1059    assert_module(Src, system).     % hack for handling boot/init.pl
 1060process_directive(pce_begin_class_definition(Name, Meta, Super, Doc), Src) :-
 1061    assert_defined_class(Src, Name, Meta, Super, Doc).
 1062process_directive(pce_autoload(Name, From), Src) :-
 1063    assert_defined_class(Src, Name, imported_from(From)).
 1064
 1065process_directive(op(P, A, N), Src) :-
 1066    xref_push_op(Src, P, A, N).
 1067process_directive(set_prolog_flag(Flag, Value), Src) :-
 1068    (   Flag == character_escapes
 1069    ->  set_prolog_flag(character_escapes, Value)
 1070    ;   true
 1071    ),
 1072    current_source_line(Line),
 1073    xref_set_prolog_flag(Flag, Value, Src, Line).
 1074process_directive(style_check(X), _) :-
 1075    style_check(X).
 1076process_directive(encoding(Enc), _) :-
 1077    (   xref_input_stream(Stream)
 1078    ->  catch(set_stream(Stream, encoding(Enc)), _, true)
 1079    ;   true                        % can this happen?
 1080    ).
 1081process_directive(pce_expansion:push_compile_operators, _) :-
 1082    '$current_source_module'(SM),
 1083    call(pce_expansion:push_compile_operators(SM)). % call to avoid xref
 1084process_directive(pce_expansion:pop_compile_operators, _) :-
 1085    call(pce_expansion:pop_compile_operators).
 1086process_directive(meta_predicate(Meta), Src) :-
 1087    process_meta_predicate(Meta, Src).
 1088process_directive(arithmetic_function(FSpec), Src) :-
 1089    arith_callable(FSpec, Goal),
 1090    !,
 1091    current_source_line(Line),
 1092    assert_called(Src, '<directive>'(Line), Goal, Line).
 1093process_directive(format_predicate(_, Goal), Src) :-
 1094    !,
 1095    current_source_line(Line),
 1096    assert_called(Src, '<directive>'(Line), Goal, Line).
 1097process_directive(if(Cond), Src) :-
 1098    !,
 1099    current_source_line(Line),
 1100    assert_called(Src, '<directive>'(Line), Cond, Line).
 1101process_directive(elif(Cond), Src) :-
 1102    !,
 1103    current_source_line(Line),
 1104    assert_called(Src, '<directive>'(Line), Cond, Line).
 1105process_directive(else, _) :- !.
 1106process_directive(endif, _) :- !.
 1107process_directive(Goal, Src) :-
 1108    current_source_line(Line),
 1109    process_body(Goal, '<directive>'(Line), Src).
 process_meta_predicate(+Decl, +Src)
Create meta_goal/3 facts from the meta-goal declaration.
 1115process_meta_predicate((A,B), Src) :-
 1116    !,
 1117    process_meta_predicate(A, Src),
 1118    process_meta_predicate(B, Src).
 1119process_meta_predicate(Decl, Src) :-
 1120    process_meta_head(Src, Decl).
 1121
 1122process_meta_head(Src, Decl) :-         % swapped arguments for maplist
 1123    compound(Decl),
 1124    compound_name_arity(Decl, Name, Arity),
 1125    compound_name_arity(Head, Name, Arity),
 1126    meta_args(1, Arity, Decl, Head, Meta),
 1127    (   (   prolog:meta_goal(Head, _)
 1128        ;   prolog:called_by(Head, _, _, _)
 1129        ;   prolog:called_by(Head, _)
 1130        ;   meta_goal(Head, _)
 1131        )
 1132    ->  true
 1133    ;   assert(meta_goal(Head, Meta, Src))
 1134    ).
 1135
 1136meta_args(I, Arity, _, _, []) :-
 1137    I > Arity,
 1138    !.
 1139meta_args(I, Arity, Decl, Head, [H|T]) :-               % 0
 1140    arg(I, Decl, 0),
 1141    !,
 1142    arg(I, Head, H),
 1143    I2 is I + 1,
 1144    meta_args(I2, Arity, Decl, Head, T).
 1145meta_args(I, Arity, Decl, Head, [H|T]) :-               % ^
 1146    arg(I, Decl, ^),
 1147    !,
 1148    arg(I, Head, EH),
 1149    setof_goal(EH, H),
 1150    I2 is I + 1,
 1151    meta_args(I2, Arity, Decl, Head, T).
 1152meta_args(I, Arity, Decl, Head, [//(H)|T]) :-
 1153    arg(I, Decl, //),
 1154    !,
 1155    arg(I, Head, H),
 1156    I2 is I + 1,
 1157    meta_args(I2, Arity, Decl, Head, T).
 1158meta_args(I, Arity, Decl, Head, [H+A|T]) :-             % I --> H+I
 1159    arg(I, Decl, A),
 1160    integer(A), A > 0,
 1161    !,
 1162    arg(I, Head, H),
 1163    I2 is I + 1,
 1164    meta_args(I2, Arity, Decl, Head, T).
 1165meta_args(I, Arity, Decl, Head, Meta) :-
 1166    I2 is I + 1,
 1167    meta_args(I2, Arity, Decl, Head, Meta).
 1168
 1169
 1170              /********************************
 1171              *             BODY              *
 1172              ********************************/
 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).
 1181xref_meta(Source, Head, Called) :-
 1182    canonical_source(Source, Src),
 1183    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.
 1198xref_meta_src(Head, Called, Src) :-
 1199    meta_goal(Head, Called, Src),
 1200    !.
 1201xref_meta_src(Head, Called, _) :-
 1202    xref_meta(Head, Called),
 1203    !.
 1204xref_meta_src(Head, Called, _) :-
 1205    compound(Head),
 1206    compound_name_arity(Head, Name, Arity),
 1207    apply_pred(Name),
 1208    Arity > 5,
 1209    !,
 1210    Extra is Arity - 1,
 1211    arg(1, Head, G),
 1212    Called = [G+Extra].
 1213xref_meta_src(Head, Called, _) :-
 1214    predicate_property(user:Head, meta_predicate(Meta)),
 1215    !,
 1216    Meta =.. [_|Args],
 1217    meta_args(Args, 1, Head, Called).
 1218
 1219meta_args([], _, _, []).
 1220meta_args([H0|T0], I, Head, [H|T]) :-
 1221    xargs(H0, N),
 1222    !,
 1223    arg(I, Head, A),
 1224    (   N == 0
 1225    ->  H = A
 1226    ;   H = (A+N)
 1227    ),
 1228    I2 is I+1,
 1229    meta_args(T0, I2, Head, T).
 1230meta_args([_|T0], I, Head, T) :-
 1231    I2 is I+1,
 1232    meta_args(T0, I2, Head, T).
 1233
 1234xargs(N, N) :- integer(N), !.
 1235xargs(//, 2).
 1236xargs(^, 0).
 1237
 1238apply_pred(call).                               % built-in
 1239apply_pred(maplist).                            % library(apply_macros)
 1240
 1241xref_meta((A, B),               [A, B]).
 1242xref_meta((A; B),               [A, B]).
 1243xref_meta((A| B),               [A, B]).
 1244xref_meta((A -> B),             [A, B]).
 1245xref_meta((A *-> B),            [A, B]).
 1246xref_meta(findall(_V,G,_L),     [G]).
 1247xref_meta(findall(_V,G,_L,_T),  [G]).
 1248xref_meta(findnsols(_N,_V,G,_L),    [G]).
 1249xref_meta(findnsols(_N,_V,G,_L,_T), [G]).
 1250xref_meta(setof(_V, EG, _L),    [G]) :-
 1251    setof_goal(EG, G).
 1252xref_meta(bagof(_V, EG, _L),    [G]) :-
 1253    setof_goal(EG, G).
 1254xref_meta(forall(A, B),         [A, B]).
 1255xref_meta(maplist(G,_),         [G+1]).
 1256xref_meta(maplist(G,_,_),       [G+2]).
 1257xref_meta(maplist(G,_,_,_),     [G+3]).
 1258xref_meta(maplist(G,_,_,_,_),   [G+4]).
 1259xref_meta(map_list_to_pairs(G,_,_), [G+2]).
 1260xref_meta(map_assoc(G, _),      [G+1]).
 1261xref_meta(map_assoc(G, _, _),   [G+2]).
 1262xref_meta(checklist(G, _L),     [G+1]).
 1263xref_meta(sublist(G, _, _),     [G+1]).
 1264xref_meta(include(G, _, _),     [G+1]).
 1265xref_meta(exclude(G, _, _),     [G+1]).
 1266xref_meta(partition(G, _, _, _, _),     [G+2]).
 1267xref_meta(partition(G, _, _, _),[G+1]).
 1268xref_meta(call(G),              [G]).
 1269xref_meta(call(G, _),           [G+1]).
 1270xref_meta(call(G, _, _),        [G+2]).
 1271xref_meta(call(G, _, _, _),     [G+3]).
 1272xref_meta(call(G, _, _, _, _),  [G+4]).
 1273xref_meta(not(G),               [G]).
 1274xref_meta(notrace(G),           [G]).
 1275xref_meta(\+(G),                [G]).
 1276xref_meta(ignore(G),            [G]).
 1277xref_meta(once(G),              [G]).
 1278xref_meta(initialization(G),    [G]).
 1279xref_meta(initialization(G,_),  [G]).
 1280xref_meta(retract(Rule),        [G]) :- head_of(Rule, G).
 1281xref_meta(clause(G, _),         [G]).
 1282xref_meta(clause(G, _, _),      [G]).
 1283xref_meta(phrase(G, _A),        [//(G)]).
 1284xref_meta(phrase(G, _A, _R),    [//(G)]).
 1285xref_meta(call_dcg(G, _A, _R),  [//(G)]).
 1286xref_meta(phrase_from_file(G,_),[//(G)]).
 1287xref_meta(catch(A, _, B),       [A, B]).
 1288xref_meta(catch_with_backtrace(A, _, B), [A, B]).
 1289xref_meta(thread_create(A,_,_), [A]).
 1290xref_meta(thread_create(A,_),   [A]).
 1291xref_meta(thread_signal(_,A),   [A]).
 1292xref_meta(thread_idle(A,_),     [A]).
 1293xref_meta(thread_at_exit(A),    [A]).
 1294xref_meta(thread_initialization(A), [A]).
 1295xref_meta(engine_create(_,A,_), [A]).
 1296xref_meta(engine_create(_,A,_,_), [A]).
 1297xref_meta(transaction(A),       [A]).
 1298xref_meta(transaction(A,B,_),   [A,B]).
 1299xref_meta(snapshot(A),          [A]).
 1300xref_meta(predsort(A,_,_),      [A+3]).
 1301xref_meta(call_cleanup(A, B),   [A, B]).
 1302xref_meta(call_cleanup(A, _, B),[A, B]).
 1303xref_meta(setup_call_cleanup(A, B, C),[A, B, C]).
 1304xref_meta(setup_call_catcher_cleanup(A, B, _, C),[A, B, C]).
 1305xref_meta(call_residue_vars(A,_), [A]).
 1306xref_meta(with_mutex(_,A),      [A]).
 1307xref_meta(assume(G),            [G]).   % library(debug)
 1308xref_meta(assertion(G),         [G]).   % library(debug)
 1309xref_meta(freeze(_, G),         [G]).
 1310xref_meta(when(C, A),           [C, A]).
 1311xref_meta(time(G),              [G]).   % development system
 1312xref_meta(call_time(G, _),      [G]).   % development system
 1313xref_meta(call_time(G, _, _),   [G]).   % development system
 1314xref_meta(profile(G),           [G]).
 1315xref_meta(at_halt(G),           [G]).
 1316xref_meta(call_with_time_limit(_, G), [G]).
 1317xref_meta(call_with_depth_limit(G, _, _), [G]).
 1318xref_meta(call_with_inference_limit(G, _, _), [G]).
 1319xref_meta(alarm(_, G, _),       [G]).
 1320xref_meta(alarm(_, G, _, _),    [G]).
 1321xref_meta('$add_directive_wic'(G), [G]).
 1322xref_meta(with_output_to(_, G), [G]).
 1323xref_meta(if(G),                [G]).
 1324xref_meta(elif(G),              [G]).
 1325xref_meta(meta_options(G,_,_),  [G+1]).
 1326xref_meta(on_signal(_,_,H),     [H+1]) :- H \== default.
 1327xref_meta(distinct(G),          [G]).   % library(solution_sequences)
 1328xref_meta(distinct(_, G),       [G]).
 1329xref_meta(order_by(_, G),       [G]).
 1330xref_meta(limit(_, G),          [G]).
 1331xref_meta(offset(_, G),         [G]).
 1332xref_meta(reset(G,_,_),         [G]).
 1333xref_meta(prolog_listen(Ev,G),  [G+N]) :- event_xargs(Ev, N).
 1334xref_meta(prolog_listen(Ev,G,_),[G+N]) :- event_xargs(Ev, N).
 1335xref_meta(tnot(G),		[G]).
 1336xref_meta(not_exists(G),	[G]).
 1337xref_meta(with_tty_raw(G),	[G]).
 1338xref_meta(residual_goals(G),    [G+2]).
 1339
 1340                                        % XPCE meta-predicates
 1341xref_meta(pce_global(_, new(_)), _) :- !, fail.
 1342xref_meta(pce_global(_, B),     [B+1]).
 1343xref_meta(ifmaintainer(G),      [G]).   % used in manual
 1344xref_meta(listen(_, G),         [G]).   % library(broadcast)
 1345xref_meta(listen(_, _, G),      [G]).
 1346xref_meta(in_pce_thread(G),     [G]).
 1347
 1348xref_meta(G, Meta) :-                   % call user extensions
 1349    prolog:meta_goal(G, Meta).
 1350xref_meta(G, Meta) :-                   % Generated from :- meta_predicate
 1351    meta_goal(G, Meta).
 1352
 1353setof_goal(EG, G) :-
 1354    var(EG), !, G = EG.
 1355setof_goal(_^EG, G) :-
 1356    !,
 1357    setof_goal(EG, G).
 1358setof_goal(G, G).
 1359
 1360event_xargs(abort,            0).
 1361event_xargs(erase,            1).
 1362event_xargs(break,            3).
 1363event_xargs(frame_finished,   1).
 1364event_xargs(thread_exit,      1).
 1365event_xargs(this_thread_exit, 0).
 1366event_xargs(PI,               2) :- pi_to_head(PI, _).
 head_of(+Rule, -Head)
Get the head for a retract call.
 1372head_of(Var, _) :-
 1373    var(Var), !, fail.
 1374head_of((Head :- _), Head).
 1375head_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.
 1383xref_hook(Hook) :-
 1384    prolog:hook(Hook).
 1385xref_hook(Hook) :-
 1386    hook(Hook).
 1387
 1388
 1389hook(attr_portray_hook(_,_)).
 1390hook(attr_unify_hook(_,_)).
 1391hook(attribute_goals(_,_,_)).
 1392hook(goal_expansion(_,_)).
 1393hook(term_expansion(_,_)).
 1394hook(resource(_,_,_)).
 1395hook('$pred_option'(_,_,_,_)).
 1396
 1397hook(emacs_prolog_colours:goal_classification(_,_)).
 1398hook(emacs_prolog_colours:term_colours(_,_)).
 1399hook(emacs_prolog_colours:goal_colours(_,_)).
 1400hook(emacs_prolog_colours:style(_,_)).
 1401hook(emacs_prolog_colours:identify(_,_)).
 1402hook(pce_principal:pce_class(_,_,_,_,_,_)).
 1403hook(pce_principal:send_implementation(_,_,_)).
 1404hook(pce_principal:get_implementation(_,_,_,_)).
 1405hook(pce_principal:pce_lazy_get_method(_,_,_)).
 1406hook(pce_principal:pce_lazy_send_method(_,_,_)).
 1407hook(pce_principal:pce_uses_template(_,_)).
 1408hook(prolog:locate_clauses(_,_)).
 1409hook(prolog:message(_,_,_)).
 1410hook(prolog:error_message(_,_,_)).
 1411hook(prolog:message_location(_,_,_)).
 1412hook(prolog:message_context(_,_,_)).
 1413hook(prolog:message_line_element(_,_)).
 1414hook(prolog:debug_control_hook(_)).
 1415hook(prolog:help_hook(_)).
 1416hook(prolog:show_profile_hook(_,_)).
 1417hook(prolog:general_exception(_,_)).
 1418hook(prolog:predicate_summary(_,_)).
 1419hook(prolog:residual_goals(_,_)).
 1420hook(prolog_edit:load).
 1421hook(prolog_edit:locate(_,_,_)).
 1422hook(shlib:unload_all_foreign_libraries).
 1423hook(system:'$foreign_registered'(_, _)).
 1424hook(predicate_options:option_decl(_,_,_)).
 1425hook(user:exception(_,_,_)).
 1426hook(user:file_search_path(_,_)).
 1427hook(user:library_directory(_)).
 1428hook(user:message_hook(_,_,_)).
 1429hook(user:portray(_)).
 1430hook(user:prolog_clause_name(_,_)).
 1431hook(user:prolog_list_goal(_)).
 1432hook(user:prolog_predicate_name(_,_)).
 1433hook(user:prolog_trace_interception(_,_,_,_)).
 1434hook(user:prolog_exception_hook(_,_,_,_)).
 1435hook(sandbox:safe_primitive(_)).
 1436hook(sandbox:safe_meta_predicate(_)).
 1437hook(sandbox:safe_meta(_,_)).
 1438hook(sandbox:safe_global_variable(_)).
 1439hook(sandbox:safe_directive(_)).
 arith_callable(+Spec, -Callable)
Translate argument of arithmetic_function/1 into a callable term
 1446arith_callable(Var, _) :-
 1447    var(Var), !, fail.
 1448arith_callable(Module:Spec, Module:Goal) :-
 1449    !,
 1450    arith_callable(Spec, Goal).
 1451arith_callable(Name/Arity, Goal) :-
 1452    PredArity is Arity + 1,
 1453    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.

 1464process_body(Body, Origin, Src) :-
 1465    forall(limit(100, process_goal(Body, Origin, Src, _Partial)),
 1466           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.
 1473process_goal(Var, _, _, _) :-
 1474    var(Var),
 1475    !.
 1476process_goal(Goal, Origin, Src, P) :-
 1477    Goal = (_,_),                               % problems
 1478    !,
 1479    phrase(conjunction(Goal), Goals),
 1480    process_conjunction(Goals, Origin, Src, P).
 1481process_goal(Goal, Origin, Src, _) :-           % Final disjunction, no
 1482    Goal = (_;_),                               % problems
 1483    !,
 1484    phrase(disjunction(Goal), Goals),
 1485    forall(member(G, Goals),
 1486           process_body(G, Origin, Src)).
 1487process_goal(Goal, Origin, Src, P) :-
 1488    (   (   xmodule(M, Src)
 1489        ->  true
 1490        ;   M = user
 1491        ),
 1492        (   predicate_property(M:Goal, imported_from(IM))
 1493        ->  true
 1494        ;   IM = M
 1495        ),
 1496        prolog:called_by(Goal, IM, M, Called)
 1497    ;   prolog:called_by(Goal, Called)
 1498    ),
 1499    !,
 1500    must_be(list, Called),
 1501    current_source_line(Here),
 1502    assert_called(Src, Origin, Goal, Here),
 1503    process_called_list(Called, Origin, Src, P).
 1504process_goal(Goal, Origin, Src, _) :-
 1505    process_xpce_goal(Goal, Origin, Src),
 1506    !.
 1507process_goal(load_foreign_library(File), _Origin, Src, _) :-
 1508    process_foreign(File, Src).
 1509process_goal(load_foreign_library(File, _Init), _Origin, Src, _) :-
 1510    process_foreign(File, Src).
 1511process_goal(use_foreign_library(File), _Origin, Src, _) :-
 1512    process_foreign(File, Src).
 1513process_goal(use_foreign_library(File, _Init), _Origin, Src, _) :-
 1514    process_foreign(File, Src).
 1515process_goal(Goal, Origin, Src, P) :-
 1516    xref_meta_src(Goal, Metas, Src),
 1517    !,
 1518    current_source_line(Here),
 1519    assert_called(Src, Origin, Goal, Here),
 1520    process_called_list(Metas, Origin, Src, P).
 1521process_goal(Goal, Origin, Src, _) :-
 1522    asserting_goal(Goal, Rule),
 1523    !,
 1524    current_source_line(Here),
 1525    assert_called(Src, Origin, Goal, Here),
 1526    process_assert(Rule, Origin, Src).
 1527process_goal(Goal, Origin, Src, P) :-
 1528    partial_evaluate(Goal, P),
 1529    current_source_line(Here),
 1530    assert_called(Src, Origin, Goal, Here).
 1531
 1532disjunction(Var)   --> {var(Var), !}, [Var].
 1533disjunction((A;B)) --> !, disjunction(A), disjunction(B).
 1534disjunction(G)     --> [G].
 1535
 1536conjunction(Var)   --> {var(Var), !}, [Var].
 1537conjunction((A,B)) --> !, conjunction(A), conjunction(B).
 1538conjunction(G)     --> [G].
 1539
 1540shares_vars(RVars, T) :-
 1541    term_variables(T, TVars0),
 1542    sort(TVars0, TVars),
 1543    ord_intersect(RVars, TVars).
 1544
 1545process_conjunction([], _, _, _).
 1546process_conjunction([Disj|Rest], Origin, Src, P) :-
 1547    nonvar(Disj),
 1548    Disj = (_;_),
 1549    Rest \== [],
 1550    !,
 1551    phrase(disjunction(Disj), Goals),
 1552    term_variables(Rest, RVars0),
 1553    sort(RVars0, RVars),
 1554    partition(shares_vars(RVars), Goals, Sharing, NonSHaring),
 1555    forall(member(G, NonSHaring),
 1556           process_body(G, Origin, Src)),
 1557    (   Sharing == []
 1558    ->  true
 1559    ;   maplist(term_variables, Sharing, GVars0),
 1560        append(GVars0, GVars1),
 1561        sort(GVars1, GVars),
 1562        ord_intersection(GVars, RVars, SVars),
 1563        VT =.. [v|SVars],
 1564        findall(VT,
 1565                (   member(G, Sharing),
 1566                    process_goal(G, Origin, Src, PS),
 1567                    PS == true
 1568                ),
 1569                Alts0),
 1570        (   Alts0 == []
 1571        ->  true
 1572        ;   (   true
 1573            ;   P = true,
 1574                sort(Alts0, Alts1),
 1575                variants(Alts1, 10, Alts),
 1576                member(VT, Alts)
 1577            )
 1578        )
 1579    ),
 1580    process_conjunction(Rest, Origin, Src, P).
 1581process_conjunction([H|T], Origin, Src, P) :-
 1582    process_goal(H, Origin, Src, P),
 1583    process_conjunction(T, Origin, Src, P).
 1584
 1585
 1586process_called_list([], _, _, _).
 1587process_called_list([H|T], Origin, Src, P) :-
 1588    process_meta(H, Origin, Src, P),
 1589    process_called_list(T, Origin, Src, P).
 1590
 1591process_meta(A+N, Origin, Src, P) :-
 1592    !,
 1593    (   extend(A, N, AX)
 1594    ->  process_goal(AX, Origin, Src, P)
 1595    ;   true
 1596    ).
 1597process_meta(//(A), Origin, Src, P) :-
 1598    !,
 1599    process_dcg_goal(A, Origin, Src, P).
 1600process_meta(G, Origin, Src, P) :-
 1601    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.
 1608process_dcg_goal(Var, _, _, _) :-
 1609    var(Var),
 1610    !.
 1611process_dcg_goal((A,B), Origin, Src, P) :-
 1612    !,
 1613    process_dcg_goal(A, Origin, Src, P),
 1614    process_dcg_goal(B, Origin, Src, P).
 1615process_dcg_goal((A;B), Origin, Src, P) :-
 1616    !,
 1617    process_dcg_goal(A, Origin, Src, P),
 1618    process_dcg_goal(B, Origin, Src, P).
 1619process_dcg_goal((A|B), Origin, Src, P) :-
 1620    !,
 1621    process_dcg_goal(A, Origin, Src, P),
 1622    process_dcg_goal(B, Origin, Src, P).
 1623process_dcg_goal((A->B), Origin, Src, P) :-
 1624    !,
 1625    process_dcg_goal(A, Origin, Src, P),
 1626    process_dcg_goal(B, Origin, Src, P).
 1627process_dcg_goal((A*->B), Origin, Src, P) :-
 1628    !,
 1629    process_dcg_goal(A, Origin, Src, P),
 1630    process_dcg_goal(B, Origin, Src, P).
 1631process_dcg_goal({Goal}, Origin, Src, P) :-
 1632    !,
 1633    process_goal(Goal, Origin, Src, P).
 1634process_dcg_goal(List, _Origin, _Src, _) :-
 1635    is_list(List),
 1636    !.               % terminal
 1637process_dcg_goal(List, _Origin, _Src, _) :-
 1638    string(List),
 1639    !.                % terminal
 1640process_dcg_goal(Callable, Origin, Src, P) :-
 1641    extend(Callable, 2, Goal),
 1642    !,
 1643    process_goal(Goal, Origin, Src, P).
 1644process_dcg_goal(_, _, _, _).
 1645
 1646
 1647extend(Var, _, _) :-
 1648    var(Var), !, fail.
 1649extend(M:G, N, M:GX) :-
 1650    !,
 1651    callable(G),
 1652    extend(G, N, GX).
 1653extend(G, N, GX) :-
 1654    (   compound(G)
 1655    ->  compound_name_arguments(G, Name, Args),
 1656        length(Rest, N),
 1657        append(Args, Rest, NArgs),
 1658        compound_name_arguments(GX, Name, NArgs)
 1659    ;   atom(G)
 1660    ->  length(NArgs, N),
 1661        compound_name_arguments(GX, G, NArgs)
 1662    ).
 1663
 1664asserting_goal(assert(Rule), Rule).
 1665asserting_goal(asserta(Rule), Rule).
 1666asserting_goal(assertz(Rule), Rule).
 1667asserting_goal(assert(Rule,_), Rule).
 1668asserting_goal(asserta(Rule,_), Rule).
 1669asserting_goal(assertz(Rule,_), Rule).
 1670
 1671process_assert(0, _, _) :- !.           % catch variables
 1672process_assert((_:-Body), Origin, Src) :-
 1673    !,
 1674    process_body(Body, Origin, Src).
 1675process_assert(_, _, _).
 variants(+SortedList, +Max, -Variants) is det
 1679variants([], _, []).
 1680variants([H|T], Max, List) :-
 1681    variants(T, H, Max, List).
 1682
 1683variants([], H, _, [H]).
 1684variants(_, _, 0, []) :- !.
 1685variants([H|T], V, Max, List) :-
 1686    (   H =@= V
 1687    ->  variants(T, V, Max, List)
 1688    ;   List = [V|List2],
 1689        Max1 is Max-1,
 1690        variants(T, H, Max1, List2)
 1691    ).
 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?
 1705partial_evaluate(Goal, P) :-
 1706    eval(Goal),
 1707    !,
 1708    P = true.
 1709partial_evaluate(_, _).
 1710
 1711eval(X = Y) :-
 1712    unify_with_occurs_check(X, Y).
 1713
 1714
 1715                 /*******************************
 1716                 *          XPCE STUFF          *
 1717                 *******************************/
 1718
 1719pce_goal(new(_,_), new(-, new)).
 1720pce_goal(send(_,_), send(arg, msg)).
 1721pce_goal(send_class(_,_,_), send_class(arg, arg, msg)).
 1722pce_goal(get(_,_,_), get(arg, msg, -)).
 1723pce_goal(get_class(_,_,_,_), get_class(arg, arg, msg, -)).
 1724pce_goal(get_chain(_,_,_), get_chain(arg, msg, -)).
 1725pce_goal(get_object(_,_,_), get_object(arg, msg, -)).
 1726
 1727process_xpce_goal(G, Origin, Src) :-
 1728    pce_goal(G, Process),
 1729    !,
 1730    current_source_line(Here),
 1731    assert_called(Src, Origin, G, Here),
 1732    (   arg(I, Process, How),
 1733        arg(I, G, Term),
 1734        process_xpce_arg(How, Term, Origin, Src),
 1735        fail
 1736    ;   true
 1737    ).
 1738
 1739process_xpce_arg(new, Term, Origin, Src) :-
 1740    callable(Term),
 1741    process_new(Term, Origin, Src).
 1742process_xpce_arg(arg, Term, Origin, Src) :-
 1743    compound(Term),
 1744    process_new(Term, Origin, Src).
 1745process_xpce_arg(msg, Term, Origin, Src) :-
 1746    compound(Term),
 1747    (   arg(_, Term, Arg),
 1748        process_xpce_arg(arg, Arg, Origin, Src),
 1749        fail
 1750    ;   true
 1751    ).
 1752
 1753process_new(_M:_Term, _, _) :- !.       % TBD: Calls on other modules!
 1754process_new(Term, Origin, Src) :-
 1755    assert_new(Src, Origin, Term),
 1756    (   compound(Term),
 1757        arg(_, Term, Arg),
 1758        process_xpce_arg(arg, Arg, Origin, Src),
 1759        fail
 1760    ;   true
 1761    ).
 1762
 1763assert_new(_, _, Term) :-
 1764    \+ callable(Term),
 1765    !.
 1766assert_new(Src, Origin, Control) :-
 1767    functor_name(Control, Class),
 1768    pce_control_class(Class),
 1769    !,
 1770    forall(arg(_, Control, Arg),
 1771           assert_new(Src, Origin, Arg)).
 1772assert_new(Src, Origin, Term) :-
 1773    compound(Term),
 1774    arg(1, Term, Prolog),
 1775    Prolog == @(prolog),
 1776    (   Term =.. [message, _, Selector | T],
 1777        atom(Selector)
 1778    ->  Called =.. [Selector|T],
 1779        process_body(Called, Origin, Src)
 1780    ;   Term =.. [?, _, Selector | T],
 1781        atom(Selector)
 1782    ->  append(T, [_R], T2),
 1783        Called =.. [Selector|T2],
 1784        process_body(Called, Origin, Src)
 1785    ),
 1786    fail.
 1787assert_new(_, _, @(_)) :- !.
 1788assert_new(Src, _, Term) :-
 1789    functor_name(Term, Name),
 1790    assert_used_class(Src, Name).
 1791
 1792
 1793pce_control_class(and).
 1794pce_control_class(or).
 1795pce_control_class(if).
 1796pce_control_class(not).
 1797
 1798
 1799                /********************************
 1800                *       INCLUDED MODULES        *
 1801                ********************************/
 process_use_module(+Modules, +Src, +Rexport) is det
 1805process_use_module(_Module:_Files, _, _) :- !.  % loaded in another module
 1806process_use_module([], _, _) :- !.
 1807process_use_module([H|T], Src, Reexport) :-
 1808    !,
 1809    process_use_module(H, Src, Reexport),
 1810    process_use_module(T, Src, Reexport).
 1811process_use_module(library(pce), Src, Reexport) :-     % bit special
 1812    !,
 1813    xref_public_list(library(pce), Path, Exports, Src),
 1814    forall(member(Import, Exports),
 1815           process_pce_import(Import, Src, Path, Reexport)).
 1816process_use_module(File, Src, Reexport) :-
 1817    load_module_if_needed(File),
 1818    (   xoption(Src, silent(Silent))
 1819    ->  Extra = [silent(Silent)]
 1820    ;   Extra = [silent(true)]
 1821    ),
 1822    (   xref_public_list(File, Src,
 1823                         [ path(Path),
 1824                           module(M),
 1825                           exports(Exports),
 1826                           public(Public),
 1827                           meta(Meta)
 1828                         | Extra
 1829                         ])
 1830    ->  assert(uses_file(File, Src, Path)),
 1831        assert_import(Src, Exports, _, Path, Reexport),
 1832        assert_xmodule_callable(Exports, M, Src, Path),
 1833        assert_xmodule_callable(Public, M, Src, Path),
 1834        maplist(process_meta_head(Src), Meta),
 1835        (   File = library(chr)     % hacky
 1836        ->  assert(mode(chr, Src))
 1837        ;   true
 1838        )
 1839    ;   assert(uses_file(File, Src, '<not_found>'))
 1840    ).
 1841
 1842process_pce_import(Name/Arity, Src, Path, Reexport) :-
 1843    atom(Name),
 1844    integer(Arity),
 1845    !,
 1846    functor(Term, Name, Arity),
 1847    (   \+ system_predicate(Term),
 1848        \+ Term = pce_error(_)      % hack!?
 1849    ->  assert_import(Src, [Name/Arity], _, Path, Reexport)
 1850    ;   true
 1851    ).
 1852process_pce_import(op(P,T,N), Src, _, _) :-
 1853    xref_push_op(Src, P, T, N).
 process_use_module2(+File, +Import, +Src, +Reexport) is det
Process use_module/2 and reexport/2.
 1859process_use_module2(File, Import, Src, Reexport) :-
 1860    load_module_if_needed(File),
 1861    (   xref_source_file(File, Path, Src)
 1862    ->  assert(uses_file(File, Src, Path)),
 1863        (   catch(public_list(Path, _, Meta, Export, _Public, []), _, fail)
 1864        ->  assert_import(Src, Import, Export, Path, Reexport),
 1865            forall((  member(Head, Meta),
 1866                      imported(Head, _, Path)
 1867                   ),
 1868                   process_meta_head(Src, Head))
 1869        ;   true
 1870        )
 1871    ;   assert(uses_file(File, Src, '<not_found>'))
 1872    ).
 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.
 1881load_module_if_needed(File) :-
 1882    prolog:no_autoload_module(File),
 1883    !,
 1884    use_module(File, []).
 1885load_module_if_needed(_).
 1886
 1887prolog:no_autoload_module(library(apply_macros)).
 1888prolog:no_autoload_module(library(arithmetic)).
 1889prolog:no_autoload_module(library(record)).
 1890prolog:no_autoload_module(library(persistency)).
 1891prolog:no_autoload_module(library(pldoc)).
 1892prolog:no_autoload_module(library(settings)).
 1893prolog:no_autoload_module(library(debug)).
 1894prolog:no_autoload_module(library(plunit)).
 process_requires(+Import, +Src)
 1899process_requires(Import, Src) :-
 1900    is_list(Import),
 1901    !,
 1902    require_list(Import, Src).
 1903process_requires(Var, _Src) :-
 1904    var(Var),
 1905    !.
 1906process_requires((A,B), Src) :-
 1907    !,
 1908    process_requires(A, Src),
 1909    process_requires(B, Src).
 1910process_requires(PI, Src) :-
 1911    requires(PI, Src).
 1912
 1913require_list([], _).
 1914require_list([H|T], Src) :-
 1915    requires(H, Src),
 1916    require_list(T, Src).
 1917
 1918requires(PI, _Src) :-
 1919    '$pi_head'(PI, Head),
 1920    '$get_predicate_attribute'(system:Head, defined, 1),
 1921    !.
 1922requires(PI, Src) :-
 1923    '$pi_head'(PI, Head),
 1924    '$pi_head'(Name/Arity, Head),
 1925    '$find_library'(_Module, Name, Arity, _LoadModule, Library),
 1926    (   imported(Head, Src, Library)
 1927    ->  true
 1928    ;   assertz(imported(Head, Src, Library))
 1929    ).
 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.
 1960xref_public_list(File, Src, Options) :-
 1961    option(path(Path), Options, _),
 1962    option(module(Module), Options, _),
 1963    option(exports(Exports), Options, _),
 1964    option(public(Public), Options, _),
 1965    option(meta(Meta), Options, _),
 1966    xref_source_file(File, Path, Src, Options),
 1967    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.
 1989xref_public_list(File, Path, Export, Src) :-
 1990    xref_source_file(File, Path, Src),
 1991    public_list(Path, _, _, Export, _, []).
 1992xref_public_list(File, Path, Module, Export, Meta, Src) :-
 1993    xref_source_file(File, Path, Src),
 1994    public_list(Path, Module, Meta, Export, _, []).
 1995xref_public_list(File, Path, Module, Export, Public, Meta, Src) :-
 1996    xref_source_file(File, Path, Src),
 1997    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.
 2007:- dynamic  public_list_cache/6. 2008:- volatile public_list_cache/6. 2009
 2010public_list(Path, Module, Meta, Export, Public, _Options) :-
 2011    public_list_cache(Path, Modified,
 2012                      Module0, Meta0, Export0, Public0),
 2013    time_file(Path, ModifiedNow),
 2014    (   abs(Modified-ModifiedNow) < 0.0001
 2015    ->  !,
 2016        t(Module,Meta,Export,Public) = t(Module0,Meta0,Export0,Public0)
 2017    ;   retractall(public_list_cache(Path, _, _, _, _, _)),
 2018        fail
 2019    ).
 2020public_list(Path, Module, Meta, Export, Public, Options) :-
 2021    public_list_nc(Path, Module0, Meta0, Export0, Public0, Options),
 2022    (   Error = error(_,_),
 2023        catch(time_file(Path, Modified), Error, fail)
 2024    ->  asserta(public_list_cache(Path, Modified,
 2025                                  Module0, Meta0, Export0, Public0))
 2026    ;   true
 2027    ),
 2028    t(Module,Meta,Export,Public) = t(Module0,Meta0,Export0,Public0).
 2029
 2030public_list_nc(Path, Module, Meta, Export, Public, Options) :-
 2031    in_temporary_module(
 2032        TempModule,
 2033        true,
 2034        public_list_diff(TempModule, Path, Module,
 2035                         Meta, [], Export, [], Public, [], Options)).
 2036
 2037
 2038public_list_diff(TempModule,
 2039                 Path, Module, Meta, MT, Export, Rest, Public, PT, Options) :-
 2040    setup_call_cleanup(
 2041        public_list_setup(TempModule, Path, In, State),
 2042        phrase(read_directives(In, Options, [true]), Directives),
 2043        public_list_cleanup(In, State)),
 2044    public_list(Directives, Path, Module, Meta, MT, Export, Rest, Public, PT).
 2045
 2046public_list_setup(TempModule, Path, In, state(OldM, OldXref)) :-
 2047    prolog_open_source(Path, In),
 2048    '$set_source_module'(OldM, TempModule),
 2049    set_xref(OldXref).
 2050
 2051public_list_cleanup(In, state(OldM, OldXref)) :-
 2052    '$set_source_module'(OldM),
 2053    set_prolog_flag(xref, OldXref),
 2054    prolog_close_source(In).
 2055
 2056
 2057read_directives(In, Options, State) -->
 2058    {  repeat,
 2059       catch(prolog_read_source_term(In, Term, Expanded,
 2060                                     [ process_comment(true),
 2061                                       syntax_errors(error)
 2062                                     ]),
 2063             E, report_syntax_error(E, -, Options))
 2064    -> nonvar(Term),
 2065       Term = (:-_)
 2066    },
 2067    !,
 2068    terms(Expanded, State, State1),
 2069    read_directives(In, Options, State1).
 2070read_directives(_, _, _) --> [].
 2071
 2072terms(Var, State, State) --> { var(Var) }, !.
 2073terms([H|T], State0, State) -->
 2074    !,
 2075    terms(H, State0, State1),
 2076    terms(T, State1, State).
 2077terms((:-if(Cond)), State0, [True|State0]) -->
 2078    !,
 2079    { eval_cond(Cond, True) }.
 2080terms((:-elif(Cond)), [True0|State], [True|State]) -->
 2081    !,
 2082    { eval_cond(Cond, True1),
 2083      elif(True0, True1, True)
 2084    }.
 2085terms((:-else), [True0|State], [True|State]) -->
 2086    !,
 2087    { negate(True0, True) }.
 2088terms((:-endif), [_|State], State) -->  !.
 2089terms(H, State, State) -->
 2090    (   {State = [true|_]}
 2091    ->  [H]
 2092    ;   []
 2093    ).
 2094
 2095eval_cond(Cond, true) :-
 2096    catch(Cond, _, fail),
 2097    !.
 2098eval_cond(_, false).
 2099
 2100elif(true,  _,    else_false) :- !.
 2101elif(false, true, true) :- !.
 2102elif(True,  _,    True).
 2103
 2104negate(true,       false).
 2105negate(false,      true).
 2106negate(else_false, else_false).
 2107
 2108public_list([(:- module(Module, Export0))|Decls], Path,
 2109            Module, Meta, MT, Export, Rest, Public, PT) :-
 2110    !,
 2111    (   is_list(Export0)
 2112    ->  append(Export0, Reexport, Export)
 2113    ;   Reexport = Export
 2114    ),
 2115    public_list_(Decls, Path, Meta, MT, Reexport, Rest, Public, PT).
 2116public_list([(:- encoding(_))|Decls], Path,
 2117            Module, Meta, MT, Export, Rest, Public, PT) :-
 2118    public_list(Decls, Path, Module, Meta, MT, Export, Rest, Public, PT).
 2119
 2120public_list_([], _, Meta, Meta, Export, Export, Public, Public).
 2121public_list_([(:-(Dir))|T], Path, Meta, MT, Export, Rest, Public, PT) :-
 2122    public_list_1(Dir, Path, Meta, MT0, Export, Rest0, Public, PT0),
 2123    !,
 2124    public_list_(T, Path, MT0, MT, Rest0, Rest, PT0, PT).
 2125public_list_([_|T], Path, Meta, MT, Export, Rest, Public, PT) :-
 2126    public_list_(T, Path, Meta, MT, Export, Rest, Public, PT).
 2127
 2128public_list_1(reexport(Spec), Path, Meta, MT, Reexport, Rest, Public, PT) :-
 2129    reexport_files(Spec, Path, Meta, MT, Reexport, Rest, Public, PT).
 2130public_list_1(reexport(Spec, Import), Path, Meta, Meta, Reexport, Rest, Public, Public) :-
 2131    public_from_import(Import, Spec, Path, Reexport, Rest).
 2132public_list_1(meta_predicate(Decl), _Path, Meta, MT, Export, Export, Public, Public) :-
 2133    phrase(meta_decls(Decl), Meta, MT).
 2134public_list_1(public(Decl), _Path, Meta, Meta, Export, Export, Public, PT) :-
 2135    phrase(public_decls(Decl), Public, PT).
 reexport_files(+Files, +Src, -Meta, ?MetaTail, -Exports, ?ExportsTail, -Public, ?PublicTail)
 2141reexport_files([], _, Meta, Meta, Export, Export, Public, Public) :- !.
 2142reexport_files([H|T], Src, Meta, MT, Export, ET, Public, PT) :-
 2143    !,
 2144    xref_source_file(H, Path, Src),
 2145    public_list(Path, _Module, Meta0, Export0, Public0, []),
 2146    append(Meta0, MT1, Meta),
 2147    append(Export0, ET1, Export),
 2148    append(Public0, PT1, Public),
 2149    reexport_files(T, Src, MT1, MT, ET1, ET, PT1, PT).
 2150reexport_files(Spec, Src, Meta, MT, Export, ET, Public, PT) :-
 2151    xref_source_file(Spec, Path, Src),
 2152    public_list(Path, _Module, Meta0, Export0, Public0, []),
 2153    append(Meta0, MT, Meta),
 2154    append(Export0, ET, Export),
 2155    append(Public0, PT, Public).
 2156
 2157public_from_import(except(Map), Path, Src, Export, Rest) :-
 2158    !,
 2159    xref_public_list(Path, _, AllExports, Src),
 2160    except(Map, AllExports, NewExports),
 2161    append(NewExports, Rest, Export).
 2162public_from_import(Import, _, _, Export, Rest) :-
 2163    import_name_map(Import, Export, Rest).
 except(+Remove, +AllExports, -Exports)
 2168except([], Exports, Exports).
 2169except([PI0 as NewName|Map], Exports0, Exports) :-
 2170    !,
 2171    canonical_pi(PI0, PI),
 2172    map_as(Exports0, PI, NewName, Exports1),
 2173    except(Map, Exports1, Exports).
 2174except([PI0|Map], Exports0, Exports) :-
 2175    canonical_pi(PI0, PI),
 2176    select(PI2, Exports0, Exports1),
 2177    same_pi(PI, PI2),
 2178    !,
 2179    except(Map, Exports1, Exports).
 2180
 2181
 2182map_as([PI|T], Repl, As, [PI2|T])  :-
 2183    same_pi(Repl, PI),
 2184    !,
 2185    pi_as(PI, As, PI2).
 2186map_as([H|T0], Repl, As, [H|T])  :-
 2187    map_as(T0, Repl, As, T).
 2188
 2189pi_as(_/Arity, Name, Name/Arity).
 2190pi_as(_//Arity, Name, Name//Arity).
 2191
 2192import_name_map([], L, L).
 2193import_name_map([_/Arity as NewName|T0], [NewName/Arity|T], Tail) :-
 2194    !,
 2195    import_name_map(T0, T, Tail).
 2196import_name_map([_//Arity as NewName|T0], [NewName//Arity|T], Tail) :-
 2197    !,
 2198    import_name_map(T0, T, Tail).
 2199import_name_map([H|T0], [H|T], Tail) :-
 2200    import_name_map(T0, T, Tail).
 2201
 2202canonical_pi(Name//Arity0, PI) :-
 2203    integer(Arity0),
 2204    !,
 2205    PI = Name/Arity,
 2206    Arity is Arity0 + 2.
 2207canonical_pi(PI, PI).
 2208
 2209same_pi(Canonical, PI2) :-
 2210    canonical_pi(PI2, Canonical).
 2211
 2212meta_decls(Var) -->
 2213    { var(Var) },
 2214    !.
 2215meta_decls((A,B)) -->
 2216    !,
 2217    meta_decls(A),
 2218    meta_decls(B).
 2219meta_decls(A) -->
 2220    [A].
 2221
 2222public_decls(Var) -->
 2223    { var(Var) },
 2224    !.
 2225public_decls((A,B)) -->
 2226    !,
 2227    public_decls(A),
 2228    public_decls(B).
 2229public_decls(A) -->
 2230    [A].
 2231
 2232                 /*******************************
 2233                 *             INCLUDE          *
 2234                 *******************************/
 2235
 2236process_include([], _) :- !.
 2237process_include([H|T], Src) :-
 2238    !,
 2239    process_include(H, Src),
 2240    process_include(T, Src).
 2241process_include(File, Src) :-
 2242    callable(File),
 2243    !,
 2244    (   once(xref_input(ParentSrc, _)),
 2245        xref_source_file(File, Path, ParentSrc)
 2246    ->  (   (   uses_file(_, Src, Path)
 2247            ;   Path == Src
 2248            )
 2249        ->  true
 2250        ;   assert(uses_file(File, Src, Path)),
 2251            (   xoption(Src, process_include(true))
 2252            ->  findall(O, xoption(Src, O), Options),
 2253                setup_call_cleanup(
 2254                    open_include_file(Path, In, Refs),
 2255                    collect(Src, Path, In, Options),
 2256                    close_include(In, Refs))
 2257            ;   true
 2258            )
 2259        )
 2260    ;   assert(uses_file(File, Src, '<not_found>'))
 2261    ).
 2262process_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.
 2270open_include_file(Path, In, [Ref]) :-
 2271    once(xref_input(_, Parent)),
 2272    stream_property(Parent, encoding(Enc)),
 2273    '$push_input_context'(xref_include),
 2274    catch((   prolog:xref_open_source(Path, In)
 2275          ->  catch(set_stream(In, encoding(Enc)),
 2276                    error(_,_), true)       % deal with non-file input
 2277          ;   include_encoding(Enc, Options),
 2278              open(Path, read, In, Options)
 2279          ), E,
 2280          ( '$pop_input_context', throw(E))),
 2281    catch((   peek_char(In, #)              % Deal with #! script
 2282          ->  skip(In, 10)
 2283          ;   true
 2284          ), E,
 2285          ( close_include(In, []), throw(E))),
 2286    asserta(xref_input(Path, In), Ref).
 2287
 2288include_encoding(wchar_t, []) :- !.
 2289include_encoding(Enc, [encoding(Enc)]).
 2290
 2291
 2292close_include(In, Refs) :-
 2293    maplist(erase, Refs),
 2294    close(In, [force(true)]),
 2295    '$pop_input_context'.
 process_foreign(+Spec, +Src)
Process a load_foreign_library/1 call.
 2301process_foreign(Spec, Src) :-
 2302    ground(Spec),
 2303    current_foreign_library(Spec, Defined),
 2304    !,
 2305    (   xmodule(Module, Src)
 2306    ->  true
 2307    ;   Module = user
 2308    ),
 2309    process_foreign_defined(Defined, Module, Src).
 2310process_foreign(_, _).
 2311
 2312process_foreign_defined([], _, _).
 2313process_foreign_defined([H|T], M, Src) :-
 2314    (   H = M:Head
 2315    ->  assert_foreign(Src, Head)
 2316    ;   assert_foreign(Src, H)
 2317    ),
 2318    process_foreign_defined(T, M, Src).
 2319
 2320
 2321                 /*******************************
 2322                 *          CHR SUPPORT         *
 2323                 *******************************/
 2324
 2325/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 2326This part of the file supports CHR. Our choice is between making special
 2327hooks to make CHR expansion work and  then handle the (complex) expanded
 2328code or process the  CHR  source   directly.  The  latter looks simpler,
 2329though I don't like the idea  of   adding  support for libraries to this
 2330module.  A  file  is  supposed  to  be  a    CHR   file  if  it  uses  a
 2331use_module(library(chr) or contains a :-   constraint/1 directive. As an
 2332extra bonus we get the source-locations right :-)
 2333- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 2334
 2335process_chr(@(_Name, Rule), Src) :-
 2336    mode(chr, Src),
 2337    process_chr(Rule, Src).
 2338process_chr(pragma(Rule, _Pragma), Src) :-
 2339    mode(chr, Src),
 2340    process_chr(Rule, Src).
 2341process_chr(<=>(Head, Body), Src) :-
 2342    mode(chr, Src),
 2343    chr_head(Head, Src, H),
 2344    chr_body(Body, H, Src).
 2345process_chr(==>(Head, Body), Src) :-
 2346    mode(chr, Src),
 2347    chr_head(Head, H, Src),
 2348    chr_body(Body, H, Src).
 2349process_chr((:- chr_constraint(_)), Src) :-
 2350    (   mode(chr, Src)
 2351    ->  true
 2352    ;   assert(mode(chr, Src))
 2353    ).
 2354
 2355chr_head(X, _, _) :-
 2356    var(X),
 2357    !.                      % Illegal.  Warn?
 2358chr_head(\(A,B), Src, H) :-
 2359    chr_head(A, Src, H),
 2360    process_body(B, H, Src).
 2361chr_head((H0,B), Src, H) :-
 2362    chr_defined(H0, Src, H),
 2363    process_body(B, H, Src).
 2364chr_head(H0, Src, H) :-
 2365    chr_defined(H0, Src, H).
 2366
 2367chr_defined(X, _, _) :-
 2368    var(X),
 2369    !.
 2370chr_defined(#(C,_Id), Src, C) :-
 2371    !,
 2372    assert_constraint(Src, C).
 2373chr_defined(A, Src, A) :-
 2374    assert_constraint(Src, A).
 2375
 2376chr_body(X, From, Src) :-
 2377    var(X),
 2378    !,
 2379    process_body(X, From, Src).
 2380chr_body('|'(Guard, Goals), H, Src) :-
 2381    !,
 2382    chr_body(Guard, H, Src),
 2383    chr_body(Goals, H, Src).
 2384chr_body(G, From, Src) :-
 2385    process_body(G, From, Src).
 2386
 2387assert_constraint(_, Head) :-
 2388    var(Head),
 2389    !.
 2390assert_constraint(Src, Head) :-
 2391    constraint(Head, Src, _),
 2392    !.
 2393assert_constraint(Src, Head) :-
 2394    generalise_term(Head, Term),
 2395    current_source_line(Line),
 2396    assert(constraint(Term, Src, Line)).
 2397
 2398
 2399                /********************************
 2400                *       PHASE 1 ASSERTIONS      *
 2401                ********************************/
 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.
 2408assert_called(_, _, Var, _) :-
 2409    var(Var),
 2410    !.
 2411assert_called(Src, From, Goal, Line) :-
 2412    var(From),
 2413    !,
 2414    assert_called(Src, '<unknown>', Goal, Line).
 2415assert_called(_, _, Goal, _) :-
 2416    expand_hide_called(Goal),
 2417    !.
 2418assert_called(Src, Origin, M:G, Line) :-
 2419    !,
 2420    (   atom(M),
 2421        callable(G)
 2422    ->  current_condition(Cond),
 2423        (   xmodule(M, Src)         % explicit call to own module
 2424        ->  assert_called(Src, Origin, G, Line)
 2425        ;   called(M:G, Src, Origin, Cond, Line) % already registered
 2426        ->  true
 2427        ;   hide_called(M:G, Src)           % not interesting (now)
 2428        ->  true
 2429        ;   generalise(Origin, OTerm),
 2430            generalise(G, GTerm)
 2431        ->  assert(called(M:GTerm, Src, OTerm, Cond, Line))
 2432        ;   true
 2433        )
 2434    ;   true                        % call to variable module
 2435    ).
 2436assert_called(Src, _, Goal, _) :-
 2437    (   xmodule(M, Src)
 2438    ->  M \== system
 2439    ;   M = user
 2440    ),
 2441    hide_called(M:Goal, Src),
 2442    !.
 2443assert_called(Src, Origin, Goal, Line) :-
 2444    current_condition(Cond),
 2445    (   called(Goal, Src, Origin, Cond, Line)
 2446    ->  true
 2447    ;   generalise(Origin, OTerm),
 2448        generalise(Goal, Term)
 2449    ->  assert(called(Term, Src, OTerm, Cond, Line))
 2450    ;   true
 2451    ).
 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.
 2459expand_hide_called(pce_principal:send_implementation(_, _, _)).
 2460expand_hide_called(pce_principal:get_implementation(_, _, _, _)).
 2461expand_hide_called(pce_principal:pce_lazy_get_method(_,_,_)).
 2462expand_hide_called(pce_principal:pce_lazy_send_method(_,_,_)).
 2463
 2464assert_defined(Src, Goal) :-
 2465    defined(Goal, Src, _),
 2466    !.
 2467assert_defined(Src, Goal) :-
 2468    generalise(Goal, Term),
 2469    current_source_line(Line),
 2470    assert(defined(Term, Src, Line)).
 2471
 2472assert_foreign(Src, Goal) :-
 2473    foreign(Goal, Src, _),
 2474    !.
 2475assert_foreign(Src, Goal) :-
 2476    generalise(Goal, Term),
 2477    current_source_line(Line),
 2478    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.
 2490assert_import(_, [], _, _, _) :- !.
 2491assert_import(Src, [H|T], Export, From, Reexport) :-
 2492    !,
 2493    assert_import(Src, H, Export, From, Reexport),
 2494    assert_import(Src, T, Export, From, Reexport).
 2495assert_import(Src, except(Except), Export, From, Reexport) :-
 2496    !,
 2497    is_list(Export),
 2498    !,
 2499    except(Except, Export, Import),
 2500    assert_import(Src, Import, _All, From, Reexport).
 2501assert_import(Src, Import as Name, Export, From, Reexport) :-
 2502    !,
 2503    pi_to_head(Import, Term0),
 2504    rename_goal(Term0, Name, Term),
 2505    (   in_export_list(Term0, Export)
 2506    ->  assert(imported(Term, Src, From)),
 2507        assert_reexport(Reexport, Src, Term)
 2508    ;   current_source_line(Line),
 2509        assert_called(Src, '<directive>'(Line), Term0, Line)
 2510    ).
 2511assert_import(Src, Import, Export, From, Reexport) :-
 2512    pi_to_head(Import, Term),
 2513    !,
 2514    (   in_export_list(Term, Export)
 2515    ->  assert(imported(Term, Src, From)),
 2516        assert_reexport(Reexport, Src, Term)
 2517    ;   current_source_line(Line),
 2518        assert_called(Src, '<directive>'(Line), Term, Line)
 2519    ).
 2520assert_import(Src, op(P,T,N), _, _, _) :-
 2521    xref_push_op(Src, P,T,N).
 2522
 2523in_export_list(_Head, Export) :-
 2524    var(Export),
 2525    !.
 2526in_export_list(Head, Export) :-
 2527    member(PI, Export),
 2528    pi_to_head(PI, Head).
 2529
 2530assert_reexport(false, _, _) :- !.
 2531assert_reexport(true, Src, Term) :-
 2532    assert(exported(Term, Src)).
 process_import(:Import, +Src)
Process an import/1 directive
 2538process_import(M:PI, Src) :-
 2539    pi_to_head(PI, Head),
 2540    !,
 2541    (   atom(M),
 2542        current_module(M),
 2543        module_property(M, file(From))
 2544    ->  true
 2545    ;   From = '<unknown>'
 2546    ),
 2547    assert(imported(Head, Src, From)).
 2548process_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?
 2557assert_xmodule_callable([], _, _, _).
 2558assert_xmodule_callable([PI|T], M, Src, From) :-
 2559    (   pi_to_head(M:PI, Head)
 2560    ->  assert(imported(Head, Src, From))
 2561    ;   true
 2562    ),
 2563    assert_xmodule_callable(T, M, Src, From).
 assert_op(+Src, +Op) is det
Arguments:
Op- Ground term op(Priority, Type, Name).
 2570assert_op(Src, op(P,T,M:N)) :-
 2571    (   '$current_source_module'(M)
 2572    ->  Name = N
 2573    ;   Name = M:N
 2574    ),
 2575    (   xop(Src, op(P,T,Name))
 2576    ->  true
 2577    ;   assert(xop(Src, op(P,T,Name)))
 2578    ).
 assert_module(+Src, +Module)
Assert we are loading code into Module. This is also used to exploit local term-expansion and other rules.
 2585assert_module(Src, Module) :-
 2586    xmodule(Module, Src),
 2587    !.
 2588assert_module(Src, Module) :-
 2589    '$set_source_module'(Module),
 2590    assert(xmodule(Module, Src)),
 2591    (   module_property(Module, class(system))
 2592    ->  retractall(xoption(Src, register_called(_))),
 2593        assert(xoption(Src, register_called(all)))
 2594    ;   true
 2595    ).
 2596
 2597assert_module_export(_, []) :- !.
 2598assert_module_export(Src, [H|T]) :-
 2599    !,
 2600    assert_module_export(Src, H),
 2601    assert_module_export(Src, T).
 2602assert_module_export(Src, PI) :-
 2603    pi_to_head(PI, Term),
 2604    !,
 2605    assert(exported(Term, Src)).
 2606assert_module_export(Src, op(P, A, N)) :-
 2607    xref_push_op(Src, P, A, N).
 assert_module3(+Import, +Src)
Handle 3th argument of module/3 declaration.
 2613assert_module3([], _) :- !.
 2614assert_module3([H|T], Src) :-
 2615    !,
 2616    assert_module3(H, Src),
 2617    assert_module3(T, Src).
 2618assert_module3(Option, Src) :-
 2619    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.
 2628process_predicates(Closure, Preds, Src) :-
 2629    is_list(Preds),
 2630    !,
 2631    process_predicate_list(Preds, Closure, Src).
 2632process_predicates(Closure, as(Preds, _Options), Src) :-
 2633    !,
 2634    process_predicates(Closure, Preds, Src).
 2635process_predicates(Closure, Preds, Src) :-
 2636    process_predicate_comma(Preds, Closure, Src).
 2637
 2638process_predicate_list([], _, _).
 2639process_predicate_list([H|T], Closure, Src) :-
 2640    (   nonvar(H)
 2641    ->  call(Closure, H, Src)
 2642    ;   true
 2643    ),
 2644    process_predicate_list(T, Closure, Src).
 2645
 2646process_predicate_comma(Var, _, _) :-
 2647    var(Var),
 2648    !.
 2649process_predicate_comma(M:(A,B), Closure, Src) :-
 2650    !,
 2651    process_predicate_comma(M:A, Closure, Src),
 2652    process_predicate_comma(M:B, Closure, Src).
 2653process_predicate_comma((A,B), Closure, Src) :-
 2654    !,
 2655    process_predicate_comma(A, Closure, Src),
 2656    process_predicate_comma(B, Closure, Src).
 2657process_predicate_comma(as(Spec, _Options), Closure, Src) :-
 2658    !,
 2659    process_predicate_comma(Spec, Closure, Src).
 2660process_predicate_comma(A, Closure, Src) :-
 2661    call(Closure, A, Src).
 2662
 2663
 2664assert_dynamic(PI, Src) :-
 2665    pi_to_head(PI, Term),
 2666    (   thread_local(Term, Src, _)  % dynamic after thread_local has
 2667    ->  true                        % no effect
 2668    ;   current_source_line(Line),
 2669        assert(dynamic(Term, Src, Line))
 2670    ).
 2671
 2672assert_thread_local(PI, Src) :-
 2673    pi_to_head(PI, Term),
 2674    current_source_line(Line),
 2675    assert(thread_local(Term, Src, Line)).
 2676
 2677assert_multifile(PI, Src) :-                    % :- multifile(Spec)
 2678    pi_to_head(PI, Term),
 2679    current_source_line(Line),
 2680    assert(multifile(Term, Src, Line)).
 2681
 2682assert_public(PI, Src) :-                       % :- public(Spec)
 2683    pi_to_head(PI, Term),
 2684    current_source_line(Line),
 2685    assert_called(Src, '<public>'(Line), Term, Line),
 2686    assert(public(Term, Src, Line)).
 2687
 2688assert_export(PI, Src) :-                       % :- export(Spec)
 2689    pi_to_head(PI, Term),
 2690    !,
 2691    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.
 2698pi_to_head(Var, _) :-
 2699    var(Var), !, fail.
 2700pi_to_head(M:PI, M:Term) :-
 2701    !,
 2702    pi_to_head(PI, Term).
 2703pi_to_head(Name/Arity, Term) :-
 2704    functor(Term, Name, Arity).
 2705pi_to_head(Name//DCGArity, Term) :-
 2706    Arity is DCGArity+2,
 2707    functor(Term, Name, Arity).
 2708
 2709
 2710assert_used_class(Src, Name) :-
 2711    used_class(Name, Src),
 2712    !.
 2713assert_used_class(Src, Name) :-
 2714    assert(used_class(Name, Src)).
 2715
 2716assert_defined_class(Src, Name, _Meta, _Super, _) :-
 2717    defined_class(Name, _, _, Src, _),
 2718    !.
 2719assert_defined_class(_, _, _, -, _) :- !.               % :- pce_extend_class
 2720assert_defined_class(Src, Name, Meta, Super, Summary) :-
 2721    current_source_line(Line),
 2722    (   Summary == @(default)
 2723    ->  Atom = ''
 2724    ;   is_list(Summary)
 2725    ->  atom_codes(Atom, Summary)
 2726    ;   string(Summary)
 2727    ->  atom_concat(Summary, '', Atom)
 2728    ),
 2729    assert(defined_class(Name, Super, Atom, Src, Line)),
 2730    (   Meta = @(_)
 2731    ->  true
 2732    ;   assert_used_class(Src, Meta)
 2733    ),
 2734    assert_used_class(Src, Super).
 2735
 2736assert_defined_class(Src, Name, imported_from(_File)) :-
 2737    defined_class(Name, _, _, Src, _),
 2738    !.
 2739assert_defined_class(Src, Name, imported_from(File)) :-
 2740    assert(defined_class(Name, _, '', Src, file(File))).
 2741
 2742
 2743                /********************************
 2744                *            UTILITIES          *
 2745                ********************************/
 generalise(+Callable, -General)
Generalise a callable term.
 2751generalise(Var, Var) :-
 2752    var(Var),
 2753    !.                    % error?
 2754generalise(pce_principal:send_implementation(Id, _, _),
 2755           pce_principal:send_implementation(Id, _, _)) :-
 2756    atom(Id),
 2757    !.
 2758generalise(pce_principal:get_implementation(Id, _, _, _),
 2759           pce_principal:get_implementation(Id, _, _, _)) :-
 2760    atom(Id),
 2761    !.
 2762generalise('<directive>'(Line), '<directive>'(Line)) :- !.
 2763generalise(Module:Goal0, Module:Goal) :-
 2764    atom(Module),
 2765    !,
 2766    generalise(Goal0, Goal).
 2767generalise(Term0, Term) :-
 2768    callable(Term0),
 2769    generalise_term(Term0, Term).
 2770
 2771
 2772                 /*******************************
 2773                 *      SOURCE MANAGEMENT       *
 2774                 *******************************/
 2775
 2776/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 2777This section of the file contains   hookable  predicates to reason about
 2778sources. The built-in code here  can  only   deal  with  files. The XPCE
 2779library(pce_prolog_xref) provides hooks to deal with XPCE objects, so we
 2780can do cross-referencing on PceEmacs edit   buffers.  Other examples for
 2781hooking can be databases, (HTTP) URIs, etc.
 2782- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 2783
 2784:- multifile
 2785    prolog:xref_source_directory/2, % +Source, -Dir
 2786    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.
 2794xref_source_file(Plain, File, Source) :-
 2795    xref_source_file(Plain, File, Source, []).
 2796
 2797xref_source_file(QSpec, File, Source, Options) :-
 2798    nonvar(QSpec), QSpec = _:Spec,
 2799    !,
 2800    must_be(acyclic, Spec),
 2801    xref_source_file(Spec, File, Source, Options).
 2802xref_source_file(Spec, File, Source, Options) :-
 2803    nonvar(Spec),
 2804    prolog:xref_source_file(Spec, File,
 2805                            [ relative_to(Source)
 2806                            | Options
 2807                            ]),
 2808    !.
 2809xref_source_file(Plain, File, Source, Options) :-
 2810    atom(Plain),
 2811    \+ is_absolute_file_name(Plain),
 2812    (   prolog:xref_source_directory(Source, Dir)
 2813    ->  true
 2814    ;   atom(Source),
 2815        file_directory_name(Source, Dir)
 2816    ),
 2817    atomic_list_concat([Dir, /, Plain], Spec0),
 2818    absolute_file_name(Spec0, Spec),
 2819    do_xref_source_file(Spec, File, Options),
 2820    !.
 2821xref_source_file(Spec, File, Source, Options) :-
 2822    do_xref_source_file(Spec, File,
 2823                        [ relative_to(Source)
 2824                        | Options
 2825                        ]),
 2826    !.
 2827xref_source_file(_, _, _, Options) :-
 2828    option(silent(true), Options),
 2829    !,
 2830    fail.
 2831xref_source_file(Spec, _, Src, _Options) :-
 2832    verbose(Src),
 2833    print_message(warning, error(existence_error(file, Spec), _)),
 2834    fail.
 2835
 2836do_xref_source_file(Spec, File, Options) :-
 2837    nonvar(Spec),
 2838    option(file_type(Type), Options, prolog),
 2839    absolute_file_name(Spec, File,
 2840                       [ file_type(Type),
 2841                         access(read),
 2842                         file_errors(fail)
 2843                       ]),
 2844    !.
 canonical_source(?Source, ?Src) is det
Src is the canonical version of Source if Source is given.
 2850canonical_source(Source, Src) :-
 2851    (   ground(Source)
 2852    ->  prolog_canonical_source(Source, Src)
 2853    ;   Source = Src
 2854    ).
 goal_name_arity(+Goal, -Name, -Arity)
Generalized version of functor/3 that can deal with name() goals.
 2861goal_name_arity(Goal, Name, Arity) :-
 2862    (   compound(Goal)
 2863    ->  compound_name_arity(Goal, Name, Arity)
 2864    ;   atom(Goal)
 2865    ->  Name = Goal, Arity = 0
 2866    ).
 2867
 2868generalise_term(Specific, General) :-
 2869    (   compound(Specific)
 2870    ->  compound_name_arity(Specific, Name, Arity),
 2871        compound_name_arity(General, Name, Arity)
 2872    ;   General = Specific
 2873    ).
 2874
 2875functor_name(Term, Name) :-
 2876    (   compound(Term)
 2877    ->  compound_name_arity(Term, Name, _)
 2878    ;   atom(Term)
 2879    ->  Name = Term
 2880    ).
 2881
 2882rename_goal(Goal0, Name, Goal) :-
 2883    (   compound(Goal0)
 2884    ->  compound_name_arity(Goal0, _, Arity),
 2885        compound_name_arity(Goal, Name, Arity)
 2886    ;   Goal = Name
 2887    )