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-2018, University of Amsterdam 7 VU University Amsterdam 8 CWI, Amsterdam 9 All rights reserved. 10 11 Redistribution and use in source and binary forms, with or without 12 modification, are permitted provided that the following conditions 13 are met: 14 15 1. Redistributions of source code must retain the above copyright 16 notice, this list of conditions and the following disclaimer. 17 18 2. Redistributions in binary form must reproduce the above copyright 19 notice, this list of conditions and the following disclaimer in 20 the documentation and/or other materials provided with the 21 distribution. 22 23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 POSSIBILITY OF SUCH DAMAGE. 35*/ 36 37/* 38Consult, derivates and basic things. This module is loaded by the 39C-written bootstrap compiler. 40 41The $:- directive is executed by the bootstrap compiler, but not 42inserted in the intermediate code file. Used to print diagnostic 43messages and start the Prolog defined compiler for the remaining boot 44modules. 45 46If you want to debug this module, put a '$:-'(trace). directive 47somewhere. The tracer will work properly under boot compilation as it 48will use the C defined write predicate to print goals and does not 49attempt to call the Prolog defined trace interceptor. 50*/ 51 52 /******************************** 53 * LOAD INTO MODULE SYSTEM * 54 ********************************/ 55 56:- '$set_source_module'(system). 57 58'$boot_message'(_Format, _Args) :- 59 current_prolog_flag(verbose, silent), 60 !. 61'$boot_message'(Format, Args) :- 62 format(Format, Args), 63 !. 64 65'$:-'('$boot_message'('Loading boot file ...~n', [])). 66 67 68 /******************************** 69 * DIRECTIVES * 70 *********************************/ 71 72:- meta_predicate 73 dynamic( ), 74 multifile( ), 75 public( ), 76 module_transparent( ), 77 discontiguous( ), 78 volatile( ), 79 thread_local( ), 80 noprofile( ), 81 non_terminal( ), 82 '$clausable'( ), 83 '$iso'( ), 84 '$hide'( ).
100dynamic(Spec) :- '$set_pattr'(Spec, pred, (dynamic)). 101multifile(Spec) :- '$set_pattr'(Spec, pred, (multifile)). 102module_transparent(Spec) :- '$set_pattr'(Spec, pred, (transparent)). 103discontiguous(Spec) :- '$set_pattr'(Spec, pred, (discontiguous)). 104volatile(Spec) :- '$set_pattr'(Spec, pred, (volatile)). 105thread_local(Spec) :- '$set_pattr'(Spec, pred, (thread_local)). 106noprofile(Spec) :- '$set_pattr'(Spec, pred, (noprofile)). 107public(Spec) :- '$set_pattr'(Spec, pred, (public)). 108non_terminal(Spec) :- '$set_pattr'(Spec, pred, (non_terminal)). 109'$iso'(Spec) :- '$set_pattr'(Spec, pred, (iso)). 110'$clausable'(Spec) :- '$set_pattr'(Spec, pred, (clausable)). 111 112'$set_pattr'(M:Pred, How, Attr) :- 113 '$set_pattr'(Pred, M, How, Attr). 114 115'$set_pattr'(X, _, _, _) :- 116 var(X), 117 throw(error(instantiation_error, _)). 118'$set_pattr'([], _, _, _) :- !. 119'$set_pattr'([H|T], M, How, Attr) :- % ISO 120 !, 121 '$set_pattr'(H, M, How, Attr), 122 '$set_pattr'(T, M, How, Attr). 123'$set_pattr'((A,B), M, How, Attr) :- % ISO and traditional 124 !, 125 '$set_pattr'(A, M, How, Attr), 126 '$set_pattr'(B, M, How, Attr). 127'$set_pattr'(M:T, _, How, Attr) :- 128 !, 129 '$set_pattr'(T, M, How, Attr). 130'$set_pattr'(A, M, pred, Attr) :- 131 !, 132 '$set_predicate_attribute'(M:A, Attr, true). 133'$set_pattr'(A, M, directive, Attr) :- 134 !, 135 catch('$set_predicate_attribute'(M:A, Attr, true), 136 error(E, _), 137 print_message(error, error(E, context((Attr)/1,_)))).
146'$pattr_directive'(dynamic(Spec), M) :- 147 '$set_pattr'(Spec, M, directive, (dynamic)). 148'$pattr_directive'(multifile(Spec), M) :- 149 '$set_pattr'(Spec, M, directive, (multifile)). 150'$pattr_directive'(module_transparent(Spec), M) :- 151 '$set_pattr'(Spec, M, directive, (transparent)). 152'$pattr_directive'(discontiguous(Spec), M) :- 153 '$set_pattr'(Spec, M, directive, (discontiguous)). 154'$pattr_directive'(volatile(Spec), M) :- 155 '$set_pattr'(Spec, M, directive, (volatile)). 156'$pattr_directive'(thread_local(Spec), M) :- 157 '$set_pattr'(Spec, M, directive, (thread_local)). 158'$pattr_directive'(noprofile(Spec), M) :- 159 '$set_pattr'(Spec, M, directive, (noprofile)). 160'$pattr_directive'(public(Spec), M) :- 161 '$set_pattr'(Spec, M, directive, (public)).
168'$hide'(Pred) :- 169 '$set_predicate_attribute'(Pred, trace, false). 170 171 172 /******************************** 173 * CALLING, CONTROL * 174 *********************************/ 175 176:- noprofile((call/1, 177 catch/3, 178 once/1, 179 ignore/1, 180 call_cleanup/2, 181 call_cleanup/3, 182 setup_call_cleanup/3, 183 setup_call_catcher_cleanup/4)). 184 185:- meta_predicate 186 ';'( , ), 187 ','( , ), 188 @( , ), 189 call( ), 190 call( , ), 191 call( , , ), 192 call( , , , ), 193 call( , , , , ), 194 call( , , , , , ), 195 call( , , , , , , ), 196 call( , , , , , , , ), 197 not( ), 198 \+( ), 199 '->'( , ), 200 '*->'( , ), 201 once( ), 202 ignore( ), 203 catch( , , ), 204 reset( , , ), 205 setup_call_cleanup( , , ), 206 setup_call_catcher_cleanup( , , , ), 207 call_cleanup( , ), 208 call_cleanup( , , ), 209 catch_with_backtrace( , , ), 210 '$meta_call'( ). 211 212:- '$iso'((call/1, (\+)/1, once/1, (;)/2, (',')/2, (->)/2, catch/3)). 213 214% The control structures are always compiled, both if they appear in a 215% clause body and if they are handed to call/1. The only way to call 216% these predicates is by means of call/2.. In that case, we call the 217% hole control structure again to get it compiled by call/1 and properly 218% deal with !, etc. Another reason for having these things as 219% predicates is to be able to define properties for them, helping code 220% analyzers. 221 222(M0:If ; M0:Then) :- !, call(M0:(If ; Then)). 223(M1:If ; M2:Then) :- call(M1:(If ; M2:Then)). 224(G1 , G2) :- call((G1 , G2)). 225(If -> Then) :- call((If -> Then)). 226(If *-> Then) :- call((If *-> Then)). 227@(Goal,Module) :- @(Goal,Module).
This implementation is used by reset/3 because the continuation cannot be captured if it contains a such a compiled temporary clause.
241'$meta_call'(M:G) :- 242 prolog_current_choice(Ch), 243 '$meta_call'(G, M, Ch). 244 245'$meta_call'(Var, _, _) :- 246 var(Var), 247 !, 248 '$instantiation_error'(Var). 249'$meta_call'((A,B), M, Ch) :- 250 !, 251 '$meta_call'(A, M, Ch), 252 '$meta_call'(B, M, Ch). 253'$meta_call'((I->T;E), M, Ch) :- 254 !, 255 ( prolog_current_choice(Ch2), 256 '$meta_call'(I, M, Ch2) 257 -> '$meta_call'(T, M, Ch) 258 ; '$meta_call'(E, M, Ch) 259 ). 260'$meta_call'((I*->T;E), M, Ch) :- 261 !, 262 ( prolog_current_choice(Ch2), 263 '$meta_call'(I, M, Ch2) 264 *-> '$meta_call'(T, M, Ch) 265 ; '$meta_call'(E, M, Ch) 266 ). 267'$meta_call'((I->T), M, Ch) :- 268 !, 269 ( prolog_current_choice(Ch2), 270 '$meta_call'(I, M, Ch2) 271 -> '$meta_call'(T, M, Ch) 272 ). 273'$meta_call'((I*->T), M, Ch) :- 274 !, 275 prolog_current_choice(Ch2), 276 '$meta_call'(I, M, Ch2), 277 '$meta_call'(T, M, Ch). 278'$meta_call'((A;B), M, Ch) :- 279 !, 280 ( '$meta_call'(A, M, Ch) 281 ; '$meta_call'(B, M, Ch) 282 ). 283'$meta_call'(\+(G), M, _) :- 284 !, 285 prolog_current_choice(Ch), 286 \+ '$meta_call'(G, M, Ch). 287'$meta_call'(call(G), M, _) :- 288 !, 289 prolog_current_choice(Ch), 290 '$meta_call'(G, M, Ch). 291'$meta_call'(M:G, _, Ch) :- 292 !, 293 '$meta_call'(G, M, Ch). 294'$meta_call'(!, _, Ch) :- 295 prolog_cut_to(Ch). 296'$meta_call'(G, M, _Ch) :- 297 call(M:G).
313:- '$iso'((call/2, 314 call/3, 315 call/4, 316 call/5, 317 call/6, 318 call/7, 319 call/8)). 320 321call(Goal) :- % make these available as predicates 322 . 323call(Goal, A) :- 324 call(Goal, A). 325call(Goal, A, B) :- 326 call(Goal, A, B). 327call(Goal, A, B, C) :- 328 call(Goal, A, B, C). 329call(Goal, A, B, C, D) :- 330 call(Goal, A, B, C, D). 331call(Goal, A, B, C, D, E) :- 332 call(Goal, A, B, C, D, E). 333call(Goal, A, B, C, D, E, F) :- 334 call(Goal, A, B, C, D, E, F). 335call(Goal, A, B, C, D, E, F, G) :- 336 call(Goal, A, B, C, D, E, F, G).
343not(Goal) :-
344 \+ .
350\+ Goal :-
351 \+ .
call((Goal, !))
.
357once(Goal) :-
358 ,
359 !.
366ignore(Goal) :- 367 , 368 !. 369ignore(_Goal). 370 371:- '$iso'((false/0)). 372 373%! false. 374% 375% Synonym for fail/0, providing a declarative reading. 376 377false :- fail.
384catch(_Goal, _Catcher, _Recover) :- 385 '$catch'. % Maps to I_CATCH, I_EXITCATCH
391prolog_cut_to(_Choice) :- 392 '$cut'. % Maps to I_CUTCHP
398reset(_Goal, _Ball, _Cont) :-
399 '$reset'.
405shift(Ball) :-
406 '$shift'(Ball).
Note that we can technically also push the entire continuation onto the environment and call it. Doing it incrementally as below exploits last-call optimization and therefore possible quadratic expansion of the continuation.
420call_continuation([]). 421call_continuation([TB|Rest]) :- 422 ( Rest == [] 423 -> '$call_continuation'(TB) 424 ; '$call_continuation'(TB), 425 call_continuation(Rest) 426 ).
library(prolog_stack)
to record a backtrace in
case of an exception.433catch_with_backtrace(Goal, Ball, Recover) :- 434 catch(Goal, Ball, Recover), 435 '$no_lco'. 436 437'$no_lco'.
447:- public '$recover_and_rethrow'/2. 448 449'$recover_and_rethrow'(Goal, Exception) :- 450 call_cleanup(Goal, throw(Exception)), 451 !.
466setup_call_catcher_cleanup(Setup, _Goal, _Catcher, _Cleanup) :- 467 '$sig_atomic'(Setup), 468 '$call_cleanup'. 469 470setup_call_cleanup(Setup, Goal, Cleanup) :- 471 setup_call_catcher_cleanup(Setup, Goal, _Catcher, Cleanup). 472 473call_cleanup(Goal, Cleanup) :- 474 setup_call_catcher_cleanup(true, Goal, _Catcher, Cleanup). 475 476call_cleanup(Goal, Catcher, Cleanup) :- 477 setup_call_catcher_cleanup(true, Goal, Catcher, Cleanup). 478 479 /******************************* 480 * INITIALIZATION * 481 *******************************/ 482 483:- meta_predicate 484 initialization( , ). 485 486:- multifile '$init_goal'/3. 487:- dynamic '$init_goal'/3.
-g goal
goals.Note that all goals are executed when a program is restored.
513initialization(Goal, When) :- 514 '$must_be'(oneof(atom, initialization_type, 515 [ now, 516 after_load, 517 restore, 518 restore_state, 519 prepare_state, 520 program, 521 main 522 ]), When), 523 '$initialization_context'(Source, Ctx), 524 '$initialization'(When, Goal, Source, Ctx). 525 526'$initialization'(now, Goal, _Source, Ctx) :- 527 '$run_init_goal'(Goal, Ctx), 528 '$compile_init_goal'(-, Goal, Ctx). 529'$initialization'(after_load, Goal, Source, Ctx) :- 530 ( Source \== (-) 531 -> '$compile_init_goal'(Source, Goal, Ctx) 532 ; throw(error(context_error(nodirective, 533 initialization(Goal, after_load)), 534 _)) 535 ). 536'$initialization'(restore, Goal, Source, Ctx) :- % deprecated 537 '$initialization'(restore_state, Goal, Source, Ctx). 538'$initialization'(restore_state, Goal, _Source, Ctx) :- 539 ( \+ current_prolog_flag(sandboxed_load, true) 540 -> '$compile_init_goal'(-, Goal, Ctx) 541 ; '$permission_error'(register, initialization(restore), Goal) 542 ). 543'$initialization'(prepare_state, Goal, _Source, Ctx) :- 544 ( \+ current_prolog_flag(sandboxed_load, true) 545 -> '$compile_init_goal'(when(prepare_state), Goal, Ctx) 546 ; '$permission_error'(register, initialization(restore), Goal) 547 ). 548'$initialization'(program, Goal, _Source, Ctx) :- 549 ( \+ current_prolog_flag(sandboxed_load, true) 550 -> '$compile_init_goal'(when(program), Goal, Ctx) 551 ; '$permission_error'(register, initialization(restore), Goal) 552 ). 553'$initialization'(main, Goal, _Source, Ctx) :- 554 ( \+ current_prolog_flag(sandboxed_load, true) 555 -> '$compile_init_goal'(when(main), Goal, Ctx) 556 ; '$permission_error'(register, initialization(restore), Goal) 557 ). 558 559 560'$compile_init_goal'(Source, Goal, Ctx) :- 561 atom(Source), 562 Source \== (-), 563 !, 564 '$store_admin_clause'(system:'$init_goal'(Source, Goal, Ctx), 565 _Layout, Source, Ctx). 566'$compile_init_goal'(Source, Goal, Ctx) :- 567 assertz('$init_goal'(Source, Goal, Ctx)).
runInitialization()
in pl-wic.c for .qlf files. The
'$run_initialization'/3 is called with Action set to loaded
when called for a QLF file.579'$run_initialization'(_, loaded, _) :- !. 580'$run_initialization'(File, _Action, Options) :- 581 '$run_initialization'(File, Options). 582 583'$run_initialization'(File, Options) :- 584 setup_call_cleanup( 585 '$start_run_initialization'(Options, Restore), 586 '$run_initialization_2'(File), 587 '$end_run_initialization'(Restore)). 588 589'$start_run_initialization'(Options, OldSandBoxed) :- 590 '$push_input_context'(initialization), 591 '$set_sandboxed_load'(Options, OldSandBoxed). 592'$end_run_initialization'(OldSandBoxed) :- 593 set_prolog_flag(sandboxed_load, OldSandBoxed), 594 '$pop_input_context'. 595 596'$run_initialization_2'(File) :- 597 ( '$init_goal'(File, Goal, Ctx), 598 File \= when(_), 599 '$run_init_goal'(Goal, Ctx), 600 fail 601 ; true 602 ). 603 604'$run_init_goal'(Goal, Ctx) :- 605 ( catch_with_backtrace('$run_init_goal'(Goal), E, 606 '$initialization_error'(E, Goal, Ctx)) 607 -> true 608 ; '$initialization_failure'(Goal, Ctx) 609 ). 610 611:- multifile prolog:sandbox_allowed_goal/1. 612 613'$run_init_goal'(Goal) :- 614 current_prolog_flag(sandboxed_load, false), 615 !, 616 call(Goal). 617'$run_init_goal'(Goal) :- 618 prolog:sandbox_allowed_goal(Goal), 619 call(Goal). 620 621'$initialization_context'(Source, Ctx) :- 622 ( source_location(File, Line) 623 -> Ctx = File:Line, 624 '$input_context'(Context), 625 '$top_file'(Context, File, Source) 626 ; Ctx = (-), 627 File = (-) 628 ). 629 630'$top_file'([input(include, F1, _, _)|T], _, F) :- 631 !, 632 '$top_file'(T, F1, F). 633'$top_file'(_, F, F). 634 635 636'$initialization_error'(E, Goal, Ctx) :- 637 print_message(error, initialization_error(Goal, E, Ctx)). 638 639'$initialization_failure'(Goal, Ctx) :- 640 print_message(warning, initialization_failure(Goal, Ctx)).
648:- public '$clear_source_admin'/1. 649 650'$clear_source_admin'(File) :- 651 retractall('$init_goal'(_, _, File:_)), 652 retractall('$load_context_module'(File, _, _)), 653 retractall('$resolved_source_path'(_, File)). 654 655 656 /******************************* 657 * STREAM * 658 *******************************/ 659 660:- '$iso'(stream_property/2). 661stream_property(Stream, Property) :- 662 nonvar(Stream), 663 nonvar(Property), 664 !, 665 '$stream_property'(Stream, Property). 666stream_property(Stream, Property) :- 667 nonvar(Stream), 668 !, 669 '$stream_properties'(Stream, Properties), 670 '$member'(Property, Properties). 671stream_property(Stream, Property) :- 672 nonvar(Property), 673 !, 674 ( Property = alias(Alias), 675 atom(Alias) 676 -> '$alias_stream'(Alias, Stream) 677 ; '$streams_properties'(Property, Pairs), 678 '$member'(Stream-Property, Pairs) 679 ). 680stream_property(Stream, Property) :- 681 '$streams_properties'(Property, Pairs), 682 '$member'(Stream-Properties, Pairs), 683 '$member'(Property, Properties). 684 685 686 /******************************** 687 * MODULES * 688 *********************************/ 689 690% '$prefix_module'(+Module, +Context, +Term, -Prefixed) 691% Tags `Term' with `Module:' if `Module' is not the context module. 692 693'$prefix_module'(Module, Module, Head, Head) :- !. 694'$prefix_module'(Module, _, Head, Module:Head).
700default_module(Me, Super) :- 701 ( atom(Me) 702 -> ( var(Super) 703 -> '$default_module'(Me, Super) 704 ; '$default_module'(Me, Super), ! 705 ) 706 ; '$type_error'(module, Me) 707 ). 708 709'$default_module'(Me, Me). 710'$default_module'(Me, Super) :- 711 import_module(Me, S), 712 '$default_module'(S, Super). 713 714 715 /******************************** 716 * TRACE AND EXCEPTIONS * 717 *********************************/ 718 719:- user:dynamic((exception/3, 720 prolog_event_hook/1)). 721:- user:multifile((exception/3, 722 prolog_event_hook/1)).
731:- public 732 '$undefined_procedure'/4. 733 734'$undefined_procedure'(Module, Name, Arity, Action) :- 735 '$prefix_module'(Module, user, Name/Arity, Pred), 736 user:exception(undefined_predicate, Pred, Action0), 737 !, 738 Action = Action0. 739'$undefined_procedure'(Module, Name, Arity, Action) :- 740 current_prolog_flag(autoload, true), 741 '$autoload'(Module, Name, Arity), 742 !, 743 Action = retry. 744'$undefined_procedure'(_, _, _, error). 745 746'$autoload'(Module, Name, Arity) :- 747 source_location(File, _Line), 748 !, 749 setup_call_cleanup( 750 '$start_aux'(File, Context), 751 '$autoload2'(Module, Name, Arity), 752 '$end_aux'(File, Context)). 753'$autoload'(Module, Name, Arity) :- 754 '$autoload2'(Module, Name, Arity). 755 756'$autoload2'(Module, Name, Arity) :- 757 '$find_library'(Module, Name, Arity, LoadModule, Library), 758 functor(Head, Name, Arity), 759 '$update_autoload_level'([autoload(true)], Old), 760 ( current_prolog_flag(verbose_autoload, true) 761 -> Level = informational 762 ; Level = silent 763 ), 764 print_message(Level, autoload(Module:Name/Arity, Library)), 765 '$compilation_mode'(OldComp, database), 766 ( Module == LoadModule 767 -> ensure_loaded(Module:Library) 768 ; ( '$get_predicate_attribute'(LoadModule:Head, defined, 1), 769 \+ '$loading'(Library) 770 -> Module:import(LoadModule:Name/Arity) 771 ; use_module(Module:Library, [Name/Arity]) 772 ) 773 ), 774 '$set_compilation_mode'(OldComp), 775 '$set_autoload_level'(Old), 776 '$c_current_predicate'(_, Module:Head).
787'$loading'(Library) :- 788 current_prolog_flag(threads, true), 789 '$loading_file'(FullFile, _Queue, _LoadThread), 790 file_name_extension(Library, _, FullFile), 791 !. 792 793% handle debugger 'w', 'p' and <N> depth options. 794 795'$set_debugger_write_options'(write) :- 796 !, 797 create_prolog_flag(debugger_write_options, 798 [ quoted(true), 799 attributes(dots), 800 spacing(next_argument) 801 ], []). 802'$set_debugger_write_options'(print) :- 803 !, 804 create_prolog_flag(debugger_write_options, 805 [ quoted(true), 806 portray(true), 807 max_depth(10), 808 attributes(portray), 809 spacing(next_argument) 810 ], []). 811'$set_debugger_write_options'(Depth) :- 812 current_prolog_flag(debugger_write_options, Options0), 813 ( '$select'(max_depth(_), Options0, Options) 814 -> true 815 ; Options = Options0 816 ), 817 create_prolog_flag(debugger_write_options, 818 [max_depth(Depth)|Options], []). 819 820 821 /******************************** 822 * SYSTEM MESSAGES * 823 *********************************/
830'$confirm'(Spec) :- 831 print_message(query, Spec), 832 between(0, 5, _), 833 get_single_char(Answer), 834 ( '$in_reply'(Answer, 'yYjJ \n') 835 -> !, 836 print_message(query, if_tty([yes-[]])) 837 ; '$in_reply'(Answer, 'nN') 838 -> !, 839 print_message(query, if_tty([no-[]])), 840 fail 841 ; print_message(help, query(confirm)), 842 fail 843 ). 844 845'$in_reply'(Code, Atom) :- 846 char_code(Char, Code), 847 sub_atom(Atom, _, _, _, Char), 848 !. 849 850:- dynamic 851 user:portray/1. 852:- multifile 853 user:portray/1. 854 855 856 /******************************* 857 * FILE_SEARCH_PATH * 858 *******************************/ 859 860:- dynamic user:file_search_path/2. 861:- multifile user:file_search_path/2. 862 863user(file_search_path(library, Dir) :- 864 library_directory(Dir)). 865user:file_search_path(swi, Home) :- 866 current_prolog_flag(home, Home). 867user:file_search_path(foreign, swi(ArchLib)) :- 868 current_prolog_flag(arch, Arch), 869 atom_concat('lib/', Arch, ArchLib). 870user:file_search_path(foreign, swi(SoLib)) :- 871 ( current_prolog_flag(windows, true) 872 -> SoLib = bin 873 ; SoLib = lib 874 ). 875user:file_search_path(path, Dir) :- 876 getenv('PATH', Path), 877 ( current_prolog_flag(windows, true) 878 -> atomic_list_concat(Dirs, (;), Path) 879 ; atomic_list_concat(Dirs, :, Path) 880 ), 881 '$member'(Dir, Dirs), 882 '$no-null-bytes'(Dir). 883 884'$no-null-bytes'(Dir) :- 885 sub_atom(Dir, _, _, _, '\u0000'), 886 !, 887 print_message(warning, null_byte_in_path(Dir)), 888 fail. 889'$no-null-bytes'(_).
897expand_file_search_path(Spec, Expanded) :- 898 catch('$expand_file_search_path'(Spec, Expanded, 0, []), 899 loop(Used), 900 throw(error(loop_error(Spec), file_search(Used)))). 901 902'$expand_file_search_path'(Spec, Expanded, N, Used) :- 903 functor(Spec, Alias, 1), 904 !, 905 user:file_search_path(Alias, Exp0), 906 NN is N + 1, 907 ( NN > 16 908 -> throw(loop(Used)) 909 ; true 910 ), 911 '$expand_file_search_path'(Exp0, Exp1, NN, [Alias=Exp0|Used]), 912 arg(1, Spec, Segments), 913 '$segments_to_atom'(Segments, File), 914 '$make_path'(Exp1, File, Expanded). 915'$expand_file_search_path'(Spec, Path, _, _) :- 916 '$segments_to_atom'(Spec, Path). 917 918'$make_path'(Dir, '.', Path) :- 919 !, 920 Path = Dir. 921'$make_path'(Dir, File, Path) :- 922 sub_atom(Dir, _, _, 0, /), 923 !, 924 atom_concat(Dir, File, Path). 925'$make_path'(Dir, File, Path) :- 926 atomic_list_concat([Dir, /, File], Path). 927 928 929 /******************************** 930 * FILE CHECKING * 931 *********************************/
942absolute_file_name(Spec, Options, Path) :- 943 '$is_options'(Options), 944 \+ '$is_options'(Path), 945 !, 946 absolute_file_name(Spec, Path, Options). 947absolute_file_name(Spec, Path, Options) :- 948 '$must_be'(options, Options), 949 % get the valid extensions 950 ( '$select_option'(extensions(Exts), Options, Options1) 951 -> '$must_be'(list, Exts) 952 ; '$option'(file_type(Type), Options) 953 -> '$must_be'(atom, Type), 954 '$file_type_extensions'(Type, Exts), 955 Options1 = Options 956 ; Options1 = Options, 957 Exts = [''] 958 ), 959 '$canonicalise_extensions'(Exts, Extensions), 960 % unless specified otherwise, ask regular file 961 ( nonvar(Type) 962 -> Options2 = Options1 963 ; '$merge_options'(_{file_type:regular}, Options1, Options2) 964 ), 965 % Det or nondet? 966 ( '$select_option'(solutions(Sols), Options2, Options3) 967 -> '$must_be'(oneof(atom, solutions, [first,all]), Sols) 968 ; Sols = first, 969 Options3 = Options2 970 ), 971 % Errors or not? 972 ( '$select_option'(file_errors(FileErrors), Options3, Options4) 973 -> '$must_be'(oneof(atom, file_errors, [error,fail]), FileErrors) 974 ; FileErrors = error, 975 Options4 = Options3 976 ), 977 % Expand shell patterns? 978 ( atomic(Spec), 979 '$select_option'(expand(Expand), Options4, Options5), 980 '$must_be'(boolean, Expand) 981 -> expand_file_name(Spec, List), 982 '$member'(Spec1, List) 983 ; Spec1 = Spec, 984 Options5 = Options4 985 ), 986 % Search for files 987 ( Sols == first 988 -> ( '$chk_file'(Spec1, Extensions, Options5, true, Path) 989 -> ! % also kill choice point of expand_file_name/2 990 ; ( FileErrors == fail 991 -> fail 992 ; '$current_module'('$bags', _File), 993 findall(P, 994 '$chk_file'(Spec1, Extensions, [access(exist)], 995 false, P), 996 Candidates), 997 '$abs_file_error'(Spec, Candidates, Options5) 998 ) 999 ) 1000 ; '$chk_file'(Spec1, Extensions, Options5, false, Path) 1001 ). 1002 1003'$abs_file_error'(Spec, Candidates, Conditions) :- 1004 '$member'(F, Candidates), 1005 '$member'(C, Conditions), 1006 '$file_condition'(C), 1007 '$file_error'(C, Spec, F, E, Comment), 1008 !, 1009 throw(error(E, context(_, Comment))). 1010'$abs_file_error'(Spec, _, _) :- 1011 '$existence_error'(source_sink, Spec). 1012 1013'$file_error'(file_type(directory), Spec, File, Error, Comment) :- 1014 \+ exists_directory(File), 1015 !, 1016 Error = existence_error(directory, Spec), 1017 Comment = not_a_directory(File). 1018'$file_error'(file_type(_), Spec, File, Error, Comment) :- 1019 exists_directory(File), 1020 !, 1021 Error = existence_error(file, Spec), 1022 Comment = directory(File). 1023'$file_error'(access(OneOrList), Spec, File, Error, _) :- 1024 '$one_or_member'(Access, OneOrList), 1025 \+ access_file(File, Access), 1026 Error = permission_error(Access, source_sink, Spec). 1027 1028'$one_or_member'(Elem, List) :- 1029 is_list(List), 1030 !, 1031 '$member'(Elem, List). 1032'$one_or_member'(Elem, Elem). 1033 1034 1035'$file_type_extensions'(source, Exts) :- % SICStus 3.9 compatibility 1036 !, 1037 '$file_type_extensions'(prolog, Exts). 1038'$file_type_extensions'(Type, Exts) :- 1039 '$current_module'('$bags', _File), 1040 !, 1041 findall(Ext, user:prolog_file_type(Ext, Type), Exts0), 1042 ( Exts0 == [], 1043 \+ '$ft_no_ext'(Type) 1044 -> '$domain_error'(file_type, Type) 1045 ; true 1046 ), 1047 '$append'(Exts0, [''], Exts). 1048'$file_type_extensions'(prolog, [pl, '']). % findall is not yet defined ... 1049 1050'$ft_no_ext'(txt). 1051'$ft_no_ext'(executable). 1052'$ft_no_ext'(directory).
Note that qlf
must be last when searching for Prolog files.
Otherwise use_module/1 will consider the file as not-loaded
because the .qlf file is not the loaded file. Must be fixed
elsewhere.
1065:- multifile(user:prolog_file_type/2). 1066:- dynamic(user:prolog_file_type/2). 1067 1068userprolog_file_type(pl, prolog). 1069userprolog_file_type(prolog, prolog). 1070userprolog_file_type(qlf, prolog). 1071userprolog_file_type(qlf, qlf). 1072userprolog_file_type(Ext, executable) :- 1073 current_prolog_flag(shared_object_extension, Ext). 1074userprolog_file_type(dylib, executable) :- 1075 current_prolog_flag(apple, true).
1082'$chk_file'(Spec, _Extensions, _Cond, _Cache, _FullName) :- 1083 \+ ground(Spec), 1084 !, 1085 '$instantiation_error'(Spec). 1086'$chk_file'(Spec, Extensions, Cond, Cache, FullName) :- 1087 compound(Spec), 1088 functor(Spec, _, 1), 1089 !, 1090 '$relative_to'(Cond, cwd, CWD), 1091 '$chk_alias_file'(Spec, Extensions, Cond, Cache, CWD, FullName). 1092'$chk_file'(Segments, Ext, Cond, Cache, FullName) :- % allow a/b/... 1093 \+ atomic(Segments), 1094 !, 1095 '$segments_to_atom'(Segments, Atom), 1096 '$chk_file'(Atom, Ext, Cond, Cache, FullName). 1097'$chk_file'(File, Exts, Cond, _, FullName) :- 1098 is_absolute_file_name(File), 1099 !, 1100 '$extend_file'(File, Exts, Extended), 1101 '$file_conditions'(Cond, Extended), 1102 '$absolute_file_name'(Extended, FullName). 1103'$chk_file'(File, Exts, Cond, _, FullName) :- 1104 '$relative_to'(Cond, source, Dir), 1105 atomic_list_concat([Dir, /, File], AbsFile), 1106 '$extend_file'(AbsFile, Exts, Extended), 1107 '$file_conditions'(Cond, Extended), 1108 !, 1109 '$absolute_file_name'(Extended, FullName). 1110'$chk_file'(File, Exts, Cond, _, FullName) :- 1111 '$extend_file'(File, Exts, Extended), 1112 '$file_conditions'(Cond, Extended), 1113 '$absolute_file_name'(Extended, FullName). 1114 1115'$segments_to_atom'(Atom, Atom) :- 1116 atomic(Atom), 1117 !. 1118'$segments_to_atom'(Segments, Atom) :- 1119 '$segments_to_list'(Segments, List, []), 1120 !, 1121 atomic_list_concat(List, /, Atom). 1122 1123'$segments_to_list'(A/B, H, T) :- 1124 '$segments_to_list'(A, H, T0), 1125 '$segments_to_list'(B, T0, T). 1126'$segments_to_list'(A, [A|T], T) :- 1127 atomic(A).
relative_to(FileOrDir)
options
or implicitely relative to the working directory or current
source-file.
1137'$relative_to'(Conditions, Default, Dir) :-
1138 ( '$option'(relative_to(FileOrDir), Conditions)
1139 *-> ( exists_directory(FileOrDir)
1140 -> Dir = FileOrDir
1141 ; atom_concat(Dir, /, FileOrDir)
1142 -> true
1143 ; file_directory_name(FileOrDir, Dir)
1144 )
1145 ; Default == cwd
1146 -> '$cwd'(Dir)
1147 ; Default == source
1148 -> source_location(ContextFile, _Line),
1149 file_directory_name(ContextFile, Dir)
1150 ).
1155:- dynamic 1156 '$search_path_file_cache'/3, % SHA1, Time, Path 1157 '$search_path_gc_time'/1. % Time 1158:- volatile 1159 '$search_path_file_cache'/3, 1160 '$search_path_gc_time'/1. 1161 1162:- create_prolog_flag(file_search_cache_time, 10, []). 1163 1164'$chk_alias_file'(Spec, Exts, Cond, true, CWD, FullFile) :- 1165 !, 1166 findall(Exp, expand_file_search_path(Spec, Exp), Expansions), 1167 Cache = cache(Exts, Cond, CWD, Expansions), 1168 variant_sha1(Spec+Cache, SHA1), 1169 get_time(Now), 1170 current_prolog_flag(file_search_cache_time, TimeOut), 1171 ( '$search_path_file_cache'(SHA1, CachedTime, FullFile), 1172 CachedTime > Now - TimeOut, 1173 '$file_conditions'(Cond, FullFile) 1174 -> '$search_message'(file_search(cache(Spec, Cond), FullFile)) 1175 ; '$member'(Expanded, Expansions), 1176 '$extend_file'(Expanded, Exts, LibFile), 1177 ( '$file_conditions'(Cond, LibFile), 1178 '$absolute_file_name'(LibFile, FullFile), 1179 '$cache_file_found'(SHA1, Now, TimeOut, FullFile) 1180 -> '$search_message'(file_search(found(Spec, Cond), FullFile)) 1181 ; '$search_message'(file_search(tried(Spec, Cond), LibFile)), 1182 fail 1183 ) 1184 ). 1185'$chk_alias_file'(Spec, Exts, Cond, false, _CWD, FullFile) :- 1186 expand_file_search_path(Spec, Expanded), 1187 '$extend_file'(Expanded, Exts, LibFile), 1188 '$file_conditions'(Cond, LibFile), 1189 '$absolute_file_name'(LibFile, FullFile). 1190 1191'$cache_file_found'(_, _, TimeOut, _) :- 1192 TimeOut =:= 0, 1193 !. 1194'$cache_file_found'(SHA1, Now, TimeOut, FullFile) :- 1195 '$search_path_file_cache'(SHA1, Saved, FullFile), 1196 !, 1197 ( Now - Saved < TimeOut/2 1198 -> true 1199 ; retractall('$search_path_file_cache'(SHA1, _, _)), 1200 asserta('$search_path_file_cache'(SHA1, Now, FullFile)) 1201 ). 1202'$cache_file_found'(SHA1, Now, TimeOut, FullFile) :- 1203 'gc_file_search_cache'(TimeOut), 1204 asserta('$search_path_file_cache'(SHA1, Now, FullFile)). 1205 1206'gc_file_search_cache'(TimeOut) :- 1207 get_time(Now), 1208 '$search_path_gc_time'(Last), 1209 Now-Last < TimeOut/2, 1210 !. 1211'gc_file_search_cache'(TimeOut) :- 1212 get_time(Now), 1213 retractall('$search_path_gc_time'(_)), 1214 assertz('$search_path_gc_time'(Now)), 1215 Before is Now - TimeOut, 1216 ( '$search_path_file_cache'(SHA1, Cached, FullFile), 1217 Cached < Before, 1218 retractall('$search_path_file_cache'(SHA1, Cached, FullFile)), 1219 fail 1220 ; true 1221 ). 1222 1223 1224'$search_message'(Term) :- 1225 current_prolog_flag(verbose_file_search, true), 1226 !, 1227 print_message(informational, Term). 1228'$search_message'(_).
1235'$file_conditions'(List, File) :- 1236 is_list(List), 1237 !, 1238 \+ ( '$member'(C, List), 1239 '$file_condition'(C), 1240 \+ '$file_condition'(C, File) 1241 ). 1242'$file_conditions'(Map, File) :- 1243 \+ ( get_dict(Key, Map, Value), 1244 C =.. [Key,Value], 1245 '$file_condition'(C), 1246 \+ '$file_condition'(C, File) 1247 ). 1248 1249'$file_condition'(file_type(directory), File) :- 1250 !, 1251 exists_directory(File). 1252'$file_condition'(file_type(_), File) :- 1253 !, 1254 \+ exists_directory(File). 1255'$file_condition'(access(Accesses), File) :- 1256 !, 1257 \+ ( '$one_or_member'(Access, Accesses), 1258 \+ access_file(File, Access) 1259 ). 1260 1261'$file_condition'(exists). 1262'$file_condition'(file_type(_)). 1263'$file_condition'(access(_)). 1264 1265'$extend_file'(File, Exts, FileEx) :- 1266 '$ensure_extensions'(Exts, File, Fs), 1267 '$list_to_set'(Fs, FsSet), 1268 '$member'(FileEx, FsSet). 1269 1270'$ensure_extensions'([], _, []). 1271'$ensure_extensions'([E|E0], F, [FE|E1]) :- 1272 file_name_extension(F, E, FE), 1273 '$ensure_extensions'(E0, F, E1).
library(lists)
provides an O(N*log(N)
)
version, but sets of file name extensions should be short enough
for this not to matter.1282'$list_to_set'(List, Set) :- 1283 '$list_to_set'(List, [], Set). 1284 1285'$list_to_set'([], _, []). 1286'$list_to_set'([H|T], Seen, R) :- 1287 memberchk(H, Seen), 1288 !, 1289 '$list_to_set'(T, R). 1290'$list_to_set'([H|T], Seen, [H|R]) :- 1291 '$list_to_set'(T, [H|Seen], R). 1292 1293/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1294Canonicalise the extension list. Old SWI-Prolog require `.pl', etc, which 1295the Quintus compatibility requests `pl'. This layer canonicalises all 1296extensions to .ext 1297- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1298 1299'$canonicalise_extensions'([], []) :- !. 1300'$canonicalise_extensions'([H|T], [CH|CT]) :- 1301 !, 1302 '$must_be'(atom, H), 1303 '$canonicalise_extension'(H, CH), 1304 '$canonicalise_extensions'(T, CT). 1305'$canonicalise_extensions'(E, [CE]) :- 1306 '$canonicalise_extension'(E, CE). 1307 1308'$canonicalise_extension'('', '') :- !. 1309'$canonicalise_extension'(DotAtom, DotAtom) :- 1310 sub_atom(DotAtom, 0, _, _, '.'), 1311 !. 1312'$canonicalise_extension'(Atom, DotAtom) :- 1313 atom_concat('.', Atom, DotAtom). 1314 1315 1316 /******************************** 1317 * CONSULT * 1318 *********************************/ 1319 1320:- dynamic 1321 user:library_directory/1, 1322 user:prolog_load_file/2. 1323:- multifile 1324 user:library_directory/1, 1325 user:prolog_load_file/2. 1326 1327:- prompt(_, '|: '). 1328 1329:- thread_local 1330 '$compilation_mode_store'/1, % database, wic, qlf 1331 '$directive_mode_store'/1. % database, wic, qlf 1332:- volatile 1333 '$compilation_mode_store'/1, 1334 '$directive_mode_store'/1. 1335 1336'$compilation_mode'(Mode) :- 1337 ( '$compilation_mode_store'(Val) 1338 -> Mode = Val 1339 ; Mode = database 1340 ). 1341 1342'$set_compilation_mode'(Mode) :- 1343 retractall('$compilation_mode_store'(_)), 1344 assertz('$compilation_mode_store'(Mode)). 1345 1346'$compilation_mode'(Old, New) :- 1347 '$compilation_mode'(Old), 1348 ( New == Old 1349 -> true 1350 ; '$set_compilation_mode'(New) 1351 ). 1352 1353'$directive_mode'(Mode) :- 1354 ( '$directive_mode_store'(Val) 1355 -> Mode = Val 1356 ; Mode = database 1357 ). 1358 1359'$directive_mode'(Old, New) :- 1360 '$directive_mode'(Old), 1361 ( New == Old 1362 -> true 1363 ; '$set_directive_mode'(New) 1364 ). 1365 1366'$set_directive_mode'(Mode) :- 1367 retractall('$directive_mode_store'(_)), 1368 assertz('$directive_mode_store'(Mode)).
1376'$compilation_level'(Level) :- 1377 '$input_context'(Stack), 1378 '$compilation_level'(Stack, Level). 1379 1380'$compilation_level'([], 0). 1381'$compilation_level'([Input|T], Level) :- 1382 ( arg(1, Input, see) 1383 -> '$compilation_level'(T, Level) 1384 ; '$compilation_level'(T, Level0), 1385 Level is Level0+1 1386 ).
1394compiling :- 1395 \+ ( '$compilation_mode'(database), 1396 '$directive_mode'(database) 1397 ). 1398 1399:- meta_predicate 1400 '$ifcompiling'( ). 1401 1402'$ifcompiling'(G) :- 1403 ( '$compilation_mode'(database) 1404 -> true 1405 ; call(G) 1406 ). 1407 1408 /******************************** 1409 * READ SOURCE * 1410 *********************************/
1414'$load_msg_level'(Action, Nesting, Start, Done) :- 1415 '$update_autoload_level'([], 0), 1416 !, 1417 current_prolog_flag(verbose_load, Type0), 1418 '$load_msg_compat'(Type0, Type), 1419 ( '$load_msg_level'(Action, Nesting, Type, Start, Done) 1420 -> true 1421 ). 1422'$load_msg_level'(_, _, silent, silent). 1423 1424'$load_msg_compat'(true, normal) :- !. 1425'$load_msg_compat'(false, silent) :- !. 1426'$load_msg_compat'(X, X). 1427 1428'$load_msg_level'(load_file, _, full, informational, informational). 1429'$load_msg_level'(include_file, _, full, informational, informational). 1430'$load_msg_level'(load_file, _, normal, silent, informational). 1431'$load_msg_level'(include_file, _, normal, silent, silent). 1432'$load_msg_level'(load_file, 0, brief, silent, informational). 1433'$load_msg_level'(load_file, _, brief, silent, silent). 1434'$load_msg_level'(include_file, _, brief, silent, silent). 1435'$load_msg_level'(load_file, _, silent, silent, silent). 1436'$load_msg_level'(include_file, _, silent, silent, silent).
1459'$source_term'(From, Read, RLayout, Term, TLayout, Stream, Options) :- 1460 '$source_term'(From, Read, RLayout, Term, TLayout, Stream, [], Options), 1461 ( Term == end_of_file 1462 -> !, fail 1463 ; Term \== begin_of_file 1464 ). 1465 1466'$source_term'(Input, _,_,_,_,_,_,_) :- 1467 \+ ground(Input), 1468 !, 1469 '$instantiation_error'(Input). 1470'$source_term'(stream(Id, In, Opts), 1471 Read, RLayout, Term, TLayout, Stream, Parents, Options) :- 1472 !, 1473 '$record_included'(Parents, Id, Id, 0.0, Message), 1474 setup_call_cleanup( 1475 '$open_source'(stream(Id, In, Opts), In, State, Parents, Options), 1476 '$term_in_file'(In, Read, RLayout, Term, TLayout, Stream, 1477 [Id|Parents], Options), 1478 '$close_source'(State, Message)). 1479'$source_term'(File, 1480 Read, RLayout, Term, TLayout, Stream, Parents, Options) :- 1481 absolute_file_name(File, Path, 1482 [ file_type(prolog), 1483 access(read) 1484 ]), 1485 time_file(Path, Time), 1486 '$record_included'(Parents, File, Path, Time, Message), 1487 setup_call_cleanup( 1488 '$open_source'(Path, In, State, Parents, Options), 1489 '$term_in_file'(In, Read, RLayout, Term, TLayout, Stream, 1490 [Path|Parents], Options), 1491 '$close_source'(State, Message)). 1492 1493:- thread_local 1494 '$load_input'/2. 1495:- volatile 1496 '$load_input'/2. 1497 1498'$open_source'(stream(Id, In, Opts), In, 1499 restore(In, StreamState, Id, Ref, Opts), Parents, Options) :- 1500 !, 1501 '$context_type'(Parents, ContextType), 1502 '$push_input_context'(ContextType), 1503 '$set_encoding'(In, Options), 1504 '$prepare_load_stream'(In, Id, StreamState), 1505 asserta('$load_input'(stream(Id), In), Ref). 1506'$open_source'(Path, In, close(In, Path, Ref), Parents, Options) :- 1507 '$context_type'(Parents, ContextType), 1508 '$push_input_context'(ContextType), 1509 open(Path, read, In), 1510 '$set_encoding'(In, Options), 1511 asserta('$load_input'(Path, In), Ref). 1512 1513'$context_type'([], load_file) :- !. 1514'$context_type'(_, include). 1515 1516'$close_source'(close(In, Id, Ref), Message) :- 1517 erase(Ref), 1518 '$end_consult'(Id), 1519 call_cleanup( 1520 close(In), 1521 '$pop_input_context'), 1522 '$close_message'(Message). 1523'$close_source'(restore(In, StreamState, Id, Ref, Opts), Message) :- 1524 erase(Ref), 1525 '$end_consult'(Id), 1526 call_cleanup( 1527 '$restore_load_stream'(In, StreamState, Opts), 1528 '$pop_input_context'), 1529 '$close_message'(Message). 1530 1531'$close_message'(message(Level, Msg)) :- 1532 !, 1533 '$print_message'(Level, Msg). 1534'$close_message'(_).
1546'$term_in_file'(In, Read, RLayout, Term, TLayout, Stream, Parents, Options) :- 1547 Parents \= [_,_|_], 1548 ( '$load_input'(_, Input) 1549 -> stream_property(Input, file_name(File)) 1550 ), 1551 '$set_source_location'(File, 0), 1552 '$expanded_term'(In, 1553 begin_of_file, 0-0, Read, RLayout, Term, TLayout, 1554 Stream, Parents, Options). 1555'$term_in_file'(In, Read, RLayout, Term, TLayout, Stream, Parents, Options) :- 1556 '$skip_script_line'(In, Options), 1557 '$read_clause_options'(Options, ReadOptions), 1558 repeat, 1559 read_clause(In, Raw, 1560 [ variable_names(Bindings), 1561 term_position(Pos), 1562 subterm_positions(RawLayout) 1563 | ReadOptions 1564 ]), 1565 b_setval('$term_position', Pos), 1566 b_setval('$variable_names', Bindings), 1567 ( Raw == end_of_file 1568 -> !, 1569 ( Parents = [_,_|_] % Included file 1570 -> fail 1571 ; '$expanded_term'(In, 1572 Raw, RawLayout, Read, RLayout, Term, TLayout, 1573 Stream, Parents, Options) 1574 ) 1575 ; '$expanded_term'(In, Raw, RawLayout, Read, RLayout, Term, TLayout, 1576 Stream, Parents, Options) 1577 ). 1578 1579'$read_clause_options'([], []). 1580'$read_clause_options'([H|T0], List) :- 1581 ( '$read_clause_option'(H) 1582 -> List = [H|T] 1583 ; List = T 1584 ), 1585 '$read_clause_options'(T0, T). 1586 1587'$read_clause_option'(syntax_errors(_)). 1588'$read_clause_option'(term_position(_)). 1589'$read_clause_option'(process_comment(_)). 1590 1591'$expanded_term'(In, Raw, RawLayout, Read, RLayout, Term, TLayout, 1592 Stream, Parents, Options) :- 1593 E = error(_,_), 1594 catch('$expand_term'(Raw, RawLayout, Expanded, ExpandedLayout), E, 1595 '$print_message_fail'(E)), 1596 ( Expanded \== [] 1597 -> '$expansion_member'(Expanded, ExpandedLayout, Term1, Layout1) 1598 ; Term1 = Expanded, 1599 Layout1 = ExpandedLayout 1600 ), 1601 ( nonvar(Term1), Term1 = (:-Directive), nonvar(Directive) 1602 -> ( Directive = include(File), 1603 '$current_source_module'(Module), 1604 '$valid_directive'(Module:include(File)) 1605 -> stream_property(In, encoding(Enc)), 1606 '$add_encoding'(Enc, Options, Options1), 1607 '$source_term'(File, Read, RLayout, Term, TLayout, 1608 Stream, Parents, Options1) 1609 ; Directive = encoding(Enc) 1610 -> set_stream(In, encoding(Enc)), 1611 fail 1612 ; Term = Term1, 1613 Stream = In, 1614 Read = Raw 1615 ) 1616 ; Term = Term1, 1617 TLayout = Layout1, 1618 Stream = In, 1619 Read = Raw, 1620 RLayout = RawLayout 1621 ). 1622 1623'$expansion_member'(Var, Layout, Var, Layout) :- 1624 var(Var), 1625 !. 1626'$expansion_member'([], _, _, _) :- !, fail. 1627'$expansion_member'(List, ListLayout, Term, Layout) :- 1628 is_list(List), 1629 !, 1630 ( var(ListLayout) 1631 -> '$member'(Term, List) 1632 ; is_list(ListLayout) 1633 -> '$member_rep2'(Term, Layout, List, ListLayout) 1634 ; Layout = ListLayout, 1635 '$member'(Term, List) 1636 ). 1637'$expansion_member'(X, Layout, X, Layout). 1638 1639% pairwise member, repeating last element of the second 1640% list. 1641 1642'$member_rep2'(H1, H2, [H1|_], [H2|_]). 1643'$member_rep2'(H1, H2, [_|T1], [T2]) :- 1644 !, 1645 '$member_rep2'(H1, H2, T1, [T2]). 1646'$member_rep2'(H1, H2, [_|T1], [_|T2]) :- 1647 '$member_rep2'(H1, H2, T1, T2).
1651'$add_encoding'(Enc, Options0, Options) :- 1652 ( Options0 = [encoding(Enc)|_] 1653 -> Options = Options0 1654 ; Options = [encoding(Enc)|Options0] 1655 ). 1656 1657 1658:- multifile 1659 '$included'/4. % Into, Line, File, LastModified 1660:- dynamic 1661 '$included'/4.
I think that the only sensible solution is to have a special statement for this, that may appear both inside and outside QLF `parts'.
1675'$record_included'([Parent|Parents], File, Path, Time, 1676 message(DoneMsgLevel, 1677 include_file(done(Level, file(File, Path))))) :- 1678 source_location(SrcFile, Line), 1679 !, 1680 '$compilation_level'(Level), 1681 '$load_msg_level'(include_file, Level, StartMsgLevel, DoneMsgLevel), 1682 '$print_message'(StartMsgLevel, 1683 include_file(start(Level, 1684 file(File, Path)))), 1685 '$last'([Parent|Parents], Owner), 1686 ( ( '$compilation_mode'(database) 1687 ; '$qlf_current_source'(Owner) 1688 ) 1689 -> '$store_admin_clause'( 1690 system:'$included'(Parent, Line, Path, Time), 1691 _, Owner, SrcFile:Line) 1692 ; '$qlf_include'(Owner, Parent, Line, Path, Time) 1693 ). 1694'$record_included'(_, _, _, _, true).
1700'$master_file'(File, MasterFile) :- 1701 '$included'(MasterFile0, _Line, File, _Time), 1702 !, 1703 '$master_file'(MasterFile0, MasterFile). 1704'$master_file'(File, File). 1705 1706 1707'$skip_script_line'(_In, Options) :- 1708 '$option'(check_script(false), Options), 1709 !. 1710'$skip_script_line'(In, _Options) :- 1711 ( peek_char(In, #) 1712 -> skip(In, 10) 1713 ; true 1714 ). 1715 1716'$set_encoding'(Stream, Options) :- 1717 '$option'(encoding(Enc), Options), 1718 !, 1719 Enc \== default, 1720 set_stream(Stream, encoding(Enc)). 1721'$set_encoding'(_, _). 1722 1723 1724'$prepare_load_stream'(In, Id, state(HasName,HasPos)) :- 1725 ( stream_property(In, file_name(_)) 1726 -> HasName = true, 1727 ( stream_property(In, position(_)) 1728 -> HasPos = true 1729 ; HasPos = false, 1730 set_stream(In, record_position(true)) 1731 ) 1732 ; HasName = false, 1733 set_stream(In, file_name(Id)), 1734 ( stream_property(In, position(_)) 1735 -> HasPos = true 1736 ; HasPos = false, 1737 set_stream(In, record_position(true)) 1738 ) 1739 ). 1740 1741'$restore_load_stream'(In, _State, Options) :- 1742 memberchk(close(true), Options), 1743 !, 1744 close(In). 1745'$restore_load_stream'(In, state(HasName, HasPos), _Options) :- 1746 ( HasName == false 1747 -> set_stream(In, file_name('')) 1748 ; true 1749 ), 1750 ( HasPos == false 1751 -> set_stream(In, record_position(false)) 1752 ; true 1753 ). 1754 1755 1756 /******************************* 1757 * DERIVED FILES * 1758 *******************************/ 1759 1760:- dynamic 1761 '$derived_source_db'/3. % Loaded, DerivedFrom, Time 1762 1763'$register_derived_source'(_, '-') :- !. 1764'$register_derived_source'(Loaded, DerivedFrom) :- 1765 retractall('$derived_source_db'(Loaded, _, _)), 1766 time_file(DerivedFrom, Time), 1767 assert('$derived_source_db'(Loaded, DerivedFrom, Time)). 1768 1769% Auto-importing dynamic predicates is not very elegant and 1770% leads to problems with qsave_program/[1,2] 1771 1772'$derived_source'(Loaded, DerivedFrom, Time) :- 1773 '$derived_source_db'(Loaded, DerivedFrom, Time). 1774 1775 1776 /******************************** 1777 * LOAD PREDICATES * 1778 *********************************/ 1779 1780:- meta_predicate 1781 ensure_loaded( ), 1782 [, | ] 1783 consult( ), 1784 use_module( ), 1785 use_module( , ), 1786 reexport( ), 1787 reexport( , ), 1788 load_files( ), 1789 load_files( , ).
1797ensure_loaded(Files) :-
1798 load_files(Files, [if(not_loaded)]).
1807use_module(Files) :-
1808 load_files(Files, [ if(not_loaded),
1809 must_be_module(true)
1810 ]).
1817use_module(File, Import) :-
1818 load_files(File, [ if(not_loaded),
1819 must_be_module(true),
1820 imports(Import)
1821 ]).
1827reexport(Files) :-
1828 load_files(Files, [ if(not_loaded),
1829 must_be_module(true),
1830 reexport(true)
1831 ]).
1837reexport(File, Import) :- 1838 load_files(File, [ if(not_loaded), 1839 must_be_module(true), 1840 imports(Import), 1841 reexport(true) 1842 ]). 1843 1844 1845[X] :- 1846 !, 1847 consult(X). 1848[M:F|R] :- 1849 consult(M:[F|R]). 1850 1851consult(M:X) :- 1852 X == user, 1853 !, 1854 flag('$user_consult', N, N+1), 1855 NN is N + 1, 1856 atom_concat('user://', NN, Id), 1857 load_files(M:Id, [stream(user_input), check_script(false), silent(false)]). 1858consult(List) :- 1859 load_files(List, [expand(true)]).
1866load_files(Files) :- 1867 load_files(Files, []). 1868load_files(Module:Files, Options) :- 1869 '$must_be'(list, Options), 1870 '$load_files'(Files, Module, Options). 1871 1872'$load_files'(X, _, _) :- 1873 var(X), 1874 !, 1875 '$instantiation_error'(X). 1876'$load_files'([], _, _) :- !. 1877'$load_files'(Id, Module, Options) :- % load_files(foo, [stream(In)]) 1878 '$option'(stream(_), Options), 1879 !, 1880 ( atom(Id) 1881 -> '$load_file'(Id, Module, Options) 1882 ; throw(error(type_error(atom, Id), _)) 1883 ). 1884'$load_files'(List, Module, Options) :- 1885 List = [_|_], 1886 !, 1887 '$must_be'(list, List), 1888 '$load_file_list'(List, Module, Options). 1889'$load_files'(File, Module, Options) :- 1890 '$load_one_file'(File, Module, Options). 1891 1892'$load_file_list'([], _, _). 1893'$load_file_list'([File|Rest], Module, Options) :- 1894 E = error(_,_), 1895 catch('$load_one_file'(File, Module, Options), E, 1896 '$print_message'(error, E)), 1897 '$load_file_list'(Rest, Module, Options). 1898 1899 1900'$load_one_file'(Spec, Module, Options) :- 1901 atomic(Spec), 1902 '$option'(expand(Expand), Options, false), 1903 Expand == true, 1904 !, 1905 expand_file_name(Spec, Expanded), 1906 ( Expanded = [Load] 1907 -> true 1908 ; Load = Expanded 1909 ), 1910 '$load_files'(Load, Module, [expand(false)|Options]). 1911'$load_one_file'(File, Module, Options) :- 1912 strip_module(Module:File, Into, PlainFile), 1913 '$load_file'(PlainFile, Into, Options).
1920'$noload'(true, _, _) :- 1921 !, 1922 fail. 1923'$noload'(not_loaded, FullFile, _) :- 1924 source_file(FullFile), 1925 !. 1926'$noload'(changed, Derived, _) :- 1927 '$derived_source'(_FullFile, Derived, LoadTime), 1928 time_file(Derived, Modified), 1929 Modified @=< LoadTime, 1930 !. 1931'$noload'(changed, FullFile, Options) :- 1932 '$time_source_file'(FullFile, LoadTime, user), 1933 '$modified_id'(FullFile, Modified, Options), 1934 Modified @=< LoadTime, 1935 !.
1954'$qlf_file'(Spec, _, Spec, stream, Options) :- 1955 '$option'(stream(_), Options), % stream: no choice 1956 !. 1957'$qlf_file'(Spec, FullFile, FullFile, compile, _) :- 1958 '$spec_extension'(Spec, Ext), % user explicitly specified 1959 user:prolog_file_type(Ext, prolog), 1960 !. 1961'$qlf_file'(Spec, FullFile, LoadFile, Mode, Options) :- 1962 '$compilation_mode'(database), 1963 file_name_extension(Base, PlExt, FullFile), 1964 user:prolog_file_type(PlExt, prolog), 1965 user:prolog_file_type(QlfExt, qlf), 1966 file_name_extension(Base, QlfExt, QlfFile), 1967 ( access_file(QlfFile, read), 1968 ( '$qlf_out_of_date'(FullFile, QlfFile, Why) 1969 -> ( access_file(QlfFile, write) 1970 -> print_message(informational, 1971 qlf(recompile(Spec, FullFile, QlfFile, Why))), 1972 Mode = qcompile 1973 ; print_message(warning, 1974 qlf(can_not_recompile(Spec, QlfFile, Why))), 1975 Mode = compile 1976 ), 1977 LoadFile = FullFile 1978 ; Mode = qload, 1979 LoadFile = QlfFile 1980 ) 1981 -> ! 1982 ; '$qlf_auto'(FullFile, QlfFile, Options) 1983 -> !, Mode = qcompile, 1984 LoadFile = FullFile 1985 ). 1986'$qlf_file'(_, FullFile, FullFile, compile, _).
1994'$qlf_out_of_date'(PlFile, QlfFile, Why) :-
1995 ( access_file(PlFile, read)
1996 -> time_file(PlFile, PlTime),
1997 time_file(QlfFile, QlfTime),
1998 ( PlTime > QlfTime
1999 -> Why = old % PlFile is newer
2000 ; Error = error(Formal,_),
2001 catch('$qlf_sources'(QlfFile, _Files), Error, true),
2002 nonvar(Formal) % QlfFile is incompatible
2003 -> Why = Error
2004 ; fail % QlfFile is up-to-date and ok
2005 )
2006 ; fail % can not read .pl; try .qlf
2007 ).
qcompile(QlfMode)
or, if this is not present, by
the prolog_flag qcompile.2015:- create_prolog_flag(qcompile, false, [type(atom)]). 2016 2017'$qlf_auto'(PlFile, QlfFile, Options) :- 2018 ( memberchk(qcompile(QlfMode), Options) 2019 -> true 2020 ; current_prolog_flag(qcompile, QlfMode), 2021 \+ '$in_system_dir'(PlFile) 2022 ), 2023 ( QlfMode == auto 2024 -> true 2025 ; QlfMode == large, 2026 size_file(PlFile, Size), 2027 Size > 100000 2028 ), 2029 access_file(QlfFile, write). 2030 2031'$in_system_dir'(PlFile) :- 2032 current_prolog_flag(home, Home), 2033 sub_atom(PlFile, 0, _, _, Home). 2034 2035'$spec_extension'(File, Ext) :- 2036 atom(File), 2037 file_name_extension(_, Ext, File). 2038'$spec_extension'(Spec, Ext) :- 2039 compound(Spec), 2040 arg(1, Spec, Arg), 2041 '$spec_extension'(Arg, Ext).
2053:- dynamic 2054 '$resolved_source_path'/2. % ?Spec, ?Path 2055 2056'$load_file'(File, Module, Options) :- 2057 \+ memberchk(stream(_), Options), 2058 user:prolog_load_file(Module:File, Options), 2059 !. 2060'$load_file'(File, Module, Options) :- 2061 memberchk(stream(_), Options), 2062 !, 2063 '$assert_load_context_module'(File, Module, Options), 2064 '$qdo_load_file'(File, File, Module, Action, Options), 2065 '$run_initialization'(File, Action, Options). 2066'$load_file'(File, Module, Options) :- 2067 '$resolved_source_path'(File, FullFile), 2068 ( '$source_file_property'(FullFile, from_state, true) 2069 ; '$source_file_property'(FullFile, resource, true) 2070 ; '$option'(if(If), Options, true), 2071 '$noload'(If, FullFile, Options) 2072 ), 2073 !, 2074 '$already_loaded'(File, FullFile, Module, Options). 2075'$load_file'(File, Module, Options) :- 2076 absolute_file_name(File, FullFile, 2077 [ file_type(prolog), 2078 access(read) 2079 ]), 2080 '$register_resolved_source_path'(File, FullFile), 2081 '$mt_load_file'(File, FullFile, Module, Options), 2082 '$register_resource_file'(FullFile). 2083 2084'$register_resolved_source_path'(File, FullFile) :- 2085 '$resolved_source_path'(File, FullFile), 2086 !. 2087'$register_resolved_source_path'(File, FullFile) :- 2088 compound(File), 2089 !, 2090 asserta('$resolved_source_path'(File, FullFile)). 2091'$register_resolved_source_path'(_, _).
2097:- public '$translated_source'/2. 2098'$translated_source'(Old, New) :- 2099 forall(retract('$resolved_source_path'(File, Old)), 2100 assertz('$resolved_source_path'(File, New))).
2107'$register_resource_file'(FullFile) :-
2108 ( sub_atom(FullFile, 0, _, _, 'res://')
2109 -> '$set_source_file'(FullFile, resource, true)
2110 ; true
2111 ).
2124'$already_loaded'(_File, FullFile, Module, Options) :- 2125 '$assert_load_context_module'(FullFile, Module, Options), 2126 '$current_module'(LoadModules, FullFile), 2127 !, 2128 ( atom(LoadModules) 2129 -> LoadModule = LoadModules 2130 ; LoadModules = [LoadModule|_] 2131 ), 2132 '$import_from_loaded_module'(LoadModule, Module, Options). 2133'$already_loaded'(_, _, user, _) :- !. 2134'$already_loaded'(File, _, Module, Options) :- 2135 '$load_file'(File, Module, [if(true)|Options]).
Synchronisation is handled using a message queue that exists while the file is being loaded. This synchronisation relies on the fact that thread_get_message/1 throws an existence_error if the message queue is destroyed. This is hacky. Events or condition variables would have made a cleaner design.
2150:- dynamic 2151 '$loading_file'/3. % File, Queue, Thread 2152:- volatile 2153 '$loading_file'/3. 2154 2155'$mt_load_file'(File, FullFile, Module, Options) :- 2156 current_prolog_flag(threads, true), 2157 !, 2158 setup_call_cleanup( 2159 with_mutex('$load_file', 2160 '$mt_start_load'(FullFile, Loading, Options)), 2161 '$mt_do_load'(Loading, File, FullFile, Module, Options), 2162 '$mt_end_load'(Loading)). 2163'$mt_load_file'(File, FullFile, Module, Options) :- 2164 '$option'(if(If), Options, true), 2165 '$noload'(If, FullFile, Options), 2166 !, 2167 '$already_loaded'(File, FullFile, Module, Options). 2168'$mt_load_file'(File, FullFile, Module, Options) :- 2169 '$qdo_load_file'(File, FullFile, Module, Action, Options), 2170 '$run_initialization'(FullFile, Action, Options). 2171 2172'$mt_start_load'(FullFile, queue(Queue), _) :- 2173 '$loading_file'(FullFile, Queue, LoadThread), 2174 \+ thread_self(LoadThread), 2175 !. 2176'$mt_start_load'(FullFile, already_loaded, Options) :- 2177 '$option'(if(If), Options, true), 2178 '$noload'(If, FullFile, Options), 2179 !. 2180'$mt_start_load'(FullFile, Ref, _) :- 2181 thread_self(Me), 2182 message_queue_create(Queue), 2183 assertz('$loading_file'(FullFile, Queue, Me), Ref). 2184 2185'$mt_do_load'(queue(Queue), File, FullFile, Module, Options) :- 2186 !, 2187 catch(thread_get_message(Queue, _), error(_,_), true), 2188 '$already_loaded'(File, FullFile, Module, Options). 2189'$mt_do_load'(already_loaded, File, FullFile, Module, Options) :- 2190 !, 2191 '$already_loaded'(File, FullFile, Module, Options). 2192'$mt_do_load'(_Ref, File, FullFile, Module, Options) :- 2193 '$assert_load_context_module'(FullFile, Module, Options), 2194 '$qdo_load_file'(File, FullFile, Module, Action, Options), 2195 '$run_initialization'(FullFile, Action, Options). 2196 2197'$mt_end_load'(queue(_)) :- !. 2198'$mt_end_load'(already_loaded) :- !. 2199'$mt_end_load'(Ref) :- 2200 clause('$loading_file'(_, Queue, _), _, Ref), 2201 erase(Ref), 2202 thread_send_message(Queue, done), 2203 message_queue_destroy(Queue).
2210'$qdo_load_file'(File, FullFile, Module, Action, Options) :- 2211 memberchk('$qlf'(QlfOut), Options), 2212 '$stage_file'(QlfOut, StageQlf), 2213 !, 2214 setup_call_catcher_cleanup( 2215 '$qstart'(StageQlf, Module, State), 2216 '$do_load_file'(File, FullFile, Module, Action, Options), 2217 Catcher, 2218 '$qend'(State, Catcher, StageQlf, QlfOut)). 2219'$qdo_load_file'(File, FullFile, Module, Action, Options) :- 2220 '$do_load_file'(File, FullFile, Module, Action, Options). 2221 2222'$qstart'(Qlf, Module, state(OldMode, OldModule)) :- 2223 '$qlf_open'(Qlf), 2224 '$compilation_mode'(OldMode, qlf), 2225 '$set_source_module'(OldModule, Module). 2226 2227'$qend'(state(OldMode, OldModule), Catcher, StageQlf, QlfOut) :- 2228 '$set_source_module'(_, OldModule), 2229 '$set_compilation_mode'(OldMode), 2230 '$qlf_close', 2231 '$install_staged_file'(Catcher, StageQlf, QlfOut, warn). 2232 2233'$set_source_module'(OldModule, Module) :- 2234 '$current_source_module'(OldModule), 2235 '$set_source_module'(Module).
2242'$do_load_file'(File, FullFile, Module, Action, Options) :- 2243 '$option'(derived_from(DerivedFrom), Options, -), 2244 '$register_derived_source'(FullFile, DerivedFrom), 2245 '$qlf_file'(File, FullFile, Absolute, Mode, Options), 2246 ( Mode == qcompile 2247 -> qcompile(Module:File, Options) 2248 ; '$do_load_file_2'(File, Absolute, Module, Action, Options) 2249 ). 2250 2251'$do_load_file_2'(File, Absolute, Module, Action, Options) :- 2252 '$source_file_property'(Absolute, number_of_clauses, OldClauses), 2253 statistics(cputime, OldTime), 2254 2255 '$setup_load'(ScopedFlags, OldSandBoxed, OldVerbose, OldAutoLevel, OldXRef, 2256 Options), 2257 2258 '$compilation_level'(Level), 2259 '$load_msg_level'(load_file, Level, StartMsgLevel, DoneMsgLevel), 2260 '$print_message'(StartMsgLevel, 2261 load_file(start(Level, 2262 file(File, Absolute)))), 2263 2264 ( memberchk(stream(FromStream), Options) 2265 -> Input = stream 2266 ; Input = source 2267 ), 2268 2269 ( Input == stream, 2270 ( '$option'(format(qlf), Options, source) 2271 -> set_stream(FromStream, file_name(Absolute)), 2272 '$qload_stream'(FromStream, Module, Action, LM, Options) 2273 ; '$consult_file'(stream(Absolute, FromStream, []), 2274 Module, Action, LM, Options) 2275 ) 2276 -> true 2277 ; Input == source, 2278 file_name_extension(_, Ext, Absolute), 2279 ( user:prolog_file_type(Ext, qlf), 2280 E = error(_,_), 2281 catch('$qload_file'(Absolute, Module, Action, LM, Options), 2282 E, 2283 print_message(warning, E)) 2284 -> true 2285 ; '$consult_file'(Absolute, Module, Action, LM, Options) 2286 ) 2287 -> true 2288 ; '$print_message'(error, load_file(failed(File))), 2289 fail 2290 ), 2291 2292 '$import_from_loaded_module'(LM, Module, Options), 2293 2294 '$source_file_property'(Absolute, number_of_clauses, NewClauses), 2295 statistics(cputime, Time), 2296 ClausesCreated is NewClauses - OldClauses, 2297 TimeUsed is Time - OldTime, 2298 2299 '$print_message'(DoneMsgLevel, 2300 load_file(done(Level, 2301 file(File, Absolute), 2302 Action, 2303 LM, 2304 TimeUsed, 2305 ClausesCreated))), 2306 2307 '$restore_load'(ScopedFlags, OldSandBoxed, OldVerbose, OldAutoLevel, OldXRef). 2308 2309'$setup_load'(ScopedFlags, OldSandBoxed, OldVerbose, OldAutoLevel, OldXRef, 2310 Options) :- 2311 '$save_file_scoped_flags'(ScopedFlags), 2312 '$set_sandboxed_load'(Options, OldSandBoxed), 2313 '$set_verbose_load'(Options, OldVerbose), 2314 '$set_optimise_load'(Options), 2315 '$update_autoload_level'(Options, OldAutoLevel), 2316 '$set_no_xref'(OldXRef). 2317 2318'$restore_load'(ScopedFlags, OldSandBoxed, OldVerbose, OldAutoLevel, OldXRef) :- 2319 '$set_autoload_level'(OldAutoLevel), 2320 set_prolog_flag(xref, OldXRef), 2321 set_prolog_flag(verbose_load, OldVerbose), 2322 set_prolog_flag(sandboxed_load, OldSandBoxed), 2323 '$restore_file_scoped_flags'(ScopedFlags).
2331'$save_file_scoped_flags'(State) :- 2332 current_predicate(findall/3), % Not when doing boot compile 2333 !, 2334 findall(SavedFlag, '$save_file_scoped_flag'(SavedFlag), State). 2335'$save_file_scoped_flags'([]). 2336 2337'$save_file_scoped_flag'(Flag-Value) :- 2338 '$file_scoped_flag'(Flag, Default), 2339 ( current_prolog_flag(Flag, Value) 2340 -> true 2341 ; Value = Default 2342 ). 2343 2344'$file_scoped_flag'(generate_debug_info, true). 2345'$file_scoped_flag'(optimise, false). 2346'$file_scoped_flag'(xref, false). 2347 2348'$restore_file_scoped_flags'([]). 2349'$restore_file_scoped_flags'([Flag-Value|T]) :- 2350 set_prolog_flag(Flag, Value), 2351 '$restore_file_scoped_flags'(T).
2358'$import_from_loaded_module'(LoadedModule, Module, Options) :- 2359 LoadedModule \== Module, 2360 atom(LoadedModule), 2361 !, 2362 '$option'(imports(Import), Options, all), 2363 '$option'(reexport(Reexport), Options, false), 2364 '$import_list'(Module, LoadedModule, Import, Reexport). 2365'$import_from_loaded_module'(_, _, _).
verbose_load
flag according to Options and unify Old
with the old value.2373'$set_verbose_load'(Options, Old) :- 2374 current_prolog_flag(verbose_load, Old), 2375 ( memberchk(silent(Silent), Options) 2376 -> ( '$negate'(Silent, Level0) 2377 -> '$load_msg_compat'(Level0, Level) 2378 ; Level = Silent 2379 ), 2380 set_prolog_flag(verbose_load, Level) 2381 ; true 2382 ). 2383 2384'$negate'(true, false). 2385'$negate'(false, true).
sandboxed_load
from Options. Old is
unified with the old flag.
2394'$set_sandboxed_load'(Options, Old) :- 2395 current_prolog_flag(sandboxed_load, Old), 2396 ( memberchk(sandboxed(SandBoxed), Options), 2397 '$enter_sandboxed'(Old, SandBoxed, New), 2398 New \== Old 2399 -> set_prolog_flag(sandboxed_load, New) 2400 ; true 2401 ). 2402 2403'$enter_sandboxed'(Old, New, SandBoxed) :- 2404 ( Old == false, New == true 2405 -> SandBoxed = true, 2406 '$ensure_loaded_library_sandbox' 2407 ; Old == true, New == false 2408 -> throw(error(permission_error(leave, sandbox, -), _)) 2409 ; SandBoxed = Old 2410 ). 2411'$enter_sandboxed'(false, true, true). 2412 2413'$ensure_loaded_library_sandbox' :- 2414 source_file_property(library(sandbox), module(sandbox)), 2415 !. 2416'$ensure_loaded_library_sandbox' :- 2417 load_files(library(sandbox), [if(not_loaded), silent(true)]). 2418 2419'$set_optimise_load'(Options) :- 2420 ( '$option'(optimise(Optimise), Options) 2421 -> set_prolog_flag(optimise, Optimise) 2422 ; true 2423 ). 2424 2425'$set_no_xref'(OldXRef) :- 2426 ( current_prolog_flag(xref, OldXRef) 2427 -> true 2428 ; OldXRef = false 2429 ), 2430 set_prolog_flag(xref, false).
2437:- thread_local 2438 '$autoload_nesting'/1. 2439 2440'$update_autoload_level'(Options, AutoLevel) :- 2441 '$option'(autoload(Autoload), Options, false), 2442 ( '$autoload_nesting'(CurrentLevel) 2443 -> AutoLevel = CurrentLevel 2444 ; AutoLevel = 0 2445 ), 2446 ( Autoload == false 2447 -> true 2448 ; NewLevel is AutoLevel + 1, 2449 '$set_autoload_level'(NewLevel) 2450 ). 2451 2452'$set_autoload_level'(New) :- 2453 retractall('$autoload_nesting'(_)), 2454 asserta('$autoload_nesting'(New)).
2462'$print_message'(Level, Term) :- 2463 current_predicate(system:print_message/2), 2464 !, 2465 print_message(Level, Term). 2466'$print_message'(warning, Term) :- 2467 source_location(File, Line), 2468 !, 2469 format(user_error, 'WARNING: ~w:~w: ~p~n', [File, Line, Term]). 2470'$print_message'(error, Term) :- 2471 !, 2472 source_location(File, Line), 2473 !, 2474 format(user_error, 'ERROR: ~w:~w: ~p~n', [File, Line, Term]). 2475'$print_message'(_Level, _Term). 2476 2477'$print_message_fail'(E) :- 2478 '$print_message'(error, E), 2479 fail.
2487'$consult_file'(Absolute, Module, What, LM, Options) :- 2488 '$current_source_module'(Module), % same module 2489 !, 2490 '$consult_file_2'(Absolute, Module, What, LM, Options). 2491'$consult_file'(Absolute, Module, What, LM, Options) :- 2492 '$set_source_module'(OldModule, Module), 2493 '$ifcompiling'('$qlf_start_sub_module'(Module)), 2494 '$consult_file_2'(Absolute, Module, What, LM, Options), 2495 '$ifcompiling'('$qlf_end_part'), 2496 '$set_source_module'(OldModule). 2497 2498'$consult_file_2'(Absolute, Module, What, LM, Options) :- 2499 '$set_source_module'(OldModule, Module), 2500 '$load_id'(Absolute, Id, Modified, Options), 2501 '$start_consult'(Id, Modified), 2502 ( '$derived_source'(Absolute, DerivedFrom, _) 2503 -> '$modified_id'(DerivedFrom, DerivedModified, Options), 2504 '$start_consult'(DerivedFrom, DerivedModified) 2505 ; true 2506 ), 2507 '$compile_type'(What), 2508 '$save_lex_state'(LexState, Options), 2509 '$set_dialect'(Options), 2510 call_cleanup('$load_file'(Absolute, Id, LM, Options), 2511 '$end_consult'(LexState, OldModule)). 2512 2513'$end_consult'(LexState, OldModule) :- 2514 '$restore_lex_state'(LexState), 2515 '$set_source_module'(OldModule). 2516 2517 2518:- create_prolog_flag(emulated_dialect, swi, [type(atom)]).
2522'$save_lex_state'(State, Options) :- 2523 memberchk(scope_settings(false), Options), 2524 !, 2525 State = (-). 2526'$save_lex_state'(lexstate(Style, Dialect), _) :- 2527 '$style_check'(Style, Style), 2528 current_prolog_flag(emulated_dialect, Dialect). 2529 2530'$restore_lex_state'(-) :- !. 2531'$restore_lex_state'(lexstate(Style, Dialect)) :- 2532 '$style_check'(_, Style), 2533 set_prolog_flag(emulated_dialect, Dialect). 2534 2535'$set_dialect'(Options) :- 2536 memberchk(dialect(Dialect), Options), 2537 !, 2538 expects_dialect(Dialect). % Autoloaded from library 2539'$set_dialect'(_). 2540 2541'$load_id'(stream(Id, _, _), Id, Modified, Options) :- 2542 !, 2543 '$modified_id'(Id, Modified, Options). 2544'$load_id'(Id, Id, Modified, Options) :- 2545 '$modified_id'(Id, Modified, Options). 2546 2547'$modified_id'(_, Modified, Options) :- 2548 '$option'(modified(Stamp), Options, Def), 2549 Stamp \== Def, 2550 !, 2551 Modified = Stamp. 2552'$modified_id'(Id, Modified, _) :- 2553 catch(time_file(Id, Modified), 2554 error(_, _), 2555 fail), 2556 !. 2557'$modified_id'(_, 0.0, _). 2558 2559 2560'$compile_type'(What) :- 2561 '$compilation_mode'(How), 2562 ( How == database 2563 -> What = compiled 2564 ; How == qlf 2565 -> What = '*qcompiled*' 2566 ; What = 'boot compiled' 2567 ).
2577:- dynamic 2578 '$load_context_module'/3. 2579:- multifile 2580 '$load_context_module'/3. 2581 2582'$assert_load_context_module'(_, _, Options) :- 2583 memberchk(register(false), Options), 2584 !. 2585'$assert_load_context_module'(File, Module, Options) :- 2586 source_location(FromFile, Line), 2587 !, 2588 '$master_file'(FromFile, MasterFile), 2589 '$check_load_non_module'(File, Module), 2590 '$add_dialect'(Options, Options1), 2591 '$load_ctx_options'(Options1, Options2), 2592 '$store_admin_clause'( 2593 system:'$load_context_module'(File, Module, Options2), 2594 _Layout, MasterFile, FromFile:Line). 2595'$assert_load_context_module'(File, Module, Options) :- 2596 '$check_load_non_module'(File, Module), 2597 '$add_dialect'(Options, Options1), 2598 '$load_ctx_options'(Options1, Options2), 2599 ( clause('$load_context_module'(File, Module, _), true, Ref), 2600 \+ clause_property(Ref, file(_)), 2601 erase(Ref) 2602 -> true 2603 ; true 2604 ), 2605 assertz('$load_context_module'(File, Module, Options2)). 2606 2607'$add_dialect'(Options0, Options) :- 2608 current_prolog_flag(emulated_dialect, Dialect), Dialect \== swi, 2609 !, 2610 Options = [dialect(Dialect)|Options0]. 2611'$add_dialect'(Options, Options).
2618'$load_ctx_options'([], []). 2619'$load_ctx_options'([H|T0], [H|T]) :- 2620 '$load_ctx_option'(H), 2621 !, 2622 '$load_ctx_options'(T0, T). 2623'$load_ctx_options'([_|T0], T) :- 2624 '$load_ctx_options'(T0, T). 2625 2626'$load_ctx_option'(derived_from(_)). 2627'$load_ctx_option'(dialect(_)). 2628'$load_ctx_option'(encoding(_)). 2629'$load_ctx_option'(imports(_)). 2630'$load_ctx_option'(reexport(_)).
2638'$check_load_non_module'(File, _) :- 2639 '$current_module'(_, File), 2640 !. % File is a module file 2641'$check_load_non_module'(File, Module) :- 2642 '$load_context_module'(File, OldModule, _), 2643 Module \== OldModule, 2644 !, 2645 format(atom(Msg), 2646 'Non-module file already loaded into module ~w; \c 2647 trying to load into ~w', 2648 [OldModule, Module]), 2649 throw(error(permission_error(load, source, File), 2650 context(load_files/2, Msg))). 2651'$check_load_non_module'(_, _).
state(FirstTerm:boolean,
Module:atom,
AtEnd:atom,
Stop:boolean,
Id:atom,
Dialect:atom)
2664'$load_file'(Path, Id, Module, Options) :- 2665 State = state(true, _, true, false, Id, -), 2666 ( '$source_term'(Path, _Read, _Layout, Term, Layout, 2667 _Stream, Options), 2668 '$valid_term'(Term), 2669 ( arg(1, State, true) 2670 -> '$first_term'(Term, Layout, Id, State, Options), 2671 nb_setarg(1, State, false) 2672 ; '$compile_term'(Term, Layout, Id) 2673 ), 2674 arg(4, State, true) 2675 ; '$end_load_file'(State) 2676 ), 2677 !, 2678 arg(2, State, Module). 2679 2680'$valid_term'(Var) :- 2681 var(Var), 2682 !, 2683 print_message(error, error(instantiation_error, _)). 2684'$valid_term'(Term) :- 2685 Term \== []. 2686 2687'$end_load_file'(State) :- 2688 arg(1, State, true), % empty file 2689 !, 2690 nb_setarg(2, State, Module), 2691 arg(5, State, Id), 2692 '$current_source_module'(Module), 2693 '$ifcompiling'('$qlf_start_file'(Id)), 2694 '$ifcompiling'('$qlf_end_part'). 2695'$end_load_file'(State) :- 2696 arg(3, State, End), 2697 '$end_load_file'(End, State). 2698 2699'$end_load_file'(true, _). 2700'$end_load_file'(end_module, State) :- 2701 arg(2, State, Module), 2702 '$check_export'(Module), 2703 '$ifcompiling'('$qlf_end_part'). 2704'$end_load_file'(end_non_module, _State) :- 2705 '$ifcompiling'('$qlf_end_part'). 2706 2707 2708'$first_term'(?-(Directive), Layout, Id, State, Options) :- 2709 !, 2710 '$first_term'(:-(Directive), Layout, Id, State, Options). 2711'$first_term'(:-(Directive), _Layout, Id, State, Options) :- 2712 nonvar(Directive), 2713 ( ( Directive = module(Name, Public) 2714 -> Imports = [] 2715 ; Directive = module(Name, Public, Imports) 2716 ) 2717 -> !, 2718 '$module_name'(Name, Id, Module, Options), 2719 '$start_module'(Module, Public, State, Options), 2720 '$module3'(Imports) 2721 ; Directive = expects_dialect(Dialect) 2722 -> !, 2723 '$set_dialect'(Dialect, State), 2724 fail % Still consider next term as first 2725 ). 2726'$first_term'(Term, Layout, Id, State, Options) :- 2727 '$start_non_module'(Id, State, Options), 2728 '$compile_term'(Term, Layout, Id). 2729 2730'$compile_term'(Term, Layout, Id) :- 2731 '$compile_term'(Term, Layout, Id, -). 2732 2733'$compile_term'(Var, _Layout, _Id, _Src) :- 2734 var(Var), 2735 !, 2736 '$instantiation_error'(Var). 2737'$compile_term'((?-Directive), _Layout, Id, _) :- 2738 !, 2739 '$execute_directive'(Directive, Id). 2740'$compile_term'((:-Directive), _Layout, Id, _) :- 2741 !, 2742 '$execute_directive'(Directive, Id). 2743'$compile_term'('$source_location'(File, Line):Term, Layout, Id, _) :- 2744 !, 2745 '$compile_term'(Term, Layout, Id, File:Line). 2746'$compile_term'(Clause, Layout, Id, SrcLoc) :- 2747 E = error(_,_), 2748 catch('$store_clause'(Clause, Layout, Id, SrcLoc), E, 2749 '$print_message'(error, E)). 2750 2751'$start_non_module'(Id, _State, Options) :- 2752 '$option'(must_be_module(true), Options, false), 2753 !, 2754 throw(error(domain_error(module_file, Id), _)). 2755'$start_non_module'(Id, State, _Options) :- 2756 '$current_source_module'(Module), 2757 '$ifcompiling'('$qlf_start_file'(Id)), 2758 '$qset_dialect'(State), 2759 nb_setarg(2, State, Module), 2760 nb_setarg(3, State, end_non_module).
Note that expects_dialect/1 itself may be autoloaded from the library.
2773'$set_dialect'(Dialect, State) :- 2774 '$compilation_mode'(qlf, database), 2775 !, 2776 expects_dialect(Dialect), 2777 '$compilation_mode'(_, qlf), 2778 nb_setarg(6, State, Dialect). 2779'$set_dialect'(Dialect, _) :- 2780 expects_dialect(Dialect). 2781 2782'$qset_dialect'(State) :- 2783 '$compilation_mode'(qlf), 2784 arg(6, State, Dialect), Dialect \== (-), 2785 !, 2786 '$add_directive_wic'(expects_dialect(Dialect)). 2787'$qset_dialect'(_). 2788 2789 2790 /******************************* 2791 * MODULES * 2792 *******************************/ 2793 2794'$start_module'(Module, _Public, State, _Options) :- 2795 '$current_module'(Module, OldFile), 2796 source_location(File, _Line), 2797 OldFile \== File, OldFile \== [], 2798 same_file(OldFile, File), 2799 !, 2800 nb_setarg(2, State, Module), 2801 nb_setarg(4, State, true). % Stop processing 2802'$start_module'(Module, Public, State, Options) :- 2803 arg(5, State, File), 2804 nb_setarg(2, State, Module), 2805 source_location(_File, Line), 2806 '$option'(redefine_module(Action), Options, false), 2807 '$module_class'(File, Class, Super), 2808 '$redefine_module'(Module, File, Action), 2809 '$declare_module'(Module, Class, Super, File, Line, false), 2810 '$export_list'(Public, Module, Ops), 2811 '$ifcompiling'('$qlf_start_module'(Module)), 2812 '$export_ops'(Ops, Module, File), 2813 '$qset_dialect'(State), 2814 nb_setarg(3, State, end_module).
2821'$module3'(Var) :- 2822 var(Var), 2823 !, 2824 '$instantiation_error'(Var). 2825'$module3'([]) :- !. 2826'$module3'([H|T]) :- 2827 !, 2828 '$module3'(H), 2829 '$module3'(T). 2830'$module3'(Id) :- 2831 use_module(library(dialect/Id)).
module(Module)
is given. In that case, use this
module and if Module is the load context, ignore the module
header.2845'$module_name'(_, _, Module, Options) :- 2846 '$option'(module(Module), Options), 2847 !, 2848 '$current_source_module'(Context), 2849 Context \== Module. % cause '$first_term'/5 to fail. 2850'$module_name'(Var, Id, Module, Options) :- 2851 var(Var), 2852 !, 2853 file_base_name(Id, File), 2854 file_name_extension(Var, _, File), 2855 '$module_name'(Var, Id, Module, Options). 2856'$module_name'(Reserved, _, _, _) :- 2857 '$reserved_module'(Reserved), 2858 !, 2859 throw(error(permission_error(load, module, Reserved), _)). 2860'$module_name'(Module, _Id, Module, _). 2861 2862 2863'$reserved_module'(system). 2864'$reserved_module'(user).
2869'$redefine_module'(_Module, _, false) :- !. 2870'$redefine_module'(Module, File, true) :- 2871 !, 2872 ( module_property(Module, file(OldFile)), 2873 File \== OldFile 2874 -> unload_file(OldFile) 2875 ; true 2876 ). 2877'$redefine_module'(Module, File, ask) :- 2878 ( stream_property(user_input, tty(true)), 2879 module_property(Module, file(OldFile)), 2880 File \== OldFile, 2881 '$rdef_response'(Module, OldFile, File, true) 2882 -> '$redefine_module'(Module, File, true) 2883 ; true 2884 ). 2885 2886'$rdef_response'(Module, OldFile, File, Ok) :- 2887 repeat, 2888 print_message(query, redefine_module(Module, OldFile, File)), 2889 get_single_char(Char), 2890 '$rdef_response'(Char, Ok0), 2891 !, 2892 Ok = Ok0. 2893 2894'$rdef_response'(Char, true) :- 2895 memberchk(Char, `yY`), 2896 format(user_error, 'yes~n', []). 2897'$rdef_response'(Char, false) :- 2898 memberchk(Char, `nN`), 2899 format(user_error, 'no~n', []). 2900'$rdef_response'(Char, _) :- 2901 memberchk(Char, `a`), 2902 format(user_error, 'abort~n', []), 2903 abort. 2904'$rdef_response'(_, _) :- 2905 print_message(help, redefine_module_reply), 2906 fail.
system
, while all normal user
modules inherit from user
.2915'$module_class'(File, Class, system) :- 2916 current_prolog_flag(home, Home), 2917 sub_atom(File, 0, Len, _, Home), 2918 !, 2919 ( sub_atom(File, Len, _, _, '/boot/') 2920 -> Class = system 2921 ; Class = library 2922 ). 2923'$module_class'(_, user, user). 2924 2925'$check_export'(Module) :- 2926 '$undefined_export'(Module, UndefList), 2927 ( '$member'(Undef, UndefList), 2928 strip_module(Undef, _, Local), 2929 print_message(error, 2930 undefined_export(Module, Local)), 2931 fail 2932 ; true 2933 ).
all
,
a list of optionally mapped predicate indicators or a term
except(Import)
.2942'$import_list'(_, _, Var, _) :- 2943 var(Var), 2944 !, 2945 throw(error(instantitation_error, _)). 2946'$import_list'(Target, Source, all, Reexport) :- 2947 !, 2948 '$exported_ops'(Source, Import, Predicates), 2949 '$module_property'(Source, exports(Predicates)), 2950 '$import_all'(Import, Target, Source, Reexport, weak). 2951'$import_list'(Target, Source, except(Spec), Reexport) :- 2952 !, 2953 '$exported_ops'(Source, Export, Predicates), 2954 '$module_property'(Source, exports(Predicates)), 2955 ( is_list(Spec) 2956 -> true 2957 ; throw(error(type_error(list, Spec), _)) 2958 ), 2959 '$import_except'(Spec, Export, Import), 2960 '$import_all'(Import, Target, Source, Reexport, weak). 2961'$import_list'(Target, Source, Import, Reexport) :- 2962 !, 2963 is_list(Import), 2964 !, 2965 '$import_all'(Import, Target, Source, Reexport, strong). 2966'$import_list'(_, _, Import, _) :- 2967 throw(error(type_error(import_specifier, Import))). 2968 2969 2970'$import_except'([], List, List). 2971'$import_except'([H|T], List0, List) :- 2972 '$import_except_1'(H, List0, List1), 2973 '$import_except'(T, List1, List). 2974 2975'$import_except_1'(Var, _, _) :- 2976 var(Var), 2977 !, 2978 throw(error(instantitation_error, _)). 2979'$import_except_1'(PI as N, List0, List) :- 2980 '$pi'(PI), atom(N), 2981 !, 2982 '$canonical_pi'(PI, CPI), 2983 '$import_as'(CPI, N, List0, List). 2984'$import_except_1'(op(P,A,N), List0, List) :- 2985 !, 2986 '$remove_ops'(List0, op(P,A,N), List). 2987'$import_except_1'(PI, List0, List) :- 2988 '$pi'(PI), 2989 !, 2990 '$canonical_pi'(PI, CPI), 2991 '$select'(P, List0, List), 2992 '$canonical_pi'(CPI, P), 2993 !. 2994'$import_except_1'(Except, _, _) :- 2995 throw(error(type_error(import_specifier, Except), _)). 2996 2997'$import_as'(CPI, N, [PI2|T], [CPI as N|T]) :- 2998 '$canonical_pi'(PI2, CPI), 2999 !. 3000'$import_as'(PI, N, [H|T0], [H|T]) :- 3001 !, 3002 '$import_as'(PI, N, T0, T). 3003'$import_as'(PI, _, _, _) :- 3004 throw(error(existence_error(export, PI), _)). 3005 3006'$pi'(N/A) :- atom(N), integer(A), !. 3007'$pi'(N//A) :- atom(N), integer(A). 3008 3009'$canonical_pi'(N//A0, N/A) :- 3010 A is A0 + 2. 3011'$canonical_pi'(PI, PI). 3012 3013'$remove_ops'([], _, []). 3014'$remove_ops'([Op|T0], Pattern, T) :- 3015 subsumes_term(Pattern, Op), 3016 !, 3017 '$remove_ops'(T0, Pattern, T). 3018'$remove_ops'([H|T0], Pattern, [H|T]) :- 3019 '$remove_ops'(T0, Pattern, T).
3024'$import_all'(Import, Context, Source, Reexport, Strength) :-
3025 '$import_all2'(Import, Context, Source, Imported, ImpOps, Strength),
3026 ( Reexport == true,
3027 ( '$list_to_conj'(Imported, Conj)
3028 -> export(Context:Conj),
3029 '$ifcompiling'('$add_directive_wic'(export(Context:Conj)))
3030 ; true
3031 ),
3032 source_location(File, _Line),
3033 '$export_ops'(ImpOps, Context, File)
3034 ; true
3035 ).
3039'$import_all2'([], _, _, [], [], _). 3040'$import_all2'([PI as NewName|Rest], Context, Source, 3041 [NewName/Arity|Imported], ImpOps, Strength) :- 3042 !, 3043 '$canonical_pi'(PI, Name/Arity), 3044 length(Args, Arity), 3045 Head =.. [Name|Args], 3046 NewHead =.. [NewName|Args], 3047 ( '$get_predicate_attribute'(Source:Head, transparent, 1) 3048 -> '$set_predicate_attribute'(Context:NewHead, transparent, true) 3049 ; true 3050 ), 3051 ( source_location(File, Line) 3052 -> E = error(_,_), 3053 catch('$store_admin_clause'((NewHead :- Source:Head), 3054 _Layout, File, File:Line), 3055 E, '$print_message'(error, E)) 3056 ; assertz(( :- !, Source:Head)) % ! avoids problems with 3057 ), % duplicate load 3058 '$import_all2'(Rest, Context, Source, Imported, ImpOps, Strength). 3059'$import_all2'([op(P,A,N)|Rest], Context, Source, Imported, 3060 [op(P,A,N)|ImpOps], Strength) :- 3061 !, 3062 '$import_ops'(Context, Source, op(P,A,N)), 3063 '$import_all2'(Rest, Context, Source, Imported, ImpOps, Strength). 3064'$import_all2'([Pred|Rest], Context, Source, [Pred|Imported], ImpOps, Strength) :- 3065 Error = error(_,_), 3066 catch(Context:'$import'(Source:Pred, Strength), Error, 3067 print_message(error, Error)), 3068 '$ifcompiling'('$import_wic'(Source, Pred, Strength)), 3069 '$import_all2'(Rest, Context, Source, Imported, ImpOps, Strength). 3070 3071 3072'$list_to_conj'([One], One) :- !. 3073'$list_to_conj'([H|T], (H,Rest)) :- 3074 '$list_to_conj'(T, Rest).
op(P,A,N)
terms representing the operators
exported from Module.3081'$exported_ops'(Module, Ops, Tail) :- 3082 '$c_current_predicate'(_, Module:'$exported_op'(_,_,_)), 3083 !, 3084 findall(op(P,A,N), Module:'$exported_op'(P,A,N), Ops, Tail). 3085'$exported_ops'(_, Ops, Ops). 3086 3087'$exported_op'(Module, P, A, N) :- 3088 '$c_current_predicate'(_, Module:'$exported_op'(_,_,_)), 3089 Module:'$exported_op'(P, A, N).
3096'$import_ops'(To, From, Pattern) :- 3097 ground(Pattern), 3098 !, 3099 Pattern = op(P,A,N), 3100 op(P,A,To:N), 3101 ( '$exported_op'(From, P, A, N) 3102 -> true 3103 ; print_message(warning, no_exported_op(From, Pattern)) 3104 ). 3105'$import_ops'(To, From, Pattern) :- 3106 ( '$exported_op'(From, Pri, Assoc, Name), 3107 Pattern = op(Pri, Assoc, Name), 3108 op(Pri, Assoc, To:Name), 3109 fail 3110 ; true 3111 ).
3119'$export_list'(Decls, Module, Ops) :- 3120 is_list(Decls), 3121 !, 3122 '$do_export_list'(Decls, Module, Ops). 3123'$export_list'(Decls, _, _) :- 3124 var(Decls), 3125 throw(error(instantiation_error, _)). 3126'$export_list'(Decls, _, _) :- 3127 throw(error(type_error(list, Decls), _)). 3128 3129'$do_export_list'([], _, []) :- !. 3130'$do_export_list'([H|T], Module, Ops) :- 3131 !, 3132 E = error(_,_), 3133 catch('$export1'(H, Module, Ops, Ops1), 3134 E, ('$print_message'(error, E), Ops = Ops1)), 3135 '$do_export_list'(T, Module, Ops1). 3136 3137'$export1'(Var, _, _, _) :- 3138 var(Var), 3139 !, 3140 throw(error(instantiation_error, _)). 3141'$export1'(Op, _, [Op|T], T) :- 3142 Op = op(_,_,_), 3143 !. 3144'$export1'(PI0, Module, Ops, Ops) :- 3145 strip_module(Module:PI0, M, PI), 3146 ( PI = (_//_) 3147 -> non_terminal(M:PI) 3148 ; true 3149 ), 3150 export(M:PI). 3151 3152'$export_ops'([op(Pri, Assoc, Name)|T], Module, File) :- 3153 E = error(_,_), 3154 catch(( '$execute_directive'(op(Pri, Assoc, Module:Name), File), 3155 '$export_op'(Pri, Assoc, Name, Module, File) 3156 ), 3157 E, '$print_message'(error, E)), 3158 '$export_ops'(T, Module, File). 3159'$export_ops'([], _, _). 3160 3161'$export_op'(Pri, Assoc, Name, Module, File) :- 3162 ( '$get_predicate_attribute'(Module:'$exported_op'(_,_,_), defined, 1) 3163 -> true 3164 ; '$execute_directive'(discontiguous(Module:'$exported_op'/3), File) 3165 ), 3166 '$store_admin_clause'('$exported_op'(Pri, Assoc, Name), _Layout, File, -).
3172'$execute_directive'(Goal, F) :- 3173 '$execute_directive_2'(Goal, F). 3174 3175'$execute_directive_2'(encoding(Encoding), _F) :- 3176 !, 3177 ( '$load_input'(_F, S) 3178 -> set_stream(S, encoding(Encoding)) 3179 ). 3180'$execute_directive_2'(ISO, F) :- 3181 '$expand_directive'(ISO, Normal), 3182 !, 3183 '$execute_directive'(Normal, F). 3184'$execute_directive_2'(Goal, _) :- 3185 \+ '$compilation_mode'(database), 3186 !, 3187 '$add_directive_wic2'(Goal, Type), 3188 ( Type == call % suspend compiling into .qlf file 3189 -> '$compilation_mode'(Old, database), 3190 setup_call_cleanup( 3191 '$directive_mode'(OldDir, Old), 3192 '$execute_directive_3'(Goal), 3193 ( '$set_compilation_mode'(Old), 3194 '$set_directive_mode'(OldDir) 3195 )) 3196 ; '$execute_directive_3'(Goal) 3197 ). 3198'$execute_directive_2'(Goal, _) :- 3199 '$execute_directive_3'(Goal). 3200 3201'$execute_directive_3'(Goal) :- 3202 '$current_source_module'(Module), 3203 '$valid_directive'(Module:Goal), 3204 !, 3205 ( '$pattr_directive'(Goal, Module) 3206 -> true 3207 ; Term = error(_,_), 3208 catch(Module:Goal, Term, '$exception_in_directive'(Term)) 3209 -> true 3210 ; '$print_message'(warning, goal_failed(directive, Module:Goal)), 3211 fail 3212 ). 3213'$execute_directive_3'(_).
sandboxed_load
is true
, this calls
prolog:sandbox_allowed_directive/1. This call can deny execution
of the directive by throwing an exception.3222:- multifile prolog:sandbox_allowed_directive/1. 3223:- multifile prolog:sandbox_allowed_clause/1. 3224:- meta_predicate '$valid_directive'( ). 3225 3226'$valid_directive'(_) :- 3227 current_prolog_flag(sandboxed_load, false), 3228 !. 3229'$valid_directive'(Goal) :- 3230 Error = error(Formal, _), 3231 catch(prolog:sandbox_allowed_directive(Goal), Error, true), 3232 !, 3233 ( var(Formal) 3234 -> true 3235 ; print_message(error, Error), 3236 fail 3237 ). 3238'$valid_directive'(Goal) :- 3239 print_message(error, 3240 error(permission_error(execute, 3241 sandboxed_directive, 3242 Goal), _)), 3243 fail. 3244 3245'$exception_in_directive'(Term) :- 3246 '$print_message'(error, Term), 3247 fail. 3248 3249% This predicate deals with the very odd ISO requirement to allow 3250% for :- dynamic(a/2, b/3, c/4) instead of the normally used 3251% :- dynamic a/2, b/3, c/4 or, if operators are not desirable, 3252% :- dynamic((a/2, b/3, c/4)). 3253 3254'$expand_directive'(Directive, Expanded) :- 3255 functor(Directive, Name, Arity), 3256 Arity > 1, 3257 '$iso_property_directive'(Name), 3258 Directive =.. [Name|Args], 3259 '$mk_normal_args'(Args, Normal), 3260 Expanded =.. [Name, Normal]. 3261 3262'$iso_property_directive'(dynamic). 3263'$iso_property_directive'(multifile). 3264'$iso_property_directive'(discontiguous). 3265 3266'$mk_normal_args'([One], One). 3267'$mk_normal_args'([H|T0], (H,T)) :- 3268 '$mk_normal_args'(T0, T). 3269 3270 3271% Note that the list, consult and ensure_loaded directives are already 3272% handled at compile time and therefore should not go into the 3273% intermediate code file. 3274 3275'$add_directive_wic2'(Goal, Type) :- 3276 '$common_goal_type'(Goal, Type), 3277 !, 3278 ( Type == load 3279 -> true 3280 ; '$current_source_module'(Module), 3281 '$add_directive_wic'(Module:Goal) 3282 ). 3283'$add_directive_wic2'(Goal, _) :- 3284 ( '$compilation_mode'(qlf) % no problem for qlf files 3285 -> true 3286 ; print_message(error, mixed_directive(Goal)) 3287 ). 3288 3289'$common_goal_type'((A,B), Type) :- 3290 !, 3291 '$common_goal_type'(A, Type), 3292 '$common_goal_type'(B, Type). 3293'$common_goal_type'((A;B), Type) :- 3294 !, 3295 '$common_goal_type'(A, Type), 3296 '$common_goal_type'(B, Type). 3297'$common_goal_type'((A->B), Type) :- 3298 !, 3299 '$common_goal_type'(A, Type), 3300 '$common_goal_type'(B, Type). 3301'$common_goal_type'(Goal, Type) :- 3302 '$goal_type'(Goal, Type). 3303 3304'$goal_type'(Goal, Type) :- 3305 ( '$load_goal'(Goal) 3306 -> Type = load 3307 ; Type = call 3308 ). 3309 3310'$load_goal'([_|_]). 3311'$load_goal'(consult(_)). 3312'$load_goal'(load_files(_)). 3313'$load_goal'(load_files(_,Options)) :- 3314 memberchk(qcompile(QlfMode), Options), 3315 '$qlf_part_mode'(QlfMode). 3316'$load_goal'(ensure_loaded(_)) :- '$compilation_mode'(wic). 3317'$load_goal'(use_module(_)) :- '$compilation_mode'(wic). 3318'$load_goal'(use_module(_, _)) :- '$compilation_mode'(wic). 3319 3320'$qlf_part_mode'(part). 3321'$qlf_part_mode'(true). % compatibility 3322 3323 3324 /******************************** 3325 * COMPILE A CLAUSE * 3326 *********************************/
3333'$store_admin_clause'(Clause, Layout, Owner, SrcLoc) :- 3334 Owner \== (-), 3335 !, 3336 setup_call_cleanup( 3337 '$start_aux'(Owner, Context), 3338 '$store_admin_clause2'(Clause, Layout, Owner, SrcLoc), 3339 '$end_aux'(Owner, Context)). 3340'$store_admin_clause'(Clause, Layout, File, SrcLoc) :- 3341 '$store_admin_clause2'(Clause, Layout, File, SrcLoc). 3342 3343'$store_admin_clause2'(Clause, _Layout, File, SrcLoc) :- 3344 ( '$compilation_mode'(database) 3345 -> '$record_clause'(Clause, File, SrcLoc) 3346 ; '$record_clause'(Clause, File, SrcLoc, Ref), 3347 '$qlf_assert_clause'(Ref, development) 3348 ).
3358'$store_clause'((_, _), _, _, _) :- 3359 !, 3360 print_message(error, cannot_redefine_comma), 3361 fail. 3362'$store_clause'(Clause, _Layout, File, SrcLoc) :- 3363 '$valid_clause'(Clause), 3364 !, 3365 ( '$compilation_mode'(database) 3366 -> '$record_clause'(Clause, File, SrcLoc) 3367 ; '$record_clause'(Clause, File, SrcLoc, Ref), 3368 '$qlf_assert_clause'(Ref, development) 3369 ). 3370 3371'$valid_clause'(_) :- 3372 current_prolog_flag(sandboxed_load, false), 3373 !. 3374'$valid_clause'(Clause) :- 3375 \+ '$cross_module_clause'(Clause), 3376 !. 3377'$valid_clause'(Clause) :- 3378 Error = error(Formal, _), 3379 catch(prolog:sandbox_allowed_clause(Clause), Error, true), 3380 !, 3381 ( var(Formal) 3382 -> true 3383 ; print_message(error, Error), 3384 fail 3385 ). 3386'$valid_clause'(Clause) :- 3387 print_message(error, 3388 error(permission_error(assert, 3389 sandboxed_clause, 3390 Clause), _)), 3391 fail. 3392 3393'$cross_module_clause'(Clause) :- 3394 '$head_module'(Clause, Module), 3395 \+ '$current_source_module'(Module). 3396 3397'$head_module'(Var, _) :- 3398 var(Var), !, fail. 3399'$head_module'((Head :- _), Module) :- 3400 '$head_module'(Head, Module). 3401'$head_module'(Module:_, Module). 3402 3403'$clause_source'('$source_location'(File,Line):Clause, Clause, File:Line) :- !. 3404'$clause_source'(Clause, Clause, -).
3411:- public 3412 '$store_clause'/2. 3413 3414'$store_clause'(Term, Id) :- 3415 '$clause_source'(Term, Clause, SrcLoc), 3416 '$store_clause'(Clause, _, Id, SrcLoc).
If the cross-referencer is active, we should not (re-)assert the clauses. Actually, we should make them known to the cross-referencer. How do we do that? Maybe we need a different API, such as in:
expand_term_aux(Goal, NewGoal, Clauses)
3437compile_aux_clauses(_Clauses) :- 3438 current_prolog_flag(xref, true), 3439 !. 3440compile_aux_clauses(Clauses) :- 3441 source_location(File, _Line), 3442 '$compile_aux_clauses'(Clauses, File). 3443 3444'$compile_aux_clauses'(Clauses, File) :- 3445 setup_call_cleanup( 3446 '$start_aux'(File, Context), 3447 '$store_aux_clauses'(Clauses, File), 3448 '$end_aux'(File, Context)). 3449 3450'$store_aux_clauses'(Clauses, File) :- 3451 is_list(Clauses), 3452 !, 3453 forall('$member'(C,Clauses), 3454 '$compile_term'(C, _Layout, File)). 3455'$store_aux_clauses'(Clause, File) :- 3456 '$compile_term'(Clause, _Layout, File). 3457 3458 3459 /******************************* 3460 * STAGING * 3461 *******************************/
3471'$stage_file'(Target, Stage) :- 3472 file_directory_name(Target, Dir), 3473 file_base_name(Target, File), 3474 current_prolog_flag(pid, Pid), 3475 format(atom(Stage), '~w/.~w.~d', [Dir,File,Pid]). 3476 3477'$install_staged_file'(exit, Staged, Target, error) :- 3478 !, 3479 rename_file(Staged, Target). 3480'$install_staged_file'(exit, Staged, Target, OnError) :- 3481 !, 3482 InstallError = error(_,_), 3483 catch(rename_file(Staged, Target), 3484 InstallError, 3485 '$install_staged_error'(OnError, InstallError, Staged, Target)). 3486'$install_staged_file'(_, Staged, _, _OnError) :- 3487 E = error(_,_), 3488 catch(delete_file(Staged), E, true). 3489 3490'$install_staged_error'(OnError, Error, Staged, _Target) :- 3491 E = error(_,_), 3492 catch(delete_file(Staged), E, true), 3493 ( OnError = silent 3494 -> true 3495 ; OnError = fail 3496 -> fail 3497 ; print_message(warning, Error) 3498 ). 3499 3500 3501 /******************************* 3502 * READING * 3503 *******************************/ 3504 3505:- multifile 3506 prolog:comment_hook/3. % hook for read_clause/3 3507 3508 3509 /******************************* 3510 * FOREIGN INTERFACE * 3511 *******************************/ 3512 3513% call-back from PL_register_foreign(). First argument is the module 3514% into which the foreign predicate is loaded and second is a term 3515% describing the arguments. 3516 3517:- dynamic 3518 '$foreign_registered'/2. 3519 3520 /******************************* 3521 * TEMPORARY TERM EXPANSION * 3522 *******************************/ 3523 3524% Provide temporary definitions for the boot-loader. These are replaced 3525% by the real thing in load.pl 3526 3527:- dynamic 3528 '$expand_goal'/2, 3529 '$expand_term'/4. 3530 3531'$expand_goal'(In, In). 3532'$expand_term'(In, Layout, In, Layout). 3533 3534 3535 /******************************* 3536 * TYPE SUPPORT * 3537 *******************************/ 3538 3539'$type_error'(Type, Value) :- 3540 ( var(Value) 3541 -> throw(error(instantiation_error, _)) 3542 ; throw(error(type_error(Type, Value), _)) 3543 ). 3544 3545'$domain_error'(Type, Value) :- 3546 throw(error(domain_error(Type, Value), _)). 3547 3548'$existence_error'(Type, Object) :- 3549 throw(error(existence_error(Type, Object), _)). 3550 3551'$permission_error'(Action, Type, Term) :- 3552 throw(error(permission_error(Action, Type, Term), _)). 3553 3554'$instantiation_error'(_Var) :- 3555 throw(error(instantiation_error, _)). 3556 3557'$uninstantiation_error'(NonVar) :- 3558 throw(error(uninstantiation_error(NonVar), _)). 3559 3560'$must_be'(list, X) :- !, 3561 '$skip_list'(_, X, Tail), 3562 ( Tail == [] 3563 -> true 3564 ; '$type_error'(list, Tail) 3565 ). 3566'$must_be'(options, X) :- !, 3567 ( '$is_options'(X) 3568 -> true 3569 ; '$type_error'(options, X) 3570 ). 3571'$must_be'(atom, X) :- !, 3572 ( atom(X) 3573 -> true 3574 ; '$type_error'(atom, X) 3575 ). 3576'$must_be'(integer, X) :- !, 3577 ( integer(X) 3578 -> true 3579 ; '$type_error'(integer, X) 3580 ). 3581'$must_be'(callable, X) :- !, 3582 ( callable(X) 3583 -> true 3584 ; '$type_error'(callable, X) 3585 ). 3586'$must_be'(oneof(Type, Domain, List), X) :- !, 3587 '$must_be'(Type, X), 3588 ( memberchk(X, List) 3589 -> true 3590 ; '$domain_error'(Domain, X) 3591 ). 3592'$must_be'(boolean, X) :- !, 3593 ( (X == true ; X == false) 3594 -> true 3595 ; '$type_error'(boolean, X) 3596 ). 3597% Use for debugging 3598%'$must_be'(Type, _X) :- format('Unknown $must_be type: ~q~n', [Type]). 3599 3600 3601 /******************************** 3602 * LIST PROCESSING * 3603 *********************************/ 3604 3605'$member'(El, [H|T]) :- 3606 '$member_'(T, El, H). 3607 3608'$member_'(_, El, El). 3609'$member_'([H|T], El, _) :- 3610 '$member_'(T, El, H). 3611 3612 3613'$append'([], L, L). 3614'$append'([H|T], L, [H|R]) :- 3615 '$append'(T, L, R). 3616 3617'$select'(X, [X|Tail], Tail). 3618'$select'(Elem, [Head|Tail], [Head|Rest]) :- 3619 '$select'(Elem, Tail, Rest). 3620 3621'$reverse'(L1, L2) :- 3622 '$reverse'(L1, [], L2). 3623 3624'$reverse'([], List, List). 3625'$reverse'([Head|List1], List2, List3) :- 3626 '$reverse'(List1, [Head|List2], List3). 3627 3628'$delete'([], _, []) :- !. 3629'$delete'([Elem|Tail], Elem, Result) :- 3630 !, 3631 '$delete'(Tail, Elem, Result). 3632'$delete'([Head|Tail], Elem, [Head|Rest]) :- 3633 '$delete'(Tail, Elem, Rest). 3634 3635'$last'([H|T], Last) :- 3636 '$last'(T, H, Last). 3637 3638'$last'([], Last, Last). 3639'$last'([H|T], _, Last) :- 3640 '$last'(T, H, Last).
3647:- '$iso'((length/2)). 3648 3649length(List, Length) :- 3650 var(Length), 3651 !, 3652 '$skip_list'(Length0, List, Tail), 3653 ( Tail == [] 3654 -> Length = Length0 % +,- 3655 ; var(Tail) 3656 -> Tail \== Length, % avoid length(L,L) 3657 '$length3'(Tail, Length, Length0) % -,- 3658 ; throw(error(type_error(list, List), 3659 context(length/2, _))) 3660 ). 3661length(List, Length) :- 3662 integer(Length), 3663 Length >= 0, 3664 !, 3665 '$skip_list'(Length0, List, Tail), 3666 ( Tail == [] % proper list 3667 -> Length = Length0 3668 ; var(Tail) 3669 -> Extra is Length-Length0, 3670 '$length'(Tail, Extra) 3671 ; throw(error(type_error(list, List), 3672 context(length/2, _))) 3673 ). 3674length(_, Length) :- 3675 integer(Length), 3676 !, 3677 throw(error(domain_error(not_less_than_zero, Length), 3678 context(length/2, _))). 3679length(_, Length) :- 3680 throw(error(type_error(integer, Length), 3681 context(length/2, _))). 3682 3683'$length3'([], N, N). 3684'$length3'([_|List], N, N0) :- 3685 N1 is N0+1, 3686 '$length3'(List, N, N1). 3687 3688 3689 /******************************* 3690 * OPTION PROCESSING * 3691 *******************************/
3697'$is_options'(Map) :- 3698 is_dict(Map, _), 3699 !. 3700'$is_options'(List) :- 3701 is_list(List), 3702 ( List == [] 3703 -> true 3704 ; List = [H|_], 3705 '$is_option'(H, _, _) 3706 ). 3707 3708'$is_option'(Var, _, _) :- 3709 var(Var), !, fail. 3710'$is_option'(F, Name, Value) :- 3711 functor(F, _, 1), 3712 !, 3713 F =.. [Name,Value]. 3714'$is_option'(Name=Value, Name, Value).
3718'$option'(Opt, Options) :- 3719 is_dict(Options), 3720 !, 3721 [Opt] :< Options. 3722'$option'(Opt, Options) :- 3723 memberchk(Opt, Options).
3727'$option'(Term, Options, Default) :-
3728 arg(1, Term, Value),
3729 functor(Term, Name, 1),
3730 ( is_dict(Options)
3731 -> ( get_dict(Name, Options, GVal)
3732 -> Value = GVal
3733 ; Value = Default
3734 )
3735 ; functor(Gen, Name, 1),
3736 arg(1, Gen, GVal),
3737 ( memberchk(Gen, Options)
3738 -> Value = GVal
3739 ; Value = Default
3740 )
3741 ).
3749'$select_option'(Opt, Options, Rest) :-
3750 select_dict([Opt], Options, Rest).
3758'$merge_options'(New, Old, Merged) :- 3759 put_dict(New, Old, Merged). 3760 3761 3762 /******************************* 3763 * HANDLE TRACER 'L'-COMMAND * 3764 *******************************/ 3765 3766:- public '$prolog_list_goal'/1. 3767 3768:- multifile 3769 user:prolog_list_goal/1. 3770 3771'$prolog_list_goal'(Goal) :- 3772 user:prolog_list_goal(Goal), 3773 !. 3774'$prolog_list_goal'(Goal) :- 3775 user:listing(Goal). 3776 3777 3778 /******************************* 3779 * HALT * 3780 *******************************/ 3781 3782:- '$iso'((halt/0)). 3783 3784halt :- 3785 halt(0).
3794:- meta_predicate at_halt( ). 3795:- dynamic system:term_expansion/2, '$at_halt'/2. 3796:- multifile system:term_expansion/2, '$at_halt'/2. 3797 3798systemterm_expansion((:- at_halt(Goal)), 3799 system:'$at_halt'(Module:Goal, File:Line)) :- 3800 \+ current_prolog_flag(xref, true), 3801 source_location(File, Line), 3802 '$current_source_module'(Module). 3803 3804at_halt(Goal) :- 3805 asserta('$at_halt'(Goal, (-):0)). 3806 3807:- public '$run_at_halt'/0. 3808 3809'$run_at_halt' :- 3810 forall(clause('$at_halt'(Goal, Src), true, Ref), 3811 ( '$call_at_halt'(Goal, Src), 3812 erase(Ref) 3813 )). 3814 3815'$call_at_halt'(Goal, _Src) :- 3816 catch(Goal, E, true), 3817 !, 3818 ( var(E) 3819 -> true 3820 ; subsumes_term(cancel_halt(_), E) 3821 -> '$print_message'(informational, E), 3822 fail 3823 ; '$print_message'(error, E) 3824 ). 3825'$call_at_halt'(Goal, _Src) :- 3826 '$print_message'(warning, goal_failed(at_halt, Goal)).
3834cancel_halt(Reason) :- 3835 throw(cancel_halt(Reason)). 3836 3837 3838 /******************************** 3839 * LOAD OTHER MODULES * 3840 *********************************/ 3841 3842:- meta_predicate 3843 '$load_wic_files'( ). 3844 3845'$load_wic_files'(Files) :- 3846 Files = Module:_, 3847 '$execute_directive'('$set_source_module'(OldM, Module), []), 3848 '$save_lex_state'(LexState, []), 3849 '$style_check'(_, 0xC7), % see style_name/2 in syspred.pl 3850 '$compilation_mode'(OldC, wic), 3851 consult(Files), 3852 '$execute_directive'('$set_source_module'(OldM), []), 3853 '$execute_directive'('$restore_lex_state'(LexState), []), 3854 '$set_compilation_mode'(OldC).
compileFileList()
in pl-wic.c. Gets the files from
"-c file ..." and loads them into the module user.3862:- public '$load_additional_boot_files'/0. 3863 3864'$load_additional_boot_files' :- 3865 current_prolog_flag(argv, Argv), 3866 '$get_files_argv'(Argv, Files), 3867 ( Files \== [] 3868 -> format('Loading additional boot files~n'), 3869 '$load_wic_files'(user:Files), 3870 format('additional boot files loaded~n') 3871 ; true 3872 ). 3873 3874'$get_files_argv'([], []) :- !. 3875'$get_files_argv'(['-c'|Files], Files) :- !. 3876'$get_files_argv'([_|Rest], Files) :- 3877 '$get_files_argv'(Rest, Files). 3878 3879'$:-'(('$boot_message'('Loading Prolog startup files~n', []), 3880 source_location(File, _Line), 3881 file_directory_name(File, Dir), 3882 atom_concat(Dir, '/load.pl', LoadFile), 3883 '$load_wic_files'(system:[LoadFile]), 3884 ( current_prolog_flag(windows, true) 3885 -> atom_concat(Dir, '/menu.pl', MenuFile), 3886 '$load_wic_files'(system:[MenuFile]) 3887 ; true 3888 ), 3889 '$boot_message'('SWI-Prolog boot files loaded~n', []), 3890 '$compilation_mode'(OldC, wic), 3891 '$execute_directive'('$set_source_module'(user), []), 3892 '$set_compilation_mode'(OldC) 3893 ))