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,
  484                       [ file_type(prolog),
  485                         access(read),
  486                         file_errors(fail)
  487                       ],
  488                       File),
  489    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.
  506exists_source(Source) :-
  507    exists_source(Source, _Path).
  508
  509exists_source(Source, Path) :-
  510    absolute_file_name(Source, Path,
  511                       [ file_type(prolog),
  512                         access(read),
  513                         file_errors(fail)
  514                       ]).
 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.
  523prolog_load_context(module, Module) :-
  524    '$current_source_module'(Module).
  525prolog_load_context(file, File) :-
  526    input_file(File).
  527prolog_load_context(source, F) :-       % SICStus compatibility
  528    input_file(F0),
  529    '$input_context'(Context),
  530    '$top_file'(Context, F0, F).
  531prolog_load_context(stream, S) :-
  532    (   system:'$load_input'(_, S0)
  533    ->  S = S0
  534    ).
  535prolog_load_context(directory, D) :-
  536    input_file(F),
  537    file_directory_name(F, D).
  538prolog_load_context(dialect, D) :-
  539    current_prolog_flag(emulated_dialect, D).
  540prolog_load_context(term_position, TermPos) :-
  541    source_location(_, L),
  542    (   nb_current('$term_position', Pos),
  543        compound(Pos),              % actually set
  544        stream_position_data(line_count, Pos, L)
  545    ->  TermPos = Pos
  546    ;   TermPos = '$stream_position'(0,L,0,0)
  547    ).
  548prolog_load_context(script, Bool) :-
  549    (   '$toplevel':loaded_init_file(script, Path),
  550        input_file(File),
  551        same_file(File, Path)
  552    ->  Bool = true
  553    ;   Bool = false
  554    ).
  555prolog_load_context(variable_names, Bindings) :-
  556    nb_current('$variable_names', Bindings).
  557prolog_load_context(term, Term) :-
  558    nb_current('$term', Term).
  559prolog_load_context(reloading, true) :-
  560    prolog_load_context(source, F),
  561    '$source_file_property'(F, reloading, true).
  562
  563input_file(File) :-
  564    (   system:'$load_input'(_, Stream)
  565    ->  stream_property(Stream, file_name(File))
  566    ),
  567    !.
  568input_file(File) :-
  569    source_location(File, _).
 unload_file(+File) is det
Remove all traces of loading file.
  576:- dynamic system:'$resolved_source_path'/2.  577
  578unload_file(File) :-
  579    (   canonical_source_file(File, Path)
  580    ->  '$unload_file'(Path),
  581        retractall(system:'$resolved_source_path'(_, Path))
  582    ;   true
  583    ).
  584
  585		 /*******************************
  586		 *      FOREIGN LIBRARIES	*
  587		 *******************************/
 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.

  606use_foreign_library(FileSpec) :-
  607    ensure_shlib,
  608    initialization(shlib:load_foreign_library(FileSpec), now).
  609
  610use_foreign_library(FileSpec, Entry) :-
  611    ensure_shlib,
  612    initialization(shlib:load_foreign_library(FileSpec, Entry), now).
  613
  614ensure_shlib :-
  615    '$get_predicate_attribute'(shlib:load_foreign_library(_), defined, 1),
  616    '$get_predicate_attribute'(shlib:load_foreign_library(_,_), defined, 1),
  617    !.
  618ensure_shlib :-
  619    use_module(library(shlib), []).
  620
  621
  622                 /*******************************
  623                 *            STREAMS           *
  624                 *******************************/
 stream_position_data(?Field, +Pos, ?Date)
Extract values from stream position objects. '$stream_position' is of the format '$stream_position'(Byte, Char, Line, LinePos)
  631stream_position_data(Prop, Term, Value) :-
  632    nonvar(Prop),
  633    !,
  634    (   stream_position_field(Prop, Pos)
  635    ->  arg(Pos, Term, Value)
  636    ;   throw(error(domain_error(stream_position_data, Prop)))
  637    ).
  638stream_position_data(Prop, Term, Value) :-
  639    stream_position_field(Prop, Pos),
  640    arg(Pos, Term, Value).
  641
  642stream_position_field(char_count,    1).
  643stream_position_field(line_count,    2).
  644stream_position_field(line_position, 3).
  645stream_position_field(byte_count,    4).
  646
  647
  648                 /*******************************
  649                 *            CONTROL           *
  650                 *******************************/
 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.
  658:- meta_predicate
  659    call_with_depth_limit(0, +, -).  660
  661call_with_depth_limit(G, Limit, Result) :-
  662    '$depth_limit'(Limit, OLimit, OReached),
  663    (   catch(G, E, '$depth_limit_except'(OLimit, OReached, E)),
  664        '$depth_limit_true'(Limit, OLimit, OReached, Result, Det),
  665        ( Det == ! -> ! ; true )
  666    ;   '$depth_limit_false'(OLimit, OReached, Result)
  667    ).
 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.

  680:- meta_predicate
  681    call_with_inference_limit(0, +, -).  682
  683call_with_inference_limit(G, Limit, Result) :-
  684    '$inference_limit'(Limit, OLimit),
  685    (   catch(G, Except,
  686              system:'$inference_limit_except'(OLimit, Except, Result0)),
  687        (   Result0 == inference_limit_exceeded
  688        ->  !
  689        ;   system:'$inference_limit_true'(Limit, OLimit, Result0),
  690            ( Result0 == ! -> ! ; true )
  691        ),
  692        Result = Result0
  693    ;   system:'$inference_limit_false'(OLimit)
  694    ).
  695
  696
  697                /********************************
  698                *           DATA BASE           *
  699                *********************************/
  700
  701/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  702The predicate current_predicate/2 is   a  difficult subject since  the
  703introduction  of defaulting     modules   and   dynamic     libraries.
  704current_predicate/2 is normally  called with instantiated arguments to
  705verify some  predicate can   be called without trapping   an undefined
  706predicate.  In this case we must  perform the search algorithm used by
  707the prolog system itself.
  708
  709If the pattern is not fully specified, we only generate the predicates
  710actually available in this  module.   This seems the best for listing,
  711etc.
  712- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  713
  714
  715:- meta_predicate
  716    current_predicate(?, :),
  717    '$defined_predicate'(:).  718
  719current_predicate(Name, Module:Head) :-
  720    (var(Module) ; var(Head)),
  721    !,
  722    generate_current_predicate(Name, Module, Head).
  723current_predicate(Name, Term) :-
  724    '$c_current_predicate'(Name, Term),
  725    '$defined_predicate'(Term),
  726    !.
  727current_predicate(Name, Module:Head) :-
  728    default_module(Module, DefModule),
  729    '$c_current_predicate'(Name, DefModule:Head),
  730    '$defined_predicate'(DefModule:Head),
  731    !.
  732current_predicate(Name, Module:Head) :-
  733    '$autoload':autoload_in(Module, general),
  734    \+ current_prolog_flag(Module:unknown, fail),
  735    (   compound(Head)
  736    ->  compound_name_arity(Head, Name, Arity)
  737    ;   Name = Head, Arity = 0
  738    ),
  739    '$find_library'(Module, Name, Arity, _LoadModule, _Library),
  740    !.
  741
  742generate_current_predicate(Name, Module, Head) :-
  743    current_module(Module),
  744    QHead = Module:Head,
  745    '$c_current_predicate'(Name, QHead),
  746    '$get_predicate_attribute'(QHead, defined, 1).
  747
  748'$defined_predicate'(Head) :-
  749    '$get_predicate_attribute'(Head, defined, 1),
  750    !.
 predicate_property(?Predicate, ?Property) is nondet
True when Property is a property of Predicate.
  756:- meta_predicate
  757    predicate_property(:, ?).  758
  759:- multifile
  760    '$predicate_property'/2.  761
  762:- '$iso'(predicate_property/2).  763
  764predicate_property(Pred, Property) :-           % Mode ?,+
  765    nonvar(Property),
  766    !,
  767    property_predicate(Property, Pred).
  768predicate_property(Pred, Property) :-           % Mode +,-
  769    define_or_generate(Pred),
  770    '$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.
  778property_predicate(undefined, Pred) :-
  779    !,
  780    Pred = Module:Head,
  781    current_module(Module),
  782    '$c_current_predicate'(_, Pred),
  783    \+ '$defined_predicate'(Pred),          % Speed up a bit
  784    \+ current_predicate(_, Pred),
  785    goal_name_arity(Head, Name, Arity),
  786    \+ system_undefined(Module:Name/Arity).
  787property_predicate(visible, Pred) :-
  788    !,
  789    visible_predicate(Pred).
  790property_predicate(autoload(File), Head) :-
  791    !,
  792    \+ current_prolog_flag(autoload, false),
  793    '$autoload':autoloadable(Head, File).
  794property_predicate(implementation_module(IM), M:Head) :-
  795    !,
  796    atom(M),
  797    (   default_module(M, DM),
  798        '$get_predicate_attribute'(DM:Head, defined, 1)
  799    ->  (   '$get_predicate_attribute'(DM:Head, imported, ImportM)
  800        ->  IM = ImportM
  801        ;   IM = M
  802        )
  803    ;   \+ current_prolog_flag(M:unknown, fail),
  804        goal_name_arity(Head, Name, Arity),
  805        '$find_library'(_, Name, Arity, LoadModule, _File)
  806    ->  IM = LoadModule
  807    ;   M = IM
  808    ).
  809property_predicate(iso, _:Head) :-
  810    callable(Head),
  811    !,
  812    goal_name_arity(Head, Name, Arity),
  813    current_predicate(system:Name/Arity),
  814    '$predicate_property'(iso, system:Head).
  815property_predicate(built_in, Module:Head) :-
  816    callable(Head),
  817    !,
  818    goal_name_arity(Head, Name, Arity),
  819    current_predicate(Module:Name/Arity),
  820    '$predicate_property'(built_in, Module:Head).
  821property_predicate(Property, Pred) :-
  822    define_or_generate(Pred),
  823    '$predicate_property'(Property, Pred).
  824
  825goal_name_arity(Head, Name, Arity) :-
  826    compound(Head),
  827    !,
  828    compound_name_arity(Head, Name, Arity).
  829goal_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.
  838define_or_generate(M:Head) :-
  839    callable(Head),
  840    atom(M),
  841    '$get_predicate_attribute'(M:Head, defined, 1),
  842    !.
  843define_or_generate(M:Head) :-
  844    callable(Head),
  845    nonvar(M), M \== system,
  846    !,
  847    '$define_predicate'(M:Head).
  848define_or_generate(Pred) :-
  849    current_predicate(_, Pred),
  850    '$define_predicate'(Pred).
  851
  852
  853'$predicate_property'(interpreted, Pred) :-
  854    '$get_predicate_attribute'(Pred, foreign, 0).
  855'$predicate_property'(visible, Pred) :-
  856    '$get_predicate_attribute'(Pred, defined, 1).
  857'$predicate_property'(built_in, Pred) :-
  858    '$get_predicate_attribute'(Pred, system, 1).
  859'$predicate_property'(exported, Pred) :-
  860    '$get_predicate_attribute'(Pred, exported, 1).
  861'$predicate_property'(public, Pred) :-
  862    '$get_predicate_attribute'(Pred, public, 1).
  863'$predicate_property'(non_terminal, Pred) :-
  864    '$get_predicate_attribute'(Pred, non_terminal, 1).
  865'$predicate_property'(foreign, Pred) :-
  866    '$get_predicate_attribute'(Pred, foreign, 1).
  867'$predicate_property'((dynamic), Pred) :-
  868    '$get_predicate_attribute'(Pred, (dynamic), 1).
  869'$predicate_property'((static), Pred) :-
  870    '$get_predicate_attribute'(Pred, (dynamic), 0).
  871'$predicate_property'((volatile), Pred) :-
  872    '$get_predicate_attribute'(Pred, (volatile), 1).
  873'$predicate_property'((thread_local), Pred) :-
  874    '$get_predicate_attribute'(Pred, (thread_local), 1).
  875'$predicate_property'((multifile), Pred) :-
  876    '$get_predicate_attribute'(Pred, (multifile), 1).
  877'$predicate_property'(imported_from(Module), Pred) :-
  878    '$get_predicate_attribute'(Pred, imported, Module).
  879'$predicate_property'(transparent, Pred) :-
  880    '$get_predicate_attribute'(Pred, transparent, 1).
  881'$predicate_property'(meta_predicate(Pattern), Pred) :-
  882    '$get_predicate_attribute'(Pred, meta_predicate, Pattern).
  883'$predicate_property'(file(File), Pred) :-
  884    '$get_predicate_attribute'(Pred, file, File).
  885'$predicate_property'(line_count(LineNumber), Pred) :-
  886    '$get_predicate_attribute'(Pred, line_count, LineNumber).
  887'$predicate_property'(notrace, Pred) :-
  888    '$get_predicate_attribute'(Pred, trace, 0).
  889'$predicate_property'(nodebug, Pred) :-
  890    '$get_predicate_attribute'(Pred, hide_childs, 1).
  891'$predicate_property'(spying, Pred) :-
  892    '$get_predicate_attribute'(Pred, spy, 1).
  893'$predicate_property'(number_of_clauses(N), Pred) :-
  894    '$get_predicate_attribute'(Pred, number_of_clauses, N).
  895'$predicate_property'(number_of_rules(N), Pred) :-
  896    '$get_predicate_attribute'(Pred, number_of_rules, N).
  897'$predicate_property'(last_modified_generation(Gen), Pred) :-
  898    '$get_predicate_attribute'(Pred, last_modified_generation, Gen).
  899'$predicate_property'(indexed(Indices), Pred) :-
  900    '$get_predicate_attribute'(Pred, indexed, Indices).
  901'$predicate_property'(noprofile, Pred) :-
  902    '$get_predicate_attribute'(Pred, noprofile, 1).
  903'$predicate_property'(ssu, Pred) :-
  904    '$get_predicate_attribute'(Pred, ssu, 1).
  905'$predicate_property'(iso, Pred) :-
  906    '$get_predicate_attribute'(Pred, iso, 1).
  907'$predicate_property'(det, Pred) :-
  908    '$get_predicate_attribute'(Pred, det, 1).
  909'$predicate_property'(quasi_quotation_syntax, Pred) :-
  910    '$get_predicate_attribute'(Pred, quasi_quotation_syntax, 1).
  911'$predicate_property'(defined, Pred) :-
  912    '$get_predicate_attribute'(Pred, defined, 1).
  913'$predicate_property'(tabled, Pred) :-
  914    '$get_predicate_attribute'(Pred, tabled, 1).
  915'$predicate_property'(tabled(Flag), Pred) :-
  916    '$get_predicate_attribute'(Pred, tabled, 1),
  917    table_flag(Flag, Pred).
  918'$predicate_property'(incremental, Pred) :-
  919    '$get_predicate_attribute'(Pred, incremental, 1).
  920'$predicate_property'(monotonic, Pred) :-
  921    '$get_predicate_attribute'(Pred, monotonic, 1).
  922'$predicate_property'(opaque, Pred) :-
  923    '$get_predicate_attribute'(Pred, opaque, 1).
  924'$predicate_property'(lazy, Pred) :-
  925    '$get_predicate_attribute'(Pred, lazy, 1).
  926'$predicate_property'(abstract(N), Pred) :-
  927    '$get_predicate_attribute'(Pred, abstract, N).
  928'$predicate_property'(size(Bytes), Pred) :-
  929    '$get_predicate_attribute'(Pred, size, Bytes).
  930
  931system_undefined(user:prolog_trace_interception/4).
  932system_undefined(user:prolog_exception_hook/4).
  933system_undefined(system:'$c_call_prolog'/0).
  934system_undefined(system:window_title/2).
  935
  936table_flag(variant, Pred) :-
  937    '$tbl_implementation'(Pred, M:Head),
  938    M:'$tabled'(Head, variant).
  939table_flag(subsumptive, Pred) :-
  940    '$tbl_implementation'(Pred, M:Head),
  941    M:'$tabled'(Head, subsumptive).
  942table_flag(shared, Pred) :-
  943    '$get_predicate_attribute'(Pred, tshared, 1).
  944table_flag(incremental, Pred) :-
  945    '$get_predicate_attribute'(Pred, incremental, 1).
  946table_flag(monotonic, Pred) :-
  947    '$get_predicate_attribute'(Pred, monotonic, 1).
  948table_flag(subgoal_abstract(N), Pred) :-
  949    '$get_predicate_attribute'(Pred, subgoal_abstract, N).
  950table_flag(answer_abstract(N), Pred) :-
  951    '$get_predicate_attribute'(Pred, subgoal_abstract, N).
  952table_flag(subgoal_abstract(N), Pred) :-
  953    '$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.
  962visible_predicate(Pred) :-
  963    Pred = M:Head,
  964    current_module(M),
  965    (   callable(Head)
  966    ->  (   '$get_predicate_attribute'(Pred, defined, 1)
  967        ->  true
  968        ;   \+ current_prolog_flag(M:unknown, fail),
  969            functor(Head, Name, Arity),
  970            '$find_library'(M, Name, Arity, _LoadModule, _Library)
  971        )
  972    ;   setof(PI, visible_in_module(M, PI), PIs),
  973        '$member'(Name/Arity, PIs),
  974        functor(Head, Name, Arity)
  975    ).
  976
  977visible_in_module(M, Name/Arity) :-
  978    default_module(M, DefM),
  979    DefHead = DefM:Head,
  980    '$c_current_predicate'(_, DefHead),
  981    '$get_predicate_attribute'(DefHead, defined, 1),
  982    \+ hidden_system_predicate(Head),
  983    functor(Head, Name, Arity).
  984visible_in_module(_, Name/Arity) :-
  985    '$in_library'(Name, Arity, _).
  986
  987hidden_system_predicate(Head) :-
  988    functor(Head, Name, _),
  989    atom(Name),                     % Avoid [].
  990    sub_atom(Name, 0, _, _, $),
  991    \+ 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.
 1016clause_property(Clause, Property) :-
 1017    '$clause_property'(Property, Clause).
 1018
 1019'$clause_property'(line_count(LineNumber), Clause) :-
 1020    '$get_clause_attribute'(Clause, line_count, LineNumber).
 1021'$clause_property'(file(File), Clause) :-
 1022    '$get_clause_attribute'(Clause, file, File).
 1023'$clause_property'(source(File), Clause) :-
 1024    '$get_clause_attribute'(Clause, owner, File).
 1025'$clause_property'(size(Bytes), Clause) :-
 1026    '$get_clause_attribute'(Clause, size, Bytes).
 1027'$clause_property'(fact, Clause) :-
 1028    '$get_clause_attribute'(Clause, fact, true).
 1029'$clause_property'(erased, Clause) :-
 1030    '$get_clause_attribute'(Clause, erased, true).
 1031'$clause_property'(predicate(PI), Clause) :-
 1032    '$get_clause_attribute'(Clause, predicate_indicator, PI).
 1033'$clause_property'(module(M), Clause) :-
 1034    '$get_clause_attribute'(Clause, module, M).
 dynamic(:Predicates, +Options) is det
Define a predicate as dynamic with optionally additional properties. Defined options are:
 1048dynamic(M:Predicates, Options) :-
 1049    '$must_be'(list, Predicates),
 1050    options_properties(Options, Props),
 1051    set_pprops(Predicates, M, [dynamic|Props]).
 1052
 1053set_pprops([], _, _).
 1054set_pprops([H|T], M, Props) :-
 1055    set_pprops1(Props, M:H),
 1056    strip_module(M:H, M2, P),
 1057    '$pi_head'(M2:P, Pred),
 1058    '$set_table_wrappers'(Pred),
 1059    set_pprops(T, M, Props).
 1060
 1061set_pprops1([], _).
 1062set_pprops1([H|T], P) :-
 1063    (   atom(H)
 1064    ->  '$set_predicate_attribute'(P, H, true)
 1065    ;   H =.. [Name,Value]
 1066    ->  '$set_predicate_attribute'(P, Name, Value)
 1067    ),
 1068    set_pprops1(T, P).
 1069
 1070options_properties(Options, Props) :-
 1071    G = opt_prop(_,_,_,_),
 1072    findall(G, G, Spec),
 1073    options_properties(Spec, Options, Props).
 1074
 1075options_properties([], _, []).
 1076options_properties([opt_prop(Name, Type, SetValue, Prop)|T],
 1077                   Options, [Prop|PT]) :-
 1078    Opt =.. [Name,V],
 1079    '$option'(Opt, Options),
 1080    '$must_be'(Type, V),
 1081    V = SetValue,
 1082    !,
 1083    options_properties(T, Options, PT).
 1084options_properties([_|T], Options, PT) :-
 1085    options_properties(T, Options, PT).
 1086
 1087opt_prop(incremental,   boolean,               Bool,  incremental(Bool)).
 1088opt_prop(abstract,      between(0,0),          0,     abstract).
 1089opt_prop(multifile,     boolean,               true,  multifile).
 1090opt_prop(discontiguous, boolean,               true,  discontiguous).
 1091opt_prop(volatile,      boolean,               true,  volatile).
 1092opt_prop(thread,        oneof(atom, [local,shared],[local,shared]),
 1093                                               local, thread_local).
 1094
 1095                /********************************
 1096                *            MODULES            *
 1097                *********************************/
 current_module(?Module) is nondet
True if Module is a currently defined module.
 1103current_module(Module) :-
 1104    '$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.
 1120module_property(Module, Property) :-
 1121    nonvar(Module), nonvar(Property),
 1122    !,
 1123    property_module(Property, Module).
 1124module_property(Module, Property) :-    % -, file(File)
 1125    nonvar(Property), Property = file(File),
 1126    !,
 1127    (   nonvar(File)
 1128    ->  '$current_module'(Modules, File),
 1129        (   atom(Modules)
 1130        ->  Module = Modules
 1131        ;   '$member'(Module, Modules)
 1132        )
 1133    ;   '$current_module'(Module, File),
 1134        File \== []
 1135    ).
 1136module_property(Module, Property) :-
 1137    current_module(Module),
 1138    property_module(Property, Module).
 1139
 1140property_module(Property, Module) :-
 1141    module_property(Property),
 1142    (   Property = exported_operators(List)
 1143    ->  '$exported_ops'(Module, List, [])
 1144    ;   '$module_property'(Module, Property)
 1145    ).
 1146
 1147module_property(class(_)).
 1148module_property(file(_)).
 1149module_property(line_count(_)).
 1150module_property(exports(_)).
 1151module_property(exported_operators(_)).
 1152module_property(size(_)).
 1153module_property(program_size(_)).
 1154module_property(program_space(_)).
 1155module_property(last_modified_generation(_)).
 module(+Module) is det
Set the module that is associated to the toplevel to Module.
 1161module(Module) :-
 1162    atom(Module),
 1163    current_module(Module),
 1164    !,
 1165    '$set_typein_module'(Module).
 1166module(Module) :-
 1167    '$set_typein_module'(Module),
 1168    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.
 1175working_directory(Old, New) :-
 1176    '$cwd'(Old),
 1177    (   Old == New
 1178    ->  true
 1179    ;   '$chdir'(New)
 1180    ).
 1181
 1182
 1183                 /*******************************
 1184                 *            TRIES             *
 1185                 *******************************/
 current_trie(?Trie) is nondet
True if Trie is the handle of an existing trie.
 1191current_trie(Trie) :-
 1192    current_blob(Trie, trie),
 1193    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
 1229trie_property(Trie, Property) :-
 1230    current_trie(Trie),
 1231    trie_property(Property),
 1232    '$trie_property'(Trie, Property).
 1233
 1234trie_property(node_count(_)).
 1235trie_property(value_count(_)).
 1236trie_property(size(_)).
 1237trie_property(hashed(_)).
 1238trie_property(compiled_size(_)).
 1239                                                % below only when -DO_TRIE_STATS
 1240trie_property(lookup_count(_)).                 % is enabled in pl-trie.h
 1241trie_property(gen_call_count(_)).
 1242trie_property(invalidated(_)).                  % IDG stats
 1243trie_property(reevaluated(_)).
 1244trie_property(deadlock(_)).                     % Shared tabling stats
 1245trie_property(wait(_)).
 1246trie_property(idg_affected_count(_)).
 1247trie_property(idg_dependent_count(_)).
 1248trie_property(idg_size(_)).
 1249
 1250
 1251                /********************************
 1252                *      SYSTEM INTERACTION       *
 1253                *********************************/
 1254
 1255shell(Command) :-
 1256    shell(Command, 0).
 1257
 1258
 1259                 /*******************************
 1260                 *            SIGNALS           *
 1261                 *******************************/
 1262
 1263:- meta_predicate
 1264    on_signal(+, :, :),
 1265    current_signal(?, ?, :).
 on_signal(+Signal, -OldHandler, :NewHandler) is det
 1269on_signal(Signal, Old, New) :-
 1270    atom(Signal),
 1271    !,
 1272    '$on_signal'(_Num, Signal, Old, New).
 1273on_signal(Signal, Old, New) :-
 1274    integer(Signal),
 1275    !,
 1276    '$on_signal'(Signal, _Name, Old, New).
 1277on_signal(Signal, _Old, _New) :-
 1278    '$type_error'(signal_name, Signal).
 current_signal(?Name, ?SignalNumber, :Handler) is nondet
 1282current_signal(Name, Id, Handler) :-
 1283    between(1, 32, Id),
 1284    '$on_signal'(Id, Name, Handler, Handler).
 1285
 1286:- multifile
 1287    prolog:called_by/2. 1288
 1289prolog:called_by(on_signal(_,_,New), [New+1]) :-
 1290    (   new == throw
 1291    ;   new == default
 1292    ), !, fail.
 1293
 1294
 1295                 /*******************************
 1296                 *            DLOPEN            *
 1297                 *******************************/
 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.
 1311open_shared_object(File, Handle) :-
 1312    open_shared_object(File, Handle, []). % use pl-load.c defaults
 1313
 1314open_shared_object(File, Handle, Flags) :-
 1315    (   is_list(Flags)
 1316    ->  true
 1317    ;   throw(error(type_error(list, Flags), _))
 1318    ),
 1319    map_dlflags(Flags, Mask),
 1320    '$open_shared_object'(File, Handle, Mask).
 1321
 1322dlopen_flag(now,        2'01).          % see pl-load.c for these constants
 1323dlopen_flag(global,     2'10).          % Solaris only
 1324
 1325map_dlflags([], 0).
 1326map_dlflags([F|T], M) :-
 1327    map_dlflags(T, M0),
 1328    (   dlopen_flag(F, I)
 1329    ->  true
 1330    ;   throw(error(domain_error(dlopen_flag, F), _))
 1331    ),
 1332    M is M0 \/ I.
 1333
 1334
 1335                 /*******************************
 1336                 *             I/O              *
 1337                 *******************************/
 1338
 1339format(Fmt) :-
 1340    format(Fmt, []).
 1341
 1342                 /*******************************
 1343                 *            FILES             *
 1344                 *******************************/
 absolute_file_name(+Term, -AbsoluteFile)
 1348absolute_file_name(Name, Abs) :-
 1349    atomic(Name),
 1350    !,
 1351    '$absolute_file_name'(Name, Abs).
 1352absolute_file_name(Term, Abs) :-
 1353    '$chk_file'(Term, [''], [access(read)], true, File),
 1354    !,
 1355    '$absolute_file_name'(File, Abs).
 1356absolute_file_name(Term, Abs) :-
 1357    '$chk_file'(Term, [''], [], true, File),
 1358    !,
 1359    '$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.
 1367tmp_file_stream(Enc, File, Stream) :-
 1368    atom(Enc), var(File), var(Stream),
 1369    !,
 1370    '$tmp_file_stream'('', Enc, File, Stream).
 1371tmp_file_stream(File, Stream, Options) :-
 1372    current_prolog_flag(encoding, DefEnc),
 1373    '$option'(encoding(Enc), Options, DefEnc),
 1374    '$option'(extension(Ext), Options, ''),
 1375    '$tmp_file_stream'(Ext, Enc, File, Stream),
 1376    set_stream(Stream, file_name(File)).
 1377
 1378
 1379                /********************************
 1380                *        MEMORY MANAGEMENT      *
 1381                *********************************/
 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.
 1390garbage_collect :-
 1391    '$garbage_collect'(0).
 set_prolog_stack(+Name, +Option) is det
Set a parameter for one of the Prolog stacks.
 1397set_prolog_stack(Stack, Option) :-
 1398    Option =.. [Name,Value0],
 1399    Value is Value0,
 1400    '$set_prolog_stack'(Stack, Name, _Old, Value).
 prolog_stack_property(?Stack, ?Property) is nondet
Examine stack properties.
 1406prolog_stack_property(Stack, Property) :-
 1407    stack_property(P),
 1408    stack_name(Stack),
 1409    Property =.. [P,Value],
 1410    '$set_prolog_stack'(Stack, P, Value, Value).
 1411
 1412stack_name(local).
 1413stack_name(global).
 1414stack_name(trail).
 1415
 1416stack_property(limit).
 1417stack_property(spare).
 1418stack_property(min_free).
 1419stack_property(low).
 1420stack_property(factor).
 1421
 1422
 1423		 /*******************************
 1424		 *            CLAUSE		*
 1425		 *******************************/
 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.
 1433rule(Head, Rule) :-
 1434    '$rule'(Head, Rule0),
 1435    conditional_rule(Rule0, Rule1),
 1436    Rule = Rule1.
 1437rule(Head, Rule, Ref) :-
 1438    '$rule'(Head, Rule0, Ref),
 1439    conditional_rule(Rule0, Rule1),
 1440    Rule = Rule1.
 1441
 1442conditional_rule(?=>(Head, Body0), (Head,Cond=>Body)) :-
 1443    split_on_cut(Body0, Cond, Body),
 1444    !.
 1445conditional_rule(Rule, Rule).
 1446
 1447split_on_cut(Var, _, _) :-
 1448    var(Var),
 1449    !,
 1450    fail.
 1451split_on_cut((Cond,!,Body), Cond, Body) :-
 1452    !.
 1453split_on_cut((A,B), (A,Cond), Body) :-
 1454    split_on_cut(B, Cond, Body).
 1455
 1456
 1457
 1458                 /*******************************
 1459                 *             TERM             *
 1460                 *******************************/
 1461
 1462:- '$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.
 1470numbervars(Term, From, To) :-
 1471    numbervars(Term, From, To, []).
 1472
 1473
 1474                 /*******************************
 1475                 *            STRING            *
 1476                 *******************************/
 term_string(?Term, ?String, +Options)
Parse/write a term from/to a string using Options.
 1482term_string(Term, String, Options) :-
 1483    nonvar(String),
 1484    !,
 1485    read_term_from_atom(String, Term, Options).
 1486term_string(Term, String, Options) :-
 1487    (   '$option'(quoted(_), Options)
 1488    ->  Options1 = Options
 1489    ;   '$merge_options'(_{quoted:true}, Options, Options1)
 1490    ),
 1491    format(string(String), '~W', [Term, Options1]).
 1492
 1493
 1494                 /*******************************
 1495                 *             GVAR             *
 1496                 *******************************/
 nb_setval(+Name, +Value) is det
Bind the non-backtrackable variable Name with a copy of Value
 1502nb_setval(Name, Value) :-
 1503    duplicate_term(Value, Copy),
 1504    nb_linkval(Name, Copy).
 1505
 1506
 1507		 /*******************************
 1508		 *            THREADS		*
 1509		 *******************************/
 1510
 1511:- meta_predicate
 1512    thread_create(0, -).
 thread_create(:Goal, -Id)
Shorthand for thread_create(Goal, Id, []).
 1518thread_create(Goal, Id) :-
 1519    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.
 1528thread_join(Id) :-
 1529    thread_join(Id, Status),
 1530    (   Status == true
 1531    ->  true
 1532    ;   throw(error(thread_error(Id, Status), _))
 1533    ).
 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.
 1550set_prolog_gc_thread(Status) :-
 1551    var(Status),
 1552    !,
 1553    '$instantiation_error'(Status).
 1554set_prolog_gc_thread(false) :-
 1555    !,
 1556    set_prolog_flag(gc_thread, false),
 1557    (   current_prolog_flag(threads, true)
 1558    ->  (   '$gc_stop'
 1559        ->  thread_join(gc)
 1560        ;   true
 1561        )
 1562    ;   true
 1563    ).
 1564set_prolog_gc_thread(true) :-
 1565    !,
 1566    set_prolog_flag(gc_thread, true).
 1567set_prolog_gc_thread(stop) :-
 1568    !,
 1569    (   current_prolog_flag(threads, true)
 1570    ->  (   '$gc_stop'
 1571        ->  thread_join(gc)
 1572        ;   true
 1573        )
 1574    ;   true
 1575    ).
 1576set_prolog_gc_thread(Status) :-
 1577    '$domain_error'(gc_thread, Status).
 transaction(:Goal)
 transaction(:Goal, +Options)
 transaction(:Goal, :Constraint, +Mutex)
 snapshot(:Goal)
Wrappers to guarantee clean Module:Goal terms.
 1586transaction(Goal) :-
 1587    '$transaction'(Goal, []).
 1588transaction(Goal, Options) :-
 1589    '$transaction'(Goal, Options).
 1590transaction(Goal, Constraint, Mutex) :-
 1591    '$transaction'(Goal, Constraint, Mutex).
 1592snapshot(Goal) :-
 1593    '$snapshot'(Goal).
 1594
 1595
 1596		 /*******************************
 1597		 *            UNDO		*
 1598		 *******************************/
 1599
 1600:- meta_predicate
 1601    undo(0).
 undo(:Goal)
Schedule Goal to be called when backtracking takes us back to before this call.
 1608undo(Goal) :-
 1609    '$undo'(Goal).
 1610
 1611:- public
 1612    '$run_undo'/1. 1613
 1614'$run_undo'([One]) :-
 1615    !,
 1616    call(One).
 1617'$run_undo'(List) :-
 1618    run_undo(List, _, Error),
 1619    (   var(Error)
 1620    ->  true
 1621    ;   throw(Error)
 1622    ).
 1623
 1624run_undo([], E, E).
 1625run_undo([H|T], E0, E) :-
 1626    (   catch(H, E1, true)
 1627    ->  (   var(E1)
 1628        ->  true
 1629        ;   '$urgent_exception'(E0, E1, E2)
 1630        )
 1631    ;   true
 1632    ),
 1633    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.
 1641:- meta_predicate
 1642    '$wrap_predicate'(:, +, -, -, +). 1643
 1644'$wrap_predicate'(M:Head, WName, Closure, call(Wrapped), Body) :-
 1645    callable_name_arguments(Head, PName, Args),
 1646    callable_name_arity(Head, PName, Arity),
 1647    (   is_most_general_term(Head)
 1648    ->  true
 1649    ;   '$domain_error'(most_general_term, Head)
 1650    ),
 1651    atomic_list_concat(['$wrap$', PName], WrapName),
 1652    volatile(M:WrapName/Arity),
 1653    module_transparent(M:WrapName/Arity),
 1654    WHead =.. [WrapName|Args],
 1655    '$c_wrap_predicate'(M:Head, WName, Closure, Wrapped, M:(WHead :- Body)).
 1656
 1657callable_name_arguments(Head, PName, Args) :-
 1658    atom(Head),
 1659    !,
 1660    PName = Head,
 1661    Args = [].
 1662callable_name_arguments(Head, PName, Args) :-
 1663    compound_name_arguments(Head, PName, Args).
 1664
 1665callable_name_arity(Head, PName, Arity) :-
 1666    atom(Head),
 1667    !,
 1668    PName = Head,
 1669    Arity = 0.
 1670callable_name_arity(Head, PName, Arity) :-
 1671    compound_name_arity(Head, PName, Arity)