谓词缓存 [英] Predicate cache
问题描述
是否有缓存谓词的 Prolog 实现或库?
Is there a Prolog implementation or library that caches predicates?
或者你会使用assertz/1和retract/1来实现一个FIFO缓存,就像这样:
Or would you implement a, say, FIFO cache using assertz/1 and retract/1, like this:
:- dynamic cache/1.
ccall(G) :- cache(G).
ccall(G) :-
\+ cache(G),
call(G),
( findall(G0,cache(G0),Gs), length(Gs,N), N =:= 100 -> once retract(cache(_)) ; true ),
assertz(cache(G)).
在 ECLiPSe-CLP 中,至少可以使用额外的逻辑变量替换 findall/3 行:
In ECLiPSe-CLP, one could at least replace the findall/3 line using extra-logical variables:
...
( getval(cache_size) =:= 100 -> once retract(cache(_)) ; incval(cache_size) ),
...
在我的机器上,1000 次调用此 ccall/1 需要 >4.00 cpu 秒,而实际目标 cpu 时间可以忽略不计(0.04 cpu 秒).所以我猜在解释器内部实现的缓存(尤其是 LRU 缓存左右)仍然会胜过 assertz/1 和 Retract/1.
On my box, 1000 calls to this ccall/1 take >4.00 cpu sec, whereas the actual goal cpu time is negliglible (0.04 cpu sec). So I guess a cache (particularly a LRU cache or so) implemented inside the interpreter would still outperform the assertz/1 and retract/1.
我不想对每个谓词都进行缓存,当然,只对少数谓词进行缓存.一个场景可能是这样的: p([H|T], E) :- q(H,E) ;p(T,E)
与 q/2
没有副作用.p/2
用于稳定增长的列表,但总是/经常用于相同的 E
.
I don't want to have caching for every predicate, of course, only for very few ones. A scenario could be like this: p([H|T], E) :- q(H,E) ; p(T,E)
with q/2
having no side effects. p/2
is called for a steadily growing list but always/often for the same E
.
推荐答案
你想要吗 制表/记忆?
XSB 提供自动制表(您声明要制表的谓词)
do you want tabling/memoization?
XSB offers automatic tabling (you declare which predicates you want to have tabling)
是的,assertz/1 等有点慢
and yes, assertz/1 etc are kinda slow
这篇关于谓词缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!