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
    6    Copyright (c)  1985-2021, 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('$syspreds',
   39          [ leash/1,
   40            visible/1,
   41            style_check/1,
   42            (spy)/1,
   43            (nospy)/1,
   44            nospyall/0,
   45            debugging/0,
   46            flag/3,
   47            atom_prefix/2,
   48            dwim_match/2,
   49            source_file_property/2,
   50            source_file/1,
   51            source_file/2,
   52            unload_file/1,
   53            exists_source/1,                    % +Spec
   54            exists_source/2,                    % +Spec, -Path
   55            use_foreign_library/1,		% :FileSpec
   56            use_foreign_library/2,		% :FileSpec, +Install
   57            prolog_load_context/2,
   58            stream_position_data/3,
   59            current_predicate/2,
   60            '$defined_predicate'/1,
   61            predicate_property/2,
   62            '$predicate_property'/2,
   63            (dynamic)/2,                        % :Predicates, +Options
   64            clause_property/2,
   65            current_module/1,                   % ?Module
   66            module_property/2,                  % ?Module, ?Property
   67            module/1,                           % +Module
   68            current_trie/1,                     % ?Trie
   69            trie_property/2,                    % ?Trie, ?Property
   70            working_directory/2,                % -OldDir, +NewDir
   71            shell/1,                            % +Command
   72            on_signal/3,
   73            current_signal/3,
   74            open_shared_object/2,
   75            open_shared_object/3,
   76            format/1,
   77            garbage_collect/0,
   78            set_prolog_stack/2,
   79            prolog_stack_property/2,
   80            absolute_file_name/2,
   81            tmp_file_stream/3,                  % +Enc, -File, -Stream
   82            call_with_depth_limit/3,            % :Goal, +Limit, -Result
   83            call_with_inference_limit/3,        % :Goal, +Limit, -Result
   84            rule/2,                             % :Head, -Rule
   85            rule/3,                             % :Head, -Rule, ?Ref
   86            numbervars/3,                       % +Term, +Start, -End
   87            term_string/3,                      % ?Term, ?String, +Options
   88            nb_setval/2,                        % +Var, +Value
   89            thread_create/2,                    % :Goal, -Id
   90            thread_join/1,                      % +Id
   91            transaction/1,                      % :Goal
   92            transaction/2,                      % :Goal, +Options
   93            transaction/3,                      % :Goal, :Constraint, +Mutex
   94            snapshot/1,                         % :Goal
   95            undo/1,                             % :Goal
   96            set_prolog_gc_thread/1,		% +Status
   97
   98            '$wrap_predicate'/5                 % :Head, +Name, -Closure, -Wrapped, +Body
   99          ]).  100
  101:- meta_predicate
  102    dynamic(:, +),
  103    use_foreign_library(:),
  104    use_foreign_library(:, +),
  105    transaction(0),
  106    transaction(0,0,+),
  107    snapshot(0),
  108    rule(:, -),
  109    rule(:, -, ?).  110
  111
  112                /********************************
  113                *           DEBUGGER            *
  114                *********************************/
 map_bits(:Pred, +Modify, +OldBits, -NewBits)
  118:- meta_predicate
  119    map_bits(2, +, +, -).  120
  121map_bits(_, Var, _, _) :-
  122    var(Var),
  123    !,
  124    '$instantiation_error'(Var).
  125map_bits(_, [], Bits, Bits) :- !.
  126map_bits(Pred, [H|T], Old, New) :-
  127    map_bits(Pred, H, Old, New0),
  128    map_bits(Pred, T, New0, New).
  129map_bits(Pred, +Name, Old, New) :-     % set a bit
  130    !,
  131    bit(Pred, Name, Bits),
  132    !,
  133    New is Old \/ Bits.
  134map_bits(Pred, -Name, Old, New) :-     % clear a bit
  135    !,
  136    bit(Pred, Name, Bits),
  137    !,
  138    New is Old /\ (\Bits).
  139map_bits(Pred, ?(Name), Old, Old) :-   % ask a bit
  140    !,
  141    bit(Pred, Name, Bits),
  142    Old /\ Bits > 0.
  143map_bits(_, Term, _, _) :-
  144    '$type_error'('+|-|?(Flag)', Term).
  145
  146bit(Pred, Name, Bits) :-
  147    call(Pred, Name, Bits),
  148    !.
  149bit(_:Pred, Name, _) :-
  150    '$domain_error'(Pred, Name).
  151
  152:- public port_name/2.                  % used by library(test_cover)
  153
  154port_name(      call, 2'000000001).
  155port_name(      exit, 2'000000010).
  156port_name(      fail, 2'000000100).
  157port_name(      redo, 2'000001000).
  158port_name(     unify, 2'000010000).
  159port_name(     break, 2'000100000).
  160port_name(  cut_call, 2'001000000).
  161port_name(  cut_exit, 2'010000000).
  162port_name( exception, 2'100000000).
  163port_name(       cut, 2'011000000).
  164port_name(       all, 2'000111111).
  165port_name(      full, 2'000101111).
  166port_name(      half, 2'000101101).     % '
  167
  168leash(Ports) :-
  169    '$leash'(Old, Old),
  170    map_bits(port_name, Ports, Old, New),
  171    '$leash'(_, New).
  172
  173visible(Ports) :-
  174    '$visible'(Old, Old),
  175    map_bits(port_name, Ports, Old, New),
  176    '$visible'(_, New).
  177
  178style_name(atom,            0x0001) :-
  179    print_message(warning, decl_no_effect(style_check(atom))).
  180style_name(singleton,       0x0042).            % semantic and syntactic
  181style_name(discontiguous,   0x0008).
  182style_name(charset,         0x0020).
  183style_name(no_effect,       0x0080).
  184style_name(var_branches,    0x0100).
 style_check(+Spec) is nondet
  188style_check(Var) :-
  189    var(Var),
  190    !,
  191    '$instantiation_error'(Var).
  192style_check(?(Style)) :-
  193    !,
  194    (   var(Style)
  195    ->  enum_style_check(Style)
  196    ;   enum_style_check(Style)
  197    ->  true
  198    ).
  199style_check(Spec) :-
  200    '$style_check'(Old, Old),
  201    map_bits(style_name, Spec, Old, New),
  202    '$style_check'(_, New).
  203
  204enum_style_check(Style) :-
  205    '$style_check'(Bits, Bits),
  206    style_name(Style, Bit),
  207    Bit /\ Bits =\= 0.
 prolog:debug_control_hook(+Action)
Allow user-hooks in the Prolog debugger interaction. See the calls below for the provided hooks. We use a single predicate with action argument to avoid an uncontrolled poliferation of hooks.
  216:- multifile
  217    prolog:debug_control_hook/1.    % +Action
  218
  219:- meta_predicate
  220    spy(:),
  221    nospy(:).
 spy :Spec is det
 nospy :Spec is det
 nospyall is det
Set/clear spy-points. A successfully set or cleared spy-point is reported using print_message/2, level informational, with one of the following terms, where Spec is of the form M:Head.
See also
- spy/1 and nospy/1 call the hook debug_control_hook/1 to allow for alternative specifications of the thing to debug.
  238spy(_:X) :-
  239    var(X),
  240    throw(error(instantiation_error, _)).
  241spy(_:[]) :- !.
  242spy(M:[H|T]) :-
  243    !,
  244    spy(M:H),
  245    spy(M:T).
  246spy(Spec) :-
  247    notrace(prolog:debug_control_hook(spy(Spec))),
  248    !.
  249spy(Spec) :-
  250    '$find_predicate'(Spec, Preds),
  251    '$member'(PI, Preds),
  252        pi_to_head(PI, Head),
  253        '$define_predicate'(Head),
  254        '$spy'(Head),
  255    fail.
  256spy(_).
  257
  258nospy(_:X) :-
  259    var(X),
  260    throw(error(instantiation_error, _)).
  261nospy(_:[]) :- !.
  262nospy(M:[H|T]) :-
  263    !,
  264    nospy(M:H),
  265    nospy(M:T).
  266nospy(Spec) :-
  267    notrace(prolog:debug_control_hook(nospy(Spec))),
  268    !.
  269nospy(Spec) :-
  270    '$find_predicate'(Spec, Preds),
  271    '$member'(PI, Preds),
  272         pi_to_head(PI, Head),
  273        '$nospy'(Head),
  274    fail.
  275nospy(_).
  276
  277nospyall :-
  278    notrace(prolog:debug_control_hook(nospyall)),
  279    fail.
  280nospyall :-
  281    spy_point(Head),
  282        '$nospy'(Head),
  283    fail.
  284nospyall.
  285
  286pi_to_head(M:PI, M:Head) :-
  287    !,
  288    pi_to_head(PI, Head).
  289pi_to_head(Name/Arity, Head) :-
  290    functor(Head, Name, Arity).
 debugging is det
Report current status of the debugger.
  296debugging :-
  297    notrace(prolog:debug_control_hook(debugging)),
  298    !.
  299debugging :-
  300    current_prolog_flag(debug, true),
  301    !,
  302    print_message(informational, debugging(on)),
  303    findall(H, spy_point(H), SpyPoints),
  304    print_message(informational, spying(SpyPoints)).
  305debugging :-
  306    print_message(informational, debugging(off)).
  307
  308spy_point(Module:Head) :-
  309    current_predicate(_, Module:Head),
  310    '$get_predicate_attribute'(Module:Head, spy, 1),
  311    \+ predicate_property(Module:Head, imported_from(_)).
 flag(+Name, -Old, +New) is det
True when Old is the current value associated with the flag Name and New has become the new value.
  318flag(Name, Old, New) :-
  319    Old == New,
  320    !,
  321    get_flag(Name, Old).
  322flag(Name, Old, New) :-
  323    with_mutex('$flag', update_flag(Name, Old, New)).
  324
  325update_flag(Name, Old, New) :-
  326    get_flag(Name, Old),
  327    (   atom(New)
  328    ->  set_flag(Name, New)
  329    ;   Value is New,
  330        set_flag(Name, Value)
  331    ).
  332
  333
  334                /********************************
  335                *             ATOMS             *
  336                *********************************/
  337
  338dwim_match(A1, A2) :-
  339    dwim_match(A1, A2, _).
  340
  341atom_prefix(Atom, Prefix) :-
  342    sub_atom(Atom, 0, _, _, Prefix).
  343
  344
  345                /********************************
  346                *             SOURCE            *
  347                *********************************/
 source_file(-File) is nondet
source_file(+File) is semidet
True if File is loaded into Prolog. If File is unbound it is bound to the canonical name for it. If File is bound it succeeds if the canonical name as defined by absolute_file_name/2 is known as a loaded filename.

Note that Time = 0.0 is used by PlDoc and other code that needs to create a file record without being interested in the time.

  360source_file(File) :-
  361    (   current_prolog_flag(access_level, user)
  362    ->  Level = user
  363    ;   true
  364    ),
  365    (   ground(File)
  366    ->  (   '$time_source_file'(File, Time, Level)
  367        ;   absolute_file_name(File, Abs),
  368            '$time_source_file'(Abs, Time, Level)
  369        ), !
  370    ;   '$time_source_file'(File, Time, Level)
  371    ),
  372    Time > 0.0.
 source_file(+Head, -File) is semidet
source_file(?Head, ?File) is nondet
True when Head is a predicate owned by File.
  379:- meta_predicate source_file(:, ?).  380
  381source_file(M:Head, File) :-
  382    nonvar(M), nonvar(Head),
  383    !,
  384    (   '$c_current_predicate'(_, M:Head),
  385        predicate_property(M:Head, multifile)
  386    ->  multi_source_files(M:Head, Files),
  387        '$member'(File, Files)
  388    ;   '$source_file'(M:Head, File)
  389    ).
  390source_file(M:Head, File) :-
  391    (   nonvar(File)
  392    ->  true
  393    ;   source_file(File)
  394    ),
  395    '$source_file_predicates'(File, Predicates),
  396    '$member'(M:Head, Predicates).
  397
  398:- thread_local found_src_file/1.  399
  400multi_source_files(Head, Files) :-
  401    call_cleanup(
  402        findall(File, multi_source_file(Head, File), Files),
  403        retractall(found_src_file(_))).
  404
  405multi_source_file(Head, File) :-
  406    nth_clause(Head, _, Clause),
  407    clause_property(Clause, source(File)),
  408    \+ found_src_file(File),
  409    asserta(found_src_file(File)).
 source_file_property(?File, ?Property) is nondet
True if Property is a property of the loaded source-file File.
  416source_file_property(File, P) :-
  417    nonvar(File),
  418    !,
  419    canonical_source_file(File, Path),
  420    property_source_file(P, Path).
  421source_file_property(File, P) :-
  422    property_source_file(P, File).
  423
  424property_source_file(modified(Time), File) :-
  425    '$time_source_file'(File, Time, user).
  426property_source_file(source(Source), File) :-
  427    (   '$source_file_property'(File, from_state, true)
  428    ->  Source = state
  429    ;   '$source_file_property'(File, resource, true)
  430    ->  Source = resource
  431    ;   Source = file
  432    ).
  433property_source_file(module(M), File) :-
  434    (   nonvar(M)
  435    ->  '$current_module'(M, File)
  436    ;   nonvar(File)
  437    ->  '$current_module'(ML, File),
  438        (   atom(ML)
  439        ->  M = ML
  440        ;   '$member'(M, ML)
  441        )
  442    ;   '$current_module'(M, File)
  443    ).
  444property_source_file(load_context(Module, Location, Options), File) :-
  445    '$time_source_file'(File, _, user),
  446    clause(system:'$load_context_module'(File, Module, Options), true, Ref),
  447    (   clause_property(Ref, file(FromFile)),
  448        clause_property(Ref, line_count(FromLine))
  449    ->  Location = FromFile:FromLine
  450    ;   Location = user
  451    ).
  452property_source_file(includes(Master, Stamp), File) :-
  453    system:'$included'(File, _Line, Master, Stamp).
  454property_source_file(included_in(Master, Line), File) :-
  455    system:'$included'(Master, Line, File, _).
  456property_source_file(derived_from(DerivedFrom, Stamp), File) :-
  457    system:'$derived_source'(File, DerivedFrom, Stamp).
  458property_source_file(reloading, File) :-
  459    source_file(File),
  460    '$source_file_property'(File, reloading, true).
  461property_source_file(load_count(Count), File) :-
  462    source_file(File),
  463    '$source_file_property'(File, load_count, Count).
  464property_source_file(number_of_clauses(Count), File) :-
  465    source_file(File),
  466    '$source_file_property'(File, number_of_clauses, Count).
 canonical_source_file(+Spec, -File) is semidet
File is the canonical representation of the source-file Spec.
  473canonical_source_file(Spec, File) :-
  474    atom(Spec),
  475    '$time_source_file'(Spec, _, _),
  476    !,
  477    File = Spec.
  478canonical_source_file(Spec, File) :-
  479    system:'$included'(_Master, _Line, Spec, _),
  480    !,
  481    File = Spec.
  482canonical_source_file(Spec, File) :-
  483    absolute_file_name(Spec, File,
  484                       [ file_type(prolog),
  485                         access(read),
  486                         file_errors(fail)
  487                       ]),
  488    source_file(File).
 exists_source(+Source) is semidet
 exists_source(+Source, -Path) is semidet
True if Source (a term valid for load_files/2) exists. Fails without error if this is not the case. The predicate is intended to be used with :- if, as in the example below. See also source_exports/2.
:- if(exists_source(library(error))).
:- use_module_library(error).
:- endif.
  505exists_source(Source) :-
  506    exists_source(Source, _Path).
  507
  508exists_source(Source, Path) :-
  509    absolute_file_name(Source, Path,
  510                       [ file_type(prolog),
  511                         access(read),
  512                         file_errors(fail)
  513                       ]).
 prolog_load_context(+Key, -Value)
Provides context information for term_expansion and directives. Note that only the line-number info is valid for the '$stream_position'. Largely Quintus compatible.
  522prolog_load_context(module, Module) :-
  523    '$current_source_module'(Module).
  524prolog_load_context(file, File) :-
  525    input_file(File).
  526prolog_load_context(source, F) :-       % SICStus compatibility
  527    input_file(F0),
  528    '$input_context'(Context),
  529    '$top_file'(Context, F0, F).
  530prolog_load_context(stream, S) :-
  531    (   system:'$load_input'(_, S0)
  532    ->  S = S0
  533    ).
  534prolog_load_context(directory, D) :-
  535    input_file(F),
  536    file_directory_name(F, D).
  537prolog_load_context(dialect, D) :-
  538    current_prolog_flag(emulated_dialect, D).
  539prolog_load_context(term_position, TermPos) :-
  540    source_location(_, L),
  541    (   nb_current('$term_position', Pos),
  542        compound(Pos),              % actually set
  543        stream_position_data(line_count, Pos, L)
  544    ->  TermPos = Pos
  545    ;   TermPos = '$stream_position'(0,L,0,0)
  546    ).
  547prolog_load_context(script, Bool) :-
  548    (   '$toplevel':loaded_init_file(script, Path),
  549        input_file(File),
  550        same_file(File, Path)
  551    ->  Bool = true
  552    ;   Bool = false
  553    ).
  554prolog_load_context(variable_names, Bindings) :-
  555    nb_current('$variable_names', Bindings).
  556prolog_load_context(term, Term) :-
  557    nb_current('$term', Term).
  558prolog_load_context(reloading, true) :-
  559    prolog_load_context(source, F),
  560    '$source_file_property'(F, reloading, true).
  561
  562input_file(File) :-
  563    (   system:'$load_input'(_, Stream)
  564    ->  stream_property(Stream, file_name(File))
  565    ),
  566    !.
  567input_file(File) :-
  568    source_location(File, _).
 unload_file(+File) is det
Remove all traces of loading file.
  575:- dynamic system:'$resolved_source_path'/2.  576
  577unload_file(File) :-
  578    (   canonical_source_file(File, Path)
  579    ->  '$unload_file'(Path),
  580        retractall(system:'$resolved_source_path'(_, Path))
  581    ;   true
  582    ).
  583
  584		 /*******************************
  585		 *      FOREIGN LIBRARIES	*
  586		 *******************************/
 use_foreign_library(+FileSpec) is det
 use_foreign_library(+FileSpec, +Entry:atom) is det
Load and install a foreign library as load_foreign_library/1,2 and register the installation using initialization/2 with the option now. This is similar to using:
:- initialization(load_foreign_library(foreign(mylib))).

but using the initialization/1 wrapper causes the library to be loaded after loading of the file in which it appears is completed, while use_foreign_library/1 loads the library immediately. I.e. the difference is only relevant if the remainder of the file uses functionality of the C-library.

  605use_foreign_library(FileSpec) :-
  606    ensure_shlib,
  607    initialization(shlib:load_foreign_library(FileSpec), now).
  608
  609use_foreign_library(FileSpec, Entry) :-
  610    ensure_shlib,
  611    initialization(shlib:load_foreign_library(FileSpec, Entry), now).
  612
  613ensure_shlib :-
  614    '$get_predicate_attribute'(shlib:load_foreign_library(_), defined, 1),
  615    '$get_predicate_attribute'(shlib:load_foreign_library(_,_), defined, 1),
  616    !.
  617ensure_shlib :-
  618    use_module(library(shlib), []).
  619
  620
  621                 /*******************************
  622                 *            STREAMS           *
  623                 *******************************/
 stream_position_data(?Field, +Pos, ?Date)
Extract values from stream position objects. '$stream_position' is of the format '$stream_position'(Byte, Char, Line, LinePos)
  630stream_position_data(Prop, Term, Value) :-
  631    nonvar(Prop),
  632    !,
  633    (   stream_position_field(Prop, Pos)
  634    ->  arg(Pos, Term, Value)
  635    ;   throw(error(domain_error(stream_position_data, Prop)))
  636    ).
  637stream_position_data(Prop, Term, Value) :-
  638    stream_position_field(Prop, Pos),
  639    arg(Pos, Term, Value).
  640
  641stream_position_field(char_count,    1).
  642stream_position_field(line_count,    2).
  643stream_position_field(line_position, 3).
  644stream_position_field(byte_count,    4).
  645
  646
  647                 /*******************************
  648                 *            CONTROL           *
  649                 *******************************/
 call_with_depth_limit(:Goal, +DepthLimit, -Result)
Try to proof Goal, but fail on any branch exceeding the indicated depth-limit. Unify Result with the maximum-reached limit on success, depth_limit_exceeded if the limit was exceeded and fails otherwise.
  657:- meta_predicate
  658    call_with_depth_limit(0, +, -).  659
  660call_with_depth_limit(G, Limit, Result) :-
  661    '$depth_limit'(Limit, OLimit, OReached),
  662    (   catch(G, E, '$depth_limit_except'(OLimit, OReached, E)),
  663        '$depth_limit_true'(Limit, OLimit, OReached, Result, Det),
  664        ( Det == ! -> ! ; true )
  665    ;   '$depth_limit_false'(OLimit, OReached, Result)
  666    ).
 call_with_inference_limit(:Goal, +InferenceLimit, -Result)
Equivalent to call(Goal), but poses a limit on the number of inferences. If this limit is reached, Result is unified with inference_limit_exceeded, otherwise Result is unified with ! if Goal succeeded without a choicepoint and true otherwise.

Note that we perform calls in system to avoid auto-importing, which makes raiseInferenceLimitException() fail to recognise that the exception happens in the overhead.

  679:- meta_predicate
  680    call_with_inference_limit(0, +, -).  681
  682call_with_inference_limit(G, Limit, Result) :-
  683    '$inference_limit'(Limit, OLimit),
  684    (   catch(G, Except,
  685              system:'$inference_limit_except'(OLimit, Except, Result0)),
  686        (   Result0 == inference_limit_exceeded
  687        ->  !
  688        ;   system:'$inference_limit_true'(Limit, OLimit, Result0),
  689            ( Result0 == ! -> ! ; true )
  690        ),
  691        Result = Result0
  692    ;   system:'$inference_limit_false'(OLimit)
  693    ).
  694
  695
  696                /********************************
  697                *           DATA BASE           *
  698                *********************************/
  699
  700/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  701The predicate current_predicate/2 is   a  difficult subject since  the
  702introduction  of defaulting     modules   and   dynamic     libraries.
  703current_predicate/2 is normally  called with instantiated arguments to
  704verify some  predicate can   be called without trapping   an undefined
  705predicate.  In this case we must  perform the search algorithm used by
  706the prolog system itself.
  707
  708If the pattern is not fully specified, we only generate the predicates
  709actually available in this  module.   This seems the best for listing,
  710etc.
  711- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  712
  713
  714:- meta_predicate
  715    current_predicate(?, :),
  716    '$defined_predicate'(:).  717
  718current_predicate(Name, Module:Head) :-
  719    (var(Module) ; var(Head)),
  720    !,
  721    generate_current_predicate(Name, Module, Head).
  722current_predicate(Name, Term) :-
  723    '$c_current_predicate'(Name, Term),
  724    '$defined_predicate'(Term),
  725    !.
  726current_predicate(Name, Module:Head) :-
  727    default_module(Module, DefModule),
  728    '$c_current_predicate'(Name, DefModule:Head),
  729    '$defined_predicate'(DefModule:Head),
  730    !.
  731current_predicate(Name, Module:Head) :-
  732    '$autoload':autoload_in(Module, general),
  733    \+ current_prolog_flag(Module:unknown, fail),
  734    (   compound(Head)
  735    ->  compound_name_arity(Head, Name, Arity)
  736    ;   Name = Head, Arity = 0
  737    ),
  738    '$find_library'(Module, Name, Arity, _LoadModule, _Library),
  739    !.
  740
  741generate_current_predicate(Name, Module, Head) :-
  742    current_module(Module),
  743    QHead = Module:Head,
  744    '$c_current_predicate'(Name, QHead),
  745    '$get_predicate_attribute'(QHead, defined, 1).
  746
  747'$defined_predicate'(Head) :-
  748    '$get_predicate_attribute'(Head, defined, 1),
  749    !.
 predicate_property(?Predicate, ?Property) is nondet
True when Property is a property of Predicate.
  755:- meta_predicate
  756    predicate_property(:, ?).  757
  758:- multifile
  759    '$predicate_property'/2.  760
  761:- '$iso'(predicate_property/2).  762
  763predicate_property(Pred, Property) :-           % Mode ?,+
  764    nonvar(Property),
  765    !,
  766    property_predicate(Property, Pred).
  767predicate_property(Pred, Property) :-           % Mode +,-
  768    define_or_generate(Pred),
  769    '$predicate_property'(Property, Pred).
 property_predicate(+Property, ?Pred)
First handle the special cases that are not about querying normally defined predicates: undefined, visible and autoload, followed by the generic case.
  777property_predicate(undefined, Pred) :-
  778    !,
  779    Pred = Module:Head,
  780    current_module(Module),
  781    '$c_current_predicate'(_, Pred),
  782    \+ '$defined_predicate'(Pred),          % Speed up a bit
  783    \+ current_predicate(_, Pred),
  784    goal_name_arity(Head, Name, Arity),
  785    \+ system_undefined(Module:Name/Arity).
  786property_predicate(visible, Pred) :-
  787    !,
  788    visible_predicate(Pred).
  789property_predicate(autoload(File), Head) :-
  790    !,
  791    \+ current_prolog_flag(autoload, false),
  792    '$autoload':autoloadable(Head, File).
  793property_predicate(implementation_module(IM), M:Head) :-
  794    !,
  795    atom(M),
  796    (   default_module(M, DM),
  797        '$get_predicate_attribute'(DM:Head, defined, 1)
  798    ->  (   '$get_predicate_attribute'(DM:Head, imported, ImportM)
  799        ->  IM = ImportM
  800        ;   IM = M
  801        )
  802    ;   \+ current_prolog_flag(M:unknown, fail),
  803        goal_name_arity(Head, Name, Arity),
  804        '$find_library'(_, Name, Arity, LoadModule, _File)
  805    ->  IM = LoadModule
  806    ;   M = IM
  807    ).
  808property_predicate(iso, _:Head) :-
  809    callable(Head),
  810    !,
  811    goal_name_arity(Head, Name, Arity),
  812    current_predicate(system:Name/Arity),
  813    '$predicate_property'(iso, system:Head).
  814property_predicate(built_in, Module:Head) :-
  815    callable(Head),
  816    !,
  817    goal_name_arity(Head, Name, Arity),
  818    current_predicate(Module:Name/Arity),
  819    '$predicate_property'(built_in, Module:Head).
  820property_predicate(Property, Pred) :-
  821    define_or_generate(Pred),
  822    '$predicate_property'(Property, Pred).
  823
  824goal_name_arity(Head, Name, Arity) :-
  825    compound(Head),
  826    !,
  827    compound_name_arity(Head, Name, Arity).
  828goal_name_arity(Head, Head, 0).
 define_or_generate(+Head) is semidet
define_or_generate(-Head) is nondet
If the predicate is known, try to resolve it. Otherwise generate the known predicate, but do not try to (auto)load the predicate.
  837define_or_generate(M:Head) :-
  838    callable(Head),
  839    atom(M),
  840    '$get_predicate_attribute'(M:Head, defined, 1),
  841    !.
  842define_or_generate(M:Head) :-
  843    callable(Head),
  844    nonvar(M), M \== system,
  845    !,
  846    '$define_predicate'(M:Head).
  847define_or_generate(Pred) :-
  848    current_predicate(_, Pred),
  849    '$define_predicate'(Pred).
  850
  851
  852'$predicate_property'(interpreted, Pred) :-
  853    '$get_predicate_attribute'(Pred, foreign, 0).
  854'$predicate_property'(visible, Pred) :-
  855    '$get_predicate_attribute'(Pred, defined, 1).
  856'$predicate_property'(built_in, Pred) :-
  857    '$get_predicate_attribute'(Pred, system, 1).
  858'$predicate_property'(exported, Pred) :-
  859    '$get_predicate_attribute'(Pred, exported, 1).
  860'$predicate_property'(public, Pred) :-
  861    '$get_predicate_attribute'(Pred, public, 1).
  862'$predicate_property'(non_terminal, Pred) :-
  863    '$get_predicate_attribute'(Pred, non_terminal, 1).
  864'$predicate_property'(foreign, Pred) :-
  865    '$get_predicate_attribute'(Pred, foreign, 1).
  866'$predicate_property'((dynamic), Pred) :-
  867    '$get_predicate_attribute'(Pred, (dynamic), 1).
  868'$predicate_property'((static), Pred) :-
  869    '$get_predicate_attribute'(Pred, (dynamic), 0).
  870'$predicate_property'((volatile), Pred) :-
  871    '$get_predicate_attribute'(Pred, (volatile), 1).
  872'$predicate_property'((thread_local), Pred) :-
  873    '$get_predicate_attribute'(Pred, (thread_local), 1).
  874'$predicate_property'((multifile), Pred) :-
  875    '$get_predicate_attribute'(Pred, (multifile), 1).
  876'$predicate_property'(imported_from(Module), Pred) :-
  877    '$get_predicate_attribute'(Pred, imported, Module).
  878'$predicate_property'(transparent, Pred) :-
  879    '$get_predicate_attribute'(Pred, transparent, 1).
  880'$predicate_property'(meta_predicate(Pattern), Pred) :-
  881    '$get_predicate_attribute'(Pred, meta_predicate, Pattern).
  882'$predicate_property'(file(File), Pred) :-
  883    '$get_predicate_attribute'(Pred, file, File).
  884'$predicate_property'(line_count(LineNumber), Pred) :-
  885    '$get_predicate_attribute'(Pred, line_count, LineNumber).
  886'$predicate_property'(notrace, Pred) :-
  887    '$get_predicate_attribute'(Pred, trace, 0).
  888'$predicate_property'(nodebug, Pred) :-
  889    '$get_predicate_attribute'(Pred, hide_childs, 1).
  890'$predicate_property'(spying, Pred) :-
  891    '$get_predicate_attribute'(Pred, spy, 1).
  892'$predicate_property'(number_of_clauses(N), Pred) :-
  893    '$get_predicate_attribute'(Pred, number_of_clauses, N).
  894'$predicate_property'(number_of_rules(N), Pred) :-
  895    '$get_predicate_attribute'(Pred, number_of_rules, N).
  896'$predicate_property'(last_modified_generation(Gen), Pred) :-
  897    '$get_predicate_attribute'(Pred, last_modified_generation, Gen).
  898'$predicate_property'(indexed(Indices), Pred) :-
  899    '$get_predicate_attribute'(Pred, indexed, Indices).
  900'$predicate_property'(noprofile, Pred) :-
  901    '$get_predicate_attribute'(Pred, noprofile, 1).
  902'$predicate_property'(ssu, Pred) :-
  903    '$get_predicate_attribute'(Pred, ssu, 1).
  904'$predicate_property'(iso, Pred) :-
  905    '$get_predicate_attribute'(Pred, iso, 1).
  906'$predicate_property'(det, Pred) :-
  907    '$get_predicate_attribute'(Pred, det, 1).
  908'$predicate_property'(quasi_quotation_syntax, Pred) :-
  909    '$get_predicate_attribute'(Pred, quasi_quotation_syntax, 1).
  910'$predicate_property'(defined, Pred) :-
  911    '$get_predicate_attribute'(Pred, defined, 1).
  912'$predicate_property'(tabled, Pred) :-
  913    '$get_predicate_attribute'(Pred, tabled, 1).
  914'$predicate_property'(tabled(Flag), Pred) :-
  915    '$get_predicate_attribute'(Pred, tabled, 1),
  916    table_flag(Flag, Pred).
  917'$predicate_property'(incremental, Pred) :-
  918    '$get_predicate_attribute'(Pred, incremental, 1).
  919'$predicate_property'(monotonic, Pred) :-
  920    '$get_predicate_attribute'(Pred, monotonic, 1).
  921'$predicate_property'(opaque, Pred) :-
  922    '$get_predicate_attribute'(Pred, opaque, 1).
  923'$predicate_property'(lazy, Pred) :-
  924    '$get_predicate_attribute'(Pred, lazy, 1).
  925'$predicate_property'(abstract(N), Pred) :-
  926    '$get_predicate_attribute'(Pred, abstract, N).
  927'$predicate_property'(size(Bytes), Pred) :-
  928    '$get_predicate_attribute'(Pred, size, Bytes).
  929
  930system_undefined(user:prolog_trace_interception/4).
  931system_undefined(user:prolog_exception_hook/4).
  932system_undefined(system:'$c_call_prolog'/0).
  933system_undefined(system:window_title/2).
  934
  935table_flag(variant, Pred) :-
  936    '$tbl_implementation'(Pred, M:Head),
  937    M:'$tabled'(Head, variant).
  938table_flag(subsumptive, Pred) :-
  939    '$tbl_implementation'(Pred, M:Head),
  940    M:'$tabled'(Head, subsumptive).
  941table_flag(shared, Pred) :-
  942    '$get_predicate_attribute'(Pred, tshared, 1).
  943table_flag(incremental, Pred) :-
  944    '$get_predicate_attribute'(Pred, incremental, 1).
  945table_flag(monotonic, Pred) :-
  946    '$get_predicate_attribute'(Pred, monotonic, 1).
  947table_flag(subgoal_abstract(N), Pred) :-
  948    '$get_predicate_attribute'(Pred, subgoal_abstract, N).
  949table_flag(answer_abstract(N), Pred) :-
  950    '$get_predicate_attribute'(Pred, subgoal_abstract, N).
  951table_flag(subgoal_abstract(N), Pred) :-
  952    '$get_predicate_attribute'(Pred, max_answers, N).
 visible_predicate(:Head) is nondet
True when Head can be called without raising an existence error. This implies it is defined, can be inherited from a default module or can be autoloaded.
  961visible_predicate(Pred) :-
  962    Pred = M:Head,
  963    current_module(M),
  964    (   callable(Head)
  965    ->  (   '$get_predicate_attribute'(Pred, defined, 1)
  966        ->  true
  967        ;   \+ current_prolog_flag(M:unknown, fail),
  968            functor(Head, Name, Arity),
  969            '$find_library'(M, Name, Arity, _LoadModule, _Library)
  970        )
  971    ;   setof(PI, visible_in_module(M, PI), PIs),
  972        '$member'(Name/Arity, PIs),
  973        functor(Head, Name, Arity)
  974    ).
  975
  976visible_in_module(M, Name/Arity) :-
  977    default_module(M, DefM),
  978    DefHead = DefM:Head,
  979    '$c_current_predicate'(_, DefHead),
  980    '$get_predicate_attribute'(DefHead, defined, 1),
  981    \+ hidden_system_predicate(Head),
  982    functor(Head, Name, Arity).
  983visible_in_module(_, Name/Arity) :-
  984    '$in_library'(Name, Arity, _).
  985
  986hidden_system_predicate(Head) :-
  987    functor(Head, Name, _),
  988    atom(Name),                     % Avoid [].
  989    sub_atom(Name, 0, _, _, $),
  990    \+ current_prolog_flag(access_level, system).
 clause_property(+ClauseRef, ?Property) is nondet
Provide information on individual clauses. Defined properties are:
line_count(-Line)
Line from which the clause is loaded.
file(-File)
File from which the clause is loaded.
source(-File)
File that `owns' the clause: reloading this file wipes the clause.
fact
Clause has body true.
erased
Clause was erased.
predicate(:PI)
Predicate indicator of the predicate this clause belongs to. Can be used to find the predicate of erased clauses.
module(-M)
Module context in which the clause was compiled.
 1015clause_property(Clause, Property) :-
 1016    '$clause_property'(Property, Clause).
 1017
 1018'$clause_property'(line_count(LineNumber), Clause) :-
 1019    '$get_clause_attribute'(Clause, line_count, LineNumber).
 1020'$clause_property'(file(File), Clause) :-
 1021    '$get_clause_attribute'(Clause, file, File).
 1022'$clause_property'(source(File), Clause) :-
 1023    '$get_clause_attribute'(Clause, owner, File).
 1024'$clause_property'(size(Bytes), Clause) :-
 1025    '$get_clause_attribute'(Clause, size, Bytes).
 1026'$clause_property'(fact, Clause) :-
 1027    '$get_clause_attribute'(Clause, fact, true).
 1028'$clause_property'(erased, Clause) :-
 1029    '$get_clause_attribute'(Clause, erased, true).
 1030'$clause_property'(predicate(PI), Clause) :-
 1031    '$get_clause_attribute'(Clause, predicate_indicator, PI).
 1032'$clause_property'(module(M), Clause) :-
 1033    '$get_clause_attribute'(Clause, module, M).
 dynamic(:Predicates, +Options) is det
Define a predicate as dynamic with optionally additional properties. Defined options are:
 1047dynamic(M:Predicates, Options) :-
 1048    '$must_be'(list, Predicates),
 1049    options_properties(Options, Props),
 1050    set_pprops(Predicates, M, [dynamic|Props]).
 1051
 1052set_pprops([], _, _).
 1053set_pprops([H|T], M, Props) :-
 1054    set_pprops1(Props, M:H),
 1055    strip_module(M:H, M2, P),
 1056    '$pi_head'(M2:P, Pred),
 1057    '$set_table_wrappers'(Pred),
 1058    set_pprops(T, M, Props).
 1059
 1060set_pprops1([], _).
 1061set_pprops1([H|T], P) :-
 1062    (   atom(H)
 1063    ->  '$set_predicate_attribute'(P, H, true)
 1064    ;   H =.. [Name,Value]
 1065    ->  '$set_predicate_attribute'(P, Name, Value)
 1066    ),
 1067    set_pprops1(T, P).
 1068
 1069options_properties(Options, Props) :-
 1070    G = opt_prop(_,_,_,_),
 1071    findall(G, G, Spec),
 1072    options_properties(Spec, Options, Props).
 1073
 1074options_properties([], _, []).
 1075options_properties([opt_prop(Name, Type, SetValue, Prop)|T],
 1076                   Options, [Prop|PT]) :-
 1077    Opt =.. [Name,V],
 1078    '$option'(Opt, Options),
 1079    '$must_be'(Type, V),
 1080    V = SetValue,
 1081    !,
 1082    options_properties(T, Options, PT).
 1083options_properties([_|T], Options, PT) :-
 1084    options_properties(T, Options, PT).
 1085
 1086opt_prop(incremental,   boolean,               Bool,  incremental(Bool)).
 1087opt_prop(abstract,      between(0,0),          0,     abstract).
 1088opt_prop(multifile,     boolean,               true,  multifile).
 1089opt_prop(discontiguous, boolean,               true,  discontiguous).
 1090opt_prop(volatile,      boolean,               true,  volatile).
 1091opt_prop(thread,        oneof(atom, [local,shared],[local,shared]),
 1092                                               local, thread_local).
 1093
 1094                /********************************
 1095                *            MODULES            *
 1096                *********************************/
 current_module(?Module) is nondet
True if Module is a currently defined module.
 1102current_module(Module) :-
 1103    '$current_module'(Module, _).
 module_property(?Module, ?Property) is nondet
True if Property is a property of Module. Defined properties are:
file(File)
Module is loaded from File.
line_count(Count)
The module declaration is on line Count of File.
exports(ListOfPredicateIndicators)
The module exports ListOfPredicateIndicators
exported_operators(ListOfOp3)
The module exports the operators ListOfOp3.
 1119module_property(Module, Property) :-
 1120    nonvar(Module), nonvar(Property),
 1121    !,
 1122    property_module(Property, Module).
 1123module_property(Module, Property) :-    % -, file(File)
 1124    nonvar(Property), Property = file(File),
 1125    !,
 1126    (   nonvar(File)
 1127    ->  '$current_module'(Modules, File),
 1128        (   atom(Modules)
 1129        ->  Module = Modules
 1130        ;   '$member'(Module, Modules)
 1131        )
 1132    ;   '$current_module'(Module, File),
 1133        File \== []
 1134    ).
 1135module_property(Module, Property) :-
 1136    current_module(Module),
 1137    property_module(Property, Module).
 1138
 1139property_module(Property, Module) :-
 1140    module_property(Property),
 1141    (   Property = exported_operators(List)
 1142    ->  '$exported_ops'(Module, List, [])
 1143    ;   '$module_property'(Module, Property)
 1144    ).
 1145
 1146module_property(class(_)).
 1147module_property(file(_)).
 1148module_property(line_count(_)).
 1149module_property(exports(_)).
 1150module_property(exported_operators(_)).
 1151module_property(size(_)).
 1152module_property(program_size(_)).
 1153module_property(program_space(_)).
 1154module_property(last_modified_generation(_)).
 module(+Module) is det
Set the module that is associated to the toplevel to Module.
 1160module(Module) :-
 1161    atom(Module),
 1162    current_module(Module),
 1163    !,
 1164    '$set_typein_module'(Module).
 1165module(Module) :-
 1166    '$set_typein_module'(Module),
 1167    print_message(warning, no_current_module(Module)).
 working_directory(-Old, +New)
True when Old is the current working directory and the working directory has been updated to New.
 1174working_directory(Old, New) :-
 1175    '$cwd'(Old),
 1176    (   Old == New
 1177    ->  true
 1178    ;   '$chdir'(New)
 1179    ).
 1180
 1181
 1182                 /*******************************
 1183                 *            TRIES             *
 1184                 *******************************/
 current_trie(?Trie) is nondet
True if Trie is the handle of an existing trie.
 1190current_trie(Trie) :-
 1191    current_blob(Trie, trie),
 1192    is_trie(Trie).
 trie_property(?Trie, ?Property)
True when Property is a property of Trie. Defined properties are:
value_count(Count)
Number of terms in the trie.
node_count(Count)
Number of nodes in the trie.
size(Bytes)
Number of bytes needed to store the trie.
hashed(Count)
Number of hashed nodes.
compiled_size(Bytes)
Size of the compiled representation (if the trie is compiled)
lookup_count(Count)
Number of data lookups on the trie
gen_call_count(Count)
Number of trie_gen/2 calls on this trie

Incremental tabling statistics:

invalidated(Count)
Number of times the trie was inivalidated
reevaluated(Count)
Number of times the trie was re-evaluated

Shared tabling statistics:

deadlock(Count)
Number of times the table was involved in a deadlock
wait(Count)
Number of times a thread had to wait for this table
 1228trie_property(Trie, Property) :-
 1229    current_trie(Trie),
 1230    trie_property(Property),
 1231    '$trie_property'(Trie, Property).
 1232
 1233trie_property(node_count(_)).
 1234trie_property(value_count(_)).
 1235trie_property(size(_)).
 1236trie_property(hashed(_)).
 1237trie_property(compiled_size(_)).
 1238                                                % below only when -DO_TRIE_STATS
 1239trie_property(lookup_count(_)).                 % is enabled in pl-trie.h
 1240trie_property(gen_call_count(_)).
 1241trie_property(invalidated(_)).                  % IDG stats
 1242trie_property(reevaluated(_)).
 1243trie_property(deadlock(_)).                     % Shared tabling stats
 1244trie_property(wait(_)).
 1245trie_property(idg_affected_count(_)).
 1246trie_property(idg_dependent_count(_)).
 1247trie_property(idg_size(_)).
 1248
 1249
 1250                /********************************
 1251                *      SYSTEM INTERACTION       *
 1252                *********************************/
 1253
 1254shell(Command) :-
 1255    shell(Command, 0).
 1256
 1257
 1258                 /*******************************
 1259                 *            SIGNALS           *
 1260                 *******************************/
 1261
 1262:- meta_predicate
 1263    on_signal(+, :, :),
 1264    current_signal(?, ?, :).
 on_signal(+Signal, -OldHandler, :NewHandler) is det
 1268on_signal(Signal, Old, New) :-
 1269    atom(Signal),
 1270    !,
 1271    '$on_signal'(_Num, Signal, Old, New).
 1272on_signal(Signal, Old, New) :-
 1273    integer(Signal),
 1274    !,
 1275    '$on_signal'(Signal, _Name, Old, New).
 1276on_signal(Signal, _Old, _New) :-
 1277    '$type_error'(signal_name, Signal).
 current_signal(?Name, ?SignalNumber, :Handler) is nondet
 1281current_signal(Name, Id, Handler) :-
 1282    between(1, 32, Id),
 1283    '$on_signal'(Id, Name, Handler, Handler).
 1284
 1285:- multifile
 1286    prolog:called_by/2. 1287
 1288prolog:called_by(on_signal(_,_,New), [New+1]) :-
 1289    (   new == throw
 1290    ;   new == default
 1291    ), !, fail.
 1292
 1293
 1294                 /*******************************
 1295                 *            DLOPEN            *
 1296                 *******************************/
 open_shared_object(+File, -Handle) is det
 open_shared_object(+File, -Handle, +Flags) is det
Open a shared object or DLL file. Flags is a list of flags. The following flags are recognised. Note however that these flags may have no affect on the target platform.
 1310open_shared_object(File, Handle) :-
 1311    open_shared_object(File, Handle, []). % use pl-load.c defaults
 1312
 1313open_shared_object(File, Handle, Flags) :-
 1314    (   is_list(Flags)
 1315    ->  true
 1316    ;   throw(error(type_error(list, Flags), _))
 1317    ),
 1318    map_dlflags(Flags, Mask),
 1319    '$open_shared_object'(File, Handle, Mask).
 1320
 1321dlopen_flag(now,        2'01).          % see pl-load.c for these constants
 1322dlopen_flag(global,     2'10).          % Solaris only
 1323
 1324map_dlflags([], 0).
 1325map_dlflags([F|T], M) :-
 1326    map_dlflags(T, M0),
 1327    (   dlopen_flag(F, I)
 1328    ->  true
 1329    ;   throw(error(domain_error(dlopen_flag, F), _))
 1330    ),
 1331    M is M0 \/ I.
 1332
 1333
 1334                 /*******************************
 1335                 *             I/O              *
 1336                 *******************************/
 1337
 1338format(Fmt) :-
 1339    format(Fmt, []).
 1340
 1341                 /*******************************
 1342                 *            FILES             *
 1343                 *******************************/
 absolute_file_name(+Term, -AbsoluteFile)
 1347absolute_file_name(Name, Abs) :-
 1348    atomic(Name),
 1349    !,
 1350    '$absolute_file_name'(Name, Abs).
 1351absolute_file_name(Term, Abs) :-
 1352    '$chk_file'(Term, [''], [access(read)], true, File),
 1353    !,
 1354    '$absolute_file_name'(File, Abs).
 1355absolute_file_name(Term, Abs) :-
 1356    '$chk_file'(Term, [''], [], true, File),
 1357    !,
 1358    '$absolute_file_name'(File, Abs).
 tmp_file_stream(-File, -Stream, +Options) is det
tmp_file_stream(+Encoding, -File, -Stream) is det
Create a temporary file and open it atomically. The second mode is for compatibility reasons.
 1366tmp_file_stream(Enc, File, Stream) :-
 1367    atom(Enc), var(File), var(Stream),
 1368    !,
 1369    '$tmp_file_stream'('', Enc, File, Stream).
 1370tmp_file_stream(File, Stream, Options) :-
 1371    current_prolog_flag(encoding, DefEnc),
 1372    '$option'(encoding(Enc), Options, DefEnc),
 1373    '$option'(extension(Ext), Options, ''),
 1374    '$tmp_file_stream'(Ext, Enc, File, Stream),
 1375    set_stream(Stream, file_name(File)).
 1376
 1377
 1378                /********************************
 1379                *        MEMORY MANAGEMENT      *
 1380                *********************************/
 garbage_collect is det
Invoke the garbage collector. The argument of the underlying '$garbage_collect'/1 is the debugging level to use during garbage collection. This only works if the system is compiled with the -DODEBUG cpp flag. Only to simplify maintenance.
 1389garbage_collect :-
 1390    '$garbage_collect'(0).
 set_prolog_stack(+Name, +Option) is det
Set a parameter for one of the Prolog stacks.
 1396set_prolog_stack(Stack, Option) :-
 1397    Option =.. [Name,Value0],
 1398    Value is Value0,
 1399    '$set_prolog_stack'(Stack, Name, _Old, Value).
 prolog_stack_property(?Stack, ?Property) is nondet
Examine stack properties.
 1405prolog_stack_property(Stack, Property) :-
 1406    stack_property(P),
 1407    stack_name(Stack),
 1408    Property =.. [P,Value],
 1409    '$set_prolog_stack'(Stack, P, Value, Value).
 1410
 1411stack_name(local).
 1412stack_name(global).
 1413stack_name(trail).
 1414
 1415stack_property(limit).
 1416stack_property(spare).
 1417stack_property(min_free).
 1418stack_property(low).
 1419stack_property(factor).
 1420
 1421
 1422		 /*******************************
 1423		 *            CLAUSE		*
 1424		 *******************************/
 rule(:Head, -Rule) is nondet
 rule(:Head, -Rule, Ref) is nondet
Similar to clause/2,3. but deals with clauses that do not use :- as neck.
 1432rule(Head, Rule) :-
 1433    '$rule'(Head, Rule0),
 1434    conditional_rule(Rule0, Rule1),
 1435    Rule = Rule1.
 1436rule(Head, Rule, Ref) :-
 1437    '$rule'(Head, Rule0, Ref),
 1438    conditional_rule(Rule0, Rule1),
 1439    Rule = Rule1.
 1440
 1441conditional_rule(?=>(Head, Body0), (Head,Cond=>Body)) :-
 1442    split_on_cut(Body0, Cond, Body),
 1443    !.
 1444conditional_rule(Rule, Rule).
 1445
 1446split_on_cut(Var, _, _) :-
 1447    var(Var),
 1448    !,
 1449    fail.
 1450split_on_cut((Cond,!,Body), Cond, Body) :-
 1451    !.
 1452split_on_cut((A,B), (A,Cond), Body) :-
 1453    split_on_cut(B, Cond, Body).
 1454
 1455
 1456
 1457                 /*******************************
 1458                 *             TERM             *
 1459                 *******************************/
 1460
 1461:- '$iso'((numbervars/3)).
 numbervars(+Term, +StartIndex, -EndIndex) is det
Number all unbound variables in Term using '$VAR'(N), where the first N is StartIndex and EndIndex is unified to the index that will be given to the next variable.
 1469numbervars(Term, From, To) :-
 1470    numbervars(Term, From, To, []).
 1471
 1472
 1473                 /*******************************
 1474                 *            STRING            *
 1475                 *******************************/
 term_string(?Term, ?String, +Options)
Parse/write a term from/to a string using Options.
 1481term_string(Term, String, Options) :-
 1482    nonvar(String),
 1483    !,
 1484    read_term_from_atom(String, Term, Options).
 1485term_string(Term, String, Options) :-
 1486    (   '$option'(quoted(_), Options)
 1487    ->  Options1 = Options
 1488    ;   '$merge_options'(_{quoted:true}, Options, Options1)
 1489    ),
 1490    format(string(String), '~W', [Term, Options1]).
 1491
 1492
 1493                 /*******************************
 1494                 *             GVAR             *
 1495                 *******************************/
 nb_setval(+Name, +Value) is det
Bind the non-backtrackable variable Name with a copy of Value
 1501nb_setval(Name, Value) :-
 1502    duplicate_term(Value, Copy),
 1503    nb_linkval(Name, Copy).
 1504
 1505
 1506		 /*******************************
 1507		 *            THREADS		*
 1508		 *******************************/
 1509
 1510:- meta_predicate
 1511    thread_create(0, -).
 thread_create(:Goal, -Id)
Shorthand for thread_create(Goal, Id, []).
 1517thread_create(Goal, Id) :-
 1518    thread_create(Goal, Id, []).
 thread_join(+Id)
Join a thread and raise an error of the thread did not succeed.
Errors
- thread_error(Status), where Status is the result of thread_join/2.
 1527thread_join(Id) :-
 1528    thread_join(Id, Status),
 1529    (   Status == true
 1530    ->  true
 1531    ;   throw(error(thread_error(Id, Status), _))
 1532    ).
 set_prolog_gc_thread(+Status)
Control the GC thread. Status is one of
false
Disable the separate GC thread, running atom and clause garbage collection in the triggering thread.
true
Enable the separate GC thread. All implicit atom and clause garbage collection is executed by the thread gc.
stop
Stop the gc thread if it is running. The thread is recreated on the next implicit atom or clause garbage collection. Used by fork/1 to avoid forking a multi-threaded application.
 1549set_prolog_gc_thread(Status) :-
 1550    var(Status),
 1551    !,
 1552    '$instantiation_error'(Status).
 1553set_prolog_gc_thread(false) :-
 1554    !,
 1555    set_prolog_flag(gc_thread, false),
 1556    (   current_prolog_flag(threads, true)
 1557    ->  (   '$gc_stop'
 1558        ->  thread_join(gc)
 1559        ;   true
 1560        )
 1561    ;   true
 1562    ).
 1563set_prolog_gc_thread(true) :-
 1564    !,
 1565    set_prolog_flag(gc_thread, true).
 1566set_prolog_gc_thread(stop) :-
 1567    !,
 1568    (   current_prolog_flag(threads, true)
 1569    ->  (   '$gc_stop'
 1570        ->  thread_join(gc)
 1571        ;   true
 1572        )
 1573    ;   true
 1574    ).
 1575set_prolog_gc_thread(Status) :-
 1576    '$domain_error'(gc_thread, Status).
 transaction(:Goal)
 transaction(:Goal, +Options)
 transaction(:Goal, :Constraint, +Mutex)
 snapshot(:Goal)
Wrappers to guarantee clean Module:Goal terms.
 1585transaction(Goal) :-
 1586    '$transaction'(Goal, []).
 1587transaction(Goal, Options) :-
 1588    '$transaction'(Goal, Options).
 1589transaction(Goal, Constraint, Mutex) :-
 1590    '$transaction'(Goal, Constraint, Mutex).
 1591snapshot(Goal) :-
 1592    '$snapshot'(Goal).
 1593
 1594
 1595		 /*******************************
 1596		 *            UNDO		*
 1597		 *******************************/
 1598
 1599:- meta_predicate
 1600    undo(0).
 undo(:Goal)
Schedule Goal to be called when backtracking takes us back to before this call.
 1607undo(Goal) :-
 1608    '$undo'(Goal).
 1609
 1610:- public
 1611    '$run_undo'/1. 1612
 1613'$run_undo'([One]) :-
 1614    !,
 1615    call(One).
 1616'$run_undo'(List) :-
 1617    run_undo(List, _, Error),
 1618    (   var(Error)
 1619    ->  true
 1620    ;   throw(Error)
 1621    ).
 1622
 1623run_undo([], E, E).
 1624run_undo([H|T], E0, E) :-
 1625    (   catch(H, E1, true)
 1626    ->  (   var(E1)
 1627        ->  true
 1628        ;   '$urgent_exception'(E0, E1, E2)
 1629        )
 1630    ;   true
 1631    ),
 1632    run_undo(T, E2, E).
 $wrap_predicate(:Head, +Name, -Closure, -Wrapped, +Body) is det
Would be nicer to have this from library(prolog_wrap), but we need it for tabling, so it must be a system predicate.
 1640:- meta_predicate
 1641    '$wrap_predicate'(:, +, -, -, +). 1642
 1643'$wrap_predicate'(M:Head, WName, Closure, call(Wrapped), Body) :-
 1644    callable_name_arguments(Head, PName, Args),
 1645    callable_name_arity(Head, PName, Arity),
 1646    (   is_most_general_term(Head)
 1647    ->  true
 1648    ;   '$domain_error'(most_general_term, Head)
 1649    ),
 1650    atomic_list_concat(['$wrap$', PName], WrapName),
 1651    volatile(M:WrapName/Arity),
 1652    module_transparent(M:WrapName/Arity),
 1653    WHead =.. [WrapName|Args],
 1654    '$c_wrap_predicate'(M:Head, WName, Closure, Wrapped, M:(WHead :- Body)).
 1655
 1656callable_name_arguments(Head, PName, Args) :-
 1657    atom(Head),
 1658    !,
 1659    PName = Head,
 1660    Args = [].
 1661callable_name_arguments(Head, PName, Args) :-
 1662    compound_name_arguments(Head, PName, Args).
 1663
 1664callable_name_arity(Head, PName, Arity) :-
 1665    atom(Head),
 1666    !,
 1667    PName = Head,
 1668    Arity = 0.
 1669callable_name_arity(Head, PName, Arity) :-
 1670    compound_name_arity(Head, PName, Arity)