List the properties for predicate(s)

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 Navigator

?- prolog_ide(open_navigator(.)).
true.

Cross-referencer

?- 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.

2 Likes