Hi
I’m getting familiar with tabling by running the fib/2 example from the SWI documentation.
:- table fib/2.
test :-
time(fib(1000, X)),
format('~w~n', [X]).
fib(0, 1) :- !.
fib(1, 1) :- !.
fib(N, F) :-
N > 1,
N1 is N-1,
N2 is N-2,
fib(N1, F1),
fib(N2, F2),
F is F1+F2.
It works fine but the number of inferences required on the second and subsequent executions seems /too/ good.
?- test.
**39,032** inferences, 0.016 CPU in 0.016 seconds (100% CPU, 2498048 Lips)
70330367711422815821835254877183549770181269836358732742604905087154537118196933579742249494562611733487750449241765991088186363265450223647106012053374121273867339111198139373125598767690091902245245323403501
true.
?- test.
**5** inferences, 0.000 CPU in 0.000 seconds (?% CPU, Infinite Lips)
70330367711422815821835254877183549770181269836358732742604905087154537118196933579742249494562611733487750449241765991088186363265450223647106012053374121273867339111198139373125598767690091902245245323403501
true.
I tried it on SWISH and each execution has the same resource requirements:
39,022 inferences, 0.022 CPU in 0.022 seconds (100% CPU, 1743120 Lips)
According to Wikipedia:
Subgoals encountered in a query evaluation are maintained in a table, along with answers to these subgoals. If a subgoal is re-encountered, the evaluation reuses information from the table rather than re-performing resolution against program clauses.
The 5 inferences make it look like the tabling is persisting between (top level) goal executions. Or maybe this is some feature of the top level I don’t understand.
Cheers
Mike