Получить продукт из пунктов списка с помощью рекурсии в Прологе?
Как получить продукт из элементов списка с помощью рекурсии?
Если я спрашиваю:
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 ответ
Я думаю, вы обнаружите, что это делает трюк:
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