许多 Prolog 系统不允许用户定义的可评估谓词。
有时问题是可评估谓词存在于
另一个命名空间。有时,Prolog 系统在使用宿主语言进行算术评估时会回避跳回 Prolog 执行。
一些 Prolog 系统仍然具有用户定义的可评估谓词,例如 ECLiPSe Prolog 和 Jekejeke Prolog。在 Jekejeke Prolog 中,开销是两倍。令我惊讶的是,新的 Dogelog 运行时用户可定义可评估
谓词显示出优势:
/* Dogelog Runtime 0.9.5 */
fact(0, 1) :- !.
fact(N, X) :- M is N-1, fact(M, Y), X is Y*N.
fact2(0, 1) :- !.
fact2(N, X) :- X is fact2(N-1)*N.
for(_).
for(N) :- N > 1, M is N - 1, for(M).
% ?- time((for(1000), fact(1000, _), fail; true)).
% % Wall 1595 ms, trim 0 ms
% ?- time((for(1000), _ is fact2(1000), fail; true)).
% % Wall 1394 ms, trim 0 ms
我将轻微的速度优势归因于事实上更简洁的公式 2/2。该公式使用较少的 Prolog 逻辑变量。并且用户定义的可评估谓词能够(is)/2 在内部也没有 Prolog 逻辑变量,发生的宿主语言分配不分配
一个Prolog的逻辑变量或者trail同理,这样最后有一个加速。