we are currently working on the implementation of the predicate reduce, which Needs to take a list L, a binary function F that operates on the elements of L and has neutral element N and maps them to a number E that is obtained by applying F to the elements of L recursively.
Here's our Code so far:
reduce([],F,NEUTRAL,EE).
reduce([H|T],F,NEUTRAL,EE) :-
Goal =.. [F, H, NEUTRAL, EE],
call(Goal),
reduce(T,F,NEUTRAL,EE).
add(N1,NEUTRAL, EE) :- EE is EE + N1 + NEUTRAL.
mult(N1,NEUTRAL, EE) :- EE is N1 * EE * NEUTRAL.
the Problem is: to same sample queries such as ?- reduce([], add, 0, R).
we just get a boolean (in this case true), to others an error back, which tells us that our Arguments are not properly instantiated. What we actually aim for is a Response like R = 0
. (for the example given above).
Hope you can help us, please do not be too complicated as we are Prolog beginners ;)
You need the neutral element to end the recursion. You don't need it at every step. I'd almost say that the neutral element belongs with the operator, not with the reduce. Something like this:
Then, your
reduce
could look like this:But let's keep it easy for now and do it as suggested in the question. You need the neutral element only if the list of operands is empty, to set your result:
Otherwise, go in the recursion and then apply the operation to the result (and you can use
call
directly):You can see here how to use
reduce/4
for example withappend/3
.Do you see
N
insidecall
? I do not see it, and it doesn't belong there.For completeness, the two operators:
There is no mention of a neutral element either.
By the way: what you have called "reduce" is also known as a "fold" over a list. You could define your
reduce/3
in terms offoldl
like this:The recursion and the
call
both happen insidefoldl
, you don't needreduce/4
at all.How would you solve this in a procedural language? Using pseudo-code with a C-like syntax, and assuming we have some support for generics, it could go like this:
(apparently if this was indeed C++ we would be using iterators, not an index...)
It is not at all that different from the Prolog version. And if you did it the same way as the
foldl
above, it would probably look like this:Again, no mention of the neutral element inside the loop, nor in the call to
op()
.