1/* Part of SWI-Prolog 2 3 Author: Jan Wielemaker 4 E-mail: J.Wielemaker@vu.nl 5 WWW: http://www.swi-prolog.org 6 Copyright (c) 1985-2021, University of Amsterdam 7 VU University Amsterdam 8 SWI-Prolog Solutions b.v. 9 All rights reserved. 10 11 Redistribution and use in source and binary forms, with or without 12 modification, are permitted provided that the following conditions 13 are met: 14 15 1. Redistributions of source code must retain the above copyright 16 notice, this list of conditions and the following disclaimer. 17 18 2. Redistributions in binary form must reproduce the above copyright 19 notice, this list of conditions and the following disclaimer in 20 the documentation and/or other materials provided with the 21 distribution. 22 23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 POSSIBILITY OF SUCH DAMAGE. 35*/ 36 37:- module('$toplevel', 38 [ '$initialise'/0, % start Prolog 39 '$toplevel'/0, % Prolog top-level (re-entrant) 40 '$compile'/0, % `-c' toplevel 41 '$config'/0, % --dump-runtime-variables toplevel 42 initialize/0, % Run program initialization 43 version/0, % Write initial banner 44 version/1, % Add message to the banner 45 prolog/0, % user toplevel predicate 46 '$query_loop'/0, % toplevel predicate 47 '$execute_query'/3, % +Query, +Bindings, -Truth 48 residual_goals/1, % +Callable 49 (initialization)/1, % initialization goal (directive) 50 '$thread_init'/0, % initialise thread 51 (thread_initialization)/1 % thread initialization goal 52 ]). 53 54 55 /******************************* 56 * VERSION BANNER * 57 *******************************/ 58 59:- dynamic 60 prolog:version_msg/1.
67version :-
68 print_message(banner, welcome).
74:- multifile 75 system:term_expansion/2. 76 77systemterm_expansion((:- version(Message)), 78 prolog:version_msg(Message)). 79 80version(Message) :- 81 ( prolog:version_msg(Message) 82 -> true 83 ; assertz(prolog:version_msg(Message)) 84 ). 85 86 87 /******************************** 88 * INITIALISATION * 89 *********************************/
swipl -f
file
or simply using swipl
. In the first case we search the
file both directly and over the alias user_app_config
. In the
latter case we only use the alias.98load_init_file :- 99 '$cmd_option_val'(init_file, OsFile), 100 !, 101 prolog_to_os_filename(File, OsFile), 102 load_init_file(File, explicit). 103load_init_file :- 104 load_init_file('init.pl', implicit).
110:- dynamic 111 loaded_init_file/2. % already loaded init files 112 113load_init_file(none, _) :- !. 114load_init_file(Base, _) :- 115 loaded_init_file(Base, _), 116 !. 117load_init_file(InitFile, explicit) :- 118 exists_file(InitFile), 119 !, 120 ensure_loaded(user:InitFile). 121load_init_file(Base, _) :- 122 absolute_file_name(user_app_config(Base), InitFile, 123 [ access(read), 124 file_errors(fail) 125 ]), 126 asserta(loaded_init_file(Base, InitFile)), 127 load_files(user:InitFile, 128 [ scope_settings(false) 129 ]). 130load_init_file('init.pl', implicit) :- 131 ( current_prolog_flag(windows, true), 132 absolute_file_name(user_profile('swipl.ini'), InitFile, 133 [ access(read), 134 file_errors(fail) 135 ]) 136 ; expand_file_name('~/.swiplrc', [InitFile]), 137 exists_file(InitFile) 138 ), 139 !, 140 print_message(warning, backcomp(init_file_moved(InitFile))). 141load_init_file(_, _). 142 143'$load_system_init_file' :- 144 loaded_init_file(system, _), 145 !. 146'$load_system_init_file' :- 147 '$cmd_option_val'(system_init_file, Base), 148 Base \== none, 149 current_prolog_flag(home, Home), 150 file_name_extension(Base, rc, Name), 151 atomic_list_concat([Home, '/', Name], File), 152 absolute_file_name(File, Path, 153 [ file_type(prolog), 154 access(read), 155 file_errors(fail) 156 ]), 157 asserta(loaded_init_file(system, Path)), 158 load_files(user:Path, 159 [ silent(true), 160 scope_settings(false) 161 ]), 162 !. 163'$load_system_init_file'. 164 165'$load_script_file' :- 166 loaded_init_file(script, _), 167 !. 168'$load_script_file' :- 169 '$cmd_option_val'(script_file, OsFiles), 170 load_script_files(OsFiles). 171 172load_script_files([]). 173load_script_files([OsFile|More]) :- 174 prolog_to_os_filename(File, OsFile), 175 ( absolute_file_name(File, Path, 176 [ file_type(prolog), 177 access(read), 178 file_errors(fail) 179 ]) 180 -> asserta(loaded_init_file(script, Path)), 181 load_files(user:Path, []), 182 load_files(More) 183 ; throw(error(existence_error(script_file, File), _)) 184 ). 185 186 187 /******************************* 188 * AT_INITIALISATION * 189 *******************************/ 190 191:- meta_predicate 192 initialization( ). 193 194:- '$iso'((initialization)/1).
203initialization(Goal) :- 204 Goal = _:G, 205 prolog:initialize_now(G, Use), 206 !, 207 print_message(warning, initialize_now(G, Use)), 208 initialization(Goal, now). 209initialization(Goal) :- 210 initialization(Goal, after_load). 211 212:- multifile 213 prolog:initialize_now/2, 214 prolog:message//1. 215 216prologinitialize_now(load_foreign_library(_), 217 'use :- use_foreign_library/1 instead'). 218prologinitialize_now(load_foreign_library(_,_), 219 'use :- use_foreign_library/2 instead'). 220 221prologmessage(initialize_now(Goal, Use)) --> 222 [ 'Initialization goal ~p will be executed'-[Goal],nl, 223 'immediately for backward compatibility reasons', nl, 224 '~w'-[Use] 225 ]. 226 227'$run_initialization' :- 228 '$run_initialization'(_, []), 229 '$thread_init'.
:- initialization(Goal, program).
. Stop
with an exception if a goal fails or raises an exception.236initialize :- 237 forall('$init_goal'(when(program), Goal, Ctx), 238 run_initialize(Goal, Ctx)). 239 240run_initialize(Goal, Ctx) :- 241 ( catch(Goal, E, true), 242 ( var(E) 243 -> true 244 ; throw(error(initialization_error(E, Goal, Ctx), _)) 245 ) 246 ; throw(error(initialization_error(failed, Goal, Ctx), _)) 247 ). 248 249 250 /******************************* 251 * THREAD INITIALIZATION * 252 *******************************/ 253 254:- meta_predicate 255 thread_initialization( ). 256:- dynamic 257 '$at_thread_initialization'/1.
263thread_initialization(Goal) :- 264 assert('$at_thread_initialization'(Goal)), 265 call(Goal), 266 !. 267 268'$thread_init' :- 269 ( '$at_thread_initialization'(Goal), 270 ( call(Goal) 271 -> fail 272 ; fail 273 ) 274 ; true 275 ). 276 277 278 /******************************* 279 * FILE SEARCH PATH (-p) * 280 *******************************/
286'$set_file_search_paths' :- 287 '$cmd_option_val'(search_paths, Paths), 288 ( '$member'(Path, Paths), 289 atom_chars(Path, Chars), 290 ( phrase('$search_path'(Name, Aliases), Chars) 291 -> '$reverse'(Aliases, Aliases1), 292 forall('$member'(Alias, Aliases1), 293 asserta(user:file_search_path(Name, Alias))) 294 ; print_message(error, commandline_arg_type(p, Path)) 295 ), 296 fail ; true 297 ). 298 299'$search_path'(Name, Aliases) --> 300 '$string'(NameChars), 301 [=], 302 !, 303 {atom_chars(Name, NameChars)}, 304 '$search_aliases'(Aliases). 305 306'$search_aliases'([Alias|More]) --> 307 '$string'(AliasChars), 308 path_sep, 309 !, 310 { '$make_alias'(AliasChars, Alias) }, 311 '$search_aliases'(More). 312'$search_aliases'([Alias]) --> 313 '$string'(AliasChars), 314 '$eos', 315 !, 316 { '$make_alias'(AliasChars, Alias) }. 317 318path_sep --> 319 { current_prolog_flag(windows, true) 320 }, 321 !, 322 [;]. 323path_sep --> 324 [:]. 325 326'$string'([]) --> []. 327'$string'([H|T]) --> [H], '$string'(T). 328 329'$eos'([], []). 330 331'$make_alias'(Chars, Alias) :- 332 catch(term_to_atom(Alias, Chars), _, fail), 333 ( atom(Alias) 334 ; functor(Alias, F, 1), 335 F \== / 336 ), 337 !. 338'$make_alias'(Chars, Alias) :- 339 atom_chars(Alias, Chars). 340 341 342 /******************************* 343 * LOADING ASSIOCIATED FILES * 344 *******************************/
argv
, extracting the leading script files.350argv_files(Files) :- 351 current_prolog_flag(argv, Argv), 352 no_option_files(Argv, Argv1, Files, ScriptArgs), 353 ( ( ScriptArgs == true 354 ; Argv1 == [] 355 ) 356 -> ( Argv1 \== Argv 357 -> set_prolog_flag(argv, Argv1) 358 ; true 359 ) 360 ; '$usage', 361 halt(1) 362 ). 363 364no_option_files([--|Argv], Argv, [], true) :- !. 365no_option_files([Opt|_], _, _, ScriptArgs) :- 366 ScriptArgs \== true, 367 sub_atom(Opt, 0, _, _, '-'), 368 !, 369 '$usage', 370 halt(1). 371no_option_files([OsFile|Argv0], Argv, [File|T], ScriptArgs) :- 372 file_name_extension(_, Ext, OsFile), 373 user:prolog_file_type(Ext, prolog), 374 !, 375 ScriptArgs = true, 376 prolog_to_os_filename(File, OsFile), 377 no_option_files(Argv0, Argv, T, ScriptArgs). 378no_option_files([OsScript|Argv], Argv, [Script], ScriptArgs) :- 379 ScriptArgs \== true, 380 !, 381 prolog_to_os_filename(Script, OsScript), 382 ( exists_file(Script) 383 -> true 384 ; '$existence_error'(file, Script) 385 ), 386 ScriptArgs = true. 387no_option_files(Argv, Argv, [], _). 388 389clean_argv :- 390 ( current_prolog_flag(argv, [--|Argv]) 391 -> set_prolog_flag(argv, Argv) 392 ; true 393 ).
402associated_files([]) :- 403 current_prolog_flag(saved_program_class, runtime), 404 !, 405 clean_argv. 406associated_files(Files) :- 407 '$set_prolog_file_extension', 408 argv_files(Files), 409 ( Files = [File|_] 410 -> absolute_file_name(File, AbsFile), 411 set_prolog_flag(associated_file, AbsFile), 412 set_working_directory(File), 413 set_window_title(Files) 414 ; true 415 ).
console_menu
,
which is set by swipl-win[.exe].425set_working_directory(File) :- 426 current_prolog_flag(console_menu, true), 427 access_file(File, read), 428 !, 429 file_directory_name(File, Dir), 430 working_directory(_, Dir). 431set_working_directory(_). 432 433set_window_title([File|More]) :- 434 current_predicate(system:window_title/2), 435 !, 436 ( More == [] 437 -> Extra = [] 438 ; Extra = ['...'] 439 ), 440 atomic_list_concat(['SWI-Prolog --', File | Extra], ' ', Title), 441 system:window_title(_, Title). 442set_window_title(_).
--pldoc[=port]
is given, load the PlDoc
system.450start_pldoc :- 451 '$cmd_option_val'(pldoc_server, Server), 452 ( Server == '' 453 -> call((doc_server(_), doc_browser)) 454 ; catch(atom_number(Server, Port), _, fail) 455 -> call(doc_server(Port)) 456 ; print_message(error, option_usage(pldoc)), 457 halt(1) 458 ). 459start_pldoc.
466load_associated_files(Files) :- 467 ( '$member'(File, Files), 468 load_files(user:File, [expand(false)]), 469 fail 470 ; true 471 ). 472 473hkey('HKEY_CURRENT_USER/Software/SWI/Prolog'). 474hkey('HKEY_LOCAL_MACHINE/Software/SWI/Prolog'). 475 476'$set_prolog_file_extension' :- 477 current_prolog_flag(windows, true), 478 hkey(Key), 479 catch(win_registry_get_value(Key, fileExtension, Ext0), 480 _, fail), 481 !, 482 ( atom_concat('.', Ext, Ext0) 483 -> true 484 ; Ext = Ext0 485 ), 486 ( user:prolog_file_type(Ext, prolog) 487 -> true 488 ; asserta(user:prolog_file_type(Ext, prolog)) 489 ). 490'$set_prolog_file_extension'. 491 492 493 /******************************** 494 * TOPLEVEL GOALS * 495 *********************************/
503'$initialise' :- 504 catch(initialise_prolog, E, initialise_error(E)). 505 506initialise_error('$aborted') :- !. 507initialise_error(E) :- 508 print_message(error, initialization_exception(E)), 509 fail. 510 511initialise_prolog :- 512 '$clean_history', 513 apple_setup_app, 514 '$run_initialization', 515 '$load_system_init_file', 516 set_toplevel, 517 '$set_file_search_paths', 518 init_debug_flags, 519 start_pldoc, 520 opt_attach_packs, 521 load_init_file, 522 catch(setup_colors, E, print_message(warning, E)), 523 associated_files(Files), 524 '$load_script_file', 525 load_associated_files(Files), 526 '$cmd_option_val'(goals, Goals), 527 ( Goals == [], 528 \+ '$init_goal'(when(_), _, _) 529 -> version % default interactive run 530 ; run_init_goals(Goals), 531 ( load_only 532 -> version 533 ; run_program_init, 534 run_main_init 535 ) 536 ). 537 538:- if(current_prolog_flag(apple,true)). 539apple_set_working_directory :- 540 ( expand_file_name('~', [Dir]), 541 exists_directory(Dir) 542 -> working_directory(_, Dir) 543 ; true 544 ). 545 546apple_set_locale :- 547 ( getenv('LC_CTYPE', 'UTF-8'), 548 apple_current_locale_identifier(LocaleID), 549 atom_concat(LocaleID, '.UTF-8', Locale), 550 catch(setlocale(ctype, _Old, Locale), _, fail) 551 -> setenv('LANG', Locale), 552 unsetenv('LC_CTYPE') 553 ; true 554 ). 555 556apple_setup_app :- 557 current_prolog_flag(apple, true), 558 current_prolog_flag(console_menu, true), % SWI-Prolog.app on MacOS 559 apple_set_working_directory, 560 apple_set_locale. 561:- endif. 562apple_setup_app. 563 564opt_attach_packs :- 565 current_prolog_flag(packs, true), 566 !, 567 attach_packs. 568opt_attach_packs. 569 570set_toplevel :- 571 '$cmd_option_val'(toplevel, TopLevelAtom), 572 catch(term_to_atom(TopLevel, TopLevelAtom), E, 573 (print_message(error, E), 574 halt(1))), 575 create_prolog_flag(toplevel_goal, TopLevel, [type(term)]). 576 577load_only :- 578 current_prolog_flag(os_argv, OSArgv), 579 memberchk('-l', OSArgv), 580 current_prolog_flag(argv, Argv), 581 \+ memberchk('-l', Argv).
588run_init_goals([]). 589run_init_goals([H|T]) :- 590 run_init_goal(H), 591 run_init_goals(T). 592 593run_init_goal(Text) :- 594 catch(term_to_atom(Goal, Text), E, 595 ( print_message(error, init_goal_syntax(E, Text)), 596 halt(2) 597 )), 598 run_init_goal(Goal, Text).
604run_program_init :- 605 forall('$init_goal'(when(program), Goal, Ctx), 606 run_init_goal(Goal, @(Goal,Ctx))). 607 608run_main_init :- 609 findall(Goal-Ctx, '$init_goal'(when(main), Goal, Ctx), Pairs), 610 '$last'(Pairs, Goal-Ctx), 611 !, 612 ( current_prolog_flag(toplevel_goal, default) 613 -> set_prolog_flag(toplevel_goal, halt) 614 ; true 615 ), 616 run_init_goal(Goal, @(Goal,Ctx)). 617run_main_init. 618 619run_init_goal(Goal, Ctx) :- 620 ( catch_with_backtrace(user:Goal, E, true) 621 -> ( var(E) 622 -> true 623 ; print_message(error, init_goal_failed(E, Ctx)), 624 halt(2) 625 ) 626 ; ( current_prolog_flag(verbose, silent) 627 -> Level = silent 628 ; Level = error 629 ), 630 print_message(Level, init_goal_failed(failed, Ctx)), 631 halt(1) 632 ).
639init_debug_flags :-
640 once(print_predicate(_, [print], PrintOptions)),
641 Keep = [keep(true)],
642 create_prolog_flag(answer_write_options, PrintOptions, Keep),
643 create_prolog_flag(prompt_alternatives_on, determinism, Keep),
644 create_prolog_flag(toplevel_extra_white_line, true, Keep),
645 create_prolog_flag(toplevel_print_factorized, false, Keep),
646 create_prolog_flag(print_write_options,
647 [ portray(true), quoted(true), numbervars(true) ],
648 Keep),
649 create_prolog_flag(toplevel_residue_vars, false, Keep),
650 create_prolog_flag(toplevel_list_wfs_residual_program, true, Keep),
651 '$set_debugger_write_options'(print).
657setup_backtrace :-
658 ( \+ current_prolog_flag(backtrace, false),
659 load_setup_file(library(prolog_stack))
660 -> true
661 ; true
662 ).
668setup_colors :-
669 ( \+ current_prolog_flag(color_term, false),
670 stream_property(user_input, tty(true)),
671 stream_property(user_error, tty(true)),
672 stream_property(user_output, tty(true)),
673 \+ getenv('TERM', dumb),
674 load_setup_file(user:library(ansi_term))
675 -> true
676 ; true
677 ).
683setup_history :-
684 ( \+ current_prolog_flag(save_history, false),
685 stream_property(user_input, tty(true)),
686 \+ current_prolog_flag(readline, false),
687 load_setup_file(library(prolog_history))
688 -> prolog_history(enable)
689 ; true
690 ),
691 set_default_history,
692 '$load_history'.
698setup_readline :- 699 ( current_prolog_flag(readline, swipl_win) 700 -> true 701 ; stream_property(user_input, tty(true)), 702 current_prolog_flag(tty_control, true), 703 \+ getenv('TERM', dumb), 704 ( current_prolog_flag(readline, ReadLine) 705 -> true 706 ; ReadLine = true 707 ), 708 readline_library(ReadLine, Library), 709 load_setup_file(library(Library)) 710 -> set_prolog_flag(readline, Library) 711 ; set_prolog_flag(readline, false) 712 ). 713 714readline_library(true, Library) :- 715 !, 716 preferred_readline(Library). 717readline_library(false, _) :- 718 !, 719 fail. 720readline_library(Library, Library). 721 722preferred_readline(editline). 723preferred_readline(readline).
729load_setup_file(File) :- 730 catch(load_files(File, 731 [ silent(true), 732 if(not_loaded) 733 ]), _, fail). 734 735 736:- '$hide'('$toplevel'/0). % avoid in the GUI stacktrace
742'$toplevel' :-
743 '$runtoplevel',
744 print_message(informational, halt).
default
and prolog
both
start the interactive toplevel, where prolog
implies the user gave
-t prolog
.
754'$runtoplevel' :- 755 current_prolog_flag(toplevel_goal, TopLevel0), 756 toplevel_goal(TopLevel0, TopLevel), 757 user:TopLevel. 758 759:- dynamic setup_done/0. 760:- volatile setup_done/0. 761 762toplevel_goal(default, '$query_loop') :- 763 !, 764 setup_interactive. 765toplevel_goal(prolog, '$query_loop') :- 766 !, 767 setup_interactive. 768toplevel_goal(Goal, Goal). 769 770setup_interactive :- 771 setup_done, 772 !. 773setup_interactive :- 774 asserta(setup_done), 775 catch(setup_backtrace, E, print_message(warning, E)), 776 catch(setup_readline, E, print_message(warning, E)), 777 catch(setup_history, E, print_message(warning, E)).
783'$compile' :- 784 ( catch('$compile_', E, (print_message(error, E), halt(1))) 785 -> true 786 ; print_message(error, error(goal_failed('$compile'), _)), 787 halt(1) 788 ), 789 halt. % set exit code 790 791'$compile_' :- 792 '$load_system_init_file', 793 catch(setup_colors, _, true), 794 '$set_file_search_paths', 795 init_debug_flags, 796 '$run_initialization', 797 opt_attach_packs, 798 use_module(library(qsave)), 799 qsave:qsave_toplevel.
805'$config' :- 806 '$load_system_init_file', 807 '$set_file_search_paths', 808 init_debug_flags, 809 '$run_initialization', 810 load_files(library(prolog_config)), 811 ( catch(prolog_dump_runtime_variables, E, 812 (print_message(error, E), halt(1))) 813 -> true 814 ; print_message(error, error(goal_failed(prolog_dump_runtime_variables),_)) 815 ). 816 817 818 /******************************** 819 * USER INTERACTIVE LOOP * 820 *********************************/
828prolog :- 829 break. 830 831:- create_prolog_flag(toplevel_mode, backtracking, []).
query_loop()
. This ensures that unhandled
exceptions are really unhandled (in Prolog).840'$query_loop' :- 841 current_prolog_flag(toplevel_mode, recursive), 842 !, 843 break_level(Level), 844 read_expanded_query(Level, Query, Bindings), 845 ( Query == end_of_file 846 -> print_message(query, query(eof)) 847 ; '$call_no_catch'('$execute_query'(Query, Bindings, _)), 848 ( current_prolog_flag(toplevel_mode, recursive) 849 -> '$query_loop' 850 ; '$switch_toplevel_mode'(backtracking), 851 '$query_loop' % Maybe throw('$switch_toplevel_mode')? 852 ) 853 ). 854'$query_loop' :- 855 break_level(BreakLev), 856 repeat, 857 read_expanded_query(BreakLev, Query, Bindings), 858 ( Query == end_of_file 859 -> !, print_message(query, query(eof)) 860 ; '$execute_query'(Query, Bindings, _), 861 ( current_prolog_flag(toplevel_mode, recursive) 862 -> !, 863 '$switch_toplevel_mode'(recursive), 864 '$query_loop' 865 ; fail 866 ) 867 ). 868 869break_level(BreakLev) :- 870 ( current_prolog_flag(break_level, BreakLev) 871 -> true 872 ; BreakLev = -1 873 ). 874 875read_expanded_query(BreakLev, ExpandedQuery, ExpandedBindings) :- 876 '$current_typein_module'(TypeIn), 877 ( stream_property(user_input, tty(true)) 878 -> '$system_prompt'(TypeIn, BreakLev, Prompt), 879 prompt(Old, '| ') 880 ; Prompt = '', 881 prompt(Old, '') 882 ), 883 trim_stacks, 884 trim_heap, 885 repeat, 886 read_query(Prompt, Query, Bindings), 887 prompt(_, Old), 888 catch(call_expand_query(Query, ExpandedQuery, 889 Bindings, ExpandedBindings), 890 Error, 891 (print_message(error, Error), fail)), 892 !.
901:- if(current_prolog_flag(emscripten, true)). 902read_query(_Prompt, Goal, Bindings) :- 903 '$can_yield', 904 !, 905 await(goal, GoalString), 906 term_string(Goal, GoalString, [variable_names(Bindings)]). 907:- endif. 908read_query(Prompt, Goal, Bindings) :- 909 current_prolog_flag(history, N), 910 integer(N), N > 0, 911 !, 912 read_term_with_history( 913 Goal, 914 [ show(h), 915 help('!h'), 916 no_save([trace, end_of_file]), 917 prompt(Prompt), 918 variable_names(Bindings) 919 ]). 920read_query(Prompt, Goal, Bindings) :- 921 remove_history_prompt(Prompt, Prompt1), 922 repeat, % over syntax errors 923 prompt1(Prompt1), 924 read_query_line(user_input, Line), 925 '$save_history_line'(Line), % save raw line (edit syntax errors) 926 '$current_typein_module'(TypeIn), 927 catch(read_term_from_atom(Line, Goal, 928 [ variable_names(Bindings), 929 module(TypeIn) 930 ]), E, 931 ( print_message(error, E), 932 fail 933 )), 934 !, 935 '$save_history_event'(Line). % save event (no syntax errors)
939read_query_line(Input, Line) :- 940 stream_property(Input, error(true)), 941 !, 942 Line = end_of_file. 943read_query_line(Input, Line) :- 944 catch(read_term_as_atom(Input, Line), Error, true), 945 save_debug_after_read, 946 ( var(Error) 947 -> true 948 ; catch(print_message(error, Error), _, true), 949 ( Error = error(syntax_error(_),_) 950 -> fail 951 ; throw(Error) 952 ) 953 ).
960read_term_as_atom(In, Line) :-
961 '$raw_read'(In, Line),
962 ( Line == end_of_file
963 -> true
964 ; skip_to_nl(In)
965 ).
972skip_to_nl(In) :- 973 repeat, 974 peek_char(In, C), 975 ( C == '%' 976 -> skip(In, '\n') 977 ; char_type(C, space) 978 -> get_char(In, _), 979 C == '\n' 980 ; true 981 ), 982 !. 983 984remove_history_prompt('', '') :- !. 985remove_history_prompt(Prompt0, Prompt) :- 986 atom_chars(Prompt0, Chars0), 987 clean_history_prompt_chars(Chars0, Chars1), 988 delete_leading_blanks(Chars1, Chars), 989 atom_chars(Prompt, Chars). 990 991clean_history_prompt_chars([], []). 992clean_history_prompt_chars(['~', !|T], T) :- !. 993clean_history_prompt_chars([H|T0], [H|T]) :- 994 clean_history_prompt_chars(T0, T). 995 996delete_leading_blanks([' '|T0], T) :- 997 !, 998 delete_leading_blanks(T0, T). 999delete_leading_blanks(L, L).
1008set_default_history :- 1009 current_prolog_flag(history, _), 1010 !. 1011set_default_history :- 1012 ( ( \+ current_prolog_flag(readline, false) 1013 ; current_prolog_flag(emacs_inferior_process, true) 1014 ) 1015 -> create_prolog_flag(history, 0, []) 1016 ; create_prolog_flag(history, 25, []) 1017 ). 1018 1019 1020 /******************************* 1021 * TOPLEVEL DEBUG * 1022 *******************************/
thread_signal(main, gdebug)
1037save_debug_after_read :- 1038 current_prolog_flag(debug, true), 1039 !, 1040 save_debug. 1041save_debug_after_read. 1042 1043save_debug :- 1044 ( tracing, 1045 notrace 1046 -> Tracing = true 1047 ; Tracing = false 1048 ), 1049 current_prolog_flag(debug, Debugging), 1050 set_prolog_flag(debug, false), 1051 create_prolog_flag(query_debug_settings, 1052 debug(Debugging, Tracing), []). 1053 1054restore_debug :- 1055 current_prolog_flag(query_debug_settings, debug(Debugging, Tracing)), 1056 set_prolog_flag(debug, Debugging), 1057 ( Tracing == true 1058 -> trace 1059 ; true 1060 ). 1061 1062:- initialization 1063 create_prolog_flag(query_debug_settings, debug(false, false), []). 1064 1065 1066 /******************************** 1067 * PROMPTING * 1068 ********************************/ 1069 1070'$system_prompt'(Module, BrekLev, Prompt) :- 1071 current_prolog_flag(toplevel_prompt, PAtom), 1072 atom_codes(PAtom, P0), 1073 ( Module \== user 1074 -> '$substitute'('~m', [Module, ': '], P0, P1) 1075 ; '$substitute'('~m', [], P0, P1) 1076 ), 1077 ( BrekLev > 0 1078 -> '$substitute'('~l', ['[', BrekLev, '] '], P1, P2) 1079 ; '$substitute'('~l', [], P1, P2) 1080 ), 1081 current_prolog_flag(query_debug_settings, debug(Debugging, Tracing)), 1082 ( Tracing == true 1083 -> '$substitute'('~d', ['[trace] '], P2, P3) 1084 ; Debugging == true 1085 -> '$substitute'('~d', ['[debug] '], P2, P3) 1086 ; '$substitute'('~d', [], P2, P3) 1087 ), 1088 atom_chars(Prompt, P3). 1089 1090'$substitute'(From, T, Old, New) :- 1091 atom_codes(From, FromCodes), 1092 phrase(subst_chars(T), T0), 1093 '$append'(Pre, S0, Old), 1094 '$append'(FromCodes, Post, S0) -> 1095 '$append'(Pre, T0, S1), 1096 '$append'(S1, Post, New), 1097 !. 1098'$substitute'(_, _, Old, Old). 1099 1100subst_chars([]) --> 1101 []. 1102subst_chars([H|T]) --> 1103 { atomic(H), 1104 !, 1105 atom_codes(H, Codes) 1106 }, 1107 , 1108 subst_chars(T). 1109subst_chars([H|T]) --> 1110 , 1111 subst_chars(T). 1112 1113 1114 /******************************** 1115 * EXECUTION * 1116 ********************************/
1122'$execute_query'(Var, _, true) :- 1123 var(Var), 1124 !, 1125 print_message(informational, var_query(Var)). 1126'$execute_query'(Goal, Bindings, Truth) :- 1127 '$current_typein_module'(TypeIn), 1128 '$dwim_correct_goal'(TypeIn:Goal, Bindings, Corrected), 1129 !, 1130 setup_call_cleanup( 1131 '$set_source_module'(M0, TypeIn), 1132 expand_goal(Corrected, Expanded), 1133 '$set_source_module'(M0)), 1134 print_message(silent, toplevel_goal(Expanded, Bindings)), 1135 '$execute_goal2'(Expanded, Bindings, Truth). 1136'$execute_query'(_, _, false) :- 1137 notrace, 1138 print_message(query, query(no)). 1139 1140'$execute_goal2'(Goal, Bindings, true) :- 1141 restore_debug, 1142 '$current_typein_module'(TypeIn), 1143 residue_vars(TypeIn:Goal, Vars, TypeIn:Delays, Chp), 1144 deterministic(Det), 1145 ( save_debug 1146 ; restore_debug, fail 1147 ), 1148 flush_output(user_output), 1149 ( Det == true 1150 -> DetOrChp = true 1151 ; DetOrChp = Chp 1152 ), 1153 call_expand_answer(Bindings, NewBindings), 1154 ( \+ \+ write_bindings(NewBindings, Vars, Delays, DetOrChp) 1155 -> ! 1156 ). 1157'$execute_goal2'(_, _, false) :- 1158 save_debug, 1159 print_message(query, query(no)). 1160 1161residue_vars(Goal, Vars, Delays, Chp) :- 1162 current_prolog_flag(toplevel_residue_vars, true), 1163 !, 1164 '$wfs_call'(call_residue_vars(stop_backtrace(Goal, Chp), Vars), Delays). 1165residue_vars(Goal, [], Delays, Chp) :- 1166 '$wfs_call'(stop_backtrace(Goal, Chp), Delays). 1167 1168stop_backtrace(Goal, Chp) :- 1169 toplevel_call(Goal), 1170 prolog_current_choice(Chp). 1171 1172toplevel_call(Goal) :- 1173 call(Goal), 1174 no_lco. 1175 1176no_lco.
groundness
gives the classical behaviour,
determinism
is considered more adequate and informative.
Succeeds if the user accepts the answer and fails otherwise.
1192write_bindings(Bindings, ResidueVars, Delays, DetOrChp) :- 1193 '$current_typein_module'(TypeIn), 1194 translate_bindings(Bindings, Bindings1, ResidueVars, TypeIn:Residuals), 1195 omit_qualifier(Delays, TypeIn, Delays1), 1196 name_vars(Bindings1, Residuals, Delays1), 1197 write_bindings2(Bindings1, Residuals, Delays1, DetOrChp). 1198 1199write_bindings2([], Residuals, Delays, _) :- 1200 current_prolog_flag(prompt_alternatives_on, groundness), 1201 !, 1202 print_message(query, query(yes(Delays, Residuals))). 1203write_bindings2(Bindings, Residuals, Delays, true) :- 1204 current_prolog_flag(prompt_alternatives_on, determinism), 1205 !, 1206 print_message(query, query(yes(Bindings, Delays, Residuals))). 1207write_bindings2(Bindings, Residuals, Delays, Chp) :- 1208 repeat, 1209 print_message(query, query(more(Bindings, Delays, Residuals))), 1210 get_respons(Action, Chp), 1211 ( Action == redo 1212 -> !, fail 1213 ; Action == show_again 1214 -> fail 1215 ; !, 1216 print_message(query, query(done)) 1217 ). 1218 1219name_vars(Bindings, Residuals, Delays) :- 1220 current_prolog_flag(toplevel_name_variables, true), 1221 !, 1222 '$term_multitons'(t(Bindings,Residuals,Delays), Vars), 1223 name_vars_(Vars, Bindings, 0), 1224 term_variables(t(Bindings,Residuals,Delays), SVars), 1225 anon_vars(SVars). 1226name_vars(_Bindings, _Residuals, _Delays). 1227 1228name_vars_([], _, _). 1229name_vars_([H|T], Bindings, N) :- 1230 name_var(Bindings, Name, N, N1), 1231 H = '$VAR'(Name), 1232 name_vars_(T, Bindings, N1). 1233 1234anon_vars([]). 1235anon_vars(['$VAR'('_')|T]) :- 1236 anon_vars(T). 1237 1238name_var(Bindings, Name, N0, N) :- 1239 between(N0, infinite, N1), 1240 I is N1//26, 1241 J is 0'A + N1 mod 26, 1242 ( I == 0 1243 -> format(atom(Name), '_~c', [J]) 1244 ; format(atom(Name), '_~c~d', [J, I]) 1245 ), 1246 ( current_prolog_flag(toplevel_print_anon, false) 1247 -> true 1248 ; \+ is_bound(Bindings, Name) 1249 ), 1250 !, 1251 N is N1+1. 1252 1253is_bound([Vars=_|T], Name) :- 1254 ( in_vars(Vars, Name) 1255 -> true 1256 ; is_bound(T, Name) 1257 ). 1258 1259in_vars(Name, Name) :- !. 1260in_vars(Names, Name) :- 1261 '$member'(Name, Names).
1268:- multifile 1269 residual_goal_collector/1. 1270 1271:- meta_predicate 1272 residual_goals( ). 1273 1274residual_goals(NonTerminal) :- 1275 throw(error(context_error(nodirective, residual_goals(NonTerminal)), _)). 1276 1277systemterm_expansion((:- residual_goals(NonTerminal)), 1278 '$toplevel':residual_goal_collector(M2:Head)) :- 1279 \+ current_prolog_flag(xref, true), 1280 prolog_load_context(module, M), 1281 strip_module(M:NonTerminal, M2, Head), 1282 '$must_be'(callable, Head).
1289:- public prolog:residual_goals//0. 1290 1291prolog:residual_goals --> 1292 { findall(NT, residual_goal_collector(NT), NTL) }, 1293 collect_residual_goals(NTL). 1294 1295collect_residual_goals([]) --> []. 1296collect_residual_goals([H|T]) --> 1297 ( call(H) -> [] ; [] ), 1298 collect_residual_goals(T).
1323:- public 1324 prolog:translate_bindings/5. 1325:- meta_predicate 1326 prolog:translate_bindings( , , , , ). 1327 1328prologtranslate_bindings(Bindings0, Bindings, ResVars, ResGoals, Residuals) :- 1329 translate_bindings(Bindings0, Bindings, ResVars, ResGoals, Residuals). 1330 1331translate_bindings(Bindings0, Bindings, ResidueVars, Residuals) :- 1332 prolog:residual_goals(ResidueGoals, []), 1333 translate_bindings(Bindings0, Bindings, ResidueVars, ResidueGoals, 1334 Residuals). 1335 1336translate_bindings(Bindings0, Bindings, [], [], _:[]-[]) :- 1337 term_attvars(Bindings0, []), 1338 !, 1339 join_same_bindings(Bindings0, Bindings1), 1340 factorize_bindings(Bindings1, Bindings2), 1341 bind_vars(Bindings2, Bindings3), 1342 filter_bindings(Bindings3, Bindings). 1343translate_bindings(Bindings0, Bindings, ResidueVars, ResGoals0, 1344 TypeIn:Residuals-HiddenResiduals) :- 1345 project_constraints(Bindings0, ResidueVars), 1346 hidden_residuals(ResidueVars, Bindings0, HiddenResiduals0), 1347 omit_qualifiers(HiddenResiduals0, TypeIn, HiddenResiduals), 1348 copy_term(Bindings0+ResGoals0, Bindings1+ResGoals1, Residuals0), 1349 '$append'(ResGoals1, Residuals0, Residuals1), 1350 omit_qualifiers(Residuals1, TypeIn, Residuals), 1351 join_same_bindings(Bindings1, Bindings2), 1352 factorize_bindings(Bindings2, Bindings3), 1353 bind_vars(Bindings3, Bindings4), 1354 filter_bindings(Bindings4, Bindings). 1355 ResidueVars, Bindings, Goal) (:- 1357 term_attvars(ResidueVars, Remaining), 1358 term_attvars(Bindings, QueryVars), 1359 subtract_vars(Remaining, QueryVars, HiddenVars), 1360 copy_term(HiddenVars, _, Goal). 1361 1362subtract_vars(All, Subtract, Remaining) :- 1363 sort(All, AllSorted), 1364 sort(Subtract, SubtractSorted), 1365 ord_subtract(AllSorted, SubtractSorted, Remaining). 1366 1367ord_subtract([], _Not, []). 1368ord_subtract([H1|T1], L2, Diff) :- 1369 diff21(L2, H1, T1, Diff). 1370 1371diff21([], H1, T1, [H1|T1]). 1372diff21([H2|T2], H1, T1, Diff) :- 1373 compare(Order, H1, H2), 1374 diff3(Order, H1, T1, H2, T2, Diff). 1375 1376diff12([], _H2, _T2, []). 1377diff12([H1|T1], H2, T2, Diff) :- 1378 compare(Order, H1, H2), 1379 diff3(Order, H1, T1, H2, T2, Diff). 1380 1381diff3(<, H1, T1, H2, T2, [H1|Diff]) :- 1382 diff12(T1, H2, T2, Diff). 1383diff3(=, _H1, T1, _H2, T2, Diff) :- 1384 ord_subtract(T1, T2, Diff). 1385diff3(>, H1, T1, _H2, T2, Diff) :- 1386 diff21(T2, H1, T1, Diff).
toplevel_residue_vars
is set to project
.1394project_constraints(Bindings, ResidueVars) :- 1395 !, 1396 term_attvars(Bindings, AttVars), 1397 phrase(attribute_modules(AttVars), Modules0), 1398 sort(Modules0, Modules), 1399 term_variables(Bindings, QueryVars), 1400 project_attributes(Modules, QueryVars, ResidueVars). 1401project_constraints(_, _). 1402 1403project_attributes([], _, _). 1404project_attributes([M|T], QueryVars, ResidueVars) :- 1405 ( current_predicate(M:project_attributes/2), 1406 catch(M:project_attributes(QueryVars, ResidueVars), E, 1407 print_message(error, E)) 1408 -> true 1409 ; true 1410 ), 1411 project_attributes(T, QueryVars, ResidueVars). 1412 1413attribute_modules([]) --> []. 1414attribute_modules([H|T]) --> 1415 { get_attrs(H, Attrs) }, 1416 attrs_modules(Attrs), 1417 attribute_modules(T). 1418 1419attrs_modules([]) --> []. 1420attrs_modules(att(Module, _, More)) --> 1421 [Module], 1422 attrs_modules(More).
1433join_same_bindings([], []). 1434join_same_bindings([Name=V0|T0], [[Name|Names]=V|T]) :- 1435 take_same_bindings(T0, V0, V, Names, T1), 1436 join_same_bindings(T1, T). 1437 1438take_same_bindings([], Val, Val, [], []). 1439take_same_bindings([Name=V1|T0], V0, V, [Name|Names], T) :- 1440 V0 == V1, 1441 !, 1442 take_same_bindings(T0, V1, V, Names, T). 1443take_same_bindings([Pair|T0], V0, V, Names, [Pair|T]) :- 1444 take_same_bindings(T0, V0, V, Names, T).
1453omit_qualifiers([], _, []). 1454omit_qualifiers([Goal0|Goals0], TypeIn, [Goal|Goals]) :- 1455 omit_qualifier(Goal0, TypeIn, Goal), 1456 omit_qualifiers(Goals0, TypeIn, Goals). 1457 1458omit_qualifier(M:G0, TypeIn, G) :- 1459 M == TypeIn, 1460 !, 1461 omit_meta_qualifiers(G0, TypeIn, G). 1462omit_qualifier(M:G0, TypeIn, G) :- 1463 predicate_property(TypeIn:G0, imported_from(M)), 1464 \+ predicate_property(G0, transparent), 1465 !, 1466 G0 = G. 1467omit_qualifier(_:G0, _, G) :- 1468 predicate_property(G0, built_in), 1469 \+ predicate_property(G0, transparent), 1470 !, 1471 G0 = G. 1472omit_qualifier(M:G0, _, M:G) :- 1473 atom(M), 1474 !, 1475 omit_meta_qualifiers(G0, M, G). 1476omit_qualifier(G0, TypeIn, G) :- 1477 omit_meta_qualifiers(G0, TypeIn, G). 1478 1479omit_meta_qualifiers(V, _, V) :- 1480 var(V), 1481 !. 1482omit_meta_qualifiers((QA,QB), TypeIn, (A,B)) :- 1483 !, 1484 omit_qualifier(QA, TypeIn, A), 1485 omit_qualifier(QB, TypeIn, B). 1486omit_meta_qualifiers(tnot(QA), TypeIn, tnot(A)) :- 1487 !, 1488 omit_qualifier(QA, TypeIn, A). 1489omit_meta_qualifiers(freeze(V, QGoal), TypeIn, freeze(V, Goal)) :- 1490 callable(QGoal), 1491 !, 1492 omit_qualifier(QGoal, TypeIn, Goal). 1493omit_meta_qualifiers(when(Cond, QGoal), TypeIn, when(Cond, Goal)) :- 1494 callable(QGoal), 1495 !, 1496 omit_qualifier(QGoal, TypeIn, Goal). 1497omit_meta_qualifiers(G, _, G).
1506bind_vars(Bindings0, Bindings) :- 1507 bind_query_vars(Bindings0, Bindings, SNames), 1508 bind_skel_vars(Bindings, Bindings, SNames, 1, _). 1509 1510bind_query_vars([], [], []). 1511bind_query_vars([binding(Names,Var,[Var2=Cycle])|T0], 1512 [binding(Names,Cycle,[])|T], [Name|SNames]) :- 1513 Var == Var2, % also implies var(Var) 1514 !, 1515 '$last'(Names, Name), 1516 Var = '$VAR'(Name), 1517 bind_query_vars(T0, T, SNames). 1518bind_query_vars([B|T0], [B|T], AllNames) :- 1519 B = binding(Names,Var,Skel), 1520 bind_query_vars(T0, T, SNames), 1521 ( var(Var), \+ attvar(Var), Skel == [] 1522 -> AllNames = [Name|SNames], 1523 '$last'(Names, Name), 1524 Var = '$VAR'(Name) 1525 ; AllNames = SNames 1526 ). 1527 1528 1529 1530bind_skel_vars([], _, _, N, N). 1531bind_skel_vars([binding(_,_,Skel)|T], Bindings, SNames, N0, N) :- 1532 bind_one_skel_vars(Skel, Bindings, SNames, N0, N1), 1533 bind_skel_vars(T, Bindings, SNames, N1, N).
1552bind_one_skel_vars([], _, _, N, N). 1553bind_one_skel_vars([Var=Value|T], Bindings, Names, N0, N) :- 1554 ( var(Var) 1555 -> ( '$member'(binding(Names, VVal, []), Bindings), 1556 same_term(Value, VVal) 1557 -> '$last'(Names, VName), 1558 Var = '$VAR'(VName), 1559 N2 = N0 1560 ; between(N0, infinite, N1), 1561 atom_concat('_S', N1, Name), 1562 \+ memberchk(Name, Names), 1563 !, 1564 Var = '$VAR'(Name), 1565 N2 is N1 + 1 1566 ) 1567 ; N2 = N0 1568 ), 1569 bind_one_skel_vars(T, Bindings, Names, N2, N).
1576factorize_bindings([], []). 1577factorize_bindings([Name=Value|T0], [binding(Name, Skel, Subst)|T]) :- 1578 '$factorize_term'(Value, Skel, Subst0), 1579 ( current_prolog_flag(toplevel_print_factorized, true) 1580 -> Subst = Subst0 1581 ; only_cycles(Subst0, Subst) 1582 ), 1583 factorize_bindings(T0, T). 1584 1585 1586only_cycles([], []). 1587only_cycles([B|T0], List) :- 1588 ( B = (Var=Value), 1589 Var = Value, 1590 acyclic_term(Var) 1591 -> only_cycles(T0, List) 1592 ; List = [B|T], 1593 only_cycles(T0, T) 1594 ).
1603filter_bindings([], []). 1604filter_bindings([H0|T0], T) :- 1605 hide_vars(H0, H), 1606 ( ( arg(1, H, []) 1607 ; self_bounded(H) 1608 ) 1609 -> filter_bindings(T0, T) 1610 ; T = [H|T1], 1611 filter_bindings(T0, T1) 1612 ). 1613 1614hide_vars(binding(Names0, Skel, Subst), binding(Names, Skel, Subst)) :- 1615 hide_names(Names0, Skel, Subst, Names). 1616 1617hide_names([], _, _, []). 1618hide_names([Name|T0], Skel, Subst, T) :- 1619 ( sub_atom(Name, 0, _, _, '_'), 1620 current_prolog_flag(toplevel_print_anon, false), 1621 sub_atom(Name, 1, 1, _, Next), 1622 char_type(Next, prolog_var_start) 1623 -> true 1624 ; Subst == [], 1625 Skel == '$VAR'(Name) 1626 ), 1627 !, 1628 hide_names(T0, Skel, Subst, T). 1629hide_names([Name|T0], Skel, Subst, [Name|T]) :- 1630 hide_names(T0, Skel, Subst, T). 1631 1632self_bounded(binding([Name], Value, [])) :- 1633 Value == '$VAR'(Name).
1639:- if(current_prolog_flag(emscripten, true)). 1640get_respons(Action, _Chp) :- 1641 '$can_yield', 1642 !, 1643 await(more, ActionS), 1644 atom_string(Action, ActionS). 1645:- endif. 1646get_respons(Action, Chp) :- 1647 repeat, 1648 flush_output(user_output), 1649 get_single_char(Char), 1650 answer_respons(Char, Chp, Action), 1651 ( Action == again 1652 -> print_message(query, query(action)), 1653 fail 1654 ; ! 1655 ). 1656 1657answer_respons(Char, _, again) :- 1658 '$in_reply'(Char, '?h'), 1659 !, 1660 print_message(help, query(help)). 1661answer_respons(Char, _, redo) :- 1662 '$in_reply'(Char, ';nrNR \t'), 1663 !, 1664 print_message(query, if_tty([ansi(bold, ';', [])])). 1665answer_respons(Char, _, redo) :- 1666 '$in_reply'(Char, 'tT'), 1667 !, 1668 trace, 1669 save_debug, 1670 print_message(query, if_tty([ansi(bold, '; [trace]', [])])). 1671answer_respons(Char, _, continue) :- 1672 '$in_reply'(Char, 'ca\n\ryY.'), 1673 !, 1674 print_message(query, if_tty([ansi(bold, '.', [])])). 1675answer_respons(0'b, _, show_again) :- 1676 !, 1677 break. 1678answer_respons(0'*, Chp, show_again) :- 1679 !, 1680 print_last_chpoint(Chp). 1681answer_respons(Char, _, show_again) :- 1682 print_predicate(Char, Pred, Options), 1683 !, 1684 print_message(query, if_tty(['~w'-[Pred]])), 1685 set_prolog_flag(answer_write_options, Options). 1686answer_respons(-1, _, show_again) :- 1687 !, 1688 print_message(query, halt('EOF')), 1689 halt(0). 1690answer_respons(Char, _, again) :- 1691 print_message(query, no_action(Char)). 1692 1693print_predicate(0'w, [write], [ quoted(true), 1694 spacing(next_argument) 1695 ]). 1696print_predicate(0'p, [print], [ quoted(true), 1697 portray(true), 1698 max_depth(10), 1699 spacing(next_argument) 1700 ]). 1701 1702 1703print_last_chpoint(Chp) :- 1704 current_predicate(print_last_choice_point/0), 1705 !, 1706 print_last_chpoint_(Chp). 1707print_last_chpoint(Chp) :- 1708 use_module(library(prolog_stack), [print_last_choicepoint/2]), 1709 print_last_chpoint_(Chp). 1710 1711print_last_chpoint_(Chp) :- 1712 print_last_choicepoint(Chp, [message_level(information)]). 1713 1714 1715 /******************************* 1716 * EXPANSION * 1717 *******************************/ 1718 1719:- user:dynamic(expand_query/4). 1720:- user:multifile(expand_query/4). 1721 1722call_expand_query(Goal, Expanded, Bindings, ExpandedBindings) :- 1723 user:expand_query(Goal, Expanded, Bindings, ExpandedBindings), 1724 !. 1725call_expand_query(Goal, Expanded, Bindings, ExpandedBindings) :- 1726 toplevel_variables:expand_query(Goal, Expanded, Bindings, ExpandedBindings), 1727 !. 1728call_expand_query(Goal, Goal, Bindings, Bindings). 1729 1730 1731:- user:dynamic(expand_answer/2). 1732:- user:multifile(expand_answer/2). 1733 1734call_expand_answer(Goal, Expanded) :- 1735 user:expand_answer(Goal, Expanded), 1736 !. 1737call_expand_answer(Goal, Expanded) :- 1738 toplevel_variables:expand_answer(Goal, Expanded), 1739 !. 1740call_expand_answer(Goal, Goal)