Получить продукт из пунктов списка с помощью рекурсии в Прологе? - PullRequest
0 голосов
/ 11 ноября 2018

Как получить продукт из элементов списка с помощью рекурсии?

Если я спрашиваю:

product([s(0), s(s(0)), s(s(0))], S).

Результат должен быть:

S = s(s(s(s(0)))).

Но я получаю неправильные результаты. Или нет результатов.

Я пытался:

product([], 0).
product([], Res).
product([H1, H2|T], Res) :- T\=[], mul(H1, H2, Res), product(T, Res).
product([H|T], Res) :- mul(H, Res, X), product(T, X).

Мул это умножение, и оно отлично работает.

Если я использую трассировку, я вижу, что она находит результат, но по какой-то причине не работает.

Call: (10) product([], s(s(s(s(0))))) ? creep
Fail: (10) product([], s(s(s(s(0))))) ? creep

Есть идеи у кого-нибудь?

1 Ответ

0 голосов
/ 11 ноября 2018

Я думаю, вы обнаружите, что это помогает:

product([], 0).
product([H], H).
product([H1, H2|T], Res) :-
    mul(H1, H2, H),
    product([H|T], Res).

Первый предикат является тривиальным базовым случаем.

Во-вторых, список содержит только один элемент - таков ответ.

Третий случай, когда у вас есть список из двух или более элементов - просто выполните mul/3 для первых двух, а затем рекурсивно позвоните product/2. Это в конечном итоге будет соответствовать предикату 2 и завершится.

Ваш пример ввода дает s(s(s(s(0)))).

Пожалуйста, в будущем включите определение для mul/3. Мне пришлось искать в интернете, чтобы найти один.

%Addition
sum(0,M,M). %the sum of an integer M and 0 is M.
sum(s(N),M,s(K)) :- sum(N,M,K). %The sum of the successor of N and M is the successor of the sum of N and M.

%Multiplication
%Will work for mul(s(s(0)),s(s(0)),X) but not terminate for mul(X,Y,s(s(0)))
mul(0,M,0). %The product of 0 with any integer is 0
mul(s(N),M,P) :- 
    mul(N,M,K), 
    sum(K,M,P). %The product of the successor of N and M is the sum of M with the product of M and N. --> (N+1)*M = N*M + M
...