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-2025, 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'.
616'$tbl_reset'(_Goal, _Ball, _Cont, _WorkList, _Skeleton, _Delays) :-
617 '$reset'.626shift(Ball) :- 627 '$shift'(Ball). 628 629shift_for_copy(Ball) :- 630 '$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.
644call_continuation([]). 645call_continuation([TB|Rest]) :- 646 ( Rest == [] 647 -> '$call_continuation'(TB) 648 ; '$call_continuation'(TB), 649 call_continuation(Rest) 650 ).
657catch_with_backtrace(Goal, Ball, Recover) :- 658 catch(Goal, Ball, Recover), 659 '$no_lco'. 660 661'$no_lco'.
unwind(Term). Note that we cut to ensure
that the exception is not delayed forever because the recover
handler leaves a choicepoint.671:- public '$recover_and_rethrow'/2. 672 673'$recover_and_rethrow'(Goal, Exception) :- 674 call_cleanup(Goal, throw(Exception)), 675 !.
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.689setup_call_catcher_cleanup(Setup, _Goal, _Catcher, _Cleanup) :- 690 sig_atomic(Setup), 691 '$call_cleanup'. 692 693setup_call_cleanup(Setup, _Goal, _Cleanup) :- 694 sig_atomic(Setup), 695 '$call_cleanup'. 696 697call_cleanup(_Goal, _Cleanup) :- 698 '$call_cleanup'. 699 700 701 /******************************* 702 * INITIALIZATION * 703 *******************************/ 704 705:- meta_predicate 706 initialization(, ). 707 708:- multifile '$init_goal'/3. 709:- dynamic '$init_goal'/3. 710:- '$notransact'('$init_goal'/3).
-g goal goals.Note that all goals are executed when a program is restored.
736initialization(Goal, When) :- 737 '$must_be'(oneof(atom, initialization_type, 738 [ now, 739 after_load, 740 restore, 741 restore_state, 742 prepare_state, 743 program, 744 main 745 ]), When), 746 '$initialization_context'(Source, Ctx), 747 '$initialization'(When, Goal, Source, Ctx). 748 749'$initialization'(now, Goal, _Source, Ctx) :- 750 '$run_init_goal'(Goal, Ctx), 751 '$compile_init_goal'(-, Goal, Ctx). 752'$initialization'(after_load, Goal, Source, Ctx) :- 753 ( Source \== (-) 754 -> '$compile_init_goal'(Source, Goal, Ctx) 755 ; throw(error(context_error(nodirective, 756 initialization(Goal, after_load)), 757 _)) 758 ). 759'$initialization'(restore, Goal, Source, Ctx) :- % deprecated 760 '$initialization'(restore_state, Goal, Source, Ctx). 761'$initialization'(restore_state, Goal, _Source, Ctx) :- 762 ( \+ current_prolog_flag(sandboxed_load, true) 763 -> '$compile_init_goal'(-, Goal, Ctx) 764 ; '$permission_error'(register, initialization(restore), Goal) 765 ). 766'$initialization'(prepare_state, Goal, _Source, Ctx) :- 767 ( \+ current_prolog_flag(sandboxed_load, true) 768 -> '$compile_init_goal'(when(prepare_state), Goal, Ctx) 769 ; '$permission_error'(register, initialization(restore), Goal) 770 ). 771'$initialization'(program, Goal, _Source, Ctx) :- 772 ( \+ current_prolog_flag(sandboxed_load, true) 773 -> '$compile_init_goal'(when(program), Goal, Ctx) 774 ; '$permission_error'(register, initialization(restore), Goal) 775 ). 776'$initialization'(main, Goal, _Source, Ctx) :- 777 ( \+ current_prolog_flag(sandboxed_load, true) 778 -> '$compile_init_goal'(when(main), Goal, Ctx) 779 ; '$permission_error'(register, initialization(restore), Goal) 780 ). 781 782 783'$compile_init_goal'(Source, Goal, Ctx) :- 784 atom(Source), 785 Source \== (-), 786 !, 787 '$store_admin_clause'(system:'$init_goal'(Source, Goal, Ctx), 788 _Layout, Source, Ctx). 789'$compile_init_goal'(Source, Goal, Ctx) :- 790 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.802'$run_initialization'(_, loaded, _) :- !. 803'$run_initialization'(File, _Action, Options) :- 804 '$run_initialization'(File, Options). 805 806'$run_initialization'(File, Options) :- 807 setup_call_cleanup( 808 '$start_run_initialization'(Options, Restore), 809 '$run_initialization_2'(File), 810 '$end_run_initialization'(Restore)). 811 812'$start_run_initialization'(Options, OldSandBoxed) :- 813 '$push_input_context'(initialization), 814 '$set_sandboxed_load'(Options, OldSandBoxed). 815'$end_run_initialization'(OldSandBoxed) :- 816 set_prolog_flag(sandboxed_load, OldSandBoxed), 817 '$pop_input_context'. 818 819'$run_initialization_2'(File) :- 820 ( '$init_goal'(File, Goal, Ctx), 821 File \= when(_), 822 '$run_init_goal'(Goal, Ctx), 823 fail 824 ; true 825 ). 826 827'$run_init_goal'(Goal, Ctx) :- 828 ( catch_with_backtrace('$run_init_goal'(Goal), E, 829 '$initialization_error'(E, Goal, Ctx)) 830 -> true 831 ; '$initialization_failure'(Goal, Ctx) 832 ). 833 834:- multifile prolog:sandbox_allowed_goal/1. 835 836'$run_init_goal'(Goal) :- 837 current_prolog_flag(sandboxed_load, false), 838 !, 839 call(Goal). 840'$run_init_goal'(Goal) :- 841 prolog:sandbox_allowed_goal(Goal), 842 call(Goal). 843 844'$initialization_context'(Source, Ctx) :- 845 ( source_location(File, Line) 846 -> Ctx = File:Line, 847 '$input_context'(Context), 848 '$top_file'(Context, File, Source) 849 ; Ctx = (-), 850 File = (-) 851 ). 852 853'$top_file'([input(include, F1, _, _)|T], _, F) :- 854 !, 855 '$top_file'(T, F1, F). 856'$top_file'(_, F, F). 857 858 859'$initialization_error'(unwind(halt(Status)), Goal, Ctx) :- 860 !, 861 print_message(warning, initialization(halt(Status), Goal, Ctx)). 862'$initialization_error'(E, Goal, Ctx) :- 863 print_message(error, initialization_error(Goal, E, Ctx)). 864 865'$initialization_failure'(Goal, Ctx) :- 866 print_message(warning, initialization_failure(Goal, Ctx)).
874:- public '$clear_source_admin'/1. 875 876'$clear_source_admin'(File) :- 877 retractall('$init_goal'(_, _, File:_)), 878 retractall('$load_context_module'(File, _, _)), 879 retractall('$resolved_source_path_db'(_, _, File)). 880 881 882 /******************************* 883 * STREAM * 884 *******************************/ 885 886:- '$iso'(stream_property/2). 887stream_property(Stream, Property) :- 888 nonvar(Stream), 889 nonvar(Property), 890 !, 891 '$stream_property'(Stream, Property). 892stream_property(Stream, Property) :- 893 nonvar(Stream), 894 !, 895 '$stream_properties'(Stream, Properties), 896 '$member'(Property, Properties). 897stream_property(Stream, Property) :- 898 nonvar(Property), 899 !, 900 ( Property = alias(Alias), 901 atom(Alias) 902 -> '$alias_stream'(Alias, Stream) 903 ; '$streams_properties'(Property, Pairs), 904 '$member'(Stream-Property, Pairs) 905 ). 906stream_property(Stream, Property) :- 907 '$streams_properties'(Property, Pairs), 908 '$member'(Stream-Properties, Pairs), 909 '$member'(Property, Properties). 910 911 912 /******************************** 913 * MODULES * 914 *********************************/ 915 916% '$prefix_module'(+Module, +Context, +Term, -Prefixed) 917% Tags `Term' with `Module:' if `Module' is not the context module. 918 919'$prefix_module'(Module, Module, Head, Head) :- !. 920'$prefix_module'(Module, _, Head, Module:Head).
926default_module(Me, Super) :- 927 ( atom(Me) 928 -> ( var(Super) 929 -> '$default_module'(Me, Super) 930 ; '$default_module'(Me, Super), ! 931 ) 932 ; '$type_error'(module, Me) 933 ). 934 935'$default_module'(Me, Me). 936'$default_module'(Me, Super) :- 937 import_module(Me, S), 938 '$default_module'(S, Super). 939 940 941 /******************************** 942 * TRACE AND EXCEPTIONS * 943 *********************************/ 944 945:- dynamic user:exception/3. 946:- multifile user:exception/3. 947:- '$hide'(user:exception/3).
956:- public 957 '$undefined_procedure'/4. 958 959'$undefined_procedure'(Module, Name, Arity, Action) :- 960 '$prefix_module'(Module, user, Name/Arity, Pred), 961 user:exception(undefined_predicate, Pred, Action0), 962 !, 963 Action = Action0. 964'$undefined_procedure'(Module, Name, Arity, Action) :- 965 \+ current_prolog_flag(autoload, false), 966 '$autoload'(Module:Name/Arity), 967 !, 968 Action = retry. 969'$undefined_procedure'(_, _, _, error).
981'$loading'(Library) :- 982 current_prolog_flag(threads, true), 983 ( '$loading_file'(Library, _Queue, _LoadThread) 984 -> true 985 ; '$loading_file'(FullFile, _Queue, _LoadThread), 986 file_name_extension(Library, _, FullFile) 987 -> true 988 ). 989 990% handle debugger 'w', 'p' and <N> depth options. 991 992'$set_debugger_write_options'(write) :- 993 !, 994 create_prolog_flag(debugger_write_options, 995 [ quoted(true), 996 attributes(dots), 997 spacing(next_argument) 998 ], []). 999'$set_debugger_write_options'(print) :- 1000 !, 1001 create_prolog_flag(debugger_write_options, 1002 [ quoted(true), 1003 portray(true), 1004 max_depth(10), 1005 attributes(portray), 1006 spacing(next_argument) 1007 ], []). 1008'$set_debugger_write_options'(Depth) :- 1009 current_prolog_flag(debugger_write_options, Options0), 1010 ( '$select'(max_depth(_), Options0, Options) 1011 -> true 1012 ; Options = Options0 1013 ), 1014 create_prolog_flag(debugger_write_options, 1015 [max_depth(Depth)|Options], []). 1016 1017 1018 /******************************** 1019 * SYSTEM MESSAGES * 1020 *********************************/
query channel. This
predicate may be hooked using confirm/2, which must return
a boolean.1029:- multifile 1030 prolog:confirm/2. 1031 1032'$confirm'(Spec) :- 1033 prolog:confirm(Spec, Result), 1034 !, 1035 Result == true. 1036'$confirm'(Spec) :- 1037 print_message(query, Spec), 1038 between(0, 5, _), 1039 get_single_char(Answer), 1040 ( '$in_reply'(Answer, 'yYjJ \n') 1041 -> !, 1042 print_message(query, if_tty([yes-[]])) 1043 ; '$in_reply'(Answer, 'nN') 1044 -> !, 1045 print_message(query, if_tty([no-[]])), 1046 fail 1047 ; print_message(help, query(confirm)), 1048 fail 1049 ). 1050 1051'$in_reply'(Code, Atom) :- 1052 char_code(Char, Code), 1053 sub_atom(Atom, _, _, _, Char), 1054 !. 1055 1056:- dynamic 1057 user:portray/1. 1058:- multifile 1059 user:portray/1. 1060:- '$notransact'(user:portray/1). 1061 1062 1063 /******************************* 1064 * FILE_SEARCH_PATH * 1065 *******************************/ 1066 1067:- dynamic 1068 user:file_search_path/2, 1069 user:library_directory/1. 1070:- multifile 1071 user:file_search_path/2, 1072 user:library_directory/1. 1073:- '$notransact'((user:file_search_path/2, 1074 user:library_directory/1)). 1075 1076user(file_search_path(library, Dir) :- 1077 library_directory(Dir)). 1078user:file_search_path(swi, Home) :- 1079 current_prolog_flag(home, Home). 1080user:file_search_path(swi, Home) :- 1081 current_prolog_flag(shared_home, Home). 1082user:file_search_path(library, app_config(lib)). 1083user:file_search_path(library, swi(library)). 1084user:file_search_path(library, swi(library/clp)). 1085user:file_search_path(library, Dir) :- 1086 '$ext_library_directory'(Dir). 1087user:file_search_path(path, Dir) :- 1088 getenv('PATH', Path), 1089 current_prolog_flag(path_sep, Sep), 1090 atomic_list_concat(Dirs, Sep, Path), 1091 '$member'(Dir, Dirs). 1092user:file_search_path(user_app_data, Dir) :- 1093 '$xdg_prolog_directory'(data, Dir). 1094user:file_search_path(common_app_data, Dir) :- 1095 '$xdg_prolog_directory'(common_data, Dir). 1096user:file_search_path(user_app_config, Dir) :- 1097 '$xdg_prolog_directory'(config, Dir). 1098user:file_search_path(common_app_config, Dir) :- 1099 '$xdg_prolog_directory'(common_config, Dir). 1100user:file_search_path(app_data, user_app_data('.')). 1101user:file_search_path(app_data, common_app_data('.')). 1102user:file_search_path(app_config, user_app_config('.')). 1103user:file_search_path(app_config, common_app_config('.')). 1104% backward compatibility 1105user:file_search_path(app_preferences, user_app_config('.')). 1106user:file_search_path(user_profile, app_preferences('.')). 1107user:file_search_path(app, swi(app)). 1108user:file_search_path(app, app_data(app)). 1109user:file_search_path(demo, swi(demo)). 1110user:file_search_path(working_directory, CWD) :- 1111 working_directory(CWD, CWD). 1112 1113'$xdg_prolog_directory'(Which, Dir) :- 1114 '$xdg_directory'(Which, XDGDir), 1115 '$make_config_dir'(XDGDir), 1116 '$ensure_slash'(XDGDir, XDGDirS), 1117 atom_concat(XDGDirS, 'swi-prolog', Dir), 1118 '$make_config_dir'(Dir). 1119 1120'$xdg_directory'(Which, Dir) :- 1121 '$xdg_directory_search'(Where), 1122 '$xdg_directory'(Which, Where, Dir). 1123 1124'$xdg_directory_search'(xdg) :- 1125 current_prolog_flag(xdg, true), 1126 !. 1127'$xdg_directory_search'(Where) :- 1128 current_prolog_flag(windows, true), 1129 ( current_prolog_flag(xdg, false) 1130 -> Where = windows 1131 ; '$member'(Where, [windows, xdg]) 1132 ). 1133 1134% config 1135'$xdg_directory'(config, windows, Home) :- 1136 catch(win_folder(appdata, Home), _, fail). 1137'$xdg_directory'(config, xdg, Home) :- 1138 getenv('XDG_CONFIG_HOME', Home). 1139'$xdg_directory'(config, xdg, Home) :- 1140 expand_file_name('~/.config', [Home]). 1141% data 1142'$xdg_directory'(data, windows, Home) :- 1143 catch(win_folder(local_appdata, Home), _, fail). 1144'$xdg_directory'(data, xdg, Home) :- 1145 getenv('XDG_DATA_HOME', Home). 1146'$xdg_directory'(data, xdg, Home) :- 1147 expand_file_name('~/.local', [Local]), 1148 '$make_config_dir'(Local), 1149 atom_concat(Local, '/share', Home), 1150 '$make_config_dir'(Home). 1151% common data 1152'$xdg_directory'(common_data, windows, Dir) :- 1153 catch(win_folder(common_appdata, Dir), _, fail). 1154'$xdg_directory'(common_data, xdg, Dir) :- 1155 '$existing_dir_from_env_path'('XDG_DATA_DIRS', 1156 [ '/usr/local/share', 1157 '/usr/share' 1158 ], 1159 Dir). 1160% common config 1161'$xdg_directory'(common_config, windows, Dir) :- 1162 catch(win_folder(common_appdata, Dir), _, fail). 1163'$xdg_directory'(common_config, xdg, Dir) :- 1164 '$existing_dir_from_env_path'('XDG_CONFIG_DIRS', ['/etc/xdg'], Dir). 1165 1166'$existing_dir_from_env_path'(Env, Defaults, Dir) :- 1167 ( getenv(Env, Path) 1168 -> current_prolog_flag(path_sep, Sep), 1169 atomic_list_concat(Dirs, Sep, Path) 1170 ; Dirs = Defaults 1171 ), 1172 '$member'(Dir, Dirs), 1173 Dir \== '', 1174 exists_directory(Dir). 1175 1176'$make_config_dir'(Dir) :- 1177 exists_directory(Dir), 1178 !. 1179'$make_config_dir'(Dir) :- 1180 nb_current('$create_search_directories', true), 1181 file_directory_name(Dir, Parent), 1182 '$my_file'(Parent), 1183 catch(make_directory(Dir), _, fail). 1184 1185'$ensure_slash'(Dir, DirS) :- 1186 ( sub_atom(Dir, _, _, 0, /) 1187 -> DirS = Dir 1188 ; atom_concat(Dir, /, DirS) 1189 ). 1190 1191:- dynamic '$ext_lib_dirs'/1. 1192:- volatile '$ext_lib_dirs'/1. 1193 1194'$ext_library_directory'(Dir) :- 1195 '$ext_lib_dirs'(Dirs), 1196 !, 1197 '$member'(Dir, Dirs). 1198'$ext_library_directory'(Dir) :- 1199 current_prolog_flag(home, Home), 1200 atom_concat(Home, '/library/ext/*', Pattern), 1201 expand_file_name(Pattern, Dirs0), 1202 '$include'(exists_directory, Dirs0, Dirs), 1203 asserta('$ext_lib_dirs'(Dirs)), 1204 '$member'(Dir, Dirs).
1209'$expand_file_search_path'(Spec, Expanded, Cond) :- 1210 '$option'(access(Access), Cond), 1211 memberchk(Access, [write,append]), 1212 !, 1213 setup_call_cleanup( 1214 nb_setval('$create_search_directories', true), 1215 expand_file_search_path(Spec, Expanded), 1216 nb_delete('$create_search_directories')). 1217'$expand_file_search_path'(Spec, Expanded, _Cond) :- 1218 expand_file_search_path(Spec, Expanded).
1226expand_file_search_path(Spec, Expanded) :- 1227 catch('$expand_file_search_path'(Spec, Expanded, 0, []), 1228 loop(Used), 1229 throw(error(loop_error(Spec), file_search(Used)))). 1230 1231'$expand_file_search_path'(Spec, Expanded, N, Used) :- 1232 functor(Spec, Alias, 1), 1233 !, 1234 user:file_search_path(Alias, Exp0), 1235 NN is N + 1, 1236 ( NN > 16 1237 -> throw(loop(Used)) 1238 ; true 1239 ), 1240 '$expand_file_search_path'(Exp0, Exp1, NN, [Alias=Exp0|Used]), 1241 arg(1, Spec, Segments), 1242 '$segments_to_atom'(Segments, File), 1243 '$make_path'(Exp1, File, Expanded). 1244'$expand_file_search_path'(Spec, Path, _, _) :- 1245 '$segments_to_atom'(Spec, Path). 1246 1247'$make_path'(Dir, '.', Path) :- 1248 !, 1249 Path = Dir. 1250'$make_path'(Dir, File, Path) :- 1251 sub_atom(Dir, _, _, 0, /), 1252 !, 1253 atom_concat(Dir, File, Path). 1254'$make_path'(Dir, File, Path) :- 1255 atomic_list_concat([Dir, /, File], Path). 1256 1257 1258 /******************************** 1259 * FILE CHECKING * 1260 *********************************/
1271absolute_file_name(Spec, Options, Path) :- 1272 '$is_options'(Options), 1273 \+ '$is_options'(Path), 1274 !, 1275 '$absolute_file_name'(Spec, Path, Options). 1276absolute_file_name(Spec, Path, Options) :- 1277 '$absolute_file_name'(Spec, Path, Options). 1278 1279'$absolute_file_name'(Spec, Path, Options0) :- 1280 '$options_dict'(Options0, Options), 1281 % get the valid extensions 1282 ( '$select_option'(extensions(Exts), Options, Options1) 1283 -> '$must_be'(list, Exts) 1284 ; '$option'(file_type(Type), Options) 1285 -> '$must_be'(atom, Type), 1286 '$file_type_extensions'(Type, Exts), 1287 Options1 = Options 1288 ; Options1 = Options, 1289 Exts = [''] 1290 ), 1291 '$canonicalise_extensions'(Exts, Extensions), 1292 % unless specified otherwise, ask regular file 1293 ( ( nonvar(Type) 1294 ; '$option'(access(none), Options, none) 1295 ) 1296 -> Options2 = Options1 1297 ; '$merge_options'(_{file_type:regular}, Options1, Options2) 1298 ), 1299 % Det or nondet? 1300 ( '$select_option'(solutions(Sols), Options2, Options3) 1301 -> '$must_be'(oneof(atom, solutions, [first,all]), Sols) 1302 ; Sols = first, 1303 Options3 = Options2 1304 ), 1305 % Errors or not? 1306 ( '$select_option'(file_errors(FileErrors), Options3, Options4) 1307 -> '$must_be'(oneof(atom, file_errors, [error,fail]), FileErrors) 1308 ; FileErrors = error, 1309 Options4 = Options3 1310 ), 1311 % Expand shell patterns? 1312 ( atomic(Spec), 1313 '$select_option'(expand(Expand), Options4, Options5), 1314 '$must_be'(boolean, Expand) 1315 -> expand_file_name(Spec, List), 1316 '$member'(Spec1, List) 1317 ; Spec1 = Spec, 1318 Options5 = Options4 1319 ), 1320 % Search for files 1321 ( Sols == first 1322 -> ( '$chk_file'(Spec1, Extensions, Options5, true, Path) 1323 -> ! % also kill choice point of expand_file_name/2 1324 ; ( FileErrors == fail 1325 -> fail 1326 ; '$current_module'('$bags', _File), 1327 findall(P, 1328 '$chk_file'(Spec1, Extensions, [access(exist)], 1329 false, P), 1330 Candidates), 1331 '$abs_file_error'(Spec, Candidates, Options5) 1332 ) 1333 ) 1334 ; '$chk_file'(Spec1, Extensions, Options5, false, Path) 1335 ). 1336 1337'$abs_file_error'(Spec, Candidates, Conditions) :- 1338 '$member'(F, Candidates), 1339 '$member'(C, Conditions), 1340 '$file_condition'(C), 1341 '$file_error'(C, Spec, F, E, Comment), 1342 !, 1343 throw(error(E, context(_, Comment))). 1344'$abs_file_error'(Spec, _, _) :- 1345 '$existence_error'(source_sink, Spec). 1346 1347'$file_error'(file_type(directory), Spec, File, Error, Comment) :- 1348 \+ exists_directory(File), 1349 !, 1350 Error = existence_error(directory, Spec), 1351 Comment = not_a_directory(File). 1352'$file_error'(file_type(_), Spec, File, Error, Comment) :- 1353 exists_directory(File), 1354 !, 1355 Error = existence_error(file, Spec), 1356 Comment = directory(File). 1357'$file_error'(access(OneOrList), Spec, File, Error, _) :- 1358 '$one_or_member'(Access, OneOrList), 1359 \+ access_file(File, Access), 1360 Error = permission_error(Access, source_sink, Spec). 1361 1362'$one_or_member'(Elem, List) :- 1363 is_list(List), 1364 !, 1365 '$member'(Elem, List). 1366'$one_or_member'(Elem, Elem). 1367 1368'$file_type_extensions'(Type, Exts) :- 1369 '$current_module'('$bags', _File), 1370 !, 1371 findall(Ext, user:prolog_file_type(Ext, Type), Exts0), 1372 ( Exts0 == [], 1373 \+ '$ft_no_ext'(Type) 1374 -> '$domain_error'(file_type, Type) 1375 ; true 1376 ), 1377 '$append'(Exts0, [''], Exts). 1378'$file_type_extensions'(prolog, [pl, '']). % findall is not yet defined ... 1379 1380'$ft_no_ext'(txt). 1381'$ft_no_ext'(executable). 1382'$ft_no_ext'(directory). 1383'$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.
1396:- multifile(user:prolog_file_type/2). 1397:- dynamic(user:prolog_file_type/2). 1398 1399userprolog_file_type(pl, prolog). 1400userprolog_file_type(prolog, prolog). 1401userprolog_file_type(qlf, prolog). 1402userprolog_file_type(pl, source). 1403userprolog_file_type(prolog, source). 1404userprolog_file_type(qlf, qlf). 1405userprolog_file_type(Ext, executable) :- 1406 current_prolog_flag(shared_object_extension, Ext). 1407userprolog_file_type(dylib, executable) :- 1408 current_prolog_flag(apple, true).
1415'$chk_file'(Spec, _Extensions, _Cond, _Cache, _FullName) :- 1416 \+ ground(Spec), 1417 !, 1418 '$instantiation_error'(Spec). 1419'$chk_file'(Spec, Extensions, Cond, Cache, FullName) :- 1420 compound(Spec), 1421 functor(Spec, _, 1), 1422 !, 1423 '$relative_to'(Cond, cwd, CWD), 1424 '$chk_alias_file'(Spec, Extensions, Cond, Cache, CWD, FullName). 1425'$chk_file'(Segments, Ext, Cond, Cache, FullName) :- % allow a/b/... 1426 \+ atomic(Segments), 1427 !, 1428 '$segments_to_atom'(Segments, Atom), 1429 '$chk_file'(Atom, Ext, Cond, Cache, FullName). 1430'$chk_file'(File, Exts, Cond, _, FullName) :- % Absolute files 1431 is_absolute_file_name(File), 1432 !, 1433 '$extend_file'(File, Exts, Extended), 1434 '$file_conditions'(Cond, Extended), 1435 '$absolute_file_name'(Extended, FullName). 1436'$chk_file'(File, Exts, Cond, _, FullName) :- % Explicit relative_to 1437 '$option'(relative_to(_), Cond), 1438 !, 1439 '$relative_to'(Cond, none, Dir), 1440 '$chk_file_relative_to'(File, Exts, Cond, Dir, FullName). 1441'$chk_file'(File, Exts, Cond, _Cache, FullName) :- % From source 1442 source_location(ContextFile, _Line), 1443 !, 1444 ( file_directory_name(ContextFile, Dir), 1445 '$chk_file_relative_to'(File, Exts, Cond, Dir, FullName) 1446 *-> true 1447 ; current_prolog_flag(source_search_working_directory, true), 1448 '$extend_file'(File, Exts, Extended), 1449 '$file_conditions'(Cond, Extended), 1450 '$absolute_file_name'(Extended, FullName), 1451 '$print_message'(warning, 1452 deprecated(source_search_working_directory( 1453 File, FullName))) 1454 ). 1455'$chk_file'(File, Exts, Cond, _Cache, FullName) :- % Not loading source 1456 '$extend_file'(File, Exts, Extended), 1457 '$file_conditions'(Cond, Extended), 1458 '$absolute_file_name'(Extended, FullName). 1459 1460'$chk_file_relative_to'(File, Exts, Cond, Dir, FullName) :- 1461 atomic_list_concat([Dir, /, File], AbsFile), 1462 '$extend_file'(AbsFile, Exts, Extended), 1463 '$file_conditions'(Cond, Extended), 1464 '$absolute_file_name'(Extended, FullName). 1465 1466 1467'$segments_to_atom'(Atom, Atom) :- 1468 atomic(Atom), 1469 !. 1470'$segments_to_atom'(Segments, Atom) :- 1471 '$segments_to_list'(Segments, List, []), 1472 !, 1473 atomic_list_concat(List, /, Atom). 1474 1475'$segments_to_list'(A/B, H, T) :- 1476 '$segments_to_list'(A, H, T0), 1477 '$segments_to_list'(B, T0, T). 1478'$segments_to_list'(A, [A|T], T) :- 1479 atomic(A).
relative_to(FileOrDir) options
or implicitely relative to the working directory or current
source-file.
1489'$relative_to'(Conditions, Default, Dir) :-
1490 ( '$option'(relative_to(FileOrDir), Conditions)
1491 *-> ( exists_directory(FileOrDir)
1492 -> Dir = FileOrDir
1493 ; atom_concat(Dir, /, FileOrDir)
1494 -> true
1495 ; file_directory_name(FileOrDir, Dir)
1496 )
1497 ; Default == cwd
1498 -> working_directory(Dir, Dir)
1499 ; Default == source
1500 -> source_location(ContextFile, _Line),
1501 file_directory_name(ContextFile, Dir)
1502 ).1507:- dynamic 1508 '$search_path_file_cache'/3, % SHA1, Time, Path 1509 '$search_path_gc_time'/1. % Time 1510:- volatile 1511 '$search_path_file_cache'/3, 1512 '$search_path_gc_time'/1. 1513:- '$notransact'(('$search_path_file_cache'/3, 1514 '$search_path_gc_time'/1)). 1515 1516:- create_prolog_flag(file_search_cache_time, 10, []). 1517 1518'$chk_alias_file'(Spec, Exts, Cond, true, CWD, FullFile) :- 1519 !, 1520 findall(Exp, '$expand_file_search_path'(Spec, Exp, Cond), Expansions), 1521 current_prolog_flag(emulated_dialect, Dialect), 1522 Cache = cache(Exts, Cond, CWD, Expansions, Dialect), 1523 variant_sha1(Spec+Cache, SHA1), 1524 get_time(Now), 1525 current_prolog_flag(file_search_cache_time, TimeOut), 1526 ( '$search_path_file_cache'(SHA1, CachedTime, FullFile), 1527 CachedTime > Now - TimeOut, 1528 '$file_conditions'(Cond, FullFile) 1529 -> '$search_message'(file_search(cache(Spec, Cond), FullFile)) 1530 ; '$member'(Expanded, Expansions), 1531 '$extend_file'(Expanded, Exts, LibFile), 1532 ( '$file_conditions'(Cond, LibFile), 1533 '$absolute_file_name'(LibFile, FullFile), 1534 '$cache_file_found'(SHA1, Now, TimeOut, FullFile) 1535 -> '$search_message'(file_search(found(Spec, Cond), FullFile)) 1536 ; '$search_message'(file_search(tried(Spec, Cond), LibFile)), 1537 fail 1538 ) 1539 ). 1540'$chk_alias_file'(Spec, Exts, Cond, false, _CWD, FullFile) :- 1541 '$expand_file_search_path'(Spec, Expanded, Cond), 1542 '$extend_file'(Expanded, Exts, LibFile), 1543 '$file_conditions'(Cond, LibFile), 1544 '$absolute_file_name'(LibFile, FullFile). 1545 1546'$cache_file_found'(_, _, TimeOut, _) :- 1547 TimeOut =:= 0, 1548 !. 1549'$cache_file_found'(SHA1, Now, TimeOut, FullFile) :- 1550 '$search_path_file_cache'(SHA1, Saved, FullFile), 1551 !, 1552 ( Now - Saved < TimeOut/2 1553 -> true 1554 ; retractall('$search_path_file_cache'(SHA1, _, _)), 1555 asserta('$search_path_file_cache'(SHA1, Now, FullFile)) 1556 ). 1557'$cache_file_found'(SHA1, Now, TimeOut, FullFile) :- 1558 'gc_file_search_cache'(TimeOut), 1559 asserta('$search_path_file_cache'(SHA1, Now, FullFile)). 1560 1561'gc_file_search_cache'(TimeOut) :- 1562 get_time(Now), 1563 '$search_path_gc_time'(Last), 1564 Now-Last < TimeOut/2, 1565 !. 1566'gc_file_search_cache'(TimeOut) :- 1567 get_time(Now), 1568 retractall('$search_path_gc_time'(_)), 1569 assertz('$search_path_gc_time'(Now)), 1570 Before is Now - TimeOut, 1571 ( '$search_path_file_cache'(SHA1, Cached, FullFile), 1572 Cached < Before, 1573 retractall('$search_path_file_cache'(SHA1, Cached, FullFile)), 1574 fail 1575 ; true 1576 ). 1577 1578 1579'$search_message'(Term) :- 1580 current_prolog_flag(verbose_file_search, true), 1581 !, 1582 print_message(informational, Term). 1583'$search_message'(_).
1590'$file_conditions'(List, File) :- 1591 is_list(List), 1592 !, 1593 \+ ( '$member'(C, List), 1594 '$file_condition'(C), 1595 \+ '$file_condition'(C, File) 1596 ). 1597'$file_conditions'(Map, File) :- 1598 \+ ( get_dict(Key, Map, Value), 1599 C =.. [Key,Value], 1600 '$file_condition'(C), 1601 \+ '$file_condition'(C, File) 1602 ). 1603 1604'$file_condition'(file_type(directory), File) :- 1605 !, 1606 exists_directory(File). 1607'$file_condition'(file_type(_), File) :- 1608 !, 1609 \+ exists_directory(File). 1610'$file_condition'(access(Accesses), File) :- 1611 !, 1612 \+ ( '$one_or_member'(Access, Accesses), 1613 \+ access_file(File, Access) 1614 ). 1615 1616'$file_condition'(exists). 1617'$file_condition'(file_type(_)). 1618'$file_condition'(access(_)). 1619 1620'$extend_file'(File, Exts, FileEx) :- 1621 '$ensure_extensions'(Exts, File, Fs), 1622 '$list_to_set'(Fs, FsSet), 1623 '$member'(FileEx, FsSet). 1624 1625'$ensure_extensions'([], _, []). 1626'$ensure_extensions'([E|E0], F, [FE|E1]) :- 1627 file_name_extension(F, E, FE), 1628 '$ensure_extensions'(E0, F, E1).
1635'$list_to_set'(List, Set) :- 1636 '$number_list'(List, 1, Numbered), 1637 sort(1, @=<, Numbered, ONum), 1638 '$remove_dup_keys'(ONum, NumSet), 1639 sort(2, @=<, NumSet, ONumSet), 1640 '$pairs_keys'(ONumSet, Set). 1641 1642'$number_list'([], _, []). 1643'$number_list'([H|T0], N, [H-N|T]) :- 1644 N1 is N+1, 1645 '$number_list'(T0, N1, T). 1646 1647'$remove_dup_keys'([], []). 1648'$remove_dup_keys'([H|T0], [H|T]) :- 1649 H = V-_, 1650 '$remove_same_key'(T0, V, T1), 1651 '$remove_dup_keys'(T1, T). 1652 1653'$remove_same_key'([V1-_|T0], V, T) :- 1654 V1 == V, 1655 !, 1656 '$remove_same_key'(T0, V, T). 1657'$remove_same_key'(L, _, L). 1658 1659'$pairs_keys'([], []). 1660'$pairs_keys'([K-_|T0], [K|T]) :- 1661 '$pairs_keys'(T0, T). 1662 1663'$pairs_values'([], []). 1664'$pairs_values'([_-V|T0], [V|T]) :- 1665 '$pairs_values'(T0, T). 1666 1667/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1668Canonicalise the extension list. Old SWI-Prolog require `.pl', etc, which 1669the Quintus compatibility requests `pl'. This layer canonicalises all 1670extensions to .ext 1671- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1672 1673'$canonicalise_extensions'([], []) :- !. 1674'$canonicalise_extensions'([H|T], [CH|CT]) :- 1675 !, 1676 '$must_be'(atom, H), 1677 '$canonicalise_extension'(H, CH), 1678 '$canonicalise_extensions'(T, CT). 1679'$canonicalise_extensions'(E, [CE]) :- 1680 '$canonicalise_extension'(E, CE). 1681 1682'$canonicalise_extension'('', '') :- !. 1683'$canonicalise_extension'(DotAtom, DotAtom) :- 1684 sub_atom(DotAtom, 0, _, _, '.'), 1685 !. 1686'$canonicalise_extension'(Atom, DotAtom) :- 1687 atom_concat('.', Atom, DotAtom). 1688 1689 1690 /******************************** 1691 * CONSULT * 1692 *********************************/ 1693 1694:- dynamic 1695 user:library_directory/1, 1696 user:prolog_load_file/2. 1697:- multifile 1698 user:library_directory/1, 1699 user:prolog_load_file/2. 1700 1701:- prompt(_, '|: '). 1702 1703:- thread_local 1704 '$compilation_mode_store'/1, % database, wic, qlf 1705 '$directive_mode_store'/1. % database, wic, qlf 1706:- volatile 1707 '$compilation_mode_store'/1, 1708 '$directive_mode_store'/1. 1709:- '$notransact'(('$compilation_mode_store'/1, 1710 '$directive_mode_store'/1)). 1711 1712'$compilation_mode'(Mode) :- 1713 ( '$compilation_mode_store'(Val) 1714 -> Mode = Val 1715 ; Mode = database 1716 ). 1717 1718'$set_compilation_mode'(Mode) :- 1719 retractall('$compilation_mode_store'(_)), 1720 assertz('$compilation_mode_store'(Mode)). 1721 1722'$compilation_mode'(Old, New) :- 1723 '$compilation_mode'(Old), 1724 ( New == Old 1725 -> true 1726 ; '$set_compilation_mode'(New) 1727 ). 1728 1729'$directive_mode'(Mode) :- 1730 ( '$directive_mode_store'(Val) 1731 -> Mode = Val 1732 ; Mode = database 1733 ). 1734 1735'$directive_mode'(Old, New) :- 1736 '$directive_mode'(Old), 1737 ( New == Old 1738 -> true 1739 ; '$set_directive_mode'(New) 1740 ). 1741 1742'$set_directive_mode'(Mode) :- 1743 retractall('$directive_mode_store'(_)), 1744 assertz('$directive_mode_store'(Mode)).
1752'$compilation_level'(Level) :- 1753 '$input_context'(Stack), 1754 '$compilation_level'(Stack, Level). 1755 1756'$compilation_level'([], 0). 1757'$compilation_level'([Input|T], Level) :- 1758 ( arg(1, Input, see) 1759 -> '$compilation_level'(T, Level) 1760 ; '$compilation_level'(T, Level0), 1761 Level is Level0+1 1762 ).
1770compiling :- 1771 \+ ( '$compilation_mode'(database), 1772 '$directive_mode'(database) 1773 ). 1774 1775:- meta_predicate 1776 '$ifcompiling'(). 1777 1778'$ifcompiling'(G) :- 1779 ( '$compilation_mode'(database) 1780 -> true 1781 ; call(G) 1782 ). 1783 1784 /******************************** 1785 * READ SOURCE * 1786 *********************************/
1790'$load_msg_level'(Action, Nesting, Start, Done) :- 1791 '$update_autoload_level'([], 0), 1792 !, 1793 current_prolog_flag(verbose_load, Type0), 1794 '$load_msg_compat'(Type0, Type), 1795 ( '$load_msg_level'(Action, Nesting, Type, Start, Done) 1796 -> true 1797 ). 1798'$load_msg_level'(_, _, silent, silent). 1799 1800'$load_msg_compat'(true, normal) :- !. 1801'$load_msg_compat'(false, silent) :- !. 1802'$load_msg_compat'(X, X). 1803 1804'$load_msg_level'(load_file, _, full, informational, informational). 1805'$load_msg_level'(include_file, _, full, informational, informational). 1806'$load_msg_level'(load_file, _, normal, silent, informational). 1807'$load_msg_level'(include_file, _, normal, silent, silent). 1808'$load_msg_level'(load_file, 0, brief, silent, informational). 1809'$load_msg_level'(load_file, _, brief, silent, silent). 1810'$load_msg_level'(include_file, _, brief, silent, silent). 1811'$load_msg_level'(load_file, _, silent, silent, silent). 1812'$load_msg_level'(include_file, _, silent, silent, silent).
1835'$source_term'(From, Read, RLayout, Term, TLayout, Stream, Options) :- 1836 '$source_term'(From, Read, RLayout, Term, TLayout, Stream, [], Options), 1837 ( Term == end_of_file 1838 -> !, fail 1839 ; Term \== begin_of_file 1840 ). 1841 1842'$source_term'(Input, _,_,_,_,_,_,_) :- 1843 \+ ground(Input), 1844 !, 1845 '$instantiation_error'(Input). 1846'$source_term'(stream(Id, In, Opts), 1847 Read, RLayout, Term, TLayout, Stream, Parents, Options) :- 1848 !, 1849 '$record_included'(Parents, Id, Id, 0.0, Message), 1850 setup_call_cleanup( 1851 '$open_source'(stream(Id, In, Opts), In, State, Parents, Options), 1852 '$term_in_file'(In, Read, RLayout, Term, TLayout, Stream, 1853 [Id|Parents], Options), 1854 '$close_source'(State, Message)). 1855'$source_term'(File, 1856 Read, RLayout, Term, TLayout, Stream, Parents, Options) :- 1857 absolute_file_name(File, Path, 1858 [ file_type(prolog), 1859 access(read) 1860 ]), 1861 time_file(Path, Time), 1862 '$record_included'(Parents, File, Path, Time, Message), 1863 setup_call_cleanup( 1864 '$open_source'(Path, In, State, Parents, Options), 1865 '$term_in_file'(In, Read, RLayout, Term, TLayout, Stream, 1866 [Path|Parents], Options), 1867 '$close_source'(State, Message)). 1868 1869:- thread_local 1870 '$load_input'/2. 1871:- volatile 1872 '$load_input'/2. 1873:- '$notransact'('$load_input'/2). 1874 1875'$open_source'(stream(Id, In, Opts), In, 1876 restore(In, StreamState, Id, Ref, Opts), Parents, _Options) :- 1877 !, 1878 '$context_type'(Parents, ContextType), 1879 '$push_input_context'(ContextType), 1880 '$prepare_load_stream'(In, Id, StreamState), 1881 asserta('$load_input'(stream(Id), In), Ref). 1882'$open_source'(Path, In, close(In, Path, Ref), Parents, Options) :- 1883 '$context_type'(Parents, ContextType), 1884 '$push_input_context'(ContextType), 1885 '$open_source'(Path, In, Options), 1886 '$set_encoding'(In, Options), 1887 asserta('$load_input'(Path, In), Ref). 1888 1889'$context_type'([], load_file) :- !. 1890'$context_type'(_, include). 1891 1892:- multifile prolog:open_source_hook/3. 1893 1894'$open_source'(Path, In, Options) :- 1895 prolog:open_source_hook(Path, In, Options), 1896 !. 1897'$open_source'(Path, In, _Options) :- 1898 open(Path, read, In). 1899 1900'$close_source'(close(In, _Id, Ref), Message) :- 1901 erase(Ref), 1902 call_cleanup( 1903 close(In), 1904 '$pop_input_context'), 1905 '$close_message'(Message). 1906'$close_source'(restore(In, StreamState, _Id, Ref, Opts), Message) :- 1907 erase(Ref), 1908 call_cleanup( 1909 '$restore_load_stream'(In, StreamState, Opts), 1910 '$pop_input_context'), 1911 '$close_message'(Message). 1912 1913'$close_message'(message(Level, Msg)) :- 1914 !, 1915 '$print_message'(Level, Msg). 1916'$close_message'(_).
1928'$term_in_file'(In, Read, RLayout, Term, TLayout, Stream, Parents, Options) :- 1929 Parents \= [_,_|_], 1930 ( '$load_input'(_, Input) 1931 -> stream_property(Input, file_name(File)) 1932 ), 1933 '$set_source_location'(File, 0), 1934 '$expanded_term'(In, 1935 begin_of_file, 0-0, Read, RLayout, Term, TLayout, 1936 Stream, Parents, Options). 1937'$term_in_file'(In, Read, RLayout, Term, TLayout, Stream, Parents, Options) :- 1938 '$skip_script_line'(In, Options), 1939 '$read_clause_options'(Options, ReadOptions), 1940 '$repeat_and_read_error_mode'(ErrorMode), 1941 read_clause(In, Raw, 1942 [ syntax_errors(ErrorMode), 1943 variable_names(Bindings), 1944 term_position(Pos), 1945 subterm_positions(RawLayout) 1946 | ReadOptions 1947 ]), 1948 b_setval('$term_position', Pos), 1949 b_setval('$variable_names', Bindings), 1950 ( Raw == end_of_file 1951 -> !, 1952 ( Parents = [_,_|_] % Included file 1953 -> fail 1954 ; '$expanded_term'(In, 1955 Raw, RawLayout, Read, RLayout, Term, TLayout, 1956 Stream, Parents, Options) 1957 ) 1958 ; '$expanded_term'(In, Raw, RawLayout, Read, RLayout, Term, TLayout, 1959 Stream, Parents, Options) 1960 ). 1961 1962'$read_clause_options'([], []). 1963'$read_clause_options'([H|T0], List) :- 1964 ( '$read_clause_option'(H) 1965 -> List = [H|T] 1966 ; List = T 1967 ), 1968 '$read_clause_options'(T0, T). 1969 1970'$read_clause_option'(syntax_errors(_)). 1971'$read_clause_option'(term_position(_)). 1972'$read_clause_option'(process_comment(_)).
expand.pl is not yet
loaded.1980'$repeat_and_read_error_mode'(Mode) :- 1981 ( current_predicate('$including'/0) 1982 -> repeat, 1983 ( '$including' 1984 -> Mode = dec10 1985 ; Mode = quiet 1986 ) 1987 ; Mode = dec10, 1988 repeat 1989 ). 1990 1991 1992'$expanded_term'(In, Raw, RawLayout, Read, RLayout, Term, TLayout, 1993 Stream, Parents, Options) :- 1994 E = error(_,_), 1995 catch('$expand_term'(Raw, RawLayout, Expanded, ExpandedLayout), E, 1996 '$print_message_fail'(E)), 1997 ( Expanded \== [] 1998 -> '$expansion_member'(Expanded, ExpandedLayout, Term1, Layout1) 1999 ; Term1 = Expanded, 2000 Layout1 = ExpandedLayout 2001 ), 2002 ( nonvar(Term1), Term1 = (:-Directive), nonvar(Directive) 2003 -> ( Directive = include(File), 2004 '$current_source_module'(Module), 2005 '$valid_directive'(Module:include(File)) 2006 -> stream_property(In, encoding(Enc)), 2007 '$add_encoding'(Enc, Options, Options1), 2008 '$source_term'(File, Read, RLayout, Term, TLayout, 2009 Stream, Parents, Options1) 2010 ; Directive = encoding(Enc) 2011 -> set_stream(In, encoding(Enc)), 2012 fail 2013 ; Term = Term1, 2014 Stream = In, 2015 Read = Raw 2016 ) 2017 ; Term = Term1, 2018 TLayout = Layout1, 2019 Stream = In, 2020 Read = Raw, 2021 RLayout = RawLayout 2022 ). 2023 2024'$expansion_member'(Var, Layout, Var, Layout) :- 2025 var(Var), 2026 !. 2027'$expansion_member'([], _, _, _) :- !, fail. 2028'$expansion_member'(List, ListLayout, Term, Layout) :- 2029 is_list(List), 2030 !, 2031 ( var(ListLayout) 2032 -> '$member'(Term, List) 2033 ; is_list(ListLayout) 2034 -> '$member_rep2'(Term, Layout, List, ListLayout) 2035 ; Layout = ListLayout, 2036 '$member'(Term, List) 2037 ). 2038'$expansion_member'(X, Layout, X, Layout). 2039 2040% pairwise member, repeating last element of the second 2041% list. 2042 2043'$member_rep2'(H1, H2, [H1|_], [H2|_]). 2044'$member_rep2'(H1, H2, [_|T1], [T2]) :- 2045 !, 2046 '$member_rep2'(H1, H2, T1, [T2]). 2047'$member_rep2'(H1, H2, [_|T1], [_|T2]) :- 2048 '$member_rep2'(H1, H2, T1, T2).
2052'$add_encoding'(Enc, Options0, Options) :- 2053 ( Options0 = [encoding(Enc)|_] 2054 -> Options = Options0 2055 ; Options = [encoding(Enc)|Options0] 2056 ). 2057 2058 2059:- multifile 2060 '$included'/4. % Into, Line, File, LastModified 2061:- dynamic 2062 '$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'.
2076'$record_included'([Parent|Parents], File, Path, Time, 2077 message(DoneMsgLevel, 2078 include_file(done(Level, file(File, Path))))) :- 2079 source_location(SrcFile, Line), 2080 !, 2081 '$compilation_level'(Level), 2082 '$load_msg_level'(include_file, Level, StartMsgLevel, DoneMsgLevel), 2083 '$print_message'(StartMsgLevel, 2084 include_file(start(Level, 2085 file(File, Path)))), 2086 '$last'([Parent|Parents], Owner), 2087 '$store_admin_clause'( 2088 system:'$included'(Parent, Line, Path, Time), 2089 _, Owner, SrcFile:Line, database), 2090 '$ifcompiling'('$qlf_include'(Owner, Parent, Line, Path, Time)). 2091'$record_included'(_, _, _, _, true).
2097'$master_file'(File, MasterFile) :- 2098 '$included'(MasterFile0, _Line, File, _Time), 2099 !, 2100 '$master_file'(MasterFile0, MasterFile). 2101'$master_file'(File, File). 2102 2103 2104'$skip_script_line'(_In, Options) :- 2105 '$option'(check_script(false), Options), 2106 !. 2107'$skip_script_line'(In, _Options) :- 2108 ( peek_char(In, #) 2109 -> skip(In, 10) 2110 ; true 2111 ). 2112 2113'$set_encoding'(Stream, Options) :- 2114 '$option'(encoding(Enc), Options), 2115 !, 2116 Enc \== default, 2117 set_stream(Stream, encoding(Enc)). 2118'$set_encoding'(_, _). 2119 2120 2121'$prepare_load_stream'(In, Id, state(HasName,HasPos)) :- 2122 ( stream_property(In, file_name(_)) 2123 -> HasName = true, 2124 ( stream_property(In, position(_)) 2125 -> HasPos = true 2126 ; HasPos = false, 2127 set_stream(In, record_position(true)) 2128 ) 2129 ; HasName = false, 2130 set_stream(In, file_name(Id)), 2131 ( stream_property(In, position(_)) 2132 -> HasPos = true 2133 ; HasPos = false, 2134 set_stream(In, record_position(true)) 2135 ) 2136 ). 2137 2138'$restore_load_stream'(In, _State, Options) :- 2139 '$option'(close(true), Options), 2140 !, 2141 close(In). 2142'$restore_load_stream'(In, state(HasName, HasPos), _Options) :- 2143 ( HasName == false 2144 -> set_stream(In, file_name('')) 2145 ; true 2146 ), 2147 ( HasPos == false 2148 -> set_stream(In, record_position(false)) 2149 ; true 2150 ). 2151 2152 2153 /******************************* 2154 * DERIVED FILES * 2155 *******************************/ 2156 2157:- dynamic 2158 '$derived_source_db'/3. % Loaded, DerivedFrom, Time 2159 2160'$register_derived_source'(_, '-') :- !. 2161'$register_derived_source'(Loaded, DerivedFrom) :- 2162 retractall('$derived_source_db'(Loaded, _, _)), 2163 time_file(DerivedFrom, Time), 2164 assert('$derived_source_db'(Loaded, DerivedFrom, Time)). 2165 2166% Auto-importing dynamic predicates is not very elegant and 2167% leads to problems with qsave_program/[1,2] 2168 2169'$derived_source'(Loaded, DerivedFrom, Time) :- 2170 '$derived_source_db'(Loaded, DerivedFrom, Time). 2171 2172 2173 /******************************** 2174 * LOAD PREDICATES * 2175 *********************************/ 2176 2177:- meta_predicate 2178 ensure_loaded(), 2179 [|], 2180 consult(), 2181 use_module(), 2182 use_module(, ), 2183 reexport(), 2184 reexport(, ), 2185 load_files(), 2186 load_files(, ).
2194ensure_loaded(Files) :-
2195 load_files(Files, [if(not_loaded)]).
2204use_module(Files) :-
2205 load_files(Files, [ if(not_loaded),
2206 must_be_module(true)
2207 ]).
2214use_module(File, Import) :-
2215 load_files(File, [ if(not_loaded),
2216 must_be_module(true),
2217 imports(Import)
2218 ]).
2224reexport(Files) :-
2225 load_files(Files, [ if(not_loaded),
2226 must_be_module(true),
2227 reexport(true)
2228 ]).2234reexport(File, Import) :- 2235 load_files(File, [ if(not_loaded), 2236 must_be_module(true), 2237 imports(Import), 2238 reexport(true) 2239 ]). 2240 2241 2242[X] :- 2243 !, 2244 consult(X). 2245[M:F|R] :- 2246 consult(M:[F|R]). 2247 2248consult(M:X) :- 2249 X == user, 2250 !, 2251 flag('$user_consult', N, N+1), 2252 NN is N + 1, 2253 atom_concat('user://', NN, Id), 2254 '$consult_user'(M:Id). 2255consult(List) :- 2256 load_files(List, [expand(true)]).
?- [user].. This is a separate predicate, such that we
can easily wrap this for the browser version.
2263'$consult_user'(Id) :-
2264 load_files(Id, [stream(user_input), check_script(false), silent(false)]).2271load_files(Files) :- 2272 load_files(Files, []). 2273load_files(Module:Files, Options) :- 2274 '$must_be'(list, Options), 2275 '$load_files'(Files, Module, Options). 2276 2277'$load_files'(X, _, _) :- 2278 var(X), 2279 !, 2280 '$instantiation_error'(X). 2281'$load_files'([], _, _) :- !. 2282'$load_files'(Id, Module, Options) :- % load_files(foo, [stream(In)]) 2283 '$option'(stream(_), Options), 2284 !, 2285 ( atom(Id) 2286 -> '$load_file'(Id, Module, Options) 2287 ; throw(error(type_error(atom, Id), _)) 2288 ). 2289'$load_files'(List, Module, Options) :- 2290 List = [_|_], 2291 !, 2292 '$must_be'(list, List), 2293 '$load_file_list'(List, Module, Options). 2294'$load_files'(File, Module, Options) :- 2295 '$load_one_file'(File, Module, Options). 2296 2297'$load_file_list'([], _, _). 2298'$load_file_list'([File|Rest], Module, Options) :- 2299 E = error(_,_), 2300 catch('$load_one_file'(File, Module, Options), E, 2301 '$print_message'(error, E)), 2302 '$load_file_list'(Rest, Module, Options). 2303 2304 2305'$load_one_file'(Spec, Module, Options) :- 2306 atomic(Spec), 2307 '$option'(expand(true), Options, false), 2308 !, 2309 expand_file_name(Spec, Expanded), 2310 ( Expanded = [Load] 2311 -> true 2312 ; Load = Expanded 2313 ), 2314 '$load_files'(Load, Module, [expand(false)|Options]). 2315'$load_one_file'(File, Module, Options) :- 2316 strip_module(Module:File, Into, PlainFile), 2317 '$load_file'(PlainFile, Into, Options).
2324'$noload'(true, _, _) :- 2325 !, 2326 fail. 2327'$noload'(_, FullFile, _Options) :- 2328 '$time_source_file'(FullFile, Time, system), 2329 float(Time), 2330 !. 2331'$noload'(not_loaded, FullFile, _) :- 2332 source_file(FullFile), 2333 !. 2334'$noload'(changed, Derived, _) :- 2335 '$derived_source'(_FullFile, Derived, LoadTime), 2336 time_file(Derived, Modified), 2337 Modified @=< LoadTime, 2338 !. 2339'$noload'(changed, FullFile, Options) :- 2340 '$time_source_file'(FullFile, LoadTime, user), 2341 '$modified_id'(FullFile, Modified, Options), 2342 Modified @=< LoadTime, 2343 !. 2344'$noload'(exists, File, Options) :- 2345 '$noload'(changed, File, Options).
2364'$qlf_file'(Spec, _, Spec, stream, Options) :- 2365 '$option'(stream(_), Options), % stream: no choice 2366 !. 2367'$qlf_file'(Spec, FullFile, LoadFile, compile, _) :- 2368 '$spec_extension'(Spec, Ext), % user explicitly specified 2369 ( user:prolog_file_type(Ext, qlf) 2370 -> absolute_file_name(Spec, LoadFile, 2371 [ file_type(qlf), 2372 access(read) 2373 ]) 2374 ; user:prolog_file_type(Ext, prolog) 2375 -> LoadFile = FullFile 2376 ), 2377 !. 2378'$qlf_file'(_, FullFile, FullFile, compile, _) :- 2379 current_prolog_flag(source, true), 2380 access_file(FullFile, read), 2381 !. 2382'$qlf_file'(Spec, FullFile, LoadFile, Mode, Options) :- 2383 '$compilation_mode'(database), 2384 file_name_extension(Base, PlExt, FullFile), 2385 user:prolog_file_type(PlExt, prolog), 2386 user:prolog_file_type(QlfExt, qlf), 2387 file_name_extension(Base, QlfExt, QlfFile), 2388 ( access_file(QlfFile, read), 2389 ( '$qlf_out_of_date'(FullFile, QlfFile, Why) 2390 -> ( access_file(QlfFile, write) 2391 -> print_message(informational, 2392 qlf(recompile(Spec, FullFile, QlfFile, Why))), 2393 Mode = qcompile, 2394 LoadFile = FullFile 2395 ; Why == old, 2396 ( current_prolog_flag(home, PlHome), 2397 sub_atom(FullFile, 0, _, _, PlHome) 2398 ; sub_atom(QlfFile, 0, _, _, 'res://') 2399 ) 2400 -> print_message(silent, 2401 qlf(system_lib_out_of_date(Spec, QlfFile))), 2402 Mode = qload, 2403 LoadFile = QlfFile 2404 ; print_message(warning, 2405 qlf(can_not_recompile(Spec, QlfFile, Why))), 2406 Mode = compile, 2407 LoadFile = FullFile 2408 ) 2409 ; Mode = qload, 2410 LoadFile = QlfFile 2411 ) 2412 -> ! 2413 ; '$qlf_auto'(FullFile, QlfFile, Options) 2414 -> !, Mode = qcompile, 2415 LoadFile = FullFile 2416 ). 2417'$qlf_file'(_, FullFile, FullFile, compile, _).
QlfFile is out of date if it is incompatible with this version or if one of the files it was compiled from changed. That is PlFile, but also the files PlFile consults or includes, which are compiled into QlfFile, and the files that qlf_dependency/2 declares. '$qlf_sources'/2 raises an exception if QlfFile is incompatible and otherwise lists these files, opening QlfFile only once. If QlfFile is incompatible, that is reported, also if a source changed, as it is the more serious problem.
2433'$qlf_out_of_date'(PlFile, QlfFile, Why) :-
2434 ( access_file(PlFile, read)
2435 -> Error = error(Formal,_),
2436 catch('$qlf_sources'(QlfFile, Sources), Error, true),
2437 ( nonvar(Formal) % QlfFile is incompatible
2438 -> Why = Error
2439 ; time_file(QlfFile, QlfTime),
2440 '$qlf_sources_changed'(PlFile, Sources, QlfTime)
2441 -> Why = old % a source changed
2442 ; fail % QlfFile is up-to-date and ok
2443 )
2444 ; fail % can not read .pl; try .qlf
2445 ).2454'$qlf_sources_changed'(PlFile, Sources, QlfTime) :- 2455 '$qlf_source_changed'(PlFile, Sources, QlfTime), 2456 !. 2457'$qlf_sources_changed'(PlFile, Sources, QlfTime) :- 2458 '$member'(Source, Sources), 2459 arg(1, Source, File), 2460 File \== PlFile, 2461 '$qlf_source_changed'(File, Sources, QlfTime), 2462 !.
If Sources records no hash for File -- the .qlf file was written by an older version, or File could not be read when it was compiled -- the times have the last word, as they had before.
Note that a file edited in the second its .qlf file was written has the time of that file, so the times do not say "may be newer" and the content is never asked. Loading every .pl file to find out would cost more than it is worth here; qlf_needs_rebuild/1 of library(prolog_qlfmake), which is what a build asks, does compare the content of every source.
2485'$qlf_source_changed'(File, Sources, QlfTime) :-
2486 catch(time_file(File, Time), error(_,_), fail),
2487 Time > QlfTime,
2488 ( '$member'(Source, Sources),
2489 arg(1, Source, File),
2490 arg(2, Source, Hash),
2491 Hash =\= 0
2492 -> \+ '$file_hash'(File, Hash)
2493 ; true
2494 ).qcompile(QlfMode) or, if this is not present, by
the prolog_flag qcompile.2502:- create_prolog_flag(qcompile, false, [type(atom)]). 2503 2504'$qlf_auto'(PlFile, QlfFile, Options) :- 2505 ( '$option'(qcompile(QlfMode), Options) 2506 -> true 2507 ; current_prolog_flag(qcompile, QlfMode), 2508 \+ '$in_system_dir'(PlFile) 2509 ), 2510 ( QlfMode == auto 2511 -> true 2512 ; QlfMode == large, 2513 size_file(PlFile, Size), 2514 Size > 100000 2515 ), 2516 access_file(QlfFile, write). 2517 2518'$in_system_dir'(PlFile) :- 2519 current_prolog_flag(home, Home), 2520 sub_atom(PlFile, 0, _, _, Home). 2521 2522'$spec_extension'(File, Ext) :- 2523 atom(File), 2524 !, 2525 file_name_extension(_, Ext, File). 2526'$spec_extension'(Spec, Ext) :- 2527 compound(Spec), 2528 arg(1, Spec, Arg), 2529 '$segments_to_atom'(Arg, File), 2530 file_name_extension(_, Ext, File).
2542:- dynamic 2543 '$resolved_source_path_db'/3. % ?Spec, ?Dialect, ?Path 2544:- '$notransact'('$resolved_source_path_db'/3). 2545 2546'$load_file'(File, Module, Options) :- 2547 '$error_count'(E0, W0), 2548 '$load_file_e'(File, Module, Options), 2549 '$error_count'(E1, W1), 2550 Errors is E1-E0, 2551 Warnings is W1-W0, 2552 ( Errors+Warnings =:= 0 2553 -> true 2554 ; '$print_message'(silent, load_file_errors(File, Errors, Warnings)) 2555 ). 2556 2557:- if(current_prolog_flag(threads, true)). 2558'$error_count'(Errors, Warnings) :- 2559 current_prolog_flag(threads, true), 2560 !, 2561 thread_self(Me), 2562 thread_statistics(Me, errors, Errors), 2563 thread_statistics(Me, warnings, Warnings). 2564:- endif. 2565'$error_count'(Errors, Warnings) :- 2566 statistics(errors, Errors), 2567 statistics(warnings, Warnings). 2568 2569'$load_file_e'(File, Module, Options) :- 2570 \+ '$option'(stream(_), Options), 2571 user:prolog_load_file(Module:File, Options), 2572 !. 2573'$load_file_e'(File, Module, Options) :- 2574 '$option'(stream(_), Options), 2575 !, 2576 '$assert_load_context_module'(File, Module, Options), 2577 '$qdo_load_file'(File, File, Module, Options). 2578'$load_file_e'(File, Module, Options) :- 2579 ( '$resolved_source_path'(File, FullFile, Options) 2580 -> true 2581 ; '$resolve_source_path'(File, FullFile, Options) 2582 ), 2583 !, 2584 '$mt_load_file'(File, FullFile, Module, Options). 2585'$load_file_e'(_, _, _).
2591'$resolved_source_path'(File, FullFile, Options) :-
2592 current_prolog_flag(emulated_dialect, Dialect),
2593 '$resolved_source_path_db'(File, Dialect, FullFile),
2594 ( '$source_file_property'(FullFile, from_state, true)
2595 ; '$source_file_property'(FullFile, resource, true)
2596 ; '$option'(if(If), Options, true),
2597 '$noload'(If, FullFile, Options)
2598 ),
2599 !.if(exists) is in Optionsexistence_error(source_sink, File)2612'$resolve_source_path'(File, FullFile, _Options) :- 2613 absolute_file_name(File, AbsFile, 2614 [ file_type(prolog), 2615 access(read), 2616 file_errors(fail) 2617 ]), 2618 !, 2619 '$admin_file'(AbsFile, FullFile), 2620 '$register_resolved_source_path'(File, FullFile). 2621'$resolve_source_path'(File, FullFile, _Options) :- 2622 absolute_file_name(File, FullFile, 2623 [ file_type(prolog), 2624 solutions(all), 2625 file_errors(fail) 2626 ]), 2627 source_file(FullFile), 2628 !. 2629'$resolve_source_path'(_File, _FullFile, Options) :- 2630 '$option'(if(exists), Options), 2631 !, 2632 fail. 2633'$resolve_source_path'(File, _FullFile, _Options) :- 2634 '$existence_error'(source_sink, File).
2642'$register_resolved_source_path'(File, FullFile) :-
2643 ( compound(File)
2644 -> current_prolog_flag(emulated_dialect, Dialect),
2645 ( '$resolved_source_path_db'(File, Dialect, FullFile)
2646 -> true
2647 ; asserta('$resolved_source_path_db'(File, Dialect, FullFile))
2648 )
2649 ; true
2650 ).2656:- public '$translated_source'/2. 2657'$translated_source'(Old, New) :- 2658 forall(retract('$resolved_source_path_db'(File, Dialect, Old)), 2659 assertz('$resolved_source_path_db'(File, Dialect, New))).
2666'$register_resource_file'(FullFile) :-
2667 ( sub_atom(FullFile, 0, _, _, 'res://'),
2668 \+ file_name_extension(_, qlf, FullFile)
2669 -> '$set_source_file'(FullFile, resource, true)
2670 ; true
2671 ).2684'$already_loaded'(_File, FullFile, Module, Options) :- 2685 '$assert_load_context_module'(FullFile, Module, Options), 2686 '$current_module'(LoadModules, FullFile), 2687 !, 2688 ( atom(LoadModules) 2689 -> LoadModule = LoadModules 2690 ; LoadModules = [LoadModule|_] 2691 ), 2692 '$import_from_loaded_module'(LoadModule, Module, Options). 2693'$already_loaded'(_, _, user, _) :- !. 2694'$already_loaded'(File, FullFile, Module, Options) :- 2695 ( '$load_context_module'(FullFile, Module, CtxOptions), 2696 '$load_ctx_options'(Options, CtxOptions) 2697 -> true 2698 ; '$load_file'(File, Module, [if(true)|Options]) 2699 ).
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.
2714:- dynamic 2715 '$loading_file'/3. % File, Queue, Thread 2716:- volatile 2717 '$loading_file'/3. 2718:- '$notransact'('$loading_file'/3). 2719 2720:- if(current_prolog_flag(threads, true)). 2721'$mt_load_file'(File, FullFile, Module, Options) :- 2722 current_prolog_flag(threads, true), 2723 !, 2724 sig_atomic(setup_call_cleanup( 2725 with_mutex('$load_file', 2726 '$mt_start_load'(FullFile, Loading, Options)), 2727 '$mt_do_load'(Loading, File, FullFile, Module, Options), 2728 '$mt_end_load'(Loading))). 2729:- endif. 2730'$mt_load_file'(File, FullFile, Module, Options) :- 2731 '$option'(if(If), Options, true), 2732 '$noload'(If, FullFile, Options), 2733 !, 2734 '$already_loaded'(File, FullFile, Module, Options). 2735:- if(current_prolog_flag(threads, true)). 2736'$mt_load_file'(File, FullFile, Module, Options) :- 2737 sig_atomic('$ctx_load_file'(File, FullFile, Module, Options)). 2738:- else. 2739'$mt_load_file'(File, FullFile, Module, Options) :- 2740 '$ctx_load_file'(File, FullFile, Module, Options). 2741:- endif.
source_file_property(FullFile, load_context(Module, ...))
reports, which make/0 and the .qlf dependencies of
qlf_dependency/2 rely on.2750'$ctx_load_file'(File, FullFile, Module, Options) :- 2751 '$assert_load_context_module'(FullFile, Module, Options), 2752 '$qdo_load_file'(File, FullFile, Module, Options). 2753 2754:- if(current_prolog_flag(threads, true)). 2755'$mt_start_load'(FullFile, queue(Queue), _) :- 2756 '$loading_file'(FullFile, Queue, LoadThread), 2757 \+ thread_self(LoadThread), 2758 !. 2759'$mt_start_load'(FullFile, already_loaded, Options) :- 2760 '$option'(if(If), Options, true), 2761 '$noload'(If, FullFile, Options), 2762 !. 2763'$mt_start_load'(FullFile, Ref, _) :- 2764 thread_self(Me), 2765 message_queue_create(Queue), 2766 assertz('$loading_file'(FullFile, Queue, Me), Ref). 2767 2768'$mt_do_load'(queue(Queue), File, FullFile, Module, Options) :- 2769 !, 2770 catch(thread_get_message(Queue, _), error(_,_), true), 2771 '$already_loaded'(File, FullFile, Module, Options). 2772'$mt_do_load'(already_loaded, File, FullFile, Module, Options) :- 2773 !, 2774 '$already_loaded'(File, FullFile, Module, Options). 2775'$mt_do_load'(_Ref, File, FullFile, Module, Options) :- 2776 '$ctx_load_file'(File, FullFile, Module, Options). 2777 2778'$mt_end_load'(queue(_)) :- !. 2779'$mt_end_load'(already_loaded) :- !. 2780'$mt_end_load'(Ref) :- 2781 clause('$loading_file'(_, Queue, _), _, Ref), 2782 erase(Ref), 2783 thread_send_message(Queue, done), 2784 message_queue_destroy(Queue). 2785:- endif.
2791'$qdo_load_file'(File, FullFile, Module, Options) :- 2792 '$qdo_load_file2'(File, FullFile, Module, Action, Options), 2793 '$register_resource_file'(FullFile), 2794 '$run_initialization'(FullFile, Action, Options). 2795 2796'$qdo_load_file2'(File, FullFile, Module, Action, Options) :- 2797 '$option'('$qlf'(QlfOut), Options), 2798 '$stage_file'(QlfOut, StageQlf), 2799 !, 2800 setup_call_catcher_cleanup( 2801 '$qstart'(StageQlf, Module, State), 2802 ( '$do_load_file'(File, FullFile, Module, Action, Options), 2803 '$qlf_add_dependencies'(FullFile) 2804 ), 2805 Catcher, 2806 '$qend'(State, Catcher, StageQlf, QlfOut)). 2807'$qdo_load_file2'(File, FullFile, Module, Action, Options) :- 2808 '$do_load_file'(File, FullFile, Module, Action, Options). 2809 2810'$qstart'(Qlf, Module, state(OldMode, OldModule)) :- 2811 '$qlf_open'(Qlf), 2812 '$compilation_mode'(OldMode, qlf), 2813 '$set_source_module'(OldModule, Module). 2814 2815'$qend'(state(OldMode, OldModule), Catcher, StageQlf, QlfOut) :- 2816 '$set_source_module'(_, OldModule), 2817 '$set_compilation_mode'(OldMode), 2818 '$qlf_close', 2819 '$install_staged_file'(Catcher, StageQlf, QlfOut, warn). 2820 2821'$set_source_module'(OldModule, Module) :- 2822 '$current_source_module'(OldModule), 2823 '$set_source_module'(Module).
This must be called with the .qlf file open and the part written, as it is here: '$qlf_dependency'/1 writes into the stream and the record belongs after the part, in the trailer.
2834'$qlf_add_dependencies'(File) :-
2835 findall(DepFile, '$dependency'(File, DepFile), DepFiles0),
2836 sort(DepFiles0, DepFiles), % a file need only be named once
2837 forall('$member'(DepFile, DepFiles),
2838 '$qlf_dependency'(DepFile)).2849:- multifile 2850 prolog:qlf_dependency/2. % +File, -DependsOn 2851 2852'$dependency'(File, DepFile) :- 2853 '$current_module'(Module, File), 2854 '$load_context_module'(DepFile, Module, _Options), 2855 '$source_defines_expansion'(DepFile). 2856'$dependency'(File, DepFile) :- 2857 prolog:qlf_dependency(File, DepFile). 2858 2859% Also used by autoload.pl 2860'$source_defines_expansion'(File) :- 2861 '$expansion_hook'(P), 2862 source_file(P, File), 2863 !. 2864 2865'$expansion_hook'(user:goal_expansion(_,_)). 2866'$expansion_hook'(user:goal_expansion(_,_,_,_)). 2867'$expansion_hook'(system:goal_expansion(_,_)). 2868'$expansion_hook'(system:goal_expansion(_,_,_,_)). 2869'$expansion_hook'(user:term_expansion(_,_)). 2870'$expansion_hook'(user:term_expansion(_,_,_,_)). 2871'$expansion_hook'(system:term_expansion(_,_)). 2872'$expansion_hook'(system:term_expansion(_,_,_,_)).
2879'$do_load_file'(File, FullFile, Module, Action, Options) :- 2880 '$option'(derived_from(DerivedFrom), Options, -), 2881 '$register_derived_source'(FullFile, DerivedFrom), 2882 '$qlf_file'(File, FullFile, Absolute, Mode, Options), 2883 ( Mode == qcompile 2884 -> qcompile(Module:File, Options) 2885 ; '$do_load_file_2'(File, FullFile, Absolute, Module, Action, Options) 2886 ). 2887 2888'$do_load_file_2'(File, FullFile, Absolute, Module, Action, Options) :- 2889 '$source_file_property'(FullFile, number_of_clauses, OldClauses), 2890 statistics(cputime, OldTime), 2891 2892 '$setup_load'(ScopedFlags, OldSandBoxed, OldVerbose, OldAutoLevel, OldXRef, 2893 Options), 2894 2895 '$compilation_level'(Level), 2896 '$load_msg_level'(load_file, Level, StartMsgLevel, DoneMsgLevel), 2897 '$print_message'(StartMsgLevel, 2898 load_file(start(Level, 2899 file(File, Absolute)))), 2900 2901 ( '$option'(stream(FromStream), Options) 2902 -> Input = stream 2903 ; Input = source 2904 ), 2905 2906 ( Input == stream, 2907 ( '$option'(format(qlf), Options, source) 2908 -> set_stream(FromStream, file_name(Absolute)), 2909 '$qload_stream'(FromStream, Module, Action, LM, Options) 2910 ; '$consult_file'(stream(Absolute, FromStream, []), 2911 Module, Action, LM, Options) 2912 ) 2913 -> true 2914 ; Input == source, 2915 file_name_extension(_, Ext, Absolute), 2916 ( user:prolog_file_type(Ext, qlf), 2917 E = error(_,_), 2918 catch('$qload_file'(Absolute, Module, Action, LM, Options), 2919 E, 2920 print_message(warning, E)) 2921 -> true 2922 ; '$consult_file'(Absolute, Module, Action, LM, Options) 2923 ) 2924 -> true 2925 ; '$print_message'(error, load_file(failed(File))), 2926 fail 2927 ), 2928 2929 '$import_from_loaded_module'(LM, Module, Options), 2930 2931 '$source_file_property'(FullFile, number_of_clauses, NewClauses), 2932 statistics(cputime, Time), 2933 ClausesCreated is NewClauses - OldClauses, 2934 TimeUsed is Time - OldTime, 2935 2936 '$print_message'(DoneMsgLevel, 2937 load_file(done(Level, 2938 file(File, Absolute), 2939 Action, 2940 LM, 2941 TimeUsed, 2942 ClausesCreated))), 2943 2944 '$restore_load'(ScopedFlags, OldSandBoxed, OldVerbose, OldAutoLevel, OldXRef). 2945 2946'$setup_load'(ScopedFlags, OldSandBoxed, OldVerbose, OldAutoLevel, OldXRef, 2947 Options) :- 2948 '$save_file_scoped_flags'(ScopedFlags), 2949 '$set_sandboxed_load'(Options, OldSandBoxed), 2950 '$set_verbose_load'(Options, OldVerbose), 2951 '$set_optimise_load'(Options), 2952 '$update_autoload_level'(Options, OldAutoLevel), 2953 '$set_no_xref'(OldXRef). 2954 2955'$restore_load'(ScopedFlags, OldSandBoxed, OldVerbose, OldAutoLevel, OldXRef) :- 2956 '$set_autoload_level'(OldAutoLevel), 2957 set_prolog_flag(xref, OldXRef), 2958 set_prolog_flag(verbose_load, OldVerbose), 2959 set_prolog_flag(sandboxed_load, OldSandBoxed), 2960 '$restore_file_scoped_flags'(ScopedFlags).
2968'$save_file_scoped_flags'(State) :- 2969 current_predicate(findall/3), % Not when doing boot compile 2970 !, 2971 findall(SavedFlag, '$save_file_scoped_flag'(SavedFlag), State). 2972'$save_file_scoped_flags'([]). 2973 2974'$save_file_scoped_flag'(Flag-Value) :- 2975 '$file_scoped_flag'(Flag, Default), 2976 ( current_prolog_flag(Flag, Value) 2977 -> true 2978 ; Value = Default 2979 ). 2980 2981'$file_scoped_flag'(generate_debug_info, true). 2982'$file_scoped_flag'(optimise, false). 2983'$file_scoped_flag'(xref, false). 2984 2985'$restore_file_scoped_flags'([]). 2986'$restore_file_scoped_flags'([Flag-Value|T]) :- 2987 set_prolog_flag(Flag, Value), 2988 '$restore_file_scoped_flags'(T).
2995'$import_from_loaded_module'(LoadedModule, Module, Options) :- 2996 LoadedModule \== Module, 2997 atom(LoadedModule), 2998 !, 2999 '$option'(imports(Import), Options, all), 3000 '$option'(reexport(Reexport), Options, false), 3001 '$import_list'(Module, LoadedModule, Import, Reexport). 3002'$import_from_loaded_module'(_, _, _).
verbose_load flag according to Options and unify Old
with the old value.3010'$set_verbose_load'(Options, Old) :- 3011 current_prolog_flag(verbose_load, Old), 3012 ( '$option'(silent(Silent), Options) 3013 -> ( '$negate'(Silent, Level0) 3014 -> '$load_msg_compat'(Level0, Level) 3015 ; Level = Silent 3016 ), 3017 set_prolog_flag(verbose_load, Level) 3018 ; true 3019 ). 3020 3021'$negate'(true, false). 3022'$negate'(false, true).
sandboxed_load from Options. Old is
unified with the old flag.
3031'$set_sandboxed_load'(Options, Old) :- 3032 current_prolog_flag(sandboxed_load, Old), 3033 ( '$option'(sandboxed(SandBoxed), Options), 3034 '$enter_sandboxed'(Old, SandBoxed, New), 3035 New \== Old 3036 -> set_prolog_flag(sandboxed_load, New) 3037 ; true 3038 ). 3039 3040'$enter_sandboxed'(Old, New, SandBoxed) :- 3041 ( Old == false, New == true 3042 -> SandBoxed = true, 3043 '$ensure_loaded_library_sandbox' 3044 ; Old == true, New == false 3045 -> throw(error(permission_error(leave, sandbox, -), _)) 3046 ; SandBoxed = Old 3047 ). 3048'$enter_sandboxed'(false, true, true). 3049 3050'$ensure_loaded_library_sandbox' :- 3051 source_file_property(library(sandbox), module(sandbox)), 3052 !. 3053'$ensure_loaded_library_sandbox' :- 3054 load_files(library(sandbox), [if(not_loaded), silent(true)]). 3055 3056'$set_optimise_load'(Options) :- 3057 ( '$option'(optimise(Optimise), Options) 3058 -> set_prolog_flag(optimise, Optimise) 3059 ; true 3060 ). 3061 3062'$set_no_xref'(OldXRef) :- 3063 ( current_prolog_flag(xref, OldXRef) 3064 -> true 3065 ; OldXRef = false 3066 ), 3067 set_prolog_flag(xref, false).
3074:- thread_local 3075 '$autoload_nesting'/1. 3076:- '$notransact'('$autoload_nesting'/1). 3077 3078'$update_autoload_level'(Options, AutoLevel) :- 3079 '$option'(autoload(Autoload), Options, false), 3080 ( '$autoload_nesting'(CurrentLevel) 3081 -> AutoLevel = CurrentLevel 3082 ; AutoLevel = 0 3083 ), 3084 ( Autoload == false 3085 -> true 3086 ; NewLevel is AutoLevel + 1, 3087 '$set_autoload_level'(NewLevel) 3088 ). 3089 3090'$set_autoload_level'(New) :- 3091 retractall('$autoload_nesting'(_)), 3092 asserta('$autoload_nesting'(New)).
3100'$print_message'(Level, Term) :- 3101 current_predicate(system:print_message/2), 3102 !, 3103 print_message(Level, Term). 3104'$print_message'(warning, Term) :- 3105 source_location(File, Line), 3106 !, 3107 format(user_error, 'WARNING: ~w:~w: ~p~n', [File, Line, Term]). 3108'$print_message'(error, Term) :- 3109 !, 3110 source_location(File, Line), 3111 !, 3112 format(user_error, 'ERROR: ~w:~w: ~p~n', [File, Line, Term]). 3113'$print_message'(_Level, _Term). 3114 3115'$print_message_fail'(E) :- 3116 '$print_message'(error, E), 3117 fail.
3125'$consult_file'(Absolute, Module, What, LM, Options) :- 3126 '$current_source_module'(Module), % same module 3127 !, 3128 '$consult_file_2'(Absolute, Module, What, LM, Options). 3129'$consult_file'(Absolute, Module, What, LM, Options) :- 3130 '$set_source_module'(OldModule, Module), 3131 '$ifcompiling'('$qlf_start_sub_module'(Module)), 3132 '$consult_file_2'(Absolute, Module, What, LM, Options), 3133 '$ifcompiling'('$qlf_end_part'), 3134 '$set_source_module'(OldModule). 3135 3136'$consult_file_2'(Absolute, Module, What, LM, Options) :- 3137 '$set_source_module'(OldModule, Module), 3138 '$load_id'(Absolute, Id, Modified, Options), 3139 '$compile_type'(What), 3140 '$save_lex_state'(LexState, Options), 3141 '$set_dialect'(Options), 3142 setup_call_cleanup( 3143 '$start_consult'(Id, Modified), 3144 '$load_file'(Absolute, Id, LM, Options), 3145 '$end_consult'(Id, LexState, OldModule)). 3146 3147'$end_consult'(Id, LexState, OldModule) :- 3148 '$end_consult'(Id), 3149 '$restore_lex_state'(LexState), 3150 '$set_source_module'(OldModule). 3151 3152 3153:- create_prolog_flag(emulated_dialect, swi, [type(atom)]).
3157'$save_lex_state'(State, Options) :- 3158 '$option'(scope_settings(false), Options), 3159 !, 3160 State = (-). 3161'$save_lex_state'(lexstate(Style, Dialect), _) :- 3162 '$style_check'(Style, Style), 3163 current_prolog_flag(emulated_dialect, Dialect). 3164 3165'$restore_lex_state'(-) :- !. 3166'$restore_lex_state'(lexstate(Style, Dialect)) :- 3167 '$style_check'(_, Style), 3168 set_prolog_flag(emulated_dialect, Dialect). 3169 3170'$set_dialect'(Options) :- 3171 '$option'(dialect(Dialect), Options), 3172 !, 3173 '$expects_dialect'(Dialect). 3174'$set_dialect'(_). 3175 3176'$load_id'(stream(Id, _, _), Id, Modified, Options) :- 3177 !, 3178 '$modified_id'(Id, Modified, Options). 3179'$load_id'(Id, Id, Modified, Options) :- 3180 '$modified_id'(Id, Modified, Options). 3181 3182'$modified_id'(_, Modified, Options) :- 3183 '$option'(modified(Stamp), Options, Def), 3184 Stamp \== Def, 3185 !, 3186 Modified = Stamp. 3187'$modified_id'(Id, Modified, _) :- 3188 catch(time_file(Id, Modified), 3189 error(_, _), 3190 fail), 3191 !. 3192'$modified_id'(_, 0, _). 3193 3194 3195'$compile_type'(What) :- 3196 '$compilation_mode'(How), 3197 ( How == database 3198 -> What = compiled 3199 ; How == qlf 3200 -> What = '*qcompiled*' 3201 ; What = 'boot compiled' 3202 ).
3212:- dynamic 3213 '$load_context_module'/3. 3214:- multifile 3215 '$load_context_module'/3. 3216:- '$notransact'('$load_context_module'/3). 3217 3218'$assert_load_context_module'(_, _, Options) :- 3219 '$option'(register(false), Options), 3220 !. 3221'$assert_load_context_module'(File, Module, Options) :- 3222 source_location(FromFile, Line), 3223 !, 3224 '$master_file'(FromFile, MasterFile), 3225 '$admin_file'(File, PlFile), 3226 '$check_load_non_module'(PlFile, Module), 3227 '$add_dialect'(Options, Options1), 3228 '$load_ctx_options'(Options1, Options2), 3229 '$store_admin_clause'( 3230 system:'$load_context_module'(PlFile, Module, Options2), 3231 _Layout, MasterFile, FromFile:Line). 3232'$assert_load_context_module'(File, Module, Options) :- 3233 '$admin_file'(File, PlFile), 3234 '$check_load_non_module'(PlFile, Module), 3235 '$add_dialect'(Options, Options1), 3236 '$load_ctx_options'(Options1, Options2), 3237 ( clause('$load_context_module'(PlFile, Module, _), true, Ref), 3238 \+ clause_property(Ref, file(_)), 3239 erase(Ref) 3240 -> true 3241 ; true 3242 ), 3243 assertz('$load_context_module'(PlFile, Module, Options2)).
3251'$admin_file'(QlfFile, PlFile) :- 3252 file_name_extension(_, qlf, QlfFile), 3253 '$qlf_module'(QlfFile, Info), 3254 get_dict(file, Info, PlFile), 3255 !. 3256'$admin_file'(File, File).
3264'$add_dialect'(Options0, Options) :- 3265 current_prolog_flag(emulated_dialect, Dialect), Dialect \== swi, 3266 !, 3267 Options = [dialect(Dialect)|Options0]. 3268'$add_dialect'(Options, Options).
3275'$load_ctx_options'(Options, CtxOptions) :- 3276 '$load_ctx_options2'(Options, CtxOptions0), 3277 sort(CtxOptions0, CtxOptions). 3278 3279'$load_ctx_options2'([], []). 3280'$load_ctx_options2'([H|T0], [H|T]) :- 3281 '$load_ctx_option'(H), 3282 !, 3283 '$load_ctx_options2'(T0, T). 3284'$load_ctx_options2'([_|T0], T) :- 3285 '$load_ctx_options2'(T0, T). 3286 3287'$load_ctx_option'(derived_from(_)). 3288'$load_ctx_option'(dialect(_)). 3289'$load_ctx_option'(encoding(_)). 3290'$load_ctx_option'(imports(_)). 3291'$load_ctx_option'(reexport(_)).
3299'$check_load_non_module'(File, _) :- 3300 '$current_module'(_, File), 3301 !. % File is a module file 3302'$check_load_non_module'(File, Module) :- 3303 '$load_context_module'(File, OldModule, _), 3304 Module \== OldModule, 3305 !, 3306 format(atom(Msg), 3307 'Non-module file already loaded into module ~w; \c 3308 trying to load into ~w', 3309 [OldModule, Module]), 3310 throw(error(permission_error(load, source, File), 3311 context(load_files/2, Msg))). 3312'$check_load_non_module'(_, _).
state(FirstTerm:boolean,
Module:atom,
AtEnd:atom,
Stop:boolean,
Id:atom,
Dialect:atom)
3325'$load_file'(Path, Id, Module, Options) :- 3326 State = state(true, _, true, false, Id, -), 3327 ( '$source_term'(Path, _Read, _Layout, Term, Layout, 3328 _Stream, Options), 3329 '$valid_term'(Term), 3330 ( arg(1, State, true) 3331 -> '$first_term'(Term, Layout, Id, State, Options), 3332 nb_setarg(1, State, false) 3333 ; '$compile_term'(Term, Layout, Id, Options) 3334 ), 3335 arg(4, State, true) 3336 ; '$fixup_reconsult'(Id), 3337 '$end_load_file'(State) 3338 ), 3339 !, 3340 arg(2, State, Module). 3341 3342'$valid_term'(Var) :- 3343 var(Var), 3344 !, 3345 print_message(error, error(instantiation_error, _)). 3346'$valid_term'(Term) :- 3347 Term \== []. 3348 3349'$end_load_file'(State) :- 3350 arg(1, State, true), % empty file 3351 !, 3352 nb_setarg(2, State, Module), 3353 arg(5, State, Id), 3354 '$current_source_module'(Module), 3355 '$ifcompiling'('$qlf_start_file'(Id)), 3356 '$ifcompiling'('$qlf_end_part'). 3357'$end_load_file'(State) :- 3358 arg(3, State, End), 3359 '$end_load_file'(End, State). 3360 3361'$end_load_file'(true, _). 3362'$end_load_file'(end_module, State) :- 3363 arg(2, State, Module), 3364 '$check_export'(Module), 3365 '$ifcompiling'('$qlf_end_part'). 3366'$end_load_file'(end_non_module, _State) :- 3367 '$ifcompiling'('$qlf_end_part'). 3368 3369 3370'$first_term'(?-(Directive), Layout, Id, State, Options) :- 3371 !, 3372 '$first_term'(:-(Directive), Layout, Id, State, Options). 3373'$first_term'(:-(Directive), _Layout, Id, State, Options) :- 3374 nonvar(Directive), 3375 ( ( Directive = module(Name, Public) 3376 -> Imports = [] 3377 ; Directive = module(Name, Public, Imports) 3378 ) 3379 -> !, 3380 '$module_name'(Name, Id, Module, Options), 3381 '$start_module'(Module, Public, State, Options), 3382 '$module3'(Imports) 3383 ; Directive = expects_dialect(Dialect) 3384 -> !, 3385 '$set_dialect'(Dialect, State), 3386 fail % Still consider next term as first 3387 ). 3388'$first_term'(Term, Layout, Id, State, Options) :- 3389 '$start_non_module'(Id, Term, State, Options), 3390 '$compile_term'(Term, Layout, Id, Options).
3397'$compile_term'(Term, Layout, SrcId, Options) :- 3398 '$compile_term'(Term, Layout, SrcId, -, Options). 3399 3400'$compile_term'(Var, _Layout, _Id, _SrcLoc, _Options) :- 3401 var(Var), 3402 !, 3403 '$instantiation_error'(Var). 3404'$compile_term'((?-Directive), _Layout, Id, _SrcLoc, Options) :- 3405 !, 3406 '$execute_directive'(Directive, Id, Options). 3407'$compile_term'((:-Directive), _Layout, Id, _SrcLoc, Options) :- 3408 !, 3409 '$execute_directive'(Directive, Id, Options). 3410'$compile_term'('$source_location'(File, Line):Term, 3411 Layout, Id, _SrcLoc, Options) :- 3412 !, 3413 '$compile_term'(Term, Layout, Id, File:Line, Options). 3414'$compile_term'(Clause, Layout, Id, SrcLoc, _Options) :- 3415 E = error(_,_), 3416 catch('$store_clause'(Clause, Layout, Id, SrcLoc), E, 3417 '$print_message'(error, E)). 3418 3419'$start_non_module'(_Id, Term, _State, Options) :- 3420 '$option'(must_be_module(true), Options, false), 3421 !, 3422 '$domain_error'(module_header, Term). 3423'$start_non_module'(Id, _Term, State, _Options) :- 3424 '$current_source_module'(Module), 3425 '$ifcompiling'('$qlf_start_file'(Id)), 3426 '$qset_dialect'(State), 3427 nb_setarg(2, State, Module), 3428 nb_setarg(3, State, end_non_module).
Note that expects_dialect/1 itself may be autoloaded from the library.
3441'$set_dialect'(Dialect, State) :- 3442 '$compilation_mode'(qlf, database), 3443 !, 3444 '$expects_dialect'(Dialect), 3445 '$compilation_mode'(_, qlf), 3446 nb_setarg(6, State, Dialect). 3447'$set_dialect'(Dialect, _) :- 3448 '$expects_dialect'(Dialect). 3449 3450'$qset_dialect'(State) :- 3451 '$compilation_mode'(qlf), 3452 arg(6, State, Dialect), Dialect \== (-), 3453 !, 3454 '$add_directive_wic'('$expects_dialect'(Dialect)). 3455'$qset_dialect'(_). 3456 3457'$expects_dialect'(Dialect) :- 3458 Dialect == swi, 3459 !, 3460 set_prolog_flag(emulated_dialect, Dialect). 3461'$expects_dialect'(Dialect) :- 3462 current_predicate(expects_dialect/1), 3463 !, 3464 expects_dialect(Dialect). 3465'$expects_dialect'(Dialect) :- 3466 use_module(library(dialect), [expects_dialect/1]), 3467 expects_dialect(Dialect). 3468 3469 3470 /******************************* 3471 * MODULES * 3472 *******************************/ 3473 3474'$start_module'(Module, _Public, State, _Options) :- 3475 '$current_module'(Module, OldFile), 3476 source_location(File, _Line), 3477 OldFile \== File, OldFile \== [], 3478 same_file(OldFile, File), 3479 !, 3480 nb_setarg(2, State, Module), 3481 nb_setarg(4, State, true). % Stop processing 3482'$start_module'(Module, Public, State, Options) :- 3483 arg(5, State, File), 3484 nb_setarg(2, State, Module), 3485 source_location(_File, Line), 3486 '$option'(redefine_module(Action), Options, false), 3487 '$module_class'(File, Class, Super), 3488 '$reset_dialect'(File, Class), 3489 '$redefine_module'(Module, File, Action), 3490 '$declare_module'(Module, Class, Super, File, Line, false), 3491 '$export_list'(Public, Module, Ops), 3492 '$ifcompiling'('$qlf_start_module'(Module)), 3493 '$export_ops'(Ops, Module, File), 3494 '$qset_dialect'(State), 3495 nb_setarg(3, State, end_module).
swi dialect.3502'$reset_dialect'(File, library) :- 3503 file_name_extension(_, pl, File), 3504 !, 3505 set_prolog_flag(emulated_dialect, swi). 3506'$reset_dialect'(_, _).
3513'$module3'(Var) :- 3514 var(Var), 3515 !, 3516 '$instantiation_error'(Var). 3517'$module3'([]) :- !. 3518'$module3'([H|T]) :- 3519 !, 3520 '$module3'(H), 3521 '$module3'(T). 3522'$module3'(Id) :- 3523 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.3537'$module_name'(_, _, Module, Options) :- 3538 '$option'(module(Module), Options), 3539 !, 3540 '$current_source_module'(Context), 3541 Context \== Module. % cause '$first_term'/5 to fail. 3542'$module_name'(Var, Id, Module, Options) :- 3543 var(Var), 3544 !, 3545 file_base_name(Id, File), 3546 file_name_extension(Var, _, File), 3547 '$module_name'(Var, Id, Module, Options). 3548'$module_name'(Reserved, _, _, _) :- 3549 '$reserved_module'(Reserved), 3550 !, 3551 throw(error(permission_error(load, module, Reserved), _)). 3552'$module_name'(Module, _Id, Module, _). 3553 3554 3555'$reserved_module'(system). 3556'$reserved_module'(user).
3561'$redefine_module'(_Module, _, false) :- !. 3562'$redefine_module'(Module, File, true) :- 3563 !, 3564 ( module_property(Module, file(OldFile)), 3565 File \== OldFile 3566 -> unload_file(OldFile) 3567 ; true 3568 ). 3569'$redefine_module'(Module, File, ask) :- 3570 ( stream_property(user_input, tty(true)), 3571 module_property(Module, file(OldFile)), 3572 File \== OldFile, 3573 '$rdef_response'(Module, OldFile, File, true) 3574 -> '$redefine_module'(Module, File, true) 3575 ; true 3576 ). 3577 3578'$rdef_response'(Module, OldFile, File, Ok) :- 3579 repeat, 3580 print_message(query, redefine_module(Module, OldFile, File)), 3581 get_single_char(Char), 3582 '$rdef_response'(Char, Ok0), 3583 !, 3584 Ok = Ok0. 3585 3586'$rdef_response'(Char, true) :- 3587 memberchk(Char, `yY`), 3588 format(user_error, 'yes~n', []). 3589'$rdef_response'(Char, false) :- 3590 memberchk(Char, `nN`), 3591 format(user_error, 'no~n', []). 3592'$rdef_response'(Char, _) :- 3593 memberchk(Char, `a`), 3594 format(user_error, 'abort~n', []), 3595 abort. 3596'$rdef_response'(_, _) :- 3597 print_message(help, redefine_module_reply), 3598 fail.
system, while all normal user modules inherit
from user.3608'$module_class'(File, Class, system) :- 3609 current_prolog_flag(home, Home), 3610 sub_atom(File, 0, Len, _, Home), 3611 ( sub_atom(File, Len, _, _, '/boot/') 3612 -> !, Class = system 3613 ; '$lib_prefix'(Prefix), 3614 sub_atom(File, Len, _, _, Prefix) 3615 -> !, Class = library 3616 ; file_directory_name(File, Home), 3617 file_name_extension(_, rc, File) 3618 -> !, Class = library 3619 ). 3620'$module_class'(_, user, user). 3621 3622'$lib_prefix'('/library'). 3623'$lib_prefix'('/xpce/prolog/'). 3624 3625'$check_export'(Module) :- 3626 '$undefined_export'(Module, UndefList), 3627 ( '$member'(Undef, UndefList), 3628 strip_module(Undef, _, Local), 3629 print_message(error, 3630 undefined_export(Module, Local)), 3631 fail 3632 ; true 3633 ).
all,
a list of optionally mapped predicate indicators or a term
except(Import).
3644'$import_list'(_, _, Var, _) :- 3645 var(Var), 3646 !, 3647 throw(error(instantitation_error, _)). 3648'$import_list'(Target, Source, all, Reexport) :- 3649 !, 3650 '$exported_ops'(Source, Import, Predicates), 3651 '$module_property'(Source, exports(Predicates)), 3652 '$import_all'(Import, Target, Source, Reexport, weak). 3653'$import_list'(Target, Source, except(Spec), Reexport) :- 3654 !, 3655 '$exported_ops'(Source, Export, Predicates), 3656 '$module_property'(Source, exports(Predicates)), 3657 ( is_list(Spec) 3658 -> true 3659 ; throw(error(type_error(list, Spec), _)) 3660 ), 3661 '$import_except'(Spec, Source, Export, Import), 3662 '$import_all'(Import, Target, Source, Reexport, weak). 3663'$import_list'(Target, Source, Import, Reexport) :- 3664 is_list(Import), 3665 !, 3666 '$exported_ops'(Source, Ops, []), 3667 '$expand_ops'(Import, Ops, Import1), 3668 '$import_all'(Import1, Target, Source, Reexport, strong). 3669'$import_list'(_, _, Import, _) :- 3670 '$type_error'(import_specifier, Import). 3671 3672'$expand_ops'([], _, []). 3673'$expand_ops'([H|T0], Ops, Imports) :- 3674 nonvar(H), H = op(_,_,_), 3675 !, 3676 '$include'('$can_unify'(H), Ops, Ops1), 3677 '$append'(Ops1, T1, Imports), 3678 '$expand_ops'(T0, Ops, T1). 3679'$expand_ops'([H|T0], Ops, [H|T1]) :- 3680 '$expand_ops'(T0, Ops, T1). 3681 3682 3683'$import_except'([], _, List, List). 3684'$import_except'([H|T], Source, List0, List) :- 3685 '$import_except_1'(H, Source, List0, List1), 3686 '$import_except'(T, Source, List1, List). 3687 3688'$import_except_1'(Var, _, _, _) :- 3689 var(Var), 3690 !, 3691 '$instantiation_error'(Var). 3692'$import_except_1'(PI as N, _, List0, List) :- 3693 '$pi'(PI), atom(N), 3694 !, 3695 '$canonical_pi'(PI, CPI), 3696 '$import_as'(CPI, N, List0, List). 3697'$import_except_1'(op(P,A,N), _, List0, List) :- 3698 !, 3699 '$remove_ops'(List0, op(P,A,N), List). 3700'$import_except_1'(PI, Source, List0, List) :- 3701 '$pi'(PI), 3702 !, 3703 '$canonical_pi'(PI, CPI), 3704 ( '$select'(P, List0, List), 3705 '$canonical_pi'(CPI, P) 3706 -> true 3707 ; print_message(warning, 3708 error(existence_error(export, PI, module(Source)), _)), 3709 List = List0 3710 ). 3711'$import_except_1'(Except, _, _, _) :- 3712 '$type_error'(import_specifier, Except). 3713 3714'$import_as'(CPI, N, [PI2|T], [CPI as N|T]) :- 3715 '$canonical_pi'(PI2, CPI), 3716 !. 3717'$import_as'(PI, N, [H|T0], [H|T]) :- 3718 !, 3719 '$import_as'(PI, N, T0, T). 3720'$import_as'(PI, _, _, _) :- 3721 '$existence_error'(export, PI). 3722 3723'$pi'(N/A) :- atom(N), integer(A), !. 3724'$pi'(N//A) :- atom(N), integer(A). 3725 3726'$canonical_pi'(N//A0, N/A) :- 3727 A is A0 + 2. 3728'$canonical_pi'(PI, PI). 3729 3730'$remove_ops'([], _, []). 3731'$remove_ops'([Op|T0], Pattern, T) :- 3732 subsumes_term(Pattern, Op), 3733 !, 3734 '$remove_ops'(T0, Pattern, T). 3735'$remove_ops'([H|T0], Pattern, [H|T]) :- 3736 '$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.
3746'$import_all'(Import, Context, Source, Reexport, Strength) :-
3747 '$import_all2'(Import, Context, Source, Imported, ImpOps, Strength),
3748 ( Reexport == true,
3749 ( '$list_to_conj'(Imported, Conj)
3750 -> export(Context:Conj),
3751 '$ifcompiling'('$add_directive_wic'(export(Context:Conj)))
3752 ; true
3753 ),
3754 source_location(File, _Line),
3755 '$export_ops'(ImpOps, Context, File)
3756 ; true
3757 ).3761'$import_all2'([], _, _, [], [], _). 3762'$import_all2'([PI as NewName|Rest], Context, Source, 3763 [NewName/Arity|Imported], ImpOps, Strength) :- 3764 !, 3765 '$canonical_pi'(PI, Name/Arity), 3766 length(Args, Arity), 3767 Head =.. [Name|Args], 3768 NewHead =.. [NewName|Args], 3769 ( '$get_predicate_attribute'(Source:Head, meta_predicate, Meta) 3770 -> Meta =.. [Name|MetaArgs], 3771 NewMeta =.. [NewName|MetaArgs], 3772 meta_predicate(Context:NewMeta) 3773 ; '$get_predicate_attribute'(Source:Head, transparent, 1) 3774 -> '$set_predicate_attribute'(Context:NewHead, transparent, true) 3775 ; true 3776 ), 3777 ( source_location(File, Line) 3778 -> E = error(_,_), 3779 catch('$store_admin_clause'((NewHead :- Source:Head), 3780 _Layout, File, File:Line), 3781 E, '$print_message'(error, E)) 3782 ; assertz(( :- !, Source:Head)) % ! avoids problems with 3783 ), % duplicate load 3784 '$import_all2'(Rest, Context, Source, Imported, ImpOps, Strength). 3785'$import_all2'([op(P,A,N)|Rest], Context, Source, Imported, 3786 [op(P,A,N)|ImpOps], Strength) :- 3787 !, 3788 '$import_ops'(Context, Source, op(P,A,N)), 3789 '$import_all2'(Rest, Context, Source, Imported, ImpOps, Strength). 3790'$import_all2'([Pred|Rest], Context, Source, [Pred|Imported], ImpOps, Strength) :- 3791 Error = error(_,_), 3792 catch(Context:'$import'(Source:Pred, Strength), Error, 3793 print_message(error, Error)), 3794 '$ifcompiling'('$import_wic'(Source, Pred, Strength)), 3795 '$import_all2'(Rest, Context, Source, Imported, ImpOps, Strength). 3796 3797 3798'$list_to_conj'([One], One) :- !. 3799'$list_to_conj'([H|T], (H,Rest)) :- 3800 '$list_to_conj'(T, Rest).
op(P,A,N) terms representing the operators
exported from Module.3807'$exported_ops'(Module, Ops, Tail) :- 3808 '$c_current_predicate'(_, Module:'$exported_op'(_,_,_)), 3809 !, 3810 findall(op(P,A,N), Module:'$exported_op'(P,A,N), Ops, Tail). 3811'$exported_ops'(_, Ops, Ops). 3812 3813'$exported_op'(Module, P, A, N) :- 3814 '$c_current_predicate'(_, Module:'$exported_op'(_,_,_)), 3815 Module:'$exported_op'(P, A, N).
3822'$import_ops'(To, From, Pattern) :- 3823 ground(Pattern), 3824 !, 3825 Pattern = op(P,A,N), 3826 op(P,A,To:N), 3827 ( '$exported_op'(From, P, A, N) 3828 -> true 3829 ; print_message(warning, no_exported_op(From, Pattern)) 3830 ). 3831'$import_ops'(To, From, Pattern) :- 3832 ( '$exported_op'(From, Pri, Assoc, Name), 3833 Pattern = op(Pri, Assoc, Name), 3834 op(Pri, Assoc, To:Name), 3835 fail 3836 ; true 3837 ).
3845'$export_list'(Decls, Module, Ops) :- 3846 is_list(Decls), 3847 !, 3848 '$do_export_list'(Decls, Module, Ops). 3849'$export_list'(Decls, _, _) :- 3850 var(Decls), 3851 throw(error(instantiation_error, _)). 3852'$export_list'(Decls, _, _) :- 3853 throw(error(type_error(list, Decls), _)). 3854 3855'$do_export_list'([], _, []) :- !. 3856'$do_export_list'([H|T], Module, Ops) :- 3857 !, 3858 E = error(_,_), 3859 catch('$export1'(H, Module, Ops, Ops1), 3860 E, ('$print_message'(error, E), Ops = Ops1)), 3861 '$do_export_list'(T, Module, Ops1). 3862 3863'$export1'(Var, _, _, _) :- 3864 var(Var), 3865 !, 3866 throw(error(instantiation_error, _)). 3867'$export1'(Op, _, [Op|T], T) :- 3868 Op = op(_,_,_), 3869 !. 3870'$export1'(PI0, Module, Ops, Ops) :- 3871 strip_module(Module:PI0, M, PI), 3872 ( PI = (_//_) 3873 -> non_terminal(M:PI) 3874 ; true 3875 ), 3876 export(M:PI). 3877 3878'$export_ops'([op(Pri, Assoc, Name)|T], Module, File) :- 3879 E = error(_,_), 3880 catch(( '$execute_directive'(op(Pri, Assoc, Module:Name), File, []), 3881 '$export_op'(Pri, Assoc, Name, Module, File) 3882 ), 3883 E, '$print_message'(error, E)), 3884 '$export_ops'(T, Module, File). 3885'$export_ops'([], _, _). 3886 3887'$export_op'(Pri, Assoc, Name, Module, File) :- 3888 ( '$get_predicate_attribute'(Module:'$exported_op'(_,_,_), defined, 1) 3889 -> true 3890 ; '$execute_directive'(discontiguous(Module:'$exported_op'/3), File, []) 3891 ), 3892 '$store_admin_clause'('$exported_op'(Pri, Assoc, Name), _Layout, File, -).
3898'$execute_directive'(Var, _F, _Options) :- 3899 var(Var), 3900 '$instantiation_error'(Var). 3901'$execute_directive'(encoding(Encoding), _F, _Options) :- 3902 !, 3903 ( '$load_input'(_F, S) 3904 -> set_stream(S, encoding(Encoding)) 3905 ). 3906'$execute_directive'(Goal, _, Options) :- 3907 \+ '$compilation_mode'(database), 3908 !, 3909 '$add_directive_wic2'(Goal, Type, Options), 3910 ( Type == call % suspend compiling into .qlf file 3911 -> '$compilation_mode'(Old, database), 3912 setup_call_cleanup( 3913 '$directive_mode'(OldDir, Old), 3914 '$execute_directive_3'(Goal), 3915 ( '$set_compilation_mode'(Old), 3916 '$set_directive_mode'(OldDir) 3917 )) 3918 ; '$execute_directive_3'(Goal) 3919 ). 3920'$execute_directive'(Goal, _, _Options) :- 3921 '$execute_directive_3'(Goal). 3922 3923'$execute_directive_3'(Goal) :- 3924 '$current_source_module'(Module), 3925 '$valid_directive'(Module:Goal), 3926 !, 3927 ( '$pattr_directive'(Goal, Module) 3928 -> true 3929 ; Term = error(_,_), 3930 catch(Module:Goal, Term, '$exception_in_directive'(Term)) 3931 -> true 3932 ; '$print_message'(warning, goal_failed(directive, Module:Goal)), 3933 fail 3934 ). 3935'$execute_directive_3'(_).
sandboxed_load is true, this calls
sandbox_allowed_directive/1. This call can deny execution
of the directive by throwing an exception.3944:- multifile prolog:sandbox_allowed_directive/1. 3945:- multifile prolog:sandbox_allowed_clause/1. 3946:- meta_predicate '$valid_directive'(). 3947 3948'$valid_directive'(_) :- 3949 current_prolog_flag(sandboxed_load, false), 3950 !. 3951'$valid_directive'(Goal) :- 3952 Error = error(Formal, _), 3953 catch(prolog:sandbox_allowed_directive(Goal), Error, true), 3954 !, 3955 ( var(Formal) 3956 -> true 3957 ; print_message(error, Error), 3958 fail 3959 ). 3960'$valid_directive'(Goal) :- 3961 print_message(error, 3962 error(permission_error(execute, 3963 sandboxed_directive, 3964 Goal), _)), 3965 fail. 3966 3967'$exception_in_directive'(Term) :- 3968 '$print_message'(error, Term), 3969 fail.
load or call. Add a call
directive to the QLF file. load directives continue the
compilation into the QLF file.3977'$add_directive_wic2'(Goal, Type, Options) :- 3978 '$common_goal_type'(Goal, Type, Options), 3979 !, 3980 ( Type == load 3981 -> true 3982 ; '$current_source_module'(Module), 3983 '$add_directive_wic'(Module:Goal) 3984 ). 3985'$add_directive_wic2'(Goal, _, _) :- 3986 ( '$compilation_mode'(qlf) % no problem for qlf files 3987 -> true 3988 ; print_message(error, mixed_directive(Goal)) 3989 ).
load
or call.3996'$common_goal_type'((A,B), Type, Options) :- 3997 !, 3998 '$common_goal_type'(A, Type, Options), 3999 '$common_goal_type'(B, Type, Options). 4000'$common_goal_type'((A;B), Type, Options) :- 4001 !, 4002 '$common_goal_type'(A, Type, Options), 4003 '$common_goal_type'(B, Type, Options). 4004'$common_goal_type'((A->B), Type, Options) :- 4005 !, 4006 '$common_goal_type'(A, Type, Options), 4007 '$common_goal_type'(B, Type, Options). 4008'$common_goal_type'(Goal, Type, Options) :- 4009 '$goal_type'(Goal, Type, Options). 4010 4011'$goal_type'(Goal, Type, Options) :- 4012 ( '$load_goal'(Goal, Options) 4013 -> Type = load 4014 ; Type = call 4015 ). 4016 4017:- thread_local 4018 '$qlf':qinclude/1. 4019 4020'$load_goal'([_|_], _). 4021'$load_goal'(consult(_), _). 4022'$load_goal'(load_files(_), _). 4023'$load_goal'(load_files(_,Options), _) :- 4024 '$option'(qcompile(QlfMode), Options), 4025 '$qlf_part_mode'(QlfMode). 4026'$load_goal'(ensure_loaded(_), _) :- '$compilation_mode'(wic). 4027'$load_goal'(use_module(_), _) :- '$compilation_mode'(wic). 4028'$load_goal'(use_module(_, _), _) :- '$compilation_mode'(wic). 4029'$load_goal'(reexport(_), _) :- '$compilation_mode'(wic). 4030'$load_goal'(reexport(_, _), _) :- '$compilation_mode'(wic). 4031'$load_goal'(Goal, _Options) :- 4032 '$qlf':qinclude(user), 4033 '$load_goal_file'(Goal, File), 4034 '$all_user_files'(File). 4035 4036 4037'$load_goal_file'(load_files(F), F). 4038'$load_goal_file'(load_files(F, _), F). 4039'$load_goal_file'(ensure_loaded(F), F). 4040'$load_goal_file'(use_module(F), F). 4041'$load_goal_file'(use_module(F, _), F). 4042'$load_goal_file'(reexport(F), F). 4043'$load_goal_file'(reexport(F, _), F). 4044 4045'$all_user_files'([]) :- 4046 !. 4047'$all_user_files'([H|T]) :- 4048 !, 4049 '$is_user_file'(H), 4050 '$all_user_files'(T). 4051'$all_user_files'(F) :- 4052 ground(F), 4053 '$is_user_file'(F). 4054 4055'$is_user_file'(File) :- 4056 absolute_file_name(File, Path, 4057 [ file_type(prolog), 4058 access(read) 4059 ]), 4060 '$module_class'(Path, user, _). 4061 4062'$qlf_part_mode'(part). 4063'$qlf_part_mode'(true). % compatibility 4064 4065 4066 /******************************** 4067 * COMPILE A CLAUSE * 4068 *********************************/
4076'$store_admin_clause'(Clause, Layout, Owner, SrcLoc) :- 4077 '$compilation_mode'(Mode), 4078 '$store_admin_clause'(Clause, Layout, Owner, SrcLoc, Mode). 4079 4080'$store_admin_clause'(Clause, Layout, Owner, SrcLoc, Mode) :- 4081 Owner \== (-), 4082 !, 4083 setup_call_cleanup( 4084 '$start_aux'(Owner, Context), 4085 '$store_admin_clause2'(Clause, Layout, Owner, SrcLoc, Mode), 4086 '$end_aux'(Owner, Context)). 4087'$store_admin_clause'(Clause, Layout, File, SrcLoc, Mode) :- 4088 '$store_admin_clause2'(Clause, Layout, File, SrcLoc, Mode). 4089 4090:- public '$store_admin_clause2'/4. % Used by autoload.pl 4091'$store_admin_clause2'(Clause, _Layout, File, SrcLoc) :- 4092 '$compilation_mode'(Mode), 4093 '$store_admin_clause2'(Clause, _Layout, File, SrcLoc, Mode). 4094 4095'$store_admin_clause2'(Clause, _Layout, File, SrcLoc, Mode) :- 4096 ( Mode == database 4097 -> '$record_clause'(Clause, File, SrcLoc) 4098 ; '$record_clause'(Clause, File, SrcLoc, Ref), 4099 '$qlf_assert_clause'(Ref, development) 4100 ).
4110'$store_clause'((_, _), _, _, _) :- 4111 !, 4112 print_message(error, cannot_redefine_comma), 4113 fail. 4114'$store_clause'((Pre => Body), _Layout, File, SrcLoc) :- 4115 nonvar(Pre), 4116 Pre = (Head,Cond), 4117 !, 4118 ( '$is_true'(Cond), current_prolog_flag(optimise, true) 4119 -> '$store_clause'((Head=>Body), _Layout, File, SrcLoc) 4120 ; '$store_clause'(?=>(Head,(Cond,!,Body)), _Layout, File, SrcLoc) 4121 ). 4122'$store_clause'(Clause, _Layout, File, SrcLoc) :- 4123 '$valid_clause'(Clause), 4124 !, 4125 ( '$compilation_mode'(database) 4126 -> '$record_clause'(Clause, File, SrcLoc) 4127 ; '$record_clause'(Clause, File, SrcLoc, Ref), 4128 '$qlf_assert_clause'(Ref, development) 4129 ). 4130 4131'$is_true'(true) => true. 4132'$is_true'((A,B)) => '$is_true'(A), '$is_true'(B). 4133'$is_true'(_) => fail. 4134 4135'$valid_clause'(_) :- 4136 current_prolog_flag(sandboxed_load, false), 4137 !. 4138'$valid_clause'(Clause) :- 4139 \+ '$cross_module_clause'(Clause), 4140 !. 4141'$valid_clause'(Clause) :- 4142 Error = error(Formal, _), 4143 catch(prolog:sandbox_allowed_clause(Clause), Error, true), 4144 !, 4145 ( var(Formal) 4146 -> true 4147 ; print_message(error, Error), 4148 fail 4149 ). 4150'$valid_clause'(Clause) :- 4151 print_message(error, 4152 error(permission_error(assert, 4153 sandboxed_clause, 4154 Clause), _)), 4155 fail. 4156 4157'$cross_module_clause'(Clause) :- 4158 '$head_module'(Clause, Module), 4159 \+ '$current_source_module'(Module). 4160 4161'$head_module'(Var, _) :- 4162 var(Var), !, fail. 4163'$head_module'((Head :- _), Module) :- 4164 '$head_module'(Head, Module). 4165'$head_module'(Module:_, Module). 4166 4167'$clause_source'('$source_location'(File,Line):Clause, Clause, File:Line) :- !. 4168'$clause_source'(Clause, Clause, -).
4175:- public 4176 '$store_clause'/2. 4177 4178'$store_clause'(Term, Id) :- 4179 '$clause_source'(Term, Clause, SrcLoc), 4180 '$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)
The clauses are owned by the file being loaded and their source location is the current source location. These differ if the clauses are compiled from an included file.
4205compile_aux_clauses(_Clauses) :- 4206 current_prolog_flag(xref, true), 4207 !. 4208compile_aux_clauses(Clauses) :- 4209 source_location(File, Line), 4210 prolog_load_context(source, Owner), 4211 '$compile_aux_clauses'(Clauses, Owner, File:Line). 4212 4213'$compile_aux_clauses'(Clauses, Owner, SrcLoc) :- 4214 setup_call_cleanup( 4215 '$start_aux'(Owner, Context), 4216 '$store_aux_clauses'(Clauses, Owner, SrcLoc), 4217 '$end_aux'(Owner, Context)). 4218 4219'$store_aux_clauses'(Clauses, Owner, SrcLoc) :- 4220 is_list(Clauses), 4221 !, 4222 forall('$member'(C,Clauses), 4223 '$compile_term'(C, _Layout, Owner, SrcLoc, [])). 4224'$store_aux_clauses'(Clause, Owner, SrcLoc) :- 4225 '$compile_term'(Clause, _Layout, Owner, SrcLoc, []). 4226 4227 4228 /******************************* 4229 * STAGING * 4230 *******************************/
4240'$stage_file'(Target, Stage) :- 4241 file_directory_name(Target, Dir), 4242 file_base_name(Target, File), 4243 current_prolog_flag(pid, Pid), 4244 format(atom(Stage), '~w/.~w.~d', [Dir,File,Pid]). 4245 4246'$install_staged_file'(exit, Staged, Target, error) :- 4247 !, 4248 win_rename_file(Staged, Target). 4249'$install_staged_file'(exit, Staged, Target, OnError) :- 4250 !, 4251 InstallError = error(_,_), 4252 catch(win_rename_file(Staged, Target), 4253 InstallError, 4254 '$install_staged_error'(OnError, InstallError, Staged, Target)). 4255'$install_staged_file'(_, Staged, _, _OnError) :- 4256 E = error(_,_), 4257 catch(delete_file(Staged), E, true). 4258 4259'$install_staged_error'(OnError, Error, Staged, _Target) :- 4260 E = error(_,_), 4261 catch(delete_file(Staged), E, true), 4262 ( OnError = silent 4263 -> true 4264 ; OnError = fail 4265 -> fail 4266 ; print_message(warning, Error) 4267 ).
4274:- if(current_prolog_flag(windows, true)). 4275win_rename_file(From, To) :- 4276 between(1, 10, _), 4277 catch(rename_file(From, To), error(permission_error(rename, file, _),_), (sleep(0.1),fail)), 4278 !. 4279:- endif. 4280win_rename_file(From, To) :- 4281 rename_file(From, To). 4282 4283 4284 /******************************* 4285 * READING * 4286 *******************************/ 4287 4288:- multifile 4289 prolog:comment_hook/4. % hook for read_clause/3 4290 4291 4292 /******************************* 4293 * FOREIGN INTERFACE * 4294 *******************************/ 4295 4296% call-back from PL_register_foreign(). First argument is the module 4297% into which the foreign predicate is loaded and second is a term 4298% describing the arguments. 4299 4300:- dynamic 4301 '$foreign_registered'/2. 4302 4303 /******************************* 4304 * TEMPORARY TERM EXPANSION * 4305 *******************************/ 4306 4307% Provide temporary definitions for the boot-loader. These are replaced 4308% by the real thing in load.pl 4309 4310:- dynamic 4311 '$expand_goal'/2, 4312 '$expand_term'/4. 4313 4314'$expand_goal'(In, In). 4315'$expand_term'(In, Layout, In, Layout). 4316 4317 4318 /******************************* 4319 * TYPE SUPPORT * 4320 *******************************/ 4321 4322'$type_error'(Type, Value) :- 4323 ( var(Value) 4324 -> throw(error(instantiation_error, _)) 4325 ; throw(error(type_error(Type, Value), _)) 4326 ). 4327 4328'$domain_error'(Type, Value) :- 4329 throw(error(domain_error(Type, Value), _)). 4330 4331'$existence_error'(Type, Object) :- 4332 throw(error(existence_error(Type, Object), _)). 4333 4334'$existence_error'(Type, Object, In) :- 4335 throw(error(existence_error(Type, Object, In), _)). 4336 4337'$permission_error'(Action, Type, Term) :- 4338 throw(error(permission_error(Action, Type, Term), _)). 4339 4340'$instantiation_error'(_Var) :- 4341 throw(error(instantiation_error, _)). 4342 4343'$uninstantiation_error'(NonVar) :- 4344 throw(error(uninstantiation_error(NonVar), _)). 4345 4346'$must_be'(list, X) :- !, 4347 '$skip_list'(_, X, Tail), 4348 ( Tail == [] 4349 -> true 4350 ; '$type_error'(list, Tail) 4351 ). 4352'$must_be'(options, X) :- !, 4353 ( '$is_options'(X) 4354 -> true 4355 ; '$type_error'(options, X) 4356 ). 4357'$must_be'(atom, X) :- !, 4358 ( atom(X) 4359 -> true 4360 ; '$type_error'(atom, X) 4361 ). 4362'$must_be'(integer, X) :- !, 4363 ( integer(X) 4364 -> true 4365 ; '$type_error'(integer, X) 4366 ). 4367'$must_be'(between(Low,High), X) :- !, 4368 ( integer(X) 4369 -> ( between(Low, High, X) 4370 -> true 4371 ; '$domain_error'(between(Low,High), X) 4372 ) 4373 ; '$type_error'(integer, X) 4374 ). 4375'$must_be'(callable, X) :- !, 4376 ( callable(X) 4377 -> true 4378 ; '$type_error'(callable, X) 4379 ). 4380'$must_be'(acyclic, X) :- !, 4381 ( acyclic_term(X) 4382 -> true 4383 ; '$domain_error'(acyclic_term, X) 4384 ). 4385'$must_be'(oneof(Type, Domain, List), X) :- !, 4386 '$must_be'(Type, X), 4387 ( memberchk(X, List) 4388 -> true 4389 ; '$domain_error'(Domain, X) 4390 ). 4391'$must_be'(boolean, X) :- !, 4392 ( (X == true ; X == false) 4393 -> true 4394 ; '$type_error'(boolean, X) 4395 ). 4396'$must_be'(ground, X) :- !, 4397 ( ground(X) 4398 -> true 4399 ; '$instantiation_error'(X) 4400 ). 4401'$must_be'(filespec, X) :- !, 4402 ( ( atom(X) 4403 ; string(X) 4404 ; compound(X), 4405 compound_name_arity(X, _, 1) 4406 ) 4407 -> true 4408 ; '$type_error'(filespec, X) 4409 ). 4410 4411% Use for debugging 4412%'$must_be'(Type, _X) :- format('Unknown $must_be type: ~q~n', [Type]). 4413 4414 4415 /******************************** 4416 * LIST PROCESSING * 4417 *********************************/ 4418 4419'$member'(El, [H|T]) :- 4420 '$member_'(T, El, H). 4421 4422'$member_'(_, El, El). 4423'$member_'([H|T], El, _) :- 4424 '$member_'(T, El, H). 4425 4426'$append'([], L, L). 4427'$append'([H|T], L, [H|R]) :- 4428 '$append'(T, L, R). 4429 4430'$append'(ListOfLists, List) :- 4431 '$must_be'(list, ListOfLists), 4432 '$append_'(ListOfLists, List). 4433 4434'$append_'([], []). 4435'$append_'([L|Ls], As) :- 4436 '$append'(L, Ws, As), 4437 '$append_'(Ls, Ws). 4438 4439'$select'(X, [X|Tail], Tail). 4440'$select'(Elem, [Head|Tail], [Head|Rest]) :- 4441 '$select'(Elem, Tail, Rest). 4442 4443'$reverse'(L1, L2) :- 4444 '$reverse'(L1, [], L2). 4445 4446'$reverse'([], List, List). 4447'$reverse'([Head|List1], List2, List3) :- 4448 '$reverse'(List1, [Head|List2], List3). 4449 4450'$delete'([], _, []) :- !. 4451'$delete'([Elem|Tail], Elem, Result) :- 4452 !, 4453 '$delete'(Tail, Elem, Result). 4454'$delete'([Head|Tail], Elem, [Head|Rest]) :- 4455 '$delete'(Tail, Elem, Rest). 4456 4457'$last'([H|T], Last) :- 4458 '$last'(T, H, Last). 4459 4460'$last'([], Last, Last). 4461'$last'([H|T], _, Last) :- 4462 '$last'(T, H, Last). 4463 4464:- meta_predicate '$include'(,,). 4465'$include'(_, [], []). 4466'$include'(G, [H|T0], L) :- 4467 ( call(G,H) 4468 -> L = [H|T] 4469 ; T = L 4470 ), 4471 '$include'(G, T0, T). 4472 4473'$can_unify'(A, B) :- 4474 \+ A \= B.
4480:- '$iso'((length/2)). 4481 4482length(List, Length) :- 4483 var(Length), 4484 !, 4485 '$skip_list'(Length0, List, Tail), 4486 ( Tail == [] 4487 -> Length = Length0 % +,- 4488 ; var(Tail) 4489 -> Tail \== Length, % avoid length(L,L) 4490 '$length3'(Tail, Length, Length0) % -,- 4491 ; throw(error(type_error(list, List), 4492 context(length/2, _))) 4493 ). 4494length(List, Length) :- 4495 integer(Length), 4496 Length >= 0, 4497 !, 4498 '$skip_list'(Length0, List, Tail), 4499 ( Tail == [] % proper list 4500 -> Length = Length0 4501 ; var(Tail) 4502 -> Extra is Length-Length0, 4503 '$length'(Tail, Extra) 4504 ; throw(error(type_error(list, List), 4505 context(length/2, _))) 4506 ). 4507length(_, Length) :- 4508 integer(Length), 4509 !, 4510 throw(error(domain_error(not_less_than_zero, Length), 4511 context(length/2, _))). 4512length(_, Length) :- 4513 throw(error(type_error(integer, Length), 4514 context(length/2, _))). 4515 4516'$length3'([], N, N). 4517'$length3'([_|List], N, N0) :- 4518 N1 is N0+1, 4519 '$length3'(List, N, N1). 4520 4521 4522 /******************************* 4523 * OPTION PROCESSING * 4524 *******************************/
4530'$is_options'(Map) :- 4531 is_dict(Map, _), 4532 !. 4533'$is_options'(List) :- 4534 is_list(List), 4535 ( List == [] 4536 -> true 4537 ; List = [H|_], 4538 '$is_option'(H, _, _) 4539 ). 4540 4541'$is_option'(Var, _, _) :- 4542 var(Var), !, fail. 4543'$is_option'(F, Name, Value) :- 4544 functor(F, _, 1), 4545 !, 4546 F =.. [Name,Value]. 4547'$is_option'(Name=Value, Name, Value).
4551'$option'(Opt, Options) :- 4552 is_dict(Options), 4553 !, 4554 [Opt] :< Options. 4555'$option'(Opt, Options) :- 4556 memberchk(Opt, Options).
4560'$option'(Term, Options, Default) :-
4561 arg(1, Term, Value),
4562 functor(Term, Name, 1),
4563 ( is_dict(Options)
4564 -> ( get_dict(Name, Options, GVal)
4565 -> Value = GVal
4566 ; Value = Default
4567 )
4568 ; functor(Gen, Name, 1),
4569 arg(1, Gen, GVal),
4570 ( memberchk(Gen, Options)
4571 -> Value = GVal
4572 ; Value = Default
4573 )
4574 ).
4582'$select_option'(Opt, Options, Rest) :-
4583 '$options_dict'(Options, Dict),
4584 select_dict([Opt], Dict, Rest).
4592'$merge_options'(New, Old, Merged) :-
4593 '$options_dict'(New, NewDict),
4594 '$options_dict'(Old, OldDict),
4595 put_dict(NewDict, OldDict, Merged).4602'$options_dict'(Options, Dict) :- 4603 is_list(Options), 4604 !, 4605 '$keyed_options'(Options, Keyed), 4606 sort(1, @<, Keyed, UniqueKeyed), 4607 '$pairs_values'(UniqueKeyed, Unique), 4608 dict_create(Dict, _, Unique). 4609'$options_dict'(Dict, Dict) :- 4610 is_dict(Dict), 4611 !. 4612'$options_dict'(Options, _) :- 4613 '$domain_error'(options, Options). 4614 4615'$keyed_options'([], []). 4616'$keyed_options'([H0|T0], [H|T]) :- 4617 '$keyed_option'(H0, H), 4618 '$keyed_options'(T0, T). 4619 4620'$keyed_option'(Var, _) :- 4621 var(Var), 4622 !, 4623 '$instantiation_error'(Var). 4624'$keyed_option'(Name=Value, Name-(Name-Value)). 4625'$keyed_option'(NameValue, Name-(Name-Value)) :- 4626 compound_name_arguments(NameValue, Name, [Value]), 4627 !. 4628'$keyed_option'(Opt, _) :- 4629 '$domain_error'(option, Opt). 4630 4631 4632 /******************************* 4633 * HANDLE TRACER 'L'-COMMAND * 4634 *******************************/ 4635 4636:- public '$prolog_list_goal'/1. 4637 4638:- multifile 4639 user:prolog_list_goal/1. 4640 4641'$prolog_list_goal'(Goal) :- 4642 user:prolog_list_goal(Goal), 4643 !. 4644'$prolog_list_goal'(Goal) :- 4645 use_module(library(listing), [listing/1]), 4646 @(listing(Goal), user). 4647 4648 4649 /******************************* 4650 * HALT * 4651 *******************************/ 4652 4653:- '$iso'((halt/0)). 4654 4655halt :- 4656 '$exit_code'(Code), 4657 ( Code == 0 4658 -> true 4659 ; print_message(warning, on_error(halt(1))) 4660 ), 4661 halt(Code).
on_error and on_warning
flags. Also used by qsave_toplevel/0.
4668'$exit_code'(Code) :-
4669 ( ( current_prolog_flag(on_error, status),
4670 statistics(errors, Count),
4671 Count > 0
4672 ; current_prolog_flag(on_warning, status),
4673 statistics(warnings, Count),
4674 Count > 0
4675 )
4676 -> Code = 1
4677 ; Code = 0
4678 ).4687:- meta_predicate at_halt(). 4688:- dynamic system:term_expansion/2, '$at_halt'/2. 4689:- multifile system:term_expansion/2, '$at_halt'/2. 4690 4691systemterm_expansion((:- at_halt(Goal)), 4692 system:'$at_halt'(Module:Goal, File:Line)) :- 4693 \+ current_prolog_flag(xref, true), 4694 source_location(File, Line), 4695 '$current_source_module'(Module). 4696 4697at_halt(Goal) :- 4698 asserta('$at_halt'(Goal, (-):0)). 4699 4700:- public '$run_at_halt'/0. 4701 4702'$run_at_halt' :- 4703 forall(clause('$at_halt'(Goal, Src), true, Ref), 4704 ( '$call_at_halt'(Goal, Src), 4705 erase(Ref) 4706 )). 4707 4708'$call_at_halt'(Goal, _Src) :- 4709 catch(Goal, E, true), 4710 !, 4711 ( var(E) 4712 -> true 4713 ; subsumes_term(cancel_halt(_), E) 4714 -> '$print_message'(informational, E), 4715 fail 4716 ; '$print_message'(error, E) 4717 ). 4718'$call_at_halt'(Goal, _Src) :- 4719 '$print_message'(warning, goal_failed(at_halt, Goal)).
4727cancel_halt(Reason) :-
4728 throw(cancel_halt(Reason)).heartbeat is
non-zero.4735:- multifile prolog:heartbeat/0. 4736 4737 4738 /******************************* 4739 * UNICODE ATOMS * 4740 *******************************/
setPrologFlag() in pl-prologflag.c when the user
sets the unicode_normalize flag and no kernel normalisation
hook is registered. Loading library(unicode) calls
PL_atom_normalize_hook from its install_t entry point. The
call propagates an error if the library is unavailable.4750:- public '$install_unicode_normalize_hook'/0. 4751 4752'$install_unicode_normalize_hook' :- 4753 use_module(library(unicode), []). 4754 4755 4756 /******************************** 4757 * LOAD OTHER MODULES * 4758 *********************************/ 4759 4760:- meta_predicate 4761 '$load_wic_files'(). 4762 4763'$load_wic_files'(Files) :- 4764 Files = Module:_, 4765 '$execute_directive'('$set_source_module'(OldM, Module), [], []), 4766 '$save_lex_state'(LexState, []), 4767 '$style_check'(_, 0xC7), % see style_name/2 in syspred.pl 4768 '$compilation_mode'(OldC, wic), 4769 consult(Files), 4770 '$execute_directive'('$set_source_module'(OldM), [], []), 4771 '$execute_directive'('$restore_lex_state'(LexState), [], []), 4772 '$set_compilation_mode'(OldC).
compileFileList() in pl-wic.c. Gets the files from
"-c file ..." and loads them into the module user.4780:- public '$load_additional_boot_files'/0. 4781 4782'$load_additional_boot_files' :- 4783 current_prolog_flag(argv, Argv), 4784 '$get_files_argv'(Argv, Files), 4785 ( Files \== [] 4786 -> format('Loading additional boot files~n'), 4787 '$load_wic_files'(user:Files), 4788 format('additional boot files loaded~n') 4789 ; true 4790 ). 4791 4792'$get_files_argv'([], []) :- !. 4793'$get_files_argv'(['-c'|Files], Files) :- !. 4794'$get_files_argv'([_|Rest], Files) :- 4795 '$get_files_argv'(Rest, Files). 4796 4797'$:-'(('$boot_message'('Loading Prolog startup files~n', []), 4798 source_location(File, _Line), 4799 file_directory_name(File, Dir), 4800 atom_concat(Dir, '/load.pl', LoadFile), 4801 '$load_wic_files'(system:[LoadFile]), 4802 '$boot_message'('SWI-Prolog boot files loaded~n', []), 4803 '$compilation_mode'(OldC, wic), 4804 '$execute_directive'('$set_source_module'(user), [], []), 4805 '$set_compilation_mode'(OldC) 4806 ))