A new bug in my old code?

I’m using: SWI-Prolog version 10.0.2.

I want the code to: retract all dynamic predicates that are not built-in.

But what I’m getting after cleanup each time I consult a file is: ERROR: Domain error: `file_type’ expected, found `prolog’.

My code looks like this:

cleanup :- forall(dynamic_not_built_in(X),retractall(X)).

dynamic_not_built_in(X) :- predicate_property(X,dynamic),
                           \+predicate_property(X,built_in).

Call the above program mwe.pl, consult it and run cleanup. Then consult it again and get the ERROR above. Code like this has never given any problem in versions < 9. From 9 on I get this behaviour. I suspect cleanup now retracts too much, perhaps an essential dynamic predicate which is not a built-in. Any help is highly appreciated! Marc

I suspect cleanup now retracts too much,

You can easily check this hypotesis. In cleanup change retractall to writeln, and check whether the result looks reasonable.

There is no overlap, so that will not filter as intended:

Welcome to SWI-Prolog (threaded, 64 bits, version 10.0.2)

101 ?- predicate_property(X, dynamic), predicate_property(X, built_in).
false.

Good suggestion, see the list below. I would have expected all of these are built-in.

I guess the last one is the culprit.

61 ?- cleanup.
prolog_load_file(_7456,_7458)
portray(_7456)
expand_answer(_7456,_7458)
resource(_7456,_7458)
exception(_7456,_7458,_7460)
term_expansion(_7456,_7458)
goal_expansion(_7456,_7458,_7460,_7462)
term_expansion(_7456,_7458,_7460,_7462)
resource(_7456,_7458,_7460)
file_search_path(_7456,_7458)
goal_expansion(_7456,_7458)
expand_query(_7456,_7458,_7460,_7462)
message_hook(_7456,_7458,_7460)
thread_message_hook(_7456,_7458,_7460)
library_directory(_7456)
prolog_file_type(_7456,_7458)
true.

But something must have changed. I seem to remember (but the program is 20y old) that it was necessary to exclude built-in predicates in those days:

´´´Welcome to SWI-Prolog (threaded, 64 bits, version 8.0.3)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit http://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- cleanup.
prolog_exception_hook(_7210,_7212,_7214,_7216)
thread_message_hook(_7210,_7212,_7214)
true.

?- [mwe].
true.

´´´BTW why is the mark-up not working on discourse?

All these were built-in in version 8:

?- predicate_property(X,dynamic),predicate_property(X,built_in).
X = prolog_event_hook(_7564) ;
X = file_search_path(_7564, _7566) ;
X = term_expansion(_7564, _7566) ;
X = resource(_7564, _7566, _7568) ;
X = prolog_file_type(_7564, _7566) ;
X = goal_expansion(_7564, _7566) ;
X = goal_expansion(_7564, _7566, _7568, _7570) ;
X = portray(_7564) ;
X = term_expansion(_7564, _7566, _7568, _7570) ;
X = expand_query(_7564, _7566, _7568, _7570) ;
X = expand_answer(_7564, _7566) ;
X = message_hook(_7564, _7566, _7568) ;
X = library_directory(_7564) ;
X = prolog_load_file(_7564, _7566) ;
X = resource(_7564, _7566) ;
X = exception(_7564, _7566, _7568) ;
false.

In conclusion: from version 8 to version 10 the number of system-like predicates that are dynamic (but not built-in) increased substantially.

My problem is now: how to discriminate in a robust way between user-defined dynamic predicates and all other dynamic predicates?

maybe you can discriminate based on file of origin:

predicate_property(P,dynamic),
predicate_property(P,file(F)),
\+ sub_atom(F,_,_,_,'/swipl/library/'),
\+ sub_atom(F,_,_,_,'/swipl/boot/').

if it has these in the name probably is not a user defined one. Not 100% safe, but may be a stopgap.