1

3 または 5 で割り切れるリスト内のすべての数値の 2 乗和を求める 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 は、取得する必要がある唯一の出力です

4

1 に答える 1

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.

2 番目のルールでは、div_test が成功するかどうかをテストしません。最初のルールで div_test(Head) の後にカット(!) を追加するか、2 番目のルールで\+div_test(Head)を追加することができます。

SWI-Prolog を使用しているので、そこにあるモジュール lambda.pl を使用できます http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/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).
于 2013-04-06T12:15:52.540 に答える