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 ]).
format(Fmt, Args)format(Fmt)ansi(Class, Fmt, Args), the latter
combining a hyperlink with a style class.
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.
126prologtranslate_message(Term) -->
127 translate_message(Term).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).
error(Format, ImplDefined)
exception terms. The ImplDefined argument is handled by
swi_location//2.186:- public term_message//1. 187term_message(Term) --> 188 {var(Term)}, 189 !, 190 [ 'Unknown error term: ~p'-[Term] ]. 191term_message(Term) --> 192 { message_lang(Lang) }, 193 prolog:error_message(Lang, Term), 194 !. 195term_message(Term) --> 196 prolog:error_message(Term), 197 !. 198term_message(Term) --> 199 iso_message(Term). 200term_message(Term) --> 201 swi_message(Term). 202term_message(Term) --> 203 [ 'Unknown error term: ~p'-[Term] ]. 204 205iso_message(resource_error(c_stack)) --> 206 out_of_c_stack. 207iso_message(resource_error(Missing)) --> 208 [ 'Not enough resources: ~w'-[Missing] ]. 209iso_message(type_error(Var, Actual)) --> 210 { var(Var) }, 211 [ 'Type error: unbound (var) type expected, found `~p'''-[Actual] ]. 212iso_message(type_error(evaluable, Actual)) --> 213 { callable(Actual) }, 214 [ 'Arithmetic: `~p'' is not a function'-[Actual] ]. 215iso_message(type_error(free_of_attvar, Actual)) --> 216 [ 'Type error: `~W'' contains attributed variables'- 217 [Actual,[portray(true), attributes(portray)]] ]. 218iso_message(type_error(Expected, Actual)) --> 219 [ 'Type error: `~w'' expected, found `~p'''-[Expected, Actual] ], 220 type_error_comment(Expected, Actual). 221iso_message(domain_error(Domain, Actual)) --> 222 [ 'Domain error: '-[] ], domain(Domain), 223 [ ' expected, found `~p'''-[Actual] ]. 224iso_message(instantiation_error) --> 225 [ 'Arguments are not sufficiently instantiated' ]. 226iso_message(uninstantiation_error(Var)) --> 227 [ 'Uninstantiated argument expected, found ~p'-[Var] ]. 228iso_message(representation_error(standard_order(T1, T2))) --> 229 [ 'Cyclic terms have no standard order: ~p and ~p'-[T1, T2] ]. 230iso_message(representation_error(What)) --> 231 [ 'Cannot represent due to `~w'''-[What] ]. 232iso_message(permission_error(Action, Type, Object)) --> 233 permission_error(Action, Type, Object). 234iso_message(evaluation_error(Which)) --> 235 [ 'Arithmetic: evaluation error: `~p'''-[Which] ]. 236iso_message(existence_error(procedure, Proc)) --> 237 [ 'Unknown procedure: ' ], 238 predicate_reference(Proc), 239 unknown_proc_msg(Proc). 240iso_message(existence_error(answer_variable, Var)) --> 241 [ '$~w was not bound by a previous query'-[Var] ]. 242iso_message(existence_error(matching_rule, Goal)) --> 243 [ 'No rule matches ~p'-[Goal] ]. 244iso_message(existence_error(Type, Object)) --> 245 [ '~w `~p'' does not exist'-[Type, Object] ]. 246iso_message(existence_error(export, PI, module(M))) --> % not ISO 247 [ 'Module ', ansi(code, '~q', [M]), ' does not export ' ], 248 predicate_reference(M:PI, [module(hide)]). 249iso_message(existence_error(Type, Object, In)) --> % not ISO 250 [ '~w `~p'' does not exist in ~p'-[Type, Object, In] ]. 251iso_message(busy(Type, Object)) --> 252 [ '~w `~p'' is busy'-[Type, Object] ]. 253iso_message(syntax_error(swi_backslash_newline)) --> 254 [ 'Deprecated: ... \\<newline><white>*. Use \\c' ]. 255iso_message(syntax_error(warning_var_tag)) --> 256 [ 'Deprecated: dict with unbound tag (_{...}). Mapped to #{...}.' ]. 257iso_message(syntax_error(var_tag)) --> 258 [ 'Syntax error: dict syntax with unbound tag (_{...}).' ]. 259iso_message(syntax_error(Id)) --> 260 [ 'Syntax error: ' ], 261 syntax_error(Id). 262iso_message(occurs_check(Var, In)) --> 263 [ 'Cannot unify ~p with ~p: would create an infinite tree'-[Var, In] ].
270permission_error(Action, built_in_procedure, Pred) --> 271 [ 'No permission to ~w built-in predicate '-[Action] ], 272 predicate_reference(Pred), 273 ( {Action \== export} 274 -> [ nl, 275 'Use :- redefine_system_predicate(+Head) if redefinition is intended' 276 ] 277 ; [] 278 ). 279permission_error(import_into(Dest), procedure, Pred) --> 280 [ 'No permission to import ' ], 281 predicate_reference(Pred), 282 [ ' into ~w'-[Dest] ]. 283permission_error(Action, static_procedure, Proc) --> 284 [ 'No permission to ~w static procedure '-[Action] ], 285 predicate_reference(Proc), 286 predicate_definition(Proc, 'Defined'). 287permission_error(input, stream, Stream) --> 288 [ 'No permission to read from output stream `~p'''-[Stream] ]. 289permission_error(output, stream, Stream) --> 290 [ 'No permission to write to input stream `~p'''-[Stream] ]. 291permission_error(input, text_stream, Stream) --> 292 [ 'No permission to read bytes from TEXT stream `~p'''-[Stream] ]. 293permission_error(output, text_stream, Stream) --> 294 [ 'No permission to write bytes to TEXT stream `~p'''-[Stream] ]. 295permission_error(input, binary_stream, Stream) --> 296 [ 'No permission to read characters from binary stream `~p'''-[Stream] ]. 297permission_error(output, binary_stream, Stream) --> 298 [ 'No permission to write characters to binary stream `~p'''-[Stream] ]. 299permission_error(open, source_sink, alias(Alias)) --> 300 [ 'No permission to reuse alias "~p": already taken'-[Alias] ]. 301permission_error(tnot, non_tabled_procedure, Pred) --> 302 [ 'The argument of ' ], predicate_reference(tnot/1), 303 [ ' is not tabled: ' ], predicate_reference(Pred). 304permission_error(assert, procedure, Pred) --> 305 { predicate_head(Pred, Head), 306 predicate_property(Head, ssu) 307 }, 308 predicate_reference(Pred), 309 [ ': an SSU (Head => Body) predicate cannot have normal Prolog clauses' ]. 310permission_error(Action, Type, Object) --> 311 [ 'No permission to ~w ~w `~p'''-[Action, Type, Object] ]. 312 313 314unknown_proc_msg(_:(^)/2) --> 315 !, 316 unknown_proc_msg((^)/2). 317unknown_proc_msg((^)/2) --> 318 !, 319 [nl, ' ^/2 can only appear as the 2nd argument of setof/3 and bagof/3']. 320unknown_proc_msg((:-)/2) --> 321 !, 322 [nl, ' Rules must be loaded from a file'], 323 faq('ToplevelMode'). 324unknown_proc_msg((=>)/2) --> 325 !, 326 [nl, ' Rules must be loaded from a file'], 327 faq('ToplevelMode'). 328unknown_proc_msg((:-)/1) --> 329 !, 330 [nl, ' Directives must be loaded from a file'], 331 faq('ToplevelMode'). 332unknown_proc_msg((?-)/1) --> 333 !, 334 [nl, ' ?- is the Prolog prompt'], 335 faq('ToplevelMode'). 336unknown_proc_msg(Proc) --> 337 { dwim_predicates(Proc, Dwims) }, 338 ( {Dwims \== []} 339 -> [nl, ' However, there are definitions for:', nl], 340 dwim_alternatives(Dwims) 341 ; [] 342 ). 343 344dependency_error(shared(Shared), private(Private)) --> 345 [ 'Shared table for ' ], predicate_reference(Shared), 346 [ ' may not depend on private ' ], predicate_reference(Private). 347dependency_error(Dep, monotonic(On)) --> 348 [ 'Dependent ' ], predicate_reference(Dep), 349 [ ' on monotonic predicate ' ], predicate_reference(On), 350 [ ' is not monotonic or incremental' ]. 351 352faq(Page) --> 353 [nl, ' See FAQ at https://www.swi-prolog.org/FAQ/', Page, '.html' ]. 354 355type_error_comment(_Expected, Actual) --> 356 { type_of(Actual, Type), 357 ( sub_atom(Type, 0, 1, _, First), 358 memberchk(First, [a,e,i,o,u]) 359 -> Article = an 360 ; Article = a 361 ) 362 }, 363 [ ' (~w ~w)'-[Article, Type] ]. 364 365type_of(Term, Type) :- 366 ( attvar(Term) -> Type = attvar 367 ; var(Term) -> Type = var 368 ; atom(Term) -> Type = atom 369 ; integer(Term) -> Type = integer 370 ; string(Term) -> Type = string 371 ; Term == [] -> Type = empty_list 372 ; blob(Term, BlobT) -> blob_type(BlobT, Type) 373 ; rational(Term) -> Type = rational 374 ; float(Term) -> Type = float 375 ; is_stream(Term) -> Type = stream 376 ; is_dict(Term) -> Type = dict 377 ; is_list(Term) -> Type = list 378 ; Term = [_|_] -> list_like(Term, Type) 379 ; cyclic_term(Term) -> Type = cyclic 380 ; compound(Term) -> Type = compound 381 ; Type = unknown 382 ). 383 384list_like(Term, Type) :- 385 '$skip_list'(_, Term, Tail), 386 ( var(Tail) 387 -> Type = partial_list 388 ; Type = invalid_list % TBD: Better name? 389 ). 390 391blob_type(BlobT, Type) :- 392 atom_concat(BlobT, '_reference', Type). 393 394syntax_error(end_of_clause) --> 395 [ 'Unexpected end of clause' ]. 396syntax_error(end_of_clause_expected) --> 397 [ 'End of clause expected' ]. 398syntax_error(end_of_file) --> 399 [ 'Unexpected end of file' ]. 400syntax_error(end_of_file_in_block_comment) --> 401 [ 'End of file in /* ... */ comment' ]. 402syntax_error(end_of_file_in_quoted(Quote)) --> 403 [ 'End of file in quoted ' ], 404 quoted_type(Quote). 405syntax_error(illegal_number) --> 406 [ 'Illegal number' ]. 407syntax_error(long_atom) --> 408 [ 'Atom too long (see style_check/1)' ]. 409syntax_error(long_string) --> 410 [ 'String too long (see style_check/1)' ]. 411syntax_error(operator_clash) --> 412 [ 'Operator priority clash' ]. 413syntax_error(operator_expected) --> 414 [ 'Operator expected' ]. 415syntax_error(operator_balance) --> 416 [ 'Unbalanced operator' ]. 417syntax_error(quoted_punctuation) --> 418 [ 'Operand expected, unquoted comma or bar found' ]. 419syntax_error(list_rest) --> 420 [ 'Unexpected comma or bar in rest of list' ]. 421syntax_error(cannot_start_term) --> 422 [ 'Illegal start of term' ]. 423syntax_error(punct(Punct, End)) --> 424 [ 'Unexpected `~w\' before `~w\''-[Punct, End] ]. 425syntax_error(undefined_char_escape(C)) --> 426 [ 'Unknown character escape in quoted atom or string: `\\~w\''-[C] ]. 427syntax_error(void_not_allowed) --> 428 [ 'Empty argument list "()"' ]. 429syntax_error(Term) --> 430 { compound(Term), 431 compound_name_arguments(Term, Syntax, [Text]) 432 }, !, 433 [ '~w expected, found '-[Syntax], ansi(code, '"~w"', [Text]) ]. 434syntax_error(Message) --> 435 [ '~w'-[Message] ]. 436 437quoted_type('\'') --> [atom]. 438quoted_type('\"') --> { current_prolog_flag(double_quotes, Type) }, [Type-[]]. 439quoted_type('\`') --> { current_prolog_flag(back_quotes, Type) }, [Type-[]]. 440 441domain(range(Low,High)) --> 442 !, 443 ['[~q..~q]'-[Low,High] ]. 444domain(Domain) --> 445 ['`~w\''-[Domain] ].
452tabling_existence_error(Ball, Context) --> 453 { table_shift_ball(Ball) }, 454 [ 'Tabling dependency error' ], 455 swi_extra(Context). 456 457table_shift_ball(dependency(_Head)). 458table_shift_ball(dependency(_Skeleton, _Trie, _Mono)). 459table_shift_ball(call_info(_Skeleton, _Status)). 460table_shift_ball(call_info(_GenSkeleton, _Skeleton, _Status)).
466dwim_predicates(Module:Name/_Arity, Dwims) :- 467 !, 468 findall(Dwim, dwim_predicate(Module:Name, Dwim), Dwims). 469dwim_predicates(Name/_Arity, Dwims) :- 470 findall(Dwim, dwim_predicate(user:Name, Dwim), Dwims). 471 472dwim_alternatives([]) --> []. 473dwim_alternatives([H|T]) --> 474 [ ' ' ], 475 predicate_reference(H, [tag(true)]), 476 [ nl ], 477 dwim_alternatives(T). 478 479swi_message(io_error(Op, Stream)) --> 480 [ 'I/O error in ~w on stream ~p'-[Op, Stream] ]. 481swi_message(thread_error(TID, false)) --> 482 [ 'Thread ~p died due to failure:'-[TID] ]. 483swi_message(thread_error(TID, exception(Error))) --> 484 [ 'Thread ~p died abnormally:'-[TID], nl ], 485 translate_message(Error). 486swi_message(dependency_error(Tabled, DependsOn)) --> 487 dependency_error(Tabled, DependsOn). 488swi_message(shell(execute, Cmd)) --> 489 [ 'Could not execute `~w'''-[Cmd] ]. 490swi_message(shell(signal(Sig), Cmd)) --> 491 [ 'Caught signal ~d on `~w'''-[Sig, Cmd] ]. 492swi_message(format(Fmt, Args)) --> 493 [ Fmt-Args ]. 494swi_message(signal(Name, Num)) --> 495 [ 'Caught signal ~d (~w)'-[Num, Name] ]. 496swi_message(limit_exceeded(Limit, MaxVal)) --> 497 [ 'Exceeded ~w limit (~w)'-[Limit, MaxVal] ]. 498swi_message(goal_failed(Goal)) --> 499 [ 'goal unexpectedly failed: ~p'-[Goal] ]. 500swi_message(shared_object(_Action, Message)) --> % Message = dlerror() 501 [ '~w'-[Message] ]. 502swi_message(system_error(Error)) --> 503 [ 'error in system call: ~w'-[Error] 504 ]. 505swi_message(system_error) --> 506 [ 'error in system call' 507 ]. 508swi_message(failure_error(Goal)) --> 509 [ 'Goal failed: ~p'-[Goal] ]. 510swi_message(timeout_error(Op, Stream)) --> 511 [ 'Timeout in ~w from ~p'-[Op, Stream] ]. 512swi_message(not_implemented(Type, What)) --> 513 [ '~w `~p\' is not implemented in this version'-[Type, What] ]. 514swi_message(context_error(nodirective, Goal)) --> 515 [ 'Wrong context: ' ], predicate_reference(Goal), 516 [ ' can only be used in a directive' ]. 517swi_message(context_error(edit, no_default_file)) --> 518 ( { current_prolog_flag(windows, true) } 519 -> [ 'Edit/0 can only be used after opening a \c 520 Prolog file by double-clicking it' ] 521 ; [ 'Edit/0 can only be used with the "-s file" commandline option' 522 ] 523 ), 524 [ nl, 'Use "?- edit(Topic)." or "?- emacs."' ]. 525swi_message(context_error(function, meta_arg(S))) --> 526 [ 'Functions are not (yet) supported for meta-arguments of type ~q'-[S] ]. 527swi_message(format_argument_type(Fmt, Arg)) --> 528 [ 'Illegal argument to format sequence ~~~w: ~p'-[Fmt, Arg] ]. 529swi_message(format(Msg)) --> 530 [ 'Format error: ~w'-[Msg] ]. 531swi_message(conditional_compilation_error(unterminated, File:Line)) --> 532 [ 'Unterminated conditional compilation from '-[], url(File:Line) ]. 533swi_message(conditional_compilation_error(no_if, What)) --> 534 [ ':- ~w without :- if'-[What] ]. 535swi_message(duplicate_key(Key)) --> 536 [ 'Duplicate key: ~p'-[Key] ]. 537swi_message(determinism_error(PI, det, Found, property)) --> 538 ( { predicate_head(PI, Head), 539 predicate_property(Head, det) 540 } 541 -> [ 'Deterministic procedure ' ], predicate_reference(PI) 542 ; [ 'Procedure ' ], predicate_reference(PI), 543 [ ' called from a deterministic procedure' ] 544 ), 545 det_error(Found). 546swi_message(determinism_error(PI, det, fail, guard)) --> 547 [ 'Procedure ' ], predicate_reference(PI), 548 [ ' failed after $-guard' ]. 549swi_message(determinism_error(PI, det, fail, guard_in_caller)) --> 550 [ 'Procedure ' ], predicate_reference(PI), 551 [ ' failed after $-guard in caller' ]. 552swi_message(determinism_error(Goal, det, fail, goal)) --> 553 [ 'Goal ~p failed'-[Goal] ]. 554swi_message(determinism_error(Goal, det, nondet, goal)) --> 555 [ 'Goal ~p succeeded with a choice point'-[Goal] ]. 556swi_message(qlf_format_error(File, Message)) --> 557 [ '~w: Invalid QLF file: ~w'-[File, Message] ]. 558swi_message(goal_expansion_error(bound, Term)) --> 559 [ 'Goal expansion bound a variable to ~p'-[Term] ]. 560 561det_error(nondet) --> 562 [ ' succeeded with a choicepoint'- [] ]. 563det_error(fail) --> 564 [ ' failed'- [] ].
error(Formal, ImplDefined) from the
ImplDefined term.572:- public swi_location//1. 573swi_location(X) --> 574 { var(X) }, 575 !. 576swi_location(Context) --> 577 { message_lang(Lang) }, 578 prolog:message_location(Lang, Context), 579 !. 580swi_location(Context) --> 581 prolog:message_location(Context), 582 !. 583swi_location(context(Caller, _Msg)) --> 584 { ground(Caller) }, 585 !, 586 caller(Caller). 587swi_location(file(Path, Line, -1, _CharNo)) --> 588 !, 589 [ url(Path:Line), ': ' ]. 590swi_location(file(Path, Line, LinePos, _CharNo)) --> 591 { Column is LinePos+1 }, % line_position is 0-based 592 [ url(Path:Line:Column), ': ' ]. 593swi_location(stream(Stream, Line, LinePos, CharNo)) --> 594 ( { is_stream(Stream), 595 stream_property(Stream, file_name(File)) 596 } 597 -> swi_location(file(File, Line, LinePos, CharNo)) 598 ; { Column is LinePos+1 }, 599 [ 'Stream ~w:~d:~d '-[Stream, Line, Column] ] 600 ). 601swi_location(autoload(File:Line)) --> 602 [ url(File:Line), ': ' ]. 603swi_location(_) --> 604 []. 605 606caller(system:'$record_clause'/3) --> 607 !, 608 []. 609caller(Caller) --> 610 { predicate_indicator(Caller, _) }, 611 !, 612 predicate_reference(Caller, [link(false)]), 613 [ ': ' ]. 614caller(Caller) --> 615 [ '~p: '-[Caller] ].
error(Formal,
ImplDefined) that is printed after the core of the message.
626swi_extra(X) --> 627 { var(X) }, 628 !, 629 []. 630swi_extra(Context) --> 631 { message_lang(Lang) }, 632 prolog:message_context(Lang, Context), 633 !. 634swi_extra(Context) --> 635 prolog:message_context(Context). 636swi_extra(context(_, Msg)) --> 637 { nonvar(Msg), 638 Msg \== '' 639 }, 640 !, 641 swi_comment(Msg). 642swi_extra(string(String, CharPos)) --> 643 { sub_string(String, 0, CharPos, _, Before), 644 sub_string(String, CharPos, _, 0, After) 645 }, 646 [ nl, '~w'-[Before], nl, '** here **', nl, '~w'-[After] ]. 647swi_extra(_) --> 648 []. 649 650swi_comment(already_from(Module)) --> 651 !, 652 [ ' (already imported from ~q)'-[Module] ]. 653swi_comment(directory(_Dir)) --> 654 !, 655 [ ' (is a directory)' ]. 656swi_comment(not_a_directory(_Dir)) --> 657 !, 658 [ ' (is not a directory)' ]. 659swi_comment(Msg) --> 660 [ ' (~w)'-[Msg] ]. 661 662 663thread_context --> 664 { \+ current_prolog_flag(toplevel_thread, true), 665 thread_self(Id) 666 }, 667 !, 668 ['[Thread ~w] '-[Id]]. 669thread_context --> 670 []. 671 672 /******************************* 673 * UNWIND MESSAGES * 674 *******************************/ 675 676unwind_message(Var) --> 677 { var(Var) }, !, 678 [ 'Unknown unwind message: ~p'-[Var] ]. 679unwind_message(abort) --> 680 [ 'Execution Aborted' ]. 681unwind_message(halt(_)) --> 682 []. 683unwind_message(thread_exit(Term)) --> 684 [ 'Invalid thread_exit/1. Payload: ~p'-[Term] ]. 685unwind_message(Term) --> 686 [ 'Unknown "unwind" exception: ~p'-[Term] ]. 687 688 689 /******************************* 690 * NORMAL MESSAGES * 691 *******************************/ 692 693:- dynamic prolog:version_msg/1. 694:- multifile prolog:version_msg/1. 695 696prolog_message(welcome) --> 697 [ 'Welcome to SWI-Prolog (' ], 698 prolog_message(threads), 699 prolog_message(address_bits), 700 ['version ' ], 701 prolog_message(version), 702 [ ')', nl ], 703 prolog_message(copyright), 704 [ nl ], 705 translate_message(user_versions), 706 [ nl ], 707 prolog_message(documentaton), 708 [ nl, nl ]. 709prolog_message(user_versions) --> 710 ( { findall(Msg, prolog:version_msg(Msg), Msgs), 711 Msgs \== [] 712 } 713 -> [nl], 714 user_version_messages(Msgs) 715 ; [] 716 ). 717prolog_message(deprecated(Term)) --> 718 { nonvar(Term) }, 719 ( { message_lang(Lang) }, 720 prolog:deprecated(Lang, Term) 721 -> [] 722 ; prolog:deprecated(Term) 723 -> [] 724 ; deprecated(Term) 725 ). 726prolog_message(unhandled_exception(E)) --> 727 { nonvar(E) }, 728 [ 'Unhandled exception: ' ], 729 ( translate_message(E) 730 -> [] 731 ; [ '~p'-[E] ] 732 ).
736prolog_message(initialization_error(_, E, File:Line)) --> 737 !, 738 [ url(File:Line), 739 ': Initialization goal raised exception:', nl 740 ], 741 translate_message(E). 742prolog_message(initialization_error(Goal, E, _)) --> 743 [ 'Initialization goal ~p raised exception:'-[Goal], nl ], 744 translate_message(E). 745prolog_message(initialization_failure(_Goal, File:Line)) --> 746 !, 747 [ url(File:Line), 748 ': Initialization goal failed'-[] 749 ]. 750prolog_message(initialization_failure(Goal, _)) --> 751 [ 'Initialization goal failed: ~p'-[Goal] 752 ]. 753prolog_message(initialization_exception(E)) --> 754 [ 'Prolog initialisation failed:', nl ], 755 translate_message(E). 756prolog_message(initialization(halt(Status), Goal, File:Line)) --> 757 [ url(File:Line), ': '], goal(Goal), [nl, 758 ' Initialization goal called ', ansi(code, '~p', [halt(Status)]), 759 '.', nl, 760 ' The program entry point should be called using ', 761 ansi(code, 'initialization/2', []), '.', nl, 762 ' Consider using ', ansi(code, 'library(main)', []), '.' 763 ]. 764prolog_message(init_goal_syntax(Error, Text)) --> 765 !, 766 [ '-g ~w: '-[Text] ], 767 translate_message(Error). 768prolog_message(init_goal_failed(failed, @(Goal,File:Line))) --> 769 !, 770 [ url(File:Line), ': ~p: false'-[Goal] ]. 771prolog_message(init_goal_failed(Error, @(Goal,File:Line))) --> 772 !, 773 [ url(File:Line), ': ~p '-[Goal] ], 774 translate_message(Error). 775prolog_message(init_goal_failed(failed, Text)) --> 776 !, 777 [ '-g ~w: false'-[Text] ]. 778prolog_message(init_goal_failed(Error, Text)) --> 779 !, 780 [ '-g ~w: '-[Text] ], 781 translate_message(Error). 782prolog_message(goal_failed(Context, Goal)) --> 783 [ 'Goal (~w) failed: ~p'-[Context, Goal] ]. 784prolog_message(no_current_module(Module)) --> 785 [ '~w is not a current module (created)'-[Module] ]. 786prolog_message(commandline_arg_type(Flag, Arg)) --> 787 [ 'Bad argument to commandline option -~w: ~w'-[Flag, Arg] ]. 788prolog_message(missing_feature(Name)) --> 789 [ 'This version of SWI-Prolog does not support ~w'-[Name] ]. 790prolog_message(singletons(_Term, List)) --> 791 [ 'Singleton variables: ~w'-[List] ]. 792prolog_message(multitons(_Term, List)) --> 793 [ 'Singleton-marked variables appearing more than once: ~w'-[List] ]. 794prolog_message(profile_no_cpu_time) --> 795 [ 'No CPU-time info. Check the SWI-Prolog manual for details' ]. 796prolog_message(non_ascii(Text, Type)) --> 797 [ 'Unquoted ~w with non-portable characters: ~w'-[Type, Text] ]. 798prolog_message(io_warning(Stream, Message)) --> 799 { stream_property(Stream, position(Position)), 800 !, 801 stream_position_data(line_count, Position, LineNo), 802 stream_position_data(line_position, Position, LinePos), 803 Column is LinePos+1 % line_position is 0-based 804 }, 805 ( { stream_property(Stream, file_name(File)) } 806 -> [ url(File:LineNo:Column) ] 807 ; [ '~p:~d:~d'-[Stream, LineNo, Column] ] 808 ), 809 [ ': ~w'-[Message] ]. 810prolog_message(io_warning(Stream, Message)) --> 811 [ 'stream ~p: ~w'-[Stream, Message] ]. 812prolog_message(option_usage(pldoc)) --> 813 [ 'Usage: --pldoc[=port]' ]. 814prolog_message(interrupt(begin)) --> 815 [ 'Action (h for help) ? ', flush ]. 816prolog_message(interrupt(end)) --> 817 [ 'continue' ]. 818prolog_message(interrupt(trace)) --> 819 [ 'continue (trace mode)' ]. 820prolog_message(unknown_in_module_user) --> 821 [ 'Using a non-error value for unknown in the global module', nl, 822 'causes most of the development environment to stop working.', nl, 823 'Please use :- dynamic or limit usage of unknown to a module.', nl, 824 'See https://www.swi-prolog.org/howto/database.html' 825 ]. 826prolog_message(untable(PI)) --> 827 [ 'Reconsult: removed tabling for ' ], predicate_reference(PI). 828prolog_message(unknown_option(Set, Opt)) --> 829 [ 'Unknown ~w option: ~p'-[Set, Opt] ]. 830 831 832 /******************************* 833 * LOADING FILES * 834 *******************************/ 835 836prolog_message(modify_active_procedure(Who, What)) --> 837 predicate_reference(Who), 838 [ ': modified active procedure ' ], 839 predicate_reference(What). 840prolog_message(load_file(failed(user:File))) --> 841 [ 'Failed to load ~p'-[File] ]. 842prolog_message(load_file(failed(Module:File))) --> 843 [ 'Failed to load ~p into module ~p'-[File, Module] ]. 844prolog_message(load_file(failed(File))) --> 845 [ 'Failed to load ~p'-[File] ]. 846prolog_message(mixed_directive(Goal)) --> 847 [ 'Cannot pre-compile mixed load/call directive: ~p'-[Goal] ]. 848prolog_message(cannot_redefine_comma) --> 849 [ 'Full stop in clause-body? Cannot redefine ,/2' ]. 850prolog_message(illegal_autoload_index(Dir, Term)) --> 851 [ 'Illegal term in INDEX file of directory ~w: ~w'-[Dir, Term] ]. 852prolog_message(redefined_procedure(Type, Proc)) --> 853 [ 'Redefined ~w procedure '-[Type] ], 854 predicate_reference(Proc), 855 predicate_definition(Proc, 'Previously defined'). 856prolog_message(declare_module(Module, abolish(Predicates))) --> 857 [ 'Loading module ~w abolished:'-[Module], nl ], 858 predicate_list(Predicates). 859prolog_message(import_private(Module, Private)) --> 860 [ 'import/1: ' ], predicate_reference(Private), 861 [ ' is not exported (still imported into ~q)'-[Module] ]. 862prolog_message(ignored_weak_import(Into, From:PI)) --> 863 [ 'Local definition of ' ], 864 predicate_reference(Into:PI, [module(show)]), 865 [ ' overrides weak import from ~q'-[From] ]. 866prolog_message(undefined_export(Module, PI)) --> 867 [ 'Exported procedure ' ], 868 predicate_reference(Module:PI, [module(show)]), 869 [ ' is not defined' ]. 870prolog_message(no_exported_op(Module, Op)) --> 871 [ 'Operator ~q:~q is not exported (still defined)'-[Module, Op] ]. 872prolog_message(discontiguous((-)/2,_)) --> 873 prolog_message(minus_in_identifier). 874prolog_message(discontiguous(Proc,Current)) --> 875 [ 'Clauses of ' ], predicate_reference(Proc), 876 [ ' are not together in the source-file' ], 877 predicate_definition(Proc, 'Earlier definition'), 878 [ nl, 'Current predicate: ' ], predicate_reference(Current), 879 [ nl, 'Use ', ansi(code, ':- discontiguous ~p.', [Proc]), 880 ' to suppress this message' 881 ]. 882prolog_message(decl_no_effect(Goal)) --> 883 [ 'Deprecated declaration has no effect: ~p'-[Goal] ]. 884prolog_message(load_file(start(Level, File))) --> 885 [ '~|~t~*+Loading '-[Level] ], 886 load_file(File), 887 [ ' ...' ]. 888prolog_message(include_file(start(Level, File))) --> 889 [ '~|~t~*+include '-[Level] ], 890 load_file(File), 891 [ ' ...' ]. 892prolog_message(include_file(done(Level, File))) --> 893 [ '~|~t~*+included '-[Level] ], 894 load_file(File). 895prolog_message(load_file(done(Level, File, Action, Module, Time, Clauses))) --> 896 [ '~|~t~*+'-[Level] ], 897 load_file(File), 898 [ ' ~w'-[Action] ], 899 load_module(Module), 900 [ ' ~2f sec, ~D clauses'-[Time, Clauses] ]. 901prolog_message(dwim_undefined(Goal, Alternatives)) --> 902 [ 'Unknown procedure: ' ], 903 predicate_reference(Goal), 904 [ nl, ' However, there are definitions for:', nl ], 905 dwim_alternatives(Alternatives). 906prolog_message(dwim_correct(Into)) --> 907 [ ansi(warning, 'Correct to: ', []), ansi(code, '~q', [Into]), 908 ansi(warning, '? ', []), flush 909 ]. 910prolog_message(error(loop_error(Spec), file_search(Used))) --> 911 [ 'File search: too many levels of indirections on: ~p'-[Spec], nl, 912 ' Used alias expansions:', nl 913 ], 914 used_search(Used). 915prolog_message(minus_in_identifier) --> 916 [ 'The "-" character should not be used to separate words in an', nl, 917 'identifier. Check the SWI-Prolog FAQ for details.' 918 ]. 919prolog_message(qlf(removed_after_error(File))) --> 920 [ 'Removed incomplete QLF file ~w'-[File] ]. 921prolog_message(qlf(recompile(Spec,_Pl,_Qlf,Reason))) --> 922 [ '~p: recompiling QLF file'-[Spec] ], 923 qlf_recompile_reason(Reason). 924prolog_message(qlf(can_not_recompile(Spec,QlfFile,_Reason))) --> 925 [ '~p: can not recompile "~w" (access denied)'-[Spec, QlfFile], nl, 926 '\tLoading from source'-[] 927 ]. 928prolog_message(qlf(system_lib_out_of_date(Spec,QlfFile))) --> 929 [ '~p: can not recompile "~w" (access denied)'-[Spec, QlfFile], nl, 930 '\tLoading QlfFile'-[] 931 ]. 932prolog_message(redefine_module(Module, OldFile, File)) --> 933 [ 'Module "~q" already loaded from ~w.'-[Module, OldFile], nl, 934 'Wipe and reload from ~w? '-[File], flush 935 ]. 936prolog_message(redefine_module_reply) --> 937 [ 'Please answer y(es), n(o) or a(bort)' ]. 938prolog_message(reloaded_in_module(Absolute, OldContext, LM)) --> 939 [ '~w was previously loaded in module ~w'-[Absolute, OldContext], nl, 940 '\tnow it is reloaded into module ~w'-[LM] ]. 941prolog_message(expected_layout(Expected, Pos)) --> 942 [ 'Layout data: expected ~w, found: ~p'-[Expected, Pos] ]. 943 944used_search([]) --> 945 []. 946used_search([Alias=Expanded|T]) --> 947 [ ' file_search_path(~p, ~p)'-[Alias, Expanded], nl ], 948 used_search(T). 949 950load_file(file(Spec, _Path)) --> 951 ( {atomic(Spec)} 952 -> [ '~w'-[Spec] ] 953 ; [ '~p'-[Spec] ] 954 ). 955%load_file(file(_, Path)) --> 956% [ '~w'-[Path] ]. 957 958load_module(user) --> !. 959load_module(system) --> !. 960load_module(Module) --> 961 [ ' into ~w'-[Module] ].
969user_predicate_indicator(Module:PI, PI) :- 970 hidden_module(Module), 971 !. 972user_predicate_indicator(PI, PI). 973 (user) :- !. 975hidden_module(system) :- !. 976hidden_module(M) :- 977 sub_atom(M, 0, _, _, $). 978 979qlf_recompile_reason(old) --> 980 !, 981 [ ' (out of date)'-[] ]. 982qlf_recompile_reason(_) --> 983 [ ' (incompatible with current Prolog version)'-[] ]. 984 985prolog_message(file_search(cache(Spec, _Cond), Path)) --> 986 [ 'File search: ~p --> ~p (cache)'-[Spec, Path] ]. 987prolog_message(file_search(found(Spec, Cond), Path)) --> 988 [ 'File search: ~p --> ~p OK ~p'-[Spec, Path, Cond] ]. 989prolog_message(file_search(tried(Spec, Cond), Path)) --> 990 [ 'File search: ~p --> ~p NO ~p'-[Spec, Path, Cond] ]. 991 992 /******************************* 993 * GC * 994 *******************************/ 995 996prolog_message(agc(start)) --> 997 thread_context, 998 [ 'AGC: ', flush ]. 999prolog_message(agc(done(Collected, Remaining, Time))) --> 1000 [ at_same_line, 1001 'reclaimed ~D atoms in ~3f sec. (remaining: ~D)'- 1002 [Collected, Time, Remaining] 1003 ]. 1004prolog_message(cgc(start)) --> 1005 thread_context, 1006 [ 'CGC: ', flush ]. 1007prolog_message(cgc(done(CollectedClauses, _CollectedBytes, 1008 RemainingBytes, Time))) --> 1009 [ at_same_line, 1010 'reclaimed ~D clauses in ~3f sec. (pending: ~D bytes)'- 1011 [CollectedClauses, Time, RemainingBytes] 1012 ]. 1013 1014 /******************************* 1015 * STACK OVERFLOW * 1016 *******************************/ 1017 1018out_of_stack(Context) --> 1019 { human_stack_size(Context.localused, Local), 1020 human_stack_size(Context.globalused, Global), 1021 human_stack_size(Context.trailused, Trail), 1022 human_stack_size(Context.stack_limit, Limit), 1023 LCO is (100*(Context.depth - Context.environments))/Context.depth 1024 }, 1025 [ 'Stack limit (~s) exceeded'-[Limit], nl, 1026 ' Stack sizes: local: ~s, global: ~s, trail: ~s'-[Local,Global,Trail], nl, 1027 ' Stack depth: ~D, last-call: ~0f%, Choice points: ~D'- 1028 [Context.depth, LCO, Context.choicepoints], nl 1029 ], 1030 overflow_reason(Context, Resolve), 1031 resolve_overflow(Resolve). 1032 1033human_stack_size(Size, String) :- 1034 Size < 100, 1035 format(string(String), '~dKb', [Size]). 1036human_stack_size(Size, String) :- 1037 Size < 100 000, 1038 Value is Size / 1024, 1039 format(string(String), '~1fMb', [Value]). 1040human_stack_size(Size, String) :- 1041 Value is Size / (1024*1024), 1042 format(string(String), '~1fGb', [Value]). 1043 1044overflow_reason(Context, fix) --> 1045 show_non_termination(Context), 1046 !. 1047overflow_reason(Context, enlarge) --> 1048 { Stack = Context.get(stack) }, 1049 !, 1050 [ ' In:'-[], nl ], 1051 stack(Stack). 1052overflow_reason(_Context, enlarge) --> 1053 [ ' Insufficient global stack'-[] ]. 1054 1055show_non_termination(Context) --> 1056 ( { Stack = Context.get(cycle) } 1057 -> [ ' Probable infinite recursion (cycle):'-[], nl ] 1058 ; { Stack = Context.get(non_terminating) } 1059 -> [ ' Possible non-terminating recursion:'-[], nl ] 1060 ), 1061 stack(Stack). 1062 1063stack([]) --> []. 1064stack([frame(Depth, M:Goal, _)|T]) --> 1065 [ ' [~D] ~q:'-[Depth, M] ], 1066 stack_goal(Goal), 1067 [ nl ], 1068 stack(T). 1069 1070stack_goal(Goal) --> 1071 { compound(Goal), 1072 !, 1073 compound_name_arity(Goal, Name, Arity) 1074 }, 1075 [ '~q('-[Name] ], 1076 stack_goal_args(1, Arity, Goal), 1077 [ ')'-[] ]. 1078stack_goal(Goal) --> 1079 [ '~q'-[Goal] ]. 1080 1081stack_goal_args(I, Arity, Goal) --> 1082 { I =< Arity, 1083 !, 1084 arg(I, Goal, A), 1085 I2 is I + 1 1086 }, 1087 stack_goal_arg(A), 1088 ( { I2 =< Arity } 1089 -> [ ', '-[] ], 1090 stack_goal_args(I2, Arity, Goal) 1091 ; [] 1092 ). 1093stack_goal_args(_, _, _) --> 1094 []. 1095 1096stack_goal_arg(A) --> 1097 { nonvar(A), 1098 A = [Len|T], 1099 ! 1100 }, 1101 ( {Len == cyclic_term} 1102 -> [ '[cyclic list]'-[] ] 1103 ; {T == []} 1104 -> [ '[length:~D]'-[Len] ] 1105 ; [ '[length:~D|~p]'-[Len, T] ] 1106 ). 1107stack_goal_arg(A) --> 1108 { nonvar(A), 1109 A = _/_, 1110 ! 1111 }, 1112 [ '<compound ~p>'-[A] ]. 1113stack_goal_arg(A) --> 1114 [ '~p'-[A] ]. 1115 1116resolve_overflow(fix) --> 1117 []. 1118resolve_overflow(enlarge) --> 1119 { current_prolog_flag(stack_limit, LimitBytes), 1120 NewLimit is LimitBytes * 2 1121 }, 1122 [ nl, 1123 'Use the --stack_limit=size[KMG] command line option or'-[], nl, 1124 '?- set_prolog_flag(stack_limit, ~I). to double the limit.'-[NewLimit] 1125 ].
1132out_of_c_stack --> 1133 { statistics(c_stack, Limit), Limit > 0 }, 1134 !, 1135 [ 'C-stack limit (~D bytes) exceeded.'-[Limit], nl ], 1136 resolve_c_stack_overflow(Limit). 1137out_of_c_stack --> 1138 { statistics(c_stack, Limit), Limit > 0 }, 1139 [ 'C-stack limit exceeded.'-[Limit], nl ], 1140 resolve_c_stack_overflow(Limit). 1141 1142resolve_c_stack_overflow(_Limit) --> 1143 { thread_self(main) }, 1144 [ 'Use the shell command ' ], code('~w', 'ulimit -s size'), 1145 [ ' to enlarge the limit.' ]. 1146resolve_c_stack_overflow(_Limit) --> 1147 [ 'Use the ' ], code('~w', 'c_stack(KBytes)'), 1148 [ ' option of '], code(thread_create/3), [' to enlarge the limit.' ]. 1149 1150 1151 /******************************* 1152 * MAKE/AUTOLOAD * 1153 *******************************/ 1154 1155prolog_message(make(reload(Files))) --> 1156 { length(Files, N) 1157 }, 1158 [ 'Make: reloading ~D files'-[N] ]. 1159prolog_message(make(done(_Files))) --> 1160 [ 'Make: finished' ]. 1161prolog_message(make(library_index(Dir))) --> 1162 [ 'Updating index for library ~w'-[Dir] ]. 1163prolog_message(autoload(Pred, File)) --> 1164 thread_context, 1165 [ 'autoloading ' ], predicate_reference(Pred, [link(false)]), 1166 [ ' from ~w'-[File] ]. 1167prolog_message(autoload(read_index(Dir))) --> 1168 [ 'Loading autoload index for ~w'-[Dir] ]. 1169prolog_message(autoload(disabled(Loaded))) --> 1170 [ 'Disabled autoloading (loaded ~D files)'-[Loaded] ]. 1171prolog_message(autoload(already_defined(PI, From))) --> 1172 predicate_reference(PI), 1173 ( { predicate_head(PI, Head), 1174 predicate_property(Head, built_in) 1175 } 1176 -> [' is a built-in predicate'] 1177 ; [ ' is already imported from module ' ], 1178 code(From) 1179 ). 1180 1181swi_message(autoload(Msg)) --> 1182 [ nl, ' ' ], 1183 autoload_message(Msg). 1184 1185autoload_message(not_exported(PI, Spec, _FullFile, _Exports)) --> 1186 [ ansi(code, '~w', [Spec]), 1187 ' does not export ' 1188 ], 1189 predicate_reference(PI, [link(false)]). 1190autoload_message(no_file(Spec)) --> 1191 [ ansi(code, '~p', [Spec]), ': No such file' ]. 1192 1193 1194 /******************************* 1195 * COMPILER WARNINGS * 1196 *******************************/ 1197 1198% print warnings about dubious code raised by the compiler. 1199% TBD: pass in PC to produce exact error locations. 1200 1201prolog_message(compiler_warnings(Clause, Warnings0)) --> 1202 { print_goal_options(DefOptions), 1203 ( prolog_load_context(variable_names, VarNames) 1204 -> warnings_with_named_vars(Warnings0, VarNames, Warnings), 1205 Options = [variable_names(VarNames)|DefOptions] 1206 ; Options = DefOptions, 1207 Warnings = Warnings0 1208 ) 1209 }, 1210 compiler_warnings(Warnings, Clause, Options). 1211 1212warnings_with_named_vars([], _, []). 1213warnings_with_named_vars([H|T0], VarNames, [H|T]) :- 1214 term_variables(H, Vars), 1215 '$member'(V1, Vars), 1216 '$member'(_=V2, VarNames), 1217 V1 == V2, 1218 !, 1219 warnings_with_named_vars(T0, VarNames, T). 1220warnings_with_named_vars([_|T0], VarNames, T) :- 1221 warnings_with_named_vars(T0, VarNames, T). 1222 1223 1224compiler_warnings([], _, _) --> []. 1225compiler_warnings([H|T], Clause, Options) --> 1226 ( compiler_warning(H, Clause, Options) 1227 -> [] 1228 ; [ 'Unknown compiler warning: ~W'-[H,Options] ] 1229 ), 1230 ( {T==[]} 1231 -> [] 1232 ; [nl] 1233 ), 1234 compiler_warnings(T, Clause, Options). 1235 1236compiler_warning(eq_vv(A,B), _Clause, Options) --> 1237 ( { A == B } 1238 -> [ 'Test is always true: ~W'-[A==B, Options] ] 1239 ; [ 'Test is always false: ~W'-[A==B, Options] ] 1240 ). 1241compiler_warning(eq_singleton(A,B), _Clause, Options) --> 1242 [ 'Test is always false: ~W'-[A==B, Options] ]. 1243compiler_warning(neq_vv(A,B), _Clause, Options) --> 1244 ( { A \== B } 1245 -> [ 'Test is always true: ~W'-[A\==B, Options] ] 1246 ; [ 'Test is always false: ~W'-[A\==B, Options] ] 1247 ). 1248compiler_warning(neq_singleton(A,B), _Clause, Options) --> 1249 [ 'Test is always true: ~W'-[A\==B, Options] ]. 1250compiler_warning(unify_singleton(A,B), _Clause, Options) --> 1251 [ 'Unified variable is not used: ~W'-[A=B, Options] ]. 1252compiler_warning(always(Bool, Pred, Arg), _Clause, Options) --> 1253 { Goal =.. [Pred,Arg] }, 1254 [ 'Test is always ~w: ~W'-[Bool, Goal, Options] ]. 1255compiler_warning(unbalanced_var(V), _Clause, Options) --> 1256 [ 'Variable not introduced in all branches: ~W'-[V, Options] ]. 1257compiler_warning(branch_singleton(V), _Clause, Options) --> 1258 [ 'Singleton variable in branch: ~W'-[V, Options] ]. 1259compiler_warning(negation_singleton(V), _Clause, Options) --> 1260 [ 'Singleton variable in \\+: ~W'-[V, Options] ]. 1261compiler_warning(multiton(V), _Clause, Options) --> 1262 [ 'Singleton-marked variable appears more than once: ~W'-[V, Options] ]. 1263 1264print_goal_options( 1265 [ quoted(true), 1266 portray(true) 1267 ]). 1268 1269 1270 /******************************* 1271 * TOPLEVEL MESSAGES * 1272 *******************************/ 1273 1274prolog_message(version) --> 1275 { current_prolog_flag(version_git, Version) }, 1276 !, 1277 [ '~w'-[Version] ]. 1278prolog_message(version) --> 1279 { current_prolog_flag(version_data, swi(Major,Minor,Patch,Options)) 1280 }, 1281 ( { '$option'(tag(Tag), Options) } 1282 -> [ '~w.~w.~w-~w'-[Major, Minor, Patch, Tag] ] 1283 ; [ '~w.~w.~w'-[Major, Minor, Patch] ] 1284 ). 1285prolog_message(address_bits) --> 1286 { current_prolog_flag(address_bits, Bits) 1287 }, 1288 !, 1289 [ '~d bits, '-[Bits] ]. 1290prolog_message(threads) --> 1291 { current_prolog_flag(threads, true) 1292 }, 1293 !, 1294 [ 'threaded, ' ]. 1295prolog_message(threads) --> 1296 []. 1297prolog_message(copyright) --> 1298 [ 'SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.', nl, 1299 'Please run ', ansi(code, '?- license.', []), ' for legal details.' 1300 ]. 1301prolog_message(documentaton) --> 1302 [ 'For online help and background, visit ', url('https://www.swi-prolog.org') ], 1303 ( { exists_source(library(help)) } 1304 -> [ nl, 1305 'For built-in help, use ', ansi(code, '?- help(Topic).', []), 1306 ' or ', ansi(code, '?- apropos(Word).', []) 1307 ] 1308 ; [] 1309 ). 1310prolog_message(about) --> 1311 [ 'SWI-Prolog version (' ], 1312 prolog_message(threads), 1313 prolog_message(address_bits), 1314 ['version ' ], 1315 prolog_message(version), 1316 [ ')', nl ], 1317 prolog_message(copyright). 1318prolog_message(halt) --> 1319 [ 'halt' ]. 1320prolog_message(break(begin, Level)) --> 1321 [ 'Break level ~d'-[Level] ]. 1322prolog_message(break(end, Level)) --> 1323 [ 'Exit break level ~d'-[Level] ]. 1324prolog_message(var_query(_)) --> 1325 [ '... 1,000,000 ............ 10,000,000 years later', nl, nl, 1326 '~t~8|>> 42 << (last release gives the question)' 1327 ]. 1328prolog_message(close_on_abort(Stream)) --> 1329 [ 'Abort: closed stream ~p'-[Stream] ]. 1330prolog_message(cancel_halt(Reason)) --> 1331 [ 'Halt cancelled: ~p'-[Reason] ]. 1332prolog_message(on_error(halt(Status))) --> 1333 { statistics(errors, Errors), 1334 statistics(warnings, Warnings) 1335 }, 1336 [ 'Halting with status ~w due to ~D errors and ~D warnings'- 1337 [Status, Errors, Warnings] ]. 1338 1339prolog_message(query(QueryResult)) --> 1340 query_result(QueryResult). 1341 1342query_result(no) --> % failure 1343 [ ansi(truth(false), 'false.', []) ], 1344 extra_line. 1345query_result(yes(true, [])) --> % prompt_alternatives_on: groundness 1346 !, 1347 [ ansi(truth(true), 'true.', []) ], 1348 extra_line. 1349query_result(yes(Delays, Residuals)) --> 1350 result([], Delays, Residuals), 1351 extra_line. 1352query_result(done) --> % user typed <CR> 1353 extra_line. 1354query_result(yes(Bindings, Delays, Residuals)) --> 1355 result(Bindings, Delays, Residuals), 1356 prompt(yes, Bindings, Delays, Residuals). 1357query_result(more(Bindings, Delays, Residuals)) --> 1358 result(Bindings, Delays, Residuals), 1359 prompt(more, Bindings, Delays, Residuals). 1360:- if(current_prolog_flag(emscripten, true)). 1361query_result(help) --> 1362 [ ansi(bold, ' Possible actions:', []), nl, 1363 ' ; (n,r,space): redo | t: trace&redo'-[], nl, 1364 ' *: show choicepoint | . (c,a): stop'-[], nl, 1365 ' w: write | p: print'-[], nl, 1366 ' +: max_depth*5 | -: max_depth//5'-[], nl, 1367 ' h (?): help'-[], 1368 nl, nl 1369 ]. 1370:- else. 1371query_result(help) --> 1372 [ ansi(bold, ' Possible actions:', []), nl, 1373 ' ; (n,r,space,TAB): redo | t: trace&redo'-[], nl, 1374 ' *: show choicepoint | . (c,a,RET): stop'-[], nl, 1375 ' w: write | p: print'-[], nl, 1376 ' +: max_depth*5 | -: max_depth//5'-[], nl, 1377 ' b: break | h (?): help'-[], 1378 nl, nl 1379 ]. 1380:- endif. 1381query_result(action) --> 1382 [ 'Action? '-[], flush ]. 1383query_result(confirm) --> 1384 [ 'Please answer \'y\' or \'n\'? '-[], flush ]. 1385query_result(eof) --> 1386 [ nl ]. 1387query_result(toplevel_open_line) --> 1388 []. 1389 1390prompt(Answer, [], true, []-[]) --> 1391 !, 1392 prompt(Answer, empty). 1393prompt(Answer, _, _, _) --> 1394 !, 1395 prompt(Answer, non_empty). 1396 1397prompt(yes, empty) --> 1398 !, 1399 [ ansi(truth(true), 'true.', []) ], 1400 extra_line. 1401prompt(yes, _) --> 1402 !, 1403 [ full_stop ], 1404 extra_line. 1405prompt(more, empty) --> 1406 !, 1407 [ ansi(truth(true), 'true ', []), flush ]. 1408prompt(more, _) --> 1409 !, 1410 [ ' '-[], flush ]. 1411 1412result(Bindings, Delays, Residuals) --> 1413 { current_prolog_flag(answer_write_options, Options0), 1414 Options = [partial(true)|Options0], 1415 GOptions = [priority(999)|Options0] 1416 }, 1417 wfs_residual_program(Delays, GOptions), 1418 bindings(Bindings, [priority(699)|Options]), 1419 ( {Residuals == []-[]} 1420 -> bind_delays_sep(Bindings, Delays), 1421 delays(Delays, GOptions) 1422 ; bind_res_sep(Bindings, Residuals), 1423 residuals(Residuals, GOptions), 1424 ( {Delays == true} 1425 -> [] 1426 ; [','-[], nl], 1427 delays(Delays, GOptions) 1428 ) 1429 ). 1430 1431bindings([], _) --> 1432 []. 1433bindings([binding(Names,Skel,Subst)|T], Options) --> 1434 { '$last'(Names, Name) }, 1435 var_names(Names), value(Name, Skel, Subst, Options), 1436 ( { T \== [] } 1437 -> [ ','-[], nl ], 1438 bindings(T, Options) 1439 ; [] 1440 ). 1441 1442var_names([Name]) --> 1443 !, 1444 [ ansi(binding(name), '~w', [Name]), ' = '-[] ]. 1445var_names([Name1,Name2|T]) --> 1446 !, 1447 [ ansi(binding(name), '~w', [Name1]), ' = '-[], 1448 ansi(binding(name), '~w', [Name2]), ', '-[] 1449 ], 1450 var_names([Name2|T]). 1451 1452 1453value(Name, Skel, Subst, Options) --> 1454 ( { var(Skel), Subst = [Skel=S] } 1455 -> { Skel = '$VAR'(Name) }, 1456 [ '~W'-[S, Options] ] 1457 ; [ '~W'-[Skel, Options] ], 1458 substitution(Subst, Options) 1459 ). 1460 1461substitution([], _) --> !. 1462substitution([N=V|T], Options) --> 1463 [ ', ', ansi(comment, '% where', []), nl, 1464 ' ~w = ~W'-[N,V,Options] ], 1465 substitutions(T, Options). 1466 1467substitutions([], _) --> []. 1468substitutions([N=V|T], Options) --> 1469 [ ','-[], nl, ' ~w = ~W'-[N,V,Options] ], 1470 substitutions(T, Options). 1471 1472 1473residuals(Normal-Hidden, Options) --> 1474 residuals1(Normal, Options), 1475 bind_res_sep(Normal, Hidden), 1476 ( {Hidden == []} 1477 -> [] 1478 ; [ansi(comment, '% with pending residual goals', []), nl] 1479 ), 1480 residuals1(Hidden, Options). 1481 1482residuals1([], _) --> 1483 []. 1484residuals1([G|Gs], Options) --> 1485 ( { Gs \== [] } 1486 -> [ '~W,'-[G, Options], nl ], 1487 residuals1(Gs, Options) 1488 ; [ '~W'-[G, Options] ] 1489 ). 1490 1491wfs_residual_program(true, _Options) --> 1492 !. 1493wfs_residual_program(Goal, _Options) --> 1494 { current_prolog_flag(toplevel_list_wfs_residual_program, true), 1495 '$current_typein_module'(TypeIn), 1496 ( current_predicate(delays_residual_program/2) 1497 -> true 1498 ; use_module(library(wfs), [delays_residual_program/2]) 1499 ), 1500 delays_residual_program(TypeIn:Goal, TypeIn:Program), 1501 Program \== [] 1502 }, 1503 !, 1504 [ ansi(comment, '% WFS residual program', []), nl ], 1505 [ ansi(wfs(residual_program), '~@', ['$messages':list_clauses(Program)]) ]. 1506wfs_residual_program(_, _) --> []. 1507 1508delays(true, _Options) --> 1509 !. 1510delays(Goal, Options) --> 1511 { current_prolog_flag(toplevel_list_wfs_residual_program, true) 1512 }, 1513 !, 1514 [ ansi(truth(undefined), '~W', [Goal, Options]) ]. 1515delays(_, _Options) --> 1516 [ ansi(truth(undefined), undefined, []) ]. 1517 1518:- public list_clauses/1. 1519 1520list_clauses([]). 1521list_clauses([H|T]) :- 1522 ( system_undefined(H) 1523 -> true 1524 ; portray_clause(user_output, H, [indent(4)]) 1525 ), 1526 list_clauses(T). 1527 1528system_undefined((undefined :- tnot(undefined))). 1529system_undefined((answer_count_restraint :- tnot(answer_count_restraint))). 1530system_undefined((radial_restraint :- tnot(radial_restraint))). 1531 1532bind_res_sep(_, []) --> !. 1533bind_res_sep(_, []-[]) --> !. 1534bind_res_sep([], _) --> !. 1535bind_res_sep(_, _) --> [','-[], nl]. 1536 1537bind_delays_sep([], _) --> !. 1538bind_delays_sep(_, true) --> !. 1539bind_delays_sep(_, _) --> [','-[], nl].
toplevel_extra_white_line is true, add an
empty line. The ~N cannot be replaced by nl because the answer
is not always left at a non-empty line. The eol element paints
the remainder of the line if the message has a background colour,
which ~N cannot do as it is written using format/3.
Note that eol ends the last line of the answer. The empty
line that separates the answer from the next query is not part of
the answer and keeps the default background.
1553extra_line --> 1554 { current_prolog_flag(toplevel_extra_white_line, true) }, 1555 !, 1556 [eol, '~N'-[]]. 1557extra_line --> 1558 [eol]. 1559 1560prolog_message(if_tty(Message)) --> 1561 ( {current_prolog_flag(tty_control, true)} 1562 -> [ at_same_line ], list(Message) 1563 ; [] 1564 ). 1565prolog_message(halt(Reason)) --> 1566 [ '~w: halt'-[Reason] ]. 1567prolog_message(no_action(Char)) --> 1568 [ 'Unknown action: ~c (h for help)'-[Char], nl ]. 1569 1570prolog_message(history(help(Show, Help))) --> 1571 [ 'History Commands:', nl, 1572 ' !!. Repeat last query', nl, 1573 ' !nr. Repeat query numbered <nr>', nl, 1574 ' !str. Repeat last query starting with <str>', nl, 1575 ' !?str. Repeat last query holding <str>', nl, 1576 ' ^old^new. Substitute <old> into <new> of last query', nl, 1577 ' !nr^old^new. Substitute in query numbered <nr>', nl, 1578 ' !str^old^new. Substitute in query starting with <str>', nl, 1579 ' !?str^old^new. Substitute in query holding <str>', nl, 1580 ' ~w.~21|Show history list'-[Show], nl, 1581 ' ~w.~21|Show this list'-[Help], nl, nl 1582 ]. 1583prolog_message(history(no_event)) --> 1584 [ '! No such event' ]. 1585prolog_message(history(bad_substitution)) --> 1586 [ '! Bad substitution' ]. 1587prolog_message(history(expanded(Event))) --> 1588 [ '~w.'-[Event] ]. 1589prolog_message(history(history(Events))) --> 1590 history_events(Events). 1591prolog_message(history(no_history)) --> 1592 [ '! event history not supported in this version' ]. 1593 1594history_events([]) --> 1595 []. 1596history_events([Nr-Event|T]) --> 1597 [ ansi(comment, '%', []), 1598 ansi(bold, '~t~w ~6|', [Nr]), 1599 ansi(code, '~s', [Event]), 1600 nl 1601 ], 1602 history_events(T).
welcome message to print information registered
using version/1.1610user_version_messages([]) --> []. 1611user_version_messages([H|T]) --> 1612 user_version_message(H), 1613 user_version_messages(T).
1617user_version_message(Term) --> 1618 translate_message(Term), !, [nl]. 1619user_version_message(Atom) --> 1620 [ '~w'-[Atom], nl ]. 1621 1622 1623 /******************************* 1624 * DEBUGGER MESSAGES * 1625 *******************************/ 1626 1627prolog_message(spy(Head)) --> 1628 [ 'New spy point on ' ], 1629 predicate_reference(Head). 1630prolog_message(already_spying(Head)) --> 1631 [ 'Already spying ' ], 1632 predicate_reference(Head). 1633prolog_message(nospy(Head)) --> 1634 [ 'Removed spy point from ' ], 1635 predicate_reference(Head). 1636prolog_message(trace_mode(OnOff)) --> 1637 [ 'Trace mode switched to ~w'-[OnOff] ]. 1638prolog_message(debug_mode(OnOff)) --> 1639 [ 'Debug mode switched to ~w'-[OnOff] ]. 1640prolog_message(debugging(OnOff, Threads)) --> 1641 [ 'Debug mode is ~w'-[OnOff] ], 1642 debugging_threads(Threads). 1643prolog_message(spying([])) --> 1644 !, 1645 [ 'No spy points' ]. 1646prolog_message(spying(Heads)) --> 1647 [ 'Spy points (see spy/1) on:', nl ], 1648 predicate_list(Heads). 1649prolog_message(trace(Head, [])) --> 1650 !, 1651 [ ' ' ], predicate_reference(Head, [tag(true)]), 1652 [ ' Not tracing'-[], nl]. 1653prolog_message(trace(Head, Ports)) --> 1654 { '$member'(Port, Ports), compound(Port), 1655 !, 1656 numbervars(Head+Ports, 0, _, [singletons(true)]) 1657 }, 1658 [ ' ~p: ~p'-[Head,Ports] ]. 1659prolog_message(trace(Head, Ports)) --> 1660 [ ' ' ], predicate_reference(Head, [tag(true)]), 1661 [ ': ~w'-[Ports], nl]. 1662prolog_message(tracing([])) --> 1663 !, 1664 [ 'No traced predicates (see trace/1,2)' ]. 1665prolog_message(tracing(Heads)) --> 1666 [ 'Trace points (see trace/1,2) on:', nl ], 1667 tracing_list(Heads).
1674predicate_list([]) --> 1675 []. 1676predicate_list([H|T]) --> 1677 [ ' ' ], predicate_reference(H, [tag(true)]), [nl], 1678 predicate_list(T). 1679 1680tracing_list([]) --> 1681 []. 1682tracing_list([trace(Head, Ports)|T]) --> 1683 translate_message(trace(Head, Ports)), 1684 tracing_list(T). 1685 1686debugging_threads([]) --> 1687 []. 1688debugging_threads(ThreadsByClass) --> 1689 [ nl, 'Threads in the following classes run in debug mode:', nl], 1690 list_threads_by_class(ThreadsByClass). 1691 1692list_threads_by_class([]) --> 1693 []. 1694list_threads_by_class([H|T]) --> 1695 list_thread_class(H), 1696 list_threads_by_class(T). 1697 1698list_thread_class(Class-Threads) --> 1699 { length(Threads, Count) }, 1700 [ ' Class ', ansi(code, '~p', [Class]), ': ~D threads'-[Count] ]. 1701 1702% frame(+Frame, +Choice, +Port, +PC) - Print for the debugger. 1703prolog_message(frame(Frame, _Choice, backtrace, _PC)) --> 1704 !, 1705 { prolog_frame_attribute(Frame, level, Level) 1706 }, 1707 [ ansi(frame(level), '~t[~D] ~10|', [Level]) ], 1708 frame_context(Frame), 1709 frame_goal(Frame, backtrace). 1710prolog_message(frame(Frame, Choice, choice, PC)) --> 1711 !, 1712 prolog_message(frame(Frame, Choice, backtrace, PC)). 1713prolog_message(frame(_, _Choice, cut_call(_PC), _)) --> !. 1714prolog_message(frame(Frame, _Choice, Port, _PC)) --> 1715 frame_flags(Frame), 1716 port(Port), 1717 frame_level(Frame), 1718 frame_context(Frame), 1719 frame_depth_limit(Port, Frame), 1720 frame_goal(Frame, Port), 1721 [ flush ]. 1722 1723% frame(:Goal, +Trace) - Print for trace/2 1724prolog_message(frame(Goal, trace(Port))) --> 1725 !, 1726 thread_context, 1727 [ ' T ' ], 1728 port(Port), 1729 predicate_goal(Goal, Port). 1730prolog_message(frame(Goal, trace(Port, Id))) --> 1731 !, 1732 thread_context, 1733 [ ' T ' ], 1734 port(Port, Id), 1735 predicate_goal(Goal, Port).
goal(Port, Parity), which allows
themes to decorate the goal depending on the port, on the parity of
the step count (striping, which separates the steps of a trace
visually) or both. See also '$answer_class'/1, which does the same
for the answers of the interactive toplevel.1746goal_style(Port0, goal(Port, Parity)) :- 1747 functor(Port0, Port, _), 1748 trace_parity(Parity). 1749 1750trace_parity(Parity) :- 1751 ( nb_current('$trace_step', C0) 1752 -> true 1753 ; C0 = 0 1754 ), 1755 C is C0+1, 1756 nb_setval('$trace_step', C), 1757 ( C mod 2 =:= 0 1758 -> Parity = even 1759 ; Parity = odd 1760 ). 1761 1762frame_goal(Frame, Port) --> 1763 { prolog_frame_attribute(Frame, goal, Goal), 1764 goal_style(Port, Style) 1765 }, 1766 ( { frame_location(Frame, Location) } 1767 -> goal(Goal, Style, Location) 1768 ; goal(Goal, Style) 1769 ).
1776predicate_goal(Goal, Port) --> 1777 { goal_style(Port, Style) 1778 }, 1779 ( { goal_links, 1780 predicate_location(Goal, Location) 1781 } 1782 -> goal(Goal, Style, Location) 1783 ; goal(Goal, Style) 1784 ). 1785 1786goal(Goal0, Style) --> 1787 { goal_format(Goal0, Goal, Options) 1788 }, 1789 [ ansi(Style, '~W', [Goal, Options]) ]. 1790 1791goal(Goal0, Style, Location) --> 1792 { goal_format(Goal0, Goal, Options) 1793 }, 1794 [ url(Location, ansi(Style, '~W', [Goal, Options])) ]. 1795 1796goal_format(Goal0, Goal, Options) :- 1797 clean_goal(Goal0, Goal), 1798 current_prolog_flag(debugger_write_options, Options).
File:Line for the call site of Frame, i.e., the place
in the clause of the parent frame from which Frame was called. This
is the position the user is at while tracing. If we cannot find it,
fall back to the clause that runs in Frame and finally to the file
that defines the predicate.
Resolving the call site uses library(prolog_stack), which has to run the decompiler and read the source file. This is affordable for an interactive tracer, but we only do it if the location can actually be used, i.e., if hyperlinks are rendered. See goal_links/0.
1813frame_location(Frame, Location) :- 1814 goal_links, 1815 catch(frame_location_(Frame, Location), _, fail). 1816 1817frame_location_(Frame, File:Line) :- 1818 prolog_frame_attribute(Frame, pc, PC), 1819 prolog_frame_attribute(Frame, parent, Parent), 1820 prolog_frame_attribute(Parent, clause, Clause), 1821 prolog_stack_frame_property(frame(_,clause(Clause,PC),_), 1822 location(File:Line)), 1823 !. 1824frame_location_(Frame, File:Line) :- 1825 prolog_frame_attribute(Frame, clause, Clause), 1826 clause_property(Clause, file(File)), 1827 clause_property(Clause, line_count(Line)), 1828 !. 1829frame_location_(Frame, Location) :- 1830 prolog_frame_attribute(Frame, goal, Goal), 1831 predicate_location(Goal, Location).
debugger_goal_links, which
is one of true, false or auto. Using auto (default) we create
the links if the console can render them.1840goal_links :- 1841 current_prolog_flag(debugger_goal_links, Links), 1842 goal_links(Links). 1843 1844goal_links(true). % note: no clause for `false` 1845goal_links(auto) :- 1846 ( current_prolog_flag(hyperlink_term, true) 1847 -> true 1848 ; predicate_property(ansi_term:hyperlink(_,_), number_of_clauses(N)), 1849 N > 0 1850 ). 1851 1852frame_level(Frame) --> 1853 { prolog_frame_attribute(Frame, level, Level) 1854 }, 1855 [ '(~D) '-[Level] ]. 1856 1857frame_context(Frame) --> 1858 ( { current_prolog_flag(debugger_show_context, true), 1859 prolog_frame_attribute(Frame, context_module, Context) 1860 } 1861 -> [ '[~w] '-[Context] ] 1862 ; [] 1863 ). 1864 1865frame_depth_limit(fail, Frame) --> 1866 { prolog_frame_attribute(Frame, depth_limit_exceeded, true) 1867 }, 1868 !, 1869 [ '[depth-limit exceeded] ' ]. 1870frame_depth_limit(_, _) --> 1871 []. 1872 1873frame_flags(Frame) --> 1874 { prolog_frame_attribute(Frame, goal, Goal), 1875 ( predicate_property(Goal, transparent) 1876 -> T = '^' 1877 ; T = ' ' 1878 ), 1879 ( predicate_property(Goal, spying) 1880 -> S = '*' 1881 ; S = ' ' 1882 ) 1883 }, 1884 [ '~w~w '-[T, S] ]. 1885 1886% trace/1 context handling 1887port(Port, Dict) --> 1888 { _{level:Level, start:Time} :< Dict 1889 }, 1890 ( { Port \== call, 1891 get_time(Now), 1892 Passed is (Now - Time)*1000.0 1893 } 1894 -> [ '[~d +~1fms] '-[Level, Passed] ] 1895 ; [ '[~d] '-[Level] ] 1896 ), 1897 port(Port). 1898port(Port, _Id-Level) --> 1899 [ '[~d] '-[Level] ], 1900 port(Port). 1901 1902port(PortTerm) --> 1903 { functor(PortTerm, Port, _), 1904 port_name(Port, Name) 1905 }, 1906 !, 1907 [ ansi(port(Port), '~w: ', [Name]) ]. 1908 1909port_name(call, 'Call'). 1910port_name(exit, 'Exit'). 1911port_name(fail, 'Fail'). 1912port_name(redo, 'Redo'). 1913port_name(unify, 'Unify'). 1914port_name(exception, 'Exception'). 1915 1916clean_goal(M:Goal, Goal) :- 1917 hidden_module(M), 1918 !. 1919clean_goal(M:Goal, Goal) :- 1920 predicate_property(M:Goal, built_in), 1921 !. 1922clean_goal(Goal, Goal). 1923 1924 1925 /******************************* 1926 * COMPATIBILITY * 1927 *******************************/ 1928 1929prolog_message(compatibility(renamed(Old, New))) --> 1930 [ 'The predicate ' ], predicate_reference(Old, [link(false)]), 1931 [ ' has been renamed to ' ], predicate_reference(New), 1932 [ '.', nl, 1933 'Please update your sources for compatibility with future versions.' 1934 ]. 1935 1936 1937 /******************************* 1938 * THREADS * 1939 *******************************/ 1940 1941prolog_message(abnormal_thread_completion(Goal, exception(Ex))) --> 1942 !, 1943 [ 'Thread running "~p" died on exception: '-[Goal] ], 1944 translate_message(Ex). 1945prolog_message(abnormal_thread_completion(Goal, fail)) --> 1946 [ 'Thread running "~p" died due to failure'-[Goal] ]. 1947prolog_message(threads_not_died(Running)) --> 1948 [ 'The following threads wouldn\'t die: ~p'-[Running] ]. 1949 1950 1951 /******************************* 1952 * PACKS * 1953 *******************************/ 1954 1955prolog_message(pack(attached(Pack, BaseDir))) --> 1956 [ 'Attached package ~w at ~q'-[Pack, BaseDir] ]. 1957prolog_message(pack(duplicate(Entry, OldDir, Dir))) --> 1958 [ 'Package ~w already attached at ~q.'-[Entry,OldDir], nl, 1959 '\tIgnoring version from ~q'- [Dir] 1960 ]. 1961prolog_message(pack(no_arch(Entry, Arch))) --> 1962 [ 'Package ~w: no binary for architecture ~w'-[Entry, Arch] ]. 1963 1964 /******************************* 1965 * MISC * 1966 *******************************/ 1967 1968prolog_message(null_byte_in_path(Component)) --> 1969 [ '0-byte in PATH component: ~p (skipped directory)'-[Component] ]. 1970prolog_message(invalid_tmp_dir(Dir, Reason)) --> 1971 [ 'Cannot use ~p as temporary file directory: ~w'-[Dir, Reason] ]. 1972prolog_message(ambiguous_stream_pair(Pair)) --> 1973 [ 'Ambiguous operation on stream pair ~p'-[Pair] ]. 1974prolog_message(backcomp(init_file_moved(FoundFile))) --> 1975 { absolute_file_name(app_config('init.pl'), InitFile, 1976 [ file_errors(fail) 1977 ]) 1978 }, 1979 [ 'The location of the config file has moved'-[], nl, 1980 ' from "~w"'-[FoundFile], nl, 1981 ' to "~w"'-[InitFile], nl, 1982 ' See https://www.swi-prolog.org/modified/config-files.html'-[] 1983 ]. 1984prolog_message(not_accessed_flags(List)) --> 1985 [ 'The following Prolog flags have been set but not used:', nl ], 1986 flags(List). 1987prolog_message(implicit_create_flag(Flag)) --> 1988 [ 'Created unknown Prolog flag ', ansi(code, '~q', Flag), 1989 ' (see create_prolog_flag/3)' 1990 ]. 1991prolog_message(prolog_flag_invalid_preset(Flag, Preset, _Type, New)) --> 1992 [ 'Prolog flag ', ansi(code, '~q', Flag), ' has been (re-)created with a type that is \c 1993 incompatible with its value.', nl, 1994 'Value updated from ', ansi(code, '~p', [Preset]), ' to default (', 1995 ansi(code, '~p', [New]), ')' 1996 ]. 1997 1998 1999flags([H|T]) --> 2000 [' ', ansi(code, '~q', [H])], 2001 ( {T == []} 2002 -> [] 2003 ; [nl], 2004 flags(T) 2005 ). 2006 2007 2008 /******************************* 2009 * DEPRECATED * 2010 *******************************/ 2011 2012deprecated(set_prolog_stack(_Stack,limit)) --> 2013 [ 'set_prolog_stack/2: limit(Size) sets the combined limit.'-[], nl, 2014 'See https://www.swi-prolog.org/changes/stack-limit.html' 2015 ]. 2016deprecated(autoload(TargetModule, File, _M:PI, expansion)) --> 2017 !, 2018 [ 'Auto-loading ' ], predicate_reference(PI, [link(false)]), 2019 [ ' from ' ], 2020 load_file(File), [ ' into ' ], 2021 target_module(TargetModule), 2022 [ ' is deprecated due to term- or goal-expansion' ]. 2023deprecated(source_search_working_directory(File, _FullFile)) --> 2024 [ 'Found file ', ansi(code, '~w', [File]), 2025 ' relative to the current working directory.', nl, 2026 'This behaviour is deprecated but still supported by', nl, 2027 'the Prolog flag ', 2028 ansi(code, source_search_working_directory, []), '.', nl 2029 ]. 2030deprecated(moved_library(Old, New)) --> 2031 [ 'Library was moved: ~q --> ~q'-[Old, New] ]. 2032 2033load_file(File) --> 2034 { file_base_name(File, Base), 2035 absolute_file_name(library(Base), File, [access(read), file_errors(fail)]), 2036 file_name_extension(Clean, pl, Base) 2037 }, 2038 !, 2039 [ ansi(code, '~p', [library(Clean)]) ]. 2040load_file(File) --> 2041 [ url(File) ]. 2042 2043target_module(Module) --> 2044 { module_property(Module, file(File)) }, 2045 !, 2046 load_file(File). 2047target_module(Module) --> 2048 [ 'module ', ansi(code, '~p', [Module]) ]. 2049 2050 2051 2052 /******************************* 2053 * TRIPWIRES * 2054 *******************************/ 2055 2056tripwire_message(max_integer_size, Bytes) --> 2057 !, 2058 [ 'Trapped tripwire max_integer_size: big integers and \c 2059 rationals are limited to ~D bytes'-[Bytes] ]. 2060tripwire_message(Wire, Context) --> 2061 [ 'Trapped tripwire ~w for '-[Wire] ], 2062 tripwire_context(Wire, Context). 2063 2064tripwire_context(_, ATrie) --> 2065 { '$is_answer_trie'(ATrie, _), 2066 !, 2067 '$tabling':atrie_goal(ATrie, QGoal), 2068 clean_goal(QGoal, Goal) % a goal, not a predicate indicator 2069 }, 2070 [ '~p'-[Goal] ]. 2071tripwire_context(_, Ctx) --> 2072 [ '~p'-[Ctx] ]. 2073 2074 2075 /******************************* 2076 * INTERNATIONALIZATION * 2077 *******************************/ 2078 2079:- create_prolog_flag(message_language, default, []).
nl_BE) and ends with en.2086message_lang(Lang) :- 2087 current_message_lang(Lang0), 2088 ( Lang0 == en 2089 -> Lang = en 2090 ; sub_atom(Lang0, 0, _, _, en_) 2091 -> longest_id(Lang0, Lang) 2092 ; ( longest_id(Lang0, Lang) 2093 ; Lang = en 2094 ) 2095 ). 2096 2097longest_id(Lang, Id) :- 2098 split_string(Lang, "_-", "", [H|Components]), 2099 longest_prefix(Components, Taken), 2100 atomic_list_concat([H|Taken], '_', Id). 2101 2102longest_prefix([H|T0], [H|T]) :- 2103 longest_prefix(T0, T). 2104longest_prefix(_, []).
2110current_message_lang(Lang) :- 2111 ( current_prolog_flag(message_language, Lang0), 2112 Lang0 \== default 2113 -> Lang = Lang0 2114 ; os_user_lang(Lang0) 2115 -> clean_encoding(Lang0, Lang1), 2116 set_prolog_flag(message_language, Lang1), 2117 Lang = Lang1 2118 ; Lang = en 2119 ). 2120 2121os_user_lang(Lang) :- 2122 current_prolog_flag(windows, true), 2123 win_get_user_preferred_ui_languages(name, [Lang|_]). 2124os_user_lang(Lang) :- 2125 catch(setlocale(messages, _, ''), _, fail), 2126 setlocale(messages, Lang, Lang). 2127os_user_lang(Lang) :- 2128 getenv('LANG', Lang). 2129 2130 2131clean_encoding(Lang0, Lang) :- 2132 ( sub_atom(Lang0, A, _, _, '.') 2133 -> sub_atom(Lang0, 0, A, _, Lang) 2134 ; Lang = Lang0 2135 ). 2136 2137 /******************************* 2138 * PRIMITIVES * 2139 *******************************/ 2140 2141code(Term) --> 2142 code('~p', Term). 2143 2144code(Format, Term) --> 2145 [ ansi(code, Format, [Term]) ]. 2146 2147list([]) --> []. 2148list([H|T]) --> [H], list(T). 2149 2150 2151 /******************************* 2152 * PREDICATE REFERENCES * 2153 *******************************/
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.
2170:- public 2171 predicate_indicator/2. 2172 2173predicate_indicator(Spec, QPI) :- 2174 strip_module(user:Spec, Module, Spec1), 2175 ( is_predicate_indicator(Spec1) 2176 -> dcg_indicator(Module, Spec1, QPI) 2177 ; callable(Spec1), 2178 '$pi_head'(Module:PI, Module:Spec1), 2179 dcg_indicator(Module, PI, QPI) 2180 ).
// notation if the predicate
is a non-terminal.2187dcg_indicator(Module, Name//DCGArity, Module:Name//DCGArity) :- 2188 !. 2189dcg_indicator(Module, Name/Arity, QPI) :- 2190 ( Arity >= 2, 2191 current_predicate(Module:Name/Arity), 2192 functor(Head, Name, Arity), 2193 predicate_property(Module:Head, non_terminal) 2194 -> DCGArity is Arity-2, 2195 QPI = Module:Name//DCGArity 2196 ; QPI = Module:Name/Arity 2197 ).
user.2205predicate_head(Spec, QHead) :- 2206 strip_module(user:Spec, Module, Spec1), 2207 ( is_predicate_indicator(Spec1) 2208 -> '$pi_head'(Module:Spec1, QHead) 2209 ; callable(Spec1), 2210 QHead = Module:Spec1 2211 ). 2212 2213is_predicate_indicator(Name/Arity) :- 2214 atomic(Name), integer(Arity). 2215is_predicate_indicator(Name//Arity) :- 2216 atomic(Name), integer(Arity).
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:
auto (default), hide or show. Using auto, the
module qualification is removed if hidden_module/1 holds for it.false, do not try to create a hyperlink. Default true.code.true, add a tag that indicates the kind of predicate.
See predicate_kind/2. Default false. Only sensible if the
reference is the only thing on the line.
If Spec cannot be interpreted as a predicate it is printed using the
code class and ~p, i.e., we never fail on a malformed message.
2242:- public 2243 predicate_reference//1, 2244 predicate_reference//2. 2245 2246predicate_reference(Spec) --> 2247 predicate_reference(Spec, []). 2248 2249predicate_reference(Spec, Options) --> 2250 { predicate_indicator(Spec, QPI) }, 2251 !, 2252 { pref_option(style(Style), Options, code), 2253 pref_option(module(Mode), Options, auto), 2254 reference_pi(Mode, QPI, PI) 2255 }, 2256 predicate_link(QPI, ansi(Style, '~q', [PI]), Options), 2257 predicate_reference_tag(QPI, Options). 2258predicate_reference(Spec, _Options) --> 2259 [ ansi(code, '~p', [Spec]) ]. 2260 2261reference_pi(auto, QPI, PI) :- 2262 !, 2263 user_predicate_indicator(QPI, PI). 2264reference_pi(hide, _:PI, PI) :- !. 2265reference_pi(_, QPI, QPI). 2266 2267predicate_link(QPI, Label, Options) --> 2268 { pref_option(link(true), Options, true), 2269 predicate_location(QPI, Location) 2270 }, 2271 !, 2272 [ url(Location, Label) ]. 2273predicate_link(_, Label, _) --> 2274 [ Label ].
boot/messages.pl must
be able to print a message before the libraries are available.
2283pref_option(Option, Options, Default) :-
2284 functor(Option, Name, 1),
2285 functor(General, Name, 1),
2286 ( memberchk(General, Options)
2287 -> General = Option
2288 ; arg(1, Option, Default)
2289 ).File:Line for the definition of the predicate Spec.
Also deals with predicates defined in C. Note that predicates that
are not loaded but can be autoloaded are located from the autoload
index, i.e., printing a message never loads a library.2298:- public 2299 predicate_location/2. 2300 2301predicate_location(Spec, Location) :- 2302 predicate_head(Spec, Head), 2303 current_predicate(_, Head), % do not (auto)load 2304 '$predicate_source_location'(Head, Location).
2311:- public 2312 predicate_definition//2. 2313 2314predicate_definition(Spec, Message) --> 2315 { predicate_location(Spec, Location) }, 2316 !, 2317 [ nl, '~w at '-[Message], url(Location) ]. 2318predicate_definition(_, _) --> 2319 [].
library(Name)module(Module)2335:- public 2336 predicate_kind/2. 2337 2338predicate_kind(Spec, Kind) :- 2339 predicate_head(Spec, Head), 2340 ( current_predicate(_, Head) % do not autoload 2341 -> defined_predicate_kind(Head, Kind) 2342 ; predicate_property(Head, autoload(File)) 2343 -> library_name(File, Name), 2344 Kind = library(Name) 2345 ; Kind = undefined 2346 ). 2347 2348defined_predicate_kind(Head, Kind) :- 2349 ( predicate_property(Head, iso) 2350 -> Kind = iso 2351 ; predicate_property(Head, built_in) 2352 -> ( predicate_property(Head, foreign) 2353 -> Kind = foreign 2354 ; Kind = built_in 2355 ) 2356 ; predicate_property(Head, imported_from(Module)) 2357 -> module_kind(Module, Kind) 2358 ; predicate_property(Head, file(File)), 2359 library_file(File) 2360 -> library_name(File, Name), 2361 Kind = library(Name) 2362 ; Kind = user 2363 ). 2364 2365module_kind(Module, Kind) :- 2366 ( hidden_module(Module) 2367 -> Kind = user 2368 ; module_property(Module, file(File)), 2369 library_file(File) 2370 -> library_name(File, Name), 2371 Kind = library(Name) 2372 ; Kind = module(Module) 2373 ).
library(Name).2381library_file(File) :- 2382 absolute_file_name(library(.), LibDir, 2383 [ file_type(directory), 2384 solutions(all), 2385 file_errors(fail) 2386 ]), 2387 sub_atom(File, 0, _, _, LibDir), 2388 !. 2389 2390library_name(File, Name) :- 2391 ( file_name_extension(Base, Ext, File), 2392 Ext \== '' 2393 -> true 2394 ; Base = File 2395 ), 2396 file_base_name(Base, Name).
2403predicate_reference_tag(QPI, Options) --> 2404 { pref_option(tag(true), Options, false), 2405 predicate_kind(QPI, Kind) 2406 }, 2407 !, 2408 predicate_kind_tag(Kind). 2409predicate_reference_tag(_, _) --> 2410 []. 2411 2412predicate_kind_tag(Kind) --> 2413 { predicate_kind_label(Kind, Label) }, 2414 [ ansi(predicate(Kind), ' [~w]', [Label]) ]. 2415 2416predicate_kind_label(iso, 'ISO'). 2417predicate_kind_label(built_in, 'built-in'). 2418predicate_kind_label(foreign, 'built-in'). 2419predicate_kind_label(user, 'user'). 2420predicate_kind_label(undefined, 'undefined'). 2421predicate_kind_label(library(Name), Label) :- 2422 format(atom(Label), 'library(~w)', [Name]). 2423predicate_kind_label(module(Name), Name). 2424 2425 2426 /******************************* 2427 * DEFAULT THEME * 2428 *******************************/ 2429 2430:- multifile 2431 prolog:theme/1, 2432 prolog:theme_base/2. 2433:- public 2434 current_theme/1, 2435 theme_ancestor/2, 2436 default_theme/2.
theme, unless this is default or auto. In that case it is
the theme of a loaded theme file, e.g., a file loaded from the
init file or by library(theme/auto). If no theme file is loaded,
Theme is default.2447current_theme(Theme) :- 2448 current_prolog_flag(theme, Selected), 2449 Selected \== default, 2450 Selected \== auto, 2451 !, 2452 Theme = Selected. 2453current_theme(Theme) :- 2454 prolog:theme(Loaded), 2455 !, 2456 Theme = Loaded. 2457current_theme(default).
2466theme_ancestor(Theme, Ancestor) :- 2467 theme_ancestor(Theme, [Theme], Ancestor). 2468 2469theme_ancestor(Theme, _, Theme). 2470theme_ancestor(Theme, Seen, Ancestor) :- 2471 prolog:theme_base(Theme, Base), 2472 !, 2473 \+ memberchk(Base, Seen), 2474 theme_ancestor(Base, [Base|Seen], Ancestor). 2475 2476 2477default_theme(var, [fg(red)]). 2478default_theme(code, [fg(blue)]). 2479default_theme(comment, [fg(green)]). 2480default_theme(warning, [fg(red)]). 2481default_theme(error, [bold, fg(red)]). 2482default_theme(truth(false), [bold, fg(red)]). 2483default_theme(truth(true), [bold]). 2484default_theme(truth(undefined), [bold, fg(cyan)]). 2485default_theme(wfs(residual_program), [fg(cyan)]). 2486default_theme(frame(level), [bold]). 2487default_theme(goal(_,_), []). 2488default_theme(port(call), [bold, fg(green)]). 2489default_theme(port(exit), [bold, fg(green)]). 2490default_theme(port(fail), [bold, fg(red)]). 2491default_theme(port(redo), [bold, fg(yellow)]). 2492default_theme(port(unify), [bold, fg(blue)]). 2493default_theme(port(exception), [bold, fg(magenta)]). 2494default_theme(prompt, [bold]). 2495default_theme(input, []). 2496default_theme(answer(_), []). 2497default_theme(binding(name), [bold]). 2498default_theme(predicate(iso), [italic, fg(cyan)]). 2499default_theme(predicate(built_in), [italic, fg(cyan)]). 2500default_theme(predicate(foreign), [italic, fg(cyan)]). 2501default_theme(predicate(library(_)), [italic, fg(green)]). 2502default_theme(predicate(module(_)), [italic, fg(green)]). 2503default_theme(predicate(user), [italic, fg(default)]). 2504default_theme(predicate(undefined), [italic, fg(red)]). 2505default_theme(message(informational), [fg(green)]). 2506default_theme(message(information), [fg(green)]). 2507default_theme(message(debug(_)), [fg(blue)]). 2508default_theme(message(Level), Attrs) :- 2509 nonvar(Level), 2510 default_theme(Level, Attrs). 2511 2512 2513 /******************************* 2514 * PRINTING MESSAGES * 2515 *******************************/ 2516 2517:- multifile 2518 user:message_hook/3, 2519 prolog:message_prefix_hook/2. 2520:- dynamic 2521 user:message_hook/3, 2522 prolog:message_prefix_hook/2. 2523:- thread_local 2524 user:thread_message_hook/3. 2525:- '$notransact'((user:message_hook/3, 2526 prolog:message_prefix_hook/2, 2527 user:thread_message_hook/3)).
2534print_message(Level, _Term) :- 2535 msg_property(Level, stream(S)), 2536 stream_property(S, error(true)), 2537 !. 2538print_message(Level, Term) :- 2539 setup_call_cleanup( 2540 notrace(push_msg(Term, Stack)), 2541 ignore(print_message_guarded(Level, Term)), 2542 notrace(pop_msg(Stack))), 2543 !. 2544print_message(Level, Term) :- 2545 ( Level \== silent 2546 -> format(user_error, 'Recursive ~w message: ~q~n', [Level, Term]), 2547 autoload_call(backtrace(20)) 2548 ; true 2549 ). 2550 2551push_msg(Term, Messages) :- 2552 nb_current('$inprint_message', Messages), 2553 !, 2554 \+ ( '$member'(Msg, Messages), 2555 Msg =@= Term 2556 ), 2557 Stack = [Term|Messages], 2558 b_setval('$inprint_message', Stack). 2559push_msg(Term, []) :- 2560 b_setval('$inprint_message', [Term]). 2561 2562pop_msg(Stack) :- 2563 nb_delete('$inprint_message'), % delete history 2564 b_setval('$inprint_message', Stack). 2565 2566print_message_guarded(Level, Term) :- 2567 ( must_print(Level, Term) 2568 -> ( prolog:message_action(Term, Level), 2569 fail % forall/2 is cleaner, but not yet 2570 ; true % defined 2571 ), 2572 ( translate_message(Term, Lines, []) 2573 -> ( nonvar(Term), 2574 ( notrace(user:thread_message_hook(Term, Level, Lines)) 2575 -> true 2576 ; notrace(user:message_hook(Term, Level, Lines)) 2577 ) 2578 -> true 2579 ; '$inc_message_count'(Level), 2580 print_system_message(Term, Level, Lines), 2581 maybe_halt_on_error(Level) 2582 ) 2583 ) 2584 ; true 2585 ). 2586 2587maybe_halt_on_error(error) :- 2588 current_prolog_flag(on_error, halt), 2589 !, 2590 halt(1). 2591maybe_halt_on_error(warning) :- 2592 current_prolog_flag(on_warning, halt), 2593 !, 2594 halt(1). 2595maybe_halt_on_error(_).
2605print_system_message(_, silent, _) :- !. 2606print_system_message(_, informational, _) :- 2607 current_prolog_flag(verbose, silent), 2608 !. 2609print_system_message(_, banner, _) :- 2610 current_prolog_flag(verbose, silent), 2611 !. 2612print_system_message(_, _, []) :- !. 2613print_system_message(Term, Kind, Lines) :- 2614 catch(flush_output(user_output), _, true), % may not exist 2615 source_location(File, Line), 2616 Term \= error(syntax_error(_), _), 2617 msg_property(Kind, location_prefix(File:Line, LocPrefix, LinePrefix)), 2618 !, 2619 to_list(LocPrefix, LocPrefixL), 2620 insert_prefix(Lines, LinePrefix, Ctx, PrefixLines), 2621 '$append'([ [begin(Kind, Ctx)], 2622 LocPrefixL, 2623 [nl], 2624 PrefixLines, 2625 [end(Ctx)] 2626 ], 2627 AllLines), 2628 msg_property(Kind, stream(Stream)), 2629 ignore(stream_property(Stream, position(Pos))), 2630 print_message_lines(Stream, AllLines), 2631 ( \+ stream_property(Stream, position(Pos)), 2632 msg_property(Kind, wait(Wait)), 2633 Wait > 0 2634 -> sleep(Wait) 2635 ; true 2636 ). 2637print_system_message(_, Kind, Lines) :- 2638 msg_property(Kind, stream(Stream)), 2639 print_message_lines(Stream, kind(Kind), Lines). 2640 2641to_list(ListIn, List) :- 2642 is_list(ListIn), 2643 !, 2644 List = ListIn. 2645to_list(NonList, [NonList]). 2646 2647:- multifile 2648 user:message_property/2. 2649 2650msg_property(Kind, Property) :- 2651 notrace(user:message_property(Kind, Property)), 2652 !. 2653msg_property(Kind, prefix(Prefix)) :- 2654 msg_prefix(Kind, Prefix), 2655 !. 2656msg_property(_, prefix('~N')) :- !. 2657msg_property(query, color_class(Class)) :- 2658 !, 2659 '$answer_class'(Class). 2660msg_property(query, stream(user_output)) :- !. 2661msg_property(_, stream(user_error)) :- !. 2662msg_property(error, tag('ERROR')). 2663msg_property(warning, tag('Warning')). 2664msg_property(Level, 2665 location_prefix(File:Line, 2666 ['~N~w: '-[Tag], url(File:Line), ':'], 2667 '~N~w: '-[Tag])) :- 2668 include_msg_location(Level), 2669 msg_property(Level, tag(Tag)). 2670msg_property(error, wait(0.1)) :- !. 2671 2672include_msg_location(warning). 2673include_msg_location(error). 2674 2675msg_prefix(debug(_), Prefix) :- 2676 msg_context('~N% ', Prefix). 2677msg_prefix(Level, Prefix) :- 2678 msg_property(Level, tag(Tag)), 2679 atomics_to_string(['~N', Tag, ': '], Prefix0), 2680 msg_context(Prefix0, Prefix). 2681msg_prefix(informational, '~N% '). 2682msg_prefix(information, '~N% ').
message_context. Recognised context terms are:
time(Format)In addition, the hook message_prefix_hook/2 is called that allows for additional context information.
2696msg_context(Prefix0, Prefix) :- 2697 current_prolog_flag(message_context, Context), 2698 is_list(Context), 2699 !, 2700 add_message_context(Context, Prefix0, Prefix). 2701msg_context(Prefix, Prefix). 2702 2703add_message_context([], Prefix, Prefix). 2704add_message_context([H|T], Prefix0, Prefix) :- 2705 ( add_message_context1(H, Prefix0, Prefix1) 2706 -> true 2707 ; Prefix1 = Prefix0 2708 ), 2709 add_message_context(T, Prefix1, Prefix). 2710 2711add_message_context1(Context, Prefix0, Prefix) :- 2712 prolog:message_prefix_hook(Context, Extra), 2713 atomics_to_string([Prefix0, Extra, ' '], Prefix). 2714add_message_context1(time, Prefix0, Prefix) :- 2715 get_time(Now), 2716 format_time(string(S), '%T.%3f ', Now), 2717 string_concat(Prefix0, S, Prefix). 2718add_message_context1(time(Format), Prefix0, Prefix) :- 2719 get_time(Now), 2720 format_time(string(S), Format, Now), 2721 atomics_to_string([Prefix0, S, ' '], Prefix). 2722add_message_context1(thread, Prefix0, Prefix) :- 2723 \+ current_prolog_flag(toplevel_thread, true), 2724 thread_self(Id0), 2725 !, 2726 ( atom(Id0) 2727 -> Id = Id0 2728 ; thread_property(Id0, id(Id)) 2729 ), 2730 format(string(Prefix), '~w[Thread ~w] ', [Prefix0, Id]).
If PrefixOrKind is kind(Kind), the message as a whole may be
decorated. To this end the lines are wrapped in begin(Class, Ctx)
and end(Ctx), where Class is derived from Kind using
msg_color_class/2. Ctx is a variable that is bound by whoever
implements prolog:message_line_element/2 for begin/2 (normally
library(ansi_term)) and remains unbound if the decoration is not
available, e.g., because Stream is not a terminal.
The elements that need Ctx are rewritten by prefix_nl/4 to carry it. See there for the details.
2748print_message_lines(Stream, kind(Kind), Lines) :- 2749 !, 2750 msg_property(Kind, prefix(Prefix)), 2751 msg_color_class(Kind, Class), 2752 insert_prefix(Lines, Prefix, Ctx, PrefixLines), 2753 '$append'([ begin(Class, Ctx) 2754 | PrefixLines 2755 ], 2756 [ end(Ctx) 2757 ], 2758 AllLines), 2759 print_message_lines(Stream, AllLines). 2760print_message_lines(Stream, Prefix, Lines) :- 2761 insert_prefix(Lines, Prefix, _, PrefixLines), 2762 print_message_lines(Stream, PrefixLines).
message(Kind) (see
level_attrs/2).2770msg_color_class(Kind, Class) :- 2771 msg_property(Kind, color_class(Class0)), 2772 !, 2773 Class = Class0. 2774msg_color_class(Kind, Kind).
at_same_line the message continues the line and no initial
prefix is added. Ctx is the message context; see prefix_nl/4 and
print_message_lines/3.2783insert_prefix([at_same_line|Lines0], Prefix, Ctx, Lines) :- 2784 !, 2785 prefix_nl(Lines0, Prefix, Ctx, Lines). 2786insert_prefix(Lines0, Prefix, Ctx, [prefix(Prefix)|Lines]) :- 2787 prefix_nl(Lines0, Prefix, Ctx, Lines).
nl and make the message context Ctx
available to the elements that need it:
nl(Ctx), flush(Ctx) and eol(Ctx).
Their handler writes the sequence that paints the remainder of
the line before ending it if the message has a background
colour.ansi(Attrs, Fmt, Args) becomes ansi(Attrs, Fmt, Args, Ctx).
Its handler re-installs the decoration of the message as a
whole after writing the element, as the element ends with a
full reset. The same applies to an ansi/3 element used as the
label of an url/2 element.
The last line of a message is ended implicitly: if Lines does not
end in nl or flush an nl is added. This one does not paint:
what follows the message is not part of it. A message that wants
its last line painted ends it using eol.
2809prefix_nl([], _, _, [nl]). 2810prefix_nl([nl], _, Ctx, [nl(Ctx)]) :- !. 2811prefix_nl([flush], _, Ctx, [flush(Ctx)]) :- !. 2812prefix_nl([nl|T0], Prefix, Ctx, [nl(Ctx), prefix(Prefix)|T]) :- 2813 !, 2814 prefix_nl(T0, Prefix, Ctx, T). 2815prefix_nl([flush|T0], Prefix, Ctx, [flush(Ctx)|T]) :- 2816 !, 2817 prefix_nl(T0, Prefix, Ctx, T). 2818prefix_nl([eol|T0], Prefix, Ctx, [eol(Ctx)|T]) :- 2819 !, 2820 prefix_nl(T0, Prefix, Ctx, T). 2821prefix_nl([ansi(Attrs,Fmt,Args)|T0], Prefix, Ctx, 2822 [ansi(Attrs,Fmt,Args,Ctx)|T]) :- 2823 !, 2824 prefix_nl(T0, Prefix, Ctx, T). 2825prefix_nl([url(URL,ansi(Attrs,Fmt,Args))|T0], Prefix, Ctx, 2826 [url(URL,ansi(Attrs,Fmt,Args,Ctx))|T]) :- 2827 !, 2828 prefix_nl(T0, Prefix, Ctx, T). 2829prefix_nl([H|T0], Prefix, Ctx, [H|T]) :- 2830 prefix_nl(T0, Prefix, Ctx, T).
2834print_message_lines(Stream, Lines) :- 2835 with_output_to( 2836 Stream, 2837 notrace(print_message_lines_guarded(current_output, Lines))). 2838 2839print_message_lines_guarded(_, []) :- !. 2840print_message_lines_guarded(S, [H|T]) :- 2841 line_element(S, H), 2842 print_message_lines_guarded(S, T). 2843 2844line_element(S, E) :- 2845 prolog:message_line_element(S, E), 2846 !. 2847line_element(S, full_stop) :- 2848 !, 2849 '$put_token'(S, '.'). % insert space if needed. 2850line_element(S, nl) :- 2851 !, 2852 nl(S). 2853line_element(S, nl(_Ctx)) :- 2854 !, 2855 nl(S). 2856line_element(S, flush(_Ctx)) :- 2857 !, 2858 flush_output(S). 2859line_element(_, eol(_Ctx)) :- !. 2860line_element(S, prefix(Fmt-Args)) :- 2861 !, 2862 safe_format(S, Fmt, Args). 2863line_element(S, prefix(Fmt)) :- 2864 !, 2865 safe_format(S, Fmt, []). 2866line_element(S, flush) :- 2867 !, 2868 flush_output(S). 2869line_element(S, Fmt-Args) :- 2870 !, 2871 safe_format(S, Fmt, Args). 2872line_element(S, ansi(_, Fmt, Args)) :- 2873 !, 2874 safe_format(S, Fmt, Args). 2875line_element(S, ansi(_, Fmt, Args, _Ctx)) :- 2876 !, 2877 safe_format(S, Fmt, Args). 2878line_element(S, url(URL)) :- 2879 !, 2880 print_link(S, URL). 2881line_element(S, url(_URL, Label)) :- 2882 !, 2883 link_label(Label, Fmt, Args), 2884 safe_format(S, Fmt, Args). 2885line_element(_, begin(_Level, _Ctx)) :- !. 2886line_element(_, end(_Ctx)) :- !. 2887line_element(S, Fmt) :- 2888 safe_format(S, Fmt, []). 2889 2890print_link(S, File:Line:Column) :- 2891 !, 2892 safe_format(S, '~w:~d:~d', [File, Line, Column]). 2893print_link(S, File:Line) :- 2894 !, 2895 safe_format(S, '~w:~d', [File, Line]). 2896print_link(S, File) :- 2897 safe_format(S, '~w', [File]).
~.2905:- public 2906 link_label/3. 2907 2908link_label(Fmt-Args, Fmt, Args) :- 2909 atom(Fmt), 2910 is_list(Args), 2911 !. 2912link_label(ansi(_Class, Fmt, Args), Fmt, Args) :- !. 2913link_label(ansi(_Class, Fmt, Args, _Ctx), Fmt, Args) :- !. 2914link_label(Text, '~w', [Text]).
2918safe_format(S, Fmt, Args) :- 2919 E = error(_,_), 2920 catch(format(S,Fmt,Args), E, 2921 format_failed(S,Fmt,Args,E)). 2922 2923format_failed(S, _Fmt, _Args, E) :- 2924 stream_property(S, error(true)), 2925 !, 2926 throw(E). 2927format_failed(S, Fmt, Args, error(E,_)) :- 2928 format(S, '~N [[ EXCEPTION while printing message ~q~n\c 2929 ~7|with arguments ~W:~n\c 2930 ~7|raised: ~W~n~4|]]~n', 2931 [ Fmt, 2932 Args, [quoted(true), max_depth(10)], 2933 E, [quoted(true), max_depth(10)] 2934 ]).
2940message_to_string(Term, Str) :- 2941 translate_message(Term, Actions, []), 2942 !, 2943 actions_to_format(Actions, Fmt, Args), 2944 format(string(Str), Fmt, Args). 2945 2946actions_to_format([], '', []) :- !. 2947actions_to_format([nl(_)|T], Fmt, Args) :- % see prefix_nl/4 2948 !, 2949 actions_to_format([nl|T], Fmt, Args). 2950actions_to_format([nl], '', []) :- !. 2951actions_to_format([Term, nl], Fmt, Args) :- 2952 !, 2953 actions_to_format([Term], Fmt, Args). 2954actions_to_format([nl|T], Fmt, Args) :- 2955 !, 2956 actions_to_format(T, Fmt0, Args), 2957 atom_concat('~n', Fmt0, Fmt). 2958actions_to_format([ansi(_Attrs, Fmt0, Args0)|Tail], Fmt, Args) :- 2959 !, 2960 actions_to_format(Tail, Fmt1, Args1), 2961 atom_concat(Fmt0, Fmt1, Fmt), 2962 append_args(Args0, Args1, Args). 2963actions_to_format([url(Pos)|Tail], Fmt, Args) :- 2964 !, 2965 actions_to_format(Tail, Fmt1, Args1), 2966 url_actions_to_format(url(Pos), Fmt1, Args1, Fmt, Args). 2967actions_to_format([url(URL, Label)|Tail], Fmt, Args) :- 2968 !, 2969 actions_to_format(Tail, Fmt1, Args1), 2970 url_actions_to_format(url(URL, Label), Fmt1, Args1, Fmt, Args). 2971actions_to_format([Fmt0-Args0|Tail], Fmt, Args) :- 2972 !, 2973 actions_to_format(Tail, Fmt1, Args1), 2974 atom_concat(Fmt0, Fmt1, Fmt), 2975 append_args(Args0, Args1, Args). 2976actions_to_format([Skip|T], Fmt, Args) :- 2977 action_skip(Skip), 2978 !, 2979 actions_to_format(T, Fmt, Args). 2980actions_to_format([Term|Tail], Fmt, Args) :- 2981 atomic(Term), 2982 !, 2983 actions_to_format(Tail, Fmt1, Args), 2984 atom_concat(Term, Fmt1, Fmt). 2985actions_to_format([Term|Tail], Fmt, Args) :- 2986 actions_to_format(Tail, Fmt1, Args1), 2987 atom_concat('~w', Fmt1, Fmt), 2988 append_args([Term], Args1, Args). 2989 2990action_skip(at_same_line). 2991action_skip(flush). 2992action_skip(flush(_Ctx)). 2993action_skip(eol). 2994action_skip(eol(_Ctx)). 2995action_skip(begin(_Level, _Ctx)). 2996action_skip(end(_Ctx)). 2997 2998url_actions_to_format(url(File:Line:Column), Fmt1, Args1, Fmt, Args) :- 2999 !, 3000 atom_concat('~w:~d:~d', Fmt1, Fmt), 3001 append_args([File,Line,Column], Args1, Args). 3002url_actions_to_format(url(File:Line), Fmt1, Args1, Fmt, Args) :- 3003 !, 3004 atom_concat('~w:~d', Fmt1, Fmt), 3005 append_args([File,Line], Args1, Args). 3006url_actions_to_format(url(File), Fmt1, Args1, Fmt, Args) :- 3007 !, 3008 atom_concat('~w', Fmt1, Fmt), 3009 append_args([File], Args1, Args). 3010url_actions_to_format(url(_URL, Label), Fmt1, Args1, Fmt, Args) :- 3011 !, 3012 link_label(Label, Fmt0, Args0), 3013 atom_concat(Fmt0, Fmt1, Fmt), 3014 append_args(Args0, Args1, Args). 3015 3016 3017append_args(M:Args0, Args1, M:Args) :- 3018 !, 3019 strip_module(Args1, _, A1), 3020 to_list(Args0, Args01), 3021 '$append'(Args01, A1, Args). 3022append_args(Args0, Args1, Args) :- 3023 strip_module(Args1, _, A1), 3024 to_list(Args0, Args01), 3025 '$append'(Args01, A1, Args). 3026 3027 /******************************* 3028 * MESSAGES TO PRINT ONCE * 3029 *******************************/ 3030 3031:- dynamic 3032 printed/2.
3038print_once(compatibility(_), _). 3039print_once(null_byte_in_path(_), _). 3040print_once(deprecated(_), _).
3046must_print(Level, Message) :- 3047 nonvar(Message), 3048 print_once(Message, Level), 3049 !, 3050 \+ printed(Message, Level), 3051 assert(printed(Message, Level)). 3052must_print(_, _)