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-2024, University of Amsterdam 7 VU University Amsterdam 8 CWI, Amsterdam 9 SWI-Prolog Solutions b.v. 10 All rights reserved. 11 12 Redistribution and use in source and binary forms, with or without 13 modification, are permitted provided that the following conditions 14 are met: 15 16 1. Redistributions of source code must retain the above copyright 17 notice, this list of conditions and the following disclaimer. 18 19 2. Redistributions in binary form must reproduce the above copyright 20 notice, this list of conditions and the following disclaimer in 21 the documentation and/or other materials provided with the 22 distribution. 23 24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 29 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 30 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 34 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 POSSIBILITY OF SUCH DAMAGE. 36*/ 37 38/* 39Consult, derivates and basic things. This module is loaded by the 40C-written bootstrap compiler. 41 42The $:- directive is executed by the bootstrap compiler, but not 43inserted in the intermediate code file. Used to print diagnostic 44messages and start the Prolog defined compiler for the remaining boot 45modules. 46 47If you want to debug this module, put a '$:-'(trace). directive 48somewhere. The tracer will work properly under boot compilation as it 49will use the C defined write predicate to print goals and does not 50attempt to call the Prolog defined trace interceptor. 51*/ 52 53 /******************************** 54 * LOAD INTO MODULE SYSTEM * 55 ********************************/ 56 57:- '$set_source_module'(system). 58 59'$boot_message'(_Format, _Args) :- 60 current_prolog_flag(verbose, silent), 61 !. 62'$boot_message'(Format, Args) :- 63 format(Format, Args), 64 !. 65 66'$:-'('$boot_message'('Loading boot file ...~n', [])).
once(member(E,List))
. Implemented in C.
If List is partial though we need to do the work in Prolog to get
the proper constraint behavior. Needs to be defined early as the
boot code uses it.76memberchk(E, List) :- 77 '$memberchk'(E, List, Tail), 78 ( nonvar(Tail) 79 -> true 80 ; Tail = [_|_], 81 memberchk(E, Tail) 82 ). 83 84 /******************************** 85 * DIRECTIVES * 86 *********************************/ 87 88:- meta_predicate 89 dynamic( ), 90 multifile( ), 91 public( ), 92 module_transparent( ), 93 discontiguous( ), 94 volatile( ), 95 thread_local( ), 96 noprofile( ), 97 non_terminal( ), 98 det( ), 99 '$clausable'( ), 100 '$iso'( ), 101 '$hide'( ), 102 '$notransact'( ).
public
also plays this role. in SWI,
public
means that the predicate can be called, even if we cannot
find a reference to it.134dynamic(Spec) :- '$set_pattr'(Spec, pred, dynamic(true)). 135multifile(Spec) :- '$set_pattr'(Spec, pred, multifile(true)). 136module_transparent(Spec) :- '$set_pattr'(Spec, pred, transparent(true)). 137discontiguous(Spec) :- '$set_pattr'(Spec, pred, discontiguous(true)). 138volatile(Spec) :- '$set_pattr'(Spec, pred, volatile(true)). 139thread_local(Spec) :- '$set_pattr'(Spec, pred, thread_local(true)). 140noprofile(Spec) :- '$set_pattr'(Spec, pred, noprofile(true)). 141public(Spec) :- '$set_pattr'(Spec, pred, public(true)). 142non_terminal(Spec) :- '$set_pattr'(Spec, pred, non_terminal(true)). 143det(Spec) :- '$set_pattr'(Spec, pred, det(true)). 144'$iso'(Spec) :- '$set_pattr'(Spec, pred, iso(true)). 145'$clausable'(Spec) :- '$set_pattr'(Spec, pred, clausable(true)). 146'$hide'(Spec) :- '$set_pattr'(Spec, pred, trace(false)). 147'$notransact'(Spec) :- '$set_pattr'(Spec, pred, transact(false)). 148 149'$set_pattr'(M:Pred, How, Attr) :- 150 '$set_pattr'(Pred, M, How, Attr).
pred
or directive
.156'$set_pattr'(X, _, _, _) :- 157 var(X), 158 '$uninstantiation_error'(X). 159'$set_pattr'(as(Spec,Options), M, How, Attr0) :- 160 !, 161 '$attr_options'(Options, Attr0, Attr), 162 '$set_pattr'(Spec, M, How, Attr). 163'$set_pattr'([], _, _, _) :- !. 164'$set_pattr'([H|T], M, How, Attr) :- % ISO 165 !, 166 '$set_pattr'(H, M, How, Attr), 167 '$set_pattr'(T, M, How, Attr). 168'$set_pattr'((A,B), M, How, Attr) :- % ISO and traditional 169 !, 170 '$set_pattr'(A, M, How, Attr), 171 '$set_pattr'(B, M, How, Attr). 172'$set_pattr'(M:T, _, How, Attr) :- 173 !, 174 '$set_pattr'(T, M, How, Attr). 175'$set_pattr'(PI, M, _, []) :- 176 !, 177 '$pi_head'(M:PI, Pred), 178 '$set_table_wrappers'(Pred). 179'$set_pattr'(A, M, How, [O|OT]) :- 180 !, 181 '$set_pattr'(A, M, How, O), 182 '$set_pattr'(A, M, How, OT). 183'$set_pattr'(A, M, pred, Attr) :- 184 !, 185 Attr =.. [Name,Val], 186 '$set_pi_attr'(M:A, Name, Val). 187'$set_pattr'(A, M, directive, Attr) :- 188 !, 189 Attr =.. [Name,Val], 190 catch('$set_pi_attr'(M:A, Name, Val), 191 error(E, _), 192 print_message(error, error(E, context((Name)/1,_)))). 193 194'$set_pi_attr'(PI, Name, Val) :- 195 '$pi_head'(PI, Head), 196 '$set_predicate_attribute'(Head, Name, Val). 197 198'$attr_options'(Var, _, _) :- 199 var(Var), 200 !, 201 '$uninstantiation_error'(Var). 202'$attr_options'((A,B), Attr0, Attr) :- 203 !, 204 '$attr_options'(A, Attr0, Attr1), 205 '$attr_options'(B, Attr1, Attr). 206'$attr_options'(Opt, Attr0, Attrs) :- 207 '$must_be'(ground, Opt), 208 ( '$attr_option'(Opt, AttrX) 209 -> ( is_list(Attr0) 210 -> '$join_attrs'(AttrX, Attr0, Attrs) 211 ; '$join_attrs'(AttrX, [Attr0], Attrs) 212 ) 213 ; '$domain_error'(predicate_option, Opt) 214 ). 215 216'$join_attrs'([], Attrs, Attrs) :- 217 !. 218'$join_attrs'([H|T], Attrs0, Attrs) :- 219 !, 220 '$join_attrs'(H, Attrs0, Attrs1), 221 '$join_attrs'(T, Attrs1, Attrs). 222'$join_attrs'(Attr, Attrs, Attrs) :- 223 memberchk(Attr, Attrs), 224 !. 225'$join_attrs'(Attr, Attrs, Attrs) :- 226 Attr =.. [Name,Value], 227 Gen =.. [Name,Existing], 228 memberchk(Gen, Attrs), 229 !, 230 throw(error(conflict_error(Name, Value, Existing), _)). 231'$join_attrs'(Attr, Attrs0, Attrs) :- 232 '$append'(Attrs0, [Attr], Attrs). 233 234'$attr_option'(incremental, [incremental(true),opaque(false)]). 235'$attr_option'(monotonic, monotonic(true)). 236'$attr_option'(lazy, lazy(true)). 237'$attr_option'(opaque, [incremental(false),opaque(true)]). 238'$attr_option'(abstract(Level0), abstract(Level)) :- 239 '$table_option'(Level0, Level). 240'$attr_option'(subgoal_abstract(Level0), subgoal_abstract(Level)) :- 241 '$table_option'(Level0, Level). 242'$attr_option'(answer_abstract(Level0), answer_abstract(Level)) :- 243 '$table_option'(Level0, Level). 244'$attr_option'(max_answers(Level0), max_answers(Level)) :- 245 '$table_option'(Level0, Level). 246'$attr_option'(volatile, volatile(true)). 247'$attr_option'(multifile, multifile(true)). 248'$attr_option'(discontiguous, discontiguous(true)). 249'$attr_option'(shared, thread_local(false)). 250'$attr_option'(local, thread_local(true)). 251'$attr_option'(private, thread_local(true)). 252 253'$table_option'(Value0, _Value) :- 254 var(Value0), 255 !, 256 '$instantiation_error'(Value0). 257'$table_option'(Value0, Value) :- 258 integer(Value0), 259 Value0 >= 0, 260 !, 261 Value = Value0. 262'$table_option'(off, -1) :- 263 !. 264'$table_option'(false, -1) :- 265 !. 266'$table_option'(infinite, -1) :- 267 !. 268'$table_option'(Value, _) :- 269 '$domain_error'(nonneg_or_false, Value).
279'$pattr_directive'(dynamic(Spec), M) :- 280 '$set_pattr'(Spec, M, directive, dynamic(true)). 281'$pattr_directive'(multifile(Spec), M) :- 282 '$set_pattr'(Spec, M, directive, multifile(true)). 283'$pattr_directive'(module_transparent(Spec), M) :- 284 '$set_pattr'(Spec, M, directive, transparent(true)). 285'$pattr_directive'(discontiguous(Spec), M) :- 286 '$set_pattr'(Spec, M, directive, discontiguous(true)). 287'$pattr_directive'(volatile(Spec), M) :- 288 '$set_pattr'(Spec, M, directive, volatile(true)). 289'$pattr_directive'(thread_local(Spec), M) :- 290 '$set_pattr'(Spec, M, directive, thread_local(true)). 291'$pattr_directive'(noprofile(Spec), M) :- 292 '$set_pattr'(Spec, M, directive, noprofile(true)). 293'$pattr_directive'(public(Spec), M) :- 294 '$set_pattr'(Spec, M, directive, public(true)). 295'$pattr_directive'(det(Spec), M) :- 296 '$set_pattr'(Spec, M, directive, det(true)).
300'$pi_head'(PI, Head) :- 301 var(PI), 302 var(Head), 303 '$instantiation_error'([PI,Head]). 304'$pi_head'(M:PI, M:Head) :- 305 !, 306 '$pi_head'(PI, Head). 307'$pi_head'(Name/Arity, Head) :- 308 !, 309 '$head_name_arity'(Head, Name, Arity). 310'$pi_head'(Name//DCGArity, Head) :- 311 !, 312 ( nonvar(DCGArity) 313 -> Arity is DCGArity+2, 314 '$head_name_arity'(Head, Name, Arity) 315 ; '$head_name_arity'(Head, Name, Arity), 316 DCGArity is Arity - 2 317 ). 318'$pi_head'(PI, _) :- 319 '$type_error'(predicate_indicator, PI).
324'$head_name_arity'(Goal, Name, Arity) :- 325 ( atom(Goal) 326 -> Name = Goal, Arity = 0 327 ; compound(Goal) 328 -> compound_name_arity(Goal, Name, Arity) 329 ; var(Goal) 330 -> ( Arity == 0 331 -> ( atom(Name) 332 -> Goal = Name 333 ; Name == [] 334 -> Goal = Name 335 ; blob(Name, closure) 336 -> Goal = Name 337 ; '$type_error'(atom, Name) 338 ) 339 ; compound_name_arity(Goal, Name, Arity) 340 ) 341 ; '$type_error'(callable, Goal) 342 ). 343 344:- '$iso'(((dynamic)/1, (multifile)/1, (discontiguous)/1)). 345 346 347 /******************************** 348 * CALLING, CONTROL * 349 *********************************/ 350 351:- noprofile((call/1, 352 catch/3, 353 once/1, 354 ignore/1, 355 call_cleanup/2, 356 setup_call_cleanup/3, 357 setup_call_catcher_cleanup/4, 358 notrace/1)). 359 360:- meta_predicate 361 ';'( , ), 362 ','( , ), 363 @( , ), 364 call( ), 365 call( , ), 366 call( , , ), 367 call( , , , ), 368 call( , , , , ), 369 call( , , , , , ), 370 call( , , , , , , ), 371 call( , , , , , , , ), 372 not( ), 373 \+( ), 374 $( ), 375 '->'( , ), 376 '*->'( , ), 377 once( ), 378 ignore( ), 379 catch( , , ), 380 reset( , , ), 381 setup_call_cleanup( , , ), 382 setup_call_catcher_cleanup( , , , ), 383 call_cleanup( , ), 384 catch_with_backtrace( , , ), 385 notrace( ), 386 '$meta_call'( ). 387 388:- '$iso'((call/1, (\+)/1, once/1, (;)/2, (',')/2, (->)/2, catch/3)). 389 390% The control structures are always compiled, both if they appear in a 391% clause body and if they are handed to call/1. The only way to call 392% these predicates is by means of call/2.. In that case, we call the 393% hole control structure again to get it compiled by call/1 and properly 394% deal with !, etc. Another reason for having these things as 395% predicates is to be able to define properties for them, helping code 396% analyzers. 397 398(M0:If ; M0:Then) :- !, call(M0:(If ; Then)). 399(M1:If ; M2:Then) :- call(M1:(If ; M2:Then)). 400(G1 , G2) :- call((G1 , G2)). 401(If -> Then) :- call((If -> Then)). 402(If *-> Then) :- call((If *-> Then)). 403@(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.
417'$meta_call'(M:G) :- 418 prolog_current_choice(Ch), 419 '$meta_call'(G, M, Ch). 420 421'$meta_call'(Var, _, _) :- 422 var(Var), 423 !, 424 '$instantiation_error'(Var). 425'$meta_call'((A,B), M, Ch) :- 426 !, 427 '$meta_call'(A, M, Ch), 428 '$meta_call'(B, M, Ch). 429'$meta_call'((I->T;E), M, Ch) :- 430 !, 431 ( prolog_current_choice(Ch2), 432 '$meta_call'(I, M, Ch2) 433 -> '$meta_call'(T, M, Ch) 434 ; '$meta_call'(E, M, Ch) 435 ). 436'$meta_call'((I*->T;E), M, Ch) :- 437 !, 438 ( prolog_current_choice(Ch2), 439 '$meta_call'(I, M, Ch2) 440 *-> '$meta_call'(T, M, Ch) 441 ; '$meta_call'(E, M, Ch) 442 ). 443'$meta_call'((I->T), M, Ch) :- 444 !, 445 ( prolog_current_choice(Ch2), 446 '$meta_call'(I, M, Ch2) 447 -> '$meta_call'(T, M, Ch) 448 ). 449'$meta_call'((I*->T), M, Ch) :- 450 !, 451 prolog_current_choice(Ch2), 452 '$meta_call'(I, M, Ch2), 453 '$meta_call'(T, M, Ch). 454'$meta_call'((A;B), M, Ch) :- 455 !, 456 ( '$meta_call'(A, M, Ch) 457 ; '$meta_call'(B, M, Ch) 458 ). 459'$meta_call'(\+(G), M, _) :- 460 !, 461 prolog_current_choice(Ch), 462 \+ '$meta_call'(G, M, Ch). 463'$meta_call'($(G), M, _) :- 464 !, 465 prolog_current_choice(Ch), 466 $('$meta_call'(G, M, Ch)). 467'$meta_call'(call(G), M, _) :- 468 !, 469 prolog_current_choice(Ch), 470 '$meta_call'(G, M, Ch). 471'$meta_call'(M:G, _, Ch) :- 472 !, 473 '$meta_call'(G, M, Ch). 474'$meta_call'(!, _, Ch) :- 475 prolog_cut_to(Ch). 476'$meta_call'(G, M, _Ch) :- 477 call(M:G).
493:- '$iso'((call/2, 494 call/3, 495 call/4, 496 call/5, 497 call/6, 498 call/7, 499 call/8)). 500 501call(Goal) :- % make these available as predicates 502 . 503call(Goal, A) :- 504 call(Goal, A). 505call(Goal, A, B) :- 506 call(Goal, A, B). 507call(Goal, A, B, C) :- 508 call(Goal, A, B, C). 509call(Goal, A, B, C, D) :- 510 call(Goal, A, B, C, D). 511call(Goal, A, B, C, D, E) :- 512 call(Goal, A, B, C, D, E). 513call(Goal, A, B, C, D, E, F) :- 514 call(Goal, A, B, C, D, E, F). 515call(Goal, A, B, C, D, E, F, G) :- 516 call(Goal, A, B, C, D, E, F, G).
523not(Goal) :-
524 \+ .
530\+ Goal :-
531 \+ .
call((Goal, !))
.
537once(Goal) :-
538 ,
539 !.
546ignore(Goal) :- 547 , 548 !. 549ignore(_Goal). 550 551:- '$iso'((false/0)).
557false :-
558 fail.
564catch(_Goal, _Catcher, _Recover) :- 565 '$catch'. % Maps to I_CATCH, I_EXITCATCH
571prolog_cut_to(_Choice) :- 572 '$cut'. % Maps to I_CUTCHP
578'$' :- '$'.
584$(Goal) :- $(Goal).
590:- '$hide'(notrace/1). 591 592notrace(Goal) :- 593 setup_call_cleanup( 594 '$notrace'(Flags, SkipLevel), 595 once(Goal), 596 '$restore_trace'(Flags, SkipLevel)).
603reset(_Goal, _Ball, _Cont) :-
604 '$reset'.
613shift(Ball) :- 614 '$shift'(Ball). 615 616shift_for_copy(Ball) :- 617 '$shift_for_copy'(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.
631call_continuation([]). 632call_continuation([TB|Rest]) :- 633 ( Rest == [] 634 -> '$call_continuation'(TB) 635 ; '$call_continuation'(TB), 636 call_continuation(Rest) 637 ).
644catch_with_backtrace(Goal, Ball, Recover) :- 645 catch(Goal, Ball, Recover), 646 '$no_lco'. 647 648'$no_lco'.
unwind(Term)
. Note that we cut to ensure
that the exception is not delayed forever because the recover
handler leaves a choicepoint.658:- public '$recover_and_rethrow'/2. 659 660'$recover_and_rethrow'(Goal, Exception) :- 661 call_cleanup(Goal, throw(Exception)), 662 !.
I_CALLCLEANUP
, I_EXITCLEANUP
. These
instructions rely on the exact stack layout left by these
predicates, where the variant is determined by the arity. See also
callCleanupHandler()
in pl-wam.c
.676setup_call_catcher_cleanup(Setup, _Goal, _Catcher, _Cleanup) :- 677 sig_atomic(Setup), 678 '$call_cleanup'. 679 680setup_call_cleanup(Setup, _Goal, _Cleanup) :- 681 sig_atomic(Setup), 682 '$call_cleanup'. 683 684call_cleanup(_Goal, _Cleanup) :- 685 '$call_cleanup'. 686 687 688 /******************************* 689 * INITIALIZATION * 690 *******************************/ 691 692:- meta_predicate 693 initialization( , ). 694 695:- multifile '$init_goal'/3. 696:- dynamic '$init_goal'/3. 697:- '$notransact'('$init_goal'/3).
-g goal
goals.Note that all goals are executed when a program is restored.
723initialization(Goal, When) :- 724 '$must_be'(oneof(atom, initialization_type, 725 [ now, 726 after_load, 727 restore, 728 restore_state, 729 prepare_state, 730 program, 731 main 732 ]), When), 733 '$initialization_context'(Source, Ctx), 734 '$initialization'(When, Goal, Source, Ctx). 735 736'$initialization'(now, Goal, _Source, Ctx) :- 737 '$run_init_goal'(Goal, Ctx), 738 '$compile_init_goal'(-, Goal, Ctx). 739'$initialization'(after_load, Goal, Source, Ctx) :- 740 ( Source \== (-) 741 -> '$compile_init_goal'(Source, Goal, Ctx) 742 ; throw(error(context_error(nodirective, 743 initialization(Goal, after_load)), 744 _)) 745 ). 746'$initialization'(restore, Goal, Source, Ctx) :- % deprecated 747 '$initialization'(restore_state, Goal, Source, Ctx). 748'$initialization'(restore_state, Goal, _Source, Ctx) :- 749 ( \+ current_prolog_flag(sandboxed_load, true) 750 -> '$compile_init_goal'(-, Goal, Ctx) 751 ; '$permission_error'(register, initialization(restore), Goal) 752 ). 753'$initialization'(prepare_state, Goal, _Source, Ctx) :- 754 ( \+ current_prolog_flag(sandboxed_load, true) 755 -> '$compile_init_goal'(when(prepare_state), Goal, Ctx) 756 ; '$permission_error'(register, initialization(restore), Goal) 757 ). 758'$initialization'(program, Goal, _Source, Ctx) :- 759 ( \+ current_prolog_flag(sandboxed_load, true) 760 -> '$compile_init_goal'(when(program), Goal, Ctx) 761 ; '$permission_error'(register, initialization(restore), Goal) 762 ). 763'$initialization'(main, Goal, _Source, Ctx) :- 764 ( \+ current_prolog_flag(sandboxed_load, true) 765 -> '$compile_init_goal'(when(main), Goal, Ctx) 766 ; '$permission_error'(register, initialization(restore), Goal) 767 ). 768 769 770'$compile_init_goal'(Source, Goal, Ctx) :- 771 atom(Source), 772 Source \== (-), 773 !, 774 '$store_admin_clause'(system:'$init_goal'(Source, Goal, Ctx), 775 _Layout, Source, Ctx). 776'$compile_init_goal'(Source, Goal, Ctx) :- 777 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.789'$run_initialization'(_, loaded, _) :- !. 790'$run_initialization'(File, _Action, Options) :- 791 '$run_initialization'(File, Options). 792 793'$run_initialization'(File, Options) :- 794 setup_call_cleanup( 795 '$start_run_initialization'(Options, Restore), 796 '$run_initialization_2'(File), 797 '$end_run_initialization'(Restore)). 798 799'$start_run_initialization'(Options, OldSandBoxed) :- 800 '$push_input_context'(initialization), 801 '$set_sandboxed_load'(Options, OldSandBoxed). 802'$end_run_initialization'(OldSandBoxed) :- 803 set_prolog_flag(sandboxed_load, OldSandBoxed), 804 '$pop_input_context'. 805 806'$run_initialization_2'(File) :- 807 ( '$init_goal'(File, Goal, Ctx), 808 File \= when(_), 809 '$run_init_goal'(Goal, Ctx), 810 fail 811 ; true 812 ). 813 814'$run_init_goal'(Goal, Ctx) :- 815 ( catch_with_backtrace('$run_init_goal'(Goal), E, 816 '$initialization_error'(E, Goal, Ctx)) 817 -> true 818 ; '$initialization_failure'(Goal, Ctx) 819 ). 820 821:- multifile prolog:sandbox_allowed_goal/1. 822 823'$run_init_goal'(Goal) :- 824 current_prolog_flag(sandboxed_load, false), 825 !, 826 call(Goal). 827'$run_init_goal'(Goal) :- 828 prolog:sandbox_allowed_goal(Goal), 829 call(Goal). 830 831'$initialization_context'(Source, Ctx) :- 832 ( source_location(File, Line) 833 -> Ctx = File:Line, 834 '$input_context'(Context), 835 '$top_file'(Context, File, Source) 836 ; Ctx = (-), 837 File = (-) 838 ). 839 840'$top_file'([input(include, F1, _, _)|T], _, F) :- 841 !, 842 '$top_file'(T, F1, F). 843'$top_file'(_, F, F). 844 845 846'$initialization_error'(E, Goal, Ctx) :- 847 print_message(error, initialization_error(Goal, E, Ctx)). 848 849'$initialization_failure'(Goal, Ctx) :- 850 print_message(warning, initialization_failure(Goal, Ctx)).
858:- public '$clear_source_admin'/1. 859 860'$clear_source_admin'(File) :- 861 retractall('$init_goal'(_, _, File:_)), 862 retractall('$load_context_module'(File, _, _)), 863 retractall('$resolved_source_path_db'(_, _, File)). 864 865 866 /******************************* 867 * STREAM * 868 *******************************/ 869 870:- '$iso'(stream_property/2). 871stream_property(Stream, Property) :- 872 nonvar(Stream), 873 nonvar(Property), 874 !, 875 '$stream_property'(Stream, Property). 876stream_property(Stream, Property) :- 877 nonvar(Stream), 878 !, 879 '$stream_properties'(Stream, Properties), 880 '$member'(Property, Properties). 881stream_property(Stream, Property) :- 882 nonvar(Property), 883 !, 884 ( Property = alias(Alias), 885 atom(Alias) 886 -> '$alias_stream'(Alias, Stream) 887 ; '$streams_properties'(Property, Pairs), 888 '$member'(Stream-Property, Pairs) 889 ). 890stream_property(Stream, Property) :- 891 '$streams_properties'(Property, Pairs), 892 '$member'(Stream-Properties, Pairs), 893 '$member'(Property, Properties). 894 895 896 /******************************** 897 * MODULES * 898 *********************************/ 899 900% '$prefix_module'(+Module, +Context, +Term, -Prefixed) 901% Tags `Term' with `Module:' if `Module' is not the context module. 902 903'$prefix_module'(Module, Module, Head, Head) :- !. 904'$prefix_module'(Module, _, Head, Module:Head).
910default_module(Me, Super) :- 911 ( atom(Me) 912 -> ( var(Super) 913 -> '$default_module'(Me, Super) 914 ; '$default_module'(Me, Super), ! 915 ) 916 ; '$type_error'(module, Me) 917 ). 918 919'$default_module'(Me, Me). 920'$default_module'(Me, Super) :- 921 import_module(Me, S), 922 '$default_module'(S, Super). 923 924 925 /******************************** 926 * TRACE AND EXCEPTIONS * 927 *********************************/ 928 929:- dynamic user:exception/3. 930:- multifile user:exception/3. 931:- '$hide'(user:exception/3).
940:- public 941 '$undefined_procedure'/4. 942 943'$undefined_procedure'(Module, Name, Arity, Action) :- 944 '$prefix_module'(Module, user, Name/Arity, Pred), 945 user:exception(undefined_predicate, Pred, Action0), 946 !, 947 Action = Action0. 948'$undefined_procedure'(Module, Name, Arity, Action) :- 949 \+ current_prolog_flag(autoload, false), 950 '$autoload'(Module:Name/Arity), 951 !, 952 Action = retry. 953'$undefined_procedure'(_, _, _, error).
965'$loading'(Library) :- 966 current_prolog_flag(threads, true), 967 ( '$loading_file'(Library, _Queue, _LoadThread) 968 -> true 969 ; '$loading_file'(FullFile, _Queue, _LoadThread), 970 file_name_extension(Library, _, FullFile) 971 -> true 972 ). 973 974% handle debugger 'w', 'p' and <N> depth options. 975 976'$set_debugger_write_options'(write) :- 977 !, 978 create_prolog_flag(debugger_write_options, 979 [ quoted(true), 980 attributes(dots), 981 spacing(next_argument) 982 ], []). 983'$set_debugger_write_options'(print) :- 984 !, 985 create_prolog_flag(debugger_write_options, 986 [ quoted(true), 987 portray(true), 988 max_depth(10), 989 attributes(portray), 990 spacing(next_argument) 991 ], []). 992'$set_debugger_write_options'(Depth) :- 993 current_prolog_flag(debugger_write_options, Options0), 994 ( '$select'(max_depth(_), Options0, Options) 995 -> true 996 ; Options = Options0 997 ), 998 create_prolog_flag(debugger_write_options, 999 [max_depth(Depth)|Options], []). 1000 1001 1002 /******************************** 1003 * SYSTEM MESSAGES * 1004 *********************************/
query
channel. This
predicate may be hooked using confirm/2, which must return
a boolean.1013:- multifile 1014 prolog:confirm/2. 1015 1016'$confirm'(Spec) :- 1017 prolog:confirm(Spec, Result), 1018 !, 1019 Result == true. 1020'$confirm'(Spec) :- 1021 print_message(query, Spec), 1022 between(0, 5, _), 1023 get_single_char(Answer), 1024 ( '$in_reply'(Answer, 'yYjJ \n') 1025 -> !, 1026 print_message(query, if_tty([yes-[]])) 1027 ; '$in_reply'(Answer, 'nN') 1028 -> !, 1029 print_message(query, if_tty([no-[]])), 1030 fail 1031 ; print_message(help, query(confirm)), 1032 fail 1033 ). 1034 1035'$in_reply'(Code, Atom) :- 1036 char_code(Char, Code), 1037 sub_atom(Atom, _, _, _, Char), 1038 !. 1039 1040:- dynamic 1041 user:portray/1. 1042:- multifile 1043 user:portray/1. 1044:- '$notransact'(user:portray/1). 1045 1046 1047 /******************************* 1048 * FILE_SEARCH_PATH * 1049 *******************************/ 1050 1051:- dynamic 1052 user:file_search_path/2, 1053 user:library_directory/1. 1054:- multifile 1055 user:file_search_path/2, 1056 user:library_directory/1. 1057:- '$notransact'((user:file_search_path/2, 1058 user:library_directory/1)). 1059 1060user(file_search_path(library, Dir) :- 1061 library_directory(Dir)). 1062user:file_search_path(swi, Home) :- 1063 current_prolog_flag(home, Home). 1064user:file_search_path(swi, Home) :- 1065 current_prolog_flag(shared_home, Home). 1066user:file_search_path(library, app_config(lib)). 1067user:file_search_path(library, swi(library)). 1068user:file_search_path(library, swi(library/clp)). 1069user:file_search_path(library, Dir) :- 1070 '$ext_library_directory'(Dir). 1071user:file_search_path(path, Dir) :- 1072 getenv('PATH', Path), 1073 current_prolog_flag(path_sep, Sep), 1074 atomic_list_concat(Dirs, Sep, Path), 1075 '$member'(Dir, Dirs). 1076user:file_search_path(user_app_data, Dir) :- 1077 '$xdg_prolog_directory'(data, Dir). 1078user:file_search_path(common_app_data, Dir) :- 1079 '$xdg_prolog_directory'(common_data, Dir). 1080user:file_search_path(user_app_config, Dir) :- 1081 '$xdg_prolog_directory'(config, Dir). 1082user:file_search_path(common_app_config, Dir) :- 1083 '$xdg_prolog_directory'(common_config, Dir). 1084user:file_search_path(app_data, user_app_data('.')). 1085user:file_search_path(app_data, common_app_data('.')). 1086user:file_search_path(app_config, user_app_config('.')). 1087user:file_search_path(app_config, common_app_config('.')). 1088% backward compatibility 1089user:file_search_path(app_preferences, user_app_config('.')). 1090user:file_search_path(user_profile, app_preferences('.')). 1091user:file_search_path(app, swi(app)). 1092user:file_search_path(app, app_data(app)). 1093user:file_search_path(working_directory, CWD) :- 1094 working_directory(CWD, CWD). 1095 1096'$xdg_prolog_directory'(Which, Dir) :- 1097 '$xdg_directory'(Which, XDGDir), 1098 '$make_config_dir'(XDGDir), 1099 '$ensure_slash'(XDGDir, XDGDirS), 1100 atom_concat(XDGDirS, 'swi-prolog', Dir), 1101 '$make_config_dir'(Dir). 1102 1103'$xdg_directory'(Which, Dir) :- 1104 '$xdg_directory_search'(Where), 1105 '$xdg_directory'(Which, Where, Dir). 1106 1107'$xdg_directory_search'(xdg) :- 1108 current_prolog_flag(xdg, true), 1109 !. 1110'$xdg_directory_search'(Where) :- 1111 current_prolog_flag(windows, true), 1112 ( current_prolog_flag(xdg, false) 1113 -> Where = windows 1114 ; '$member'(Where, [windows, xdg]) 1115 ). 1116 1117% config 1118'$xdg_directory'(config, windows, Home) :- 1119 catch(win_folder(appdata, Home), _, fail). 1120'$xdg_directory'(config, xdg, Home) :- 1121 getenv('XDG_CONFIG_HOME', Home). 1122'$xdg_directory'(config, xdg, Home) :- 1123 expand_file_name('~/.config', [Home]). 1124% data 1125'$xdg_directory'(data, windows, Home) :- 1126 catch(win_folder(local_appdata, Home), _, fail). 1127'$xdg_directory'(data, xdg, Home) :- 1128 getenv('XDG_DATA_HOME', Home). 1129'$xdg_directory'(data, xdg, Home) :- 1130 expand_file_name('~/.local', [Local]), 1131 '$make_config_dir'(Local), 1132 atom_concat(Local, '/share', Home), 1133 '$make_config_dir'(Home). 1134% common data 1135'$xdg_directory'(common_data, windows, Dir) :- 1136 catch(win_folder(common_appdata, Dir), _, fail). 1137'$xdg_directory'(common_data, xdg, Dir) :- 1138 '$existing_dir_from_env_path'('XDG_DATA_DIRS', 1139 [ '/usr/local/share', 1140 '/usr/share' 1141 ], 1142 Dir). 1143% common config 1144'$xdg_directory'(common_config, windows, Dir) :- 1145 catch(win_folder(common_appdata, Dir), _, fail). 1146'$xdg_directory'(common_config, xdg, Dir) :- 1147 '$existing_dir_from_env_path'('XDG_CONFIG_DIRS', ['/etc/xdg'], Dir). 1148 1149'$existing_dir_from_env_path'(Env, Defaults, Dir) :- 1150 ( getenv(Env, Path) 1151 -> current_prolog_flag(path_sep, Sep), 1152 atomic_list_concat(Dirs, Sep, Path) 1153 ; Dirs = Defaults 1154 ), 1155 '$member'(Dir, Dirs), 1156 Dir \== '', 1157 exists_directory(Dir). 1158 1159'$make_config_dir'(Dir) :- 1160 exists_directory(Dir), 1161 !. 1162'$make_config_dir'(Dir) :- 1163 nb_current('$create_search_directories', true), 1164 file_directory_name(Dir, Parent), 1165 '$my_file'(Parent), 1166 catch(make_directory(Dir), _, fail). 1167 1168'$ensure_slash'(Dir, DirS) :- 1169 ( sub_atom(Dir, _, _, 0, /) 1170 -> DirS = Dir 1171 ; atom_concat(Dir, /, DirS) 1172 ). 1173 1174:- dynamic '$ext_lib_dirs'/1. 1175:- volatile '$ext_lib_dirs'/1. 1176 1177'$ext_library_directory'(Dir) :- 1178 '$ext_lib_dirs'(Dirs), 1179 !, 1180 '$member'(Dir, Dirs). 1181'$ext_library_directory'(Dir) :- 1182 current_prolog_flag(home, Home), 1183 atom_concat(Home, '/library/ext/*', Pattern), 1184 expand_file_name(Pattern, Dirs0), 1185 '$include'(exists_directory, Dirs0, Dirs), 1186 asserta('$ext_lib_dirs'(Dirs)), 1187 '$member'(Dir, Dirs).
1192'$expand_file_search_path'(Spec, Expanded, Cond) :- 1193 '$option'(access(Access), Cond), 1194 memberchk(Access, [write,append]), 1195 !, 1196 setup_call_cleanup( 1197 nb_setval('$create_search_directories', true), 1198 expand_file_search_path(Spec, Expanded), 1199 nb_delete('$create_search_directories')). 1200'$expand_file_search_path'(Spec, Expanded, _Cond) :- 1201 expand_file_search_path(Spec, Expanded).
1209expand_file_search_path(Spec, Expanded) :- 1210 catch('$expand_file_search_path'(Spec, Expanded, 0, []), 1211 loop(Used), 1212 throw(error(loop_error(Spec), file_search(Used)))). 1213 1214'$expand_file_search_path'(Spec, Expanded, N, Used) :- 1215 functor(Spec, Alias, 1), 1216 !, 1217 user:file_search_path(Alias, Exp0), 1218 NN is N + 1, 1219 ( NN > 16 1220 -> throw(loop(Used)) 1221 ; true 1222 ), 1223 '$expand_file_search_path'(Exp0, Exp1, NN, [Alias=Exp0|Used]), 1224 arg(1, Spec, Segments), 1225 '$segments_to_atom'(Segments, File), 1226 '$make_path'(Exp1, File, Expanded). 1227'$expand_file_search_path'(Spec, Path, _, _) :- 1228 '$segments_to_atom'(Spec, Path). 1229 1230'$make_path'(Dir, '.', Path) :- 1231 !, 1232 Path = Dir. 1233'$make_path'(Dir, File, Path) :- 1234 sub_atom(Dir, _, _, 0, /), 1235 !, 1236 atom_concat(Dir, File, Path). 1237'$make_path'(Dir, File, Path) :- 1238 atomic_list_concat([Dir, /, File], Path). 1239 1240 1241 /******************************** 1242 * FILE CHECKING * 1243 *********************************/
1254absolute_file_name(Spec, Options, Path) :- 1255 '$is_options'(Options), 1256 \+ '$is_options'(Path), 1257 !, 1258 '$absolute_file_name'(Spec, Path, Options). 1259absolute_file_name(Spec, Path, Options) :- 1260 '$absolute_file_name'(Spec, Path, Options). 1261 1262'$absolute_file_name'(Spec, Path, Options0) :- 1263 '$options_dict'(Options0, Options), 1264 % get the valid extensions 1265 ( '$select_option'(extensions(Exts), Options, Options1) 1266 -> '$must_be'(list, Exts) 1267 ; '$option'(file_type(Type), Options) 1268 -> '$must_be'(atom, Type), 1269 '$file_type_extensions'(Type, Exts), 1270 Options1 = Options 1271 ; Options1 = Options, 1272 Exts = [''] 1273 ), 1274 '$canonicalise_extensions'(Exts, Extensions), 1275 % unless specified otherwise, ask regular file 1276 ( ( nonvar(Type) 1277 ; '$option'(access(none), Options, none) 1278 ) 1279 -> Options2 = Options1 1280 ; '$merge_options'(_{file_type:regular}, Options1, Options2) 1281 ), 1282 % Det or nondet? 1283 ( '$select_option'(solutions(Sols), Options2, Options3) 1284 -> '$must_be'(oneof(atom, solutions, [first,all]), Sols) 1285 ; Sols = first, 1286 Options3 = Options2 1287 ), 1288 % Errors or not? 1289 ( '$select_option'(file_errors(FileErrors), Options3, Options4) 1290 -> '$must_be'(oneof(atom, file_errors, [error,fail]), FileErrors) 1291 ; FileErrors = error, 1292 Options4 = Options3 1293 ), 1294 % Expand shell patterns? 1295 ( atomic(Spec), 1296 '$select_option'(expand(Expand), Options4, Options5), 1297 '$must_be'(boolean, Expand) 1298 -> expand_file_name(Spec, List), 1299 '$member'(Spec1, List) 1300 ; Spec1 = Spec, 1301 Options5 = Options4 1302 ), 1303 % Search for files 1304 ( Sols == first 1305 -> ( '$chk_file'(Spec1, Extensions, Options5, true, Path) 1306 -> ! % also kill choice point of expand_file_name/2 1307 ; ( FileErrors == fail 1308 -> fail 1309 ; '$current_module'('$bags', _File), 1310 findall(P, 1311 '$chk_file'(Spec1, Extensions, [access(exist)], 1312 false, P), 1313 Candidates), 1314 '$abs_file_error'(Spec, Candidates, Options5) 1315 ) 1316 ) 1317 ; '$chk_file'(Spec1, Extensions, Options5, false, Path) 1318 ). 1319 1320'$abs_file_error'(Spec, Candidates, Conditions) :- 1321 '$member'(F, Candidates), 1322 '$member'(C, Conditions), 1323 '$file_condition'(C), 1324 '$file_error'(C, Spec, F, E, Comment), 1325 !, 1326 throw(error(E, context(_, Comment))). 1327'$abs_file_error'(Spec, _, _) :- 1328 '$existence_error'(source_sink, Spec). 1329 1330'$file_error'(file_type(directory), Spec, File, Error, Comment) :- 1331 \+ exists_directory(File), 1332 !, 1333 Error = existence_error(directory, Spec), 1334 Comment = not_a_directory(File). 1335'$file_error'(file_type(_), Spec, File, Error, Comment) :- 1336 exists_directory(File), 1337 !, 1338 Error = existence_error(file, Spec), 1339 Comment = directory(File). 1340'$file_error'(access(OneOrList), Spec, File, Error, _) :- 1341 '$one_or_member'(Access, OneOrList), 1342 \+ access_file(File, Access), 1343 Error = permission_error(Access, source_sink, Spec). 1344 1345'$one_or_member'(Elem, List) :- 1346 is_list(List), 1347 !, 1348 '$member'(Elem, List). 1349'$one_or_member'(Elem, Elem). 1350 1351 1352'$file_type_extensions'(source, Exts) :- % SICStus 3.9 compatibility 1353 !, 1354 '$file_type_extensions'(prolog, Exts). 1355'$file_type_extensions'(Type, Exts) :- 1356 '$current_module'('$bags', _File), 1357 !, 1358 findall(Ext, user:prolog_file_type(Ext, Type), Exts0), 1359 ( Exts0 == [], 1360 \+ '$ft_no_ext'(Type) 1361 -> '$domain_error'(file_type, Type) 1362 ; true 1363 ), 1364 '$append'(Exts0, [''], Exts). 1365'$file_type_extensions'(prolog, [pl, '']). % findall is not yet defined ... 1366 1367'$ft_no_ext'(txt). 1368'$ft_no_ext'(executable). 1369'$ft_no_ext'(directory). 1370'$ft_no_ext'(regular).
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.
1383:- multifile(user:prolog_file_type/2). 1384:- dynamic(user:prolog_file_type/2). 1385 1386userprolog_file_type(pl, prolog). 1387userprolog_file_type(prolog, prolog). 1388userprolog_file_type(qlf, prolog). 1389userprolog_file_type(qlf, qlf). 1390userprolog_file_type(Ext, executable) :- 1391 current_prolog_flag(shared_object_extension, Ext). 1392userprolog_file_type(dylib, executable) :- 1393 current_prolog_flag(apple, true).
1400'$chk_file'(Spec, _Extensions, _Cond, _Cache, _FullName) :- 1401 \+ ground(Spec), 1402 !, 1403 '$instantiation_error'(Spec). 1404'$chk_file'(Spec, Extensions, Cond, Cache, FullName) :- 1405 compound(Spec), 1406 functor(Spec, _, 1), 1407 !, 1408 '$relative_to'(Cond, cwd, CWD), 1409 '$chk_alias_file'(Spec, Extensions, Cond, Cache, CWD, FullName). 1410'$chk_file'(Segments, Ext, Cond, Cache, FullName) :- % allow a/b/... 1411 \+ atomic(Segments), 1412 !, 1413 '$segments_to_atom'(Segments, Atom), 1414 '$chk_file'(Atom, Ext, Cond, Cache, FullName). 1415'$chk_file'(File, Exts, Cond, _, FullName) :- % Absolute files 1416 is_absolute_file_name(File), 1417 !, 1418 '$extend_file'(File, Exts, Extended), 1419 '$file_conditions'(Cond, Extended), 1420 '$absolute_file_name'(Extended, FullName). 1421'$chk_file'(File, Exts, Cond, _, FullName) :- % Explicit relative_to 1422 '$option'(relative_to(_), Cond), 1423 !, 1424 '$relative_to'(Cond, none, Dir), 1425 '$chk_file_relative_to'(File, Exts, Cond, Dir, FullName). 1426'$chk_file'(File, Exts, Cond, _Cache, FullName) :- % From source 1427 source_location(ContextFile, _Line), 1428 !, 1429 ( file_directory_name(ContextFile, Dir), 1430 '$chk_file_relative_to'(File, Exts, Cond, Dir, FullName) 1431 -> true 1432 ; current_prolog_flag(source_search_working_directory, true), 1433 '$extend_file'(File, Exts, Extended), 1434 '$file_conditions'(Cond, Extended), 1435 '$absolute_file_name'(Extended, FullName), 1436 '$print_message'(warning, 1437 deprecated(source_search_working_directory( 1438 File, FullName))) 1439 ). 1440'$chk_file'(File, Exts, Cond, _Cache, FullName) :- % Not loading source 1441 '$extend_file'(File, Exts, Extended), 1442 '$file_conditions'(Cond, Extended), 1443 '$absolute_file_name'(Extended, FullName). 1444 1445'$chk_file_relative_to'(File, Exts, Cond, Dir, FullName) :- 1446 atomic_list_concat([Dir, /, File], AbsFile), 1447 '$extend_file'(AbsFile, Exts, Extended), 1448 '$file_conditions'(Cond, Extended), 1449 '$absolute_file_name'(Extended, FullName). 1450 1451 1452'$segments_to_atom'(Atom, Atom) :- 1453 atomic(Atom), 1454 !. 1455'$segments_to_atom'(Segments, Atom) :- 1456 '$segments_to_list'(Segments, List, []), 1457 !, 1458 atomic_list_concat(List, /, Atom). 1459 1460'$segments_to_list'(A/B, H, T) :- 1461 '$segments_to_list'(A, H, T0), 1462 '$segments_to_list'(B, T0, T). 1463'$segments_to_list'(A, [A|T], T) :- 1464 atomic(A).
relative_to(FileOrDir)
options
or implicitely relative to the working directory or current
source-file.
1474'$relative_to'(Conditions, Default, Dir) :-
1475 ( '$option'(relative_to(FileOrDir), Conditions)
1476 *-> ( exists_directory(FileOrDir)
1477 -> Dir = FileOrDir
1478 ; atom_concat(Dir, /, FileOrDir)
1479 -> true
1480 ; file_directory_name(FileOrDir, Dir)
1481 )
1482 ; Default == cwd
1483 -> working_directory(Dir, Dir)
1484 ; Default == source
1485 -> source_location(ContextFile, _Line),
1486 file_directory_name(ContextFile, Dir)
1487 ).
1492:- dynamic 1493 '$search_path_file_cache'/3, % SHA1, Time, Path 1494 '$search_path_gc_time'/1. % Time 1495:- volatile 1496 '$search_path_file_cache'/3, 1497 '$search_path_gc_time'/1. 1498:- '$notransact'(('$search_path_file_cache'/3, 1499 '$search_path_gc_time'/1)). 1500 1501:- create_prolog_flag(file_search_cache_time, 10, []). 1502 1503'$chk_alias_file'(Spec, Exts, Cond, true, CWD, FullFile) :- 1504 !, 1505 findall(Exp, '$expand_file_search_path'(Spec, Exp, Cond), Expansions), 1506 current_prolog_flag(emulated_dialect, Dialect), 1507 Cache = cache(Exts, Cond, CWD, Expansions, Dialect), 1508 variant_sha1(Spec+Cache, SHA1), 1509 get_time(Now), 1510 current_prolog_flag(file_search_cache_time, TimeOut), 1511 ( '$search_path_file_cache'(SHA1, CachedTime, FullFile), 1512 CachedTime > Now - TimeOut, 1513 '$file_conditions'(Cond, FullFile) 1514 -> '$search_message'(file_search(cache(Spec, Cond), FullFile)) 1515 ; '$member'(Expanded, Expansions), 1516 '$extend_file'(Expanded, Exts, LibFile), 1517 ( '$file_conditions'(Cond, LibFile), 1518 '$absolute_file_name'(LibFile, FullFile), 1519 '$cache_file_found'(SHA1, Now, TimeOut, FullFile) 1520 -> '$search_message'(file_search(found(Spec, Cond), FullFile)) 1521 ; '$search_message'(file_search(tried(Spec, Cond), LibFile)), 1522 fail 1523 ) 1524 ). 1525'$chk_alias_file'(Spec, Exts, Cond, false, _CWD, FullFile) :- 1526 '$expand_file_search_path'(Spec, Expanded, Cond), 1527 '$extend_file'(Expanded, Exts, LibFile), 1528 '$file_conditions'(Cond, LibFile), 1529 '$absolute_file_name'(LibFile, FullFile). 1530 1531'$cache_file_found'(_, _, TimeOut, _) :- 1532 TimeOut =:= 0, 1533 !. 1534'$cache_file_found'(SHA1, Now, TimeOut, FullFile) :- 1535 '$search_path_file_cache'(SHA1, Saved, FullFile), 1536 !, 1537 ( Now - Saved < TimeOut/2 1538 -> true 1539 ; retractall('$search_path_file_cache'(SHA1, _, _)), 1540 asserta('$search_path_file_cache'(SHA1, Now, FullFile)) 1541 ). 1542'$cache_file_found'(SHA1, Now, TimeOut, FullFile) :- 1543 'gc_file_search_cache'(TimeOut), 1544 asserta('$search_path_file_cache'(SHA1, Now, FullFile)). 1545 1546'gc_file_search_cache'(TimeOut) :- 1547 get_time(Now), 1548 '$search_path_gc_time'(Last), 1549 Now-Last < TimeOut/2, 1550 !. 1551'gc_file_search_cache'(TimeOut) :- 1552 get_time(Now), 1553 retractall('$search_path_gc_time'(_)), 1554 assertz('$search_path_gc_time'(Now)), 1555 Before is Now - TimeOut, 1556 ( '$search_path_file_cache'(SHA1, Cached, FullFile), 1557 Cached < Before, 1558 retractall('$search_path_file_cache'(SHA1, Cached, FullFile)), 1559 fail 1560 ; true 1561 ). 1562 1563 1564'$search_message'(Term) :- 1565 current_prolog_flag(verbose_file_search, true), 1566 !, 1567 print_message(informational, Term). 1568'$search_message'(_).
1575'$file_conditions'(List, File) :- 1576 is_list(List), 1577 !, 1578 \+ ( '$member'(C, List), 1579 '$file_condition'(C), 1580 \+ '$file_condition'(C, File) 1581 ). 1582'$file_conditions'(Map, File) :- 1583 \+ ( get_dict(Key, Map, Value), 1584 C =.. [Key,Value], 1585 '$file_condition'(C), 1586 \+ '$file_condition'(C, File) 1587 ). 1588 1589'$file_condition'(file_type(directory), File) :- 1590 !, 1591 exists_directory(File). 1592'$file_condition'(file_type(_), File) :- 1593 !, 1594 \+ exists_directory(File). 1595'$file_condition'(access(Accesses), File) :- 1596 !, 1597 \+ ( '$one_or_member'(Access, Accesses), 1598 \+ access_file(File, Access) 1599 ). 1600 1601'$file_condition'(exists). 1602'$file_condition'(file_type(_)). 1603'$file_condition'(access(_)). 1604 1605'$extend_file'(File, Exts, FileEx) :- 1606 '$ensure_extensions'(Exts, File, Fs), 1607 '$list_to_set'(Fs, FsSet), 1608 '$member'(FileEx, FsSet). 1609 1610'$ensure_extensions'([], _, []). 1611'$ensure_extensions'([E|E0], F, [FE|E1]) :- 1612 file_name_extension(F, E, FE), 1613 '$ensure_extensions'(E0, F, E1).
1620'$list_to_set'(List, Set) :- 1621 '$number_list'(List, 1, Numbered), 1622 sort(1, @=<, Numbered, ONum), 1623 '$remove_dup_keys'(ONum, NumSet), 1624 sort(2, @=<, NumSet, ONumSet), 1625 '$pairs_keys'(ONumSet, Set). 1626 1627'$number_list'([], _, []). 1628'$number_list'([H|T0], N, [H-N|T]) :- 1629 N1 is N+1, 1630 '$number_list'(T0, N1, T). 1631 1632'$remove_dup_keys'([], []). 1633'$remove_dup_keys'([H|T0], [H|T]) :- 1634 H = V-_, 1635 '$remove_same_key'(T0, V, T1), 1636 '$remove_dup_keys'(T1, T). 1637 1638'$remove_same_key'([V1-_|T0], V, T) :- 1639 V1 == V, 1640 !, 1641 '$remove_same_key'(T0, V, T). 1642'$remove_same_key'(L, _, L). 1643 1644'$pairs_keys'([], []). 1645'$pairs_keys'([K-_|T0], [K|T]) :- 1646 '$pairs_keys'(T0, T). 1647 1648'$pairs_values'([], []). 1649'$pairs_values'([_-V|T0], [V|T]) :- 1650 '$pairs_values'(T0, T). 1651 1652/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1653Canonicalise the extension list. Old SWI-Prolog require `.pl', etc, which 1654the Quintus compatibility requests `pl'. This layer canonicalises all 1655extensions to .ext 1656- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1657 1658'$canonicalise_extensions'([], []) :- !. 1659'$canonicalise_extensions'([H|T], [CH|CT]) :- 1660 !, 1661 '$must_be'(atom, H), 1662 '$canonicalise_extension'(H, CH), 1663 '$canonicalise_extensions'(T, CT). 1664'$canonicalise_extensions'(E, [CE]) :- 1665 '$canonicalise_extension'(E, CE). 1666 1667'$canonicalise_extension'('', '') :- !. 1668'$canonicalise_extension'(DotAtom, DotAtom) :- 1669 sub_atom(DotAtom, 0, _, _, '.'), 1670 !. 1671'$canonicalise_extension'(Atom, DotAtom) :- 1672 atom_concat('.', Atom, DotAtom). 1673 1674 1675 /******************************** 1676 * CONSULT * 1677 *********************************/ 1678 1679:- dynamic 1680 user:library_directory/1, 1681 user:prolog_load_file/2. 1682:- multifile 1683 user:library_directory/1, 1684 user:prolog_load_file/2. 1685 1686:- prompt(_, '|: '). 1687 1688:- thread_local 1689 '$compilation_mode_store'/1, % database, wic, qlf 1690 '$directive_mode_store'/1. % database, wic, qlf 1691:- volatile 1692 '$compilation_mode_store'/1, 1693 '$directive_mode_store'/1. 1694:- '$notransact'(('$compilation_mode_store'/1, 1695 '$directive_mode_store'/1)). 1696 1697'$compilation_mode'(Mode) :- 1698 ( '$compilation_mode_store'(Val) 1699 -> Mode = Val 1700 ; Mode = database 1701 ). 1702 1703'$set_compilation_mode'(Mode) :- 1704 retractall('$compilation_mode_store'(_)), 1705 assertz('$compilation_mode_store'(Mode)). 1706 1707'$compilation_mode'(Old, New) :- 1708 '$compilation_mode'(Old), 1709 ( New == Old 1710 -> true 1711 ; '$set_compilation_mode'(New) 1712 ). 1713 1714'$directive_mode'(Mode) :- 1715 ( '$directive_mode_store'(Val) 1716 -> Mode = Val 1717 ; Mode = database 1718 ). 1719 1720'$directive_mode'(Old, New) :- 1721 '$directive_mode'(Old), 1722 ( New == Old 1723 -> true 1724 ; '$set_directive_mode'(New) 1725 ). 1726 1727'$set_directive_mode'(Mode) :- 1728 retractall('$directive_mode_store'(_)), 1729 assertz('$directive_mode_store'(Mode)).
1737'$compilation_level'(Level) :- 1738 '$input_context'(Stack), 1739 '$compilation_level'(Stack, Level). 1740 1741'$compilation_level'([], 0). 1742'$compilation_level'([Input|T], Level) :- 1743 ( arg(1, Input, see) 1744 -> '$compilation_level'(T, Level) 1745 ; '$compilation_level'(T, Level0), 1746 Level is Level0+1 1747 ).
1755compiling :- 1756 \+ ( '$compilation_mode'(database), 1757 '$directive_mode'(database) 1758 ). 1759 1760:- meta_predicate 1761 '$ifcompiling'( ). 1762 1763'$ifcompiling'(G) :- 1764 ( '$compilation_mode'(database) 1765 -> true 1766 ; call(G) 1767 ). 1768 1769 /******************************** 1770 * READ SOURCE * 1771 *********************************/
1775'$load_msg_level'(Action, Nesting, Start, Done) :- 1776 '$update_autoload_level'([], 0), 1777 !, 1778 current_prolog_flag(verbose_load, Type0), 1779 '$load_msg_compat'(Type0, Type), 1780 ( '$load_msg_level'(Action, Nesting, Type, Start, Done) 1781 -> true 1782 ). 1783'$load_msg_level'(_, _, silent, silent). 1784 1785'$load_msg_compat'(true, normal) :- !. 1786'$load_msg_compat'(false, silent) :- !. 1787'$load_msg_compat'(X, X). 1788 1789'$load_msg_level'(load_file, _, full, informational, informational). 1790'$load_msg_level'(include_file, _, full, informational, informational). 1791'$load_msg_level'(load_file, _, normal, silent, informational). 1792'$load_msg_level'(include_file, _, normal, silent, silent). 1793'$load_msg_level'(load_file, 0, brief, silent, informational). 1794'$load_msg_level'(load_file, _, brief, silent, silent). 1795'$load_msg_level'(include_file, _, brief, silent, silent). 1796'$load_msg_level'(load_file, _, silent, silent, silent). 1797'$load_msg_level'(include_file, _, silent, silent, silent).
1820'$source_term'(From, Read, RLayout, Term, TLayout, Stream, Options) :- 1821 '$source_term'(From, Read, RLayout, Term, TLayout, Stream, [], Options), 1822 ( Term == end_of_file 1823 -> !, fail 1824 ; Term \== begin_of_file 1825 ). 1826 1827'$source_term'(Input, _,_,_,_,_,_,_) :- 1828 \+ ground(Input), 1829 !, 1830 '$instantiation_error'(Input). 1831'$source_term'(stream(Id, In, Opts), 1832 Read, RLayout, Term, TLayout, Stream, Parents, Options) :- 1833 !, 1834 '$record_included'(Parents, Id, Id, 0.0, Message), 1835 setup_call_cleanup( 1836 '$open_source'(stream(Id, In, Opts), In, State, Parents, Options), 1837 '$term_in_file'(In, Read, RLayout, Term, TLayout, Stream, 1838 [Id|Parents], Options), 1839 '$close_source'(State, Message)). 1840'$source_term'(File, 1841 Read, RLayout, Term, TLayout, Stream, Parents, Options) :- 1842 absolute_file_name(File, Path, 1843 [ file_type(prolog), 1844 access(read) 1845 ]), 1846 time_file(Path, Time), 1847 '$record_included'(Parents, File, Path, Time, Message), 1848 setup_call_cleanup( 1849 '$open_source'(Path, In, State, Parents, Options), 1850 '$term_in_file'(In, Read, RLayout, Term, TLayout, Stream, 1851 [Path|Parents], Options), 1852 '$close_source'(State, Message)). 1853 1854:- thread_local 1855 '$load_input'/2. 1856:- volatile 1857 '$load_input'/2. 1858:- '$notransact'('$load_input'/2). 1859 1860'$open_source'(stream(Id, In, Opts), In, 1861 restore(In, StreamState, Id, Ref, Opts), Parents, _Options) :- 1862 !, 1863 '$context_type'(Parents, ContextType), 1864 '$push_input_context'(ContextType), 1865 '$prepare_load_stream'(In, Id, StreamState), 1866 asserta('$load_input'(stream(Id), In), Ref). 1867'$open_source'(Path, In, close(In, Path, Ref), Parents, Options) :- 1868 '$context_type'(Parents, ContextType), 1869 '$push_input_context'(ContextType), 1870 '$open_source'(Path, In, Options), 1871 '$set_encoding'(In, Options), 1872 asserta('$load_input'(Path, In), Ref). 1873 1874'$context_type'([], load_file) :- !. 1875'$context_type'(_, include). 1876 1877:- multifile prolog:open_source_hook/3. 1878 1879'$open_source'(Path, In, Options) :- 1880 prolog:open_source_hook(Path, In, Options), 1881 !. 1882'$open_source'(Path, In, _Options) :- 1883 open(Path, read, In). 1884 1885'$close_source'(close(In, _Id, Ref), Message) :- 1886 erase(Ref), 1887 call_cleanup( 1888 close(In), 1889 '$pop_input_context'), 1890 '$close_message'(Message). 1891'$close_source'(restore(In, StreamState, _Id, Ref, Opts), Message) :- 1892 erase(Ref), 1893 call_cleanup( 1894 '$restore_load_stream'(In, StreamState, Opts), 1895 '$pop_input_context'), 1896 '$close_message'(Message). 1897 1898'$close_message'(message(Level, Msg)) :- 1899 !, 1900 '$print_message'(Level, Msg). 1901'$close_message'(_).
1913'$term_in_file'(In, Read, RLayout, Term, TLayout, Stream, Parents, Options) :- 1914 Parents \= [_,_|_], 1915 ( '$load_input'(_, Input) 1916 -> stream_property(Input, file_name(File)) 1917 ), 1918 '$set_source_location'(File, 0), 1919 '$expanded_term'(In, 1920 begin_of_file, 0-0, Read, RLayout, Term, TLayout, 1921 Stream, Parents, Options). 1922'$term_in_file'(In, Read, RLayout, Term, TLayout, Stream, Parents, Options) :- 1923 '$skip_script_line'(In, Options), 1924 '$read_clause_options'(Options, ReadOptions), 1925 '$repeat_and_read_error_mode'(ErrorMode), 1926 read_clause(In, Raw, 1927 [ syntax_errors(ErrorMode), 1928 variable_names(Bindings), 1929 term_position(Pos), 1930 subterm_positions(RawLayout) 1931 | ReadOptions 1932 ]), 1933 b_setval('$term_position', Pos), 1934 b_setval('$variable_names', Bindings), 1935 ( Raw == end_of_file 1936 -> !, 1937 ( Parents = [_,_|_] % Included file 1938 -> fail 1939 ; '$expanded_term'(In, 1940 Raw, RawLayout, Read, RLayout, Term, TLayout, 1941 Stream, Parents, Options) 1942 ) 1943 ; '$expanded_term'(In, Raw, RawLayout, Read, RLayout, Term, TLayout, 1944 Stream, Parents, Options) 1945 ). 1946 1947'$read_clause_options'([], []). 1948'$read_clause_options'([H|T0], List) :- 1949 ( '$read_clause_option'(H) 1950 -> List = [H|T] 1951 ; List = T 1952 ), 1953 '$read_clause_options'(T0, T). 1954 1955'$read_clause_option'(syntax_errors(_)). 1956'$read_clause_option'(term_position(_)). 1957'$read_clause_option'(process_comment(_)).
expand.pl
is not yet
loaded.1965'$repeat_and_read_error_mode'(Mode) :- 1966 ( current_predicate('$including'/0) 1967 -> repeat, 1968 ( '$including' 1969 -> Mode = dec10 1970 ; Mode = quiet 1971 ) 1972 ; Mode = dec10, 1973 repeat 1974 ). 1975 1976 1977'$expanded_term'(In, Raw, RawLayout, Read, RLayout, Term, TLayout, 1978 Stream, Parents, Options) :- 1979 E = error(_,_), 1980 catch('$expand_term'(Raw, RawLayout, Expanded, ExpandedLayout), E, 1981 '$print_message_fail'(E)), 1982 ( Expanded \== [] 1983 -> '$expansion_member'(Expanded, ExpandedLayout, Term1, Layout1) 1984 ; Term1 = Expanded, 1985 Layout1 = ExpandedLayout 1986 ), 1987 ( nonvar(Term1), Term1 = (:-Directive), nonvar(Directive) 1988 -> ( Directive = include(File), 1989 '$current_source_module'(Module), 1990 '$valid_directive'(Module:include(File)) 1991 -> stream_property(In, encoding(Enc)), 1992 '$add_encoding'(Enc, Options, Options1), 1993 '$source_term'(File, Read, RLayout, Term, TLayout, 1994 Stream, Parents, Options1) 1995 ; Directive = encoding(Enc) 1996 -> set_stream(In, encoding(Enc)), 1997 fail 1998 ; Term = Term1, 1999 Stream = In, 2000 Read = Raw 2001 ) 2002 ; Term = Term1, 2003 TLayout = Layout1, 2004 Stream = In, 2005 Read = Raw, 2006 RLayout = RawLayout 2007 ). 2008 2009'$expansion_member'(Var, Layout, Var, Layout) :- 2010 var(Var), 2011 !. 2012'$expansion_member'([], _, _, _) :- !, fail. 2013'$expansion_member'(List, ListLayout, Term, Layout) :- 2014 is_list(List), 2015 !, 2016 ( var(ListLayout) 2017 -> '$member'(Term, List) 2018 ; is_list(ListLayout) 2019 -> '$member_rep2'(Term, Layout, List, ListLayout) 2020 ; Layout = ListLayout, 2021 '$member'(Term, List) 2022 ). 2023'$expansion_member'(X, Layout, X, Layout). 2024 2025% pairwise member, repeating last element of the second 2026% list. 2027 2028'$member_rep2'(H1, H2, [H1|_], [H2|_]). 2029'$member_rep2'(H1, H2, [_|T1], [T2]) :- 2030 !, 2031 '$member_rep2'(H1, H2, T1, [T2]). 2032'$member_rep2'(H1, H2, [_|T1], [_|T2]) :- 2033 '$member_rep2'(H1, H2, T1, T2).
2037'$add_encoding'(Enc, Options0, Options) :- 2038 ( Options0 = [encoding(Enc)|_] 2039 -> Options = Options0 2040 ; Options = [encoding(Enc)|Options0] 2041 ). 2042 2043 2044:- multifile 2045 '$included'/4. % Into, Line, File, LastModified 2046:- dynamic 2047 '$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'.
2061'$record_included'([Parent|Parents], File, Path, Time, 2062 message(DoneMsgLevel, 2063 include_file(done(Level, file(File, Path))))) :- 2064 source_location(SrcFile, Line), 2065 !, 2066 '$compilation_level'(Level), 2067 '$load_msg_level'(include_file, Level, StartMsgLevel, DoneMsgLevel), 2068 '$print_message'(StartMsgLevel, 2069 include_file(start(Level, 2070 file(File, Path)))), 2071 '$last'([Parent|Parents], Owner), 2072 ( ( '$compilation_mode'(database) 2073 ; '$qlf_current_source'(Owner) 2074 ) 2075 -> '$store_admin_clause'( 2076 system:'$included'(Parent, Line, Path, Time), 2077 _, Owner, SrcFile:Line) 2078 ; '$qlf_include'(Owner, Parent, Line, Path, Time) 2079 ). 2080'$record_included'(_, _, _, _, true).
2086'$master_file'(File, MasterFile) :- 2087 '$included'(MasterFile0, _Line, File, _Time), 2088 !, 2089 '$master_file'(MasterFile0, MasterFile). 2090'$master_file'(File, File). 2091 2092 2093'$skip_script_line'(_In, Options) :- 2094 '$option'(check_script(false), Options), 2095 !. 2096'$skip_script_line'(In, _Options) :- 2097 ( peek_char(In, #) 2098 -> skip(In, 10) 2099 ; true 2100 ). 2101 2102'$set_encoding'(Stream, Options) :- 2103 '$option'(encoding(Enc), Options), 2104 !, 2105 Enc \== default, 2106 set_stream(Stream, encoding(Enc)). 2107'$set_encoding'(_, _). 2108 2109 2110'$prepare_load_stream'(In, Id, state(HasName,HasPos)) :- 2111 ( stream_property(In, file_name(_)) 2112 -> HasName = true, 2113 ( stream_property(In, position(_)) 2114 -> HasPos = true 2115 ; HasPos = false, 2116 set_stream(In, record_position(true)) 2117 ) 2118 ; HasName = false, 2119 set_stream(In, file_name(Id)), 2120 ( stream_property(In, position(_)) 2121 -> HasPos = true 2122 ; HasPos = false, 2123 set_stream(In, record_position(true)) 2124 ) 2125 ). 2126 2127'$restore_load_stream'(In, _State, Options) :- 2128 memberchk(close(true), Options), 2129 !, 2130 close(In). 2131'$restore_load_stream'(In, state(HasName, HasPos), _Options) :- 2132 ( HasName == false 2133 -> set_stream(In, file_name('')) 2134 ; true 2135 ), 2136 ( HasPos == false 2137 -> set_stream(In, record_position(false)) 2138 ; true 2139 ). 2140 2141 2142 /******************************* 2143 * DERIVED FILES * 2144 *******************************/ 2145 2146:- dynamic 2147 '$derived_source_db'/3. % Loaded, DerivedFrom, Time 2148 2149'$register_derived_source'(_, '-') :- !. 2150'$register_derived_source'(Loaded, DerivedFrom) :- 2151 retractall('$derived_source_db'(Loaded, _, _)), 2152 time_file(DerivedFrom, Time), 2153 assert('$derived_source_db'(Loaded, DerivedFrom, Time)). 2154 2155% Auto-importing dynamic predicates is not very elegant and 2156% leads to problems with qsave_program/[1,2] 2157 2158'$derived_source'(Loaded, DerivedFrom, Time) :- 2159 '$derived_source_db'(Loaded, DerivedFrom, Time). 2160 2161 2162 /******************************** 2163 * LOAD PREDICATES * 2164 *********************************/ 2165 2166:- meta_predicate 2167 ensure_loaded( ), 2168 [, | ] 2169 consult( ), 2170 use_module( ), 2171 use_module( , ), 2172 reexport( ), 2173 reexport( , ), 2174 load_files( ), 2175 load_files( , ).
2183ensure_loaded(Files) :-
2184 load_files(Files, [if(not_loaded)]).
2193use_module(Files) :-
2194 load_files(Files, [ if(not_loaded),
2195 must_be_module(true)
2196 ]).
2203use_module(File, Import) :-
2204 load_files(File, [ if(not_loaded),
2205 must_be_module(true),
2206 imports(Import)
2207 ]).
2213reexport(Files) :-
2214 load_files(Files, [ if(not_loaded),
2215 must_be_module(true),
2216 reexport(true)
2217 ]).
2223reexport(File, Import) :- 2224 load_files(File, [ if(not_loaded), 2225 must_be_module(true), 2226 imports(Import), 2227 reexport(true) 2228 ]). 2229 2230 2231[X] :- 2232 !, 2233 consult(X). 2234[M:F|R] :- 2235 consult(M:[F|R]). 2236 2237consult(M:X) :- 2238 X == user, 2239 !, 2240 flag('$user_consult', N, N+1), 2241 NN is N + 1, 2242 atom_concat('user://', NN, Id), 2243 load_files(M:Id, [stream(user_input), check_script(false), silent(false)]). 2244consult(List) :- 2245 load_files(List, [expand(true)]).
2252load_files(Files) :- 2253 load_files(Files, []). 2254load_files(Module:Files, Options) :- 2255 '$must_be'(list, Options), 2256 '$load_files'(Files, Module, Options). 2257 2258'$load_files'(X, _, _) :- 2259 var(X), 2260 !, 2261 '$instantiation_error'(X). 2262'$load_files'([], _, _) :- !. 2263'$load_files'(Id, Module, Options) :- % load_files(foo, [stream(In)]) 2264 '$option'(stream(_), Options), 2265 !, 2266 ( atom(Id) 2267 -> '$load_file'(Id, Module, Options) 2268 ; throw(error(type_error(atom, Id), _)) 2269 ). 2270'$load_files'(List, Module, Options) :- 2271 List = [_|_], 2272 !, 2273 '$must_be'(list, List), 2274 '$load_file_list'(List, Module, Options). 2275'$load_files'(File, Module, Options) :- 2276 '$load_one_file'(File, Module, Options). 2277 2278'$load_file_list'([], _, _). 2279'$load_file_list'([File|Rest], Module, Options) :- 2280 E = error(_,_), 2281 catch('$load_one_file'(File, Module, Options), E, 2282 '$print_message'(error, E)), 2283 '$load_file_list'(Rest, Module, Options). 2284 2285 2286'$load_one_file'(Spec, Module, Options) :- 2287 atomic(Spec), 2288 '$option'(expand(Expand), Options, false), 2289 Expand == true, 2290 !, 2291 expand_file_name(Spec, Expanded), 2292 ( Expanded = [Load] 2293 -> true 2294 ; Load = Expanded 2295 ), 2296 '$load_files'(Load, Module, [expand(false)|Options]). 2297'$load_one_file'(File, Module, Options) :- 2298 strip_module(Module:File, Into, PlainFile), 2299 '$load_file'(PlainFile, Into, Options).
2306'$noload'(true, _, _) :- 2307 !, 2308 fail. 2309'$noload'(_, FullFile, _Options) :- 2310 '$time_source_file'(FullFile, Time, system), 2311 float(Time), 2312 !. 2313'$noload'(not_loaded, FullFile, _) :- 2314 source_file(FullFile), 2315 !. 2316'$noload'(changed, Derived, _) :- 2317 '$derived_source'(_FullFile, Derived, LoadTime), 2318 time_file(Derived, Modified), 2319 Modified @=< LoadTime, 2320 !. 2321'$noload'(changed, FullFile, Options) :- 2322 '$time_source_file'(FullFile, LoadTime, user), 2323 '$modified_id'(FullFile, Modified, Options), 2324 Modified @=< LoadTime, 2325 !. 2326'$noload'(exists, File, Options) :- 2327 '$noload'(changed, File, Options).
2346'$qlf_file'(Spec, _, Spec, stream, Options) :- 2347 '$option'(stream(_), Options), % stream: no choice 2348 !. 2349'$qlf_file'(Spec, FullFile, FullFile, compile, _) :- 2350 '$spec_extension'(Spec, Ext), % user explicitly specified 2351 user:prolog_file_type(Ext, prolog), 2352 !. 2353'$qlf_file'(Spec, FullFile, LoadFile, Mode, Options) :- 2354 '$compilation_mode'(database), 2355 file_name_extension(Base, PlExt, FullFile), 2356 user:prolog_file_type(PlExt, prolog), 2357 user:prolog_file_type(QlfExt, qlf), 2358 file_name_extension(Base, QlfExt, QlfFile), 2359 ( access_file(QlfFile, read), 2360 ( '$qlf_out_of_date'(FullFile, QlfFile, Why) 2361 -> ( access_file(QlfFile, write) 2362 -> print_message(informational, 2363 qlf(recompile(Spec, FullFile, QlfFile, Why))), 2364 Mode = qcompile, 2365 LoadFile = FullFile 2366 ; Why == old, 2367 ( current_prolog_flag(home, PlHome), 2368 sub_atom(FullFile, 0, _, _, PlHome) 2369 ; sub_atom(QlfFile, 0, _, _, 'res://') 2370 ) 2371 -> print_message(silent, 2372 qlf(system_lib_out_of_date(Spec, QlfFile))), 2373 Mode = qload, 2374 LoadFile = QlfFile 2375 ; print_message(warning, 2376 qlf(can_not_recompile(Spec, QlfFile, Why))), 2377 Mode = compile, 2378 LoadFile = FullFile 2379 ) 2380 ; Mode = qload, 2381 LoadFile = QlfFile 2382 ) 2383 -> ! 2384 ; '$qlf_auto'(FullFile, QlfFile, Options) 2385 -> !, Mode = qcompile, 2386 LoadFile = FullFile 2387 ). 2388'$qlf_file'(_, FullFile, FullFile, compile, _).
2396'$qlf_out_of_date'(PlFile, QlfFile, Why) :-
2397 ( access_file(PlFile, read)
2398 -> time_file(PlFile, PlTime),
2399 time_file(QlfFile, QlfTime),
2400 ( PlTime > QlfTime
2401 -> Why = old % PlFile is newer
2402 ; Error = error(Formal,_),
2403 catch('$qlf_is_compatible'(QlfFile), Error, true),
2404 nonvar(Formal) % QlfFile is incompatible
2405 -> Why = Error
2406 ; fail % QlfFile is up-to-date and ok
2407 )
2408 ; fail % can not read .pl; try .qlf
2409 ).
qcompile(QlfMode)
or, if this is not present, by
the prolog_flag qcompile.2417:- create_prolog_flag(qcompile, false, [type(atom)]). 2418 2419'$qlf_auto'(PlFile, QlfFile, Options) :- 2420 ( memberchk(qcompile(QlfMode), Options) 2421 -> true 2422 ; current_prolog_flag(qcompile, QlfMode), 2423 \+ '$in_system_dir'(PlFile) 2424 ), 2425 ( QlfMode == auto 2426 -> true 2427 ; QlfMode == large, 2428 size_file(PlFile, Size), 2429 Size > 100000 2430 ), 2431 access_file(QlfFile, write). 2432 2433'$in_system_dir'(PlFile) :- 2434 current_prolog_flag(home, Home), 2435 sub_atom(PlFile, 0, _, _, Home). 2436 2437'$spec_extension'(File, Ext) :- 2438 atom(File), 2439 file_name_extension(_, Ext, File). 2440'$spec_extension'(Spec, Ext) :- 2441 compound(Spec), 2442 arg(1, Spec, Arg), 2443 '$spec_extension'(Arg, Ext).
2455:- dynamic 2456 '$resolved_source_path_db'/3. % ?Spec, ?Dialect, ?Path 2457:- '$notransact'('$resolved_source_path_db'/3). 2458 2459'$load_file'(File, Module, Options) :- 2460 '$error_count'(E0, W0), 2461 '$load_file_e'(File, Module, Options), 2462 '$error_count'(E1, W1), 2463 Errors is E1-E0, 2464 Warnings is W1-W0, 2465 ( Errors+Warnings =:= 0 2466 -> true 2467 ; '$print_message'(silent, load_file_errors(File, Errors, Warnings)) 2468 ). 2469 2470:- if(current_prolog_flag(threads, true)). 2471'$error_count'(Errors, Warnings) :- 2472 current_prolog_flag(threads, true), 2473 !, 2474 thread_self(Me), 2475 thread_statistics(Me, errors, Errors), 2476 thread_statistics(Me, warnings, Warnings). 2477:- endif. 2478'$error_count'(Errors, Warnings) :- 2479 statistics(errors, Errors), 2480 statistics(warnings, Warnings). 2481 2482'$load_file_e'(File, Module, Options) :- 2483 \+ memberchk(stream(_), Options), 2484 user:prolog_load_file(Module:File, Options), 2485 !. 2486'$load_file_e'(File, Module, Options) :- 2487 memberchk(stream(_), Options), 2488 !, 2489 '$assert_load_context_module'(File, Module, Options), 2490 '$qdo_load_file'(File, File, Module, Options). 2491'$load_file_e'(File, Module, Options) :- 2492 ( '$resolved_source_path'(File, FullFile, Options) 2493 -> true 2494 ; '$resolve_source_path'(File, FullFile, Options) 2495 ), 2496 !, 2497 '$mt_load_file'(File, FullFile, Module, Options). 2498'$load_file_e'(_, _, _).
2504'$resolved_source_path'(File, FullFile, Options) :-
2505 current_prolog_flag(emulated_dialect, Dialect),
2506 '$resolved_source_path_db'(File, Dialect, FullFile),
2507 ( '$source_file_property'(FullFile, from_state, true)
2508 ; '$source_file_property'(FullFile, resource, true)
2509 ; '$option'(if(If), Options, true),
2510 '$noload'(If, FullFile, Options)
2511 ),
2512 !.
2519'$resolve_source_path'(File, FullFile, Options) :- 2520 ( '$option'(if(If), Options), 2521 If == exists 2522 -> Extra = [file_errors(fail)] 2523 ; Extra = [] 2524 ), 2525 absolute_file_name(File, FullFile, 2526 [ file_type(prolog), 2527 access(read) 2528 | Extra 2529 ]), 2530 '$register_resolved_source_path'(File, FullFile). 2531 2532'$register_resolved_source_path'(File, FullFile) :- 2533 ( compound(File) 2534 -> current_prolog_flag(emulated_dialect, Dialect), 2535 ( '$resolved_source_path_db'(File, Dialect, FullFile) 2536 -> true 2537 ; asserta('$resolved_source_path_db'(File, Dialect, FullFile)) 2538 ) 2539 ; true 2540 ).
2546:- public '$translated_source'/2. 2547'$translated_source'(Old, New) :- 2548 forall(retract('$resolved_source_path_db'(File, Dialect, Old)), 2549 assertz('$resolved_source_path_db'(File, Dialect, New))).
2556'$register_resource_file'(FullFile) :-
2557 ( sub_atom(FullFile, 0, _, _, 'res://'),
2558 \+ file_name_extension(_, qlf, FullFile)
2559 -> '$set_source_file'(FullFile, resource, true)
2560 ; true
2561 ).
2574'$already_loaded'(_File, FullFile, Module, Options) :- 2575 '$assert_load_context_module'(FullFile, Module, Options), 2576 '$current_module'(LoadModules, FullFile), 2577 !, 2578 ( atom(LoadModules) 2579 -> LoadModule = LoadModules 2580 ; LoadModules = [LoadModule|_] 2581 ), 2582 '$import_from_loaded_module'(LoadModule, Module, Options). 2583'$already_loaded'(_, _, user, _) :- !. 2584'$already_loaded'(File, FullFile, Module, Options) :- 2585 ( '$load_context_module'(FullFile, Module, CtxOptions), 2586 '$load_ctx_options'(Options, CtxOptions) 2587 -> true 2588 ; '$load_file'(File, Module, [if(true)|Options]) 2589 ).
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.
2604:- dynamic 2605 '$loading_file'/3. % File, Queue, Thread 2606:- volatile 2607 '$loading_file'/3. 2608:- '$notransact'('$loading_file'/3). 2609 2610:- if(current_prolog_flag(threads, true)). 2611'$mt_load_file'(File, FullFile, Module, Options) :- 2612 current_prolog_flag(threads, true), 2613 !, 2614 sig_atomic(setup_call_cleanup( 2615 with_mutex('$load_file', 2616 '$mt_start_load'(FullFile, Loading, Options)), 2617 '$mt_do_load'(Loading, File, FullFile, Module, Options), 2618 '$mt_end_load'(Loading))). 2619:- endif. 2620'$mt_load_file'(File, FullFile, Module, Options) :- 2621 '$option'(if(If), Options, true), 2622 '$noload'(If, FullFile, Options), 2623 !, 2624 '$already_loaded'(File, FullFile, Module, Options). 2625:- if(current_prolog_flag(threads, true)). 2626'$mt_load_file'(File, FullFile, Module, Options) :- 2627 sig_atomic('$qdo_load_file'(File, FullFile, Module, Options)). 2628:- else. 2629'$mt_load_file'(File, FullFile, Module, Options) :- 2630 '$qdo_load_file'(File, FullFile, Module, Options). 2631:- endif. 2632 2633:- if(current_prolog_flag(threads, true)). 2634'$mt_start_load'(FullFile, queue(Queue), _) :- 2635 '$loading_file'(FullFile, Queue, LoadThread), 2636 \+ thread_self(LoadThread), 2637 !. 2638'$mt_start_load'(FullFile, already_loaded, Options) :- 2639 '$option'(if(If), Options, true), 2640 '$noload'(If, FullFile, Options), 2641 !. 2642'$mt_start_load'(FullFile, Ref, _) :- 2643 thread_self(Me), 2644 message_queue_create(Queue), 2645 assertz('$loading_file'(FullFile, Queue, Me), Ref). 2646 2647'$mt_do_load'(queue(Queue), File, FullFile, Module, Options) :- 2648 !, 2649 catch(thread_get_message(Queue, _), error(_,_), true), 2650 '$already_loaded'(File, FullFile, Module, Options). 2651'$mt_do_load'(already_loaded, File, FullFile, Module, Options) :- 2652 !, 2653 '$already_loaded'(File, FullFile, Module, Options). 2654'$mt_do_load'(_Ref, File, FullFile, Module, Options) :- 2655 '$assert_load_context_module'(FullFile, Module, Options), 2656 '$qdo_load_file'(File, FullFile, Module, Options). 2657 2658'$mt_end_load'(queue(_)) :- !. 2659'$mt_end_load'(already_loaded) :- !. 2660'$mt_end_load'(Ref) :- 2661 clause('$loading_file'(_, Queue, _), _, Ref), 2662 erase(Ref), 2663 thread_send_message(Queue, done), 2664 message_queue_destroy(Queue). 2665:- endif.
2671'$qdo_load_file'(File, FullFile, Module, Options) :- 2672 '$qdo_load_file2'(File, FullFile, Module, Action, Options), 2673 '$register_resource_file'(FullFile), 2674 '$run_initialization'(FullFile, Action, Options). 2675 2676'$qdo_load_file2'(File, FullFile, Module, Action, Options) :- 2677 memberchk('$qlf'(QlfOut), Options), 2678 '$stage_file'(QlfOut, StageQlf), 2679 !, 2680 setup_call_catcher_cleanup( 2681 '$qstart'(StageQlf, Module, State), 2682 '$do_load_file'(File, FullFile, Module, Action, Options), 2683 Catcher, 2684 '$qend'(State, Catcher, StageQlf, QlfOut)). 2685'$qdo_load_file2'(File, FullFile, Module, Action, Options) :- 2686 '$do_load_file'(File, FullFile, Module, Action, Options). 2687 2688'$qstart'(Qlf, Module, state(OldMode, OldModule)) :- 2689 '$qlf_open'(Qlf), 2690 '$compilation_mode'(OldMode, qlf), 2691 '$set_source_module'(OldModule, Module). 2692 2693'$qend'(state(OldMode, OldModule), Catcher, StageQlf, QlfOut) :- 2694 '$set_source_module'(_, OldModule), 2695 '$set_compilation_mode'(OldMode), 2696 '$qlf_close', 2697 '$install_staged_file'(Catcher, StageQlf, QlfOut, warn). 2698 2699'$set_source_module'(OldModule, Module) :- 2700 '$current_source_module'(OldModule), 2701 '$set_source_module'(Module).
2708'$do_load_file'(File, FullFile, Module, Action, Options) :- 2709 '$option'(derived_from(DerivedFrom), Options, -), 2710 '$register_derived_source'(FullFile, DerivedFrom), 2711 '$qlf_file'(File, FullFile, Absolute, Mode, Options), 2712 ( Mode == qcompile 2713 -> qcompile(Module:File, Options) 2714 ; '$do_load_file_2'(File, Absolute, Module, Action, Options) 2715 ). 2716 2717'$do_load_file_2'(File, Absolute, Module, Action, Options) :- 2718 '$source_file_property'(Absolute, number_of_clauses, OldClauses), 2719 statistics(cputime, OldTime), 2720 2721 '$setup_load'(ScopedFlags, OldSandBoxed, OldVerbose, OldAutoLevel, OldXRef, 2722 Options), 2723 2724 '$compilation_level'(Level), 2725 '$load_msg_level'(load_file, Level, StartMsgLevel, DoneMsgLevel), 2726 '$print_message'(StartMsgLevel, 2727 load_file(start(Level, 2728 file(File, Absolute)))), 2729 2730 ( memberchk(stream(FromStream), Options) 2731 -> Input = stream 2732 ; Input = source 2733 ), 2734 2735 ( Input == stream, 2736 ( '$option'(format(qlf), Options, source) 2737 -> set_stream(FromStream, file_name(Absolute)), 2738 '$qload_stream'(FromStream, Module, Action, LM, Options) 2739 ; '$consult_file'(stream(Absolute, FromStream, []), 2740 Module, Action, LM, Options) 2741 ) 2742 -> true 2743 ; Input == source, 2744 file_name_extension(_, Ext, Absolute), 2745 ( user:prolog_file_type(Ext, qlf), 2746 E = error(_,_), 2747 catch('$qload_file'(Absolute, Module, Action, LM, Options), 2748 E, 2749 print_message(warning, E)) 2750 -> true 2751 ; '$consult_file'(Absolute, Module, Action, LM, Options) 2752 ) 2753 -> true 2754 ; '$print_message'(error, load_file(failed(File))), 2755 fail 2756 ), 2757 2758 '$import_from_loaded_module'(LM, Module, Options), 2759 2760 '$source_file_property'(Absolute, number_of_clauses, NewClauses), 2761 statistics(cputime, Time), 2762 ClausesCreated is NewClauses - OldClauses, 2763 TimeUsed is Time - OldTime, 2764 2765 '$print_message'(DoneMsgLevel, 2766 load_file(done(Level, 2767 file(File, Absolute), 2768 Action, 2769 LM, 2770 TimeUsed, 2771 ClausesCreated))), 2772 2773 '$restore_load'(ScopedFlags, OldSandBoxed, OldVerbose, OldAutoLevel, OldXRef). 2774 2775'$setup_load'(ScopedFlags, OldSandBoxed, OldVerbose, OldAutoLevel, OldXRef, 2776 Options) :- 2777 '$save_file_scoped_flags'(ScopedFlags), 2778 '$set_sandboxed_load'(Options, OldSandBoxed), 2779 '$set_verbose_load'(Options, OldVerbose), 2780 '$set_optimise_load'(Options), 2781 '$update_autoload_level'(Options, OldAutoLevel), 2782 '$set_no_xref'(OldXRef). 2783 2784'$restore_load'(ScopedFlags, OldSandBoxed, OldVerbose, OldAutoLevel, OldXRef) :- 2785 '$set_autoload_level'(OldAutoLevel), 2786 set_prolog_flag(xref, OldXRef), 2787 set_prolog_flag(verbose_load, OldVerbose), 2788 set_prolog_flag(sandboxed_load, OldSandBoxed), 2789 '$restore_file_scoped_flags'(ScopedFlags).
2797'$save_file_scoped_flags'(State) :- 2798 current_predicate(findall/3), % Not when doing boot compile 2799 !, 2800 findall(SavedFlag, '$save_file_scoped_flag'(SavedFlag), State). 2801'$save_file_scoped_flags'([]). 2802 2803'$save_file_scoped_flag'(Flag-Value) :- 2804 '$file_scoped_flag'(Flag, Default), 2805 ( current_prolog_flag(Flag, Value) 2806 -> true 2807 ; Value = Default 2808 ). 2809 2810'$file_scoped_flag'(generate_debug_info, true). 2811'$file_scoped_flag'(optimise, false). 2812'$file_scoped_flag'(xref, false). 2813 2814'$restore_file_scoped_flags'([]). 2815'$restore_file_scoped_flags'([Flag-Value|T]) :- 2816 set_prolog_flag(Flag, Value), 2817 '$restore_file_scoped_flags'(T).
2824'$import_from_loaded_module'(LoadedModule, Module, Options) :- 2825 LoadedModule \== Module, 2826 atom(LoadedModule), 2827 !, 2828 '$option'(imports(Import), Options, all), 2829 '$option'(reexport(Reexport), Options, false), 2830 '$import_list'(Module, LoadedModule, Import, Reexport). 2831'$import_from_loaded_module'(_, _, _).
verbose_load
flag according to Options and unify Old
with the old value.2839'$set_verbose_load'(Options, Old) :- 2840 current_prolog_flag(verbose_load, Old), 2841 ( memberchk(silent(Silent), Options) 2842 -> ( '$negate'(Silent, Level0) 2843 -> '$load_msg_compat'(Level0, Level) 2844 ; Level = Silent 2845 ), 2846 set_prolog_flag(verbose_load, Level) 2847 ; true 2848 ). 2849 2850'$negate'(true, false). 2851'$negate'(false, true).
sandboxed_load
from Options. Old is
unified with the old flag.
2860'$set_sandboxed_load'(Options, Old) :- 2861 current_prolog_flag(sandboxed_load, Old), 2862 ( memberchk(sandboxed(SandBoxed), Options), 2863 '$enter_sandboxed'(Old, SandBoxed, New), 2864 New \== Old 2865 -> set_prolog_flag(sandboxed_load, New) 2866 ; true 2867 ). 2868 2869'$enter_sandboxed'(Old, New, SandBoxed) :- 2870 ( Old == false, New == true 2871 -> SandBoxed = true, 2872 '$ensure_loaded_library_sandbox' 2873 ; Old == true, New == false 2874 -> throw(error(permission_error(leave, sandbox, -), _)) 2875 ; SandBoxed = Old 2876 ). 2877'$enter_sandboxed'(false, true, true). 2878 2879'$ensure_loaded_library_sandbox' :- 2880 source_file_property(library(sandbox), module(sandbox)), 2881 !. 2882'$ensure_loaded_library_sandbox' :- 2883 load_files(library(sandbox), [if(not_loaded), silent(true)]). 2884 2885'$set_optimise_load'(Options) :- 2886 ( '$option'(optimise(Optimise), Options) 2887 -> set_prolog_flag(optimise, Optimise) 2888 ; true 2889 ). 2890 2891'$set_no_xref'(OldXRef) :- 2892 ( current_prolog_flag(xref, OldXRef) 2893 -> true 2894 ; OldXRef = false 2895 ), 2896 set_prolog_flag(xref, false).
2903:- thread_local 2904 '$autoload_nesting'/1. 2905:- '$notransact'('$autoload_nesting'/1). 2906 2907'$update_autoload_level'(Options, AutoLevel) :- 2908 '$option'(autoload(Autoload), Options, false), 2909 ( '$autoload_nesting'(CurrentLevel) 2910 -> AutoLevel = CurrentLevel 2911 ; AutoLevel = 0 2912 ), 2913 ( Autoload == false 2914 -> true 2915 ; NewLevel is AutoLevel + 1, 2916 '$set_autoload_level'(NewLevel) 2917 ). 2918 2919'$set_autoload_level'(New) :- 2920 retractall('$autoload_nesting'(_)), 2921 asserta('$autoload_nesting'(New)).
2929'$print_message'(Level, Term) :- 2930 current_predicate(system:print_message/2), 2931 !, 2932 print_message(Level, Term). 2933'$print_message'(warning, Term) :- 2934 source_location(File, Line), 2935 !, 2936 format(user_error, 'WARNING: ~w:~w: ~p~n', [File, Line, Term]). 2937'$print_message'(error, Term) :- 2938 !, 2939 source_location(File, Line), 2940 !, 2941 format(user_error, 'ERROR: ~w:~w: ~p~n', [File, Line, Term]). 2942'$print_message'(_Level, _Term). 2943 2944'$print_message_fail'(E) :- 2945 '$print_message'(error, E), 2946 fail.
2954'$consult_file'(Absolute, Module, What, LM, Options) :- 2955 '$current_source_module'(Module), % same module 2956 !, 2957 '$consult_file_2'(Absolute, Module, What, LM, Options). 2958'$consult_file'(Absolute, Module, What, LM, Options) :- 2959 '$set_source_module'(OldModule, Module), 2960 '$ifcompiling'('$qlf_start_sub_module'(Module)), 2961 '$consult_file_2'(Absolute, Module, What, LM, Options), 2962 '$ifcompiling'('$qlf_end_part'), 2963 '$set_source_module'(OldModule). 2964 2965'$consult_file_2'(Absolute, Module, What, LM, Options) :- 2966 '$set_source_module'(OldModule, Module), 2967 '$load_id'(Absolute, Id, Modified, Options), 2968 '$compile_type'(What), 2969 '$save_lex_state'(LexState, Options), 2970 '$set_dialect'(Options), 2971 setup_call_cleanup( 2972 '$start_consult'(Id, Modified), 2973 '$load_file'(Absolute, Id, LM, Options), 2974 '$end_consult'(Id, LexState, OldModule)). 2975 2976'$end_consult'(Id, LexState, OldModule) :- 2977 '$end_consult'(Id), 2978 '$restore_lex_state'(LexState), 2979 '$set_source_module'(OldModule). 2980 2981 2982:- create_prolog_flag(emulated_dialect, swi, [type(atom)]).
2986'$save_lex_state'(State, Options) :- 2987 memberchk(scope_settings(false), Options), 2988 !, 2989 State = (-). 2990'$save_lex_state'(lexstate(Style, Dialect), _) :- 2991 '$style_check'(Style, Style), 2992 current_prolog_flag(emulated_dialect, Dialect). 2993 2994'$restore_lex_state'(-) :- !. 2995'$restore_lex_state'(lexstate(Style, Dialect)) :- 2996 '$style_check'(_, Style), 2997 set_prolog_flag(emulated_dialect, Dialect). 2998 2999'$set_dialect'(Options) :- 3000 memberchk(dialect(Dialect), Options), 3001 !, 3002 '$expects_dialect'(Dialect). 3003'$set_dialect'(_). 3004 3005'$load_id'(stream(Id, _, _), Id, Modified, Options) :- 3006 !, 3007 '$modified_id'(Id, Modified, Options). 3008'$load_id'(Id, Id, Modified, Options) :- 3009 '$modified_id'(Id, Modified, Options). 3010 3011'$modified_id'(_, Modified, Options) :- 3012 '$option'(modified(Stamp), Options, Def), 3013 Stamp \== Def, 3014 !, 3015 Modified = Stamp. 3016'$modified_id'(Id, Modified, _) :- 3017 catch(time_file(Id, Modified), 3018 error(_, _), 3019 fail), 3020 !. 3021'$modified_id'(_, 0, _). 3022 3023 3024'$compile_type'(What) :- 3025 '$compilation_mode'(How), 3026 ( How == database 3027 -> What = compiled 3028 ; How == qlf 3029 -> What = '*qcompiled*' 3030 ; What = 'boot compiled' 3031 ).
3041:- dynamic 3042 '$load_context_module'/3. 3043:- multifile 3044 '$load_context_module'/3. 3045:- '$notransact'('$load_context_module'/3). 3046 3047'$assert_load_context_module'(_, _, Options) :- 3048 memberchk(register(false), Options), 3049 !. 3050'$assert_load_context_module'(File, Module, Options) :- 3051 source_location(FromFile, Line), 3052 !, 3053 '$master_file'(FromFile, MasterFile), 3054 '$check_load_non_module'(File, Module), 3055 '$add_dialect'(Options, Options1), 3056 '$load_ctx_options'(Options1, Options2), 3057 '$store_admin_clause'( 3058 system:'$load_context_module'(File, Module, Options2), 3059 _Layout, MasterFile, FromFile:Line). 3060'$assert_load_context_module'(File, Module, Options) :- 3061 '$check_load_non_module'(File, Module), 3062 '$add_dialect'(Options, Options1), 3063 '$load_ctx_options'(Options1, Options2), 3064 ( clause('$load_context_module'(File, Module, _), true, Ref), 3065 \+ clause_property(Ref, file(_)), 3066 erase(Ref) 3067 -> true 3068 ; true 3069 ), 3070 assertz('$load_context_module'(File, Module, Options2)). 3071 3072'$add_dialect'(Options0, Options) :- 3073 current_prolog_flag(emulated_dialect, Dialect), Dialect \== swi, 3074 !, 3075 Options = [dialect(Dialect)|Options0]. 3076'$add_dialect'(Options, Options).
3083'$load_ctx_options'(Options, CtxOptions) :- 3084 '$load_ctx_options2'(Options, CtxOptions0), 3085 sort(CtxOptions0, CtxOptions). 3086 3087'$load_ctx_options2'([], []). 3088'$load_ctx_options2'([H|T0], [H|T]) :- 3089 '$load_ctx_option'(H), 3090 !, 3091 '$load_ctx_options2'(T0, T). 3092'$load_ctx_options2'([_|T0], T) :- 3093 '$load_ctx_options2'(T0, T). 3094 3095'$load_ctx_option'(derived_from(_)). 3096'$load_ctx_option'(dialect(_)). 3097'$load_ctx_option'(encoding(_)). 3098'$load_ctx_option'(imports(_)). 3099'$load_ctx_option'(reexport(_)).
3107'$check_load_non_module'(File, _) :- 3108 '$current_module'(_, File), 3109 !. % File is a module file 3110'$check_load_non_module'(File, Module) :- 3111 '$load_context_module'(File, OldModule, _), 3112 Module \== OldModule, 3113 !, 3114 format(atom(Msg), 3115 'Non-module file already loaded into module ~w; \c 3116 trying to load into ~w', 3117 [OldModule, Module]), 3118 throw(error(permission_error(load, source, File), 3119 context(load_files/2, Msg))). 3120'$check_load_non_module'(_, _).
state(FirstTerm:boolean,
Module:atom,
AtEnd:atom,
Stop:boolean,
Id:atom,
Dialect:atom)
3133'$load_file'(Path, Id, Module, Options) :- 3134 State = state(true, _, true, false, Id, -), 3135 ( '$source_term'(Path, _Read, _Layout, Term, Layout, 3136 _Stream, Options), 3137 '$valid_term'(Term), 3138 ( arg(1, State, true) 3139 -> '$first_term'(Term, Layout, Id, State, Options), 3140 nb_setarg(1, State, false) 3141 ; '$compile_term'(Term, Layout, Id, Options) 3142 ), 3143 arg(4, State, true) 3144 ; '$fixup_reconsult'(Id), 3145 '$end_load_file'(State) 3146 ), 3147 !, 3148 arg(2, State, Module). 3149 3150'$valid_term'(Var) :- 3151 var(Var), 3152 !, 3153 print_message(error, error(instantiation_error, _)). 3154'$valid_term'(Term) :- 3155 Term \== []. 3156 3157'$end_load_file'(State) :- 3158 arg(1, State, true), % empty file 3159 !, 3160 nb_setarg(2, State, Module), 3161 arg(5, State, Id), 3162 '$current_source_module'(Module), 3163 '$ifcompiling'('$qlf_start_file'(Id)), 3164 '$ifcompiling'('$qlf_end_part'). 3165'$end_load_file'(State) :- 3166 arg(3, State, End), 3167 '$end_load_file'(End, State). 3168 3169'$end_load_file'(true, _). 3170'$end_load_file'(end_module, State) :- 3171 arg(2, State, Module), 3172 '$check_export'(Module), 3173 '$ifcompiling'('$qlf_end_part'). 3174'$end_load_file'(end_non_module, _State) :- 3175 '$ifcompiling'('$qlf_end_part'). 3176 3177 3178'$first_term'(?-(Directive), Layout, Id, State, Options) :- 3179 !, 3180 '$first_term'(:-(Directive), Layout, Id, State, Options). 3181'$first_term'(:-(Directive), _Layout, Id, State, Options) :- 3182 nonvar(Directive), 3183 ( ( Directive = module(Name, Public) 3184 -> Imports = [] 3185 ; Directive = module(Name, Public, Imports) 3186 ) 3187 -> !, 3188 '$module_name'(Name, Id, Module, Options), 3189 '$start_module'(Module, Public, State, Options), 3190 '$module3'(Imports) 3191 ; Directive = expects_dialect(Dialect) 3192 -> !, 3193 '$set_dialect'(Dialect, State), 3194 fail % Still consider next term as first 3195 ). 3196'$first_term'(Term, Layout, Id, State, Options) :- 3197 '$start_non_module'(Id, Term, State, Options), 3198 '$compile_term'(Term, Layout, Id, Options).
3205'$compile_term'(Term, Layout, SrcId, Options) :- 3206 '$compile_term'(Term, Layout, SrcId, -, Options). 3207 3208'$compile_term'(Var, _Layout, _Id, _SrcLoc, _Options) :- 3209 var(Var), 3210 !, 3211 '$instantiation_error'(Var). 3212'$compile_term'((?-Directive), _Layout, Id, _SrcLoc, Options) :- 3213 !, 3214 '$execute_directive'(Directive, Id, Options). 3215'$compile_term'((:-Directive), _Layout, Id, _SrcLoc, Options) :- 3216 !, 3217 '$execute_directive'(Directive, Id, Options). 3218'$compile_term'('$source_location'(File, Line):Term, 3219 Layout, Id, _SrcLoc, Options) :- 3220 !, 3221 '$compile_term'(Term, Layout, Id, File:Line, Options). 3222'$compile_term'(Clause, Layout, Id, SrcLoc, _Options) :- 3223 E = error(_,_), 3224 catch('$store_clause'(Clause, Layout, Id, SrcLoc), E, 3225 '$print_message'(error, E)). 3226 3227'$start_non_module'(_Id, Term, _State, Options) :- 3228 '$option'(must_be_module(true), Options, false), 3229 !, 3230 '$domain_error'(module_header, Term). 3231'$start_non_module'(Id, _Term, State, _Options) :- 3232 '$current_source_module'(Module), 3233 '$ifcompiling'('$qlf_start_file'(Id)), 3234 '$qset_dialect'(State), 3235 nb_setarg(2, State, Module), 3236 nb_setarg(3, State, end_non_module).
Note that expects_dialect/1 itself may be autoloaded from the library.
3249'$set_dialect'(Dialect, State) :- 3250 '$compilation_mode'(qlf, database), 3251 !, 3252 '$expects_dialect'(Dialect), 3253 '$compilation_mode'(_, qlf), 3254 nb_setarg(6, State, Dialect). 3255'$set_dialect'(Dialect, _) :- 3256 '$expects_dialect'(Dialect). 3257 3258'$qset_dialect'(State) :- 3259 '$compilation_mode'(qlf), 3260 arg(6, State, Dialect), Dialect \== (-), 3261 !, 3262 '$add_directive_wic'('$expects_dialect'(Dialect)). 3263'$qset_dialect'(_). 3264 3265'$expects_dialect'(Dialect) :- 3266 Dialect == swi, 3267 !, 3268 set_prolog_flag(emulated_dialect, Dialect). 3269'$expects_dialect'(Dialect) :- 3270 current_predicate(expects_dialect/1), 3271 !, 3272 expects_dialect(Dialect). 3273'$expects_dialect'(Dialect) :- 3274 use_module(library(dialect), [expects_dialect/1]), 3275 expects_dialect(Dialect). 3276 3277 3278 /******************************* 3279 * MODULES * 3280 *******************************/ 3281 3282'$start_module'(Module, _Public, State, _Options) :- 3283 '$current_module'(Module, OldFile), 3284 source_location(File, _Line), 3285 OldFile \== File, OldFile \== [], 3286 same_file(OldFile, File), 3287 !, 3288 nb_setarg(2, State, Module), 3289 nb_setarg(4, State, true). % Stop processing 3290'$start_module'(Module, Public, State, Options) :- 3291 arg(5, State, File), 3292 nb_setarg(2, State, Module), 3293 source_location(_File, Line), 3294 '$option'(redefine_module(Action), Options, false), 3295 '$module_class'(File, Class, Super), 3296 '$reset_dialect'(File, Class), 3297 '$redefine_module'(Module, File, Action), 3298 '$declare_module'(Module, Class, Super, File, Line, false), 3299 '$export_list'(Public, Module, Ops), 3300 '$ifcompiling'('$qlf_start_module'(Module)), 3301 '$export_ops'(Ops, Module, File), 3302 '$qset_dialect'(State), 3303 nb_setarg(3, State, end_module).
swi
dialect.3310'$reset_dialect'(File, library) :- 3311 file_name_extension(_, pl, File), 3312 !, 3313 set_prolog_flag(emulated_dialect, swi). 3314'$reset_dialect'(_, _).
3321'$module3'(Var) :- 3322 var(Var), 3323 !, 3324 '$instantiation_error'(Var). 3325'$module3'([]) :- !. 3326'$module3'([H|T]) :- 3327 !, 3328 '$module3'(H), 3329 '$module3'(T). 3330'$module3'(Id) :- 3331 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.3345'$module_name'(_, _, Module, Options) :- 3346 '$option'(module(Module), Options), 3347 !, 3348 '$current_source_module'(Context), 3349 Context \== Module. % cause '$first_term'/5 to fail. 3350'$module_name'(Var, Id, Module, Options) :- 3351 var(Var), 3352 !, 3353 file_base_name(Id, File), 3354 file_name_extension(Var, _, File), 3355 '$module_name'(Var, Id, Module, Options). 3356'$module_name'(Reserved, _, _, _) :- 3357 '$reserved_module'(Reserved), 3358 !, 3359 throw(error(permission_error(load, module, Reserved), _)). 3360'$module_name'(Module, _Id, Module, _). 3361 3362 3363'$reserved_module'(system). 3364'$reserved_module'(user).
3369'$redefine_module'(_Module, _, false) :- !. 3370'$redefine_module'(Module, File, true) :- 3371 !, 3372 ( module_property(Module, file(OldFile)), 3373 File \== OldFile 3374 -> unload_file(OldFile) 3375 ; true 3376 ). 3377'$redefine_module'(Module, File, ask) :- 3378 ( stream_property(user_input, tty(true)), 3379 module_property(Module, file(OldFile)), 3380 File \== OldFile, 3381 '$rdef_response'(Module, OldFile, File, true) 3382 -> '$redefine_module'(Module, File, true) 3383 ; true 3384 ). 3385 3386'$rdef_response'(Module, OldFile, File, Ok) :- 3387 repeat, 3388 print_message(query, redefine_module(Module, OldFile, File)), 3389 get_single_char(Char), 3390 '$rdef_response'(Char, Ok0), 3391 !, 3392 Ok = Ok0. 3393 3394'$rdef_response'(Char, true) :- 3395 memberchk(Char, `yY`), 3396 format(user_error, 'yes~n', []). 3397'$rdef_response'(Char, false) :- 3398 memberchk(Char, `nN`), 3399 format(user_error, 'no~n', []). 3400'$rdef_response'(Char, _) :- 3401 memberchk(Char, `a`), 3402 format(user_error, 'abort~n', []), 3403 abort. 3404'$rdef_response'(_, _) :- 3405 print_message(help, redefine_module_reply), 3406 fail.
system
, while all normal user modules inherit
from user
.3416'$module_class'(File, Class, system) :- 3417 current_prolog_flag(home, Home), 3418 sub_atom(File, 0, Len, _, Home), 3419 ( sub_atom(File, Len, _, _, '/boot/') 3420 -> !, Class = system 3421 ; '$lib_prefix'(Prefix), 3422 sub_atom(File, Len, _, _, Prefix) 3423 -> !, Class = library 3424 ; file_directory_name(File, Home), 3425 file_name_extension(_, rc, File) 3426 -> !, Class = library 3427 ). 3428'$module_class'(_, user, user). 3429 3430'$lib_prefix'('/library'). 3431'$lib_prefix'('/xpce/prolog/'). 3432 3433'$check_export'(Module) :- 3434 '$undefined_export'(Module, UndefList), 3435 ( '$member'(Undef, UndefList), 3436 strip_module(Undef, _, Local), 3437 print_message(error, 3438 undefined_export(Module, Local)), 3439 fail 3440 ; true 3441 ).
all
,
a list of optionally mapped predicate indicators or a term
except(Import)
.
3452'$import_list'(_, _, Var, _) :- 3453 var(Var), 3454 !, 3455 throw(error(instantitation_error, _)). 3456'$import_list'(Target, Source, all, Reexport) :- 3457 !, 3458 '$exported_ops'(Source, Import, Predicates), 3459 '$module_property'(Source, exports(Predicates)), 3460 '$import_all'(Import, Target, Source, Reexport, weak). 3461'$import_list'(Target, Source, except(Spec), Reexport) :- 3462 !, 3463 '$exported_ops'(Source, Export, Predicates), 3464 '$module_property'(Source, exports(Predicates)), 3465 ( is_list(Spec) 3466 -> true 3467 ; throw(error(type_error(list, Spec), _)) 3468 ), 3469 '$import_except'(Spec, Source, Export, Import), 3470 '$import_all'(Import, Target, Source, Reexport, weak). 3471'$import_list'(Target, Source, Import, Reexport) :- 3472 is_list(Import), 3473 !, 3474 '$exported_ops'(Source, Ops, []), 3475 '$expand_ops'(Import, Ops, Import1), 3476 '$import_all'(Import1, Target, Source, Reexport, strong). 3477'$import_list'(_, _, Import, _) :- 3478 '$type_error'(import_specifier, Import). 3479 3480'$expand_ops'([], _, []). 3481'$expand_ops'([H|T0], Ops, Imports) :- 3482 nonvar(H), H = op(_,_,_), 3483 !, 3484 '$include'('$can_unify'(H), Ops, Ops1), 3485 '$append'(Ops1, T1, Imports), 3486 '$expand_ops'(T0, Ops, T1). 3487'$expand_ops'([H|T0], Ops, [H|T1]) :- 3488 '$expand_ops'(T0, Ops, T1). 3489 3490 3491'$import_except'([], _, List, List). 3492'$import_except'([H|T], Source, List0, List) :- 3493 '$import_except_1'(H, Source, List0, List1), 3494 '$import_except'(T, Source, List1, List). 3495 3496'$import_except_1'(Var, _, _, _) :- 3497 var(Var), 3498 !, 3499 '$instantiation_error'(Var). 3500'$import_except_1'(PI as N, _, List0, List) :- 3501 '$pi'(PI), atom(N), 3502 !, 3503 '$canonical_pi'(PI, CPI), 3504 '$import_as'(CPI, N, List0, List). 3505'$import_except_1'(op(P,A,N), _, List0, List) :- 3506 !, 3507 '$remove_ops'(List0, op(P,A,N), List). 3508'$import_except_1'(PI, Source, List0, List) :- 3509 '$pi'(PI), 3510 !, 3511 '$canonical_pi'(PI, CPI), 3512 ( '$select'(P, List0, List), 3513 '$canonical_pi'(CPI, P) 3514 -> true 3515 ; print_message(warning, 3516 error(existence_error(export, PI, module(Source)), _)), 3517 List = List0 3518 ). 3519'$import_except_1'(Except, _, _, _) :- 3520 '$type_error'(import_specifier, Except). 3521 3522'$import_as'(CPI, N, [PI2|T], [CPI as N|T]) :- 3523 '$canonical_pi'(PI2, CPI), 3524 !. 3525'$import_as'(PI, N, [H|T0], [H|T]) :- 3526 !, 3527 '$import_as'(PI, N, T0, T). 3528'$import_as'(PI, _, _, _) :- 3529 '$existence_error'(export, PI). 3530 3531'$pi'(N/A) :- atom(N), integer(A), !. 3532'$pi'(N//A) :- atom(N), integer(A). 3533 3534'$canonical_pi'(N//A0, N/A) :- 3535 A is A0 + 2. 3536'$canonical_pi'(PI, PI). 3537 3538'$remove_ops'([], _, []). 3539'$remove_ops'([Op|T0], Pattern, T) :- 3540 subsumes_term(Pattern, Op), 3541 !, 3542 '$remove_ops'(T0, Pattern, T). 3543'$remove_ops'([H|T0], Pattern, [H|T]) :- 3544 '$remove_ops'(T0, Pattern, T).
true
, add
the imported material to the exports of Context. If Strength is
weak
, definitions in Context overrule the import. If strong
, a
local definition is considered an error.
3554'$import_all'(Import, Context, Source, Reexport, Strength) :-
3555 '$import_all2'(Import, Context, Source, Imported, ImpOps, Strength),
3556 ( Reexport == true,
3557 ( '$list_to_conj'(Imported, Conj)
3558 -> export(Context:Conj),
3559 '$ifcompiling'('$add_directive_wic'(export(Context:Conj)))
3560 ; true
3561 ),
3562 source_location(File, _Line),
3563 '$export_ops'(ImpOps, Context, File)
3564 ; true
3565 ).
3569'$import_all2'([], _, _, [], [], _). 3570'$import_all2'([PI as NewName|Rest], Context, Source, 3571 [NewName/Arity|Imported], ImpOps, Strength) :- 3572 !, 3573 '$canonical_pi'(PI, Name/Arity), 3574 length(Args, Arity), 3575 Head =.. [Name|Args], 3576 NewHead =.. [NewName|Args], 3577 ( '$get_predicate_attribute'(Source:Head, meta_predicate, Meta) 3578 -> Meta =.. [Name|MetaArgs], 3579 NewMeta =.. [NewName|MetaArgs], 3580 meta_predicate(Context:NewMeta) 3581 ; '$get_predicate_attribute'(Source:Head, transparent, 1) 3582 -> '$set_predicate_attribute'(Context:NewHead, transparent, true) 3583 ; true 3584 ), 3585 ( source_location(File, Line) 3586 -> E = error(_,_), 3587 catch('$store_admin_clause'((NewHead :- Source:Head), 3588 _Layout, File, File:Line), 3589 E, '$print_message'(error, E)) 3590 ; assertz(( :- !, Source:Head)) % ! avoids problems with 3591 ), % duplicate load 3592 '$import_all2'(Rest, Context, Source, Imported, ImpOps, Strength). 3593'$import_all2'([op(P,A,N)|Rest], Context, Source, Imported, 3594 [op(P,A,N)|ImpOps], Strength) :- 3595 !, 3596 '$import_ops'(Context, Source, op(P,A,N)), 3597 '$import_all2'(Rest, Context, Source, Imported, ImpOps, Strength). 3598'$import_all2'([Pred|Rest], Context, Source, [Pred|Imported], ImpOps, Strength) :- 3599 Error = error(_,_), 3600 catch(Context:'$import'(Source:Pred, Strength), Error, 3601 print_message(error, Error)), 3602 '$ifcompiling'('$import_wic'(Source, Pred, Strength)), 3603 '$import_all2'(Rest, Context, Source, Imported, ImpOps, Strength). 3604 3605 3606'$list_to_conj'([One], One) :- !. 3607'$list_to_conj'([H|T], (H,Rest)) :- 3608 '$list_to_conj'(T, Rest).
op(P,A,N)
terms representing the operators
exported from Module.3615'$exported_ops'(Module, Ops, Tail) :- 3616 '$c_current_predicate'(_, Module:'$exported_op'(_,_,_)), 3617 !, 3618 findall(op(P,A,N), Module:'$exported_op'(P,A,N), Ops, Tail). 3619'$exported_ops'(_, Ops, Ops). 3620 3621'$exported_op'(Module, P, A, N) :- 3622 '$c_current_predicate'(_, Module:'$exported_op'(_,_,_)), 3623 Module:'$exported_op'(P, A, N).
3630'$import_ops'(To, From, Pattern) :- 3631 ground(Pattern), 3632 !, 3633 Pattern = op(P,A,N), 3634 op(P,A,To:N), 3635 ( '$exported_op'(From, P, A, N) 3636 -> true 3637 ; print_message(warning, no_exported_op(From, Pattern)) 3638 ). 3639'$import_ops'(To, From, Pattern) :- 3640 ( '$exported_op'(From, Pri, Assoc, Name), 3641 Pattern = op(Pri, Assoc, Name), 3642 op(Pri, Assoc, To:Name), 3643 fail 3644 ; true 3645 ).
3653'$export_list'(Decls, Module, Ops) :- 3654 is_list(Decls), 3655 !, 3656 '$do_export_list'(Decls, Module, Ops). 3657'$export_list'(Decls, _, _) :- 3658 var(Decls), 3659 throw(error(instantiation_error, _)). 3660'$export_list'(Decls, _, _) :- 3661 throw(error(type_error(list, Decls), _)). 3662 3663'$do_export_list'([], _, []) :- !. 3664'$do_export_list'([H|T], Module, Ops) :- 3665 !, 3666 E = error(_,_), 3667 catch('$export1'(H, Module, Ops, Ops1), 3668 E, ('$print_message'(error, E), Ops = Ops1)), 3669 '$do_export_list'(T, Module, Ops1). 3670 3671'$export1'(Var, _, _, _) :- 3672 var(Var), 3673 !, 3674 throw(error(instantiation_error, _)). 3675'$export1'(Op, _, [Op|T], T) :- 3676 Op = op(_,_,_), 3677 !. 3678'$export1'(PI0, Module, Ops, Ops) :- 3679 strip_module(Module:PI0, M, PI), 3680 ( PI = (_//_) 3681 -> non_terminal(M:PI) 3682 ; true 3683 ), 3684 export(M:PI). 3685 3686'$export_ops'([op(Pri, Assoc, Name)|T], Module, File) :- 3687 E = error(_,_), 3688 catch(( '$execute_directive'(op(Pri, Assoc, Module:Name), File, []), 3689 '$export_op'(Pri, Assoc, Name, Module, File) 3690 ), 3691 E, '$print_message'(error, E)), 3692 '$export_ops'(T, Module, File). 3693'$export_ops'([], _, _). 3694 3695'$export_op'(Pri, Assoc, Name, Module, File) :- 3696 ( '$get_predicate_attribute'(Module:'$exported_op'(_,_,_), defined, 1) 3697 -> true 3698 ; '$execute_directive'(discontiguous(Module:'$exported_op'/3), File, []) 3699 ), 3700 '$store_admin_clause'('$exported_op'(Pri, Assoc, Name), _Layout, File, -).
3706'$execute_directive'(Var, _F, _Options) :- 3707 var(Var), 3708 '$instantiation_error'(Var). 3709'$execute_directive'(encoding(Encoding), _F, _Options) :- 3710 !, 3711 ( '$load_input'(_F, S) 3712 -> set_stream(S, encoding(Encoding)) 3713 ). 3714'$execute_directive'(Goal, _, Options) :- 3715 \+ '$compilation_mode'(database), 3716 !, 3717 '$add_directive_wic2'(Goal, Type, Options), 3718 ( Type == call % suspend compiling into .qlf file 3719 -> '$compilation_mode'(Old, database), 3720 setup_call_cleanup( 3721 '$directive_mode'(OldDir, Old), 3722 '$execute_directive_3'(Goal), 3723 ( '$set_compilation_mode'(Old), 3724 '$set_directive_mode'(OldDir) 3725 )) 3726 ; '$execute_directive_3'(Goal) 3727 ). 3728'$execute_directive'(Goal, _, _Options) :- 3729 '$execute_directive_3'(Goal). 3730 3731'$execute_directive_3'(Goal) :- 3732 '$current_source_module'(Module), 3733 '$valid_directive'(Module:Goal), 3734 !, 3735 ( '$pattr_directive'(Goal, Module) 3736 -> true 3737 ; Term = error(_,_), 3738 catch(Module:Goal, Term, '$exception_in_directive'(Term)) 3739 -> true 3740 ; '$print_message'(warning, goal_failed(directive, Module:Goal)), 3741 fail 3742 ). 3743'$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.3752:- multifile prolog:sandbox_allowed_directive/1. 3753:- multifile prolog:sandbox_allowed_clause/1. 3754:- meta_predicate '$valid_directive'( ). 3755 3756'$valid_directive'(_) :- 3757 current_prolog_flag(sandboxed_load, false), 3758 !. 3759'$valid_directive'(Goal) :- 3760 Error = error(Formal, _), 3761 catch(prolog:sandbox_allowed_directive(Goal), Error, true), 3762 !, 3763 ( var(Formal) 3764 -> true 3765 ; print_message(error, Error), 3766 fail 3767 ). 3768'$valid_directive'(Goal) :- 3769 print_message(error, 3770 error(permission_error(execute, 3771 sandboxed_directive, 3772 Goal), _)), 3773 fail. 3774 3775'$exception_in_directive'(Term) :- 3776 '$print_message'(error, Term), 3777 fail. 3778 3779%! '$add_directive_wic2'(+Directive, -Type, +Options) is det. 3780% 3781% Classify Directive as one of `load` or `call`. Add a `call` 3782% directive to the QLF file. `load` directives continue the 3783% compilation into the QLF file. 3784 3785'$add_directive_wic2'(Goal, Type, Options) :- 3786 '$common_goal_type'(Goal, Type, Options), 3787 !, 3788 ( Type == load 3789 -> true 3790 ; '$current_source_module'(Module), 3791 '$add_directive_wic'(Module:Goal) 3792 ). 3793'$add_directive_wic2'(Goal, _, _) :- 3794 ( '$compilation_mode'(qlf) % no problem for qlf files 3795 -> true 3796 ; print_message(error, mixed_directive(Goal)) 3797 ).
load
or call
.3804'$common_goal_type'((A,B), Type, Options) :- 3805 !, 3806 '$common_goal_type'(A, Type, Options), 3807 '$common_goal_type'(B, Type, Options). 3808'$common_goal_type'((A;B), Type, Options) :- 3809 !, 3810 '$common_goal_type'(A, Type, Options), 3811 '$common_goal_type'(B, Type, Options). 3812'$common_goal_type'((A->B), Type, Options) :- 3813 !, 3814 '$common_goal_type'(A, Type, Options), 3815 '$common_goal_type'(B, Type, Options). 3816'$common_goal_type'(Goal, Type, Options) :- 3817 '$goal_type'(Goal, Type, Options). 3818 3819'$goal_type'(Goal, Type, Options) :- 3820 ( '$load_goal'(Goal, Options) 3821 -> Type = load 3822 ; Type = call 3823 ). 3824 3825:- thread_local 3826 '$qlf':qinclude/1. 3827 3828'$load_goal'([_|_], _). 3829'$load_goal'(consult(_), _). 3830'$load_goal'(load_files(_), _). 3831'$load_goal'(load_files(_,Options), _) :- 3832 memberchk(qcompile(QlfMode), Options), 3833 '$qlf_part_mode'(QlfMode). 3834'$load_goal'(ensure_loaded(_), _) :- '$compilation_mode'(wic). 3835'$load_goal'(use_module(_), _) :- '$compilation_mode'(wic). 3836'$load_goal'(use_module(_, _), _) :- '$compilation_mode'(wic). 3837'$load_goal'(reexport(_), _) :- '$compilation_mode'(wic). 3838'$load_goal'(reexport(_, _), _) :- '$compilation_mode'(wic). 3839'$load_goal'(Goal, _Options) :- 3840 '$qlf':qinclude(user), 3841 '$load_goal_file'(Goal, File), 3842 '$all_user_files'(File). 3843 3844 3845'$load_goal_file'(load_files(F), F). 3846'$load_goal_file'(load_files(F, _), F). 3847'$load_goal_file'(ensure_loaded(F), F). 3848'$load_goal_file'(use_module(F), F). 3849'$load_goal_file'(use_module(F, _), F). 3850'$load_goal_file'(reexport(F), F). 3851'$load_goal_file'(reexport(F, _), F). 3852 3853'$all_user_files'([]) :- 3854 !. 3855'$all_user_files'([H|T]) :- 3856 !, 3857 '$is_user_file'(H), 3858 '$all_user_files'(T). 3859'$all_user_files'(F) :- 3860 ground(F), 3861 '$is_user_file'(F). 3862 3863'$is_user_file'(File) :- 3864 absolute_file_name(File, Path, 3865 [ file_type(prolog), 3866 access(read) 3867 ]), 3868 '$module_class'(Path, user, _). 3869 3870'$qlf_part_mode'(part). 3871'$qlf_part_mode'(true). % compatibility 3872 3873 3874 /******************************** 3875 * COMPILE A CLAUSE * 3876 *********************************/
3883'$store_admin_clause'(Clause, Layout, Owner, SrcLoc) :- 3884 Owner \== (-), 3885 !, 3886 setup_call_cleanup( 3887 '$start_aux'(Owner, Context), 3888 '$store_admin_clause2'(Clause, Layout, Owner, SrcLoc), 3889 '$end_aux'(Owner, Context)). 3890'$store_admin_clause'(Clause, Layout, File, SrcLoc) :- 3891 '$store_admin_clause2'(Clause, Layout, File, SrcLoc). 3892 3893'$store_admin_clause2'(Clause, _Layout, File, SrcLoc) :- 3894 ( '$compilation_mode'(database) 3895 -> '$record_clause'(Clause, File, SrcLoc) 3896 ; '$record_clause'(Clause, File, SrcLoc, Ref), 3897 '$qlf_assert_clause'(Ref, development) 3898 ).
3908'$store_clause'((_, _), _, _, _) :- 3909 !, 3910 print_message(error, cannot_redefine_comma), 3911 fail. 3912'$store_clause'((Pre => Body), _Layout, File, SrcLoc) :- 3913 nonvar(Pre), 3914 Pre = (Head,Cond), 3915 !, 3916 ( '$is_true'(Cond), current_prolog_flag(optimise, true) 3917 -> '$store_clause'((Head=>Body), _Layout, File, SrcLoc) 3918 ; '$store_clause'(?=>(Head,(Cond,!,Body)), _Layout, File, SrcLoc) 3919 ). 3920'$store_clause'(Clause, _Layout, File, SrcLoc) :- 3921 '$valid_clause'(Clause), 3922 !, 3923 ( '$compilation_mode'(database) 3924 -> '$record_clause'(Clause, File, SrcLoc) 3925 ; '$record_clause'(Clause, File, SrcLoc, Ref), 3926 '$qlf_assert_clause'(Ref, development) 3927 ). 3928 3929'$is_true'(true) => true. 3930'$is_true'((A,B)) => '$is_true'(A), '$is_true'(B). 3931'$is_true'(_) => fail. 3932 3933'$valid_clause'(_) :- 3934 current_prolog_flag(sandboxed_load, false), 3935 !. 3936'$valid_clause'(Clause) :- 3937 \+ '$cross_module_clause'(Clause), 3938 !. 3939'$valid_clause'(Clause) :- 3940 Error = error(Formal, _), 3941 catch(prolog:sandbox_allowed_clause(Clause), Error, true), 3942 !, 3943 ( var(Formal) 3944 -> true 3945 ; print_message(error, Error), 3946 fail 3947 ). 3948'$valid_clause'(Clause) :- 3949 print_message(error, 3950 error(permission_error(assert, 3951 sandboxed_clause, 3952 Clause), _)), 3953 fail. 3954 3955'$cross_module_clause'(Clause) :- 3956 '$head_module'(Clause, Module), 3957 \+ '$current_source_module'(Module). 3958 3959'$head_module'(Var, _) :- 3960 var(Var), !, fail. 3961'$head_module'((Head :- _), Module) :- 3962 '$head_module'(Head, Module). 3963'$head_module'(Module:_, Module). 3964 3965'$clause_source'('$source_location'(File,Line):Clause, Clause, File:Line) :- !. 3966'$clause_source'(Clause, Clause, -).
3973:- public 3974 '$store_clause'/2. 3975 3976'$store_clause'(Term, Id) :- 3977 '$clause_source'(Term, Clause, SrcLoc), 3978 '$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)
3999compile_aux_clauses(_Clauses) :- 4000 current_prolog_flag(xref, true), 4001 !. 4002compile_aux_clauses(Clauses) :- 4003 source_location(File, _Line), 4004 '$compile_aux_clauses'(Clauses, File). 4005 4006'$compile_aux_clauses'(Clauses, File) :- 4007 setup_call_cleanup( 4008 '$start_aux'(File, Context), 4009 '$store_aux_clauses'(Clauses, File), 4010 '$end_aux'(File, Context)). 4011 4012'$store_aux_clauses'(Clauses, File) :- 4013 is_list(Clauses), 4014 !, 4015 forall('$member'(C,Clauses), 4016 '$compile_term'(C, _Layout, File, [])). 4017'$store_aux_clauses'(Clause, File) :- 4018 '$compile_term'(Clause, _Layout, File, []). 4019 4020 4021 /******************************* 4022 * STAGING * 4023 *******************************/
4033'$stage_file'(Target, Stage) :- 4034 file_directory_name(Target, Dir), 4035 file_base_name(Target, File), 4036 current_prolog_flag(pid, Pid), 4037 format(atom(Stage), '~w/.~w.~d', [Dir,File,Pid]). 4038 4039'$install_staged_file'(exit, Staged, Target, error) :- 4040 !, 4041 rename_file(Staged, Target). 4042'$install_staged_file'(exit, Staged, Target, OnError) :- 4043 !, 4044 InstallError = error(_,_), 4045 catch(rename_file(Staged, Target), 4046 InstallError, 4047 '$install_staged_error'(OnError, InstallError, Staged, Target)). 4048'$install_staged_file'(_, Staged, _, _OnError) :- 4049 E = error(_,_), 4050 catch(delete_file(Staged), E, true). 4051 4052'$install_staged_error'(OnError, Error, Staged, _Target) :- 4053 E = error(_,_), 4054 catch(delete_file(Staged), E, true), 4055 ( OnError = silent 4056 -> true 4057 ; OnError = fail 4058 -> fail 4059 ; print_message(warning, Error) 4060 ). 4061 4062 4063 /******************************* 4064 * READING * 4065 *******************************/ 4066 4067:- multifile 4068 prolog:comment_hook/3. % hook for read_clause/3 4069 4070 4071 /******************************* 4072 * FOREIGN INTERFACE * 4073 *******************************/ 4074 4075% call-back from PL_register_foreign(). First argument is the module 4076% into which the foreign predicate is loaded and second is a term 4077% describing the arguments. 4078 4079:- dynamic 4080 '$foreign_registered'/2. 4081 4082 /******************************* 4083 * TEMPORARY TERM EXPANSION * 4084 *******************************/ 4085 4086% Provide temporary definitions for the boot-loader. These are replaced 4087% by the real thing in load.pl 4088 4089:- dynamic 4090 '$expand_goal'/2, 4091 '$expand_term'/4. 4092 4093'$expand_goal'(In, In). 4094'$expand_term'(In, Layout, In, Layout). 4095 4096 4097 /******************************* 4098 * TYPE SUPPORT * 4099 *******************************/ 4100 4101'$type_error'(Type, Value) :- 4102 ( var(Value) 4103 -> throw(error(instantiation_error, _)) 4104 ; throw(error(type_error(Type, Value), _)) 4105 ). 4106 4107'$domain_error'(Type, Value) :- 4108 throw(error(domain_error(Type, Value), _)). 4109 4110'$existence_error'(Type, Object) :- 4111 throw(error(existence_error(Type, Object), _)). 4112 4113'$existence_error'(Type, Object, In) :- 4114 throw(error(existence_error(Type, Object, In), _)). 4115 4116'$permission_error'(Action, Type, Term) :- 4117 throw(error(permission_error(Action, Type, Term), _)). 4118 4119'$instantiation_error'(_Var) :- 4120 throw(error(instantiation_error, _)). 4121 4122'$uninstantiation_error'(NonVar) :- 4123 throw(error(uninstantiation_error(NonVar), _)). 4124 4125'$must_be'(list, X) :- !, 4126 '$skip_list'(_, X, Tail), 4127 ( Tail == [] 4128 -> true 4129 ; '$type_error'(list, Tail) 4130 ). 4131'$must_be'(options, X) :- !, 4132 ( '$is_options'(X) 4133 -> true 4134 ; '$type_error'(options, X) 4135 ). 4136'$must_be'(atom, X) :- !, 4137 ( atom(X) 4138 -> true 4139 ; '$type_error'(atom, X) 4140 ). 4141'$must_be'(integer, X) :- !, 4142 ( integer(X) 4143 -> true 4144 ; '$type_error'(integer, X) 4145 ). 4146'$must_be'(between(Low,High), X) :- !, 4147 ( integer(X) 4148 -> ( between(Low, High, X) 4149 -> true 4150 ; '$domain_error'(between(Low,High), X) 4151 ) 4152 ; '$type_error'(integer, X) 4153 ). 4154'$must_be'(callable, X) :- !, 4155 ( callable(X) 4156 -> true 4157 ; '$type_error'(callable, X) 4158 ). 4159'$must_be'(acyclic, X) :- !, 4160 ( acyclic_term(X) 4161 -> true 4162 ; '$domain_error'(acyclic_term, X) 4163 ). 4164'$must_be'(oneof(Type, Domain, List), X) :- !, 4165 '$must_be'(Type, X), 4166 ( memberchk(X, List) 4167 -> true 4168 ; '$domain_error'(Domain, X) 4169 ). 4170'$must_be'(boolean, X) :- !, 4171 ( (X == true ; X == false) 4172 -> true 4173 ; '$type_error'(boolean, X) 4174 ). 4175'$must_be'(ground, X) :- !, 4176 ( ground(X) 4177 -> true 4178 ; '$instantiation_error'(X) 4179 ). 4180'$must_be'(filespec, X) :- !, 4181 ( ( atom(X) 4182 ; string(X) 4183 ; compound(X), 4184 compound_name_arity(X, _, 1) 4185 ) 4186 -> true 4187 ; '$type_error'(filespec, X) 4188 ). 4189 4190% Use for debugging 4191%'$must_be'(Type, _X) :- format('Unknown $must_be type: ~q~n', [Type]). 4192 4193 4194 /******************************** 4195 * LIST PROCESSING * 4196 *********************************/ 4197 4198'$member'(El, [H|T]) :- 4199 '$member_'(T, El, H). 4200 4201'$member_'(_, El, El). 4202'$member_'([H|T], El, _) :- 4203 '$member_'(T, El, H). 4204 4205'$append'([], L, L). 4206'$append'([H|T], L, [H|R]) :- 4207 '$append'(T, L, R). 4208 4209'$append'(ListOfLists, List) :- 4210 '$must_be'(list, ListOfLists), 4211 '$append_'(ListOfLists, List). 4212 4213'$append_'([], []). 4214'$append_'([L|Ls], As) :- 4215 '$append'(L, Ws, As), 4216 '$append_'(Ls, Ws). 4217 4218'$select'(X, [X|Tail], Tail). 4219'$select'(Elem, [Head|Tail], [Head|Rest]) :- 4220 '$select'(Elem, Tail, Rest). 4221 4222'$reverse'(L1, L2) :- 4223 '$reverse'(L1, [], L2). 4224 4225'$reverse'([], List, List). 4226'$reverse'([Head|List1], List2, List3) :- 4227 '$reverse'(List1, [Head|List2], List3). 4228 4229'$delete'([], _, []) :- !. 4230'$delete'([Elem|Tail], Elem, Result) :- 4231 !, 4232 '$delete'(Tail, Elem, Result). 4233'$delete'([Head|Tail], Elem, [Head|Rest]) :- 4234 '$delete'(Tail, Elem, Rest). 4235 4236'$last'([H|T], Last) :- 4237 '$last'(T, H, Last). 4238 4239'$last'([], Last, Last). 4240'$last'([H|T], _, Last) :- 4241 '$last'(T, H, Last). 4242 4243:- meta_predicate '$include'( , , ). 4244'$include'(_, [], []). 4245'$include'(G, [H|T0], L) :- 4246 ( call(G,H) 4247 -> L = [H|T] 4248 ; T = L 4249 ), 4250 '$include'(G, T0, T). 4251 4252'$can_unify'(A, B) :- 4253 \+ A \= B.
4259:- '$iso'((length/2)). 4260 4261length(List, Length) :- 4262 var(Length), 4263 !, 4264 '$skip_list'(Length0, List, Tail), 4265 ( Tail == [] 4266 -> Length = Length0 % +,- 4267 ; var(Tail) 4268 -> Tail \== Length, % avoid length(L,L) 4269 '$length3'(Tail, Length, Length0) % -,- 4270 ; throw(error(type_error(list, List), 4271 context(length/2, _))) 4272 ). 4273length(List, Length) :- 4274 integer(Length), 4275 Length >= 0, 4276 !, 4277 '$skip_list'(Length0, List, Tail), 4278 ( Tail == [] % proper list 4279 -> Length = Length0 4280 ; var(Tail) 4281 -> Extra is Length-Length0, 4282 '$length'(Tail, Extra) 4283 ; throw(error(type_error(list, List), 4284 context(length/2, _))) 4285 ). 4286length(_, Length) :- 4287 integer(Length), 4288 !, 4289 throw(error(domain_error(not_less_than_zero, Length), 4290 context(length/2, _))). 4291length(_, Length) :- 4292 throw(error(type_error(integer, Length), 4293 context(length/2, _))). 4294 4295'$length3'([], N, N). 4296'$length3'([_|List], N, N0) :- 4297 N1 is N0+1, 4298 '$length3'(List, N, N1). 4299 4300 4301 /******************************* 4302 * OPTION PROCESSING * 4303 *******************************/
4309'$is_options'(Map) :- 4310 is_dict(Map, _), 4311 !. 4312'$is_options'(List) :- 4313 is_list(List), 4314 ( List == [] 4315 -> true 4316 ; List = [H|_], 4317 '$is_option'(H, _, _) 4318 ). 4319 4320'$is_option'(Var, _, _) :- 4321 var(Var), !, fail. 4322'$is_option'(F, Name, Value) :- 4323 functor(F, _, 1), 4324 !, 4325 F =.. [Name,Value]. 4326'$is_option'(Name=Value, Name, Value).
4330'$option'(Opt, Options) :- 4331 is_dict(Options), 4332 !, 4333 [Opt] :< Options. 4334'$option'(Opt, Options) :- 4335 memberchk(Opt, Options).
4339'$option'(Term, Options, Default) :-
4340 arg(1, Term, Value),
4341 functor(Term, Name, 1),
4342 ( is_dict(Options)
4343 -> ( get_dict(Name, Options, GVal)
4344 -> Value = GVal
4345 ; Value = Default
4346 )
4347 ; functor(Gen, Name, 1),
4348 arg(1, Gen, GVal),
4349 ( memberchk(Gen, Options)
4350 -> Value = GVal
4351 ; Value = Default
4352 )
4353 ).
4361'$select_option'(Opt, Options, Rest) :-
4362 '$options_dict'(Options, Dict),
4363 select_dict([Opt], Dict, Rest).
4371'$merge_options'(New, Old, Merged) :-
4372 '$options_dict'(New, NewDict),
4373 '$options_dict'(Old, OldDict),
4374 put_dict(NewDict, OldDict, Merged).
4381'$options_dict'(Options, Dict) :- 4382 is_list(Options), 4383 !, 4384 '$keyed_options'(Options, Keyed), 4385 sort(1, @<, Keyed, UniqueKeyed), 4386 '$pairs_values'(UniqueKeyed, Unique), 4387 dict_create(Dict, _, Unique). 4388'$options_dict'(Dict, Dict) :- 4389 is_dict(Dict), 4390 !. 4391'$options_dict'(Options, _) :- 4392 '$domain_error'(options, Options). 4393 4394'$keyed_options'([], []). 4395'$keyed_options'([H0|T0], [H|T]) :- 4396 '$keyed_option'(H0, H), 4397 '$keyed_options'(T0, T). 4398 4399'$keyed_option'(Var, _) :- 4400 var(Var), 4401 !, 4402 '$instantiation_error'(Var). 4403'$keyed_option'(Name=Value, Name-(Name-Value)). 4404'$keyed_option'(NameValue, Name-(Name-Value)) :- 4405 compound_name_arguments(NameValue, Name, [Value]), 4406 !. 4407'$keyed_option'(Opt, _) :- 4408 '$domain_error'(option, Opt). 4409 4410 4411 /******************************* 4412 * HANDLE TRACER 'L'-COMMAND * 4413 *******************************/ 4414 4415:- public '$prolog_list_goal'/1. 4416 4417:- multifile 4418 user:prolog_list_goal/1. 4419 4420'$prolog_list_goal'(Goal) :- 4421 user:prolog_list_goal(Goal), 4422 !. 4423'$prolog_list_goal'(Goal) :- 4424 use_module(library(listing), [listing/1]), 4425 @(listing(Goal), user). 4426 4427 4428 /******************************* 4429 * HALT * 4430 *******************************/ 4431 4432:- '$iso'((halt/0)). 4433 4434halt :- 4435 '$exit_code'(Code), 4436 ( Code == 0 4437 -> true 4438 ; print_message(warning, on_error(halt(1))) 4439 ), 4440 halt(Code).
on_error
and on_warning
flags. Also used by qsave_toplevel/0.
4447'$exit_code'(Code) :-
4448 ( ( current_prolog_flag(on_error, status),
4449 statistics(errors, Count),
4450 Count > 0
4451 ; current_prolog_flag(on_warning, status),
4452 statistics(warnings, Count),
4453 Count > 0
4454 )
4455 -> Code = 1
4456 ; Code = 0
4457 ).
4466:- meta_predicate at_halt( ). 4467:- dynamic system:term_expansion/2, '$at_halt'/2. 4468:- multifile system:term_expansion/2, '$at_halt'/2. 4469 4470systemterm_expansion((:- at_halt(Goal)), 4471 system:'$at_halt'(Module:Goal, File:Line)) :- 4472 \+ current_prolog_flag(xref, true), 4473 source_location(File, Line), 4474 '$current_source_module'(Module). 4475 4476at_halt(Goal) :- 4477 asserta('$at_halt'(Goal, (-):0)). 4478 4479:- public '$run_at_halt'/0. 4480 4481'$run_at_halt' :- 4482 forall(clause('$at_halt'(Goal, Src), true, Ref), 4483 ( '$call_at_halt'(Goal, Src), 4484 erase(Ref) 4485 )). 4486 4487'$call_at_halt'(Goal, _Src) :- 4488 catch(Goal, E, true), 4489 !, 4490 ( var(E) 4491 -> true 4492 ; subsumes_term(cancel_halt(_), E) 4493 -> '$print_message'(informational, E), 4494 fail 4495 ; '$print_message'(error, E) 4496 ). 4497'$call_at_halt'(Goal, _Src) :- 4498 '$print_message'(warning, goal_failed(at_halt, Goal)).
4506cancel_halt(Reason) :-
4507 throw(cancel_halt(Reason)).
heartbeat
is
non-zero.4514:- multifile prolog:heartbeat/0. 4515 4516 4517 /******************************** 4518 * LOAD OTHER MODULES * 4519 *********************************/ 4520 4521:- meta_predicate 4522 '$load_wic_files'( ). 4523 4524'$load_wic_files'(Files) :- 4525 Files = Module:_, 4526 '$execute_directive'('$set_source_module'(OldM, Module), [], []), 4527 '$save_lex_state'(LexState, []), 4528 '$style_check'(_, 0xC7), % see style_name/2 in syspred.pl 4529 '$compilation_mode'(OldC, wic), 4530 consult(Files), 4531 '$execute_directive'('$set_source_module'(OldM), [], []), 4532 '$execute_directive'('$restore_lex_state'(LexState), [], []), 4533 '$set_compilation_mode'(OldC).
compileFileList()
in pl-wic.c. Gets the files from
"-c file ..." and loads them into the module user.4541:- public '$load_additional_boot_files'/0. 4542 4543'$load_additional_boot_files' :- 4544 current_prolog_flag(argv, Argv), 4545 '$get_files_argv'(Argv, Files), 4546 ( Files \== [] 4547 -> format('Loading additional boot files~n'), 4548 '$load_wic_files'(user:Files), 4549 format('additional boot files loaded~n') 4550 ; true 4551 ). 4552 4553'$get_files_argv'([], []) :- !. 4554'$get_files_argv'(['-c'|Files], Files) :- !. 4555'$get_files_argv'([_|Rest], Files) :- 4556 '$get_files_argv'(Rest, Files). 4557 4558'$:-'(('$boot_message'('Loading Prolog startup files~n', []), 4559 source_location(File, _Line), 4560 file_directory_name(File, Dir), 4561 atom_concat(Dir, '/load.pl', LoadFile), 4562 '$load_wic_files'(system:[LoadFile]), 4563 ( current_prolog_flag(windows, true) 4564 -> atom_concat(Dir, '/menu.pl', MenuFile), 4565 '$load_wic_files'(system:[MenuFile]) 4566 ; true 4567 ), 4568 '$boot_message'('SWI-Prolog boot files loaded~n', []), 4569 '$compilation_mode'(OldC, wic), 4570 '$execute_directive'('$set_source_module'(user), [], []), 4571 '$set_compilation_mode'(OldC) 4572 ))