Tabling inside Threads

Hello,

Is it possible to have tabling inside threads forked by first_solution/3?

My program’s knowledge base changes at runtime, and it is necessary for me to use thread_local/1 instead of dynamic/1 to localize the changes that occur in the knowledge base to the thread that causes such changes. The predicates that are added/removed from the knowledge base during execution are all defined as thread_local/1.

How can I make this:
:- dynamic([some_predicate/1], [incremental(true)]).

work with thread_local/1 so that each thread created by first_solution/3 has its separate tabling structure(s)?

Thanks.

Tables can be private (to a thread) or shared (between threads). By default they are private. So yes, each thread participating in first_solution/3 by default builds its own tables (an they are discarded as the thread terminates). That should be fine.

In this case you also want a thread private (local) dynamic predicate that is incremental. There are a large number of ways to achieve that:

:- dynamic([p/1], [incremental(true), thread(local)]).
:- dynamic (p/1) as (incremental, private).

Or in two steps:

:- dynamic([p/1], [incremental(true)]).
:- thread_local p/1.

These alternatives come from the support for XSB syntax as well as something in line with the ISO tradition. Note that in XSB, as is a high-priority operator and parenthesis are not needed. In SWI as pre-existed as low-priority operator.

Note that the domain of thread shared tabling is still rather unexplored. Where I could copy all tests from XSB for the other tabling properties, XSB’s shared tabling is barely existent and has no tests. I have created a few tests, but this is waiting for a good power user to explore all corners. So far that seems irrelevant to you.

Welcome to the wonder world of tabling :slight_smile:

1 Like

Thanks a lot! :slight_smile:

P.s. Be aware that XSB doesn’t really combine threads and tables and has no test cases for it. This also implies there are no tests for thread local incremental predicates. I see little reasons why that wouldn’t work out of the box, but if you see something strange you should suspect SWI-Prolog as well as your understanding of tabling :slight_smile: