Issue with Prolog code doing summation of elements in a list

Viewed 68

Hoping you are well. I am fairly new to prolog and I am having an issue with a code that I am writing. The purpose of the code is quite simple. It adds each element from a list until the last one. Something I could do in Java as:

    static void add(double[] array){
        double x = .0;
        for (int i = 0; i < array.length; ++i)
            x += array[i];
        System.out.println(x);
    }

However, I have been scratching my head about how to do it in prolog. I have the following code

add_list([], X):- write(X).
add_list([Head|Tail],X) :- 
    Y is Head,
    X is 0 + Y, %initialize X and add Y every time it runs.
    add_list(Tail, X).

The error I do get is that the variable X is already bounded when the code runs for the second time which makes sense, but I don't really know how to go about solving the issue.

Any help will be greatly appreciated.

Thanks.

2 Answers

Prolog programs are relations. Using a name starting with add_ sounds more like an imperative program. If you want to learn Prolog, avoid such names as much as you can. In this case you want to establish a relation between a list and the sum of its elements. list_sum/2 sounds like a much better name.

:- use_module(library(clpz)). % or clpfd
:- op(150, fx, #).

list_sum([], 0).
list_sum([E|Es], S) :-
   #S #= #E + #Si,
   list_sum(Es, Si).

Now, given that definition, try it out!

?- list_sum([1,2,3], N).
   N = 6.
?- list_sum([1,2,3], 7).
   false.
?- list_sum([1,2,E], 7).
   E = 4.
?- list_sum([1,E,E], 7).
   E = 3.

I came up with a way to get the result I need. Following the advice of @false I renamed my rule from add_list to list_sum. I came up with the following code that works, but will need a digit (0 ideally. Any other number will increase the result by that number.) to be provided when it is called.

list_sum([], X):- write(X). 
list_sum([Head|Tail], X)  :- 
    K is X,
    W is K + Head, 
    list_sum(Tail, W).

The issue with the code now is that if you enter 1 instead of 0 as the initial variable as mentioned above, it increases the result by 1. I am not totally satisfied with the result to be honest.

Related