Monotonic tables depend on monotonic dynamic predicates. In some situations there is external dynamic data such as a database. One solution is to maintain a shadow copy of all the external data in a dynamic predicate. This wastes resources and introduces maintenance problems. The system allows to use this information directly from the external source. To do this, create a dynamic and monotonic predicate that accesses the data:
:- dynamic my_data/2 as monotonic.
my_data(X, Y) :-
    <access external data>.
Any monotonic table that depends on my_data/2 will be populated 
correctly and build a dependency. Next, if a new answer is added to the 
external data the user must call incr_propagate_calls/1 
from the Prolog library library(increval). Similarly, when 
an answer is removed from the external data we use incr_invalidate_calls/1. 
Both notification calls must be made after the external data 
has been updated, i.e., my_data/2 must reflect the new situation before 
calling incr_propagate_calls/1 
or incr_invalidate_calls/1.
:- use_module(library(increval)).
on_new_my_data(X, Y) :-
    incr_propagate_calls(my_data(X, Y)).
on_removed_my_data(X,Y) :-
    incr_invalidate_calls(my_data(X, Y)).
Status
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.