View source with raw comments or as raw
    1/*  Part of SWI-Prolog
    2
    3    Author:        Jan Wielemaker
    4    E-mail:        jan@swi-prolog.org
    5    WWW:           https://www.swi-prolog.org
    6    Copyright (c)  1997-2026, University of Amsterdam
    7                              VU University Amsterdam
    8                              CWI, Amsterdam
    9                              SWI-Prolog Solutions b.v.
   10    All rights reserved.
   11
   12    Redistribution and use in source and binary forms, with or without
   13    modification, are permitted provided that the following conditions
   14    are met:
   15
   16    1. Redistributions of source code must retain the above copyright
   17       notice, this list of conditions and the following disclaimer.
   18
   19    2. Redistributions in binary form must reproduce the above copyright
   20       notice, this list of conditions and the following disclaimer in
   21       the documentation and/or other materials provided with the
   22       distribution.
   23
   24    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   25    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   26    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   27    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   28    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   29    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   30    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   31    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   32    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   34    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   35    POSSIBILITY OF SUCH DAMAGE.
   36*/
   37
   38:- module('$messages',
   39          [ print_message/2,            % +Kind, +Term
   40            print_message_lines/3,      % +Stream, +Prefix, +Lines
   41            message_to_string/2         % +Term, -String
   42          ]).   43
   44:- multifile
   45    prolog:message//1,              % entire message
   46    prolog:error_message//1,        % 1-st argument of error term
   47    prolog:message_context//1,      % Context of error messages
   48    prolog:deprecated//1,	    % Deprecated features
   49    prolog:message_location//1,     % (File) location of error messages
   50    prolog:message_line_element/2,  % Extend printing
   51    prolog:message_action/2.        % Side effects (broadcast)
   52:- dynamic
   53    prolog:message_action/2.        % Allow overruling
   54:- '$hide'((
   55    prolog:message//1,
   56    prolog:error_message//1,
   57    prolog:message_context//1,
   58    prolog:deprecated//1,
   59    prolog:message_location//1,
   60    prolog:message_line_element/2)).   61% Lang, Term versions
   62:- multifile
   63    prolog:message//2,              % entire message
   64    prolog:error_message//2,        % 1-st argument of error term
   65    prolog:message_context//2,      % Context of error messages
   66    prolog:message_location//2,	    % (File) location of error messages
   67    prolog:deprecated//2.	    % Deprecated features
   68:- '$hide'((
   69    prolog:message//2,
   70    prolog:error_message//2,
   71    prolog:message_context//2,
   72    prolog:deprecated//2,
   73    prolog:message_location//2)).   74
   75:- discontiguous
   76    prolog_message/3.   77
   78:- public
   79    translate_message//1,           % +Message (deprecated)
   80    prolog:translate_message//1.    % +Message
   81
   82:- create_prolog_flag(message_context, [thread], []).   83:- create_prolog_flag(debugger_goal_links, auto,
   84                      [ type(oneof([false,true,auto])),
   85                        keep(true)
   86                      ]).
 translate_message(+Term)// is det
Translate a message Term into message lines. The produced lines is a list of
nl
Emit a newline
Fmt - Args
Emit the result of format(Fmt, Args)
Fmt
Emit the result of format(Fmt)
ansi(Class, Fmt, Args)
Use ansi_format/3 for color output.
url(Location)
Emit a source location as a hyperlink. Location is File:Line:Column, File:Line, File or a URL.
url(Location, Label)
As above, but print Label rather than Location. Label is plain text, Fmt-Args or ansi(Class, Fmt, Args), the latter combining a hyperlink with a style class.
flush
Used only as last element of the list. Simply flush the output instead of producing a final newline.
at_same_line
Start the messages at the same line (instead of using ~N)
eol
End the decorated part of the last line. See print_message_lines/3.

The elements begin(Class, Ctx) and end(Ctx) that decorate the message as a whole are added by print_message_lines/3.

Use predicate_reference//1,2 to refer to a predicate rather than formatting the predicate indicator by hand.

deprecated
- Use code for message translation should call translate_message//1.
  126prolog:translate_message(Term) -->
  127    translate_message(Term).
 translate_message(+Term)// is det
Translate a message term into message lines. This version may be called from user and library definitions for message translation.
  134translate_message(Term) -->
  135    { nonvar(Term) },
  136    (   { message_lang(Lang) },
  137        prolog:message(Lang, Term)
  138    ;   prolog:message(Term)
  139    ),
  140    !.
  141translate_message(Term) -->
  142    { nonvar(Term) },
  143    translate_message2(Term),
  144    !.
  145translate_message(Term) -->
  146    { nonvar(Term),
  147      Term = error(_, _)
  148    },
  149    [ 'Unknown exception: ~p'-[Term] ].
  150translate_message(Term) -->
  151    [ 'Unknown message: ~p'-[Term] ].
  152
  153translate_message2(Term) -->
  154    prolog_message(Term).
  155translate_message2(error(resource_error(stack), Context)) -->
  156    !,
  157    out_of_stack(Context).
  158translate_message2(error(resource_error(tripwire(Wire, Context)), _)) -->
  159    !,
  160    tripwire_message(Wire, Context).
  161translate_message2(error(existence_error(reset, Ball), SWI)) -->
  162    swi_location(SWI),
  163    tabling_existence_error(Ball, SWI).
  164translate_message2(error(ISO, SWI)) -->
  165    swi_location(SWI),
  166    term_message(ISO),
  167    swi_extra(SWI).
  168translate_message2(unwind(Term)) -->
  169    unwind_message(Term).
  170translate_message2(message_lines(Lines), L, T) :- % deal with old C-warning()
  171    make_message_lines(Lines, L, T).
  172translate_message2(format(Fmt, Args)) -->
  173    [ Fmt-Args ].
  174
  175make_message_lines([], T, T) :- !.
  176make_message_lines([Last],  ['~w'-[Last]|T], T) :- !.
  177make_message_lines([L0|LT], ['~w'-[L0],nl|T0], T) :-
  178    make_message_lines(LT, T0, T).
 term_message(+Term)//
Deal with the formal argument of error(Format, ImplDefined) exception terms. The ImplDefined argument is handled by swi_location//2.
  186:- public term_message//1.  187term_message(Term) -->
  188    {var(Term)},
  189    !,
  190    [ 'Unknown error term: ~p'-[Term] ].
  191term_message(Term) -->
  192    { message_lang(Lang) },
  193    prolog:error_message(Lang, Term),
  194    !.
  195term_message(Term) -->
  196    prolog:error_message(Term),
  197    !.
  198term_message(Term) -->
  199    iso_message(Term).
  200term_message(Term) -->
  201    swi_message(Term).
  202term_message(Term) -->
  203    [ 'Unknown error term: ~p'-[Term] ].
  204
  205iso_message(resource_error(c_stack)) -->
  206    out_of_c_stack.
  207iso_message(resource_error(Missing)) -->
  208    [ 'Not enough resources: ~w'-[Missing] ].
  209iso_message(type_error(Var, Actual)) -->
  210    { var(Var) },
  211    [ 'Type error: unbound (var) type expected, found `~p'''-[Actual] ].
  212iso_message(type_error(evaluable, Actual)) -->
  213    { callable(Actual) },
  214    [ 'Arithmetic: `~p'' is not a function'-[Actual] ].
  215iso_message(type_error(free_of_attvar, Actual)) -->
  216    [ 'Type error: `~W'' contains attributed variables'-
  217      [Actual,[portray(true), attributes(portray)]] ].
  218iso_message(type_error(Expected, Actual)) -->
  219    [ 'Type error: `~w'' expected, found `~p'''-[Expected, Actual] ],
  220    type_error_comment(Expected, Actual).
  221iso_message(domain_error(Domain, Actual)) -->
  222    [ 'Domain error: '-[] ], domain(Domain),
  223    [ ' expected, found `~p'''-[Actual] ].
  224iso_message(instantiation_error) -->
  225    [ 'Arguments are not sufficiently instantiated' ].
  226iso_message(uninstantiation_error(Var)) -->
  227    [ 'Uninstantiated argument expected, found ~p'-[Var] ].
  228iso_message(representation_error(standard_order(T1, T2))) -->
  229    [ 'Cyclic terms have no standard order: ~p and ~p'-[T1, T2] ].
  230iso_message(representation_error(What)) -->
  231    [ 'Cannot represent due to `~w'''-[What] ].
  232iso_message(permission_error(Action, Type, Object)) -->
  233    permission_error(Action, Type, Object).
  234iso_message(evaluation_error(Which)) -->
  235    [ 'Arithmetic: evaluation error: `~p'''-[Which] ].
  236iso_message(existence_error(procedure, Proc)) -->
  237    [ 'Unknown procedure: ' ],
  238    predicate_reference(Proc),
  239    unknown_proc_msg(Proc).
  240iso_message(existence_error(answer_variable, Var)) -->
  241    [ '$~w was not bound by a previous query'-[Var] ].
  242iso_message(existence_error(matching_rule, Goal)) -->
  243    [ 'No rule matches ~p'-[Goal] ].
  244iso_message(existence_error(Type, Object)) -->
  245    [ '~w `~p'' does not exist'-[Type, Object] ].
  246iso_message(existence_error(export, PI, module(M))) --> % not ISO
  247    [ 'Module ', ansi(code, '~q', [M]), ' does not export ' ],
  248    predicate_reference(M:PI, [module(hide)]).
  249iso_message(existence_error(Type, Object, In)) --> % not ISO
  250    [ '~w `~p'' does not exist in ~p'-[Type, Object, In] ].
  251iso_message(busy(Type, Object)) -->
  252    [ '~w `~p'' is busy'-[Type, Object] ].
  253iso_message(syntax_error(swi_backslash_newline)) -->
  254    [ 'Deprecated: ... \\<newline><white>*.  Use \\c' ].
  255iso_message(syntax_error(warning_var_tag)) -->
  256    [ 'Deprecated: dict with unbound tag (_{...}).  Mapped to #{...}.' ].
  257iso_message(syntax_error(var_tag)) -->
  258    [ 'Syntax error: dict syntax with unbound tag (_{...}).' ].
  259iso_message(syntax_error(Id)) -->
  260    [ 'Syntax error: ' ],
  261    syntax_error(Id).
  262iso_message(occurs_check(Var, In)) -->
  263    [ 'Cannot unify ~p with ~p: would create an infinite tree'-[Var, In] ].
 permission_error(Action, Type, Object)//
Translate permission errors. Most follow te pattern "No permission to Action Type Object", but some are a bit different.
  270permission_error(Action, built_in_procedure, Pred) -->
  271    [ 'No permission to ~w built-in predicate '-[Action] ],
  272    predicate_reference(Pred),
  273    (   {Action \== export}
  274    ->  [ nl,
  275          'Use :- redefine_system_predicate(+Head) if redefinition is intended'
  276        ]
  277    ;   []
  278    ).
  279permission_error(import_into(Dest), procedure, Pred) -->
  280    [ 'No permission to import ' ],
  281    predicate_reference(Pred),
  282    [ ' into ~w'-[Dest] ].
  283permission_error(Action, static_procedure, Proc) -->
  284    [ 'No permission to ~w static procedure '-[Action] ],
  285    predicate_reference(Proc),
  286    predicate_definition(Proc, 'Defined').
  287permission_error(input, stream, Stream) -->
  288    [ 'No permission to read from output stream `~p'''-[Stream] ].
  289permission_error(output, stream, Stream) -->
  290    [ 'No permission to write to input stream `~p'''-[Stream] ].
  291permission_error(input, text_stream, Stream) -->
  292    [ 'No permission to read bytes from TEXT stream `~p'''-[Stream] ].
  293permission_error(output, text_stream, Stream) -->
  294    [ 'No permission to write bytes to TEXT stream `~p'''-[Stream] ].
  295permission_error(input, binary_stream, Stream) -->
  296    [ 'No permission to read characters from binary stream `~p'''-[Stream] ].
  297permission_error(output, binary_stream, Stream) -->
  298    [ 'No permission to write characters to binary stream `~p'''-[Stream] ].
  299permission_error(open, source_sink, alias(Alias)) -->
  300    [ 'No permission to reuse alias "~p": already taken'-[Alias] ].
  301permission_error(tnot, non_tabled_procedure, Pred) -->
  302    [ 'The argument of ' ], predicate_reference(tnot/1),
  303    [ ' is not tabled: ' ], predicate_reference(Pred).
  304permission_error(assert, procedure, Pred) -->
  305    { predicate_head(Pred, Head),
  306      predicate_property(Head, ssu)
  307    },
  308    predicate_reference(Pred),
  309    [ ': an SSU (Head => Body) predicate cannot have normal Prolog clauses' ].
  310permission_error(Action, Type, Object) -->
  311    [ 'No permission to ~w ~w `~p'''-[Action, Type, Object] ].
  312
  313
  314unknown_proc_msg(_:(^)/2) -->
  315    !,
  316    unknown_proc_msg((^)/2).
  317unknown_proc_msg((^)/2) -->
  318    !,
  319    [nl, '  ^/2 can only appear as the 2nd argument of setof/3 and bagof/3'].
  320unknown_proc_msg((:-)/2) -->
  321    !,
  322    [nl, '  Rules must be loaded from a file'],
  323    faq('ToplevelMode').
  324unknown_proc_msg((=>)/2) -->
  325    !,
  326    [nl, '  Rules must be loaded from a file'],
  327    faq('ToplevelMode').
  328unknown_proc_msg((:-)/1) -->
  329    !,
  330    [nl, '  Directives must be loaded from a file'],
  331    faq('ToplevelMode').
  332unknown_proc_msg((?-)/1) -->
  333    !,
  334    [nl, '  ?- is the Prolog prompt'],
  335    faq('ToplevelMode').
  336unknown_proc_msg(Proc) -->
  337    { dwim_predicates(Proc, Dwims) },
  338    (   {Dwims \== []}
  339    ->  [nl, '  However, there are definitions for:', nl],
  340        dwim_alternatives(Dwims)
  341    ;   []
  342    ).
  343
  344dependency_error(shared(Shared), private(Private)) -->
  345    [ 'Shared table for ' ], predicate_reference(Shared),
  346    [ ' may not depend on private ' ], predicate_reference(Private).
  347dependency_error(Dep, monotonic(On)) -->
  348    [ 'Dependent ' ], predicate_reference(Dep),
  349    [ ' on monotonic predicate ' ], predicate_reference(On),
  350    [ ' is not monotonic or incremental' ].
  351
  352faq(Page) -->
  353    [nl, '  See FAQ at https://www.swi-prolog.org/FAQ/', Page, '.html' ].
  354
  355type_error_comment(_Expected, Actual) -->
  356    { type_of(Actual, Type),
  357      (   sub_atom(Type, 0, 1, _, First),
  358          memberchk(First, [a,e,i,o,u])
  359      ->  Article = an
  360      ;   Article = a
  361      )
  362    },
  363    [ ' (~w ~w)'-[Article, Type] ].
  364
  365type_of(Term, Type) :-
  366    (   attvar(Term)      -> Type = attvar
  367    ;   var(Term)         -> Type = var
  368    ;   atom(Term)        -> Type = atom
  369    ;   integer(Term)     -> Type = integer
  370    ;   string(Term)      -> Type = string
  371    ;   Term == []        -> Type = empty_list
  372    ;   blob(Term, BlobT) -> blob_type(BlobT, Type)
  373    ;   rational(Term)    -> Type = rational
  374    ;   float(Term)       -> Type = float
  375    ;   is_stream(Term)   -> Type = stream
  376    ;   is_dict(Term)     -> Type = dict
  377    ;   is_list(Term)     -> Type = list
  378    ;   Term = [_|_]      -> list_like(Term, Type)
  379    ;   cyclic_term(Term) -> Type = cyclic
  380    ;   compound(Term)    -> Type = compound
  381    ;                        Type = unknown
  382    ).
  383
  384list_like(Term, Type) :-
  385    '$skip_list'(_, Term, Tail),
  386    (   var(Tail)
  387    ->  Type = partial_list
  388    ;   Type = invalid_list                      % TBD: Better name?
  389    ).
  390
  391blob_type(BlobT, Type) :-
  392    atom_concat(BlobT, '_reference', Type).
  393
  394syntax_error(end_of_clause) -->
  395    [ 'Unexpected end of clause' ].
  396syntax_error(end_of_clause_expected) -->
  397    [ 'End of clause expected' ].
  398syntax_error(end_of_file) -->
  399    [ 'Unexpected end of file' ].
  400syntax_error(end_of_file_in_block_comment) -->
  401    [ 'End of file in /* ... */ comment' ].
  402syntax_error(end_of_file_in_quoted(Quote)) -->
  403    [ 'End of file in quoted ' ],
  404    quoted_type(Quote).
  405syntax_error(illegal_number) -->
  406    [ 'Illegal number' ].
  407syntax_error(long_atom) -->
  408    [ 'Atom too long (see style_check/1)' ].
  409syntax_error(long_string) -->
  410    [ 'String too long (see style_check/1)' ].
  411syntax_error(operator_clash) -->
  412    [ 'Operator priority clash' ].
  413syntax_error(operator_expected) -->
  414    [ 'Operator expected' ].
  415syntax_error(operator_balance) -->
  416    [ 'Unbalanced operator' ].
  417syntax_error(quoted_punctuation) -->
  418    [ 'Operand expected, unquoted comma or bar found' ].
  419syntax_error(list_rest) -->
  420    [ 'Unexpected comma or bar in rest of list' ].
  421syntax_error(cannot_start_term) -->
  422    [ 'Illegal start of term' ].
  423syntax_error(punct(Punct, End)) -->
  424    [ 'Unexpected `~w\' before `~w\''-[Punct, End] ].
  425syntax_error(undefined_char_escape(C)) -->
  426    [ 'Unknown character escape in quoted atom or string: `\\~w\''-[C] ].
  427syntax_error(void_not_allowed) -->
  428    [ 'Empty argument list "()"' ].
  429syntax_error(Term) -->
  430    { compound(Term),
  431      compound_name_arguments(Term, Syntax, [Text])
  432    }, !,
  433    [ '~w expected, found '-[Syntax], ansi(code, '"~w"', [Text]) ].
  434syntax_error(Message) -->
  435    [ '~w'-[Message] ].
  436
  437quoted_type('\'') --> [atom].
  438quoted_type('\"') --> { current_prolog_flag(double_quotes, Type) }, [Type-[]].
  439quoted_type('\`') --> { current_prolog_flag(back_quotes, Type) }, [Type-[]].
  440
  441domain(range(Low,High)) -->
  442    !,
  443    ['[~q..~q]'-[Low,High] ].
  444domain(Domain) -->
  445    ['`~w\''-[Domain] ].
 tabling_existence_error(+Ball, +Context)//
Called on invalid shift/1 calls. Track those that result from tabling errors.
  452tabling_existence_error(Ball, Context) -->
  453    { table_shift_ball(Ball) },
  454    [ 'Tabling dependency error' ],
  455    swi_extra(Context).
  456
  457table_shift_ball(dependency(_Head)).
  458table_shift_ball(dependency(_Skeleton, _Trie, _Mono)).
  459table_shift_ball(call_info(_Skeleton, _Status)).
  460table_shift_ball(call_info(_GenSkeleton, _Skeleton, _Status)).
 dwim_predicates(+PI, -Dwims)
Find related predicate indicators.
  466dwim_predicates(Module:Name/_Arity, Dwims) :-
  467    !,
  468    findall(Dwim, dwim_predicate(Module:Name, Dwim), Dwims).
  469dwim_predicates(Name/_Arity, Dwims) :-
  470    findall(Dwim, dwim_predicate(user:Name, Dwim), Dwims).
  471
  472dwim_alternatives([]) --> [].
  473dwim_alternatives([H|T]) -->
  474    [ '        ' ],
  475    predicate_reference(H, [tag(true)]),
  476    [ nl ],
  477    dwim_alternatives(T).
  478
  479swi_message(io_error(Op, Stream)) -->
  480    [ 'I/O error in ~w on stream ~p'-[Op, Stream] ].
  481swi_message(thread_error(TID, false)) -->
  482    [ 'Thread ~p died due to failure:'-[TID] ].
  483swi_message(thread_error(TID, exception(Error))) -->
  484    [ 'Thread ~p died abnormally:'-[TID], nl ],
  485    translate_message(Error).
  486swi_message(dependency_error(Tabled, DependsOn)) -->
  487    dependency_error(Tabled, DependsOn).
  488swi_message(shell(execute, Cmd)) -->
  489    [ 'Could not execute `~w'''-[Cmd] ].
  490swi_message(shell(signal(Sig), Cmd)) -->
  491    [ 'Caught signal ~d on `~w'''-[Sig, Cmd] ].
  492swi_message(format(Fmt, Args)) -->
  493    [ Fmt-Args ].
  494swi_message(signal(Name, Num)) -->
  495    [ 'Caught signal ~d (~w)'-[Num, Name] ].
  496swi_message(limit_exceeded(Limit, MaxVal)) -->
  497    [ 'Exceeded ~w limit (~w)'-[Limit, MaxVal] ].
  498swi_message(goal_failed(Goal)) -->
  499    [ 'goal unexpectedly failed: ~p'-[Goal] ].
  500swi_message(shared_object(_Action, Message)) --> % Message = dlerror()
  501    [ '~w'-[Message] ].
  502swi_message(system_error(Error)) -->
  503    [ 'error in system call: ~w'-[Error]
  504    ].
  505swi_message(system_error) -->
  506    [ 'error in system call'
  507    ].
  508swi_message(failure_error(Goal)) -->
  509    [ 'Goal failed: ~p'-[Goal] ].
  510swi_message(timeout_error(Op, Stream)) -->
  511    [ 'Timeout in ~w from ~p'-[Op, Stream] ].
  512swi_message(not_implemented(Type, What)) -->
  513    [ '~w `~p\' is not implemented in this version'-[Type, What] ].
  514swi_message(context_error(nodirective, Goal)) -->
  515    [ 'Wrong context: ' ], predicate_reference(Goal),
  516    [ ' can only be used in a directive' ].
  517swi_message(context_error(edit, no_default_file)) -->
  518    (   { current_prolog_flag(windows, true) }
  519    ->  [ 'Edit/0 can only be used after opening a \c
  520               Prolog file by double-clicking it' ]
  521    ;   [ 'Edit/0 can only be used with the "-s file" commandline option'
  522        ]
  523    ),
  524    [ nl, 'Use "?- edit(Topic)." or "?- emacs."' ].
  525swi_message(context_error(function, meta_arg(S))) -->
  526    [ 'Functions are not (yet) supported for meta-arguments of type ~q'-[S] ].
  527swi_message(format_argument_type(Fmt, Arg)) -->
  528    [ 'Illegal argument to format sequence ~~~w: ~p'-[Fmt, Arg] ].
  529swi_message(format(Msg)) -->
  530    [ 'Format error: ~w'-[Msg] ].
  531swi_message(conditional_compilation_error(unterminated, File:Line)) -->
  532    [ 'Unterminated conditional compilation from '-[], url(File:Line) ].
  533swi_message(conditional_compilation_error(no_if, What)) -->
  534    [ ':- ~w without :- if'-[What] ].
  535swi_message(duplicate_key(Key)) -->
  536    [ 'Duplicate key: ~p'-[Key] ].
  537swi_message(determinism_error(PI, det, Found, property)) -->
  538    (   { predicate_head(PI, Head),
  539          predicate_property(Head, det)
  540        }
  541    ->  [ 'Deterministic procedure ' ], predicate_reference(PI)
  542    ;   [ 'Procedure ' ], predicate_reference(PI),
  543        [ ' called from a deterministic procedure' ]
  544    ),
  545    det_error(Found).
  546swi_message(determinism_error(PI, det, fail, guard)) -->
  547    [ 'Procedure ' ], predicate_reference(PI),
  548    [ ' failed after $-guard' ].
  549swi_message(determinism_error(PI, det, fail, guard_in_caller)) -->
  550    [ 'Procedure ' ], predicate_reference(PI),
  551    [ ' failed after $-guard in caller' ].
  552swi_message(determinism_error(Goal, det, fail, goal)) -->
  553    [ 'Goal ~p failed'-[Goal] ].
  554swi_message(determinism_error(Goal, det, nondet, goal)) -->
  555    [ 'Goal ~p succeeded with a choice point'-[Goal] ].
  556swi_message(qlf_format_error(File, Message)) -->
  557    [ '~w: Invalid QLF file: ~w'-[File, Message] ].
  558swi_message(goal_expansion_error(bound, Term)) -->
  559    [ 'Goal expansion bound a variable to ~p'-[Term] ].
  560
  561det_error(nondet) -->
  562    [ ' succeeded with a choicepoint'- [] ].
  563det_error(fail) -->
  564    [ ' failed'- [] ].
 swi_location(+Term)// is det
Print location information for error(Formal, ImplDefined) from the ImplDefined term.
  572:- public swi_location//1.  573swi_location(X) -->
  574    { var(X) },
  575    !.
  576swi_location(Context) -->
  577    { message_lang(Lang) },
  578    prolog:message_location(Lang, Context),
  579    !.
  580swi_location(Context) -->
  581    prolog:message_location(Context),
  582    !.
  583swi_location(context(Caller, _Msg)) -->
  584    { ground(Caller) },
  585    !,
  586    caller(Caller).
  587swi_location(file(Path, Line, -1, _CharNo)) -->
  588    !,
  589    [ url(Path:Line), ': ' ].
  590swi_location(file(Path, Line, LinePos, _CharNo)) -->
  591    { Column is LinePos+1 },                    % line_position is 0-based
  592    [ url(Path:Line:Column), ': ' ].
  593swi_location(stream(Stream, Line, LinePos, CharNo)) -->
  594    (   { is_stream(Stream),
  595          stream_property(Stream, file_name(File))
  596        }
  597    ->  swi_location(file(File, Line, LinePos, CharNo))
  598    ;   { Column is LinePos+1 },
  599        [ 'Stream ~w:~d:~d '-[Stream, Line, Column] ]
  600    ).
  601swi_location(autoload(File:Line)) -->
  602    [ url(File:Line), ': ' ].
  603swi_location(_) -->
  604    [].
  605
  606caller(system:'$record_clause'/3) -->
  607    !,
  608    [].
  609caller(Caller) -->
  610    { predicate_indicator(Caller, _) },
  611    !,
  612    predicate_reference(Caller, [link(false)]),
  613    [ ': ' ].
  614caller(Caller) -->
  615    [ '~p: '-[Caller] ].
 swi_extra(+Term)// is det
Extract information from the second argument of an error(Formal, ImplDefined) that is printed after the core of the message.
See also
- swi_location//1 uses the same term to insert context before the core of the message.
  626swi_extra(X) -->
  627    { var(X) },
  628    !,
  629    [].
  630swi_extra(Context) -->
  631    { message_lang(Lang) },
  632    prolog:message_context(Lang, Context),
  633    !.
  634swi_extra(Context) -->
  635    prolog:message_context(Context).
  636swi_extra(context(_, Msg)) -->
  637    { nonvar(Msg),
  638      Msg \== ''
  639    },
  640    !,
  641    swi_comment(Msg).
  642swi_extra(string(String, CharPos)) -->
  643    { sub_string(String, 0, CharPos, _, Before),
  644      sub_string(String, CharPos, _, 0, After)
  645    },
  646    [ nl, '~w'-[Before], nl, '** here **', nl, '~w'-[After] ].
  647swi_extra(_) -->
  648    [].
  649
  650swi_comment(already_from(Module)) -->
  651    !,
  652    [ ' (already imported from ~q)'-[Module] ].
  653swi_comment(directory(_Dir)) -->
  654    !,
  655    [ ' (is a directory)' ].
  656swi_comment(not_a_directory(_Dir)) -->
  657    !,
  658    [ ' (is not a directory)' ].
  659swi_comment(Msg) -->
  660    [ ' (~w)'-[Msg] ].
  661
  662
  663thread_context -->
  664    { \+ current_prolog_flag(toplevel_thread, true),
  665      thread_self(Id)
  666    },
  667    !,
  668    ['[Thread ~w] '-[Id]].
  669thread_context -->
  670    [].
  671
  672		 /*******************************
  673		 *        UNWIND MESSAGES	*
  674		 *******************************/
  675
  676unwind_message(Var) -->
  677    { var(Var) }, !,
  678    [ 'Unknown unwind message: ~p'-[Var] ].
  679unwind_message(abort) -->
  680    [ 'Execution Aborted' ].
  681unwind_message(halt(_)) -->
  682    [].
  683unwind_message(thread_exit(Term)) -->
  684    [ 'Invalid thread_exit/1.  Payload: ~p'-[Term] ].
  685unwind_message(Term) -->
  686    [ 'Unknown "unwind" exception: ~p'-[Term] ].
  687
  688
  689                 /*******************************
  690                 *        NORMAL MESSAGES       *
  691                 *******************************/
  692
  693:- dynamic prolog:version_msg/1.  694:- multifile prolog:version_msg/1.  695
  696prolog_message(welcome) -->
  697    [ 'Welcome to SWI-Prolog (' ],
  698    prolog_message(threads),
  699    prolog_message(address_bits),
  700    ['version ' ],
  701    prolog_message(version),
  702    [ ')', nl ],
  703    prolog_message(copyright),
  704    [ nl ],
  705    translate_message(user_versions),
  706    [ nl ],
  707    prolog_message(documentaton),
  708    [ nl, nl ].
  709prolog_message(user_versions) -->
  710    (   { findall(Msg, prolog:version_msg(Msg), Msgs),
  711          Msgs \== []
  712        }
  713    ->  [nl],
  714        user_version_messages(Msgs)
  715    ;   []
  716    ).
  717prolog_message(deprecated(Term)) -->
  718    { nonvar(Term) },
  719    (   { message_lang(Lang) },
  720        prolog:deprecated(Lang, Term)
  721    ->  []
  722    ;   prolog:deprecated(Term)
  723    ->  []
  724    ;   deprecated(Term)
  725    ).
  726prolog_message(unhandled_exception(E)) -->
  727    { nonvar(E) },
  728    [ 'Unhandled exception: ' ],
  729    (   translate_message(E)
  730    ->  []
  731    ;   [ '~p'-[E] ]
  732    ).
 prolog_message(+Term)//
  736prolog_message(initialization_error(_, E, File:Line)) -->
  737    !,
  738    [ url(File:Line),
  739      ': Initialization goal raised exception:', nl
  740    ],
  741    translate_message(E).
  742prolog_message(initialization_error(Goal, E, _)) -->
  743    [ 'Initialization goal ~p raised exception:'-[Goal], nl ],
  744    translate_message(E).
  745prolog_message(initialization_failure(_Goal, File:Line)) -->
  746    !,
  747    [ url(File:Line),
  748      ': Initialization goal failed'-[]
  749    ].
  750prolog_message(initialization_failure(Goal, _)) -->
  751    [ 'Initialization goal failed: ~p'-[Goal]
  752    ].
  753prolog_message(initialization_exception(E)) -->
  754    [ 'Prolog initialisation failed:', nl ],
  755    translate_message(E).
  756prolog_message(initialization(halt(Status), Goal, File:Line)) -->
  757    [ url(File:Line), ': '], goal(Goal), [nl,
  758      '  Initialization goal called ', ansi(code, '~p', [halt(Status)]),
  759      '.', nl,
  760      '  The program entry point should be called using ',
  761      ansi(code, 'initialization/2', []), '.', nl,
  762      '  Consider using ', ansi(code, 'library(main)', []), '.'
  763    ].
  764prolog_message(init_goal_syntax(Error, Text)) -->
  765    !,
  766    [ '-g ~w: '-[Text] ],
  767    translate_message(Error).
  768prolog_message(init_goal_failed(failed, @(Goal,File:Line))) -->
  769    !,
  770    [ url(File:Line), ': ~p: false'-[Goal] ].
  771prolog_message(init_goal_failed(Error, @(Goal,File:Line))) -->
  772    !,
  773    [ url(File:Line), ': ~p '-[Goal] ],
  774    translate_message(Error).
  775prolog_message(init_goal_failed(failed, Text)) -->
  776    !,
  777    [ '-g ~w: false'-[Text] ].
  778prolog_message(init_goal_failed(Error, Text)) -->
  779    !,
  780    [ '-g ~w: '-[Text] ],
  781    translate_message(Error).
  782prolog_message(goal_failed(Context, Goal)) -->
  783    [ 'Goal (~w) failed: ~p'-[Context, Goal] ].
  784prolog_message(no_current_module(Module)) -->
  785    [ '~w is not a current module (created)'-[Module] ].
  786prolog_message(commandline_arg_type(Flag, Arg)) -->
  787    [ 'Bad argument to commandline option -~w: ~w'-[Flag, Arg] ].
  788prolog_message(missing_feature(Name)) -->
  789    [ 'This version of SWI-Prolog does not support ~w'-[Name] ].
  790prolog_message(singletons(_Term, List)) -->
  791    [ 'Singleton variables: ~w'-[List] ].
  792prolog_message(multitons(_Term, List)) -->
  793    [ 'Singleton-marked variables appearing more than once: ~w'-[List] ].
  794prolog_message(profile_no_cpu_time) -->
  795    [ 'No CPU-time info.  Check the SWI-Prolog manual for details' ].
  796prolog_message(non_ascii(Text, Type)) -->
  797    [ 'Unquoted ~w with non-portable characters: ~w'-[Type, Text] ].
  798prolog_message(io_warning(Stream, Message)) -->
  799    { stream_property(Stream, position(Position)),
  800      !,
  801      stream_position_data(line_count, Position, LineNo),
  802      stream_position_data(line_position, Position, LinePos),
  803      Column is LinePos+1                       % line_position is 0-based
  804    },
  805    (   { stream_property(Stream, file_name(File)) }
  806    ->  [ url(File:LineNo:Column) ]
  807    ;   [ '~p:~d:~d'-[Stream, LineNo, Column] ]
  808    ),
  809    [ ': ~w'-[Message] ].
  810prolog_message(io_warning(Stream, Message)) -->
  811    [ 'stream ~p: ~w'-[Stream, Message] ].
  812prolog_message(option_usage(pldoc)) -->
  813    [ 'Usage: --pldoc[=port]' ].
  814prolog_message(interrupt(begin)) -->
  815    [ 'Action (h for help) ? ', flush ].
  816prolog_message(interrupt(end)) -->
  817    [ 'continue' ].
  818prolog_message(interrupt(trace)) -->
  819    [ 'continue (trace mode)' ].
  820prolog_message(unknown_in_module_user) -->
  821    [ 'Using a non-error value for unknown in the global module', nl,
  822      'causes most of the development environment to stop working.', nl,
  823      'Please use :- dynamic or limit usage of unknown to a module.', nl,
  824      'See https://www.swi-prolog.org/howto/database.html'
  825    ].
  826prolog_message(untable(PI)) -->
  827    [ 'Reconsult: removed tabling for ' ], predicate_reference(PI).
  828prolog_message(unknown_option(Set, Opt)) -->
  829    [ 'Unknown ~w option: ~p'-[Set, Opt] ].
  830
  831
  832                 /*******************************
  833                 *         LOADING FILES        *
  834                 *******************************/
  835
  836prolog_message(modify_active_procedure(Who, What)) -->
  837    predicate_reference(Who),
  838    [ ': modified active procedure ' ],
  839    predicate_reference(What).
  840prolog_message(load_file(failed(user:File))) -->
  841    [ 'Failed to load ~p'-[File] ].
  842prolog_message(load_file(failed(Module:File))) -->
  843    [ 'Failed to load ~p into module ~p'-[File, Module] ].
  844prolog_message(load_file(failed(File))) -->
  845    [ 'Failed to load ~p'-[File] ].
  846prolog_message(mixed_directive(Goal)) -->
  847    [ 'Cannot pre-compile mixed load/call directive: ~p'-[Goal] ].
  848prolog_message(cannot_redefine_comma) -->
  849    [ 'Full stop in clause-body?  Cannot redefine ,/2' ].
  850prolog_message(illegal_autoload_index(Dir, Term)) -->
  851    [ 'Illegal term in INDEX file of directory ~w: ~w'-[Dir, Term] ].
  852prolog_message(redefined_procedure(Type, Proc)) -->
  853    [ 'Redefined ~w procedure '-[Type] ],
  854    predicate_reference(Proc),
  855    predicate_definition(Proc, 'Previously defined').
  856prolog_message(declare_module(Module, abolish(Predicates))) -->
  857    [ 'Loading module ~w abolished:'-[Module], nl ],
  858    predicate_list(Predicates).
  859prolog_message(import_private(Module, Private)) -->
  860    [ 'import/1: ' ], predicate_reference(Private),
  861    [ ' is not exported (still imported into ~q)'-[Module] ].
  862prolog_message(ignored_weak_import(Into, From:PI)) -->
  863    [ 'Local definition of ' ],
  864    predicate_reference(Into:PI, [module(show)]),
  865    [ ' overrides weak import from ~q'-[From] ].
  866prolog_message(undefined_export(Module, PI)) -->
  867    [ 'Exported procedure ' ],
  868    predicate_reference(Module:PI, [module(show)]),
  869    [ ' is not defined' ].
  870prolog_message(no_exported_op(Module, Op)) -->
  871    [ 'Operator ~q:~q is not exported (still defined)'-[Module, Op] ].
  872prolog_message(discontiguous((-)/2,_)) -->
  873    prolog_message(minus_in_identifier).
  874prolog_message(discontiguous(Proc,Current)) -->
  875    [ 'Clauses of ' ], predicate_reference(Proc),
  876    [ ' are not together in the source-file' ],
  877    predicate_definition(Proc, 'Earlier definition'),
  878    [ nl, 'Current predicate: ' ], predicate_reference(Current),
  879    [ nl, 'Use ', ansi(code, ':- discontiguous ~p.', [Proc]),
  880      ' to suppress this message'
  881    ].
  882prolog_message(decl_no_effect(Goal)) -->
  883    [ 'Deprecated declaration has no effect: ~p'-[Goal] ].
  884prolog_message(load_file(start(Level, File))) -->
  885    [ '~|~t~*+Loading '-[Level] ],
  886    load_file(File),
  887    [ ' ...' ].
  888prolog_message(include_file(start(Level, File))) -->
  889    [ '~|~t~*+include '-[Level] ],
  890    load_file(File),
  891    [ ' ...' ].
  892prolog_message(include_file(done(Level, File))) -->
  893    [ '~|~t~*+included '-[Level] ],
  894    load_file(File).
  895prolog_message(load_file(done(Level, File, Action, Module, Time, Clauses))) -->
  896    [ '~|~t~*+'-[Level] ],
  897    load_file(File),
  898    [ ' ~w'-[Action] ],
  899    load_module(Module),
  900    [ ' ~2f sec, ~D clauses'-[Time, Clauses] ].
  901prolog_message(dwim_undefined(Goal, Alternatives)) -->
  902    [ 'Unknown procedure: ' ],
  903    predicate_reference(Goal),
  904    [ nl, '    However, there are definitions for:', nl ],
  905    dwim_alternatives(Alternatives).
  906prolog_message(dwim_correct(Into)) -->
  907    [ ansi(warning, 'Correct to: ', []), ansi(code, '~q', [Into]),
  908      ansi(warning, '? ', []), flush
  909    ].
  910prolog_message(error(loop_error(Spec), file_search(Used))) -->
  911    [ 'File search: too many levels of indirections on: ~p'-[Spec], nl,
  912      '    Used alias expansions:', nl
  913    ],
  914    used_search(Used).
  915prolog_message(minus_in_identifier) -->
  916    [ 'The "-" character should not be used to separate words in an', nl,
  917      'identifier.  Check the SWI-Prolog FAQ for details.'
  918    ].
  919prolog_message(qlf(removed_after_error(File))) -->
  920    [ 'Removed incomplete QLF file ~w'-[File] ].
  921prolog_message(qlf(recompile(Spec,_Pl,_Qlf,Reason))) -->
  922    [ '~p: recompiling QLF file'-[Spec] ],
  923    qlf_recompile_reason(Reason).
  924prolog_message(qlf(can_not_recompile(Spec,QlfFile,_Reason))) -->
  925    [ '~p: can not recompile "~w" (access denied)'-[Spec, QlfFile], nl,
  926      '\tLoading from source'-[]
  927    ].
  928prolog_message(qlf(system_lib_out_of_date(Spec,QlfFile))) -->
  929    [ '~p: can not recompile "~w" (access denied)'-[Spec, QlfFile], nl,
  930      '\tLoading QlfFile'-[]
  931    ].
  932prolog_message(redefine_module(Module, OldFile, File)) -->
  933    [ 'Module "~q" already loaded from ~w.'-[Module, OldFile], nl,
  934      'Wipe and reload from ~w? '-[File], flush
  935    ].
  936prolog_message(redefine_module_reply) -->
  937    [ 'Please answer y(es), n(o) or a(bort)' ].
  938prolog_message(reloaded_in_module(Absolute, OldContext, LM)) -->
  939    [ '~w was previously loaded in module ~w'-[Absolute, OldContext], nl,
  940      '\tnow it is reloaded into module ~w'-[LM] ].
  941prolog_message(expected_layout(Expected, Pos)) -->
  942    [ 'Layout data: expected ~w, found: ~p'-[Expected, Pos] ].
  943
  944used_search([]) -->
  945    [].
  946used_search([Alias=Expanded|T]) -->
  947    [ '        file_search_path(~p, ~p)'-[Alias, Expanded], nl ],
  948    used_search(T).
  949
  950load_file(file(Spec, _Path)) -->
  951    (   {atomic(Spec)}
  952    ->  [ '~w'-[Spec] ]
  953    ;   [ '~p'-[Spec] ]
  954    ).
  955%load_file(file(_, Path)) -->
  956%       [ '~w'-[Path] ].
  957
  958load_module(user) --> !.
  959load_module(system) --> !.
  960load_module(Module) -->
  961    [ ' into ~w'-[Module] ].
 user_predicate_indicator(+QPI, -PI) is det
Remove the module qualification from QPI if it does not add information for the user. This is the single module hiding policy of this file. See also predicate_reference//2.
  969user_predicate_indicator(Module:PI, PI) :-
  970    hidden_module(Module),
  971    !.
  972user_predicate_indicator(PI, PI).
  973
  974hidden_module(user) :- !.
  975hidden_module(system) :- !.
  976hidden_module(M) :-
  977    sub_atom(M, 0, _, _, $).
  978
  979qlf_recompile_reason(old) -->
  980    !,
  981    [ ' (out of date)'-[] ].
  982qlf_recompile_reason(_) -->
  983    [ ' (incompatible with current Prolog version)'-[] ].
  984
  985prolog_message(file_search(cache(Spec, _Cond), Path)) -->
  986    [ 'File search: ~p --> ~p (cache)'-[Spec, Path] ].
  987prolog_message(file_search(found(Spec, Cond), Path)) -->
  988    [ 'File search: ~p --> ~p OK ~p'-[Spec, Path, Cond] ].
  989prolog_message(file_search(tried(Spec, Cond), Path)) -->
  990    [ 'File search: ~p --> ~p NO ~p'-[Spec, Path, Cond] ].
  991
  992                 /*******************************
  993                 *              GC              *
  994                 *******************************/
  995
  996prolog_message(agc(start)) -->
  997    thread_context,
  998    [ 'AGC: ', flush ].
  999prolog_message(agc(done(Collected, Remaining, Time))) -->
 1000    [ at_same_line,
 1001      'reclaimed ~D atoms in ~3f sec. (remaining: ~D)'-
 1002      [Collected, Time, Remaining]
 1003    ].
 1004prolog_message(cgc(start)) -->
 1005    thread_context,
 1006    [ 'CGC: ', flush ].
 1007prolog_message(cgc(done(CollectedClauses, _CollectedBytes,
 1008                        RemainingBytes, Time))) -->
 1009    [ at_same_line,
 1010      'reclaimed ~D clauses in ~3f sec. (pending: ~D bytes)'-
 1011      [CollectedClauses, Time, RemainingBytes]
 1012    ].
 1013
 1014		 /*******************************
 1015		 *        STACK OVERFLOW	*
 1016		 *******************************/
 1017
 1018out_of_stack(Context) -->
 1019    { human_stack_size(Context.localused,   Local),
 1020      human_stack_size(Context.globalused,  Global),
 1021      human_stack_size(Context.trailused,   Trail),
 1022      human_stack_size(Context.stack_limit, Limit),
 1023      LCO is (100*(Context.depth - Context.environments))/Context.depth
 1024    },
 1025    [ 'Stack limit (~s) exceeded'-[Limit], nl,
 1026      '  Stack sizes: local: ~s, global: ~s, trail: ~s'-[Local,Global,Trail], nl,
 1027      '  Stack depth: ~D, last-call: ~0f%, Choice points: ~D'-
 1028         [Context.depth, LCO, Context.choicepoints], nl
 1029    ],
 1030    overflow_reason(Context, Resolve),
 1031    resolve_overflow(Resolve).
 1032
 1033human_stack_size(Size, String) :-
 1034    Size < 100,
 1035    format(string(String), '~dKb', [Size]).
 1036human_stack_size(Size, String) :-
 1037    Size < 100 000,
 1038    Value is Size / 1024,
 1039    format(string(String), '~1fMb', [Value]).
 1040human_stack_size(Size, String) :-
 1041    Value is Size / (1024*1024),
 1042    format(string(String), '~1fGb', [Value]).
 1043
 1044overflow_reason(Context, fix) -->
 1045    show_non_termination(Context),
 1046    !.
 1047overflow_reason(Context, enlarge) -->
 1048    { Stack = Context.get(stack) },
 1049    !,
 1050    [ '  In:'-[], nl ],
 1051    stack(Stack).
 1052overflow_reason(_Context, enlarge) -->
 1053    [ '  Insufficient global stack'-[] ].
 1054
 1055show_non_termination(Context) -->
 1056    (   { Stack = Context.get(cycle) }
 1057    ->  [ '  Probable infinite recursion (cycle):'-[], nl ]
 1058    ;   { Stack = Context.get(non_terminating) }
 1059    ->  [ '  Possible non-terminating recursion:'-[], nl ]
 1060    ),
 1061    stack(Stack).
 1062
 1063stack([]) --> [].
 1064stack([frame(Depth, M:Goal, _)|T]) -->
 1065    [ '    [~D] ~q:'-[Depth, M] ],
 1066    stack_goal(Goal),
 1067    [ nl ],
 1068    stack(T).
 1069
 1070stack_goal(Goal) -->
 1071    { compound(Goal),
 1072      !,
 1073      compound_name_arity(Goal, Name, Arity)
 1074    },
 1075    [ '~q('-[Name] ],
 1076    stack_goal_args(1, Arity, Goal),
 1077    [ ')'-[] ].
 1078stack_goal(Goal) -->
 1079    [ '~q'-[Goal] ].
 1080
 1081stack_goal_args(I, Arity, Goal) -->
 1082    { I =< Arity,
 1083      !,
 1084      arg(I, Goal, A),
 1085      I2 is I + 1
 1086    },
 1087    stack_goal_arg(A),
 1088    (   { I2 =< Arity }
 1089    ->  [ ', '-[] ],
 1090        stack_goal_args(I2, Arity, Goal)
 1091    ;   []
 1092    ).
 1093stack_goal_args(_, _, _) -->
 1094    [].
 1095
 1096stack_goal_arg(A) -->
 1097    { nonvar(A),
 1098      A = [Len|T],
 1099      !
 1100    },
 1101    (   {Len == cyclic_term}
 1102    ->  [ '[cyclic list]'-[] ]
 1103    ;   {T == []}
 1104    ->  [ '[length:~D]'-[Len] ]
 1105    ;   [ '[length:~D|~p]'-[Len, T] ]
 1106    ).
 1107stack_goal_arg(A) -->
 1108    { nonvar(A),
 1109      A = _/_,
 1110      !
 1111    },
 1112    [ '<compound ~p>'-[A] ].
 1113stack_goal_arg(A) -->
 1114    [ '~p'-[A] ].
 1115
 1116resolve_overflow(fix) -->
 1117    [].
 1118resolve_overflow(enlarge) -->
 1119    { current_prolog_flag(stack_limit, LimitBytes),
 1120      NewLimit is LimitBytes * 2
 1121    },
 1122    [ nl,
 1123      'Use the --stack_limit=size[KMG] command line option or'-[], nl,
 1124      '?- set_prolog_flag(stack_limit, ~I). to double the limit.'-[NewLimit]
 1125    ].
 out_of_c_stack
The thread's C-stack limit was exceeded. Give some advice on how to resolve this.
 1132out_of_c_stack -->
 1133    { statistics(c_stack, Limit), Limit > 0 },
 1134    !,
 1135    [ 'C-stack limit (~D bytes) exceeded.'-[Limit], nl ],
 1136    resolve_c_stack_overflow(Limit).
 1137out_of_c_stack -->
 1138    { statistics(c_stack, Limit), Limit > 0 },
 1139    [ 'C-stack limit exceeded.'-[Limit], nl ],
 1140    resolve_c_stack_overflow(Limit).
 1141
 1142resolve_c_stack_overflow(_Limit) -->
 1143    { thread_self(main) },
 1144    [ 'Use the shell command ' ], code('~w', 'ulimit -s size'),
 1145    [ ' to enlarge the limit.' ].
 1146resolve_c_stack_overflow(_Limit) -->
 1147    [ 'Use the ' ], code('~w', 'c_stack(KBytes)'),
 1148    [ ' option of '], code(thread_create/3), [' to enlarge the limit.' ].
 1149
 1150
 1151                 /*******************************
 1152                 *        MAKE/AUTOLOAD         *
 1153                 *******************************/
 1154
 1155prolog_message(make(reload(Files))) -->
 1156    { length(Files, N)
 1157    },
 1158    [ 'Make: reloading ~D files'-[N] ].
 1159prolog_message(make(done(_Files))) -->
 1160    [ 'Make: finished' ].
 1161prolog_message(make(library_index(Dir))) -->
 1162    [ 'Updating index for library ~w'-[Dir] ].
 1163prolog_message(autoload(Pred, File)) -->
 1164    thread_context,
 1165    [ 'autoloading ' ], predicate_reference(Pred, [link(false)]),
 1166    [ ' from ~w'-[File] ].
 1167prolog_message(autoload(read_index(Dir))) -->
 1168    [ 'Loading autoload index for ~w'-[Dir] ].
 1169prolog_message(autoload(disabled(Loaded))) -->
 1170    [ 'Disabled autoloading (loaded ~D files)'-[Loaded] ].
 1171prolog_message(autoload(already_defined(PI, From))) -->
 1172    predicate_reference(PI),
 1173    (   { predicate_head(PI, Head),
 1174          predicate_property(Head, built_in)
 1175        }
 1176    ->  [' is a built-in predicate']
 1177    ;   [ ' is already imported from module ' ],
 1178        code(From)
 1179    ).
 1180
 1181swi_message(autoload(Msg)) -->
 1182    [ nl, '  ' ],
 1183    autoload_message(Msg).
 1184
 1185autoload_message(not_exported(PI, Spec, _FullFile, _Exports)) -->
 1186    [ ansi(code, '~w', [Spec]),
 1187      ' does not export '
 1188    ],
 1189    predicate_reference(PI, [link(false)]).
 1190autoload_message(no_file(Spec)) -->
 1191    [ ansi(code, '~p', [Spec]), ': No such file' ].
 1192
 1193
 1194                 /*******************************
 1195                 *       COMPILER WARNINGS      *
 1196                 *******************************/
 1197
 1198% print warnings about dubious code raised by the compiler.
 1199% TBD: pass in PC to produce exact error locations.
 1200
 1201prolog_message(compiler_warnings(Clause, Warnings0)) -->
 1202    {   print_goal_options(DefOptions),
 1203        (   prolog_load_context(variable_names, VarNames)
 1204        ->  warnings_with_named_vars(Warnings0, VarNames, Warnings),
 1205            Options = [variable_names(VarNames)|DefOptions]
 1206        ;   Options = DefOptions,
 1207            Warnings = Warnings0
 1208        )
 1209    },
 1210    compiler_warnings(Warnings, Clause, Options).
 1211
 1212warnings_with_named_vars([], _, []).
 1213warnings_with_named_vars([H|T0], VarNames, [H|T]) :-
 1214    term_variables(H, Vars),
 1215    '$member'(V1, Vars),
 1216    '$member'(_=V2, VarNames),
 1217    V1 == V2,
 1218    !,
 1219    warnings_with_named_vars(T0, VarNames, T).
 1220warnings_with_named_vars([_|T0], VarNames, T) :-
 1221    warnings_with_named_vars(T0, VarNames, T).
 1222
 1223
 1224compiler_warnings([], _, _) --> [].
 1225compiler_warnings([H|T], Clause, Options) -->
 1226    (   compiler_warning(H, Clause, Options)
 1227    ->  []
 1228    ;   [ 'Unknown compiler warning: ~W'-[H,Options] ]
 1229    ),
 1230    (   {T==[]}
 1231    ->  []
 1232    ;   [nl]
 1233    ),
 1234    compiler_warnings(T, Clause, Options).
 1235
 1236compiler_warning(eq_vv(A,B), _Clause, Options) -->
 1237    (   { A == B }
 1238    ->  [ 'Test is always true: ~W'-[A==B, Options] ]
 1239    ;   [ 'Test is always false: ~W'-[A==B, Options] ]
 1240    ).
 1241compiler_warning(eq_singleton(A,B), _Clause, Options) -->
 1242    [ 'Test is always false: ~W'-[A==B, Options] ].
 1243compiler_warning(neq_vv(A,B), _Clause, Options) -->
 1244    (   { A \== B }
 1245    ->  [ 'Test is always true: ~W'-[A\==B, Options] ]
 1246    ;   [ 'Test is always false: ~W'-[A\==B, Options] ]
 1247    ).
 1248compiler_warning(neq_singleton(A,B), _Clause, Options) -->
 1249    [ 'Test is always true: ~W'-[A\==B, Options] ].
 1250compiler_warning(unify_singleton(A,B), _Clause, Options) -->
 1251    [ 'Unified variable is not used: ~W'-[A=B, Options] ].
 1252compiler_warning(always(Bool, Pred, Arg), _Clause, Options) -->
 1253    { Goal =.. [Pred,Arg] },
 1254    [ 'Test is always ~w: ~W'-[Bool, Goal, Options] ].
 1255compiler_warning(unbalanced_var(V), _Clause, Options) -->
 1256    [ 'Variable not introduced in all branches: ~W'-[V, Options] ].
 1257compiler_warning(branch_singleton(V), _Clause, Options) -->
 1258    [ 'Singleton variable in branch: ~W'-[V, Options] ].
 1259compiler_warning(negation_singleton(V), _Clause, Options) -->
 1260    [ 'Singleton variable in \\+: ~W'-[V, Options] ].
 1261compiler_warning(multiton(V), _Clause, Options) -->
 1262    [ 'Singleton-marked variable appears more than once: ~W'-[V, Options] ].
 1263
 1264print_goal_options(
 1265    [ quoted(true),
 1266      portray(true)
 1267    ]).
 1268
 1269
 1270                 /*******************************
 1271                 *      TOPLEVEL MESSAGES       *
 1272                 *******************************/
 1273
 1274prolog_message(version) -->
 1275    { current_prolog_flag(version_git, Version) },
 1276    !,
 1277    [ '~w'-[Version] ].
 1278prolog_message(version) -->
 1279    { current_prolog_flag(version_data, swi(Major,Minor,Patch,Options))
 1280    },
 1281    (   { '$option'(tag(Tag), Options) }
 1282    ->  [ '~w.~w.~w-~w'-[Major, Minor, Patch, Tag] ]
 1283    ;   [ '~w.~w.~w'-[Major, Minor, Patch] ]
 1284    ).
 1285prolog_message(address_bits) -->
 1286    { current_prolog_flag(address_bits, Bits)
 1287    },
 1288    !,
 1289    [ '~d bits, '-[Bits] ].
 1290prolog_message(threads) -->
 1291    { current_prolog_flag(threads, true)
 1292    },
 1293    !,
 1294    [ 'threaded, ' ].
 1295prolog_message(threads) -->
 1296    [].
 1297prolog_message(copyright) -->
 1298    [ 'SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.', nl,
 1299      'Please run ', ansi(code, '?- license.', []), ' for legal details.'
 1300    ].
 1301prolog_message(documentaton) -->
 1302    [ 'For online help and background, visit ', url('https://www.swi-prolog.org') ],
 1303    (   { exists_source(library(help)) }
 1304    ->  [ nl,
 1305          'For built-in help, use ', ansi(code, '?- help(Topic).', []),
 1306          ' or ', ansi(code, '?- apropos(Word).', [])
 1307        ]
 1308    ;   []
 1309    ).
 1310prolog_message(about) -->
 1311    [ 'SWI-Prolog version (' ],
 1312    prolog_message(threads),
 1313    prolog_message(address_bits),
 1314    ['version ' ],
 1315    prolog_message(version),
 1316    [ ')', nl ],
 1317    prolog_message(copyright).
 1318prolog_message(halt) -->
 1319    [ 'halt' ].
 1320prolog_message(break(begin, Level)) -->
 1321    [ 'Break level ~d'-[Level] ].
 1322prolog_message(break(end, Level)) -->
 1323    [ 'Exit break level ~d'-[Level] ].
 1324prolog_message(var_query(_)) -->
 1325    [ '... 1,000,000 ............ 10,000,000 years later', nl, nl,
 1326      '~t~8|>> 42 << (last release gives the question)'
 1327    ].
 1328prolog_message(close_on_abort(Stream)) -->
 1329    [ 'Abort: closed stream ~p'-[Stream] ].
 1330prolog_message(cancel_halt(Reason)) -->
 1331    [ 'Halt cancelled: ~p'-[Reason] ].
 1332prolog_message(on_error(halt(Status))) -->
 1333    { statistics(errors, Errors),
 1334      statistics(warnings, Warnings)
 1335    },
 1336    [ 'Halting with status ~w due to ~D errors and ~D warnings'-
 1337      [Status, Errors, Warnings] ].
 1338
 1339prolog_message(query(QueryResult)) -->
 1340    query_result(QueryResult).
 1341
 1342query_result(no) -->            % failure
 1343    [ ansi(truth(false), 'false.', []) ],
 1344    extra_line.
 1345query_result(yes(true, [])) -->      % prompt_alternatives_on: groundness
 1346    !,
 1347    [ ansi(truth(true), 'true.', []) ],
 1348    extra_line.
 1349query_result(yes(Delays, Residuals)) -->
 1350    result([], Delays, Residuals),
 1351    extra_line.
 1352query_result(done) -->          % user typed <CR>
 1353    extra_line.
 1354query_result(yes(Bindings, Delays, Residuals)) -->
 1355    result(Bindings, Delays, Residuals),
 1356    prompt(yes, Bindings, Delays, Residuals).
 1357query_result(more(Bindings, Delays, Residuals)) -->
 1358    result(Bindings, Delays, Residuals),
 1359    prompt(more, Bindings, Delays, Residuals).
 1360:- if(current_prolog_flag(emscripten, true)). 1361query_result(help) -->
 1362    [ ansi(bold, '  Possible actions:', []), nl,
 1363      '  ; (n,r,space): redo              | t:       trace&redo'-[], nl,
 1364      '  *:             show choicepoint  | . (c,a): stop'-[], nl,
 1365      '  w:             write             | p:       print'-[], nl,
 1366      '  +:             max_depth*5       | -:       max_depth//5'-[], nl,
 1367      '  h (?):         help'-[],
 1368      nl, nl
 1369    ].
 1370:- else. 1371query_result(help) -->
 1372    [ ansi(bold, '  Possible actions:', []), nl,
 1373      '  ; (n,r,space,TAB): redo              | t:           trace&redo'-[], nl,
 1374      '  *:                 show choicepoint  | . (c,a,RET): stop'-[], nl,
 1375      '  w:                 write             | p:           print'-[], nl,
 1376      '  +:                 max_depth*5       | -:           max_depth//5'-[], nl,
 1377      '  b:                 break             | h (?):       help'-[],
 1378      nl, nl
 1379    ].
 1380:- endif. 1381query_result(action) -->
 1382    [ 'Action? '-[], flush ].
 1383query_result(confirm) -->
 1384    [ 'Please answer \'y\' or \'n\'? '-[], flush ].
 1385query_result(eof) -->
 1386    [ nl ].
 1387query_result(toplevel_open_line) -->
 1388    [].
 1389
 1390prompt(Answer, [], true, []-[]) -->
 1391    !,
 1392    prompt(Answer, empty).
 1393prompt(Answer, _, _, _) -->
 1394    !,
 1395    prompt(Answer, non_empty).
 1396
 1397prompt(yes, empty) -->
 1398    !,
 1399    [ ansi(truth(true), 'true.', []) ],
 1400    extra_line.
 1401prompt(yes, _) -->
 1402    !,
 1403    [ full_stop ],
 1404    extra_line.
 1405prompt(more, empty) -->
 1406    !,
 1407    [ ansi(truth(true), 'true ', []), flush ].
 1408prompt(more, _) -->
 1409    !,
 1410    [ ' '-[], flush ].
 1411
 1412result(Bindings, Delays, Residuals) -->
 1413    { current_prolog_flag(answer_write_options, Options0),
 1414      Options = [partial(true)|Options0],
 1415      GOptions = [priority(999)|Options0]
 1416    },
 1417    wfs_residual_program(Delays, GOptions),
 1418    bindings(Bindings, [priority(699)|Options]),
 1419    (   {Residuals == []-[]}
 1420    ->  bind_delays_sep(Bindings, Delays),
 1421        delays(Delays, GOptions)
 1422    ;   bind_res_sep(Bindings, Residuals),
 1423        residuals(Residuals, GOptions),
 1424        (   {Delays == true}
 1425        ->  []
 1426        ;   [','-[], nl],
 1427            delays(Delays, GOptions)
 1428        )
 1429    ).
 1430
 1431bindings([], _) -->
 1432    [].
 1433bindings([binding(Names,Skel,Subst)|T], Options) -->
 1434    { '$last'(Names, Name) },
 1435    var_names(Names), value(Name, Skel, Subst, Options),
 1436    (   { T \== [] }
 1437    ->  [ ','-[], nl ],
 1438        bindings(T, Options)
 1439    ;   []
 1440    ).
 1441
 1442var_names([Name]) -->
 1443    !,
 1444    [ ansi(binding(name), '~w', [Name]), ' = '-[] ].
 1445var_names([Name1,Name2|T]) -->
 1446    !,
 1447    [ ansi(binding(name), '~w', [Name1]), ' = '-[],
 1448      ansi(binding(name), '~w', [Name2]), ', '-[]
 1449    ],
 1450    var_names([Name2|T]).
 1451
 1452
 1453value(Name, Skel, Subst, Options) -->
 1454    (   { var(Skel), Subst = [Skel=S] }
 1455    ->  { Skel = '$VAR'(Name) },
 1456        [ '~W'-[S, Options] ]
 1457    ;   [ '~W'-[Skel, Options] ],
 1458        substitution(Subst, Options)
 1459    ).
 1460
 1461substitution([], _) --> !.
 1462substitution([N=V|T], Options) -->
 1463    [ ', ', ansi(comment, '% where', []), nl,
 1464      '    ~w = ~W'-[N,V,Options] ],
 1465    substitutions(T, Options).
 1466
 1467substitutions([], _) --> [].
 1468substitutions([N=V|T], Options) -->
 1469    [ ','-[], nl, '    ~w = ~W'-[N,V,Options] ],
 1470    substitutions(T, Options).
 1471
 1472
 1473residuals(Normal-Hidden, Options) -->
 1474    residuals1(Normal, Options),
 1475    bind_res_sep(Normal, Hidden),
 1476    (   {Hidden == []}
 1477    ->  []
 1478    ;   [ansi(comment, '% with pending residual goals', []), nl]
 1479    ),
 1480    residuals1(Hidden, Options).
 1481
 1482residuals1([], _) -->
 1483    [].
 1484residuals1([G|Gs], Options) -->
 1485    (   { Gs \== [] }
 1486    ->  [ '~W,'-[G, Options], nl ],
 1487        residuals1(Gs, Options)
 1488    ;   [ '~W'-[G, Options] ]
 1489    ).
 1490
 1491wfs_residual_program(true, _Options) -->
 1492    !.
 1493wfs_residual_program(Goal, _Options) -->
 1494    { current_prolog_flag(toplevel_list_wfs_residual_program, true),
 1495      '$current_typein_module'(TypeIn),
 1496      (   current_predicate(delays_residual_program/2)
 1497      ->  true
 1498      ;   use_module(library(wfs), [delays_residual_program/2])
 1499      ),
 1500      delays_residual_program(TypeIn:Goal, TypeIn:Program),
 1501      Program \== []
 1502    },
 1503    !,
 1504    [ ansi(comment, '% WFS residual program', []), nl ],
 1505    [ ansi(wfs(residual_program), '~@', ['$messages':list_clauses(Program)]) ].
 1506wfs_residual_program(_, _) --> [].
 1507
 1508delays(true, _Options) -->
 1509    !.
 1510delays(Goal, Options) -->
 1511    { current_prolog_flag(toplevel_list_wfs_residual_program, true)
 1512    },
 1513    !,
 1514    [ ansi(truth(undefined), '~W', [Goal, Options]) ].
 1515delays(_, _Options) -->
 1516    [ ansi(truth(undefined), undefined, []) ].
 1517
 1518:- public list_clauses/1. 1519
 1520list_clauses([]).
 1521list_clauses([H|T]) :-
 1522    (   system_undefined(H)
 1523    ->  true
 1524    ;   portray_clause(user_output, H, [indent(4)])
 1525    ),
 1526    list_clauses(T).
 1527
 1528system_undefined((undefined :- tnot(undefined))).
 1529system_undefined((answer_count_restraint :- tnot(answer_count_restraint))).
 1530system_undefined((radial_restraint :- tnot(radial_restraint))).
 1531
 1532bind_res_sep(_, []) --> !.
 1533bind_res_sep(_, []-[]) --> !.
 1534bind_res_sep([], _) --> !.
 1535bind_res_sep(_, _) --> [','-[], nl].
 1536
 1537bind_delays_sep([], _) --> !.
 1538bind_delays_sep(_, true) --> !.
 1539bind_delays_sep(_, _) --> [','-[], nl].
 extra_line// is det
End the answer and, if toplevel_extra_white_line is true, add an empty line. The ~N cannot be replaced by nl because the answer is not always left at a non-empty line. The eol element paints the remainder of the line if the message has a background colour, which ~N cannot do as it is written using format/3.

Note that eol ends the last line of the answer. The empty line that separates the answer from the next query is not part of the answer and keeps the default background.

 1553extra_line -->
 1554    { current_prolog_flag(toplevel_extra_white_line, true) },
 1555    !,
 1556    [eol, '~N'-[]].
 1557extra_line -->
 1558    [eol].
 1559
 1560prolog_message(if_tty(Message)) -->
 1561    (   {current_prolog_flag(tty_control, true)}
 1562    ->  [ at_same_line ], list(Message)
 1563    ;   []
 1564    ).
 1565prolog_message(halt(Reason)) -->
 1566    [ '~w: halt'-[Reason] ].
 1567prolog_message(no_action(Char)) -->
 1568    [ 'Unknown action: ~c (h for help)'-[Char], nl ].
 1569
 1570prolog_message(history(help(Show, Help))) -->
 1571    [ 'History Commands:', nl,
 1572      '    !!.              Repeat last query', nl,
 1573      '    !nr.             Repeat query numbered <nr>', nl,
 1574      '    !str.            Repeat last query starting with <str>', nl,
 1575      '    !?str.           Repeat last query holding <str>', nl,
 1576      '    ^old^new.        Substitute <old> into <new> of last query', nl,
 1577      '    !nr^old^new.     Substitute in query numbered <nr>', nl,
 1578      '    !str^old^new.    Substitute in query starting with <str>', nl,
 1579      '    !?str^old^new.   Substitute in query holding <str>', nl,
 1580      '    ~w.~21|Show history list'-[Show], nl,
 1581      '    ~w.~21|Show this list'-[Help], nl, nl
 1582    ].
 1583prolog_message(history(no_event)) -->
 1584    [ '! No such event' ].
 1585prolog_message(history(bad_substitution)) -->
 1586    [ '! Bad substitution' ].
 1587prolog_message(history(expanded(Event))) -->
 1588    [ '~w.'-[Event] ].
 1589prolog_message(history(history(Events))) -->
 1590    history_events(Events).
 1591prolog_message(history(no_history)) -->
 1592    [ '! event history not supported in this version' ].
 1593
 1594history_events([]) -->
 1595    [].
 1596history_events([Nr-Event|T]) -->
 1597    [ ansi(comment, '%', []),
 1598      ansi(bold, '~t~w ~6|', [Nr]),
 1599      ansi(code, '~s', [Event]),
 1600      nl
 1601    ],
 1602    history_events(T).
 user_version_messages(+Terms)//
Helper for the welcome message to print information registered using version/1.
 1610user_version_messages([]) --> [].
 1611user_version_messages([H|T]) -->
 1612    user_version_message(H),
 1613    user_version_messages(T).
 user_version_message(+Term)
 1617user_version_message(Term) -->
 1618    translate_message(Term), !, [nl].
 1619user_version_message(Atom) -->
 1620    [ '~w'-[Atom], nl ].
 1621
 1622
 1623                 /*******************************
 1624                 *       DEBUGGER MESSAGES      *
 1625                 *******************************/
 1626
 1627prolog_message(spy(Head)) -->
 1628    [ 'New spy point on ' ],
 1629    predicate_reference(Head).
 1630prolog_message(already_spying(Head)) -->
 1631    [ 'Already spying ' ],
 1632    predicate_reference(Head).
 1633prolog_message(nospy(Head)) -->
 1634    [ 'Removed spy point from ' ],
 1635    predicate_reference(Head).
 1636prolog_message(trace_mode(OnOff)) -->
 1637    [ 'Trace mode switched to ~w'-[OnOff] ].
 1638prolog_message(debug_mode(OnOff)) -->
 1639    [ 'Debug mode switched to ~w'-[OnOff] ].
 1640prolog_message(debugging(OnOff, Threads)) -->
 1641    [ 'Debug mode is ~w'-[OnOff] ],
 1642    debugging_threads(Threads).
 1643prolog_message(spying([])) -->
 1644    !,
 1645    [ 'No spy points' ].
 1646prolog_message(spying(Heads)) -->
 1647    [ 'Spy points (see spy/1) on:', nl ],
 1648    predicate_list(Heads).
 1649prolog_message(trace(Head, [])) -->
 1650    !,
 1651    [ '    ' ], predicate_reference(Head, [tag(true)]),
 1652    [ ' Not tracing'-[], nl].
 1653prolog_message(trace(Head, Ports)) -->
 1654    { '$member'(Port, Ports), compound(Port),
 1655      !,
 1656      numbervars(Head+Ports, 0, _, [singletons(true)])
 1657    },
 1658    [ '    ~p: ~p'-[Head,Ports] ].
 1659prolog_message(trace(Head, Ports)) -->
 1660    [ '    ' ], predicate_reference(Head, [tag(true)]),
 1661    [ ': ~w'-[Ports], nl].
 1662prolog_message(tracing([])) -->
 1663    !,
 1664    [ 'No traced predicates (see trace/1,2)' ].
 1665prolog_message(tracing(Heads)) -->
 1666    [ 'Trace points (see trace/1,2) on:', nl ],
 1667    tracing_list(Heads).
 predicate_list(+Specs)// is det
Emit a list of predicates, one per line, each tagged with its kind. See predicate_reference//2.
 1674predicate_list([]) -->
 1675    [].
 1676predicate_list([H|T]) -->
 1677    [ '    ' ], predicate_reference(H, [tag(true)]), [nl],
 1678    predicate_list(T).
 1679
 1680tracing_list([]) -->
 1681    [].
 1682tracing_list([trace(Head, Ports)|T]) -->
 1683    translate_message(trace(Head, Ports)),
 1684    tracing_list(T).
 1685
 1686debugging_threads([]) -->
 1687    [].
 1688debugging_threads(ThreadsByClass) -->
 1689    [ nl, 'Threads in the following classes run in debug mode:', nl],
 1690    list_threads_by_class(ThreadsByClass).
 1691
 1692list_threads_by_class([]) -->
 1693    [].
 1694list_threads_by_class([H|T]) -->
 1695    list_thread_class(H),
 1696    list_threads_by_class(T).
 1697
 1698list_thread_class(Class-Threads) -->
 1699    { length(Threads, Count) },
 1700    [ '    Class ', ansi(code, '~p', [Class]), ': ~D threads'-[Count] ].
 1701
 1702% frame(+Frame, +Choice, +Port, +PC) - Print for the debugger.
 1703prolog_message(frame(Frame, _Choice, backtrace, _PC)) -->
 1704    !,
 1705    { prolog_frame_attribute(Frame, level, Level)
 1706    },
 1707    [ ansi(frame(level), '~t[~D] ~10|', [Level]) ],
 1708    frame_context(Frame),
 1709    frame_goal(Frame, backtrace).
 1710prolog_message(frame(Frame, Choice, choice, PC)) -->
 1711    !,
 1712    prolog_message(frame(Frame, Choice, backtrace, PC)).
 1713prolog_message(frame(_, _Choice, cut_call(_PC), _)) --> !.
 1714prolog_message(frame(Frame, _Choice, Port, _PC)) -->
 1715    frame_flags(Frame),
 1716    port(Port),
 1717    frame_level(Frame),
 1718    frame_context(Frame),
 1719    frame_depth_limit(Port, Frame),
 1720    frame_goal(Frame, Port),
 1721    [ flush ].
 1722
 1723% frame(:Goal, +Trace)		- Print for trace/2
 1724prolog_message(frame(Goal, trace(Port))) -->
 1725    !,
 1726    thread_context,
 1727    [ ' T ' ],
 1728    port(Port),
 1729    predicate_goal(Goal, Port).
 1730prolog_message(frame(Goal, trace(Port, Id))) -->
 1731    !,
 1732    thread_context,
 1733    [ ' T ' ],
 1734    port(Port, Id),
 1735    predicate_goal(Goal, Port).
 goal_style(+Port, -Style) is det
Style is the colour class used for the goal of a frame that is being reported for Port. It is a term goal(Port, Parity), which allows themes to decorate the goal depending on the port, on the parity of the step count (striping, which separates the steps of a trace visually) or both. See also '$answer_class'/1, which does the same for the answers of the interactive toplevel.
 1746goal_style(Port0, goal(Port, Parity)) :-
 1747    functor(Port0, Port, _),
 1748    trace_parity(Parity).
 1749
 1750trace_parity(Parity) :-
 1751    (   nb_current('$trace_step', C0)
 1752    ->  true
 1753    ;   C0 = 0
 1754    ),
 1755    C is C0+1,
 1756    nb_setval('$trace_step', C),
 1757    (   C mod 2 =:= 0
 1758    ->  Parity = even
 1759    ;   Parity = odd
 1760    ).
 1761
 1762frame_goal(Frame, Port) -->
 1763    { prolog_frame_attribute(Frame, goal, Goal),
 1764      goal_style(Port, Style)
 1765    },
 1766    (   { frame_location(Frame, Location) }
 1767    ->  goal(Goal, Style, Location)
 1768    ;   goal(Goal, Style)
 1769    ).
 predicate_goal(+Goal, +Port)// is det
Emit Goal, linking it to the definition of its predicate. Used if we have no frame, i.e., for the messages of library(prolog_trace).
 1776predicate_goal(Goal, Port) -->
 1777    { goal_style(Port, Style)
 1778    },
 1779    (   { goal_links,
 1780          predicate_location(Goal, Location)
 1781        }
 1782    ->  goal(Goal, Style, Location)
 1783    ;   goal(Goal, Style)
 1784    ).
 1785
 1786goal(Goal0, Style) -->
 1787    { goal_format(Goal0, Goal, Options)
 1788    },
 1789    [ ansi(Style, '~W', [Goal, Options]) ].
 1790
 1791goal(Goal0, Style, Location) -->
 1792    { goal_format(Goal0, Goal, Options)
 1793    },
 1794    [ url(Location, ansi(Style, '~W', [Goal, Options])) ].
 1795
 1796goal_format(Goal0, Goal, Options) :-
 1797    clean_goal(Goal0, Goal),
 1798    current_prolog_flag(debugger_write_options, Options).
 frame_location(+Frame, -Location) is semidet
Location is File:Line for the call site of Frame, i.e., the place in the clause of the parent frame from which Frame was called. This is the position the user is at while tracing. If we cannot find it, fall back to the clause that runs in Frame and finally to the file that defines the predicate.

Resolving the call site uses library(prolog_stack), which has to run the decompiler and read the source file. This is affordable for an interactive tracer, but we only do it if the location can actually be used, i.e., if hyperlinks are rendered. See goal_links/0.

 1813frame_location(Frame, Location) :-
 1814    goal_links,
 1815    catch(frame_location_(Frame, Location), _, fail).
 1816
 1817frame_location_(Frame, File:Line) :-
 1818    prolog_frame_attribute(Frame, pc, PC),
 1819    prolog_frame_attribute(Frame, parent, Parent),
 1820    prolog_frame_attribute(Parent, clause, Clause),
 1821    prolog_stack_frame_property(frame(_,clause(Clause,PC),_),
 1822                                location(File:Line)),
 1823    !.
 1824frame_location_(Frame, File:Line) :-
 1825    prolog_frame_attribute(Frame, clause, Clause),
 1826    clause_property(Clause, file(File)),
 1827    clause_property(Clause, line_count(Line)),
 1828    !.
 1829frame_location_(Frame, Location) :-
 1830    prolog_frame_attribute(Frame, goal, Goal),
 1831    predicate_location(Goal, Location).
 goal_links is semidet
True when goals printed by the debugger should be linked to their source location. Controlled by the flag debugger_goal_links, which is one of true, false or auto. Using auto (default) we create the links if the console can render them.
 1840goal_links :-
 1841    current_prolog_flag(debugger_goal_links, Links),
 1842    goal_links(Links).
 1843
 1844goal_links(true).                       % note: no clause for `false`
 1845goal_links(auto) :-
 1846    (   current_prolog_flag(hyperlink_term, true)
 1847    ->  true
 1848    ;   predicate_property(ansi_term:hyperlink(_,_), number_of_clauses(N)),
 1849        N > 0
 1850    ).
 1851
 1852frame_level(Frame) -->
 1853    { prolog_frame_attribute(Frame, level, Level)
 1854    },
 1855    [ '(~D) '-[Level] ].
 1856
 1857frame_context(Frame) -->
 1858    (   { current_prolog_flag(debugger_show_context, true),
 1859          prolog_frame_attribute(Frame, context_module, Context)
 1860        }
 1861    ->  [ '[~w] '-[Context] ]
 1862    ;   []
 1863    ).
 1864
 1865frame_depth_limit(fail, Frame) -->
 1866    { prolog_frame_attribute(Frame, depth_limit_exceeded, true)
 1867    },
 1868    !,
 1869    [ '[depth-limit exceeded] ' ].
 1870frame_depth_limit(_, _) -->
 1871    [].
 1872
 1873frame_flags(Frame) -->
 1874    { prolog_frame_attribute(Frame, goal, Goal),
 1875      (   predicate_property(Goal, transparent)
 1876      ->  T = '^'
 1877      ;   T = ' '
 1878      ),
 1879      (   predicate_property(Goal, spying)
 1880      ->  S = '*'
 1881      ;   S = ' '
 1882      )
 1883    },
 1884    [ '~w~w '-[T, S] ].
 1885
 1886% trace/1 context handling
 1887port(Port, Dict) -->
 1888    { _{level:Level, start:Time} :< Dict
 1889    },
 1890    (   { Port \== call,
 1891          get_time(Now),
 1892          Passed is (Now - Time)*1000.0
 1893        }
 1894    ->  [ '[~d +~1fms] '-[Level, Passed] ]
 1895    ;   [ '[~d] '-[Level] ]
 1896    ),
 1897    port(Port).
 1898port(Port, _Id-Level) -->
 1899    [ '[~d] '-[Level] ],
 1900    port(Port).
 1901
 1902port(PortTerm) -->
 1903    { functor(PortTerm, Port, _),
 1904      port_name(Port, Name)
 1905    },
 1906    !,
 1907    [ ansi(port(Port), '~w: ', [Name]) ].
 1908
 1909port_name(call,      'Call').
 1910port_name(exit,      'Exit').
 1911port_name(fail,      'Fail').
 1912port_name(redo,      'Redo').
 1913port_name(unify,     'Unify').
 1914port_name(exception, 'Exception').
 1915
 1916clean_goal(M:Goal, Goal) :-
 1917    hidden_module(M),
 1918    !.
 1919clean_goal(M:Goal, Goal) :-
 1920    predicate_property(M:Goal, built_in),
 1921    !.
 1922clean_goal(Goal, Goal).
 1923
 1924
 1925                 /*******************************
 1926                 *        COMPATIBILITY         *
 1927                 *******************************/
 1928
 1929prolog_message(compatibility(renamed(Old, New))) -->
 1930    [ 'The predicate ' ], predicate_reference(Old, [link(false)]),
 1931    [ ' has been renamed to ' ], predicate_reference(New),
 1932    [ '.', nl,
 1933      'Please update your sources for compatibility with future versions.'
 1934    ].
 1935
 1936
 1937                 /*******************************
 1938                 *            THREADS           *
 1939                 *******************************/
 1940
 1941prolog_message(abnormal_thread_completion(Goal, exception(Ex))) -->
 1942    !,
 1943    [ 'Thread running "~p" died on exception: '-[Goal] ],
 1944    translate_message(Ex).
 1945prolog_message(abnormal_thread_completion(Goal, fail)) -->
 1946    [ 'Thread running "~p" died due to failure'-[Goal] ].
 1947prolog_message(threads_not_died(Running)) -->
 1948    [ 'The following threads wouldn\'t die: ~p'-[Running] ].
 1949
 1950
 1951                 /*******************************
 1952                 *             PACKS            *
 1953                 *******************************/
 1954
 1955prolog_message(pack(attached(Pack, BaseDir))) -->
 1956    [ 'Attached package ~w at ~q'-[Pack, BaseDir] ].
 1957prolog_message(pack(duplicate(Entry, OldDir, Dir))) -->
 1958    [ 'Package ~w already attached at ~q.'-[Entry,OldDir], nl,
 1959      '\tIgnoring version from ~q'- [Dir]
 1960    ].
 1961prolog_message(pack(no_arch(Entry, Arch))) -->
 1962    [ 'Package ~w: no binary for architecture ~w'-[Entry, Arch] ].
 1963
 1964                 /*******************************
 1965                 *             MISC             *
 1966                 *******************************/
 1967
 1968prolog_message(null_byte_in_path(Component)) -->
 1969    [ '0-byte in PATH component: ~p (skipped directory)'-[Component] ].
 1970prolog_message(invalid_tmp_dir(Dir, Reason)) -->
 1971    [ 'Cannot use ~p as temporary file directory: ~w'-[Dir, Reason] ].
 1972prolog_message(ambiguous_stream_pair(Pair)) -->
 1973    [ 'Ambiguous operation on stream pair ~p'-[Pair] ].
 1974prolog_message(backcomp(init_file_moved(FoundFile))) -->
 1975    { absolute_file_name(app_config('init.pl'), InitFile,
 1976                         [ file_errors(fail)
 1977                         ])
 1978    },
 1979    [ 'The location of the config file has moved'-[], nl,
 1980      '  from "~w"'-[FoundFile], nl,
 1981      '  to   "~w"'-[InitFile], nl,
 1982      '  See https://www.swi-prolog.org/modified/config-files.html'-[]
 1983    ].
 1984prolog_message(not_accessed_flags(List)) -->
 1985    [ 'The following Prolog flags have been set but not used:', nl ],
 1986    flags(List).
 1987prolog_message(implicit_create_flag(Flag)) -->
 1988    [ 'Created unknown Prolog flag ', ansi(code, '~q', Flag),
 1989      ' (see create_prolog_flag/3)'
 1990    ].
 1991prolog_message(prolog_flag_invalid_preset(Flag, Preset, _Type, New)) -->
 1992    [ 'Prolog flag ', ansi(code, '~q', Flag), ' has been (re-)created with a type that is \c
 1993       incompatible with its value.', nl,
 1994      'Value updated from ', ansi(code, '~p', [Preset]), ' to default (',
 1995      ansi(code, '~p', [New]), ')'
 1996    ].
 1997
 1998
 1999flags([H|T]) -->
 2000    ['  ', ansi(code, '~q', [H])],
 2001    (   {T == []}
 2002    ->  []
 2003    ;   [nl],
 2004        flags(T)
 2005    ).
 2006
 2007
 2008		 /*******************************
 2009		 *          DEPRECATED		*
 2010		 *******************************/
 2011
 2012deprecated(set_prolog_stack(_Stack,limit)) -->
 2013    [ 'set_prolog_stack/2: limit(Size) sets the combined limit.'-[], nl,
 2014      'See https://www.swi-prolog.org/changes/stack-limit.html'
 2015    ].
 2016deprecated(autoload(TargetModule, File, _M:PI, expansion)) -->
 2017    !,
 2018    [ 'Auto-loading ' ], predicate_reference(PI, [link(false)]),
 2019    [ ' from ' ],
 2020    load_file(File), [ ' into ' ],
 2021    target_module(TargetModule),
 2022    [ ' is deprecated due to term- or goal-expansion' ].
 2023deprecated(source_search_working_directory(File, _FullFile)) -->
 2024    [ 'Found file ', ansi(code, '~w', [File]),
 2025      ' relative to the current working directory.', nl,
 2026      'This behaviour is deprecated but still supported by', nl,
 2027      'the Prolog flag ',
 2028      ansi(code, source_search_working_directory, []), '.', nl
 2029    ].
 2030deprecated(moved_library(Old, New)) -->
 2031    [ 'Library was moved: ~q --> ~q'-[Old, New] ].
 2032
 2033load_file(File) -->
 2034    { file_base_name(File, Base),
 2035      absolute_file_name(library(Base), File, [access(read), file_errors(fail)]),
 2036      file_name_extension(Clean, pl, Base)
 2037    },
 2038    !,
 2039    [ ansi(code, '~p', [library(Clean)]) ].
 2040load_file(File) -->
 2041    [ url(File) ].
 2042
 2043target_module(Module) -->
 2044    { module_property(Module, file(File)) },
 2045    !,
 2046    load_file(File).
 2047target_module(Module) -->
 2048    [ 'module ', ansi(code, '~p', [Module]) ].
 2049
 2050
 2051
 2052		 /*******************************
 2053		 *           TRIPWIRES		*
 2054		 *******************************/
 2055
 2056tripwire_message(max_integer_size, Bytes) -->
 2057    !,
 2058    [ 'Trapped tripwire max_integer_size: big integers and \c
 2059       rationals are limited to ~D bytes'-[Bytes] ].
 2060tripwire_message(Wire, Context) -->
 2061    [ 'Trapped tripwire ~w for '-[Wire] ],
 2062    tripwire_context(Wire, Context).
 2063
 2064tripwire_context(_, ATrie) -->
 2065    { '$is_answer_trie'(ATrie, _),
 2066      !,
 2067      '$tabling':atrie_goal(ATrie, QGoal),
 2068      clean_goal(QGoal, Goal)          % a goal, not a predicate indicator
 2069    },
 2070    [ '~p'-[Goal] ].
 2071tripwire_context(_, Ctx) -->
 2072    [ '~p'-[Ctx] ].
 2073
 2074
 2075		 /*******************************
 2076		 *     INTERNATIONALIZATION	*
 2077		 *******************************/
 2078
 2079:- create_prolog_flag(message_language, default, []).
 message_lang(-Lang) is multi
True when Lang is a language id preferred for messages. Starts with the most specific language (e.g., nl_BE) and ends with en.
 2086message_lang(Lang) :-
 2087    current_message_lang(Lang0),
 2088    (   Lang0 == en
 2089    ->  Lang = en
 2090    ;   sub_atom(Lang0, 0, _, _, en_)
 2091    ->  longest_id(Lang0, Lang)
 2092    ;   (   longest_id(Lang0, Lang)
 2093        ;   Lang = en
 2094        )
 2095    ).
 2096
 2097longest_id(Lang, Id) :-
 2098    split_string(Lang, "_-", "", [H|Components]),
 2099    longest_prefix(Components, Taken),
 2100    atomic_list_concat([H|Taken], '_', Id).
 2101
 2102longest_prefix([H|T0], [H|T]) :-
 2103    longest_prefix(T0, T).
 2104longest_prefix(_, []).
 current_message_lang(-Lang) is det
Get the current language for messages.
 2110current_message_lang(Lang) :-
 2111    (   current_prolog_flag(message_language, Lang0),
 2112        Lang0 \== default
 2113    ->  Lang = Lang0
 2114    ;   os_user_lang(Lang0)
 2115    ->  clean_encoding(Lang0, Lang1),
 2116        set_prolog_flag(message_language, Lang1),
 2117        Lang = Lang1
 2118    ;   Lang = en
 2119    ).
 2120
 2121os_user_lang(Lang) :-
 2122    current_prolog_flag(windows, true),
 2123    win_get_user_preferred_ui_languages(name, [Lang|_]).
 2124os_user_lang(Lang) :-
 2125    catch(setlocale(messages, _, ''), _, fail),
 2126    setlocale(messages, Lang, Lang).
 2127os_user_lang(Lang) :-
 2128    getenv('LANG', Lang).
 2129
 2130
 2131clean_encoding(Lang0, Lang) :-
 2132    (   sub_atom(Lang0, A, _, _, '.')
 2133    ->  sub_atom(Lang0, 0, A, _, Lang)
 2134    ;   Lang = Lang0
 2135    ).
 2136
 2137		 /*******************************
 2138		 *          PRIMITIVES		*
 2139		 *******************************/
 2140
 2141code(Term) -->
 2142    code('~p', Term).
 2143
 2144code(Format, Term) -->
 2145    [ ansi(code, Format, [Term]) ].
 2146
 2147list([]) --> [].
 2148list([H|T]) --> [H], list(T).
 2149
 2150
 2151		 /*******************************
 2152		 *     PREDICATE REFERENCES	*
 2153		 *******************************/
 predicate_indicator(+Spec, -QPI) is semidet
QPI is the fully qualified predicate indicator Module:Name/Arity or, for a non-terminal, Module:Name//Arity for Spec. Spec is one of

The module is kept here. Whether or not it is printed is left to predicate_reference//2, which uses user_predicate_indicator/2.

See also
- pi_head/2 of library(prolog_code) for the general version. This one is in the boot files and thus cannot use it.
 2170:- public
 2171    predicate_indicator/2. 2172
 2173predicate_indicator(Spec, QPI) :-
 2174    strip_module(user:Spec, Module, Spec1),
 2175    (   is_predicate_indicator(Spec1)
 2176    ->  dcg_indicator(Module, Spec1, QPI)
 2177    ;   callable(Spec1),
 2178        '$pi_head'(Module:PI, Module:Spec1),
 2179        dcg_indicator(Module, PI, QPI)
 2180    ).
 dcg_indicator(+Module, +PI, -QPI) is det
Qualify PI with Module and use the // notation if the predicate is a non-terminal.
 2187dcg_indicator(Module, Name//DCGArity, Module:Name//DCGArity) :-
 2188    !.
 2189dcg_indicator(Module, Name/Arity, QPI) :-
 2190    (   Arity >= 2,
 2191        current_predicate(Module:Name/Arity),
 2192        functor(Head, Name, Arity),
 2193        predicate_property(Module:Head, non_terminal)
 2194    ->  DCGArity is Arity-2,
 2195        QPI = Module:Name//DCGArity
 2196    ;   QPI = Module:Name/Arity
 2197    ).
 predicate_head(+Spec, -QHead) is semidet
QHead is the module qualified head for Spec, accepting the same input as predicate_indicator/2. Unqualified specs are qualified using user.
 2205predicate_head(Spec, QHead) :-
 2206    strip_module(user:Spec, Module, Spec1),
 2207    (   is_predicate_indicator(Spec1)
 2208    ->  '$pi_head'(Module:Spec1, QHead)
 2209    ;   callable(Spec1),
 2210        QHead = Module:Spec1
 2211    ).
 2212
 2213is_predicate_indicator(Name/Arity) :-
 2214    atomic(Name), integer(Arity).
 2215is_predicate_indicator(Name//Arity) :-
 2216    atomic(Name), integer(Arity).
 predicate_reference(+Spec)// is det
 predicate_reference(+Spec, +Options)// is det
Emit a reference to a predicate. Spec is a (possibly qualified) head or predicate indicator. The reference is printed using the style class code and, if the location of the predicate is known and the output is a terminal that supports it, it is a hyperlink to the definition. Options:
module(+Which)
One of auto (default), hide or show. Using auto, the module qualification is removed if hidden_module/1 holds for it.
link(+Bool)
If false, do not try to create a hyperlink. Default true.
style(+Class)
Style class for the reference. Default code.
tag(+Bool)
If true, add a tag that indicates the kind of predicate. See predicate_kind/2. Default false. Only sensible if the reference is the only thing on the line.

If Spec cannot be interpreted as a predicate it is printed using the code class and ~p, i.e., we never fail on a malformed message.

 2242:- public
 2243    predicate_reference//1,
 2244    predicate_reference//2. 2245
 2246predicate_reference(Spec) -->
 2247    predicate_reference(Spec, []).
 2248
 2249predicate_reference(Spec, Options) -->
 2250    { predicate_indicator(Spec, QPI) },
 2251    !,
 2252    { pref_option(style(Style), Options, code),
 2253      pref_option(module(Mode), Options, auto),
 2254      reference_pi(Mode, QPI, PI)
 2255    },
 2256    predicate_link(QPI, ansi(Style, '~q', [PI]), Options),
 2257    predicate_reference_tag(QPI, Options).
 2258predicate_reference(Spec, _Options) -->
 2259    [ ansi(code, '~p', [Spec]) ].
 2260
 2261reference_pi(auto, QPI, PI) :-
 2262    !,
 2263    user_predicate_indicator(QPI, PI).
 2264reference_pi(hide, _:PI, PI) :- !.
 2265reference_pi(_, QPI, QPI).
 2266
 2267predicate_link(QPI, Label, Options) -->
 2268    { pref_option(link(true), Options, true),
 2269      predicate_location(QPI, Location)
 2270    },
 2271    !,
 2272    [ url(Location, Label) ].
 2273predicate_link(_, Label, _) -->
 2274    [ Label ].
 pref_option(?Option, +Options, +Default) is semidet
Get an option from the option list of predicate_reference//2. Fails if Options holds a value for Option that does not unify. Note that this deliberately does not use library(option): boot/messages.pl must be able to print a message before the libraries are available.
 2283pref_option(Option, Options, Default) :-
 2284    functor(Option, Name, 1),
 2285    functor(General, Name, 1),
 2286    (   memberchk(General, Options)
 2287    ->  General = Option
 2288    ;   arg(1, Option, Default)
 2289    ).
 predicate_location(+Spec, -Location) is semidet
Location is File:Line for the definition of the predicate Spec. Also deals with predicates defined in C. Note that predicates that are not loaded but can be autoloaded are located from the autoload index, i.e., printing a message never loads a library.
 2298:- public
 2299    predicate_location/2. 2300
 2301predicate_location(Spec, Location) :-
 2302    predicate_head(Spec, Head),
 2303    current_predicate(_, Head),                 % do not (auto)load
 2304    '$predicate_source_location'(Head, Location).
 predicate_definition(+Spec, +Message)// is det
Emit "Message at File:Line" on a new line if the location of Spec is known and nothing at all if it is not.
 2311:- public
 2312    predicate_definition//2. 2313
 2314predicate_definition(Spec, Message) -->
 2315    { predicate_location(Spec, Location) },
 2316    !,
 2317    [ nl, '~w at '-[Message], url(Location) ].
 2318predicate_definition(_, _) -->
 2319    [].
 predicate_kind(+Spec, -Kind) is semidet
Classify a predicate for the benefit of the user who has to pick one from a list of candidates. Fails if Spec is not a predicate. Kind is one of
 2335:- public
 2336    predicate_kind/2. 2337
 2338predicate_kind(Spec, Kind) :-
 2339    predicate_head(Spec, Head),
 2340    (   current_predicate(_, Head)              % do not autoload
 2341    ->  defined_predicate_kind(Head, Kind)
 2342    ;   predicate_property(Head, autoload(File))
 2343    ->  library_name(File, Name),
 2344        Kind = library(Name)
 2345    ;   Kind = undefined
 2346    ).
 2347
 2348defined_predicate_kind(Head, Kind) :-
 2349    (   predicate_property(Head, iso)
 2350    ->  Kind = iso
 2351    ;   predicate_property(Head, built_in)
 2352    ->  (   predicate_property(Head, foreign)
 2353        ->  Kind = foreign
 2354        ;   Kind = built_in
 2355        )
 2356    ;   predicate_property(Head, imported_from(Module))
 2357    ->  module_kind(Module, Kind)
 2358    ;   predicate_property(Head, file(File)),
 2359        library_file(File)
 2360    ->  library_name(File, Name),
 2361        Kind = library(Name)
 2362    ;   Kind = user
 2363    ).
 2364
 2365module_kind(Module, Kind) :-
 2366    (   hidden_module(Module)
 2367    ->  Kind = user
 2368    ;   module_property(Module, file(File)),
 2369        library_file(File)
 2370    ->  library_name(File, Name),
 2371        Kind = library(Name)
 2372    ;   Kind = module(Module)
 2373    ).
 library_file(+File) is semidet
 library_name(+File, -Name) is det
True if File is in one of the library directories and, if so, Name is how the file is referred to as library(Name).
 2381library_file(File) :-
 2382    absolute_file_name(library(.), LibDir,
 2383                       [ file_type(directory),
 2384                         solutions(all),
 2385                         file_errors(fail)
 2386                       ]),
 2387    sub_atom(File, 0, _, _, LibDir),
 2388    !.
 2389
 2390library_name(File, Name) :-
 2391    (   file_name_extension(Base, Ext, File),
 2392        Ext \== ''
 2393    ->  true
 2394    ;   Base = File
 2395    ),
 2396    file_base_name(Base, Name).
 predicate_reference_tag(+QPI, +Options)// is det
 predicate_kind_tag(+Kind)// is det
Emit the kind of the predicate as a short tag.
 2403predicate_reference_tag(QPI, Options) -->
 2404    { pref_option(tag(true), Options, false),
 2405      predicate_kind(QPI, Kind)
 2406    },
 2407    !,
 2408    predicate_kind_tag(Kind).
 2409predicate_reference_tag(_, _) -->
 2410    [].
 2411
 2412predicate_kind_tag(Kind) -->
 2413    { predicate_kind_label(Kind, Label) },
 2414    [ ansi(predicate(Kind), ' [~w]', [Label]) ].
 2415
 2416predicate_kind_label(iso,          'ISO').
 2417predicate_kind_label(built_in,     'built-in').
 2418predicate_kind_label(foreign,      'built-in').
 2419predicate_kind_label(user,         'user').
 2420predicate_kind_label(undefined,    'undefined').
 2421predicate_kind_label(library(Name), Label) :-
 2422    format(atom(Label), 'library(~w)', [Name]).
 2423predicate_kind_label(module(Name), Name).
 2424
 2425
 2426		 /*******************************
 2427		 *        DEFAULT THEME		*
 2428		 *******************************/
 2429
 2430:- multifile
 2431    prolog:theme/1,
 2432    prolog:theme_base/2. 2433:- public
 2434    current_theme/1,
 2435    theme_ancestor/2,
 2436    default_theme/2.
 current_theme(-Theme) is det
Theme is the theme that defines the console colours (see prolog:console_color/3). This is the value of the Prolog flag theme, unless this is default or auto. In that case it is the theme of a loaded theme file, e.g., a file loaded from the init file or by library(theme/auto). If no theme file is loaded, Theme is default.
 2447current_theme(Theme) :-
 2448    current_prolog_flag(theme, Selected),
 2449    Selected \== default,
 2450    Selected \== auto,
 2451    !,
 2452    Theme = Selected.
 2453current_theme(Theme) :-
 2454    prolog:theme(Loaded),
 2455    !,
 2456    Theme = Loaded.
 2457current_theme(default).
 theme_ancestor(+Theme, -Ancestor) is nondet
Ancestor is Theme or a theme Theme is based on, nearest first. A theme is based on another theme using the multifile hook prolog:theme_base/2. A theme uses the settings of its base theme that it does not define itself.
 2466theme_ancestor(Theme, Ancestor) :-
 2467    theme_ancestor(Theme, [Theme], Ancestor).
 2468
 2469theme_ancestor(Theme, _, Theme).
 2470theme_ancestor(Theme, Seen, Ancestor) :-
 2471    prolog:theme_base(Theme, Base),
 2472    !,
 2473    \+ memberchk(Base, Seen),
 2474    theme_ancestor(Base, [Base|Seen], Ancestor).
 2475
 2476
 2477default_theme(var,                    [fg(red)]).
 2478default_theme(code,                   [fg(blue)]).
 2479default_theme(comment,                [fg(green)]).
 2480default_theme(warning,                [fg(red)]).
 2481default_theme(error,                  [bold, fg(red)]).
 2482default_theme(truth(false),           [bold, fg(red)]).
 2483default_theme(truth(true),            [bold]).
 2484default_theme(truth(undefined),       [bold, fg(cyan)]).
 2485default_theme(wfs(residual_program),  [fg(cyan)]).
 2486default_theme(frame(level),           [bold]).
 2487default_theme(goal(_,_),              []).
 2488default_theme(port(call),             [bold, fg(green)]).
 2489default_theme(port(exit),             [bold, fg(green)]).
 2490default_theme(port(fail),             [bold, fg(red)]).
 2491default_theme(port(redo),             [bold, fg(yellow)]).
 2492default_theme(port(unify),            [bold, fg(blue)]).
 2493default_theme(port(exception),        [bold, fg(magenta)]).
 2494default_theme(prompt,                 [bold]).
 2495default_theme(input,                  []).
 2496default_theme(answer(_),              []).
 2497default_theme(binding(name),          [bold]).
 2498default_theme(predicate(iso),         [italic, fg(cyan)]).
 2499default_theme(predicate(built_in),    [italic, fg(cyan)]).
 2500default_theme(predicate(foreign),     [italic, fg(cyan)]).
 2501default_theme(predicate(library(_)),  [italic, fg(green)]).
 2502default_theme(predicate(module(_)),   [italic, fg(green)]).
 2503default_theme(predicate(user),        [italic, fg(default)]).
 2504default_theme(predicate(undefined),   [italic, fg(red)]).
 2505default_theme(message(informational), [fg(green)]).
 2506default_theme(message(information),   [fg(green)]).
 2507default_theme(message(debug(_)),      [fg(blue)]).
 2508default_theme(message(Level),         Attrs) :-
 2509    nonvar(Level),
 2510    default_theme(Level, Attrs).
 2511
 2512
 2513                 /*******************************
 2514                 *      PRINTING MESSAGES       *
 2515                 *******************************/
 2516
 2517:- multifile
 2518    user:message_hook/3,
 2519    prolog:message_prefix_hook/2. 2520:- dynamic
 2521    user:message_hook/3,
 2522    prolog:message_prefix_hook/2. 2523:- thread_local
 2524    user:thread_message_hook/3. 2525:- '$notransact'((user:message_hook/3,
 2526                  prolog:message_prefix_hook/2,
 2527                  user:thread_message_hook/3)).
 print_message(+Kind, +Term)
Print an error message using a term as generated by the exception system.
 2534print_message(Level, _Term) :-
 2535    msg_property(Level, stream(S)),
 2536    stream_property(S, error(true)),
 2537    !.
 2538print_message(Level, Term) :-
 2539    setup_call_cleanup(
 2540        notrace(push_msg(Term, Stack)),
 2541        ignore(print_message_guarded(Level, Term)),
 2542        notrace(pop_msg(Stack))),
 2543    !.
 2544print_message(Level, Term) :-
 2545    (   Level \== silent
 2546    ->  format(user_error, 'Recursive ~w message: ~q~n', [Level, Term]),
 2547        autoload_call(backtrace(20))
 2548    ;   true
 2549    ).
 2550
 2551push_msg(Term, Messages) :-
 2552    nb_current('$inprint_message', Messages),
 2553    !,
 2554    \+ ( '$member'(Msg, Messages),
 2555         Msg =@= Term
 2556       ),
 2557    Stack = [Term|Messages],
 2558    b_setval('$inprint_message', Stack).
 2559push_msg(Term, []) :-
 2560    b_setval('$inprint_message', [Term]).
 2561
 2562pop_msg(Stack) :-
 2563    nb_delete('$inprint_message'),              % delete history
 2564    b_setval('$inprint_message', Stack).
 2565
 2566print_message_guarded(Level, Term) :-
 2567    (   must_print(Level, Term)
 2568    ->  (   prolog:message_action(Term, Level),
 2569            fail                                % forall/2 is cleaner, but not yet
 2570        ;   true                                % defined
 2571        ),
 2572        (   translate_message(Term, Lines, [])
 2573        ->  (   nonvar(Term),
 2574                (   notrace(user:thread_message_hook(Term, Level, Lines))
 2575                ->  true
 2576                ;   notrace(user:message_hook(Term, Level, Lines))
 2577                )
 2578            ->  true
 2579            ;   '$inc_message_count'(Level),
 2580                print_system_message(Term, Level, Lines),
 2581                maybe_halt_on_error(Level)
 2582            )
 2583        )
 2584    ;   true
 2585    ).
 2586
 2587maybe_halt_on_error(error) :-
 2588    current_prolog_flag(on_error, halt),
 2589    !,
 2590    halt(1).
 2591maybe_halt_on_error(warning) :-
 2592    current_prolog_flag(on_warning, halt),
 2593    !,
 2594    halt(1).
 2595maybe_halt_on_error(_).
 print_system_message(+Term, +Kind, +Lines)
Print the message if the user did not intecept the message. The first is used for errors and warnings that can be related to source-location. Note that syntax errors have their own source-location and should therefore not be handled this way.
 2605print_system_message(_, silent, _) :- !.
 2606print_system_message(_, informational, _) :-
 2607    current_prolog_flag(verbose, silent),
 2608    !.
 2609print_system_message(_, banner, _) :-
 2610    current_prolog_flag(verbose, silent),
 2611    !.
 2612print_system_message(_, _, []) :- !.
 2613print_system_message(Term, Kind, Lines) :-
 2614    catch(flush_output(user_output), _, true),      % may not exist
 2615    source_location(File, Line),
 2616    Term \= error(syntax_error(_), _),
 2617    msg_property(Kind, location_prefix(File:Line, LocPrefix, LinePrefix)),
 2618    !,
 2619    to_list(LocPrefix, LocPrefixL),
 2620    insert_prefix(Lines, LinePrefix, Ctx, PrefixLines),
 2621    '$append'([ [begin(Kind, Ctx)],
 2622                LocPrefixL,
 2623                [nl],
 2624                PrefixLines,
 2625                [end(Ctx)]
 2626              ],
 2627              AllLines),
 2628    msg_property(Kind, stream(Stream)),
 2629    ignore(stream_property(Stream, position(Pos))),
 2630    print_message_lines(Stream, AllLines),
 2631    (   \+ stream_property(Stream, position(Pos)),
 2632        msg_property(Kind, wait(Wait)),
 2633        Wait > 0
 2634    ->  sleep(Wait)
 2635    ;   true
 2636    ).
 2637print_system_message(_, Kind, Lines) :-
 2638    msg_property(Kind, stream(Stream)),
 2639    print_message_lines(Stream, kind(Kind), Lines).
 2640
 2641to_list(ListIn, List) :-
 2642    is_list(ListIn),
 2643    !,
 2644    List = ListIn.
 2645to_list(NonList, [NonList]).
 2646
 2647:- multifile
 2648    user:message_property/2. 2649
 2650msg_property(Kind, Property) :-
 2651    notrace(user:message_property(Kind, Property)),
 2652    !.
 2653msg_property(Kind, prefix(Prefix)) :-
 2654    msg_prefix(Kind, Prefix),
 2655    !.
 2656msg_property(_, prefix('~N')) :- !.
 2657msg_property(query, color_class(Class)) :-
 2658    !,
 2659    '$answer_class'(Class).
 2660msg_property(query, stream(user_output)) :- !.
 2661msg_property(_, stream(user_error)) :- !.
 2662msg_property(error, tag('ERROR')).
 2663msg_property(warning, tag('Warning')).
 2664msg_property(Level,
 2665             location_prefix(File:Line,
 2666                             ['~N~w: '-[Tag], url(File:Line), ':'],
 2667                             '~N~w:    '-[Tag])) :-
 2668    include_msg_location(Level),
 2669    msg_property(Level, tag(Tag)).
 2670msg_property(error,   wait(0.1)) :- !.
 2671
 2672include_msg_location(warning).
 2673include_msg_location(error).
 2674
 2675msg_prefix(debug(_), Prefix) :-
 2676    msg_context('~N% ', Prefix).
 2677msg_prefix(Level, Prefix) :-
 2678    msg_property(Level, tag(Tag)),
 2679    atomics_to_string(['~N', Tag, ': '], Prefix0),
 2680    msg_context(Prefix0, Prefix).
 2681msg_prefix(informational, '~N% ').
 2682msg_prefix(information,   '~N% ').
 msg_context(+Prefix0, -Prefix) is det
Add contextual information to a message. This uses the Prolog flag message_context. Recognised context terms are:

In addition, the hook message_prefix_hook/2 is called that allows for additional context information.

 2696msg_context(Prefix0, Prefix) :-
 2697    current_prolog_flag(message_context, Context),
 2698    is_list(Context),
 2699    !,
 2700    add_message_context(Context, Prefix0, Prefix).
 2701msg_context(Prefix, Prefix).
 2702
 2703add_message_context([], Prefix, Prefix).
 2704add_message_context([H|T], Prefix0, Prefix) :-
 2705    (   add_message_context1(H, Prefix0, Prefix1)
 2706    ->  true
 2707    ;   Prefix1 = Prefix0
 2708    ),
 2709    add_message_context(T, Prefix1, Prefix).
 2710
 2711add_message_context1(Context, Prefix0, Prefix) :-
 2712    prolog:message_prefix_hook(Context, Extra),
 2713    atomics_to_string([Prefix0, Extra, ' '], Prefix).
 2714add_message_context1(time, Prefix0, Prefix) :-
 2715    get_time(Now),
 2716    format_time(string(S), '%T.%3f ', Now),
 2717    string_concat(Prefix0, S, Prefix).
 2718add_message_context1(time(Format), Prefix0, Prefix) :-
 2719    get_time(Now),
 2720    format_time(string(S), Format, Now),
 2721    atomics_to_string([Prefix0, S, ' '], Prefix).
 2722add_message_context1(thread, Prefix0, Prefix) :-
 2723    \+ current_prolog_flag(toplevel_thread, true),
 2724    thread_self(Id0),
 2725    !,
 2726    (   atom(Id0)
 2727    ->  Id = Id0
 2728    ;   thread_property(Id0, id(Id))
 2729    ),
 2730    format(string(Prefix), '~w[Thread ~w] ', [Prefix0, Id]).
 print_message_lines(+Stream, +PrefixOrKind, +Lines)
Quintus compatibility predicate to print message lines using a prefix.

If PrefixOrKind is kind(Kind), the message as a whole may be decorated. To this end the lines are wrapped in begin(Class, Ctx) and end(Ctx), where Class is derived from Kind using msg_color_class/2. Ctx is a variable that is bound by whoever implements prolog:message_line_element/2 for begin/2 (normally library(ansi_term)) and remains unbound if the decoration is not available, e.g., because Stream is not a terminal.

The elements that need Ctx are rewritten by prefix_nl/4 to carry it. See there for the details.

 2748print_message_lines(Stream, kind(Kind), Lines) :-
 2749    !,
 2750    msg_property(Kind, prefix(Prefix)),
 2751    msg_color_class(Kind, Class),
 2752    insert_prefix(Lines, Prefix, Ctx, PrefixLines),
 2753    '$append'([ begin(Class, Ctx)
 2754              | PrefixLines
 2755              ],
 2756              [ end(Ctx)
 2757              ],
 2758              AllLines),
 2759    print_message_lines(Stream, AllLines).
 2760print_message_lines(Stream, Prefix, Lines) :-
 2761    insert_prefix(Lines, Prefix, _, PrefixLines),
 2762    print_message_lines(Stream, PrefixLines).
 msg_color_class(+Kind, -Class) is det
Colour class used to decorate an entire message of the given Kind. Defaults to Kind itself, which is mapped to message(Kind) (see level_attrs/2).
 2770msg_color_class(Kind, Class) :-
 2771    msg_property(Kind, color_class(Class0)),
 2772    !,
 2773    Class = Class0.
 2774msg_color_class(Kind, Kind).
 insert_prefix(+Lines, +Prefix, ?Ctx, -PrefixedLines) is det
Add Prefix to the start of each line of Lines. If the first element is at_same_line the message continues the line and no initial prefix is added. Ctx is the message context; see prefix_nl/4 and print_message_lines/3.
 2783insert_prefix([at_same_line|Lines0], Prefix, Ctx, Lines) :-
 2784    !,
 2785    prefix_nl(Lines0, Prefix, Ctx, Lines).
 2786insert_prefix(Lines0, Prefix, Ctx, [prefix(Prefix)|Lines]) :-
 2787    prefix_nl(Lines0, Prefix, Ctx, Lines).
 prefix_nl(+Lines, +Prefix, ?Ctx, -Lines) is det
Insert Prefix after each nl and make the message context Ctx available to the elements that need it:

The last line of a message is ended implicitly: if Lines does not end in nl or flush an nl is added. This one does not paint: what follows the message is not part of it. A message that wants its last line painted ends it using eol.

 2809prefix_nl([], _, _, [nl]).
 2810prefix_nl([nl], _, Ctx, [nl(Ctx)]) :- !.
 2811prefix_nl([flush], _, Ctx, [flush(Ctx)]) :- !.
 2812prefix_nl([nl|T0], Prefix, Ctx, [nl(Ctx), prefix(Prefix)|T]) :-
 2813    !,
 2814    prefix_nl(T0, Prefix, Ctx, T).
 2815prefix_nl([flush|T0], Prefix, Ctx, [flush(Ctx)|T]) :-
 2816    !,
 2817    prefix_nl(T0, Prefix, Ctx, T).
 2818prefix_nl([eol|T0], Prefix, Ctx, [eol(Ctx)|T]) :-
 2819    !,
 2820    prefix_nl(T0, Prefix, Ctx, T).
 2821prefix_nl([ansi(Attrs,Fmt,Args)|T0], Prefix, Ctx,
 2822          [ansi(Attrs,Fmt,Args,Ctx)|T]) :-
 2823    !,
 2824    prefix_nl(T0, Prefix, Ctx, T).
 2825prefix_nl([url(URL,ansi(Attrs,Fmt,Args))|T0], Prefix, Ctx,
 2826          [url(URL,ansi(Attrs,Fmt,Args,Ctx))|T]) :-
 2827    !,
 2828    prefix_nl(T0, Prefix, Ctx, T).
 2829prefix_nl([H|T0], Prefix, Ctx, [H|T]) :-
 2830    prefix_nl(T0, Prefix, Ctx, T).
 print_message_lines(+Stream, +Lines)
 2834print_message_lines(Stream, Lines) :-
 2835    with_output_to(
 2836        Stream,
 2837        notrace(print_message_lines_guarded(current_output, Lines))).
 2838
 2839print_message_lines_guarded(_, []) :- !.
 2840print_message_lines_guarded(S, [H|T]) :-
 2841    line_element(S, H),
 2842    print_message_lines_guarded(S, T).
 2843
 2844line_element(S, E) :-
 2845    prolog:message_line_element(S, E),
 2846    !.
 2847line_element(S, full_stop) :-
 2848    !,
 2849    '$put_token'(S, '.').           % insert space if needed.
 2850line_element(S, nl) :-
 2851    !,
 2852    nl(S).
 2853line_element(S, nl(_Ctx)) :-
 2854    !,
 2855    nl(S).
 2856line_element(S, flush(_Ctx)) :-
 2857    !,
 2858    flush_output(S).
 2859line_element(_, eol(_Ctx)) :- !.
 2860line_element(S, prefix(Fmt-Args)) :-
 2861    !,
 2862    safe_format(S, Fmt, Args).
 2863line_element(S, prefix(Fmt)) :-
 2864    !,
 2865    safe_format(S, Fmt, []).
 2866line_element(S, flush) :-
 2867    !,
 2868    flush_output(S).
 2869line_element(S, Fmt-Args) :-
 2870    !,
 2871    safe_format(S, Fmt, Args).
 2872line_element(S, ansi(_, Fmt, Args)) :-
 2873    !,
 2874    safe_format(S, Fmt, Args).
 2875line_element(S, ansi(_, Fmt, Args, _Ctx)) :-
 2876    !,
 2877    safe_format(S, Fmt, Args).
 2878line_element(S, url(URL)) :-
 2879    !,
 2880    print_link(S, URL).
 2881line_element(S, url(_URL, Label)) :-
 2882    !,
 2883    link_label(Label, Fmt, Args),
 2884    safe_format(S, Fmt, Args).
 2885line_element(_, begin(_Level, _Ctx)) :- !.
 2886line_element(_, end(_Ctx)) :- !.
 2887line_element(S, Fmt) :-
 2888    safe_format(S, Fmt, []).
 2889
 2890print_link(S, File:Line:Column) :-
 2891    !,
 2892    safe_format(S, '~w:~d:~d', [File, Line, Column]).
 2893print_link(S, File:Line) :-
 2894    !,
 2895    safe_format(S, '~w:~d', [File, Line]).
 2896print_link(S, File) :-
 2897    safe_format(S, '~w', [File]).
 link_label(+Label, -Format, -Args) is det
Decompose the label of an url/2 message element. See url/2 in print_message_lines/3. Note that a plain label is text rather than a format: it typically holds a file name, which may contain ~.
 2905:- public
 2906    link_label/3. 2907
 2908link_label(Fmt-Args, Fmt, Args) :-
 2909    atom(Fmt),
 2910    is_list(Args),
 2911    !.
 2912link_label(ansi(_Class, Fmt, Args), Fmt, Args) :- !.
 2913link_label(ansi(_Class, Fmt, Args, _Ctx), Fmt, Args) :- !.
 2914link_label(Text, '~w', [Text]).
 safe_format(+Stream, +Format, +Args) is det
 2918safe_format(S, Fmt, Args) :-
 2919    E = error(_,_),
 2920    catch(format(S,Fmt,Args), E,
 2921          format_failed(S,Fmt,Args,E)).
 2922
 2923format_failed(S, _Fmt, _Args, E) :-
 2924    stream_property(S, error(true)),
 2925    !,
 2926    throw(E).
 2927format_failed(S, Fmt, Args, error(E,_)) :-
 2928    format(S, '~N    [[ EXCEPTION while printing message ~q~n\c
 2929                        ~7|with arguments ~W:~n\c
 2930                        ~7|raised: ~W~n~4|]]~n',
 2931           [ Fmt,
 2932             Args, [quoted(true), max_depth(10)],
 2933             E, [quoted(true), max_depth(10)]
 2934           ]).
 message_to_string(+Term, -String)
Translate an error term into a string
 2940message_to_string(Term, Str) :-
 2941    translate_message(Term, Actions, []),
 2942    !,
 2943    actions_to_format(Actions, Fmt, Args),
 2944    format(string(Str), Fmt, Args).
 2945
 2946actions_to_format([], '', []) :- !.
 2947actions_to_format([nl(_)|T], Fmt, Args) :-      % see prefix_nl/4
 2948    !,
 2949    actions_to_format([nl|T], Fmt, Args).
 2950actions_to_format([nl], '', []) :- !.
 2951actions_to_format([Term, nl], Fmt, Args) :-
 2952    !,
 2953    actions_to_format([Term], Fmt, Args).
 2954actions_to_format([nl|T], Fmt, Args) :-
 2955    !,
 2956    actions_to_format(T, Fmt0, Args),
 2957    atom_concat('~n', Fmt0, Fmt).
 2958actions_to_format([ansi(_Attrs, Fmt0, Args0)|Tail], Fmt, Args) :-
 2959    !,
 2960    actions_to_format(Tail, Fmt1, Args1),
 2961    atom_concat(Fmt0, Fmt1, Fmt),
 2962    append_args(Args0, Args1, Args).
 2963actions_to_format([url(Pos)|Tail], Fmt, Args) :-
 2964    !,
 2965    actions_to_format(Tail, Fmt1, Args1),
 2966    url_actions_to_format(url(Pos), Fmt1, Args1, Fmt, Args).
 2967actions_to_format([url(URL, Label)|Tail], Fmt, Args) :-
 2968    !,
 2969    actions_to_format(Tail, Fmt1, Args1),
 2970    url_actions_to_format(url(URL, Label), Fmt1, Args1, Fmt, Args).
 2971actions_to_format([Fmt0-Args0|Tail], Fmt, Args) :-
 2972    !,
 2973    actions_to_format(Tail, Fmt1, Args1),
 2974    atom_concat(Fmt0, Fmt1, Fmt),
 2975    append_args(Args0, Args1, Args).
 2976actions_to_format([Skip|T], Fmt, Args) :-
 2977    action_skip(Skip),
 2978    !,
 2979    actions_to_format(T, Fmt, Args).
 2980actions_to_format([Term|Tail], Fmt, Args) :-
 2981    atomic(Term),
 2982    !,
 2983    actions_to_format(Tail, Fmt1, Args),
 2984    atom_concat(Term, Fmt1, Fmt).
 2985actions_to_format([Term|Tail], Fmt, Args) :-
 2986    actions_to_format(Tail, Fmt1, Args1),
 2987    atom_concat('~w', Fmt1, Fmt),
 2988    append_args([Term], Args1, Args).
 2989
 2990action_skip(at_same_line).
 2991action_skip(flush).
 2992action_skip(flush(_Ctx)).
 2993action_skip(eol).
 2994action_skip(eol(_Ctx)).
 2995action_skip(begin(_Level, _Ctx)).
 2996action_skip(end(_Ctx)).
 2997
 2998url_actions_to_format(url(File:Line:Column), Fmt1, Args1, Fmt, Args) :-
 2999    !,
 3000    atom_concat('~w:~d:~d', Fmt1, Fmt),
 3001    append_args([File,Line,Column], Args1, Args).
 3002url_actions_to_format(url(File:Line), Fmt1, Args1, Fmt, Args) :-
 3003    !,
 3004    atom_concat('~w:~d', Fmt1, Fmt),
 3005    append_args([File,Line], Args1, Args).
 3006url_actions_to_format(url(File), Fmt1, Args1, Fmt, Args) :-
 3007    !,
 3008    atom_concat('~w', Fmt1, Fmt),
 3009    append_args([File], Args1, Args).
 3010url_actions_to_format(url(_URL, Label), Fmt1, Args1, Fmt, Args) :-
 3011    !,
 3012    link_label(Label, Fmt0, Args0),
 3013    atom_concat(Fmt0, Fmt1, Fmt),
 3014    append_args(Args0, Args1, Args).
 3015
 3016
 3017append_args(M:Args0, Args1, M:Args) :-
 3018    !,
 3019    strip_module(Args1, _, A1),
 3020    to_list(Args0, Args01),
 3021    '$append'(Args01, A1, Args).
 3022append_args(Args0, Args1, Args) :-
 3023    strip_module(Args1, _, A1),
 3024    to_list(Args0, Args01),
 3025    '$append'(Args01, A1, Args).
 3026
 3027                 /*******************************
 3028                 *    MESSAGES TO PRINT ONCE    *
 3029                 *******************************/
 3030
 3031:- dynamic
 3032    printed/2.
 print_once(Message, Level)
True for messages that must be printed only once.
 3038print_once(compatibility(_), _).
 3039print_once(null_byte_in_path(_), _).
 3040print_once(deprecated(_), _).
 must_print(+Level, +Message)
True if the message must be printed.
 3046must_print(Level, Message) :-
 3047    nonvar(Message),
 3048    print_once(Message, Level),
 3049    !,
 3050    \+ printed(Message, Level),
 3051    assert(printed(Message, Level)).
 3052must_print(_, _)