Выход пролога дает ложь после истины - PullRequest
0 голосов
/ 23 декабря 2018

У меня есть прологическая программа для представления рейсов между двумя штатами с указанием их стоимости.

Моя программа такая:

flight(newyork,washington,7). %its mean that there is a flight between both washington and newyork, newyork and washington with cost 7. 
flight(lasvegas,losangeles,4).
flight(california,arizona,8).

route(A,B,C):-
    flight(A,B,C);flight(B,A,C). %there is a route if there is a flight between A and B with cost C `OR` B and A with cost C.

Теперь, когда я пишу такой запрос:

?-route(washington,newyork,7).

его дай мне true.Этот запрос работает хорошо для меня.

Но когда я пишу этот запрос:

?-route(newyork,washington,7).

Это дает мне вначале true и после false. Но я этого не хочу.Я хочу только true, почему он дает false после true?Почему это дает два выхода?

Ответы [ 2 ]

0 голосов
/ 23 декабря 2018

Это дает мне сначала 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] мета-предикат для оценки вызова один раз.В этом случае либо предикат успешен (и объединяет переменные), либо нет (и терпит неудачу).Кроме того, конечно, все еще возможно, что предикат вызывает ошибку или застрял в бесконечном цикле.

0 голосов
/ 23 декабря 2018

Ваше определение предиката route/2 не является детерминированным.Если левая цель в дизъюнкции успешна, также возможно, что правая цель также будет успешной.Т.е. дизъюнкция подразумевает точку выбора:

?- route(newyork,washington,7).
true ;
false.

Когда вы набираете ;, вы запрашиваете у Пролога альтернативное решение.Двигатель Prolog возвращается к точке выбора и пытается достичь правильной цели.Когда эта цель не достигнута, на верхнем уровне Prolog печатается false, чтобы вы знали, что альтернативное решение не найдено.

...