Почему поведение SWI-Prolog, по-видимому, противоречиво? - PullRequest
0 голосов
/ 25 декабря 2018

Пытаясь понять комбинацию cut-fail в Прологе, я нашел следующий пример и начал с ним играть:

enjoys(vincent,X)  :-  big_kahuna_burger(X),!,fail. 
enjoys(vincent,X)  :-  burger(X). 

burger(X)  :-  big_kahuna_burger(X). 
burger(X)  :-  big_mac(X). 
burger(X)  :-  whopper(X). 


big_kahuna_burger(b). 
big_mac(a).  
whopper(d).

Я пробовал два разных запроса.

В запросе 1: enjoys(vincent,b) результат состоит в том, что SWI-Prolog выводит false, что является ожидаемым поведением и останавливается, не спрашивая меня, хочу ли я найти другие решения.

В запросе 2: enjoys(vincent,a), первый SWI-Prolog выдает true, что снова ожидается, но затем он дает мне возможность нажать "next" , и он пытается найти другойрешение, а затем выводит false.

Почему это дает мне возможность проверить другое решение во время второго запроса, но не в первом?

Ответы [ 2 ]

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

Ваш первый запрос обрывается, что сигнализирует Прологу прекратить любые дальнейшие попытки поиска решений.Затем он нажимает false, что делает запрос неудачным и сообщает пользователю false, а затем, поскольку сокращение уже сократило все возможности для дальнейшего поиска, Пролог останавливается.

Anнесложная реализация вполне может попытаться выполнить поиск после пропуска, даже если это бесполезно, только для того, чтобы сразу обнаружить разрыв при возврате и затем, наконец, остановиться.

В вашем втором запросе big_kahuna_burger(a) завершается неудачно, и сокращение избегается.Будущее пространство поиска не сокращается.

burger(a)  :-  big_kahuna_burger(a). 

завершается неудачно, но

burger(a)  :-  big_mac(a). 

успешно, и еще есть

burger(a)  :-  whopper(a). 

, чтобы попробовать.

Таким образом, Пролог полностью ожидает возможности найти некоторые из них, если будет искать еще.Так же, как наша «неискушенная» реализация подойдет даже в первом случае.

Чтобы остановиться, потребовалось бы, чтобы реализация смотрела в будущее и заранее проверяла будущие результаты, обнаруживая, что whopper(a) действительно обречено на неудачу.Но это слишком дорого, чтобы делать всегда, и это делается только в нескольких очень специфических случаях, если таковые имеются.

Я думаю, что это называется "индексация".Поиск по «индексации Пролога» дает довольно много просмотров.

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

Короче говоря : потому что false означает, что после исчерпывающего поиска не может быть найдено никаких (дополнительных) решений.

Почему это произошлодать мне возможность проверить другое решение во втором запросе, но не в первом?

Поскольку, если он выдает false, это означает, что ему не удалось найти решение после исчерпывающий поиск.Следовательно, это означает: « Я не нашел никаких решений (больше). ».Поэтому после false не имеет смысла искать дополнительные решения.

Однако, если он предлагает решение, это не означает, что все решения исчерпаны.Таким образом, он может предложить дополнительные решения.В зависимости от оптимизаций, которые имеет интерпретатор Prolog, он может заранее знать, что дополнительных решений нет.Если это не так, он печатает решение, а затем делает паузу.Затем пользователь может запросить дополнительные решения.

Например, если мы напишем:

foo(a, 1).
foo(a, 2).
foo(b, 3).
foo(c, 4).

, тогда запрос с помощью foo(b, 3) будет, по крайней мере, в SWI-Prolog и, вероятно, в большинстве переводчиков,только скажи true, а потом знай, что это сделано.Поскольку SWI-Prolog проанализирует функтор / константу первого аргумента и, таким образом, заранее знает, что, если первый аргумент обоснован, других foo/2 с b в качестве первого аргумента не будет.

...