List the properties for predicate(s)
predicate_properties(M:Name/Arity,(predicate(M:Name/Arity),properties(Bag))) :-
ground(M),
ground(Name),
ground(Arity),
var(Bag), !,
compound_name_arity(Head,Name,Arity),
bagof(Property, predicate_property(M:Head,Property), Bag).
predicate_properties(M:Name/Arity,Sets) :-
var(Sets), !,
setof(pi(M:Name/Arity),local_predicate_generator(Name,M:Name/Arity),PI_set),
predicate_properties(PI_set,Sets).
predicate_properties(PI_set,Sets) :-
member(pi(M:Name/Arity),PI_set),
bagof(Set,predicate_properties(M:Name/Arity,Set),Sets).
local_predicate_generator(Name,M:Name/Arity) :-
current_predicate(M:Name/Arity),
local_predicate(M:Name/Arity).
local_predicate(M:Name/Arity) :-
compound_name_arity(Head,Name,Arity),
\+ predicate_property(M:Head,imported_from(_)).
Example usage:
?- predicate_properties(lists:append/3,Properties).
Properties = (predicate(lists:append/3), properties([interpreted, visible, exported, static, file('c:/program files/swipl/library/lists.pl'), line_count(123), nodebug, number_of_clauses(2), number_of_rules(1), last_modified_generation(5870), defined, size(480)])).
?- predicate_properties(lists:append/Arity,Properties).
Properties = [(predicate(lists:append/2), properties([interpreted, visible, exported, static, file('c:/program files/swipl/library/lists.pl'), line_count(134), nodebug, number_of_clauses(1), number_of_rules(1), last_modified_generation(5871), defined, size(288)]))] ;
Properties = [(predicate(lists:append/3), properties([interpreted, visible, exported, static, file('c:/program files/swipl/library/lists.pl'), line_count(123), nodebug, number_of_clauses(2), number_of_rules(1), last_modified_generation(5870), defined, size(480)]))].
?- predicate_properties(M:append/Arity,Properties).
Properties = [(predicate(lists:append/2), properties([interpreted, visible, exported, static, file('c:/program files/swipl/library/lists.pl'), line_count(134), nodebug, number_of_clauses(1), number_of_rules(1), last_modified_generation(5871), defined, size(288)]))] ;
Properties = [(predicate(lists:append/3), properties([interpreted, visible, exported, static, file('c:/program files/swipl/library/lists.pl'), line_count(123), nodebug, number_of_clauses(2), number_of_rules(1), last_modified_generation(5870), defined, size(480)]))] ;
Properties = [(predicate(system:append/1), properties([visible, built_in, foreign, static, nodebug, defined, size(144)]))].
?- predicate_properties(lists:Name/Arity,Properties).
Properties = [(predicate(lists:'$autoload'/3), properties([interpreted, visible, static, file('c:/program files/swipl/library/lists.pl'), line_count(76), notrace, number_of_clauses(2), number_of_rules(0), last_modified_generation(5865), defined, size(688)]))] ;
Properties = [(predicate(lists:append/2), properties([interpreted, visible, exported, static, file('c:/program files/swipl/library/lists.pl'), line_count(134), nodebug, number_of_clauses(1), number_of_rules(1), last_modified_generation(5871), defined, size(288)]))] ;
Properties = [(predicate(lists:append/3), properties([interpreted, visible, exported, static, file('c:/program files/swipl/library/lists.pl'), line_count(123), nodebug, number_of_clauses(2), number_of_rules(1), last_modified_generation(5870), defined, size(480)]))] ;
Properties = [(predicate(lists:append_/2), properties([interpreted, visible, static, file('c:/program files/swipl/library/lists.pl'), line_count(138), nodebug, number_of_clauses(2), number_of_rules(1), last_modified_generation(5873), defined, size(448)]))] ;
...
?- predicate_properties(Module:Name/Arity,Properties).
Properties = [(predicate('$predopts':canonical_pi/2), properties([interpreted, visible, built_in, static, file('c:/program files/swipl/boot/predopts.pl'), line_count(137), nodebug, number_of_clauses(3), number_of_rules(2), last_modified_generation(2508), defined, size(920)]))] ;
Properties = [(predicate('$predopts':expand_predicate_options/4), properties([interpreted, visible, built_in, static, file('c:/program files/swipl/boot/predopts.pl'), line_count(53), nodebug, number_of_clauses(1), number_of_rules(1), last_modified_generation(2489), defined, size(1184)]))] ;
Properties = [(predicate('$predopts':mode_and_type/3), properties([interpreted, visible, built_in, static, file('c:/program files/swipl/boot/predopts.pl'), line_count(123), nodebug, number_of_clauses(3), number_of_rules(3), last_modified_generation(2504), defined, size(768)]))] ;
Properties = [(predicate('$predopts':modes_and_types/3), properties([interpreted, visible, built_in, static, file('c:/program files/swipl/boot/predopts.pl'), line_count(110), nodebug, number_of_clauses(2), number_of_rules(1), last_modified_generation(2501), defined, size(920)]))] ;
...
I made this a Discourse Wiki topic so that anyone with a proper trust level can edit this. If you want to improve the code, add some documentation, or other, feel free.
There will probably be a few more topics in this category related to Prolog code analysis that I might pull together into a Wiki, but for now having the code in a more prominent place is better than being buried in a Wiki discussion topic.
SWI-Prolog includes some graphical tools related to code analysis,.
?- prolog_ide(open_navigator(.)).
true.
?- gxref.
true.
Also see: Prolog code walker
Note: prolog_walk_code/1 is used by Pack callgraph.
For an example of using using callgraph see this post.