Механизм исполнения Пролога не интуитивно понятен. Он сочетает в себе рекурсию (как вы знаете из других языков) с возвратом. Но есть хороший выход. Вы можете рассмотреть небольшие программы вместо вашей оригинальной программы.
Чтобы лучше понять действительный цикл, вот минимальный фрагмент программы, называемый fail-slice , который является причиной отсутствия завершения. В этом есть дополнительная фальшивка: некоторые цели false
. С этими целями количество выводов уменьшается (или остается неизменным). Таким образом, когда результирующая программа зацикливается, это также является причиной, по которой ваша исходная программа зацикливается.
connection(harry, ron).
connection(ron, harry).
<s>connection(herminone, harry) :- <b>false</b></s>.
<s>connected(A, B) :- <b>false</b>, connection(A, B)</s>.
connected(A, B) :-
connection(A, C),
connected(C, B), <b>false</b>.
?- connected(A, B).
Запрос по-прежнему зацикливается. Обратите внимание, что это не удается (и, следовательно, завершается), когда спрашивают нужных людей (вы знаете, кто, я полагаю):
?- connected(tom, B).
false.
Чтобы решить эту проблему, проще всего использовать closure/3
примерно так:
connected(A, B) :-
closure(connection, A, B).