Есть ли реализация Пролога или библиотека, которая кэширует предикаты?
Или вы бы реализовали, скажем, кеш FIFO, используя assertz / 1 и retract / 1, например:
:- 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, используя дополнительные логические переменные:
...
( getval(cache_size) =:= 100 -> once retract(cache(_)) ; incval(cache_size) ),
...
На моем компьютере 1000 вызовов этого ccall / 1 занимают> 4,00 ЦП с, тогда как фактическое целевое время ЦП ничтожно (0,04 ЦП с). Поэтому я предполагаю, что кеш (особенно кеш LRU или около того), реализованный внутри интерпретатора, все равно будет превосходить assertz / 1 и retract / 1.
Я не хочу иметь кеширование для каждого предиката, конечно, только для очень несколько. Сценарий может быть таким: p ([H | T], E): - q (H, E); p (T, E)
с q / 2
без побочных эффектов. p / 2
вызывается для постоянно растущего списка, но всегда / часто для одного и того же E
.