Я пытаюсь смоделировать набор зубчатых колес в Прологе. И запросить, если два колеса соединены цепью других.
У меня есть простая рекурсия:
connected(X,Y) :-
engages(X,Y).
connected(X,Y) :-
engages(X,Z),
connected(Z,Y).
Если я определяю взаимодействия в терминах предиката:
engages(X,Y) :- touches(X,Y).
и
touches(z1,z2).
touches(z2,z3).
touches(z3,z4).
Тогда это работает.
Тест
connected(z1,z4).
производит истину и
connected(z1,z5).
производит ложь.
Однако, если я заменю свой предикат касаний вычислением (что сумма двух радиусов примерно равна расстоянию между двумя центрами), тогда этот поиск переходит к тому, что выглядит как бесконечная рекурсия (переполнение стека), когда ответ должно быть ложным.
Почему это должно быть, учитывая, что мои вычисления "касаний" сами по себе не называют "подключенным" функтором? Это потому, что функтор touch будет пытаться сопоставить больше атомов, чем явные предикаты?
Это, примерно, мои расчетные касания (A и B - колеса, ARAD и BRAD - их радиусы, D - расстояние, а прибл. - функция "приблизительно равно").
touches(A,B) :-
wheel(A,_,_,ARAD),
wheel(B,_,_,BRAD),
distance(A,B,D),
approx(D,(ARAD+BRAD),2),
A \== B.