Predicate-Sensitive Incremental Tabling


Let’s say I have predicates p1/1 and p2/1 that I want to table. Predicate p1/1 depends on some predicate d1/1 which might change during runtime, and predicate p2/1 depends on some predicate d2/1 which might also change during runtime.

In my (multi-threaded) code, I have this tabling setup captured as:

:- table p1/1.
:- table p2/1.
:- dynamic([d1/1], [incremental(true)]).
:- thread_local d1/1.
:- dynamic([d2/1], [incremental(true)]).
:- thread_local d2/1.

Are tables for predicate p1/1 recomputed when d2/1 changes although p1/1 does not depend on d2/1?


No. The system maintains a dependency graph between dynamic predicates and tables (and between tables). It recomputes only the affected tables and does so bottom up (starting from the tables close to the dynamic predicates). Each time it re-evaluated a table it checks whether the new content changed. If not, the no-change is propagated to avoid recomputation of tables that depends on this table.

1 Like

Thank you.

Why is there a need to annotate the dynamic predicates that might invalidate tables as “incremental”? Is it expensive for the tabling system to figure them out using only the dependency graph?

Eventually that may go or at least be more automatic. Right now SWI-Prolog mostly copies XSB for the APIs. XSB tends to work with lots of directives to configure the system while SWI-Prolog has changed over time to minimize required declarations.

Not sure how simple that is here. Some care is needed to keep the size of the dependency graph within reason and setting up the instrumentation to maintain it is not free either.

Thanks :slight_smile: