Any way to get listing/1 to show just the predicates in a given module?

If I issue a

?- listing(mymodule:_).

it will give me a listing of all predicates accessible from that module’s context, including imports, not just those that actually belong to that module. Is there a way to just list the ones with mymodule as their module? Or, also good, a way to list all clauses defined in that module’s file (including e.g. user:portray clauses) without clauses defined elsewhere?

Similarly, is there any way to:

  • hook trace/1 onto all predicates defined in a specific module? mymodule:_ picks up imports, like I mentioned.
  • remove trace/1 wrappers from any predicates in a current module that are currently wrapped?
  • remove trace/1 wrappers from all predicates, like nospyall/0 does for spy points?

Interesting, I don’t get that behavior. Using a small test file like this:

:- module(potato, [exported/0, append/3]).
:- use_module(library(lists)).

exported.
unexported.

If I load the module and get a listing of it, I see only the predicates defined in the module, and no imported predicates (not even if I re-export them, as I’ve done here with append/3):

?- use_module(potato).
true.

?- listing(potato:_).

exported.

unexported.
true.

The listing/0 documentation also says:

To list the content of the module mymodule, use one of the calls below.

?- mymodule:listing.
?- listing(mymodule:_).

But potato:listing gives me the same result as listing(potato:_).

I don’t know any good way to get all clauses from a certain file. But for a specific predicate, you can use clause/3 to enumerate all of its clauses, and use the returned clause reference with clause_property/2 to look up what file the clause was defined in. For example, to find all places where SWI defines goal_expansion/2 clauses:

?- clause(system:goal_expansion(Goal1, Goal2), Body, _Ref), (clause_property(_Ref, file(File)) -> true ; File = no_file).
Goal1 = debug(_4452, _4454, _4456),
Goal2 = true,
Body = prolog_debug:(optimise_debug->true;debug_topic(_4452), fail),
File = '.../home/library/debug.pl' ;
Goal1 = debugging(_6554),
Goal2 = fail,
Body = prolog_debug:(optimise_debug->true;debug_topic(_6554), fail),
File = '.../home/library/debug.pl' ;
Goal1 = assertion(_8652),
Goal2 = true,
Body = prolog_debug:optimise_debug,
File = '.../home/library/debug.pl' ;
Goal1 = assume(_10728),
Goal2 = true,
Body = prolog_debug:(print_message(informational, compatibility(renamed(assume/1, assertion/1))), optimise_debug),
File = '.../home/library/debug.pl' ;
Body = arithmetic:math_goal_expansion(Goal1, Goal2),
File = '.../home/library/arithmetic.pl'.

You could use this to find all clauses from a certain file, by iterating over all predicates using current_predicate/2 and then checking where their clauses come from, but that’s not exactly nice or efficient…

Okay, that’s weird, because now I can’t get that behavior either! We’ll see if I remember what project I was working on when it happened, until then, thanks for the second pair of eyes :grinning_face_with_smiling_eyes: