Как заметил Джефф, проблема в правиле:
add( A, B, C ) :- add( B, A, C ).
В общем, это правило, которое выражает то, что вы хотите быть правдой, но это не помогает вам решить цель. Запрос add(1,2,X)
по этому правилу приводит к подзапросу add(2,1,X)
, что приводит к подзапросу add(1,2,X)
: разрешение SLD может тратить вечно на эту ветку (если у него нет других правил более высокого приоритета, и он не определяет что правило не прогрессирует), никуда не деться. Вы должны использовать такое правило только с условиями (например, strictlylessthan (B,A)
), которые гарантируют, что правило применимо только тогда, когда оно может выполнять полезную работу. Проблема таких правил является причиной, по которой Пролог на самом деле не является декларативным языком.
Чтобы восстановить коммутативность, вам нужно добавить правило:
add (0, [A], A).
Ваш предикат добавления является нечетным: add([1],0,1)
- это истина, как и add([1],[0],1)
, но add([0],1,1)
- это не так, как и add([1],[0],[1])
. add
совершенно значим с вычислительной точки зрения, но действительно ли это то, что вы хотите?