# A new bug in my old code?

**URL:** <https://swi-prolog.discourse.group/t/a-new-bug-in-my-old-code/9804>\
**Category:** Help!\
**Tags:** bug\
**Created:** [August 30, 2026, 2:13pm UTC](https://swi-prolog.discourse.group/t/a-new-bug-in-my-old-code/9804 "2026-08-30T14:13:27Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Marc](https://avatars.discourse-cdn.com/v4/letter/m/8dc957/32.png) [@Marc](https://swi-prolog.discourse.group/u/Marc)\
**Post date:** [August 30, 2026, 2:13pm UTC](https://swi-prolog.discourse.group/t/a-new-bug-in-my-old-code/9804/1 "2026-08-30T14:13:27Z")

</div>

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:

```prolog
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

---

<div class="post-metadata">

**Author:** ![Olopierpa](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/olopierpa/32/6855_2.png) [@Olopierpa](https://swi-prolog.discourse.group/u/Olopierpa)\
**Post date:** [August 30, 2026, 3:27pm UTC](https://swi-prolog.discourse.group/t/a-new-bug-in-my-old-code/9804/2 "2026-08-30T15:27:49Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)\
**Post date:** [August 30, 2026, 4:20pm UTC](https://swi-prolog.discourse.group/t/a-new-bug-in-my-old-code/9804/3 "2026-08-30T16:20:54Z")

</div>

> [@Marc](#):
>
> ```prolog
> predicate_property(X,dynamic),
> \+predicate_property(X,built_in)
> 
> ```

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

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

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

```

---

<div class="post-metadata">

**Author:** ![Marc](https://avatars.discourse-cdn.com/v4/letter/m/8dc957/32.png) [@Marc](https://swi-prolog.discourse.group/u/Marc)\
**Post date:** [August 30, 2026, 4:32pm UTC](https://swi-prolog.discourse.group/t/a-new-bug-in-my-old-code/9804/4 "2026-08-30T16:32:12Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Marc](https://avatars.discourse-cdn.com/v4/letter/m/8dc957/32.png) [@Marc](https://swi-prolog.discourse.group/u/Marc)\
**Post date:** [August 30, 2026, 4:47pm UTC](https://swi-prolog.discourse.group/t/a-new-bug-in-my-old-code/9804/5 "2026-08-30T16:47:00Z")

</div>

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:

````prolog

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

````

All these were built-in in version 8:

````prolog

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

````

---

<div class="post-metadata">

**Author:** ![Marc](https://avatars.discourse-cdn.com/v4/letter/m/8dc957/32.png) [@Marc](https://swi-prolog.discourse.group/u/Marc)\
**Post date:** [August 30, 2026, 4:56pm UTC](https://swi-prolog.discourse.group/t/a-new-bug-in-my-old-code/9804/6 "2026-08-30T16:56:44Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![Olopierpa](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/olopierpa/32/6855_2.png) [@Olopierpa](https://swi-prolog.discourse.group/u/Olopierpa)\
**Post date:** [August 30, 2026, 5:45pm UTC](https://swi-prolog.discourse.group/t/a-new-bug-in-my-old-code/9804/7 "2026-08-30T17:45:13Z")

</div>

maybe you can discriminate based on file of origin:

> ```prolog
> 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.

---

<div class="post-metadata">

**Author:** ![Marc](https://avatars.discourse-cdn.com/v4/letter/m/8dc957/32.png) [@Marc](https://swi-prolog.discourse.group/u/Marc)\
**Post date:** [August 31, 2026, 1:58pm UTC](https://swi-prolog.discourse.group/t/a-new-bug-in-my-old-code/9804/8 "2026-08-31T13:58:56Z")

</div>

Appreciated the help, and tried it. However, on my platform (LM22.3) the substring /swipl/ should be /swi-prolog/, so I’m afraid it’s very fragile. For the moment I’m just going to exclude `prolog_file_type` from the retract of dynamic predicates. Hopefully a little more robust, but again a stop-gap. The better solution would be to change the input format.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [September 1, 2026, 9:03am UTC](https://swi-prolog.discourse.group/t/a-new-bug-in-my-old-code/9804/9 "2026-09-01T09:03:11Z")

</div>

For historic reasons, many _hooks_ live in the `user` module and are dynamic. Just wiping these seems a bad idea (as you noted). As you will also wipe term/goal expansion, you are likely to kill far too much. You might get closer to what you want by not wiping predicates marked as `multifile` or not wiping predicates that have a source location, i.e., (part of) their clauses result from loading a file rather than assert/1.

The real question is of course what you want to achieve. Quite likely there is a more elegant solution 🙂

---

<div class="post-metadata">

**Author:** ![Marc](https://avatars.discourse-cdn.com/v4/letter/m/8dc957/32.png) [@Marc](https://swi-prolog.discourse.group/u/Marc)\
**Post date:** [September 2, 2026, 6:21am UTC](https://swi-prolog.discourse.group/t/a-new-bug-in-my-old-code/9804/10 "2026-09-02T06:21:38Z")

</div>

A good, robust solution would be to include the signature of the logical theory in the input data. If only I had understood that 20 years ago … Another solution (which I have chosen for the moment) is a small reduction of the functionality of the code.

I want to thank everybody for their responses. One last question: what was the reason that more than a dozen system-like predicates have lost the property “built-in” in between version 8 and version 10? (I hopped over v9 after a long break). I feel that “historical reasons” cannot explain this.

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [September 2, 2026, 6:12pm UTC](https://swi-prolog.discourse.group/t/a-new-bug-in-my-old-code/9804/11 "2026-09-02T18:12:18Z")

</div>

> [@Marc](#):
>
> One last question: what was the reason that more than a dozen system-like predicates have lost the property “built-in” in between version 8 and version 10?

I don’t know … Built-in predicate detection typically serve a role in meta-interpreters (do not meta-interpret this). I have no clue when this was changed and whether or not this was on purpose. Ideally, the `user` module should be empty and all _hooks_ should live in `prolog` or the module using the hook. History blocks doing so. Net result is that the `user` module contains stuff to keep the system going ☹
