When creating a module and needing to create the exports list for use with module/2,3 it would be nice to have a simple predicate do the heavy lifting.
build_export(M,Exports) :-
current_module(M), !,
(
setof(Predicate_indicator,local_predicate_generator(M:Predicate_indicator),Exports), !
;
Exports = []
).
build_export(M,_) :-
format(string(Lines),'Module `~w'' not loaded.~nPlease use consult/1 or use_module/1 to load the module.~n',[M]),
print_message_lines(user_error,kind(error),[Lines]).
local_predicate_generator(PI) :-
current_predicate(M:Name/Arity),
local_predicate(M:Name/Arity),
dcg_indicator(M:Name/Arity,PI).
local_predicate(M:Name/Arity) :-
compound_name_arity(Head,Name,Arity),
\+ predicate_property(M:Head,imported_from(_)).
dcg_indicator(M:Name/Arity0,PI) :-
compound_name_arity(Head,Name,Arity0),
(
predicate_property(M:Head,non_terminal)
->
Arity is Arity0 - 2,
PI = M:Name//Arity
;
PI = M:Name/Arity0
).
Example usage
Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.4-11-g1db629e24)
?- working_directory(_,'C:/Users/Groot/Documents').
true.
?- [module_exports].
true.
?- build_export(dcg_basics,Exports);true.
ERROR: Module `dcg_basics' not loaded.
Please use consult/1 or use_module/1 to load the module.
true ;
true.
?- consult(library(dcg/basics)).
true.
?- build_export(dcg_basics,Exports);true.
Exports = [mkval/3, mkval/4, alpha_to_lower//1, atom//1, blank//0, blanks//0, blanks_to_nl//0, digit//1, ... // ...|...] [write]
Exports = [mkval/3, mkval/4, alpha_to_lower//1, atom//1, blank//0, blanks//0, blanks_to_nl//0, digit//1, digits//1, dot//0, eos//0, exp//0, float//1, int_codes//1, integer//1, list_string_without//2, nonblank//1, nonblanks//1, number//1, prolog_id_cont//1, prolog_var_name//1, remainder//1, sign//1, string//1, string_without//2, white//0, whites//0, xdigit//1, xdigits//1, xinteger//1] ;
true.
Variation for names of unit tests.
build_test_names(M,Test_names) :-
current_module(M), !,
(
setof(Name,test_name_generator(M,Name),Test_names), !
;
Test_names = []
).
build_test_names(M,_) :-
format(string(Lines),'Module `~w'' not loaded.~nPlease use consult/1 or use_module/1 to load the module.~n',[M]),
print_message_lines(user_error,kind(error),[Lines]).
test_name_generator(M,Name) :-
current_module(M), !,
current_predicate(M:'unit test'/4),
clause(M:'unit test'(Name,_,_,_),_).
Notes
Original code is from this post.
For the use of ;true
added to the query see: Help: I want the whole answer