I can’t say I remember why I’m module-qualifying clause/2 rather than is argument.
On the bright side I tracked the error more precisely to a bit of code that tries to decide whether a predicate is a built-in or autoloaded:
built_in_or_library_predicate(H):-
predicate_property(H, built_in)
,!.
built_in_or_library_predicate(H):-
predicate_property(H, autoload(_)).
This is called before calling program/3 to stop program/3 from collecting clauses of built-ins or predicates from libraries, which shouldn’t be further processed. In particular, I want to avoid meta-interpreting those predicates (especially since trying to do that with built-ins raises an error) which is what eventually happens to the predicates collected by program/3 (that is, they are passed to a meta-interpreter).
This is one of the calls that fail and ultimately cause an error to be raised (btw this error is not a SWI-Prolog error but an exception thrown by my system to guard against things like that specifically. Hey, defensive programming works):
211 ?- predicate_property(addConstraints_(_11594,_11596,_11598), P).
false.
Obviously addConstraints_/3 is neither a built-in nor autoloaded but I’m not sure how to catch code from external libraries.
predicate_property/1 keeps confusing me. For example, if I call it with a functor/arity it succeeds but it always thinks the predicate is defined in librar(yall) and I don’t know why.
212 ?- predicate_property(addConstraints_/3, P).
P = interpreted ;
P = visible ;
P = static ;
P = imported_from(yall) ;
P = transparent ;
P = (meta_predicate? / 0) ;
P = file('C:/Program Files/swipl/library/yall.pl') ;
P = line_count(275) ;
P = number_of_clauses(1) ;
P = number_of_rules(1) ;
P = last_modified_generation(25213) ;
P = defined ;
P = size(408) ;
false.
I mean it does that for every predicate.
213 ?- predicate_property(member/2, P).
P = interpreted ;
P = visible ;
P = static ;
P = imported_from(yall) ;
P = transparent ;
P = (meta_predicate? / 0) ;
P = file('C:/Program Files/swipl/library/yall.pl') ;
P = line_count(275) ;
P = number_of_clauses(1) ;
P = number_of_rules(1) ;
P = last_modified_generation(25213) ;
P = defined ;
P = size(408) ;
false.
On the other hand, if I module-qualify the goal like @ridgeworks suggests I get what I expect:
214 ?- predicate_property(M:addConstraints_(_11594,_11596,_11598), P).
M = clpBNR,
P = interpreted ;
M = clpBNR,
P = visible ;
M = clpBNR,
P = static ;
M = clpBNR,
P = file('C:/Users/YeGoblynQueenne/AppData/Local/swi-prolog/pack/clpBNR/prolog/clpBNR.pl') ;
M = clpBNR,
P = line_count(999) ;
M = clpBNR,
P = number_of_clauses(4) ;
M = clpBNR,
P = number_of_rules(4) ;
M = clpBNR,
P = last_modified_generation(28180) ;
M = clpBNR,
P = defined ;
M = clpBNR,
P = size(1344) ;
M = clpBNR,
P = primary_index(1) ;
false.
I can do hack something on top of that but what I would really like to have is a clean and simple way to keep built-ins and library predicates, including but not restricted to auto-loaded ones, out of my meta-interpreter. Btw, even when an error is not raised, meta-interpreting some of those just causes unnecessary overhead.
On the other hand I think that may just need a better design on my part. My system is trying to guess what predicates should and shouldn’t be meta-interpreted and that’s always going to cause stuff to fail. Maybe I should just ask the user to flag those predicates up. But that adds more work for the user so I tried to avoid it.