37
52
53 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', [])).
67
68
75
76memberchk(E, List) :-
77 '$memberchk'(E, List, Tail),
78 ( nonvar(Tail)
79 -> true
80 ; Tail = [_|_],
81 memberchk(E, Tail)
82 ).
83
84 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'(:). 103
117
122
129
133
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).
151
155
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) :- 165 !,
166 '$set_pattr'(H, M, How, Attr),
167 '$set_pattr'(T, M, How, Attr).
168'$set_pattr'((A,B), M, How, Attr) :- 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).
270
271
278
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)).
297
299
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).
320
323
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 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 ';'(0,0),
362 ','(0,0),
363 @(0,+),
364 call(0),
365 call(1,?),
366 call(2,?,?),
367 call(3,?,?,?),
368 call(4,?,?,?,?),
369 call(5,?,?,?,?,?),
370 call(6,?,?,?,?,?,?),
371 call(7,?,?,?,?,?,?,?),
372 not(0),
373 \+(0),
374 $(0),
375 '->'(0,0),
376 '*->'(0,0),
377 once(0),
378 ignore(0),
379 catch(0,?,0),
380 reset(0,?,-),
381 setup_call_cleanup(0,0,0),
382 setup_call_catcher_cleanup(0,0,?,0),
383 call_cleanup(0,0),
384 catch_with_backtrace(0,?,0),
385 notrace(0),
386 '$meta_call'(0). 387
388:- '$iso'((call/1, (\+)/1, once/1, (;)/2, (',')/2, (->)/2, catch/3)). 389
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).
404
416
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).
478
492
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) :- 502 Goal.
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).
517
522
523not(Goal) :-
524 \+ Goal.
525
529
530\+ Goal :-
531 \+ Goal.
532
536
537once(Goal) :-
538 Goal,
539 !.
540
545
546ignore(Goal) :-
547 Goal,
548 !.
549ignore(_Goal).
550
551:- '$iso'((false/0)). 552
556
557false :-
558 fail.
559
563
564catch(_Goal, _Catcher, _Recover) :-
565 '$catch'. 566
570
571prolog_cut_to(_Choice) :-
572 '$cut'. 573
577
578'$' :- '$'.
579
583
584$(Goal) :- $(Goal).
585
589
590:- '$hide'(notrace/1). 591
592notrace(Goal) :-
593 setup_call_cleanup(
594 '$notrace'(Flags, SkipLevel),
595 once(Goal),
596 '$restore_trace'(Flags, SkipLevel)).
597
598
602
603reset(_Goal, _Ball, _Cont) :-
604 '$reset'.
605
612
613shift(Ball) :-
614 '$shift'(Ball).
615
616shift_for_copy(Ball) :-
617 '$shift_for_copy'(Ball).
618
630
631call_continuation([]).
632call_continuation([TB|Rest]) :-
633 ( Rest == []
634 -> '$call_continuation'(TB)
635 ; '$call_continuation'(TB),
636 call_continuation(Rest)
637 ).
638
643
644catch_with_backtrace(Goal, Ball, Recover) :-
645 catch(Goal, Ball, Recover),
646 '$no_lco'.
647
648'$no_lco'.
649
657
658:- public '$recover_and_rethrow'/2. 659
660'$recover_and_rethrow'(Goal, Exception) :-
661 call_cleanup(Goal, throw(Exception)),
662 !.
663
664
675
676setup_call_catcher_cleanup(Setup, _Goal, _Catcher, _Cleanup) :-
677 sig_atomic(Setup),
678 '$call_cleanup'.
679
680setup_call_cleanup(Setup, _Goal, _Cleanup) :-
681 sig_atomic(Setup),
682 '$call_cleanup'.
683
684call_cleanup(_Goal, _Cleanup) :-
685 '$call_cleanup'.
686
687
688 691
692:- meta_predicate
693 initialization(0, +). 694
695:- multifile '$init_goal'/3. 696:- dynamic '$init_goal'/3. 697:- '$notransact'('$init_goal'/3). 698
722
723initialization(Goal, When) :-
724 '$must_be'(oneof(atom, initialization_type,
725 [ now,
726 after_load,
727 restore,
728 restore_state,
729 prepare_state,
730 program,
731 main
732 ]), When),
733 '$initialization_context'(Source, Ctx),
734 '$initialization'(When, Goal, Source, Ctx).
735
736'$initialization'(now, Goal, _Source, Ctx) :-
737 '$run_init_goal'(Goal, Ctx),
738 '$compile_init_goal'(-, Goal, Ctx).
739'$initialization'(after_load, Goal, Source, Ctx) :-
740 ( Source \== (-)
741 -> '$compile_init_goal'(Source, Goal, Ctx)
742 ; throw(error(context_error(nodirective,
743 initialization(Goal, after_load)),
744 _))
745 ).
746'$initialization'(restore, Goal, Source, Ctx) :- 747 '$initialization'(restore_state, Goal, Source, Ctx).
748'$initialization'(restore_state, Goal, _Source, Ctx) :-
749 ( \+ current_prolog_flag(sandboxed_load, true)
750 -> '$compile_init_goal'(-, Goal, Ctx)
751 ; '$permission_error'(register, initialization(restore), Goal)
752 ).
753'$initialization'(prepare_state, Goal, _Source, Ctx) :-
754 ( \+ current_prolog_flag(sandboxed_load, true)
755 -> '$compile_init_goal'(when(prepare_state), Goal, Ctx)
756 ; '$permission_error'(register, initialization(restore), Goal)
757 ).
758'$initialization'(program, Goal, _Source, Ctx) :-
759 ( \+ current_prolog_flag(sandboxed_load, true)
760 -> '$compile_init_goal'(when(program), Goal, Ctx)
761 ; '$permission_error'(register, initialization(restore), Goal)
762 ).
763'$initialization'(main, Goal, _Source, Ctx) :-
764 ( \+ current_prolog_flag(sandboxed_load, true)
765 -> '$compile_init_goal'(when(main), Goal, Ctx)
766 ; '$permission_error'(register, initialization(restore), Goal)
767 ).
768
769
770'$compile_init_goal'(Source, Goal, Ctx) :-
771 atom(Source),
772 Source \== (-),
773 !,
774 '$store_admin_clause'(system:'$init_goal'(Source, Goal, Ctx),
775 _Layout, Source, Ctx).
776'$compile_init_goal'(Source, Goal, Ctx) :-
777 assertz('$init_goal'(Source, Goal, Ctx)).
778
779
788
789'$run_initialization'(_, loaded, _) :- !.
790'$run_initialization'(File, _Action, Options) :-
791 '$run_initialization'(File, Options).
792
793'$run_initialization'(File, Options) :-
794 setup_call_cleanup(
795 '$start_run_initialization'(Options, Restore),
796 '$run_initialization_2'(File),
797 '$end_run_initialization'(Restore)).
798
799'$start_run_initialization'(Options, OldSandBoxed) :-
800 '$push_input_context'(initialization),
801 '$set_sandboxed_load'(Options, OldSandBoxed).
802'$end_run_initialization'(OldSandBoxed) :-
803 set_prolog_flag(sandboxed_load, OldSandBoxed),
804 '$pop_input_context'.
805
806'$run_initialization_2'(File) :-
807 ( '$init_goal'(File, Goal, Ctx),
808 File \= when(_),
809 '$run_init_goal'(Goal, Ctx),
810 fail
811 ; true
812 ).
813
814'$run_init_goal'(Goal, Ctx) :-
815 ( catch_with_backtrace('$run_init_goal'(Goal), E,
816 '$initialization_error'(E, Goal, Ctx))
817 -> true
818 ; '$initialization_failure'(Goal, Ctx)
819 ).
820
821:- multifile prolog:sandbox_allowed_goal/1. 822
823'$run_init_goal'(Goal) :-
824 current_prolog_flag(sandboxed_load, false),
825 !,
826 call(Goal).
827'$run_init_goal'(Goal) :-
828 prolog:sandbox_allowed_goal(Goal),
829 call(Goal).
830
831'$initialization_context'(Source, Ctx) :-
832 ( source_location(File, Line)
833 -> Ctx = File:Line,
834 '$input_context'(Context),
835 '$top_file'(Context, File, Source)
836 ; Ctx = (-),
837 File = (-)
838 ).
839
840'$top_file'([input(include, F1, _, _)|T], _, F) :-
841 !,
842 '$top_file'(T, F1, F).
843'$top_file'(_, F, F).
844
845
846'$initialization_error'(unwind(halt(Status)), Goal, Ctx) :-
847 !,
848 print_message(warning, initialization(halt(Status), Goal, Ctx)).
849'$initialization_error'(E, Goal, Ctx) :-
850 print_message(error, initialization_error(Goal, E, Ctx)).
851
852'$initialization_failure'(Goal, Ctx) :-
853 print_message(warning, initialization_failure(Goal, Ctx)).
854
860
861:- public '$clear_source_admin'/1. 862
863'$clear_source_admin'(File) :-
864 retractall('$init_goal'(_, _, File:_)),
865 retractall('$load_context_module'(File, _, _)),
866 retractall('$resolved_source_path_db'(_, _, File)).
867
868
869 872
873:- '$iso'(stream_property/2). 874stream_property(Stream, Property) :-
875 nonvar(Stream),
876 nonvar(Property),
877 !,
878 '$stream_property'(Stream, Property).
879stream_property(Stream, Property) :-
880 nonvar(Stream),
881 !,
882 '$stream_properties'(Stream, Properties),
883 '$member'(Property, Properties).
884stream_property(Stream, Property) :-
885 nonvar(Property),
886 !,
887 ( Property = alias(Alias),
888 atom(Alias)
889 -> '$alias_stream'(Alias, Stream)
890 ; '$streams_properties'(Property, Pairs),
891 '$member'(Stream-Property, Pairs)
892 ).
893stream_property(Stream, Property) :-
894 '$streams_properties'(Property, Pairs),
895 '$member'(Stream-Properties, Pairs),
896 '$member'(Property, Properties).
897
898
899 902
905
906'$prefix_module'(Module, Module, Head, Head) :- !.
907'$prefix_module'(Module, _, Head, Module:Head).
908
912
913default_module(Me, Super) :-
914 ( atom(Me)
915 -> ( var(Super)
916 -> '$default_module'(Me, Super)
917 ; '$default_module'(Me, Super), !
918 )
919 ; '$type_error'(module, Me)
920 ).
921
922'$default_module'(Me, Me).
923'$default_module'(Me, Super) :-
924 import_module(Me, S),
925 '$default_module'(S, Super).
926
927
928 931
932:- dynamic user:exception/3. 933:- multifile user:exception/3. 934:- '$hide'(user:exception/3). 935
942
943:- public
944 '$undefined_procedure'/4. 945
946'$undefined_procedure'(Module, Name, Arity, Action) :-
947 '$prefix_module'(Module, user, Name/Arity, Pred),
948 user:exception(undefined_predicate, Pred, Action0),
949 !,
950 Action = Action0.
951'$undefined_procedure'(Module, Name, Arity, Action) :-
952 \+ current_prolog_flag(autoload, false),
953 '$autoload'(Module:Name/Arity),
954 !,
955 Action = retry.
956'$undefined_procedure'(_, _, _, error).
957
958
967
968'$loading'(Library) :-
969 current_prolog_flag(threads, true),
970 ( '$loading_file'(Library, _Queue, _LoadThread)
971 -> true
972 ; '$loading_file'(FullFile, _Queue, _LoadThread),
973 file_name_extension(Library, _, FullFile)
974 -> true
975 ).
976
978
979'$set_debugger_write_options'(write) :-
980 !,
981 create_prolog_flag(debugger_write_options,
982 [ quoted(true),
983 attributes(dots),
984 spacing(next_argument)
985 ], []).
986'$set_debugger_write_options'(print) :-
987 !,
988 create_prolog_flag(debugger_write_options,
989 [ quoted(true),
990 portray(true),
991 max_depth(10),
992 attributes(portray),
993 spacing(next_argument)
994 ], []).
995'$set_debugger_write_options'(Depth) :-
996 current_prolog_flag(debugger_write_options, Options0),
997 ( '$select'(max_depth(_), Options0, Options)
998 -> true
999 ; Options = Options0
1000 ),
1001 create_prolog_flag(debugger_write_options,
1002 [max_depth(Depth)|Options], []).
1003
1004
1005 1008
1015
1016:- multifile
1017 prolog:confirm/2. 1018
1019'$confirm'(Spec) :-
1020 prolog:confirm(Spec, Result),
1021 !,
1022 Result == true.
1023'$confirm'(Spec) :-
1024 print_message(query, Spec),
1025 between(0, 5, _),
1026 get_single_char(Answer),
1027 ( '$in_reply'(Answer, 'yYjJ \n')
1028 -> !,
1029 print_message(query, if_tty([yes-[]]))
1030 ; '$in_reply'(Answer, 'nN')
1031 -> !,
1032 print_message(query, if_tty([no-[]])),
1033 fail
1034 ; print_message(help, query(confirm)),
1035 fail
1036 ).
1037
1038'$in_reply'(Code, Atom) :-
1039 char_code(Char, Code),
1040 sub_atom(Atom, _, _, _, Char),
1041 !.
1042
1043:- dynamic
1044 user:portray/1. 1045:- multifile
1046 user:portray/1. 1047:- '$notransact'(user:portray/1). 1048
1049
1050 1053
1054:- dynamic
1055 user:file_search_path/2,
1056 user:library_directory/1. 1057:- multifile
1058 user:file_search_path/2,
1059 user:library_directory/1. 1060:- '$notransact'((user:file_search_path/2,
1061 user:library_directory/1)). 1062
1063user:(file_search_path(library, Dir) :-
1064 library_directory(Dir)).
1065user:file_search_path(swi, Home) :-
1066 current_prolog_flag(home, Home).
1067user:file_search_path(swi, Home) :-
1068 current_prolog_flag(shared_home, Home).
1069user:file_search_path(library, app_config(lib)).
1070user:file_search_path(library, swi(library)).
1071user:file_search_path(library, swi(library/clp)).
1072user:file_search_path(library, Dir) :-
1073 '$ext_library_directory'(Dir).
1074user:file_search_path(path, Dir) :-
1075 getenv('PATH', Path),
1076 current_prolog_flag(path_sep, Sep),
1077 atomic_list_concat(Dirs, Sep, Path),
1078 '$member'(Dir, Dirs).
1079user:file_search_path(user_app_data, Dir) :-
1080 '$xdg_prolog_directory'(data, Dir).
1081user:file_search_path(common_app_data, Dir) :-
1082 '$xdg_prolog_directory'(common_data, Dir).
1083user:file_search_path(user_app_config, Dir) :-
1084 '$xdg_prolog_directory'(config, Dir).
1085user:file_search_path(common_app_config, Dir) :-
1086 '$xdg_prolog_directory'(common_config, Dir).
1087user:file_search_path(app_data, user_app_data('.')).
1088user:file_search_path(app_data, common_app_data('.')).
1089user:file_search_path(app_config, user_app_config('.')).
1090user:file_search_path(app_config, common_app_config('.')).
1092user:file_search_path(app_preferences, user_app_config('.')).
1093user:file_search_path(user_profile, app_preferences('.')).
1094user:file_search_path(app, swi(app)).
1095user:file_search_path(app, app_data(app)).
1096user:file_search_path(demo, swi(demo)).
1097user:file_search_path(working_directory, CWD) :-
1098 working_directory(CWD, CWD).
1099
1100'$xdg_prolog_directory'(Which, Dir) :-
1101 '$xdg_directory'(Which, XDGDir),
1102 '$make_config_dir'(XDGDir),
1103 '$ensure_slash'(XDGDir, XDGDirS),
1104 atom_concat(XDGDirS, 'swi-prolog', Dir),
1105 '$make_config_dir'(Dir).
1106
1107'$xdg_directory'(Which, Dir) :-
1108 '$xdg_directory_search'(Where),
1109 '$xdg_directory'(Which, Where, Dir).
1110
1111'$xdg_directory_search'(xdg) :-
1112 current_prolog_flag(xdg, true),
1113 !.
1114'$xdg_directory_search'(Where) :-
1115 current_prolog_flag(windows, true),
1116 ( current_prolog_flag(xdg, false)
1117 -> Where = windows
1118 ; '$member'(Where, [windows, xdg])
1119 ).
1120
1122'$xdg_directory'(config, windows, Home) :-
1123 catch(win_folder(appdata, Home), _, fail).
1124'$xdg_directory'(config, xdg, Home) :-
1125 getenv('XDG_CONFIG_HOME', Home).
1126'$xdg_directory'(config, xdg, Home) :-
1127 expand_file_name('~/.config', [Home]).
1129'$xdg_directory'(data, windows, Home) :-
1130 catch(win_folder(local_appdata, Home), _, fail).
1131'$xdg_directory'(data, xdg, Home) :-
1132 getenv('XDG_DATA_HOME', Home).
1133'$xdg_directory'(data, xdg, Home) :-
1134 expand_file_name('~/.local', [Local]),
1135 '$make_config_dir'(Local),
1136 atom_concat(Local, '/share', Home),
1137 '$make_config_dir'(Home).
1139'$xdg_directory'(common_data, windows, Dir) :-
1140 catch(win_folder(common_appdata, Dir), _, fail).
1141'$xdg_directory'(common_data, xdg, Dir) :-
1142 '$existing_dir_from_env_path'('XDG_DATA_DIRS',
1143 [ '/usr/local/share',
1144 '/usr/share'
1145 ],
1146 Dir).
1148'$xdg_directory'(common_config, windows, Dir) :-
1149 catch(win_folder(common_appdata, Dir), _, fail).
1150'$xdg_directory'(common_config, xdg, Dir) :-
1151 '$existing_dir_from_env_path'('XDG_CONFIG_DIRS', ['/etc/xdg'], Dir).
1152
1153'$existing_dir_from_env_path'(Env, Defaults, Dir) :-
1154 ( getenv(Env, Path)
1155 -> current_prolog_flag(path_sep, Sep),
1156 atomic_list_concat(Dirs, Sep, Path)
1157 ; Dirs = Defaults
1158 ),
1159 '$member'(Dir, Dirs),
1160 Dir \== '',
1161 exists_directory(Dir).
1162
1163'$make_config_dir'(Dir) :-
1164 exists_directory(Dir),
1165 !.
1166'$make_config_dir'(Dir) :-
1167 nb_current('$create_search_directories', true),
1168 file_directory_name(Dir, Parent),
1169 '$my_file'(Parent),
1170 catch(make_directory(Dir), _, fail).
1171
1172'$ensure_slash'(Dir, DirS) :-
1173 ( sub_atom(Dir, _, _, 0, /)
1174 -> DirS = Dir
1175 ; atom_concat(Dir, /, DirS)
1176 ).
1177
1178:- dynamic '$ext_lib_dirs'/1. 1179:- volatile '$ext_lib_dirs'/1. 1180
1181'$ext_library_directory'(Dir) :-
1182 '$ext_lib_dirs'(Dirs),
1183 !,
1184 '$member'(Dir, Dirs).
1185'$ext_library_directory'(Dir) :-
1186 current_prolog_flag(home, Home),
1187 atom_concat(Home, '/library/ext/*', Pattern),
1188 expand_file_name(Pattern, Dirs0),
1189 '$include'(exists_directory, Dirs0, Dirs),
1190 asserta('$ext_lib_dirs'(Dirs)),
1191 '$member'(Dir, Dirs).
1192
1193
1195
1196'$expand_file_search_path'(Spec, Expanded, Cond) :-
1197 '$option'(access(Access), Cond),
1198 memberchk(Access, [write,append]),
1199 !,
1200 setup_call_cleanup(
1201 nb_setval('$create_search_directories', true),
1202 expand_file_search_path(Spec, Expanded),
1203 nb_delete('$create_search_directories')).
1204'$expand_file_search_path'(Spec, Expanded, _Cond) :-
1205 expand_file_search_path(Spec, Expanded).
1206
1212
1213expand_file_search_path(Spec, Expanded) :-
1214 catch('$expand_file_search_path'(Spec, Expanded, 0, []),
1215 loop(Used),
1216 throw(error(loop_error(Spec), file_search(Used)))).
1217
1218'$expand_file_search_path'(Spec, Expanded, N, Used) :-
1219 functor(Spec, Alias, 1),
1220 !,
1221 user:file_search_path(Alias, Exp0),
1222 NN is N + 1,
1223 ( NN > 16
1224 -> throw(loop(Used))
1225 ; true
1226 ),
1227 '$expand_file_search_path'(Exp0, Exp1, NN, [Alias=Exp0|Used]),
1228 arg(1, Spec, Segments),
1229 '$segments_to_atom'(Segments, File),
1230 '$make_path'(Exp1, File, Expanded).
1231'$expand_file_search_path'(Spec, Path, _, _) :-
1232 '$segments_to_atom'(Spec, Path).
1233
1234'$make_path'(Dir, '.', Path) :-
1235 !,
1236 Path = Dir.
1237'$make_path'(Dir, File, Path) :-
1238 sub_atom(Dir, _, _, 0, /),
1239 !,
1240 atom_concat(Dir, File, Path).
1241'$make_path'(Dir, File, Path) :-
1242 atomic_list_concat([Dir, /, File], Path).
1243
1244
1245 1248
1257
1258absolute_file_name(Spec, Options, Path) :-
1259 '$is_options'(Options),
1260 \+ '$is_options'(Path),
1261 !,
1262 '$absolute_file_name'(Spec, Path, Options).
1263absolute_file_name(Spec, Path, Options) :-
1264 '$absolute_file_name'(Spec, Path, Options).
1265
1266'$absolute_file_name'(Spec, Path, Options0) :-
1267 '$options_dict'(Options0, Options),
1268 1269 ( '$select_option'(extensions(Exts), Options, Options1)
1270 -> '$must_be'(list, Exts)
1271 ; '$option'(file_type(Type), Options)
1272 -> '$must_be'(atom, Type),
1273 '$file_type_extensions'(Type, Exts),
1274 Options1 = Options
1275 ; Options1 = Options,
1276 Exts = ['']
1277 ),
1278 '$canonicalise_extensions'(Exts, Extensions),
1279 1280 ( ( nonvar(Type)
1281 ; '$option'(access(none), Options, none)
1282 )
1283 -> Options2 = Options1
1284 ; '$merge_options'(_{file_type:regular}, Options1, Options2)
1285 ),
1286 1287 ( '$select_option'(solutions(Sols), Options2, Options3)
1288 -> '$must_be'(oneof(atom, solutions, [first,all]), Sols)
1289 ; Sols = first,
1290 Options3 = Options2
1291 ),
1292 1293 ( '$select_option'(file_errors(FileErrors), Options3, Options4)
1294 -> '$must_be'(oneof(atom, file_errors, [error,fail]), FileErrors)
1295 ; FileErrors = error,
1296 Options4 = Options3
1297 ),
1298 1299 ( atomic(Spec),
1300 '$select_option'(expand(Expand), Options4, Options5),
1301 '$must_be'(boolean, Expand)
1302 -> expand_file_name(Spec, List),
1303 '$member'(Spec1, List)
1304 ; Spec1 = Spec,
1305 Options5 = Options4
1306 ),
1307 1308 ( Sols == first
1309 -> ( '$chk_file'(Spec1, Extensions, Options5, true, Path)
1310 -> ! 1311 ; ( FileErrors == fail
1312 -> fail
1313 ; '$current_module'('$bags', _File),
1314 findall(P,
1315 '$chk_file'(Spec1, Extensions, [access(exist)],
1316 false, P),
1317 Candidates),
1318 '$abs_file_error'(Spec, Candidates, Options5)
1319 )
1320 )
1321 ; '$chk_file'(Spec1, Extensions, Options5, false, Path)
1322 ).
1323
1324'$abs_file_error'(Spec, Candidates, Conditions) :-
1325 '$member'(F, Candidates),
1326 '$member'(C, Conditions),
1327 '$file_condition'(C),
1328 '$file_error'(C, Spec, F, E, Comment),
1329 !,
1330 throw(error(E, context(_, Comment))).
1331'$abs_file_error'(Spec, _, _) :-
1332 '$existence_error'(source_sink, Spec).
1333
1334'$file_error'(file_type(directory), Spec, File, Error, Comment) :-
1335 \+ exists_directory(File),
1336 !,
1337 Error = existence_error(directory, Spec),
1338 Comment = not_a_directory(File).
1339'$file_error'(file_type(_), Spec, File, Error, Comment) :-
1340 exists_directory(File),
1341 !,
1342 Error = existence_error(file, Spec),
1343 Comment = directory(File).
1344'$file_error'(access(OneOrList), Spec, File, Error, _) :-
1345 '$one_or_member'(Access, OneOrList),
1346 \+ access_file(File, Access),
1347 Error = permission_error(Access, source_sink, Spec).
1348
1349'$one_or_member'(Elem, List) :-
1350 is_list(List),
1351 !,
1352 '$member'(Elem, List).
1353'$one_or_member'(Elem, Elem).
1354
1355'$file_type_extensions'(Type, Exts) :-
1356 '$current_module'('$bags', _File),
1357 !,
1358 findall(Ext, user:prolog_file_type(Ext, Type), Exts0),
1359 ( Exts0 == [],
1360 \+ '$ft_no_ext'(Type)
1361 -> '$domain_error'(file_type, Type)
1362 ; true
1363 ),
1364 '$append'(Exts0, [''], Exts).
1365'$file_type_extensions'(prolog, [pl, '']). 1366
1367'$ft_no_ext'(txt).
1368'$ft_no_ext'(executable).
1369'$ft_no_ext'(directory).
1370'$ft_no_ext'(regular).
1371
1382
1383:- multifile(user:prolog_file_type/2). 1384:- dynamic(user:prolog_file_type/2). 1385
1386user:prolog_file_type(pl, prolog).
1387user:prolog_file_type(prolog, prolog).
1388user:prolog_file_type(qlf, prolog).
1389user:prolog_file_type(pl, source).
1390user:prolog_file_type(prolog, source).
1391user:prolog_file_type(qlf, qlf).
1392user:prolog_file_type(Ext, executable) :-
1393 current_prolog_flag(shared_object_extension, Ext).
1394user:prolog_file_type(dylib, executable) :-
1395 current_prolog_flag(apple, true).
1396
1401
1402'$chk_file'(Spec, _Extensions, _Cond, _Cache, _FullName) :-
1403 \+ ground(Spec),
1404 !,
1405 '$instantiation_error'(Spec).
1406'$chk_file'(Spec, Extensions, Cond, Cache, FullName) :-
1407 compound(Spec),
1408 functor(Spec, _, 1),
1409 !,
1410 '$relative_to'(Cond, cwd, CWD),
1411 '$chk_alias_file'(Spec, Extensions, Cond, Cache, CWD, FullName).
1412'$chk_file'(Segments, Ext, Cond, Cache, FullName) :- 1413 \+ atomic(Segments),
1414 !,
1415 '$segments_to_atom'(Segments, Atom),
1416 '$chk_file'(Atom, Ext, Cond, Cache, FullName).
1417'$chk_file'(File, Exts, Cond, _, FullName) :- 1418 is_absolute_file_name(File),
1419 !,
1420 '$extend_file'(File, Exts, Extended),
1421 '$file_conditions'(Cond, Extended),
1422 '$absolute_file_name'(Extended, FullName).
1423'$chk_file'(File, Exts, Cond, _, FullName) :- 1424 '$option'(relative_to(_), Cond),
1425 !,
1426 '$relative_to'(Cond, none, Dir),
1427 '$chk_file_relative_to'(File, Exts, Cond, Dir, FullName).
1428'$chk_file'(File, Exts, Cond, _Cache, FullName) :- 1429 source_location(ContextFile, _Line),
1430 !,
1431 ( file_directory_name(ContextFile, Dir),
1432 '$chk_file_relative_to'(File, Exts, Cond, Dir, FullName)
1433 *-> true
1434 ; current_prolog_flag(source_search_working_directory, true),
1435 '$extend_file'(File, Exts, Extended),
1436 '$file_conditions'(Cond, Extended),
1437 '$absolute_file_name'(Extended, FullName),
1438 '$print_message'(warning,
1439 deprecated(source_search_working_directory(
1440 File, FullName)))
1441 ).
1442'$chk_file'(File, Exts, Cond, _Cache, FullName) :- 1443 '$extend_file'(File, Exts, Extended),
1444 '$file_conditions'(Cond, Extended),
1445 '$absolute_file_name'(Extended, FullName).
1446
1447'$chk_file_relative_to'(File, Exts, Cond, Dir, FullName) :-
1448 atomic_list_concat([Dir, /, File], AbsFile),
1449 '$extend_file'(AbsFile, Exts, Extended),
1450 '$file_conditions'(Cond, Extended),
1451 '$absolute_file_name'(Extended, FullName).
1452
1453
1454'$segments_to_atom'(Atom, Atom) :-
1455 atomic(Atom),
1456 !.
1457'$segments_to_atom'(Segments, Atom) :-
1458 '$segments_to_list'(Segments, List, []),
1459 !,
1460 atomic_list_concat(List, /, Atom).
1461
1462'$segments_to_list'(A/B, H, T) :-
1463 '$segments_to_list'(A, H, T0),
1464 '$segments_to_list'(B, T0, T).
1465'$segments_to_list'(A, [A|T], T) :-
1466 atomic(A).
1467
1468
1475
1476'$relative_to'(Conditions, Default, Dir) :-
1477 ( '$option'(relative_to(FileOrDir), Conditions)
1478 *-> ( exists_directory(FileOrDir)
1479 -> Dir = FileOrDir
1480 ; atom_concat(Dir, /, FileOrDir)
1481 -> true
1482 ; file_directory_name(FileOrDir, Dir)
1483 )
1484 ; Default == cwd
1485 -> working_directory(Dir, Dir)
1486 ; Default == source
1487 -> source_location(ContextFile, _Line),
1488 file_directory_name(ContextFile, Dir)
1489 ).
1490
1493
1494:- dynamic
1495 '$search_path_file_cache'/3, 1496 '$search_path_gc_time'/1. 1497:- volatile
1498 '$search_path_file_cache'/3,
1499 '$search_path_gc_time'/1. 1500:- '$notransact'(('$search_path_file_cache'/3,
1501 '$search_path_gc_time'/1)). 1502
1503:- create_prolog_flag(file_search_cache_time, 10, []). 1504
1505'$chk_alias_file'(Spec, Exts, Cond, true, CWD, FullFile) :-
1506 !,
1507 findall(Exp, '$expand_file_search_path'(Spec, Exp, Cond), Expansions),
1508 current_prolog_flag(emulated_dialect, Dialect),
1509 Cache = cache(Exts, Cond, CWD, Expansions, Dialect),
1510 variant_sha1(Spec+Cache, SHA1),
1511 get_time(Now),
1512 current_prolog_flag(file_search_cache_time, TimeOut),
1513 ( '$search_path_file_cache'(SHA1, CachedTime, FullFile),
1514 CachedTime > Now - TimeOut,
1515 '$file_conditions'(Cond, FullFile)
1516 -> '$search_message'(file_search(cache(Spec, Cond), FullFile))
1517 ; '$member'(Expanded, Expansions),
1518 '$extend_file'(Expanded, Exts, LibFile),
1519 ( '$file_conditions'(Cond, LibFile),
1520 '$absolute_file_name'(LibFile, FullFile),
1521 '$cache_file_found'(SHA1, Now, TimeOut, FullFile)
1522 -> '$search_message'(file_search(found(Spec, Cond), FullFile))
1523 ; '$search_message'(file_search(tried(Spec, Cond), LibFile)),
1524 fail
1525 )
1526 ).
1527'$chk_alias_file'(Spec, Exts, Cond, false, _CWD, FullFile) :-
1528 '$expand_file_search_path'(Spec, Expanded, Cond),
1529 '$extend_file'(Expanded, Exts, LibFile),
1530 '$file_conditions'(Cond, LibFile),
1531 '$absolute_file_name'(LibFile, FullFile).
1532
1533'$cache_file_found'(_, _, TimeOut, _) :-
1534 TimeOut =:= 0,
1535 !.
1536'$cache_file_found'(SHA1, Now, TimeOut, FullFile) :-
1537 '$search_path_file_cache'(SHA1, Saved, FullFile),
1538 !,
1539 ( Now - Saved < TimeOut/2
1540 -> true
1541 ; retractall('$search_path_file_cache'(SHA1, _, _)),
1542 asserta('$search_path_file_cache'(SHA1, Now, FullFile))
1543 ).
1544'$cache_file_found'(SHA1, Now, TimeOut, FullFile) :-
1545 'gc_file_search_cache'(TimeOut),
1546 asserta('$search_path_file_cache'(SHA1, Now, FullFile)).
1547
1548'gc_file_search_cache'(TimeOut) :-
1549 get_time(Now),
1550 '$search_path_gc_time'(Last),
1551 Now-Last < TimeOut/2,
1552 !.
1553'gc_file_search_cache'(TimeOut) :-
1554 get_time(Now),
1555 retractall('$search_path_gc_time'(_)),
1556 assertz('$search_path_gc_time'(Now)),
1557 Before is Now - TimeOut,
1558 ( '$search_path_file_cache'(SHA1, Cached, FullFile),
1559 Cached < Before,
1560 retractall('$search_path_file_cache'(SHA1, Cached, FullFile)),
1561 fail
1562 ; true
1563 ).
1564
1565
1566'$search_message'(Term) :-
1567 current_prolog_flag(verbose_file_search, true),
1568 !,
1569 print_message(informational, Term).
1570'$search_message'(_).
1571
1572
1576
1577'$file_conditions'(List, File) :-
1578 is_list(List),
1579 !,
1580 \+ ( '$member'(C, List),
1581 '$file_condition'(C),
1582 \+ '$file_condition'(C, File)
1583 ).
1584'$file_conditions'(Map, File) :-
1585 \+ ( get_dict(Key, Map, Value),
1586 C =.. [Key,Value],
1587 '$file_condition'(C),
1588 \+ '$file_condition'(C, File)
1589 ).
1590
1591'$file_condition'(file_type(directory), File) :-
1592 !,
1593 exists_directory(File).
1594'$file_condition'(file_type(_), File) :-
1595 !,
1596 \+ exists_directory(File).
1597'$file_condition'(access(Accesses), File) :-
1598 !,
1599 \+ ( '$one_or_member'(Access, Accesses),
1600 \+ access_file(File, Access)
1601 ).
1602
1603'$file_condition'(exists).
1604'$file_condition'(file_type(_)).
1605'$file_condition'(access(_)).
1606
1607'$extend_file'(File, Exts, FileEx) :-
1608 '$ensure_extensions'(Exts, File, Fs),
1609 '$list_to_set'(Fs, FsSet),
1610 '$member'(FileEx, FsSet).
1611
1612'$ensure_extensions'([], _, []).
1613'$ensure_extensions'([E|E0], F, [FE|E1]) :-
1614 file_name_extension(F, E, FE),
1615 '$ensure_extensions'(E0, F, E1).
1616
1621
1622'$list_to_set'(List, Set) :-
1623 '$number_list'(List, 1, Numbered),
1624 sort(1, @=<, Numbered, ONum),
1625 '$remove_dup_keys'(ONum, NumSet),
1626 sort(2, @=<, NumSet, ONumSet),
1627 '$pairs_keys'(ONumSet, Set).
1628
1629'$number_list'([], _, []).
1630'$number_list'([H|T0], N, [H-N|T]) :-
1631 N1 is N+1,
1632 '$number_list'(T0, N1, T).
1633
1634'$remove_dup_keys'([], []).
1635'$remove_dup_keys'([H|T0], [H|T]) :-
1636 H = V-_,
1637 '$remove_same_key'(T0, V, T1),
1638 '$remove_dup_keys'(T1, T).
1639
1640'$remove_same_key'([V1-_|T0], V, T) :-
1641 V1 == V,
1642 !,
1643 '$remove_same_key'(T0, V, T).
1644'$remove_same_key'(L, _, L).
1645
1646'$pairs_keys'([], []).
1647'$pairs_keys'([K-_|T0], [K|T]) :-
1648 '$pairs_keys'(T0, T).
1649
1650'$pairs_values'([], []).
1651'$pairs_values'([_-V|T0], [V|T]) :-
1652 '$pairs_values'(T0, T).
1653
1659
1660'$canonicalise_extensions'([], []) :- !.
1661'$canonicalise_extensions'([H|T], [CH|CT]) :-
1662 !,
1663 '$must_be'(atom, H),
1664 '$canonicalise_extension'(H, CH),
1665 '$canonicalise_extensions'(T, CT).
1666'$canonicalise_extensions'(E, [CE]) :-
1667 '$canonicalise_extension'(E, CE).
1668
1669'$canonicalise_extension'('', '') :- !.
1670'$canonicalise_extension'(DotAtom, DotAtom) :-
1671 sub_atom(DotAtom, 0, _, _, '.'),
1672 !.
1673'$canonicalise_extension'(Atom, DotAtom) :-
1674 atom_concat('.', Atom, DotAtom).
1675
1676
1677 1680
1681:- dynamic
1682 user:library_directory/1,
1683 user:prolog_load_file/2. 1684:- multifile
1685 user:library_directory/1,
1686 user:prolog_load_file/2. 1687
1688:- prompt(_, '|: '). 1689
1690:- thread_local
1691 '$compilation_mode_store'/1, 1692 '$directive_mode_store'/1. 1693:- volatile
1694 '$compilation_mode_store'/1,
1695 '$directive_mode_store'/1. 1696:- '$notransact'(('$compilation_mode_store'/1,
1697 '$directive_mode_store'/1)). 1698
1699'$compilation_mode'(Mode) :-
1700 ( '$compilation_mode_store'(Val)
1701 -> Mode = Val
1702 ; Mode = database
1703 ).
1704
1705'$set_compilation_mode'(Mode) :-
1706 retractall('$compilation_mode_store'(_)),
1707 assertz('$compilation_mode_store'(Mode)).
1708
1709'$compilation_mode'(Old, New) :-
1710 '$compilation_mode'(Old),
1711 ( New == Old
1712 -> true
1713 ; '$set_compilation_mode'(New)
1714 ).
1715
1716'$directive_mode'(Mode) :-
1717 ( '$directive_mode_store'(Val)
1718 -> Mode = Val
1719 ; Mode = database
1720 ).
1721
1722'$directive_mode'(Old, New) :-
1723 '$directive_mode'(Old),
1724 ( New == Old
1725 -> true
1726 ; '$set_directive_mode'(New)
1727 ).
1728
1729'$set_directive_mode'(Mode) :-
1730 retractall('$directive_mode_store'(_)),
1731 assertz('$directive_mode_store'(Mode)).
1732
1733
1738
1739'$compilation_level'(Level) :-
1740 '$input_context'(Stack),
1741 '$compilation_level'(Stack, Level).
1742
1743'$compilation_level'([], 0).
1744'$compilation_level'([Input|T], Level) :-
1745 ( arg(1, Input, see)
1746 -> '$compilation_level'(T, Level)
1747 ; '$compilation_level'(T, Level0),
1748 Level is Level0+1
1749 ).
1750
1751
1756
1757compiling :-
1758 \+ ( '$compilation_mode'(database),
1759 '$directive_mode'(database)
1760 ).
1761
1762:- meta_predicate
1763 '$ifcompiling'(0). 1764
1765'$ifcompiling'(G) :-
1766 ( '$compilation_mode'(database)
1767 -> true
1768 ; call(G)
1769 ).
1770
1771 1774
1776
1777'$load_msg_level'(Action, Nesting, Start, Done) :-
1778 '$update_autoload_level'([], 0),
1779 !,
1780 current_prolog_flag(verbose_load, Type0),
1781 '$load_msg_compat'(Type0, Type),
1782 ( '$load_msg_level'(Action, Nesting, Type, Start, Done)
1783 -> true
1784 ).
1785'$load_msg_level'(_, _, silent, silent).
1786
1787'$load_msg_compat'(true, normal) :- !.
1788'$load_msg_compat'(false, silent) :- !.
1789'$load_msg_compat'(X, X).
1790
1791'$load_msg_level'(load_file, _, full, informational, informational).
1792'$load_msg_level'(include_file, _, full, informational, informational).
1793'$load_msg_level'(load_file, _, normal, silent, informational).
1794'$load_msg_level'(include_file, _, normal, silent, silent).
1795'$load_msg_level'(load_file, 0, brief, silent, informational).
1796'$load_msg_level'(load_file, _, brief, silent, silent).
1797'$load_msg_level'(include_file, _, brief, silent, silent).
1798'$load_msg_level'(load_file, _, silent, silent, silent).
1799'$load_msg_level'(include_file, _, silent, silent, silent).
1800
1821
1822'$source_term'(From, Read, RLayout, Term, TLayout, Stream, Options) :-
1823 '$source_term'(From, Read, RLayout, Term, TLayout, Stream, [], Options),
1824 ( Term == end_of_file
1825 -> !, fail
1826 ; Term \== begin_of_file
1827 ).
1828
1829'$source_term'(Input, _,_,_,_,_,_,_) :-
1830 \+ ground(Input),
1831 !,
1832 '$instantiation_error'(Input).
1833'$source_term'(stream(Id, In, Opts),
1834 Read, RLayout, Term, TLayout, Stream, Parents, Options) :-
1835 !,
1836 '$record_included'(Parents, Id, Id, 0.0, Message),
1837 setup_call_cleanup(
1838 '$open_source'(stream(Id, In, Opts), In, State, Parents, Options),
1839 '$term_in_file'(In, Read, RLayout, Term, TLayout, Stream,
1840 [Id|Parents], Options),
1841 '$close_source'(State, Message)).
1842'$source_term'(File,
1843 Read, RLayout, Term, TLayout, Stream, Parents, Options) :-
1844 absolute_file_name(File, Path,
1845 [ file_type(prolog),
1846 access(read)
1847 ]),
1848 time_file(Path, Time),
1849 '$record_included'(Parents, File, Path, Time, Message),
1850 setup_call_cleanup(
1851 '$open_source'(Path, In, State, Parents, Options),
1852 '$term_in_file'(In, Read, RLayout, Term, TLayout, Stream,
1853 [Path|Parents], Options),
1854 '$close_source'(State, Message)).
1855
1856:- thread_local
1857 '$load_input'/2. 1858:- volatile
1859 '$load_input'/2. 1860:- '$notransact'('$load_input'/2). 1861
1862'$open_source'(stream(Id, In, Opts), In,
1863 restore(In, StreamState, Id, Ref, Opts), Parents, _Options) :-
1864 !,
1865 '$context_type'(Parents, ContextType),
1866 '$push_input_context'(ContextType),
1867 '$prepare_load_stream'(In, Id, StreamState),
1868 asserta('$load_input'(stream(Id), In), Ref).
1869'$open_source'(Path, In, close(In, Path, Ref), Parents, Options) :-
1870 '$context_type'(Parents, ContextType),
1871 '$push_input_context'(ContextType),
1872 '$open_source'(Path, In, Options),
1873 '$set_encoding'(In, Options),
1874 asserta('$load_input'(Path, In), Ref).
1875
1876'$context_type'([], load_file) :- !.
1877'$context_type'(_, include).
1878
1879:- multifile prolog:open_source_hook/3. 1880
1881'$open_source'(Path, In, Options) :-
1882 prolog:open_source_hook(Path, In, Options),
1883 !.
1884'$open_source'(Path, In, _Options) :-
1885 open(Path, read, In).
1886
1887'$close_source'(close(In, _Id, Ref), Message) :-
1888 erase(Ref),
1889 call_cleanup(
1890 close(In),
1891 '$pop_input_context'),
1892 '$close_message'(Message).
1893'$close_source'(restore(In, StreamState, _Id, Ref, Opts), Message) :-
1894 erase(Ref),
1895 call_cleanup(
1896 '$restore_load_stream'(In, StreamState, Opts),
1897 '$pop_input_context'),
1898 '$close_message'(Message).
1899
1900'$close_message'(message(Level, Msg)) :-
1901 !,
1902 '$print_message'(Level, Msg).
1903'$close_message'(_).
1904
1905
1914
1915'$term_in_file'(In, Read, RLayout, Term, TLayout, Stream, Parents, Options) :-
1916 Parents \= [_,_|_],
1917 ( '$load_input'(_, Input)
1918 -> stream_property(Input, file_name(File))
1919 ),
1920 '$set_source_location'(File, 0),
1921 '$expanded_term'(In,
1922 begin_of_file, 0-0, Read, RLayout, Term, TLayout,
1923 Stream, Parents, Options).
1924'$term_in_file'(In, Read, RLayout, Term, TLayout, Stream, Parents, Options) :-
1925 '$skip_script_line'(In, Options),
1926 '$read_clause_options'(Options, ReadOptions),
1927 '$repeat_and_read_error_mode'(ErrorMode),
1928 read_clause(In, Raw,
1929 [ syntax_errors(ErrorMode),
1930 variable_names(Bindings),
1931 term_position(Pos),
1932 subterm_positions(RawLayout)
1933 | ReadOptions
1934 ]),
1935 b_setval('$term_position', Pos),
1936 b_setval('$variable_names', Bindings),
1937 ( Raw == end_of_file
1938 -> !,
1939 ( Parents = [_,_|_] 1940 -> fail
1941 ; '$expanded_term'(In,
1942 Raw, RawLayout, Read, RLayout, Term, TLayout,
1943 Stream, Parents, Options)
1944 )
1945 ; '$expanded_term'(In, Raw, RawLayout, Read, RLayout, Term, TLayout,
1946 Stream, Parents, Options)
1947 ).
1948
1949'$read_clause_options'([], []).
1950'$read_clause_options'([H|T0], List) :-
1951 ( '$read_clause_option'(H)
1952 -> List = [H|T]
1953 ; List = T
1954 ),
1955 '$read_clause_options'(T0, T).
1956
1957'$read_clause_option'(syntax_errors(_)).
1958'$read_clause_option'(term_position(_)).
1959'$read_clause_option'(process_comment(_)).
1960
1966
1967'$repeat_and_read_error_mode'(Mode) :-
1968 ( current_predicate('$including'/0)
1969 -> repeat,
1970 ( '$including'
1971 -> Mode = dec10
1972 ; Mode = quiet
1973 )
1974 ; Mode = dec10,
1975 repeat
1976 ).
1977
1978
1979'$expanded_term'(In, Raw, RawLayout, Read, RLayout, Term, TLayout,
1980 Stream, Parents, Options) :-
1981 E = error(_,_),
1982 catch('$expand_term'(Raw, RawLayout, Expanded, ExpandedLayout), E,
1983 '$print_message_fail'(E)),
1984 ( Expanded \== []
1985 -> '$expansion_member'(Expanded, ExpandedLayout, Term1, Layout1)
1986 ; Term1 = Expanded,
1987 Layout1 = ExpandedLayout
1988 ),
1989 ( nonvar(Term1), Term1 = (:-Directive), nonvar(Directive)
1990 -> ( Directive = include(File),
1991 '$current_source_module'(Module),
1992 '$valid_directive'(Module:include(File))
1993 -> stream_property(In, encoding(Enc)),
1994 '$add_encoding'(Enc, Options, Options1),
1995 '$source_term'(File, Read, RLayout, Term, TLayout,
1996 Stream, Parents, Options1)
1997 ; Directive = encoding(Enc)
1998 -> set_stream(In, encoding(Enc)),
1999 fail
2000 ; Term = Term1,
2001 Stream = In,
2002 Read = Raw
2003 )
2004 ; Term = Term1,
2005 TLayout = Layout1,
2006 Stream = In,
2007 Read = Raw,
2008 RLayout = RawLayout
2009 ).
2010
2011'$expansion_member'(Var, Layout, Var, Layout) :-
2012 var(Var),
2013 !.
2014'$expansion_member'([], _, _, _) :- !, fail.
2015'$expansion_member'(List, ListLayout, Term, Layout) :-
2016 is_list(List),
2017 !,
2018 ( var(ListLayout)
2019 -> '$member'(Term, List)
2020 ; is_list(ListLayout)
2021 -> '$member_rep2'(Term, Layout, List, ListLayout)
2022 ; Layout = ListLayout,
2023 '$member'(Term, List)
2024 ).
2025'$expansion_member'(X, Layout, X, Layout).
2026
2029
2030'$member_rep2'(H1, H2, [H1|_], [H2|_]).
2031'$member_rep2'(H1, H2, [_|T1], [T2]) :-
2032 !,
2033 '$member_rep2'(H1, H2, T1, [T2]).
2034'$member_rep2'(H1, H2, [_|T1], [_|T2]) :-
2035 '$member_rep2'(H1, H2, T1, T2).
2036
2038
2039'$add_encoding'(Enc, Options0, Options) :-
2040 ( Options0 = [encoding(Enc)|_]
2041 -> Options = Options0
2042 ; Options = [encoding(Enc)|Options0]
2043 ).
2044
2045
2046:- multifile
2047 '$included'/4. 2048:- dynamic
2049 '$included'/4. 2050
2062
2063'$record_included'([Parent|Parents], File, Path, Time,
2064 message(DoneMsgLevel,
2065 include_file(done(Level, file(File, Path))))) :-
2066 source_location(SrcFile, Line),
2067 !,
2068 '$compilation_level'(Level),
2069 '$load_msg_level'(include_file, Level, StartMsgLevel, DoneMsgLevel),
2070 '$print_message'(StartMsgLevel,
2071 include_file(start(Level,
2072 file(File, Path)))),
2073 '$last'([Parent|Parents], Owner),
2074 '$store_admin_clause'(
2075 system:'$included'(Parent, Line, Path, Time),
2076 _, Owner, SrcFile:Line, database),
2077 '$ifcompiling'('$qlf_include'(Owner, Parent, Line, Path, Time)).
2078'$record_included'(_, _, _, _, true).
2079
2083
2084'$master_file'(File, MasterFile) :-
2085 '$included'(MasterFile0, _Line, File, _Time),
2086 !,
2087 '$master_file'(MasterFile0, MasterFile).
2088'$master_file'(File, File).
2089
2090
2091'$skip_script_line'(_In, Options) :-
2092 '$option'(check_script(false), Options),
2093 !.
2094'$skip_script_line'(In, _Options) :-
2095 ( peek_char(In, #)
2096 -> skip(In, 10)
2097 ; true
2098 ).
2099
2100'$set_encoding'(Stream, Options) :-
2101 '$option'(encoding(Enc), Options),
2102 !,
2103 Enc \== default,
2104 set_stream(Stream, encoding(Enc)).
2105'$set_encoding'(_, _).
2106
2107
2108'$prepare_load_stream'(In, Id, state(HasName,HasPos)) :-
2109 ( stream_property(In, file_name(_))
2110 -> HasName = true,
2111 ( stream_property(In, position(_))
2112 -> HasPos = true
2113 ; HasPos = false,
2114 set_stream(In, record_position(true))
2115 )
2116 ; HasName = false,
2117 set_stream(In, file_name(Id)),
2118 ( stream_property(In, position(_))
2119 -> HasPos = true
2120 ; HasPos = false,
2121 set_stream(In, record_position(true))
2122 )
2123 ).
2124
2125'$restore_load_stream'(In, _State, Options) :-
2126 '$option'(close(true), Options),
2127 !,
2128 close(In).
2129'$restore_load_stream'(In, state(HasName, HasPos), _Options) :-
2130 ( HasName == false
2131 -> set_stream(In, file_name(''))
2132 ; true
2133 ),
2134 ( HasPos == false
2135 -> set_stream(In, record_position(false))
2136 ; true
2137 ).
2138
2139
2140 2143
2144:- dynamic
2145 '$derived_source_db'/3. 2146
2147'$register_derived_source'(_, '-') :- !.
2148'$register_derived_source'(Loaded, DerivedFrom) :-
2149 retractall('$derived_source_db'(Loaded, _, _)),
2150 time_file(DerivedFrom, Time),
2151 assert('$derived_source_db'(Loaded, DerivedFrom, Time)).
2152
2155
2156'$derived_source'(Loaded, DerivedFrom, Time) :-
2157 '$derived_source_db'(Loaded, DerivedFrom, Time).
2158
2159
2160 2163
2164:- meta_predicate
2165 ensure_loaded(:),
2166 [:|+],
2167 consult(:),
2168 use_module(:),
2169 use_module(:, +),
2170 reexport(:),
2171 reexport(:, +),
2172 load_files(:),
2173 load_files(:, +). 2174
2180
2181ensure_loaded(Files) :-
2182 load_files(Files, [if(not_loaded)]).
2183
2190
2191use_module(Files) :-
2192 load_files(Files, [ if(not_loaded),
2193 must_be_module(true)
2194 ]).
2195
2200
2201use_module(File, Import) :-
2202 load_files(File, [ if(not_loaded),
2203 must_be_module(true),
2204 imports(Import)
2205 ]).
2206
2210
2211reexport(Files) :-
2212 load_files(Files, [ if(not_loaded),
2213 must_be_module(true),
2214 reexport(true)
2215 ]).
2216
2220
2221reexport(File, Import) :-
2222 load_files(File, [ if(not_loaded),
2223 must_be_module(true),
2224 imports(Import),
2225 reexport(true)
2226 ]).
2227
2228
2229[X] :-
2230 !,
2231 consult(X).
2232[M:F|R] :-
2233 consult(M:[F|R]).
2234
2235consult(M:X) :-
2236 X == user,
2237 !,
2238 flag('$user_consult', N, N+1),
2239 NN is N + 1,
2240 atom_concat('user://', NN, Id),
2241 '$consult_user'(M:Id).
2242consult(List) :-
2243 load_files(List, [expand(true)]).
2244
2249
2250'$consult_user'(Id) :-
2251 load_files(Id, [stream(user_input), check_script(false), silent(false)]).
2252
2257
2258load_files(Files) :-
2259 load_files(Files, []).
2260load_files(Module:Files, Options) :-
2261 '$must_be'(list, Options),
2262 '$load_files'(Files, Module, Options).
2263
2264'$load_files'(X, _, _) :-
2265 var(X),
2266 !,
2267 '$instantiation_error'(X).
2268'$load_files'([], _, _) :- !.
2269'$load_files'(Id, Module, Options) :- 2270 '$option'(stream(_), Options),
2271 !,
2272 ( atom(Id)
2273 -> '$load_file'(Id, Module, Options)
2274 ; throw(error(type_error(atom, Id), _))
2275 ).
2276'$load_files'(List, Module, Options) :-
2277 List = [_|_],
2278 !,
2279 '$must_be'(list, List),
2280 '$load_file_list'(List, Module, Options).
2281'$load_files'(File, Module, Options) :-
2282 '$load_one_file'(File, Module, Options).
2283
2284'$load_file_list'([], _, _).
2285'$load_file_list'([File|Rest], Module, Options) :-
2286 E = error(_,_),
2287 catch('$load_one_file'(File, Module, Options), E,
2288 '$print_message'(error, E)),
2289 '$load_file_list'(Rest, Module, Options).
2290
2291
2292'$load_one_file'(Spec, Module, Options) :-
2293 atomic(Spec),
2294 '$option'(expand(true), Options, false),
2295 !,
2296 expand_file_name(Spec, Expanded),
2297 ( Expanded = [Load]
2298 -> true
2299 ; Load = Expanded
2300 ),
2301 '$load_files'(Load, Module, [expand(false)|Options]).
2302'$load_one_file'(File, Module, Options) :-
2303 strip_module(Module:File, Into, PlainFile),
2304 '$load_file'(PlainFile, Into, Options).
2305
2306
2310
2311'$noload'(true, _, _) :-
2312 !,
2313 fail.
2314'$noload'(_, FullFile, _Options) :-
2315 '$time_source_file'(FullFile, Time, system),
2316 float(Time),
2317 !.
2318'$noload'(not_loaded, FullFile, _) :-
2319 source_file(FullFile),
2320 !.
2321'$noload'(changed, Derived, _) :-
2322 '$derived_source'(_FullFile, Derived, LoadTime),
2323 time_file(Derived, Modified),
2324 Modified @=< LoadTime,
2325 !.
2326'$noload'(changed, FullFile, Options) :-
2327 '$time_source_file'(FullFile, LoadTime, user),
2328 '$modified_id'(FullFile, Modified, Options),
2329 Modified @=< LoadTime,
2330 !.
2331'$noload'(exists, File, Options) :-
2332 '$noload'(changed, File, Options).
2333
2350
2351'$qlf_file'(Spec, _, Spec, stream, Options) :-
2352 '$option'(stream(_), Options), 2353 !.
2354'$qlf_file'(Spec, FullFile, LoadFile, compile, _) :-
2355 '$spec_extension'(Spec, Ext), 2356 ( user:prolog_file_type(Ext, qlf)
2357 -> absolute_file_name(Spec, LoadFile,
2358 [ file_type(qlf),
2359 access(read)
2360 ])
2361 ; user:prolog_file_type(Ext, prolog)
2362 -> LoadFile = FullFile
2363 ),
2364 !.
2365'$qlf_file'(_, FullFile, FullFile, compile, _) :-
2366 current_prolog_flag(source, true),
2367 access_file(FullFile, read),
2368 !.
2369'$qlf_file'(Spec, FullFile, LoadFile, Mode, Options) :-
2370 '$compilation_mode'(database),
2371 file_name_extension(Base, PlExt, FullFile),
2372 user:prolog_file_type(PlExt, prolog),
2373 user:prolog_file_type(QlfExt, qlf),
2374 file_name_extension(Base, QlfExt, QlfFile),
2375 ( access_file(QlfFile, read),
2376 ( '$qlf_out_of_date'(FullFile, QlfFile, Why)
2377 -> ( access_file(QlfFile, write)
2378 -> print_message(informational,
2379 qlf(recompile(Spec, FullFile, QlfFile, Why))),
2380 Mode = qcompile,
2381 LoadFile = FullFile
2382 ; Why == old,
2383 ( current_prolog_flag(home, PlHome),
2384 sub_atom(FullFile, 0, _, _, PlHome)
2385 ; sub_atom(QlfFile, 0, _, _, 'res://')
2386 )
2387 -> print_message(silent,
2388 qlf(system_lib_out_of_date(Spec, QlfFile))),
2389 Mode = qload,
2390 LoadFile = QlfFile
2391 ; print_message(warning,
2392 qlf(can_not_recompile(Spec, QlfFile, Why))),
2393 Mode = compile,
2394 LoadFile = FullFile
2395 )
2396 ; Mode = qload,
2397 LoadFile = QlfFile
2398 )
2399 -> !
2400 ; '$qlf_auto'(FullFile, QlfFile, Options)
2401 -> !, Mode = qcompile,
2402 LoadFile = FullFile
2403 ).
2404'$qlf_file'(_, FullFile, FullFile, compile, _).
2405
2419
2420'$qlf_out_of_date'(PlFile, QlfFile, Why) :-
2421 ( access_file(PlFile, read)
2422 -> Error = error(Formal,_),
2423 catch('$qlf_sources'(QlfFile, Sources), Error, true),
2424 ( nonvar(Formal) 2425 -> Why = Error
2426 ; time_file(QlfFile, QlfTime),
2427 '$qlf_sources_changed'(PlFile, Sources, QlfTime)
2428 -> Why = old 2429 ; fail 2430 )
2431 ; fail 2432 ).
2433
2440
2441'$qlf_sources_changed'(PlFile, Sources, QlfTime) :-
2442 '$qlf_source_changed'(PlFile, Sources, QlfTime),
2443 !.
2444'$qlf_sources_changed'(PlFile, Sources, QlfTime) :-
2445 '$member'(Source, Sources),
2446 arg(1, Source, File),
2447 File \== PlFile,
2448 '$qlf_source_changed'(File, Sources, QlfTime),
2449 !.
2450
2471
2472'$qlf_source_changed'(File, Sources, QlfTime) :-
2473 catch(time_file(File, Time), error(_,_), fail),
2474 Time > QlfTime,
2475 ( '$member'(Source, Sources),
2476 arg(1, Source, File),
2477 arg(2, Source, Hash),
2478 Hash =\= 0
2479 -> \+ '$file_hash'(File, Hash)
2480 ; true
2481 ).
2482
2488
2489:- create_prolog_flag(qcompile, false, [type(atom)]). 2490
2491'$qlf_auto'(PlFile, QlfFile, Options) :-
2492 ( '$option'(qcompile(QlfMode), Options)
2493 -> true
2494 ; current_prolog_flag(qcompile, QlfMode),
2495 \+ '$in_system_dir'(PlFile)
2496 ),
2497 ( QlfMode == auto
2498 -> true
2499 ; QlfMode == large,
2500 size_file(PlFile, Size),
2501 Size > 100000
2502 ),
2503 access_file(QlfFile, write).
2504
2505'$in_system_dir'(PlFile) :-
2506 current_prolog_flag(home, Home),
2507 sub_atom(PlFile, 0, _, _, Home).
2508
2509'$spec_extension'(File, Ext) :-
2510 atom(File),
2511 !,
2512 file_name_extension(_, Ext, File).
2513'$spec_extension'(Spec, Ext) :-
2514 compound(Spec),
2515 arg(1, Spec, Arg),
2516 '$segments_to_atom'(Arg, File),
2517 file_name_extension(_, Ext, File).
2518
2519
2528
2529:- dynamic
2530 '$resolved_source_path_db'/3. 2531:- '$notransact'('$resolved_source_path_db'/3). 2532
2533'$load_file'(File, Module, Options) :-
2534 '$error_count'(E0, W0),
2535 '$load_file_e'(File, Module, Options),
2536 '$error_count'(E1, W1),
2537 Errors is E1-E0,
2538 Warnings is W1-W0,
2539 ( Errors+Warnings =:= 0
2540 -> true
2541 ; '$print_message'(silent, load_file_errors(File, Errors, Warnings))
2542 ).
2543
2544:- if(current_prolog_flag(threads, true)). 2545'$error_count'(Errors, Warnings) :-
2546 current_prolog_flag(threads, true),
2547 !,
2548 thread_self(Me),
2549 thread_statistics(Me, errors, Errors),
2550 thread_statistics(Me, warnings, Warnings).
2551:- endif. 2552'$error_count'(Errors, Warnings) :-
2553 statistics(errors, Errors),
2554 statistics(warnings, Warnings).
2555
2556'$load_file_e'(File, Module, Options) :-
2557 \+ '$option'(stream(_), Options),
2558 user:prolog_load_file(Module:File, Options),
2559 !.
2560'$load_file_e'(File, Module, Options) :-
2561 '$option'(stream(_), Options),
2562 !,
2563 '$assert_load_context_module'(File, Module, Options),
2564 '$qdo_load_file'(File, File, Module, Options).
2565'$load_file_e'(File, Module, Options) :-
2566 ( '$resolved_source_path'(File, FullFile, Options)
2567 -> true
2568 ; '$resolve_source_path'(File, FullFile, Options)
2569 ),
2570 !,
2571 '$mt_load_file'(File, FullFile, Module, Options).
2572'$load_file_e'(_, _, _).
2573
2577
2578'$resolved_source_path'(File, FullFile, Options) :-
2579 current_prolog_flag(emulated_dialect, Dialect),
2580 '$resolved_source_path_db'(File, Dialect, FullFile),
2581 ( '$source_file_property'(FullFile, from_state, true)
2582 ; '$source_file_property'(FullFile, resource, true)
2583 ; '$option'(if(If), Options, true),
2584 '$noload'(If, FullFile, Options)
2585 ),
2586 !.
2587
2598
2599'$resolve_source_path'(File, FullFile, _Options) :-
2600 absolute_file_name(File, AbsFile,
2601 [ file_type(prolog),
2602 access(read),
2603 file_errors(fail)
2604 ]),
2605 !,
2606 '$admin_file'(AbsFile, FullFile),
2607 '$register_resolved_source_path'(File, FullFile).
2608'$resolve_source_path'(File, FullFile, _Options) :-
2609 absolute_file_name(File, FullFile,
2610 [ file_type(prolog),
2611 solutions(all),
2612 file_errors(fail)
2613 ]),
2614 source_file(FullFile),
2615 !.
2616'$resolve_source_path'(_File, _FullFile, Options) :-
2617 '$option'(if(exists), Options),
2618 !,
2619 fail.
2620'$resolve_source_path'(File, _FullFile, _Options) :-
2621 '$existence_error'(source_sink, File).
2622
2628
2629'$register_resolved_source_path'(File, FullFile) :-
2630 ( compound(File)
2631 -> current_prolog_flag(emulated_dialect, Dialect),
2632 ( '$resolved_source_path_db'(File, Dialect, FullFile)
2633 -> true
2634 ; asserta('$resolved_source_path_db'(File, Dialect, FullFile))
2635 )
2636 ; true
2637 ).
2638
2642
2643:- public '$translated_source'/2. 2644'$translated_source'(Old, New) :-
2645 forall(retract('$resolved_source_path_db'(File, Dialect, Old)),
2646 assertz('$resolved_source_path_db'(File, Dialect, New))).
2647
2652
2653'$register_resource_file'(FullFile) :-
2654 ( sub_atom(FullFile, 0, _, _, 'res://'),
2655 \+ file_name_extension(_, qlf, FullFile)
2656 -> '$set_source_file'(FullFile, resource, true)
2657 ; true
2658 ).
2659
2670
2671'$already_loaded'(_File, FullFile, Module, Options) :-
2672 '$assert_load_context_module'(FullFile, Module, Options),
2673 '$current_module'(LoadModules, FullFile),
2674 !,
2675 ( atom(LoadModules)
2676 -> LoadModule = LoadModules
2677 ; LoadModules = [LoadModule|_]
2678 ),
2679 '$import_from_loaded_module'(LoadModule, Module, Options).
2680'$already_loaded'(_, _, user, _) :- !.
2681'$already_loaded'(File, FullFile, Module, Options) :-
2682 ( '$load_context_module'(FullFile, Module, CtxOptions),
2683 '$load_ctx_options'(Options, CtxOptions)
2684 -> true
2685 ; '$load_file'(File, Module, [if(true)|Options])
2686 ).
2687
2700
2701:- dynamic
2702 '$loading_file'/3. 2703:- volatile
2704 '$loading_file'/3. 2705:- '$notransact'('$loading_file'/3). 2706
2707:- if(current_prolog_flag(threads, true)). 2708'$mt_load_file'(File, FullFile, Module, Options) :-
2709 current_prolog_flag(threads, true),
2710 !,
2711 sig_atomic(setup_call_cleanup(
2712 with_mutex('$load_file',
2713 '$mt_start_load'(FullFile, Loading, Options)),
2714 '$mt_do_load'(Loading, File, FullFile, Module, Options),
2715 '$mt_end_load'(Loading))).
2716:- endif. 2717'$mt_load_file'(File, FullFile, Module, Options) :-
2718 '$option'(if(If), Options, true),
2719 '$noload'(If, FullFile, Options),
2720 !,
2721 '$already_loaded'(File, FullFile, Module, Options).
2722:- if(current_prolog_flag(threads, true)). 2723'$mt_load_file'(File, FullFile, Module, Options) :-
2724 sig_atomic('$ctx_load_file'(File, FullFile, Module, Options)).
2725:- else. 2726'$mt_load_file'(File, FullFile, Module, Options) :-
2727 '$ctx_load_file'(File, FullFile, Module, Options).
2728:- endif. 2729
2736
2737'$ctx_load_file'(File, FullFile, Module, Options) :-
2738 '$assert_load_context_module'(FullFile, Module, Options),
2739 '$qdo_load_file'(File, FullFile, Module, Options).
2740
2741:- if(current_prolog_flag(threads, true)). 2742'$mt_start_load'(FullFile, queue(Queue), _) :-
2743 '$loading_file'(FullFile, Queue, LoadThread),
2744 \+ thread_self(LoadThread),
2745 !.
2746'$mt_start_load'(FullFile, already_loaded, Options) :-
2747 '$option'(if(If), Options, true),
2748 '$noload'(If, FullFile, Options),
2749 !.
2750'$mt_start_load'(FullFile, Ref, _) :-
2751 thread_self(Me),
2752 message_queue_create(Queue),
2753 assertz('$loading_file'(FullFile, Queue, Me), Ref).
2754
2755'$mt_do_load'(queue(Queue), File, FullFile, Module, Options) :-
2756 !,
2757 catch(thread_get_message(Queue, _), error(_,_), true),
2758 '$already_loaded'(File, FullFile, Module, Options).
2759'$mt_do_load'(already_loaded, File, FullFile, Module, Options) :-
2760 !,
2761 '$already_loaded'(File, FullFile, Module, Options).
2762'$mt_do_load'(_Ref, File, FullFile, Module, Options) :-
2763 '$ctx_load_file'(File, FullFile, Module, Options).
2764
2765'$mt_end_load'(queue(_)) :- !.
2766'$mt_end_load'(already_loaded) :- !.
2767'$mt_end_load'(Ref) :-
2768 clause('$loading_file'(_, Queue, _), _, Ref),
2769 erase(Ref),
2770 thread_send_message(Queue, done),
2771 message_queue_destroy(Queue).
2772:- endif. 2773
2777
2778'$qdo_load_file'(File, FullFile, Module, Options) :-
2779 '$qdo_load_file2'(File, FullFile, Module, Action, Options),
2780 '$register_resource_file'(FullFile),
2781 '$run_initialization'(FullFile, Action, Options).
2782
2783'$qdo_load_file2'(File, FullFile, Module, Action, Options) :-
2784 '$option'('$qlf'(QlfOut), Options),
2785 '$stage_file'(QlfOut, StageQlf),
2786 !,
2787 setup_call_catcher_cleanup(
2788 '$qstart'(StageQlf, Module, State),
2789 ( '$do_load_file'(File, FullFile, Module, Action, Options),
2790 '$qlf_add_dependencies'(FullFile)
2791 ),
2792 Catcher,
2793 '$qend'(State, Catcher, StageQlf, QlfOut)).
2794'$qdo_load_file2'(File, FullFile, Module, Action, Options) :-
2795 '$do_load_file'(File, FullFile, Module, Action, Options).
2796
2797'$qstart'(Qlf, Module, state(OldMode, OldModule)) :-
2798 '$qlf_open'(Qlf),
2799 '$compilation_mode'(OldMode, qlf),
2800 '$set_source_module'(OldModule, Module).
2801
2802'$qend'(state(OldMode, OldModule), Catcher, StageQlf, QlfOut) :-
2803 '$set_source_module'(_, OldModule),
2804 '$set_compilation_mode'(OldMode),
2805 '$qlf_close',
2806 '$install_staged_file'(Catcher, StageQlf, QlfOut, warn).
2807
2808'$set_source_module'(OldModule, Module) :-
2809 '$current_source_module'(OldModule),
2810 '$set_source_module'(Module).
2811
2820
2821'$qlf_add_dependencies'(File) :-
2822 findall(DepFile, '$dependency'(File, DepFile), DepFiles0),
2823 sort(DepFiles0, DepFiles), 2824 forall('$member'(DepFile, DepFiles),
2825 '$qlf_dependency'(DepFile)).
2826
2835
2836:- multifile
2837 prolog:qlf_dependency/2. 2838
2839'$dependency'(File, DepFile) :-
2840 '$current_module'(Module, File),
2841 '$load_context_module'(DepFile, Module, _Options),
2842 '$source_defines_expansion'(DepFile).
2843'$dependency'(File, DepFile) :-
2844 prolog:qlf_dependency(File, DepFile).
2845
2847'$source_defines_expansion'(File) :-
2848 '$expansion_hook'(P),
2849 source_file(P, File),
2850 !.
2851
2852'$expansion_hook'(user:goal_expansion(_,_)).
2853'$expansion_hook'(user:goal_expansion(_,_,_,_)).
2854'$expansion_hook'(system:goal_expansion(_,_)).
2855'$expansion_hook'(system:goal_expansion(_,_,_,_)).
2856'$expansion_hook'(user:term_expansion(_,_)).
2857'$expansion_hook'(user:term_expansion(_,_,_,_)).
2858'$expansion_hook'(system:term_expansion(_,_)).
2859'$expansion_hook'(system:term_expansion(_,_,_,_)).
2860
2865
2866'$do_load_file'(File, FullFile, Module, Action, Options) :-
2867 '$option'(derived_from(DerivedFrom), Options, -),
2868 '$register_derived_source'(FullFile, DerivedFrom),
2869 '$qlf_file'(File, FullFile, Absolute, Mode, Options),
2870 ( Mode == qcompile
2871 -> qcompile(Module:File, Options)
2872 ; '$do_load_file_2'(File, FullFile, Absolute, Module, Action, Options)
2873 ).
2874
2875'$do_load_file_2'(File, FullFile, Absolute, Module, Action, Options) :-
2876 '$source_file_property'(FullFile, number_of_clauses, OldClauses),
2877 statistics(cputime, OldTime),
2878
2879 '$setup_load'(ScopedFlags, OldSandBoxed, OldVerbose, OldAutoLevel, OldXRef,
2880 Options),
2881
2882 '$compilation_level'(Level),
2883 '$load_msg_level'(load_file, Level, StartMsgLevel, DoneMsgLevel),
2884 '$print_message'(StartMsgLevel,
2885 load_file(start(Level,
2886 file(File, Absolute)))),
2887
2888 ( '$option'(stream(FromStream), Options)
2889 -> Input = stream
2890 ; Input = source
2891 ),
2892
2893 ( Input == stream,
2894 ( '$option'(format(qlf), Options, source)
2895 -> set_stream(FromStream, file_name(Absolute)),
2896 '$qload_stream'(FromStream, Module, Action, LM, Options)
2897 ; '$consult_file'(stream(Absolute, FromStream, []),
2898 Module, Action, LM, Options)
2899 )
2900 -> true
2901 ; Input == source,
2902 file_name_extension(_, Ext, Absolute),
2903 ( user:prolog_file_type(Ext, qlf),
2904 E = error(_,_),
2905 catch('$qload_file'(Absolute, Module, Action, LM, Options),
2906 E,
2907 print_message(warning, E))
2908 -> true
2909 ; '$consult_file'(Absolute, Module, Action, LM, Options)
2910 )
2911 -> true
2912 ; '$print_message'(error, load_file(failed(File))),
2913 fail
2914 ),
2915
2916 '$import_from_loaded_module'(LM, Module, Options),
2917
2918 '$source_file_property'(FullFile, number_of_clauses, NewClauses),
2919 statistics(cputime, Time),
2920 ClausesCreated is NewClauses - OldClauses,
2921 TimeUsed is Time - OldTime,
2922
2923 '$print_message'(DoneMsgLevel,
2924 load_file(done(Level,
2925 file(File, Absolute),
2926 Action,
2927 LM,
2928 TimeUsed,
2929 ClausesCreated))),
2930
2931 '$restore_load'(ScopedFlags, OldSandBoxed, OldVerbose, OldAutoLevel, OldXRef).
2932
2933'$setup_load'(ScopedFlags, OldSandBoxed, OldVerbose, OldAutoLevel, OldXRef,
2934 Options) :-
2935 '$save_file_scoped_flags'(ScopedFlags),
2936 '$set_sandboxed_load'(Options, OldSandBoxed),
2937 '$set_verbose_load'(Options, OldVerbose),
2938 '$set_optimise_load'(Options),
2939 '$update_autoload_level'(Options, OldAutoLevel),
2940 '$set_no_xref'(OldXRef).
2941
2942'$restore_load'(ScopedFlags, OldSandBoxed, OldVerbose, OldAutoLevel, OldXRef) :-
2943 '$set_autoload_level'(OldAutoLevel),
2944 set_prolog_flag(xref, OldXRef),
2945 set_prolog_flag(verbose_load, OldVerbose),
2946 set_prolog_flag(sandboxed_load, OldSandBoxed),
2947 '$restore_file_scoped_flags'(ScopedFlags).
2948
2949
2954
2955'$save_file_scoped_flags'(State) :-
2956 current_predicate(findall/3), 2957 !,
2958 findall(SavedFlag, '$save_file_scoped_flag'(SavedFlag), State).
2959'$save_file_scoped_flags'([]).
2960
2961'$save_file_scoped_flag'(Flag-Value) :-
2962 '$file_scoped_flag'(Flag, Default),
2963 ( current_prolog_flag(Flag, Value)
2964 -> true
2965 ; Value = Default
2966 ).
2967
2968'$file_scoped_flag'(generate_debug_info, true).
2969'$file_scoped_flag'(optimise, false).
2970'$file_scoped_flag'(xref, false).
2971
2972'$restore_file_scoped_flags'([]).
2973'$restore_file_scoped_flags'([Flag-Value|T]) :-
2974 set_prolog_flag(Flag, Value),
2975 '$restore_file_scoped_flags'(T).
2976
2977
2981
2982'$import_from_loaded_module'(LoadedModule, Module, Options) :-
2983 LoadedModule \== Module,
2984 atom(LoadedModule),
2985 !,
2986 '$option'(imports(Import), Options, all),
2987 '$option'(reexport(Reexport), Options, false),
2988 '$import_list'(Module, LoadedModule, Import, Reexport).
2989'$import_from_loaded_module'(_, _, _).
2990
2991
2996
2997'$set_verbose_load'(Options, Old) :-
2998 current_prolog_flag(verbose_load, Old),
2999 ( '$option'(silent(Silent), Options)
3000 -> ( '$negate'(Silent, Level0)
3001 -> '$load_msg_compat'(Level0, Level)
3002 ; Level = Silent
3003 ),
3004 set_prolog_flag(verbose_load, Level)
3005 ; true
3006 ).
3007
3008'$negate'(true, false).
3009'$negate'(false, true).
3010
3017
3018'$set_sandboxed_load'(Options, Old) :-
3019 current_prolog_flag(sandboxed_load, Old),
3020 ( '$option'(sandboxed(SandBoxed), Options),
3021 '$enter_sandboxed'(Old, SandBoxed, New),
3022 New \== Old
3023 -> set_prolog_flag(sandboxed_load, New)
3024 ; true
3025 ).
3026
3027'$enter_sandboxed'(Old, New, SandBoxed) :-
3028 ( Old == false, New == true
3029 -> SandBoxed = true,
3030 '$ensure_loaded_library_sandbox'
3031 ; Old == true, New == false
3032 -> throw(error(permission_error(leave, sandbox, -), _))
3033 ; SandBoxed = Old
3034 ).
3035'$enter_sandboxed'(false, true, true).
3036
3037'$ensure_loaded_library_sandbox' :-
3038 source_file_property(library(sandbox), module(sandbox)),
3039 !.
3040'$ensure_loaded_library_sandbox' :-
3041 load_files(library(sandbox), [if(not_loaded), silent(true)]).
3042
3043'$set_optimise_load'(Options) :-
3044 ( '$option'(optimise(Optimise), Options)
3045 -> set_prolog_flag(optimise, Optimise)
3046 ; true
3047 ).
3048
3049'$set_no_xref'(OldXRef) :-
3050 ( current_prolog_flag(xref, OldXRef)
3051 -> true
3052 ; OldXRef = false
3053 ),
3054 set_prolog_flag(xref, false).
3055
3056
3060
3061:- thread_local
3062 '$autoload_nesting'/1. 3063:- '$notransact'('$autoload_nesting'/1). 3064
3065'$update_autoload_level'(Options, AutoLevel) :-
3066 '$option'(autoload(Autoload), Options, false),
3067 ( '$autoload_nesting'(CurrentLevel)
3068 -> AutoLevel = CurrentLevel
3069 ; AutoLevel = 0
3070 ),
3071 ( Autoload == false
3072 -> true
3073 ; NewLevel is AutoLevel + 1,
3074 '$set_autoload_level'(NewLevel)
3075 ).
3076
3077'$set_autoload_level'(New) :-
3078 retractall('$autoload_nesting'(_)),
3079 asserta('$autoload_nesting'(New)).
3080
3081
3086
3087'$print_message'(Level, Term) :-
3088 current_predicate(system:print_message/2),
3089 !,
3090 print_message(Level, Term).
3091'$print_message'(warning, Term) :-
3092 source_location(File, Line),
3093 !,
3094 format(user_error, 'WARNING: ~w:~w: ~p~n', [File, Line, Term]).
3095'$print_message'(error, Term) :-
3096 !,
3097 source_location(File, Line),
3098 !,
3099 format(user_error, 'ERROR: ~w:~w: ~p~n', [File, Line, Term]).
3100'$print_message'(_Level, _Term).
3101
3102'$print_message_fail'(E) :-
3103 '$print_message'(error, E),
3104 fail.
3105
3111
3112'$consult_file'(Absolute, Module, What, LM, Options) :-
3113 '$current_source_module'(Module), 3114 !,
3115 '$consult_file_2'(Absolute, Module, What, LM, Options).
3116'$consult_file'(Absolute, Module, What, LM, Options) :-
3117 '$set_source_module'(OldModule, Module),
3118 '$ifcompiling'('$qlf_start_sub_module'(Module)),
3119 '$consult_file_2'(Absolute, Module, What, LM, Options),
3120 '$ifcompiling'('$qlf_end_part'),
3121 '$set_source_module'(OldModule).
3122
3123'$consult_file_2'(Absolute, Module, What, LM, Options) :-
3124 '$set_source_module'(OldModule, Module),
3125 '$load_id'(Absolute, Id, Modified, Options),
3126 '$compile_type'(What),
3127 '$save_lex_state'(LexState, Options),
3128 '$set_dialect'(Options),
3129 setup_call_cleanup(
3130 '$start_consult'(Id, Modified),
3131 '$load_file'(Absolute, Id, LM, Options),
3132 '$end_consult'(Id, LexState, OldModule)).
3133
3134'$end_consult'(Id, LexState, OldModule) :-
3135 '$end_consult'(Id),
3136 '$restore_lex_state'(LexState),
3137 '$set_source_module'(OldModule).
3138
3139
3140:- create_prolog_flag(emulated_dialect, swi, [type(atom)]). 3141
3143
3144'$save_lex_state'(State, Options) :-
3145 '$option'(scope_settings(false), Options),
3146 !,
3147 State = (-).
3148'$save_lex_state'(lexstate(Style, Dialect), _) :-
3149 '$style_check'(Style, Style),
3150 current_prolog_flag(emulated_dialect, Dialect).
3151
3152'$restore_lex_state'(-) :- !.
3153'$restore_lex_state'(lexstate(Style, Dialect)) :-
3154 '$style_check'(_, Style),
3155 set_prolog_flag(emulated_dialect, Dialect).
3156
3157'$set_dialect'(Options) :-
3158 '$option'(dialect(Dialect), Options),
3159 !,
3160 '$expects_dialect'(Dialect).
3161'$set_dialect'(_).
3162
3163'$load_id'(stream(Id, _, _), Id, Modified, Options) :-
3164 !,
3165 '$modified_id'(Id, Modified, Options).
3166'$load_id'(Id, Id, Modified, Options) :-
3167 '$modified_id'(Id, Modified, Options).
3168
3169'$modified_id'(_, Modified, Options) :-
3170 '$option'(modified(Stamp), Options, Def),
3171 Stamp \== Def,
3172 !,
3173 Modified = Stamp.
3174'$modified_id'(Id, Modified, _) :-
3175 catch(time_file(Id, Modified),
3176 error(_, _),
3177 fail),
3178 !.
3179'$modified_id'(_, 0, _).
3180
3181
3182'$compile_type'(What) :-
3183 '$compilation_mode'(How),
3184 ( How == database
3185 -> What = compiled
3186 ; How == qlf
3187 -> What = '*qcompiled*'
3188 ; What = 'boot compiled'
3189 ).
3190
3198
3199:- dynamic
3200 '$load_context_module'/3. 3201:- multifile
3202 '$load_context_module'/3. 3203:- '$notransact'('$load_context_module'/3). 3204
3205'$assert_load_context_module'(_, _, Options) :-
3206 '$option'(register(false), Options),
3207 !.
3208'$assert_load_context_module'(File, Module, Options) :-
3209 source_location(FromFile, Line),
3210 !,
3211 '$master_file'(FromFile, MasterFile),
3212 '$admin_file'(File, PlFile),
3213 '$check_load_non_module'(PlFile, Module),
3214 '$add_dialect'(Options, Options1),
3215 '$load_ctx_options'(Options1, Options2),
3216 '$store_admin_clause'(
3217 system:'$load_context_module'(PlFile, Module, Options2),
3218 _Layout, MasterFile, FromFile:Line).
3219'$assert_load_context_module'(File, Module, Options) :-
3220 '$admin_file'(File, PlFile),
3221 '$check_load_non_module'(PlFile, Module),
3222 '$add_dialect'(Options, Options1),
3223 '$load_ctx_options'(Options1, Options2),
3224 ( clause('$load_context_module'(PlFile, Module, _), true, Ref),
3225 \+ clause_property(Ref, file(_)),
3226 erase(Ref)
3227 -> true
3228 ; true
3229 ),
3230 assertz('$load_context_module'(PlFile, Module, Options2)).
3231
3237
3238'$admin_file'(QlfFile, PlFile) :-
3239 file_name_extension(_, qlf, QlfFile),
3240 '$qlf_module'(QlfFile, Info),
3241 get_dict(file, Info, PlFile),
3242 !.
3243'$admin_file'(File, File).
3244
3250
3251'$add_dialect'(Options0, Options) :-
3252 current_prolog_flag(emulated_dialect, Dialect), Dialect \== swi,
3253 !,
3254 Options = [dialect(Dialect)|Options0].
3255'$add_dialect'(Options, Options).
3256
3261
3262'$load_ctx_options'(Options, CtxOptions) :-
3263 '$load_ctx_options2'(Options, CtxOptions0),
3264 sort(CtxOptions0, CtxOptions).
3265
3266'$load_ctx_options2'([], []).
3267'$load_ctx_options2'([H|T0], [H|T]) :-
3268 '$load_ctx_option'(H),
3269 !,
3270 '$load_ctx_options2'(T0, T).
3271'$load_ctx_options2'([_|T0], T) :-
3272 '$load_ctx_options2'(T0, T).
3273
3274'$load_ctx_option'(derived_from(_)).
3275'$load_ctx_option'(dialect(_)).
3276'$load_ctx_option'(encoding(_)).
3277'$load_ctx_option'(imports(_)).
3278'$load_ctx_option'(reexport(_)).
3279
3280
3285
3286'$check_load_non_module'(File, _) :-
3287 '$current_module'(_, File),
3288 !. 3289'$check_load_non_module'(File, Module) :-
3290 '$load_context_module'(File, OldModule, _),
3291 Module \== OldModule,
3292 !,
3293 format(atom(Msg),
3294 'Non-module file already loaded into module ~w; \c
3295 trying to load into ~w',
3296 [OldModule, Module]),
3297 throw(error(permission_error(load, source, File),
3298 context(load_files/2, Msg))).
3299'$check_load_non_module'(_, _).
3300
3311
3312'$load_file'(Path, Id, Module, Options) :-
3313 State = state(true, _, true, false, Id, -),
3314 ( '$source_term'(Path, _Read, _Layout, Term, Layout,
3315 _Stream, Options),
3316 '$valid_term'(Term),
3317 ( arg(1, State, true)
3318 -> '$first_term'(Term, Layout, Id, State, Options),
3319 nb_setarg(1, State, false)
3320 ; '$compile_term'(Term, Layout, Id, Options)
3321 ),
3322 arg(4, State, true)
3323 ; '$fixup_reconsult'(Id),
3324 '$end_load_file'(State)
3325 ),
3326 !,
3327 arg(2, State, Module).
3328
3329'$valid_term'(Var) :-
3330 var(Var),
3331 !,
3332 print_message(error, error(instantiation_error, _)).
3333'$valid_term'(Term) :-
3334 Term \== [].
3335
3336'$end_load_file'(State) :-
3337 arg(1, State, true), 3338 !,
3339 nb_setarg(2, State, Module),
3340 arg(5, State, Id),
3341 '$current_source_module'(Module),
3342 '$ifcompiling'('$qlf_start_file'(Id)),
3343 '$ifcompiling'('$qlf_end_part').
3344'$end_load_file'(State) :-
3345 arg(3, State, End),
3346 '$end_load_file'(End, State).
3347
3348'$end_load_file'(true, _).
3349'$end_load_file'(end_module, State) :-
3350 arg(2, State, Module),
3351 '$check_export'(Module),
3352 '$ifcompiling'('$qlf_end_part').
3353'$end_load_file'(end_non_module, _State) :-
3354 '$ifcompiling'('$qlf_end_part').
3355
3356
3357'$first_term'(?-(Directive), Layout, Id, State, Options) :-
3358 !,
3359 '$first_term'(:-(Directive), Layout, Id, State, Options).
3360'$first_term'(:-(Directive), _Layout, Id, State, Options) :-
3361 nonvar(Directive),
3362 ( ( Directive = module(Name, Public)
3363 -> Imports = []
3364 ; Directive = module(Name, Public, Imports)
3365 )
3366 -> !,
3367 '$module_name'(Name, Id, Module, Options),
3368 '$start_module'(Module, Public, State, Options),
3369 '$module3'(Imports)
3370 ; Directive = expects_dialect(Dialect)
3371 -> !,
3372 '$set_dialect'(Dialect, State),
3373 fail 3374 ).
3375'$first_term'(Term, Layout, Id, State, Options) :-
3376 '$start_non_module'(Id, Term, State, Options),
3377 '$compile_term'(Term, Layout, Id, Options).
3378
3383
3384'$compile_term'(Term, Layout, SrcId, Options) :-
3385 '$compile_term'(Term, Layout, SrcId, -, Options).
3386
3387'$compile_term'(Var, _Layout, _Id, _SrcLoc, _Options) :-
3388 var(Var),
3389 !,
3390 '$instantiation_error'(Var).
3391'$compile_term'((?-Directive), _Layout, Id, _SrcLoc, Options) :-
3392 !,
3393 '$execute_directive'(Directive, Id, Options).
3394'$compile_term'((:-Directive), _Layout, Id, _SrcLoc, Options) :-
3395 !,
3396 '$execute_directive'(Directive, Id, Options).
3397'$compile_term'('$source_location'(File, Line):Term,
3398 Layout, Id, _SrcLoc, Options) :-
3399 !,
3400 '$compile_term'(Term, Layout, Id, File:Line, Options).
3401'$compile_term'(Clause, Layout, Id, SrcLoc, _Options) :-
3402 E = error(_,_),
3403 catch('$store_clause'(Clause, Layout, Id, SrcLoc), E,
3404 '$print_message'(error, E)).
3405
3406'$start_non_module'(_Id, Term, _State, Options) :-
3407 '$option'(must_be_module(true), Options, false),
3408 !,
3409 '$domain_error'(module_header, Term).
3410'$start_non_module'(Id, _Term, State, _Options) :-
3411 '$current_source_module'(Module),
3412 '$ifcompiling'('$qlf_start_file'(Id)),
3413 '$qset_dialect'(State),
3414 nb_setarg(2, State, Module),
3415 nb_setarg(3, State, end_non_module).
3416
3427
3428'$set_dialect'(Dialect, State) :-
3429 '$compilation_mode'(qlf, database),
3430 !,
3431 '$expects_dialect'(Dialect),
3432 '$compilation_mode'(_, qlf),
3433 nb_setarg(6, State, Dialect).
3434'$set_dialect'(Dialect, _) :-
3435 '$expects_dialect'(Dialect).
3436
3437'$qset_dialect'(State) :-
3438 '$compilation_mode'(qlf),
3439 arg(6, State, Dialect), Dialect \== (-),
3440 !,
3441 '$add_directive_wic'('$expects_dialect'(Dialect)).
3442'$qset_dialect'(_).
3443
3444'$expects_dialect'(Dialect) :-
3445 Dialect == swi,
3446 !,
3447 set_prolog_flag(emulated_dialect, Dialect).
3448'$expects_dialect'(Dialect) :-
3449 current_predicate(expects_dialect/1),
3450 !,
3451 expects_dialect(Dialect).
3452'$expects_dialect'(Dialect) :-
3453 use_module(library(dialect), [expects_dialect/1]),
3454 expects_dialect(Dialect).
3455
3456
3457 3460
3461'$start_module'(Module, _Public, State, _Options) :-
3462 '$current_module'(Module, OldFile),
3463 source_location(File, _Line),
3464 OldFile \== File, OldFile \== [],
3465 same_file(OldFile, File),
3466 !,
3467 nb_setarg(2, State, Module),
3468 nb_setarg(4, State, true). 3469'$start_module'(Module, Public, State, Options) :-
3470 arg(5, State, File),
3471 nb_setarg(2, State, Module),
3472 source_location(_File, Line),
3473 '$option'(redefine_module(Action), Options, false),
3474 '$module_class'(File, Class, Super),
3475 '$reset_dialect'(File, Class),
3476 '$redefine_module'(Module, File, Action),
3477 '$declare_module'(Module, Class, Super, File, Line, false),
3478 '$export_list'(Public, Module, Ops),
3479 '$ifcompiling'('$qlf_start_module'(Module)),
3480 '$export_ops'(Ops, Module, File),
3481 '$qset_dialect'(State),
3482 nb_setarg(3, State, end_module).
3483
3488
3489'$reset_dialect'(File, library) :-
3490 file_name_extension(_, pl, File),
3491 !,
3492 set_prolog_flag(emulated_dialect, swi).
3493'$reset_dialect'(_, _).
3494
3495
3499
3500'$module3'(Var) :-
3501 var(Var),
3502 !,
3503 '$instantiation_error'(Var).
3504'$module3'([]) :- !.
3505'$module3'([H|T]) :-
3506 !,
3507 '$module3'(H),
3508 '$module3'(T).
3509'$module3'(Id) :-
3510 use_module(library(dialect/Id)).
3511
3523
3524'$module_name'(_, _, Module, Options) :-
3525 '$option'(module(Module), Options),
3526 !,
3527 '$current_source_module'(Context),
3528 Context \== Module. 3529'$module_name'(Var, Id, Module, Options) :-
3530 var(Var),
3531 !,
3532 file_base_name(Id, File),
3533 file_name_extension(Var, _, File),
3534 '$module_name'(Var, Id, Module, Options).
3535'$module_name'(Reserved, _, _, _) :-
3536 '$reserved_module'(Reserved),
3537 !,
3538 throw(error(permission_error(load, module, Reserved), _)).
3539'$module_name'(Module, _Id, Module, _).
3540
3541
3542'$reserved_module'(system).
3543'$reserved_module'(user).
3544
3545
3547
3548'$redefine_module'(_Module, _, false) :- !.
3549'$redefine_module'(Module, File, true) :-
3550 !,
3551 ( module_property(Module, file(OldFile)),
3552 File \== OldFile
3553 -> unload_file(OldFile)
3554 ; true
3555 ).
3556'$redefine_module'(Module, File, ask) :-
3557 ( stream_property(user_input, tty(true)),
3558 module_property(Module, file(OldFile)),
3559 File \== OldFile,
3560 '$rdef_response'(Module, OldFile, File, true)
3561 -> '$redefine_module'(Module, File, true)
3562 ; true
3563 ).
3564
3565'$rdef_response'(Module, OldFile, File, Ok) :-
3566 repeat,
3567 print_message(query, redefine_module(Module, OldFile, File)),
3568 get_single_char(Char),
3569 '$rdef_response'(Char, Ok0),
3570 !,
3571 Ok = Ok0.
3572
3573'$rdef_response'(Char, true) :-
3574 memberchk(Char, `yY`),
3575 format(user_error, 'yes~n', []).
3576'$rdef_response'(Char, false) :-
3577 memberchk(Char, `nN`),
3578 format(user_error, 'no~n', []).
3579'$rdef_response'(Char, _) :-
3580 memberchk(Char, `a`),
3581 format(user_error, 'abort~n', []),
3582 abort.
3583'$rdef_response'(_, _) :-
3584 print_message(help, redefine_module_reply),
3585 fail.
3586
3587
3594
3595'$module_class'(File, Class, system) :-
3596 current_prolog_flag(home, Home),
3597 sub_atom(File, 0, Len, _, Home),
3598 ( sub_atom(File, Len, _, _, '/boot/')
3599 -> !, Class = system
3600 ; '$lib_prefix'(Prefix),
3601 sub_atom(File, Len, _, _, Prefix)
3602 -> !, Class = library
3603 ; file_directory_name(File, Home),
3604 file_name_extension(_, rc, File)
3605 -> !, Class = library
3606 ).
3607'$module_class'(_, user, user).
3608
3609'$lib_prefix'('/library').
3610'$lib_prefix'('/xpce/prolog/').
3611
3612'$check_export'(Module) :-
3613 '$undefined_export'(Module, UndefList),
3614 ( '$member'(Undef, UndefList),
3615 strip_module(Undef, _, Local),
3616 print_message(error,
3617 undefined_export(Module, Local)),
3618 fail
3619 ; true
3620 ).
3621
3622
3630
3631'$import_list'(_, _, Var, _) :-
3632 var(Var),
3633 !,
3634 throw(error(instantitation_error, _)).
3635'$import_list'(Target, Source, all, Reexport) :-
3636 !,
3637 '$exported_ops'(Source, Import, Predicates),
3638 '$module_property'(Source, exports(Predicates)),
3639 '$import_all'(Import, Target, Source, Reexport, weak).
3640'$import_list'(Target, Source, except(Spec), Reexport) :-
3641 !,
3642 '$exported_ops'(Source, Export, Predicates),
3643 '$module_property'(Source, exports(Predicates)),
3644 ( is_list(Spec)
3645 -> true
3646 ; throw(error(type_error(list, Spec), _))
3647 ),
3648 '$import_except'(Spec, Source, Export, Import),
3649 '$import_all'(Import, Target, Source, Reexport, weak).
3650'$import_list'(Target, Source, Import, Reexport) :-
3651 is_list(Import),
3652 !,
3653 '$exported_ops'(Source, Ops, []),
3654 '$expand_ops'(Import, Ops, Import1),
3655 '$import_all'(Import1, Target, Source, Reexport, strong).
3656'$import_list'(_, _, Import, _) :-
3657 '$type_error'(import_specifier, Import).
3658
3659'$expand_ops'([], _, []).
3660'$expand_ops'([H|T0], Ops, Imports) :-
3661 nonvar(H), H = op(_,_,_),
3662 !,
3663 '$include'('$can_unify'(H), Ops, Ops1),
3664 '$append'(Ops1, T1, Imports),
3665 '$expand_ops'(T0, Ops, T1).
3666'$expand_ops'([H|T0], Ops, [H|T1]) :-
3667 '$expand_ops'(T0, Ops, T1).
3668
3669
3670'$import_except'([], _, List, List).
3671'$import_except'([H|T], Source, List0, List) :-
3672 '$import_except_1'(H, Source, List0, List1),
3673 '$import_except'(T, Source, List1, List).
3674
3675'$import_except_1'(Var, _, _, _) :-
3676 var(Var),
3677 !,
3678 '$instantiation_error'(Var).
3679'$import_except_1'(PI as N, _, List0, List) :-
3680 '$pi'(PI), atom(N),
3681 !,
3682 '$canonical_pi'(PI, CPI),
3683 '$import_as'(CPI, N, List0, List).
3684'$import_except_1'(op(P,A,N), _, List0, List) :-
3685 !,
3686 '$remove_ops'(List0, op(P,A,N), List).
3687'$import_except_1'(PI, Source, List0, List) :-
3688 '$pi'(PI),
3689 !,
3690 '$canonical_pi'(PI, CPI),
3691 ( '$select'(P, List0, List),
3692 '$canonical_pi'(CPI, P)
3693 -> true
3694 ; print_message(warning,
3695 error(existence_error(export, PI, module(Source)), _)),
3696 List = List0
3697 ).
3698'$import_except_1'(Except, _, _, _) :-
3699 '$type_error'(import_specifier, Except).
3700
3701'$import_as'(CPI, N, [PI2|T], [CPI as N|T]) :-
3702 '$canonical_pi'(PI2, CPI),
3703 !.
3704'$import_as'(PI, N, [H|T0], [H|T]) :-
3705 !,
3706 '$import_as'(PI, N, T0, T).
3707'$import_as'(PI, _, _, _) :-
3708 '$existence_error'(export, PI).
3709
3710'$pi'(N/A) :- atom(N), integer(A), !.
3711'$pi'(N//A) :- atom(N), integer(A).
3712
3713'$canonical_pi'(N//A0, N/A) :-
3714 A is A0 + 2.
3715'$canonical_pi'(PI, PI).
3716
3717'$remove_ops'([], _, []).
3718'$remove_ops'([Op|T0], Pattern, T) :-
3719 subsumes_term(Pattern, Op),
3720 !,
3721 '$remove_ops'(T0, Pattern, T).
3722'$remove_ops'([H|T0], Pattern, [H|T]) :-
3723 '$remove_ops'(T0, Pattern, T).
3724
3725
3732
3733'$import_all'(Import, Context, Source, Reexport, Strength) :-
3734 '$import_all2'(Import, Context, Source, Imported, ImpOps, Strength),
3735 ( Reexport == true,
3736 ( '$list_to_conj'(Imported, Conj)
3737 -> export(Context:Conj),
3738 '$ifcompiling'('$add_directive_wic'(export(Context:Conj)))
3739 ; true
3740 ),
3741 source_location(File, _Line),
3742 '$export_ops'(ImpOps, Context, File)
3743 ; true
3744 ).
3745
3747
3748'$import_all2'([], _, _, [], [], _).
3749'$import_all2'([PI as NewName|Rest], Context, Source,
3750 [NewName/Arity|Imported], ImpOps, Strength) :-
3751 !,
3752 '$canonical_pi'(PI, Name/Arity),
3753 length(Args, Arity),
3754 Head =.. [Name|Args],
3755 NewHead =.. [NewName|Args],
3756 ( '$get_predicate_attribute'(Source:Head, meta_predicate, Meta)
3757 -> Meta =.. [Name|MetaArgs],
3758 NewMeta =.. [NewName|MetaArgs],
3759 meta_predicate(Context:NewMeta)
3760 ; '$get_predicate_attribute'(Source:Head, transparent, 1)
3761 -> '$set_predicate_attribute'(Context:NewHead, transparent, true)
3762 ; true
3763 ),
3764 ( source_location(File, Line)
3765 -> E = error(_,_),
3766 catch('$store_admin_clause'((NewHead :- Source:Head),
3767 _Layout, File, File:Line),
3768 E, '$print_message'(error, E))
3769 ; assertz((NewHead :- !, Source:Head)) 3770 ), 3771 '$import_all2'(Rest, Context, Source, Imported, ImpOps, Strength).
3772'$import_all2'([op(P,A,N)|Rest], Context, Source, Imported,
3773 [op(P,A,N)|ImpOps], Strength) :-
3774 !,
3775 '$import_ops'(Context, Source, op(P,A,N)),
3776 '$import_all2'(Rest, Context, Source, Imported, ImpOps, Strength).
3777'$import_all2'([Pred|Rest], Context, Source, [Pred|Imported], ImpOps, Strength) :-
3778 Error = error(_,_),
3779 catch(Context:'$import'(Source:Pred, Strength), Error,
3780 print_message(error, Error)),
3781 '$ifcompiling'('$import_wic'(Source, Pred, Strength)),
3782 '$import_all2'(Rest, Context, Source, Imported, ImpOps, Strength).
3783
3784
3785'$list_to_conj'([One], One) :- !.
3786'$list_to_conj'([H|T], (H,Rest)) :-
3787 '$list_to_conj'(T, Rest).
3788
3793
3794'$exported_ops'(Module, Ops, Tail) :-
3795 '$c_current_predicate'(_, Module:'$exported_op'(_,_,_)),
3796 !,
3797 findall(op(P,A,N), Module:'$exported_op'(P,A,N), Ops, Tail).
3798'$exported_ops'(_, Ops, Ops).
3799
3800'$exported_op'(Module, P, A, N) :-
3801 '$c_current_predicate'(_, Module:'$exported_op'(_,_,_)),
3802 Module:'$exported_op'(P, A, N).
3803
3808
3809'$import_ops'(To, From, Pattern) :-
3810 ground(Pattern),
3811 !,
3812 Pattern = op(P,A,N),
3813 op(P,A,To:N),
3814 ( '$exported_op'(From, P, A, N)
3815 -> true
3816 ; print_message(warning, no_exported_op(From, Pattern))
3817 ).
3818'$import_ops'(To, From, Pattern) :-
3819 ( '$exported_op'(From, Pri, Assoc, Name),
3820 Pattern = op(Pri, Assoc, Name),
3821 op(Pri, Assoc, To:Name),
3822 fail
3823 ; true
3824 ).
3825
3826
3831
3832'$export_list'(Decls, Module, Ops) :-
3833 is_list(Decls),
3834 !,
3835 '$do_export_list'(Decls, Module, Ops).
3836'$export_list'(Decls, _, _) :-
3837 var(Decls),
3838 throw(error(instantiation_error, _)).
3839'$export_list'(Decls, _, _) :-
3840 throw(error(type_error(list, Decls), _)).
3841
3842'$do_export_list'([], _, []) :- !.
3843'$do_export_list'([H|T], Module, Ops) :-
3844 !,
3845 E = error(_,_),
3846 catch('$export1'(H, Module, Ops, Ops1),
3847 E, ('$print_message'(error, E), Ops = Ops1)),
3848 '$do_export_list'(T, Module, Ops1).
3849
3850'$export1'(Var, _, _, _) :-
3851 var(Var),
3852 !,
3853 throw(error(instantiation_error, _)).
3854'$export1'(Op, _, [Op|T], T) :-
3855 Op = op(_,_,_),
3856 !.
3857'$export1'(PI0, Module, Ops, Ops) :-
3858 strip_module(Module:PI0, M, PI),
3859 ( PI = (_//_)
3860 -> non_terminal(M:PI)
3861 ; true
3862 ),
3863 export(M:PI).
3864
3865'$export_ops'([op(Pri, Assoc, Name)|T], Module, File) :-
3866 E = error(_,_),
3867 catch(( '$execute_directive'(op(Pri, Assoc, Module:Name), File, []),
3868 '$export_op'(Pri, Assoc, Name, Module, File)
3869 ),
3870 E, '$print_message'(error, E)),
3871 '$export_ops'(T, Module, File).
3872'$export_ops'([], _, _).
3873
3874'$export_op'(Pri, Assoc, Name, Module, File) :-
3875 ( '$get_predicate_attribute'(Module:'$exported_op'(_,_,_), defined, 1)
3876 -> true
3877 ; '$execute_directive'(discontiguous(Module:'$exported_op'/3), File, [])
3878 ),
3879 '$store_admin_clause'('$exported_op'(Pri, Assoc, Name), _Layout, File, -).
3880
3884
3885'$execute_directive'(Var, _F, _Options) :-
3886 var(Var),
3887 '$instantiation_error'(Var).
3888'$execute_directive'(encoding(Encoding), _F, _Options) :-
3889 !,
3890 ( '$load_input'(_F, S)
3891 -> set_stream(S, encoding(Encoding))
3892 ).
3893'$execute_directive'(Goal, _, Options) :-
3894 \+ '$compilation_mode'(database),
3895 !,
3896 '$add_directive_wic2'(Goal, Type, Options),
3897 ( Type == call 3898 -> '$compilation_mode'(Old, database),
3899 setup_call_cleanup(
3900 '$directive_mode'(OldDir, Old),
3901 '$execute_directive_3'(Goal),
3902 ( '$set_compilation_mode'(Old),
3903 '$set_directive_mode'(OldDir)
3904 ))
3905 ; '$execute_directive_3'(Goal)
3906 ).
3907'$execute_directive'(Goal, _, _Options) :-
3908 '$execute_directive_3'(Goal).
3909
3910'$execute_directive_3'(Goal) :-
3911 '$current_source_module'(Module),
3912 '$valid_directive'(Module:Goal),
3913 !,
3914 ( '$pattr_directive'(Goal, Module)
3915 -> true
3916 ; Term = error(_,_),
3917 catch(Module:Goal, Term, '$exception_in_directive'(Term))
3918 -> true
3919 ; '$print_message'(warning, goal_failed(directive, Module:Goal)),
3920 fail
3921 ).
3922'$execute_directive_3'(_).
3923
3924
3930
3931:- multifile prolog:sandbox_allowed_directive/1. 3932:- multifile prolog:sandbox_allowed_clause/1. 3933:- meta_predicate '$valid_directive'(:). 3934
3935'$valid_directive'(_) :-
3936 current_prolog_flag(sandboxed_load, false),
3937 !.
3938'$valid_directive'(Goal) :-
3939 Error = error(Formal, _),
3940 catch(prolog:sandbox_allowed_directive(Goal), Error, true),
3941 !,
3942 ( var(Formal)
3943 -> true
3944 ; print_message(error, Error),
3945 fail
3946 ).
3947'$valid_directive'(Goal) :-
3948 print_message(error,
3949 error(permission_error(execute,
3950 sandboxed_directive,
3951 Goal), _)),
3952 fail.
3953
3954'$exception_in_directive'(Term) :-
3955 '$print_message'(error, Term),
3956 fail.
3957
3963
3964'$add_directive_wic2'(Goal, Type, Options) :-
3965 '$common_goal_type'(Goal, Type, Options),
3966 !,
3967 ( Type == load
3968 -> true
3969 ; '$current_source_module'(Module),
3970 '$add_directive_wic'(Module:Goal)
3971 ).
3972'$add_directive_wic2'(Goal, _, _) :-
3973 ( '$compilation_mode'(qlf) 3974 -> true
3975 ; print_message(error, mixed_directive(Goal))
3976 ).
3977
3982
3983'$common_goal_type'((A,B), Type, Options) :-
3984 !,
3985 '$common_goal_type'(A, Type, Options),
3986 '$common_goal_type'(B, Type, Options).
3987'$common_goal_type'((A;B), Type, Options) :-
3988 !,
3989 '$common_goal_type'(A, Type, Options),
3990 '$common_goal_type'(B, Type, Options).
3991'$common_goal_type'((A->B), Type, Options) :-
3992 !,
3993 '$common_goal_type'(A, Type, Options),
3994 '$common_goal_type'(B, Type, Options).
3995'$common_goal_type'(Goal, Type, Options) :-
3996 '$goal_type'(Goal, Type, Options).
3997
3998'$goal_type'(Goal, Type, Options) :-
3999 ( '$load_goal'(Goal, Options)
4000 -> Type = load
4001 ; Type = call
4002 ).
4003
4004:- thread_local
4005 '$qlf':qinclude/1. 4006
4007'$load_goal'([_|_], _).
4008'$load_goal'(consult(_), _).
4009'$load_goal'(load_files(_), _).
4010'$load_goal'(load_files(_,Options), _) :-
4011 '$option'(qcompile(QlfMode), Options),
4012 '$qlf_part_mode'(QlfMode).
4013'$load_goal'(ensure_loaded(_), _) :- '$compilation_mode'(wic).
4014'$load_goal'(use_module(_), _) :- '$compilation_mode'(wic).
4015'$load_goal'(use_module(_, _), _) :- '$compilation_mode'(wic).
4016'$load_goal'(reexport(_), _) :- '$compilation_mode'(wic).
4017'$load_goal'(reexport(_, _), _) :- '$compilation_mode'(wic).
4018'$load_goal'(Goal, _Options) :-
4019 '$qlf':qinclude(user),
4020 '$load_goal_file'(Goal, File),
4021 '$all_user_files'(File).
4022
4023
4024'$load_goal_file'(load_files(F), F).
4025'$load_goal_file'(load_files(F, _), F).
4026'$load_goal_file'(ensure_loaded(F), F).
4027'$load_goal_file'(use_module(F), F).
4028'$load_goal_file'(use_module(F, _), F).
4029'$load_goal_file'(reexport(F), F).
4030'$load_goal_file'(reexport(F, _), F).
4031
4032'$all_user_files'([]) :-
4033 !.
4034'$all_user_files'([H|T]) :-
4035 !,
4036 '$is_user_file'(H),
4037 '$all_user_files'(T).
4038'$all_user_files'(F) :-
4039 ground(F),
4040 '$is_user_file'(F).
4041
4042'$is_user_file'(File) :-
4043 absolute_file_name(File, Path,
4044 [ file_type(prolog),
4045 access(read)
4046 ]),
4047 '$module_class'(Path, user, _).
4048
4049'$qlf_part_mode'(part).
4050'$qlf_part_mode'(true). 4051
4052
4053 4056
4062
4063'$store_admin_clause'(Clause, Layout, Owner, SrcLoc) :-
4064 '$compilation_mode'(Mode),
4065 '$store_admin_clause'(Clause, Layout, Owner, SrcLoc, Mode).
4066
4067'$store_admin_clause'(Clause, Layout, Owner, SrcLoc, Mode) :-
4068 Owner \== (-),
4069 !,
4070 setup_call_cleanup(
4071 '$start_aux'(Owner, Context),
4072 '$store_admin_clause2'(Clause, Layout, Owner, SrcLoc, Mode),
4073 '$end_aux'(Owner, Context)).
4074'$store_admin_clause'(Clause, Layout, File, SrcLoc, Mode) :-
4075 '$store_admin_clause2'(Clause, Layout, File, SrcLoc, Mode).
4076
4077:- public '$store_admin_clause2'/4. 4078'$store_admin_clause2'(Clause, _Layout, File, SrcLoc) :-
4079 '$compilation_mode'(Mode),
4080 '$store_admin_clause2'(Clause, _Layout, File, SrcLoc, Mode).
4081
4082'$store_admin_clause2'(Clause, _Layout, File, SrcLoc, Mode) :-
4083 ( Mode == database
4084 -> '$record_clause'(Clause, File, SrcLoc)
4085 ; '$record_clause'(Clause, File, SrcLoc, Ref),
4086 '$qlf_assert_clause'(Ref, development)
4087 ).
4088
4096
4097'$store_clause'((_, _), _, _, _) :-
4098 !,
4099 print_message(error, cannot_redefine_comma),
4100 fail.
4101'$store_clause'((Pre => Body), _Layout, File, SrcLoc) :-
4102 nonvar(Pre),
4103 Pre = (Head,Cond),
4104 !,
4105 ( '$is_true'(Cond), current_prolog_flag(optimise, true)
4106 -> '$store_clause'((Head=>Body), _Layout, File, SrcLoc)
4107 ; '$store_clause'(?=>(Head,(Cond,!,Body)), _Layout, File, SrcLoc)
4108 ).
4109'$store_clause'(Clause, _Layout, File, SrcLoc) :-
4110 '$valid_clause'(Clause),
4111 !,
4112 ( '$compilation_mode'(database)
4113 -> '$record_clause'(Clause, File, SrcLoc)
4114 ; '$record_clause'(Clause, File, SrcLoc, Ref),
4115 '$qlf_assert_clause'(Ref, development)
4116 ).
4117
4118'$is_true'(true) => true.
4119'$is_true'((A,B)) => '$is_true'(A), '$is_true'(B).
4120'$is_true'(_) => fail.
4121
4122'$valid_clause'(_) :-
4123 current_prolog_flag(sandboxed_load, false),
4124 !.
4125'$valid_clause'(Clause) :-
4126 \+ '$cross_module_clause'(Clause),
4127 !.
4128'$valid_clause'(Clause) :-
4129 Error = error(Formal, _),
4130 catch(prolog:sandbox_allowed_clause(Clause), Error, true),
4131 !,
4132 ( var(Formal)
4133 -> true
4134 ; print_message(error, Error),
4135 fail
4136 ).
4137'$valid_clause'(Clause) :-
4138 print_message(error,
4139 error(permission_error(assert,
4140 sandboxed_clause,
4141 Clause), _)),
4142 fail.
4143
4144'$cross_module_clause'(Clause) :-
4145 '$head_module'(Clause, Module),
4146 \+ '$current_source_module'(Module).
4147
4148'$head_module'(Var, _) :-
4149 var(Var), !, fail.
4150'$head_module'((Head :- _), Module) :-
4151 '$head_module'(Head, Module).
4152'$head_module'(Module:_, Module).
4153
4154'$clause_source'('$source_location'(File,Line):Clause, Clause, File:Line) :- !.
4155'$clause_source'(Clause, Clause, -).
4156
4161
4162:- public
4163 '$store_clause'/2. 4164
4165'$store_clause'(Term, Id) :-
4166 '$clause_source'(Term, Clause, SrcLoc),
4167 '$store_clause'(Clause, _, Id, SrcLoc).
4168
4191
4192compile_aux_clauses(_Clauses) :-
4193 current_prolog_flag(xref, true),
4194 !.
4195compile_aux_clauses(Clauses) :-
4196 source_location(File, Line),
4197 prolog_load_context(source, Owner),
4198 '$compile_aux_clauses'(Clauses, Owner, File:Line).
4199
4200'$compile_aux_clauses'(Clauses, Owner, SrcLoc) :-
4201 setup_call_cleanup(
4202 '$start_aux'(Owner, Context),
4203 '$store_aux_clauses'(Clauses, Owner, SrcLoc),
4204 '$end_aux'(Owner, Context)).
4205
4206'$store_aux_clauses'(Clauses, Owner, SrcLoc) :-
4207 is_list(Clauses),
4208 !,
4209 forall('$member'(C,Clauses),
4210 '$compile_term'(C, _Layout, Owner, SrcLoc, [])).
4211'$store_aux_clauses'(Clause, Owner, SrcLoc) :-
4212 '$compile_term'(Clause, _Layout, Owner, SrcLoc, []).
4213
4214
4215 4218
4226
4227'$stage_file'(Target, Stage) :-
4228 file_directory_name(Target, Dir),
4229 file_base_name(Target, File),
4230 current_prolog_flag(pid, Pid),
4231 format(atom(Stage), '~w/.~w.~d', [Dir,File,Pid]).
4232
4233'$install_staged_file'(exit, Staged, Target, error) :-
4234 !,
4235 win_rename_file(Staged, Target).
4236'$install_staged_file'(exit, Staged, Target, OnError) :-
4237 !,
4238 InstallError = error(_,_),
4239 catch(win_rename_file(Staged, Target),
4240 InstallError,
4241 '$install_staged_error'(OnError, InstallError, Staged, Target)).
4242'$install_staged_file'(_, Staged, _, _OnError) :-
4243 E = error(_,_),
4244 catch(delete_file(Staged), E, true).
4245
4246'$install_staged_error'(OnError, Error, Staged, _Target) :-
4247 E = error(_,_),
4248 catch(delete_file(Staged), E, true),
4249 ( OnError = silent
4250 -> true
4251 ; OnError = fail
4252 -> fail
4253 ; print_message(warning, Error)
4254 ).
4255
4260
4261:- if(current_prolog_flag(windows, true)). 4262win_rename_file(From, To) :-
4263 between(1, 10, _),
4264 catch(rename_file(From, To), error(permission_error(rename, file, _),_), (sleep(0.1),fail)),
4265 !.
4266:- endif. 4267win_rename_file(From, To) :-
4268 rename_file(From, To).
4269
4270
4271 4274
4275:- multifile
4276 prolog:comment_hook/4. 4277
4278
4279 4282
4286
4287:- dynamic
4288 '$foreign_registered'/2. 4289
4290 4293
4296
4297:- dynamic
4298 '$expand_goal'/2,
4299 '$expand_term'/4. 4300
4301'$expand_goal'(In, In).
4302'$expand_term'(In, Layout, In, Layout).
4303
4304
4305 4308
4309'$type_error'(Type, Value) :-
4310 ( var(Value)
4311 -> throw(error(instantiation_error, _))
4312 ; throw(error(type_error(Type, Value), _))
4313 ).
4314
4315'$domain_error'(Type, Value) :-
4316 throw(error(domain_error(Type, Value), _)).
4317
4318'$existence_error'(Type, Object) :-
4319 throw(error(existence_error(Type, Object), _)).
4320
4321'$existence_error'(Type, Object, In) :-
4322 throw(error(existence_error(Type, Object, In), _)).
4323
4324'$permission_error'(Action, Type, Term) :-
4325 throw(error(permission_error(Action, Type, Term), _)).
4326
4327'$instantiation_error'(_Var) :-
4328 throw(error(instantiation_error, _)).
4329
4330'$uninstantiation_error'(NonVar) :-
4331 throw(error(uninstantiation_error(NonVar), _)).
4332
4333'$must_be'(list, X) :- !,
4334 '$skip_list'(_, X, Tail),
4335 ( Tail == []
4336 -> true
4337 ; '$type_error'(list, Tail)
4338 ).
4339'$must_be'(options, X) :- !,
4340 ( '$is_options'(X)
4341 -> true
4342 ; '$type_error'(options, X)
4343 ).
4344'$must_be'(atom, X) :- !,
4345 ( atom(X)
4346 -> true
4347 ; '$type_error'(atom, X)
4348 ).
4349'$must_be'(integer, X) :- !,
4350 ( integer(X)
4351 -> true
4352 ; '$type_error'(integer, X)
4353 ).
4354'$must_be'(between(Low,High), X) :- !,
4355 ( integer(X)
4356 -> ( between(Low, High, X)
4357 -> true
4358 ; '$domain_error'(between(Low,High), X)
4359 )
4360 ; '$type_error'(integer, X)
4361 ).
4362'$must_be'(callable, X) :- !,
4363 ( callable(X)
4364 -> true
4365 ; '$type_error'(callable, X)
4366 ).
4367'$must_be'(acyclic, X) :- !,
4368 ( acyclic_term(X)
4369 -> true
4370 ; '$domain_error'(acyclic_term, X)
4371 ).
4372'$must_be'(oneof(Type, Domain, List), X) :- !,
4373 '$must_be'(Type, X),
4374 ( memberchk(X, List)
4375 -> true
4376 ; '$domain_error'(Domain, X)
4377 ).
4378'$must_be'(boolean, X) :- !,
4379 ( (X == true ; X == false)
4380 -> true
4381 ; '$type_error'(boolean, X)
4382 ).
4383'$must_be'(ground, X) :- !,
4384 ( ground(X)
4385 -> true
4386 ; '$instantiation_error'(X)
4387 ).
4388'$must_be'(filespec, X) :- !,
4389 ( ( atom(X)
4390 ; string(X)
4391 ; compound(X),
4392 compound_name_arity(X, _, 1)
4393 )
4394 -> true
4395 ; '$type_error'(filespec, X)
4396 ).
4397
4400
4401
4402 4405
4406'$member'(El, [H|T]) :-
4407 '$member_'(T, El, H).
4408
4409'$member_'(_, El, El).
4410'$member_'([H|T], El, _) :-
4411 '$member_'(T, El, H).
4412
4413'$append'([], L, L).
4414'$append'([H|T], L, [H|R]) :-
4415 '$append'(T, L, R).
4416
4417'$append'(ListOfLists, List) :-
4418 '$must_be'(list, ListOfLists),
4419 '$append_'(ListOfLists, List).
4420
4421'$append_'([], []).
4422'$append_'([L|Ls], As) :-
4423 '$append'(L, Ws, As),
4424 '$append_'(Ls, Ws).
4425
4426'$select'(X, [X|Tail], Tail).
4427'$select'(Elem, [Head|Tail], [Head|Rest]) :-
4428 '$select'(Elem, Tail, Rest).
4429
4430'$reverse'(L1, L2) :-
4431 '$reverse'(L1, [], L2).
4432
4433'$reverse'([], List, List).
4434'$reverse'([Head|List1], List2, List3) :-
4435 '$reverse'(List1, [Head|List2], List3).
4436
4437'$delete'([], _, []) :- !.
4438'$delete'([Elem|Tail], Elem, Result) :-
4439 !,
4440 '$delete'(Tail, Elem, Result).
4441'$delete'([Head|Tail], Elem, [Head|Rest]) :-
4442 '$delete'(Tail, Elem, Rest).
4443
4444'$last'([H|T], Last) :-
4445 '$last'(T, H, Last).
4446
4447'$last'([], Last, Last).
4448'$last'([H|T], _, Last) :-
4449 '$last'(T, H, Last).
4450
4451:- meta_predicate '$include'(1,+,-). 4452'$include'(_, [], []).
4453'$include'(G, [H|T0], L) :-
4454 ( call(G,H)
4455 -> L = [H|T]
4456 ; T = L
4457 ),
4458 '$include'(G, T0, T).
4459
4460'$can_unify'(A, B) :-
4461 \+ A \= B.
4462
4466
4467:- '$iso'((length/2)). 4468
4469length(List, Length) :-
4470 var(Length),
4471 !,
4472 '$skip_list'(Length0, List, Tail),
4473 ( Tail == []
4474 -> Length = Length0 4475 ; var(Tail)
4476 -> Tail \== Length, 4477 '$length3'(Tail, Length, Length0) 4478 ; throw(error(type_error(list, List),
4479 context(length/2, _)))
4480 ).
4481length(List, Length) :-
4482 integer(Length),
4483 Length >= 0,
4484 !,
4485 '$skip_list'(Length0, List, Tail),
4486 ( Tail == [] 4487 -> Length = Length0
4488 ; var(Tail)
4489 -> Extra is Length-Length0,
4490 '$length'(Tail, Extra)
4491 ; throw(error(type_error(list, List),
4492 context(length/2, _)))
4493 ).
4494length(_, Length) :-
4495 integer(Length),
4496 !,
4497 throw(error(domain_error(not_less_than_zero, Length),
4498 context(length/2, _))).
4499length(_, Length) :-
4500 throw(error(type_error(integer, Length),
4501 context(length/2, _))).
4502
4503'$length3'([], N, N).
4504'$length3'([_|List], N, N0) :-
4505 N1 is N0+1,
4506 '$length3'(List, N, N1).
4507
4508
4509 4512
4516
4517'$is_options'(Map) :-
4518 is_dict(Map, _),
4519 !.
4520'$is_options'(List) :-
4521 is_list(List),
4522 ( List == []
4523 -> true
4524 ; List = [H|_],
4525 '$is_option'(H, _, _)
4526 ).
4527
4528'$is_option'(Var, _, _) :-
4529 var(Var), !, fail.
4530'$is_option'(F, Name, Value) :-
4531 functor(F, _, 1),
4532 !,
4533 F =.. [Name,Value].
4534'$is_option'(Name=Value, Name, Value).
4535
4537
4538'$option'(Opt, Options) :-
4539 is_dict(Options),
4540 !,
4541 [Opt] :< Options.
4542'$option'(Opt, Options) :-
4543 memberchk(Opt, Options).
4544
4546
4547'$option'(Term, Options, Default) :-
4548 arg(1, Term, Value),
4549 functor(Term, Name, 1),
4550 ( is_dict(Options)
4551 -> ( get_dict(Name, Options, GVal)
4552 -> Value = GVal
4553 ; Value = Default
4554 )
4555 ; functor(Gen, Name, 1),
4556 arg(1, Gen, GVal),
4557 ( memberchk(Gen, Options)
4558 -> Value = GVal
4559 ; Value = Default
4560 )
4561 ).
4562
4568
4569'$select_option'(Opt, Options, Rest) :-
4570 '$options_dict'(Options, Dict),
4571 select_dict([Opt], Dict, Rest).
4572
4578
4579'$merge_options'(New, Old, Merged) :-
4580 '$options_dict'(New, NewDict),
4581 '$options_dict'(Old, OldDict),
4582 put_dict(NewDict, OldDict, Merged).
4583
4588
4589'$options_dict'(Options, Dict) :-
4590 is_list(Options),
4591 !,
4592 '$keyed_options'(Options, Keyed),
4593 sort(1, @<, Keyed, UniqueKeyed),
4594 '$pairs_values'(UniqueKeyed, Unique),
4595 dict_create(Dict, _, Unique).
4596'$options_dict'(Dict, Dict) :-
4597 is_dict(Dict),
4598 !.
4599'$options_dict'(Options, _) :-
4600 '$domain_error'(options, Options).
4601
4602'$keyed_options'([], []).
4603'$keyed_options'([H0|T0], [H|T]) :-
4604 '$keyed_option'(H0, H),
4605 '$keyed_options'(T0, T).
4606
4607'$keyed_option'(Var, _) :-
4608 var(Var),
4609 !,
4610 '$instantiation_error'(Var).
4611'$keyed_option'(Name=Value, Name-(Name-Value)).
4612'$keyed_option'(NameValue, Name-(Name-Value)) :-
4613 compound_name_arguments(NameValue, Name, [Value]),
4614 !.
4615'$keyed_option'(Opt, _) :-
4616 '$domain_error'(option, Opt).
4617
4618
4619 4622
4623:- public '$prolog_list_goal'/1. 4624
4625:- multifile
4626 user:prolog_list_goal/1. 4627
4628'$prolog_list_goal'(Goal) :-
4629 user:prolog_list_goal(Goal),
4630 !.
4631'$prolog_list_goal'(Goal) :-
4632 use_module(library(listing), [listing/1]),
4633 @(listing(Goal), user).
4634
4635
4636 4639
4640:- '$iso'((halt/0)). 4641
4642halt :-
4643 '$exit_code'(Code),
4644 ( Code == 0
4645 -> true
4646 ; print_message(warning, on_error(halt(1)))
4647 ),
4648 halt(Code).
4649
4654
4655'$exit_code'(Code) :-
4656 ( ( current_prolog_flag(on_error, status),
4657 statistics(errors, Count),
4658 Count > 0
4659 ; current_prolog_flag(on_warning, status),
4660 statistics(warnings, Count),
4661 Count > 0
4662 )
4663 -> Code = 1
4664 ; Code = 0
4665 ).
4666
4667
4673
4674:- meta_predicate at_halt(0). 4675:- dynamic system:term_expansion/2, '$at_halt'/2. 4676:- multifile system:term_expansion/2, '$at_halt'/2. 4677
4678system:term_expansion((:- at_halt(Goal)),
4679 system:'$at_halt'(Module:Goal, File:Line)) :-
4680 \+ current_prolog_flag(xref, true),
4681 source_location(File, Line),
4682 '$current_source_module'(Module).
4683
4684at_halt(Goal) :-
4685 asserta('$at_halt'(Goal, (-):0)).
4686
4687:- public '$run_at_halt'/0. 4688
4689'$run_at_halt' :-
4690 forall(clause('$at_halt'(Goal, Src), true, Ref),
4691 ( '$call_at_halt'(Goal, Src),
4692 erase(Ref)
4693 )).
4694
4695'$call_at_halt'(Goal, _Src) :-
4696 catch(Goal, E, true),
4697 !,
4698 ( var(E)
4699 -> true
4700 ; subsumes_term(cancel_halt(_), E)
4701 -> '$print_message'(informational, E),
4702 fail
4703 ; '$print_message'(error, E)
4704 ).
4705'$call_at_halt'(Goal, _Src) :-
4706 '$print_message'(warning, goal_failed(at_halt, Goal)).
4707
4713
4714cancel_halt(Reason) :-
4715 throw(cancel_halt(Reason)).
4716
4721
4722:- multifile prolog:heartbeat/0. 4723
4724
4725 4728
4736
4737:- public '$install_unicode_normalize_hook'/0. 4738
4739'$install_unicode_normalize_hook' :-
4740 use_module(library(unicode), []).
4741
4742
4743 4746
4747:- meta_predicate
4748 '$load_wic_files'(:). 4749
4750'$load_wic_files'(Files) :-
4751 Files = Module:_,
4752 '$execute_directive'('$set_source_module'(OldM, Module), [], []),
4753 '$save_lex_state'(LexState, []),
4754 '$style_check'(_, 0xC7), 4755 '$compilation_mode'(OldC, wic),
4756 consult(Files),
4757 '$execute_directive'('$set_source_module'(OldM), [], []),
4758 '$execute_directive'('$restore_lex_state'(LexState), [], []),
4759 '$set_compilation_mode'(OldC).
4760
4761
4766
4767:- public '$load_additional_boot_files'/0. 4768
4769'$load_additional_boot_files' :-
4770 current_prolog_flag(argv, Argv),
4771 '$get_files_argv'(Argv, Files),
4772 ( Files \== []
4773 -> format('Loading additional boot files~n'),
4774 '$load_wic_files'(user:Files),
4775 format('additional boot files loaded~n')
4776 ; true
4777 ).
4778
4779'$get_files_argv'([], []) :- !.
4780'$get_files_argv'(['-c'|Files], Files) :- !.
4781'$get_files_argv'([_|Rest], Files) :-
4782 '$get_files_argv'(Rest, Files).
4783
4784'$:-'(('$boot_message'('Loading Prolog startup files~n', []),
4785 source_location(File, _Line),
4786 file_directory_name(File, Dir),
4787 atom_concat(Dir, '/load.pl', LoadFile),
4788 '$load_wic_files'(system:[LoadFile]),
4789 '$boot_message'('SWI-Prolog boot files loaded~n', []),
4790 '$compilation_mode'(OldC, wic),
4791 '$execute_directive'('$set_source_module'(user), [], []),
4792 '$set_compilation_mode'(OldC)
4793 ))