View source with raw comments or as raw
    1/*  Part of SWI-Prolog
    2
    3    Author:        Jan Wielemaker
    4    E-mail:        J.Wielemaker@vu.nl
    5    WWW:           http://www.swi-prolog.org
    6    Copyright (c)  1997-2019, University of Amsterdam
    7                              VU University Amsterdam
    8                              CWI, Amsterdam
    9    All rights reserved.
   10
   11    Redistribution and use in source and binary forms, with or without
   12    modification, are permitted provided that the following conditions
   13    are met:
   14
   15    1. Redistributions of source code must retain the above copyright
   16       notice, this list of conditions and the following disclaimer.
   17
   18    2. Redistributions in binary form must reproduce the above copyright
   19       notice, this list of conditions and the following disclaimer in
   20       the documentation and/or other materials provided with the
   21       distribution.
   22
   23    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   24    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   25    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   26    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   27    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   28    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   29    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   30    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   31    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   33    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   34    POSSIBILITY OF SUCH DAMAGE.
   35*/
   36
   37:- module('$messages',
   38          [ print_message/2,            % +Kind, +Term
   39            print_message_lines/3,      % +Stream, +Prefix, +Lines
   40            message_to_string/2         % +Term, -String
   41          ]).   42
   43:- multifile
   44    prolog:message//1,              % entire message
   45    prolog:error_message//1,        % 1-st argument of error term
   46    prolog:message_context//1,      % Context of error messages
   47    prolog:message_location//1,     % (File) location of error messages
   48    prolog:message_line_element/2.  % Extend printing
   49:- discontiguous
   50    prolog_message/3.   51
   52:- public
   53    translate_message//1.   54
   55:- create_prolog_flag(message_context, [thread], []).
 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)
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)
   74translate_message(Term) -->
   75    translate_message2(Term),
   76    !.
   77translate_message(Term) -->
   78    { Term = error(_, _) },
   79    [ 'Unknown exception: ~p'-[Term] ].
   80translate_message(Term) -->
   81    [ 'Unknown message: ~p'-[Term] ].
   82
   83translate_message2(Term) -->
   84    {var(Term)},
   85    !,
   86    [ 'Unknown message: ~p'-[Term] ].
   87translate_message2(Term) -->
   88    prolog:message(Term).
   89translate_message2(Term) -->
   90    prolog_message(Term).
   91translate_message2(error(resource_error(stack), Context)) -->
   92    out_of_stack(Context).
   93translate_message2(error(resource_error(Missing), _)) -->
   94    [ 'Not enough resources: ~w'-[Missing] ].
   95translate_message2(error(ISO, SWI)) -->
   96    swi_location(SWI),
   97    term_message(ISO),
   98    swi_extra(SWI).
   99translate_message2('$aborted') -->
  100    [ 'Execution Aborted' ].
  101translate_message2(message_lines(Lines), L, T) :- % deal with old C-warning()
  102    make_message_lines(Lines, L, T).
  103translate_message2(format(Fmt, Args)) -->
  104    [ Fmt-Args ].
  105
  106make_message_lines([], T, T) :- !.
  107make_message_lines([Last],  ['~w'-[Last]|T], T) :- !.
  108make_message_lines([L0|LT], ['~w'-[L0],nl|T0], T) :-
  109    make_message_lines(LT, T0, T).
  110
  111term_message(Term) -->
  112    {var(Term)},
  113    !,
  114    [ 'Unknown error term: ~p'-[Term] ].
  115term_message(Term) -->
  116    prolog:error_message(Term).
  117term_message(Term) -->
  118    iso_message(Term).
  119term_message(Term) -->
  120    swi_message(Term).
  121term_message(Term) -->
  122    [ 'Unknown error term: ~p'-[Term] ].
  123
  124iso_message(type_error(evaluable, Actual)) -->
  125    { callable(Actual) },
  126    [ 'Arithmetic: `~p'' is not a function'-[Actual] ].
  127iso_message(type_error(free_of_attvar, Actual)) -->
  128    [ 'Type error: `~W'' contains attributed variables'-
  129      [Actual,[portray(true), attributes(portray)]] ].
  130iso_message(type_error(Expected, Actual)) -->
  131    [ 'Type error: `~w'' expected, found `~p'''-[Expected, Actual] ],
  132    type_error_comment(Expected, Actual).
  133iso_message(domain_error(Domain, Actual)) -->
  134    [ 'Domain error: '-[] ], domain(Domain),
  135    [ ' expected, found `~p'''-[Actual] ].
  136iso_message(instantiation_error) -->
  137    [ 'Arguments are not sufficiently instantiated' ].
  138iso_message(uninstantiation_error(Var)) -->
  139    [ 'Uninstantiated argument expected, found ~p'-[Var] ].
  140iso_message(representation_error(What)) -->
  141    [ 'Cannot represent due to `~w'''-[What] ].
  142iso_message(permission_error(Action, Type, Object)) -->
  143    permission_error(Action, Type, Object).
  144iso_message(evaluation_error(Which)) -->
  145    [ 'Arithmetic: evaluation error: `~p'''-[Which] ].
  146iso_message(existence_error(procedure, Proc)) -->
  147    [ 'Unknown procedure: ~q'-[Proc] ],
  148    unknown_proc_msg(Proc).
  149iso_message(existence_error(answer_variable, Var)) -->
  150    [ '$~w was not bound by a previous query'-[Var] ].
  151iso_message(existence_error(Type, Object)) -->
  152    [ '~w `~p'' does not exist'-[Type, Object] ].
  153iso_message(existence_error(Type, Object, In)) --> % not ISO
  154    [ '~w `~p'' does not exist in ~p'-[Type, Object, In] ].
  155iso_message(busy(Type, Object)) -->
  156    [ '~w `~p'' is busy'-[Type, Object] ].
  157iso_message(syntax_error(swi_backslash_newline)) -->
  158    [ 'Deprecated ... \\<newline><white>*.  Use \\c' ].
  159iso_message(syntax_error(Id)) -->
  160    [ 'Syntax error: ' ],
  161    syntax_error(Id).
  162iso_message(occurs_check(Var, In)) -->
  163    [ '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.
  170permission_error(Action, built_in_procedure, Pred) -->
  171    { user_predicate_indicator(Pred, PI)
  172    },
  173    [ 'No permission to ~w built-in predicate `~p'''-[Action, PI] ],
  174    (   {Action \== export}
  175    ->  [ nl,
  176          'Use :- redefine_system_predicate(+Head) if redefinition is intended'
  177        ]
  178    ;   []
  179    ).
  180permission_error(import_into(Dest), procedure, Pred) -->
  181    [ 'No permission to import ~p into ~w'-[Pred, Dest] ].
  182permission_error(Action, static_procedure, Proc) -->
  183    [ 'No permission to ~w static procedure `~p'''-[Action, Proc] ],
  184    defined_definition('Defined', Proc).
  185permission_error(input, stream, Stream) -->
  186    [ 'No permission to read from output stream `~p'''-[Stream] ].
  187permission_error(output, stream, Stream) -->
  188    [ 'No permission to write to input stream `~p'''-[Stream] ].
  189permission_error(input, text_stream, Stream) -->
  190    [ 'No permission to read bytes from TEXT stream `~p'''-[Stream] ].
  191permission_error(output, text_stream, Stream) -->
  192    [ 'No permission to write bytes to TEXT stream `~p'''-[Stream] ].
  193permission_error(input, binary_stream, Stream) -->
  194    [ 'No permission to read characters from binary stream `~p'''-[Stream] ].
  195permission_error(output, binary_stream, Stream) -->
  196    [ 'No permission to write characters to binary stream `~p'''-[Stream] ].
  197permission_error(open, source_sink, alias(Alias)) -->
  198    [ 'No permission to reuse alias "~p": already taken'-[Alias] ].
  199permission_error(tnot, non_tabled_procedure, Pred) -->
  200    [ 'The argument of tnot/1 is not tabled: ~p'-[Pred] ].
  201permission_error(Action, Type, Object) -->
  202    [ 'No permission to ~w ~w `~p'''-[Action, Type, Object] ].
  203
  204
  205unknown_proc_msg(_:(^)/2) -->
  206    !,
  207    unknown_proc_msg((^)/2).
  208unknown_proc_msg((^)/2) -->
  209    !,
  210    [nl, '  ^/2 can only appear as the 2nd argument of setof/3 and bagof/3'].
  211unknown_proc_msg((:-)/2) -->
  212    !,
  213    [nl, '  Rules must be loaded from a file'],
  214    faq('ToplevelMode').
  215unknown_proc_msg((:-)/1) -->
  216    !,
  217    [nl, '  Directives must be loaded from a file'],
  218    faq('ToplevelMode').
  219unknown_proc_msg((?-)/1) -->
  220    !,
  221    [nl, '  ?- is the Prolog prompt'],
  222    faq('ToplevelMode').
  223unknown_proc_msg(Proc) -->
  224    { dwim_predicates(Proc, Dwims) },
  225    (   {Dwims \== []}
  226    ->  [nl, '  However, there are definitions for:', nl],
  227        dwim_message(Dwims)
  228    ;   []
  229    ).
  230
  231faq(Page) -->
  232    [nl, '  See FAQ at http://www.swi-prolog.org/FAQ/', Page, '.txt' ].
  233
  234type_error_comment(_Expected, Actual) -->
  235    { type_of(Actual, Type),
  236      (   sub_atom(Type, 0, 1, _, First),
  237          memberchk(First, [a,e,i,o,u])
  238      ->  Article = an
  239      ;   Article = a
  240      )
  241    },
  242    [ ' (~w ~w)'-[Article, Type] ].
  243
  244type_of(Term, Type) :-
  245    (   attvar(Term)      -> Type = attvar
  246    ;   var(Term)         -> Type = var
  247    ;   atom(Term)        -> Type = atom
  248    ;   integer(Term)     -> Type = integer
  249    ;   string(Term)      -> Type = string
  250    ;   Term == []        -> Type = empty_list
  251    ;   blob(Term, BlobT) -> blob_type(BlobT, Type)
  252    ;   rational(Term)    -> Type = rational
  253    ;   float(Term)       -> Type = float
  254    ;   is_stream(Term)   -> Type = stream
  255    ;   is_dict(Term)     -> Type = dict
  256    ;   is_list(Term)     -> Type = list
  257    ;   cyclic_term(Term) -> Type = cyclic
  258    ;   compound(Term)    -> Type = compound
  259    ;                        Type = unknown
  260    ).
  261
  262blob_type(BlobT, Type) :-
  263    atom_concat(BlobT, '_reference', Type).
  264
  265syntax_error(end_of_clause) -->
  266    [ 'Unexpected end of clause' ].
  267syntax_error(end_of_clause_expected) -->
  268    [ 'End of clause expected' ].
  269syntax_error(end_of_file) -->
  270    [ 'Unexpected end of file' ].
  271syntax_error(end_of_file_in_block_comment) -->
  272    [ 'End of file in /* ... */ comment' ].
  273syntax_error(end_of_file_in_quoted(Quote)) -->
  274    [ 'End of file in quoted ' ],
  275    quoted_type(Quote).
  276syntax_error(illegal_number) -->
  277    [ 'Illegal number' ].
  278syntax_error(long_atom) -->
  279    [ 'Atom too long (see style_check/1)' ].
  280syntax_error(long_string) -->
  281    [ 'String too long (see style_check/1)' ].
  282syntax_error(operator_clash) -->
  283    [ 'Operator priority clash' ].
  284syntax_error(operator_expected) -->
  285    [ 'Operator expected' ].
  286syntax_error(operator_balance) -->
  287    [ 'Unbalanced operator' ].
  288syntax_error(quoted_punctuation) -->
  289    [ 'Operand expected, unquoted comma or bar found' ].
  290syntax_error(list_rest) -->
  291    [ 'Unexpected comma or bar in rest of list' ].
  292syntax_error(cannot_start_term) -->
  293    [ 'Illegal start of term' ].
  294syntax_error(punct(Punct, End)) -->
  295    [ 'Unexpected `~w\' before `~w\''-[Punct, End] ].
  296syntax_error(undefined_char_escape(C)) -->
  297    [ 'Unknown character escape in quoted atom or string: `\\~w\''-[C] ].
  298syntax_error(void_not_allowed) -->
  299    [ 'Empty argument list "()"' ].
  300syntax_error(Message) -->
  301    [ '~w'-[Message] ].
  302
  303quoted_type('\'') --> [atom].
  304quoted_type('\"') --> { current_prolog_flag(double_quotes, Type) }, [Type-[]].
  305quoted_type('\`') --> { current_prolog_flag(back_quotes, Type) }, [Type-[]].
  306
  307domain(range(Low,High)) -->
  308    !,
  309    ['[~q..~q]'-[Low,High] ].
  310domain(Domain) -->
  311    ['`~w\''-[Domain] ].
  312
  313dwim_predicates(Module:Name/_Arity, Dwims) :-
  314    !,
  315    findall(Dwim, dwim_predicate(Module:Name, Dwim), Dwims).
  316dwim_predicates(Name/_Arity, Dwims) :-
  317    findall(Dwim, dwim_predicate(user:Name, Dwim), Dwims).
  318
  319dwim_message([]) --> [].
  320dwim_message([M:Head|T]) -->
  321    { hidden_module(M),
  322      !,
  323      functor(Head, Name, Arity)
  324    },
  325    [ '        ~q'-[Name/Arity], nl ],
  326    dwim_message(T).
  327dwim_message([Module:Head|T]) -->
  328    !,
  329    { functor(Head, Name, Arity)
  330    },
  331    [ '        ~q'-[Module:Name/Arity], nl],
  332    dwim_message(T).
  333dwim_message([Head|T]) -->
  334    {functor(Head, Name, Arity)},
  335    [ '        ~q'-[Name/Arity], nl],
  336    dwim_message(T).
  337
  338
  339swi_message(io_error(Op, Stream)) -->
  340    [ 'I/O error in ~w on stream ~p'-[Op, Stream] ].
  341swi_message(shell(execute, Cmd)) -->
  342    [ 'Could not execute `~w'''-[Cmd] ].
  343swi_message(shell(signal(Sig), Cmd)) -->
  344    [ 'Caught signal ~d on `~w'''-[Sig, Cmd] ].
  345swi_message(format(Fmt, Args)) -->
  346    [ Fmt-Args ].
  347swi_message(signal(Name, Num)) -->
  348    [ 'Caught signal ~d (~w)'-[Num, Name] ].
  349swi_message(limit_exceeded(Limit, MaxVal)) -->
  350    [ 'Exceeded ~w limit (~w)'-[Limit, MaxVal] ].
  351swi_message(goal_failed(Goal)) -->
  352    [ 'goal unexpectedly failed: ~p'-[Goal] ].
  353swi_message(shared_object(_Action, Message)) --> % Message = dlerror()
  354    [ '~w'-[Message] ].
  355swi_message(system_error(Error)) -->
  356    [ 'error in system call: ~w'-[Error]
  357    ].
  358swi_message(system_error) -->
  359    [ 'error in system call'
  360    ].
  361swi_message(failure_error(Goal)) -->
  362    [ 'Goal failed: ~p'-[Goal] ].
  363swi_message(timeout_error(Op, Stream)) -->
  364    [ 'Timeout in ~w from ~p'-[Op, Stream] ].
  365swi_message(not_implemented(Type, What)) -->
  366    [ '~w `~p\' is not implemented in this version'-[Type, What] ].
  367swi_message(context_error(nodirective, Goal)) -->
  368    { goal_to_predicate_indicator(Goal, PI) },
  369    [ 'Wrong context: ~p can only be used in a directive'-[PI] ].
  370swi_message(context_error(edit, no_default_file)) -->
  371    (   { current_prolog_flag(windows, true) }
  372    ->  [ 'Edit/0 can only be used after opening a \c
  373               Prolog file by double-clicking it' ]
  374    ;   [ 'Edit/0 can only be used with the "-s file" commandline option'
  375        ]
  376    ),
  377    [ nl, 'Use "?- edit(Topic)." or "?- emacs."' ].
  378swi_message(context_error(function, meta_arg(S))) -->
  379    [ 'Functions are not (yet) supported for meta-arguments of type ~q'-[S] ].
  380swi_message(format_argument_type(Fmt, Arg)) -->
  381    [ 'Illegal argument to format sequence ~~~w: ~p'-[Fmt, Arg] ].
  382swi_message(format(Msg)) -->
  383    [ 'Format error: ~w'-[Msg] ].
  384swi_message(conditional_compilation_error(unterminated, Where)) -->
  385    [ 'Unterminated conditional compilation from '-[] ],
  386    cond_location(Where).
  387swi_message(conditional_compilation_error(no_if, What)) -->
  388    [ ':- ~w without :- if'-[What] ].
  389swi_message(duplicate_key(Key)) -->
  390    [ 'Duplicate key: ~p'-[Key] ].
  391swi_message(initialization_error(failed, Goal, File:Line)) -->
  392    !,
  393    [ '~w:~w: ~p: false'-[File, Line, Goal] ].
  394swi_message(initialization_error(Error, Goal, File:Line)) -->
  395    [ '~w:~w: ~p '-[File, Line, Goal] ],
  396    translate_message(Error).
  397swi_message(qlf_format_error(File, Message)) -->
  398    [ '~w: Invalid QLF file: ~w'-[File, Message] ].
  399
  400cond_location(File:Line) -->
  401    { file_base_name(File, Base) },
  402    [ '~w:~d'-[Base, Line] ].
  403
  404swi_location(X) -->
  405    { var(X)
  406    },
  407    !,
  408    [].
  409swi_location(Context) -->
  410    prolog:message_location(Context),
  411    !.
  412swi_location(context(Caller, _Msg)) -->
  413    { ground(Caller)
  414    },
  415    !,
  416    caller(Caller).
  417swi_location(file(Path, Line, -1, _CharNo)) -->
  418    !,
  419    [ '~w:~d: '-[Path, Line] ].
  420swi_location(file(Path, Line, LinePos, _CharNo)) -->
  421    [ '~w:~d:~d: '-[Path, Line, LinePos] ].
  422swi_location(stream(Stream, Line, LinePos, CharNo)) -->
  423    (   { is_stream(Stream),
  424          stream_property(Stream, file_name(File))
  425        }
  426    ->  swi_location(file(File, Line, LinePos, CharNo))
  427    ;   [ 'Stream ~w:~d:~d '-[Stream, Line, LinePos] ]
  428    ).
  429swi_location(_) -->
  430    [].
  431
  432caller(system:'$record_clause'/3) -->
  433    !,
  434    [].
  435caller(Module:Name/Arity) -->
  436    !,
  437    (   { \+ hidden_module(Module) }
  438    ->  [ '~q:~q/~w: '-[Module, Name, Arity] ]
  439    ;   [ '~q/~w: '-[Name, Arity] ]
  440    ).
  441caller(Name/Arity) -->
  442    [ '~q/~w: '-[Name, Arity] ].
  443caller(Caller) -->
  444    [ '~p: '-[Caller] ].
  445
  446
  447swi_extra(X) -->
  448    { var(X)
  449    },
  450    !,
  451    [].
  452swi_extra(Context) -->
  453    prolog:message_context(Context).
  454swi_extra(context(_, Msg)) -->
  455    { nonvar(Msg),
  456      Msg \== ''
  457    },
  458    !,
  459    swi_comment(Msg).
  460swi_extra(string(String, CharPos)) -->
  461    { sub_string(String, 0, CharPos, _, Before),
  462      sub_string(String, CharPos, _, 0, After)
  463    },
  464    [ nl, '~w'-[Before], nl, '** here **', nl, '~w'-[After] ].
  465swi_extra(_) -->
  466    [].
  467
  468swi_comment(already_from(Module)) -->
  469    !,
  470    [ ' (already imported from ~q)'-[Module] ].
  471swi_comment(directory(_Dir)) -->
  472    !,
  473    [ ' (is a directory)' ].
  474swi_comment(not_a_directory(_Dir)) -->
  475    !,
  476    [ ' (is not a directory)' ].
  477swi_comment(Msg) -->
  478    [ ' (~w)'-[Msg] ].
  479
  480
  481thread_context -->
  482    { thread_self(Me), Me \== main, thread_property(Me, id(Id)) },
  483    !,
  484    ['[Thread ~w] '-[Id]].
  485thread_context -->
  486    [].
  487
  488                 /*******************************
  489                 *        NORMAL MESSAGES       *
  490                 *******************************/
  491
  492prolog_message(initialization_error(_, E, File:Line)) -->
  493    !,
  494    [ '~w:~d: '-[File, Line],
  495      'Initialization goal raised exception:', nl
  496    ],
  497    translate_message(E).
  498prolog_message(initialization_error(Goal, E, _)) -->
  499    [ 'Initialization goal ~p raised exception:'-[Goal], nl ],
  500    translate_message(E).
  501prolog_message(initialization_failure(_Goal, File:Line)) -->
  502    !,
  503    [ '~w:~d: '-[File, Line],
  504      'Initialization goal failed'-[]
  505    ].
  506prolog_message(initialization_failure(Goal, _)) -->
  507    [ 'Initialization goal failed: ~p'-[Goal]
  508    ].
  509prolog_message(initialization_exception(E)) -->
  510    [ 'Prolog initialisation failed:', nl ],
  511    translate_message(E).
  512prolog_message(init_goal_syntax(Error, Text)) -->
  513    !,
  514    [ '-g ~w: '-[Text] ],
  515    translate_message(Error).
  516prolog_message(init_goal_failed(failed, @(Goal,File:Line))) -->
  517    !,
  518    [ '~w:~w: ~p: false'-[File, Line, Goal] ].
  519prolog_message(init_goal_failed(Error, @(Goal,File:Line))) -->
  520    !,
  521    [ '~w:~w: ~p '-[File, Line, Goal] ],
  522    translate_message(Error).
  523prolog_message(init_goal_failed(failed, Text)) -->
  524    !,
  525    [ '-g ~w: false'-[Text] ].
  526prolog_message(init_goal_failed(Error, Text)) -->
  527    !,
  528    [ '-g ~w: '-[Text] ],
  529    translate_message(Error).
  530prolog_message(unhandled_exception(E)) -->
  531    [ 'Unhandled exception: ' ],
  532    (   translate_message2(E)
  533    ->  []
  534    ;   [ '~p'-[E] ]
  535    ).
  536prolog_message(goal_failed(Context, Goal)) -->
  537    [ 'Goal (~w) failed: ~p'-[Context, Goal] ].
  538prolog_message(no_current_module(Module)) -->
  539    [ '~w is not a current module (created)'-[Module] ].
  540prolog_message(commandline_arg_type(Flag, Arg)) -->
  541    [ 'Bad argument to commandline option -~w: ~w'-[Flag, Arg] ].
  542prolog_message(missing_feature(Name)) -->
  543    [ 'This version of SWI-Prolog does not support ~w'-[Name] ].
  544prolog_message(singletons(_Term, List)) -->
  545    [ 'Singleton variables: ~w'-[List] ].
  546prolog_message(multitons(_Term, List)) -->
  547    [ 'Singleton-marked variables appearing more than once: ~w'-[List] ].
  548prolog_message(profile_no_cpu_time) -->
  549    [ 'No CPU-time info.  Check the SWI-Prolog manual for details' ].
  550prolog_message(non_ascii(Text, Type)) -->
  551    [ 'Unquoted ~w with non-portable characters: ~w'-[Type, Text] ].
  552prolog_message(io_warning(Stream, Message)) -->
  553    { stream_property(Stream, position(Position)),
  554      !,
  555      stream_position_data(line_count, Position, LineNo),
  556      stream_position_data(line_position, Position, LinePos),
  557      (   stream_property(Stream, file_name(File))
  558      ->  Obj = File
  559      ;   Obj = Stream
  560      )
  561    },
  562    [ '~p:~d:~d: ~w'-[Obj, LineNo, LinePos, Message] ].
  563prolog_message(io_warning(Stream, Message)) -->
  564    [ 'stream ~p: ~w'-[Stream, Message] ].
  565prolog_message(option_usage(pldoc)) -->
  566    [ 'Usage: --pldoc[=port]' ].
  567prolog_message(interrupt(begin)) -->
  568    [ 'Action (h for help) ? ', flush ].
  569prolog_message(interrupt(end)) -->
  570    [ 'continue' ].
  571prolog_message(interrupt(trace)) -->
  572    [ 'continue (trace mode)' ].
  573prolog_message(unknown_in_module_user) -->
  574    [ 'Using a non-error value for unknown in the global module', nl,
  575      'causes most of the development environment to stop working.', nl,
  576      'Please use :- dynamic or limit usage of unknown to a module.', nl,
  577      'See http://www.swi-prolog.org/howto/database.html'
  578    ].
  579prolog_message(deprecated(What)) -->
  580    deprecated(What).
  581
  582
  583                 /*******************************
  584                 *         LOADING FILES        *
  585                 *******************************/
  586
  587prolog_message(modify_active_procedure(Who, What)) -->
  588    [ '~p: modified active procedure ~p'-[Who, What] ].
  589prolog_message(load_file(failed(user:File))) -->
  590    [ 'Failed to load ~p'-[File] ].
  591prolog_message(load_file(failed(Module:File))) -->
  592    [ 'Failed to load ~p into module ~p'-[File, Module] ].
  593prolog_message(load_file(failed(File))) -->
  594    [ 'Failed to load ~p'-[File] ].
  595prolog_message(mixed_directive(Goal)) -->
  596    [ 'Cannot pre-compile mixed load/call directive: ~p'-[Goal] ].
  597prolog_message(cannot_redefine_comma) -->
  598    [ 'Full stop in clause-body?  Cannot redefine ,/2' ].
  599prolog_message(illegal_autoload_index(Dir, Term)) -->
  600    [ 'Illegal term in INDEX file of directory ~w: ~w'-[Dir, Term] ].
  601prolog_message(redefined_procedure(Type, Proc)) -->
  602    [ 'Redefined ~w procedure ~p'-[Type, Proc] ],
  603    defined_definition('Previously defined', Proc).
  604prolog_message(declare_module(Module, abolish(Predicates))) -->
  605    [ 'Loading module ~w abolished: ~p'-[Module, Predicates] ].
  606prolog_message(import_private(Module, Private)) -->
  607    [ 'import/1: ~p is not exported (still imported into ~q)'-
  608      [Private, Module]
  609    ].
  610prolog_message(ignored_weak_import(Into, From:PI)) -->
  611    [ 'Local definition of ~p overrides weak import from ~q'-
  612      [Into:PI, From]
  613    ].
  614prolog_message(undefined_export(Module, PI)) -->
  615    [ 'Exported procedure ~q:~q is not defined'-[Module, PI] ].
  616prolog_message(no_exported_op(Module, Op)) -->
  617    [ 'Operator ~q:~q is not exported (still defined)'-[Module, Op] ].
  618prolog_message(discontiguous((-)/2,_)) -->
  619    prolog_message(minus_in_identifier).
  620prolog_message(discontiguous(Proc,Current)) -->
  621    [ 'Clauses of ', ansi(code, '~p', [Proc]),
  622      ' are not together in the source-file', nl ],
  623    current_definition(Proc, 'Earlier definition at '),
  624    [ 'Current predicate: ', ansi(code, '~p', [Current]), nl,
  625      'Use ', ansi(code, ':- discontiguous ~p.', [Proc]),
  626      ' to suppress this message'
  627    ].
  628prolog_message(decl_no_effect(Goal)) -->
  629    [ 'Deprecated declaration has no effect: ~p'-[Goal] ].
  630prolog_message(load_file(start(Level, File))) -->
  631    [ '~|~t~*+Loading '-[Level] ],
  632    load_file(File),
  633    [ ' ...' ].
  634prolog_message(include_file(start(Level, File))) -->
  635    [ '~|~t~*+include '-[Level] ],
  636    load_file(File),
  637    [ ' ...' ].
  638prolog_message(include_file(done(Level, File))) -->
  639    [ '~|~t~*+included '-[Level] ],
  640    load_file(File).
  641prolog_message(load_file(done(Level, File, Action, Module, Time, Clauses))) -->
  642    [ '~|~t~*+'-[Level] ],
  643    load_file(File),
  644    [ ' ~w'-[Action] ],
  645    load_module(Module),
  646    [ ' ~2f sec, ~D clauses'-[Time, Clauses] ].
  647prolog_message(dwim_undefined(Goal, Alternatives)) -->
  648    { goal_to_predicate_indicator(Goal, Pred)
  649    },
  650    [ 'Unknown procedure: ~q'-[Pred], nl,
  651      '    However, there are definitions for:', nl
  652    ],
  653    dwim_message(Alternatives).
  654prolog_message(dwim_correct(Into)) -->
  655    [ 'Correct to: ~q? '-[Into], flush ].
  656prolog_message(error(loop_error(Spec), file_search(Used))) -->
  657    [ 'File search: too many levels of indirections on: ~p'-[Spec], nl,
  658      '    Used alias expansions:', nl
  659    ],
  660    used_search(Used).
  661prolog_message(minus_in_identifier) -->
  662    [ 'The "-" character should not be used to seperate words in an', nl,
  663      'identifier.  Check the SWI-Prolog FAQ for details.'
  664    ].
  665prolog_message(qlf(removed_after_error(File))) -->
  666    [ 'Removed incomplete QLF file ~w'-[File] ].
  667prolog_message(qlf(recompile(Spec,_Pl,_Qlf,Reason))) -->
  668    [ '~p: recompiling QLF file'-[Spec] ],
  669    qlf_recompile_reason(Reason).
  670prolog_message(qlf(can_not_recompile(Spec,QlfFile,_Reason))) -->
  671    [ '~p: can not recompile "~w" (access denied)'-[Spec, QlfFile], nl,
  672      '\tLoading from source'-[]
  673    ].
  674prolog_message(qlf(system_lib_out_of_date(Spec,QlfFile))) -->
  675    [ '~p: can not recompile "~w" (access denied)'-[Spec, QlfFile], nl,
  676      '\tLoading QlfFile'-[]
  677    ].
  678prolog_message(redefine_module(Module, OldFile, File)) -->
  679    [ 'Module "~q" already loaded from ~w.'-[Module, OldFile], nl,
  680      'Wipe and reload from ~w? '-[File], flush
  681    ].
  682prolog_message(redefine_module_reply) -->
  683    [ 'Please answer y(es), n(o) or a(bort)' ].
  684prolog_message(reloaded_in_module(Absolute, OldContext, LM)) -->
  685    [ '~w was previously loaded in module ~w'-[Absolute, OldContext], nl,
  686      '\tnow it is reloaded into module ~w'-[LM] ].
  687prolog_message(expected_layout(Expected, Pos)) -->
  688    [ 'Layout data: expected ~w, found: ~p'-[Expected, Pos] ].
  689
  690defined_definition(Message, Spec) -->
  691    { strip_module(user:Spec, M, Name/Arity),
  692      functor(Head, Name, Arity),
  693      predicate_property(M:Head, file(File)),
  694      predicate_property(M:Head, line_count(Line))
  695    },
  696    !,
  697    [ nl, '~w at ~w:~d'-[Message, File,Line] ].
  698defined_definition(_, _) --> [].
  699
  700used_search([]) -->
  701    [].
  702used_search([Alias=Expanded|T]) -->
  703    [ '        file_search_path(~p, ~p)'-[Alias, Expanded], nl ],
  704    used_search(T).
  705
  706load_file(file(Spec, _Path)) -->
  707    (   {atomic(Spec)}
  708    ->  [ '~w'-[Spec] ]
  709    ;   [ '~p'-[Spec] ]
  710    ).
  711%load_file(file(_, Path)) -->
  712%       [ '~w'-[Path] ].
  713
  714load_module(user) --> !.
  715load_module(system) --> !.
  716load_module(Module) -->
  717    [ ' into ~w'-[Module] ].
  718
  719goal_to_predicate_indicator(Goal, PI) :-
  720    strip_module(Goal, Module, Head),
  721    callable_name_arity(Head, Name, Arity),
  722    user_predicate_indicator(Module:Name/Arity, PI).
  723
  724callable_name_arity(Goal, Name, Arity) :-
  725    compound(Goal),
  726    !,
  727    compound_name_arity(Goal, Name, Arity).
  728callable_name_arity(Goal, Goal, 0) :-
  729    atom(Goal).
  730
  731user_predicate_indicator(Module:PI, PI) :-
  732    hidden_module(Module),
  733    !.
  734user_predicate_indicator(PI, PI).
  735
  736hidden_module(user) :- !.
  737hidden_module(system) :- !.
  738hidden_module(M) :-
  739    sub_atom(M, 0, _, _, $).
  740
  741current_definition(Proc, Prefix) -->
  742    { pi_head(Proc, Head),
  743      predicate_property(Head, file(File)),
  744      predicate_property(Head, line_count(Line))
  745    },
  746    [ '~w'-[Prefix], '~w:~d'-[File,Line], nl ].
  747current_definition(_, _) --> [].
  748
  749pi_head(Module:Name/Arity, Module:Head) :-
  750    !,
  751    atom(Module), atom(Name), integer(Arity),
  752    functor(Head, Name, Arity).
  753pi_head(Name/Arity, user:Head) :-
  754    atom(Name), integer(Arity),
  755    functor(Head, Name, Arity).
  756
  757qlf_recompile_reason(old) -->
  758    !,
  759    [ ' (out of date)'-[] ].
  760qlf_recompile_reason(_) -->
  761    [ ' (incompatible with current Prolog version)'-[] ].
  762
  763prolog_message(file_search(cache(Spec, _Cond), Path)) -->
  764    [ 'File search: ~p --> ~p (cache)'-[Spec, Path] ].
  765prolog_message(file_search(found(Spec, Cond), Path)) -->
  766    [ 'File search: ~p --> ~p OK ~p'-[Spec, Path, Cond] ].
  767prolog_message(file_search(tried(Spec, Cond), Path)) -->
  768    [ 'File search: ~p --> ~p NO ~p'-[Spec, Path, Cond] ].
  769
  770                 /*******************************
  771                 *              GC              *
  772                 *******************************/
  773
  774prolog_message(agc(start)) -->
  775    thread_context,
  776    [ 'AGC: ', flush ].
  777prolog_message(agc(done(Collected, Remaining, Time))) -->
  778    [ at_same_line,
  779      'reclaimed ~D atoms in ~3f sec. (remaining: ~D)'-
  780      [Collected, Time, Remaining]
  781    ].
  782prolog_message(cgc(start)) -->
  783    thread_context,
  784    [ 'CGC: ', flush ].
  785prolog_message(cgc(done(CollectedClauses, _CollectedBytes,
  786                        RemainingBytes, Time))) -->
  787    [ at_same_line,
  788      'reclaimed ~D clauses in ~3f sec. (pending: ~D bytes)'-
  789      [CollectedClauses, Time, RemainingBytes]
  790    ].
  791
  792		 /*******************************
  793		 *        STACK OVERFLOW	*
  794		 *******************************/
  795
  796out_of_stack(Context) -->
  797    { human_stack_size(Context.localused,   Local),
  798      human_stack_size(Context.globalused,  Global),
  799      human_stack_size(Context.trailused,   Trail),
  800      human_stack_size(Context.stack_limit, Limit),
  801      LCO is (100*(Context.depth - Context.environments))/Context.depth
  802    },
  803    [ 'Stack limit (~s) exceeded'-[Limit], nl,
  804      '  Stack sizes: local: ~s, global: ~s, trail: ~s'-[Local,Global,Trail], nl,
  805      '  Stack depth: ~D, last-call: ~0f%, Choice points: ~D'-
  806         [Context.depth, LCO, Context.choicepoints], nl
  807    ],
  808    overflow_reason(Context, Resolve),
  809    resolve_overflow(Resolve).
  810
  811human_stack_size(Size, String) :-
  812    Size < 100,
  813    format(string(String), '~dKb', [Size]).
  814human_stack_size(Size, String) :-
  815    Size < 100 000,
  816    Value is Size / 1024,
  817    format(string(String), '~1fMb', [Value]).
  818human_stack_size(Size, String) :-
  819    Value is Size / (1024*1024),
  820    format(string(String), '~1fGb', [Value]).
  821
  822overflow_reason(Context, fix) -->
  823    show_non_termination(Context),
  824    !.
  825overflow_reason(Context, enlarge) -->
  826    { Stack = Context.get(stack) },
  827    !,
  828    [ '  In:'-[], nl ],
  829    stack(Stack).
  830overflow_reason(_Context, enlarge) -->
  831    [ '  Insufficient global stack'-[] ].
  832
  833show_non_termination(Context) -->
  834    (   { Stack = Context.get(cycle) }
  835    ->  [ '  Probable infinite recursion (cycle):'-[], nl ]
  836    ;   { Stack = Context.get(non_terminating) }
  837    ->  [ '  Possible non-terminating recursion:'-[], nl ]
  838    ),
  839    stack(Stack).
  840
  841stack([]) --> [].
  842stack([frame(Depth, M:Goal, _)|T]) -->
  843    [ '    [~D] ~q:'-[Depth, M] ],
  844    stack_goal(Goal),
  845    [ nl ],
  846    stack(T).
  847
  848stack_goal(Goal) -->
  849    { compound(Goal),
  850      !,
  851      compound_name_arity(Goal, Name, Arity)
  852    },
  853    [ '~q('-[Name] ],
  854    stack_goal_args(1, Arity, Goal),
  855    [ ')'-[] ].
  856stack_goal(Goal) -->
  857    [ '~q'-[Goal] ].
  858
  859stack_goal_args(I, Arity, Goal) -->
  860    { I =< Arity,
  861      !,
  862      arg(I, Goal, A),
  863      I2 is I + 1
  864    },
  865    stack_goal_arg(A),
  866    (   { I2 =< Arity }
  867    ->  [ ', '-[] ],
  868        stack_goal_args(I2, Arity, Goal)
  869    ;   []
  870    ).
  871stack_goal_args(_, _, _) -->
  872    [].
  873
  874stack_goal_arg(A) -->
  875    { nonvar(A),
  876      A = [Len|T],
  877      !
  878    },
  879    (   {Len == cyclic_term}
  880    ->  [ '[cyclic list]'-[] ]
  881    ;   {T == []}
  882    ->  [ '[length:~D]'-[Len] ]
  883    ;   [ '[length:~D|~p]'-[Len, T] ]
  884    ).
  885stack_goal_arg(A) -->
  886    { nonvar(A),
  887      A = _/_,
  888      !
  889    },
  890    [ '<compound ~p>'-[A] ].
  891stack_goal_arg(A) -->
  892    [ '~p'-[A] ].
  893
  894resolve_overflow(fix) -->
  895    [].
  896resolve_overflow(enlarge) -->
  897    { current_prolog_flag(stack_limit, LimitBytes),
  898      NewLimit is LimitBytes * 2
  899    },
  900    [ nl,
  901      'Use the --stack_limit=size[KMG] command line option or'-[], nl,
  902      '?- set_prolog_flag(stack_limit, ~I). to double the limit.'-[NewLimit]
  903    ].
  904
  905
  906                 /*******************************
  907                 *        MAKE/AUTOLOAD         *
  908                 *******************************/
  909
  910prolog_message(make(reload(Files))) -->
  911    { length(Files, N)
  912    },
  913    [ 'Make: reloading ~D files'-[N] ].
  914prolog_message(make(done(_Files))) -->
  915    [ 'Make: finished' ].
  916prolog_message(make(library_index(Dir))) -->
  917    [ 'Updating index for library ~w'-[Dir] ].
  918prolog_message(autoload(Pred, File)) -->
  919    thread_context,
  920    [ 'autoloading ~p from ~w'-[Pred, File] ].
  921prolog_message(autoload(read_index(Dir))) -->
  922    [ 'Loading autoload index for ~w'-[Dir] ].
  923
  924
  925                 /*******************************
  926                 *       COMPILER WARNINGS      *
  927                 *******************************/
  928
  929% print warnings about dubious code raised by the compiler.
  930% TBD: pass in PC to produce exact error locations.
  931
  932prolog_message(compiler_warnings(Clause, Warnings0)) -->
  933    {   print_goal_options(DefOptions),
  934        (   prolog_load_context(variable_names, VarNames)
  935        ->  warnings_with_named_vars(Warnings0, VarNames, Warnings),
  936            Options = [variable_names(VarNames)|DefOptions]
  937        ;   Options = DefOptions,
  938            Warnings = Warnings0
  939        )
  940    },
  941    compiler_warnings(Warnings, Clause, Options).
  942
  943warnings_with_named_vars([], _, []).
  944warnings_with_named_vars([H|T0], VarNames, [H|T]) :-
  945    term_variables(H, Vars),
  946    '$member'(V1, Vars),
  947    '$member'(_=V2, VarNames),
  948    V1 == V2,
  949    !,
  950    warnings_with_named_vars(T0, VarNames, T).
  951warnings_with_named_vars([_|T0], VarNames, T) :-
  952    warnings_with_named_vars(T0, VarNames, T).
  953
  954
  955compiler_warnings([], _, _) --> [].
  956compiler_warnings([H|T], Clause, Options) -->
  957    (   compiler_warning(H, Clause, Options)
  958    ->  []
  959    ;   [ 'Unknown compiler warning: ~W'-[H,Options] ]
  960    ),
  961    (   {T==[]}
  962    ->  []
  963    ;   [nl]
  964    ),
  965    compiler_warnings(T, Clause, Options).
  966
  967compiler_warning(eq_vv(A,B), _Clause, Options) -->
  968    (   { A == B }
  969    ->  [ 'Test is always true: ~W'-[A==B, Options] ]
  970    ;   [ 'Test is always false: ~W'-[A==B, Options] ]
  971    ).
  972compiler_warning(eq_singleton(A,B), _Clause, Options) -->
  973    [ 'Test is always false: ~W'-[A==B, Options] ].
  974compiler_warning(neq_vv(A,B), _Clause, Options) -->
  975    (   { A \== B }
  976    ->  [ 'Test is always true: ~W'-[A\==B, Options] ]
  977    ;   [ 'Test is always false: ~W'-[A\==B, Options] ]
  978    ).
  979compiler_warning(neq_singleton(A,B), _Clause, Options) -->
  980    [ 'Test is always true: ~W'-[A\==B, Options] ].
  981compiler_warning(unify_singleton(A,B), _Clause, Options) -->
  982    [ 'Unified variable is not used: ~W'-[A=B, Options] ].
  983compiler_warning(always(Bool, Pred, Arg), _Clause, Options) -->
  984    { Goal =.. [Pred,Arg] },
  985    [ 'Test is always ~w: ~W'-[Bool, Goal, Options] ].
  986compiler_warning(unbalanced_var(V), _Clause, Options) -->
  987    [ 'Variable not introduced in all branches: ~W'-[V, Options] ].
  988compiler_warning(branch_singleton(V), _Clause, Options) -->
  989    [ 'Singleton variable in branch: ~W'-[V, Options] ].
  990compiler_warning(negation_singleton(V), _Clause, Options) -->
  991    [ 'Singleton variable in \\+: ~W'-[V, Options] ].
  992compiler_warning(multiton(V), _Clause, Options) -->
  993    [ 'Singleton-marked variable appears more than once: ~W'-[V, Options] ].
  994
  995print_goal_options(
  996    [ quoted(true),
  997      portray(true)
  998    ]).
  999
 1000
 1001                 /*******************************
 1002                 *      TOPLEVEL MESSAGES       *
 1003                 *******************************/
 1004
 1005prolog_message(version) -->
 1006    { current_prolog_flag(version_git, Version) },
 1007    !,
 1008    [ '~w'-[Version] ].
 1009prolog_message(version) -->
 1010    { current_prolog_flag(version_data, swi(Major,Minor,Patch,Options))
 1011    },
 1012    (   { memberchk(tag(Tag), Options) }
 1013    ->  [ '~w.~w.~w-~w'-[Major, Minor, Patch, Tag] ]
 1014    ;   [ '~w.~w.~w'-[Major, Minor, Patch] ]
 1015    ).
 1016prolog_message(address_bits) -->
 1017    { current_prolog_flag(address_bits, Bits)
 1018    },
 1019    !,
 1020    [ '~d bits, '-[Bits] ].
 1021prolog_message(threads) -->
 1022    { current_prolog_flag(threads, true)
 1023    },
 1024    !,
 1025    [ 'threaded, ' ].
 1026prolog_message(threads) -->
 1027    [].
 1028prolog_message(copyright) -->
 1029    [ 'SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.', nl,
 1030      'Please run ?- license. for legal details.'
 1031    ].
 1032prolog_message(user_versions) -->
 1033    (   { findall(Msg, prolog:version_msg(Msg), Msgs),
 1034          Msgs \== []
 1035        }
 1036    ->  [nl],
 1037        user_version_messages(Msgs)
 1038    ;   []
 1039    ).
 1040prolog_message(documentaton) -->
 1041    [ 'For online help and background, visit http://www.swi-prolog.org', nl,
 1042      'For built-in help, use ?- help(Topic). or ?- apropos(Word).'
 1043    ].
 1044prolog_message(welcome) -->
 1045    [ 'Welcome to SWI-Prolog (' ],
 1046    prolog_message(threads),
 1047    prolog_message(address_bits),
 1048    ['version ' ],
 1049    prolog_message(version),
 1050    [ ')', nl ],
 1051    prolog_message(copyright),
 1052    [ nl ],
 1053    prolog_message(user_versions),
 1054    [ nl ],
 1055    prolog_message(documentaton),
 1056    [ nl, nl ].
 1057prolog_message(about) -->
 1058    [ 'SWI-Prolog version (' ],
 1059    prolog_message(threads),
 1060    prolog_message(address_bits),
 1061    ['version ' ],
 1062    prolog_message(version),
 1063    [ ')', nl ],
 1064    prolog_message(copyright).
 1065prolog_message(halt) -->
 1066    [ 'halt' ].
 1067prolog_message(break(begin, Level)) -->
 1068    [ 'Break level ~d'-[Level] ].
 1069prolog_message(break(end, Level)) -->
 1070    [ 'Exit break level ~d'-[Level] ].
 1071prolog_message(var_query(_)) -->
 1072    [ '... 1,000,000 ............ 10,000,000 years later', nl, nl,
 1073      '~t~8|>> 42 << (last release gives the question)'
 1074    ].
 1075prolog_message(close_on_abort(Stream)) -->
 1076    [ 'Abort: closed stream ~p'-[Stream] ].
 1077prolog_message(cancel_halt(Reason)) -->
 1078    [ 'Halt cancelled: ~p'-[Reason] ].
 1079
 1080prolog_message(query(QueryResult)) -->
 1081    query_result(QueryResult).
 1082
 1083query_result(no) -->            % failure
 1084    [ ansi([bold,fg(red)], 'false.', []) ],
 1085    extra_line.
 1086query_result(yes(true, [])) -->      % prompt_alternatives_on: groundness
 1087    !,
 1088    [ ansi(bold, 'true.', []) ],
 1089    extra_line.
 1090query_result(yes(Delays, Residuals)) -->
 1091    result([], Delays, Residuals),
 1092    extra_line.
 1093query_result(done) -->          % user typed <CR>
 1094    extra_line.
 1095query_result(yes(Bindings, Delays, Residuals)) -->
 1096    result(Bindings, Delays, Residuals),
 1097    prompt(yes, Bindings, Delays, Residuals).
 1098query_result(more(Bindings, Delays, Residuals)) -->
 1099    result(Bindings, Delays, Residuals),
 1100    prompt(more, Bindings, Delays, Residuals).
 1101query_result(help) -->
 1102    [ nl, 'Actions:'-[], nl, nl,
 1103      '; (n, r, space, TAB): redo    t:          trace & redo'-[], nl,
 1104      'b:                    break   c (a, RET): exit'-[], nl,
 1105      'w:                    write   p           print'-[], nl,
 1106      'h (?):                help'-[],
 1107      nl, nl
 1108    ].
 1109query_result(action) -->
 1110    [ 'Action? '-[], flush ].
 1111query_result(confirm) -->
 1112    [ 'Please answer \'y\' or \'n\'? '-[], flush ].
 1113query_result(eof) -->
 1114    [ nl ].
 1115query_result(toplevel_open_line) -->
 1116    [].
 1117
 1118prompt(Answer, [], true, []-[]) -->
 1119    !,
 1120    prompt(Answer, empty).
 1121prompt(Answer, _, _, _) -->
 1122    !,
 1123    prompt(Answer, non_empty).
 1124
 1125prompt(yes, empty) -->
 1126    !,
 1127    [ ansi(bold, 'true.', []) ],
 1128    extra_line.
 1129prompt(yes, _) -->
 1130    !,
 1131    [ full_stop ],
 1132    extra_line.
 1133prompt(more, empty) -->
 1134    !,
 1135    [ ansi(bold, 'true ', []), flush ].
 1136prompt(more, _) -->
 1137    !,
 1138    [ ' '-[], flush ].
 1139
 1140result(Bindings, Delays, Residuals) -->
 1141    { current_prolog_flag(answer_write_options, Options0),
 1142      Options = [partial(true)|Options0],
 1143      GOptions = [priority(999)|Options0]
 1144    },
 1145    wfs_residual_program(Delays, GOptions),
 1146    bindings(Bindings, [priority(699)|Options]),
 1147    (   {Residuals == []-[]}
 1148    ->  bind_delays_sep(Bindings, Delays),
 1149        delays(Delays, GOptions)
 1150    ;   bind_res_sep(Bindings, Residuals),
 1151        residuals(Residuals, GOptions),
 1152        (   {Delays == true}
 1153        ->  []
 1154        ;   [','-[], nl],
 1155            delays(Delays, GOptions)
 1156        )
 1157    ).
 1158
 1159bindings([], _) -->
 1160    [].
 1161bindings([binding(Names,Skel,Subst)|T], Options) -->
 1162    { '$last'(Names, Name) },
 1163    var_names(Names), value(Name, Skel, Subst, Options),
 1164    (   { T \== [] }
 1165    ->  [ ','-[], nl ],
 1166        bindings(T, Options)
 1167    ;   []
 1168    ).
 1169
 1170var_names([Name]) -->
 1171    !,
 1172    [ '~w = '-[Name] ].
 1173var_names([Name1,Name2|T]) -->
 1174    !,
 1175    [ '~w = ~w, '-[Name1, Name2] ],
 1176    var_names([Name2|T]).
 1177
 1178
 1179value(Name, Skel, Subst, Options) -->
 1180    (   { var(Skel), Subst = [Skel=S] }
 1181    ->  { Skel = '$VAR'(Name) },
 1182        [ '~W'-[S, Options] ]
 1183    ;   [ '~W'-[Skel, Options] ],
 1184        substitution(Subst, Options)
 1185    ).
 1186
 1187substitution([], _) --> !.
 1188substitution([N=V|T], Options) -->
 1189    [ ', ', ansi(fg(green), '% where', []), nl,
 1190      '    ~w = ~W'-[N,V,Options] ],
 1191    substitutions(T, Options).
 1192
 1193substitutions([], _) --> [].
 1194substitutions([N=V|T], Options) -->
 1195    [ ','-[], nl, '    ~w = ~W'-[N,V,Options] ],
 1196    substitutions(T, Options).
 1197
 1198
 1199residuals(Normal-Hidden, Options) -->
 1200    residuals1(Normal, Options),
 1201    bind_res_sep(Normal, Hidden),
 1202    (   {Hidden == []}
 1203    ->  []
 1204    ;   [ansi(fg(green), '% with pending residual goals', []), nl]
 1205    ),
 1206    residuals1(Hidden, Options).
 1207
 1208residuals1([], _) -->
 1209    [].
 1210residuals1([G|Gs], Options) -->
 1211    (   { Gs \== [] }
 1212    ->  [ '~W,'-[G, Options], nl ],
 1213        residuals1(Gs, Options)
 1214    ;   [ '~W'-[G, Options] ]
 1215    ).
 1216
 1217wfs_residual_program(true, _Options) -->
 1218    !.
 1219wfs_residual_program(Goal, _Options) -->
 1220    { current_prolog_flag(toplevel_list_wfs_residual_program, true),
 1221      '$current_typein_module'(TypeIn),
 1222      (   current_predicate(delays_residual_program/2)
 1223      ->  true
 1224      ;   use_module(library(wfs), [delays_residual_program/2])
 1225      ),
 1226      delays_residual_program(TypeIn:Goal, TypeIn:Program),
 1227      Program \== []
 1228    },
 1229    !,
 1230    [ ansi(fg(green), '% WFS residual program', []), nl ],
 1231    [ ansi(fg(cyan), '~@', ['$messages':list_clauses(Program)]) ].
 1232wfs_residual_program(_, _) --> [].
 1233
 1234delays(true, _Options) -->
 1235    !.
 1236delays(Goal, Options) -->
 1237    { current_prolog_flag(toplevel_list_wfs_residual_program, true)
 1238    },
 1239    !,
 1240    [ ansi([bold], '~W', [Goal, Options]) ].
 1241delays(_, _Options) -->
 1242    [ ansi([bold,fg(cyan)], undefined, []) ].
 1243
 1244:- public list_clauses/1. 1245
 1246list_clauses([]).
 1247list_clauses([H|T]) :-
 1248    portray_clause(user_output, H, [indent(4)]),
 1249    list_clauses(T).
 1250
 1251bind_res_sep(_, []) --> !.
 1252bind_res_sep(_, []-[]) --> !.
 1253bind_res_sep([], _) --> !.
 1254bind_res_sep(_, _) --> [','-[], nl].
 1255
 1256bind_delays_sep([], _) --> !.
 1257bind_delays_sep(_, true) --> !.
 1258bind_delays_sep(_, _) --> [','-[], nl].
 1259
 1260extra_line -->
 1261    { current_prolog_flag(toplevel_extra_white_line, true) },
 1262    !,
 1263    ['~N'-[]].
 1264extra_line -->
 1265    [].
 1266
 1267prolog_message(if_tty(Message)) -->
 1268    (   {current_prolog_flag(tty_control, true)}
 1269    ->  [ at_same_line | Message ]
 1270    ;   []
 1271    ).
 1272prolog_message(halt(Reason)) -->
 1273    [ '~w: halt'-[Reason] ].
 1274prolog_message(no_action(Char)) -->
 1275    [ 'Unknown action: ~c (h for help)'-[Char], nl ].
 1276
 1277prolog_message(history(help(Show, Help))) -->
 1278    [ 'History Commands:', nl,
 1279      '    !!.              Repeat last query', nl,
 1280      '    !nr.             Repeat query numbered <nr>', nl,
 1281      '    !str.            Repeat last query starting with <str>', nl,
 1282      '    !?str.           Repeat last query holding <str>', nl,
 1283      '    ^old^new.        Substitute <old> into <new> of last query', nl,
 1284      '    !nr^old^new.     Substitute in query numbered <nr>', nl,
 1285      '    !str^old^new.    Substitute in query starting with <str>', nl,
 1286      '    !?str^old^new.   Substitute in query holding <str>', nl,
 1287      '    ~w.~21|Show history list'-[Show], nl,
 1288      '    ~w.~21|Show this list'-[Help], nl, nl
 1289    ].
 1290prolog_message(history(no_event)) -->
 1291    [ '! No such event' ].
 1292prolog_message(history(bad_substitution)) -->
 1293    [ '! Bad substitution' ].
 1294prolog_message(history(expanded(Event))) -->
 1295    [ '~w.'-[Event] ].
 1296prolog_message(history(history(Events))) -->
 1297    history_events(Events).
 1298
 1299history_events([]) -->
 1300    [].
 1301history_events([Nr/Event|T]) -->
 1302    [ '~t~w   ~8|~W~W'-[ Nr,
 1303                         Event, [partial(true)],
 1304                         '.', [partial(true)]
 1305                       ],
 1306      nl
 1307    ],
 1308    history_events(T).
 1309
 1310
 1311user_version_messages([]) --> [].
 1312user_version_messages([H|T]) -->
 1313    user_version_message(H),
 1314    user_version_messages(T).
 user_version_message(+Term)
 1318user_version_message(Term) -->
 1319    translate_message2(Term), !, [nl].
 1320user_version_message(Atom) -->
 1321    [ '~w'-[Atom], nl ].
 1322
 1323
 1324                 /*******************************
 1325                 *       DEBUGGER MESSAGES      *
 1326                 *******************************/
 1327
 1328prolog_message(spy(Head)) -->
 1329    { goal_to_predicate_indicator(Head, Pred)
 1330    },
 1331    [ 'Spy point on ~p'-[Pred] ].
 1332prolog_message(nospy(Head)) -->
 1333    { goal_to_predicate_indicator(Head, Pred)
 1334    },
 1335    [ 'Spy point removed from ~p'-[Pred] ].
 1336prolog_message(trace_mode(Bool)) -->
 1337    [ 'Trace mode switched to ~w'-[Bool] ].
 1338prolog_message(debug_mode(Bool)) -->
 1339    [ 'Debug mode switched to ~w'-[Bool] ].
 1340prolog_message(debugging(Bool)) -->
 1341    [ 'Debug mode is ~w'-[Bool] ].
 1342prolog_message(spying([])) -->
 1343    !,
 1344    [ 'No spy points' ].
 1345prolog_message(spying(Heads)) -->
 1346    [ 'Spy points (see spy/1) on:', nl ],
 1347    predicate_list(Heads).
 1348prolog_message(trace(Head, [])) -->
 1349    !,
 1350    { goal_to_predicate_indicator(Head, Pred)
 1351    },
 1352    [ '        ~p: Not tracing'-[Pred], nl].
 1353prolog_message(trace(Head, Ports)) -->
 1354    { goal_to_predicate_indicator(Head, Pred)
 1355    },
 1356    [ '        ~p: ~w'-[Pred, Ports], nl].
 1357prolog_message(tracing([])) -->
 1358    !,
 1359    [ 'No traced predicates (see trace/1)' ].
 1360prolog_message(tracing(Heads)) -->
 1361    [ 'Trace points (see trace/1) on:', nl ],
 1362    tracing_list(Heads).
 1363
 1364predicate_list([]) -->                  % TBD: Share with dwim, etc.
 1365    [].
 1366predicate_list([H|T]) -->
 1367    { goal_to_predicate_indicator(H, Pred)
 1368    },
 1369    [ '        ~p'-[Pred], nl],
 1370    predicate_list(T).
 1371
 1372tracing_list([]) -->
 1373    [].
 1374tracing_list([trace(Head, Ports)|T]) -->
 1375    translate_message(trace(Head, Ports)),
 1376    tracing_list(T).
 1377
 1378prolog_message(frame(Frame, backtrace, _PC)) -->
 1379    !,
 1380    { prolog_frame_attribute(Frame, level, Level)
 1381    },
 1382    [ ansi(bold, '~t[~D] ~10|', [Level]) ],
 1383    frame_context(Frame),
 1384    frame_goal(Frame).
 1385prolog_message(frame(Frame, choice, PC)) -->
 1386    !,
 1387    prolog_message(frame(Frame, backtrace, PC)).
 1388prolog_message(frame(_, cut_call, _)) --> !, [].
 1389prolog_message(frame(Goal, trace(Port))) -->
 1390    !,
 1391    [ ' T ' ],
 1392    port(Port),
 1393    goal(Goal).
 1394prolog_message(frame(Frame, Port, _PC)) -->
 1395    frame_flags(Frame),
 1396    port(Port),
 1397    frame_level(Frame),
 1398    frame_context(Frame),
 1399    frame_depth_limit(Port, Frame),
 1400    frame_goal(Frame),
 1401    [ flush ].
 1402
 1403frame_goal(Frame) -->
 1404    { prolog_frame_attribute(Frame, goal, Goal)
 1405    },
 1406    goal(Goal).
 1407
 1408goal(Goal0) -->
 1409    { clean_goal(Goal0, Goal),
 1410      current_prolog_flag(debugger_write_options, Options)
 1411    },
 1412    [ '~W'-[Goal, Options] ].
 1413
 1414frame_level(Frame) -->
 1415    { prolog_frame_attribute(Frame, level, Level)
 1416    },
 1417    [ '(~D) '-[Level] ].
 1418
 1419frame_context(Frame) -->
 1420    (   { current_prolog_flag(debugger_show_context, true),
 1421          prolog_frame_attribute(Frame, context_module, Context)
 1422        }
 1423    ->  [ '[~w] '-[Context] ]
 1424    ;   []
 1425    ).
 1426
 1427frame_depth_limit(fail, Frame) -->
 1428    { prolog_frame_attribute(Frame, depth_limit_exceeded, true)
 1429    },
 1430    !,
 1431    [ '[depth-limit exceeded] ' ].
 1432frame_depth_limit(_, _) -->
 1433    [].
 1434
 1435frame_flags(Frame) -->
 1436    { prolog_frame_attribute(Frame, goal, Goal),
 1437      (   predicate_property(Goal, transparent)
 1438      ->  T = '^'
 1439      ;   T = ' '
 1440      ),
 1441      (   predicate_property(Goal, spying)
 1442      ->  S = '*'
 1443      ;   S = ' '
 1444      )
 1445    },
 1446    [ '~w~w '-[T, S] ].
 1447
 1448port(Port) -->
 1449    { port_name(Port, Colour, Name)
 1450    },
 1451    !,
 1452    [ ansi([bold,fg(Colour)], '~w: ', [Name]) ].
 1453
 1454port_name(call,      green,   'Call').
 1455port_name(exit,      green,   'Exit').
 1456port_name(fail,      red,     'Fail').
 1457port_name(redo,      yellow,  'Redo').
 1458port_name(unify,     blue,    'Unify').
 1459port_name(exception, magenta, 'Exception').
 1460
 1461clean_goal(M:Goal, Goal) :-
 1462    hidden_module(M),
 1463    !.
 1464clean_goal(M:Goal, Goal) :-
 1465    predicate_property(M:Goal, built_in),
 1466    !.
 1467clean_goal(Goal, Goal).
 1468
 1469
 1470                 /*******************************
 1471                 *        COMPATIBILITY         *
 1472                 *******************************/
 1473
 1474prolog_message(compatibility(renamed(Old, New))) -->
 1475    [ 'The predicate ~p has been renamed to ~p.'-[Old, New], nl,
 1476      'Please update your sources for compatibility with future versions.'
 1477    ].
 1478
 1479
 1480                 /*******************************
 1481                 *            THREADS           *
 1482                 *******************************/
 1483
 1484prolog_message(abnormal_thread_completion(Goal, exception(Ex))) -->
 1485    !,
 1486    [ 'Thread running "~p" died on exception: '-[Goal] ],
 1487    translate_message(Ex).
 1488prolog_message(abnormal_thread_completion(Goal, fail)) -->
 1489    [ 'Thread running "~p" died due to failure'-[Goal] ].
 1490prolog_message(threads_not_died(Running)) -->
 1491    [ 'The following threads wouldn\'t die: ~p'-[Running] ].
 1492
 1493
 1494                 /*******************************
 1495                 *             PACKS            *
 1496                 *******************************/
 1497
 1498prolog_message(pack(attached(Pack, BaseDir))) -->
 1499    [ 'Attached package ~w at ~q'-[Pack, BaseDir] ].
 1500prolog_message(pack(duplicate(Entry, OldDir, Dir))) -->
 1501    [ 'Package ~w already attached at ~q.'-[Entry,OldDir], nl,
 1502      '\tIgnoring version from ~q'- [Entry, OldDir, Dir]
 1503    ].
 1504prolog_message(pack(no_arch(Entry, Arch))) -->
 1505    [ 'Package ~w: no binary for architecture ~w'-[Entry, Arch] ].
 1506
 1507                 /*******************************
 1508                 *             MISC             *
 1509                 *******************************/
 1510
 1511prolog_message(null_byte_in_path(Component)) -->
 1512    [ '0-byte in PATH component: ~p (skipped directory)'-[Component] ].
 1513prolog_message(invalid_tmp_dir(Dir, Reason)) -->
 1514    [ 'Cannot use ~p as temporary file directory: ~w'-[Dir, Reason] ].
 1515prolog_message(ambiguous_stream_pair(Pair)) -->
 1516    [ 'Ambiguous operation on stream pair ~p'-[Pair] ].
 1517
 1518env(Name) -->
 1519    { current_prolog_flag(windows, true) },
 1520    [ '%~w%'-[Name] ].
 1521env(Name) -->
 1522    [ '$~w'-[Name] ].
 1523
 1524		 /*******************************
 1525		 *          DEPRECATED		*
 1526		 *******************************/
 1527
 1528deprecated(set_prolog_stack(_Stack,limit)) -->
 1529    [ 'set_prolog_stack/2: limit(Size) sets the combined limit.'-[], nl,
 1530      'See http://www.swi-prolog.org/changes/stack-limit.html'
 1531    ].
 1532
 1533
 1534                 /*******************************
 1535                 *      PRINTING MESSAGES       *
 1536                 *******************************/
 1537
 1538:- multifile
 1539    user:message_hook/3,
 1540    prolog:message_prefix_hook/2. 1541:- dynamic
 1542    user:message_hook/3,
 1543    prolog:message_prefix_hook/2. 1544:- thread_local
 1545    user:thread_message_hook/3.
 print_message(+Kind, +Term)
Print an error message using a term as generated by the exception system.
 1552print_message(Level, Term) :-
 1553    (   must_print(Level, Term)
 1554    ->  (   translate_message(Term, Lines, [])
 1555        ->  (   nonvar(Term),
 1556                (   notrace(user:thread_message_hook(Term, Level, Lines))
 1557                ->  true
 1558                ;   notrace(user:message_hook(Term, Level, Lines))
 1559                )
 1560            ->  true
 1561            ;   print_system_message(Term, Level, Lines)
 1562            )
 1563        )
 1564    ;   true
 1565    ).
 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.
 1574print_system_message(_, silent, _) :- !.
 1575print_system_message(_, informational, _) :-
 1576    current_prolog_flag(verbose, silent),
 1577    !.
 1578print_system_message(_, banner, _) :-
 1579    current_prolog_flag(verbose, silent),
 1580    !.
 1581print_system_message(_, _, []) :- !.
 1582print_system_message(Term, Kind, Lines) :-
 1583    catch(flush_output(user_output), _, true),      % may not exist
 1584    source_location(File, Line),
 1585    Term \= error(syntax_error(_), _),
 1586    msg_property(Kind, location_prefix(File:Line, LocPrefix, LinePrefix)),
 1587    !,
 1588    insert_prefix(Lines, LinePrefix, Ctx, PrefixLines),
 1589    '$append'([ begin(Kind, Ctx),
 1590                LocPrefix,
 1591                nl
 1592              | PrefixLines
 1593              ],
 1594              [ end(Ctx)
 1595              ],
 1596              AllLines),
 1597    msg_property(Kind, stream(Stream)),
 1598    ignore(stream_property(Stream, position(Pos))),
 1599    print_message_lines(Stream, AllLines),
 1600    (   \+ stream_property(Stream, position(Pos)),
 1601        msg_property(Kind, wait(Wait)),
 1602        Wait > 0
 1603    ->  sleep(Wait)
 1604    ;   true
 1605    ).
 1606print_system_message(_, Kind, Lines) :-
 1607    msg_property(Kind, stream(Stream)),
 1608    print_message_lines(Stream, kind(Kind), Lines).
 1609
 1610:- multifile
 1611    user:message_property/2. 1612
 1613msg_property(Kind, Property) :-
 1614    user:message_property(Kind, Property),
 1615    !.
 1616msg_property(Kind, prefix(Prefix)) :-
 1617    msg_prefix(Kind, Prefix),
 1618    !.
 1619msg_property(_, prefix('~N')) :- !.
 1620msg_property(query, stream(user_output)) :- !.
 1621msg_property(_, stream(user_error)) :- !.
 1622msg_property(error,
 1623             location_prefix(File:Line,
 1624                             '~NERROR: ~w:~d:'-[File,Line],
 1625                             '~NERROR:    ')) :- !.
 1626msg_property(warning,
 1627             location_prefix(File:Line,
 1628                             '~NWarning: ~w:~d:'-[File,Line],
 1629                             '~NWarning:    ')) :- !.
 1630msg_property(error,   wait(0.1)) :- !.
 1631
 1632msg_prefix(debug(_), Prefix) :-
 1633    msg_context('~N% ', Prefix).
 1634msg_prefix(warning, Prefix) :-
 1635    msg_context('~NWarning: ', Prefix).
 1636msg_prefix(error, Prefix) :-
 1637    msg_context('~NERROR: ', Prefix).
 1638msg_prefix(informational, '~N% ').
 1639msg_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.

 1653msg_context(Prefix0, Prefix) :-
 1654    current_prolog_flag(message_context, Context),
 1655    is_list(Context),
 1656    !,
 1657    add_message_context(Context, Prefix0, Prefix).
 1658msg_context(Prefix, Prefix).
 1659
 1660add_message_context([], Prefix, Prefix).
 1661add_message_context([H|T], Prefix0, Prefix) :-
 1662    (   add_message_context1(H, Prefix0, Prefix1)
 1663    ->  true
 1664    ;   Prefix1 = Prefix0
 1665    ),
 1666    add_message_context(T, Prefix1, Prefix).
 1667
 1668add_message_context1(Context, Prefix0, Prefix) :-
 1669    prolog:message_prefix_hook(Context, Extra),
 1670    atomics_to_string([Prefix0, Extra, ' '], Prefix).
 1671add_message_context1(time, Prefix0, Prefix) :-
 1672    get_time(Now),
 1673    format_time(string(S), '%T.%3f ', Now),
 1674    string_concat(Prefix0, S, Prefix).
 1675add_message_context1(time(Format), Prefix0, Prefix) :-
 1676    get_time(Now),
 1677    format_time(string(S), Format, Now),
 1678    atomics_to_string([Prefix0, S, ' '], Prefix).
 1679add_message_context1(thread, Prefix0, Prefix) :-
 1680    thread_self(Id0),
 1681    Id0 \== main,
 1682    !,
 1683    (   atom(Id0)
 1684    ->  Id = Id0
 1685    ;   thread_property(Id0, id(Id))
 1686    ),
 1687    format(string(Prefix), '~w[Thread ~w] ', [Prefix0, Id]).
 print_message_lines(+Stream, +PrefixOrKind, +Lines)
Quintus compatibility predicate to print message lines using a prefix.
 1694print_message_lines(Stream, kind(Kind), Lines) :-
 1695    !,
 1696    msg_property(Kind, prefix(Prefix)),
 1697    insert_prefix(Lines, Prefix, Ctx, PrefixLines),
 1698    '$append'([ begin(Kind, Ctx)
 1699              | PrefixLines
 1700              ],
 1701              [ end(Ctx)
 1702              ],
 1703              AllLines),
 1704    print_message_lines(Stream, AllLines).
 1705print_message_lines(Stream, Prefix, Lines) :-
 1706    insert_prefix(Lines, Prefix, _, PrefixLines),
 1707    print_message_lines(Stream, PrefixLines).
 insert_prefix(+Lines, +Prefix, +Ctx, -PrefixedLines)
 1711insert_prefix([at_same_line|Lines0], Prefix, Ctx, Lines) :-
 1712    !,
 1713    prefix_nl(Lines0, Prefix, Ctx, Lines).
 1714insert_prefix(Lines0, Prefix, Ctx, [prefix(Prefix)|Lines]) :-
 1715    prefix_nl(Lines0, Prefix, Ctx, Lines).
 1716
 1717prefix_nl([], _, _, [nl]).
 1718prefix_nl([nl], _, _, [nl]) :- !.
 1719prefix_nl([flush], _, _, [flush]) :- !.
 1720prefix_nl([nl|T0], Prefix, Ctx, [nl, prefix(Prefix)|T]) :-
 1721    !,
 1722    prefix_nl(T0, Prefix, Ctx, T).
 1723prefix_nl([ansi(Attrs,Fmt,Args)|T0], Prefix, Ctx,
 1724          [ansi(Attrs,Fmt,Args,Ctx)|T]) :-
 1725    !,
 1726    prefix_nl(T0, Prefix, Ctx, T).
 1727prefix_nl([H|T0], Prefix, Ctx, [H|T]) :-
 1728    prefix_nl(T0, Prefix, Ctx, T).
 print_message_lines(+Stream, +Lines)
 1732print_message_lines(Stream, Lines) :-
 1733    with_output_to(
 1734        Stream,
 1735        notrace(print_message_lines_guarded(current_output, Lines))).
 1736
 1737print_message_lines_guarded(_, []) :- !.
 1738print_message_lines_guarded(S, [H|T]) :-
 1739    line_element(S, H),
 1740    print_message_lines_guarded(S, T).
 1741
 1742line_element(S, E) :-
 1743    prolog:message_line_element(S, E),
 1744    !.
 1745line_element(S, full_stop) :-
 1746    !,
 1747    '$put_token'(S, '.').           % insert space if needed.
 1748line_element(S, nl) :-
 1749    !,
 1750    nl(S).
 1751line_element(S, prefix(Fmt-Args)) :-
 1752    !,
 1753    safe_format(S, Fmt, Args).
 1754line_element(S, prefix(Fmt)) :-
 1755    !,
 1756    safe_format(S, Fmt, []).
 1757line_element(S, flush) :-
 1758    !,
 1759    flush_output(S).
 1760line_element(S, Fmt-Args) :-
 1761    !,
 1762    safe_format(S, Fmt, Args).
 1763line_element(S, ansi(_, Fmt, Args)) :-
 1764    !,
 1765    safe_format(S, Fmt, Args).
 1766line_element(S, ansi(_, Fmt, Args, _Ctx)) :-
 1767    !,
 1768    safe_format(S, Fmt, Args).
 1769line_element(_, begin(_Level, _Ctx)) :- !.
 1770line_element(_, end(_Ctx)) :- !.
 1771line_element(S, Fmt) :-
 1772    safe_format(S, Fmt, []).
 safe_format(+Stream, +Format, +Args) is det
 1776safe_format(S, Fmt, Args) :-
 1777    E = error(_,_),
 1778    catch(format(S,Fmt,Args), E,
 1779          format_failed(S,Fmt,Args,E)).
 1780
 1781format_failed(S, _Fmt, _Args, E) :-
 1782    E = error(io_error(_,S),_),
 1783    !,
 1784    throw(E).
 1785format_failed(S, Fmt, Args, error(E,_)) :-
 1786    format(S, '~N    [[ EXCEPTION while printing message ~q~n\c
 1787                        ~7|with arguments ~W:~n\c
 1788                        ~7|raised: ~W~n~4|]]~n',
 1789           [ Fmt,
 1790             Args, [quoted(true), max_depth(10)],
 1791             E, [quoted(true), max_depth(10)]
 1792           ]).
 message_to_string(+Term, -String)
Translate an error term into a string
 1798message_to_string(Term, Str) :-
 1799    translate_message(Term, Actions, []),
 1800    !,
 1801    actions_to_format(Actions, Fmt, Args),
 1802    format(string(Str), Fmt, Args).
 1803
 1804actions_to_format([], '', []) :- !.
 1805actions_to_format([nl], '', []) :- !.
 1806actions_to_format([Term, nl], Fmt, Args) :-
 1807    !,
 1808    actions_to_format([Term], Fmt, Args).
 1809actions_to_format([nl|T], Fmt, Args) :-
 1810    !,
 1811    actions_to_format(T, Fmt0, Args),
 1812    atom_concat('~n', Fmt0, Fmt).
 1813actions_to_format([Skip|T], Fmt, Args) :-
 1814    action_skip(Skip),
 1815    !,
 1816    actions_to_format(T, Fmt, Args).
 1817actions_to_format([Fmt0-Args0|Tail], Fmt, Args) :-
 1818    !,
 1819    actions_to_format(Tail, Fmt1, Args1),
 1820    atom_concat(Fmt0, Fmt1, Fmt),
 1821    append_args(Args0, Args1, Args).
 1822actions_to_format([Term|Tail], Fmt, Args) :-
 1823    atomic(Term),
 1824    !,
 1825    actions_to_format(Tail, Fmt1, Args),
 1826    atom_concat(Term, Fmt1, Fmt).
 1827actions_to_format([Term|Tail], Fmt, Args) :-
 1828    actions_to_format(Tail, Fmt1, Args1),
 1829    atom_concat('~w', Fmt1, Fmt),
 1830    append_args([Term], Args1, Args).
 1831
 1832action_skip(at_same_line).
 1833action_skip(flush).
 1834action_skip(ansi(_Attrs, _Fmt, _Args)).
 1835action_skip(begin(_Level, _Ctx)).
 1836action_skip(end(_Ctx)).
 1837
 1838append_args(M:Args0, Args1, M:Args) :-
 1839    !,
 1840    strip_module(Args1, _, A1),
 1841    '$append'(Args0, A1, Args).
 1842append_args(Args0, Args1, Args) :-
 1843    strip_module(Args1, _, A1),
 1844    '$append'(Args0, A1, Args).
 1845
 1846
 1847                 /*******************************
 1848                 *    MESSAGES TO PRINT ONCE    *
 1849                 *******************************/
 1850
 1851:- dynamic
 1852    printed/2.
 print_once(Message, Level)
True for messages that must be printed only once.
 1858print_once(compatibility(_), _).
 1859print_once(null_byte_in_path(_), _).
 1860print_once(deprecated(_), _).
 must_print(+Level, +Message)
True if the message must be printed.
 1866must_print(Level, Message) :-
 1867    nonvar(Message),
 1868    print_once(Message, Level),
 1869    !,
 1870    \+ printed(Message, Level),
 1871    assert(printed(Message, Level)).
 1872must_print(_, _)