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-2022, University of Amsterdam
    7                              VU University Amsterdam
    8                              CWI, Amsterdam
    9                              SWI-Prolog Solutions b.v.
   10    All rights reserved.
   11
   12    Redistribution and use in source and binary forms, with or without
   13    modification, are permitted provided that the following conditions
   14    are met:
   15
   16    1. Redistributions of source code must retain the above copyright
   17       notice, this list of conditions and the following disclaimer.
   18
   19    2. Redistributions in binary form must reproduce the above copyright
   20       notice, this list of conditions and the following disclaimer in
   21       the documentation and/or other materials provided with the
   22       distribution.
   23
   24    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   25    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   26    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   27    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   28    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   29    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   30    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   31    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   32    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   34    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   35    POSSIBILITY OF SUCH DAMAGE.
   36*/
   37
   38:- module(prolog_xref,
   39          [ xref_source/1,              % +Source
   40            xref_source/2,              % +Source, +Options
   41            xref_called/3,              % ?Source, ?Callable, ?By
   42            xref_called/4,              % ?Source, ?Callable, ?By, ?Cond
   43            xref_called/5,              % ?Source, ?Callable, ?By, ?Cond, ?Line
   44            xref_defined/3,             % ?Source. ?Callable, -How
   45            xref_definition_line/2,     % +How, -Line
   46            xref_exported/2,            % ?Source, ?Callable
   47            xref_module/2,              % ?Source, ?Module
   48            xref_uses_file/3,           % ?Source, ?Spec, ?Path
   49            xref_op/2,                  % ?Source, ?Op
   50            xref_prolog_flag/4,         % ?Source, ?Flag, ?Value, ?Line
   51            xref_comment/3,             % ?Source, ?Title, ?Comment
   52            xref_comment/4,             % ?Source, ?Head, ?Summary, ?Comment
   53            xref_mode/3,                % ?Source, ?Mode, ?Det
   54            xref_option/2,              % ?Source, ?Option
   55            xref_clean/1,               % +Source
   56            xref_current_source/1,      % ?Source
   57            xref_done/2,                % +Source, -When
   58            xref_built_in/1,            % ?Callable
   59            xref_source_file/3,         % +Spec, -Path, +Source
   60            xref_source_file/4,         % +Spec, -Path, +Source, +Options
   61            xref_public_list/3,         % +File, +Src, +Options
   62            xref_public_list/4,         % +File, -Path, -Export, +Src
   63            xref_public_list/6,         % +File, -Path, -Module, -Export, -Meta, +Src
   64            xref_public_list/7,         % +File, -Path, -Module, -Export, -Public, -Meta, +Src
   65            xref_meta/3,                % +Source, +Goal, -Called
   66            xref_meta/2,                % +Goal, -Called
   67            xref_hook/1,                % ?Callable
   68                                        % XPCE class references
   69            xref_used_class/2,          % ?Source, ?ClassName
   70            xref_defined_class/3        % ?Source, ?ClassName, -How
   71          ]).   72:- autoload(library(apply),[maplist/2,partition/4,maplist/3]).   73:- autoload(library(debug),[debug/3]).   74:- autoload(library(dialect),[expects_dialect/1]).   75:- autoload(library(error),[must_be/2,instantiation_error/1]).   76:- autoload(library(lists),[member/2,append/2,append/3,select/3]).   77:- autoload(library(modules),[in_temporary_module/3]).   78:- autoload(library(operators),[push_op/3]).   79:- autoload(library(option),[option/2,option/3]).   80:- autoload(library(ordsets),[ord_intersect/2,ord_intersection/3]).   81:- autoload(library(prolog_code), [pi_head/2]).   82:- autoload(library(prolog_source),
   83	    [ prolog_canonical_source/2,
   84	      prolog_open_source/2,
   85	      prolog_close_source/1,
   86	      prolog_read_source_term/4
   87	    ]).   88
   89:- if(exists_source(library(shlib))).   90:- autoload(library(shlib),[current_foreign_library/2]).   91:- endif.   92:- autoload(library(solution_sequences),[distinct/2,limit/2]).   93
   94:- if(exists_source(library(pldoc))).   95:- use_module(library(pldoc), []).      % Must be loaded before doc_process
   96:- use_module(library(pldoc/doc_process)).   97
   98:- endif.   99
  100:- predicate_options(xref_source/2, 2,
  101                     [ silent(boolean),
  102                       module(atom),
  103                       register_called(oneof([all,non_iso,non_built_in])),
  104                       comments(oneof([store,collect,ignore])),
  105                       process_include(boolean)
  106                     ]).  107
  108
  109:- dynamic
  110    called/5,                       % Head, Src, From, Cond, Line
  111    (dynamic)/3,                    % Head, Src, Line
  112    (thread_local)/3,               % Head, Src, Line
  113    (multifile)/3,                  % Head, Src, Line
  114    (public)/3,                     % Head, Src, Line
  115    defined/3,                      % Head, Src, Line
  116    meta_goal/3,                    % Head, Called, Src
  117    foreign/3,                      % Head, Src, Line
  118    constraint/3,                   % Head, Src, Line
  119    imported/3,                     % Head, Src, From
  120    exported/2,                     % Head, Src
  121    xmodule/2,                      % Module, Src
  122    uses_file/3,                    % Spec, Src, Path
  123    xop/2,                          % Src, Op
  124    source/2,                       % Src, Time
  125    used_class/2,                   % Name, Src
  126    defined_class/5,                % Name, Super, Summary, Src, Line
  127    (mode)/2,                       % Mode, Src
  128    xoption/2,                      % Src, Option
  129    xflag/4,                        % Name, Value, Src, Line
  130
  131    module_comment/3,               % Src, Title, Comment
  132    pred_comment/4,                 % Head, Src, Summary, Comment
  133    pred_comment_link/3,            % Head, Src, HeadTo
  134    pred_mode/3.                    % Head, Src, Det
  135
  136:- 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.
  173:- predicate_options(xref_source_file/4, 4,
  174                     [ file_type(oneof([txt,prolog,directory])),
  175                       silent(boolean)
  176                     ]).  177:- predicate_options(xref_public_list/3, 3,
  178                     [ path(-atom),
  179                       module(-atom),
  180                       exports(-list(any)),
  181                       public(-list(any)),
  182                       meta(-list(any)),
  183                       silent(boolean)
  184                     ]).  185
  186
  187                 /*******************************
  188                 *            HOOKS             *
  189                 *******************************/
 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).
  216:- multifile
  217    prolog:called_by/4,             % +Goal, +Module, +Context, -Called
  218    prolog:called_by/2,             % +Goal, -Called
  219    prolog:meta_goal/2,             % +Goal, -Pattern
  220    prolog:hook/1,                  % +Callable
  221    prolog:generated_predicate/1,   % :PI
  222    prolog:no_autoload_module/1.    % Module is not suitable for autoloading.
  223
  224:- meta_predicate
  225    prolog:generated_predicate(:).  226
  227:- dynamic
  228    meta_goal/2.  229
  230:- meta_predicate
  231    process_predicates(2, +, +).  232
  233                 /*******************************
  234                 *           BUILT-INS          *
  235                 *******************************/
 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.
  243hide_called(Callable, Src) :-
  244    xoption(Src, register_called(Which)),
  245    !,
  246    mode_hide_called(Which, Callable).
  247hide_called(Callable, _) :-
  248    mode_hide_called(non_built_in, Callable).
  249
  250mode_hide_called(all, _) :- !, fail.
  251mode_hide_called(non_iso, _:Goal) :-
  252    goal_name_arity(Goal, Name, Arity),
  253    current_predicate(system:Name/Arity),
  254    predicate_property(system:Goal, iso).
  255mode_hide_called(non_built_in, _:Goal) :-
  256    goal_name_arity(Goal, Name, Arity),
  257    current_predicate(system:Name/Arity),
  258    predicate_property(system:Goal, built_in).
  259mode_hide_called(non_built_in, M:Goal) :-
  260    goal_name_arity(Goal, Name, Arity),
  261    current_predicate(M:Name/Arity),
  262    predicate_property(M:Goal, built_in).
 built_in_predicate(+Callable)
True if Callable is a built-in
  268system_predicate(Goal) :-
  269    goal_name_arity(Goal, Name, Arity),
  270    current_predicate(system:Name/Arity),   % avoid autoloading
  271    predicate_property(system:Goal, built_in),
  272    !.
  273
  274
  275                /********************************
  276                *            TOPLEVEL           *
  277                ********************************/
  278
  279verbose(Src) :-
  280    \+ xoption(Src, silent(true)).
  281
  282:- thread_local
  283    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
  311xref_source(Source) :-
  312    xref_source(Source, []).
  313
  314xref_source(Source, Options) :-
  315    prolog_canonical_source(Source, Src),
  316    (   last_modified(Source, Modified)
  317    ->  (   source(Src, Modified)
  318        ->  true
  319        ;   xref_clean(Src),
  320            assert(source(Src, Modified)),
  321            do_xref(Src, Options)
  322        )
  323    ;   xref_clean(Src),
  324        get_time(Now),
  325        assert(source(Src, Now)),
  326        do_xref(Src, Options)
  327    ).
  328
  329do_xref(Src, Options) :-
  330    must_be(list, Options),
  331    setup_call_cleanup(
  332        xref_setup(Src, In, Options, State),
  333        collect(Src, Src, In, Options),
  334        xref_cleanup(State)).
  335
  336last_modified(Source, Modified) :-
  337    prolog:xref_source_time(Source, Modified),
  338    !.
  339last_modified(Source, Modified) :-
  340    atom(Source),
  341    \+ is_global_url(Source),
  342    exists_file(Source),
  343    time_file(Source, Modified).
  344
  345is_global_url(File) :-
  346    sub_atom(File, B, _, _, '://'),
  347    !,
  348    B > 1,
  349    sub_atom(File, 0, B, _, Scheme),
  350    atom_codes(Scheme, Codes),
  351    maplist(between(0'a, 0'z), Codes).
  352
  353xref_setup(Src, In, Options, state(In, Dialect, Xref, [SRef|HRefs])) :-
  354    maplist(assert_option(Src), Options),
  355    assert_default_options(Src),
  356    current_prolog_flag(emulated_dialect, Dialect),
  357    prolog_open_source(Src, In),
  358    set_initial_mode(In, Options),
  359    asserta(xref_input(Src, In), SRef),
  360    set_xref(Xref),
  361    (   verbose(Src)
  362    ->  HRefs = []
  363    ;   asserta((user:thread_message_hook(_,Level,_) :-
  364                     hide_message(Level)),
  365                Ref),
  366        HRefs = [Ref]
  367    ).
  368
  369hide_message(warning).
  370hide_message(error).
  371hide_message(informational).
  372
  373assert_option(_, Var) :-
  374    var(Var),
  375    !,
  376    instantiation_error(Var).
  377assert_option(Src, silent(Boolean)) :-
  378    !,
  379    must_be(boolean, Boolean),
  380    assert(xoption(Src, silent(Boolean))).
  381assert_option(Src, register_called(Which)) :-
  382    !,
  383    must_be(oneof([all,non_iso,non_built_in]), Which),
  384    assert(xoption(Src, register_called(Which))).
  385assert_option(Src, comments(CommentHandling)) :-
  386    !,
  387    must_be(oneof([store,collect,ignore]), CommentHandling),
  388    assert(xoption(Src, comments(CommentHandling))).
  389assert_option(Src, module(Module)) :-
  390    !,
  391    must_be(atom, Module),
  392    assert(xoption(Src, module(Module))).
  393assert_option(Src, process_include(Boolean)) :-
  394    !,
  395    must_be(boolean, Boolean),
  396    assert(xoption(Src, process_include(Boolean))).
  397
  398assert_default_options(Src) :-
  399    (   xref_option_default(Opt),
  400        generalise_term(Opt, Gen),
  401        (   xoption(Src, Gen)
  402        ->  true
  403        ;   assertz(xoption(Src, Opt))
  404        ),
  405        fail
  406    ;   true
  407    ).
  408
  409xref_option_default(silent(false)).
  410xref_option_default(register_called(non_built_in)).
  411xref_option_default(comments(collect)).
  412xref_option_default(process_include(true)).
 xref_cleanup(+State) is det
Restore processing state according to the saved State.
  418xref_cleanup(state(In, Dialect, Xref, Refs)) :-
  419    prolog_close_source(In),
  420    set_prolog_flag(emulated_dialect, Dialect),
  421    set_prolog_flag(xref, Xref),
  422    maplist(erase, Refs).
  423
  424set_xref(Xref) :-
  425    current_prolog_flag(xref, Xref),
  426    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.
  435set_initial_mode(_Stream, Options) :-
  436    option(module(Module), Options),
  437    !,
  438    '$set_source_module'(Module).
  439set_initial_mode(Stream, _) :-
  440    stream_property(Stream, file_name(Path)),
  441    source_file_property(Path, load_context(M, _, Opts)),
  442    !,
  443    '$set_source_module'(M),
  444    (   option(dialect(Dialect), Opts)
  445    ->  expects_dialect(Dialect)
  446    ;   true
  447    ).
  448set_initial_mode(_, _) :-
  449    '$set_source_module'(user).
 xref_input_stream(-Stream) is det
Current input stream for cross-referencer.
  455xref_input_stream(Stream) :-
  456    xref_input(_, Var),
  457    !,
  458    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.
  465xref_push_op(Src, P, T, N0) :-
  466    '$current_source_module'(M0),
  467    strip_module(M0:N0, M, N),
  468    (   is_list(N),
  469        N \== []
  470    ->  maplist(push_op(Src, P, T, M), N)
  471    ;   push_op(Src, P, T, M, N)
  472    ).
  473
  474push_op(Src, P, T, M0, N0) :-
  475    strip_module(M0:N0, M, N),
  476    Name = M:N,
  477    valid_op(op(P,T,Name)),
  478    push_op(P, T, Name),
  479    assert_op(Src, op(P,T,Name)),
  480    debug(xref(op), ':- ~w.', [op(P,T,Name)]).
  481
  482valid_op(op(P,T,M:N)) :-
  483    atom(M),
  484    valid_op_name(N),
  485    integer(P),
  486    between(0, 1200, P),
  487    atom(T),
  488    op_type(T).
  489
  490valid_op_name(N) :-
  491    atom(N),
  492    !.
  493valid_op_name(N) :-
  494    N == [].
  495
  496op_type(xf).
  497op_type(yf).
  498op_type(fx).
  499op_type(fy).
  500op_type(xfx).
  501op_type(xfy).
  502op_type(yfx).
 xref_set_prolog_flag(+Flag, +Value, +Src, +Line)
Called when a directive sets a Prolog flag.
  508xref_set_prolog_flag(Flag, Value, Src, Line) :-
  509    atom(Flag),
  510    !,
  511    assertz(xflag(Flag, Value, Src, Line)).
  512xref_set_prolog_flag(_, _, _, _).
 xref_clean(+Source) is det
Reset the database for the given source.
  518xref_clean(Source) :-
  519    prolog_canonical_source(Source, Src),
  520    retractall(called(_, Src, _Origin, _Cond, _Line)),
  521    retractall(dynamic(_, Src, Line)),
  522    retractall(multifile(_, Src, Line)),
  523    retractall(public(_, Src, Line)),
  524    retractall(defined(_, Src, Line)),
  525    retractall(meta_goal(_, _, Src)),
  526    retractall(foreign(_, Src, Line)),
  527    retractall(constraint(_, Src, Line)),
  528    retractall(imported(_, Src, _From)),
  529    retractall(exported(_, Src)),
  530    retractall(uses_file(_, Src, _)),
  531    retractall(xmodule(_, Src)),
  532    retractall(xop(Src, _)),
  533    retractall(xoption(Src, _)),
  534    retractall(xflag(_Name, _Value, Src, Line)),
  535    retractall(source(Src, _)),
  536    retractall(used_class(_, Src)),
  537    retractall(defined_class(_, _, _, Src, _)),
  538    retractall(mode(_, Src)),
  539    retractall(module_comment(Src, _, _)),
  540    retractall(pred_comment(_, Src, _, _)),
  541    retractall(pred_comment_link(_, Src, _)),
  542    retractall(pred_mode(_, Src, _)).
  543
  544
  545                 /*******************************
  546                 *          READ RESULTS        *
  547                 *******************************/
 xref_current_source(?Source)
Check what sources have been analysed.
  553xref_current_source(Source) :-
  554    source(Source, _Time).
 xref_done(+Source, -Time) is det
Cross-reference executed at Time
  561xref_done(Source, Time) :-
  562    prolog_canonical_source(Source, Src),
  563    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.
  585xref_called(Source, Called, By) :-
  586    xref_called(Source, Called, By, _).
  587
  588xref_called(Source, Called, By, Cond) :-
  589    canonical_source(Source, Src),
  590    distinct(Called-By, called(Called, Src, By, Cond, _)).
  591
  592xref_called(Source, Called, By, Cond, Line) :-
  593    canonical_source(Source, Src),
  594    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.
  615xref_defined(Source, Called, How) :-
  616    nonvar(Source),
  617    !,
  618    canonical_source(Source, Src),
  619    xref_defined2(How, Src, Called).
  620xref_defined(Source, Called, How) :-
  621    xref_defined2(How, Src, Called),
  622    canonical_source(Source, Src).
  623
  624xref_defined2(dynamic(Line), Src, Called) :-
  625    dynamic(Called, Src, Line).
  626xref_defined2(thread_local(Line), Src, Called) :-
  627    thread_local(Called, Src, Line).
  628xref_defined2(multifile(Line), Src, Called) :-
  629    multifile(Called, Src, Line).
  630xref_defined2(public(Line), Src, Called) :-
  631    public(Called, Src, Line).
  632xref_defined2(local(Line), Src, Called) :-
  633    defined(Called, Src, Line).
  634xref_defined2(foreign(Line), Src, Called) :-
  635    foreign(Called, Src, Line).
  636xref_defined2(constraint(Line), Src, Called) :-
  637    constraint(Called, Src, Line).
  638xref_defined2(imported(From), Src, Called) :-
  639    imported(Called, Src, From).
 xref_definition_line(+How, -Line)
If the 3th argument of xref_defined contains line info, return this in Line.
  647xref_definition_line(local(Line),        Line).
  648xref_definition_line(dynamic(Line),      Line).
  649xref_definition_line(thread_local(Line), Line).
  650xref_definition_line(multifile(Line),    Line).
  651xref_definition_line(public(Line),       Line).
  652xref_definition_line(constraint(Line),   Line).
  653xref_definition_line(foreign(Line),      Line).
 xref_exported(?Source, ?Head) is nondet
True when Source exports Head.
  660xref_exported(Source, Called) :-
  661    prolog_canonical_source(Source, Src),
  662    exported(Called, Src).
 xref_module(?Source, ?Module) is nondet
True if Module is defined in Source.
  668xref_module(Source, Module) :-
  669    nonvar(Source),
  670    !,
  671    prolog_canonical_source(Source, Src),
  672    xmodule(Module, Src).
  673xref_module(Source, Module) :-
  674    xmodule(Module, Src),
  675    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>.
  685xref_uses_file(Source, Spec, Path) :-
  686    prolog_canonical_source(Source, Src),
  687    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)
  697xref_op(Source, Op) :-
  698    prolog_canonical_source(Source, Src),
  699    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.
  707xref_prolog_flag(Source, Flag, Value, Line) :-
  708    prolog_canonical_source(Source, Src),
  709    xflag(Flag, Value, Src, Line).
  710
  711xref_built_in(Head) :-
  712    system_predicate(Head).
  713
  714xref_used_class(Source, Class) :-
  715    prolog_canonical_source(Source, Src),
  716    used_class(Class, Src).
  717
  718xref_defined_class(Source, Class, local(Line, Super, Summary)) :-
  719    prolog_canonical_source(Source, Src),
  720    defined_class(Class, Super, Summary, Src, Line),
  721    integer(Line),
  722    !.
  723xref_defined_class(Source, Class, file(File)) :-
  724    prolog_canonical_source(Source, Src),
  725    defined_class(Class, _, _, Src, file(File)).
  726
  727:- thread_local
  728    current_cond/1,
  729    source_line/1,
  730    current_test_unit/2.  731
  732current_source_line(Line) :-
  733    source_line(Var),
  734    !,
  735    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.
  743collect(Src, File, In, Options) :-
  744    (   Src == File
  745    ->  SrcSpec = Line
  746    ;   SrcSpec = (File:Line)
  747    ),
  748    option(comments(CommentHandling), Options, collect),
  749    (   CommentHandling == ignore
  750    ->  CommentOptions = [],
  751        Comments = []
  752    ;   CommentHandling == store
  753    ->  CommentOptions = [ process_comment(true) ],
  754        Comments = []
  755    ;   CommentOptions = [ comments(Comments) ]
  756    ),
  757    repeat,
  758        catch(prolog_read_source_term(
  759                  In, Term, Expanded,
  760                  [ term_position(TermPos)
  761                  | CommentOptions
  762                  ]),
  763              E, report_syntax_error(E, Src, [])),
  764        update_condition(Term),
  765        stream_position_data(line_count, TermPos, Line),
  766        setup_call_cleanup(
  767            asserta(source_line(SrcSpec), Ref),
  768            catch(process(Expanded, Comments, Term, TermPos, Src, EOF),
  769                  E, print_message(error, E)),
  770            erase(Ref)),
  771        EOF == true,
  772    !.
  773
  774report_syntax_error(E, _, _) :-
  775    fatal_error(E),
  776    throw(E).
  777report_syntax_error(_, _, Options) :-
  778    option(silent(true), Options),
  779    !,
  780    fail.
  781report_syntax_error(E, Src, _Options) :-
  782    (   verbose(Src)
  783    ->  print_message(error, E)
  784    ;   true
  785    ),
  786    fail.
  787
  788fatal_error(time_limit_exceeded).
  789fatal_error(error(resource_error(_),_)).
 update_condition(+Term) is det
Update the condition under which the current code is compiled.
  795update_condition((:-Directive)) :-
  796    !,
  797    update_cond(Directive).
  798update_condition(_).
  799
  800update_cond(if(Cond)) :-
  801    !,
  802    asserta(current_cond(Cond)).
  803update_cond(else) :-
  804    retract(current_cond(C0)),
  805    !,
  806    assert(current_cond(\+C0)).
  807update_cond(elif(Cond)) :-
  808    retract(current_cond(C0)),
  809    !,
  810    assert(current_cond((\+C0,Cond))).
  811update_cond(endif) :-
  812    retract(current_cond(_)),
  813    !.
  814update_cond(_).
 current_condition(-Condition) is det
Condition is the current compilation condition as defined by the :- if/1 directive and friends.
  821current_condition(Condition) :-
  822    \+ current_cond(_),
  823    !,
  824    Condition = true.
  825current_condition(Condition) :-
  826    findall(C, current_cond(C), List),
  827    list_to_conj(List, Condition).
  828
  829list_to_conj([], true).
  830list_to_conj([C], C) :- !.
  831list_to_conj([H|T], (H,C)) :-
  832    list_to_conj(T, C).
  833
  834
  835                 /*******************************
  836                 *           PROCESS            *
  837                 *******************************/
 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.
  849process(Expanded, Comments, Term0, TermPos, Src, EOF) :-
  850    is_list(Expanded),                          % term_expansion into list.
  851    !,
  852    (   member(Term, Expanded),
  853        process(Term, Term0, Src),
  854        Term == end_of_file
  855    ->  EOF = true
  856    ;   EOF = false
  857    ),
  858    xref_comments(Comments, TermPos, Src).
  859process(end_of_file, _, _, _, _, true) :-
  860    !.
  861process(Term, Comments, Term0, TermPos, Src, false) :-
  862    process(Term, Term0, Src),
  863    xref_comments(Comments, TermPos, Src).
 process(+Term, +Term0, +Src) is det
  867process(_, Term0, _) :-
  868    ignore_raw_term(Term0),
  869    !.
  870process(Term, _Term0, Src) :-
  871    process(Term, Src).
  872
  873ignore_raw_term((:- predicate_options(_,_,_))).
 process(+Term, +Src) is det
  877process(Var, _) :-
  878    var(Var),
  879    !.                    % Warn?
  880process(end_of_file, _) :- !.
  881process((:- Directive), Src) :-
  882    !,
  883    process_directive(Directive, Src),
  884    !.
  885process((?- Directive), Src) :-
  886    !,
  887    process_directive(Directive, Src),
  888    !.
  889process((Head :- Body), Src) :-
  890    !,
  891    assert_defined(Src, Head),
  892    process_body(Body, Head, Src).
  893process((Left => Body), Src) :-
  894    !,
  895    (   nonvar(Left),
  896        Left = (Head, Guard)
  897    ->  assert_defined(Src, Head),
  898        process_body(Guard, Head, Src),
  899        process_body(Body, Head, Src)
  900    ;   assert_defined(Src, Left),
  901        process_body(Body, Left, Src)
  902    ).
  903process(?=>(Head, Body), Src) :-
  904    !,
  905    assert_defined(Src, Head),
  906    process_body(Body, Head, Src).
  907process('$source_location'(_File, _Line):Clause, Src) :-
  908    !,
  909    process(Clause, Src).
  910process(Term, Src) :-
  911    process_chr(Term, Src),
  912    !.
  913process(M:(Head :- Body), Src) :-
  914    !,
  915    process((M:Head :- M:Body), Src).
  916process(Head, Src) :-
  917    assert_defined(Src, Head).
  918
  919
  920                 /*******************************
  921                 *            COMMENTS          *
  922                 *******************************/
 xref_comments(+Comments, +FilePos, +Src) is det
  926xref_comments([], _Pos, _Src).
  927:- if(current_predicate(parse_comment/3)).  928xref_comments([Pos-Comment|T], TermPos, Src) :-
  929    (   Pos @> TermPos              % comments inside term
  930    ->  true
  931    ;   stream_position_data(line_count, Pos, Line),
  932        FilePos = Src:Line,
  933        (   parse_comment(Comment, FilePos, Parsed)
  934        ->  assert_comments(Parsed, Src)
  935        ;   true
  936        ),
  937        xref_comments(T, TermPos, Src)
  938    ).
  939
  940assert_comments([], _).
  941assert_comments([H|T], Src) :-
  942    assert_comment(H, Src),
  943    assert_comments(T, Src).
  944
  945assert_comment(section(_Id, Title, Comment), Src) :-
  946    assertz(module_comment(Src, Title, Comment)).
  947assert_comment(predicate(PI, Summary, Comment), Src) :-
  948    pi_to_head(PI, Src, Head),
  949    assertz(pred_comment(Head, Src, Summary, Comment)).
  950assert_comment(link(PI, PITo), Src) :-
  951    pi_to_head(PI, Src, Head),
  952    pi_to_head(PITo, Src, HeadTo),
  953    assertz(pred_comment_link(Head, Src, HeadTo)).
  954assert_comment(mode(Head, Det), Src) :-
  955    assertz(pred_mode(Head, Src, Det)).
  956
  957pi_to_head(PI, Src, Head) :-
  958    pi_to_head(PI, Head0),
  959    (   Head0 = _:_
  960    ->  strip_module(Head0, M, Plain),
  961        (   xmodule(M, Src)
  962        ->  Head = Plain
  963        ;   Head = M:Plain
  964        )
  965    ;   Head = Head0
  966    ).
  967:- endif.
 xref_comment(?Source, ?Title, ?Comment) is nondet
Is true when Source has a section comment with Title and Comment
  973xref_comment(Source, Title, Comment) :-
  974    canonical_source(Source, Src),
  975    module_comment(Src, Title, Comment).
 xref_comment(?Source, ?Head, ?Summary, ?Comment) is nondet
Is true when Head in Source has the given PlDoc comment.
  981xref_comment(Source, Head, Summary, Comment) :-
  982    canonical_source(Source, Src),
  983    (   pred_comment(Head, Src, Summary, Comment)
  984    ;   pred_comment_link(Head, Src, HeadTo),
  985        pred_comment(HeadTo, Src, Summary, Comment)
  986    ).
 xref_mode(?Source, ?Mode, ?Det) is nondet
Is true when Source provides a predicate with Mode and determinism.
  993xref_mode(Source, Mode, Det) :-
  994    canonical_source(Source, Src),
  995    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.
 1002xref_option(Source, Option) :-
 1003    canonical_source(Source, Src),
 1004    xoption(Src, Option).
 1005
 1006
 1007                 /********************************
 1008                 *           DIRECTIVES         *
 1009                 ********************************/
 1010
 1011process_directive(Var, _) :-
 1012    var(Var),
 1013    !.                    % error, but that isn't our business
 1014process_directive(Dir, _Src) :-
 1015    debug(xref(directive), 'Processing :- ~q', [Dir]),
 1016    fail.
 1017process_directive((A,B), Src) :-       % TBD: what about other control
 1018    !,
 1019    process_directive(A, Src),      % structures?
 1020    process_directive(B, Src).
 1021process_directive(List, Src) :-
 1022    is_list(List),
 1023    !,
 1024    process_directive(consult(List), Src).
 1025process_directive(use_module(File, Import), Src) :-
 1026    process_use_module2(File, Import, Src, false).
 1027process_directive(autoload(File, Import), Src) :-
 1028    process_use_module2(File, Import, Src, false).
 1029process_directive(require(Import), Src) :-
 1030    process_requires(Import, Src).
 1031process_directive(expects_dialect(Dialect), Src) :-
 1032    process_directive(use_module(library(dialect/Dialect)), Src),
 1033    expects_dialect(Dialect).
 1034process_directive(reexport(File, Import), Src) :-
 1035    process_use_module2(File, Import, Src, true).
 1036process_directive(reexport(Modules), Src) :-
 1037    process_use_module(Modules, Src, true).
 1038process_directive(autoload(Modules), Src) :-
 1039    process_use_module(Modules, Src, false).
 1040process_directive(use_module(Modules), Src) :-
 1041    process_use_module(Modules, Src, false).
 1042process_directive(consult(Modules), Src) :-
 1043    process_use_module(Modules, Src, false).
 1044process_directive(ensure_loaded(Modules), Src) :-
 1045    process_use_module(Modules, Src, false).
 1046process_directive(load_files(Files, _Options), Src) :-
 1047    process_use_module(Files, Src, false).
 1048process_directive(include(Files), Src) :-
 1049    process_include(Files, Src).
 1050process_directive(dynamic(Dynamic), Src) :-
 1051    process_predicates(assert_dynamic, Dynamic, Src).
 1052process_directive(dynamic(Dynamic, _Options), Src) :-
 1053    process_predicates(assert_dynamic, Dynamic, Src).
 1054process_directive(thread_local(Dynamic), Src) :-
 1055    process_predicates(assert_thread_local, Dynamic, Src).
 1056process_directive(multifile(Dynamic), Src) :-
 1057    process_predicates(assert_multifile, Dynamic, Src).
 1058process_directive(public(Public), Src) :-
 1059    process_predicates(assert_public, Public, Src).
 1060process_directive(export(Export), Src) :-
 1061    process_predicates(assert_export, Export, Src).
 1062process_directive(import(Import), Src) :-
 1063    process_import(Import, Src).
 1064process_directive(module(Module, Export), Src) :-
 1065    assert_module(Src, Module),
 1066    assert_module_export(Src, Export).
 1067process_directive(module(Module, Export, Import), Src) :-
 1068    assert_module(Src, Module),
 1069    assert_module_export(Src, Export),
 1070    assert_module3(Import, Src).
 1071process_directive(begin_tests(Unit, _Options), Src) :-
 1072    enter_test_unit(Unit, Src).
 1073process_directive(begin_tests(Unit), Src) :-
 1074    enter_test_unit(Unit, Src).
 1075process_directive(end_tests(Unit), Src) :-
 1076    leave_test_unit(Unit, Src).
 1077process_directive('$set_source_module'(system), Src) :-
 1078    assert_module(Src, system).     % hack for handling boot/init.pl
 1079process_directive(pce_begin_class_definition(Name, Meta, Super, Doc), Src) :-
 1080    assert_defined_class(Src, Name, Meta, Super, Doc).
 1081process_directive(pce_autoload(Name, From), Src) :-
 1082    assert_defined_class(Src, Name, imported_from(From)).
 1083
 1084process_directive(op(P, A, N), Src) :-
 1085    xref_push_op(Src, P, A, N).
 1086process_directive(set_prolog_flag(Flag, Value), Src) :-
 1087    (   Flag == character_escapes
 1088    ->  set_prolog_flag(character_escapes, Value)
 1089    ;   true
 1090    ),
 1091    current_source_line(Line),
 1092    xref_set_prolog_flag(Flag, Value, Src, Line).
 1093process_directive(style_check(X), _) :-
 1094    style_check(X).
 1095process_directive(encoding(Enc), _) :-
 1096    (   xref_input_stream(Stream)
 1097    ->  catch(set_stream(Stream, encoding(Enc)), _, true)
 1098    ;   true                        % can this happen?
 1099    ).
 1100process_directive(pce_expansion:push_compile_operators, _) :-
 1101    '$current_source_module'(SM),
 1102    call(pce_expansion:push_compile_operators(SM)). % call to avoid xref
 1103process_directive(pce_expansion:pop_compile_operators, _) :-
 1104    call(pce_expansion:pop_compile_operators).
 1105process_directive(meta_predicate(Meta), Src) :-
 1106    process_meta_predicate(Meta, Src).
 1107process_directive(arithmetic_function(FSpec), Src) :-
 1108    arith_callable(FSpec, Goal),
 1109    !,
 1110    current_source_line(Line),
 1111    assert_called(Src, '<directive>'(Line), Goal, Line).
 1112process_directive(format_predicate(_, Goal), Src) :-
 1113    !,
 1114    current_source_line(Line),
 1115    assert_called(Src, '<directive>'(Line), Goal, Line).
 1116process_directive(if(Cond), Src) :-
 1117    !,
 1118    current_source_line(Line),
 1119    assert_called(Src, '<directive>'(Line), Cond, Line).
 1120process_directive(elif(Cond), Src) :-
 1121    !,
 1122    current_source_line(Line),
 1123    assert_called(Src, '<directive>'(Line), Cond, Line).
 1124process_directive(else, _) :- !.
 1125process_directive(endif, _) :- !.
 1126process_directive(Goal, Src) :-
 1127    current_source_line(Line),
 1128    process_body(Goal, '<directive>'(Line), Src).
 process_meta_predicate(+Decl, +Src)
Create meta_goal/3 facts from the meta-goal declaration.
 1134process_meta_predicate((A,B), Src) :-
 1135    !,
 1136    process_meta_predicate(A, Src),
 1137    process_meta_predicate(B, Src).
 1138process_meta_predicate(Decl, Src) :-
 1139    process_meta_head(Src, Decl).
 1140
 1141process_meta_head(Src, Decl) :-         % swapped arguments for maplist
 1142    compound(Decl),
 1143    compound_name_arity(Decl, Name, Arity),
 1144    compound_name_arity(Head, Name, Arity),
 1145    meta_args(1, Arity, Decl, Head, Meta),
 1146    (   (   prolog:meta_goal(Head, _)
 1147        ;   prolog:called_by(Head, _, _, _)
 1148        ;   prolog:called_by(Head, _)
 1149        ;   meta_goal(Head, _)
 1150        )
 1151    ->  true
 1152    ;   assert(meta_goal(Head, Meta, Src))
 1153    ).
 1154
 1155meta_args(I, Arity, _, _, []) :-
 1156    I > Arity,
 1157    !.
 1158meta_args(I, Arity, Decl, Head, [H|T]) :-               % 0
 1159    arg(I, Decl, 0),
 1160    !,
 1161    arg(I, Head, H),
 1162    I2 is I + 1,
 1163    meta_args(I2, Arity, Decl, Head, T).
 1164meta_args(I, Arity, Decl, Head, [H|T]) :-               % ^
 1165    arg(I, Decl, ^),
 1166    !,
 1167    arg(I, Head, EH),
 1168    setof_goal(EH, H),
 1169    I2 is I + 1,
 1170    meta_args(I2, Arity, Decl, Head, T).
 1171meta_args(I, Arity, Decl, Head, [//(H)|T]) :-
 1172    arg(I, Decl, //),
 1173    !,
 1174    arg(I, Head, H),
 1175    I2 is I + 1,
 1176    meta_args(I2, Arity, Decl, Head, T).
 1177meta_args(I, Arity, Decl, Head, [H+A|T]) :-             % I --> H+I
 1178    arg(I, Decl, A),
 1179    integer(A), A > 0,
 1180    !,
 1181    arg(I, Head, H),
 1182    I2 is I + 1,
 1183    meta_args(I2, Arity, Decl, Head, T).
 1184meta_args(I, Arity, Decl, Head, Meta) :-
 1185    I2 is I + 1,
 1186    meta_args(I2, Arity, Decl, Head, Meta).
 1187
 1188
 1189              /********************************
 1190              *             BODY              *
 1191              ********************************/
 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).
 1200xref_meta(Source, Head, Called) :-
 1201    canonical_source(Source, Src),
 1202    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.
 1217xref_meta_src(Head, Called, Src) :-
 1218    meta_goal(Head, Called, Src),
 1219    !.
 1220xref_meta_src(Head, Called, _) :-
 1221    xref_meta(Head, Called),
 1222    !.
 1223xref_meta_src(Head, Called, _) :-
 1224    compound(Head),
 1225    compound_name_arity(Head, Name, Arity),
 1226    apply_pred(Name),
 1227    Arity > 5,
 1228    !,
 1229    Extra is Arity - 1,
 1230    arg(1, Head, G),
 1231    Called = [G+Extra].
 1232xref_meta_src(Head, Called, _) :-
 1233    predicate_property('$xref_tmp':Head, meta_predicate(Meta)),
 1234    !,
 1235    Meta =.. [_|Args],
 1236    meta_args(Args, 1, Head, Called).
 1237
 1238meta_args([], _, _, []).
 1239meta_args([H0|T0], I, Head, [H|T]) :-
 1240    xargs(H0, N),
 1241    !,
 1242    arg(I, Head, A),
 1243    (   N == 0
 1244    ->  H = A
 1245    ;   H = (A+N)
 1246    ),
 1247    I2 is I+1,
 1248    meta_args(T0, I2, Head, T).
 1249meta_args([_|T0], I, Head, T) :-
 1250    I2 is I+1,
 1251    meta_args(T0, I2, Head, T).
 1252
 1253xargs(N, N) :- integer(N), !.
 1254xargs(//, 2).
 1255xargs(^, 0).
 1256
 1257apply_pred(call).                               % built-in
 1258apply_pred(maplist).                            % library(apply_macros)
 1259
 1260xref_meta((A, B),               [A, B]).
 1261xref_meta((A; B),               [A, B]).
 1262xref_meta((A| B),               [A, B]).
 1263xref_meta((A -> B),             [A, B]).
 1264xref_meta((A *-> B),            [A, B]).
 1265xref_meta(findall(_V,G,_L),     [G]).
 1266xref_meta(findall(_V,G,_L,_T),  [G]).
 1267xref_meta(findnsols(_N,_V,G,_L),    [G]).
 1268xref_meta(findnsols(_N,_V,G,_L,_T), [G]).
 1269xref_meta(setof(_V, EG, _L),    [G]) :-
 1270    setof_goal(EG, G).
 1271xref_meta(bagof(_V, EG, _L),    [G]) :-
 1272    setof_goal(EG, G).
 1273xref_meta(forall(A, B),         [A, B]).
 1274xref_meta(maplist(G,_),         [G+1]).
 1275xref_meta(maplist(G,_,_),       [G+2]).
 1276xref_meta(maplist(G,_,_,_),     [G+3]).
 1277xref_meta(maplist(G,_,_,_,_),   [G+4]).
 1278xref_meta(map_list_to_pairs(G,_,_), [G+2]).
 1279xref_meta(map_assoc(G, _),      [G+1]).
 1280xref_meta(map_assoc(G, _, _),   [G+2]).
 1281xref_meta(checklist(G, _L),     [G+1]).
 1282xref_meta(sublist(G, _, _),     [G+1]).
 1283xref_meta(include(G, _, _),     [G+1]).
 1284xref_meta(exclude(G, _, _),     [G+1]).
 1285xref_meta(partition(G, _, _, _, _),     [G+2]).
 1286xref_meta(partition(G, _, _, _),[G+1]).
 1287xref_meta(call(G),              [G]).
 1288xref_meta(call(G, _),           [G+1]).
 1289xref_meta(call(G, _, _),        [G+2]).
 1290xref_meta(call(G, _, _, _),     [G+3]).
 1291xref_meta(call(G, _, _, _, _),  [G+4]).
 1292xref_meta(not(G),               [G]).
 1293xref_meta(notrace(G),           [G]).
 1294xref_meta('$notrace'(G),        [G]).
 1295xref_meta(\+(G),                [G]).
 1296xref_meta(ignore(G),            [G]).
 1297xref_meta(once(G),              [G]).
 1298xref_meta(initialization(G),    [G]).
 1299xref_meta(initialization(G,_),  [G]).
 1300xref_meta(retract(Rule),        [G]) :- head_of(Rule, G).
 1301xref_meta(clause(G, _),         [G]).
 1302xref_meta(clause(G, _, _),      [G]).
 1303xref_meta(phrase(G, _A),        [//(G)]).
 1304xref_meta(phrase(G, _A, _R),    [//(G)]).
 1305xref_meta(call_dcg(G, _A, _R),  [//(G)]).
 1306xref_meta(phrase_from_file(G,_),[//(G)]).
 1307xref_meta(catch(A, _, B),       [A, B]).
 1308xref_meta(catch_with_backtrace(A, _, B), [A, B]).
 1309xref_meta(thread_create(A,_,_), [A]).
 1310xref_meta(thread_create(A,_),   [A]).
 1311xref_meta(thread_signal(_,A),   [A]).
 1312xref_meta(thread_idle(A,_),     [A]).
 1313xref_meta(thread_at_exit(A),    [A]).
 1314xref_meta(thread_initialization(A), [A]).
 1315xref_meta(engine_create(_,A,_), [A]).
 1316xref_meta(engine_create(_,A,_,_), [A]).
 1317xref_meta(transaction(A),       [A]).
 1318xref_meta(transaction(A,B,_),   [A,B]).
 1319xref_meta(snapshot(A),          [A]).
 1320xref_meta(predsort(A,_,_),      [A+3]).
 1321xref_meta(call_cleanup(A, B),   [A, B]).
 1322xref_meta(call_cleanup(A, _, B),[A, B]).
 1323xref_meta(setup_call_cleanup(A, B, C),[A, B, C]).
 1324xref_meta(setup_call_catcher_cleanup(A, B, _, C),[A, B, C]).
 1325xref_meta(call_residue_vars(A,_), [A]).
 1326xref_meta(with_mutex(_,A),      [A]).
 1327xref_meta(assume(G),            [G]).   % library(debug)
 1328xref_meta(assertion(G),         [G]).   % library(debug)
 1329xref_meta(freeze(_, G),         [G]).
 1330xref_meta(when(C, A),           [C, A]).
 1331xref_meta(time(G),              [G]).   % development system
 1332xref_meta(call_time(G, _),      [G]).   % development system
 1333xref_meta(call_time(G, _, _),   [G]).   % development system
 1334xref_meta(profile(G),           [G]).
 1335xref_meta(at_halt(G),           [G]).
 1336xref_meta(call_with_time_limit(_, G), [G]).
 1337xref_meta(call_with_depth_limit(G, _, _), [G]).
 1338xref_meta(call_with_inference_limit(G, _, _), [G]).
 1339xref_meta(alarm(_, G, _),       [G]).
 1340xref_meta(alarm(_, G, _, _),    [G]).
 1341xref_meta('$add_directive_wic'(G), [G]).
 1342xref_meta(with_output_to(_, G), [G]).
 1343xref_meta(if(G),                [G]).
 1344xref_meta(elif(G),              [G]).
 1345xref_meta(meta_options(G,_,_),  [G+1]).
 1346xref_meta(on_signal(_,_,H),     [H+1]) :- H \== default.
 1347xref_meta(distinct(G),          [G]).   % library(solution_sequences)
 1348xref_meta(distinct(_, G),       [G]).
 1349xref_meta(order_by(_, G),       [G]).
 1350xref_meta(limit(_, G),          [G]).
 1351xref_meta(offset(_, G),         [G]).
 1352xref_meta(reset(G,_,_),         [G]).
 1353xref_meta(prolog_listen(Ev,G),  [G+N]) :- event_xargs(Ev, N).
 1354xref_meta(prolog_listen(Ev,G,_),[G+N]) :- event_xargs(Ev, N).
 1355xref_meta(tnot(G),		[G]).
 1356xref_meta(not_exists(G),	[G]).
 1357xref_meta(with_tty_raw(G),	[G]).
 1358xref_meta(residual_goals(G),    [G+2]).
 1359
 1360                                        % XPCE meta-predicates
 1361xref_meta(pce_global(_, new(_)), _) :- !, fail.
 1362xref_meta(pce_global(_, B),     [B+1]).
 1363xref_meta(ifmaintainer(G),      [G]).   % used in manual
 1364xref_meta(listen(_, G),         [G]).   % library(broadcast)
 1365xref_meta(listen(_, _, G),      [G]).
 1366xref_meta(in_pce_thread(G),     [G]).
 1367
 1368xref_meta(G, Meta) :-                   % call user extensions
 1369    prolog:meta_goal(G, Meta).
 1370xref_meta(G, Meta) :-                   % Generated from :- meta_predicate
 1371    meta_goal(G, Meta).
 1372
 1373setof_goal(EG, G) :-
 1374    var(EG), !, G = EG.
 1375setof_goal(_^EG, G) :-
 1376    !,
 1377    setof_goal(EG, G).
 1378setof_goal(G, G).
 1379
 1380event_xargs(abort,            0).
 1381event_xargs(erase,            1).
 1382event_xargs(break,            3).
 1383event_xargs(frame_finished,   1).
 1384event_xargs(thread_exit,      1).
 1385event_xargs(this_thread_exit, 0).
 1386event_xargs(PI,               2) :- pi_to_head(PI, _).
 head_of(+Rule, -Head)
Get the head for a retract call.
 1392head_of(Var, _) :-
 1393    var(Var), !, fail.
 1394head_of((Head :- _), Head).
 1395head_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.
 1403xref_hook(Hook) :-
 1404    prolog:hook(Hook).
 1405xref_hook(Hook) :-
 1406    hook(Hook).
 1407
 1408
 1409hook(attr_portray_hook(_,_)).
 1410hook(attr_unify_hook(_,_)).
 1411hook(attribute_goals(_,_,_)).
 1412hook(goal_expansion(_,_)).
 1413hook(term_expansion(_,_)).
 1414hook(resource(_,_,_)).
 1415hook('$pred_option'(_,_,_,_)).
 1416
 1417hook(emacs_prolog_colours:goal_classification(_,_)).
 1418hook(emacs_prolog_colours:term_colours(_,_)).
 1419hook(emacs_prolog_colours:goal_colours(_,_)).
 1420hook(emacs_prolog_colours:style(_,_)).
 1421hook(emacs_prolog_colours:identify(_,_)).
 1422hook(pce_principal:pce_class(_,_,_,_,_,_)).
 1423hook(pce_principal:send_implementation(_,_,_)).
 1424hook(pce_principal:get_implementation(_,_,_,_)).
 1425hook(pce_principal:pce_lazy_get_method(_,_,_)).
 1426hook(pce_principal:pce_lazy_send_method(_,_,_)).
 1427hook(pce_principal:pce_uses_template(_,_)).
 1428hook(prolog:locate_clauses(_,_)).
 1429hook(prolog:message(_,_,_)).
 1430hook(prolog:error_message(_,_,_)).
 1431hook(prolog:message_location(_,_,_)).
 1432hook(prolog:message_context(_,_,_)).
 1433hook(prolog:message_line_element(_,_)).
 1434hook(prolog:debug_control_hook(_)).
 1435hook(prolog:help_hook(_)).
 1436hook(prolog:show_profile_hook(_,_)).
 1437hook(prolog:general_exception(_,_)).
 1438hook(prolog:predicate_summary(_,_)).
 1439hook(prolog:residual_goals(_,_)).
 1440hook(prolog_edit:load).
 1441hook(prolog_edit:locate(_,_,_)).
 1442hook(shlib:unload_all_foreign_libraries).
 1443hook(system:'$foreign_registered'(_, _)).
 1444hook(predicate_options:option_decl(_,_,_)).
 1445hook(user:exception(_,_,_)).
 1446hook(user:file_search_path(_,_)).
 1447hook(user:library_directory(_)).
 1448hook(user:message_hook(_,_,_)).
 1449hook(user:portray(_)).
 1450hook(user:prolog_clause_name(_,_)).
 1451hook(user:prolog_list_goal(_)).
 1452hook(user:prolog_predicate_name(_,_)).
 1453hook(user:prolog_trace_interception(_,_,_,_)).
 1454hook(user:prolog_exception_hook(_,_,_,_)).
 1455hook(sandbox:safe_primitive(_)).
 1456hook(sandbox:safe_meta_predicate(_)).
 1457hook(sandbox:safe_meta(_,_)).
 1458hook(sandbox:safe_global_variable(_)).
 1459hook(sandbox:safe_directive(_)).
 arith_callable(+Spec, -Callable)
Translate argument of arithmetic_function/1 into a callable term
 1466arith_callable(Var, _) :-
 1467    var(Var), !, fail.
 1468arith_callable(Module:Spec, Module:Goal) :-
 1469    !,
 1470    arith_callable(Spec, Goal).
 1471arith_callable(Name/Arity, Goal) :-
 1472    PredArity is Arity + 1,
 1473    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.

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