Passing results to prologue
I am trying to create a function that has a list of lists, it multiplies the sum of the inner list by the outer list. While I can compose the list, I have created a function sumlist ([1..n], X) that will return X = (result). But I can't get another function to usefully work with this function, I've tried both, to no avail.
source to share
Is this what you mean?
prodsumlist([], 1).
prodsumlist([Head | Tail], Result) :-
sumlist(Head, Sum_Of_Head),
prodsumlist(Tail, ProdSum_Of_Tail),
Result is Sum_Of_Head * ProdSum_Of_Tail.
where sumlist/2
is the embedded SWI-Prolog.
Usage example:
?- prodsumlist([[1, 2], [3], [-4]], Result). Result = -36.
source to share
The "multiplies the sum of the inner list by the outer list" part is not entirely clear, but I believe you mean that given a list of [L1,...,Ln]
lists of numbers, you want to calculate S1*..*Sn
where Si
is the sum of the elements from Li
(for each i
).
I am assuming existence plus
and mult
with their obvious meaning (e.g. plus(N,M,R)
holds exactly when R
equal N+M
). First, we need a predicate sum
such that it sum(L,S)
holds if and only if S
is the sum of elements from L
. If L
empty, S
it should obviously be 0
:
sum([],0).
If L
not empty, but forms [N|L2]
, then we have what S
should be N
plus the sum of the S2
elements in L2
. In other words, we must have both sum(L2,S2)
(to get S2 as the sum of elements L2
) and plus(N,S2,S)
. I.e:
sum([N|L2],S) :- sum(L2,S2), plus(N,S2,S).
In the same way, you can find the predicate p
you are looking for. We want to be p(L,R)
fulfilled if and only if it R
is a product S1
through Sn
, where L=[L1,...,Ln]
and sum(Li,Si)
for everyone i
. If L
empty, it R
should be 1
:
p([],1).
If L
not empty, but forms [LL|L2]
, then we have what R
should be the product of 'S', the sum of elements LL
and 'P', the product of the sums of lists in L2
. For S
we already have sum(LL,S)
, so this gives us the following.
p([LL|L2],R) :- sum(LL,S), p(L2,P), mult(S,P,R).
One thing I would like to add is that it probably isn't all that good to see these predicates as functions that you could use from imperative or functional programming. This is not the case when sumlist([1,..,n],X)
returns X = (result)
; (result)
- meaning for X
what is sumlist([1,...,n],X)
true. This requires a slightly different mindset. Instead of thinking, "How can I compute X so that p (X) does?" you have to think, "When is P (X) executed?" and use the answer ( "Well, if q (X) or r (X)!"), to make proposals ( p(X) :- q(X)
and p(X) :- r(X)
).
source to share
Here is a correspondence from Kaarel's answer (that's the intent anyway!) But tail is recursive .
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).
source to share