Incrementally tabling a predicate that uses rdf

I have an expensive-to-execute predicate that retrieves values from the rdf store that I want to memoize. Is there a way to do this?

I tried with this simple example:

% I was unclear how to mark rdf_assert/4 as dynamic 
% since it didn't appear to be, so I tried this:
:- dynamic([s/1], [incremental(true)]).
s(X) :-
    rdf_assert(default, X, is, b).

% This is my simplified 'predicate that I want to memoize':
:- table g/1 as incremental.
g(X) :-
    rdf(default, X, is, b).

Then when I run it:

?- g(a).
false.

?- s(a).
true.

?- g(a).
false.

I am looking for a way to make the final g(a) return true due to incremental tabling…

Any ideas?

Good question. The code below works. I’ll let you puzzle out why :slight_smile: Just ask if you don’t understand. Note that the invalidate must be more subtle if you include the reasoning predicates such as rdf_has/4.

:- use_module(library(dialect/xsb/increval)).
:- use_module(library(semweb/rdf11)).

:- dynamic drdf/4 as incremental.
:- rdf_meta
    drdf(r,r,o,r),
    drdf_assert(r,r,o,r).

drdf(S,P,O,G) :-
    rdf(S,P,O,G).

drdf_assert(S,P,O,G) :-
    rdf_assert(S,P,O,G),
    incr_invalidate_call(drdf(S,P,O,G)).

s(X) :-
    drdf_assert(default, X, is, b).

% This is my simplified 'predicate that I want to memoize':
:- table g/1 as incremental.

g(X) :-
    drdf(default, X, is, b).

Great, thanks @jan! I didn’t find the increval.pl predicates when I was investigating. My usage of rdf is very simple right now, just using rdf/4 to query triplets, so I think this will be enough.

Please check my work! here’s what I think is going on:

  • drdf/4 is being incrementally tabled via the dynamic drdf/4 directive
  • drdf_assert/4 must be used if you want the tabling to be updated. It uses incr_invalidate_call/1 to notify the system of the data that has been changed and trigger a recalculation of the affected parts of the tabling
  • I think the rdf_meta predicate is being used so that rdf prefixes are properly handled by the wrapper predicates drdf/4 and drdf_assert/4? I’ve not been using URIs at all in my usage of rdf so I’m not well versed on how this part of the system works…

Based on reading the docs for incr_invalidate_call/1, that is the right call to use if I have another predicate that uses rdf_retractall too right?

drdf_retract(S,P,O,G) :-
    rdf_retractall(S,P,O,G),
    incr_invalidate_call(drdf(S,P,O,G)).
1 Like

Probably this library should be moved from the XSB dialect emulation to the main library. In any case, the we’re still in the position that you can find useful stuff and hints in the XSB emulation library and the XSB docs.