Tabling goal arguments + states passed based on global variables

Hello,

I have a goal/predicate that i consider tabling – mainly to gain speed via memoing.

However, within the rather complex goal, there is also access to some global variables, that are set prior to calling the goal. States set in those global variables have an effect on whether the goal with succeed or fail, in addition to the arguments passed to the goal.

I am now wondering, if i were to use tabling for memoing - wouldn’t global variables render the tabled results incorrect in some cases – when goal results are dependent not only on the goals arguments but on the (somewhat arbitrary) settings of the global variables.

As a remedy – should i create an auxiliary goal that makes all global variables explicit as additional arguments – to give tabling a chance to map all input states (arguments and global var states) to goal success or failure.

thanks,

Dan

There are many ways out. But yes, tables memoize and thus lead to outdated results if you change anything to the world. Incremental and monotonic tabling automatically track changes to dynamic predicates (that are declared as incremental or monotonic). For anything else you can of course pass the state in additional arguments. That may of course blow up your tables. Alternatively you can abolish affected tables or define your tables as incremental/monotonic and use incr_invalidate_call/1 and friends from library(dialect/xsb/increval). This library will probably move to the core library at some point.

In this case, using a dynamic predicate rather than a global variable might be an option?

I guess you mean that if I retract and reassert a different “global” setting – then this can automatically invalidate the table forcing it to be abolished and recreated.

What is the performance cost for this vs. changing and accessing a global variable?

However, I am thinking that I want to eat the cake and have it too – i.e. retain the tabling while extending it to include global state “modifiers”.

I guess your concern then is that this potentially multiplies the table entries by the number of global states possible (a multiplier also).

I need to experiment to see if this is the case – i am hoping that its not the case, given the underlying logic at work … but, will have to test this – otherwise, the dynamic predicate might be the way to go.

thank you,

Dan

Does something like this make sense for tabling:

Probably the first one shouldn’t be there but dealt separately.

predicate(_A, _B, State_1, _State_2) :-
State_1 = true.

predicate(A, B, _State_1, State_2) :-
process_1(A, B, State_2).

predicate(A, B_, _State_1, State_2) :-
process_2(A, B).