Hi !
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: [12] throw(error(uninstantiation_error(2),_23840))
ERROR: [10] '$wrap$p'(1,2,3)1-st clause of '$wrap$p'/3 <no source>
ERROR: [9] 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 ?
Thanks