Это дает мне сначала true
и после false
.Но я не хочу этого.Я хочу только true
, почему он дает false
после true
?Почему он дает два выхода?
Потому что у Prolog есть встроенный возврат.После того, как он предложит первое решение, он сообщит об этом решении, но затем вернется в поисках другого решения.
В зависимости от точного запроса, Prolog может заранее знать, что вариантов возврата нет.Prolog оценивает факты / предложения предиката сверху вниз, поэтому это означает, что если, например, он успешно завершает работу с последним предложением (и нет рекурсивных вызовов), он точно знает, что он исчерпывающе искал все параметры.
Здесь вы пишете:
route(A, B, C):-
flight(A, B, C);
flight(B, A, C).
Таким образом, это означает, что если вы позвоните route(newyork, washington, 7).
, он сначала вызовет flight(newyork, washington, 7)
. И это удастся (это даже первый flight/3
факт), ноесть еще варианты, как это могло бы преуспеть: возможно, есть еще один flight(newyork, washington, 7)
факт, так что это может дать true
во второй раз.
Большинство систем Prolog, однако, имеют передовые стратегии поиска, чтобы увидеть, что это единственныйflight/3
факт с newyork
в качестве первого параметра, поэтому современная система Prolog, как правило, заранее знает, что нет надежды найти другой flight/3
факт, но это не значит, что мы закончили.
Вы определили в теле вашего route/3
предложения flight(B, A, C)
, поэтому Пролог начнет поиск flight/3
, но с измененными местами.Таким образом, после сообщения о первом решении он продолжит запрос и вызовет flight(washington, newyork, 7)
в надежде найти другое решение.
Если в запросе используются переменные, это весьма полезно, так как в предложенномРешения, значения, которые присваиваются переменным, могут (и очень часто являются ) разными, поэтому это можно использовать как инструмент поиска.
Вы можете использовать Once / 1 [SWI-DOC] мета-предикат для оценки вызова один раз.В этом случае либо предикат успешен (и объединяет переменные), либо нет (и терпит неудачу).Кроме того, конечно, все еще возможно, что предикат вызывает ошибку или застрял в бесконечном цикле.