2013-04-06 2 views
1

У меня есть программа 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 является единственным выходом я должен получить

ответ

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 succe ред. Вы можете либо добавить разрез (!) После div_test (Head) в первом правиле или добавить \ + div_test (Head), во втором правиле.

Вы можете использовать SWI-Пролог, так что вы можете использовать модуль 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). 
+0

Спасибо! Я понятия не имел о разрезе пролога ха-ха (я новичок в Prolog). Я посмотрю на лямбда-модуль :) – thegalah

Смежные вопросы