37
38:- module('$messages',
39 [ print_message/2, 40 print_message_lines/3, 41 message_to_string/2 42 ]). 43
44:- multifile
45 prolog:message//1, 46 prolog:error_message//1, 47 prolog:message_context//1, 48 prolog:deprecated//1, 49 prolog:message_location//1, 50 prolog:message_line_element/2, 51 prolog:message_action/2. 52:- dynamic
53 prolog:message_action/2. 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)). 62:- multifile
63 prolog:message//2, 64 prolog:error_message//2, 65 prolog:message_context//2, 66 prolog:message_location//2, 67 prolog:deprecated//2. 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, 80 prolog:translate_message//1. 81
82:- create_prolog_flag(message_context, [thread], []). 83
105
106prolog:translate_message(Term) -->
107 translate_message(Term).
108
113
114translate_message(Term) -->
115 { nonvar(Term) },
116 ( { message_lang(Lang) },
117 prolog:message(Lang, Term)
118 ; prolog:message(Term)
119 ),
120 !.
121translate_message(Term) -->
122 { nonvar(Term) },
123 translate_message2(Term),
124 !.
125translate_message(Term) -->
126 { nonvar(Term),
127 Term = error(_, _)
128 },
129 [ 'Unknown exception: ~p'-[Term] ].
130translate_message(Term) -->
131 [ 'Unknown message: ~p'-[Term] ].
132
133translate_message2(Term) -->
134 prolog_message(Term).
135translate_message2(error(resource_error(stack), Context)) -->
136 !,
137 out_of_stack(Context).
138translate_message2(error(resource_error(tripwire(Wire, Context)), _)) -->
139 !,
140 tripwire_message(Wire, Context).
141translate_message2(error(existence_error(reset, Ball), SWI)) -->
142 swi_location(SWI),
143 tabling_existence_error(Ball, SWI).
144translate_message2(error(ISO, SWI)) -->
145 swi_location(SWI),
146 term_message(ISO),
147 swi_extra(SWI).
148translate_message2(unwind(Term)) -->
149 unwind_message(Term).
150translate_message2(message_lines(Lines), L, T) :- 151 make_message_lines(Lines, L, T).
152translate_message2(format(Fmt, Args)) -->
153 [ Fmt-Args ].
154
155make_message_lines([], T, T) :- !.
156make_message_lines([Last], ['~w'-[Last]|T], T) :- !.
157make_message_lines([L0|LT], ['~w'-[L0],nl|T0], T) :-
158 make_message_lines(LT, T0, T).
159
165
166:- public term_message//1. 167term_message(Term) -->
168 {var(Term)},
169 !,
170 [ 'Unknown error term: ~p'-[Term] ].
171term_message(Term) -->
172 { message_lang(Lang) },
173 prolog:error_message(Lang, Term),
174 !.
175term_message(Term) -->
176 prolog:error_message(Term),
177 !.
178term_message(Term) -->
179 iso_message(Term).
180term_message(Term) -->
181 swi_message(Term).
182term_message(Term) -->
183 [ 'Unknown error term: ~p'-[Term] ].
184
185iso_message(resource_error(c_stack)) -->
186 out_of_c_stack.
187iso_message(resource_error(Missing)) -->
188 [ 'Not enough resources: ~w'-[Missing] ].
189iso_message(type_error(Var, Actual)) -->
190 { var(Var) },
191 [ 'Type error: unbound (var) type expected, found `~p'''-[Actual] ].
192iso_message(type_error(evaluable, Actual)) -->
193 { callable(Actual) },
194 [ 'Arithmetic: `~p'' is not a function'-[Actual] ].
195iso_message(type_error(free_of_attvar, Actual)) -->
196 [ 'Type error: `~W'' contains attributed variables'-
197 [Actual,[portray(true), attributes(portray)]] ].
198iso_message(type_error(Expected, Actual)) -->
199 [ 'Type error: `~w'' expected, found `~p'''-[Expected, Actual] ],
200 type_error_comment(Expected, Actual).
201iso_message(domain_error(Domain, Actual)) -->
202 [ 'Domain error: '-[] ], domain(Domain),
203 [ ' expected, found `~p'''-[Actual] ].
204iso_message(instantiation_error) -->
205 [ 'Arguments are not sufficiently instantiated' ].
206iso_message(uninstantiation_error(Var)) -->
207 [ 'Uninstantiated argument expected, found ~p'-[Var] ].
208iso_message(representation_error(What)) -->
209 [ 'Cannot represent due to `~w'''-[What] ].
210iso_message(permission_error(Action, Type, Object)) -->
211 permission_error(Action, Type, Object).
212iso_message(evaluation_error(Which)) -->
213 [ 'Arithmetic: evaluation error: `~p'''-[Which] ].
214iso_message(existence_error(procedure, Proc)) -->
215 [ 'Unknown procedure: ~q'-[Proc] ],
216 unknown_proc_msg(Proc).
217iso_message(existence_error(answer_variable, Var)) -->
218 [ '$~w was not bound by a previous query'-[Var] ].
219iso_message(existence_error(matching_rule, Goal)) -->
220 [ 'No rule matches ~p'-[Goal] ].
221iso_message(existence_error(Type, Object)) -->
222 [ '~w `~p'' does not exist'-[Type, Object] ].
223iso_message(existence_error(export, PI, module(M))) --> 224 [ 'Module ', ansi(code, '~q', [M]), ' does not export ',
225 ansi(code, '~q', [PI]) ].
226iso_message(existence_error(Type, Object, In)) --> 227 [ '~w `~p'' does not exist in ~p'-[Type, Object, In] ].
228iso_message(busy(Type, Object)) -->
229 [ '~w `~p'' is busy'-[Type, Object] ].
230iso_message(syntax_error(swi_backslash_newline)) -->
231 [ 'Deprecated: ... \\<newline><white>*. Use \\c' ].
232iso_message(syntax_error(warning_var_tag)) -->
233 [ 'Deprecated: dict with unbound tag (_{...}). Mapped to #{...}.' ].
234iso_message(syntax_error(var_tag)) -->
235 [ 'Syntax error: dict syntax with unbound tag (_{...}).' ].
236iso_message(syntax_error(Id)) -->
237 [ 'Syntax error: ' ],
238 syntax_error(Id).
239iso_message(occurs_check(Var, In)) -->
240 [ 'Cannot unify ~p with ~p: would create an infinite tree'-[Var, In] ].
241
246
247permission_error(Action, built_in_procedure, Pred) -->
248 { user_predicate_indicator(Pred, PI)
249 },
250 [ 'No permission to ~w built-in predicate `~p'''-[Action, PI] ],
251 ( {Action \== export}
252 -> [ nl,
253 'Use :- redefine_system_predicate(+Head) if redefinition is intended'
254 ]
255 ; []
256 ).
257permission_error(import_into(Dest), procedure, Pred) -->
258 [ 'No permission to import ~p into ~w'-[Pred, Dest] ].
259permission_error(Action, static_procedure, Proc) -->
260 [ 'No permission to ~w static procedure `~p'''-[Action, Proc] ],
261 defined_definition('Defined', Proc).
262permission_error(input, stream, Stream) -->
263 [ 'No permission to read from output stream `~p'''-[Stream] ].
264permission_error(output, stream, Stream) -->
265 [ 'No permission to write to input stream `~p'''-[Stream] ].
266permission_error(input, text_stream, Stream) -->
267 [ 'No permission to read bytes from TEXT stream `~p'''-[Stream] ].
268permission_error(output, text_stream, Stream) -->
269 [ 'No permission to write bytes to TEXT stream `~p'''-[Stream] ].
270permission_error(input, binary_stream, Stream) -->
271 [ 'No permission to read characters from binary stream `~p'''-[Stream] ].
272permission_error(output, binary_stream, Stream) -->
273 [ 'No permission to write characters to binary stream `~p'''-[Stream] ].
274permission_error(open, source_sink, alias(Alias)) -->
275 [ 'No permission to reuse alias "~p": already taken'-[Alias] ].
276permission_error(tnot, non_tabled_procedure, Pred) -->
277 [ 'The argument of tnot/1 is not tabled: ~p'-[Pred] ].
278permission_error(assert, procedure, Pred) -->
279 { '$pi_head'(Pred, Head),
280 predicate_property(Head, ssu)
281 },
282 [ '~p: an SSU (Head => Body) predicate cannot have normal Prolog clauses'-
283 [Pred] ].
284permission_error(Action, Type, Object) -->
285 [ 'No permission to ~w ~w `~p'''-[Action, Type, Object] ].
286
287
288unknown_proc_msg(_:(^)/2) -->
289 !,
290 unknown_proc_msg((^)/2).
291unknown_proc_msg((^)/2) -->
292 !,
293 [nl, ' ^/2 can only appear as the 2nd argument of setof/3 and bagof/3'].
294unknown_proc_msg((:-)/2) -->
295 !,
296 [nl, ' Rules must be loaded from a file'],
297 faq('ToplevelMode').
298unknown_proc_msg((=>)/2) -->
299 !,
300 [nl, ' Rules must be loaded from a file'],
301 faq('ToplevelMode').
302unknown_proc_msg((:-)/1) -->
303 !,
304 [nl, ' Directives must be loaded from a file'],
305 faq('ToplevelMode').
306unknown_proc_msg((?-)/1) -->
307 !,
308 [nl, ' ?- is the Prolog prompt'],
309 faq('ToplevelMode').
310unknown_proc_msg(Proc) -->
311 { dwim_predicates(Proc, Dwims) },
312 ( {Dwims \== []}
313 -> [nl, ' However, there are definitions for:', nl],
314 dwim_message(Dwims)
315 ; []
316 ).
317
318dependency_error(shared(Shared), private(Private)) -->
319 [ 'Shared table for ~p may not depend on private ~p'-[Shared, Private] ].
320dependency_error(Dep, monotonic(On)) -->
321 { '$pi_head'(PI, Dep),
322 '$pi_head'(MPI, On)
323 },
324 [ 'Dependent ~p on monotonic predicate ~p is not monotonic or incremental'-
325 [PI, MPI]
326 ].
327
328faq(Page) -->
329 [nl, ' See FAQ at https://www.swi-prolog.org/FAQ/', Page, '.html' ].
330
(_Expected, Actual) -->
332 { type_of(Actual, Type),
333 ( sub_atom(Type, 0, 1, _, First),
334 memberchk(First, [a,e,i,o,u])
335 -> Article = an
336 ; Article = a
337 )
338 },
339 [ ' (~w ~w)'-[Article, Type] ].
340
341type_of(Term, Type) :-
342 ( attvar(Term) -> Type = attvar
343 ; var(Term) -> Type = var
344 ; atom(Term) -> Type = atom
345 ; integer(Term) -> Type = integer
346 ; string(Term) -> Type = string
347 ; Term == [] -> Type = empty_list
348 ; blob(Term, BlobT) -> blob_type(BlobT, Type)
349 ; rational(Term) -> Type = rational
350 ; float(Term) -> Type = float
351 ; is_stream(Term) -> Type = stream
352 ; is_dict(Term) -> Type = dict
353 ; is_list(Term) -> Type = list
354 ; Term = [_|_] -> list_like(Term, Type)
355 ; cyclic_term(Term) -> Type = cyclic
356 ; compound(Term) -> Type = compound
357 ; Type = unknown
358 ).
359
360list_like(Term, Type) :-
361 '$skip_list'(_, Term, Tail),
362 ( var(Tail)
363 -> Type = partial_list
364 ; Type = invalid_list 365 ).
366
367blob_type(BlobT, Type) :-
368 atom_concat(BlobT, '_reference', Type).
369
370syntax_error(end_of_clause) -->
371 [ 'Unexpected end of clause' ].
372syntax_error(end_of_clause_expected) -->
373 [ 'End of clause expected' ].
374syntax_error(end_of_file) -->
375 [ 'Unexpected end of file' ].
376syntax_error(end_of_file_in_block_comment) -->
377 [ 'End of file in /* ... */ comment' ].
378syntax_error(end_of_file_in_quoted(Quote)) -->
379 [ 'End of file in quoted ' ],
380 quoted_type(Quote).
381syntax_error(illegal_number) -->
382 [ 'Illegal number' ].
383syntax_error(long_atom) -->
384 [ 'Atom too long (see style_check/1)' ].
385syntax_error(long_string) -->
386 [ 'String too long (see style_check/1)' ].
387syntax_error(operator_clash) -->
388 [ 'Operator priority clash' ].
389syntax_error(operator_expected) -->
390 [ 'Operator expected' ].
391syntax_error(operator_balance) -->
392 [ 'Unbalanced operator' ].
393syntax_error(quoted_punctuation) -->
394 [ 'Operand expected, unquoted comma or bar found' ].
395syntax_error(list_rest) -->
396 [ 'Unexpected comma or bar in rest of list' ].
397syntax_error(cannot_start_term) -->
398 [ 'Illegal start of term' ].
399syntax_error(punct(Punct, End)) -->
400 [ 'Unexpected `~w\' before `~w\''-[Punct, End] ].
401syntax_error(undefined_char_escape(C)) -->
402 [ 'Unknown character escape in quoted atom or string: `\\~w\''-[C] ].
403syntax_error(void_not_allowed) -->
404 [ 'Empty argument list "()"' ].
405syntax_error(Term) -->
406 { compound(Term),
407 compound_name_arguments(Term, Syntax, [Text])
408 }, !,
409 [ '~w expected, found '-[Syntax], ansi(code, '"~w"', [Text]) ].
410syntax_error(Message) -->
411 [ '~w'-[Message] ].
412
413quoted_type('\'') --> [atom].
414quoted_type('\"') --> { current_prolog_flag(double_quotes, Type) }, [Type-[]].
415quoted_type('\`') --> { current_prolog_flag(back_quotes, Type) }, [Type-[]].
416
417domain(range(Low,High)) -->
418 !,
419 ['[~q..~q]'-[Low,High] ].
420domain(Domain) -->
421 ['`~w\''-[Domain] ].
422
427
428tabling_existence_error(Ball, Context) -->
429 { table_shift_ball(Ball) },
430 [ 'Tabling dependency error' ],
431 swi_extra(Context).
432
433table_shift_ball(dependency(_Head)).
434table_shift_ball(dependency(_Skeleton, _Trie, _Mono)).
435table_shift_ball(call_info(_Skeleton, _Status)).
436table_shift_ball(call_info(_GenSkeleton, _Skeleton, _Status)).
437
441
442dwim_predicates(Module:Name/_Arity, Dwims) :-
443 !,
444 findall(Dwim, dwim_predicate(Module:Name, Dwim), Dwims).
445dwim_predicates(Name/_Arity, Dwims) :-
446 findall(Dwim, dwim_predicate(user:Name, Dwim), Dwims).
447
448dwim_message([]) --> [].
449dwim_message([M:Head|T]) -->
450 { hidden_module(M),
451 !,
452 functor(Head, Name, Arity)
453 },
454 [ ' ~q'-[Name/Arity], nl ],
455 dwim_message(T).
456dwim_message([Module:Head|T]) -->
457 !,
458 { functor(Head, Name, Arity)
459 },
460 [ ' ~q'-[Module:Name/Arity], nl],
461 dwim_message(T).
462dwim_message([Head|T]) -->
463 {functor(Head, Name, Arity)},
464 [ ' ~q'-[Name/Arity], nl],
465 dwim_message(T).
466
467
468swi_message(io_error(Op, Stream)) -->
469 [ 'I/O error in ~w on stream ~p'-[Op, Stream] ].
470swi_message(thread_error(TID, false)) -->
471 [ 'Thread ~p died due to failure:'-[TID] ].
472swi_message(thread_error(TID, exception(Error))) -->
473 [ 'Thread ~p died abnormally:'-[TID], nl ],
474 translate_message(Error).
475swi_message(dependency_error(Tabled, DependsOn)) -->
476 dependency_error(Tabled, DependsOn).
477swi_message(shell(execute, Cmd)) -->
478 [ 'Could not execute `~w'''-[Cmd] ].
479swi_message(shell(signal(Sig), Cmd)) -->
480 [ 'Caught signal ~d on `~w'''-[Sig, Cmd] ].
481swi_message(format(Fmt, Args)) -->
482 [ Fmt-Args ].
483swi_message(signal(Name, Num)) -->
484 [ 'Caught signal ~d (~w)'-[Num, Name] ].
485swi_message(limit_exceeded(Limit, MaxVal)) -->
486 [ 'Exceeded ~w limit (~w)'-[Limit, MaxVal] ].
487swi_message(goal_failed(Goal)) -->
488 [ 'goal unexpectedly failed: ~p'-[Goal] ].
489swi_message(shared_object(_Action, Message)) --> 490 [ '~w'-[Message] ].
491swi_message(system_error(Error)) -->
492 [ 'error in system call: ~w'-[Error]
493 ].
494swi_message(system_error) -->
495 [ 'error in system call'
496 ].
497swi_message(failure_error(Goal)) -->
498 [ 'Goal failed: ~p'-[Goal] ].
499swi_message(timeout_error(Op, Stream)) -->
500 [ 'Timeout in ~w from ~p'-[Op, Stream] ].
501swi_message(not_implemented(Type, What)) -->
502 [ '~w `~p\' is not implemented in this version'-[Type, What] ].
503swi_message(context_error(nodirective, Goal)) -->
504 { goal_to_predicate_indicator(Goal, PI) },
505 [ 'Wrong context: ~p can only be used in a directive'-[PI] ].
506swi_message(context_error(edit, no_default_file)) -->
507 ( { current_prolog_flag(windows, true) }
508 -> [ 'Edit/0 can only be used after opening a \c
509 Prolog file by double-clicking it' ]
510 ; [ 'Edit/0 can only be used with the "-s file" commandline option'
511 ]
512 ),
513 [ nl, 'Use "?- edit(Topic)." or "?- emacs."' ].
514swi_message(context_error(function, meta_arg(S))) -->
515 [ 'Functions are not (yet) supported for meta-arguments of type ~q'-[S] ].
516swi_message(format_argument_type(Fmt, Arg)) -->
517 [ 'Illegal argument to format sequence ~~~w: ~p'-[Fmt, Arg] ].
518swi_message(format(Msg)) -->
519 [ 'Format error: ~w'-[Msg] ].
520swi_message(conditional_compilation_error(unterminated, File:Line)) -->
521 [ 'Unterminated conditional compilation from '-[], url(File:Line) ].
522swi_message(conditional_compilation_error(no_if, What)) -->
523 [ ':- ~w without :- if'-[What] ].
524swi_message(duplicate_key(Key)) -->
525 [ 'Duplicate key: ~p'-[Key] ].
526swi_message(determinism_error(PI, det, Found, property)) -->
527 ( { '$pi_head'(user:PI, Head),
528 predicate_property(Head, det)
529 }
530 -> [ 'Deterministic procedure ~p'-[PI] ]
531 ; [ 'Procedure ~p called from a deterministic procedure'-[PI] ]
532 ),
533 det_error(Found).
534swi_message(determinism_error(PI, det, fail, guard)) -->
535 [ 'Procedure ~p failed after $-guard'-[PI] ].
536swi_message(determinism_error(PI, det, fail, guard_in_caller)) -->
537 [ 'Procedure ~p failed after $-guard in caller'-[PI] ].
538swi_message(determinism_error(Goal, det, fail, goal)) -->
539 [ 'Goal ~p failed'-[Goal] ].
540swi_message(determinism_error(Goal, det, nondet, goal)) -->
541 [ 'Goal ~p succeeded with a choice point'-[Goal] ].
542swi_message(qlf_format_error(File, Message)) -->
543 [ '~w: Invalid QLF file: ~w'-[File, Message] ].
544swi_message(goal_expansion_error(bound, Term)) -->
545 [ 'Goal expansion bound a variable to ~p'-[Term] ].
546
547det_error(nondet) -->
548 [ ' succeeded with a choicepoint'- [] ].
549det_error(fail) -->
550 [ ' failed'- [] ].
551
552
557
558:- public swi_location//1. 559swi_location(X) -->
560 { var(X) },
561 !.
562swi_location(Context) -->
563 { message_lang(Lang) },
564 prolog:message_location(Lang, Context),
565 !.
566swi_location(Context) -->
567 prolog:message_location(Context),
568 !.
569swi_location(context(Caller, _Msg)) -->
570 { ground(Caller) },
571 !,
572 caller(Caller).
573swi_location(file(Path, Line, -1, _CharNo)) -->
574 !,
575 [ url(Path:Line), ': ' ].
576swi_location(file(Path, Line, LinePos, _CharNo)) -->
577 [ url(Path:Line:LinePos), ': ' ].
578swi_location(stream(Stream, Line, LinePos, CharNo)) -->
579 ( { is_stream(Stream),
580 stream_property(Stream, file_name(File))
581 }
582 -> swi_location(file(File, Line, LinePos, CharNo))
583 ; [ 'Stream ~w:~d:~d '-[Stream, Line, LinePos] ]
584 ).
585swi_location(autoload(File:Line)) -->
586 [ url(File:Line), ': ' ].
587swi_location(_) -->
588 [].
589
590caller(system:'$record_clause'/3) -->
591 !,
592 [].
593caller(Module:Name/Arity) -->
594 !,
595 ( { \+ hidden_module(Module) }
596 -> [ '~q:~q/~w: '-[Module, Name, Arity] ]
597 ; [ '~q/~w: '-[Name, Arity] ]
598 ).
599caller(Name/Arity) -->
600 [ '~q/~w: '-[Name, Arity] ].
601caller(Caller) -->
602 [ '~p: '-[Caller] ].
603
604
612
(X) -->
614 { var(X) },
615 !,
616 [].
617swi_extra(Context) -->
618 { message_lang(Lang) },
619 prolog:message_context(Lang, Context),
620 !.
621swi_extra(Context) -->
622 prolog:message_context(Context).
623swi_extra(context(_, Msg)) -->
624 { nonvar(Msg),
625 Msg \== ''
626 },
627 !,
628 swi_comment(Msg).
629swi_extra(string(String, CharPos)) -->
630 { sub_string(String, 0, CharPos, _, Before),
631 sub_string(String, CharPos, _, 0, After)
632 },
633 [ nl, '~w'-[Before], nl, '** here **', nl, '~w'-[After] ].
634swi_extra(_) -->
635 [].
636
(already_from(Module)) -->
638 !,
639 [ ' (already imported from ~q)'-[Module] ].
640swi_comment(directory(_Dir)) -->
641 !,
642 [ ' (is a directory)' ].
643swi_comment(not_a_directory(_Dir)) -->
644 !,
645 [ ' (is not a directory)' ].
646swi_comment(Msg) -->
647 [ ' (~w)'-[Msg] ].
648
649
650thread_context -->
651 { \+ current_prolog_flag(toplevel_thread, true),
652 thread_self(Id)
653 },
654 !,
655 ['[Thread ~w] '-[Id]].
656thread_context -->
657 [].
658
659 662
663unwind_message(Var) -->
664 { var(Var) }, !,
665 [ 'Unknown unwind message: ~p'-[Var] ].
666unwind_message(abort) -->
667 [ 'Execution Aborted' ].
668unwind_message(halt(_)) -->
669 [].
670unwind_message(thread_exit(Term)) -->
671 [ 'Invalid thread_exit/1. Payload: ~p'-[Term] ].
672unwind_message(Term) -->
673 [ 'Unknown "unwind" exception: ~p'-[Term] ].
674
675
676 679
680:- dynamic prolog:version_msg/1. 681:- multifile prolog:version_msg/1. 682
683prolog_message(welcome) -->
684 [ 'Welcome to SWI-Prolog (' ],
685 prolog_message(threads),
686 prolog_message(address_bits),
687 ['version ' ],
688 prolog_message(version),
689 [ ')', nl ],
690 prolog_message(copyright),
691 [ nl ],
692 translate_message(user_versions),
693 [ nl ],
694 prolog_message(documentaton),
695 [ nl, nl ].
696prolog_message(user_versions) -->
697 ( { findall(Msg, prolog:version_msg(Msg), Msgs),
698 Msgs \== []
699 }
700 -> [nl],
701 user_version_messages(Msgs)
702 ; []
703 ).
704prolog_message(deprecated(Term)) -->
705 { nonvar(Term) },
706 ( { message_lang(Lang) },
707 prolog:deprecated(Lang, Term)
708 -> []
709 ; prolog:deprecated(Term)
710 -> []
711 ; deprecated(Term)
712 ).
713prolog_message(unhandled_exception(E)) -->
714 { nonvar(E) },
715 [ 'Unhandled exception: ' ],
716 ( translate_message(E)
717 -> []
718 ; [ '~p'-[E] ]
719 ).
720
722
723prolog_message(initialization_error(_, E, File:Line)) -->
724 !,
725 [ url(File:Line),
726 ': Initialization goal raised exception:', nl
727 ],
728 translate_message(E).
729prolog_message(initialization_error(Goal, E, _)) -->
730 [ 'Initialization goal ~p raised exception:'-[Goal], nl ],
731 translate_message(E).
732prolog_message(initialization_failure(_Goal, File:Line)) -->
733 !,
734 [ url(File:Line),
735 ': Initialization goal failed'-[]
736 ].
737prolog_message(initialization_failure(Goal, _)) -->
738 [ 'Initialization goal failed: ~p'-[Goal]
739 ].
740prolog_message(initialization_exception(E)) -->
741 [ 'Prolog initialisation failed:', nl ],
742 translate_message(E).
743prolog_message(initialization(halt(Status), Goal, File:Line)) -->
744 [ url(File:Line), ': '], goal(Goal), [nl,
745 ' Initialization goal called ', ansi(code, '~p', [halt(Status)]),
746 '.', nl,
747 ' The program entry point should be called using ',
748 ansi(code, 'initialization/2', []), '.', nl,
749 ' Consider using ', ansi(code, 'library(main)', []), '.'
750 ].
751prolog_message(init_goal_syntax(Error, Text)) -->
752 !,
753 [ '-g ~w: '-[Text] ],
754 translate_message(Error).
755prolog_message(init_goal_failed(failed, @(Goal,File:Line))) -->
756 !,
757 [ url(File:Line), ': ~p: false'-[Goal] ].
758prolog_message(init_goal_failed(Error, @(Goal,File:Line))) -->
759 !,
760 [ url(File:Line), ': ~p '-[Goal] ],
761 translate_message(Error).
762prolog_message(init_goal_failed(failed, Text)) -->
763 !,
764 [ '-g ~w: false'-[Text] ].
765prolog_message(init_goal_failed(Error, Text)) -->
766 !,
767 [ '-g ~w: '-[Text] ],
768 translate_message(Error).
769prolog_message(goal_failed(Context, Goal)) -->
770 [ 'Goal (~w) failed: ~p'-[Context, Goal] ].
771prolog_message(no_current_module(Module)) -->
772 [ '~w is not a current module (created)'-[Module] ].
773prolog_message(commandline_arg_type(Flag, Arg)) -->
774 [ 'Bad argument to commandline option -~w: ~w'-[Flag, Arg] ].
775prolog_message(missing_feature(Name)) -->
776 [ 'This version of SWI-Prolog does not support ~w'-[Name] ].
777prolog_message(singletons(_Term, List)) -->
778 [ 'Singleton variables: ~w'-[List] ].
779prolog_message(multitons(_Term, List)) -->
780 [ 'Singleton-marked variables appearing more than once: ~w'-[List] ].
781prolog_message(profile_no_cpu_time) -->
782 [ 'No CPU-time info. Check the SWI-Prolog manual for details' ].
783prolog_message(non_ascii(Text, Type)) -->
784 [ 'Unquoted ~w with non-portable characters: ~w'-[Type, Text] ].
785prolog_message(io_warning(Stream, Message)) -->
786 { stream_property(Stream, position(Position)),
787 !,
788 stream_position_data(line_count, Position, LineNo),
789 stream_position_data(line_position, Position, LinePos),
790 ( stream_property(Stream, file_name(File))
791 -> Obj = File
792 ; Obj = Stream
793 )
794 },
795 [ '~p:~d:~d: ~w'-[Obj, LineNo, LinePos, Message] ].
796prolog_message(io_warning(Stream, Message)) -->
797 [ 'stream ~p: ~w'-[Stream, Message] ].
798prolog_message(option_usage(pldoc)) -->
799 [ 'Usage: --pldoc[=port]' ].
800prolog_message(interrupt(begin)) -->
801 [ 'Action (h for help) ? ', flush ].
802prolog_message(interrupt(end)) -->
803 [ 'continue' ].
804prolog_message(interrupt(trace)) -->
805 [ 'continue (trace mode)' ].
806prolog_message(unknown_in_module_user) -->
807 [ 'Using a non-error value for unknown in the global module', nl,
808 'causes most of the development environment to stop working.', nl,
809 'Please use :- dynamic or limit usage of unknown to a module.', nl,
810 'See https://www.swi-prolog.org/howto/database.html'
811 ].
812prolog_message(untable(PI)) -->
813 [ 'Reconsult: removed tabling for ~p'-[PI] ].
814prolog_message(unknown_option(Set, Opt)) -->
815 [ 'Unknown ~w option: ~p'-[Set, Opt] ].
816
817
818 821
822prolog_message(modify_active_procedure(Who, What)) -->
823 [ '~p: modified active procedure ~p'-[Who, What] ].
824prolog_message(load_file(failed(user:File))) -->
825 [ 'Failed to load ~p'-[File] ].
826prolog_message(load_file(failed(Module:File))) -->
827 [ 'Failed to load ~p into module ~p'-[File, Module] ].
828prolog_message(load_file(failed(File))) -->
829 [ 'Failed to load ~p'-[File] ].
830prolog_message(mixed_directive(Goal)) -->
831 [ 'Cannot pre-compile mixed load/call directive: ~p'-[Goal] ].
832prolog_message(cannot_redefine_comma) -->
833 [ 'Full stop in clause-body? Cannot redefine ,/2' ].
834prolog_message(illegal_autoload_index(Dir, Term)) -->
835 [ 'Illegal term in INDEX file of directory ~w: ~w'-[Dir, Term] ].
836prolog_message(redefined_procedure(Type, Proc)) -->
837 [ 'Redefined ~w procedure ~p'-[Type, Proc] ],
838 defined_definition('Previously defined', Proc).
839prolog_message(declare_module(Module, abolish(Predicates))) -->
840 [ 'Loading module ~w abolished: ~p'-[Module, Predicates] ].
841prolog_message(import_private(Module, Private)) -->
842 [ 'import/1: ~p is not exported (still imported into ~q)'-
843 [Private, Module]
844 ].
845prolog_message(ignored_weak_import(Into, From:PI)) -->
846 [ 'Local definition of ~p overrides weak import from ~q'-
847 [Into:PI, From]
848 ].
849prolog_message(undefined_export(Module, PI)) -->
850 [ 'Exported procedure ~q:~q is not defined'-[Module, PI] ].
851prolog_message(no_exported_op(Module, Op)) -->
852 [ 'Operator ~q:~q is not exported (still defined)'-[Module, Op] ].
853prolog_message(discontiguous((-)/2,_)) -->
854 prolog_message(minus_in_identifier).
855prolog_message(discontiguous(Proc,Current)) -->
856 [ 'Clauses of ', ansi(code, '~p', [Proc]),
857 ' are not together in the source-file', nl ],
858 current_definition(Proc, 'Earlier definition at '),
859 [ 'Current predicate: ', ansi(code, '~p', [Current]), nl,
860 'Use ', ansi(code, ':- discontiguous ~p.', [Proc]),
861 ' to suppress this message'
862 ].
863prolog_message(decl_no_effect(Goal)) -->
864 [ 'Deprecated declaration has no effect: ~p'-[Goal] ].
865prolog_message(load_file(start(Level, File))) -->
866 [ '~|~t~*+Loading '-[Level] ],
867 load_file(File),
868 [ ' ...' ].
869prolog_message(include_file(start(Level, File))) -->
870 [ '~|~t~*+include '-[Level] ],
871 load_file(File),
872 [ ' ...' ].
873prolog_message(include_file(done(Level, File))) -->
874 [ '~|~t~*+included '-[Level] ],
875 load_file(File).
876prolog_message(load_file(done(Level, File, Action, Module, Time, Clauses))) -->
877 [ '~|~t~*+'-[Level] ],
878 load_file(File),
879 [ ' ~w'-[Action] ],
880 load_module(Module),
881 [ ' ~2f sec, ~D clauses'-[Time, Clauses] ].
882prolog_message(dwim_undefined(Goal, Alternatives)) -->
883 { goal_to_predicate_indicator(Goal, Pred)
884 },
885 [ 'Unknown procedure: ~q'-[Pred], nl,
886 ' However, there are definitions for:', nl
887 ],
888 dwim_message(Alternatives).
889prolog_message(dwim_correct(Into)) -->
890 [ 'Correct to: ~q? '-[Into], flush ].
891prolog_message(error(loop_error(Spec), file_search(Used))) -->
892 [ 'File search: too many levels of indirections on: ~p'-[Spec], nl,
893 ' Used alias expansions:', nl
894 ],
895 used_search(Used).
896prolog_message(minus_in_identifier) -->
897 [ 'The "-" character should not be used to separate words in an', nl,
898 'identifier. Check the SWI-Prolog FAQ for details.'
899 ].
900prolog_message(qlf(removed_after_error(File))) -->
901 [ 'Removed incomplete QLF file ~w'-[File] ].
902prolog_message(qlf(recompile(Spec,_Pl,_Qlf,Reason))) -->
903 [ '~p: recompiling QLF file'-[Spec] ],
904 qlf_recompile_reason(Reason).
905prolog_message(qlf(can_not_recompile(Spec,QlfFile,_Reason))) -->
906 [ '~p: can not recompile "~w" (access denied)'-[Spec, QlfFile], nl,
907 '\tLoading from source'-[]
908 ].
909prolog_message(qlf(system_lib_out_of_date(Spec,QlfFile))) -->
910 [ '~p: can not recompile "~w" (access denied)'-[Spec, QlfFile], nl,
911 '\tLoading QlfFile'-[]
912 ].
913prolog_message(redefine_module(Module, OldFile, File)) -->
914 [ 'Module "~q" already loaded from ~w.'-[Module, OldFile], nl,
915 'Wipe and reload from ~w? '-[File], flush
916 ].
917prolog_message(redefine_module_reply) -->
918 [ 'Please answer y(es), n(o) or a(bort)' ].
919prolog_message(reloaded_in_module(Absolute, OldContext, LM)) -->
920 [ '~w was previously loaded in module ~w'-[Absolute, OldContext], nl,
921 '\tnow it is reloaded into module ~w'-[LM] ].
922prolog_message(expected_layout(Expected, Pos)) -->
923 [ 'Layout data: expected ~w, found: ~p'-[Expected, Pos] ].
924
925defined_definition(Message, Spec) -->
926 { strip_module(user:Spec, M, Name/Arity),
927 functor(Head, Name, Arity),
928 predicate_property(M:Head, file(File)),
929 predicate_property(M:Head, line_count(Line))
930 },
931 !,
932 [ nl, '~w at '-[Message], url(File:Line) ].
933defined_definition(_, _) --> [].
934
935used_search([]) -->
936 [].
937used_search([Alias=Expanded|T]) -->
938 [ ' file_search_path(~p, ~p)'-[Alias, Expanded], nl ],
939 used_search(T).
940
941load_file(file(Spec, _Path)) -->
942 ( {atomic(Spec)}
943 -> [ '~w'-[Spec] ]
944 ; [ '~p'-[Spec] ]
945 ).
948
949load_module(user) --> !.
950load_module(system) --> !.
951load_module(Module) -->
952 [ ' into ~w'-[Module] ].
953
954goal_to_predicate_indicator(Goal, PI) :-
955 strip_module(Goal, Module, Head),
956 '$pi_head'(PI0, Module:Head),
957 ( current_predicate(PI0),
958 predicate_property(Module:Head, non_terminal)
959 -> dcg_pi(PI0, PI)
960 ; PI = PI0
961 ),
962 user_predicate_indicator(PI, PI).
963
964dcg_pi(Module:Name/Arity, Module:Name//DCGArity) :-
965 DCGArity is Arity-2.
966
967user_predicate_indicator(Module:PI, PI) :-
968 hidden_module(Module),
969 !.
970user_predicate_indicator(PI, PI).
971
972hidden_module(user) :- !.
973hidden_module(system) :- !.
974hidden_module(M) :-
975 sub_atom(M, 0, _, _, $).
976
977current_definition(Proc, Prefix) -->
978 { pi_uhead(Proc, Head),
979 predicate_property(Head, file(File)),
980 predicate_property(Head, line_count(Line))
981 },
982 [ '~w'-[Prefix], url(File:Line), nl ].
983current_definition(_, _) --> [].
984
985pi_uhead(Module:Name/Arity, Module:Head) :-
986 !,
987 atom(Module), atom(Name), integer(Arity),
988 functor(Head, Name, Arity).
989pi_uhead(Name/Arity, user:Head) :-
990 atom(Name), integer(Arity),
991 functor(Head, Name, Arity).
992
993qlf_recompile_reason(old) -->
994 !,
995 [ ' (out of date)'-[] ].
996qlf_recompile_reason(_) -->
997 [ ' (incompatible with current Prolog version)'-[] ].
998
999prolog_message(file_search(cache(Spec, _Cond), Path)) -->
1000 [ 'File search: ~p --> ~p (cache)'-[Spec, Path] ].
1001prolog_message(file_search(found(Spec, Cond), Path)) -->
1002 [ 'File search: ~p --> ~p OK ~p'-[Spec, Path, Cond] ].
1003prolog_message(file_search(tried(Spec, Cond), Path)) -->
1004 [ 'File search: ~p --> ~p NO ~p'-[Spec, Path, Cond] ].
1005
1006 1009
1010prolog_message(agc(start)) -->
1011 thread_context,
1012 [ 'AGC: ', flush ].
1013prolog_message(agc(done(Collected, Remaining, Time))) -->
1014 [ at_same_line,
1015 'reclaimed ~D atoms in ~3f sec. (remaining: ~D)'-
1016 [Collected, Time, Remaining]
1017 ].
1018prolog_message(cgc(start)) -->
1019 thread_context,
1020 [ 'CGC: ', flush ].
1021prolog_message(cgc(done(CollectedClauses, _CollectedBytes,
1022 RemainingBytes, Time))) -->
1023 [ at_same_line,
1024 'reclaimed ~D clauses in ~3f sec. (pending: ~D bytes)'-
1025 [CollectedClauses, Time, RemainingBytes]
1026 ].
1027
1028 1031
1032out_of_stack(Context) -->
1033 { human_stack_size(Context.localused, Local),
1034 human_stack_size(Context.globalused, Global),
1035 human_stack_size(Context.trailused, Trail),
1036 human_stack_size(Context.stack_limit, Limit),
1037 LCO is (100*(Context.depth - Context.environments))/Context.depth
1038 },
1039 [ 'Stack limit (~s) exceeded'-[Limit], nl,
1040 ' Stack sizes: local: ~s, global: ~s, trail: ~s'-[Local,Global,Trail], nl,
1041 ' Stack depth: ~D, last-call: ~0f%, Choice points: ~D'-
1042 [Context.depth, LCO, Context.choicepoints], nl
1043 ],
1044 overflow_reason(Context, Resolve),
1045 resolve_overflow(Resolve).
1046
1047human_stack_size(Size, String) :-
1048 Size < 100,
1049 format(string(String), '~dKb', [Size]).
1050human_stack_size(Size, String) :-
1051 Size < 100 000,
1052 Value is Size / 1024,
1053 format(string(String), '~1fMb', [Value]).
1054human_stack_size(Size, String) :-
1055 Value is Size / (1024*1024),
1056 format(string(String), '~1fGb', [Value]).
1057
1058overflow_reason(Context, fix) -->
1059 show_non_termination(Context),
1060 !.
1061overflow_reason(Context, enlarge) -->
1062 { Stack = Context.get(stack) },
1063 !,
1064 [ ' In:'-[], nl ],
1065 stack(Stack).
1066overflow_reason(_Context, enlarge) -->
1067 [ ' Insufficient global stack'-[] ].
1068
1069show_non_termination(Context) -->
1070 ( { Stack = Context.get(cycle) }
1071 -> [ ' Probable infinite recursion (cycle):'-[], nl ]
1072 ; { Stack = Context.get(non_terminating) }
1073 -> [ ' Possible non-terminating recursion:'-[], nl ]
1074 ),
1075 stack(Stack).
1076
1077stack([]) --> [].
1078stack([frame(Depth, M:Goal, _)|T]) -->
1079 [ ' [~D] ~q:'-[Depth, M] ],
1080 stack_goal(Goal),
1081 [ nl ],
1082 stack(T).
1083
1084stack_goal(Goal) -->
1085 { compound(Goal),
1086 !,
1087 compound_name_arity(Goal, Name, Arity)
1088 },
1089 [ '~q('-[Name] ],
1090 stack_goal_args(1, Arity, Goal),
1091 [ ')'-[] ].
1092stack_goal(Goal) -->
1093 [ '~q'-[Goal] ].
1094
1095stack_goal_args(I, Arity, Goal) -->
1096 { I =< Arity,
1097 !,
1098 arg(I, Goal, A),
1099 I2 is I + 1
1100 },
1101 stack_goal_arg(A),
1102 ( { I2 =< Arity }
1103 -> [ ', '-[] ],
1104 stack_goal_args(I2, Arity, Goal)
1105 ; []
1106 ).
1107stack_goal_args(_, _, _) -->
1108 [].
1109
1110stack_goal_arg(A) -->
1111 { nonvar(A),
1112 A = [Len|T],
1113 !
1114 },
1115 ( {Len == cyclic_term}
1116 -> [ '[cyclic list]'-[] ]
1117 ; {T == []}
1118 -> [ '[length:~D]'-[Len] ]
1119 ; [ '[length:~D|~p]'-[Len, T] ]
1120 ).
1121stack_goal_arg(A) -->
1122 { nonvar(A),
1123 A = _/_,
1124 !
1125 },
1126 [ '<compound ~p>'-[A] ].
1127stack_goal_arg(A) -->
1128 [ '~p'-[A] ].
1129
1130resolve_overflow(fix) -->
1131 [].
1132resolve_overflow(enlarge) -->
1133 { current_prolog_flag(stack_limit, LimitBytes),
1134 NewLimit is LimitBytes * 2
1135 },
1136 [ nl,
1137 'Use the --stack_limit=size[KMG] command line option or'-[], nl,
1138 '?- set_prolog_flag(stack_limit, ~I). to double the limit.'-[NewLimit]
1139 ].
1140
1145
1146out_of_c_stack -->
1147 { statistics(c_stack, Limit), Limit > 0 },
1148 !,
1149 [ 'C-stack limit (~D bytes) exceeded.'-[Limit], nl ],
1150 resolve_c_stack_overflow(Limit).
1151out_of_c_stack -->
1152 { statistics(c_stack, Limit), Limit > 0 },
1153 [ 'C-stack limit exceeded.'-[Limit], nl ],
1154 resolve_c_stack_overflow(Limit).
1155
1156resolve_c_stack_overflow(_Limit) -->
1157 { thread_self(main) },
1158 [ 'Use the shell command ' ], code('~w', 'ulimit -s size'),
1159 [ ' to enlarge the limit.' ].
1160resolve_c_stack_overflow(_Limit) -->
1161 [ 'Use the ' ], code('~w', 'c_stack(KBytes)'),
1162 [ ' option of '], code(thread_create/3), [' to enlarge the limit.' ].
1163
1164
1165 1168
1169prolog_message(make(reload(Files))) -->
1170 { length(Files, N)
1171 },
1172 [ 'Make: reloading ~D files'-[N] ].
1173prolog_message(make(done(_Files))) -->
1174 [ 'Make: finished' ].
1175prolog_message(make(library_index(Dir))) -->
1176 [ 'Updating index for library ~w'-[Dir] ].
1177prolog_message(autoload(Pred, File)) -->
1178 thread_context,
1179 [ 'autoloading ~p from ~w'-[Pred, File] ].
1180prolog_message(autoload(read_index(Dir))) -->
1181 [ 'Loading autoload index for ~w'-[Dir] ].
1182prolog_message(autoload(disabled(Loaded))) -->
1183 [ 'Disabled autoloading (loaded ~D files)'-[Loaded] ].
1184prolog_message(autoload(already_defined(PI, From))) -->
1185 code(PI),
1186 ( { '$pi_head'(PI, Head),
1187 predicate_property(Head, built_in)
1188 }
1189 -> [' is a built-in predicate']
1190 ; [ ' is already imported from module ' ],
1191 code(From)
1192 ).
1193
1194swi_message(autoload(Msg)) -->
1195 [ nl, ' ' ],
1196 autoload_message(Msg).
1197
1198autoload_message(not_exported(PI, Spec, _FullFile, _Exports)) -->
1199 [ ansi(code, '~w', [Spec]),
1200 ' does not export ',
1201 ansi(code, '~p', [PI])
1202 ].
1203autoload_message(no_file(Spec)) -->
1204 [ ansi(code, '~p', [Spec]), ': No such file' ].
1205
1206
1207 1210
1213
1214prolog_message(compiler_warnings(Clause, Warnings0)) -->
1215 { print_goal_options(DefOptions),
1216 ( prolog_load_context(variable_names, VarNames)
1217 -> warnings_with_named_vars(Warnings0, VarNames, Warnings),
1218 Options = [variable_names(VarNames)|DefOptions]
1219 ; Options = DefOptions,
1220 Warnings = Warnings0
1221 )
1222 },
1223 compiler_warnings(Warnings, Clause, Options).
1224
1225warnings_with_named_vars([], _, []).
1226warnings_with_named_vars([H|T0], VarNames, [H|T]) :-
1227 term_variables(H, Vars),
1228 '$member'(V1, Vars),
1229 '$member'(_=V2, VarNames),
1230 V1 == V2,
1231 !,
1232 warnings_with_named_vars(T0, VarNames, T).
1233warnings_with_named_vars([_|T0], VarNames, T) :-
1234 warnings_with_named_vars(T0, VarNames, T).
1235
1236
1237compiler_warnings([], _, _) --> [].
1238compiler_warnings([H|T], Clause, Options) -->
1239 ( compiler_warning(H, Clause, Options)
1240 -> []
1241 ; [ 'Unknown compiler warning: ~W'-[H,Options] ]
1242 ),
1243 ( {T==[]}
1244 -> []
1245 ; [nl]
1246 ),
1247 compiler_warnings(T, Clause, Options).
1248
1249compiler_warning(eq_vv(A,B), _Clause, Options) -->
1250 ( { A == B }
1251 -> [ 'Test is always true: ~W'-[A==B, Options] ]
1252 ; [ 'Test is always false: ~W'-[A==B, Options] ]
1253 ).
1254compiler_warning(eq_singleton(A,B), _Clause, Options) -->
1255 [ 'Test is always false: ~W'-[A==B, Options] ].
1256compiler_warning(neq_vv(A,B), _Clause, Options) -->
1257 ( { A \== B }
1258 -> [ 'Test is always true: ~W'-[A\==B, Options] ]
1259 ; [ 'Test is always false: ~W'-[A\==B, Options] ]
1260 ).
1261compiler_warning(neq_singleton(A,B), _Clause, Options) -->
1262 [ 'Test is always true: ~W'-[A\==B, Options] ].
1263compiler_warning(unify_singleton(A,B), _Clause, Options) -->
1264 [ 'Unified variable is not used: ~W'-[A=B, Options] ].
1265compiler_warning(always(Bool, Pred, Arg), _Clause, Options) -->
1266 { Goal =.. [Pred,Arg] },
1267 [ 'Test is always ~w: ~W'-[Bool, Goal, Options] ].
1268compiler_warning(unbalanced_var(V), _Clause, Options) -->
1269 [ 'Variable not introduced in all branches: ~W'-[V, Options] ].
1270compiler_warning(branch_singleton(V), _Clause, Options) -->
1271 [ 'Singleton variable in branch: ~W'-[V, Options] ].
1272compiler_warning(negation_singleton(V), _Clause, Options) -->
1273 [ 'Singleton variable in \\+: ~W'-[V, Options] ].
1274compiler_warning(multiton(V), _Clause, Options) -->
1275 [ 'Singleton-marked variable appears more than once: ~W'-[V, Options] ].
1276
1277print_goal_options(
1278 [ quoted(true),
1279 portray(true)
1280 ]).
1281
1282
1283 1286
1287prolog_message(version) -->
1288 { current_prolog_flag(version_git, Version) },
1289 !,
1290 [ '~w'-[Version] ].
1291prolog_message(version) -->
1292 { current_prolog_flag(version_data, swi(Major,Minor,Patch,Options))
1293 },
1294 ( { '$option'(tag(Tag), Options) }
1295 -> [ '~w.~w.~w-~w'-[Major, Minor, Patch, Tag] ]
1296 ; [ '~w.~w.~w'-[Major, Minor, Patch] ]
1297 ).
1298prolog_message(address_bits) -->
1299 { current_prolog_flag(address_bits, Bits)
1300 },
1301 !,
1302 [ '~d bits, '-[Bits] ].
1303prolog_message(threads) -->
1304 { current_prolog_flag(threads, true)
1305 },
1306 !,
1307 [ 'threaded, ' ].
1308prolog_message(threads) -->
1309 [].
1310prolog_message(copyright) -->
1311 [ 'SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.', nl,
1312 'Please run ', ansi(code, '?- license.', []), ' for legal details.'
1313 ].
1314prolog_message(documentaton) -->
1315 [ 'For online help and background, visit ', url('https://www.swi-prolog.org') ],
1316 ( { exists_source(library(help)) }
1317 -> [ nl,
1318 'For built-in help, use ', ansi(code, '?- help(Topic).', []),
1319 ' or ', ansi(code, '?- apropos(Word).', [])
1320 ]
1321 ; []
1322 ).
1323prolog_message(about) -->
1324 [ 'SWI-Prolog version (' ],
1325 prolog_message(threads),
1326 prolog_message(address_bits),
1327 ['version ' ],
1328 prolog_message(version),
1329 [ ')', nl ],
1330 prolog_message(copyright).
1331prolog_message(halt) -->
1332 [ 'halt' ].
1333prolog_message(break(begin, Level)) -->
1334 [ 'Break level ~d'-[Level] ].
1335prolog_message(break(end, Level)) -->
1336 [ 'Exit break level ~d'-[Level] ].
1337prolog_message(var_query(_)) -->
1338 [ '... 1,000,000 ............ 10,000,000 years later', nl, nl,
1339 '~t~8|>> 42 << (last release gives the question)'
1340 ].
1341prolog_message(close_on_abort(Stream)) -->
1342 [ 'Abort: closed stream ~p'-[Stream] ].
1343prolog_message(cancel_halt(Reason)) -->
1344 [ 'Halt cancelled: ~p'-[Reason] ].
1345prolog_message(on_error(halt(Status))) -->
1346 { statistics(errors, Errors),
1347 statistics(warnings, Warnings)
1348 },
1349 [ 'Halting with status ~w due to ~D errors and ~D warnings'-
1350 [Status, Errors, Warnings] ].
1351
1352prolog_message(query(QueryResult)) -->
1353 query_result(QueryResult).
1354
1355query_result(no) --> 1356 [ ansi(truth(false), 'false.', []) ],
1357 extra_line.
1358query_result(yes(true, [])) --> 1359 !,
1360 [ ansi(truth(true), 'true.', []) ],
1361 extra_line.
1362query_result(yes(Delays, Residuals)) -->
1363 result([], Delays, Residuals),
1364 extra_line.
1365query_result(done) --> 1366 extra_line.
1367query_result(yes(Bindings, Delays, Residuals)) -->
1368 result(Bindings, Delays, Residuals),
1369 prompt(yes, Bindings, Delays, Residuals).
1370query_result(more(Bindings, Delays, Residuals)) -->
1371 result(Bindings, Delays, Residuals),
1372 prompt(more, Bindings, Delays, Residuals).
1373:- if(current_prolog_flag(emscripten, true)). 1374query_result(help) -->
1375 [ ansi(bold, ' Possible actions:', []), nl,
1376 ' ; (n,r,space): redo | t: trace&redo'-[], nl,
1377 ' *: show choicepoint | . (c,a): stop'-[], nl,
1378 ' w: write | p: print'-[], nl,
1379 ' +: max_depth*5 | -: max_depth//5'-[], nl,
1380 ' h (?): help'-[],
1381 nl, nl
1382 ].
1383:- else. 1384query_result(help) -->
1385 [ ansi(bold, ' Possible actions:', []), nl,
1386 ' ; (n,r,space,TAB): redo | t: trace&redo'-[], nl,
1387 ' *: show choicepoint | . (c,a,RET): stop'-[], nl,
1388 ' w: write | p: print'-[], nl,
1389 ' +: max_depth*5 | -: max_depth//5'-[], nl,
1390 ' b: break | h (?): help'-[],
1391 nl, nl
1392 ].
1393:- endif. 1394query_result(action) -->
1395 [ 'Action? '-[], flush ].
1396query_result(confirm) -->
1397 [ 'Please answer \'y\' or \'n\'? '-[], flush ].
1398query_result(eof) -->
1399 [ nl ].
1400query_result(toplevel_open_line) -->
1401 [].
1402
1403prompt(Answer, [], true, []-[]) -->
1404 !,
1405 prompt(Answer, empty).
1406prompt(Answer, _, _, _) -->
1407 !,
1408 prompt(Answer, non_empty).
1409
1410prompt(yes, empty) -->
1411 !,
1412 [ ansi(truth(true), 'true.', []) ],
1413 extra_line.
1414prompt(yes, _) -->
1415 !,
1416 [ full_stop ],
1417 extra_line.
1418prompt(more, empty) -->
1419 !,
1420 [ ansi(truth(true), 'true ', []), flush ].
1421prompt(more, _) -->
1422 !,
1423 [ ' '-[], flush ].
1424
1425result(Bindings, Delays, Residuals) -->
1426 { current_prolog_flag(answer_write_options, Options0),
1427 Options = [partial(true)|Options0],
1428 GOptions = [priority(999)|Options0]
1429 },
1430 wfs_residual_program(Delays, GOptions),
1431 bindings(Bindings, [priority(699)|Options]),
1432 ( {Residuals == []-[]}
1433 -> bind_delays_sep(Bindings, Delays),
1434 delays(Delays, GOptions)
1435 ; bind_res_sep(Bindings, Residuals),
1436 residuals(Residuals, GOptions),
1437 ( {Delays == true}
1438 -> []
1439 ; [','-[], nl],
1440 delays(Delays, GOptions)
1441 )
1442 ).
1443
1444bindings([], _) -->
1445 [].
1446bindings([binding(Names,Skel,Subst)|T], Options) -->
1447 { '$last'(Names, Name) },
1448 var_names(Names), value(Name, Skel, Subst, Options),
1449 ( { T \== [] }
1450 -> [ ','-[], nl ],
1451 bindings(T, Options)
1452 ; []
1453 ).
1454
1455var_names([Name]) -->
1456 !,
1457 [ '~w = '-[Name] ].
1458var_names([Name1,Name2|T]) -->
1459 !,
1460 [ '~w = ~w, '-[Name1, Name2] ],
1461 var_names([Name2|T]).
1462
1463
1464value(Name, Skel, Subst, Options) -->
1465 ( { var(Skel), Subst = [Skel=S] }
1466 -> { Skel = '$VAR'(Name) },
1467 [ '~W'-[S, Options] ]
1468 ; [ '~W'-[Skel, Options] ],
1469 substitution(Subst, Options)
1470 ).
1471
1472substitution([], _) --> !.
1473substitution([N=V|T], Options) -->
1474 [ ', ', ansi(comment, '% where', []), nl,
1475 ' ~w = ~W'-[N,V,Options] ],
1476 substitutions(T, Options).
1477
1478substitutions([], _) --> [].
1479substitutions([N=V|T], Options) -->
1480 [ ','-[], nl, ' ~w = ~W'-[N,V,Options] ],
1481 substitutions(T, Options).
1482
1483
1484residuals(Normal-Hidden, Options) -->
1485 residuals1(Normal, Options),
1486 bind_res_sep(Normal, Hidden),
1487 ( {Hidden == []}
1488 -> []
1489 ; [ansi(comment, '% with pending residual goals', []), nl]
1490 ),
1491 residuals1(Hidden, Options).
1492
1493residuals1([], _) -->
1494 [].
1495residuals1([G|Gs], Options) -->
1496 ( { Gs \== [] }
1497 -> [ '~W,'-[G, Options], nl ],
1498 residuals1(Gs, Options)
1499 ; [ '~W'-[G, Options] ]
1500 ).
1501
1502wfs_residual_program(true, _Options) -->
1503 !.
1504wfs_residual_program(Goal, _Options) -->
1505 { current_prolog_flag(toplevel_list_wfs_residual_program, true),
1506 '$current_typein_module'(TypeIn),
1507 ( current_predicate(delays_residual_program/2)
1508 -> true
1509 ; use_module(library(wfs), [delays_residual_program/2])
1510 ),
1511 delays_residual_program(TypeIn:Goal, TypeIn:Program),
1512 Program \== []
1513 },
1514 !,
1515 [ ansi(comment, '% WFS residual program', []), nl ],
1516 [ ansi(wfs(residual_program), '~@', ['$messages':list_clauses(Program)]) ].
1517wfs_residual_program(_, _) --> [].
1518
1519delays(true, _Options) -->
1520 !.
1521delays(Goal, Options) -->
1522 { current_prolog_flag(toplevel_list_wfs_residual_program, true)
1523 },
1524 !,
1525 [ ansi(truth(undefined), '~W', [Goal, Options]) ].
1526delays(_, _Options) -->
1527 [ ansi(truth(undefined), undefined, []) ].
1528
1529:- public list_clauses/1. 1530
1531list_clauses([]).
1532list_clauses([H|T]) :-
1533 ( system_undefined(H)
1534 -> true
1535 ; portray_clause(user_output, H, [indent(4)])
1536 ),
1537 list_clauses(T).
1538
1539system_undefined((undefined :- tnot(undefined))).
1540system_undefined((answer_count_restraint :- tnot(answer_count_restraint))).
1541system_undefined((radial_restraint :- tnot(radial_restraint))).
1542
1543bind_res_sep(_, []) --> !.
1544bind_res_sep(_, []-[]) --> !.
1545bind_res_sep([], _) --> !.
1546bind_res_sep(_, _) --> [','-[], nl].
1547
1548bind_delays_sep([], _) --> !.
1549bind_delays_sep(_, true) --> !.
1550bind_delays_sep(_, _) --> [','-[], nl].
1551
-->
1553 { current_prolog_flag(toplevel_extra_white_line, true) },
1554 !,
1555 ['~N'-[]].
1556extra_line -->
1557 [].
1558
1559prolog_message(if_tty(Message)) -->
1560 ( {current_prolog_flag(tty_control, true)}
1561 -> [ at_same_line ], list(Message)
1562 ; []
1563 ).
1564prolog_message(halt(Reason)) -->
1565 [ '~w: halt'-[Reason] ].
1566prolog_message(no_action(Char)) -->
1567 [ 'Unknown action: ~c (h for help)'-[Char], nl ].
1568
1569prolog_message(history(help(Show, Help))) -->
1570 [ 'History Commands:', nl,
1571 ' !!. Repeat last query', nl,
1572 ' !nr. Repeat query numbered <nr>', nl,
1573 ' !str. Repeat last query starting with <str>', nl,
1574 ' !?str. Repeat last query holding <str>', nl,
1575 ' ^old^new. Substitute <old> into <new> of last query', nl,
1576 ' !nr^old^new. Substitute in query numbered <nr>', nl,
1577 ' !str^old^new. Substitute in query starting with <str>', nl,
1578 ' !?str^old^new. Substitute in query holding <str>', nl,
1579 ' ~w.~21|Show history list'-[Show], nl,
1580 ' ~w.~21|Show this list'-[Help], nl, nl
1581 ].
1582prolog_message(history(no_event)) -->
1583 [ '! No such event' ].
1584prolog_message(history(bad_substitution)) -->
1585 [ '! Bad substitution' ].
1586prolog_message(history(expanded(Event))) -->
1587 [ '~w.'-[Event] ].
1588prolog_message(history(history(Events))) -->
1589 history_events(Events).
1590prolog_message(history(no_history)) -->
1591 [ '! event history not supported in this version' ].
1592
1593history_events([]) -->
1594 [].
1595history_events([Nr-Event|T]) -->
1596 [ ansi(comment, '%', []),
1597 ansi(bold, '~t~w ~6|', [Nr]),
1598 ansi(code, '~s', [Event]),
1599 nl
1600 ],
1601 history_events(T).
1602
1603
1608
1609user_version_messages([]) --> [].
1610user_version_messages([H|T]) -->
1611 user_version_message(H),
1612 user_version_messages(T).
1613
1615
1616user_version_message(Term) -->
1617 translate_message(Term), !, [nl].
1618user_version_message(Atom) -->
1619 [ '~w'-[Atom], nl ].
1620
1621
1622 1625
1626prolog_message(spy(Head)) -->
1627 [ 'New spy point on ' ],
1628 goal_predicate(Head).
1629prolog_message(already_spying(Head)) -->
1630 [ 'Already spying ' ],
1631 goal_predicate(Head).
1632prolog_message(nospy(Head)) -->
1633 [ 'Removed spy point from ' ],
1634 goal_predicate(Head).
1635prolog_message(trace_mode(OnOff)) -->
1636 [ 'Trace mode switched to ~w'-[OnOff] ].
1637prolog_message(debug_mode(OnOff)) -->
1638 [ 'Debug mode switched to ~w'-[OnOff] ].
1639prolog_message(debugging(OnOff, Threads)) -->
1640 [ 'Debug mode is ~w'-[OnOff] ],
1641 debugging_threads(Threads).
1642prolog_message(spying([])) -->
1643 !,
1644 [ 'No spy points' ].
1645prolog_message(spying(Heads)) -->
1646 [ 'Spy points (see spy/1) on:', nl ],
1647 predicate_list(Heads).
1648prolog_message(trace(Head, [])) -->
1649 !,
1650 [ ' ' ], goal_predicate(Head), [ ' Not tracing'-[], nl].
1651prolog_message(trace(Head, Ports)) -->
1652 { '$member'(Port, Ports), compound(Port),
1653 !,
1654 numbervars(Head+Ports, 0, _, [singletons(true)])
1655 },
1656 [ ' ~p: ~p'-[Head,Ports] ].
1657prolog_message(trace(Head, Ports)) -->
1658 [ ' ' ], goal_predicate(Head), [ ': ~w'-[Ports], nl].
1659prolog_message(tracing([])) -->
1660 !,
1661 [ 'No traced predicates (see trace/1,2)' ].
1662prolog_message(tracing(Heads)) -->
1663 [ 'Trace points (see trace/1,2) on:', nl ],
1664 tracing_list(Heads).
1665
1666goal_predicate(Head) -->
1667 { predicate_property(Head, file(File)),
1668 predicate_property(Head, line_count(Line)),
1669 goal_to_predicate_indicator(Head, PI),
1670 term_string(PI, PIS, [quoted(true)])
1671 },
1672 [ url(File:Line, PIS) ].
1673goal_predicate(Head) -->
1674 { goal_to_predicate_indicator(Head, PI)
1675 },
1676 [ ansi(code, '~p', [PI]) ].
1677
1678
1679predicate_list([]) --> 1680 [].
1681predicate_list([H|T]) -->
1682 [ ' ' ], goal_predicate(H), [nl],
1683 predicate_list(T).
1684
1685tracing_list([]) -->
1686 [].
1687tracing_list([trace(Head, Ports)|T]) -->
1688 translate_message(trace(Head, Ports)),
1689 tracing_list(T).
1690
1691debugging_threads([]) -->
1692 [].
1693debugging_threads(ThreadsByClass) -->
1694 [ nl, 'Threads in the following classes run in debug mode:', nl],
1695 list_threads_by_class(ThreadsByClass).
1696
1697list_threads_by_class([]) -->
1698 [].
1699list_threads_by_class([H|T]) -->
1700 list_thread_class(H),
1701 list_threads_by_class(T).
1702
1703list_thread_class(Class-Threads) -->
1704 { length(Threads, Count) },
1705 [ ' Class ', ansi(code, '~p', [Class]), ': ~D threads'-[Count] ].
1706
1708prolog_message(frame(Frame, _Choice, backtrace, _PC)) -->
1709 !,
1710 { prolog_frame_attribute(Frame, level, Level)
1711 },
1712 [ ansi(frame(level), '~t[~D] ~10|', [Level]) ],
1713 frame_context(Frame),
1714 frame_goal(Frame).
1715prolog_message(frame(Frame, _Choice, choice, PC)) -->
1716 !,
1717 prolog_message(frame(Frame, backtrace, PC)).
1718prolog_message(frame(_, _Choice, cut_call(_PC), _)) --> !.
1719prolog_message(frame(Frame, _Choice, Port, _PC)) -->
1720 frame_flags(Frame),
1721 port(Port),
1722 frame_level(Frame),
1723 frame_context(Frame),
1724 frame_depth_limit(Port, Frame),
1725 frame_goal(Frame),
1726 [ flush ].
1727
1729prolog_message(frame(Goal, trace(Port))) -->
1730 !,
1731 thread_context,
1732 [ ' T ' ],
1733 port(Port),
1734 goal(Goal).
1735prolog_message(frame(Goal, trace(Port, Id))) -->
1736 !,
1737 thread_context,
1738 [ ' T ' ],
1739 port(Port, Id),
1740 goal(Goal).
1741
1742frame_goal(Frame) -->
1743 { prolog_frame_attribute(Frame, goal, Goal)
1744 },
1745 goal(Goal).
1746
1747goal(Goal0) -->
1748 { clean_goal(Goal0, Goal),
1749 current_prolog_flag(debugger_write_options, Options)
1750 },
1751 [ '~W'-[Goal, Options] ].
1752
1753frame_level(Frame) -->
1754 { prolog_frame_attribute(Frame, level, Level)
1755 },
1756 [ '(~D) '-[Level] ].
1757
1758frame_context(Frame) -->
1759 ( { current_prolog_flag(debugger_show_context, true),
1760 prolog_frame_attribute(Frame, context_module, Context)
1761 }
1762 -> [ '[~w] '-[Context] ]
1763 ; []
1764 ).
1765
1766frame_depth_limit(fail, Frame) -->
1767 { prolog_frame_attribute(Frame, depth_limit_exceeded, true)
1768 },
1769 !,
1770 [ '[depth-limit exceeded] ' ].
1771frame_depth_limit(_, _) -->
1772 [].
1773
1774frame_flags(Frame) -->
1775 { prolog_frame_attribute(Frame, goal, Goal),
1776 ( predicate_property(Goal, transparent)
1777 -> T = '^'
1778 ; T = ' '
1779 ),
1780 ( predicate_property(Goal, spying)
1781 -> S = '*'
1782 ; S = ' '
1783 )
1784 },
1785 [ '~w~w '-[T, S] ].
1786
1788port(Port, Dict) -->
1789 { _{level:Level, start:Time} :< Dict
1790 },
1791 ( { Port \== call,
1792 get_time(Now),
1793 Passed is (Now - Time)*1000.0
1794 }
1795 -> [ '[~d +~1fms] '-[Level, Passed] ]
1796 ; [ '[~d] '-[Level] ]
1797 ),
1798 port(Port).
1799port(Port, _Id-Level) -->
1800 [ '[~d] '-[Level] ],
1801 port(Port).
1802
1803port(PortTerm) -->
1804 { functor(PortTerm, Port, _),
1805 port_name(Port, Name)
1806 },
1807 !,
1808 [ ansi(port(Port), '~w: ', [Name]) ].
1809
1810port_name(call, 'Call').
1811port_name(exit, 'Exit').
1812port_name(fail, 'Fail').
1813port_name(redo, 'Redo').
1814port_name(unify, 'Unify').
1815port_name(exception, 'Exception').
1816
1817clean_goal(M:Goal, Goal) :-
1818 hidden_module(M),
1819 !.
1820clean_goal(M:Goal, Goal) :-
1821 predicate_property(M:Goal, built_in),
1822 !.
1823clean_goal(Goal, Goal).
1824
1825
1826 1829
1830prolog_message(compatibility(renamed(Old, New))) -->
1831 [ 'The predicate ~p has been renamed to ~p.'-[Old, New], nl,
1832 'Please update your sources for compatibility with future versions.'
1833 ].
1834
1835
1836 1839
1840prolog_message(abnormal_thread_completion(Goal, exception(Ex))) -->
1841 !,
1842 [ 'Thread running "~p" died on exception: '-[Goal] ],
1843 translate_message(Ex).
1844prolog_message(abnormal_thread_completion(Goal, fail)) -->
1845 [ 'Thread running "~p" died due to failure'-[Goal] ].
1846prolog_message(threads_not_died(Running)) -->
1847 [ 'The following threads wouldn\'t die: ~p'-[Running] ].
1848
1849
1850 1853
1854prolog_message(pack(attached(Pack, BaseDir))) -->
1855 [ 'Attached package ~w at ~q'-[Pack, BaseDir] ].
1856prolog_message(pack(duplicate(Entry, OldDir, Dir))) -->
1857 [ 'Package ~w already attached at ~q.'-[Entry,OldDir], nl,
1858 '\tIgnoring version from ~q'- [Dir]
1859 ].
1860prolog_message(pack(no_arch(Entry, Arch))) -->
1861 [ 'Package ~w: no binary for architecture ~w'-[Entry, Arch] ].
1862
1863 1866
1867prolog_message(null_byte_in_path(Component)) -->
1868 [ '0-byte in PATH component: ~p (skipped directory)'-[Component] ].
1869prolog_message(invalid_tmp_dir(Dir, Reason)) -->
1870 [ 'Cannot use ~p as temporary file directory: ~w'-[Dir, Reason] ].
1871prolog_message(ambiguous_stream_pair(Pair)) -->
1872 [ 'Ambiguous operation on stream pair ~p'-[Pair] ].
1873prolog_message(backcomp(init_file_moved(FoundFile))) -->
1874 { absolute_file_name(app_config('init.pl'), InitFile,
1875 [ file_errors(fail)
1876 ])
1877 },
1878 [ 'The location of the config file has moved'-[], nl,
1879 ' from "~w"'-[FoundFile], nl,
1880 ' to "~w"'-[InitFile], nl,
1881 ' See https://www.swi-prolog.org/modified/config-files.html'-[]
1882 ].
1883prolog_message(not_accessed_flags(List)) -->
1884 [ 'The following Prolog flags have been set but not used:', nl ],
1885 flags(List).
1886prolog_message(prolog_flag_invalid_preset(Flag, Preset, _Type, New)) -->
1887 [ 'Prolog flag ', ansi(code, '~q', Flag), ' has been (re-)created with a type that is \c
1888 incompatible with its value.', nl,
1889 'Value updated from ', ansi(code, '~p', [Preset]), ' to default (',
1890 ansi(code, '~p', [New]), ')'
1891 ].
1892
1893
1894flags([H|T]) -->
1895 [' ', ansi(code, '~q', [H])],
1896 ( {T == []}
1897 -> []
1898 ; [nl],
1899 flags(T)
1900 ).
1901
1902
1903 1906
1907deprecated(set_prolog_stack(_Stack,limit)) -->
1908 [ 'set_prolog_stack/2: limit(Size) sets the combined limit.'-[], nl,
1909 'See https://www.swi-prolog.org/changes/stack-limit.html'
1910 ].
1911deprecated(autoload(TargetModule, File, _M:PI, expansion)) -->
1912 !,
1913 [ 'Auto-loading ', ansi(code, '~p', [PI]), ' from ' ],
1914 load_file(File), [ ' into ' ],
1915 target_module(TargetModule),
1916 [ ' is deprecated due to term- or goal-expansion' ].
1917deprecated(source_search_working_directory(File, _FullFile)) -->
1918 [ 'Found file ', ansi(code, '~w', [File]),
1919 ' relative to the current working directory.', nl,
1920 'This behaviour is deprecated but still supported by', nl,
1921 'the Prolog flag ',
1922 ansi(code, source_search_working_directory, []), '.', nl
1923 ].
1924deprecated(moved_library(Old, New)) -->
1925 [ 'Library was moved: ~q --> ~q'-[Old, New] ].
1926
1927load_file(File) -->
1928 { file_base_name(File, Base),
1929 absolute_file_name(library(Base), File, [access(read), file_errors(fail)]),
1930 file_name_extension(Clean, pl, Base)
1931 },
1932 !,
1933 [ ansi(code, '~p', [library(Clean)]) ].
1934load_file(File) -->
1935 [ url(File) ].
1936
1937target_module(Module) -->
1938 { module_property(Module, file(File)) },
1939 !,
1940 load_file(File).
1941target_module(Module) -->
1942 [ 'module ', ansi(code, '~p', [Module]) ].
1943
1944
1945
1946 1949
1950tripwire_message(max_integer_size, Bytes) -->
1951 !,
1952 [ 'Trapped tripwire max_integer_size: big integers and \c
1953 rationals are limited to ~D bytes'-[Bytes] ].
1954tripwire_message(Wire, Context) -->
1955 [ 'Trapped tripwire ~w for '-[Wire] ],
1956 tripwire_context(Wire, Context).
1957
1958tripwire_context(_, ATrie) -->
1959 { '$is_answer_trie'(ATrie, _),
1960 !,
1961 '$tabling':atrie_goal(ATrie, QGoal),
1962 user_predicate_indicator(QGoal, Goal)
1963 },
1964 [ '~p'-[Goal] ].
1965tripwire_context(_, Ctx) -->
1966 [ '~p'-[Ctx] ].
1967
1968
1969 1972
1973:- create_prolog_flag(message_language, default, []). 1974
1979
1980message_lang(Lang) :-
1981 current_message_lang(Lang0),
1982 ( Lang0 == en
1983 -> Lang = en
1984 ; sub_atom(Lang0, 0, _, _, en_)
1985 -> longest_id(Lang0, Lang)
1986 ; ( longest_id(Lang0, Lang)
1987 ; Lang = en
1988 )
1989 ).
1990
1991longest_id(Lang, Id) :-
1992 split_string(Lang, "_-", "", [H|Components]),
1993 longest_prefix(Components, Taken),
1994 atomic_list_concat([H|Taken], '_', Id).
1995
1996longest_prefix([H|T0], [H|T]) :-
1997 longest_prefix(T0, T).
1998longest_prefix(_, []).
1999
2003
2004current_message_lang(Lang) :-
2005 ( current_prolog_flag(message_language, Lang0),
2006 Lang0 \== default
2007 -> Lang = Lang0
2008 ; os_user_lang(Lang0)
2009 -> clean_encoding(Lang0, Lang1),
2010 set_prolog_flag(message_language, Lang1),
2011 Lang = Lang1
2012 ; Lang = en
2013 ).
2014
2015os_user_lang(Lang) :-
2016 current_prolog_flag(windows, true),
2017 win_get_user_preferred_ui_languages(name, [Lang|_]).
2018os_user_lang(Lang) :-
2019 catch(setlocale(messages, _, ''), _, fail),
2020 setlocale(messages, Lang, Lang).
2021os_user_lang(Lang) :-
2022 getenv('LANG', Lang).
2023
2024
2025clean_encoding(Lang0, Lang) :-
2026 ( sub_atom(Lang0, A, _, _, '.')
2027 -> sub_atom(Lang0, 0, A, _, Lang)
2028 ; Lang = Lang0
2029 ).
2030
2031 2034
2035code(Term) -->
2036 code('~p', Term).
2037
2038code(Format, Term) -->
2039 [ ansi(code, Format, [Term]) ].
2040
2041list([]) --> [].
2042list([H|T]) --> [H], list(T).
2043
2044
2045 2048
2049:- public default_theme/2. 2050
2051default_theme(var, [fg(red)]).
2052default_theme(code, [fg(blue)]).
2053default_theme(comment, [fg(green)]).
2054default_theme(warning, [fg(red)]).
2055default_theme(error, [bold, fg(red)]).
2056default_theme(truth(false), [bold, fg(red)]).
2057default_theme(truth(true), [bold]).
2058default_theme(truth(undefined), [bold, fg(cyan)]).
2059default_theme(wfs(residual_program), [fg(cyan)]).
2060default_theme(frame(level), [bold]).
2061default_theme(port(call), [bold, fg(green)]).
2062default_theme(port(exit), [bold, fg(green)]).
2063default_theme(port(fail), [bold, fg(red)]).
2064default_theme(port(redo), [bold, fg(yellow)]).
2065default_theme(port(unify), [bold, fg(blue)]).
2066default_theme(port(exception), [bold, fg(magenta)]).
2067default_theme(message(informational), [fg(green)]).
2068default_theme(message(information), [fg(green)]).
2069default_theme(message(debug(_)), [fg(blue)]).
2070default_theme(message(Level), Attrs) :-
2071 nonvar(Level),
2072 default_theme(Level, Attrs).
2073
2074
2075 2078
2079:- multifile
2080 user:message_hook/3,
2081 prolog:message_prefix_hook/2. 2082:- dynamic
2083 user:message_hook/3,
2084 prolog:message_prefix_hook/2. 2085:- thread_local
2086 user:thread_message_hook/3. 2087:- '$notransact'((user:message_hook/3,
2088 prolog:message_prefix_hook/2,
2089 user:thread_message_hook/3)). 2090
2095
2096print_message(Level, _Term) :-
2097 msg_property(Level, stream(S)),
2098 stream_property(S, error(true)),
2099 !.
2100print_message(Level, Term) :-
2101 setup_call_cleanup(
2102 notrace(push_msg(Term, Stack)),
2103 ignore(print_message_guarded(Level, Term)),
2104 notrace(pop_msg(Stack))),
2105 !.
2106print_message(Level, Term) :-
2107 ( Level \== silent
2108 -> format(user_error, 'Recursive ~w message: ~q~n', [Level, Term]),
2109 autoload_call(backtrace(20))
2110 ; true
2111 ).
2112
2113push_msg(Term, Messages) :-
2114 nb_current('$inprint_message', Messages),
2115 !,
2116 \+ ( '$member'(Msg, Messages),
2117 Msg =@= Term
2118 ),
2119 Stack = [Term|Messages],
2120 b_setval('$inprint_message', Stack).
2121push_msg(Term, []) :-
2122 b_setval('$inprint_message', [Term]).
2123
2124pop_msg(Stack) :-
2125 nb_delete('$inprint_message'), 2126 b_setval('$inprint_message', Stack).
2127
2128print_message_guarded(Level, Term) :-
2129 ( must_print(Level, Term)
2130 -> ( prolog:message_action(Term, Level),
2131 fail 2132 ; true 2133 ),
2134 ( translate_message(Term, Lines, [])
2135 -> ( nonvar(Term),
2136 ( notrace(user:thread_message_hook(Term, Level, Lines))
2137 -> true
2138 ; notrace(user:message_hook(Term, Level, Lines))
2139 )
2140 -> true
2141 ; '$inc_message_count'(Level),
2142 print_system_message(Term, Level, Lines),
2143 maybe_halt_on_error(Level)
2144 )
2145 )
2146 ; true
2147 ).
2148
2149maybe_halt_on_error(error) :-
2150 current_prolog_flag(on_error, halt),
2151 !,
2152 halt(1).
2153maybe_halt_on_error(warning) :-
2154 current_prolog_flag(on_warning, halt),
2155 !,
2156 halt(1).
2157maybe_halt_on_error(_).
2158
2159
2166
2167print_system_message(_, silent, _) :- !.
2168print_system_message(_, informational, _) :-
2169 current_prolog_flag(verbose, silent),
2170 !.
2171print_system_message(_, banner, _) :-
2172 current_prolog_flag(verbose, silent),
2173 !.
2174print_system_message(_, _, []) :- !.
2175print_system_message(Term, Kind, Lines) :-
2176 catch(flush_output(user_output), _, true), 2177 source_location(File, Line),
2178 Term \= error(syntax_error(_), _),
2179 msg_property(Kind, location_prefix(File:Line, LocPrefix, LinePrefix)),
2180 !,
2181 to_list(LocPrefix, LocPrefixL),
2182 insert_prefix(Lines, LinePrefix, Ctx, PrefixLines),
2183 '$append'([ [begin(Kind, Ctx)],
2184 LocPrefixL,
2185 [nl],
2186 PrefixLines,
2187 [end(Ctx)]
2188 ],
2189 AllLines),
2190 msg_property(Kind, stream(Stream)),
2191 ignore(stream_property(Stream, position(Pos))),
2192 print_message_lines(Stream, AllLines),
2193 ( \+ stream_property(Stream, position(Pos)),
2194 msg_property(Kind, wait(Wait)),
2195 Wait > 0
2196 -> sleep(Wait)
2197 ; true
2198 ).
2199print_system_message(_, Kind, Lines) :-
2200 msg_property(Kind, stream(Stream)),
2201 print_message_lines(Stream, kind(Kind), Lines).
2202
2203to_list(ListIn, List) :-
2204 is_list(ListIn),
2205 !,
2206 List = ListIn.
2207to_list(NonList, [NonList]).
2208
2209:- multifile
2210 user:message_property/2. 2211
2212msg_property(Kind, Property) :-
2213 notrace(user:message_property(Kind, Property)),
2214 !.
2215msg_property(Kind, prefix(Prefix)) :-
2216 msg_prefix(Kind, Prefix),
2217 !.
2218msg_property(_, prefix('~N')) :- !.
2219msg_property(query, stream(user_output)) :- !.
2220msg_property(_, stream(user_error)) :- !.
2221msg_property(error, tag('ERROR')).
2222msg_property(warning, tag('Warning')).
2223msg_property(Level,
2224 location_prefix(File:Line,
2225 ['~N~w: '-[Tag], url(File:Line), ':'],
2226 '~N~w: '-[Tag])) :-
2227 include_msg_location(Level),
2228 msg_property(Level, tag(Tag)).
2229msg_property(error, wait(0.1)) :- !.
2230
2231include_msg_location(warning).
2232include_msg_location(error).
2233
2234msg_prefix(debug(_), Prefix) :-
2235 msg_context('~N% ', Prefix).
2236msg_prefix(Level, Prefix) :-
2237 msg_property(Level, tag(Tag)),
2238 atomics_to_string(['~N', Tag, ': '], Prefix0),
2239 msg_context(Prefix0, Prefix).
2240msg_prefix(informational, '~N% ').
2241msg_prefix(information, '~N% ').
2242
2254
2255msg_context(Prefix0, Prefix) :-
2256 current_prolog_flag(message_context, Context),
2257 is_list(Context),
2258 !,
2259 add_message_context(Context, Prefix0, Prefix).
2260msg_context(Prefix, Prefix).
2261
2262add_message_context([], Prefix, Prefix).
2263add_message_context([H|T], Prefix0, Prefix) :-
2264 ( add_message_context1(H, Prefix0, Prefix1)
2265 -> true
2266 ; Prefix1 = Prefix0
2267 ),
2268 add_message_context(T, Prefix1, Prefix).
2269
2270add_message_context1(Context, Prefix0, Prefix) :-
2271 prolog:message_prefix_hook(Context, Extra),
2272 atomics_to_string([Prefix0, Extra, ' '], Prefix).
2273add_message_context1(time, Prefix0, Prefix) :-
2274 get_time(Now),
2275 format_time(string(S), '%T.%3f ', Now),
2276 string_concat(Prefix0, S, Prefix).
2277add_message_context1(time(Format), Prefix0, Prefix) :-
2278 get_time(Now),
2279 format_time(string(S), Format, Now),
2280 atomics_to_string([Prefix0, S, ' '], Prefix).
2281add_message_context1(thread, Prefix0, Prefix) :-
2282 \+ current_prolog_flag(toplevel_thread, true),
2283 thread_self(Id0),
2284 !,
2285 ( atom(Id0)
2286 -> Id = Id0
2287 ; thread_property(Id0, id(Id))
2288 ),
2289 format(string(Prefix), '~w[Thread ~w] ', [Prefix0, Id]).
2290
2295
2296print_message_lines(Stream, kind(Kind), Lines) :-
2297 !,
2298 msg_property(Kind, prefix(Prefix)),
2299 insert_prefix(Lines, Prefix, Ctx, PrefixLines),
2300 '$append'([ begin(Kind, Ctx)
2301 | PrefixLines
2302 ],
2303 [ end(Ctx)
2304 ],
2305 AllLines),
2306 print_message_lines(Stream, AllLines).
2307print_message_lines(Stream, Prefix, Lines) :-
2308 insert_prefix(Lines, Prefix, _, PrefixLines),
2309 print_message_lines(Stream, PrefixLines).
2310
2312
2313insert_prefix([at_same_line|Lines0], Prefix, Ctx, Lines) :-
2314 !,
2315 prefix_nl(Lines0, Prefix, Ctx, Lines).
2316insert_prefix(Lines0, Prefix, Ctx, [prefix(Prefix)|Lines]) :-
2317 prefix_nl(Lines0, Prefix, Ctx, Lines).
2318
2319prefix_nl([], _, _, [nl]).
2320prefix_nl([nl], _, _, [nl]) :- !.
2321prefix_nl([flush], _, _, [flush]) :- !.
2322prefix_nl([nl|T0], Prefix, Ctx, [nl, prefix(Prefix)|T]) :-
2323 !,
2324 prefix_nl(T0, Prefix, Ctx, T).
2325prefix_nl([ansi(Attrs,Fmt,Args)|T0], Prefix, Ctx,
2326 [ansi(Attrs,Fmt,Args,Ctx)|T]) :-
2327 !,
2328 prefix_nl(T0, Prefix, Ctx, T).
2329prefix_nl([H|T0], Prefix, Ctx, [H|T]) :-
2330 prefix_nl(T0, Prefix, Ctx, T).
2331
2333
2334print_message_lines(Stream, Lines) :-
2335 with_output_to(
2336 Stream,
2337 notrace(print_message_lines_guarded(current_output, Lines))).
2338
2339print_message_lines_guarded(_, []) :- !.
2340print_message_lines_guarded(S, [H|T]) :-
2341 line_element(S, H),
2342 print_message_lines_guarded(S, T).
2343
2344line_element(S, E) :-
2345 prolog:message_line_element(S, E),
2346 !.
2347line_element(S, full_stop) :-
2348 !,
2349 '$put_token'(S, '.'). 2350line_element(S, nl) :-
2351 !,
2352 nl(S).
2353line_element(S, prefix(Fmt-Args)) :-
2354 !,
2355 safe_format(S, Fmt, Args).
2356line_element(S, prefix(Fmt)) :-
2357 !,
2358 safe_format(S, Fmt, []).
2359line_element(S, flush) :-
2360 !,
2361 flush_output(S).
2362line_element(S, Fmt-Args) :-
2363 !,
2364 safe_format(S, Fmt, Args).
2365line_element(S, ansi(_, Fmt, Args)) :-
2366 !,
2367 safe_format(S, Fmt, Args).
2368line_element(S, ansi(_, Fmt, Args, _Ctx)) :-
2369 !,
2370 safe_format(S, Fmt, Args).
2371line_element(S, url(URL)) :-
2372 !,
2373 print_link(S, URL).
2374line_element(S, url(_URL, Fmt-Args)) :-
2375 !,
2376 safe_format(S, Fmt, Args).
2377line_element(S, url(_URL, Fmt)) :-
2378 !,
2379 safe_format(S, Fmt, []).
2380line_element(_, begin(_Level, _Ctx)) :- !.
2381line_element(_, end(_Ctx)) :- !.
2382line_element(S, Fmt) :-
2383 safe_format(S, Fmt, []).
2384
2385print_link(S, File:Line:Column) :-
2386 !,
2387 safe_format(S, '~w:~d:~d', [File, Line, Column]).
2388print_link(S, File:Line) :-
2389 !,
2390 safe_format(S, '~w:~d', [File, Line]).
2391print_link(S, File) :-
2392 safe_format(S, '~w', [File]).
2393
2395
2396safe_format(S, Fmt, Args) :-
2397 E = error(_,_),
2398 catch(format(S,Fmt,Args), E,
2399 format_failed(S,Fmt,Args,E)).
2400
2401format_failed(S, _Fmt, _Args, E) :-
2402 stream_property(S, error(true)),
2403 !,
2404 throw(E).
2405format_failed(S, Fmt, Args, error(E,_)) :-
2406 format(S, '~N [[ EXCEPTION while printing message ~q~n\c
2407 ~7|with arguments ~W:~n\c
2408 ~7|raised: ~W~n~4|]]~n',
2409 [ Fmt,
2410 Args, [quoted(true), max_depth(10)],
2411 E, [quoted(true), max_depth(10)]
2412 ]).
2413
2417
2418message_to_string(Term, Str) :-
2419 translate_message(Term, Actions, []),
2420 !,
2421 actions_to_format(Actions, Fmt, Args),
2422 format(string(Str), Fmt, Args).
2423
2424actions_to_format([], '', []) :- !.
2425actions_to_format([nl], '', []) :- !.
2426actions_to_format([Term, nl], Fmt, Args) :-
2427 !,
2428 actions_to_format([Term], Fmt, Args).
2429actions_to_format([nl|T], Fmt, Args) :-
2430 !,
2431 actions_to_format(T, Fmt0, Args),
2432 atom_concat('~n', Fmt0, Fmt).
2433actions_to_format([ansi(_Attrs, Fmt0, Args0)|Tail], Fmt, Args) :-
2434 !,
2435 actions_to_format(Tail, Fmt1, Args1),
2436 atom_concat(Fmt0, Fmt1, Fmt),
2437 append_args(Args0, Args1, Args).
2438actions_to_format([url(Pos)|Tail], Fmt, Args) :-
2439 !,
2440 actions_to_format(Tail, Fmt1, Args1),
2441 url_actions_to_format(url(Pos), Fmt1, Args1, Fmt, Args).
2442actions_to_format([url(URL, Label)|Tail], Fmt, Args) :-
2443 !,
2444 actions_to_format(Tail, Fmt1, Args1),
2445 url_actions_to_format(url(URL, Label), Fmt1, Args1, Fmt, Args).
2446actions_to_format([Fmt0-Args0|Tail], Fmt, Args) :-
2447 !,
2448 actions_to_format(Tail, Fmt1, Args1),
2449 atom_concat(Fmt0, Fmt1, Fmt),
2450 append_args(Args0, Args1, Args).
2451actions_to_format([Skip|T], Fmt, Args) :-
2452 action_skip(Skip),
2453 !,
2454 actions_to_format(T, Fmt, Args).
2455actions_to_format([Term|Tail], Fmt, Args) :-
2456 atomic(Term),
2457 !,
2458 actions_to_format(Tail, Fmt1, Args),
2459 atom_concat(Term, Fmt1, Fmt).
2460actions_to_format([Term|Tail], Fmt, Args) :-
2461 actions_to_format(Tail, Fmt1, Args1),
2462 atom_concat('~w', Fmt1, Fmt),
2463 append_args([Term], Args1, Args).
2464
2465action_skip(at_same_line).
2466action_skip(flush).
2467action_skip(begin(_Level, _Ctx)).
2468action_skip(end(_Ctx)).
2469
2470url_actions_to_format(url(File:Line:Column), Fmt1, Args1, Fmt, Args) :-
2471 !,
2472 atom_concat('~w:~d:~d', Fmt1, Fmt),
2473 append_args([File,Line,Column], Args1, Args).
2474url_actions_to_format(url(File:Line), Fmt1, Args1, Fmt, Args) :-
2475 !,
2476 atom_concat('~w:~d', Fmt1, Fmt),
2477 append_args([File,Line], Args1, Args).
2478url_actions_to_format(url(File), Fmt1, Args1, Fmt, Args) :-
2479 !,
2480 atom_concat('~w', Fmt1, Fmt),
2481 append_args([File], Args1, Args).
2482url_actions_to_format(url(_URL, Label), Fmt1, Args1, Fmt, Args) :-
2483 !,
2484 atom_concat('~w', Fmt1, Fmt),
2485 append_args([Label], Args1, Args).
2486
2487
2488append_args(M:Args0, Args1, M:Args) :-
2489 !,
2490 strip_module(Args1, _, A1),
2491 to_list(Args0, Args01),
2492 '$append'(Args01, A1, Args).
2493append_args(Args0, Args1, Args) :-
2494 strip_module(Args1, _, A1),
2495 to_list(Args0, Args01),
2496 '$append'(Args01, A1, Args).
2497
2498 2501
2502:- dynamic
2503 printed/2. 2504
2508
2509print_once(compatibility(_), _).
2510print_once(null_byte_in_path(_), _).
2511print_once(deprecated(_), _).
2512
2516
2517must_print(Level, Message) :-
2518 nonvar(Message),
2519 print_once(Message, Level),
2520 !,
2521 \+ printed(Message, Level),
2522 assert(printed(Message, Level)).
2523must_print(_, _)