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 current_prolog_flag(xref, Xref), 441 ( Xref == true 442 -> call(Goal) 443 ; setup_call_cleanup( 444 set_prolog_flag(xref, true), 445 Goal, 446 set_prolog_flag(xref, Xref)) 447 ).
457set_initial_mode(_Stream, Options) :- 458 option(module(Module), Options), 459 !, 460 '$set_source_module'(Module). 461set_initial_mode(Stream, _) :- 462 stream_property(Stream, file_name(Path)), 463 source_file_property(Path, load_context(M, _, Opts)), 464 !, 465 '$set_source_module'(M), 466 ( option(dialect(Dialect), Opts) 467 -> expects_dialect(Dialect) 468 ; true 469 ). 470set_initial_mode(_, _) :- 471 '$set_source_module'(user).
477xref_input_stream(Stream) :-
478 xref_input(_, Var),
479 !,
480 Stream = Var.487xref_push_op(Src, P, T, N0) :- 488 '$current_source_module'(M0), 489 strip_module(M0:N0, M, N), 490 ( is_list(N), 491 N \== [] 492 -> maplist(push_op(Src, P, T, M), N) 493 ; push_op(Src, P, T, M, N) 494 ). 495 496push_op(Src, P, T, M0, N0) :- 497 strip_module(M0:N0, M, N), 498 Name = M:N, 499 valid_op(op(P,T,Name)), 500 push_op(P, T, Name), 501 assert_op(Src, op(P,T,Name)), 502 debug(xref(op), ':- ~w.', [op(P,T,Name)]). 503 504valid_op(op(P,T,M:N)) :- 505 atom(M), 506 valid_op_name(N), 507 integer(P), 508 between(0, 1200, P), 509 atom(T), 510 op_type(T). 511 512valid_op_name(N) :- 513 atom(N), 514 !. 515valid_op_name(N) :- 516 N == []. 517 518op_type(xf). 519op_type(yf). 520op_type(fx). 521op_type(fy). 522op_type(xfx). 523op_type(xfy). 524op_type(yfx).
530xref_set_prolog_flag(Flag, Value, Src, Line) :- 531 atom(Flag), 532 !, 533 assertz(xflag(Flag, Value, Src, Line)). 534xref_set_prolog_flag(_, _, _, _).
540xref_clean(Source) :- 541 prolog_canonical_source(Source, Src), 542 retractall(called(_, Src, _Origin, _Cond, _Line)), 543 retractall(dynamic(_, Src, Line)), 544 retractall(multifile(_, Src, Line)), 545 retractall(public(_, Src, Line)), 546 retractall(declared(_, _, Src, Line)), 547 retractall(defined(_, Src, Line)), 548 retractall(meta_goal(_, _, Src)), 549 retractall(foreign(_, Src, Line)), 550 retractall(constraint(_, Src, Line)), 551 retractall(imported(_, Src, _From)), 552 retractall(exported(_, Src)), 553 retractall(uses_file(_, Src, _)), 554 retractall(xmodule(_, Src)), 555 retractall(xop(Src, _)), 556 retractall(grammar_rule(_, Src)), 557 retractall(xoption(Src, _)), 558 retractall(xflag(_Name, _Value, Src, Line)), 559 retractall(source(Src, _)), 560 retractall(used_class(_, Src)), 561 retractall(defined_class(_, _, _, Src, _)), 562 retractall(mode(_, Src)), 563 retractall(module_comment(Src, _, _)), 564 retractall(pred_comment(_, Src, _, _)), 565 retractall(pred_comment_link(_, Src, _)), 566 retractall(pred_mode(_, Src, _)). 567 568 569 /******************************* 570 * READ RESULTS * 571 *******************************/
577xref_current_source(Source) :-
578 source(Source, _Time).
585xref_done(Source, Time) :-
586 prolog_canonical_source(Source, Src),
587 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.
609xref_called(Source, Called, By) :- 610 xref_called(Source, Called, By, _). 611 612xref_called(Source, Called, By, Cond) :- 613 canonical_source(Source, Src), 614 distinct(Called-By, called(Called, Src, By, Cond, _)). 615 616xref_called(Source, Called, By, Cond, Line) :- 617 canonical_source(Source, Src), 618 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)640xref_defined(Source, Called, How) :- 641 nonvar(Source), 642 !, 643 canonical_source(Source, Src), 644 xref_defined2(How, Src, Called). 645xref_defined(Source, Called, How) :- 646 xref_defined2(How, Src, Called), 647 canonical_source(Source, Src). 648 649xref_defined2(dynamic(Line), Src, Called) :- 650 dynamic(Called, Src, Line). 651xref_defined2(thread_local(Line), Src, Called) :- 652 thread_local(Called, Src, Line). 653xref_defined2(multifile(Line), Src, Called) :- 654 multifile(Called, Src, Line). 655xref_defined2(public(Line), Src, Called) :- 656 public(Called, Src, Line). 657xref_defined2(local(Line), Src, Called) :- 658 defined(Called, Src, Line). 659xref_defined2(foreign(Line), Src, Called) :- 660 foreign(Called, Src, Line). 661xref_defined2(constraint(Line), Src, Called) :- 662 ( constraint(Called, Src, Line) 663 -> true 664 ; declared(Called, chr_constraint, Src, Line) 665 ). 666xref_defined2(imported(From), Src, Called) :- 667 imported(Called, Src, From). 668xref_defined2(dcg, Src, Called) :- 669 grammar_rule(Called, Src).
677xref_definition_line(local(Line), Line). 678xref_definition_line(dynamic(Line), Line). 679xref_definition_line(thread_local(Line), Line). 680xref_definition_line(multifile(Line), Line). 681xref_definition_line(public(Line), Line). 682xref_definition_line(constraint(Line), Line). 683xref_definition_line(foreign(Line), Line).
690xref_exported(Source, Called) :-
691 prolog_canonical_source(Source, Src),
692 exported(Called, Src).698xref_module(Source, Module) :- 699 nonvar(Source), 700 !, 701 prolog_canonical_source(Source, Src), 702 xmodule(Module, Src). 703xref_module(Source, Module) :- 704 xmodule(Module, Src), 705 prolog_canonical_source(Source, Src).
715xref_uses_file(Source, Spec, Path) :-
716 prolog_canonical_source(Source, Src),
717 uses_file(Spec, Src, Path).
727xref_op(Source, Op) :-
728 prolog_canonical_source(Source, Src),
729 xop(Src, Op).737xref_prolog_flag(Source, Flag, Value, Line) :- 738 prolog_canonical_source(Source, Src), 739 xflag(Flag, Value, Src, Line). 740 741xref_built_in(Head) :- 742 system_predicate(Head). 743 744xref_used_class(Source, Class) :- 745 prolog_canonical_source(Source, Src), 746 used_class(Class, Src). 747 748xref_defined_class(Source, Class, local(Line, Super, Summary)) :- 749 prolog_canonical_source(Source, Src), 750 defined_class(Class, Super, Summary, Src, Line), 751 integer(Line), 752 !. 753xref_defined_class(Source, Class, file(File)) :- 754 prolog_canonical_source(Source, Src), 755 defined_class(Class, _, _, Src, file(File)). 756 757:- thread_local 758 current_cond/1, 759 source_line/1, 760 current_test_unit/2. 761 762current_source_line(Line) :- 763 source_line(Var), 764 !, 765 Line = Var.
773collect(Src, File, In, Options) :- 774 ( Src == File 775 -> SrcSpec = Line 776 ; SrcSpec = (File:Line) 777 ), 778 ( current_prolog_flag(xref_store_comments, OldStore) 779 -> true 780 ; OldStore = false 781 ), 782 option(comments(CommentHandling), Options, collect), 783 ( CommentHandling == ignore 784 -> CommentOptions = [], 785 Comments = [] 786 ; CommentHandling == store 787 -> CommentOptions = [ process_comment(true) ], 788 Comments = [], 789 set_prolog_flag(xref_store_comments, true) 790 ; CommentOptions = [ comments(Comments) ] 791 ), 792 repeat, 793 E = error(_,_), 794 catch(prolog_read_source_term( 795 In, Term, Expanded, 796 [ term_position(TermPos) 797 | CommentOptions 798 ]), 799 E, report_syntax_error(E, Src, [])), 800 update_condition(Term), 801 stream_position_data(line_count, TermPos, Line), 802 setup_call_cleanup( 803 asserta(source_line(SrcSpec), Ref), 804 catch(process(Expanded, Comments, Term, TermPos, Src, EOF), 805 E, print_message(error, E)), 806 erase(Ref)), 807 EOF == true, 808 !, 809 set_prolog_flag(xref_store_comments, OldStore). 810 811report_syntax_error(_, _, Options) :- 812 option(silent(true), Options), 813 !, 814 fail. 815report_syntax_error(E, Src, _Options) :- 816 ( verbose(Src) 817 -> print_message(error, E) 818 ; true 819 ), 820 fail.
826update_condition((:-Directive)) :- 827 !, 828 update_cond(Directive). 829update_condition(_). 830 831update_cond(if(Cond)) :- 832 !, 833 asserta(current_cond(Cond)). 834update_cond(else) :- 835 retract(current_cond(C0)), 836 !, 837 assert(current_cond(\+C0)). 838update_cond(elif(Cond)) :- 839 retract(current_cond(C0)), 840 !, 841 assert(current_cond((\+C0,Cond))). 842update_cond(endif) :- 843 retract(current_cond(_)), 844 !. 845update_cond(_).
852current_condition(Condition) :- 853 \+ current_cond(_), 854 !, 855 Condition = true. 856current_condition(Condition) :- 857 findall(C, current_cond(C), List), 858 list_to_conj(List, Condition). 859 860list_to_conj([], true). 861list_to_conj([C], C) :- !. 862list_to_conj([H|T], (H,C)) :- 863 list_to_conj(T, C). 864 865 866 /******************************* 867 * PROCESS * 868 *******************************/
880process(Expanded, Comments, Term0, TermPos, Src, EOF) :- 881 is_list(Expanded), % term_expansion into list. 882 !, 883 ( member(Term, Expanded), 884 process(Term, Term0, Src), 885 Term == end_of_file 886 -> EOF = true 887 ; EOF = false 888 ), 889 xref_comments(Comments, TermPos, Src). 890process(end_of_file, _, _, _, _, true) :- 891 !. 892process(Term, Comments, Term0, TermPos, Src, false) :- 893 process(Term, Term0, Src), 894 xref_comments(Comments, TermPos, Src).
898process(_, Term0, _) :- 899 ignore_raw_term(Term0), 900 !. 901process(Head :- Body, Head0 --> _, Src) :- 902 pi_head(F/A, Head), 903 pi_head(F/A0, Head0), 904 A =:= A0 + 2, 905 !, 906 assert_grammar_rule(Src, Head), 907 process((Head :- Body), Src). 908process(Term, _Term0, Src) :- 909 process(Term, Src). 910 911ignore_raw_term((:- predicate_options(_,_,_))).
915process(Var, _) :- 916 var(Var), 917 !. % Warn? 918process(end_of_file, _) :- !. 919process((:- Directive), Src) :- 920 !, 921 process_directive(Directive, Src), 922 !. 923process((?- Directive), Src) :- 924 !, 925 process_directive(Directive, Src), 926 !. 927process((Head :- Body), Src) :- 928 !, 929 assert_defined(Src, Head), 930 process_body(Body, Head, Src). 931process((Left => Body), Src) :- 932 !, 933 ( nonvar(Left), 934 Left = (Head, Guard) 935 -> assert_defined(Src, Head), 936 process_body(Guard, Head, Src), 937 process_body(Body, Head, Src) 938 ; assert_defined(Src, Left), 939 process_body(Body, Left, Src) 940 ). 941process(?=>(Head, Body), Src) :- 942 !, 943 assert_defined(Src, Head), 944 process_body(Body, Head, Src). 945process('$source_location'(_File, _Line):Clause, Src) :- 946 !, 947 process(Clause, Src). 948process(Term, Src) :- 949 process_chr(Term, Src), 950 !. 951process(M:(Head :- Body), Src) :- 952 !, 953 process((M:Head :- M:Body), Src). 954process(Head, Src) :- 955 assert_defined(Src, Head). 956 957 958 /******************************* 959 * COMMENTS * 960 *******************************/
964xref_comments([], _Pos, _Src). 965:- if(current_predicate(parse_comment/3)). 966xref_comments([Pos-Comment|T], TermPos, Src) :- 967 ( Pos @> TermPos % comments inside term 968 -> true 969 ; stream_position_data(line_count, Pos, Line), 970 FilePos = Src:Line, 971 ( parse_comment(Comment, FilePos, Parsed) 972 -> assert_comments(Parsed, Src) 973 ; true 974 ), 975 xref_comments(T, TermPos, Src) 976 ). 977 978assert_comments([], _). 979assert_comments([H|T], Src) :- 980 assert_comment(H, Src), 981 assert_comments(T, Src). 982 983assert_comment(section(_Id, Title, Comment), Src) :- 984 assertz(module_comment(Src, Title, Comment)). 985assert_comment(predicate(PI, Summary, Comment), Src) :- 986 pi_to_head(PI, Src, Head), 987 assertz(pred_comment(Head, Src, Summary, Comment)). 988assert_comment(link(PI, PITo), Src) :- 989 pi_to_head(PI, Src, Head), 990 pi_to_head(PITo, Src, HeadTo), 991 assertz(pred_comment_link(Head, Src, HeadTo)). 992assert_comment(mode(Head, Det), Src) :- 993 assertz(pred_mode(Head, Src, Det)). 994 995pi_to_head(PI, Src, Head) :- 996 pi_to_head(PI, Head0), 997 ( Head0 = _:_ 998 -> strip_module(Head0, M, Plain), 999 ( xmodule(M, Src) 1000 -> Head = Plain 1001 ; Head = M:Plain 1002 ) 1003 ; Head = Head0 1004 ). 1005:- endif.
1011xref_comment(Source, Title, Comment) :-
1012 canonical_source(Source, Src),
1013 module_comment(Src, Title, Comment).
1019xref_comment(Source, Head, Summary, Comment) :-
1020 canonical_source(Source, Src),
1021 ( pred_comment(Head, Src, Summary, Comment)
1022 ; pred_comment_link(Head, Src, HeadTo),
1023 pred_comment(HeadTo, Src, Summary, Comment)
1024 ).
1031xref_mode(Source, Mode, Det) :-
1032 canonical_source(Source, Src),
1033 pred_mode(Mode, Src, Det).1040xref_option(Source, Option) :- 1041 canonical_source(Source, Src), 1042 xoption(Src, Option). 1043 1044 1045 /******************************** 1046 * DIRECTIVES * 1047 ********************************/ 1048 1049process_directive(Var, _) :- 1050 var(Var), 1051 !. % error, but that isn't our business 1052process_directive(Dir, _Src) :- 1053 debug(xref(directive), 'Processing :- ~q', [Dir]), 1054 fail. 1055process_directive((A,B), Src) :- % TBD: what about other control 1056 !, 1057 process_directive(A, Src), % structures? 1058 process_directive(B, Src). 1059process_directive(List, Src) :- 1060 is_list(List), 1061 !, 1062 process_directive(consult(List), Src). 1063process_directive(use_module(File, Import), Src) :- 1064 process_use_module2(File, Import, Src, false). 1065process_directive(autoload(File, Import), Src) :- 1066 process_use_module2(File, Import, Src, false). 1067process_directive(require(Import), Src) :- 1068 process_requires(Import, Src). 1069process_directive(expects_dialect(Dialect), Src) :- 1070 process_directive(use_module(library(dialect/Dialect)), Src), 1071 expects_dialect(Dialect). 1072process_directive(reexport(File, Import), Src) :- 1073 process_use_module2(File, Import, Src, true). 1074process_directive(reexport(Modules), Src) :- 1075 process_use_module(Modules, Src, true). 1076process_directive(autoload(Modules), Src) :- 1077 process_use_module(Modules, Src, false). 1078process_directive(use_module(Modules), Src) :- 1079 process_use_module(Modules, Src, false). 1080process_directive(consult(Modules), Src) :- 1081 process_use_module(Modules, Src, false). 1082process_directive(ensure_loaded(Modules), Src) :- 1083 process_use_module(Modules, Src, false). 1084process_directive(load_files(Files, _Options), Src) :- 1085 process_use_module(Files, Src, false). 1086process_directive(include(Files), Src) :- 1087 process_include(Files, Src). 1088process_directive(dynamic(Dynamic), Src) :- 1089 process_predicates(assert_dynamic, Dynamic, Src). 1090process_directive(dynamic(Dynamic, _Options), Src) :- 1091 process_predicates(assert_dynamic, Dynamic, Src). 1092process_directive(thread_local(Dynamic), Src) :- 1093 process_predicates(assert_thread_local, Dynamic, Src). 1094process_directive(multifile(Dynamic), Src) :- 1095 process_predicates(assert_multifile, Dynamic, Src). 1096process_directive(public(Public), Src) :- 1097 process_predicates(assert_public, Public, Src). 1098process_directive(export(Export), Src) :- 1099 process_predicates(assert_export, Export, Src). 1100process_directive(import(Import), Src) :- 1101 process_import(Import, Src). 1102process_directive(module(Module, Export), Src) :- 1103 assert_module(Src, Module), 1104 assert_module_export(Src, Export). 1105process_directive(module(Module, Export, Import), Src) :- 1106 assert_module(Src, Module), 1107 assert_module_export(Src, Export), 1108 assert_module3(Import, Src). 1109process_directive(begin_tests(Unit, _Options), Src) :- 1110 enter_test_unit(Unit, Src). 1111process_directive(begin_tests(Unit), Src) :- 1112 enter_test_unit(Unit, Src). 1113process_directive(end_tests(Unit), Src) :- 1114 leave_test_unit(Unit, Src). 1115process_directive('$set_source_module'(system), Src) :- 1116 assert_module(Src, system). % hack for handling boot/init.pl 1117process_directive(pce_begin_class_definition(Name, Meta, Super, Doc), Src) :- 1118 assert_defined_class(Src, Name, Meta, Super, Doc). 1119process_directive(pce_autoload(Name, From), Src) :- 1120 assert_defined_class(Src, Name, imported_from(From)). 1121 1122process_directive(op(P, A, N), Src) :- 1123 xref_push_op(Src, P, A, N). 1124process_directive(set_prolog_flag(Flag, Value), Src) :- 1125 ( Flag == character_escapes 1126 -> set_prolog_flag(character_escapes, Value) 1127 ; true 1128 ), 1129 current_source_line(Line), 1130 xref_set_prolog_flag(Flag, Value, Src, Line). 1131process_directive(style_check(X), _) :- 1132 style_check(X). 1133process_directive(encoding(Enc), _) :- 1134 ( xref_input_stream(Stream) 1135 -> catch(set_stream(Stream, encoding(Enc)), error(_,_), true) 1136 ; true % can this happen? 1137 ). 1138process_directive(pce_expansion:push_compile_operators, _) :- 1139 '$current_source_module'(SM), 1140 call(pce_expansion:push_compile_operators(SM)). % call to avoid xref 1141process_directive(pce_expansion:pop_compile_operators, _) :- 1142 call(pce_expansion:pop_compile_operators). 1143process_directive(meta_predicate(Meta), Src) :- 1144 process_meta_predicate(Meta, Src). 1145process_directive(arithmetic_function(FSpec), Src) :- 1146 arith_callable(FSpec, Goal), 1147 !, 1148 current_source_line(Line), 1149 assert_called(Src, '<directive>'(Line), Goal, Line). 1150process_directive(format_predicate(_, Goal), Src) :- 1151 !, 1152 current_source_line(Line), 1153 assert_called(Src, '<directive>'(Line), Goal, Line). 1154process_directive(if(Cond), Src) :- 1155 !, 1156 current_source_line(Line), 1157 assert_called(Src, '<directive>'(Line), Cond, Line). 1158process_directive(elif(Cond), Src) :- 1159 !, 1160 current_source_line(Line), 1161 assert_called(Src, '<directive>'(Line), Cond, Line). 1162process_directive(else, _) :- !. 1163process_directive(endif, _) :- !. 1164process_directive(Goal, Src) :- 1165 current_source_line(Line), 1166 process_body(Goal, '<directive>'(Line), Src).
1172process_meta_predicate((A,B), Src) :- 1173 !, 1174 process_meta_predicate(A, Src), 1175 process_meta_predicate(B, Src). 1176process_meta_predicate(Decl, Src) :- 1177 process_meta_head(Src, Decl). 1178 1179process_meta_head(Src, Decl) :- % swapped arguments for maplist 1180 compound(Decl), 1181 compound_name_arity(Decl, Name, Arity), 1182 compound_name_arity(Head, Name, Arity), 1183 meta_args(1, Arity, Decl, Head, Meta), 1184 ( ( prolog:meta_goal(Head, _) 1185 ; prolog:called_by(Head, _, _, _) 1186 ; prolog:called_by(Head, _) 1187 ; meta_goal(Head, Meta, _Src) 1188 ) 1189 -> true 1190 ; warn_late_meta_predicate(Decl, Src), 1191 retractall(meta_goal(Head, _, Src)), 1192 assert(meta_goal(Head, Meta, Src)) 1193 ). 1194 1195meta_args(I, Arity, _, _, []) :- 1196 I > Arity, 1197 !. 1198meta_args(I, Arity, Decl, Head, [H|T]) :- % 0 1199 arg(I, Decl, 0), 1200 !, 1201 arg(I, Head, H), 1202 I2 is I + 1, 1203 meta_args(I2, Arity, Decl, Head, T). 1204meta_args(I, Arity, Decl, Head, [H|T]) :- % ^ 1205 arg(I, Decl, ^), 1206 !, 1207 arg(I, Head, EH), 1208 setof_goal(EH, H), 1209 I2 is I + 1, 1210 meta_args(I2, Arity, Decl, Head, T). 1211meta_args(I, Arity, Decl, Head, [//(H)|T]) :- 1212 arg(I, Decl, //), 1213 !, 1214 arg(I, Head, H), 1215 I2 is I + 1, 1216 meta_args(I2, Arity, Decl, Head, T). 1217meta_args(I, Arity, Decl, Head, [H+A|T]) :- % I --> H+I 1218 arg(I, Decl, A), 1219 integer(A), A > 0, 1220 !, 1221 arg(I, Head, H), 1222 I2 is I + 1, 1223 meta_args(I2, Arity, Decl, Head, T). 1224meta_args(I, Arity, Decl, Head, Meta) :- 1225 I2 is I + 1, 1226 meta_args(I2, Arity, Decl, Head, Meta). 1227 1228 1229warn_late_meta_predicate(Decl, Src) :- 1230 xref_called(Src, Decl, By), 1231 !, 1232 print_message(warning, meta_predicate_after_call(Decl, By)). 1233warn_late_meta_predicate(_, _). 1234 1235 1236 /******************************** 1237 * BODY * 1238 ********************************/
1247xref_meta(Source, Head, Called) :-
1248 canonical_source(Source, Src),
1249 xref_meta_src(Head, Called, Src).1264xref_meta_src(Head, Called, Src) :- 1265 meta_goal(Head, Called, Src), 1266 !. 1267xref_meta_src(Head, Called, _) :- 1268 xref_meta(Head, Called), 1269 !. 1270xref_meta_src(Head, Called, _) :- 1271 compound(Head), 1272 compound_name_arity(Head, Name, Arity), 1273 apply_pred(Name), 1274 Arity > 5, 1275 !, 1276 Extra is Arity - 1, 1277 arg(1, Head, G), 1278 Called = [G+Extra]. 1279xref_meta_src(Head, Called, _) :- 1280 with_xref(predicate_property('$xref_tmp':Head, meta_predicate(Meta))), 1281 !, 1282 Meta =.. [_|Args], 1283 meta_args(Args, 1, Head, Called). 1284 1285meta_args([], _, _, []). 1286meta_args([H0|T0], I, Head, [H|T]) :- 1287 xargs(H0, N), 1288 !, 1289 arg(I, Head, A), 1290 ( N == 0 1291 -> H = A 1292 ; H = (A+N) 1293 ), 1294 I2 is I+1, 1295 meta_args(T0, I2, Head, T). 1296meta_args([_|T0], I, Head, T) :- 1297 I2 is I+1, 1298 meta_args(T0, I2, Head, T). 1299 1300xargs(N, N) :- integer(N), !. 1301xargs(//, 2). 1302xargs(^, 0). 1303 1304apply_pred(call). % built-in 1305apply_pred(maplist). % library(apply_macros) 1306 1307xref_meta((A, B), [A, B]). 1308xref_meta((A; B), [A, B]). 1309xref_meta((A| B), [A, B]). 1310xref_meta((A -> B), [A, B]). 1311xref_meta((A *-> B), [A, B]). 1312xref_meta(findall(_V,G,_L), [G]). 1313xref_meta(findall(_V,G,_L,_T), [G]). 1314xref_meta(findnsols(_N,_V,G,_L), [G]). 1315xref_meta(findnsols(_N,_V,G,_L,_T), [G]). 1316xref_meta(setof(_V, EG, _L), [G]) :- 1317 setof_goal(EG, G). 1318xref_meta(bagof(_V, EG, _L), [G]) :- 1319 setof_goal(EG, G). 1320xref_meta(forall(A, B), [A, B]). 1321xref_meta(maplist(G,_), [G+1]). 1322xref_meta(maplist(G,_,_), [G+2]). 1323xref_meta(maplist(G,_,_,_), [G+3]). 1324xref_meta(maplist(G,_,_,_,_), [G+4]). 1325xref_meta(map_list_to_pairs(G,_,_), [G+2]). 1326xref_meta(map_assoc(G, _), [G+1]). 1327xref_meta(map_assoc(G, _, _), [G+2]). 1328xref_meta(checklist(G, _L), [G+1]). 1329xref_meta(sublist(G, _, _), [G+1]). 1330xref_meta(include(G, _, _), [G+1]). 1331xref_meta(exclude(G, _, _), [G+1]). 1332xref_meta(partition(G, _, _, _, _), [G+2]). 1333xref_meta(partition(G, _, _, _),[G+1]). 1334xref_meta(call(G), [G]). 1335xref_meta(call(G, _), [G+1]). 1336xref_meta(call(G, _, _), [G+2]). 1337xref_meta(call(G, _, _, _), [G+3]). 1338xref_meta(call(G, _, _, _, _), [G+4]). 1339xref_meta(not(G), [G]). 1340xref_meta(notrace(G), [G]). 1341xref_meta('$notrace'(G), [G]). 1342xref_meta(\+(G), [G]). 1343xref_meta(ignore(G), [G]). 1344xref_meta(once(G), [G]). 1345xref_meta(initialization(G), [G]). 1346xref_meta(initialization(G,_), [G]). 1347xref_meta(retract(Rule), [G]) :- head_of(Rule, G). 1348xref_meta(clause(G, _), [G]). 1349xref_meta(clause(G, _, _), [G]). 1350xref_meta(phrase(G, _A), [//(G)]). 1351xref_meta(phrase(G, _A, _R), [//(G)]). 1352xref_meta(call_dcg(G, _A, _R), [//(G)]). 1353xref_meta(phrase_from_file(G,_),[//(G)]). 1354xref_meta(catch(A, _, B), [A, B]). 1355xref_meta(catch_with_backtrace(A, _, B), [A, B]). 1356xref_meta(thread_create(A,_,_), [A]). 1357xref_meta(thread_create(A,_), [A]). 1358xref_meta(thread_signal(_,A), [A]). 1359xref_meta(thread_idle(A,_), [A]). 1360xref_meta(thread_at_exit(A), [A]). 1361xref_meta(thread_initialization(A), [A]). 1362xref_meta(engine_create(_,A,_), [A]). 1363xref_meta(engine_create(_,A,_,_), [A]). 1364xref_meta(transaction(A), [A]). 1365xref_meta(transaction(A,B,_), [A,B]). 1366xref_meta(snapshot(A), [A]). 1367xref_meta(predsort(A,_,_), [A+3]). 1368xref_meta(call_cleanup(A, B), [A, B]). 1369xref_meta(call_cleanup(A, _, B),[A, B]). 1370xref_meta(setup_call_cleanup(A, B, C),[A, B, C]). 1371xref_meta(setup_call_catcher_cleanup(A, B, _, C),[A, B, C]). 1372xref_meta(call_residue_vars(A,_), [A]). 1373xref_meta(with_mutex(_,A), [A]). 1374xref_meta(assume(G), [G]). % library(debug) 1375xref_meta(assertion(G), [G]). % library(debug) 1376xref_meta(freeze(_, G), [G]). 1377xref_meta(when(C, A), [C, A]). 1378xref_meta(time(G), [G]). % development system 1379xref_meta(call_time(G, _), [G]). % development system 1380xref_meta(call_time(G, _, _), [G]). % development system 1381xref_meta(profile(G), [G]). 1382xref_meta(at_halt(G), [G]). 1383xref_meta(call_with_time_limit(_, G), [G]). 1384xref_meta(call_with_depth_limit(G, _, _), [G]). 1385xref_meta(call_with_inference_limit(G, _, _), [G]). 1386xref_meta(alarm(_, G, _), [G]). 1387xref_meta(alarm(_, G, _, _), [G]). 1388xref_meta('$add_directive_wic'(G), [G]). 1389xref_meta(with_output_to(_, G), [G]). 1390xref_meta(if(G), [G]). 1391xref_meta(elif(G), [G]). 1392xref_meta(meta_options(G,_,_), [G+1]). 1393xref_meta(on_signal(_,_,H), [H+1]) :- H \== default. 1394xref_meta(distinct(G), [G]). % library(solution_sequences) 1395xref_meta(distinct(_, G), [G]). 1396xref_meta(order_by(_, G), [G]). 1397xref_meta(limit(_, G), [G]). 1398xref_meta(offset(_, G), [G]). 1399xref_meta(reset(G,_,_), [G]). 1400xref_meta(prolog_listen(Ev,G), [G+N]) :- event_xargs(Ev, N). 1401xref_meta(prolog_listen(Ev,G,_),[G+N]) :- event_xargs(Ev, N). 1402xref_meta(tnot(G), [G]). 1403xref_meta(not_exists(G), [G]). 1404xref_meta(with_tty_raw(G), [G]). 1405xref_meta(residual_goals(G), [G+2]). 1406 1407 % XPCE meta-predicates 1408xref_meta(pce_global(_, new(_)), _) :- !, fail. 1409xref_meta(pce_global(_, B), [B+1]). 1410xref_meta(ifmaintainer(G), [G]). % used in manual 1411xref_meta(listen(_, G), [G]). % library(broadcast) 1412xref_meta(listen(_, _, G), [G]). 1413xref_meta(in_pce_thread(G), [G]). 1414 1415xref_meta(G, Meta) :- % call user extensions 1416 prolog:meta_goal(G, Meta). 1417xref_meta(G, Meta) :- % Generated from :- meta_predicate 1418 meta_goal(G, Meta, _Src). 1419 1420setof_goal(EG, G) :- 1421 var(EG), !, G = EG. 1422setof_goal(_^EG, G) :- 1423 !, 1424 setof_goal(EG, G). 1425setof_goal(G, G). 1426 1427event_xargs(abort, 0). 1428event_xargs(erase, 1). 1429event_xargs(break, 3). 1430event_xargs(frame_finished, 1). 1431event_xargs(thread_exit, 1). 1432event_xargs(this_thread_exit, 0). 1433event_xargs(PI, 2) :- pi_to_head(PI, _).
1439head_of(Var, _) :- 1440 var(Var), !, fail. 1441head_of((Head :- _), Head). 1442head_of(Head, Head).
1450xref_hook(Hook) :- 1451 prolog:hook(Hook). 1452xref_hook(Hook) :- 1453 hook(Hook). 1454 1455 1456hook(attr_portray_hook(_,_)). 1457hook(attr_unify_hook(_,_)). 1458hook(attribute_goals(_,_,_)). 1459hook(goal_expansion(_,_)). 1460hook(term_expansion(_,_)). 1461hook(goal_expansion(_,_,_,_)). 1462hook(term_expansion(_,_,_,_)). 1463hook(resource(_,_,_)). 1464hook('$pred_option'(_,_,_,_)). 1465hook('$nowarn_autoload'(_,_)). 1466 1467hook(emacs_prolog_colours:goal_classification(_,_)). 1468hook(emacs_prolog_colours:goal_colours(_,_)). 1469hook(emacs_prolog_colours:identify(_,_)). 1470hook(emacs_prolog_colours:style(_,_)). 1471hook(emacs_prolog_colours:term_colours(_,_)). 1472hook(pce_principal:get_implementation(_,_,_,_)). 1473hook(pce_principal:pce_class(_,_,_,_,_,_)). 1474hook(pce_principal:pce_lazy_get_method(_,_,_)). 1475hook(pce_principal:pce_lazy_send_method(_,_,_)). 1476hook(pce_principal:pce_uses_template(_,_)). 1477hook(pce_principal:send_implementation(_,_,_)). 1478hook(predicate_options:option_decl(_,_,_)). 1479hook(prolog:debug_control_hook(_)). 1480hook(prolog:error_message(_,_,_)). 1481hook(prolog:expand_answer(_,_,_)). 1482hook(prolog:general_exception(_,_)). 1483hook(prolog:help_hook(_)). 1484hook(prolog:locate_clauses(_,_)). 1485hook(prolog:message(_,_,_)). 1486hook(prolog:message_context(_,_,_)). 1487hook(prolog:message_line_element(_,_)). 1488hook(prolog:message_location(_,_,_)). 1489hook(prolog:predicate_summary(_,_)). 1490hook(prolog:prolog_exception_hook(_,_,_,_,_)). 1491hook(prolog:residual_goals(_,_)). 1492hook(prolog:show_profile_hook(_,_)). 1493hook(prolog_edit:load). 1494hook(prolog_edit:locate(_,_,_)). 1495hook(sandbox:safe_directive(_)). 1496hook(sandbox:safe_global_variable(_)). 1497hook(sandbox:safe_meta(_,_)). 1498hook(sandbox:safe_meta_predicate(_)). 1499hook(sandbox:safe_primitive(_)). 1500hook(sandbox:safe_prolog_flag(_,_)). 1501hook(shlib:unload_all_foreign_libraries). 1502hook(system:'$foreign_registered'(_, _)). 1503hook(user:exception(_,_,_)). 1504hook(user:expand_answer(_,_)). 1505hook(user:expand_query(_,_,_,_)). 1506hook(user:file_search_path(_,_)). 1507hook(user:library_directory(_)). 1508hook(user:message_hook(_,_,_)). 1509hook(prolog:message_action(_,_)). 1510hook(user:portray(_)). 1511hook(user:prolog_clause_name(_,_)). 1512hook(user:prolog_list_goal(_)). 1513hook(user:prolog_predicate_name(_,_)). 1514hook(user:prolog_trace_interception(_,_,_,_)).
1520arith_callable(Var, _) :- 1521 var(Var), !, fail. 1522arith_callable(Module:Spec, Module:Goal) :- 1523 !, 1524 arith_callable(Spec, Goal). 1525arith_callable(Name/Arity, Goal) :- 1526 PredArity is Arity + 1, 1527 functor(Goal, Name, PredArity).
We limit the number of explored paths to 100 to avoid getting trapped in this analysis.
1538process_body(Body, Origin, Src) :-
1539 forall(limit(100, process_goal(Body, Origin, Src, _Partial)),
1540 true).true if there was a
partial evalation inside Goal that has bound variables.1547process_goal(Var, _, _, _) :- 1548 var(Var), 1549 !. 1550process_goal(_:Goal, _, _, _) :- 1551 var(Goal), 1552 !. 1553process_goal(Goal, Origin, Src, P) :- 1554 Goal = (_,_), % problems 1555 !, 1556 phrase(conjunction(Goal), Goals), 1557 process_conjunction(Goals, Origin, Src, P). 1558process_goal(Goal, Origin, Src, _) :- % Final disjunction, no 1559 Goal = (_;_), % problems 1560 !, 1561 phrase(disjunction(Goal), Goals), 1562 forall(member(G, Goals), 1563 process_body(G, Origin, Src)). 1564process_goal(Goal, Origin, Src, P) :- 1565 ( ( xmodule(M, Src) 1566 -> true 1567 ; M = user 1568 ), 1569 pi_head(PI, M:Goal), 1570 ( current_predicate(PI), 1571 predicate_property(M:Goal, imported_from(IM)) 1572 -> true 1573 ; PI = M:Name/Arity, 1574 '$find_library'(M, Name, Arity, IM, _Library) 1575 -> true 1576 ; IM = M 1577 ), 1578 prolog:called_by(Goal, IM, M, Called) 1579 ; prolog:called_by(Goal, Called) 1580 ), 1581 !, 1582 must_be(list, Called), 1583 current_source_line(Here), 1584 assert_called(Src, Origin, Goal, Here), 1585 process_called_list(Called, Origin, Src, P). 1586process_goal(Goal, Origin, Src, _) :- 1587 process_xpce_goal(Goal, Origin, Src), 1588 !. 1589process_goal(load_foreign_library(File), _Origin, Src, _) :- 1590 process_foreign(File, Src). 1591process_goal(load_foreign_library(File, _Init), _Origin, Src, _) :- 1592 process_foreign(File, Src). 1593process_goal(use_foreign_library(File), _Origin, Src, _) :- 1594 process_foreign(File, Src). 1595process_goal(use_foreign_library(File, _Init), _Origin, Src, _) :- 1596 process_foreign(File, Src). 1597process_goal(Goal, Origin, Src, P) :- 1598 xref_meta_src(Goal, Metas, Src), 1599 !, 1600 current_source_line(Here), 1601 assert_called(Src, Origin, Goal, Here), 1602 process_called_list(Metas, Origin, Src, P). 1603process_goal(Goal, Origin, Src, _) :- 1604 asserting_goal(Goal, Rule), 1605 !, 1606 current_source_line(Here), 1607 assert_called(Src, Origin, Goal, Here), 1608 process_assert(Rule, Origin, Src). 1609process_goal(Goal, Origin, Src, P) :- 1610 partial_evaluate(Goal, P), 1611 current_source_line(Here), 1612 assert_called(Src, Origin, Goal, Here). 1613 1614disjunction(Var) --> {var(Var), !}, [Var]. 1615disjunction((A;B)) --> !, disjunction(A), disjunction(B). 1616disjunction(G) --> [G]. 1617 1618conjunction(Var) --> {var(Var), !}, [Var]. 1619conjunction((A,B)) --> !, conjunction(A), conjunction(B). 1620conjunction(G) --> [G]. 1621 (RVars, T) :- 1623 term_variables(T, TVars0), 1624 sort(TVars0, TVars), 1625 ord_intersect(RVars, TVars). 1626 1627process_conjunction([], _, _, _). 1628process_conjunction([Disj|Rest], Origin, Src, P) :- 1629 nonvar(Disj), 1630 Disj = (_;_), 1631 Rest \== [], 1632 !, 1633 phrase(disjunction(Disj), Goals), 1634 term_variables(Rest, RVars0), 1635 sort(RVars0, RVars), 1636 partition(shares_vars(RVars), Goals, Sharing, NonSHaring), 1637 forall(member(G, NonSHaring), 1638 process_body(G, Origin, Src)), 1639 ( Sharing == [] 1640 -> true 1641 ; maplist(term_variables, Sharing, GVars0), 1642 append(GVars0, GVars1), 1643 sort(GVars1, GVars), 1644 ord_intersection(GVars, RVars, SVars), 1645 VT =.. [v|SVars], 1646 findall(VT, 1647 ( member(G, Sharing), 1648 process_goal(G, Origin, Src, PS), 1649 PS == true 1650 ), 1651 Alts0), 1652 ( Alts0 == [] 1653 -> true 1654 ; ( true 1655 ; P = true, 1656 sort(Alts0, Alts1), 1657 variants(Alts1, 10, Alts), 1658 member(VT, Alts) 1659 ) 1660 ) 1661 ), 1662 process_conjunction(Rest, Origin, Src, P). 1663process_conjunction([H|T], Origin, Src, P) :- 1664 process_goal(H, Origin, Src, P), 1665 process_conjunction(T, Origin, Src, P). 1666 1667 1668process_called_list([], _, _, _). 1669process_called_list([H|T], Origin, Src, P) :- 1670 process_meta(H, Origin, Src, P), 1671 process_called_list(T, Origin, Src, P). 1672 1673process_meta(A+N, Origin, Src, P) :- 1674 !, 1675 ( extend(A, N, AX) 1676 -> process_goal(AX, Origin, Src, P) 1677 ; true 1678 ). 1679process_meta(//(A), Origin, Src, P) :- 1680 !, 1681 process_dcg_goal(A, Origin, Src, P). 1682process_meta(G, Origin, Src, P) :- 1683 process_goal(G, Origin, Src, P).
1690process_dcg_goal(Var, _, _, _) :- 1691 var(Var), 1692 !. 1693process_dcg_goal((A,B), Origin, Src, P) :- 1694 !, 1695 process_dcg_goal(A, Origin, Src, P), 1696 process_dcg_goal(B, Origin, Src, P). 1697process_dcg_goal((A;B), Origin, Src, P) :- 1698 !, 1699 process_dcg_goal(A, Origin, Src, P), 1700 process_dcg_goal(B, Origin, Src, P). 1701process_dcg_goal((A|B), Origin, Src, P) :- 1702 !, 1703 process_dcg_goal(A, Origin, Src, P), 1704 process_dcg_goal(B, Origin, Src, P). 1705process_dcg_goal((A->B), Origin, Src, P) :- 1706 !, 1707 process_dcg_goal(A, Origin, Src, P), 1708 process_dcg_goal(B, Origin, Src, P). 1709process_dcg_goal((A*->B), Origin, Src, P) :- 1710 !, 1711 process_dcg_goal(A, Origin, Src, P), 1712 process_dcg_goal(B, Origin, Src, P). 1713process_dcg_goal({Goal}, Origin, Src, P) :- 1714 !, 1715 process_goal(Goal, Origin, Src, P). 1716process_dcg_goal(List, _Origin, _Src, _) :- 1717 is_list(List), 1718 !. % terminal 1719process_dcg_goal(List, _Origin, _Src, _) :- 1720 string(List), 1721 !. % terminal 1722process_dcg_goal(Callable, Origin, Src, P) :- 1723 extend(Callable, 2, Goal), 1724 !, 1725 process_goal(Goal, Origin, Src, P). 1726process_dcg_goal(_, _, _, _). 1727 1728 1729extend(Var, _, _) :- 1730 var(Var), !, fail. 1731extend(M:G, N, M:GX) :- 1732 !, 1733 callable(G), 1734 extend(G, N, GX). 1735extend(G, N, GX) :- 1736 ( compound(G) 1737 -> compound_name_arguments(G, Name, Args), 1738 length(Rest, N), 1739 append(Args, Rest, NArgs), 1740 compound_name_arguments(GX, Name, NArgs) 1741 ; atom(G) 1742 -> length(NArgs, N), 1743 compound_name_arguments(GX, G, NArgs) 1744 ). 1745 1746asserting_goal(assert(Rule), Rule). 1747asserting_goal(asserta(Rule), Rule). 1748asserting_goal(assertz(Rule), Rule). 1749asserting_goal(assert(Rule,_), Rule). 1750asserting_goal(asserta(Rule,_), Rule). 1751asserting_goal(assertz(Rule,_), Rule). 1752 1753process_assert(0, _, _) :- !. % catch variables 1754process_assert((_:-Body), Origin, Src) :- 1755 !, 1756 process_body(Body, Origin, Src). 1757process_assert(_, _, _).
1761variants([], _, []). 1762variants([H|T], Max, List) :- 1763 variants(T, H, Max, List). 1764 1765variants([], H, _, [H]). 1766variants(_, _, 0, []) :- !. 1767variants([H|T], V, Max, List) :- 1768 ( H =@= V 1769 -> variants(T, V, Max, List) 1770 ; List = [V|List2], 1771 Max1 is Max-1, 1772 variants(T, H, Max1, List2) 1773 ).
T = hello(X),
findall(T, T, List),
1787partial_evaluate(Goal, P) :- 1788 eval(Goal), 1789 !, 1790 P = true. 1791partial_evaluate(_, _). 1792 1793eval(X = Y) :- 1794 unify_with_occurs_check(X, Y). 1795 1796 /******************************* 1797 * PLUNIT SUPPORT * 1798 *******************************/ 1799 1800enter_test_unit(Unit, _Src) :- 1801 current_source_line(Line), 1802 asserta(current_test_unit(Unit, Line)). 1803 1804leave_test_unit(Unit, _Src) :- 1805 retractall(current_test_unit(Unit, _)). 1806 1807 1808 /******************************* 1809 * XPCE STUFF * 1810 *******************************/ 1811 1812pce_goal(new(_,_), new(-, new)). 1813pce_goal(send(_,_), send(arg, msg)). 1814pce_goal(send_class(_,_,_), send_class(arg, arg, msg)). 1815pce_goal(get(_,_,_), get(arg, msg, -)). 1816pce_goal(get_class(_,_,_,_), get_class(arg, arg, msg, -)). 1817pce_goal(get_chain(_,_,_), get_chain(arg, msg, -)). 1818pce_goal(get_object(_,_,_), get_object(arg, msg, -)). 1819 1820process_xpce_goal(G, Origin, Src) :- 1821 pce_goal(G, Process), 1822 !, 1823 current_source_line(Here), 1824 assert_called(Src, Origin, G, Here), 1825 ( arg(I, Process, How), 1826 arg(I, G, Term), 1827 process_xpce_arg(How, Term, Origin, Src), 1828 fail 1829 ; true 1830 ). 1831 1832process_xpce_arg(new, Term, Origin, Src) :- 1833 callable(Term), 1834 process_new(Term, Origin, Src). 1835process_xpce_arg(arg, Term, Origin, Src) :- 1836 compound(Term), 1837 process_new(Term, Origin, Src). 1838process_xpce_arg(msg, Term, Origin, Src) :- 1839 compound(Term), 1840 ( arg(_, Term, Arg), 1841 process_xpce_arg(arg, Arg, Origin, Src), 1842 fail 1843 ; true 1844 ). 1845 1846process_new(_M:_Term, _, _) :- !. % TBD: Calls on other modules! 1847process_new(Term, Origin, Src) :- 1848 assert_new(Src, Origin, Term), 1849 ( compound(Term), 1850 arg(_, Term, Arg), 1851 process_xpce_arg(arg, Arg, Origin, Src), 1852 fail 1853 ; true 1854 ). 1855 1856assert_new(_, _, Term) :- 1857 \+ callable(Term), 1858 !. 1859assert_new(Src, Origin, Control) :- 1860 functor_name(Control, Class), 1861 pce_control_class(Class), 1862 !, 1863 forall(arg(_, Control, Arg), 1864 assert_new(Src, Origin, Arg)). 1865assert_new(Src, Origin, Term) :- 1866 compound(Term), 1867 arg(1, Term, Prolog), 1868 Prolog == @(prolog), 1869 ( Term =.. [message, _, Selector | T], 1870 atom(Selector) 1871 -> Called =.. [Selector|T], 1872 process_body(Called, Origin, Src) 1873 ; Term =.. [?, _, Selector | T], 1874 atom(Selector) 1875 -> append(T, [_R], T2), 1876 Called =.. [Selector|T2], 1877 process_body(Called, Origin, Src) 1878 ), 1879 fail. 1880assert_new(_, _, @(_)) :- !. 1881assert_new(Src, _, Term) :- 1882 functor_name(Term, Name), 1883 assert_used_class(Src, Name). 1884 1885 1886pce_control_class(and). 1887pce_control_class(or). 1888pce_control_class(if). 1889pce_control_class(not). 1890 1891 1892 /******************************** 1893 * INCLUDED MODULES * 1894 ********************************/
1898process_use_module(_Module:_Files, _, _) :- !. % loaded in another module 1899process_use_module([], _, _) :- !. 1900process_use_module([H|T], Src, Reexport) :- 1901 !, 1902 process_use_module(H, Src, Reexport), 1903 process_use_module(T, Src, Reexport). 1904process_use_module(library(pce), Src, Reexport) :- % bit special 1905 !, 1906 xref_public_list(library(pce), Path, Exports, Src), 1907 forall(member(Import, Exports), 1908 process_pce_import(Import, Src, Path, Reexport)). 1909process_use_module(File, Src, Reexport) :- 1910 load_module_if_needed(File), 1911 ( xoption(Src, silent(Silent)) 1912 -> Extra = [silent(Silent)] 1913 ; Extra = [silent(true)] 1914 ), 1915 ( xref_public_list(File, Src, 1916 [ path(Path), 1917 module(M), 1918 exports(Exports), 1919 public(Public), 1920 meta(Meta) 1921 | Extra 1922 ]) 1923 -> assert(uses_file(File, Src, Path)), 1924 assert_import(Src, Exports, _, Path, Reexport), 1925 assert_xmodule_callable(Exports, M, Src, Path), 1926 assert_xmodule_callable(Public, M, Src, Path), 1927 maplist(process_meta_head(Src), Meta), 1928 ( File = library(chr) % hacky 1929 -> assert(mode(chr, Src)) 1930 ; true 1931 ) 1932 ; assert(uses_file(File, Src, '<not_found>')) 1933 ). 1934 1935process_pce_import(Name/Arity, Src, Path, Reexport) :- 1936 atom(Name), 1937 integer(Arity), 1938 !, 1939 functor(Term, Name, Arity), 1940 ( \+ system_predicate(Term), 1941 \+ Term = pce_error(_) % hack!? 1942 -> assert_import(Src, [Name/Arity], _, Path, Reexport) 1943 ; true 1944 ). 1945process_pce_import(op(P,T,N), Src, _, _) :- 1946 xref_push_op(Src, P, T, N).
1952process_use_module2(File, Import, Src, Reexport) :-
1953 load_module_if_needed(File),
1954 ( catch(xref_public_list(File, Src,
1955 [ path(Path),
1956 exports(Export),
1957 meta(Meta)
1958 ]),
1959 error(_,_),
1960 fail)
1961 -> assertz(uses_file(File, Src, Path)),
1962 assert_import(Src, Import, Export, Path, Reexport),
1963 forall(( member(Head, Meta),
1964 imported(Head, _, Path)
1965 ),
1966 process_meta_head(Src, Head))
1967 ; assertz(uses_file(File, Src, '<not_found>'))
1968 ).1977load_module_if_needed(File) :- 1978 prolog:no_autoload_module(File), 1979 !, 1980 use_module(File, []). 1981load_module_if_needed(_). 1982 1983prologno_autoload_module(library(apply_macros)). 1984prologno_autoload_module(library(arithmetic)). 1985prologno_autoload_module(library(record)). 1986prologno_autoload_module(library(persistency)). 1987prologno_autoload_module(library(pldoc)). 1988prologno_autoload_module(library(settings)). 1989prologno_autoload_module(library(debug)). 1990prologno_autoload_module(library(plunit)). 1991prologno_autoload_module(library(macros)). 1992prologno_autoload_module(library(yall)).
1997process_requires(Import, Src) :- 1998 is_list(Import), 1999 !, 2000 require_list(Import, Src). 2001process_requires(Var, _Src) :- 2002 var(Var), 2003 !. 2004process_requires((A,B), Src) :- 2005 !, 2006 process_requires(A, Src), 2007 process_requires(B, Src). 2008process_requires(PI, Src) :- 2009 requires(PI, Src). 2010 2011require_list([], _). 2012require_list([H|T], Src) :- 2013 requires(H, Src), 2014 require_list(T, Src). 2015 2016requires(PI, _Src) :- 2017 '$pi_head'(PI, Head), 2018 '$get_predicate_attribute'(system:Head, defined, 1), 2019 !. 2020requires(PI, Src) :- 2021 '$pi_head'(PI, Head), 2022 '$pi_head'(Name/Arity, Head), 2023 '$find_library'(_Module, Name, Arity, _LoadModule, Library), 2024 ( imported(Head, Src, Library) 2025 -> true 2026 ; assertz(imported(Head, Src, Library)) 2027 ).
[] 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.
2063xref_public_list(File, Src, Options) :-
2064 option(path(Source), Options, _),
2065 option(module(Module), Options, _),
2066 option(exports(Exports), Options, _),
2067 option(public(Public), Options, _),
2068 option(meta(Meta), Options, _),
2069 xref_source_file(File, Path, Src, Options),
2070 public_list(Path, Source, Module, Meta, Exports, Public, Options).These predicates fail if File is not a module-file.
2092xref_public_list(File, Source, Export, Src) :- 2093 xref_source_file(File, Path, Src), 2094 public_list(Path, Source, _, _, Export, _, []). 2095xref_public_list(File, Source, Module, Export, Meta, Src) :- 2096 xref_source_file(File, Path, Src), 2097 public_list(Path, Source, Module, Meta, Export, _, []). 2098xref_public_list(File, Source, Module, Export, Public, Meta, Src) :- 2099 xref_source_file(File, Path, Src), 2100 public_list(Path, Source, Module, Meta, Export, Public, []).
true, ignore (syntax) errors. If not specified the default
is inherited from xref_source/2.2111:- dynamic public_list_cache/7. 2112:- volatile public_list_cache/7. 2113 2114public_list(Path, Source, Module, Meta, Export, Public, _Options) :- 2115 public_list_cache(Path, Source, Modified, 2116 Module0, Meta0, Export0, Public0), 2117 time_file(Path, ModifiedNow), 2118 ( abs(Modified-ModifiedNow) < 0.0001 2119 -> !, 2120 t(Module,Meta,Export,Public) = t(Module0,Meta0,Export0,Public0) 2121 ; retractall(public_list_cache(Path, _, _, _, _, _, _)), 2122 fail 2123 ). 2124public_list(Path, Source, Module, Meta, Export, Public, Options) :- 2125 public_list_nc(Path, Source, Module0, Meta0, Export0, Public0, Options), 2126 ( Error = error(_,_), 2127 catch(time_file(Path, Modified), Error, fail) 2128 -> asserta(public_list_cache(Path, Source, Modified, 2129 Module0, Meta0, Export0, Public0)) 2130 ; true 2131 ), 2132 t(Module,Meta,Export,Public) = t(Module0,Meta0,Export0,Public0). 2133 2134public_list_nc(Path, Source, Module, Meta, Export, Public, _Options) :- 2135 public_list_from_index(Path, Module, Meta, Export, Public), 2136 !, 2137 qlf_pl_file(Path, Source). 2138public_list_nc(Path, Source, Module, [], Export, [], _Options) :- 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 exists_file(Path), 2145 !, 2146 prolog_file_directives(Path, Directives, Options), 2147 public_list(Directives, Path, Module, Meta, [], Export, [], Public, []). 2148public_list_nc(Path, Path, Module, [], Export, [], _Options) :- 2149 qlf_pl_file(QlfFile, Path), 2150 '$qlf_module'(QlfFile, Info), 2151 _{module:Module, exports:Export} :< Info. 2152 2153public_list([(:- module(Module, Export0))|Decls], Path, 2154 Module, Meta, MT, Export, Rest, Public, PT) :- 2155 !, 2156 ( is_list(Export0) 2157 -> append(Export0, Reexport, Export) 2158 ; Reexport = Export 2159 ), 2160 public_list_(Decls, Path, Meta, MT, Reexport, Rest, Public, PT). 2161public_list([(:- encoding(_))|Decls], Path, 2162 Module, Meta, MT, Export, Rest, Public, PT) :- 2163 public_list(Decls, Path, Module, Meta, MT, Export, Rest, Public, PT). 2164 2165public_list_([], _, Meta, Meta, Export, Export, Public, Public). 2166public_list_([(:-(Dir))|T], Path, Meta, MT, Export, Rest, Public, PT) :- 2167 public_list_1(Dir, Path, Meta, MT0, Export, Rest0, Public, PT0), 2168 !, 2169 public_list_(T, Path, MT0, MT, Rest0, Rest, PT0, PT). 2170public_list_([_|T], Path, Meta, MT, Export, Rest, Public, PT) :- 2171 public_list_(T, Path, Meta, MT, Export, Rest, Public, PT). 2172 2173public_list_1(reexport(Spec), Path, Meta, MT, Reexport, Rest, Public, PT) :- 2174 reexport_files(Spec, Path, Meta, MT, Reexport, Rest, Public, PT). 2175public_list_1(reexport(Spec, Import), Path, Meta, Meta, Reexport, Rest, Public, Public) :- 2176 public_from_import(Import, Spec, Path, Reexport, Rest). 2177public_list_1(meta_predicate(Decl), _Path, Meta, MT, Export, Export, Public, Public) :- 2178 phrase(meta_decls(Decl), Meta, MT). 2179public_list_1(public(Decl), _Path, Meta, Meta, Export, Export, Public, PT) :- 2180 phrase(public_decls(Decl), Public, PT).
2186reexport_files([], _, Meta, Meta, Export, Export, Public, Public) :- !. 2187reexport_files([H|T], Src, Meta, MT, Export, ET, Public, PT) :- 2188 !, 2189 xref_source_file(H, Path, Src), 2190 public_list(Path, _Source, _Module, Meta0, Export0, Public0, []), 2191 append(Meta0, MT1, Meta), 2192 append(Export0, ET1, Export), 2193 append(Public0, PT1, Public), 2194 reexport_files(T, Src, MT1, MT, ET1, ET, PT1, PT). 2195reexport_files(Spec, Src, Meta, MT, Export, ET, Public, PT) :- 2196 xref_source_file(Spec, Path, Src), 2197 public_list(Path, _Source, _Module, Meta0, Export0, Public0, []), 2198 append(Meta0, MT, Meta), 2199 append(Export0, ET, Export), 2200 append(Public0, PT, Public). 2201 2202public_from_import(except(Map), Path, Src, Export, Rest) :- 2203 !, 2204 xref_public_list(Path, _, AllExports, Src), 2205 except(Map, AllExports, NewExports), 2206 append(NewExports, Rest, Export). 2207public_from_import(Import, _, _, Export, Rest) :- 2208 import_name_map(Import, Export, Rest).
2213except([], Exports, Exports). 2214except([PI0 as NewName|Map], Exports0, Exports) :- 2215 !, 2216 canonical_pi(PI0, PI), 2217 map_as(Exports0, PI, NewName, Exports1), 2218 except(Map, Exports1, Exports). 2219except([PI0|Map], Exports0, Exports) :- 2220 canonical_pi(PI0, PI), 2221 select(PI2, Exports0, Exports1), 2222 same_pi(PI, PI2), 2223 !, 2224 except(Map, Exports1, Exports). 2225 2226 2227map_as([PI|T], Repl, As, [PI2|T]) :- 2228 same_pi(Repl, PI), 2229 !, 2230 pi_as(PI, As, PI2). 2231map_as([H|T0], Repl, As, [H|T]) :- 2232 map_as(T0, Repl, As, T). 2233 2234pi_as(_/Arity, Name, Name/Arity). 2235pi_as(_//Arity, Name, Name//Arity). 2236 2237import_name_map([], L, L). 2238import_name_map([_/Arity as NewName|T0], [NewName/Arity|T], Tail) :- 2239 !, 2240 import_name_map(T0, T, Tail). 2241import_name_map([_//Arity as NewName|T0], [NewName//Arity|T], Tail) :- 2242 !, 2243 import_name_map(T0, T, Tail). 2244import_name_map([H|T0], [H|T], Tail) :- 2245 import_name_map(T0, T, Tail). 2246 2247canonical_pi(Name//Arity0, PI) :- 2248 integer(Arity0), 2249 !, 2250 PI = Name/Arity, 2251 Arity is Arity0 + 2. 2252canonical_pi(PI, PI). 2253 2254same_pi(Canonical, PI2) :- 2255 canonical_pi(PI2, Canonical). 2256 2257meta_decls(Var) --> 2258 { var(Var) }, 2259 !. 2260meta_decls((A,B)) --> 2261 !, 2262 meta_decls(A), 2263 meta_decls(B). 2264meta_decls(A) --> 2265 [A]. 2266 2267public_decls(Var) --> 2268 { var(Var) }, 2269 !. 2270public_decls((A,B)) --> 2271 !, 2272 public_decls(A), 2273 public_decls(B). 2274public_decls(A) --> 2275 [A].
INDEX.pl file in the same
directory.2282public_list_from_index(Path, Module, Meta, Export, Public) :- 2283 file_name_extension(BasePath, _Ext, Path), 2284 file_directory_name(BasePath, Dir), 2285 atom_concat(Dir, '/INDEX.pl', IndexFile), 2286 exists_file(IndexFile), 2287 file_base_name(BasePath, Base), 2288 setup_call_cleanup( 2289 '$push_input_context'(autoload_index), 2290 setup_call_cleanup( 2291 open(IndexFile, read, In), 2292 index_public_list(In, Base, Module, Meta, Export, Public), 2293 close(In)), 2294 '$pop_input_context'). 2295 2296index_public_list(In, Base, Module, Meta, Export, Public) :- 2297 read_term(In, Term, []), 2298 index_public_list(Term, In, Base, Module, Meta, Export, Public). 2299 2300index_public_list(end_of_file, _In, _Base, _Module, [], [], []). 2301index_public_list(index(op:Op, Module, Base), In, Base, Module, Meta, [Op|Export], Public) :- 2302 !, 2303 read_term(In, Term, []), 2304 index_public_list(Term, In, Base, Module, Meta, Export, Public). 2305index_public_list(index((public):Head, Module, Base), In, Base, Module, Meta, Export, [PI|Public]) :- 2306 !, 2307 pi_head(PI, Head), 2308 read_term(In, Term, []), 2309 index_public_list(Term, In, Base, Module, Meta, Export, Public). 2310index_public_list(index(Head, Module, Base), In, Base, Module, Meta, [PI|Export], Public) :- 2311 !, 2312 pi_head(PI, Head), 2313 ( meta_mode(Head) 2314 -> Meta = [Head|MetaT] 2315 ; Meta = MetaT 2316 ), 2317 read_term(In, Term, []), 2318 index_public_list(Term, In, Base, Module, MetaT, Export, Public). 2319index_public_list(index(Name, Arity, Module, Base), In, Base, Module, Meta, [Name/Arity|Export], Public) :- 2320 !, 2321 read_term(In, Term, []), 2322 index_public_list(Term, In, Base, Module, Meta, Export, Public). 2323index_public_list(_, In, Base, Module, Meta, Export, Public) :- 2324 read_term(In, Term, []), 2325 index_public_list(Term, In, Base, Module, Meta, Export, Public). 2326 2327meta_mode(H) :- 2328 compound(H), 2329 arg(_, H, A), 2330 meta_arg(A), 2331 !. 2332 2333meta_arg(I) :- 2334 integer(I), 2335 !. 2336meta_arg(:). 2337meta_arg(^). 2338meta_arg(//). 2339 2340 /******************************* 2341 * INCLUDE * 2342 *******************************/ 2343 2344process_include([], _) :- !. 2345process_include([H|T], Src) :- 2346 !, 2347 process_include(H, Src), 2348 process_include(T, Src). 2349process_include(File, Src) :- 2350 callable(File), 2351 !, 2352 ( once(xref_input(ParentSrc, _)), 2353 xref_source_file(File, Path, ParentSrc) 2354 -> ( ( uses_file(_, Src, Path) 2355 ; Path == Src 2356 ) 2357 -> true 2358 ; assert(uses_file(File, Src, Path)), 2359 ( xoption(Src, process_include(true)) 2360 -> findall(O, xoption(Src, O), Options), 2361 setup_call_cleanup( 2362 open_include_file(Path, In, Refs), 2363 collect(Src, Path, In, Options), 2364 close_include(In, Refs)) 2365 ; true 2366 ) 2367 ) 2368 ; assert(uses_file(File, Src, '<not_found>')) 2369 ). 2370process_include(_, _).
include(File) referenced file. Note that we cannot
use prolog_open_source/2 because we should not safe/restore
the lexical context.2378open_include_file(Path, In, [Ref]) :- 2379 once(xref_input(_, Parent)), 2380 stream_property(Parent, encoding(Enc)), 2381 '$push_input_context'(xref_include), 2382 catch(( prolog:xref_open_source(Path, In) 2383 -> catch(set_stream(In, encoding(Enc)), 2384 error(_,_), true) % deal with non-file input 2385 ; include_encoding(Enc, Options), 2386 open(Path, read, In, Options) 2387 ), E, 2388 ( '$pop_input_context', throw(E))), 2389 catch(( peek_char(In, #) % Deal with #! script 2390 -> skip(In, 10) 2391 ; true 2392 ), E, 2393 ( close_include(In, []), throw(E))), 2394 asserta(xref_input(Path, In), Ref). 2395 2396include_encoding(wchar_t, []) :- !. 2397include_encoding(Enc, [encoding(Enc)]). 2398 2399 2400close_include(In, Refs) :- 2401 maplist(erase, Refs), 2402 close(In, [force(true)]), 2403 '$pop_input_context'.
2409process_foreign(Spec, Src) :- 2410 ground(Spec), 2411 current_foreign_library(Spec, Defined), 2412 !, 2413 ( xmodule(Module, Src) 2414 -> true 2415 ; Module = user 2416 ), 2417 process_foreign_defined(Defined, Module, Src). 2418process_foreign(_, _). 2419 2420process_foreign_defined([], _, _). 2421process_foreign_defined([H|T], M, Src) :- 2422 ( H = M:Head 2423 -> assert_foreign(Src, Head) 2424 ; assert_foreign(Src, H) 2425 ), 2426 process_foreign_defined(T, M, Src). 2427 2428 2429 /******************************* 2430 * CHR SUPPORT * 2431 *******************************/ 2432 2433/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2434This part of the file supports CHR. Our choice is between making special 2435hooks to make CHR expansion work and then handle the (complex) expanded 2436code or process the CHR source directly. The latter looks simpler, 2437though I don't like the idea of adding support for libraries to this 2438module. A file is supposed to be a CHR file if it uses a 2439use_module(library(chr) or contains a :- constraint/1 directive. As an 2440extra bonus we get the source-locations right :-) 2441- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 2442 2443process_chr(@(_Name, Rule), Src) :- 2444 mode(chr, Src), 2445 process_chr(Rule, Src). 2446process_chr(pragma(Rule, _Pragma), Src) :- 2447 mode(chr, Src), 2448 process_chr(Rule, Src). 2449process_chr(<=>(Head, Body), Src) :- 2450 mode(chr, Src), 2451 chr_head(Head, Src, H), 2452 chr_body(Body, H, Src). 2453process_chr(==>(Head, Body), Src) :- 2454 mode(chr, Src), 2455 chr_head(Head, H, Src), 2456 chr_body(Body, H, Src). 2457process_chr((:- chr_constraint(Decls)), Src) :- 2458 ( mode(chr, Src) 2459 -> true 2460 ; assert(mode(chr, Src)) 2461 ), 2462 chr_decls(Decls, Src). 2463 2464chr_decls((A,B), Src) => 2465 chr_decls(A, Src), 2466 chr_decls(B, Src). 2467chr_decls(Head, Src) => 2468 generalise_term(Head, Gen), 2469 ( declared(Gen, chr_constraint, Src, _) 2470 -> true 2471 ; current_source_line(Line), 2472 assertz(declared(Gen, chr_constraint, Src, Line)) 2473 ). 2474 2475chr_head(X, _, _) :- 2476 var(X), 2477 !. % Illegal. Warn? 2478chr_head(\(A,B), Src, H) :- 2479 chr_head(A, Src, H), 2480 process_body(B, H, Src). 2481chr_head((H0,B), Src, H) :- 2482 chr_defined(H0, Src, H), 2483 process_body(B, H, Src). 2484chr_head(H0, Src, H) :- 2485 chr_defined(H0, Src, H). 2486 2487chr_defined(X, _, _) :- 2488 var(X), 2489 !. 2490chr_defined(#(C,_Id), Src, C) :- 2491 !, 2492 assert_constraint(Src, C). 2493chr_defined(A, Src, A) :- 2494 assert_constraint(Src, A). 2495 2496chr_body(X, From, Src) :- 2497 var(X), 2498 !, 2499 process_body(X, From, Src). 2500chr_body('|'(Guard, Goals), H, Src) :- 2501 !, 2502 chr_body(Guard, H, Src), 2503 chr_body(Goals, H, Src). 2504chr_body(G, From, Src) :- 2505 process_body(G, From, Src). 2506 2507assert_constraint(_, Head) :- 2508 var(Head), 2509 !. 2510assert_constraint(Src, Head) :- 2511 constraint(Head, Src, _), 2512 !. 2513assert_constraint(Src, Head) :- 2514 generalise_term(Head, Term), 2515 current_source_line(Line), 2516 assert(constraint(Term, Src, Line)). 2517 2518 2519 /******************************** 2520 * PHASE 1 ASSERTIONS * 2521 ********************************/
2528assert_called(_, _, Var, _) :- 2529 var(Var), 2530 !. 2531assert_called(Src, From, Goal, Line) :- 2532 var(From), 2533 !, 2534 assert_called(Src, '<unknown>', Goal, Line). 2535assert_called(_, _, Goal, _) :- 2536 expand_hide_called(Goal), 2537 !. 2538assert_called(Src, Origin, M:G, Line) :- 2539 !, 2540 ( atom(M), 2541 callable(G) 2542 -> current_condition(Cond), 2543 ( xmodule(M, Src) % explicit call to own module 2544 -> assert_called(Src, Origin, G, Line) 2545 ; called(M:G, Src, Origin, Cond, Line) % already registered 2546 -> true 2547 ; hide_called(M:G, Src) % not interesting (now) 2548 -> true 2549 ; generalise(Origin, OTerm), 2550 generalise(G, GTerm) 2551 -> assert(called(M:GTerm, Src, OTerm, Cond, Line)) 2552 ; true 2553 ) 2554 ; true % call to variable module 2555 ). 2556assert_called(Src, _, Goal, _) :- 2557 ( xmodule(M, Src) 2558 -> M \== system 2559 ; M = user 2560 ), 2561 hide_called(M:Goal, Src), 2562 !. 2563assert_called(Src, Origin, Goal, Line) :- 2564 current_condition(Cond), 2565 ( called(Goal, Src, Origin, Cond, Line) 2566 -> true 2567 ; generalise(Origin, OTerm), 2568 generalise(Goal, Term) 2569 -> assert(called(Term, Src, OTerm, Cond, Line)) 2570 ; true 2571 ).
2579expand_hide_called(pce_principal:send_implementation(_, _, _)). 2580expand_hide_called(pce_principal:get_implementation(_, _, _, _)). 2581expand_hide_called(pce_principal:pce_lazy_get_method(_,_,_)). 2582expand_hide_called(pce_principal:pce_lazy_send_method(_,_,_)). 2583 2584assert_defined(Src, Goal) :- 2585 Goal = test(_Test), 2586 current_test_unit(Unit, Line), 2587 assert_called(Src, '<test_unit>'(Unit), Goal, Line), 2588 fail. 2589assert_defined(Src, Goal) :- 2590 Goal = test(_Test, _Options), 2591 current_test_unit(Unit, Line), 2592 assert_called(Src, '<test_unit>'(Unit), Goal, Line), 2593 fail. 2594assert_defined(Src, Goal) :- 2595 defined(Goal, Src, _), 2596 !. 2597assert_defined(Src, Goal) :- 2598 generalise(Goal, Term), 2599 current_source_line(Line), 2600 assert(defined(Term, Src, Line)). 2601 2602assert_foreign(Src, Goal) :- 2603 foreign(Goal, Src, _), 2604 !. 2605assert_foreign(Src, Goal) :- 2606 generalise(Goal, Term), 2607 current_source_line(Line), 2608 assert(foreign(Term, Src, Line)). 2609 2610assert_grammar_rule(Src, Goal) :- 2611 grammar_rule(Goal, Src), 2612 !. 2613assert_grammar_rule(Src, Goal) :- 2614 generalise(Goal, Term), 2615 assert(grammar_rule(Term, Src)).
true, re-export the
imported predicates.
2628assert_import(_, [], _, _, _) :- !. 2629assert_import(Src, [H|T], Export, From, Reexport) :- 2630 !, 2631 assert_import(Src, H, Export, From, Reexport), 2632 assert_import(Src, T, Export, From, Reexport). 2633assert_import(Src, except(Except), Export, From, Reexport) :- 2634 !, 2635 is_list(Export), 2636 !, 2637 except(Except, Export, Import), 2638 assert_import(Src, Import, _All, From, Reexport). 2639assert_import(Src, Import as Name, Export, From, Reexport) :- 2640 !, 2641 pi_to_head(Import, Term0), 2642 rename_goal(Term0, Name, Term), 2643 ( in_export_list(Term0, Export) 2644 -> assert(imported(Term, Src, From)), 2645 assert_reexport(Reexport, Src, Term) 2646 ; current_source_line(Line), 2647 assert_called(Src, '<directive>'(Line), Term0, Line) 2648 ). 2649assert_import(Src, Import, Export, From, Reexport) :- 2650 pi_to_head(Import, Term), 2651 !, 2652 ( in_export_list(Term, Export) 2653 -> assert(imported(Term, Src, From)), 2654 assert_reexport(Reexport, Src, Term) 2655 ; current_source_line(Line), 2656 assert_called(Src, '<directive>'(Line), Term, Line) 2657 ). 2658assert_import(Src, op(P,T,N), _, _, _) :- 2659 xref_push_op(Src, P,T,N). 2660 2661in_export_list(_Head, Export) :- 2662 var(Export), 2663 !. 2664in_export_list(Head, Export) :- 2665 member(PI, Export), 2666 pi_to_head(PI, Head). 2667 2668assert_reexport(false, _, _) :- !. 2669assert_reexport(true, Src, Term) :- 2670 assert(exported(Term, Src)).
2676process_import(M:PI, Src) :- 2677 pi_to_head(PI, Head), 2678 !, 2679 ( atom(M), 2680 current_module(M), 2681 module_property(M, file(From)) 2682 -> true 2683 ; From = '<unknown>' 2684 ), 2685 assert(imported(Head, Src, From)). 2686process_import(_, _).
2695assert_xmodule_callable([], _, _, _). 2696assert_xmodule_callable([PI|T], M, Src, From) :- 2697 ( pi_to_head(M:PI, Head) 2698 -> assert(imported(Head, Src, From)) 2699 ; true 2700 ), 2701 assert_xmodule_callable(T, M, Src, From).
2708assert_op(Src, op(P,T,M:N)) :-
2709 ( '$current_source_module'(M)
2710 -> Name = N
2711 ; Name = M:N
2712 ),
2713 ( xop(Src, op(P,T,Name))
2714 -> true
2715 ; assert(xop(Src, op(P,T,Name)))
2716 ).2723assert_module(Src, Module) :- 2724 xmodule(Module, Src), 2725 !. 2726assert_module(Src, Module) :- 2727 '$set_source_module'(Module), 2728 assert(xmodule(Module, Src)), 2729 ( module_property(Module, class(system)) 2730 -> retractall(xoption(Src, register_called(_))), 2731 assert(xoption(Src, register_called(all))) 2732 ; true 2733 ). 2734 2735assert_module_export(_, []) :- !. 2736assert_module_export(Src, [H|T]) :- 2737 !, 2738 assert_module_export(Src, H), 2739 assert_module_export(Src, T). 2740assert_module_export(Src, PI) :- 2741 pi_to_head(PI, Term), 2742 !, 2743 assert(exported(Term, Src)). 2744assert_module_export(Src, op(P, A, N)) :- 2745 xref_push_op(Src, P, A, N).
2751assert_module3([], _) :- !. 2752assert_module3([H|T], Src) :- 2753 !, 2754 assert_module3(H, Src), 2755 assert_module3(T, Src). 2756assert_module3(Option, Src) :- 2757 process_use_module(library(dialect/Option), Src, false).
call(Closure, PI,
Src). Handles both lists of specifications and (PI,...)
specifications.2766process_predicates(Closure, Preds, Src) :- 2767 is_list(Preds), 2768 !, 2769 process_predicate_list(Preds, Closure, Src). 2770process_predicates(Closure, as(Preds, _Options), Src) :- 2771 !, 2772 process_predicates(Closure, Preds, Src). 2773process_predicates(Closure, Preds, Src) :- 2774 process_predicate_comma(Preds, Closure, Src). 2775 2776process_predicate_list([], _, _). 2777process_predicate_list([H|T], Closure, Src) :- 2778 ( nonvar(H) 2779 -> call(Closure, H, Src) 2780 ; true 2781 ), 2782 process_predicate_list(T, Closure, Src). 2783 2784process_predicate_comma(Var, _, _) :- 2785 var(Var), 2786 !. 2787process_predicate_comma(M:(A,B), Closure, Src) :- 2788 !, 2789 process_predicate_comma(M:A, Closure, Src), 2790 process_predicate_comma(M:B, Closure, Src). 2791process_predicate_comma((A,B), Closure, Src) :- 2792 !, 2793 process_predicate_comma(A, Closure, Src), 2794 process_predicate_comma(B, Closure, Src). 2795process_predicate_comma(as(Spec, _Options), Closure, Src) :- 2796 !, 2797 process_predicate_comma(Spec, Closure, Src). 2798process_predicate_comma(A, Closure, Src) :- 2799 call(Closure, A, Src). 2800 2801 2802assert_dynamic(PI, Src) :- 2803 pi_to_head(PI, Term), 2804 ( thread_local(Term, Src, _) % dynamic after thread_local has 2805 -> true % no effect 2806 ; current_source_line(Line), 2807 assert(dynamic(Term, Src, Line)) 2808 ). 2809 2810assert_thread_local(PI, Src) :- 2811 pi_to_head(PI, Term), 2812 current_source_line(Line), 2813 assert(thread_local(Term, Src, Line)). 2814 2815assert_multifile(PI, Src) :- % :- multifile(Spec) 2816 pi_to_head(PI, Term), 2817 current_source_line(Line), 2818 assert(multifile(Term, Src, Line)). 2819 2820assert_public(PI, Src) :- % :- public(Spec) 2821 pi_to_head(PI, Term), 2822 current_source_line(Line), 2823 assert_called(Src, '<public>'(Line), Term, Line), 2824 assert(public(Term, Src, Line)). 2825 2826assert_export(PI, Src) :- % :- export(Spec) 2827 pi_to_head(PI, Term), 2828 !, 2829 assert(exported(Term, Src)).
2836pi_to_head(Var, _) :- 2837 var(Var), !, fail. 2838pi_to_head(M:PI, M:Term) :- 2839 !, 2840 pi_to_head(PI, Term). 2841pi_to_head(Name/Arity, Term) :- 2842 functor(Term, Name, Arity). 2843pi_to_head(Name//DCGArity, Term) :- 2844 Arity is DCGArity+2, 2845 functor(Term, Name, Arity). 2846 2847 2848assert_used_class(Src, Name) :- 2849 used_class(Name, Src), 2850 !. 2851assert_used_class(Src, Name) :- 2852 assert(used_class(Name, Src)). 2853 2854assert_defined_class(Src, Name, _Meta, _Super, _) :- 2855 defined_class(Name, _, _, Src, _), 2856 !. 2857assert_defined_class(_, _, _, -, _) :- !. % :- pce_extend_class 2858assert_defined_class(Src, Name, Meta, Super, Summary) :- 2859 current_source_line(Line), 2860 ( Summary == @(default) 2861 -> Atom = '' 2862 ; is_list(Summary) 2863 -> atom_codes(Atom, Summary) 2864 ; string(Summary) 2865 -> atom_concat(Summary, '', Atom) 2866 ), 2867 assert(defined_class(Name, Super, Atom, Src, Line)), 2868 ( Meta = @(_) 2869 -> true 2870 ; assert_used_class(Src, Meta) 2871 ), 2872 assert_used_class(Src, Super). 2873 2874assert_defined_class(Src, Name, imported_from(_File)) :- 2875 defined_class(Name, _, _, Src, _), 2876 !. 2877assert_defined_class(Src, Name, imported_from(File)) :- 2878 assert(defined_class(Name, _, '', Src, file(File))). 2879 2880 2881 /******************************** 2882 * UTILITIES * 2883 ********************************/
2889generalise(Var, Var) :- 2890 var(Var), 2891 !. % error? 2892generalise(pce_principal:send_implementation(Id, _, _), 2893 pce_principal:send_implementation(Id, _, _)) :- 2894 atom(Id), 2895 !. 2896generalise(pce_principal:get_implementation(Id, _, _, _), 2897 pce_principal:get_implementation(Id, _, _, _)) :- 2898 atom(Id), 2899 !. 2900generalise('<directive>'(Line), '<directive>'(Line)) :- !. 2901generalise(test(Test), test(Test)) :- 2902 current_test_unit(_,_), 2903 ground(Test), 2904 !. 2905generalise(test(Test, _), test(Test, _)) :- 2906 current_test_unit(_,_), 2907 ground(Test), 2908 !. 2909generalise('<test_unit>'(Line), '<test_unit>'(Line)) :- !. 2910generalise(Module:Goal0, Module:Goal) :- 2911 atom(Module), 2912 !, 2913 generalise(Goal0, Goal). 2914generalise(Term0, Term) :- 2915 callable(Term0), 2916 generalise_term(Term0, Term). 2917 2918 2919 /******************************* 2920 * SOURCE MANAGEMENT * 2921 *******************************/ 2922 2923/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2924This section of the file contains hookable predicates to reason about 2925sources. The built-in code here can only deal with files. The XPCE 2926library(pce_prolog_xref) provides hooks to deal with XPCE objects, so we 2927can do cross-referencing on PceEmacs edit buffers. Other examples for 2928hooking can be databases, (HTTP) URIs, etc. 2929- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 2930 2931:- multifile 2932 prolog:xref_source_directory/2, % +Source, -Dir 2933 prolog:xref_source_file/3. % +Spec, -Path, +Options
2941xref_source_file(Plain, File, Source) :- 2942 xref_source_file(Plain, File, Source, []). 2943 2944xref_source_file(QSpec, File, Source, Options) :- 2945 nonvar(QSpec), QSpec = _:Spec, 2946 !, 2947 must_be(acyclic, Spec), 2948 xref_source_file(Spec, File, Source, Options). 2949xref_source_file(Spec, File, Source, Options) :- 2950 nonvar(Spec), 2951 prolog:xref_source_file(Spec, File, 2952 [ relative_to(Source) 2953 | Options 2954 ]), 2955 !. 2956xref_source_file(Plain, File, Source, Options) :- 2957 atom(Plain), 2958 \+ is_absolute_file_name(Plain), 2959 ( prolog:xref_source_directory(Source, Dir) 2960 -> true 2961 ; atom(Source), 2962 file_directory_name(Source, Dir) 2963 ), 2964 atomic_list_concat([Dir, /, Plain], Spec0), 2965 absolute_file_name(Spec0, Spec), 2966 do_xref_source_file(Spec, File, Options), 2967 !. 2968xref_source_file(Spec, File, Source, Options) :- 2969 do_xref_source_file(Spec, File, 2970 [ relative_to(Source) 2971 | Options 2972 ]), 2973 !. 2974xref_source_file(_, _, _, Options) :- 2975 option(silent(true), Options), 2976 !, 2977 fail. 2978xref_source_file(Spec, _, Src, _Options) :- 2979 verbose(Src), 2980 print_message(warning, error(existence_error(file, Spec), _)), 2981 fail. 2982 2983do_xref_source_file(Spec, File, Options) :- 2984 nonvar(Spec), 2985 option(file_type(Type), Options, prolog), 2986 absolute_file_name(Spec, File0, 2987 [ file_type(Type), 2988 access(read), 2989 file_errors(fail) 2990 ]), 2991 !, 2992 qlf_pl_file(File0, File). 2993do_xref_source_file(Spec, File, Options) :- 2994 atom(Spec), % handle absolute /file/to/source.pl without sources 2995 file_name_extension(Base, Ext, Spec), 2996 user:prolog_file_type(Ext, source), 2997 option(file_type(prolog), Options, prolog), 2998 absolute_file_name(Base, File0, 2999 [ file_type(prolog), 3000 access(read), 3001 file_errors(fail) 3002 ]), 3003 qlf_pl_file(File0, File).
3007qlf_pl_file(QlfFile, PlFile) :- 3008 nonvar(QlfFile), 3009 is_qlf_file(QlfFile), 3010 !, 3011 '$qlf_module'(QlfFile, Info), 3012 #{file:PlFile} :< Info. 3013qlf_pl_file(QlfFile, PlFile) :- 3014 nonvar(PlFile), 3015 !, 3016 ( file_name_extension(Base, Ext, PlFile), 3017 user:prolog_file_type(Ext, source) 3018 -> true 3019 ), 3020 ( user:prolog_file_type(QlfExt, qlf), 3021 file_name_extension(Base, QlfExt, QlfFile), 3022 exists_file(QlfFile) 3023 -> true 3024 ), 3025 '$qlf_module'(QlfFile, Info), 3026 #{file:PlFile} :< Info, 3027 !. 3028qlf_pl_file(PlFile, PlFile). 3029 3030is_qlf_file(QlfFile) :- 3031 file_name_extension(_, Ext, QlfFile), 3032 user:prolog_file_type(Ext, qlf), 3033 !.
3039canonical_source(Source, Src) :-
3040 ( ground(Source)
3041 -> prolog_canonical_source(Source, Src)
3042 ; Source = Src
3043 ).name()
goals.3050goal_name_arity(Goal, Name, Arity) :- 3051 ( compound(Goal) 3052 -> compound_name_arity(Goal, Name, Arity) 3053 ; atom(Goal) 3054 -> Name = Goal, Arity = 0 3055 ). 3056 3057generalise_term(Specific, General) :- 3058 ( compound(Specific) 3059 -> compound_name_arity(Specific, Name, Arity), 3060 compound_name_arity(General, Name, Arity) 3061 ; General = Specific 3062 ). 3063 3064functor_name(Term, Name) :- 3065 ( compound(Term) 3066 -> compound_name_arity(Term, Name, _) 3067 ; atom(Term) 3068 -> Name = Term 3069 ). 3070 3071rename_goal(Goal0, Name, Goal) :- 3072 ( compound(Goal0) 3073 -> compound_name_arity(Goal0, _, Arity), 3074 compound_name_arity(Goal, Name, Arity) 3075 ; Goal = Name 3076 ). 3077 3078 3079 /******************************* 3080 * MESSAGES * 3081 *******************************/< 3082 3083:- multifile prolog:message//1. 3084 3085prologmessage(meta_predicate_after_call(Decl, By)) --> 3086 { pi_head(ByPI, By) }, 3087 [ ansi(code, ':- meta_predicate(~p)', [Decl]), 3088 ' declaration appears after call from '-[], 3089 ansi(code, '~p', [ByPI]) 3090 ]
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.