1/* Part of SWI-Prolog 2 3 Author: Jan Wielemaker 4 E-mail: J.Wielemaker@vu.nl 5 WWW: http://www.swi-prolog.org/projects/xpce/ 6 Copyright (c) 2006-2025, University of Amsterdam 7 VU University Amsterdam 8 CWI, Amsterdam 9 SWI-Prolog Solutions b.v. 10 All rights reserved. 11 12 Redistribution and use in source and binary forms, with or without 13 modification, are permitted provided that the following conditions 14 are met: 15 16 1. Redistributions of source code must retain the above copyright 17 notice, this list of conditions and the following disclaimer. 18 19 2. Redistributions in binary form must reproduce the above copyright 20 notice, this list of conditions and the following disclaimer in 21 the documentation and/or other materials provided with the 22 distribution. 23 24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 29 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 30 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 34 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 POSSIBILITY OF SUCH DAMAGE. 36*/ 37 38:- module(prolog_xref, 39 [ xref_source/1, % +Source 40 xref_source/2, % +Source, +Options 41 xref_called/3, % ?Source, ?Callable, ?By 42 xref_called/4, % ?Source, ?Callable, ?By, ?Cond 43 xref_called/5, % ?Source, ?Callable, ?By, ?Cond, ?Line 44 xref_defined/3, % ?Source. ?Callable, -How 45 xref_definition_line/2, % +How, -Line 46 xref_exported/2, % ?Source, ?Callable 47 xref_module/2, % ?Source, ?Module 48 xref_uses_file/3, % ?Source, ?Spec, ?Path 49 xref_op/2, % ?Source, ?Op 50 xref_prolog_flag/4, % ?Source, ?Flag, ?Value, ?Line 51 xref_comment/3, % ?Source, ?Title, ?Comment 52 xref_comment/4, % ?Source, ?Head, ?Summary, ?Comment 53 xref_mode/3, % ?Source, ?Mode, ?Det 54 xref_option/2, % ?Source, ?Option 55 xref_clean/1, % +Source 56 xref_current_source/1, % ?Source 57 xref_done/2, % +Source, -When 58 xref_built_in/1, % ?Callable 59 xref_source_file/3, % +Spec, -Path, +Source 60 xref_source_file/4, % +Spec, -Path, +Source, +Options 61 xref_public_list/3, % +File, +Src, +Options 62 xref_public_list/4, % +File, -Path, -Export, +Src 63 xref_public_list/6, % +File, -Path, -Module, -Export, -Meta, +Src 64 xref_public_list/7, % +File, -Path, -Module, -Export, -Public, -Meta, +Src 65 xref_meta/3, % +Source, +Goal, -Called 66 xref_meta/2, % +Goal, -Called 67 xref_hook/1, % ?Callable 68 % XPCE class references 69 xref_used_class/2, % ?Source, ?ClassName 70 xref_defined_class/3 % ?Source, ?ClassName, -How 71 ]). 72:- autoload(library(apply),[maplist/2,partition/4,maplist/3]). 73:- use_module(library(debug),[debug/3]). 74:- autoload(library(dialect),[expects_dialect/1]). 75:- autoload(library(error),[must_be/2,instantiation_error/1]). 76:- autoload(library(lists),[member/2,append/2,append/3,select/3]). 77:- autoload(library(operators),[push_op/3]). 78:- autoload(library(option),[option/2,option/3]). 79:- autoload(library(ordsets),[ord_intersect/2,ord_intersection/3]). 80:- autoload(library(prolog_code), [pi_head/2]). 81:- autoload(library(prolog_source), 82 [ prolog_canonical_source/2, 83 prolog_open_source/2, 84 prolog_close_source/1, 85 prolog_read_source_term/4, 86 prolog_file_directives/3 87 ]). 88 89:- if(exists_source(library(shlib))). 90:- autoload(library(shlib),[current_foreign_library/2]). 91:- endif. 92:- autoload(library(solution_sequences),[distinct/2,limit/2]). 93 94:- if(exists_source(library(pldoc))). 95:- use_module(library(pldoc), []). % Must be loaded before doc_process 96:- use_module(library(pldoc/doc_process)). 97 98:- endif. 99 100:- predicate_options(xref_source/2, 2, 101 [ silent(boolean), 102 module(atom), 103 register_called(oneof([all,non_iso,non_built_in])), 104 comments(oneof([store,collect,ignore])), 105 process_include(boolean), 106 stream(stream) 107 ]). 108 109 110:- dynamic 111 called/5, % Head, Src, From, Cond, Line 112 (dynamic)/3, % Head, Src, Line 113 (thread_local)/3, % Head, Src, Line 114 (multifile)/3, % Head, Src, Line 115 (public)/3, % Head, Src, Line 116 (declared)/4, % Head, How, Src, Line 117 defined/3, % Head, Src, Line 118 meta_goal/3, % Head, Called, Src 119 foreign/3, % Head, Src, Line 120 constraint/3, % Head, Src, Line 121 imported/3, % Head, Src, From 122 exported/2, % Head, Src 123 xmodule/2, % Module, Src 124 uses_file/3, % Spec, Src, Path 125 xop/2, % Src, Op 126 source/2, % Src, Time 127 used_class/2, % Name, Src 128 defined_class/5, % Name, Super, Summary, Src, Line 129 (mode)/2, % Mode, Src 130 xoption/2, % Src, Option 131 xflag/4, % Name, Value, Src, Line 132 grammar_rule/2, % Head, Src 133 module_comment/3, % Src, Title, Comment 134 pred_comment/4, % Head, Src, Summary, Comment 135 pred_comment_link/3, % Head, Src, HeadTo 136 pred_mode/3. % Head, Src, Det 137 138:- create_prolog_flag(xref, false, [type(boolean)]).
175:- predicate_options(xref_source_file/4, 4, 176 [ file_type(oneof([txt,prolog,directory])), 177 silent(boolean) 178 ]). 179:- predicate_options(xref_public_list/3, 3, 180 [ path(-atom), 181 module(-atom), 182 exports(-list(any)), 183 public(-list(any)), 184 meta(-list(any)), 185 silent(boolean) 186 ]). 187 188 189 /******************************* 190 * HOOKS * 191 *******************************/
218:- multifile 219 prolog:called_by/4, % +Goal, +Module, +Context, -Called 220 prolog:called_by/2, % +Goal, -Called 221 prolog:meta_goal/2, % +Goal, -Pattern 222 prolog:hook/1, % +Callable 223 prolog:generated_predicate/1, % :PI 224 prolog:no_autoload_module/1, % Module is not suitable for autoloading. 225 prolog:xref_source_time/2. % +Source, =Modified 226 227:- meta_predicate 228 prolog:generated_predicate(). 229 230:- meta_predicate 231 process_predicates(, , ). 232 233 /******************************* 234 * BUILT-INS * 235 *******************************/
register_called.243hide_called(Callable, Src) :- 244 xoption(Src, register_called(Which)), 245 !, 246 mode_hide_called(Which, Callable). 247hide_called(Callable, _) :- 248 mode_hide_called(non_built_in, Callable). 249 250mode_hide_called(all, _) :- !, fail. 251mode_hide_called(non_iso, _:Goal) :- 252 goal_name_arity(Goal, Name, Arity), 253 current_predicate(system:Name/Arity), 254 predicate_property(system:Goal, iso). 255mode_hide_called(non_built_in, _:Goal) :- 256 goal_name_arity(Goal, Name, Arity), 257 current_predicate(system:Name/Arity), 258 predicate_property(system:Goal, built_in). 259mode_hide_called(non_built_in, M:Goal) :- 260 goal_name_arity(Goal, Name, Arity), 261 current_predicate(M:Name/Arity), 262 predicate_property(M:Goal, built_in).
268system_predicate(Goal) :- 269 goal_name_arity(Goal, Name, Arity), 270 current_predicate(system:Name/Arity), % avoid autoloading 271 predicate_property(system:Goal, built_in), 272 !. 273 274 275 /******************************** 276 * TOPLEVEL * 277 ********************************/ 278 279verbose(Src) :- 280 \+ xoption(Src, silent(true)). 281 282:- thread_local 283 xref_input/2. % File, Stream
true (default false), emit warning messages.all, non_iso or non_built_in (default).store, comments are stored into the
database as if the file was compiled. If collect, comments are
entered to the xref database and made available through
xref_mode/2 and xref_comment/4. If ignore, comments are simply
ignored. Default is to collect comments.true).313xref_source(Source) :- 314 xref_source(Source, []). 315 316xref_source(Source, Options) :- 317 prolog_canonical_source(Source, Src), 318 ( last_modified(Source, Modified) 319 -> ( source(Src, Modified) 320 -> true 321 ; xref_clean(Src), 322 assert(source(Src, Modified)), 323 do_xref(Src, Options) 324 ) 325 ; xref_clean(Src), 326 get_time(Now), 327 assert(source(Src, Now)), 328 do_xref(Src, Options) 329 ). 330 331do_xref(Src, Options) :- 332 must_be(list, Options), 333 setup_call_cleanup( 334 xref_setup(Src, In, Options, State), 335 collect(Src, Src, In, Options), 336 xref_cleanup(State)). 337 338last_modified(Source, Modified) :- 339 prolog:xref_source_time(Source, Modified), 340 !. 341last_modified(Source, Modified) :- 342 atom(Source), 343 \+ is_global_url(Source), 344 exists_file(Source), 345 time_file(Source, Modified). 346 347is_global_url(File) :- 348 sub_atom(File, B, _, _, '://'), 349 !, 350 B > 1, 351 sub_atom(File, 0, B, _, Scheme), 352 atom_codes(Scheme, Codes), 353 maplist(between(0'a, 0'z), Codes). 354 355xref_setup(Src, In, Options, state(CleanIn, Dialect, Xref, [SRef|HRefs])) :- 356 maplist(assert_option(Src), Options), 357 assert_default_options(Src), 358 current_prolog_flag(emulated_dialect, Dialect), 359 ( option(stream(Stream), Options) 360 -> In = Stream, 361 CleanIn = true 362 ; prolog_open_source(Src, In), 363 CleanIn = prolog_close_source(In) 364 ), 365 set_initial_mode(In, Options), 366 asserta(xref_input(Src, In), SRef), 367 set_xref(Xref), 368 ( verbose(Src) 369 -> HRefs = [] 370 ; asserta((user:thread_message_hook(_,Level,_) :- 371 hide_message(Level)), 372 Ref), 373 HRefs = [Ref] 374 ). 375 376hide_message(warning). 377hide_message(error). 378hide_message(informational). 379 380assert_option(_, Var) :- 381 var(Var), 382 !, 383 instantiation_error(Var). 384assert_option(Src, silent(Boolean)) :- 385 !, 386 must_be(boolean, Boolean), 387 assert(xoption(Src, silent(Boolean))). 388assert_option(Src, register_called(Which)) :- 389 !, 390 must_be(oneof([all,non_iso,non_built_in]), Which), 391 assert(xoption(Src, register_called(Which))). 392assert_option(Src, comments(CommentHandling)) :- 393 !, 394 must_be(oneof([store,collect,ignore]), CommentHandling), 395 assert(xoption(Src, comments(CommentHandling))). 396assert_option(Src, module(Module)) :- 397 !, 398 must_be(atom, Module), 399 assert(xoption(Src, module(Module))). 400assert_option(Src, process_include(Boolean)) :- 401 !, 402 must_be(boolean, Boolean), 403 assert(xoption(Src, process_include(Boolean))). 404assert_option(_, _). 405 406assert_default_options(Src) :- 407 ( xref_option_default(Opt), 408 generalise_term(Opt, Gen), 409 ( xoption(Src, Gen) 410 -> true 411 ; assertz(xoption(Src, Opt)) 412 ), 413 fail 414 ; true 415 ). 416 417xref_option_default(silent(false)). 418xref_option_default(register_called(non_built_in)). 419xref_option_default(comments(collect)). 420xref_option_default(process_include(true)).
426xref_cleanup(state(CleanIn, Dialect, Xref, Refs)) :- 427 call(CleanIn), 428 set_prolog_flag(emulated_dialect, Dialect), 429 set_prolog_flag(xref, Xref), 430 maplist(erase, Refs). 431 432set_xref(Xref) :- 433 current_prolog_flag(xref, Xref), 434 set_prolog_flag(xref, true). 435 436:- meta_predicate 437 with_xref(). 438 439with_xref(Goal) :- 440 setup_call_cleanup( 441 push_prolog_flag(xref, true), 442 Goal, 443 pop_prolog_flag(xref)).
453set_initial_mode(_Stream, Options) :- 454 option(module(Module), Options), 455 !, 456 '$set_source_module'(Module). 457set_initial_mode(Stream, _) :- 458 stream_property(Stream, file_name(Path)), 459 source_file_property(Path, load_context(M, _, Opts)), 460 !, 461 '$set_source_module'(M), 462 ( option(dialect(Dialect), Opts) 463 -> expects_dialect(Dialect) 464 ; true 465 ). 466set_initial_mode(_, _) :- 467 '$set_source_module'(user).
473xref_input_stream(Stream) :-
474 xref_input(_, Var),
475 !,
476 Stream = Var.483xref_push_op(Src, P, T, N0) :- 484 '$current_source_module'(M0), 485 strip_module(M0:N0, M, N), 486 ( is_list(N), 487 N \== [] 488 -> maplist(push_op(Src, P, T, M), N) 489 ; push_op(Src, P, T, M, N) 490 ). 491 492push_op(Src, P, T, M0, N0) :- 493 strip_module(M0:N0, M, N), 494 Name = M:N, 495 valid_op(op(P,T,Name)), 496 push_op(P, T, Name), 497 assert_op(Src, op(P,T,Name)), 498 debug(xref(op), ':- ~w.', [op(P,T,Name)]). 499 500valid_op(op(P,T,M:N)) :- 501 atom(M), 502 valid_op_name(N), 503 integer(P), 504 between(0, 1200, P), 505 atom(T), 506 op_type(T). 507 508valid_op_name(N) :- 509 atom(N), 510 !. 511valid_op_name(N) :- 512 N == []. 513 514op_type(xf). 515op_type(yf). 516op_type(fx). 517op_type(fy). 518op_type(xfx). 519op_type(xfy). 520op_type(yfx).
526xref_set_prolog_flag(Flag, Value, Src, Line) :- 527 atom(Flag), 528 !, 529 assertz(xflag(Flag, Value, Src, Line)). 530xref_set_prolog_flag(_, _, _, _).
536xref_clean(Source) :- 537 prolog_canonical_source(Source, Src), 538 retractall(called(_, Src, _Origin, _Cond, _Line)), 539 retractall(dynamic(_, Src, Line)), 540 retractall(multifile(_, Src, Line)), 541 retractall(public(_, Src, Line)), 542 retractall(declared(_, _, Src, Line)), 543 retractall(defined(_, Src, Line)), 544 retractall(meta_goal(_, _, Src)), 545 retractall(foreign(_, Src, Line)), 546 retractall(constraint(_, Src, Line)), 547 retractall(imported(_, Src, _From)), 548 retractall(exported(_, Src)), 549 retractall(uses_file(_, Src, _)), 550 retractall(xmodule(_, Src)), 551 retractall(xop(Src, _)), 552 retractall(grammar_rule(_, Src)), 553 retractall(xoption(Src, _)), 554 retractall(xflag(_Name, _Value, Src, Line)), 555 retractall(source(Src, _)), 556 retractall(used_class(_, Src)), 557 retractall(defined_class(_, _, _, Src, _)), 558 retractall(mode(_, Src)), 559 retractall(module_comment(Src, _, _)), 560 retractall(pred_comment(_, Src, _, _)), 561 retractall(pred_comment_link(_, Src, _)), 562 retractall(pred_mode(_, Src, _)). 563 564 565 /******************************* 566 * READ RESULTS * 567 *******************************/
573xref_current_source(Source) :-
574 source(Source, _Time).
581xref_done(Source, Time) :-
582 prolog_canonical_source(Source, Src),
583 source(Src, Time).Called-By pairs. The xref_called/5 version may return
duplicate Called-By if Called is called from multiple clauses in
By, but at most one call per clause.
605xref_called(Source, Called, By) :- 606 xref_called(Source, Called, By, _). 607 608xref_called(Source, Called, By, Cond) :- 609 canonical_source(Source, Src), 610 distinct(Called-By, called(Called, Src, By, Cond, _)). 611 612xref_called(Source, Called, By, Cond, Line) :- 613 canonical_source(Source, Src), 614 called(Called, Src, By, Cond, Line).
include(File)) directive.
dynamic(Location)thread_local(Location)multifile(Location)public(Location)local(Location)foreign(Location)constraint(Location)imported(From)636xref_defined(Source, Called, How) :- 637 nonvar(Source), 638 !, 639 canonical_source(Source, Src), 640 xref_defined2(How, Src, Called). 641xref_defined(Source, Called, How) :- 642 xref_defined2(How, Src, Called), 643 canonical_source(Source, Src). 644 645xref_defined2(dynamic(Line), Src, Called) :- 646 dynamic(Called, Src, Line). 647xref_defined2(thread_local(Line), Src, Called) :- 648 thread_local(Called, Src, Line). 649xref_defined2(multifile(Line), Src, Called) :- 650 multifile(Called, Src, Line). 651xref_defined2(public(Line), Src, Called) :- 652 public(Called, Src, Line). 653xref_defined2(local(Line), Src, Called) :- 654 defined(Called, Src, Line). 655xref_defined2(foreign(Line), Src, Called) :- 656 foreign(Called, Src, Line). 657xref_defined2(constraint(Line), Src, Called) :- 658 ( constraint(Called, Src, Line) 659 -> true 660 ; declared(Called, chr_constraint, Src, Line) 661 ). 662xref_defined2(imported(From), Src, Called) :- 663 imported(Called, Src, From). 664xref_defined2(dcg, Src, Called) :- 665 grammar_rule(Called, Src).
673xref_definition_line(local(Line), Line). 674xref_definition_line(dynamic(Line), Line). 675xref_definition_line(thread_local(Line), Line). 676xref_definition_line(multifile(Line), Line). 677xref_definition_line(public(Line), Line). 678xref_definition_line(constraint(Line), Line). 679xref_definition_line(foreign(Line), Line).
686xref_exported(Source, Called) :-
687 prolog_canonical_source(Source, Src),
688 exported(Called, Src).694xref_module(Source, Module) :- 695 nonvar(Source), 696 !, 697 prolog_canonical_source(Source, Src), 698 xmodule(Module, Src). 699xref_module(Source, Module) :- 700 xmodule(Module, Src), 701 prolog_canonical_source(Source, Src).
711xref_uses_file(Source, Spec, Path) :-
712 prolog_canonical_source(Source, Src),
713 uses_file(Spec, Src, Path).
723xref_op(Source, Op) :-
724 prolog_canonical_source(Source, Src),
725 xop(Src, Op).733xref_prolog_flag(Source, Flag, Value, Line) :- 734 prolog_canonical_source(Source, Src), 735 xflag(Flag, Value, Src, Line). 736 737xref_built_in(Head) :- 738 system_predicate(Head). 739 740xref_used_class(Source, Class) :- 741 prolog_canonical_source(Source, Src), 742 used_class(Class, Src). 743 744xref_defined_class(Source, Class, local(Line, Super, Summary)) :- 745 prolog_canonical_source(Source, Src), 746 defined_class(Class, Super, Summary, Src, Line), 747 integer(Line), 748 !. 749xref_defined_class(Source, Class, file(File)) :- 750 prolog_canonical_source(Source, Src), 751 defined_class(Class, _, _, Src, file(File)). 752 753:- thread_local 754 current_cond/1, 755 source_line/1, 756 current_test_unit/2. 757 758current_source_line(Line) :- 759 source_line(Var), 760 !, 761 Line = Var.
769collect(Src, File, In, Options) :- 770 ( Src == File 771 -> SrcSpec = Line 772 ; SrcSpec = (File:Line) 773 ), 774 ( current_prolog_flag(xref_store_comments, OldStore) 775 -> true 776 ; OldStore = false 777 ), 778 option(comments(CommentHandling), Options, collect), 779 ( CommentHandling == ignore 780 -> CommentOptions = [], 781 Comments = [] 782 ; CommentHandling == store 783 -> CommentOptions = [ process_comment(true) ], 784 Comments = [], 785 set_prolog_flag(xref_store_comments, true) 786 ; CommentOptions = [ comments(Comments) ] 787 ), 788 repeat, 789 E = error(_,_), 790 catch(prolog_read_source_term( 791 In, Term, Expanded, 792 [ term_position(TermPos) 793 | CommentOptions 794 ]), 795 E, report_syntax_error(E, Src, [])), 796 update_condition(Term), 797 stream_position_data(line_count, TermPos, Line), 798 setup_call_cleanup( 799 asserta(source_line(SrcSpec), Ref), 800 catch(process(Expanded, Comments, Term, TermPos, Src, EOF), 801 E, print_message(error, E)), 802 erase(Ref)), 803 EOF == true, 804 !, 805 set_prolog_flag(xref_store_comments, OldStore). 806 807report_syntax_error(_, _, Options) :- 808 option(silent(true), Options), 809 !, 810 fail. 811report_syntax_error(E, Src, _Options) :- 812 ( verbose(Src) 813 -> print_message(error, E) 814 ; true 815 ), 816 fail.
822update_condition((:-Directive)) :- 823 !, 824 update_cond(Directive). 825update_condition(_). 826 827update_cond(if(Cond)) :- 828 !, 829 asserta(current_cond(Cond)). 830update_cond(else) :- 831 retract(current_cond(C0)), 832 !, 833 assert(current_cond(\+C0)). 834update_cond(elif(Cond)) :- 835 retract(current_cond(C0)), 836 !, 837 assert(current_cond((\+C0,Cond))). 838update_cond(endif) :- 839 retract(current_cond(_)), 840 !. 841update_cond(_).
848current_condition(Condition) :- 849 \+ current_cond(_), 850 !, 851 Condition = true. 852current_condition(Condition) :- 853 findall(C, current_cond(C), List), 854 list_to_conj(List, Condition). 855 856list_to_conj([], true). 857list_to_conj([C], C) :- !. 858list_to_conj([H|T], (H,C)) :- 859 list_to_conj(T, C). 860 861 862 /******************************* 863 * PROCESS * 864 *******************************/
876process(Expanded, Comments, Term0, TermPos, Src, EOF) :- 877 is_list(Expanded), % term_expansion into list. 878 !, 879 ( member(Term, Expanded), 880 process(Term, Term0, Src), 881 Term == end_of_file 882 -> EOF = true 883 ; EOF = false 884 ), 885 xref_comments(Comments, TermPos, Src). 886process(end_of_file, _, _, _, _, true) :- 887 !. 888process(Term, Comments, Term0, TermPos, Src, false) :- 889 process(Term, Term0, Src), 890 xref_comments(Comments, TermPos, Src).
894process(_, Term0, _) :- 895 ignore_raw_term(Term0), 896 !. 897process(Head :- Body, Head0 --> _, Src) :- 898 pi_head(F/A, Head), 899 pi_head(F/A0, Head0), 900 A =:= A0 + 2, 901 !, 902 assert_grammar_rule(Src, Head), 903 process((Head :- Body), Src). 904process(Term, _Term0, Src) :- 905 process(Term, Src). 906 907ignore_raw_term((:- predicate_options(_,_,_))).
911process(Var, _) :- 912 var(Var), 913 !. % Warn? 914process(end_of_file, _) :- !. 915process((:- Directive), Src) :- 916 !, 917 process_directive(Directive, Src), 918 !. 919process((?- Directive), Src) :- 920 !, 921 process_directive(Directive, Src), 922 !. 923process((Head :- Body), Src) :- 924 !, 925 assert_defined(Src, Head), 926 process_body(Body, Head, Src). 927process((Left => Body), Src) :- 928 !, 929 ( nonvar(Left), 930 Left = (Head, Guard) 931 -> assert_defined(Src, Head), 932 process_body(Guard, Head, Src), 933 process_body(Body, Head, Src) 934 ; assert_defined(Src, Left), 935 process_body(Body, Left, Src) 936 ). 937process(?=>(Head, Body), Src) :- 938 !, 939 assert_defined(Src, Head), 940 process_body(Body, Head, Src). 941process('$source_location'(_File, _Line):Clause, Src) :- 942 !, 943 process(Clause, Src). 944process(Term, Src) :- 945 process_chr(Term, Src), 946 !. 947process(M:(Head :- Body), Src) :- 948 !, 949 process((M:Head :- M:Body), Src). 950process(Head, Src) :- 951 assert_defined(Src, Head). 952 953 954 /******************************* 955 * COMMENTS * 956 *******************************/
960xref_comments([], _Pos, _Src). 961:- if(current_predicate(parse_comment/3)). 962xref_comments([Pos-Comment|T], TermPos, Src) :- 963 ( Pos @> TermPos % comments inside term 964 -> true 965 ; stream_position_data(line_count, Pos, Line), 966 FilePos = Src:Line, 967 ( parse_comment(Comment, FilePos, Parsed) 968 -> assert_comments(Parsed, Src) 969 ; true 970 ), 971 xref_comments(T, TermPos, Src) 972 ). 973 974assert_comments([], _). 975assert_comments([H|T], Src) :- 976 assert_comment(H, Src), 977 assert_comments(T, Src). 978 979assert_comment(section(_Id, Title, Comment), Src) :- 980 assertz(module_comment(Src, Title, Comment)). 981assert_comment(predicate(PI, Summary, Comment), Src) :- 982 pi_to_head(PI, Src, Head), 983 assertz(pred_comment(Head, Src, Summary, Comment)). 984assert_comment(link(PI, PITo), Src) :- 985 pi_to_head(PI, Src, Head), 986 pi_to_head(PITo, Src, HeadTo), 987 assertz(pred_comment_link(Head, Src, HeadTo)). 988assert_comment(mode(Head, Det), Src) :- 989 assertz(pred_mode(Head, Src, Det)). 990 991pi_to_head(PI, Src, Head) :- 992 pi_to_head(PI, Head0), 993 ( Head0 = _:_ 994 -> strip_module(Head0, M, Plain), 995 ( xmodule(M, Src) 996 -> Head = Plain 997 ; Head = M:Plain 998 ) 999 ; Head = Head0 1000 ). 1001:- endif.
1007xref_comment(Source, Title, Comment) :-
1008 canonical_source(Source, Src),
1009 module_comment(Src, Title, Comment).
1015xref_comment(Source, Head, Summary, Comment) :-
1016 canonical_source(Source, Src),
1017 ( pred_comment(Head, Src, Summary, Comment)
1018 ; pred_comment_link(Head, Src, HeadTo),
1019 pred_comment(HeadTo, Src, Summary, Comment)
1020 ).
1027xref_mode(Source, Mode, Det) :-
1028 canonical_source(Source, Src),
1029 pred_mode(Mode, Src, Det).1036xref_option(Source, Option) :- 1037 canonical_source(Source, Src), 1038 xoption(Src, Option). 1039 1040 1041 /******************************** 1042 * DIRECTIVES * 1043 ********************************/ 1044 1045process_directive(Var, _) :- 1046 var(Var), 1047 !. % error, but that isn't our business 1048process_directive(Dir, _Src) :- 1049 debug(xref(directive), 'Processing :- ~q', [Dir]), 1050 fail. 1051process_directive((A,B), Src) :- % TBD: what about other control 1052 !, 1053 process_directive(A, Src), % structures? 1054 process_directive(B, Src). 1055process_directive(List, Src) :- 1056 is_list(List), 1057 !, 1058 process_directive(consult(List), Src). 1059process_directive(use_module(File, Import), Src) :- 1060 process_use_module2(File, Import, Src, false). 1061process_directive(autoload(File, Import), Src) :- 1062 process_use_module2(File, Import, Src, false). 1063process_directive(require(Import), Src) :- 1064 process_requires(Import, Src). 1065process_directive(expects_dialect(Dialect), Src) :- 1066 process_directive(use_module(library(dialect/Dialect)), Src), 1067 expects_dialect(Dialect). 1068process_directive(reexport(File, Import), Src) :- 1069 process_use_module2(File, Import, Src, true). 1070process_directive(reexport(Modules), Src) :- 1071 process_use_module(Modules, Src, true). 1072process_directive(autoload(Modules), Src) :- 1073 process_use_module(Modules, Src, false). 1074process_directive(use_module(Modules), Src) :- 1075 process_use_module(Modules, Src, false). 1076process_directive(consult(Modules), Src) :- 1077 process_use_module(Modules, Src, false). 1078process_directive(ensure_loaded(Modules), Src) :- 1079 process_use_module(Modules, Src, false). 1080process_directive(load_files(Files, _Options), Src) :- 1081 process_use_module(Files, Src, false). 1082process_directive(include(Files), Src) :- 1083 process_include(Files, Src). 1084process_directive(dynamic(Dynamic), Src) :- 1085 process_predicates(assert_dynamic, Dynamic, Src). 1086process_directive(dynamic(Dynamic, _Options), Src) :- 1087 process_predicates(assert_dynamic, Dynamic, Src). 1088process_directive(thread_local(Dynamic), Src) :- 1089 process_predicates(assert_thread_local, Dynamic, Src). 1090process_directive(multifile(Dynamic), Src) :- 1091 process_predicates(assert_multifile, Dynamic, Src). 1092process_directive(public(Public), Src) :- 1093 process_predicates(assert_public, Public, Src). 1094process_directive(export(Export), Src) :- 1095 process_predicates(assert_export, Export, Src). 1096process_directive(import(Import), Src) :- 1097 process_import(Import, Src). 1098process_directive(module(Module, Export), Src) :- 1099 assert_module(Src, Module), 1100 assert_module_export(Src, Export). 1101process_directive(module(Module, Export, Import), Src) :- 1102 assert_module(Src, Module), 1103 assert_module_export(Src, Export), 1104 assert_module3(Import, Src). 1105process_directive(begin_tests(Unit, _Options), Src) :- 1106 enter_test_unit(Unit, Src). 1107process_directive(begin_tests(Unit), Src) :- 1108 enter_test_unit(Unit, Src). 1109process_directive(end_tests(Unit), Src) :- 1110 leave_test_unit(Unit, Src). 1111process_directive('$set_source_module'(system), Src) :- 1112 assert_module(Src, system). % hack for handling boot/init.pl 1113process_directive(pce_begin_class_definition(Name, Meta, Super, Doc), Src) :- 1114 assert_defined_class(Src, Name, Meta, Super, Doc). 1115process_directive(pce_autoload(Name, From), Src) :- 1116 assert_defined_class(Src, Name, imported_from(From)). 1117 1118process_directive(op(P, A, N), Src) :- 1119 xref_push_op(Src, P, A, N). 1120process_directive(set_prolog_flag(Flag, Value), Src) :- 1121 ( Flag == character_escapes 1122 -> set_prolog_flag(character_escapes, Value) 1123 ; true 1124 ), 1125 current_source_line(Line), 1126 xref_set_prolog_flag(Flag, Value, Src, Line). 1127process_directive(style_check(X), _) :- 1128 style_check(X). 1129process_directive(encoding(Enc), _) :- 1130 ( xref_input_stream(Stream) 1131 -> catch(set_stream(Stream, encoding(Enc)), error(_,_), true) 1132 ; true % can this happen? 1133 ). 1134process_directive(pce_expansion:push_compile_operators, _) :- 1135 '$current_source_module'(SM), 1136 call(pce_expansion:push_compile_operators(SM)). % call to avoid xref 1137process_directive(pce_expansion:pop_compile_operators, _) :- 1138 call(pce_expansion:pop_compile_operators). 1139process_directive(meta_predicate(Meta), Src) :- 1140 process_meta_predicate(Meta, Src). 1141process_directive(arithmetic_function(FSpec), Src) :- 1142 arith_callable(FSpec, Goal), 1143 !, 1144 current_source_line(Line), 1145 assert_called(Src, '<directive>'(Line), Goal, Line). 1146process_directive(format_predicate(_, Goal), Src) :- 1147 !, 1148 current_source_line(Line), 1149 assert_called(Src, '<directive>'(Line), Goal, Line). 1150process_directive(if(Cond), Src) :- 1151 !, 1152 current_source_line(Line), 1153 assert_called(Src, '<directive>'(Line), Cond, Line). 1154process_directive(elif(Cond), Src) :- 1155 !, 1156 current_source_line(Line), 1157 assert_called(Src, '<directive>'(Line), Cond, Line). 1158process_directive(else, _) :- !. 1159process_directive(endif, _) :- !. 1160process_directive(Goal, Src) :- 1161 current_source_line(Line), 1162 process_body(Goal, '<directive>'(Line), Src).
1168process_meta_predicate((A,B), Src) :- 1169 !, 1170 process_meta_predicate(A, Src), 1171 process_meta_predicate(B, Src). 1172process_meta_predicate(Decl, Src) :- 1173 process_meta_head(Src, Decl). 1174 1175process_meta_head(Src, Decl) :- % swapped arguments for maplist 1176 compound(Decl), 1177 compound_name_arity(Decl, Name, Arity), 1178 compound_name_arity(Head, Name, Arity), 1179 meta_args(1, Arity, Decl, Head, Meta), 1180 ( ( prolog:meta_goal(Head, _) 1181 ; prolog:called_by(Head, _, _, _) 1182 ; prolog:called_by(Head, _) 1183 ; meta_goal(Head, Meta, _Src) 1184 ) 1185 -> true 1186 ; warn_late_meta_predicate(Decl, Src), 1187 retractall(meta_goal(Head, _, Src)), 1188 assert(meta_goal(Head, Meta, Src)) 1189 ). 1190 1191meta_args(I, Arity, _, _, []) :- 1192 I > Arity, 1193 !. 1194meta_args(I, Arity, Decl, Head, [H|T]) :- % 0 1195 arg(I, Decl, 0), 1196 !, 1197 arg(I, Head, H), 1198 I2 is I + 1, 1199 meta_args(I2, Arity, Decl, Head, T). 1200meta_args(I, Arity, Decl, Head, [H|T]) :- % ^ 1201 arg(I, Decl, ^), 1202 !, 1203 arg(I, Head, EH), 1204 setof_goal(EH, H), 1205 I2 is I + 1, 1206 meta_args(I2, Arity, Decl, Head, T). 1207meta_args(I, Arity, Decl, Head, [//(H)|T]) :- 1208 arg(I, Decl, //), 1209 !, 1210 arg(I, Head, H), 1211 I2 is I + 1, 1212 meta_args(I2, Arity, Decl, Head, T). 1213meta_args(I, Arity, Decl, Head, [H+A|T]) :- % I --> H+I 1214 arg(I, Decl, A), 1215 integer(A), A > 0, 1216 !, 1217 arg(I, Head, H), 1218 I2 is I + 1, 1219 meta_args(I2, Arity, Decl, Head, T). 1220meta_args(I, Arity, Decl, Head, Meta) :- 1221 I2 is I + 1, 1222 meta_args(I2, Arity, Decl, Head, Meta). 1223 1224 1225warn_late_meta_predicate(Decl, Src) :- 1226 xref_called(Src, Decl, By), 1227 !, 1228 print_message(warning, meta_predicate_after_call(Decl, By)). 1229warn_late_meta_predicate(_, _). 1230 1231 1232 /******************************** 1233 * BODY * 1234 ********************************/
1243xref_meta(Source, Head, Called) :-
1244 canonical_source(Source, Src),
1245 xref_meta_src(Head, Called, Src).1260xref_meta_src(Head, Called, Src) :- 1261 meta_goal(Head, Called, Src), 1262 !. 1263xref_meta_src(Head, Called, _) :- 1264 xref_meta(Head, Called), 1265 !. 1266xref_meta_src(Head, Called, _) :- 1267 compound(Head), 1268 compound_name_arity(Head, Name, Arity), 1269 apply_pred(Name), 1270 Arity > 5, 1271 !, 1272 Extra is Arity - 1, 1273 arg(1, Head, G), 1274 Called = [G+Extra]. 1275xref_meta_src(Head, Called, _) :- 1276 with_xref(predicate_property('$xref_tmp':Head, meta_predicate(Meta))), 1277 !, 1278 Meta =.. [_|Args], 1279 meta_args(Args, 1, Head, Called). 1280 1281meta_args([], _, _, []). 1282meta_args([H0|T0], I, Head, [H|T]) :- 1283 xargs(H0, N), 1284 !, 1285 arg(I, Head, A), 1286 ( N == 0 1287 -> H = A 1288 ; H = (A+N) 1289 ), 1290 I2 is I+1, 1291 meta_args(T0, I2, Head, T). 1292meta_args([_|T0], I, Head, T) :- 1293 I2 is I+1, 1294 meta_args(T0, I2, Head, T). 1295 1296xargs(N, N) :- integer(N), !. 1297xargs(//, 2). 1298xargs(^, 0). 1299 1300apply_pred(call). % built-in 1301apply_pred(maplist). % library(apply_macros) 1302 1303xref_meta((A, B), [A, B]). 1304xref_meta((A; B), [A, B]). 1305xref_meta((A| B), [A, B]). 1306xref_meta((A -> B), [A, B]). 1307xref_meta((A *-> B), [A, B]). 1308xref_meta(findall(_V,G,_L), [G]). 1309xref_meta(findall(_V,G,_L,_T), [G]). 1310xref_meta(findnsols(_N,_V,G,_L), [G]). 1311xref_meta(findnsols(_N,_V,G,_L,_T), [G]). 1312xref_meta(setof(_V, EG, _L), [G]) :- 1313 setof_goal(EG, G). 1314xref_meta(bagof(_V, EG, _L), [G]) :- 1315 setof_goal(EG, G). 1316xref_meta(forall(A, B), [A, B]). 1317xref_meta(maplist(G,_), [G+1]). 1318xref_meta(maplist(G,_,_), [G+2]). 1319xref_meta(maplist(G,_,_,_), [G+3]). 1320xref_meta(maplist(G,_,_,_,_), [G+4]). 1321xref_meta(map_list_to_pairs(G,_,_), [G+2]). 1322xref_meta(map_assoc(G, _), [G+1]). 1323xref_meta(map_assoc(G, _, _), [G+2]). 1324xref_meta(checklist(G, _L), [G+1]). 1325xref_meta(sublist(G, _, _), [G+1]). 1326xref_meta(include(G, _, _), [G+1]). 1327xref_meta(exclude(G, _, _), [G+1]). 1328xref_meta(partition(G, _, _, _, _), [G+2]). 1329xref_meta(partition(G, _, _, _),[G+1]). 1330xref_meta(call(G), [G]). 1331xref_meta(call(G, _), [G+1]). 1332xref_meta(call(G, _, _), [G+2]). 1333xref_meta(call(G, _, _, _), [G+3]). 1334xref_meta(call(G, _, _, _, _), [G+4]). 1335xref_meta(not(G), [G]). 1336xref_meta(notrace(G), [G]). 1337xref_meta('$notrace'(G), [G]). 1338xref_meta(\+(G), [G]). 1339xref_meta(ignore(G), [G]). 1340xref_meta(once(G), [G]). 1341xref_meta(initialization(G), [G]). 1342xref_meta(initialization(G,_), [G]). 1343xref_meta(retract(Rule), [G]) :- head_of(Rule, G). 1344xref_meta(clause(G, _), [G]). 1345xref_meta(clause(G, _, _), [G]). 1346xref_meta(phrase(G, _A), [//(G)]). 1347xref_meta(phrase(G, _A, _R), [//(G)]). 1348xref_meta(call_dcg(G, _A, _R), [//(G)]). 1349xref_meta(phrase_from_file(G,_),[//(G)]). 1350xref_meta(catch(A, _, B), [A, B]). 1351xref_meta(catch_with_backtrace(A, _, B), [A, B]). 1352xref_meta(thread_create(A,_,_), [A]). 1353xref_meta(thread_create(A,_), [A]). 1354xref_meta(thread_signal(_,A), [A]). 1355xref_meta(thread_idle(A,_), [A]). 1356xref_meta(thread_at_exit(A), [A]). 1357xref_meta(thread_initialization(A), [A]). 1358xref_meta(engine_create(_,A,_), [A]). 1359xref_meta(engine_create(_,A,_,_), [A]). 1360xref_meta(transaction(A), [A]). 1361xref_meta(transaction(A,B,_), [A,B]). 1362xref_meta(snapshot(A), [A]). 1363xref_meta(predsort(A,_,_), [A+3]). 1364xref_meta(call_cleanup(A, B), [A, B]). 1365xref_meta(call_cleanup(A, _, B),[A, B]). 1366xref_meta(setup_call_cleanup(A, B, C),[A, B, C]). 1367xref_meta(setup_call_catcher_cleanup(A, B, _, C),[A, B, C]). 1368xref_meta(call_residue_vars(A,_), [A]). 1369xref_meta(with_mutex(_,A), [A]). 1370xref_meta(assume(G), [G]). % library(debug) 1371xref_meta(assertion(G), [G]). % library(debug) 1372xref_meta(freeze(_, G), [G]). 1373xref_meta(when(C, A), [C, A]). 1374xref_meta(time(G), [G]). % development system 1375xref_meta(call_time(G, _), [G]). % development system 1376xref_meta(call_time(G, _, _), [G]). % development system 1377xref_meta(profile(G), [G]). 1378xref_meta(at_halt(G), [G]). 1379xref_meta(call_with_time_limit(_, G), [G]). 1380xref_meta(call_with_depth_limit(G, _, _), [G]). 1381xref_meta(call_with_inference_limit(G, _, _), [G]). 1382xref_meta(alarm(_, G, _), [G]). 1383xref_meta(alarm(_, G, _, _), [G]). 1384xref_meta('$add_directive_wic'(G), [G]). 1385xref_meta(with_output_to(_, G), [G]). 1386xref_meta(if(G), [G]). 1387xref_meta(elif(G), [G]). 1388xref_meta(meta_options(G,_,_), [G+1]). 1389xref_meta(on_signal(_,_,H), [H+1]) :- H \== default. 1390xref_meta(distinct(G), [G]). % library(solution_sequences) 1391xref_meta(distinct(_, G), [G]). 1392xref_meta(order_by(_, G), [G]). 1393xref_meta(limit(_, G), [G]). 1394xref_meta(offset(_, G), [G]). 1395xref_meta(reset(G,_,_), [G]). 1396xref_meta(prolog_listen(Ev,G), [G+N]) :- event_xargs(Ev, N). 1397xref_meta(prolog_listen(Ev,G,_),[G+N]) :- event_xargs(Ev, N). 1398xref_meta(tnot(G), [G]). 1399xref_meta(not_exists(G), [G]). 1400xref_meta(with_tty_raw(G), [G]). 1401xref_meta(residual_goals(G), [G+2]). 1402 1403 % XPCE meta-predicates 1404xref_meta(pce_global(_, new(_)), _) :- !, fail. 1405xref_meta(pce_global(_, B), [B+1]). 1406xref_meta(ifmaintainer(G), [G]). % used in manual 1407xref_meta(listen(_, G), [G]). % library(broadcast) 1408xref_meta(listen(_, _, G), [G]). 1409xref_meta(in_pce_thread(G), [G]). 1410 1411xref_meta(G, Meta) :- % call user extensions 1412 prolog:meta_goal(G, Meta). 1413xref_meta(G, Meta) :- % Generated from :- meta_predicate 1414 meta_goal(G, Meta, _Src). 1415 1416setof_goal(EG, G) :- 1417 var(EG), !, G = EG. 1418setof_goal(_^EG, G) :- 1419 !, 1420 setof_goal(EG, G). 1421setof_goal(G, G). 1422 1423event_xargs(abort, 0). 1424event_xargs(erase, 1). 1425event_xargs(break, 3). 1426event_xargs(frame_finished, 1). 1427event_xargs(thread_exit, 1). 1428event_xargs(this_thread_exit, 0). 1429event_xargs(PI, 2) :- pi_to_head(PI, _).
1435head_of(Var, _) :- 1436 var(Var), !, fail. 1437head_of((Head :- _), Head). 1438head_of(Head, Head).
1446xref_hook(Hook) :- 1447 prolog:hook(Hook). 1448xref_hook(Hook) :- 1449 hook(Hook). 1450 1451 1452hook(attr_portray_hook(_,_)). 1453hook(attr_unify_hook(_,_)). 1454hook(attribute_goals(_,_,_)). 1455hook(goal_expansion(_,_)). 1456hook(term_expansion(_,_)). 1457hook(goal_expansion(_,_,_,_)). 1458hook(term_expansion(_,_,_,_)). 1459hook(resource(_,_,_)). 1460hook('$pred_option'(_,_,_,_)). 1461hook('$nowarn_autoload'(_,_)). 1462 1463hook(emacs_prolog_colours:goal_classification(_,_)). 1464hook(emacs_prolog_colours:goal_colours(_,_)). 1465hook(emacs_prolog_colours:identify(_,_)). 1466hook(emacs_prolog_colours:style(_,_)). 1467hook(emacs_prolog_colours:term_colours(_,_)). 1468hook(pce_principal:get_implementation(_,_,_,_)). 1469hook(pce_principal:pce_class(_,_,_,_,_,_)). 1470hook(pce_principal:pce_lazy_get_method(_,_,_)). 1471hook(pce_principal:pce_lazy_send_method(_,_,_)). 1472hook(pce_principal:pce_uses_template(_,_)). 1473hook(pce_principal:send_implementation(_,_,_)). 1474hook(predicate_options:option_decl(_,_,_)). 1475hook(prolog:debug_control_hook(_)). 1476hook(prolog:error_message(_,_,_)). 1477hook(prolog:expand_answer(_,_,_)). 1478hook(prolog:general_exception(_,_)). 1479hook(prolog:help_hook(_)). 1480hook(prolog:locate_clauses(_,_)). 1481hook(prolog:message(_,_,_)). 1482hook(prolog:message_context(_,_,_)). 1483hook(prolog:message_line_element(_,_)). 1484hook(prolog:message_location(_,_,_)). 1485hook(prolog:predicate_summary(_,_)). 1486hook(prolog:prolog_exception_hook(_,_,_,_,_)). 1487hook(prolog:residual_goals(_,_)). 1488hook(prolog_edit:load). 1489hook(prolog_edit:locate(_,_,_)). 1490hook(sandbox:safe_directive(_)). 1491hook(sandbox:safe_global_variable(_)). 1492hook(sandbox:safe_meta(_,_)). 1493hook(sandbox:safe_meta_predicate(_)). 1494hook(sandbox:safe_primitive(_)). 1495hook(sandbox:safe_prolog_flag(_,_)). 1496hook(shlib:unload_all_foreign_libraries). 1497hook(system:'$foreign_registered'(_, _)). 1498hook(user:exception(_,_,_)). 1499hook(user:expand_answer(_,_)). 1500hook(user:expand_query(_,_,_,_)). 1501hook(user:file_search_path(_,_)). 1502hook(user:library_directory(_)). 1503hook(user:message_hook(_,_,_)). 1504hook(prolog:message_action(_,_)). 1505hook(user:portray(_)). 1506hook(user:prolog_clause_name(_,_)). 1507hook(user:prolog_list_goal(_)). 1508hook(user:prolog_predicate_name(_,_)). 1509hook(user:prolog_trace_interception(_,_,_,_)).
1515arith_callable(Var, _) :- 1516 var(Var), !, fail. 1517arith_callable(Module:Spec, Module:Goal) :- 1518 !, 1519 arith_callable(Spec, Goal). 1520arith_callable(Name/Arity, Goal) :- 1521 PredArity is Arity + 1, 1522 functor(Goal, Name, PredArity).
We limit the number of explored paths to 100 to avoid getting trapped in this analysis.
1533process_body(Body, Origin, Src) :-
1534 forall(limit(100, process_goal(Body, Origin, Src, _Partial)),
1535 true).true if there was a
partial evalation inside Goal that has bound variables.1542process_goal(Var, _, _, _) :- 1543 var(Var), 1544 !. 1545process_goal(_:Goal, _, _, _) :- 1546 var(Goal), 1547 !. 1548process_goal(Goal, Origin, Src, P) :- 1549 Goal = (_,_), % problems 1550 !, 1551 phrase(conjunction(Goal), Goals), 1552 process_conjunction(Goals, Origin, Src, P). 1553process_goal(Goal, Origin, Src, _) :- % Final disjunction, no 1554 Goal = (_;_), % problems 1555 !, 1556 phrase(disjunction(Goal), Goals), 1557 forall(member(G, Goals), 1558 process_body(G, Origin, Src)). 1559process_goal(Goal, Origin, Src, P) :- 1560 ( ( xmodule(M, Src) 1561 -> true 1562 ; M = user 1563 ), 1564 pi_head(PI, M:Goal), 1565 ( current_predicate(PI), 1566 predicate_property(M:Goal, imported_from(IM)) 1567 -> true 1568 ; PI = M:Name/Arity, 1569 '$find_library'(M, Name, Arity, IM, _Library) 1570 -> true 1571 ; IM = M 1572 ), 1573 prolog:called_by(Goal, IM, M, Called) 1574 ; prolog:called_by(Goal, Called) 1575 ), 1576 !, 1577 must_be(list, Called), 1578 current_source_line(Here), 1579 assert_called(Src, Origin, Goal, Here), 1580 process_called_list(Called, Origin, Src, P). 1581process_goal(Goal, Origin, Src, _) :- 1582 process_xpce_goal(Goal, Origin, Src), 1583 !. 1584process_goal(load_foreign_library(File), _Origin, Src, _) :- 1585 process_foreign(File, Src). 1586process_goal(load_foreign_library(File, _Init), _Origin, Src, _) :- 1587 process_foreign(File, Src). 1588process_goal(use_foreign_library(File), _Origin, Src, _) :- 1589 process_foreign(File, Src). 1590process_goal(use_foreign_library(File, _Init), _Origin, Src, _) :- 1591 process_foreign(File, Src). 1592process_goal(Goal, Origin, Src, P) :- 1593 xref_meta_src(Goal, Metas, Src), 1594 !, 1595 current_source_line(Here), 1596 assert_called(Src, Origin, Goal, Here), 1597 process_called_list(Metas, Origin, Src, P). 1598process_goal(Goal, Origin, Src, _) :- 1599 asserting_goal(Goal, Rule), 1600 !, 1601 current_source_line(Here), 1602 assert_called(Src, Origin, Goal, Here), 1603 process_assert(Rule, Origin, Src). 1604process_goal(Goal, Origin, Src, P) :- 1605 partial_evaluate(Goal, P), 1606 current_source_line(Here), 1607 assert_called(Src, Origin, Goal, Here). 1608 1609disjunction(Var) --> {var(Var), !}, [Var]. 1610disjunction((A;B)) --> !, disjunction(A), disjunction(B). 1611disjunction(G) --> [G]. 1612 1613conjunction(Var) --> {var(Var), !}, [Var]. 1614conjunction((A,B)) --> !, conjunction(A), conjunction(B). 1615conjunction(G) --> [G]. 1616 (RVars, T) :- 1618 term_variables(T, TVars0), 1619 sort(TVars0, TVars), 1620 ord_intersect(RVars, TVars). 1621 1622process_conjunction([], _, _, _). 1623process_conjunction([Disj|Rest], Origin, Src, P) :- 1624 nonvar(Disj), 1625 Disj = (_;_), 1626 Rest \== [], 1627 !, 1628 phrase(disjunction(Disj), Goals), 1629 term_variables(Rest, RVars0), 1630 sort(RVars0, RVars), 1631 partition(shares_vars(RVars), Goals, Sharing, NonSHaring), 1632 forall(member(G, NonSHaring), 1633 process_body(G, Origin, Src)), 1634 ( Sharing == [] 1635 -> true 1636 ; maplist(term_variables, Sharing, GVars0), 1637 append(GVars0, GVars1), 1638 sort(GVars1, GVars), 1639 ord_intersection(GVars, RVars, SVars), 1640 VT =.. [v|SVars], 1641 findall(VT, 1642 ( member(G, Sharing), 1643 process_goal(G, Origin, Src, PS), 1644 PS == true 1645 ), 1646 Alts0), 1647 ( Alts0 == [] 1648 -> true 1649 ; ( true 1650 ; P = true, 1651 sort(Alts0, Alts1), 1652 variants(Alts1, 10, Alts), 1653 member(VT, Alts) 1654 ) 1655 ) 1656 ), 1657 process_conjunction(Rest, Origin, Src, P). 1658process_conjunction([H|T], Origin, Src, P) :- 1659 process_goal(H, Origin, Src, P), 1660 process_conjunction(T, Origin, Src, P). 1661 1662 1663process_called_list([], _, _, _). 1664process_called_list([H|T], Origin, Src, P) :- 1665 process_meta(H, Origin, Src, P), 1666 process_called_list(T, Origin, Src, P). 1667 1668process_meta(A+N, Origin, Src, P) :- 1669 !, 1670 ( extend(A, N, AX) 1671 -> process_goal(AX, Origin, Src, P) 1672 ; true 1673 ). 1674process_meta(//(A), Origin, Src, P) :- 1675 !, 1676 process_dcg_goal(A, Origin, Src, P). 1677process_meta(G, Origin, Src, P) :- 1678 process_goal(G, Origin, Src, P).
1685process_dcg_goal(Var, _, _, _) :- 1686 var(Var), 1687 !. 1688process_dcg_goal((A,B), Origin, Src, P) :- 1689 !, 1690 process_dcg_goal(A, Origin, Src, P), 1691 process_dcg_goal(B, Origin, Src, P). 1692process_dcg_goal((A;B), Origin, Src, P) :- 1693 !, 1694 process_dcg_goal(A, Origin, Src, P), 1695 process_dcg_goal(B, Origin, Src, P). 1696process_dcg_goal((A|B), Origin, Src, P) :- 1697 !, 1698 process_dcg_goal(A, Origin, Src, P), 1699 process_dcg_goal(B, Origin, Src, P). 1700process_dcg_goal((A->B), Origin, Src, P) :- 1701 !, 1702 process_dcg_goal(A, Origin, Src, P), 1703 process_dcg_goal(B, Origin, Src, P). 1704process_dcg_goal((A*->B), Origin, Src, P) :- 1705 !, 1706 process_dcg_goal(A, Origin, Src, P), 1707 process_dcg_goal(B, Origin, Src, P). 1708process_dcg_goal({Goal}, Origin, Src, P) :- 1709 !, 1710 process_goal(Goal, Origin, Src, P). 1711process_dcg_goal(List, _Origin, _Src, _) :- 1712 is_list(List), 1713 !. % terminal 1714process_dcg_goal(List, _Origin, _Src, _) :- 1715 string(List), 1716 !. % terminal 1717process_dcg_goal(Callable, Origin, Src, P) :- 1718 extend(Callable, 2, Goal), 1719 !, 1720 process_goal(Goal, Origin, Src, P). 1721process_dcg_goal(_, _, _, _). 1722 1723 1724extend(Var, _, _) :- 1725 var(Var), !, fail. 1726extend(M:G, N, M:GX) :- 1727 !, 1728 callable(G), 1729 extend(G, N, GX). 1730extend(G, N, GX) :- 1731 ( compound(G) 1732 -> compound_name_arguments(G, Name, Args), 1733 length(Rest, N), 1734 append(Args, Rest, NArgs), 1735 compound_name_arguments(GX, Name, NArgs) 1736 ; atom(G) 1737 -> length(NArgs, N), 1738 compound_name_arguments(GX, G, NArgs) 1739 ). 1740 1741asserting_goal(assert(Rule), Rule). 1742asserting_goal(asserta(Rule), Rule). 1743asserting_goal(assertz(Rule), Rule). 1744asserting_goal(assert(Rule,_), Rule). 1745asserting_goal(asserta(Rule,_), Rule). 1746asserting_goal(assertz(Rule,_), Rule). 1747 1748process_assert(0, _, _) :- !. % catch variables 1749process_assert((_:-Body), Origin, Src) :- 1750 !, 1751 process_body(Body, Origin, Src). 1752process_assert(_, _, _).
1756variants([], _, []). 1757variants([H|T], Max, List) :- 1758 variants(T, H, Max, List). 1759 1760variants([], H, _, [H]). 1761variants(_, _, 0, []) :- !. 1762variants([H|T], V, Max, List) :- 1763 ( H =@= V 1764 -> variants(T, V, Max, List) 1765 ; List = [V|List2], 1766 Max1 is Max-1, 1767 variants(T, H, Max1, List2) 1768 ).
T = hello(X),
findall(T, T, List),
1782partial_evaluate(Goal, P) :- 1783 eval(Goal), 1784 !, 1785 P = true. 1786partial_evaluate(_, _). 1787 1788eval(X = Y) :- 1789 unify_with_occurs_check(X, Y). 1790 1791 /******************************* 1792 * PLUNIT SUPPORT * 1793 *******************************/ 1794 1795enter_test_unit(Unit, _Src) :- 1796 current_source_line(Line), 1797 asserta(current_test_unit(Unit, Line)). 1798 1799leave_test_unit(Unit, _Src) :- 1800 retractall(current_test_unit(Unit, _)). 1801 1802 1803 /******************************* 1804 * XPCE STUFF * 1805 *******************************/ 1806 1807pce_goal(new(_,_), new(-, new)). 1808pce_goal(send(_,_), send(arg, msg)). 1809pce_goal(send_class(_,_,_), send_class(arg, arg, msg)). 1810pce_goal(get(_,_,_), get(arg, msg, -)). 1811pce_goal(get_class(_,_,_,_), get_class(arg, arg, msg, -)). 1812pce_goal(get_chain(_,_,_), get_chain(arg, msg, -)). 1813pce_goal(get_object(_,_,_), get_object(arg, msg, -)). 1814 1815process_xpce_goal(G, Origin, Src) :- 1816 pce_goal(G, Process), 1817 !, 1818 current_source_line(Here), 1819 assert_called(Src, Origin, G, Here), 1820 ( arg(I, Process, How), 1821 arg(I, G, Term), 1822 process_xpce_arg(How, Term, Origin, Src), 1823 fail 1824 ; true 1825 ). 1826 1827process_xpce_arg(new, Term, Origin, Src) :- 1828 callable(Term), 1829 process_new(Term, Origin, Src). 1830process_xpce_arg(arg, Term, Origin, Src) :- 1831 compound(Term), 1832 process_new(Term, Origin, Src). 1833process_xpce_arg(msg, Term, Origin, Src) :- 1834 compound(Term), 1835 ( arg(_, Term, Arg), 1836 process_xpce_arg(arg, Arg, Origin, Src), 1837 fail 1838 ; true 1839 ). 1840 1841process_new(_M:_Term, _, _) :- !. % TBD: Calls on other modules! 1842process_new(Term, Origin, Src) :- 1843 assert_new(Src, Origin, Term), 1844 ( compound(Term), 1845 arg(_, Term, Arg), 1846 process_xpce_arg(arg, Arg, Origin, Src), 1847 fail 1848 ; true 1849 ). 1850 1851assert_new(_, _, Term) :- 1852 \+ callable(Term), 1853 !. 1854assert_new(Src, Origin, Control) :- 1855 functor_name(Control, Class), 1856 pce_control_class(Class), 1857 !, 1858 forall(arg(_, Control, Arg), 1859 assert_new(Src, Origin, Arg)). 1860assert_new(Src, Origin, Term) :- 1861 compound(Term), 1862 arg(1, Term, Prolog), 1863 Prolog == @(prolog), 1864 ( Term =.. [message, _, Selector | T], 1865 atom(Selector) 1866 -> Called =.. [Selector|T], 1867 process_body(Called, Origin, Src) 1868 ; Term =.. [?, _, Selector | T], 1869 atom(Selector) 1870 -> append(T, [_R], T2), 1871 Called =.. [Selector|T2], 1872 process_body(Called, Origin, Src) 1873 ), 1874 fail. 1875assert_new(_, _, @(_)) :- !. 1876assert_new(Src, _, Term) :- 1877 functor_name(Term, Name), 1878 assert_used_class(Src, Name). 1879 1880 1881pce_control_class(and). 1882pce_control_class(or). 1883pce_control_class(if). 1884pce_control_class(not). 1885 1886 1887 /******************************** 1888 * INCLUDED MODULES * 1889 ********************************/
1893process_use_module(_Module:_Files, _, _) :- !. % loaded in another module 1894process_use_module([], _, _) :- !. 1895process_use_module([H|T], Src, Reexport) :- 1896 !, 1897 process_use_module(H, Src, Reexport), 1898 process_use_module(T, Src, Reexport). 1899process_use_module(library(pce), Src, Reexport) :- % bit special 1900 !, 1901 xref_public_list(library(pce), Path, Exports, Src), 1902 forall(member(Import, Exports), 1903 process_pce_import(Import, Src, Path, Reexport)). 1904process_use_module(File, Src, Reexport) :- 1905 load_module_if_needed(File), 1906 ( xoption(Src, silent(Silent)) 1907 -> Extra = [silent(Silent)] 1908 ; Extra = [silent(true)] 1909 ), 1910 ( xref_public_list(File, Src, 1911 [ path(Path), 1912 module(M), 1913 exports(Exports), 1914 public(Public), 1915 meta(Meta) 1916 | Extra 1917 ]) 1918 -> assert(uses_file(File, Src, Path)), 1919 assert_import(Src, Exports, _, Path, Reexport), 1920 assert_xmodule_callable(Exports, M, Src, Path), 1921 assert_xmodule_callable(Public, M, Src, Path), 1922 maplist(process_meta_head(Src), Meta), 1923 ( File = library(chr) % hacky 1924 -> assert(mode(chr, Src)) 1925 ; true 1926 ) 1927 ; assert(uses_file(File, Src, '<not_found>')) 1928 ). 1929 1930process_pce_import(Name/Arity, Src, Path, Reexport) :- 1931 atom(Name), 1932 integer(Arity), 1933 !, 1934 functor(Term, Name, Arity), 1935 ( \+ system_predicate(Term), 1936 \+ Term = pce_error(_) % hack!? 1937 -> assert_import(Src, [Name/Arity], _, Path, Reexport) 1938 ; true 1939 ). 1940process_pce_import(op(P,T,N), Src, _, _) :- 1941 xref_push_op(Src, P, T, N).
1947process_use_module2(File, Import, Src, Reexport) :-
1948 load_module_if_needed(File),
1949 ( catch(xref_public_list(File, Src,
1950 [ path(Path),
1951 exports(Export),
1952 meta(Meta)
1953 ]),
1954 error(_,_),
1955 fail)
1956 -> assertz(uses_file(File, Src, Path)),
1957 assert_import(Src, Import, Export, Path, Reexport),
1958 forall(( member(Head, Meta),
1959 imported(Head, _, Path)
1960 ),
1961 process_meta_head(Src, Head))
1962 ; assertz(uses_file(File, Src, '<not_found>'))
1963 ).1972load_module_if_needed(File) :- 1973 prolog:no_autoload_module(File), 1974 !, 1975 use_module(File, []). 1976load_module_if_needed(_). 1977 1978prologno_autoload_module(library(apply_macros)). 1979prologno_autoload_module(library(arithmetic)). 1980prologno_autoload_module(library(record)). 1981prologno_autoload_module(library(persistency)). 1982prologno_autoload_module(library(pldoc)). 1983prologno_autoload_module(library(settings)). 1984prologno_autoload_module(library(debug)). 1985prologno_autoload_module(library(plunit)). 1986prologno_autoload_module(library(macros)). 1987prologno_autoload_module(library(yall)).
1992process_requires(Import, Src) :- 1993 is_list(Import), 1994 !, 1995 require_list(Import, Src). 1996process_requires(Var, _Src) :- 1997 var(Var), 1998 !. 1999process_requires((A,B), Src) :- 2000 !, 2001 process_requires(A, Src), 2002 process_requires(B, Src). 2003process_requires(PI, Src) :- 2004 requires(PI, Src). 2005 2006require_list([], _). 2007require_list([H|T], Src) :- 2008 requires(H, Src), 2009 require_list(T, Src). 2010 2011requires(PI, _Src) :- 2012 '$pi_head'(PI, Head), 2013 '$get_predicate_attribute'(system:Head, defined, 1), 2014 !. 2015requires(PI, Src) :- 2016 '$pi_head'(PI, Head), 2017 '$pi_head'(Name/Arity, Head), 2018 '$find_library'(_Module, Name, Arity, _LoadModule, Library), 2019 ( imported(Head, Src, Library) 2020 -> true 2021 ; assertz(imported(Head, Src, Library)) 2022 ).
[] for
.qlf files.[] for .qlf files.The information collected by this predicate is cached. The cached data is considered valid as long as the modification time of the file does not change.
2058xref_public_list(File, Src, Options) :-
2059 option(path(Source), Options, _),
2060 option(module(Module), Options, _),
2061 option(exports(Exports), Options, _),
2062 option(public(Public), Options, _),
2063 option(meta(Meta), Options, _),
2064 xref_source_file(File, Path, Src, Options),
2065 public_list(Path, Source, Module, Meta, Exports, Public, Options).These predicates fail if File is not a module-file.
2089xref_public_list(File, Source, Export, Src) :- 2090 xref_source_file(File, Path, Src), 2091 public_list(Path, Source, _, _, Export, _, []). 2092xref_public_list(File, Source, Module, Export, Meta, Src) :- 2093 xref_source_file(File, Path, Src), 2094 public_list(Path, Source, Module, Meta, Export, _, []). 2095xref_public_list(File, Source, Module, Export, Public, Meta, Src) :- 2096 xref_source_file(File, Path, Src), 2097 public_list(Path, Source, Module, Meta, Export, Public, []).
true, ignore (syntax) errors. If not specified the default
is inherited from xref_source/2.2108:- dynamic public_list_cache/7. 2109:- volatile public_list_cache/7. 2110 2111public_list(Path, Source, Module, Meta, Export, Public, _Options) :- 2112 \+ is_stream(Path), 2113 public_list_cache(Path, Source, Modified, 2114 Module0, Meta0, Export0, Public0), 2115 time_file(Path, ModifiedNow), 2116 ( abs(Modified-ModifiedNow) < 0.0001 2117 -> !, 2118 t(Module,Meta,Export,Public) = t(Module0,Meta0,Export0,Public0) 2119 ; retractall(public_list_cache(Path, _, _, _, _, _, _)), 2120 fail 2121 ). 2122public_list(Path, Source, Module, Meta, Export, Public, Options) :- 2123 public_list_nc(Path, Source, Module0, Meta0, Export0, Public0, Options), 2124 ( Error = error(_,_), 2125 catch(time_file(Path, Modified), Error, fail) 2126 -> asserta(public_list_cache(Path, Source, Modified, 2127 Module0, Meta0, Export0, Public0)) 2128 ; true 2129 ), 2130 t(Module,Meta,Export,Public) = t(Module0,Meta0,Export0,Public0). 2131 2132public_list_nc(Path, Source, Module, Meta, Export, Public, _Options) :- 2133 \+ is_stream(Path), 2134 public_list_from_index(Path, Module, Meta, Export, Public), 2135 !, 2136 qlf_pl_file(Path, Source). 2137public_list_nc(Path, Source, Module, [], Export, [], _Options) :- 2138 \+ is_stream(Path), 2139 is_qlf_file(Path), 2140 !, 2141 '$qlf_module'(Path, Info), 2142 _{module:Module, exports:Export, file:Source} :< Info. 2143public_list_nc(Path, Path, Module, Meta, Export, Public, Options) :- 2144 ( is_stream(Path) 2145 ; exists_file(Path) 2146 ), 2147 !, 2148 prolog_file_directives(Path, Directives, Options), 2149 public_list(Directives, Path, Module, Meta, [], Export, [], Public, []). 2150public_list_nc(Path, Path, Module, [], Export, [], _Options) :- 2151 \+ is_stream(Path), 2152 qlf_pl_file(QlfFile, Path), 2153 '$qlf_module'(QlfFile, Info), 2154 _{module:Module, exports:Export} :< Info. 2155 2156public_list([(:- module(Module, Export0))|Decls], Path, 2157 Module, Meta, MT, Export, Rest, Public, PT) :- 2158 !, 2159 ( is_list(Export0) 2160 -> append(Export0, Reexport, Export) 2161 ; Reexport = Export 2162 ), 2163 public_list_(Decls, Path, Meta, MT, Reexport, Rest, Public, PT). 2164public_list([(:- encoding(_))|Decls], Path, 2165 Module, Meta, MT, Export, Rest, Public, PT) :- 2166 public_list(Decls, Path, Module, Meta, MT, Export, Rest, Public, PT). 2167 2168public_list_([], _, Meta, Meta, Export, Export, Public, Public). 2169public_list_([(:-(Dir))|T], Path, Meta, MT, Export, Rest, Public, PT) :- 2170 public_list_1(Dir, Path, Meta, MT0, Export, Rest0, Public, PT0), 2171 !, 2172 public_list_(T, Path, MT0, MT, Rest0, Rest, PT0, PT). 2173public_list_([_|T], Path, Meta, MT, Export, Rest, Public, PT) :- 2174 public_list_(T, Path, Meta, MT, Export, Rest, Public, PT). 2175 2176public_list_1(reexport(Spec), Path, Meta, MT, Reexport, Rest, Public, PT) :- 2177 reexport_files(Spec, Path, Meta, MT, Reexport, Rest, Public, PT). 2178public_list_1(reexport(Spec, Import), Path, Meta, Meta, Reexport, Rest, Public, Public) :- 2179 public_from_import(Import, Spec, Path, Reexport, Rest). 2180public_list_1(meta_predicate(Decl), _Path, Meta, MT, Export, Export, Public, Public) :- 2181 phrase(meta_decls(Decl), Meta, MT). 2182public_list_1(public(Decl), _Path, Meta, Meta, Export, Export, Public, PT) :- 2183 phrase(public_decls(Decl), Public, PT).
2189reexport_files([], _, Meta, Meta, Export, Export, Public, Public) :- !. 2190reexport_files([H|T], Src, Meta, MT, Export, ET, Public, PT) :- 2191 !, 2192 xref_source_file(H, Path, Src), 2193 public_list(Path, _Source, _Module, Meta0, Export0, Public0, []), 2194 append(Meta0, MT1, Meta), 2195 append(Export0, ET1, Export), 2196 append(Public0, PT1, Public), 2197 reexport_files(T, Src, MT1, MT, ET1, ET, PT1, PT). 2198reexport_files(Spec, Src, Meta, MT, Export, ET, Public, PT) :- 2199 xref_source_file(Spec, Path, Src), 2200 public_list(Path, _Source, _Module, Meta0, Export0, Public0, []), 2201 append(Meta0, MT, Meta), 2202 append(Export0, ET, Export), 2203 append(Public0, PT, Public). 2204 2205public_from_import(except(Map), Path, Src, Export, Rest) :- 2206 !, 2207 xref_public_list(Path, _, AllExports, Src), 2208 except(Map, AllExports, NewExports), 2209 append(NewExports, Rest, Export). 2210public_from_import(Import, _, _, Export, Rest) :- 2211 import_name_map(Import, Export, Rest).
2216except([], Exports, Exports). 2217except([PI0 as NewName|Map], Exports0, Exports) :- 2218 !, 2219 canonical_pi(PI0, PI), 2220 map_as(Exports0, PI, NewName, Exports1), 2221 except(Map, Exports1, Exports). 2222except([PI0|Map], Exports0, Exports) :- 2223 canonical_pi(PI0, PI), 2224 select(PI2, Exports0, Exports1), 2225 same_pi(PI, PI2), 2226 !, 2227 except(Map, Exports1, Exports). 2228 2229 2230map_as([PI|T], Repl, As, [PI2|T]) :- 2231 same_pi(Repl, PI), 2232 !, 2233 pi_as(PI, As, PI2). 2234map_as([H|T0], Repl, As, [H|T]) :- 2235 map_as(T0, Repl, As, T). 2236 2237pi_as(_/Arity, Name, Name/Arity). 2238pi_as(_//Arity, Name, Name//Arity). 2239 2240import_name_map([], L, L). 2241import_name_map([_/Arity as NewName|T0], [NewName/Arity|T], Tail) :- 2242 !, 2243 import_name_map(T0, T, Tail). 2244import_name_map([_//Arity as NewName|T0], [NewName//Arity|T], Tail) :- 2245 !, 2246 import_name_map(T0, T, Tail). 2247import_name_map([H|T0], [H|T], Tail) :- 2248 import_name_map(T0, T, Tail). 2249 2250canonical_pi(Name//Arity0, PI) :- 2251 integer(Arity0), 2252 !, 2253 PI = Name/Arity, 2254 Arity is Arity0 + 2. 2255canonical_pi(PI, PI). 2256 2257same_pi(Canonical, PI2) :- 2258 canonical_pi(PI2, Canonical). 2259 2260meta_decls(Var) --> 2261 { var(Var) }, 2262 !. 2263meta_decls((A,B)) --> 2264 !, 2265 meta_decls(A), 2266 meta_decls(B). 2267meta_decls(A) --> 2268 [A]. 2269 2270public_decls(Var) --> 2271 { var(Var) }, 2272 !. 2273public_decls((A,B)) --> 2274 !, 2275 public_decls(A), 2276 public_decls(B). 2277public_decls(A) --> 2278 [A].
INDEX.pl file in the same
directory.2285public_list_from_index(Path, Module, Meta, Export, Public) :- 2286 file_name_extension(BasePath, _Ext, Path), 2287 file_directory_name(BasePath, Dir), 2288 atom_concat(Dir, '/INDEX.pl', IndexFile), 2289 exists_file(IndexFile), 2290 file_base_name(BasePath, Base), 2291 setup_call_cleanup( 2292 '$push_input_context'(autoload_index), 2293 setup_call_cleanup( 2294 open(IndexFile, read, In), 2295 index_public_list(In, Base, Module, Meta, Export, Public), 2296 close(In)), 2297 '$pop_input_context'). 2298 2299index_public_list(In, Base, Module, Meta, Export, Public) :- 2300 read_term(In, Term, []), 2301 index_public_list(Term, In, Base, Module, Meta, Export, Public). 2302 2303index_public_list(end_of_file, _In, _Base, _Module, [], [], []). 2304index_public_list(index(op:Op, Module, Base), In, Base, Module, Meta, [Op|Export], Public) :- 2305 !, 2306 read_term(In, Term, []), 2307 index_public_list(Term, In, Base, Module, Meta, Export, Public). 2308index_public_list(index((public):Head, Module, Base), In, Base, Module, Meta, Export, [PI|Public]) :- 2309 !, 2310 pi_head(PI, Head), 2311 read_term(In, Term, []), 2312 index_public_list(Term, In, Base, Module, Meta, Export, Public). 2313index_public_list(index(Head, Module, Base), In, Base, Module, Meta, [PI|Export], Public) :- 2314 !, 2315 pi_head(PI, Head), 2316 ( meta_mode(Head) 2317 -> Meta = [Head|MetaT] 2318 ; Meta = MetaT 2319 ), 2320 read_term(In, Term, []), 2321 index_public_list(Term, In, Base, Module, MetaT, Export, Public). 2322index_public_list(index(Name, Arity, Module, Base), In, Base, Module, Meta, [Name/Arity|Export], Public) :- 2323 !, 2324 read_term(In, Term, []), 2325 index_public_list(Term, In, Base, Module, Meta, Export, Public). 2326index_public_list(_, In, Base, Module, Meta, Export, Public) :- 2327 read_term(In, Term, []), 2328 index_public_list(Term, In, Base, Module, Meta, Export, Public). 2329 2330meta_mode(H) :- 2331 compound(H), 2332 arg(_, H, A), 2333 meta_arg(A), 2334 !. 2335 2336meta_arg(I) :- 2337 integer(I), 2338 !. 2339meta_arg(:). 2340meta_arg(^). 2341meta_arg(//). 2342 2343 /******************************* 2344 * INCLUDE * 2345 *******************************/ 2346 2347process_include([], _) :- !. 2348process_include([H|T], Src) :- 2349 !, 2350 process_include(H, Src), 2351 process_include(T, Src). 2352process_include(File, Src) :- 2353 callable(File), 2354 !, 2355 ( once(xref_input(ParentSrc, _)), 2356 xref_source_file(File, Path, ParentSrc) 2357 -> ( ( uses_file(_, Src, Path) 2358 ; Path == Src 2359 ) 2360 -> true 2361 ; assert(uses_file(File, Src, Path)), 2362 ( xoption(Src, process_include(true)) 2363 -> findall(O, xoption(Src, O), Options), 2364 setup_call_cleanup( 2365 open_include_file(Path, In, Refs), 2366 collect(Src, Path, In, Options), 2367 close_include(In, Refs)) 2368 ; true 2369 ) 2370 ) 2371 ; assert(uses_file(File, Src, '<not_found>')) 2372 ). 2373process_include(_, _).
include(File) referenced file. Note that we cannot
use prolog_open_source/2 because we should not safe/restore
the lexical context.2381open_include_file(Path, In, [Ref]) :- 2382 once(xref_input(_, Parent)), 2383 stream_property(Parent, encoding(Enc)), 2384 '$push_input_context'(xref_include), 2385 catch(( prolog:xref_open_source(Path, In) 2386 -> catch(set_stream(In, encoding(Enc)), 2387 error(_,_), true) % deal with non-file input 2388 ; include_encoding(Enc, Options), 2389 open(Path, read, In, Options) 2390 ), E, 2391 ( '$pop_input_context', throw(E))), 2392 catch(( peek_char(In, #) % Deal with #! script 2393 -> skip(In, 10) 2394 ; true 2395 ), E, 2396 ( close_include(In, []), throw(E))), 2397 asserta(xref_input(Path, In), Ref). 2398 2399include_encoding(wchar_t, []) :- !. 2400include_encoding(Enc, [encoding(Enc)]). 2401 2402 2403close_include(In, Refs) :- 2404 maplist(erase, Refs), 2405 close(In, [force(true)]), 2406 '$pop_input_context'.
2412process_foreign(Spec, Src) :- 2413 ground(Spec), 2414 current_foreign_library(Spec, Defined), 2415 !, 2416 ( xmodule(Module, Src) 2417 -> true 2418 ; Module = user 2419 ), 2420 process_foreign_defined(Defined, Module, Src). 2421process_foreign(_, _). 2422 2423process_foreign_defined([], _, _). 2424process_foreign_defined([H|T], M, Src) :- 2425 ( H = M:Head 2426 -> assert_foreign(Src, Head) 2427 ; assert_foreign(Src, H) 2428 ), 2429 process_foreign_defined(T, M, Src). 2430 2431 2432 /******************************* 2433 * CHR SUPPORT * 2434 *******************************/ 2435 2436/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2437This part of the file supports CHR. Our choice is between making special 2438hooks to make CHR expansion work and then handle the (complex) expanded 2439code or process the CHR source directly. The latter looks simpler, 2440though I don't like the idea of adding support for libraries to this 2441module. A file is supposed to be a CHR file if it uses a 2442use_module(library(chr) or contains a :- constraint/1 directive. As an 2443extra bonus we get the source-locations right :-) 2444- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 2445 2446process_chr(@(_Name, Rule), Src) :- 2447 mode(chr, Src), 2448 process_chr(Rule, Src). 2449process_chr(pragma(Rule, _Pragma), Src) :- 2450 mode(chr, Src), 2451 process_chr(Rule, Src). 2452process_chr(<=>(Head, Body), Src) :- 2453 mode(chr, Src), 2454 chr_head(Head, Src, H), 2455 chr_body(Body, H, Src). 2456process_chr(==>(Head, Body), Src) :- 2457 mode(chr, Src), 2458 chr_head(Head, H, Src), 2459 chr_body(Body, H, Src). 2460process_chr((:- chr_constraint(Decls)), Src) :- 2461 ( mode(chr, Src) 2462 -> true 2463 ; assert(mode(chr, Src)) 2464 ), 2465 chr_decls(Decls, Src). 2466 2467chr_decls((A,B), Src) => 2468 chr_decls(A, Src), 2469 chr_decls(B, Src). 2470chr_decls(Head, Src) => 2471 generalise_term(Head, Gen), 2472 ( declared(Gen, chr_constraint, Src, _) 2473 -> true 2474 ; current_source_line(Line), 2475 assertz(declared(Gen, chr_constraint, Src, Line)) 2476 ). 2477 2478chr_head(X, _, _) :- 2479 var(X), 2480 !. % Illegal. Warn? 2481chr_head(\(A,B), Src, H) :- 2482 chr_head(A, Src, H), 2483 process_body(B, H, Src). 2484chr_head((H0,B), Src, H) :- 2485 chr_defined(H0, Src, H), 2486 process_body(B, H, Src). 2487chr_head(H0, Src, H) :- 2488 chr_defined(H0, Src, H). 2489 2490chr_defined(X, _, _) :- 2491 var(X), 2492 !. 2493chr_defined(#(C,_Id), Src, C) :- 2494 !, 2495 assert_constraint(Src, C). 2496chr_defined(A, Src, A) :- 2497 assert_constraint(Src, A). 2498 2499chr_body(X, From, Src) :- 2500 var(X), 2501 !, 2502 process_body(X, From, Src). 2503chr_body('|'(Guard, Goals), H, Src) :- 2504 !, 2505 chr_body(Guard, H, Src), 2506 chr_body(Goals, H, Src). 2507chr_body(G, From, Src) :- 2508 process_body(G, From, Src). 2509 2510assert_constraint(_, Head) :- 2511 var(Head), 2512 !. 2513assert_constraint(Src, Head) :- 2514 constraint(Head, Src, _), 2515 !. 2516assert_constraint(Src, Head) :- 2517 generalise_term(Head, Term), 2518 current_source_line(Line), 2519 assert(constraint(Term, Src, Line)). 2520 2521 2522 /******************************** 2523 * PHASE 1 ASSERTIONS * 2524 ********************************/
2531assert_called(_, _, Var, _) :- 2532 var(Var), 2533 !. 2534assert_called(Src, From, Goal, Line) :- 2535 var(From), 2536 !, 2537 assert_called(Src, '<unknown>', Goal, Line). 2538assert_called(_, _, Goal, _) :- 2539 expand_hide_called(Goal), 2540 !. 2541assert_called(Src, Origin, M:G, Line) :- 2542 !, 2543 ( atom(M), 2544 callable(G) 2545 -> current_condition(Cond), 2546 ( xmodule(M, Src) % explicit call to own module 2547 -> assert_called(Src, Origin, G, Line) 2548 ; called(M:G, Src, Origin, Cond, Line) % already registered 2549 -> true 2550 ; hide_called(M:G, Src) % not interesting (now) 2551 -> true 2552 ; generalise(Origin, OTerm), 2553 generalise(G, GTerm) 2554 -> assert(called(M:GTerm, Src, OTerm, Cond, Line)) 2555 ; true 2556 ) 2557 ; true % call to variable module 2558 ). 2559assert_called(Src, _, Goal, _) :- 2560 ( xmodule(M, Src) 2561 -> M \== system 2562 ; M = user 2563 ), 2564 hide_called(M:Goal, Src), 2565 !. 2566assert_called(Src, Origin, Goal, Line) :- 2567 current_condition(Cond), 2568 ( called(Goal, Src, Origin, Cond, Line) 2569 -> true 2570 ; generalise(Origin, OTerm), 2571 generalise(Goal, Term) 2572 -> assert(called(Term, Src, OTerm, Cond, Line)) 2573 ; true 2574 ).
2582expand_hide_called(pce_principal:send_implementation(_, _, _)). 2583expand_hide_called(pce_principal:get_implementation(_, _, _, _)). 2584expand_hide_called(pce_principal:pce_lazy_get_method(_,_,_)). 2585expand_hide_called(pce_principal:pce_lazy_send_method(_,_,_)). 2586 2587assert_defined(Src, Goal) :- 2588 Goal = test(_Test), 2589 current_test_unit(Unit, Line), 2590 assert_called(Src, '<test_unit>'(Unit), Goal, Line), 2591 fail. 2592assert_defined(Src, Goal) :- 2593 Goal = test(_Test, _Options), 2594 current_test_unit(Unit, Line), 2595 assert_called(Src, '<test_unit>'(Unit), Goal, Line), 2596 fail. 2597assert_defined(Src, Goal) :- 2598 defined(Goal, Src, _), 2599 !. 2600assert_defined(Src, Goal) :- 2601 generalise(Goal, Term), 2602 current_source_line(Line), 2603 assert(defined(Term, Src, Line)). 2604 2605assert_foreign(Src, Goal) :- 2606 foreign(Goal, Src, _), 2607 !. 2608assert_foreign(Src, Goal) :- 2609 generalise(Goal, Term), 2610 current_source_line(Line), 2611 assert(foreign(Term, Src, Line)). 2612 2613assert_grammar_rule(Src, Goal) :- 2614 grammar_rule(Goal, Src), 2615 !. 2616assert_grammar_rule(Src, Goal) :- 2617 generalise(Goal, Term), 2618 assert(grammar_rule(Term, Src)).
true, re-export the
imported predicates.
2631assert_import(_, [], _, _, _) :- !. 2632assert_import(Src, [H|T], Export, From, Reexport) :- 2633 !, 2634 assert_import(Src, H, Export, From, Reexport), 2635 assert_import(Src, T, Export, From, Reexport). 2636assert_import(Src, except(Except), Export, From, Reexport) :- 2637 !, 2638 is_list(Export), 2639 !, 2640 except(Except, Export, Import), 2641 assert_import(Src, Import, _All, From, Reexport). 2642assert_import(Src, Import as Name, Export, From, Reexport) :- 2643 !, 2644 pi_to_head(Import, Term0), 2645 rename_goal(Term0, Name, Term), 2646 ( in_export_list(Term0, Export) 2647 -> assert(imported(Term, Src, From)), 2648 assert_reexport(Reexport, Src, Term) 2649 ; current_source_line(Line), 2650 assert_called(Src, '<directive>'(Line), Term0, Line) 2651 ). 2652assert_import(Src, Import, Export, From, Reexport) :- 2653 pi_to_head(Import, Term), 2654 !, 2655 ( in_export_list(Term, Export) 2656 -> assert(imported(Term, Src, From)), 2657 assert_reexport(Reexport, Src, Term) 2658 ; current_source_line(Line), 2659 assert_called(Src, '<directive>'(Line), Term, Line) 2660 ). 2661assert_import(Src, op(P,T,N), _, _, _) :- 2662 xref_push_op(Src, P,T,N). 2663 2664in_export_list(_Head, Export) :- 2665 var(Export), 2666 !. 2667in_export_list(Head, Export) :- 2668 member(PI, Export), 2669 pi_to_head(PI, Head). 2670 2671assert_reexport(false, _, _) :- !. 2672assert_reexport(true, Src, Term) :- 2673 assert(exported(Term, Src)).
2679process_import(M:PI, Src) :- 2680 pi_to_head(PI, Head), 2681 !, 2682 ( atom(M), 2683 current_module(M), 2684 module_property(M, file(From)) 2685 -> true 2686 ; From = '<unknown>' 2687 ), 2688 assert(imported(Head, Src, From)). 2689process_import(_, _).
2698assert_xmodule_callable([], _, _, _). 2699assert_xmodule_callable([PI|T], M, Src, From) :- 2700 ( pi_to_head(M:PI, Head) 2701 -> assert(imported(Head, Src, From)) 2702 ; true 2703 ), 2704 assert_xmodule_callable(T, M, Src, From).
2711assert_op(Src, op(P,T,M:N)) :-
2712 ( '$current_source_module'(M)
2713 -> Name = N
2714 ; Name = M:N
2715 ),
2716 ( xop(Src, op(P,T,Name))
2717 -> true
2718 ; assert(xop(Src, op(P,T,Name)))
2719 ).2726assert_module(Src, Module) :- 2727 xmodule(Module, Src), 2728 !. 2729assert_module(Src, Module) :- 2730 '$set_source_module'(Module), 2731 assert(xmodule(Module, Src)), 2732 ( module_property(Module, class(system)) 2733 -> retractall(xoption(Src, register_called(_))), 2734 assert(xoption(Src, register_called(all))) 2735 ; true 2736 ). 2737 2738assert_module_export(_, []) :- !. 2739assert_module_export(Src, [H|T]) :- 2740 !, 2741 assert_module_export(Src, H), 2742 assert_module_export(Src, T). 2743assert_module_export(Src, PI) :- 2744 pi_to_head(PI, Term), 2745 !, 2746 assert(exported(Term, Src)). 2747assert_module_export(Src, op(P, A, N)) :- 2748 xref_push_op(Src, P, A, N).
2754assert_module3([], _) :- !. 2755assert_module3([H|T], Src) :- 2756 !, 2757 assert_module3(H, Src), 2758 assert_module3(T, Src). 2759assert_module3(Option, Src) :- 2760 process_use_module(library(dialect/Option), Src, false).
call(Closure, PI,
Src). Handles both lists of specifications and (PI,...)
specifications.2769process_predicates(Closure, Preds, Src) :- 2770 is_list(Preds), 2771 !, 2772 process_predicate_list(Preds, Closure, Src). 2773process_predicates(Closure, as(Preds, _Options), Src) :- 2774 !, 2775 process_predicates(Closure, Preds, Src). 2776process_predicates(Closure, Preds, Src) :- 2777 process_predicate_comma(Preds, Closure, Src). 2778 2779process_predicate_list([], _, _). 2780process_predicate_list([H|T], Closure, Src) :- 2781 ( nonvar(H) 2782 -> call(Closure, H, Src) 2783 ; true 2784 ), 2785 process_predicate_list(T, Closure, Src). 2786 2787process_predicate_comma(Var, _, _) :- 2788 var(Var), 2789 !. 2790process_predicate_comma(M:(A,B), Closure, Src) :- 2791 !, 2792 process_predicate_comma(M:A, Closure, Src), 2793 process_predicate_comma(M:B, Closure, Src). 2794process_predicate_comma((A,B), Closure, Src) :- 2795 !, 2796 process_predicate_comma(A, Closure, Src), 2797 process_predicate_comma(B, Closure, Src). 2798process_predicate_comma(as(Spec, _Options), Closure, Src) :- 2799 !, 2800 process_predicate_comma(Spec, Closure, Src). 2801process_predicate_comma(A, Closure, Src) :- 2802 call(Closure, A, Src). 2803 2804 2805assert_dynamic(PI, Src) :- 2806 pi_to_head(PI, Term), 2807 ( thread_local(Term, Src, _) % dynamic after thread_local has 2808 -> true % no effect 2809 ; current_source_line(Line), 2810 assert(dynamic(Term, Src, Line)) 2811 ). 2812 2813assert_thread_local(PI, Src) :- 2814 pi_to_head(PI, Term), 2815 current_source_line(Line), 2816 assert(thread_local(Term, Src, Line)). 2817 2818assert_multifile(PI, Src) :- % :- multifile(Spec) 2819 pi_to_head(PI, Term), 2820 current_source_line(Line), 2821 assert(multifile(Term, Src, Line)). 2822 2823assert_public(PI, Src) :- % :- public(Spec) 2824 pi_to_head(PI, Term), 2825 current_source_line(Line), 2826 assert_called(Src, '<public>'(Line), Term, Line), 2827 assert(public(Term, Src, Line)). 2828 2829assert_export(PI, Src) :- % :- export(Spec) 2830 pi_to_head(PI, Term), 2831 !, 2832 assert(exported(Term, Src)).
2839pi_to_head(Var, _) :- 2840 var(Var), !, fail. 2841pi_to_head(M:PI, M:Term) :- 2842 !, 2843 pi_to_head(PI, Term). 2844pi_to_head(Name/Arity, Term) :- 2845 functor(Term, Name, Arity). 2846pi_to_head(Name//DCGArity, Term) :- 2847 Arity is DCGArity+2, 2848 functor(Term, Name, Arity). 2849 2850 2851assert_used_class(Src, Name) :- 2852 used_class(Name, Src), 2853 !. 2854assert_used_class(Src, Name) :- 2855 assert(used_class(Name, Src)). 2856 2857assert_defined_class(Src, Name, _Meta, _Super, _) :- 2858 defined_class(Name, _, _, Src, _), 2859 !. 2860assert_defined_class(_, _, _, -, _) :- !. % :- pce_extend_class 2861assert_defined_class(Src, Name, Meta, Super, Summary) :- 2862 current_source_line(Line), 2863 ( Summary == @(default) 2864 -> Atom = '' 2865 ; is_list(Summary) 2866 -> atom_codes(Atom, Summary) 2867 ; string(Summary) 2868 -> atom_concat(Summary, '', Atom) 2869 ), 2870 assert(defined_class(Name, Super, Atom, Src, Line)), 2871 ( Meta = @(_) 2872 -> true 2873 ; assert_used_class(Src, Meta) 2874 ), 2875 assert_used_class(Src, Super). 2876 2877assert_defined_class(Src, Name, imported_from(_File)) :- 2878 defined_class(Name, _, _, Src, _), 2879 !. 2880assert_defined_class(Src, Name, imported_from(File)) :- 2881 assert(defined_class(Name, _, '', Src, file(File))). 2882 2883 2884 /******************************** 2885 * UTILITIES * 2886 ********************************/
2892generalise(Var, Var) :- 2893 var(Var), 2894 !. % error? 2895generalise(pce_principal:send_implementation(Id, _, _), 2896 pce_principal:send_implementation(Id, _, _)) :- 2897 atom(Id), 2898 !. 2899generalise(pce_principal:get_implementation(Id, _, _, _), 2900 pce_principal:get_implementation(Id, _, _, _)) :- 2901 atom(Id), 2902 !. 2903generalise('<directive>'(Line), '<directive>'(Line)) :- !. 2904generalise(test(Test), test(Test)) :- 2905 current_test_unit(_,_), 2906 ground(Test), 2907 !. 2908generalise(test(Test, _), test(Test, _)) :- 2909 current_test_unit(_,_), 2910 ground(Test), 2911 !. 2912generalise('<test_unit>'(Line), '<test_unit>'(Line)) :- !. 2913generalise(Module:Goal0, Module:Goal) :- 2914 atom(Module), 2915 !, 2916 generalise(Goal0, Goal). 2917generalise(Term0, Term) :- 2918 callable(Term0), 2919 generalise_term(Term0, Term). 2920 2921 2922 /******************************* 2923 * SOURCE MANAGEMENT * 2924 *******************************/ 2925 2926/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2927This section of the file contains hookable predicates to reason about 2928sources. The built-in code here can only deal with files. The XPCE 2929library(pce_prolog_xref) provides hooks to deal with XPCE objects, so we 2930can do cross-referencing on PceEmacs edit buffers. Other examples for 2931hooking can be databases, (HTTP) URIs, etc. 2932- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 2933 2934:- multifile 2935 prolog:xref_source_directory/2, % +Source, -Dir 2936 prolog:xref_source_file/3. % +Spec, -Path, +Options
2944xref_source_file(Plain, File, Source) :- 2945 xref_source_file(Plain, File, Source, []). 2946 2947xref_source_file(QSpec, File, Source, Options) :- 2948 nonvar(QSpec), QSpec = _:Spec, 2949 !, 2950 must_be(acyclic, Spec), 2951 xref_source_file(Spec, File, Source, Options). 2952xref_source_file(Spec, File, _Source, _Options) :- 2953 is_stream(Spec), !, 2954 File = Spec. 2955xref_source_file(Spec, File, Source, Options) :- 2956 nonvar(Spec), 2957 prolog:xref_source_file(Spec, File, 2958 [ relative_to(Source) 2959 | Options 2960 ]), 2961 !. 2962xref_source_file(Plain, File, Source, Options) :- 2963 atom(Plain), 2964 \+ is_absolute_file_name(Plain), 2965 ( prolog:xref_source_directory(Source, Dir) 2966 -> true 2967 ; atom(Source), 2968 file_directory_name(Source, Dir) 2969 ), 2970 atomic_list_concat([Dir, /, Plain], Spec0), 2971 absolute_file_name(Spec0, Spec), 2972 do_xref_source_file(Spec, File, Options), 2973 !. 2974xref_source_file(Spec, File, Source, Options) :- 2975 do_xref_source_file(Spec, File, 2976 [ relative_to(Source) 2977 | Options 2978 ]), 2979 !. 2980xref_source_file(_, _, _, Options) :- 2981 option(silent(true), Options), 2982 !, 2983 fail. 2984xref_source_file(Spec, _, Src, _Options) :- 2985 verbose(Src), 2986 print_message(warning, error(existence_error(file, Spec), _)), 2987 fail. 2988 2989do_xref_source_file(Spec, File, Options) :- 2990 nonvar(Spec), 2991 option(file_type(Type), Options, prolog), 2992 absolute_file_name(Spec, File0, 2993 [ file_type(Type), 2994 access(read), 2995 file_errors(fail) 2996 ]), 2997 !, 2998 qlf_pl_file(File0, File). 2999do_xref_source_file(Spec, File, Options) :- 3000 atom(Spec), % handle absolute /file/to/source.pl without sources 3001 file_name_extension(Base, Ext, Spec), 3002 user:prolog_file_type(Ext, source), 3003 option(file_type(prolog), Options, prolog), 3004 absolute_file_name(Base, File0, 3005 [ file_type(prolog), 3006 access(read), 3007 file_errors(fail) 3008 ]), 3009 qlf_pl_file(File0, File).
3013qlf_pl_file(QlfFile, PlFile) :- 3014 nonvar(QlfFile), 3015 is_qlf_file(QlfFile), 3016 !, 3017 '$qlf_module'(QlfFile, Info), 3018 #{file:PlFile} :< Info. 3019qlf_pl_file(QlfFile, PlFile) :- 3020 nonvar(PlFile), 3021 !, 3022 ( file_name_extension(Base, Ext, PlFile), 3023 user:prolog_file_type(Ext, source) 3024 -> true 3025 ), 3026 ( user:prolog_file_type(QlfExt, qlf), 3027 file_name_extension(Base, QlfExt, QlfFile), 3028 exists_file(QlfFile) 3029 -> true 3030 ), 3031 '$qlf_module'(QlfFile, Info), 3032 #{file:PlFile} :< Info, 3033 !. 3034qlf_pl_file(PlFile, PlFile). 3035 3036is_qlf_file(QlfFile) :- 3037 file_name_extension(_, Ext, QlfFile), 3038 user:prolog_file_type(Ext, qlf), 3039 !.
3045canonical_source(Source, Src) :-
3046 ( ground(Source)
3047 -> prolog_canonical_source(Source, Src)
3048 ; Source = Src
3049 ).name()
goals.3056goal_name_arity(Goal, Name, Arity) :- 3057 ( compound(Goal) 3058 -> compound_name_arity(Goal, Name, Arity) 3059 ; atom(Goal) 3060 -> Name = Goal, Arity = 0 3061 ). 3062 3063generalise_term(Specific, General) :- 3064 ( compound(Specific) 3065 -> compound_name_arity(Specific, Name, Arity), 3066 compound_name_arity(General, Name, Arity) 3067 ; General = Specific 3068 ). 3069 3070functor_name(Term, Name) :- 3071 ( compound(Term) 3072 -> compound_name_arity(Term, Name, _) 3073 ; atom(Term) 3074 -> Name = Term 3075 ). 3076 3077rename_goal(Goal0, Name, Goal) :- 3078 ( compound(Goal0) 3079 -> compound_name_arity(Goal0, _, Arity), 3080 compound_name_arity(Goal, Name, Arity) 3081 ; Goal = Name 3082 ). 3083 3084 3085 /******************************* 3086 * MESSAGES * 3087 *******************************/< 3088 3089:- multifile prolog:message//1. 3090 3091prologmessage(meta_predicate_after_call(Decl, By)) --> 3092 { pi_head(ByPI, By) }, 3093 [ ansi(code, ':- meta_predicate(~p)', [Decl]), 3094 ' declaration appears after call from '-[], 3095 ansi(code, '~p', [ByPI]) 3096 ]
Prolog cross-referencer data collection
This library collects information on defined and used objects in Prolog source files. Typically these are predicates, but we expect the library to deal with other types of objects in the future. The library is a building block for tools doing dependency tracking in applications. Dependency tracking is useful to reveal the structure of an unknown program or detect missing components at compile time, but also for program transformation or minimising a program saved state by only saving the reachable objects.
The library is exploited by two graphical tools in the SWI-Prolog environment: the XPCE front-end started by gxref/0, and library(prolog_colour), which exploits this library for its syntax highlighting.
For all predicates described below, Source is the source that is processed. This is normally a filename in any notation acceptable to the file loading predicates (see load_files/2). Input handling is done by the library(prolog_source), which may be hooked to process any source that can be translated into a Prolog stream holding Prolog source text. Callable is a callable term (see callable/1). Callables do not carry a module qualifier unless the referred predicate is not in the module defined by Source.