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

 1551extra_line -->
 1552    { current_prolog_flag(toplevel_extra_white_line, true) },
 1553    !,
 1554    [eol, '~N'-[]].
 1555extra_line -->
 1556    [eol].
 1557
 1558prolog_message(if_tty(Message)) -->
 1559    (   {current_prolog_flag(tty_control, true)}
 1560    ->  [ at_same_line ], list(Message)
 1561    ;   []
 1562    ).
 1563prolog_message(halt(Reason)) -->
 1564    [ '~w: halt'-[Reason] ].
 1565prolog_message(no_action(Char)) -->
 1566    [ 'Unknown action: ~c (h for help)'-[Char], nl ].
 1567
 1568prolog_message(history(help(Show, Help))) -->
 1569    [ 'History Commands:', nl,
 1570      '    !!.              Repeat last query', nl,
 1571      '    !nr.             Repeat query numbered <nr>', nl,
 1572      '    !str.            Repeat last query starting with <str>', nl,
 1573      '    !?str.           Repeat last query holding <str>', nl,
 1574      '    ^old^new.        Substitute <old> into <new> of last query', nl,
 1575      '    !nr^old^new.     Substitute in query numbered <nr>', nl,
 1576      '    !str^old^new.    Substitute in query starting with <str>', nl,
 1577      '    !?str^old^new.   Substitute in query holding <str>', nl,
 1578      '    ~w.~21|Show history list'-[Show], nl,
 1579      '    ~w.~21|Show this list'-[Help], nl, nl
 1580    ].
 1581prolog_message(history(no_event)) -->
 1582    [ '! No such event' ].
 1583prolog_message(history(bad_substitution)) -->
 1584    [ '! Bad substitution' ].
 1585prolog_message(history(expanded(Event))) -->
 1586    [ '~w.'-[Event] ].
 1587prolog_message(history(history(Events))) -->
 1588    history_events(Events).
 1589prolog_message(history(no_history)) -->
 1590    [ '! event history not supported in this version' ].
 1591
 1592history_events([]) -->
 1593    [].
 1594history_events([Nr-Event|T]) -->
 1595    [ ansi(comment, '%', []),
 1596      ansi(bold, '~t~w ~6|', [Nr]),
 1597      ansi(code, '~s', [Event]),
 1598      nl
 1599    ],
 1600    history_events(T).
 user_version_messages(+Terms)//
Helper for the welcome message to print information registered using version/1.
 1608user_version_messages([]) --> [].
 1609user_version_messages([H|T]) -->
 1610    user_version_message(H),
 1611    user_version_messages(T).
 user_version_message(+Term)
 1615user_version_message(Term) -->
 1616    translate_message(Term), !, [nl].
 1617user_version_message(Atom) -->
 1618    [ '~w'-[Atom], nl ].
 1619
 1620
 1621                 /*******************************
 1622                 *       DEBUGGER MESSAGES      *
 1623                 *******************************/
 1624
 1625prolog_message(spy(Head)) -->
 1626    [ 'New spy point on ' ],
 1627    predicate_reference(Head).
 1628prolog_message(already_spying(Head)) -->
 1629    [ 'Already spying ' ],
 1630    predicate_reference(Head).
 1631prolog_message(nospy(Head)) -->
 1632    [ 'Removed spy point from ' ],
 1633    predicate_reference(Head).
 1634prolog_message(trace_mode(OnOff)) -->
 1635    [ 'Trace mode switched to ~w'-[OnOff] ].
 1636prolog_message(debug_mode(OnOff)) -->
 1637    [ 'Debug mode switched to ~w'-[OnOff] ].
 1638prolog_message(debugging(OnOff, Threads)) -->
 1639    [ 'Debug mode is ~w'-[OnOff] ],
 1640    debugging_threads(Threads).
 1641prolog_message(spying([])) -->
 1642    !,
 1643    [ 'No spy points' ].
 1644prolog_message(spying(Heads)) -->
 1645    [ 'Spy points (see spy/1) on:', nl ],
 1646    predicate_list(Heads).
 1647prolog_message(trace(Head, [])) -->
 1648    !,
 1649    [ '    ' ], predicate_reference(Head, [tag(true)]),
 1650    [ ' Not tracing'-[], nl].
 1651prolog_message(trace(Head, Ports)) -->
 1652    { '$member'(Port, Ports), compound(Port),
 1653      !,
 1654      numbervars(Head+Ports, 0, _, [singletons(true)])
 1655    },
 1656    [ '    ~p: ~p'-[Head,Ports] ].
 1657prolog_message(trace(Head, Ports)) -->
 1658    [ '    ' ], predicate_reference(Head, [tag(true)]),
 1659    [ ': ~w'-[Ports], nl].
 1660prolog_message(tracing([])) -->
 1661    !,
 1662    [ 'No traced predicates (see trace/1,2)' ].
 1663prolog_message(tracing(Heads)) -->
 1664    [ 'Trace points (see trace/1,2) on:', nl ],
 1665    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.
 1672predicate_list([]) -->
 1673    [].
 1674predicate_list([H|T]) -->
 1675    [ '    ' ], predicate_reference(H, [tag(true)]), [nl],
 1676    predicate_list(T).
 1677
 1678tracing_list([]) -->
 1679    [].
 1680tracing_list([trace(Head, Ports)|T]) -->
 1681    translate_message(trace(Head, Ports)),
 1682    tracing_list(T).
 1683
 1684debugging_threads([]) -->
 1685    [].
 1686debugging_threads(ThreadsByClass) -->
 1687    [ nl, 'Threads in the following classes run in debug mode:', nl],
 1688    list_threads_by_class(ThreadsByClass).
 1689
 1690list_threads_by_class([]) -->
 1691    [].
 1692list_threads_by_class([H|T]) -->
 1693    list_thread_class(H),
 1694    list_threads_by_class(T).
 1695
 1696list_thread_class(Class-Threads) -->
 1697    { length(Threads, Count) },
 1698    [ '    Class ', ansi(code, '~p', [Class]), ': ~D threads'-[Count] ].
 1699
 1700% frame(+Frame, +Choice, +Port, +PC) - Print for the debugger.
 1701prolog_message(frame(Frame, _Choice, backtrace, _PC)) -->
 1702    !,
 1703    { prolog_frame_attribute(Frame, level, Level)
 1704    },
 1705    [ ansi(frame(level), '~t[~D] ~10|', [Level]) ],
 1706    frame_context(Frame),
 1707    frame_goal(Frame, backtrace).
 1708prolog_message(frame(Frame, Choice, choice, PC)) -->
 1709    !,
 1710    prolog_message(frame(Frame, Choice, backtrace, PC)).
 1711prolog_message(frame(_, _Choice, cut_call(_PC), _)) --> !.
 1712prolog_message(frame(Frame, _Choice, Port, _PC)) -->
 1713    frame_flags(Frame),
 1714    port(Port),
 1715    frame_level(Frame),
 1716    frame_context(Frame),
 1717    frame_depth_limit(Port, Frame),
 1718    frame_goal(Frame, Port),
 1719    [ flush ].
 1720
 1721% frame(:Goal, +Trace)		- Print for trace/2
 1722prolog_message(frame(Goal, trace(Port))) -->
 1723    !,
 1724    thread_context,
 1725    [ ' T ' ],
 1726    port(Port),
 1727    predicate_goal(Goal, Port).
 1728prolog_message(frame(Goal, trace(Port, Id))) -->
 1729    !,
 1730    thread_context,
 1731    [ ' T ' ],
 1732    port(Port, Id),
 1733    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.
 1744goal_style(Port0, goal(Port, Parity)) :-
 1745    functor(Port0, Port, _),
 1746    trace_parity(Parity).
 1747
 1748trace_parity(Parity) :-
 1749    (   nb_current('$trace_step', C0)
 1750    ->  true
 1751    ;   C0 = 0
 1752    ),
 1753    C is C0+1,
 1754    nb_setval('$trace_step', C),
 1755    (   C mod 2 =:= 0
 1756    ->  Parity = even
 1757    ;   Parity = odd
 1758    ).
 1759
 1760frame_goal(Frame, Port) -->
 1761    { prolog_frame_attribute(Frame, goal, Goal),
 1762      goal_style(Port, Style)
 1763    },
 1764    (   { frame_location(Frame, Location) }
 1765    ->  goal(Goal, Style, Location)
 1766    ;   goal(Goal, Style)
 1767    ).
 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).
 1774predicate_goal(Goal, Port) -->
 1775    { goal_style(Port, Style)
 1776    },
 1777    (   { goal_links,
 1778          predicate_location(Goal, Location)
 1779        }
 1780    ->  goal(Goal, Style, Location)
 1781    ;   goal(Goal, Style)
 1782    ).
 1783
 1784goal(Goal0, Style) -->
 1785    { goal_format(Goal0, Goal, Options)
 1786    },
 1787    [ ansi(Style, '~W', [Goal, Options]) ].
 1788
 1789goal(Goal0, Style, Location) -->
 1790    { goal_format(Goal0, Goal, Options)
 1791    },
 1792    [ url(Location, ansi(Style, '~W', [Goal, Options])) ].
 1793
 1794goal_format(Goal0, Goal, Options) :-
 1795    clean_goal(Goal0, Goal),
 1796    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.

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

 2236:- public
 2237    predicate_reference//1,
 2238    predicate_reference//2. 2239
 2240predicate_reference(Spec) -->
 2241    predicate_reference(Spec, []).
 2242
 2243predicate_reference(Spec, Options) -->
 2244    { predicate_indicator(Spec, QPI) },
 2245    !,
 2246    { pref_option(style(Style), Options, code),
 2247      pref_option(module(Mode), Options, auto),
 2248      reference_pi(Mode, QPI, PI)
 2249    },
 2250    predicate_link(QPI, ansi(Style, '~q', [PI]), Options),
 2251    predicate_reference_tag(QPI, Options).
 2252predicate_reference(Spec, _Options) -->
 2253    [ ansi(code, '~p', [Spec]) ].
 2254
 2255reference_pi(auto, QPI, PI) :-
 2256    !,
 2257    user_predicate_indicator(QPI, PI).
 2258reference_pi(hide, _:PI, PI) :- !.
 2259reference_pi(_, QPI, QPI).
 2260
 2261predicate_link(QPI, Label, Options) -->
 2262    { pref_option(link(true), Options, true),
 2263      predicate_location(QPI, Location)
 2264    },
 2265    !,
 2266    [ url(Location, Label) ].
 2267predicate_link(_, Label, _) -->
 2268    [ 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.
 2277pref_option(Option, Options, Default) :-
 2278    functor(Option, Name, 1),
 2279    functor(General, Name, 1),
 2280    (   memberchk(General, Options)
 2281    ->  General = Option
 2282    ;   arg(1, Option, Default)
 2283    ).
 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.
 2292:- public
 2293    predicate_location/2. 2294
 2295predicate_location(Spec, Location) :-
 2296    predicate_head(Spec, Head),
 2297    current_predicate(_, Head),                 % do not (auto)load
 2298    '$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.
 2305:- public
 2306    predicate_definition//2. 2307
 2308predicate_definition(Spec, Message) -->
 2309    { predicate_location(Spec, Location) },
 2310    !,
 2311    [ nl, '~w at '-[Message], url(Location) ].
 2312predicate_definition(_, _) -->
 2313    [].
 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
 2329:- public
 2330    predicate_kind/2. 2331
 2332predicate_kind(Spec, Kind) :-
 2333    predicate_head(Spec, Head),
 2334    (   current_predicate(_, Head)              % do not autoload
 2335    ->  defined_predicate_kind(Head, Kind)
 2336    ;   predicate_property(Head, autoload(File))
 2337    ->  library_name(File, Name),
 2338        Kind = library(Name)
 2339    ;   Kind = undefined
 2340    ).
 2341
 2342defined_predicate_kind(Head, Kind) :-
 2343    (   predicate_property(Head, iso)
 2344    ->  Kind = iso
 2345    ;   predicate_property(Head, built_in)
 2346    ->  (   predicate_property(Head, foreign)
 2347        ->  Kind = foreign
 2348        ;   Kind = built_in
 2349        )
 2350    ;   predicate_property(Head, imported_from(Module))
 2351    ->  module_kind(Module, Kind)
 2352    ;   predicate_property(Head, file(File)),
 2353        library_file(File)
 2354    ->  library_name(File, Name),
 2355        Kind = library(Name)
 2356    ;   Kind = user
 2357    ).
 2358
 2359module_kind(Module, Kind) :-
 2360    (   hidden_module(Module)
 2361    ->  Kind = user
 2362    ;   module_property(Module, file(File)),
 2363        library_file(File)
 2364    ->  library_name(File, Name),
 2365        Kind = library(Name)
 2366    ;   Kind = module(Module)
 2367    ).
 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).
 2375library_file(File) :-
 2376    absolute_file_name(library(.), LibDir,
 2377                       [ file_type(directory),
 2378                         solutions(all),
 2379                         file_errors(fail)
 2380                       ]),
 2381    sub_atom(File, 0, _, _, LibDir),
 2382    !.
 2383
 2384library_name(File, Name) :-
 2385    (   file_name_extension(Base, Ext, File),
 2386        Ext \== ''
 2387    ->  true
 2388    ;   Base = File
 2389    ),
 2390    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.
 2397predicate_reference_tag(QPI, Options) -->
 2398    { pref_option(tag(true), Options, false),
 2399      predicate_kind(QPI, Kind)
 2400    },
 2401    !,
 2402    predicate_kind_tag(Kind).
 2403predicate_reference_tag(_, _) -->
 2404    [].
 2405
 2406predicate_kind_tag(Kind) -->
 2407    { predicate_kind_label(Kind, Label) },
 2408    [ ansi(predicate(Kind), ' [~w]', [Label]) ].
 2409
 2410predicate_kind_label(iso,          'ISO').
 2411predicate_kind_label(built_in,     'built-in').
 2412predicate_kind_label(foreign,      'built-in').
 2413predicate_kind_label(user,         'user').
 2414predicate_kind_label(undefined,    'undefined').
 2415predicate_kind_label(library(Name), Label) :-
 2416    format(atom(Label), 'library(~w)', [Name]).
 2417predicate_kind_label(module(Name), Name).
 2418
 2419
 2420		 /*******************************
 2421		 *        DEFAULT THEME		*
 2422		 *******************************/
 2423
 2424:- public default_theme/2. 2425
 2426default_theme(var,                    [fg(red)]).
 2427default_theme(code,                   [fg(blue)]).
 2428default_theme(comment,                [fg(green)]).
 2429default_theme(warning,                [fg(red)]).
 2430default_theme(error,                  [bold, fg(red)]).
 2431default_theme(truth(false),           [bold, fg(red)]).
 2432default_theme(truth(true),            [bold]).
 2433default_theme(truth(undefined),       [bold, fg(cyan)]).
 2434default_theme(wfs(residual_program),  [fg(cyan)]).
 2435default_theme(frame(level),           [bold]).
 2436default_theme(goal(_,_),              []).
 2437default_theme(port(call),             [bold, fg(green)]).
 2438default_theme(port(exit),             [bold, fg(green)]).
 2439default_theme(port(fail),             [bold, fg(red)]).
 2440default_theme(port(redo),             [bold, fg(yellow)]).
 2441default_theme(port(unify),            [bold, fg(blue)]).
 2442default_theme(port(exception),        [bold, fg(magenta)]).
 2443default_theme(prompt,                 [bold]).
 2444default_theme(input,                  []).
 2445default_theme(answer(_),              []).
 2446default_theme(binding(name),          [bold]).
 2447default_theme(predicate(iso),         [italic, fg(cyan)]).
 2448default_theme(predicate(built_in),    [italic, fg(cyan)]).
 2449default_theme(predicate(foreign),     [italic, fg(cyan)]).
 2450default_theme(predicate(library(_)),  [italic, fg(green)]).
 2451default_theme(predicate(module(_)),   [italic, fg(green)]).
 2452default_theme(predicate(user),        [italic, fg(default)]).
 2453default_theme(predicate(undefined),   [italic, fg(red)]).
 2454default_theme(message(informational), [fg(green)]).
 2455default_theme(message(information),   [fg(green)]).
 2456default_theme(message(debug(_)),      [fg(blue)]).
 2457default_theme(message(Level),         Attrs) :-
 2458    nonvar(Level),
 2459    default_theme(Level, Attrs).
 2460
 2461
 2462                 /*******************************
 2463                 *      PRINTING MESSAGES       *
 2464                 *******************************/
 2465
 2466:- multifile
 2467    user:message_hook/3,
 2468    prolog:message_prefix_hook/2. 2469:- dynamic
 2470    user:message_hook/3,
 2471    prolog:message_prefix_hook/2. 2472:- thread_local
 2473    user:thread_message_hook/3. 2474:- '$notransact'((user:message_hook/3,
 2475                  prolog:message_prefix_hook/2,
 2476                  user:thread_message_hook/3)).
 print_message(+Kind, +Term)
Print an error message using a term as generated by the exception system.
 2483print_message(Level, _Term) :-
 2484    msg_property(Level, stream(S)),
 2485    stream_property(S, error(true)),
 2486    !.
 2487print_message(Level, Term) :-
 2488    setup_call_cleanup(
 2489        notrace(push_msg(Term, Stack)),
 2490        ignore(print_message_guarded(Level, Term)),
 2491        notrace(pop_msg(Stack))),
 2492    !.
 2493print_message(Level, Term) :-
 2494    (   Level \== silent
 2495    ->  format(user_error, 'Recursive ~w message: ~q~n', [Level, Term]),
 2496        autoload_call(backtrace(20))
 2497    ;   true
 2498    ).
 2499
 2500push_msg(Term, Messages) :-
 2501    nb_current('$inprint_message', Messages),
 2502    !,
 2503    \+ ( '$member'(Msg, Messages),
 2504         Msg =@= Term
 2505       ),
 2506    Stack = [Term|Messages],
 2507    b_setval('$inprint_message', Stack).
 2508push_msg(Term, []) :-
 2509    b_setval('$inprint_message', [Term]).
 2510
 2511pop_msg(Stack) :-
 2512    nb_delete('$inprint_message'),              % delete history
 2513    b_setval('$inprint_message', Stack).
 2514
 2515print_message_guarded(Level, Term) :-
 2516    (   must_print(Level, Term)
 2517    ->  (   prolog:message_action(Term, Level),
 2518            fail                                % forall/2 is cleaner, but not yet
 2519        ;   true                                % defined
 2520        ),
 2521        (   translate_message(Term, Lines, [])
 2522        ->  (   nonvar(Term),
 2523                (   notrace(user:thread_message_hook(Term, Level, Lines))
 2524                ->  true
 2525                ;   notrace(user:message_hook(Term, Level, Lines))
 2526                )
 2527            ->  true
 2528            ;   '$inc_message_count'(Level),
 2529                print_system_message(Term, Level, Lines),
 2530                maybe_halt_on_error(Level)
 2531            )
 2532        )
 2533    ;   true
 2534    ).
 2535
 2536maybe_halt_on_error(error) :-
 2537    current_prolog_flag(on_error, halt),
 2538    !,
 2539    halt(1).
 2540maybe_halt_on_error(warning) :-
 2541    current_prolog_flag(on_warning, halt),
 2542    !,
 2543    halt(1).
 2544maybe_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.
 2554print_system_message(_, silent, _) :- !.
 2555print_system_message(_, informational, _) :-
 2556    current_prolog_flag(verbose, silent),
 2557    !.
 2558print_system_message(_, banner, _) :-
 2559    current_prolog_flag(verbose, silent),
 2560    !.
 2561print_system_message(_, _, []) :- !.
 2562print_system_message(Term, Kind, Lines) :-
 2563    catch(flush_output(user_output), _, true),      % may not exist
 2564    source_location(File, Line),
 2565    Term \= error(syntax_error(_), _),
 2566    msg_property(Kind, location_prefix(File:Line, LocPrefix, LinePrefix)),
 2567    !,
 2568    to_list(LocPrefix, LocPrefixL),
 2569    insert_prefix(Lines, LinePrefix, Ctx, PrefixLines),
 2570    '$append'([ [begin(Kind, Ctx)],
 2571                LocPrefixL,
 2572                [nl],
 2573                PrefixLines,
 2574                [end(Ctx)]
 2575              ],
 2576              AllLines),
 2577    msg_property(Kind, stream(Stream)),
 2578    ignore(stream_property(Stream, position(Pos))),
 2579    print_message_lines(Stream, AllLines),
 2580    (   \+ stream_property(Stream, position(Pos)),
 2581        msg_property(Kind, wait(Wait)),
 2582        Wait > 0
 2583    ->  sleep(Wait)
 2584    ;   true
 2585    ).
 2586print_system_message(_, Kind, Lines) :-
 2587    msg_property(Kind, stream(Stream)),
 2588    print_message_lines(Stream, kind(Kind), Lines).
 2589
 2590to_list(ListIn, List) :-
 2591    is_list(ListIn),
 2592    !,
 2593    List = ListIn.
 2594to_list(NonList, [NonList]).
 2595
 2596:- multifile
 2597    user:message_property/2. 2598
 2599msg_property(Kind, Property) :-
 2600    notrace(user:message_property(Kind, Property)),
 2601    !.
 2602msg_property(Kind, prefix(Prefix)) :-
 2603    msg_prefix(Kind, Prefix),
 2604    !.
 2605msg_property(_, prefix('~N')) :- !.
 2606msg_property(query, color_class(Class)) :-
 2607    !,
 2608    '$answer_class'(Class).
 2609msg_property(query, stream(user_output)) :- !.
 2610msg_property(_, stream(user_error)) :- !.
 2611msg_property(error, tag('ERROR')).
 2612msg_property(warning, tag('Warning')).
 2613msg_property(Level,
 2614             location_prefix(File:Line,
 2615                             ['~N~w: '-[Tag], url(File:Line), ':'],
 2616                             '~N~w:    '-[Tag])) :-
 2617    include_msg_location(Level),
 2618    msg_property(Level, tag(Tag)).
 2619msg_property(error,   wait(0.1)) :- !.
 2620
 2621include_msg_location(warning).
 2622include_msg_location(error).
 2623
 2624msg_prefix(debug(_), Prefix) :-
 2625    msg_context('~N% ', Prefix).
 2626msg_prefix(Level, Prefix) :-
 2627    msg_property(Level, tag(Tag)),
 2628    atomics_to_string(['~N', Tag, ': '], Prefix0),
 2629    msg_context(Prefix0, Prefix).
 2630msg_prefix(informational, '~N% ').
 2631msg_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.

 2645msg_context(Prefix0, Prefix) :-
 2646    current_prolog_flag(message_context, Context),
 2647    is_list(Context),
 2648    !,
 2649    add_message_context(Context, Prefix0, Prefix).
 2650msg_context(Prefix, Prefix).
 2651
 2652add_message_context([], Prefix, Prefix).
 2653add_message_context([H|T], Prefix0, Prefix) :-
 2654    (   add_message_context1(H, Prefix0, Prefix1)
 2655    ->  true
 2656    ;   Prefix1 = Prefix0
 2657    ),
 2658    add_message_context(T, Prefix1, Prefix).
 2659
 2660add_message_context1(Context, Prefix0, Prefix) :-
 2661    prolog:message_prefix_hook(Context, Extra),
 2662    atomics_to_string([Prefix0, Extra, ' '], Prefix).
 2663add_message_context1(time, Prefix0, Prefix) :-
 2664    get_time(Now),
 2665    format_time(string(S), '%T.%3f ', Now),
 2666    string_concat(Prefix0, S, Prefix).
 2667add_message_context1(time(Format), Prefix0, Prefix) :-
 2668    get_time(Now),
 2669    format_time(string(S), Format, Now),
 2670    atomics_to_string([Prefix0, S, ' '], Prefix).
 2671add_message_context1(thread, Prefix0, Prefix) :-
 2672    \+ current_prolog_flag(toplevel_thread, true),
 2673    thread_self(Id0),
 2674    !,
 2675    (   atom(Id0)
 2676    ->  Id = Id0
 2677    ;   thread_property(Id0, id(Id))
 2678    ),
 2679    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.

 2697print_message_lines(Stream, kind(Kind), Lines) :-
 2698    !,
 2699    msg_property(Kind, prefix(Prefix)),
 2700    msg_color_class(Kind, Class),
 2701    insert_prefix(Lines, Prefix, Ctx, PrefixLines),
 2702    '$append'([ begin(Class, Ctx)
 2703              | PrefixLines
 2704              ],
 2705              [ end(Ctx)
 2706              ],
 2707              AllLines),
 2708    print_message_lines(Stream, AllLines).
 2709print_message_lines(Stream, Prefix, Lines) :-
 2710    insert_prefix(Lines, Prefix, _, PrefixLines),
 2711    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).
 2719msg_color_class(Kind, Class) :-
 2720    msg_property(Kind, color_class(Class0)),
 2721    !,
 2722    Class = Class0.
 2723msg_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.
 2732insert_prefix([at_same_line|Lines0], Prefix, Ctx, Lines) :-
 2733    !,
 2734    prefix_nl(Lines0, Prefix, Ctx, Lines).
 2735insert_prefix(Lines0, Prefix, Ctx, [prefix(Prefix)|Lines]) :-
 2736    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.

 2758prefix_nl([], _, _, [nl]).
 2759prefix_nl([nl], _, Ctx, [nl(Ctx)]) :- !.
 2760prefix_nl([flush], _, Ctx, [flush(Ctx)]) :- !.
 2761prefix_nl([nl|T0], Prefix, Ctx, [nl(Ctx), prefix(Prefix)|T]) :-
 2762    !,
 2763    prefix_nl(T0, Prefix, Ctx, T).
 2764prefix_nl([flush|T0], Prefix, Ctx, [flush(Ctx)|T]) :-
 2765    !,
 2766    prefix_nl(T0, Prefix, Ctx, T).
 2767prefix_nl([eol|T0], Prefix, Ctx, [eol(Ctx)|T]) :-
 2768    !,
 2769    prefix_nl(T0, Prefix, Ctx, T).
 2770prefix_nl([ansi(Attrs,Fmt,Args)|T0], Prefix, Ctx,
 2771          [ansi(Attrs,Fmt,Args,Ctx)|T]) :-
 2772    !,
 2773    prefix_nl(T0, Prefix, Ctx, T).
 2774prefix_nl([url(URL,ansi(Attrs,Fmt,Args))|T0], Prefix, Ctx,
 2775          [url(URL,ansi(Attrs,Fmt,Args,Ctx))|T]) :-
 2776    !,
 2777    prefix_nl(T0, Prefix, Ctx, T).
 2778prefix_nl([H|T0], Prefix, Ctx, [H|T]) :-
 2779    prefix_nl(T0, Prefix, Ctx, T).
 print_message_lines(+Stream, +Lines)
 2783print_message_lines(Stream, Lines) :-
 2784    with_output_to(
 2785        Stream,
 2786        notrace(print_message_lines_guarded(current_output, Lines))).
 2787
 2788print_message_lines_guarded(_, []) :- !.
 2789print_message_lines_guarded(S, [H|T]) :-
 2790    line_element(S, H),
 2791    print_message_lines_guarded(S, T).
 2792
 2793line_element(S, E) :-
 2794    prolog:message_line_element(S, E),
 2795    !.
 2796line_element(S, full_stop) :-
 2797    !,
 2798    '$put_token'(S, '.').           % insert space if needed.
 2799line_element(S, nl) :-
 2800    !,
 2801    nl(S).
 2802line_element(S, nl(_Ctx)) :-
 2803    !,
 2804    nl(S).
 2805line_element(S, flush(_Ctx)) :-
 2806    !,
 2807    flush_output(S).
 2808line_element(_, eol(_Ctx)) :- !.
 2809line_element(S, prefix(Fmt-Args)) :-
 2810    !,
 2811    safe_format(S, Fmt, Args).
 2812line_element(S, prefix(Fmt)) :-
 2813    !,
 2814    safe_format(S, Fmt, []).
 2815line_element(S, flush) :-
 2816    !,
 2817    flush_output(S).
 2818line_element(S, Fmt-Args) :-
 2819    !,
 2820    safe_format(S, Fmt, Args).
 2821line_element(S, ansi(_, Fmt, Args)) :-
 2822    !,
 2823    safe_format(S, Fmt, Args).
 2824line_element(S, ansi(_, Fmt, Args, _Ctx)) :-
 2825    !,
 2826    safe_format(S, Fmt, Args).
 2827line_element(S, url(URL)) :-
 2828    !,
 2829    print_link(S, URL).
 2830line_element(S, url(_URL, Label)) :-
 2831    !,
 2832    link_label(Label, Fmt, Args),
 2833    safe_format(S, Fmt, Args).
 2834line_element(_, begin(_Level, _Ctx)) :- !.
 2835line_element(_, end(_Ctx)) :- !.
 2836line_element(S, Fmt) :-
 2837    safe_format(S, Fmt, []).
 2838
 2839print_link(S, File:Line:Column) :-
 2840    !,
 2841    safe_format(S, '~w:~d:~d', [File, Line, Column]).
 2842print_link(S, File:Line) :-
 2843    !,
 2844    safe_format(S, '~w:~d', [File, Line]).
 2845print_link(S, File) :-
 2846    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 ~.
 2854:- public
 2855    link_label/3. 2856
 2857link_label(Fmt-Args, Fmt, Args) :-
 2858    atom(Fmt),
 2859    is_list(Args),
 2860    !.
 2861link_label(ansi(_Class, Fmt, Args), Fmt, Args) :- !.
 2862link_label(ansi(_Class, Fmt, Args, _Ctx), Fmt, Args) :- !.
 2863link_label(Text, '~w', [Text]).
 safe_format(+Stream, +Format, +Args) is det
 2867safe_format(S, Fmt, Args) :-
 2868    E = error(_,_),
 2869    catch(format(S,Fmt,Args), E,
 2870          format_failed(S,Fmt,Args,E)).
 2871
 2872format_failed(S, _Fmt, _Args, E) :-
 2873    stream_property(S, error(true)),
 2874    !,
 2875    throw(E).
 2876format_failed(S, Fmt, Args, error(E,_)) :-
 2877    format(S, '~N    [[ EXCEPTION while printing message ~q~n\c
 2878                        ~7|with arguments ~W:~n\c
 2879                        ~7|raised: ~W~n~4|]]~n',
 2880           [ Fmt,
 2881             Args, [quoted(true), max_depth(10)],
 2882             E, [quoted(true), max_depth(10)]
 2883           ]).
 message_to_string(+Term, -String)
Translate an error term into a string
 2889message_to_string(Term, Str) :-
 2890    translate_message(Term, Actions, []),
 2891    !,
 2892    actions_to_format(Actions, Fmt, Args),
 2893    format(string(Str), Fmt, Args).
 2894
 2895actions_to_format([], '', []) :- !.
 2896actions_to_format([nl(_)|T], Fmt, Args) :-      % see prefix_nl/4
 2897    !,
 2898    actions_to_format([nl|T], Fmt, Args).
 2899actions_to_format([nl], '', []) :- !.
 2900actions_to_format([Term, nl], Fmt, Args) :-
 2901    !,
 2902    actions_to_format([Term], Fmt, Args).
 2903actions_to_format([nl|T], Fmt, Args) :-
 2904    !,
 2905    actions_to_format(T, Fmt0, Args),
 2906    atom_concat('~n', Fmt0, Fmt).
 2907actions_to_format([ansi(_Attrs, Fmt0, Args0)|Tail], Fmt, Args) :-
 2908    !,
 2909    actions_to_format(Tail, Fmt1, Args1),
 2910    atom_concat(Fmt0, Fmt1, Fmt),
 2911    append_args(Args0, Args1, Args).
 2912actions_to_format([url(Pos)|Tail], Fmt, Args) :-
 2913    !,
 2914    actions_to_format(Tail, Fmt1, Args1),
 2915    url_actions_to_format(url(Pos), Fmt1, Args1, Fmt, Args).
 2916actions_to_format([url(URL, Label)|Tail], Fmt, Args) :-
 2917    !,
 2918    actions_to_format(Tail, Fmt1, Args1),
 2919    url_actions_to_format(url(URL, Label), Fmt1, Args1, Fmt, Args).
 2920actions_to_format([Fmt0-Args0|Tail], Fmt, Args) :-
 2921    !,
 2922    actions_to_format(Tail, Fmt1, Args1),
 2923    atom_concat(Fmt0, Fmt1, Fmt),
 2924    append_args(Args0, Args1, Args).
 2925actions_to_format([Skip|T], Fmt, Args) :-
 2926    action_skip(Skip),
 2927    !,
 2928    actions_to_format(T, Fmt, Args).
 2929actions_to_format([Term|Tail], Fmt, Args) :-
 2930    atomic(Term),
 2931    !,
 2932    actions_to_format(Tail, Fmt1, Args),
 2933    atom_concat(Term, Fmt1, Fmt).
 2934actions_to_format([Term|Tail], Fmt, Args) :-
 2935    actions_to_format(Tail, Fmt1, Args1),
 2936    atom_concat('~w', Fmt1, Fmt),
 2937    append_args([Term], Args1, Args).
 2938
 2939action_skip(at_same_line).
 2940action_skip(flush).
 2941action_skip(flush(_Ctx)).
 2942action_skip(eol).
 2943action_skip(eol(_Ctx)).
 2944action_skip(begin(_Level, _Ctx)).
 2945action_skip(end(_Ctx)).
 2946
 2947url_actions_to_format(url(File:Line:Column), Fmt1, Args1, Fmt, Args) :-
 2948    !,
 2949    atom_concat('~w:~d:~d', Fmt1, Fmt),
 2950    append_args([File,Line,Column], Args1, Args).
 2951url_actions_to_format(url(File:Line), Fmt1, Args1, Fmt, Args) :-
 2952    !,
 2953    atom_concat('~w:~d', Fmt1, Fmt),
 2954    append_args([File,Line], Args1, Args).
 2955url_actions_to_format(url(File), Fmt1, Args1, Fmt, Args) :-
 2956    !,
 2957    atom_concat('~w', Fmt1, Fmt),
 2958    append_args([File], Args1, Args).
 2959url_actions_to_format(url(_URL, Label), Fmt1, Args1, Fmt, Args) :-
 2960    !,
 2961    link_label(Label, Fmt0, Args0),
 2962    atom_concat(Fmt0, Fmt1, Fmt),
 2963    append_args(Args0, Args1, Args).
 2964
 2965
 2966append_args(M:Args0, Args1, M:Args) :-
 2967    !,
 2968    strip_module(Args1, _, A1),
 2969    to_list(Args0, Args01),
 2970    '$append'(Args01, A1, Args).
 2971append_args(Args0, Args1, Args) :-
 2972    strip_module(Args1, _, A1),
 2973    to_list(Args0, Args01),
 2974    '$append'(Args01, A1, Args).
 2975
 2976                 /*******************************
 2977                 *    MESSAGES TO PRINT ONCE    *
 2978                 *******************************/
 2979
 2980:- dynamic
 2981    printed/2.
 print_once(Message, Level)
True for messages that must be printed only once.
 2987print_once(compatibility(_), _).
 2988print_once(null_byte_in_path(_), _).
 2989print_once(deprecated(_), _).
 must_print(+Level, +Message)
True if the message must be printed.
 2995must_print(Level, Message) :-
 2996    nonvar(Message),
 2997    print_once(Message, Level),
 2998    !,
 2999    \+ printed(Message, Level),
 3000    assert(printed(Message, Level)).
 3001must_print(_, _)