Whenever a goal fails that you expect to succeed, see this as an opportunity to learn (short form for logic earn = earn logic). After all, this is Prolog which was meant to mean Programming in Logic. So where is the logic in your program?
For the moment your program fails, but you expected it to succeed. Where is the culprit? Let's generalize your program such that the resulting program still fails, but is much smaller. There are two easy ways to generalize a program:
We can do this pretty blindly. No need to understand your program. Just recheck that the goal still fails. Here is what I came up with on my first try:
:- op(950, fy, *).
* _G_0. % ignore the argument _G_0
sum([], _/*0*/).
sum([_/*[_,Head]*/|[_,Tail]], Sum) :-
* sum([_,Tail], Sum2),
* Sum is Head+Sum2.
?- sum([_/*[a, 1]*/, _/*[b, 2]*/, _/*[c, 3]*/, _/*[d, 4]*/], Total).
false. % gnah - still fails
One problem has to be in the remaining visible part. Too difficult to figure out? Let Prolog explain it to you by querying the most general query:
?- sum(Xs, Sum).
Xs = []
; Xs = [_A,_B,_C].
So only two lengths of lists are possible: The empty list and a list with three elements. Note that we have currently a generalized version of the predicate. So there is no guarantee that we will find solutions for both lengths. However, we can be 100% sure that for all other lengths there will be no solution.
Let's get back at the original program and ask the most general query:
?- sum(Os, Total).
Os = [], Total = 0
; false.
Oh no, there is a single solution only. And not even a single solution for sum([_|_], Total)
.
So let's generalize the program again but now with respect to this failing goal:
sum([], _/*0*/).
sum([_/*[_,Head]*/|[_,Tail|_/*[]*/]], Sum) :-
sum([_,Tail], Sum2),
* Sum is Head+Sum2.
?- Os = [_|_], sum(Os, Total).
false.
In this part there must be a further error. And in fact, the goal sum([_,Tail], Sum2)
is the culprit: It is about a list of exactly two elements, but the rule wants at least three
For the actual fixes, see the other answers.
This method works for pure, monotonic programs such as yours.