As is, assert uses a lock to include the new clause into the linked list of clauses. Probably could be achieved lock-free as well, but I’m not aware of this lock suffering from significant contention. Retracts merely sets the retract generation. Asynchronous clause garbage collection (running in the gc
thread) detects clauses that are erased and there is no open query with a generation in which the clause is visible. It uses the same lock as above to remove the clause from the predicate. The clause is placed in quarantine as reading threads may be scanning it. Eventually it can be really reclaimed. So yes, executing a predicate is lock free, both for static and dynamic code.
This doesn’t affect the current prototype wait-on-change mechanism. That basically makes the POSIX condition variable fully available to the Prolog user. It notably allows zero or more agents to listen to database changes that can include zero or more elementary changes. This is more flexible than a message queue. The extra power comes with extra responsibilities though: lock-based consistency management is easy to get wrong. The use case I have in mind is mostly a multi-threaded blackboard design This is hard to implement with message queues only as a term written on a queue can only be picked up by a single thread.