I am currently working with prolog and want to multiply two lists together but in a certian way. For example:
[1,2,3] and [4,5,6] are my two lists.
I want to preform the following actions:
(1*4)+(2*5)+(3*6) = 32
Such that the first element of each list is multiplied to each other then added with the second elements multiplied together etc.
Is this possible to go in Prolog?
I know in other languages you can do a recursive function with takes the head of the list and the tail (the rest of the entries). This allows for a simple multiplication but I do not think that is possible in prolog?
Using built-ins:
mult(X, Y, Z) :- Z is X * Y.
sum_prod(A, B, SumProd) :-
maplist(mult, A, B, Prods),
sumlist(Prods, SumProd). % In GNU Prolog this is sum_list
Using simple recursion:
sum_prod([A|As], [B|Bs], SumProd) :-
sum_prod(As, Bs, SP),
SumProd is SP + A*B.
sum_prod([], [], 0).
Using tail recursion:
sum_prod(A, B, SumProd) :-
sum_prod(A, B, 0, SumProd).
sum_prod([A|As], [B|Bs], Acc, SumProd) :-
Acc1 is Acc + A*B,
sum_prod(As, Bs, Acc1, SumProd).
sum_prod([], [], Acc, Acc).
If all items of your lists are integers and your Prolog implementation offers clpfd, you can simply use the
clpfd built-in predicate scalar_product/4
, like this:
?- scalar_product([1,2,3],[4,5,6],#=,Product).
Product = 32.
Edit:
You may also be interested in the related question "Prolog: Multiplying 2 lists with 1 of them not instantiated?", particularly in this answer.
as an alternative to 'hand coded' loops, using library(aggregate) and nth1/3:
sum_prod(A,B,S) :-
aggregate(sum(M), I^X^Y^(nth1(I,A,X), nth1(I,B,Y), M is X*Y), S).