I would like to set up tabling so that only the most specific calls are tabled. So I have written the following code:
:- table p(_,po(isSubsumedBy/2),_). % I tested also the following directive to compare with the one above % :- table p/3. isSubsumedBy(T1,T2):- subsumes_term(T2,T1). p(1,_,3). p(1,2,3).
In order to see the content of the table, I’ve written the following predicates (display_table displays all memoized calls with the list of their associated keys):
display_table:- findall([T,LKey], (current_table(T,Trie), findall(Key,(trie_gen_compiled(Trie, Key)), LKey)), Res), writeln("Current table :"), writeList(Res). writeList(L):- write("["), writeList2(L), writeln("]"). writeList2(). writeList2([H]):- write(H). writeList2([H|[H2|T]]) :- writeln(H), writeList2([H2|T]).
Then I obtain the following results. First I give the reference tests (not using partial-order answer subsumption during tabling):
/* SWI-Prolog threaded, 64 bits, version 8.4.2 With :- table p/3. we get: */ 2 ?- p(X,Z,Y). X = 1, Y = 3 ; X = 1, Z = 2, Y = 3. 3 ?- display_table. Current table : [[p(_14378,_14380,_14382),[ret(1,_14400,3),ret(1,2,3)]]] true ; false. 4 ?- p(1,2,3). true.
That’s ok, everything works fine.
Now I want to keep only the most specific call in the table, ie p(1,2,3), discarding p(1,_,3). I obtain with SWI 8.4.2:
/* SWI-Prolog threaded, 64 bits, version 8.4.2 With :- table p(_,po(isSubsumedBy/2),_). we get: */ 2 ?- p(X,Z,Y). X = 1, Z = 2, Y = 3.
Up to here, that’s exactly what I want, but problems occur with subsequent queries:
3 ?- display_table. Current table : [[p(_12788,_12790,_12792),]] true ; false.
This does not seem coherent with the first query.
4 ?- p(1,2,3). ERROR: Uninstantiated argument expected, found 2 ERROR: In: ERROR:  throw(error(uninstantiation_error(2),_23840)) ERROR:  '$wrap$p'(1,2,3)1-st clause of '$wrap$p'/3 <no source> ERROR:  toplevel_call(user:user: ...) at c:/program files/swipl842/boot/toplevel.pl:1158 ERROR: ERROR: Note: some frames are missing due to last-call optimization. ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
I do not understand what happens here.
I also made the same tests with SWI 8.5.17:
/* SWI-Prolog threaded, 64 bits, version 8.5.17 With :- table p(_,po(isSubsumedBy/2),_). we get: */ 2 ?- p(X,Z,Y). X = 1, Z = 2, Y = 3. 3 ?- display_table. Assertion failed: isAttVar(*av), file /home/swipl/src/swipl-devel/src/pl-attvar.c, line 173
Once again I do not understand what happens. It is likely I have not fully understood partial-order answer subsumption, but I cannot say.
Could you help me ?