Prolog递归程序返回太多结果

时间:2013-04-06 08:21:16

标签: list recursion prolog

我有一个Prolog程序,用于查找可被三或五整除的列表中所有数字的平方和。但是它会返回多个结果,我不知道为什么。

% --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.

给出以下输入:

?-square_sum([1,2,3,4,5],Sum).

我得到以下输出:

Sum = 34 ;
Sum = 9 ;
Sum = 25 ;
Sum = 0.

34是我应该得到的唯一输出

1 个答案:

答案 0 :(得分:2)

% --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.

在第二条规则中,您不测试div_test是否成功。 您可以在第一个规则中在div_test(Head)之后添加剪切(!),或在第二个规则中添加 \ + div_test(Head)

你使用SWI-Prolog,所以你可以使用http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl找到的模块lambda.pl并写

:- 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).