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