Reputation: 528
I have a Prolog program which is meant to find the sum of the squares of all the numbers in a list divisible by three or five. However it returns more than one result and I'm not sure why.
% --divisibility tests--
div_test(N):-
% divisible by three?
0 is N mod 3.
div_test(N):-
% divisible by five?
0 is N mod 5.
% sum of an empty list is zero (base case)
square_sum([], Sum):-
Sum is 0.
% --recursive cases
square_sum([Head | Tail], Sum) :-
div_test(Head),
square_sum(Tail, TempSum),
Sum is Head*Head + TempSum.
square_sum([Head | Tail], Sum) :-
square_sum(Tail, TempSum),
Sum is TempSum.
Given the following input:
?-square_sum([1,2,3,4,5],Sum).
I get the following output:
Sum = 34 ;
Sum = 9 ;
Sum = 25 ;
Sum = 0.
34 is the only output I should get
Upvotes: 1
Views: 528
Reputation: 5645
% --recursive cases
square_sum([Head | Tail], Sum) :-
div_test(Head),
square_sum(Tail, TempSum),
Sum is Head*Head + TempSum.
square_sum([Head | Tail], Sum) :-
square_sum(Tail, TempSum),
Sum is TempSum.
In the second rule you don't test if div_test succeeds. You can either add a cut (!) after div_test(Head), in the first rule or add \+div_test(Head), in the second rule.
You use SWI-Prolog, so you can use module lambda.pl found there http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl and write
:- use_module(library(lambda)).
div_test(N):-
% divisible by three?
0 is N mod 3.
div_test(N):-
% divisible by five?
0 is N mod 5.
square_sum(Lst, Sum) :-
foldl(\X^Y^Z^((div_test(X); div_test(X))
-> Z is Y + X*X
; Z = Y), Lst, 0, Sum).
Upvotes: 2