Лучший способ локализовать проблему - это сначала упростить ваш запрос:
?- 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)).
Рекурсивные правила относительно сложно читать в Прологе.Самый простой способ понять их - взглянуть на :-
и понять, что это должна быть стрелка ← (то есть стрелка справа налево), означающая:
при условии, что цели справа -правая сторона
мы заключаем, что находится с левой стороны
Итак, по сравнению с неформальной записью стрелки указывают в противоположном направлении!
Для нашего запроса мыможно рассмотреть следующую реализацию, заменив Xs
на []
и X
на 0.
sum([s(0)| [] ], Sum) :- sum([0| []],s(Sum)).
Так что теперь это правило читается справа налево: при условии, sum([0],s(Sum))
- true, ..Однако мы знаем, что имеет место только sum([0],0)
, но не эта цель.Следовательно, это правило никогда не применяется!То, что вы намеревались, было скорее наоборот:
sum([s(X)|Xs], s(Sum)):-sum([X|Xs],Sum).