|Did you know ...||Search Documentation:|
Incremental tabling (section 7.7) maintains the consistency of tables that depend directly or indirectly on (incremental) dynamic predicates. This is done by invalidating dependent tables on an assert or retract and lazily re-evaluate invalid tables when their content is needed. Incremental tabling preserves all normal tabling properties, including well founded semantics. The downside is that re-evaluation recomputes the table from scratch. This section deals with monotonic tabling, a mechanism that propagates the consequences of assert/1 and friends without recomputing the dependent tables from scratch. Unlike incremental tabling though, monotonic tabling can only deal with monotonic programs, in particular it does not deal with negation.
The example below defines the transitive closure of a bi-directional graph using monotonic tabling. This program builds tables for the connected/2 and maintains these tables when new facts are added for link/2 .
:- table connected/2 as monotonic. :- dynamic link/2 as monotonic. connected(X, Y) :- connected(Y, X). connected(X, Z) :- connected(X, Y), connected(Y, Z). connected(X, Y) :- link(X, Y).
The list below describes properties of monotonic tabling and relation to other tabling primitives:
incrementaland it allowed to have both incremental and monotonic tabled predicates that depend on such dynamic predicates.
Monotonic tabling is experimental and incomplete. Notably support for answer subsumption and call subsumption is probably possible and may greatly improve the application domain and resource usage. Monotonic tabling should work with both shared and private tables. Concurrency issues have not yet been tested though.