Передача результатов в прологе - PullRequest
1 голос
/ 08 декабря 2008

Я пытаюсь создать функцию со списком списков, она умножает сумму внутреннего списка на внешний список. Пока я могу суммировать список, я создал функцию sumlist ([1..n], X), которая будет возвращать X = (результат). Но я не могу заставить другую функцию с пользой работать с этой функцией, я пробовал и есть, и = безрезультатно.

Ответы [ 3 ]

2 голосов
/ 09 декабря 2008

Это то, что вы имеете в виду?

prodsumlist([], 1).

prodsumlist([Head | Tail], Result) :-
    sumlist(Head, Sum_Of_Head),
    prodsumlist(Tail, ProdSum_Of_Tail),
    Result is Sum_Of_Head * ProdSum_Of_Tail.

где sumlist/2 - встроенный SWI-Prolog.

Пример использования:

?- prodsumlist([[1, 2], [3], [-4]], Result).
Result = -36.
1 голос
/ 09 декабря 2008

Часть "она умножает сумму внутреннего списка на внешний список" не совсем понятна, но я думаю, вы имеете в виду, что, учитывая список [L1,...,Ln] списков чисел, вы хотите вычислить S1*..*Sn где Si - сумма элементов в Li (для каждого i).

Я предполагаю существование plus и mult с их очевидным значением (например, plus(N,M,R) верно именно тогда, когда R равно N+M). Сначала нам нужен предикат sum такой, что sum(L,S) выполняется тогда и только тогда, когда S является суммой элементов L. Если L пусто, S, очевидно, должно быть 0:

sum([],0).

Если L не пустой, а имеет форму [N|L2], то у нас есть S должно быть N плюс сумма S2 элементов в L2. Другими словами, мы должны иметь и sum(L2,S2) (чтобы S2 была суммой элементов L2) и plus(N,S2,S). То есть:

sum([N|L2],S) :- sum(L2,S2), plus(N,S2,S).

Таким же образом вы можете определить предикат p, который вы ищете. Мы хотим, чтобы p(L,R) выполнялось тогда и только тогда, когда R является произведением от S1 до Sn, где L=[L1,...,Ln] и sum(Li,Si) для всех i. Если L пусто, R должно быть 1:

p([],1).

Если L не пустой, но имеет форму [LL|L2], то мы имеем, что R должно быть произведением 'S', суммы элементов LL, и 'P', произведение сумм списков в L2. Для S у нас уже есть sum(LL,S), так что это дает нам следующее.

p([LL|L2],R) :- sum(LL,S), p(L2,P), mult(S,P,R).

Одна вещь, которую я хотел бы добавить, состоит в том, что, вероятно, не очень хорошая идея видеть эти предикаты как функции, которые вы могли бы использовать для императивного или функционального программирования. Это не тот случай, когда sumlist([1,..,n],X) возвращает X = (result); (result) - это значение для X, такое, что sumlist([1,...,n],X) является истинным. Это требует несколько иного мышления. Вместо того, чтобы думать "Как я могу вычислить X так, чтобы p (X) держалось?" Вы должны подумать: «Когда держится P (X)?» и используйте ответ («Хорошо, если q (X) или r (X)!»), чтобы составить предложения (p(X) :- q(X) и p(X) :- r(X)).

0 голосов
/ 28 октября 2009

Вот переписывание ответа Каарела (это все равно намерение!), Но рекурсивный хвост .

prodsumlist(List, Result) :-
    xprodsumlist(List,1,Result).

xprodsumlist([],R,R).

xprodsumlist([Head|Rest],Sofar,Result) :-
    sumlist(Head, Sum_Of_Head),
    NewSofar is Sofar * Sum_Of_Head,
    xprodsumlist(Rest, NewSofar, Result).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...