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:- dynamic 231 meta_goal/2. 232 233:- meta_predicate 234 process_predicates( , , ). 235 236 /******************************* 237 * BUILT-INS * 238 *******************************/
register_called
.246hide_called(Callable, Src) :- 247 xoption(Src, register_called(Which)), 248 !, 249 mode_hide_called(Which, Callable). 250hide_called(Callable, _) :- 251 mode_hide_called(non_built_in, Callable). 252 253mode_hide_called(all, _) :- !, fail. 254mode_hide_called(non_iso, _:Goal) :- 255 goal_name_arity(Goal, Name, Arity), 256 current_predicate(system:Name/Arity), 257 predicate_property(system:Goal, iso). 258mode_hide_called(non_built_in, _:Goal) :- 259 goal_name_arity(Goal, Name, Arity), 260 current_predicate(system:Name/Arity), 261 predicate_property(system:Goal, built_in). 262mode_hide_called(non_built_in, M:Goal) :- 263 goal_name_arity(Goal, Name, Arity), 264 current_predicate(M:Name/Arity), 265 predicate_property(M:Goal, built_in).
271system_predicate(Goal) :- 272 goal_name_arity(Goal, Name, Arity), 273 current_predicate(system:Name/Arity), % avoid autoloading 274 predicate_property(system:Goal, built_in), 275 !. 276 277 278 /******************************** 279 * TOPLEVEL * 280 ********************************/ 281 282verbose(Src) :- 283 \+ xoption(Src, silent(true)). 284 285:- thread_local 286 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
).316xref_source(Source) :- 317 xref_source(Source, []). 318 319xref_source(Source, Options) :- 320 prolog_canonical_source(Source, Src), 321 ( last_modified(Source, Modified) 322 -> ( source(Src, Modified) 323 -> true 324 ; xref_clean(Src), 325 assert(source(Src, Modified)), 326 do_xref(Src, Options) 327 ) 328 ; xref_clean(Src), 329 get_time(Now), 330 assert(source(Src, Now)), 331 do_xref(Src, Options) 332 ). 333 334do_xref(Src, Options) :- 335 must_be(list, Options), 336 setup_call_cleanup( 337 xref_setup(Src, In, Options, State), 338 collect(Src, Src, In, Options), 339 xref_cleanup(State)). 340 341last_modified(Source, Modified) :- 342 prolog:xref_source_time(Source, Modified), 343 !. 344last_modified(Source, Modified) :- 345 atom(Source), 346 \+ is_global_url(Source), 347 exists_file(Source), 348 time_file(Source, Modified). 349 350is_global_url(File) :- 351 sub_atom(File, B, _, _, '://'), 352 !, 353 B > 1, 354 sub_atom(File, 0, B, _, Scheme), 355 atom_codes(Scheme, Codes), 356 maplist(between(0'a, 0'z), Codes). 357 358xref_setup(Src, In, Options, state(CleanIn, Dialect, Xref, [SRef|HRefs])) :- 359 maplist(assert_option(Src), Options), 360 assert_default_options(Src), 361 current_prolog_flag(emulated_dialect, Dialect), 362 ( option(stream(Stream), Options) 363 -> In = Stream, 364 CleanIn = true 365 ; prolog_open_source(Src, In), 366 CleanIn = prolog_close_source(In) 367 ), 368 set_initial_mode(In, Options), 369 asserta(xref_input(Src, In), SRef), 370 set_xref(Xref), 371 ( verbose(Src) 372 -> HRefs = [] 373 ; asserta((user:thread_message_hook(_,Level,_) :- 374 hide_message(Level)), 375 Ref), 376 HRefs = [Ref] 377 ). 378 379hide_message(warning). 380hide_message(error). 381hide_message(informational). 382 383assert_option(_, Var) :- 384 var(Var), 385 !, 386 instantiation_error(Var). 387assert_option(Src, silent(Boolean)) :- 388 !, 389 must_be(boolean, Boolean), 390 assert(xoption(Src, silent(Boolean))). 391assert_option(Src, register_called(Which)) :- 392 !, 393 must_be(oneof([all,non_iso,non_built_in]), Which), 394 assert(xoption(Src, register_called(Which))). 395assert_option(Src, comments(CommentHandling)) :- 396 !, 397 must_be(oneof([store,collect,ignore]), CommentHandling), 398 assert(xoption(Src, comments(CommentHandling))). 399assert_option(Src, module(Module)) :- 400 !, 401 must_be(atom, Module), 402 assert(xoption(Src, module(Module))). 403assert_option(Src, process_include(Boolean)) :- 404 !, 405 must_be(boolean, Boolean), 406 assert(xoption(Src, process_include(Boolean))). 407assert_option(_, _). 408 409assert_default_options(Src) :- 410 ( xref_option_default(Opt), 411 generalise_term(Opt, Gen), 412 ( xoption(Src, Gen) 413 -> true 414 ; assertz(xoption(Src, Opt)) 415 ), 416 fail 417 ; true 418 ). 419 420xref_option_default(silent(false)). 421xref_option_default(register_called(non_built_in)). 422xref_option_default(comments(collect)). 423xref_option_default(process_include(true)).
429xref_cleanup(state(CleanIn, Dialect, Xref, Refs)) :- 430 call(CleanIn), 431 set_prolog_flag(emulated_dialect, Dialect), 432 set_prolog_flag(xref, Xref), 433 maplist(erase, Refs). 434 435set_xref(Xref) :- 436 current_prolog_flag(xref, Xref), 437 set_prolog_flag(xref, true). 438 439:- meta_predicate 440 with_xref( ). 441 442with_xref(Goal) :- 443 current_prolog_flag(xref, Xref), 444 ( Xref == true 445 -> call(Goal) 446 ; setup_call_cleanup( 447 set_prolog_flag(xref, true), 448 Goal, 449 set_prolog_flag(xref, Xref)) 450 ).
460set_initial_mode(_Stream, Options) :- 461 option(module(Module), Options), 462 !, 463 '$set_source_module'(Module). 464set_initial_mode(Stream, _) :- 465 stream_property(Stream, file_name(Path)), 466 source_file_property(Path, load_context(M, _, Opts)), 467 !, 468 '$set_source_module'(M), 469 ( option(dialect(Dialect), Opts) 470 -> expects_dialect(Dialect) 471 ; true 472 ). 473set_initial_mode(_, _) :- 474 '$set_source_module'(user).
480xref_input_stream(Stream) :-
481 xref_input(_, Var),
482 !,
483 Stream = Var.
490xref_push_op(Src, P, T, N0) :- 491 '$current_source_module'(M0), 492 strip_module(M0:N0, M, N), 493 ( is_list(N), 494 N \== [] 495 -> maplist(push_op(Src, P, T, M), N) 496 ; push_op(Src, P, T, M, N) 497 ). 498 499push_op(Src, P, T, M0, N0) :- 500 strip_module(M0:N0, M, N), 501 Name = M:N, 502 valid_op(op(P,T,Name)), 503 push_op(P, T, Name), 504 assert_op(Src, op(P,T,Name)), 505 debug(xref(op), ':- ~w.', [op(P,T,Name)]). 506 507valid_op(op(P,T,M:N)) :- 508 atom(M), 509 valid_op_name(N), 510 integer(P), 511 between(0, 1200, P), 512 atom(T), 513 op_type(T). 514 515valid_op_name(N) :- 516 atom(N), 517 !. 518valid_op_name(N) :- 519 N == []. 520 521op_type(xf). 522op_type(yf). 523op_type(fx). 524op_type(fy). 525op_type(xfx). 526op_type(xfy). 527op_type(yfx).
533xref_set_prolog_flag(Flag, Value, Src, Line) :- 534 atom(Flag), 535 !, 536 assertz(xflag(Flag, Value, Src, Line)). 537xref_set_prolog_flag(_, _, _, _).
543xref_clean(Source) :- 544 prolog_canonical_source(Source, Src), 545 retractall(called(_, Src, _Origin, _Cond, _Line)), 546 retractall(dynamic(_, Src, Line)), 547 retractall(multifile(_, Src, Line)), 548 retractall(public(_, Src, Line)), 549 retractall(declared(_, _, Src, Line)), 550 retractall(defined(_, Src, Line)), 551 retractall(meta_goal(_, _, Src)), 552 retractall(foreign(_, Src, Line)), 553 retractall(constraint(_, Src, Line)), 554 retractall(imported(_, Src, _From)), 555 retractall(exported(_, Src)), 556 retractall(uses_file(_, Src, _)), 557 retractall(xmodule(_, Src)), 558 retractall(xop(Src, _)), 559 retractall(grammar_rule(_, Src)), 560 retractall(xoption(Src, _)), 561 retractall(xflag(_Name, _Value, Src, Line)), 562 retractall(source(Src, _)), 563 retractall(used_class(_, Src)), 564 retractall(defined_class(_, _, _, Src, _)), 565 retractall(mode(_, Src)), 566 retractall(module_comment(Src, _, _)), 567 retractall(pred_comment(_, Src, _, _)), 568 retractall(pred_comment_link(_, Src, _)), 569 retractall(pred_mode(_, Src, _)). 570 571 572 /******************************* 573 * READ RESULTS * 574 *******************************/
580xref_current_source(Source) :-
581 source(Source, _Time).
588xref_done(Source, Time) :-
589 prolog_canonical_source(Source, Src),
590 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.
612xref_called(Source, Called, By) :- 613 xref_called(Source, Called, By, _). 614 615xref_called(Source, Called, By, Cond) :- 616 canonical_source(Source, Src), 617 distinct(Called-By, called(Called, Src, By, Cond, _)). 618 619xref_called(Source, Called, By, Cond, Line) :- 620 canonical_source(Source, Src), 621 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)
643xref_defined(Source, Called, How) :- 644 nonvar(Source), 645 !, 646 canonical_source(Source, Src), 647 xref_defined2(How, Src, Called). 648xref_defined(Source, Called, How) :- 649 xref_defined2(How, Src, Called), 650 canonical_source(Source, Src). 651 652xref_defined2(dynamic(Line), Src, Called) :- 653 dynamic(Called, Src, Line). 654xref_defined2(thread_local(Line), Src, Called) :- 655 thread_local(Called, Src, Line). 656xref_defined2(multifile(Line), Src, Called) :- 657 multifile(Called, Src, Line). 658xref_defined2(public(Line), Src, Called) :- 659 public(Called, Src, Line). 660xref_defined2(local(Line), Src, Called) :- 661 defined(Called, Src, Line). 662xref_defined2(foreign(Line), Src, Called) :- 663 foreign(Called, Src, Line). 664xref_defined2(constraint(Line), Src, Called) :- 665 ( constraint(Called, Src, Line) 666 -> true 667 ; declared(Called, chr_constraint, Src, Line) 668 ). 669xref_defined2(imported(From), Src, Called) :- 670 imported(Called, Src, From). 671xref_defined2(dcg, Src, Called) :- 672 grammar_rule(Called, Src).
680xref_definition_line(local(Line), Line). 681xref_definition_line(dynamic(Line), Line). 682xref_definition_line(thread_local(Line), Line). 683xref_definition_line(multifile(Line), Line). 684xref_definition_line(public(Line), Line). 685xref_definition_line(constraint(Line), Line). 686xref_definition_line(foreign(Line), Line).
693xref_exported(Source, Called) :-
694 prolog_canonical_source(Source, Src),
695 exported(Called, Src).
701xref_module(Source, Module) :- 702 nonvar(Source), 703 !, 704 prolog_canonical_source(Source, Src), 705 xmodule(Module, Src). 706xref_module(Source, Module) :- 707 xmodule(Module, Src), 708 prolog_canonical_source(Source, Src).
718xref_uses_file(Source, Spec, Path) :-
719 prolog_canonical_source(Source, Src),
720 uses_file(Spec, Src, Path).
730xref_op(Source, Op) :-
731 prolog_canonical_source(Source, Src),
732 xop(Src, Op).
740xref_prolog_flag(Source, Flag, Value, Line) :- 741 prolog_canonical_source(Source, Src), 742 xflag(Flag, Value, Src, Line). 743 744xref_built_in(Head) :- 745 system_predicate(Head). 746 747xref_used_class(Source, Class) :- 748 prolog_canonical_source(Source, Src), 749 used_class(Class, Src). 750 751xref_defined_class(Source, Class, local(Line, Super, Summary)) :- 752 prolog_canonical_source(Source, Src), 753 defined_class(Class, Super, Summary, Src, Line), 754 integer(Line), 755 !. 756xref_defined_class(Source, Class, file(File)) :- 757 prolog_canonical_source(Source, Src), 758 defined_class(Class, _, _, Src, file(File)). 759 760:- thread_local 761 current_cond/1, 762 source_line/1, 763 current_test_unit/2. 764 765current_source_line(Line) :- 766 source_line(Var), 767 !, 768 Line = Var.
776collect(Src, File, In, Options) :- 777 ( Src == File 778 -> SrcSpec = Line 779 ; SrcSpec = (File:Line) 780 ), 781 ( current_prolog_flag(xref_store_comments, OldStore) 782 -> true 783 ; OldStore = false 784 ), 785 option(comments(CommentHandling), Options, collect), 786 ( CommentHandling == ignore 787 -> CommentOptions = [], 788 Comments = [] 789 ; CommentHandling == store 790 -> CommentOptions = [ process_comment(true) ], 791 Comments = [], 792 set_prolog_flag(xref_store_comments, true) 793 ; CommentOptions = [ comments(Comments) ] 794 ), 795 repeat, 796 E = error(_,_), 797 catch(prolog_read_source_term( 798 In, Term, Expanded, 799 [ term_position(TermPos) 800 | CommentOptions 801 ]), 802 E, report_syntax_error(E, Src, [])), 803 update_condition(Term), 804 stream_position_data(line_count, TermPos, Line), 805 setup_call_cleanup( 806 asserta(source_line(SrcSpec), Ref), 807 catch(process(Expanded, Comments, Term, TermPos, Src, EOF), 808 E, print_message(error, E)), 809 erase(Ref)), 810 EOF == true, 811 !, 812 set_prolog_flag(xref_store_comments, OldStore). 813 814report_syntax_error(_, _, Options) :- 815 option(silent(true), Options), 816 !, 817 fail. 818report_syntax_error(E, Src, _Options) :- 819 ( verbose(Src) 820 -> print_message(error, E) 821 ; true 822 ), 823 fail.
829update_condition((:-Directive)) :- 830 !, 831 update_cond(Directive). 832update_condition(_). 833 834update_cond(if(Cond)) :- 835 !, 836 asserta(current_cond(Cond)). 837update_cond(else) :- 838 retract(current_cond(C0)), 839 !, 840 assert(current_cond(\+C0)). 841update_cond(elif(Cond)) :- 842 retract(current_cond(C0)), 843 !, 844 assert(current_cond((\+C0,Cond))). 845update_cond(endif) :- 846 retract(current_cond(_)), 847 !. 848update_cond(_).
855current_condition(Condition) :- 856 \+ current_cond(_), 857 !, 858 Condition = true. 859current_condition(Condition) :- 860 findall(C, current_cond(C), List), 861 list_to_conj(List, Condition). 862 863list_to_conj([], true). 864list_to_conj([C], C) :- !. 865list_to_conj([H|T], (H,C)) :- 866 list_to_conj(T, C). 867 868 869 /******************************* 870 * PROCESS * 871 *******************************/
883process(Expanded, Comments, Term0, TermPos, Src, EOF) :- 884 is_list(Expanded), % term_expansion into list. 885 !, 886 ( member(Term, Expanded), 887 process(Term, Term0, Src), 888 Term == end_of_file 889 -> EOF = true 890 ; EOF = false 891 ), 892 xref_comments(Comments, TermPos, Src). 893process(end_of_file, _, _, _, _, true) :- 894 !. 895process(Term, Comments, Term0, TermPos, Src, false) :- 896 process(Term, Term0, Src), 897 xref_comments(Comments, TermPos, Src).
901process(_, Term0, _) :- 902 ignore_raw_term(Term0), 903 !. 904process(Head :- Body, Head0 --> _, Src) :- 905 pi_head(F/A, Head), 906 pi_head(F/A0, Head0), 907 A =:= A0 + 2, 908 !, 909 assert_grammar_rule(Src, Head), 910 process((Head :- Body), Src). 911process(Term, _Term0, Src) :- 912 process(Term, Src). 913 914ignore_raw_term((:- predicate_options(_,_,_))).
918process(Var, _) :- 919 var(Var), 920 !. % Warn? 921process(end_of_file, _) :- !. 922process((:- Directive), Src) :- 923 !, 924 process_directive(Directive, Src), 925 !. 926process((?- Directive), Src) :- 927 !, 928 process_directive(Directive, Src), 929 !. 930process((Head :- Body), Src) :- 931 !, 932 assert_defined(Src, Head), 933 process_body(Body, Head, Src). 934process((Left => Body), Src) :- 935 !, 936 ( nonvar(Left), 937 Left = (Head, Guard) 938 -> assert_defined(Src, Head), 939 process_body(Guard, Head, Src), 940 process_body(Body, Head, Src) 941 ; assert_defined(Src, Left), 942 process_body(Body, Left, Src) 943 ). 944process(?=>(Head, Body), Src) :- 945 !, 946 assert_defined(Src, Head), 947 process_body(Body, Head, Src). 948process('$source_location'(_File, _Line):Clause, Src) :- 949 !, 950 process(Clause, Src). 951process(Term, Src) :- 952 process_chr(Term, Src), 953 !. 954process(M:(Head :- Body), Src) :- 955 !, 956 process((M:Head :- M:Body), Src). 957process(Head, Src) :- 958 assert_defined(Src, Head). 959 960 961 /******************************* 962 * COMMENTS * 963 *******************************/
967xref_comments([], _Pos, _Src). 968:- if(current_predicate(parse_comment/3)). 969xref_comments([Pos-Comment|T], TermPos, Src) :- 970 ( Pos @> TermPos % comments inside term 971 -> true 972 ; stream_position_data(line_count, Pos, Line), 973 FilePos = Src:Line, 974 ( parse_comment(Comment, FilePos, Parsed) 975 -> assert_comments(Parsed, Src) 976 ; true 977 ), 978 xref_comments(T, TermPos, Src) 979 ). 980 981assert_comments([], _). 982assert_comments([H|T], Src) :- 983 assert_comment(H, Src), 984 assert_comments(T, Src). 985 986assert_comment(section(_Id, Title, Comment), Src) :- 987 assertz(module_comment(Src, Title, Comment)). 988assert_comment(predicate(PI, Summary, Comment), Src) :- 989 pi_to_head(PI, Src, Head), 990 assertz(pred_comment(Head, Src, Summary, Comment)). 991assert_comment(link(PI, PITo), Src) :- 992 pi_to_head(PI, Src, Head), 993 pi_to_head(PITo, Src, HeadTo), 994 assertz(pred_comment_link(Head, Src, HeadTo)). 995assert_comment(mode(Head, Det), Src) :- 996 assertz(pred_mode(Head, Src, Det)). 997 998pi_to_head(PI, Src, Head) :- 999 pi_to_head(PI, Head0), 1000 ( Head0 = _:_ 1001 -> strip_module(Head0, M, Plain), 1002 ( xmodule(M, Src) 1003 -> Head = Plain 1004 ; Head = M:Plain 1005 ) 1006 ; Head = Head0 1007 ). 1008:- endif.
1014xref_comment(Source, Title, Comment) :-
1015 canonical_source(Source, Src),
1016 module_comment(Src, Title, Comment).
1022xref_comment(Source, Head, Summary, Comment) :-
1023 canonical_source(Source, Src),
1024 ( pred_comment(Head, Src, Summary, Comment)
1025 ; pred_comment_link(Head, Src, HeadTo),
1026 pred_comment(HeadTo, Src, Summary, Comment)
1027 ).
1034xref_mode(Source, Mode, Det) :-
1035 canonical_source(Source, Src),
1036 pred_mode(Mode, Src, Det).
1043xref_option(Source, Option) :- 1044 canonical_source(Source, Src), 1045 xoption(Src, Option). 1046 1047 1048 /******************************** 1049 * DIRECTIVES * 1050 ********************************/ 1051 1052process_directive(Var, _) :- 1053 var(Var), 1054 !. % error, but that isn't our business 1055process_directive(Dir, _Src) :- 1056 debug(xref(directive), 'Processing :- ~q', [Dir]), 1057 fail. 1058process_directive((A,B), Src) :- % TBD: what about other control 1059 !, 1060 process_directive(A, Src), % structures? 1061 process_directive(B, Src). 1062process_directive(List, Src) :- 1063 is_list(List), 1064 !, 1065 process_directive(consult(List), Src). 1066process_directive(use_module(File, Import), Src) :- 1067 process_use_module2(File, Import, Src, false). 1068process_directive(autoload(File, Import), Src) :- 1069 process_use_module2(File, Import, Src, false). 1070process_directive(require(Import), Src) :- 1071 process_requires(Import, Src). 1072process_directive(expects_dialect(Dialect), Src) :- 1073 process_directive(use_module(library(dialect/Dialect)), Src), 1074 expects_dialect(Dialect). 1075process_directive(reexport(File, Import), Src) :- 1076 process_use_module2(File, Import, Src, true). 1077process_directive(reexport(Modules), Src) :- 1078 process_use_module(Modules, Src, true). 1079process_directive(autoload(Modules), Src) :- 1080 process_use_module(Modules, Src, false). 1081process_directive(use_module(Modules), Src) :- 1082 process_use_module(Modules, Src, false). 1083process_directive(consult(Modules), Src) :- 1084 process_use_module(Modules, Src, false). 1085process_directive(ensure_loaded(Modules), Src) :- 1086 process_use_module(Modules, Src, false). 1087process_directive(load_files(Files, _Options), Src) :- 1088 process_use_module(Files, Src, false). 1089process_directive(include(Files), Src) :- 1090 process_include(Files, Src). 1091process_directive(dynamic(Dynamic), Src) :- 1092 process_predicates(assert_dynamic, Dynamic, Src). 1093process_directive(dynamic(Dynamic, _Options), Src) :- 1094 process_predicates(assert_dynamic, Dynamic, Src). 1095process_directive(thread_local(Dynamic), Src) :- 1096 process_predicates(assert_thread_local, Dynamic, Src). 1097process_directive(multifile(Dynamic), Src) :- 1098 process_predicates(assert_multifile, Dynamic, Src). 1099process_directive(public(Public), Src) :- 1100 process_predicates(assert_public, Public, Src). 1101process_directive(export(Export), Src) :- 1102 process_predicates(assert_export, Export, Src). 1103process_directive(import(Import), Src) :- 1104 process_import(Import, Src). 1105process_directive(module(Module, Export), Src) :- 1106 assert_module(Src, Module), 1107 assert_module_export(Src, Export). 1108process_directive(module(Module, Export, Import), Src) :- 1109 assert_module(Src, Module), 1110 assert_module_export(Src, Export), 1111 assert_module3(Import, Src). 1112process_directive(begin_tests(Unit, _Options), Src) :- 1113 enter_test_unit(Unit, Src). 1114process_directive(begin_tests(Unit), Src) :- 1115 enter_test_unit(Unit, Src). 1116process_directive(end_tests(Unit), Src) :- 1117 leave_test_unit(Unit, Src). 1118process_directive('$set_source_module'(system), Src) :- 1119 assert_module(Src, system). % hack for handling boot/init.pl 1120process_directive(pce_begin_class_definition(Name, Meta, Super, Doc), Src) :- 1121 assert_defined_class(Src, Name, Meta, Super, Doc). 1122process_directive(pce_autoload(Name, From), Src) :- 1123 assert_defined_class(Src, Name, imported_from(From)). 1124 1125process_directive(op(P, A, N), Src) :- 1126 xref_push_op(Src, P, A, N). 1127process_directive(set_prolog_flag(Flag, Value), Src) :- 1128 ( Flag == character_escapes 1129 -> set_prolog_flag(character_escapes, Value) 1130 ; true 1131 ), 1132 current_source_line(Line), 1133 xref_set_prolog_flag(Flag, Value, Src, Line). 1134process_directive(style_check(X), _) :- 1135 style_check(X). 1136process_directive(encoding(Enc), _) :- 1137 ( xref_input_stream(Stream) 1138 -> catch(set_stream(Stream, encoding(Enc)), error(_,_), true) 1139 ; true % can this happen? 1140 ). 1141process_directive(pce_expansion:push_compile_operators, _) :- 1142 '$current_source_module'(SM), 1143 call(pce_expansion:push_compile_operators(SM)). % call to avoid xref 1144process_directive(pce_expansion:pop_compile_operators, _) :- 1145 call(pce_expansion:pop_compile_operators). 1146process_directive(meta_predicate(Meta), Src) :- 1147 process_meta_predicate(Meta, Src). 1148process_directive(arithmetic_function(FSpec), Src) :- 1149 arith_callable(FSpec, Goal), 1150 !, 1151 current_source_line(Line), 1152 assert_called(Src, '<directive>'(Line), Goal, Line). 1153process_directive(format_predicate(_, Goal), Src) :- 1154 !, 1155 current_source_line(Line), 1156 assert_called(Src, '<directive>'(Line), Goal, Line). 1157process_directive(if(Cond), Src) :- 1158 !, 1159 current_source_line(Line), 1160 assert_called(Src, '<directive>'(Line), Cond, Line). 1161process_directive(elif(Cond), Src) :- 1162 !, 1163 current_source_line(Line), 1164 assert_called(Src, '<directive>'(Line), Cond, Line). 1165process_directive(else, _) :- !. 1166process_directive(endif, _) :- !. 1167process_directive(Goal, Src) :- 1168 current_source_line(Line), 1169 process_body(Goal, '<directive>'(Line), Src).
1175process_meta_predicate((A,B), Src) :- 1176 !, 1177 process_meta_predicate(A, Src), 1178 process_meta_predicate(B, Src). 1179process_meta_predicate(Decl, Src) :- 1180 process_meta_head(Src, Decl). 1181 1182process_meta_head(Src, Decl) :- % swapped arguments for maplist 1183 compound(Decl), 1184 compound_name_arity(Decl, Name, Arity), 1185 compound_name_arity(Head, Name, Arity), 1186 meta_args(1, Arity, Decl, Head, Meta), 1187 ( ( prolog:meta_goal(Head, _) 1188 ; prolog:called_by(Head, _, _, _) 1189 ; prolog:called_by(Head, _) 1190 ; meta_goal(Head, _) 1191 ) 1192 -> true 1193 ; assert(meta_goal(Head, Meta, Src)) 1194 ). 1195 1196meta_args(I, Arity, _, _, []) :- 1197 I > Arity, 1198 !. 1199meta_args(I, Arity, Decl, Head, [H|T]) :- % 0 1200 arg(I, Decl, 0), 1201 !, 1202 arg(I, Head, H), 1203 I2 is I + 1, 1204 meta_args(I2, Arity, Decl, Head, T). 1205meta_args(I, Arity, Decl, Head, [H|T]) :- % ^ 1206 arg(I, Decl, ^), 1207 !, 1208 arg(I, Head, EH), 1209 setof_goal(EH, H), 1210 I2 is I + 1, 1211 meta_args(I2, Arity, Decl, Head, T). 1212meta_args(I, Arity, Decl, Head, [//(H)|T]) :- 1213 arg(I, Decl, //), 1214 !, 1215 arg(I, Head, H), 1216 I2 is I + 1, 1217 meta_args(I2, Arity, Decl, Head, T). 1218meta_args(I, Arity, Decl, Head, [H+A|T]) :- % I --> H+I 1219 arg(I, Decl, A), 1220 integer(A), A > 0, 1221 !, 1222 arg(I, Head, H), 1223 I2 is I + 1, 1224 meta_args(I2, Arity, Decl, Head, T). 1225meta_args(I, Arity, Decl, Head, Meta) :- 1226 I2 is I + 1, 1227 meta_args(I2, Arity, Decl, Head, Meta). 1228 1229 1230 /******************************** 1231 * BODY * 1232 ********************************/
1241xref_meta(Source, Head, Called) :-
1242 canonical_source(Source, Src),
1243 xref_meta_src(Head, Called, Src).
1258xref_meta_src(Head, Called, Src) :- 1259 meta_goal(Head, Called, Src), 1260 !. 1261xref_meta_src(Head, Called, _) :- 1262 xref_meta(Head, Called), 1263 !. 1264xref_meta_src(Head, Called, _) :- 1265 compound(Head), 1266 compound_name_arity(Head, Name, Arity), 1267 apply_pred(Name), 1268 Arity > 5, 1269 !, 1270 Extra is Arity - 1, 1271 arg(1, Head, G), 1272 Called = [G+Extra]. 1273xref_meta_src(Head, Called, _) :- 1274 with_xref(predicate_property('$xref_tmp':Head, meta_predicate(Meta))), 1275 !, 1276 Meta =.. [_|Args], 1277 meta_args(Args, 1, Head, Called). 1278 1279meta_args([], _, _, []). 1280meta_args([H0|T0], I, Head, [H|T]) :- 1281 xargs(H0, N), 1282 !, 1283 arg(I, Head, A), 1284 ( N == 0 1285 -> H = A 1286 ; H = (A+N) 1287 ), 1288 I2 is I+1, 1289 meta_args(T0, I2, Head, T). 1290meta_args([_|T0], I, Head, T) :- 1291 I2 is I+1, 1292 meta_args(T0, I2, Head, T). 1293 1294xargs(N, N) :- integer(N), !. 1295xargs(//, 2). 1296xargs(^, 0). 1297 1298apply_pred(call). % built-in 1299apply_pred(maplist). % library(apply_macros) 1300 1301xref_meta((A, B), [A, B]). 1302xref_meta((A; B), [A, B]). 1303xref_meta((A| B), [A, B]). 1304xref_meta((A -> B), [A, B]). 1305xref_meta((A *-> B), [A, B]). 1306xref_meta(findall(_V,G,_L), [G]). 1307xref_meta(findall(_V,G,_L,_T), [G]). 1308xref_meta(findnsols(_N,_V,G,_L), [G]). 1309xref_meta(findnsols(_N,_V,G,_L,_T), [G]). 1310xref_meta(setof(_V, EG, _L), [G]) :- 1311 setof_goal(EG, G). 1312xref_meta(bagof(_V, EG, _L), [G]) :- 1313 setof_goal(EG, G). 1314xref_meta(forall(A, B), [A, B]). 1315xref_meta(maplist(G,_), [G+1]). 1316xref_meta(maplist(G,_,_), [G+2]). 1317xref_meta(maplist(G,_,_,_), [G+3]). 1318xref_meta(maplist(G,_,_,_,_), [G+4]). 1319xref_meta(map_list_to_pairs(G,_,_), [G+2]). 1320xref_meta(map_assoc(G, _), [G+1]). 1321xref_meta(map_assoc(G, _, _), [G+2]). 1322xref_meta(checklist(G, _L), [G+1]). 1323xref_meta(sublist(G, _, _), [G+1]). 1324xref_meta(include(G, _, _), [G+1]). 1325xref_meta(exclude(G, _, _), [G+1]). 1326xref_meta(partition(G, _, _, _, _), [G+2]). 1327xref_meta(partition(G, _, _, _),[G+1]). 1328xref_meta(call(G), [G]). 1329xref_meta(call(G, _), [G+1]). 1330xref_meta(call(G, _, _), [G+2]). 1331xref_meta(call(G, _, _, _), [G+3]). 1332xref_meta(call(G, _, _, _, _), [G+4]). 1333xref_meta(not(G), [G]). 1334xref_meta(notrace(G), [G]). 1335xref_meta('$notrace'(G), [G]). 1336xref_meta(\+(G), [G]). 1337xref_meta(ignore(G), [G]). 1338xref_meta(once(G), [G]). 1339xref_meta(initialization(G), [G]). 1340xref_meta(initialization(G,_), [G]). 1341xref_meta(retract(Rule), [G]) :- head_of(Rule, G). 1342xref_meta(clause(G, _), [G]). 1343xref_meta(clause(G, _, _), [G]). 1344xref_meta(phrase(G, _A), [//(G)]). 1345xref_meta(phrase(G, _A, _R), [//(G)]). 1346xref_meta(call_dcg(G, _A, _R), [//(G)]). 1347xref_meta(phrase_from_file(G,_),[//(G)]). 1348xref_meta(catch(A, _, B), [A, B]). 1349xref_meta(catch_with_backtrace(A, _, B), [A, B]). 1350xref_meta(thread_create(A,_,_), [A]). 1351xref_meta(thread_create(A,_), [A]). 1352xref_meta(thread_signal(_,A), [A]). 1353xref_meta(thread_idle(A,_), [A]). 1354xref_meta(thread_at_exit(A), [A]). 1355xref_meta(thread_initialization(A), [A]). 1356xref_meta(engine_create(_,A,_), [A]). 1357xref_meta(engine_create(_,A,_,_), [A]). 1358xref_meta(transaction(A), [A]). 1359xref_meta(transaction(A,B,_), [A,B]). 1360xref_meta(snapshot(A), [A]). 1361xref_meta(predsort(A,_,_), [A+3]). 1362xref_meta(call_cleanup(A, B), [A, B]). 1363xref_meta(call_cleanup(A, _, B),[A, B]). 1364xref_meta(setup_call_cleanup(A, B, C),[A, B, C]). 1365xref_meta(setup_call_catcher_cleanup(A, B, _, C),[A, B, C]). 1366xref_meta(call_residue_vars(A,_), [A]). 1367xref_meta(with_mutex(_,A), [A]). 1368xref_meta(assume(G), [G]). % library(debug) 1369xref_meta(assertion(G), [G]). % library(debug) 1370xref_meta(freeze(_, G), [G]). 1371xref_meta(when(C, A), [C, A]). 1372xref_meta(time(G), [G]). % development system 1373xref_meta(call_time(G, _), [G]). % development system 1374xref_meta(call_time(G, _, _), [G]). % development system 1375xref_meta(profile(G), [G]). 1376xref_meta(at_halt(G), [G]). 1377xref_meta(call_with_time_limit(_, G), [G]). 1378xref_meta(call_with_depth_limit(G, _, _), [G]). 1379xref_meta(call_with_inference_limit(G, _, _), [G]). 1380xref_meta(alarm(_, G, _), [G]). 1381xref_meta(alarm(_, G, _, _), [G]). 1382xref_meta('$add_directive_wic'(G), [G]). 1383xref_meta(with_output_to(_, G), [G]). 1384xref_meta(if(G), [G]). 1385xref_meta(elif(G), [G]). 1386xref_meta(meta_options(G,_,_), [G+1]). 1387xref_meta(on_signal(_,_,H), [H+1]) :- H \== default. 1388xref_meta(distinct(G), [G]). % library(solution_sequences) 1389xref_meta(distinct(_, G), [G]). 1390xref_meta(order_by(_, G), [G]). 1391xref_meta(limit(_, G), [G]). 1392xref_meta(offset(_, G), [G]). 1393xref_meta(reset(G,_,_), [G]). 1394xref_meta(prolog_listen(Ev,G), [G+N]) :- event_xargs(Ev, N). 1395xref_meta(prolog_listen(Ev,G,_),[G+N]) :- event_xargs(Ev, N). 1396xref_meta(tnot(G), [G]). 1397xref_meta(not_exists(G), [G]). 1398xref_meta(with_tty_raw(G), [G]). 1399xref_meta(residual_goals(G), [G+2]). 1400 1401 % XPCE meta-predicates 1402xref_meta(pce_global(_, new(_)), _) :- !, fail. 1403xref_meta(pce_global(_, B), [B+1]). 1404xref_meta(ifmaintainer(G), [G]). % used in manual 1405xref_meta(listen(_, G), [G]). % library(broadcast) 1406xref_meta(listen(_, _, G), [G]). 1407xref_meta(in_pce_thread(G), [G]). 1408 1409xref_meta(G, Meta) :- % call user extensions 1410 prolog:meta_goal(G, Meta). 1411xref_meta(G, Meta) :- % Generated from :- meta_predicate 1412 meta_goal(G, Meta). 1413 1414setof_goal(EG, G) :- 1415 var(EG), !, G = EG. 1416setof_goal(_^EG, G) :- 1417 !, 1418 setof_goal(EG, G). 1419setof_goal(G, G). 1420 1421event_xargs(abort, 0). 1422event_xargs(erase, 1). 1423event_xargs(break, 3). 1424event_xargs(frame_finished, 1). 1425event_xargs(thread_exit, 1). 1426event_xargs(this_thread_exit, 0). 1427event_xargs(PI, 2) :- pi_to_head(PI, _).
1433head_of(Var, _) :- 1434 var(Var), !, fail. 1435head_of((Head :- _), Head). 1436head_of(Head, Head).
1444xref_hook(Hook) :- 1445 prolog:hook(Hook). 1446xref_hook(Hook) :- 1447 hook(Hook). 1448 1449 1450hook(attr_portray_hook(_,_)). 1451hook(attr_unify_hook(_,_)). 1452hook(attribute_goals(_,_,_)). 1453hook(goal_expansion(_,_)). 1454hook(term_expansion(_,_)). 1455hook(goal_expansion(_,_,_,_)). 1456hook(term_expansion(_,_,_,_)). 1457hook(resource(_,_,_)). 1458hook('$pred_option'(_,_,_,_)). 1459hook('$nowarn_autoload'(_,_)). 1460 1461hook(emacs_prolog_colours:goal_classification(_,_)). 1462hook(emacs_prolog_colours:goal_colours(_,_)). 1463hook(emacs_prolog_colours:identify(_,_)). 1464hook(emacs_prolog_colours:style(_,_)). 1465hook(emacs_prolog_colours:term_colours(_,_)). 1466hook(pce_principal:get_implementation(_,_,_,_)). 1467hook(pce_principal:pce_class(_,_,_,_,_,_)). 1468hook(pce_principal:pce_lazy_get_method(_,_,_)). 1469hook(pce_principal:pce_lazy_send_method(_,_,_)). 1470hook(pce_principal:pce_uses_template(_,_)). 1471hook(pce_principal:send_implementation(_,_,_)). 1472hook(predicate_options:option_decl(_,_,_)). 1473hook(prolog:debug_control_hook(_)). 1474hook(prolog:error_message(_,_,_)). 1475hook(prolog:expand_answer(_,_,_)). 1476hook(prolog:general_exception(_,_)). 1477hook(prolog:help_hook(_)). 1478hook(prolog:locate_clauses(_,_)). 1479hook(prolog:message(_,_,_)). 1480hook(prolog:message_context(_,_,_)). 1481hook(prolog:message_line_element(_,_)). 1482hook(prolog:message_location(_,_,_)). 1483hook(prolog:predicate_summary(_,_)). 1484hook(prolog:prolog_exception_hook(_,_,_,_,_)). 1485hook(prolog:residual_goals(_,_)). 1486hook(prolog:show_profile_hook(_,_)). 1487hook(prolog_edit:load). 1488hook(prolog_edit:locate(_,_,_)). 1489hook(sandbox:safe_directive(_)). 1490hook(sandbox:safe_global_variable(_)). 1491hook(sandbox:safe_meta(_,_)). 1492hook(sandbox:safe_meta_predicate(_)). 1493hook(sandbox:safe_primitive(_)). 1494hook(sandbox:safe_prolog_flag(_,_)). 1495hook(shlib:unload_all_foreign_libraries). 1496hook(system:'$foreign_registered'(_, _)). 1497hook(user:exception(_,_,_)). 1498hook(user:expand_answer(_,_)). 1499hook(user:expand_query(_,_,_,_)). 1500hook(user:file_search_path(_,_)). 1501hook(user:library_directory(_)). 1502hook(user:message_hook(_,_,_)). 1503hook(user:portray(_)). 1504hook(user:prolog_clause_name(_,_)). 1505hook(user:prolog_list_goal(_)). 1506hook(user:prolog_predicate_name(_,_)). 1507hook(user:prolog_trace_interception(_,_,_,_)).
1513arith_callable(Var, _) :- 1514 var(Var), !, fail. 1515arith_callable(Module:Spec, Module:Goal) :- 1516 !, 1517 arith_callable(Spec, Goal). 1518arith_callable(Name/Arity, Goal) :- 1519 PredArity is Arity + 1, 1520 functor(Goal, Name, PredArity).
We limit the number of explored paths to 100 to avoid getting trapped in this analysis.
1531process_body(Body, Origin, Src) :-
1532 forall(limit(100, process_goal(Body, Origin, Src, _Partial)),
1533 true).
true
if there was a
partial evalation inside Goal that has bound variables.1540process_goal(Var, _, _, _) :- 1541 var(Var), 1542 !. 1543process_goal(_:Goal, _, _, _) :- 1544 var(Goal), 1545 !. 1546process_goal(Goal, Origin, Src, P) :- 1547 Goal = (_,_), % problems 1548 !, 1549 phrase(conjunction(Goal), Goals), 1550 process_conjunction(Goals, Origin, Src, P). 1551process_goal(Goal, Origin, Src, _) :- % Final disjunction, no 1552 Goal = (_;_), % problems 1553 !, 1554 phrase(disjunction(Goal), Goals), 1555 forall(member(G, Goals), 1556 process_body(G, Origin, Src)). 1557process_goal(Goal, Origin, Src, P) :- 1558 ( ( xmodule(M, Src) 1559 -> true 1560 ; M = user 1561 ), 1562 pi_head(PI, M:Goal), 1563 ( current_predicate(PI), 1564 predicate_property(M:Goal, imported_from(IM)) 1565 -> true 1566 ; PI = M:Name/Arity, 1567 '$find_library'(M, Name, Arity, IM, _Library) 1568 -> true 1569 ; IM = M 1570 ), 1571 prolog:called_by(Goal, IM, M, Called) 1572 ; prolog:called_by(Goal, Called) 1573 ), 1574 !, 1575 must_be(list, Called), 1576 current_source_line(Here), 1577 assert_called(Src, Origin, Goal, Here), 1578 process_called_list(Called, Origin, Src, P). 1579process_goal(Goal, Origin, Src, _) :- 1580 process_xpce_goal(Goal, Origin, Src), 1581 !. 1582process_goal(load_foreign_library(File), _Origin, Src, _) :- 1583 process_foreign(File, Src). 1584process_goal(load_foreign_library(File, _Init), _Origin, Src, _) :- 1585 process_foreign(File, Src). 1586process_goal(use_foreign_library(File), _Origin, Src, _) :- 1587 process_foreign(File, Src). 1588process_goal(use_foreign_library(File, _Init), _Origin, Src, _) :- 1589 process_foreign(File, Src). 1590process_goal(Goal, Origin, Src, P) :- 1591 xref_meta_src(Goal, Metas, Src), 1592 !, 1593 current_source_line(Here), 1594 assert_called(Src, Origin, Goal, Here), 1595 process_called_list(Metas, Origin, Src, P). 1596process_goal(Goal, Origin, Src, _) :- 1597 asserting_goal(Goal, Rule), 1598 !, 1599 current_source_line(Here), 1600 assert_called(Src, Origin, Goal, Here), 1601 process_assert(Rule, Origin, Src). 1602process_goal(Goal, Origin, Src, P) :- 1603 partial_evaluate(Goal, P), 1604 current_source_line(Here), 1605 assert_called(Src, Origin, Goal, Here). 1606 1607disjunction(Var) --> {var(Var), !}, [Var]. 1608disjunction((A;B)) --> !, disjunction(A), disjunction(B). 1609disjunction(G) --> [G]. 1610 1611conjunction(Var) --> {var(Var), !}, [Var]. 1612conjunction((A,B)) --> !, conjunction(A), conjunction(B). 1613conjunction(G) --> [G]. 1614 RVars, T) (:- 1616 term_variables(T, TVars0), 1617 sort(TVars0, TVars), 1618 ord_intersect(RVars, TVars). 1619 1620process_conjunction([], _, _, _). 1621process_conjunction([Disj|Rest], Origin, Src, P) :- 1622 nonvar(Disj), 1623 Disj = (_;_), 1624 Rest \== [], 1625 !, 1626 phrase(disjunction(Disj), Goals), 1627 term_variables(Rest, RVars0), 1628 sort(RVars0, RVars), 1629 partition(shares_vars(RVars), Goals, Sharing, NonSHaring), 1630 forall(member(G, NonSHaring), 1631 process_body(G, Origin, Src)), 1632 ( Sharing == [] 1633 -> true 1634 ; maplist(term_variables, Sharing, GVars0), 1635 append(GVars0, GVars1), 1636 sort(GVars1, GVars), 1637 ord_intersection(GVars, RVars, SVars), 1638 VT =.. [v|SVars], 1639 findall(VT, 1640 ( member(G, Sharing), 1641 process_goal(G, Origin, Src, PS), 1642 PS == true 1643 ), 1644 Alts0), 1645 ( Alts0 == [] 1646 -> true 1647 ; ( true 1648 ; P = true, 1649 sort(Alts0, Alts1), 1650 variants(Alts1, 10, Alts), 1651 member(VT, Alts) 1652 ) 1653 ) 1654 ), 1655 process_conjunction(Rest, Origin, Src, P). 1656process_conjunction([H|T], Origin, Src, P) :- 1657 process_goal(H, Origin, Src, P), 1658 process_conjunction(T, Origin, Src, P). 1659 1660 1661process_called_list([], _, _, _). 1662process_called_list([H|T], Origin, Src, P) :- 1663 process_meta(H, Origin, Src, P), 1664 process_called_list(T, Origin, Src, P). 1665 1666process_meta(A+N, Origin, Src, P) :- 1667 !, 1668 ( extend(A, N, AX) 1669 -> process_goal(AX, Origin, Src, P) 1670 ; true 1671 ). 1672process_meta(//(A), Origin, Src, P) :- 1673 !, 1674 process_dcg_goal(A, Origin, Src, P). 1675process_meta(G, Origin, Src, P) :- 1676 process_goal(G, Origin, Src, P).
1683process_dcg_goal(Var, _, _, _) :- 1684 var(Var), 1685 !. 1686process_dcg_goal((A,B), Origin, Src, P) :- 1687 !, 1688 process_dcg_goal(A, Origin, Src, P), 1689 process_dcg_goal(B, Origin, Src, P). 1690process_dcg_goal((A;B), Origin, Src, P) :- 1691 !, 1692 process_dcg_goal(A, Origin, Src, P), 1693 process_dcg_goal(B, Origin, Src, P). 1694process_dcg_goal((A|B), Origin, Src, P) :- 1695 !, 1696 process_dcg_goal(A, Origin, Src, P), 1697 process_dcg_goal(B, Origin, Src, P). 1698process_dcg_goal((A->B), Origin, Src, P) :- 1699 !, 1700 process_dcg_goal(A, Origin, Src, P), 1701 process_dcg_goal(B, Origin, Src, P). 1702process_dcg_goal((A*->B), Origin, Src, P) :- 1703 !, 1704 process_dcg_goal(A, Origin, Src, P), 1705 process_dcg_goal(B, Origin, Src, P). 1706process_dcg_goal({Goal}, Origin, Src, P) :- 1707 !, 1708 process_goal(Goal, Origin, Src, P). 1709process_dcg_goal(List, _Origin, _Src, _) :- 1710 is_list(List), 1711 !. % terminal 1712process_dcg_goal(List, _Origin, _Src, _) :- 1713 string(List), 1714 !. % terminal 1715process_dcg_goal(Callable, Origin, Src, P) :- 1716 extend(Callable, 2, Goal), 1717 !, 1718 process_goal(Goal, Origin, Src, P). 1719process_dcg_goal(_, _, _, _). 1720 1721 1722extend(Var, _, _) :- 1723 var(Var), !, fail. 1724extend(M:G, N, M:GX) :- 1725 !, 1726 callable(G), 1727 extend(G, N, GX). 1728extend(G, N, GX) :- 1729 ( compound(G) 1730 -> compound_name_arguments(G, Name, Args), 1731 length(Rest, N), 1732 append(Args, Rest, NArgs), 1733 compound_name_arguments(GX, Name, NArgs) 1734 ; atom(G) 1735 -> length(NArgs, N), 1736 compound_name_arguments(GX, G, NArgs) 1737 ). 1738 1739asserting_goal(assert(Rule), Rule). 1740asserting_goal(asserta(Rule), Rule). 1741asserting_goal(assertz(Rule), Rule). 1742asserting_goal(assert(Rule,_), Rule). 1743asserting_goal(asserta(Rule,_), Rule). 1744asserting_goal(assertz(Rule,_), Rule). 1745 1746process_assert(0, _, _) :- !. % catch variables 1747process_assert((_:-Body), Origin, Src) :- 1748 !, 1749 process_body(Body, Origin, Src). 1750process_assert(_, _, _).
1754variants([], _, []). 1755variants([H|T], Max, List) :- 1756 variants(T, H, Max, List). 1757 1758variants([], H, _, [H]). 1759variants(_, _, 0, []) :- !. 1760variants([H|T], V, Max, List) :- 1761 ( H =@= V 1762 -> variants(T, V, Max, List) 1763 ; List = [V|List2], 1764 Max1 is Max-1, 1765 variants(T, H, Max1, List2) 1766 ).
T = hello(X), findall(T, T, List),
1780partial_evaluate(Goal, P) :- 1781 eval(Goal), 1782 !, 1783 P = true. 1784partial_evaluate(_, _). 1785 1786eval(X = Y) :- 1787 unify_with_occurs_check(X, Y). 1788 1789 /******************************* 1790 * PLUNIT SUPPORT * 1791 *******************************/ 1792 1793enter_test_unit(Unit, _Src) :- 1794 current_source_line(Line), 1795 asserta(current_test_unit(Unit, Line)). 1796 1797leave_test_unit(Unit, _Src) :- 1798 retractall(current_test_unit(Unit, _)). 1799 1800 1801 /******************************* 1802 * XPCE STUFF * 1803 *******************************/ 1804 1805pce_goal(new(_,_), new(-, new)). 1806pce_goal(send(_,_), send(arg, msg)). 1807pce_goal(send_class(_,_,_), send_class(arg, arg, msg)). 1808pce_goal(get(_,_,_), get(arg, msg, -)). 1809pce_goal(get_class(_,_,_,_), get_class(arg, arg, msg, -)). 1810pce_goal(get_chain(_,_,_), get_chain(arg, msg, -)). 1811pce_goal(get_object(_,_,_), get_object(arg, msg, -)). 1812 1813process_xpce_goal(G, Origin, Src) :- 1814 pce_goal(G, Process), 1815 !, 1816 current_source_line(Here), 1817 assert_called(Src, Origin, G, Here), 1818 ( arg(I, Process, How), 1819 arg(I, G, Term), 1820 process_xpce_arg(How, Term, Origin, Src), 1821 fail 1822 ; true 1823 ). 1824 1825process_xpce_arg(new, Term, Origin, Src) :- 1826 callable(Term), 1827 process_new(Term, Origin, Src). 1828process_xpce_arg(arg, Term, Origin, Src) :- 1829 compound(Term), 1830 process_new(Term, Origin, Src). 1831process_xpce_arg(msg, Term, Origin, Src) :- 1832 compound(Term), 1833 ( arg(_, Term, Arg), 1834 process_xpce_arg(arg, Arg, Origin, Src), 1835 fail 1836 ; true 1837 ). 1838 1839process_new(_M:_Term, _, _) :- !. % TBD: Calls on other modules! 1840process_new(Term, Origin, Src) :- 1841 assert_new(Src, Origin, Term), 1842 ( compound(Term), 1843 arg(_, Term, Arg), 1844 process_xpce_arg(arg, Arg, Origin, Src), 1845 fail 1846 ; true 1847 ). 1848 1849assert_new(_, _, Term) :- 1850 \+ callable(Term), 1851 !. 1852assert_new(Src, Origin, Control) :- 1853 functor_name(Control, Class), 1854 pce_control_class(Class), 1855 !, 1856 forall(arg(_, Control, Arg), 1857 assert_new(Src, Origin, Arg)). 1858assert_new(Src, Origin, Term) :- 1859 compound(Term), 1860 arg(1, Term, Prolog), 1861 Prolog == @(prolog), 1862 ( Term =.. [message, _, Selector | T], 1863 atom(Selector) 1864 -> Called =.. [Selector|T], 1865 process_body(Called, Origin, Src) 1866 ; Term =.. [?, _, Selector | T], 1867 atom(Selector) 1868 -> append(T, [_R], T2), 1869 Called =.. [Selector|T2], 1870 process_body(Called, Origin, Src) 1871 ), 1872 fail. 1873assert_new(_, _, @(_)) :- !. 1874assert_new(Src, _, Term) :- 1875 functor_name(Term, Name), 1876 assert_used_class(Src, Name). 1877 1878 1879pce_control_class(and). 1880pce_control_class(or). 1881pce_control_class(if). 1882pce_control_class(not). 1883 1884 1885 /******************************** 1886 * INCLUDED MODULES * 1887 ********************************/
1891process_use_module(_Module:_Files, _, _) :- !. % loaded in another module 1892process_use_module([], _, _) :- !. 1893process_use_module([H|T], Src, Reexport) :- 1894 !, 1895 process_use_module(H, Src, Reexport), 1896 process_use_module(T, Src, Reexport). 1897process_use_module(library(pce), Src, Reexport) :- % bit special 1898 !, 1899 xref_public_list(library(pce), Path, Exports, Src), 1900 forall(member(Import, Exports), 1901 process_pce_import(Import, Src, Path, Reexport)). 1902process_use_module(File, Src, Reexport) :- 1903 load_module_if_needed(File), 1904 ( xoption(Src, silent(Silent)) 1905 -> Extra = [silent(Silent)] 1906 ; Extra = [silent(true)] 1907 ), 1908 ( xref_public_list(File, Src, 1909 [ path(Path), 1910 module(M), 1911 exports(Exports), 1912 public(Public), 1913 meta(Meta) 1914 | Extra 1915 ]) 1916 -> assert(uses_file(File, Src, Path)), 1917 assert_import(Src, Exports, _, Path, Reexport), 1918 assert_xmodule_callable(Exports, M, Src, Path), 1919 assert_xmodule_callable(Public, M, Src, Path), 1920 maplist(process_meta_head(Src), Meta), 1921 ( File = library(chr) % hacky 1922 -> assert(mode(chr, Src)) 1923 ; true 1924 ) 1925 ; assert(uses_file(File, Src, '<not_found>')) 1926 ). 1927 1928process_pce_import(Name/Arity, Src, Path, Reexport) :- 1929 atom(Name), 1930 integer(Arity), 1931 !, 1932 functor(Term, Name, Arity), 1933 ( \+ system_predicate(Term), 1934 \+ Term = pce_error(_) % hack!? 1935 -> assert_import(Src, [Name/Arity], _, Path, Reexport) 1936 ; true 1937 ). 1938process_pce_import(op(P,T,N), Src, _, _) :- 1939 xref_push_op(Src, P, T, N).
1945process_use_module2(File, Import, Src, Reexport) :-
1946 load_module_if_needed(File),
1947 ( catch(xref_public_list(File, Src,
1948 [ path(Path),
1949 exports(Export),
1950 meta(Meta)
1951 ]),
1952 error(_,_),
1953 fail)
1954 -> assertz(uses_file(File, Src, Path)),
1955 assert_import(Src, Import, Export, Path, Reexport),
1956 forall(( member(Head, Meta),
1957 imported(Head, _, Path)
1958 ),
1959 process_meta_head(Src, Head))
1960 ; assertz(uses_file(File, Src, '<not_found>'))
1961 ).
1970load_module_if_needed(File) :- 1971 prolog:no_autoload_module(File), 1972 !, 1973 use_module(File, []). 1974load_module_if_needed(_). 1975 1976prologno_autoload_module(library(apply_macros)). 1977prologno_autoload_module(library(arithmetic)). 1978prologno_autoload_module(library(record)). 1979prologno_autoload_module(library(persistency)). 1980prologno_autoload_module(library(pldoc)). 1981prologno_autoload_module(library(settings)). 1982prologno_autoload_module(library(debug)). 1983prologno_autoload_module(library(plunit)). 1984prologno_autoload_module(library(macros)). 1985prologno_autoload_module(library(yall)).
1990process_requires(Import, Src) :- 1991 is_list(Import), 1992 !, 1993 require_list(Import, Src). 1994process_requires(Var, _Src) :- 1995 var(Var), 1996 !. 1997process_requires((A,B), Src) :- 1998 !, 1999 process_requires(A, Src), 2000 process_requires(B, Src). 2001process_requires(PI, Src) :- 2002 requires(PI, Src). 2003 2004require_list([], _). 2005require_list([H|T], Src) :- 2006 requires(H, Src), 2007 require_list(T, Src). 2008 2009requires(PI, _Src) :- 2010 '$pi_head'(PI, Head), 2011 '$get_predicate_attribute'(system:Head, defined, 1), 2012 !. 2013requires(PI, Src) :- 2014 '$pi_head'(PI, Head), 2015 '$pi_head'(Name/Arity, Head), 2016 '$find_library'(_Module, Name, Arity, _LoadModule, Library), 2017 ( imported(Head, Src, Library) 2018 -> true 2019 ; assertz(imported(Head, Src, Library)) 2020 ).
[]
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.
2056xref_public_list(File, Src, Options) :-
2057 option(path(Source), Options, _),
2058 option(module(Module), Options, _),
2059 option(exports(Exports), Options, _),
2060 option(public(Public), Options, _),
2061 option(meta(Meta), Options, _),
2062 xref_source_file(File, Path, Src, Options),
2063 public_list(Path, Source, Module, Meta, Exports, Public, Options).
These predicates fail if File is not a module-file.
2085xref_public_list(File, Source, Export, Src) :- 2086 xref_source_file(File, Path, Src), 2087 public_list(Path, Source, _, _, Export, _, []). 2088xref_public_list(File, Source, Module, Export, Meta, Src) :- 2089 xref_source_file(File, Path, Src), 2090 public_list(Path, Source, Module, Meta, Export, _, []). 2091xref_public_list(File, Source, Module, Export, Public, Meta, Src) :- 2092 xref_source_file(File, Path, Src), 2093 public_list(Path, Source, Module, Meta, Export, Public, []).
true
, ignore (syntax) errors. If not specified the default
is inherited from xref_source/2.2104:- dynamic public_list_cache/7. 2105:- volatile public_list_cache/7. 2106 2107public_list(Path, Source, Module, Meta, Export, Public, _Options) :- 2108 public_list_cache(Path, Source, Modified, 2109 Module0, Meta0, Export0, Public0), 2110 time_file(Path, ModifiedNow), 2111 ( abs(Modified-ModifiedNow) < 0.0001 2112 -> !, 2113 t(Module,Meta,Export,Public) = t(Module0,Meta0,Export0,Public0) 2114 ; retractall(public_list_cache(Path, _, _, _, _, _, _)), 2115 fail 2116 ). 2117public_list(Path, Source, Module, Meta, Export, Public, Options) :- 2118 public_list_nc(Path, Source, Module0, Meta0, Export0, Public0, Options), 2119 ( Error = error(_,_), 2120 catch(time_file(Path, Modified), Error, fail) 2121 -> asserta(public_list_cache(Path, Source, Modified, 2122 Module0, Meta0, Export0, Public0)) 2123 ; true 2124 ), 2125 t(Module,Meta,Export,Public) = t(Module0,Meta0,Export0,Public0). 2126 2127public_list_nc(Path, Source, Module, Meta, Export, Public, _Options) :- 2128 public_list_from_index(Path, Module, Meta, Export, Public), 2129 !, 2130 qlf_pl_file(Path, Source). 2131public_list_nc(Path, Source, Module, [], Export, [], _Options) :- 2132 is_qlf_file(Path), 2133 !, 2134 '$qlf_module'(Path, Info), 2135 _{module:Module, exports:Export, file:Source} :< Info. 2136public_list_nc(Path, Path, Module, Meta, Export, Public, Options) :- 2137 exists_file(Path), 2138 !, 2139 prolog_file_directives(Path, Directives, Options), 2140 public_list(Directives, Path, Module, Meta, [], Export, [], Public, []). 2141public_list_nc(Path, Path, Module, [], Export, [], _Options) :- 2142 qlf_pl_file(QlfFile, Path), 2143 '$qlf_module'(QlfFile, Info), 2144 _{module:Module, exports:Export} :< Info. 2145 2146public_list([(:- module(Module, Export0))|Decls], Path, 2147 Module, Meta, MT, Export, Rest, Public, PT) :- 2148 !, 2149 ( is_list(Export0) 2150 -> append(Export0, Reexport, Export) 2151 ; Reexport = Export 2152 ), 2153 public_list_(Decls, Path, Meta, MT, Reexport, Rest, Public, PT). 2154public_list([(:- encoding(_))|Decls], Path, 2155 Module, Meta, MT, Export, Rest, Public, PT) :- 2156 public_list(Decls, Path, Module, Meta, MT, Export, Rest, Public, PT). 2157 2158public_list_([], _, Meta, Meta, Export, Export, Public, Public). 2159public_list_([(:-(Dir))|T], Path, Meta, MT, Export, Rest, Public, PT) :- 2160 public_list_1(Dir, Path, Meta, MT0, Export, Rest0, Public, PT0), 2161 !, 2162 public_list_(T, Path, MT0, MT, Rest0, Rest, PT0, PT). 2163public_list_([_|T], Path, Meta, MT, Export, Rest, Public, PT) :- 2164 public_list_(T, Path, Meta, MT, Export, Rest, Public, PT). 2165 2166public_list_1(reexport(Spec), Path, Meta, MT, Reexport, Rest, Public, PT) :- 2167 reexport_files(Spec, Path, Meta, MT, Reexport, Rest, Public, PT). 2168public_list_1(reexport(Spec, Import), Path, Meta, Meta, Reexport, Rest, Public, Public) :- 2169 public_from_import(Import, Spec, Path, Reexport, Rest). 2170public_list_1(meta_predicate(Decl), _Path, Meta, MT, Export, Export, Public, Public) :- 2171 phrase(meta_decls(Decl), Meta, MT). 2172public_list_1(public(Decl), _Path, Meta, Meta, Export, Export, Public, PT) :- 2173 phrase(public_decls(Decl), Public, PT).
2179reexport_files([], _, Meta, Meta, Export, Export, Public, Public) :- !. 2180reexport_files([H|T], Src, Meta, MT, Export, ET, Public, PT) :- 2181 !, 2182 xref_source_file(H, Path, Src), 2183 public_list(Path, _Source, _Module, Meta0, Export0, Public0, []), 2184 append(Meta0, MT1, Meta), 2185 append(Export0, ET1, Export), 2186 append(Public0, PT1, Public), 2187 reexport_files(T, Src, MT1, MT, ET1, ET, PT1, PT). 2188reexport_files(Spec, Src, Meta, MT, Export, ET, Public, PT) :- 2189 xref_source_file(Spec, Path, Src), 2190 public_list(Path, _Source, _Module, Meta0, Export0, Public0, []), 2191 append(Meta0, MT, Meta), 2192 append(Export0, ET, Export), 2193 append(Public0, PT, Public). 2194 2195public_from_import(except(Map), Path, Src, Export, Rest) :- 2196 !, 2197 xref_public_list(Path, _, AllExports, Src), 2198 except(Map, AllExports, NewExports), 2199 append(NewExports, Rest, Export). 2200public_from_import(Import, _, _, Export, Rest) :- 2201 import_name_map(Import, Export, Rest).
2206except([], Exports, Exports). 2207except([PI0 as NewName|Map], Exports0, Exports) :- 2208 !, 2209 canonical_pi(PI0, PI), 2210 map_as(Exports0, PI, NewName, Exports1), 2211 except(Map, Exports1, Exports). 2212except([PI0|Map], Exports0, Exports) :- 2213 canonical_pi(PI0, PI), 2214 select(PI2, Exports0, Exports1), 2215 same_pi(PI, PI2), 2216 !, 2217 except(Map, Exports1, Exports). 2218 2219 2220map_as([PI|T], Repl, As, [PI2|T]) :- 2221 same_pi(Repl, PI), 2222 !, 2223 pi_as(PI, As, PI2). 2224map_as([H|T0], Repl, As, [H|T]) :- 2225 map_as(T0, Repl, As, T). 2226 2227pi_as(_/Arity, Name, Name/Arity). 2228pi_as(_//Arity, Name, Name//Arity). 2229 2230import_name_map([], L, L). 2231import_name_map([_/Arity as NewName|T0], [NewName/Arity|T], Tail) :- 2232 !, 2233 import_name_map(T0, T, Tail). 2234import_name_map([_//Arity as NewName|T0], [NewName//Arity|T], Tail) :- 2235 !, 2236 import_name_map(T0, T, Tail). 2237import_name_map([H|T0], [H|T], Tail) :- 2238 import_name_map(T0, T, Tail). 2239 2240canonical_pi(Name//Arity0, PI) :- 2241 integer(Arity0), 2242 !, 2243 PI = Name/Arity, 2244 Arity is Arity0 + 2. 2245canonical_pi(PI, PI). 2246 2247same_pi(Canonical, PI2) :- 2248 canonical_pi(PI2, Canonical). 2249 2250meta_decls(Var) --> 2251 { var(Var) }, 2252 !. 2253meta_decls((A,B)) --> 2254 !, 2255 meta_decls(A), 2256 meta_decls(B). 2257meta_decls(A) --> 2258 [A]. 2259 2260public_decls(Var) --> 2261 { var(Var) }, 2262 !. 2263public_decls((A,B)) --> 2264 !, 2265 public_decls(A), 2266 public_decls(B). 2267public_decls(A) --> 2268 [A].
INDEX.pl
file in the same
directory.2275public_list_from_index(Path, Module, Meta, Export, Public) :- 2276 file_name_extension(BasePath, _Ext, Path), 2277 file_directory_name(BasePath, Dir), 2278 atom_concat(Dir, '/INDEX.pl', IndexFile), 2279 exists_file(IndexFile), 2280 file_base_name(BasePath, Base), 2281 setup_call_cleanup( 2282 '$push_input_context'(autoload_index), 2283 setup_call_cleanup( 2284 open(IndexFile, read, In), 2285 index_public_list(In, Base, Module, Meta, Export, Public), 2286 close(In)), 2287 '$pop_input_context'). 2288 2289index_public_list(In, Base, Module, Meta, Export, Public) :- 2290 read_term(In, Term, []), 2291 index_public_list(Term, In, Base, Module, Meta, Export, Public). 2292 2293index_public_list(end_of_file, _In, _Base, _Module, [], [], []). 2294index_public_list(index(op:Op, Module, Base), In, Base, Module, Meta, [Op|Export], Public) :- 2295 !, 2296 read_term(In, Term, []), 2297 index_public_list(Term, In, Base, Module, Meta, Export, Public). 2298index_public_list(index((public):Head, Module, Base), In, Base, Module, Meta, Export, [PI|Public]) :- 2299 !, 2300 pi_head(PI, Head), 2301 read_term(In, Term, []), 2302 index_public_list(Term, In, Base, Module, Meta, Export, Public). 2303index_public_list(index(Head, Module, Base), In, Base, Module, Meta, [PI|Export], Public) :- 2304 !, 2305 pi_head(PI, Head), 2306 ( meta_mode(Head) 2307 -> Meta = [Head|MetaT] 2308 ; Meta = MetaT 2309 ), 2310 read_term(In, Term, []), 2311 index_public_list(Term, In, Base, Module, MetaT, Export, Public). 2312index_public_list(index(Name, Arity, Module, Base), In, Base, Module, Meta, [Name/Arity|Export], Public) :- 2313 !, 2314 read_term(In, Term, []), 2315 index_public_list(Term, In, Base, Module, Meta, Export, Public). 2316index_public_list(_, In, Base, Module, Meta, Export, Public) :- 2317 read_term(In, Term, []), 2318 index_public_list(Term, In, Base, Module, Meta, Export, Public). 2319 2320meta_mode(H) :- 2321 compound(H), 2322 arg(_, H, A), 2323 meta_arg(A), 2324 !. 2325 2326meta_arg(I) :- 2327 integer(I), 2328 !. 2329meta_arg(:). 2330meta_arg(^). 2331meta_arg(//). 2332 2333 /******************************* 2334 * INCLUDE * 2335 *******************************/ 2336 2337process_include([], _) :- !. 2338process_include([H|T], Src) :- 2339 !, 2340 process_include(H, Src), 2341 process_include(T, Src). 2342process_include(File, Src) :- 2343 callable(File), 2344 !, 2345 ( once(xref_input(ParentSrc, _)), 2346 xref_source_file(File, Path, ParentSrc) 2347 -> ( ( uses_file(_, Src, Path) 2348 ; Path == Src 2349 ) 2350 -> true 2351 ; assert(uses_file(File, Src, Path)), 2352 ( xoption(Src, process_include(true)) 2353 -> findall(O, xoption(Src, O), Options), 2354 setup_call_cleanup( 2355 open_include_file(Path, In, Refs), 2356 collect(Src, Path, In, Options), 2357 close_include(In, Refs)) 2358 ; true 2359 ) 2360 ) 2361 ; assert(uses_file(File, Src, '<not_found>')) 2362 ). 2363process_include(_, _).
include(File)
referenced file. Note that we cannot
use prolog_open_source/2 because we should not safe/restore
the lexical context.2371open_include_file(Path, In, [Ref]) :- 2372 once(xref_input(_, Parent)), 2373 stream_property(Parent, encoding(Enc)), 2374 '$push_input_context'(xref_include), 2375 catch(( prolog:xref_open_source(Path, In) 2376 -> catch(set_stream(In, encoding(Enc)), 2377 error(_,_), true) % deal with non-file input 2378 ; include_encoding(Enc, Options), 2379 open(Path, read, In, Options) 2380 ), E, 2381 ( '$pop_input_context', throw(E))), 2382 catch(( peek_char(In, #) % Deal with #! script 2383 -> skip(In, 10) 2384 ; true 2385 ), E, 2386 ( close_include(In, []), throw(E))), 2387 asserta(xref_input(Path, In), Ref). 2388 2389include_encoding(wchar_t, []) :- !. 2390include_encoding(Enc, [encoding(Enc)]). 2391 2392 2393close_include(In, Refs) :- 2394 maplist(erase, Refs), 2395 close(In, [force(true)]), 2396 '$pop_input_context'.
2402process_foreign(Spec, Src) :- 2403 ground(Spec), 2404 current_foreign_library(Spec, Defined), 2405 !, 2406 ( xmodule(Module, Src) 2407 -> true 2408 ; Module = user 2409 ), 2410 process_foreign_defined(Defined, Module, Src). 2411process_foreign(_, _). 2412 2413process_foreign_defined([], _, _). 2414process_foreign_defined([H|T], M, Src) :- 2415 ( H = M:Head 2416 -> assert_foreign(Src, Head) 2417 ; assert_foreign(Src, H) 2418 ), 2419 process_foreign_defined(T, M, Src). 2420 2421 2422 /******************************* 2423 * CHR SUPPORT * 2424 *******************************/ 2425 2426/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2427This part of the file supports CHR. Our choice is between making special 2428hooks to make CHR expansion work and then handle the (complex) expanded 2429code or process the CHR source directly. The latter looks simpler, 2430though I don't like the idea of adding support for libraries to this 2431module. A file is supposed to be a CHR file if it uses a 2432use_module(library(chr) or contains a :- constraint/1 directive. As an 2433extra bonus we get the source-locations right :-) 2434- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 2435 2436process_chr(@(_Name, Rule), Src) :- 2437 mode(chr, Src), 2438 process_chr(Rule, Src). 2439process_chr(pragma(Rule, _Pragma), Src) :- 2440 mode(chr, Src), 2441 process_chr(Rule, Src). 2442process_chr(<=>(Head, Body), Src) :- 2443 mode(chr, Src), 2444 chr_head(Head, Src, H), 2445 chr_body(Body, H, Src). 2446process_chr(==>(Head, Body), Src) :- 2447 mode(chr, Src), 2448 chr_head(Head, H, Src), 2449 chr_body(Body, H, Src). 2450process_chr((:- chr_constraint(Decls)), Src) :- 2451 ( mode(chr, Src) 2452 -> true 2453 ; assert(mode(chr, Src)) 2454 ), 2455 chr_decls(Decls, Src). 2456 2457chr_decls((A,B), Src) => 2458 chr_decls(A, Src), 2459 chr_decls(B, Src). 2460chr_decls(Head, Src) => 2461 generalise_term(Head, Gen), 2462 ( declared(Gen, chr_constraint, Src, _) 2463 -> true 2464 ; current_source_line(Line), 2465 assertz(declared(Gen, chr_constraint, Src, Line)) 2466 ). 2467 2468chr_head(X, _, _) :- 2469 var(X), 2470 !. % Illegal. Warn? 2471chr_head(\(A,B), Src, H) :- 2472 chr_head(A, Src, H), 2473 process_body(B, H, Src). 2474chr_head((H0,B), Src, H) :- 2475 chr_defined(H0, Src, H), 2476 process_body(B, H, Src). 2477chr_head(H0, Src, H) :- 2478 chr_defined(H0, Src, H). 2479 2480chr_defined(X, _, _) :- 2481 var(X), 2482 !. 2483chr_defined(#(C,_Id), Src, C) :- 2484 !, 2485 assert_constraint(Src, C). 2486chr_defined(A, Src, A) :- 2487 assert_constraint(Src, A). 2488 2489chr_body(X, From, Src) :- 2490 var(X), 2491 !, 2492 process_body(X, From, Src). 2493chr_body('|'(Guard, Goals), H, Src) :- 2494 !, 2495 chr_body(Guard, H, Src), 2496 chr_body(Goals, H, Src). 2497chr_body(G, From, Src) :- 2498 process_body(G, From, Src). 2499 2500assert_constraint(_, Head) :- 2501 var(Head), 2502 !. 2503assert_constraint(Src, Head) :- 2504 constraint(Head, Src, _), 2505 !. 2506assert_constraint(Src, Head) :- 2507 generalise_term(Head, Term), 2508 current_source_line(Line), 2509 assert(constraint(Term, Src, Line)). 2510 2511 2512 /******************************** 2513 * PHASE 1 ASSERTIONS * 2514 ********************************/
2521assert_called(_, _, Var, _) :- 2522 var(Var), 2523 !. 2524assert_called(Src, From, Goal, Line) :- 2525 var(From), 2526 !, 2527 assert_called(Src, '<unknown>', Goal, Line). 2528assert_called(_, _, Goal, _) :- 2529 expand_hide_called(Goal), 2530 !. 2531assert_called(Src, Origin, M:G, Line) :- 2532 !, 2533 ( atom(M), 2534 callable(G) 2535 -> current_condition(Cond), 2536 ( xmodule(M, Src) % explicit call to own module 2537 -> assert_called(Src, Origin, G, Line) 2538 ; called(M:G, Src, Origin, Cond, Line) % already registered 2539 -> true 2540 ; hide_called(M:G, Src) % not interesting (now) 2541 -> true 2542 ; generalise(Origin, OTerm), 2543 generalise(G, GTerm) 2544 -> assert(called(M:GTerm, Src, OTerm, Cond, Line)) 2545 ; true 2546 ) 2547 ; true % call to variable module 2548 ). 2549assert_called(Src, _, Goal, _) :- 2550 ( xmodule(M, Src) 2551 -> M \== system 2552 ; M = user 2553 ), 2554 hide_called(M:Goal, Src), 2555 !. 2556assert_called(Src, Origin, Goal, Line) :- 2557 current_condition(Cond), 2558 ( called(Goal, Src, Origin, Cond, Line) 2559 -> true 2560 ; generalise(Origin, OTerm), 2561 generalise(Goal, Term) 2562 -> assert(called(Term, Src, OTerm, Cond, Line)) 2563 ; true 2564 ).
2572expand_hide_called(pce_principal:send_implementation(_, _, _)). 2573expand_hide_called(pce_principal:get_implementation(_, _, _, _)). 2574expand_hide_called(pce_principal:pce_lazy_get_method(_,_,_)). 2575expand_hide_called(pce_principal:pce_lazy_send_method(_,_,_)). 2576 2577assert_defined(Src, Goal) :- 2578 Goal = test(_Test), 2579 current_test_unit(Unit, Line), 2580 assert_called(Src, '<test_unit>'(Unit), Goal, Line), 2581 fail. 2582assert_defined(Src, Goal) :- 2583 Goal = test(_Test, _Options), 2584 current_test_unit(Unit, Line), 2585 assert_called(Src, '<test_unit>'(Unit), Goal, Line), 2586 fail. 2587assert_defined(Src, Goal) :- 2588 defined(Goal, Src, _), 2589 !. 2590assert_defined(Src, Goal) :- 2591 generalise(Goal, Term), 2592 current_source_line(Line), 2593 assert(defined(Term, Src, Line)). 2594 2595assert_foreign(Src, Goal) :- 2596 foreign(Goal, Src, _), 2597 !. 2598assert_foreign(Src, Goal) :- 2599 generalise(Goal, Term), 2600 current_source_line(Line), 2601 assert(foreign(Term, Src, Line)). 2602 2603assert_grammar_rule(Src, Goal) :- 2604 grammar_rule(Goal, Src), 2605 !. 2606assert_grammar_rule(Src, Goal) :- 2607 generalise(Goal, Term), 2608 assert(grammar_rule(Term, Src)).
true
, re-export the
imported predicates.
2621assert_import(_, [], _, _, _) :- !. 2622assert_import(Src, [H|T], Export, From, Reexport) :- 2623 !, 2624 assert_import(Src, H, Export, From, Reexport), 2625 assert_import(Src, T, Export, From, Reexport). 2626assert_import(Src, except(Except), Export, From, Reexport) :- 2627 !, 2628 is_list(Export), 2629 !, 2630 except(Except, Export, Import), 2631 assert_import(Src, Import, _All, From, Reexport). 2632assert_import(Src, Import as Name, Export, From, Reexport) :- 2633 !, 2634 pi_to_head(Import, Term0), 2635 rename_goal(Term0, Name, Term), 2636 ( in_export_list(Term0, Export) 2637 -> assert(imported(Term, Src, From)), 2638 assert_reexport(Reexport, Src, Term) 2639 ; current_source_line(Line), 2640 assert_called(Src, '<directive>'(Line), Term0, Line) 2641 ). 2642assert_import(Src, Import, Export, From, Reexport) :- 2643 pi_to_head(Import, Term), 2644 !, 2645 ( in_export_list(Term, Export) 2646 -> assert(imported(Term, Src, From)), 2647 assert_reexport(Reexport, Src, Term) 2648 ; current_source_line(Line), 2649 assert_called(Src, '<directive>'(Line), Term, Line) 2650 ). 2651assert_import(Src, op(P,T,N), _, _, _) :- 2652 xref_push_op(Src, P,T,N). 2653 2654in_export_list(_Head, Export) :- 2655 var(Export), 2656 !. 2657in_export_list(Head, Export) :- 2658 member(PI, Export), 2659 pi_to_head(PI, Head). 2660 2661assert_reexport(false, _, _) :- !. 2662assert_reexport(true, Src, Term) :- 2663 assert(exported(Term, Src)).
2669process_import(M:PI, Src) :- 2670 pi_to_head(PI, Head), 2671 !, 2672 ( atom(M), 2673 current_module(M), 2674 module_property(M, file(From)) 2675 -> true 2676 ; From = '<unknown>' 2677 ), 2678 assert(imported(Head, Src, From)). 2679process_import(_, _).
2688assert_xmodule_callable([], _, _, _). 2689assert_xmodule_callable([PI|T], M, Src, From) :- 2690 ( pi_to_head(M:PI, Head) 2691 -> assert(imported(Head, Src, From)) 2692 ; true 2693 ), 2694 assert_xmodule_callable(T, M, Src, From).
2701assert_op(Src, op(P,T,M:N)) :-
2702 ( '$current_source_module'(M)
2703 -> Name = N
2704 ; Name = M:N
2705 ),
2706 ( xop(Src, op(P,T,Name))
2707 -> true
2708 ; assert(xop(Src, op(P,T,Name)))
2709 ).
2716assert_module(Src, Module) :- 2717 xmodule(Module, Src), 2718 !. 2719assert_module(Src, Module) :- 2720 '$set_source_module'(Module), 2721 assert(xmodule(Module, Src)), 2722 ( module_property(Module, class(system)) 2723 -> retractall(xoption(Src, register_called(_))), 2724 assert(xoption(Src, register_called(all))) 2725 ; true 2726 ). 2727 2728assert_module_export(_, []) :- !. 2729assert_module_export(Src, [H|T]) :- 2730 !, 2731 assert_module_export(Src, H), 2732 assert_module_export(Src, T). 2733assert_module_export(Src, PI) :- 2734 pi_to_head(PI, Term), 2735 !, 2736 assert(exported(Term, Src)). 2737assert_module_export(Src, op(P, A, N)) :- 2738 xref_push_op(Src, P, A, N).
2744assert_module3([], _) :- !. 2745assert_module3([H|T], Src) :- 2746 !, 2747 assert_module3(H, Src), 2748 assert_module3(T, Src). 2749assert_module3(Option, Src) :- 2750 process_use_module(library(dialect/Option), Src, false).
call(Closure, PI,
Src)
. Handles both lists of specifications and (PI,...)
specifications.2759process_predicates(Closure, Preds, Src) :- 2760 is_list(Preds), 2761 !, 2762 process_predicate_list(Preds, Closure, Src). 2763process_predicates(Closure, as(Preds, _Options), Src) :- 2764 !, 2765 process_predicates(Closure, Preds, Src). 2766process_predicates(Closure, Preds, Src) :- 2767 process_predicate_comma(Preds, Closure, Src). 2768 2769process_predicate_list([], _, _). 2770process_predicate_list([H|T], Closure, Src) :- 2771 ( nonvar(H) 2772 -> call(Closure, H, Src) 2773 ; true 2774 ), 2775 process_predicate_list(T, Closure, Src). 2776 2777process_predicate_comma(Var, _, _) :- 2778 var(Var), 2779 !. 2780process_predicate_comma(M:(A,B), Closure, Src) :- 2781 !, 2782 process_predicate_comma(M:A, Closure, Src), 2783 process_predicate_comma(M:B, Closure, Src). 2784process_predicate_comma((A,B), Closure, Src) :- 2785 !, 2786 process_predicate_comma(A, Closure, Src), 2787 process_predicate_comma(B, Closure, Src). 2788process_predicate_comma(as(Spec, _Options), Closure, Src) :- 2789 !, 2790 process_predicate_comma(Spec, Closure, Src). 2791process_predicate_comma(A, Closure, Src) :- 2792 call(Closure, A, Src). 2793 2794 2795assert_dynamic(PI, Src) :- 2796 pi_to_head(PI, Term), 2797 ( thread_local(Term, Src, _) % dynamic after thread_local has 2798 -> true % no effect 2799 ; current_source_line(Line), 2800 assert(dynamic(Term, Src, Line)) 2801 ). 2802 2803assert_thread_local(PI, Src) :- 2804 pi_to_head(PI, Term), 2805 current_source_line(Line), 2806 assert(thread_local(Term, Src, Line)). 2807 2808assert_multifile(PI, Src) :- % :- multifile(Spec) 2809 pi_to_head(PI, Term), 2810 current_source_line(Line), 2811 assert(multifile(Term, Src, Line)). 2812 2813assert_public(PI, Src) :- % :- public(Spec) 2814 pi_to_head(PI, Term), 2815 current_source_line(Line), 2816 assert_called(Src, '<public>'(Line), Term, Line), 2817 assert(public(Term, Src, Line)). 2818 2819assert_export(PI, Src) :- % :- export(Spec) 2820 pi_to_head(PI, Term), 2821 !, 2822 assert(exported(Term, Src)).
2829pi_to_head(Var, _) :- 2830 var(Var), !, fail. 2831pi_to_head(M:PI, M:Term) :- 2832 !, 2833 pi_to_head(PI, Term). 2834pi_to_head(Name/Arity, Term) :- 2835 functor(Term, Name, Arity). 2836pi_to_head(Name//DCGArity, Term) :- 2837 Arity is DCGArity+2, 2838 functor(Term, Name, Arity). 2839 2840 2841assert_used_class(Src, Name) :- 2842 used_class(Name, Src), 2843 !. 2844assert_used_class(Src, Name) :- 2845 assert(used_class(Name, Src)). 2846 2847assert_defined_class(Src, Name, _Meta, _Super, _) :- 2848 defined_class(Name, _, _, Src, _), 2849 !. 2850assert_defined_class(_, _, _, -, _) :- !. % :- pce_extend_class 2851assert_defined_class(Src, Name, Meta, Super, Summary) :- 2852 current_source_line(Line), 2853 ( Summary == @(default) 2854 -> Atom = '' 2855 ; is_list(Summary) 2856 -> atom_codes(Atom, Summary) 2857 ; string(Summary) 2858 -> atom_concat(Summary, '', Atom) 2859 ), 2860 assert(defined_class(Name, Super, Atom, Src, Line)), 2861 ( Meta = @(_) 2862 -> true 2863 ; assert_used_class(Src, Meta) 2864 ), 2865 assert_used_class(Src, Super). 2866 2867assert_defined_class(Src, Name, imported_from(_File)) :- 2868 defined_class(Name, _, _, Src, _), 2869 !. 2870assert_defined_class(Src, Name, imported_from(File)) :- 2871 assert(defined_class(Name, _, '', Src, file(File))). 2872 2873 2874 /******************************** 2875 * UTILITIES * 2876 ********************************/
2882generalise(Var, Var) :- 2883 var(Var), 2884 !. % error? 2885generalise(pce_principal:send_implementation(Id, _, _), 2886 pce_principal:send_implementation(Id, _, _)) :- 2887 atom(Id), 2888 !. 2889generalise(pce_principal:get_implementation(Id, _, _, _), 2890 pce_principal:get_implementation(Id, _, _, _)) :- 2891 atom(Id), 2892 !. 2893generalise('<directive>'(Line), '<directive>'(Line)) :- !. 2894generalise(test(Test), test(Test)) :- 2895 current_test_unit(_,_), 2896 ground(Test), 2897 !. 2898generalise(test(Test, _), test(Test, _)) :- 2899 current_test_unit(_,_), 2900 ground(Test), 2901 !. 2902generalise('<test_unit>'(Line), '<test_unit>'(Line)) :- !. 2903generalise(Module:Goal0, Module:Goal) :- 2904 atom(Module), 2905 !, 2906 generalise(Goal0, Goal). 2907generalise(Term0, Term) :- 2908 callable(Term0), 2909 generalise_term(Term0, Term). 2910 2911 2912 /******************************* 2913 * SOURCE MANAGEMENT * 2914 *******************************/ 2915 2916/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 2917This section of the file contains hookable predicates to reason about 2918sources. The built-in code here can only deal with files. The XPCE 2919library(pce_prolog_xref) provides hooks to deal with XPCE objects, so we 2920can do cross-referencing on PceEmacs edit buffers. Other examples for 2921hooking can be databases, (HTTP) URIs, etc. 2922- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 2923 2924:- multifile 2925 prolog:xref_source_directory/2, % +Source, -Dir 2926 prolog:xref_source_file/3. % +Spec, -Path, +Options
2934xref_source_file(Plain, File, Source) :- 2935 xref_source_file(Plain, File, Source, []). 2936 2937xref_source_file(QSpec, File, Source, Options) :- 2938 nonvar(QSpec), QSpec = _:Spec, 2939 !, 2940 must_be(acyclic, Spec), 2941 xref_source_file(Spec, File, Source, Options). 2942xref_source_file(Spec, File, Source, Options) :- 2943 nonvar(Spec), 2944 prolog:xref_source_file(Spec, File, 2945 [ relative_to(Source) 2946 | Options 2947 ]), 2948 !. 2949xref_source_file(Plain, File, Source, Options) :- 2950 atom(Plain), 2951 \+ is_absolute_file_name(Plain), 2952 ( prolog:xref_source_directory(Source, Dir) 2953 -> true 2954 ; atom(Source), 2955 file_directory_name(Source, Dir) 2956 ), 2957 atomic_list_concat([Dir, /, Plain], Spec0), 2958 absolute_file_name(Spec0, Spec), 2959 do_xref_source_file(Spec, File, Options), 2960 !. 2961xref_source_file(Spec, File, Source, Options) :- 2962 do_xref_source_file(Spec, File, 2963 [ relative_to(Source) 2964 | Options 2965 ]), 2966 !. 2967xref_source_file(_, _, _, Options) :- 2968 option(silent(true), Options), 2969 !, 2970 fail. 2971xref_source_file(Spec, _, Src, _Options) :- 2972 verbose(Src), 2973 print_message(warning, error(existence_error(file, Spec), _)), 2974 fail. 2975 2976do_xref_source_file(Spec, File, Options) :- 2977 nonvar(Spec), 2978 option(file_type(Type), Options, prolog), 2979 absolute_file_name(Spec, File0, 2980 [ file_type(Type), 2981 access(read), 2982 file_errors(fail) 2983 ]), 2984 !, 2985 qlf_pl_file(File0, File). 2986do_xref_source_file(Spec, File, Options) :- 2987 atom(Spec), % handle absolute /file/to/source.pl without sources 2988 file_name_extension(Base, Ext, Spec), 2989 user:prolog_file_type(Ext, source), 2990 option(file_type(prolog), Options, prolog), 2991 absolute_file_name(Base, File0, 2992 [ file_type(prolog), 2993 access(read), 2994 file_errors(fail) 2995 ]), 2996 qlf_pl_file(File0, File).
3000qlf_pl_file(QlfFile, PlFile) :- 3001 nonvar(QlfFile), 3002 is_qlf_file(QlfFile), 3003 !, 3004 '$qlf_module'(QlfFile, Info), 3005 #{file:PlFile} :< Info. 3006qlf_pl_file(QlfFile, PlFile) :- 3007 nonvar(PlFile), 3008 !, 3009 ( file_name_extension(Base, Ext, PlFile), 3010 user:prolog_file_type(Ext, source) 3011 -> true 3012 ), 3013 ( user:prolog_file_type(QlfExt, qlf), 3014 file_name_extension(Base, QlfExt, QlfFile), 3015 exists_file(QlfFile) 3016 -> true 3017 ), 3018 '$qlf_module'(QlfFile, Info), 3019 #{file:PlFile} :< Info, 3020 !. 3021qlf_pl_file(PlFile, PlFile). 3022 3023is_qlf_file(QlfFile) :- 3024 file_name_extension(_, Ext, QlfFile), 3025 user:prolog_file_type(Ext, qlf), 3026 !.
3032canonical_source(Source, Src) :-
3033 ( ground(Source)
3034 -> prolog_canonical_source(Source, Src)
3035 ; Source = Src
3036 ).
name()
goals.3043goal_name_arity(Goal, Name, Arity) :- 3044 ( compound(Goal) 3045 -> compound_name_arity(Goal, Name, Arity) 3046 ; atom(Goal) 3047 -> Name = Goal, Arity = 0 3048 ). 3049 3050generalise_term(Specific, General) :- 3051 ( compound(Specific) 3052 -> compound_name_arity(Specific, Name, Arity), 3053 compound_name_arity(General, Name, Arity) 3054 ; General = Specific 3055 ). 3056 3057functor_name(Term, Name) :- 3058 ( compound(Term) 3059 -> compound_name_arity(Term, Name, _) 3060 ; atom(Term) 3061 -> Name = Term 3062 ). 3063 3064rename_goal(Goal0, Name, Goal) :- 3065 ( compound(Goal0) 3066 -> compound_name_arity(Goal0, _, Arity), 3067 compound_name_arity(Goal, Name, Arity) 3068 ; Goal = Name 3069 )
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.