Лучший способ локализовать проблему - сначала упростить запрос:
?- sum([0],S).
true
?- sum([],S).
true
Даже для них вы получите ответ, что подойдет любой S
. Нравится
?- sum([],s(s(0))).
yes
Поскольку []
может обрабатываться только вашим фактом, ошибка должна заключаться именно в этом факте. Вы заявили:
sum([], Sum).
Это означает, что сумма []
- это что угодно. Вы, наверное, имели ввиду 0.
Еще одна ошибка кроется в последнем правиле ... После исправления первой ошибки получаем
?- sum([0],Sum).
Sum = 0
?- sum([s(0)],Sum).
no
Здесь отвечает последний пункт. Он гласит:
sum([s(X)|Xs], Sum):-sum([X|Xs],s(Sum)).
Рекурсивные правила относительно сложно читать на Прологе. Самый простой способ понять их - взглянуть на :-
и понять, что это должна быть стрелка (то есть стрелка справа налево), означающая:
provided, that the goals on the right-hand side are true
we conclude what is found on the left-hand side
Итак, по сравнению с неформальным письмом стрелки указывают в противоположном направлении!
Для нашего запроса мы можем рассмотреть следующий экземпляр, заменяющий Xs
на []
и X
на 0.
sum([s(0)| [] ], Sum) :- sum([0| []],s(Sum)).
Итак, это правило теперь читается справа налево: При условии, sum([0],s(Sum))
верно, ... Однако мы знаем, что выполняется только sum([0],0)
, но не эта цель. Следовательно, это правило никогда не применяется! То, что вы намеревались сделать, было скорее противоположным:
sum([s(X)|Xs], s(Sum)):-sum([X|Xs],Sum).
person
false
schedule
14.03.2012