I was playing with negation delay trying to understand why it does not quite work and ran into the same problem with monotonically growing attributes, which prevents termination.
Here is a simple example distilled from large use cases:
:- import when/2 from constraintLib.
:- table foo/1.
foo(S) :- foo(S), when(ground(S),tnot foo(S)).
foo(S) :- when(ground(S),tnot foo(S)).
Here the query does not terminate because the attribute of S grows monotonically.
I was wondering what should tabling do?
One solution is to apply bounded rationality to attributes.
Another is to maybe check if the incoming subgoal is a variant of what's in the table
modulo the attributes. "Module the attrs" here means that the attributes of each variable
in the incoming goal are supersets of the attrs of the subgoal already in the table.
If so, then the incoming goal is suspended.
Another possibility is to do something in constraintLib:suspend/2. But then it should be a different, tweaked library.
What do you think?