Как бы вы преобразовали это в нерекурсивный. Этот код выдает факториал N.Prolog factorial non-recursive
fakultaet(0, 1).
fakultaet(N, F) :-
N > 0,
N1 is N – 1,
fakultaet(N1, F1),
F is N * F1.
Как бы вы преобразовали это в нерекурсивный. Этот код выдает факториал N.Prolog factorial non-recursive
fakultaet(0, 1).
fakultaet(N, F) :-
N > 0,
N1 is N – 1,
fakultaet(N1, F1),
F is N * F1.
Один из способов сделать это без рекурсивного вызова в вашем определении будет:
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.
Оба 'numlist/2' и' foldl/4' не являются предикатами ISO. Однако было бы легко писать с рекурсией. ;) –
@ DanielLyons Придерживаясь религиозных предикатов ISO, на самом деле не получится очень далеко, если вы захотите написать полезные материалы в Prolog :(Но да, просто посмотрите на реализацию либо из SWI-Prolog, который является открытым исходным кодом а не ISO-совместимый. –
@ DanielLyons BTW, я совершенно уверен, что это не тот ответ, о котором идет OP. Что такое OP после того, как я действительно не знаю. Для другого неразрешимого вопроса см. [здесь] (http: /stackoverflow.com/q/41700196/1812457). –
если ваш Пролог имеет 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, но в результате программа будет очень, очень неэффективно
Я предполагаю, что «Факультет» означает «факториал»? –
В Прологе действительно нет способа избежать рекурсии. Вы хотите сделать его хвостом рекурсивным для повышения производительности? –
@ DanielLyons Вы могли бы, конечно, обмануть и попробовать сделать это с помощью 'foldl', иначе вы могли бы сделать это без рекурсии: используйте' repeat' и глобальную переменную или memoization. –