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            set_prolog_gc_thread/1,		% +Status
   89
   90            '$wrap_predicate'/5                 % :Head, +Name, -Closure, -Wrapped, +Body
   91          ]).   92
   93:- meta_predicate
   94    dynamic(:, +),
   95    use_foreign_library(:),
   96    use_foreign_library(:, +).   97
   98
   99                /********************************
  100                *           DEBUGGER            *
  101                *********************************/
 map_bits(:Pred, +Modify, +OldBits, -NewBits)
  105:- meta_predicate
  106    map_bits(2, +, +, -).  107
  108map_bits(_, Var, _, _) :-
  109    var(Var),
  110    !,
  111    '$instantiation_error'(Var).
  112map_bits(_, [], Bits, Bits) :- !.
  113map_bits(Pred, [H|T], Old, New) :-
  114    map_bits(Pred, H, Old, New0),
  115    map_bits(Pred, T, New0, New).
  116map_bits(Pred, +Name, Old, New) :-     % set a bit
  117    !,
  118    bit(Pred, Name, Bits),
  119    !,
  120    New is Old \/ Bits.
  121map_bits(Pred, -Name, Old, New) :-     % clear a bit
  122    !,
  123    bit(Pred, Name, Bits),
  124    !,
  125    New is Old /\ (\Bits).
  126map_bits(Pred, ?(Name), Old, Old) :-   % ask a bit
  127    !,
  128    bit(Pred, Name, Bits),
  129    Old /\ Bits > 0.
  130map_bits(_, Term, _, _) :-
  131    '$type_error'('+|-|?(Flag)', Term).
  132
  133bit(Pred, Name, Bits) :-
  134    call(Pred, Name, Bits),
  135    !.
  136bit(_:Pred, Name, _) :-
  137    '$domain_error'(Pred, Name).
  138
  139:- public port_name/2.                  % used by library(test_cover)
  140
  141port_name(      call, 2'000000001).
  142port_name(      exit, 2'000000010).
  143port_name(      fail, 2'000000100).
  144port_name(      redo, 2'000001000).
  145port_name(     unify, 2'000010000).
  146port_name(     break, 2'000100000).
  147port_name(  cut_call, 2'001000000).
  148port_name(  cut_exit, 2'010000000).
  149port_name( exception, 2'100000000).
  150port_name(       cut, 2'011000000).
  151port_name(       all, 2'000111111).
  152port_name(      full, 2'000101111).
  153port_name(      half, 2'000101101).     % '
  154
  155leash(Ports) :-
  156    '$leash'(Old, Old),
  157    map_bits(port_name, Ports, Old, New),
  158    '$leash'(_, New).
  159
  160visible(Ports) :-
  161    '$visible'(Old, Old),
  162    map_bits(port_name, Ports, Old, New),
  163    '$visible'(_, New).
  164
  165style_name(atom,            0x0001) :-
  166    print_message(warning, decl_no_effect(style_check(atom))).
  167style_name(singleton,       0x0042).            % semantic and syntactic
  168style_name(discontiguous,   0x0008).
  169style_name(charset,         0x0020).
  170style_name(no_effect,       0x0080).
  171style_name(var_branches,    0x0100).
 style_check(+Spec) is nondet
  175style_check(Var) :-
  176    var(Var),
  177    !,
  178    '$instantiation_error'(Var).
  179style_check(?(Style)) :-
  180    !,
  181    (   var(Style)
  182    ->  enum_style_check(Style)
  183    ;   enum_style_check(Style)
  184    ->  true
  185    ).
  186style_check(Spec) :-
  187    '$style_check'(Old, Old),
  188    map_bits(style_name, Spec, Old, New),
  189    '$style_check'(_, New).
  190
  191enum_style_check(Style) :-
  192    '$style_check'(Bits, Bits),
  193    style_name(Style, Bit),
  194    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.
  203:- multifile
  204    prolog:debug_control_hook/1.    % +Action
  205
  206:- meta_predicate
  207    spy(:),
  208    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.
  225spy(_:X) :-
  226    var(X),
  227    throw(error(instantiation_error, _)).
  228spy(_:[]) :- !.
  229spy(M:[H|T]) :-
  230    !,
  231    spy(M:H),
  232    spy(M:T).
  233spy(Spec) :-
  234    notrace(prolog:debug_control_hook(spy(Spec))),
  235    !.
  236spy(Spec) :-
  237    '$find_predicate'(Spec, Preds),
  238    '$member'(PI, Preds),
  239        pi_to_head(PI, Head),
  240        '$define_predicate'(Head),
  241        '$spy'(Head),
  242    fail.
  243spy(_).
  244
  245nospy(_:X) :-
  246    var(X),
  247    throw(error(instantiation_error, _)).
  248nospy(_:[]) :- !.
  249nospy(M:[H|T]) :-
  250    !,
  251    nospy(M:H),
  252    nospy(M:T).
  253nospy(Spec) :-
  254    notrace(prolog:debug_control_hook(nospy(Spec))),
  255    !.
  256nospy(Spec) :-
  257    '$find_predicate'(Spec, Preds),
  258    '$member'(PI, Preds),
  259         pi_to_head(PI, Head),
  260        '$nospy'(Head),
  261    fail.
  262nospy(_).
  263
  264nospyall :-
  265    notrace(prolog:debug_control_hook(nospyall)),
  266    fail.
  267nospyall :-
  268    spy_point(Head),
  269        '$nospy'(Head),
  270    fail.
  271nospyall.
  272
  273pi_to_head(M:PI, M:Head) :-
  274    !,
  275    pi_to_head(PI, Head).
  276pi_to_head(Name/Arity, Head) :-
  277    functor(Head, Name, Arity).
 debugging is det
Report current status of the debugger.
  283debugging :-
  284    notrace(prolog:debug_control_hook(debugging)),
  285    !.
  286debugging :-
  287    current_prolog_flag(debug, true),
  288    !,
  289    print_message(informational, debugging(on)),
  290    findall(H, spy_point(H), SpyPoints),
  291    print_message(informational, spying(SpyPoints)).
  292debugging :-
  293    print_message(informational, debugging(off)).
  294
  295spy_point(Module:Head) :-
  296    current_predicate(_, Module:Head),
  297    '$get_predicate_attribute'(Module:Head, spy, 1),
  298    \+ 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.
  305flag(Name, Old, New) :-
  306    Old == New,
  307    !,
  308    get_flag(Name, Old).
  309flag(Name, Old, New) :-
  310    with_mutex('$flag', update_flag(Name, Old, New)).
  311
  312update_flag(Name, Old, New) :-
  313    get_flag(Name, Old),
  314    (   atom(New)
  315    ->  set_flag(Name, New)
  316    ;   Value is New,
  317        set_flag(Name, Value)
  318    ).
  319
  320
  321                /********************************
  322                *             ATOMS             *
  323                *********************************/
  324
  325dwim_match(A1, A2) :-
  326    dwim_match(A1, A2, _).
  327
  328atom_prefix(Atom, Prefix) :-
  329    sub_atom(Atom, 0, _, _, Prefix).
  330
  331
  332                /********************************
  333                *             SOURCE            *
  334                *********************************/
 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.

  347source_file(File) :-
  348    (   current_prolog_flag(access_level, user)
  349    ->  Level = user
  350    ;   true
  351    ),
  352    (   ground(File)
  353    ->  (   '$time_source_file'(File, Time, Level)
  354        ;   absolute_file_name(File, Abs),
  355            '$time_source_file'(Abs, Time, Level)
  356        ), !
  357    ;   '$time_source_file'(File, Time, Level)
  358    ),
  359    Time > 0.0.
 source_file(+Head, -File) is semidet
source_file(?Head, ?File) is nondet
True when Head is a predicate owned by File.
  366:- meta_predicate source_file(:, ?).  367
  368source_file(M:Head, File) :-
  369    nonvar(M), nonvar(Head),
  370    !,
  371    (   '$c_current_predicate'(_, M:Head),
  372        predicate_property(M:Head, multifile)
  373    ->  multi_source_files(M:Head, Files),
  374        '$member'(File, Files)
  375    ;   '$source_file'(M:Head, File)
  376    ).
  377source_file(M:Head, File) :-
  378    (   nonvar(File)
  379    ->  true
  380    ;   source_file(File)
  381    ),
  382    '$source_file_predicates'(File, Predicates),
  383    '$member'(M:Head, Predicates).
  384
  385:- thread_local found_src_file/1.  386
  387multi_source_files(Head, Files) :-
  388    call_cleanup(
  389        findall(File, multi_source_file(Head, File), Files),
  390        retractall(found_src_file(_))).
  391
  392multi_source_file(Head, File) :-
  393    nth_clause(Head, _, Clause),
  394    clause_property(Clause, source(File)),
  395    \+ found_src_file(File),
  396    asserta(found_src_file(File)).
 source_file_property(?File, ?Property) is nondet
True if Property is a property of the loaded source-file File.
  403source_file_property(File, P) :-
  404    nonvar(File),
  405    !,
  406    canonical_source_file(File, Path),
  407    property_source_file(P, Path).
  408source_file_property(File, P) :-
  409    property_source_file(P, File).
  410
  411property_source_file(modified(Time), File) :-
  412    '$time_source_file'(File, Time, user).
  413property_source_file(source(Source), File) :-
  414    (   '$source_file_property'(File, from_state, true)
  415    ->  Source = state
  416    ;   '$source_file_property'(File, resource, true)
  417    ->  Source = resource
  418    ;   Source = file
  419    ).
  420property_source_file(module(M), File) :-
  421    (   nonvar(M)
  422    ->  '$current_module'(M, File)
  423    ;   nonvar(File)
  424    ->  '$current_module'(ML, File),
  425        (   atom(ML)
  426        ->  M = ML
  427        ;   '$member'(M, ML)
  428        )
  429    ;   '$current_module'(M, File)
  430    ).
  431property_source_file(load_context(Module, Location, Options), File) :-
  432    '$time_source_file'(File, _, user),
  433    clause(system:'$load_context_module'(File, Module, Options), true, Ref),
  434    (   clause_property(Ref, file(FromFile)),
  435        clause_property(Ref, line_count(FromLine))
  436    ->  Location = FromFile:FromLine
  437    ;   Location = user
  438    ).
  439property_source_file(includes(Master, Stamp), File) :-
  440    system:'$included'(File, _Line, Master, Stamp).
  441property_source_file(included_in(Master, Line), File) :-
  442    system:'$included'(Master, Line, File, _).
  443property_source_file(derived_from(DerivedFrom, Stamp), File) :-
  444    system:'$derived_source'(File, DerivedFrom, Stamp).
  445property_source_file(reloading, File) :-
  446    source_file(File),
  447    '$source_file_property'(File, reloading, true).
  448property_source_file(load_count(Count), File) :-
  449    source_file(File),
  450    '$source_file_property'(File, load_count, Count).
  451property_source_file(number_of_clauses(Count), File) :-
  452    source_file(File),
  453    '$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.
  460canonical_source_file(Spec, File) :-
  461    atom(Spec),
  462    '$time_source_file'(Spec, _, _),
  463    !,
  464    File = Spec.
  465canonical_source_file(Spec, File) :-
  466    system:'$included'(_Master, _Line, Spec, _),
  467    !,
  468    File = Spec.
  469canonical_source_file(Spec, File) :-
  470    absolute_file_name(Spec,
  471                           [ file_type(prolog),
  472                             access(read),
  473                             file_errors(fail)
  474                           ],
  475                           File),
  476    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.
  493exists_source(Source) :-
  494    exists_source(Source, _Path).
  495
  496exists_source(Source, Path) :-
  497    absolute_file_name(Source, Path,
  498                       [ file_type(prolog),
  499                         access(read),
  500                         file_errors(fail)
  501                       ]).
 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.
  510prolog_load_context(module, Module) :-
  511    '$current_source_module'(Module).
  512prolog_load_context(file, File) :-
  513    input_file(File).
  514prolog_load_context(source, F) :-       % SICStus compatibility
  515    input_file(F0),
  516    '$input_context'(Context),
  517    '$top_file'(Context, F0, F).
  518prolog_load_context(stream, S) :-
  519    (   system:'$load_input'(_, S0)
  520    ->  S = S0
  521    ).
  522prolog_load_context(directory, D) :-
  523    input_file(F),
  524    file_directory_name(F, D).
  525prolog_load_context(dialect, D) :-
  526    current_prolog_flag(emulated_dialect, D).
  527prolog_load_context(term_position, TermPos) :-
  528    source_location(_, L),
  529    (   nb_current('$term_position', Pos),
  530        compound(Pos),              % actually set
  531        stream_position_data(line_count, Pos, L)
  532    ->  TermPos = Pos
  533    ;   TermPos = '$stream_position'(0,L,0,0)
  534    ).
  535prolog_load_context(script, Bool) :-
  536    (   '$toplevel':loaded_init_file(script, Path),
  537        input_file(File),
  538        same_file(File, Path)
  539    ->  Bool = true
  540    ;   Bool = false
  541    ).
  542prolog_load_context(variable_names, Bindings) :-
  543    nb_current('$variable_names', Bindings).
  544prolog_load_context(term, Term) :-
  545    nb_current('$term', Term).
  546prolog_load_context(reloading, true) :-
  547    prolog_load_context(source, F),
  548    '$source_file_property'(F, reloading, true).
  549
  550input_file(File) :-
  551    (   system:'$load_input'(_, Stream)
  552    ->  stream_property(Stream, file_name(File))
  553    ),
  554    !.
  555input_file(File) :-
  556    source_location(File, _).
 unload_file(+File) is det
Remove all traces of loading file.
  563:- dynamic system:'$resolved_source_path'/2.  564
  565unload_file(File) :-
  566    (   canonical_source_file(File, Path)
  567    ->  '$unload_file'(Path),
  568        retractall(system:'$resolved_source_path'(_, Path))
  569    ;   true
  570    ).
  571
  572		 /*******************************
  573		 *      FOREIGN LIBRARIES	*
  574		 *******************************/
 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.

  593use_foreign_library(FileSpec) :-
  594    ensure_shlib,
  595    initialization(shlib:load_foreign_library(FileSpec), now).
  596
  597use_foreign_library(FileSpec, Entry) :-
  598    ensure_shlib,
  599    initialization(shlib:load_foreign_library(FileSpec, Entry), now).
  600
  601ensure_shlib :-
  602    '$get_predicate_attribute'(shlib:load_foreign_library(_), defined, 1),
  603    '$get_predicate_attribute'(shlib:load_foreign_library(_,_), defined, 1),
  604    !.
  605ensure_shlib :-
  606    use_module(library(shlib), []).
  607
  608
  609                 /*******************************
  610                 *            STREAMS           *
  611                 *******************************/
 stream_position_data(?Field, +Pos, ?Date)
Extract values from stream position objects. '$stream_position' is of the format '$stream_position'(Byte, Char, Line, LinePos)
  618stream_position_data(Prop, Term, Value) :-
  619    nonvar(Prop),
  620    !,
  621    (   stream_position_field(Prop, Pos)
  622    ->  arg(Pos, Term, Value)
  623    ;   throw(error(domain_error(stream_position_data, Prop)))
  624    ).
  625stream_position_data(Prop, Term, Value) :-
  626    stream_position_field(Prop, Pos),
  627    arg(Pos, Term, Value).
  628
  629stream_position_field(char_count,    1).
  630stream_position_field(line_count,    2).
  631stream_position_field(line_position, 3).
  632stream_position_field(byte_count,    4).
  633
  634
  635                 /*******************************
  636                 *            CONTROL           *
  637                 *******************************/
 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.
  645:- meta_predicate
  646    call_with_depth_limit(0, +, -).  647
  648call_with_depth_limit(G, Limit, Result) :-
  649    '$depth_limit'(Limit, OLimit, OReached),
  650    (   catch(G, E, '$depth_limit_except'(OLimit, OReached, E)),
  651        '$depth_limit_true'(Limit, OLimit, OReached, Result, Det),
  652        ( Det == ! -> ! ; true )
  653    ;   '$depth_limit_false'(OLimit, OReached, Result)
  654    ).
 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.

  668:- meta_predicate
  669    call_with_inference_limit(0, +, -).  670
  671call_with_inference_limit(G, Limit, Result) :-
  672    '$inference_limit'(Limit, OLimit),
  673    (   catch(G, Except,
  674              system:'$inference_limit_except'(OLimit, Except, Result0)),
  675        system:'$inference_limit_true'(Limit, OLimit, Result0),
  676        ( Result0 == ! -> ! ; true ),
  677        Result = Result0
  678    ;   system:'$inference_limit_false'(OLimit)
  679    ).
  680
  681
  682                /********************************
  683                *           DATA BASE           *
  684                *********************************/
  685
  686/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  687The predicate current_predicate/2 is   a  difficult subject since  the
  688introduction  of defaulting     modules   and   dynamic     libraries.
  689current_predicate/2 is normally  called with instantiated arguments to
  690verify some  predicate can   be called without trapping   an undefined
  691predicate.  In this case we must  perform the search algorithm used by
  692the prolog system itself.
  693
  694If the pattern is not fully specified, we only generate the predicates
  695actually available in this  module.   This seems the best for listing,
  696etc.
  697- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  698
  699
  700:- meta_predicate
  701    current_predicate(?, :),
  702    '$defined_predicate'(:).  703
  704current_predicate(Name, Module:Head) :-
  705    (var(Module) ; var(Head)),
  706    !,
  707    generate_current_predicate(Name, Module, Head).
  708current_predicate(Name, Term) :-
  709    '$c_current_predicate'(Name, Term),
  710    '$defined_predicate'(Term),
  711    !.
  712current_predicate(Name, Module:Head) :-
  713    default_module(Module, DefModule),
  714    '$c_current_predicate'(Name, DefModule:Head),
  715    '$defined_predicate'(DefModule:Head),
  716    !.
  717current_predicate(Name, Module:Head) :-
  718    '$autoload':autoload_in(Module, general),
  719    \+ current_prolog_flag(Module:unknown, fail),
  720    (   compound(Head)
  721    ->  compound_name_arity(Head, Name, Arity)
  722    ;   Name = Head, Arity = 0
  723    ),
  724    '$find_library'(Module, Name, Arity, _LoadModule, _Library),
  725    !.
  726
  727generate_current_predicate(Name, Module, Head) :-
  728    current_module(Module),
  729    QHead = Module:Head,
  730    '$c_current_predicate'(Name, QHead),
  731    '$get_predicate_attribute'(QHead, defined, 1).
  732
  733'$defined_predicate'(Head) :-
  734    '$get_predicate_attribute'(Head, defined, 1),
  735    !.
 predicate_property(?Predicate, ?Property) is nondet
True when Property is a property of Predicate.
  741:- meta_predicate
  742    predicate_property(:, ?).  743
  744:- multifile
  745    '$predicate_property'/2.  746
  747:- '$iso'(predicate_property/2).  748
  749predicate_property(Pred, Property) :-           % Mode ?,+
  750    nonvar(Property),
  751    !,
  752    property_predicate(Property, Pred).
  753predicate_property(Pred, Property) :-           % Mode +,-
  754    define_or_generate(Pred),
  755    '$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.
  763property_predicate(undefined, Pred) :-
  764    !,
  765    Pred = Module:Head,
  766    current_module(Module),
  767    '$c_current_predicate'(_, Pred),
  768    \+ '$defined_predicate'(Pred),          % Speed up a bit
  769    \+ current_predicate(_, Pred),
  770    goal_name_arity(Head, Name, Arity),
  771    \+ system_undefined(Module:Name/Arity).
  772property_predicate(visible, Pred) :-
  773    !,
  774    visible_predicate(Pred).
  775property_predicate(autoload(File), Head) :-
  776    !,
  777    \+ current_prolog_flag(autoload, false),
  778    '$autoload':autoloadable(Head, File).
  779property_predicate(implementation_module(IM), M:Head) :-
  780    !,
  781    atom(M),
  782    (   default_module(M, DM),
  783        '$get_predicate_attribute'(DM:Head, defined, 1)
  784    ->  (   '$get_predicate_attribute'(DM:Head, imported, ImportM)
  785        ->  IM = ImportM
  786        ;   IM = M
  787        )
  788    ;   \+ current_prolog_flag(M:unknown, fail),
  789        goal_name_arity(Head, Name, Arity),
  790        '$find_library'(_, Name, Arity, LoadModule, _File)
  791    ->  IM = LoadModule
  792    ;   M = IM
  793    ).
  794property_predicate(iso, _:Head) :-
  795    callable(Head),
  796    !,
  797    goal_name_arity(Head, Name, Arity),
  798    current_predicate(system:Name/Arity),
  799    '$predicate_property'(iso, system:Head).
  800property_predicate(built_in, Module:Head) :-
  801    callable(Head),
  802    !,
  803    goal_name_arity(Head, Name, Arity),
  804    current_predicate(Module:Name/Arity),
  805    '$predicate_property'(built_in, Module:Head).
  806property_predicate(Property, Pred) :-
  807    define_or_generate(Pred),
  808    '$predicate_property'(Property, Pred).
  809
  810goal_name_arity(Head, Name, Arity) :-
  811    compound(Head),
  812    !,
  813    compound_name_arity(Head, Name, Arity).
  814goal_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.
  823define_or_generate(M:Head) :-
  824    callable(Head),
  825    atom(M),
  826    '$get_predicate_attribute'(M:Head, defined, 1),
  827    !.
  828define_or_generate(M:Head) :-
  829    callable(Head),
  830    nonvar(M), M \== system,
  831    !,
  832    '$define_predicate'(M:Head).
  833define_or_generate(Pred) :-
  834    current_predicate(_, Pred),
  835    '$define_predicate'(Pred).
  836
  837
  838'$predicate_property'(interpreted, Pred) :-
  839    '$get_predicate_attribute'(Pred, foreign, 0).
  840'$predicate_property'(visible, Pred) :-
  841    '$get_predicate_attribute'(Pred, defined, 1).
  842'$predicate_property'(built_in, Pred) :-
  843    '$get_predicate_attribute'(Pred, system, 1).
  844'$predicate_property'(exported, Pred) :-
  845    '$get_predicate_attribute'(Pred, exported, 1).
  846'$predicate_property'(public, Pred) :-
  847    '$get_predicate_attribute'(Pred, public, 1).
  848'$predicate_property'(non_terminal, Pred) :-
  849    '$get_predicate_attribute'(Pred, non_terminal, 1).
  850'$predicate_property'(foreign, Pred) :-
  851    '$get_predicate_attribute'(Pred, foreign, 1).
  852'$predicate_property'((dynamic), Pred) :-
  853    '$get_predicate_attribute'(Pred, (dynamic), 1).
  854'$predicate_property'((static), Pred) :-
  855    '$get_predicate_attribute'(Pred, (dynamic), 0).
  856'$predicate_property'((volatile), Pred) :-
  857    '$get_predicate_attribute'(Pred, (volatile), 1).
  858'$predicate_property'((thread_local), Pred) :-
  859    '$get_predicate_attribute'(Pred, (thread_local), 1).
  860'$predicate_property'((multifile), Pred) :-
  861    '$get_predicate_attribute'(Pred, (multifile), 1).
  862'$predicate_property'(imported_from(Module), Pred) :-
  863    '$get_predicate_attribute'(Pred, imported, Module).
  864'$predicate_property'(transparent, Pred) :-
  865    '$get_predicate_attribute'(Pred, transparent, 1).
  866'$predicate_property'(meta_predicate(Pattern), Pred) :-
  867    '$get_predicate_attribute'(Pred, meta_predicate, Pattern).
  868'$predicate_property'(file(File), Pred) :-
  869    '$get_predicate_attribute'(Pred, file, File).
  870'$predicate_property'(line_count(LineNumber), Pred) :-
  871    '$get_predicate_attribute'(Pred, line_count, LineNumber).
  872'$predicate_property'(notrace, Pred) :-
  873    '$get_predicate_attribute'(Pred, trace, 0).
  874'$predicate_property'(nodebug, Pred) :-
  875    '$get_predicate_attribute'(Pred, hide_childs, 1).
  876'$predicate_property'(spying, Pred) :-
  877    '$get_predicate_attribute'(Pred, spy, 1).
  878'$predicate_property'(number_of_clauses(N), Pred) :-
  879    '$get_predicate_attribute'(Pred, number_of_clauses, N).
  880'$predicate_property'(number_of_rules(N), Pred) :-
  881    '$get_predicate_attribute'(Pred, number_of_rules, N).
  882'$predicate_property'(last_modified_generation(Gen), Pred) :-
  883    '$get_predicate_attribute'(Pred, last_modified_generation, Gen).
  884'$predicate_property'(indexed(Indices), Pred) :-
  885    '$get_predicate_attribute'(Pred, indexed, Indices).
  886'$predicate_property'(noprofile, Pred) :-
  887    '$get_predicate_attribute'(Pred, noprofile, 1).
  888'$predicate_property'(iso, Pred) :-
  889    '$get_predicate_attribute'(Pred, iso, 1).
  890'$predicate_property'(quasi_quotation_syntax, Pred) :-
  891    '$get_predicate_attribute'(Pred, quasi_quotation_syntax, 1).
  892'$predicate_property'(defined, Pred) :-
  893    '$get_predicate_attribute'(Pred, defined, 1).
  894'$predicate_property'(tabled, Pred) :-
  895    '$get_predicate_attribute'(Pred, tabled, 1).
  896'$predicate_property'(tabled(Flag), Pred) :-
  897    '$get_predicate_attribute'(Pred, tabled, 1),
  898    table_flag(Flag, Pred).
  899'$predicate_property'(incremental, Pred) :-
  900    '$get_predicate_attribute'(Pred, incremental, 1).
  901'$predicate_property'(abstract(N), Pred) :-
  902    '$get_predicate_attribute'(Pred, abstract, N).
  903'$predicate_property'(size(Bytes), Pred) :-
  904    '$get_predicate_attribute'(Pred, size, Bytes).
  905
  906system_undefined(user:prolog_trace_interception/4).
  907system_undefined(user:prolog_exception_hook/4).
  908system_undefined(system:'$c_call_prolog'/0).
  909system_undefined(system:window_title/2).
  910
  911table_flag(variant, Pred) :-
  912    '$tbl_implementation'(Pred, M:Head),
  913    M:'$tabled'(Head, variant).
  914table_flag(subsumptive, Pred) :-
  915    '$tbl_implementation'(Pred, M:Head),
  916    M:'$tabled'(Head, subsumptive).
  917table_flag(shared, Pred) :-
  918    '$get_predicate_attribute'(Pred, tshared, 1).
  919table_flag(incremental, Pred) :-
  920    '$get_predicate_attribute'(Pred, incremental, 1).
  921table_flag(subgoal_abstract(N), Pred) :-
  922    '$get_predicate_attribute'(Pred, subgoal_abstract, N).
  923table_flag(answer_abstract(N), Pred) :-
  924    '$get_predicate_attribute'(Pred, subgoal_abstract, N).
  925table_flag(subgoal_abstract(N), Pred) :-
  926    '$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.
  935visible_predicate(Pred) :-
  936    Pred = M:Head,
  937    current_module(M),
  938    (   callable(Head)
  939    ->  (   '$get_predicate_attribute'(Pred, defined, 1)
  940        ->  true
  941        ;   \+ current_prolog_flag(M:unknown, fail),
  942            functor(Head, Name, Arity),
  943            '$find_library'(M, Name, Arity, _LoadModule, _Library)
  944        )
  945    ;   setof(PI, visible_in_module(M, PI), PIs),
  946        '$member'(Name/Arity, PIs),
  947        functor(Head, Name, Arity)
  948    ).
  949
  950visible_in_module(M, Name/Arity) :-
  951    default_module(M, DefM),
  952    DefHead = DefM:Head,
  953    '$c_current_predicate'(_, DefHead),
  954    '$get_predicate_attribute'(DefHead, defined, 1),
  955    \+ hidden_system_predicate(Head),
  956    functor(Head, Name, Arity).
  957visible_in_module(_, Name/Arity) :-
  958    '$in_library'(Name, Arity, _).
  959
  960hidden_system_predicate(Head) :-
  961    functor(Head, Name, _),
  962    atom(Name),                     % Avoid [].
  963    sub_atom(Name, 0, _, _, $),
  964    \+ 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.
  989clause_property(Clause, Property) :-
  990    '$clause_property'(Property, Clause).
  991
  992'$clause_property'(line_count(LineNumber), Clause) :-
  993    '$get_clause_attribute'(Clause, line_count, LineNumber).
  994'$clause_property'(file(File), Clause) :-
  995    '$get_clause_attribute'(Clause, file, File).
  996'$clause_property'(source(File), Clause) :-
  997    '$get_clause_attribute'(Clause, owner, File).
  998'$clause_property'(size(Bytes), Clause) :-
  999    '$get_clause_attribute'(Clause, size, Bytes).
 1000'$clause_property'(fact, Clause) :-
 1001    '$get_clause_attribute'(Clause, fact, true).
 1002'$clause_property'(erased, Clause) :-
 1003    '$get_clause_attribute'(Clause, erased, true).
 1004'$clause_property'(predicate(PI), Clause) :-
 1005    '$get_clause_attribute'(Clause, predicate_indicator, PI).
 1006'$clause_property'(module(M), Clause) :-
 1007    '$get_clause_attribute'(Clause, module, M).
 dynamic(:Predicates, +Options) is det
Define a predicate as dynamic with optionally additional properties. Defined options are:
 1021dynamic(M:Predicates, Options) :-
 1022    '$must_be'(list, Predicates),
 1023    options_properties(Options, Props),
 1024    set_pprops(Predicates, M, [dynamic|Props]).
 1025
 1026set_pprops([], _, _).
 1027set_pprops([H|T], M, Props) :-
 1028    set_pprops1(Props, M:H),
 1029    strip_module(M:H, M2, P),
 1030    '$pi_head'(M2:P, Pred),
 1031    (   '$get_predicate_attribute'(Pred, incremental, 1)
 1032    ->  '$wrap_incremental'(Pred)
 1033    ;   '$unwrap_incremental'(Pred)
 1034    ),
 1035    set_pprops(T, M, Props).
 1036
 1037set_pprops1([], _).
 1038set_pprops1([H|T], P) :-
 1039    (   atom(H)
 1040    ->  '$set_predicate_attribute'(P, H, true)
 1041    ;   H =.. [Name,Value]
 1042    ->  '$set_predicate_attribute'(P, Name, Value)
 1043    ),
 1044    set_pprops1(T, P).
 1045
 1046options_properties(Options, Props) :-
 1047    G = opt_prop(_,_,_,_),
 1048    findall(G, G, Spec),
 1049    options_properties(Spec, Options, Props).
 1050
 1051options_properties([], _, []).
 1052options_properties([opt_prop(Name, Type, SetValue, Prop)|T],
 1053                   Options, [Prop|PT]) :-
 1054    Opt =.. [Name,V],
 1055    '$option'(Opt, Options),
 1056    '$must_be'(Type, V),
 1057    V = SetValue,
 1058    !,
 1059    options_properties(T, Options, PT).
 1060options_properties([_|T], Options, PT) :-
 1061    options_properties(T, Options, PT).
 1062
 1063opt_prop(incremental,   boolean,               Bool,  incremental(Bool)).
 1064opt_prop(abstract,      between(0,0),          0,     abstract).
 1065opt_prop(multifile,     boolean,               true,  multifile).
 1066opt_prop(discontiguous, boolean,               true,  discontiguous).
 1067opt_prop(volatile,      boolean,               true,  volatile).
 1068opt_prop(thread,        oneof(atom, [local,shared],[local,shared]),
 1069                                               local, thread_local).
 1070
 1071                /********************************
 1072                *            MODULES            *
 1073                *********************************/
 current_module(?Module) is nondet
True if Module is a currently defined module.
 1079current_module(Module) :-
 1080    '$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.
 1096module_property(Module, Property) :-
 1097    nonvar(Module), nonvar(Property),
 1098    !,
 1099    property_module(Property, Module).
 1100module_property(Module, Property) :-    % -, file(File)
 1101    nonvar(Property), Property = file(File),
 1102    !,
 1103    (   nonvar(File)
 1104    ->  '$current_module'(Modules, File),
 1105        (   atom(Modules)
 1106        ->  Module = Modules
 1107        ;   '$member'(Module, Modules)
 1108        )
 1109    ;   '$current_module'(Module, File),
 1110        File \== []
 1111    ).
 1112module_property(Module, Property) :-
 1113    current_module(Module),
 1114    property_module(Property, Module).
 1115
 1116property_module(Property, Module) :-
 1117    module_property(Property),
 1118    (   Property = exported_operators(List)
 1119    ->  '$exported_ops'(Module, List, [])
 1120    ;   '$module_property'(Module, Property)
 1121    ).
 1122
 1123module_property(class(_)).
 1124module_property(file(_)).
 1125module_property(line_count(_)).
 1126module_property(exports(_)).
 1127module_property(exported_operators(_)).
 1128module_property(size(_)).
 1129module_property(program_size(_)).
 1130module_property(program_space(_)).
 1131module_property(last_modified_generation(_)).
 module(+Module) is det
Set the module that is associated to the toplevel to Module.
 1137module(Module) :-
 1138    atom(Module),
 1139    current_module(Module),
 1140    !,
 1141    '$set_typein_module'(Module).
 1142module(Module) :-
 1143    '$set_typein_module'(Module),
 1144    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.
 1151working_directory(Old, New) :-
 1152    '$cwd'(Old),
 1153    (   Old == New
 1154    ->  true
 1155    ;   '$chdir'(New)
 1156    ).
 1157
 1158
 1159                 /*******************************
 1160                 *            TRIES             *
 1161                 *******************************/
 current_trie(?Trie) is nondet
True if Trie is the handle of an existing trie.
 1167current_trie(Trie) :-
 1168    current_blob(Trie, trie),
 1169    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
 1205trie_property(Trie, Property) :-
 1206    current_trie(Trie),
 1207    trie_property(Property),
 1208    '$trie_property'(Trie, Property).
 1209
 1210trie_property(node_count(_)).
 1211trie_property(value_count(_)).
 1212trie_property(size(_)).
 1213trie_property(hashed(_)).
 1214trie_property(compiled_size(_)).
 1215                                                % below only when -DO_TRIE_STATS
 1216trie_property(lookup_count(_)).                 % is enabled in pl-trie.h
 1217trie_property(gen_call_count(_)).
 1218trie_property(invalidated(_)).                  % IDG stats
 1219trie_property(reevaluated(_)).
 1220trie_property(deadlock(_)).                     % Shared tabling stats
 1221trie_property(wait(_)).
 1222trie_property(idg_affected_count(_)).
 1223trie_property(idg_dependent_count(_)).
 1224trie_property(idg_size(_)).
 1225
 1226
 1227                /********************************
 1228                *      SYSTEM INTERACTION       *
 1229                *********************************/
 1230
 1231shell(Command) :-
 1232    shell(Command, 0).
 1233
 1234
 1235                 /*******************************
 1236                 *            SIGNALS           *
 1237                 *******************************/
 1238
 1239:- meta_predicate
 1240    on_signal(+, :, :),
 1241    current_signal(?, ?, :).
 on_signal(+Signal, -OldHandler, :NewHandler) is det
 1245on_signal(Signal, Old, New) :-
 1246    atom(Signal),
 1247    !,
 1248    '$on_signal'(_Num, Signal, Old, New).
 1249on_signal(Signal, Old, New) :-
 1250    integer(Signal),
 1251    !,
 1252    '$on_signal'(Signal, _Name, Old, New).
 1253on_signal(Signal, _Old, _New) :-
 1254    '$type_error'(signal_name, Signal).
 current_signal(?Name, ?SignalNumber, :Handler) is nondet
 1258current_signal(Name, Id, Handler) :-
 1259    between(1, 32, Id),
 1260    '$on_signal'(Id, Name, Handler, Handler).
 1261
 1262:- multifile
 1263    prolog:called_by/2. 1264
 1265prolog:called_by(on_signal(_,_,New), [New+1]) :-
 1266    (   new == throw
 1267    ;   new == default
 1268    ), !, fail.
 1269
 1270
 1271                 /*******************************
 1272                 *            DLOPEN            *
 1273                 *******************************/
 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.
 1287open_shared_object(File, Handle) :-
 1288    open_shared_object(File, Handle, []). % use pl-load.c defaults
 1289
 1290open_shared_object(File, Handle, Flags) :-
 1291    (   is_list(Flags)
 1292    ->  true
 1293    ;   throw(error(type_error(list, Flags), _))
 1294    ),
 1295    map_dlflags(Flags, Mask),
 1296    '$open_shared_object'(File, Handle, Mask).
 1297
 1298dlopen_flag(now,        2'01).          % see pl-load.c for these constants
 1299dlopen_flag(global,     2'10).          % Solaris only
 1300
 1301map_dlflags([], 0).
 1302map_dlflags([F|T], M) :-
 1303    map_dlflags(T, M0),
 1304    (   dlopen_flag(F, I)
 1305    ->  true
 1306    ;   throw(error(domain_error(dlopen_flag, F), _))
 1307    ),
 1308    M is M0 \/ I.
 1309
 1310
 1311                 /*******************************
 1312                 *             I/O              *
 1313                 *******************************/
 1314
 1315format(Fmt) :-
 1316    format(Fmt, []).
 1317
 1318                 /*******************************
 1319                 *            FILES             *
 1320                 *******************************/
 absolute_file_name(+Term, -AbsoluteFile)
 1324absolute_file_name(Name, Abs) :-
 1325    atomic(Name),
 1326    !,
 1327    '$absolute_file_name'(Name, Abs).
 1328absolute_file_name(Term, Abs) :-
 1329    '$chk_file'(Term, [''], [access(read)], true, File),
 1330    !,
 1331    '$absolute_file_name'(File, Abs).
 1332absolute_file_name(Term, Abs) :-
 1333    '$chk_file'(Term, [''], [], true, File),
 1334    !,
 1335    '$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.
 1343tmp_file_stream(Enc, File, Stream) :-
 1344    atom(Enc), var(File), var(Stream),
 1345    !,
 1346    '$tmp_file_stream'('', Enc, File, Stream).
 1347tmp_file_stream(File, Stream, Options) :-
 1348    current_prolog_flag(encoding, DefEnc),
 1349    '$option'(encoding(Enc), Options, DefEnc),
 1350    '$option'(extension(Ext), Options, ''),
 1351    '$tmp_file_stream'(Ext, Enc, File, Stream),
 1352    set_stream(Stream, file_name(File)).
 1353
 1354
 1355                /********************************
 1356                *        MEMORY MANAGEMENT      *
 1357                *********************************/
 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.
 1366garbage_collect :-
 1367    '$garbage_collect'(0).
 set_prolog_stack(+Name, +Option) is det
Set a parameter for one of the Prolog stacks.
 1373set_prolog_stack(Stack, Option) :-
 1374    Option =.. [Name,Value0],
 1375    Value is Value0,
 1376    '$set_prolog_stack'(Stack, Name, _Old, Value).
 prolog_stack_property(?Stack, ?Property) is nondet
Examine stack properties.
 1382prolog_stack_property(Stack, Property) :-
 1383    stack_property(P),
 1384    stack_name(Stack),
 1385    Property =.. [P,Value],
 1386    '$set_prolog_stack'(Stack, P, Value, Value).
 1387
 1388stack_name(local).
 1389stack_name(global).
 1390stack_name(trail).
 1391
 1392stack_property(limit).
 1393stack_property(spare).
 1394stack_property(min_free).
 1395stack_property(low).
 1396stack_property(factor).
 1397
 1398
 1399                 /*******************************
 1400                 *             TERM             *
 1401                 *******************************/
 1402
 1403:- '$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.
 1411numbervars(Term, From, To) :-
 1412    numbervars(Term, From, To, []).
 1413
 1414
 1415                 /*******************************
 1416                 *            STRING            *
 1417                 *******************************/
 term_string(?Term, ?String, +Options)
Parse/write a term from/to a string using Options.
 1423term_string(Term, String, Options) :-
 1424    nonvar(String),
 1425    !,
 1426    read_term_from_atom(String, Term, Options).
 1427term_string(Term, String, Options) :-
 1428    (   '$option'(quoted(_), Options)
 1429    ->  Options1 = Options
 1430    ;   '$merge_options'(_{quoted:true}, Options, Options1)
 1431    ),
 1432    format(string(String), '~W', [Term, Options1]).
 1433
 1434
 1435                 /*******************************
 1436                 *             GVAR             *
 1437                 *******************************/
 nb_setval(+Name, +Value) is det
Bind the non-backtrackable variable Name with a copy of Value
 1443nb_setval(Name, Value) :-
 1444    duplicate_term(Value, Copy),
 1445    nb_linkval(Name, Copy).
 1446
 1447
 1448		 /*******************************
 1449		 *            THREADS		*
 1450		 *******************************/
 1451
 1452:- meta_predicate
 1453    thread_create(0, -).
 thread_create(:Goal, -Id)
Shorthand for thread_create(Goal, Id, []).
 1459thread_create(Goal, Id) :-
 1460    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.
 1469thread_join(Id) :-
 1470    thread_join(Id, Status),
 1471    (   Status == true
 1472    ->  true
 1473    ;   throw(error(thread_error(Id, Status), _))
 1474    ).
 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.
 1491set_prolog_gc_thread(Status) :-
 1492    var(Status),
 1493    !,
 1494    '$instantiation_error'(Status).
 1495set_prolog_gc_thread(false) :-
 1496    !,
 1497    set_prolog_flag(gc_thread, false),
 1498    (   current_prolog_flag(threads, true)
 1499    ->  (   '$gc_stop'
 1500        ->  thread_join(gc)
 1501        ;   true
 1502        )
 1503    ;   true
 1504    ).
 1505set_prolog_gc_thread(true) :-
 1506    !,
 1507    set_prolog_flag(gc_thread, true).
 1508set_prolog_gc_thread(stop) :-
 1509    !,
 1510    (   current_prolog_flag(threads, true)
 1511    ->  (   '$gc_stop'
 1512        ->  thread_join(gc)
 1513        ;   true
 1514        )
 1515    ;   true
 1516    ).
 1517set_prolog_gc_thread(Status) :-
 1518    '$domain_error'(gc_thread, Status).
 $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.
 1525:- meta_predicate
 1526    '$wrap_predicate'(:, +, -, -, +). 1527
 1528'$wrap_predicate'(M:Head, WName, Closure, call(Wrapped), Body) :-
 1529    callable_name_arguments(Head, PName, Args),
 1530    callable_name_arity(Head, PName, Arity),
 1531    (   is_most_general_term(Head)
 1532    ->  true
 1533    ;   '$domain_error'(most_general_term, Head)
 1534    ),
 1535    atomic_list_concat(['$wrap$', PName], WrapName),
 1536    volatile(M:WrapName/Arity),
 1537    module_transparent(M:WrapName/Arity),
 1538    WHead =.. [WrapName|Args],
 1539    '$c_wrap_predicate'(M:Head, WName, Closure, Wrapped, M:(WHead :- Body)).
 1540
 1541callable_name_arguments(Head, PName, Args) :-
 1542    atom(Head),
 1543    !,
 1544    PName = Head,
 1545    Args = [].
 1546callable_name_arguments(Head, PName, Args) :-
 1547    compound_name_arguments(Head, PName, Args).
 1548
 1549callable_name_arity(Head, PName, Arity) :-
 1550    atom(Head),
 1551    !,
 1552    PName = Head,
 1553    Arity = 0.
 1554callable_name_arity(Head, PName, Arity) :-
 1555    compound_name_arity(Head, PName, Arity)