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-2018, University of Amsterdam
    7                              VU University Amsterdam
    8    All rights reserved.
    9
   10    Redistribution and use in source and binary forms, with or without
   11    modification, are permitted provided that the following conditions
   12    are met:
   13
   14    1. Redistributions of source code must retain the above copyright
   15       notice, this list of conditions and the following disclaimer.
   16
   17    2. Redistributions in binary form must reproduce the above copyright
   18       notice, this list of conditions and the following disclaimer in
   19       the documentation and/or other materials provided with the
   20       distribution.
   21
   22    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   23    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   24    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   25    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   26    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   27    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   28    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   29    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   30    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   32    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   33    POSSIBILITY OF SUCH DAMAGE.
   34*/
   35
   36:- module('$syspreds',
   37          [ leash/1,
   38            visible/1,
   39            style_check/1,
   40            (spy)/1,
   41            (nospy)/1,
   42            trace/1,
   43            trace/2,
   44            nospyall/0,
   45            debugging/0,
   46            rational/3,
   47            flag/3,
   48            atom_prefix/2,
   49            dwim_match/2,
   50            source_file_property/2,
   51            source_file/1,
   52            source_file/2,
   53            unload_file/1,
   54            prolog_load_context/2,
   55            stream_position_data/3,
   56            current_predicate/2,
   57            '$defined_predicate'/1,
   58            predicate_property/2,
   59            '$predicate_property'/2,
   60            clause_property/2,
   61            current_module/1,                   % ?Module
   62            module_property/2,                  % ?Module, ?Property
   63            module/1,                           % +Module
   64            current_trie/1,                     % ?Trie
   65            trie_property/2,                    % ?Trie, ?Property
   66            working_directory/2,                % -OldDir, +NewDir
   67            shell/1,                            % +Command
   68            on_signal/3,
   69            current_signal/3,
   70            open_shared_object/2,
   71            open_shared_object/3,
   72            format/1,
   73            garbage_collect/0,
   74            set_prolog_stack/2,
   75            prolog_stack_property/2,
   76            absolute_file_name/2,
   77            tmp_file_stream/3,                  % +Enc, -File, -Stream
   78            require/1,
   79            call_with_depth_limit/3,            % :Goal, +Limit, -Result
   80            call_with_inference_limit/3,        % :Goal, +Limit, -Result
   81            numbervars/3,                       % +Term, +Start, -End
   82            term_string/3,                      % ?Term, ?String, +Options
   83            nb_setval/2,                        % +Var, +Value
   84            thread_create/2,                    % :Goal, -Id
   85            thread_join/1,                      % +Id
   86            set_prolog_gc_thread/1		% +Status
   87          ]).   88
   89                /********************************
   90                *           DEBUGGER            *
   91                *********************************/
 map_bits(:Pred, +Modify, +OldBits, -NewBits)
   95:- meta_predicate
   96    map_bits(2, +, +, -).   97
   98map_bits(_, Var, _, _) :-
   99    var(Var),
  100    !,
  101    '$instantiation_error'(Var).
  102map_bits(_, [], Bits, Bits) :- !.
  103map_bits(Pred, [H|T], Old, New) :-
  104    map_bits(Pred, H, Old, New0),
  105    map_bits(Pred, T, New0, New).
  106map_bits(Pred, +Name, Old, New) :-     % set a bit
  107    !,
  108    bit(Pred, Name, Bits),
  109    !,
  110    New is Old \/ Bits.
  111map_bits(Pred, -Name, Old, New) :-     % clear a bit
  112    !,
  113    bit(Pred, Name, Bits),
  114    !,
  115    New is Old /\ (\Bits).
  116map_bits(Pred, ?(Name), Old, Old) :-   % ask a bit
  117    !,
  118    bit(Pred, Name, Bits),
  119    Old /\ Bits > 0.
  120map_bits(_, Term, _, _) :-
  121    '$type_error'('+|-|?(Flag)', Term).
  122
  123bit(Pred, Name, Bits) :-
  124    call(Pred, Name, Bits),
  125    !.
  126bit(_:Pred, Name, _) :-
  127    '$domain_error'(Pred, Name).
  128
  129:- public port_name/2.                  % used by library(test_cover)
  130
  131port_name(      call, 2'000000001).
  132port_name(      exit, 2'000000010).
  133port_name(      fail, 2'000000100).
  134port_name(      redo, 2'000001000).
  135port_name(     unify, 2'000010000).
  136port_name(     break, 2'000100000).
  137port_name(  cut_call, 2'001000000).
  138port_name(  cut_exit, 2'010000000).
  139port_name( exception, 2'100000000).
  140port_name(       cut, 2'011000000).
  141port_name(       all, 2'000111111).
  142port_name(      full, 2'000101111).
  143port_name(      half, 2'000101101).     % '
  144
  145leash(Ports) :-
  146    '$leash'(Old, Old),
  147    map_bits(port_name, Ports, Old, New),
  148    '$leash'(_, New).
  149
  150visible(Ports) :-
  151    '$visible'(Old, Old),
  152    map_bits(port_name, Ports, Old, New),
  153    '$visible'(_, New).
  154
  155style_name(atom,            0x0001) :-
  156    print_message(warning, decl_no_effect(style_check(atom))).
  157style_name(singleton,       0x0042).            % semantic and syntactic
  158style_name(discontiguous,   0x0008).
  159style_name(charset,         0x0020).
  160style_name(no_effect,       0x0080).
  161style_name(var_branches,    0x0100).
 style_check(+Spec) is nondet
  165style_check(Var) :-
  166    var(Var),
  167    !,
  168    '$instantiation_error'(Var).
  169style_check(?(Style)) :-
  170    !,
  171    (   var(Style)
  172    ->  enum_style_check(Style)
  173    ;   enum_style_check(Style)
  174    ->  true
  175    ).
  176style_check(Spec) :-
  177    '$style_check'(Old, Old),
  178    map_bits(style_name, Spec, Old, New),
  179    '$style_check'(_, New).
  180
  181enum_style_check(Style) :-
  182    '$style_check'(Bits, Bits),
  183    style_name(Style, Bit),
  184    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.

TBD: What hooks to provide for trace/[1,2]

  195:- multifile
  196    prolog:debug_control_hook/1.    % +Action
 trace(:Preds) is det
 trace(:Preds, +PortSpec) is det
Start printing messages if control passes specified ports of the given predicates.
  204:- meta_predicate
  205    trace(:),
  206    trace(:, +).  207
  208trace(Preds) :-
  209    trace(Preds, +all).
  210
  211trace(_:X, _) :-
  212    var(X),
  213    !,
  214    throw(error(instantiation_error, _)).
  215trace(_:[], _) :- !.
  216trace(M:[H|T], Ps) :-
  217    !,
  218    trace(M:H, Ps),
  219    trace(M:T, Ps).
  220trace(Pred, Ports) :-
  221    '$find_predicate'(Pred, Preds),
  222    Preds \== [],
  223    set_prolog_flag(debug, true),
  224    (   '$member'(PI, Preds),
  225            pi_to_head(PI, Head),
  226            (   Head = _:_
  227            ->  QHead0 = Head
  228            ;   QHead0 = user:Head
  229            ),
  230            '$define_predicate'(QHead0),
  231            (   predicate_property(QHead0, imported_from(M))
  232            ->  QHead0 = _:Plain,
  233                QHead = M:Plain
  234            ;   QHead = QHead0
  235            ),
  236            '$trace'(Ports, QHead),
  237            trace_ports(QHead, Tracing),
  238            print_message(informational, trace(QHead, Tracing)),
  239        fail
  240    ;   true
  241    ).
  242
  243trace_alias(all,  [trace_call, trace_redo, trace_exit, trace_fail]).
  244trace_alias(call, [trace_call]).
  245trace_alias(redo, [trace_redo]).
  246trace_alias(exit, [trace_exit]).
  247trace_alias(fail, [trace_fail]).
  248
  249'$trace'([], _) :- !.
  250'$trace'([H|T], Head) :-
  251    !,
  252    '$trace'(H, Head),
  253    '$trace'(T, Head).
  254'$trace'(+H, Head) :-
  255    trace_alias(H, A0),
  256    !,
  257    tag_list(A0, +, A1),
  258    '$trace'(A1, Head).
  259'$trace'(+H, Head) :-
  260    !,
  261    trace_alias(_, [H]),
  262    '$set_predicate_attribute'(Head, H, true).
  263'$trace'(-H, Head) :-
  264    trace_alias(H, A0),
  265    !,
  266    tag_list(A0, -, A1),
  267    '$trace'(A1, Head).
  268'$trace'(-H, Head) :-
  269    !,
  270    trace_alias(_, [H]),
  271    '$set_predicate_attribute'(Head, H, false).
  272'$trace'(H, Head) :-
  273    atom(H),
  274    '$trace'(+H, Head).
  275
  276tag_list([], _, []).
  277tag_list([H0|T0], F, [H1|T1]) :-
  278    H1 =.. [F, H0],
  279    tag_list(T0, F, T1).
  280
  281:- meta_predicate
  282    spy(:),
  283    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.
  300spy(_:X) :-
  301    var(X),
  302    throw(error(instantiation_error, _)).
  303spy(_:[]) :- !.
  304spy(M:[H|T]) :-
  305    !,
  306    spy(M:H),
  307    spy(M:T).
  308spy(Spec) :-
  309    notrace(prolog:debug_control_hook(spy(Spec))),
  310    !.
  311spy(Spec) :-
  312    '$find_predicate'(Spec, Preds),
  313    '$member'(PI, Preds),
  314        pi_to_head(PI, Head),
  315        '$define_predicate'(Head),
  316        '$spy'(Head),
  317    fail.
  318spy(_).
  319
  320nospy(_:X) :-
  321    var(X),
  322    throw(error(instantiation_error, _)).
  323nospy(_:[]) :- !.
  324nospy(M:[H|T]) :-
  325    !,
  326    nospy(M:H),
  327    nospy(M:T).
  328nospy(Spec) :-
  329    notrace(prolog:debug_control_hook(nospy(Spec))),
  330    !.
  331nospy(Spec) :-
  332    '$find_predicate'(Spec, Preds),
  333    '$member'(PI, Preds),
  334         pi_to_head(PI, Head),
  335        '$nospy'(Head),
  336    fail.
  337nospy(_).
  338
  339nospyall :-
  340    notrace(prolog:debug_control_hook(nospyall)),
  341    fail.
  342nospyall :-
  343    spy_point(Head),
  344        '$nospy'(Head),
  345    fail.
  346nospyall.
  347
  348pi_to_head(M:PI, M:Head) :-
  349    !,
  350    pi_to_head(PI, Head).
  351pi_to_head(Name/Arity, Head) :-
  352    functor(Head, Name, Arity).
 debugging is det
Report current status of the debugger.
  358debugging :-
  359    notrace(prolog:debug_control_hook(debugging)),
  360    !.
  361debugging :-
  362    current_prolog_flag(debug, true),
  363    !,
  364    print_message(informational, debugging(on)),
  365    findall(H, spy_point(H), SpyPoints),
  366    print_message(informational, spying(SpyPoints)),
  367    findall(trace(H,P), trace_point(H,P), TracePoints),
  368    print_message(informational, tracing(TracePoints)).
  369debugging :-
  370    print_message(informational, debugging(off)).
  371
  372spy_point(Module:Head) :-
  373    current_predicate(_, Module:Head),
  374    '$get_predicate_attribute'(Module:Head, spy, 1),
  375    \+ predicate_property(Module:Head, imported_from(_)).
  376
  377trace_point(Module:Head, Ports) :-
  378    current_predicate(_, Module:Head),
  379        '$get_predicate_attribute'(Module:Head, trace_any, 1),
  380        \+ predicate_property(Module:Head, imported_from(_)),
  381        trace_ports(Module:Head, Ports).
  382
  383trace_ports(Head, Ports) :-
  384    findall(Port,
  385            (trace_alias(Port, [AttName]),
  386             '$get_predicate_attribute'(Head, AttName, 1)),
  387            Ports).
 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.
  395flag(Name, Old, New) :-
  396    Old == New,
  397    !,
  398    get_flag(Name, Old).
  399flag(Name, Old, New) :-
  400    with_mutex('$flag', update_flag(Name, Old, New)).
  401
  402update_flag(Name, Old, New) :-
  403    get_flag(Name, Old),
  404    (   atom(New)
  405    ->  set_flag(Name, New)
  406    ;   Value is New,
  407        set_flag(Name, Value)
  408    ).
  409
  410
  411                 /*******************************
  412                 *            RATIONAL          *
  413                 *******************************/
 rational(+Rat, -Numerator, -Denominator) is semidet
True when Rat is a rational number with given Numerator and Denominator.
  420rational(Rat, M, N) :-
  421    rational(Rat),
  422    (   Rat = rdiv(M, N)
  423    ->  true
  424    ;   integer(Rat)
  425    ->  M = Rat,
  426        N = 1
  427    ).
  428
  429
  430                /********************************
  431                *             ATOMS             *
  432                *********************************/
  433
  434dwim_match(A1, A2) :-
  435    dwim_match(A1, A2, _).
  436
  437atom_prefix(Atom, Prefix) :-
  438    sub_atom(Atom, 0, _, _, Prefix).
  439
  440
  441                /********************************
  442                *             SOURCE            *
  443                *********************************/
 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.

  456source_file(File) :-
  457    (   current_prolog_flag(access_level, user)
  458    ->  Level = user
  459    ;   true
  460    ),
  461    (   ground(File)
  462    ->  (   '$time_source_file'(File, Time, Level)
  463        ;   absolute_file_name(File, Abs),
  464            '$time_source_file'(Abs, Time, Level)
  465        ), !
  466    ;   '$time_source_file'(File, Time, Level)
  467    ),
  468    Time > 0.0.
 source_file(+Head, -File) is semidet
source_file(?Head, ?File) is nondet
True when Head is a predicate owned by File.
  475:- meta_predicate source_file(:, ?).  476
  477source_file(M:Head, File) :-
  478    nonvar(M), nonvar(Head),
  479    !,
  480    (   '$c_current_predicate'(_, M:Head),
  481        predicate_property(M:Head, multifile)
  482    ->  multi_source_files(M:Head, Files),
  483        '$member'(File, Files)
  484    ;   '$source_file'(M:Head, File)
  485    ).
  486source_file(M:Head, File) :-
  487    (   nonvar(File)
  488    ->  true
  489    ;   source_file(File)
  490    ),
  491    '$source_file_predicates'(File, Predicates),
  492    '$member'(M:Head, Predicates).
  493
  494:- thread_local found_src_file/1.  495
  496multi_source_files(Head, Files) :-
  497    call_cleanup(
  498        findall(File, multi_source_file(Head, File), Files),
  499        retractall(found_src_file(_))).
  500
  501multi_source_file(Head, File) :-
  502    nth_clause(Head, _, Clause),
  503    clause_property(Clause, source(File)),
  504    \+ found_src_file(File),
  505    asserta(found_src_file(File)).
 source_file_property(?File, ?Property) is nondet
True if Property is a property of the loaded source-file File.
  512source_file_property(File, P) :-
  513    nonvar(File),
  514    !,
  515    canonical_source_file(File, Path),
  516    property_source_file(P, Path).
  517source_file_property(File, P) :-
  518    property_source_file(P, File).
  519
  520property_source_file(modified(Time), File) :-
  521    '$time_source_file'(File, Time, user).
  522property_source_file(source(Source), File) :-
  523    (   '$source_file_property'(File, from_state, true)
  524    ->  Source = state
  525    ;   '$source_file_property'(File, resource, true)
  526    ->  Source = resource
  527    ;   Source = file
  528    ).
  529property_source_file(module(M), File) :-
  530    (   nonvar(M)
  531    ->  '$current_module'(M, File)
  532    ;   nonvar(File)
  533    ->  '$current_module'(ML, File),
  534        (   atom(ML)
  535        ->  M = ML
  536        ;   '$member'(M, ML)
  537        )
  538    ;   '$current_module'(M, File)
  539    ).
  540property_source_file(load_context(Module, Location, Options), File) :-
  541    '$time_source_file'(File, _, user),
  542    clause(system:'$load_context_module'(File, Module, Options), true, Ref),
  543    (   clause_property(Ref, file(FromFile)),
  544        clause_property(Ref, line_count(FromLine))
  545    ->  Location = FromFile:FromLine
  546    ;   Location = user
  547    ).
  548property_source_file(includes(Master, Stamp), File) :-
  549    system:'$included'(File, _Line, Master, Stamp).
  550property_source_file(included_in(Master, Line), File) :-
  551    system:'$included'(Master, Line, File, _).
  552property_source_file(derived_from(DerivedFrom, Stamp), File) :-
  553    system:'$derived_source'(File, DerivedFrom, Stamp).
  554property_source_file(reloading, File) :-
  555    source_file(File),
  556    '$source_file_property'(File, reloading, true).
  557property_source_file(load_count(Count), File) :-
  558    source_file(File),
  559    '$source_file_property'(File, load_count, Count).
  560property_source_file(number_of_clauses(Count), File) :-
  561    source_file(File),
  562    '$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.
  569canonical_source_file(Spec, File) :-
  570    atom(Spec),
  571    '$time_source_file'(Spec, _, _),
  572    !,
  573    File = Spec.
  574canonical_source_file(Spec, File) :-
  575    system:'$included'(_Master, _Line, Spec, _),
  576    !,
  577    File = Spec.
  578canonical_source_file(Spec, File) :-
  579    absolute_file_name(Spec,
  580                           [ file_type(prolog),
  581                             access(read),
  582                             file_errors(fail)
  583                           ],
  584                           File),
  585    source_file(File).
 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.
  594prolog_load_context(module, Module) :-
  595    '$current_source_module'(Module).
  596prolog_load_context(file, F) :-
  597    source_location(F, _).
  598prolog_load_context(source, F) :-       % SICStus compatibility
  599    source_location(F0, _),
  600    '$input_context'(Context),
  601    '$top_file'(Context, F0, F).
  602prolog_load_context(stream, S) :-
  603    (   system:'$load_input'(_, S0)
  604    ->  S = S0
  605    ).
  606prolog_load_context(directory, D) :-
  607    source_location(F, _),
  608    file_directory_name(F, D).
  609prolog_load_context(dialect, D) :-
  610    current_prolog_flag(emulated_dialect, D).
  611prolog_load_context(term_position, TermPos) :-
  612    source_location(_, L),
  613    (   nb_current('$term_position', Pos),
  614        compound(Pos),              % actually set
  615        stream_position_data(line_count, Pos, L)
  616    ->  TermPos = Pos
  617    ;   TermPos = '$stream_position'(0,L,0,0)
  618    ).
  619prolog_load_context(script, Bool) :-
  620    (   '$toplevel':loaded_init_file(script, Path),
  621        source_location(Path, _)
  622    ->  Bool = true
  623    ;   Bool = false
  624    ).
  625prolog_load_context(variable_names, Bindings) :-
  626    nb_current('$variable_names', Bindings).
  627prolog_load_context(term, Term) :-
  628    nb_current('$term', Term).
  629prolog_load_context(reloading, true) :-
  630    prolog_load_context(source, F),
  631    '$source_file_property'(F, reloading, true).
 unload_file(+File) is det
Remove all traces of loading file.
  637:- dynamic system:'$resolved_source_path'/2.  638
  639unload_file(File) :-
  640    (   canonical_source_file(File, Path)
  641    ->  '$unload_file'(Path),
  642        retractall(system:'$resolved_source_path'(_, Path))
  643    ;   true
  644    ).
  645
  646
  647                 /*******************************
  648                 *            STREAMS           *
  649                 *******************************/
 stream_position_data(?Field, +Pos, ?Date)
Extract values from stream position objects. '$stream_position' is of the format '$stream_position'(Byte, Char, Line, LinePos)
  656stream_position_data(Prop, Term, Value) :-
  657    nonvar(Prop),
  658    !,
  659    (   stream_position_field(Prop, Pos)
  660    ->  arg(Pos, Term, Value)
  661    ;   throw(error(domain_error(stream_position_data, Prop)))
  662    ).
  663stream_position_data(Prop, Term, Value) :-
  664    stream_position_field(Prop, Pos),
  665    arg(Pos, Term, Value).
  666
  667stream_position_field(char_count,    1).
  668stream_position_field(line_count,    2).
  669stream_position_field(line_position, 3).
  670stream_position_field(byte_count,    4).
  671
  672
  673                 /*******************************
  674                 *            CONTROL           *
  675                 *******************************/
 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.
  683:- meta_predicate
  684    call_with_depth_limit(0, +, -).  685
  686call_with_depth_limit(G, Limit, Result) :-
  687    '$depth_limit'(Limit, OLimit, OReached),
  688    (   catch(G, E, '$depth_limit_except'(OLimit, OReached, E)),
  689        '$depth_limit_true'(Limit, OLimit, OReached, Result, Det),
  690        ( Det == ! -> ! ; true )
  691    ;   '$depth_limit_false'(OLimit, OReached, Result)
  692    ).
 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.

  706:- meta_predicate
  707    call_with_inference_limit(0, +, -).  708
  709call_with_inference_limit(G, Limit, Result) :-
  710    '$inference_limit'(Limit, OLimit),
  711    (   catch(G, Except,
  712              system:'$inference_limit_except'(OLimit, Except, Result0)),
  713        system:'$inference_limit_true'(Limit, OLimit, Result0),
  714        ( Result0 == ! -> ! ; true ),
  715        Result = Result0
  716    ;   system:'$inference_limit_false'(OLimit)
  717    ).
  718
  719
  720                /********************************
  721                *           DATA BASE           *
  722                *********************************/
  723
  724/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  725The predicate current_predicate/2 is   a  difficult subject since  the
  726introduction  of defaulting     modules   and   dynamic     libraries.
  727current_predicate/2 is normally  called with instantiated arguments to
  728verify some  predicate can   be called without trapping   an undefined
  729predicate.  In this case we must  perform the search algorithm used by
  730the prolog system itself.
  731
  732If the pattern is not fully specified, we only generate the predicates
  733actually available in this  module.   This seems the best for listing,
  734etc.
  735- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  736
  737
  738:- meta_predicate
  739    current_predicate(?, :),
  740    '$defined_predicate'(:).  741
  742current_predicate(Name, Module:Head) :-
  743    (var(Module) ; var(Head)),
  744    !,
  745    generate_current_predicate(Name, Module, Head).
  746current_predicate(Name, Term) :-
  747    '$c_current_predicate'(Name, Term),
  748    '$defined_predicate'(Term),
  749    !.
  750current_predicate(Name, Module:Head) :-
  751    default_module(Module, DefModule),
  752    '$c_current_predicate'(Name, DefModule:Head),
  753    '$defined_predicate'(DefModule:Head),
  754    !.
  755current_predicate(Name, Module:Head) :-
  756    current_prolog_flag(autoload, true),
  757    \+ current_prolog_flag(Module:unknown, fail),
  758    (   compound(Head)
  759    ->  compound_name_arity(Head, Name, Arity)
  760    ;   Name = Head, Arity = 0
  761    ),
  762    '$find_library'(Module, Name, Arity, _LoadModule, _Library),
  763    !.
  764
  765generate_current_predicate(Name, Module, Head) :-
  766    current_module(Module),
  767    QHead = Module:Head,
  768    '$c_current_predicate'(Name, QHead),
  769    '$get_predicate_attribute'(QHead, defined, 1).
  770
  771'$defined_predicate'(Head) :-
  772    '$get_predicate_attribute'(Head, defined, 1),
  773    !.
 predicate_property(?Predicate, ?Property) is nondet
True when Property is a property of Predicate.
  779:- meta_predicate
  780    predicate_property(:, ?).  781
  782:- '$iso'(predicate_property/2).  783
  784predicate_property(Pred, Property) :-           % Mode ?,+
  785    nonvar(Property),
  786    !,
  787    property_predicate(Property, Pred).
  788predicate_property(Pred, Property) :-           % Mode +,-
  789    define_or_generate(Pred),
  790    '$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.
  798property_predicate(undefined, Pred) :-
  799    !,
  800    Pred = Module:Head,
  801    current_module(Module),
  802    '$c_current_predicate'(_, Pred),
  803    \+ '$defined_predicate'(Pred),          % Speed up a bit
  804    \+ current_predicate(_, Pred),
  805    goal_name_arity(Head, Name, Arity),
  806    \+ system_undefined(Module:Name/Arity).
  807property_predicate(visible, Pred) :-
  808    !,
  809    visible_predicate(Pred).
  810property_predicate(autoload(File), _:Head) :-
  811    !,
  812    current_prolog_flag(autoload, true),
  813    (   callable(Head)
  814    ->  goal_name_arity(Head, Name, Arity),
  815        (   '$find_library'(_, Name, Arity, _, File)
  816        ->  true
  817        )
  818    ;   '$in_library'(Name, Arity, File),
  819        functor(Head, Name, Arity)
  820    ).
  821property_predicate(implementation_module(IM), M:Head) :-
  822    !,
  823    atom(M),
  824    (   default_module(M, DM),
  825        '$get_predicate_attribute'(DM:Head, defined, 1)
  826    ->  (   '$get_predicate_attribute'(DM:Head, imported, ImportM)
  827        ->  IM = ImportM
  828        ;   IM = M
  829        )
  830    ;   \+ current_prolog_flag(M:unknown, fail),
  831        goal_name_arity(Head, Name, Arity),
  832        '$find_library'(_, Name, Arity, LoadModule, _File)
  833    ->  IM = LoadModule
  834    ;   M = IM
  835    ).
  836property_predicate(iso, _:Head) :-
  837    callable(Head),
  838    !,
  839    goal_name_arity(Head, Name, Arity),
  840    current_predicate(system:Name/Arity),
  841    '$predicate_property'(iso, system:Head).
  842property_predicate(Property, Pred) :-
  843    define_or_generate(Pred),
  844    '$predicate_property'(Property, Pred).
  845
  846goal_name_arity(Head, Name, Arity) :-
  847    compound(Head),
  848    !,
  849    compound_name_arity(Head, Name, Arity).
  850goal_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.
  859define_or_generate(M:Head) :-
  860    callable(Head),
  861    atom(M),
  862    '$get_predicate_attribute'(M:Head, defined, 1),
  863    !.
  864define_or_generate(M:Head) :-
  865    callable(Head),
  866    nonvar(M), M \== system,
  867    !,
  868    '$define_predicate'(M:Head).
  869define_or_generate(Pred) :-
  870    current_predicate(_, Pred),
  871    '$define_predicate'(Pred).
  872
  873
  874'$predicate_property'(interpreted, Pred) :-
  875    '$get_predicate_attribute'(Pred, foreign, 0).
  876'$predicate_property'(visible, Pred) :-
  877    '$get_predicate_attribute'(Pred, defined, 1).
  878'$predicate_property'(built_in, Pred) :-
  879    '$get_predicate_attribute'(Pred, system, 1).
  880'$predicate_property'(exported, Pred) :-
  881    '$get_predicate_attribute'(Pred, exported, 1).
  882'$predicate_property'(public, Pred) :-
  883    '$get_predicate_attribute'(Pred, public, 1).
  884'$predicate_property'(non_terminal, Pred) :-
  885    '$get_predicate_attribute'(Pred, non_terminal, 1).
  886'$predicate_property'(foreign, Pred) :-
  887    '$get_predicate_attribute'(Pred, foreign, 1).
  888'$predicate_property'((dynamic), Pred) :-
  889    '$get_predicate_attribute'(Pred, (dynamic), 1).
  890'$predicate_property'((static), Pred) :-
  891    '$get_predicate_attribute'(Pred, (dynamic), 0).
  892'$predicate_property'((volatile), Pred) :-
  893    '$get_predicate_attribute'(Pred, (volatile), 1).
  894'$predicate_property'((thread_local), Pred) :-
  895    '$get_predicate_attribute'(Pred, (thread_local), 1).
  896'$predicate_property'((multifile), Pred) :-
  897    '$get_predicate_attribute'(Pred, (multifile), 1).
  898'$predicate_property'(imported_from(Module), Pred) :-
  899    '$get_predicate_attribute'(Pred, imported, Module).
  900'$predicate_property'(transparent, Pred) :-
  901    '$get_predicate_attribute'(Pred, transparent, 1).
  902'$predicate_property'(meta_predicate(Pattern), Pred) :-
  903    '$get_predicate_attribute'(Pred, meta_predicate, Pattern).
  904'$predicate_property'(file(File), Pred) :-
  905    '$get_predicate_attribute'(Pred, file, File).
  906'$predicate_property'(line_count(LineNumber), Pred) :-
  907    '$get_predicate_attribute'(Pred, line_count, LineNumber).
  908'$predicate_property'(notrace, Pred) :-
  909    '$get_predicate_attribute'(Pred, trace, 0).
  910'$predicate_property'(nodebug, Pred) :-
  911    '$get_predicate_attribute'(Pred, hide_childs, 1).
  912'$predicate_property'(spying, Pred) :-
  913    '$get_predicate_attribute'(Pred, spy, 1).
  914'$predicate_property'(number_of_clauses(N), Pred) :-
  915    '$get_predicate_attribute'(Pred, number_of_clauses, N).
  916'$predicate_property'(number_of_rules(N), Pred) :-
  917    '$get_predicate_attribute'(Pred, number_of_rules, N).
  918'$predicate_property'(last_modified_generation(Gen), Pred) :-
  919    '$get_predicate_attribute'(Pred, last_modified_generation, Gen).
  920'$predicate_property'(indexed(Indices), Pred) :-
  921    '$get_predicate_attribute'(Pred, indexed, Indices).
  922'$predicate_property'(noprofile, Pred) :-
  923    '$get_predicate_attribute'(Pred, noprofile, 1).
  924'$predicate_property'(iso, Pred) :-
  925    '$get_predicate_attribute'(Pred, iso, 1).
  926'$predicate_property'(quasi_quotation_syntax, Pred) :-
  927    '$get_predicate_attribute'(Pred, quasi_quotation_syntax, 1).
  928'$predicate_property'(defined, Pred) :-
  929    '$get_predicate_attribute'(Pred, defined, 1).
  930
  931system_undefined(user:prolog_trace_interception/4).
  932system_undefined(user:prolog_exception_hook/4).
  933system_undefined(system:'$c_call_prolog'/0).
  934system_undefined(system:window_title/2).
 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.
  942visible_predicate(Pred) :-
  943    Pred = M:Head,
  944    current_module(M),
  945    (   callable(Head)
  946    ->  (   '$get_predicate_attribute'(Pred, defined, 1)
  947        ->  true
  948        ;   \+ current_prolog_flag(M:unknown, fail),
  949            functor(Head, Name, Arity),
  950            '$find_library'(M, Name, Arity, _LoadModule, _Library)
  951        )
  952    ;   setof(PI, visible_in_module(M, PI), PIs),
  953        '$member'(Name/Arity, PIs),
  954        functor(Head, Name, Arity)
  955    ).
  956
  957visible_in_module(M, Name/Arity) :-
  958    default_module(M, DefM),
  959    DefHead = DefM:Head,
  960    '$c_current_predicate'(_, DefHead),
  961    '$get_predicate_attribute'(DefHead, defined, 1),
  962    \+ hidden_system_predicate(Head),
  963    functor(Head, Name, Arity).
  964visible_in_module(_, Name/Arity) :-
  965    '$in_library'(Name, Arity, _).
  966
  967hidden_system_predicate(Head) :-
  968    functor(Head, Name, _),
  969    atom(Name),                     % Avoid [].
  970    sub_atom(Name, 0, _, _, $),
  971    \+ 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.
  996clause_property(Clause, Property) :-
  997    '$clause_property'(Property, Clause).
  998
  999'$clause_property'(line_count(LineNumber), Clause) :-
 1000    '$get_clause_attribute'(Clause, line_count, LineNumber).
 1001'$clause_property'(file(File), Clause) :-
 1002    '$get_clause_attribute'(Clause, file, File).
 1003'$clause_property'(source(File), Clause) :-
 1004    '$get_clause_attribute'(Clause, owner, File).
 1005'$clause_property'(size(Bytes), Clause) :-
 1006    '$get_clause_attribute'(Clause, size, Bytes).
 1007'$clause_property'(fact, Clause) :-
 1008    '$get_clause_attribute'(Clause, fact, true).
 1009'$clause_property'(erased, Clause) :-
 1010    '$get_clause_attribute'(Clause, erased, true).
 1011'$clause_property'(predicate(PI), Clause) :-
 1012    '$get_clause_attribute'(Clause, predicate_indicator, PI).
 1013'$clause_property'(module(M), Clause) :-
 1014    '$get_clause_attribute'(Clause, module, M).
 1015
 1016
 1017                 /*******************************
 1018                 *             REQUIRE          *
 1019                 *******************************/
 1020
 1021:- meta_predicate
 1022    require(:).
 require(:ListOfPredIndicators) is det
Tag given predicates as undefined, so they will be included into a saved state through the autoloader.
See also
- autoload/0.
 1031require(M:List) :-
 1032    (   is_list(List)
 1033    ->  require(List, M)
 1034    ;   throw(error(type_error(list, List), _))
 1035    ).
 1036
 1037require([], _).
 1038require([N/A|T], M) :-
 1039    !,
 1040    functor(Head, N, A),
 1041    '$require'(M:Head),
 1042    require(T, M).
 1043require([H|_T], _) :-
 1044    throw(error(type_error(predicate_indicator, H), _)).
 1045
 1046
 1047                /********************************
 1048                *            MODULES            *
 1049                *********************************/
 current_module(?Module) is nondet
True if Module is a currently defined module.
 1055current_module(Module) :-
 1056    '$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.
 1072module_property(Module, Property) :-
 1073    nonvar(Module), nonvar(Property),
 1074    !,
 1075    property_module(Property, Module).
 1076module_property(Module, Property) :-    % -, file(File)
 1077    nonvar(Property), Property = file(File),
 1078    !,
 1079    (   nonvar(File)
 1080    ->  '$current_module'(Modules, File),
 1081        (   atom(Modules)
 1082        ->  Module = Modules
 1083        ;   '$member'(Module, Modules)
 1084        )
 1085    ;   '$current_module'(Module, File),
 1086        File \== []
 1087    ).
 1088module_property(Module, Property) :-
 1089    current_module(Module),
 1090    property_module(Property, Module).
 1091
 1092property_module(Property, Module) :-
 1093    module_property(Property),
 1094    (   Property = exported_operators(List)
 1095    ->  '$exported_ops'(Module, List, []),
 1096        List \== []
 1097    ;   '$module_property'(Module, Property)
 1098    ).
 1099
 1100module_property(class(_)).
 1101module_property(file(_)).
 1102module_property(line_count(_)).
 1103module_property(exports(_)).
 1104module_property(exported_operators(_)).
 1105module_property(program_size(_)).
 1106module_property(program_space(_)).
 1107module_property(last_modified_generation(_)).
 module(+Module) is det
Set the module that is associated to the toplevel to Module.
 1113module(Module) :-
 1114    atom(Module),
 1115    current_module(Module),
 1116    !,
 1117    '$set_typein_module'(Module).
 1118module(Module) :-
 1119    '$set_typein_module'(Module),
 1120    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.
 1127working_directory(Old, New) :-
 1128    '$cwd'(Old),
 1129    (   Old == New
 1130    ->  true
 1131    ;   '$chdir'(New)
 1132    ).
 1133
 1134
 1135                 /*******************************
 1136                 *            TRIES             *
 1137                 *******************************/
 current_trie(?Trie) is nondet
True if Trie is the handle of an existing trie.
 1143current_trie(Trie) :-
 1144    current_blob(Trie, trie),
 1145    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.
 1161trie_property(Trie, Property) :-
 1162    current_trie(Trie),
 1163    trie_property(Property),
 1164    '$trie_property'(Trie, Property).
 1165
 1166trie_property(node_count(_)).
 1167trie_property(value_count(_)).
 1168trie_property(size(_)).
 1169trie_property(hashed(_)).
 1170
 1171
 1172
 1173                /********************************
 1174                *      SYSTEM INTERACTION       *
 1175                *********************************/
 1176
 1177shell(Command) :-
 1178    shell(Command, 0).
 win_add_dll_directory(+AbsDir) is det
Add AbsDir to the directories where dependent DLLs are searched on Windows systems.
 1185:- if(current_prolog_flag(windows, true)). 1186:- export(win_add_dll_directory/1). 1187win_add_dll_directory(Dir) :-
 1188    win_add_dll_directory(Dir, _),
 1189    !.
 1190win_add_dll_directory(Dir) :-
 1191    prolog_to_os_filename(Dir, OSDir),
 1192    getenv('PATH', Path0),
 1193    atomic_list_concat([Path0, OSDir], ';', Path),
 1194    setenv('PATH', Path).
 1195:- endif. 1196
 1197                 /*******************************
 1198                 *            SIGNALS           *
 1199                 *******************************/
 1200
 1201:- meta_predicate
 1202    on_signal(+, :, :),
 1203    current_signal(?, ?, :).
 on_signal(+Signal, -OldHandler, :NewHandler) is det
 1207on_signal(Signal, Old, New) :-
 1208    atom(Signal),
 1209    !,
 1210    '$on_signal'(_Num, Signal, Old, New).
 1211on_signal(Signal, Old, New) :-
 1212    integer(Signal),
 1213    !,
 1214    '$on_signal'(Signal, _Name, Old, New).
 1215on_signal(Signal, _Old, _New) :-
 1216    '$type_error'(signal_name, Signal).
 current_signal(?Name, ?SignalNumber, :Handler) is nondet
 1220current_signal(Name, Id, Handler) :-
 1221    between(1, 32, Id),
 1222    '$on_signal'(Id, Name, Handler, Handler).
 1223
 1224:- multifile
 1225    prolog:called_by/2. 1226
 1227prolog:called_by(on_signal(_,_,New), [New+1]) :-
 1228    (   new == throw
 1229    ;   new == default
 1230    ), !, fail.
 1231
 1232
 1233                 /*******************************
 1234                 *            DLOPEN            *
 1235                 *******************************/
 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.
 1249open_shared_object(File, Handle) :-
 1250    open_shared_object(File, Handle, []). % use pl-load.c defaults
 1251
 1252open_shared_object(File, Handle, Flags) :-
 1253    (   is_list(Flags)
 1254    ->  true
 1255    ;   throw(error(type_error(list, Flags), _))
 1256    ),
 1257    map_dlflags(Flags, Mask),
 1258    '$open_shared_object'(File, Handle, Mask).
 1259
 1260dlopen_flag(now,        2'01).          % see pl-load.c for these constants
 1261dlopen_flag(global,     2'10).          % Solaris only
 1262
 1263map_dlflags([], 0).
 1264map_dlflags([F|T], M) :-
 1265    map_dlflags(T, M0),
 1266    (   dlopen_flag(F, I)
 1267    ->  true
 1268    ;   throw(error(domain_error(dlopen_flag, F), _))
 1269    ),
 1270    M is M0 \/ I.
 1271
 1272
 1273                 /*******************************
 1274                 *             I/O              *
 1275                 *******************************/
 1276
 1277format(Fmt) :-
 1278    format(Fmt, []).
 1279
 1280                 /*******************************
 1281                 *            FILES             *
 1282                 *******************************/
 absolute_file_name(+Term, -AbsoluteFile)
 1286absolute_file_name(Name, Abs) :-
 1287    atomic(Name),
 1288    !,
 1289    '$absolute_file_name'(Name, Abs).
 1290absolute_file_name(Term, Abs) :-
 1291    '$chk_file'(Term, [''], [access(read)], true, File),
 1292    !,
 1293    '$absolute_file_name'(File, Abs).
 1294absolute_file_name(Term, Abs) :-
 1295    '$chk_file'(Term, [''], [], true, File),
 1296    !,
 1297    '$absolute_file_name'(File, Abs).
 tmp_file_stream(-File, -Stream, +Encoding) is det
tmp_file_stream(+Encoding, -File, -Stream) is det
 1302tmp_file_stream(Enc, File, Stream) :-
 1303    atom(Enc), var(File), var(Stream),
 1304    !,
 1305    '$tmp_file_stream'('', Enc, File, Stream).
 1306tmp_file_stream(File, Stream, Options) :-
 1307    current_prolog_flag(encoding, DefEnc),
 1308    '$option'(encoding(Enc), Options, DefEnc),
 1309    '$option'(extension(Ext), Options, ''),
 1310    '$tmp_file_stream'(Ext, Enc, File, Stream).
 1311
 1312
 1313                /********************************
 1314                *        MEMORY MANAGEMENT      *
 1315                *********************************/
 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.
 1324garbage_collect :-
 1325    '$garbage_collect'(0).
 set_prolog_stack(+Name, +Option) is det
Set a parameter for one of the Prolog stacks.
 1331set_prolog_stack(Stack, Option) :-
 1332    Option =.. [Name,Value0],
 1333    Value is Value0,
 1334    '$set_prolog_stack'(Stack, Name, _Old, Value).
 prolog_stack_property(?Stack, ?Property) is nondet
Examine stack properties.
 1340prolog_stack_property(Stack, Property) :-
 1341    stack_property(P),
 1342    stack_name(Stack),
 1343    Property =.. [P,Value],
 1344    '$set_prolog_stack'(Stack, P, Value, Value).
 1345
 1346stack_name(local).
 1347stack_name(global).
 1348stack_name(trail).
 1349
 1350stack_property(limit).
 1351stack_property(spare).
 1352stack_property(min_free).
 1353stack_property(low).
 1354stack_property(factor).
 1355
 1356
 1357                 /*******************************
 1358                 *             TERM             *
 1359                 *******************************/
 1360
 1361:- '$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.
 1369numbervars(Term, From, To) :-
 1370    numbervars(Term, From, To, []).
 1371
 1372
 1373                 /*******************************
 1374                 *            STRING            *
 1375                 *******************************/
 term_string(?Term, ?String, +Options)
Parse/write a term from/to a string using Options.
 1381term_string(Term, String, Options) :-
 1382    nonvar(String),
 1383    !,
 1384    read_term_from_atom(String, Term, Options).
 1385term_string(Term, String, Options) :-
 1386    (   '$option'(quoted(_), Options)
 1387    ->  Options1 = Options
 1388    ;   '$merge_options'(_{quoted:true}, Options, Options1)
 1389    ),
 1390    format(string(String), '~W', [Term, Options1]).
 1391
 1392
 1393                 /*******************************
 1394                 *             GVAR             *
 1395                 *******************************/
 nb_setval(+Name, +Value) is det
Bind the non-backtrackable variable Name with a copy of Value
 1401nb_setval(Name, Value) :-
 1402    duplicate_term(Value, Copy),
 1403    nb_linkval(Name, Copy).
 1404
 1405
 1406		 /*******************************
 1407		 *            THREADS		*
 1408		 *******************************/
 1409
 1410:- meta_predicate
 1411    thread_create(0, -).
 thread_create(:Goal, -Id)
Shorthand for thread_create(Goal, Id, []).
 1417thread_create(Goal, Id) :-
 1418    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.
 1427thread_join(Id) :-
 1428    thread_join(Id, Status),
 1429    (   Status == true
 1430    ->  true
 1431    ;   throw(error(thread_error(Status), _))
 1432    ).
 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.
 1449set_prolog_gc_thread(Status) :-
 1450    var(Status),
 1451    !,
 1452    '$instantiation_error'(Status).
 1453:- if(current_prolog_flag(threads,true)). 1454set_prolog_gc_thread(false) :-
 1455    !,
 1456    set_prolog_flag(gc_thread, false),
 1457    (   '$gc_stop'
 1458    ->  thread_join(gc)
 1459    ;   true
 1460    ).
 1461set_prolog_gc_thread(true) :-
 1462    !,
 1463    set_prolog_flag(gc_thread, true).
 1464set_prolog_gc_thread(stop) :-
 1465    !,
 1466    (   '$gc_stop'
 1467    ->  thread_join(gc)
 1468    ;   true
 1469    ).
 1470:- else. 1471set_prolog_gc_thread(false) :- !.
 1472set_prolog_gc_thread(true) :- !.
 1473set_prolog_gc_thread(stop) :- !.
 1474:- endif. 1475set_prolog_gc_thread(Status) :-
 1476    '$domain_error'(gc_thread, Status)