Вообще говоря, ответ @ m09 в основном прав насчет важности хвостовой рекурсии.
Для больших N
, расчет продукта по-другому выигрывает! Подумайте «двоичное дерево», а не «линейный список» ...
Давайте попробуем оба способа и сравним время выполнения. Во-первых, @ m09's factorial/2
:
?- time((factorial(100000,_),false)).
% 200,004 inferences, 1.606 CPU in <b>1.606</b> seconds (100% CPU, 124513 Lips)
false.
Далее мы делаем это в древовидном стиле - используя мета-предикат reduce/3
вместе с лямбда-выражениями :
?- time((numlist(1,100000,Xs),reduce(\X^Y^XY^(XY is X*Y),Xs,_),false)).
% 1,300,042 inferences, 0.264 CPU in <b>0.264</b> seconds (100% CPU, 4922402 Lips)
false.
Наконец, давайте определим и используем выделенный вспомогательный предикат x_y_product/3
:
x_y_product(X, Y, XY) :- XY is X*Y.
Что выиграть? Давайте попросим секундомер !
?- time((numlist(1,100000,Xs),reduce(x_y_product,Xs,_),false)).
% 500,050 inferences, 0.094 CPU in <b>0.094</b> seconds (100% CPU, 5325635 Lips)
false.