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-2020, University of Amsterdam
    7                              VU University Amsterdam
    8                              CWI, Amsterdam
    9    All rights reserved.
   10
   11    Redistribution and use in source and binary forms, with or without
   12    modification, are permitted provided that the following conditions
   13    are met:
   14
   15    1. Redistributions of source code must retain the above copyright
   16       notice, this list of conditions and the following disclaimer.
   17
   18    2. Redistributions in binary form must reproduce the above copyright
   19       notice, this list of conditions and the following disclaimer in
   20       the documentation and/or other materials provided with the
   21       distribution.
   22
   23    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   24    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   25    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   26    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   27    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   28    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   29    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   30    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   31    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   33    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   34    POSSIBILITY OF SUCH DAMAGE.
   35*/
   36
   37:- module('$syspreds',
   38          [ leash/1,
   39            visible/1,
   40            style_check/1,
   41            (spy)/1,
   42            (nospy)/1,
   43            nospyall/0,
   44            debugging/0,
   45            flag/3,
   46            atom_prefix/2,
   47            dwim_match/2,
   48            source_file_property/2,
   49            source_file/1,
   50            source_file/2,
   51            unload_file/1,
   52            exists_source/1,                    % +Spec
   53            exists_source/2,                    % +Spec, -Path
   54            use_foreign_library/1,		% :FileSpec
   55            use_foreign_library/2,		% :FileSpec, +Install
   56            prolog_load_context/2,
   57            stream_position_data/3,
   58            current_predicate/2,
   59            '$defined_predicate'/1,
   60            predicate_property/2,
   61            '$predicate_property'/2,
   62            (dynamic)/2,                        % :Predicates, +Options
   63            clause_property/2,
   64            current_module/1,                   % ?Module
   65            module_property/2,                  % ?Module, ?Property
   66            module/1,                           % +Module
   67            current_trie/1,                     % ?Trie
   68            trie_property/2,                    % ?Trie, ?Property
   69            working_directory/2,                % -OldDir, +NewDir
   70            shell/1,                            % +Command
   71            on_signal/3,
   72            current_signal/3,
   73            open_shared_object/2,
   74            open_shared_object/3,
   75            format/1,
   76            garbage_collect/0,
   77            set_prolog_stack/2,
   78            prolog_stack_property/2,
   79            absolute_file_name/2,
   80            tmp_file_stream/3,                  % +Enc, -File, -Stream
   81            call_with_depth_limit/3,            % :Goal, +Limit, -Result
   82            call_with_inference_limit/3,        % :Goal, +Limit, -Result
   83            numbervars/3,                       % +Term, +Start, -End
   84            term_string/3,                      % ?Term, ?String, +Options
   85            nb_setval/2,                        % +Var, +Value
   86            thread_create/2,                    % :Goal, -Id
   87            thread_join/1,                      % +Id
   88            transaction/1,                      % :Goal
   89            transaction/3,                      % :Goal, :Constraint, +Mutex
   90            snapshot/1,                         % :Goal
   91            set_prolog_gc_thread/1,		% +Status
   92
   93            '$wrap_predicate'/5                 % :Head, +Name, -Closure, -Wrapped, +Body
   94          ]).   95
   96:- meta_predicate
   97    dynamic(:, +),
   98    use_foreign_library(:),
   99    use_foreign_library(:, +),
  100    transaction(0),
  101    transaction(0,0,+),
  102    snapshot(0).  103
  104
  105                /********************************
  106                *           DEBUGGER            *
  107                *********************************/
 map_bits(:Pred, +Modify, +OldBits, -NewBits)
  111:- meta_predicate
  112    map_bits(2, +, +, -).  113
  114map_bits(_, Var, _, _) :-
  115    var(Var),
  116    !,
  117    '$instantiation_error'(Var).
  118map_bits(_, [], Bits, Bits) :- !.
  119map_bits(Pred, [H|T], Old, New) :-
  120    map_bits(Pred, H, Old, New0),
  121    map_bits(Pred, T, New0, New).
  122map_bits(Pred, +Name, Old, New) :-     % set a bit
  123    !,
  124    bit(Pred, Name, Bits),
  125    !,
  126    New is Old \/ Bits.
  127map_bits(Pred, -Name, Old, New) :-     % clear a bit
  128    !,
  129    bit(Pred, Name, Bits),
  130    !,
  131    New is Old /\ (\Bits).
  132map_bits(Pred, ?(Name), Old, Old) :-   % ask a bit
  133    !,
  134    bit(Pred, Name, Bits),
  135    Old /\ Bits > 0.
  136map_bits(_, Term, _, _) :-
  137    '$type_error'('+|-|?(Flag)', Term).
  138
  139bit(Pred, Name, Bits) :-
  140    call(Pred, Name, Bits),
  141    !.
  142bit(_:Pred, Name, _) :-
  143    '$domain_error'(Pred, Name).
  144
  145:- public port_name/2.                  % used by library(test_cover)
  146
  147port_name(      call, 2'000000001).
  148port_name(      exit, 2'000000010).
  149port_name(      fail, 2'000000100).
  150port_name(      redo, 2'000001000).
  151port_name(     unify, 2'000010000).
  152port_name(     break, 2'000100000).
  153port_name(  cut_call, 2'001000000).
  154port_name(  cut_exit, 2'010000000).
  155port_name( exception, 2'100000000).
  156port_name(       cut, 2'011000000).
  157port_name(       all, 2'000111111).
  158port_name(      full, 2'000101111).
  159port_name(      half, 2'000101101).     % '
  160
  161leash(Ports) :-
  162    '$leash'(Old, Old),
  163    map_bits(port_name, Ports, Old, New),
  164    '$leash'(_, New).
  165
  166visible(Ports) :-
  167    '$visible'(Old, Old),
  168    map_bits(port_name, Ports, Old, New),
  169    '$visible'(_, New).
  170
  171style_name(atom,            0x0001) :-
  172    print_message(warning, decl_no_effect(style_check(atom))).
  173style_name(singleton,       0x0042).            % semantic and syntactic
  174style_name(discontiguous,   0x0008).
  175style_name(charset,         0x0020).
  176style_name(no_effect,       0x0080).
  177style_name(var_branches,    0x0100).
 style_check(+Spec) is nondet
  181style_check(Var) :-
  182    var(Var),
  183    !,
  184    '$instantiation_error'(Var).
  185style_check(?(Style)) :-
  186    !,
  187    (   var(Style)
  188    ->  enum_style_check(Style)
  189    ;   enum_style_check(Style)
  190    ->  true
  191    ).
  192style_check(Spec) :-
  193    '$style_check'(Old, Old),
  194    map_bits(style_name, Spec, Old, New),
  195    '$style_check'(_, New).
  196
  197enum_style_check(Style) :-
  198    '$style_check'(Bits, Bits),
  199    style_name(Style, Bit),
  200    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.
  209:- multifile
  210    prolog:debug_control_hook/1.    % +Action
  211
  212:- meta_predicate
  213    spy(:),
  214    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.
  231spy(_:X) :-
  232    var(X),
  233    throw(error(instantiation_error, _)).
  234spy(_:[]) :- !.
  235spy(M:[H|T]) :-
  236    !,
  237    spy(M:H),
  238    spy(M:T).
  239spy(Spec) :-
  240    notrace(prolog:debug_control_hook(spy(Spec))),
  241    !.
  242spy(Spec) :-
  243    '$find_predicate'(Spec, Preds),
  244    '$member'(PI, Preds),
  245        pi_to_head(PI, Head),
  246        '$define_predicate'(Head),
  247        '$spy'(Head),
  248    fail.
  249spy(_).
  250
  251nospy(_:X) :-
  252    var(X),
  253    throw(error(instantiation_error, _)).
  254nospy(_:[]) :- !.
  255nospy(M:[H|T]) :-
  256    !,
  257    nospy(M:H),
  258    nospy(M:T).
  259nospy(Spec) :-
  260    notrace(prolog:debug_control_hook(nospy(Spec))),
  261    !.
  262nospy(Spec) :-
  263    '$find_predicate'(Spec, Preds),
  264    '$member'(PI, Preds),
  265         pi_to_head(PI, Head),
  266        '$nospy'(Head),
  267    fail.
  268nospy(_).
  269
  270nospyall :-
  271    notrace(prolog:debug_control_hook(nospyall)),
  272    fail.
  273nospyall :-
  274    spy_point(Head),
  275        '$nospy'(Head),
  276    fail.
  277nospyall.
  278
  279pi_to_head(M:PI, M:Head) :-
  280    !,
  281    pi_to_head(PI, Head).
  282pi_to_head(Name/Arity, Head) :-
  283    functor(Head, Name, Arity).
 debugging is det
Report current status of the debugger.
  289debugging :-
  290    notrace(prolog:debug_control_hook(debugging)),
  291    !.
  292debugging :-
  293    current_prolog_flag(debug, true),
  294    !,
  295    print_message(informational, debugging(on)),
  296    findall(H, spy_point(H), SpyPoints),
  297    print_message(informational, spying(SpyPoints)).
  298debugging :-
  299    print_message(informational, debugging(off)).
  300
  301spy_point(Module:Head) :-
  302    current_predicate(_, Module:Head),
  303    '$get_predicate_attribute'(Module:Head, spy, 1),
  304    \+ 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.
  311flag(Name, Old, New) :-
  312    Old == New,
  313    !,
  314    get_flag(Name, Old).
  315flag(Name, Old, New) :-
  316    with_mutex('$flag', update_flag(Name, Old, New)).
  317
  318update_flag(Name, Old, New) :-
  319    get_flag(Name, Old),
  320    (   atom(New)
  321    ->  set_flag(Name, New)
  322    ;   Value is New,
  323        set_flag(Name, Value)
  324    ).
  325
  326
  327                /********************************
  328                *             ATOMS             *
  329                *********************************/
  330
  331dwim_match(A1, A2) :-
  332    dwim_match(A1, A2, _).
  333
  334atom_prefix(Atom, Prefix) :-
  335    sub_atom(Atom, 0, _, _, Prefix).
  336
  337
  338                /********************************
  339                *             SOURCE            *
  340                *********************************/
 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.

  353source_file(File) :-
  354    (   current_prolog_flag(access_level, user)
  355    ->  Level = user
  356    ;   true
  357    ),
  358    (   ground(File)
  359    ->  (   '$time_source_file'(File, Time, Level)
  360        ;   absolute_file_name(File, Abs),
  361            '$time_source_file'(Abs, Time, Level)
  362        ), !
  363    ;   '$time_source_file'(File, Time, Level)
  364    ),
  365    Time > 0.0.
 source_file(+Head, -File) is semidet
source_file(?Head, ?File) is nondet
True when Head is a predicate owned by File.
  372:- meta_predicate source_file(:, ?).  373
  374source_file(M:Head, File) :-
  375    nonvar(M), nonvar(Head),
  376    !,
  377    (   '$c_current_predicate'(_, M:Head),
  378        predicate_property(M:Head, multifile)
  379    ->  multi_source_files(M:Head, Files),
  380        '$member'(File, Files)
  381    ;   '$source_file'(M:Head, File)
  382    ).
  383source_file(M:Head, File) :-
  384    (   nonvar(File)
  385    ->  true
  386    ;   source_file(File)
  387    ),
  388    '$source_file_predicates'(File, Predicates),
  389    '$member'(M:Head, Predicates).
  390
  391:- thread_local found_src_file/1.  392
  393multi_source_files(Head, Files) :-
  394    call_cleanup(
  395        findall(File, multi_source_file(Head, File), Files),
  396        retractall(found_src_file(_))).
  397
  398multi_source_file(Head, File) :-
  399    nth_clause(Head, _, Clause),
  400    clause_property(Clause, source(File)),
  401    \+ found_src_file(File),
  402    asserta(found_src_file(File)).
 source_file_property(?File, ?Property) is nondet
True if Property is a property of the loaded source-file File.
  409source_file_property(File, P) :-
  410    nonvar(File),
  411    !,
  412    canonical_source_file(File, Path),
  413    property_source_file(P, Path).
  414source_file_property(File, P) :-
  415    property_source_file(P, File).
  416
  417property_source_file(modified(Time), File) :-
  418    '$time_source_file'(File, Time, user).
  419property_source_file(source(Source), File) :-
  420    (   '$source_file_property'(File, from_state, true)
  421    ->  Source = state
  422    ;   '$source_file_property'(File, resource, true)
  423    ->  Source = resource
  424    ;   Source = file
  425    ).
  426property_source_file(module(M), File) :-
  427    (   nonvar(M)
  428    ->  '$current_module'(M, File)
  429    ;   nonvar(File)
  430    ->  '$current_module'(ML, File),
  431        (   atom(ML)
  432        ->  M = ML
  433        ;   '$member'(M, ML)
  434        )
  435    ;   '$current_module'(M, File)
  436    ).
  437property_source_file(load_context(Module, Location, Options), File) :-
  438    '$time_source_file'(File, _, user),
  439    clause(system:'$load_context_module'(File, Module, Options), true, Ref),
  440    (   clause_property(Ref, file(FromFile)),
  441        clause_property(Ref, line_count(FromLine))
  442    ->  Location = FromFile:FromLine
  443    ;   Location = user
  444    ).
  445property_source_file(includes(Master, Stamp), File) :-
  446    system:'$included'(File, _Line, Master, Stamp).
  447property_source_file(included_in(Master, Line), File) :-
  448    system:'$included'(Master, Line, File, _).
  449property_source_file(derived_from(DerivedFrom, Stamp), File) :-
  450    system:'$derived_source'(File, DerivedFrom, Stamp).
  451property_source_file(reloading, File) :-
  452    source_file(File),
  453    '$source_file_property'(File, reloading, true).
  454property_source_file(load_count(Count), File) :-
  455    source_file(File),
  456    '$source_file_property'(File, load_count, Count).
  457property_source_file(number_of_clauses(Count), File) :-
  458    source_file(File),
  459    '$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.
  466canonical_source_file(Spec, File) :-
  467    atom(Spec),
  468    '$time_source_file'(Spec, _, _),
  469    !,
  470    File = Spec.
  471canonical_source_file(Spec, File) :-
  472    system:'$included'(_Master, _Line, Spec, _),
  473    !,
  474    File = Spec.
  475canonical_source_file(Spec, File) :-
  476    absolute_file_name(Spec,
  477                           [ file_type(prolog),
  478                             access(read),
  479                             file_errors(fail)
  480                           ],
  481                           File),
  482    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.
  499exists_source(Source) :-
  500    exists_source(Source, _Path).
  501
  502exists_source(Source, Path) :-
  503    absolute_file_name(Source, Path,
  504                       [ file_type(prolog),
  505                         access(read),
  506                         file_errors(fail)
  507                       ]).
 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.
  516prolog_load_context(module, Module) :-
  517    '$current_source_module'(Module).
  518prolog_load_context(file, File) :-
  519    input_file(File).
  520prolog_load_context(source, F) :-       % SICStus compatibility
  521    input_file(F0),
  522    '$input_context'(Context),
  523    '$top_file'(Context, F0, F).
  524prolog_load_context(stream, S) :-
  525    (   system:'$load_input'(_, S0)
  526    ->  S = S0
  527    ).
  528prolog_load_context(directory, D) :-
  529    input_file(F),
  530    file_directory_name(F, D).
  531prolog_load_context(dialect, D) :-
  532    current_prolog_flag(emulated_dialect, D).
  533prolog_load_context(term_position, TermPos) :-
  534    source_location(_, L),
  535    (   nb_current('$term_position', Pos),
  536        compound(Pos),              % actually set
  537        stream_position_data(line_count, Pos, L)
  538    ->  TermPos = Pos
  539    ;   TermPos = '$stream_position'(0,L,0,0)
  540    ).
  541prolog_load_context(script, Bool) :-
  542    (   '$toplevel':loaded_init_file(script, Path),
  543        input_file(File),
  544        same_file(File, Path)
  545    ->  Bool = true
  546    ;   Bool = false
  547    ).
  548prolog_load_context(variable_names, Bindings) :-
  549    nb_current('$variable_names', Bindings).
  550prolog_load_context(term, Term) :-
  551    nb_current('$term', Term).
  552prolog_load_context(reloading, true) :-
  553    prolog_load_context(source, F),
  554    '$source_file_property'(F, reloading, true).
  555
  556input_file(File) :-
  557    (   system:'$load_input'(_, Stream)
  558    ->  stream_property(Stream, file_name(File))
  559    ),
  560    !.
  561input_file(File) :-
  562    source_location(File, _).
 unload_file(+File) is det
Remove all traces of loading file.
  569:- dynamic system:'$resolved_source_path'/2.  570
  571unload_file(File) :-
  572    (   canonical_source_file(File, Path)
  573    ->  '$unload_file'(Path),
  574        retractall(system:'$resolved_source_path'(_, Path))
  575    ;   true
  576    ).
  577
  578		 /*******************************
  579		 *      FOREIGN LIBRARIES	*
  580		 *******************************/
 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.

  599use_foreign_library(FileSpec) :-
  600    ensure_shlib,
  601    initialization(shlib:load_foreign_library(FileSpec), now).
  602
  603use_foreign_library(FileSpec, Entry) :-
  604    ensure_shlib,
  605    initialization(shlib:load_foreign_library(FileSpec, Entry), now).
  606
  607ensure_shlib :-
  608    '$get_predicate_attribute'(shlib:load_foreign_library(_), defined, 1),
  609    '$get_predicate_attribute'(shlib:load_foreign_library(_,_), defined, 1),
  610    !.
  611ensure_shlib :-
  612    use_module(library(shlib), []).
  613
  614
  615                 /*******************************
  616                 *            STREAMS           *
  617                 *******************************/
 stream_position_data(?Field, +Pos, ?Date)
Extract values from stream position objects. '$stream_position' is of the format '$stream_position'(Byte, Char, Line, LinePos)
  624stream_position_data(Prop, Term, Value) :-
  625    nonvar(Prop),
  626    !,
  627    (   stream_position_field(Prop, Pos)
  628    ->  arg(Pos, Term, Value)
  629    ;   throw(error(domain_error(stream_position_data, Prop)))
  630    ).
  631stream_position_data(Prop, Term, Value) :-
  632    stream_position_field(Prop, Pos),
  633    arg(Pos, Term, Value).
  634
  635stream_position_field(char_count,    1).
  636stream_position_field(line_count,    2).
  637stream_position_field(line_position, 3).
  638stream_position_field(byte_count,    4).
  639
  640
  641                 /*******************************
  642                 *            CONTROL           *
  643                 *******************************/
 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.
  651:- meta_predicate
  652    call_with_depth_limit(0, +, -).  653
  654call_with_depth_limit(G, Limit, Result) :-
  655    '$depth_limit'(Limit, OLimit, OReached),
  656    (   catch(G, E, '$depth_limit_except'(OLimit, OReached, E)),
  657        '$depth_limit_true'(Limit, OLimit, OReached, Result, Det),
  658        ( Det == ! -> ! ; true )
  659    ;   '$depth_limit_false'(OLimit, OReached, Result)
  660    ).
 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.

  674:- meta_predicate
  675    call_with_inference_limit(0, +, -).  676
  677call_with_inference_limit(G, Limit, Result) :-
  678    '$inference_limit'(Limit, OLimit),
  679    (   catch(G, Except,
  680              system:'$inference_limit_except'(OLimit, Except, Result0)),
  681        system:'$inference_limit_true'(Limit, OLimit, Result0),
  682        ( Result0 == ! -> ! ; true ),
  683        Result = Result0
  684    ;   system:'$inference_limit_false'(OLimit)
  685    ).
  686
  687
  688                /********************************
  689                *           DATA BASE           *
  690                *********************************/
  691
  692/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  693The predicate current_predicate/2 is   a  difficult subject since  the
  694introduction  of defaulting     modules   and   dynamic     libraries.
  695current_predicate/2 is normally  called with instantiated arguments to
  696verify some  predicate can   be called without trapping   an undefined
  697predicate.  In this case we must  perform the search algorithm used by
  698the prolog system itself.
  699
  700If the pattern is not fully specified, we only generate the predicates
  701actually available in this  module.   This seems the best for listing,
  702etc.
  703- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  704
  705
  706:- meta_predicate
  707    current_predicate(?, :),
  708    '$defined_predicate'(:).  709
  710current_predicate(Name, Module:Head) :-
  711    (var(Module) ; var(Head)),
  712    !,
  713    generate_current_predicate(Name, Module, Head).
  714current_predicate(Name, Term) :-
  715    '$c_current_predicate'(Name, Term),
  716    '$defined_predicate'(Term),
  717    !.
  718current_predicate(Name, Module:Head) :-
  719    default_module(Module, DefModule),
  720    '$c_current_predicate'(Name, DefModule:Head),
  721    '$defined_predicate'(DefModule:Head),
  722    !.
  723current_predicate(Name, Module:Head) :-
  724    '$autoload':autoload_in(Module, general),
  725    \+ current_prolog_flag(Module:unknown, fail),
  726    (   compound(Head)
  727    ->  compound_name_arity(Head, Name, Arity)
  728    ;   Name = Head, Arity = 0
  729    ),
  730    '$find_library'(Module, Name, Arity, _LoadModule, _Library),
  731    !.
  732
  733generate_current_predicate(Name, Module, Head) :-
  734    current_module(Module),
  735    QHead = Module:Head,
  736    '$c_current_predicate'(Name, QHead),
  737    '$get_predicate_attribute'(QHead, defined, 1).
  738
  739'$defined_predicate'(Head) :-
  740    '$get_predicate_attribute'(Head, defined, 1),
  741    !.
 predicate_property(?Predicate, ?Property) is nondet
True when Property is a property of Predicate.
  747:- meta_predicate
  748    predicate_property(:, ?).  749
  750:- multifile
  751    '$predicate_property'/2.  752
  753:- '$iso'(predicate_property/2).  754
  755predicate_property(Pred, Property) :-           % Mode ?,+
  756    nonvar(Property),
  757    !,
  758    property_predicate(Property, Pred).
  759predicate_property(Pred, Property) :-           % Mode +,-
  760    define_or_generate(Pred),
  761    '$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.
  769property_predicate(undefined, Pred) :-
  770    !,
  771    Pred = Module:Head,
  772    current_module(Module),
  773    '$c_current_predicate'(_, Pred),
  774    \+ '$defined_predicate'(Pred),          % Speed up a bit
  775    \+ current_predicate(_, Pred),
  776    goal_name_arity(Head, Name, Arity),
  777    \+ system_undefined(Module:Name/Arity).
  778property_predicate(visible, Pred) :-
  779    !,
  780    visible_predicate(Pred).
  781property_predicate(autoload(File), Head) :-
  782    !,
  783    \+ current_prolog_flag(autoload, false),
  784    '$autoload':autoloadable(Head, File).
  785property_predicate(implementation_module(IM), M:Head) :-
  786    !,
  787    atom(M),
  788    (   default_module(M, DM),
  789        '$get_predicate_attribute'(DM:Head, defined, 1)
  790    ->  (   '$get_predicate_attribute'(DM:Head, imported, ImportM)
  791        ->  IM = ImportM
  792        ;   IM = M
  793        )
  794    ;   \+ current_prolog_flag(M:unknown, fail),
  795        goal_name_arity(Head, Name, Arity),
  796        '$find_library'(_, Name, Arity, LoadModule, _File)
  797    ->  IM = LoadModule
  798    ;   M = IM
  799    ).
  800property_predicate(iso, _:Head) :-
  801    callable(Head),
  802    !,
  803    goal_name_arity(Head, Name, Arity),
  804    current_predicate(system:Name/Arity),
  805    '$predicate_property'(iso, system:Head).
  806property_predicate(built_in, Module:Head) :-
  807    callable(Head),
  808    !,
  809    goal_name_arity(Head, Name, Arity),
  810    current_predicate(Module:Name/Arity),
  811    '$predicate_property'(built_in, Module:Head).
  812property_predicate(Property, Pred) :-
  813    define_or_generate(Pred),
  814    '$predicate_property'(Property, Pred).
  815
  816goal_name_arity(Head, Name, Arity) :-
  817    compound(Head),
  818    !,
  819    compound_name_arity(Head, Name, Arity).
  820goal_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.
  829define_or_generate(M:Head) :-
  830    callable(Head),
  831    atom(M),
  832    '$get_predicate_attribute'(M:Head, defined, 1),
  833    !.
  834define_or_generate(M:Head) :-
  835    callable(Head),
  836    nonvar(M), M \== system,
  837    !,
  838    '$define_predicate'(M:Head).
  839define_or_generate(Pred) :-
  840    current_predicate(_, Pred),
  841    '$define_predicate'(Pred).
  842
  843
  844'$predicate_property'(interpreted, Pred) :-
  845    '$get_predicate_attribute'(Pred, foreign, 0).
  846'$predicate_property'(visible, Pred) :-
  847    '$get_predicate_attribute'(Pred, defined, 1).
  848'$predicate_property'(built_in, Pred) :-
  849    '$get_predicate_attribute'(Pred, system, 1).
  850'$predicate_property'(exported, Pred) :-
  851    '$get_predicate_attribute'(Pred, exported, 1).
  852'$predicate_property'(public, Pred) :-
  853    '$get_predicate_attribute'(Pred, public, 1).
  854'$predicate_property'(non_terminal, Pred) :-
  855    '$get_predicate_attribute'(Pred, non_terminal, 1).
  856'$predicate_property'(foreign, Pred) :-
  857    '$get_predicate_attribute'(Pred, foreign, 1).
  858'$predicate_property'((dynamic), Pred) :-
  859    '$get_predicate_attribute'(Pred, (dynamic), 1).
  860'$predicate_property'((static), Pred) :-
  861    '$get_predicate_attribute'(Pred, (dynamic), 0).
  862'$predicate_property'((volatile), Pred) :-
  863    '$get_predicate_attribute'(Pred, (volatile), 1).
  864'$predicate_property'((thread_local), Pred) :-
  865    '$get_predicate_attribute'(Pred, (thread_local), 1).
  866'$predicate_property'((multifile), Pred) :-
  867    '$get_predicate_attribute'(Pred, (multifile), 1).
  868'$predicate_property'(imported_from(Module), Pred) :-
  869    '$get_predicate_attribute'(Pred, imported, Module).
  870'$predicate_property'(transparent, Pred) :-
  871    '$get_predicate_attribute'(Pred, transparent, 1).
  872'$predicate_property'(meta_predicate(Pattern), Pred) :-
  873    '$get_predicate_attribute'(Pred, meta_predicate, Pattern).
  874'$predicate_property'(file(File), Pred) :-
  875    '$get_predicate_attribute'(Pred, file, File).
  876'$predicate_property'(line_count(LineNumber), Pred) :-
  877    '$get_predicate_attribute'(Pred, line_count, LineNumber).
  878'$predicate_property'(notrace, Pred) :-
  879    '$get_predicate_attribute'(Pred, trace, 0).
  880'$predicate_property'(nodebug, Pred) :-
  881    '$get_predicate_attribute'(Pred, hide_childs, 1).
  882'$predicate_property'(spying, Pred) :-
  883    '$get_predicate_attribute'(Pred, spy, 1).
  884'$predicate_property'(number_of_clauses(N), Pred) :-
  885    '$get_predicate_attribute'(Pred, number_of_clauses, N).
  886'$predicate_property'(number_of_rules(N), Pred) :-
  887    '$get_predicate_attribute'(Pred, number_of_rules, N).
  888'$predicate_property'(last_modified_generation(Gen), Pred) :-
  889    '$get_predicate_attribute'(Pred, last_modified_generation, Gen).
  890'$predicate_property'(indexed(Indices), Pred) :-
  891    '$get_predicate_attribute'(Pred, indexed, Indices).
  892'$predicate_property'(noprofile, Pred) :-
  893    '$get_predicate_attribute'(Pred, noprofile, 1).
  894'$predicate_property'(iso, Pred) :-
  895    '$get_predicate_attribute'(Pred, iso, 1).
  896'$predicate_property'(quasi_quotation_syntax, Pred) :-
  897    '$get_predicate_attribute'(Pred, quasi_quotation_syntax, 1).
  898'$predicate_property'(defined, Pred) :-
  899    '$get_predicate_attribute'(Pred, defined, 1).
  900'$predicate_property'(tabled, Pred) :-
  901    '$get_predicate_attribute'(Pred, tabled, 1).
  902'$predicate_property'(tabled(Flag), Pred) :-
  903    '$get_predicate_attribute'(Pred, tabled, 1),
  904    table_flag(Flag, Pred).
  905'$predicate_property'(incremental, Pred) :-
  906    '$get_predicate_attribute'(Pred, incremental, 1).
  907'$predicate_property'(abstract(N), Pred) :-
  908    '$get_predicate_attribute'(Pred, abstract, N).
  909'$predicate_property'(size(Bytes), Pred) :-
  910    '$get_predicate_attribute'(Pred, size, Bytes).
  911
  912system_undefined(user:prolog_trace_interception/4).
  913system_undefined(user:prolog_exception_hook/4).
  914system_undefined(system:'$c_call_prolog'/0).
  915system_undefined(system:window_title/2).
  916
  917table_flag(variant, Pred) :-
  918    '$tbl_implementation'(Pred, M:Head),
  919    M:'$tabled'(Head, variant).
  920table_flag(subsumptive, Pred) :-
  921    '$tbl_implementation'(Pred, M:Head),
  922    M:'$tabled'(Head, subsumptive).
  923table_flag(shared, Pred) :-
  924    '$get_predicate_attribute'(Pred, tshared, 1).
  925table_flag(incremental, Pred) :-
  926    '$get_predicate_attribute'(Pred, incremental, 1).
  927table_flag(monotonic, Pred) :-
  928    '$get_predicate_attribute'(Pred, monotonic, 1).
  929table_flag(subgoal_abstract(N), Pred) :-
  930    '$get_predicate_attribute'(Pred, subgoal_abstract, N).
  931table_flag(answer_abstract(N), Pred) :-
  932    '$get_predicate_attribute'(Pred, subgoal_abstract, N).
  933table_flag(subgoal_abstract(N), Pred) :-
  934    '$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.
  943visible_predicate(Pred) :-
  944    Pred = M:Head,
  945    current_module(M),
  946    (   callable(Head)
  947    ->  (   '$get_predicate_attribute'(Pred, defined, 1)
  948        ->  true
  949        ;   \+ current_prolog_flag(M:unknown, fail),
  950            functor(Head, Name, Arity),
  951            '$find_library'(M, Name, Arity, _LoadModule, _Library)
  952        )
  953    ;   setof(PI, visible_in_module(M, PI), PIs),
  954        '$member'(Name/Arity, PIs),
  955        functor(Head, Name, Arity)
  956    ).
  957
  958visible_in_module(M, Name/Arity) :-
  959    default_module(M, DefM),
  960    DefHead = DefM:Head,
  961    '$c_current_predicate'(_, DefHead),
  962    '$get_predicate_attribute'(DefHead, defined, 1),
  963    \+ hidden_system_predicate(Head),
  964    functor(Head, Name, Arity).
  965visible_in_module(_, Name/Arity) :-
  966    '$in_library'(Name, Arity, _).
  967
  968hidden_system_predicate(Head) :-
  969    functor(Head, Name, _),
  970    atom(Name),                     % Avoid [].
  971    sub_atom(Name, 0, _, _, $),
  972    \+ 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.
  997clause_property(Clause, Property) :-
  998    '$clause_property'(Property, Clause).
  999
 1000'$clause_property'(line_count(LineNumber), Clause) :-
 1001    '$get_clause_attribute'(Clause, line_count, LineNumber).
 1002'$clause_property'(file(File), Clause) :-
 1003    '$get_clause_attribute'(Clause, file, File).
 1004'$clause_property'(source(File), Clause) :-
 1005    '$get_clause_attribute'(Clause, owner, File).
 1006'$clause_property'(size(Bytes), Clause) :-
 1007    '$get_clause_attribute'(Clause, size, Bytes).
 1008'$clause_property'(fact, Clause) :-
 1009    '$get_clause_attribute'(Clause, fact, true).
 1010'$clause_property'(erased, Clause) :-
 1011    '$get_clause_attribute'(Clause, erased, true).
 1012'$clause_property'(predicate(PI), Clause) :-
 1013    '$get_clause_attribute'(Clause, predicate_indicator, PI).
 1014'$clause_property'(module(M), Clause) :-
 1015    '$get_clause_attribute'(Clause, module, M).
 dynamic(:Predicates, +Options) is det
Define a predicate as dynamic with optionally additional properties. Defined options are:
 1029dynamic(M:Predicates, Options) :-
 1030    '$must_be'(list, Predicates),
 1031    options_properties(Options, Props),
 1032    set_pprops(Predicates, M, [dynamic|Props]).
 1033
 1034set_pprops([], _, _).
 1035set_pprops([H|T], M, Props) :-
 1036    set_pprops1(Props, M:H),
 1037    strip_module(M:H, M2, P),
 1038    '$pi_head'(M2:P, Pred),
 1039    '$set_table_wrappers'(Pred),
 1040    set_pprops(T, M, Props).
 1041
 1042set_pprops1([], _).
 1043set_pprops1([H|T], P) :-
 1044    (   atom(H)
 1045    ->  '$set_predicate_attribute'(P, H, true)
 1046    ;   H =.. [Name,Value]
 1047    ->  '$set_predicate_attribute'(P, Name, Value)
 1048    ),
 1049    set_pprops1(T, P).
 1050
 1051options_properties(Options, Props) :-
 1052    G = opt_prop(_,_,_,_),
 1053    findall(G, G, Spec),
 1054    options_properties(Spec, Options, Props).
 1055
 1056options_properties([], _, []).
 1057options_properties([opt_prop(Name, Type, SetValue, Prop)|T],
 1058                   Options, [Prop|PT]) :-
 1059    Opt =.. [Name,V],
 1060    '$option'(Opt, Options),
 1061    '$must_be'(Type, V),
 1062    V = SetValue,
 1063    !,
 1064    options_properties(T, Options, PT).
 1065options_properties([_|T], Options, PT) :-
 1066    options_properties(T, Options, PT).
 1067
 1068opt_prop(incremental,   boolean,               Bool,  incremental(Bool)).
 1069opt_prop(abstract,      between(0,0),          0,     abstract).
 1070opt_prop(multifile,     boolean,               true,  multifile).
 1071opt_prop(discontiguous, boolean,               true,  discontiguous).
 1072opt_prop(volatile,      boolean,               true,  volatile).
 1073opt_prop(thread,        oneof(atom, [local,shared],[local,shared]),
 1074                                               local, thread_local).
 1075
 1076                /********************************
 1077                *            MODULES            *
 1078                *********************************/
 current_module(?Module) is nondet
True if Module is a currently defined module.
 1084current_module(Module) :-
 1085    '$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.
 1101module_property(Module, Property) :-
 1102    nonvar(Module), nonvar(Property),
 1103    !,
 1104    property_module(Property, Module).
 1105module_property(Module, Property) :-    % -, file(File)
 1106    nonvar(Property), Property = file(File),
 1107    !,
 1108    (   nonvar(File)
 1109    ->  '$current_module'(Modules, File),
 1110        (   atom(Modules)
 1111        ->  Module = Modules
 1112        ;   '$member'(Module, Modules)
 1113        )
 1114    ;   '$current_module'(Module, File),
 1115        File \== []
 1116    ).
 1117module_property(Module, Property) :-
 1118    current_module(Module),
 1119    property_module(Property, Module).
 1120
 1121property_module(Property, Module) :-
 1122    module_property(Property),
 1123    (   Property = exported_operators(List)
 1124    ->  '$exported_ops'(Module, List, [])
 1125    ;   '$module_property'(Module, Property)
 1126    ).
 1127
 1128module_property(class(_)).
 1129module_property(file(_)).
 1130module_property(line_count(_)).
 1131module_property(exports(_)).
 1132module_property(exported_operators(_)).
 1133module_property(size(_)).
 1134module_property(program_size(_)).
 1135module_property(program_space(_)).
 1136module_property(last_modified_generation(_)).
 module(+Module) is det
Set the module that is associated to the toplevel to Module.
 1142module(Module) :-
 1143    atom(Module),
 1144    current_module(Module),
 1145    !,
 1146    '$set_typein_module'(Module).
 1147module(Module) :-
 1148    '$set_typein_module'(Module),
 1149    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.
 1156working_directory(Old, New) :-
 1157    '$cwd'(Old),
 1158    (   Old == New
 1159    ->  true
 1160    ;   '$chdir'(New)
 1161    ).
 1162
 1163
 1164                 /*******************************
 1165                 *            TRIES             *
 1166                 *******************************/
 current_trie(?Trie) is nondet
True if Trie is the handle of an existing trie.
 1172current_trie(Trie) :-
 1173    current_blob(Trie, trie),
 1174    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
 1210trie_property(Trie, Property) :-
 1211    current_trie(Trie),
 1212    trie_property(Property),
 1213    '$trie_property'(Trie, Property).
 1214
 1215trie_property(node_count(_)).
 1216trie_property(value_count(_)).
 1217trie_property(size(_)).
 1218trie_property(hashed(_)).
 1219trie_property(compiled_size(_)).
 1220                                                % below only when -DO_TRIE_STATS
 1221trie_property(lookup_count(_)).                 % is enabled in pl-trie.h
 1222trie_property(gen_call_count(_)).
 1223trie_property(invalidated(_)).                  % IDG stats
 1224trie_property(reevaluated(_)).
 1225trie_property(deadlock(_)).                     % Shared tabling stats
 1226trie_property(wait(_)).
 1227trie_property(idg_affected_count(_)).
 1228trie_property(idg_dependent_count(_)).
 1229trie_property(idg_size(_)).
 1230
 1231
 1232                /********************************
 1233                *      SYSTEM INTERACTION       *
 1234                *********************************/
 1235
 1236shell(Command) :-
 1237    shell(Command, 0).
 1238
 1239
 1240                 /*******************************
 1241                 *            SIGNALS           *
 1242                 *******************************/
 1243
 1244:- meta_predicate
 1245    on_signal(+, :, :),
 1246    current_signal(?, ?, :).
 on_signal(+Signal, -OldHandler, :NewHandler) is det
 1250on_signal(Signal, Old, New) :-
 1251    atom(Signal),
 1252    !,
 1253    '$on_signal'(_Num, Signal, Old, New).
 1254on_signal(Signal, Old, New) :-
 1255    integer(Signal),
 1256    !,
 1257    '$on_signal'(Signal, _Name, Old, New).
 1258on_signal(Signal, _Old, _New) :-
 1259    '$type_error'(signal_name, Signal).
 current_signal(?Name, ?SignalNumber, :Handler) is nondet
 1263current_signal(Name, Id, Handler) :-
 1264    between(1, 32, Id),
 1265    '$on_signal'(Id, Name, Handler, Handler).
 1266
 1267:- multifile
 1268    prolog:called_by/2. 1269
 1270prolog:called_by(on_signal(_,_,New), [New+1]) :-
 1271    (   new == throw
 1272    ;   new == default
 1273    ), !, fail.
 1274
 1275
 1276                 /*******************************
 1277                 *            DLOPEN            *
 1278                 *******************************/
 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.
 1292open_shared_object(File, Handle) :-
 1293    open_shared_object(File, Handle, []). % use pl-load.c defaults
 1294
 1295open_shared_object(File, Handle, Flags) :-
 1296    (   is_list(Flags)
 1297    ->  true
 1298    ;   throw(error(type_error(list, Flags), _))
 1299    ),
 1300    map_dlflags(Flags, Mask),
 1301    '$open_shared_object'(File, Handle, Mask).
 1302
 1303dlopen_flag(now,        2'01).          % see pl-load.c for these constants
 1304dlopen_flag(global,     2'10).          % Solaris only
 1305
 1306map_dlflags([], 0).
 1307map_dlflags([F|T], M) :-
 1308    map_dlflags(T, M0),
 1309    (   dlopen_flag(F, I)
 1310    ->  true
 1311    ;   throw(error(domain_error(dlopen_flag, F), _))
 1312    ),
 1313    M is M0 \/ I.
 1314
 1315
 1316                 /*******************************
 1317                 *             I/O              *
 1318                 *******************************/
 1319
 1320format(Fmt) :-
 1321    format(Fmt, []).
 1322
 1323                 /*******************************
 1324                 *            FILES             *
 1325                 *******************************/
 absolute_file_name(+Term, -AbsoluteFile)
 1329absolute_file_name(Name, Abs) :-
 1330    atomic(Name),
 1331    !,
 1332    '$absolute_file_name'(Name, Abs).
 1333absolute_file_name(Term, Abs) :-
 1334    '$chk_file'(Term, [''], [access(read)], true, File),
 1335    !,
 1336    '$absolute_file_name'(File, Abs).
 1337absolute_file_name(Term, Abs) :-
 1338    '$chk_file'(Term, [''], [], true, File),
 1339    !,
 1340    '$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.
 1348tmp_file_stream(Enc, File, Stream) :-
 1349    atom(Enc), var(File), var(Stream),
 1350    !,
 1351    '$tmp_file_stream'('', Enc, File, Stream).
 1352tmp_file_stream(File, Stream, Options) :-
 1353    current_prolog_flag(encoding, DefEnc),
 1354    '$option'(encoding(Enc), Options, DefEnc),
 1355    '$option'(extension(Ext), Options, ''),
 1356    '$tmp_file_stream'(Ext, Enc, File, Stream),
 1357    set_stream(Stream, file_name(File)).
 1358
 1359
 1360                /********************************
 1361                *        MEMORY MANAGEMENT      *
 1362                *********************************/
 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.
 1371garbage_collect :-
 1372    '$garbage_collect'(0).
 set_prolog_stack(+Name, +Option) is det
Set a parameter for one of the Prolog stacks.
 1378set_prolog_stack(Stack, Option) :-
 1379    Option =.. [Name,Value0],
 1380    Value is Value0,
 1381    '$set_prolog_stack'(Stack, Name, _Old, Value).
 prolog_stack_property(?Stack, ?Property) is nondet
Examine stack properties.
 1387prolog_stack_property(Stack, Property) :-
 1388    stack_property(P),
 1389    stack_name(Stack),
 1390    Property =.. [P,Value],
 1391    '$set_prolog_stack'(Stack, P, Value, Value).
 1392
 1393stack_name(local).
 1394stack_name(global).
 1395stack_name(trail).
 1396
 1397stack_property(limit).
 1398stack_property(spare).
 1399stack_property(min_free).
 1400stack_property(low).
 1401stack_property(factor).
 1402
 1403
 1404                 /*******************************
 1405                 *             TERM             *
 1406                 *******************************/
 1407
 1408:- '$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.
 1416numbervars(Term, From, To) :-
 1417    numbervars(Term, From, To, []).
 1418
 1419
 1420                 /*******************************
 1421                 *            STRING            *
 1422                 *******************************/
 term_string(?Term, ?String, +Options)
Parse/write a term from/to a string using Options.
 1428term_string(Term, String, Options) :-
 1429    nonvar(String),
 1430    !,
 1431    read_term_from_atom(String, Term, Options).
 1432term_string(Term, String, Options) :-
 1433    (   '$option'(quoted(_), Options)
 1434    ->  Options1 = Options
 1435    ;   '$merge_options'(_{quoted:true}, Options, Options1)
 1436    ),
 1437    format(string(String), '~W', [Term, Options1]).
 1438
 1439
 1440                 /*******************************
 1441                 *             GVAR             *
 1442                 *******************************/
 nb_setval(+Name, +Value) is det
Bind the non-backtrackable variable Name with a copy of Value
 1448nb_setval(Name, Value) :-
 1449    duplicate_term(Value, Copy),
 1450    nb_linkval(Name, Copy).
 1451
 1452
 1453		 /*******************************
 1454		 *            THREADS		*
 1455		 *******************************/
 1456
 1457:- meta_predicate
 1458    thread_create(0, -).
 thread_create(:Goal, -Id)
Shorthand for thread_create(Goal, Id, []).
 1464thread_create(Goal, Id) :-
 1465    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.
 1474thread_join(Id) :-
 1475    thread_join(Id, Status),
 1476    (   Status == true
 1477    ->  true
 1478    ;   throw(error(thread_error(Id, Status), _))
 1479    ).
 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.
 1496set_prolog_gc_thread(Status) :-
 1497    var(Status),
 1498    !,
 1499    '$instantiation_error'(Status).
 1500set_prolog_gc_thread(false) :-
 1501    !,
 1502    set_prolog_flag(gc_thread, false),
 1503    (   current_prolog_flag(threads, true)
 1504    ->  (   '$gc_stop'
 1505        ->  thread_join(gc)
 1506        ;   true
 1507        )
 1508    ;   true
 1509    ).
 1510set_prolog_gc_thread(true) :-
 1511    !,
 1512    set_prolog_flag(gc_thread, true).
 1513set_prolog_gc_thread(stop) :-
 1514    !,
 1515    (   current_prolog_flag(threads, true)
 1516    ->  (   '$gc_stop'
 1517        ->  thread_join(gc)
 1518        ;   true
 1519        )
 1520    ;   true
 1521    ).
 1522set_prolog_gc_thread(Status) :-
 1523    '$domain_error'(gc_thread, Status).
 transaction(:Goal)
 snapshot(:Goal)
Wrappers to guarantee clean Module:Goal terms.
 1530transaction(Goal) :-
 1531    '$transaction'(Goal).
 1532transaction(Goal, Constraint, Mutex) :-
 1533    '$transaction'(Goal, Constraint, Mutex).
 1534snapshot(Goal) :-
 1535    '$snapshot'(Goal).
 $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.
 1543:- meta_predicate
 1544    '$wrap_predicate'(:, +, -, -, +). 1545
 1546'$wrap_predicate'(M:Head, WName, Closure, call(Wrapped), Body) :-
 1547    callable_name_arguments(Head, PName, Args),
 1548    callable_name_arity(Head, PName, Arity),
 1549    (   is_most_general_term(Head)
 1550    ->  true
 1551    ;   '$domain_error'(most_general_term, Head)
 1552    ),
 1553    atomic_list_concat(['$wrap$', PName], WrapName),
 1554    volatile(M:WrapName/Arity),
 1555    module_transparent(M:WrapName/Arity),
 1556    WHead =.. [WrapName|Args],
 1557    '$c_wrap_predicate'(M:Head, WName, Closure, Wrapped, M:(WHead :- Body)).
 1558
 1559callable_name_arguments(Head, PName, Args) :-
 1560    atom(Head),
 1561    !,
 1562    PName = Head,
 1563    Args = [].
 1564callable_name_arguments(Head, PName, Args) :-
 1565    compound_name_arguments(Head, PName, Args).
 1566
 1567callable_name_arity(Head, PName, Arity) :-
 1568    atom(Head),
 1569    !,
 1570    PName = Head,
 1571    Arity = 0.
 1572callable_name_arity(Head, PName, Arity) :-
 1573    compound_name_arity(Head, PName, Arity)