2017-01-19 20 views
-1

Как бы вы преобразовали это в нерекурсивный. Этот код выдает факториал N.Prolog factorial non-recursive

fakultaet(0, 1). 
fakultaet(N, F) :- 
    N > 0, 
    N1 is N – 1, 
    fakultaet(N1, F1), 
    F is N * F1. 
+2

Я предполагаю, что «Факультет» означает «факториал»? –

+1

В Прологе действительно нет способа избежать рекурсии. Вы хотите сделать его хвостом рекурсивным для повышения производительности? –

+1

@ DanielLyons Вы могли бы, конечно, обмануть и попробовать сделать это с помощью 'foldl', иначе вы могли бы сделать это без рекурсии: используйте' repeat' и глобальную переменную или memoization. –

ответ

3

Один из способов сделать это без рекурсивного вызова в вашем определении будет:

factorial(0, 1). 
factorial(1, 1). 
factorial(N, F) :- 
    % the call to numlist/3 will fail if N < 2 
    numlist(2, N, [X|Xs]), % [X|Xs] = [2,3,...,N] 
    foldl(mult, Xs, X, P), % P = 2*3*...*N 
    F is P. 

mult(A, B, B*A). 

Такой подход позволяет избежать рекурсии на синтаксическом уровне в вашем определении , Оба numlist/2 и foldl/4, скорее всего, имеют рекурсивное определение, но вы не должны иметь посмотреть на него. Вероятно, это попадает в «d» что-то еще, что мне не хватает »категории from my comment to your question.

+1

Оба 'numlist/2' и' foldl/4' не являются предикатами ISO. Однако было бы легко писать с рекурсией. ;) –

+1

@ DanielLyons Придерживаясь религиозных предикатов ISO, на самом деле не получится очень далеко, если вы захотите написать полезные материалы в Prolog :(Но да, просто посмотрите на реализацию либо из SWI-Prolog, который является открытым исходным кодом а не ISO-совместимый. –

+0

@ DanielLyons BTW, я совершенно уверен, что это не тот ответ, о котором идет OP. Что такое OP после того, как я действительно не знаю. Для другого неразрешимого вопроса см. [здесь] (http: /stackoverflow.com/q/41700196/1812457). –

-1

если ваш Пролог имеет global variables, вы можете сделать

fakultaet(N,F) :- 
    nb_setval(f,1), 
    forall(between(2,N,I), (nb_getval(f,T), G is T*I, nb_setval(f,G))), 
    nb_getval(f,F). 

Это особое использование nb_setval/2, nb_getval/2 может быть частично смоделированы с утверждают/1, втягивать/1, но в результате программа будет очень, очень неэффективно