2014-12-05 2 views
0

Prolog Question: Только что начал изучать пролог, и это было на одном из тех викторин, которые мы получили.Порядок запроса правил запроса

Дано:

avenger(thor). 
avenger(captainAmerica). 
sibling(thor,loki). 
asgardian(thor). 
asgardian(X) :- sibling(Y,X),asgardian(Y). 
train1(X,Y) :- avenger(X),!,avenger(Y). 
train2(X,Y) :- avenger(X),X\=Y,avenger(Y). 

Список всех ответов, возвращаемые следующие вопросы.

train2(A, captainAmerica). %returns A=thor. 
train2(captainAmerica, A). %returns false. 

Мой вопрос касается второго запроса. Почему бы это не вернуть A = thor. ? я бездельничал немного, и если я изменить train2 к

train2(X,Y) :- avenger(X),avenger(Y),X\=Y. 

, когда я запускаю второй запрос я получаю

A=thor. 

Быстрое объяснение того, почему порядок правил в запросе значение здесь будет будь офигенным. Благодарю.

+0

См. [Этот ответ] (http://stackoverflow.com/a/8523825/772868). Поэтому либо используйте 'dif/2', либо [' iso_dif/2'] (http://stackoverflow.com/a/20238931/772868) – false

ответ

2

\= - это странный предикат ... В нем говорится: «Если объединение двух аргументов будет успешным, потерпите неудачу, если унификация завершится неудачно». Итак, поскольку объединение свободной переменной с атомом всегда будет успешным, оно терпит неудачу.

После Y унифицирован с thor, объединение captainAmerica с thor выходит из строя, поэтому X \= Y успешно.

В любом случае, вы не должны использовать \=. Вместо этого используйте dif/2. Попробуйте возиться с предикатом, определенным как:

train3(X, Y) :- 
    dif(X, Y), 
    avenger(X), 
    avenger(Y). 

Лучше, чем два других в нескольких направлениях. Вы можете найти SO для других вопросов с помощью dif/2.

0

Стандартный предикат \=/2 является истинным, когда его аргументы не объединяются. Таким образом, он требует, чтобы оба аргумента были связаны (т. Е. Не переменными), чтобы иметь смысл. Ваше решение:

train2(X,Y) :- avenger(X), avenger(Y), X \= Y. 

является правильным, поскольку два исходящих звонков в avenger/1 предиката гарантировать, что и X и Y будет достаточно инстанцирован перед вызовом к \=/2 предиката.

Как объяснил Борис в своем ответе, альтернатива использованию предиката dif/2 имеет силу, заключающуюся в том, что цель в указанном выше пункте не имеет значения. Однако есть оговорка. Предикат dif/2 не является стандартным предикатом, и не все его реализации обеспечивают его.

+0

Давно было оживленное обсуждение с участием 'dif/2': http: // stackoverflow.com/questions/13757261/using-or-dif. У меня сложилось впечатление, что это стандарт «де-факто». Когда дело доходит до различий между реализацией, вы, конечно, знаете больше, чем большинство. –

+0

Основные реализации Prolog, поддерживающие 'dif/2' в качестве встроенного предиката, включают B-Prolog, SWI-Prolog и YAP. ECLiPSe и SICStus Prolog поддерживают его как библиотечный предикат. Основные реализации Prolog (в настоящее время), не поддерживающие его, включают GNU Prolog и XSB.Другие менее популярные реализации Prolog также не поддерживают его. Таким образом, я бы не классифицировал его как стандартный предикат * de facto *. Надеюсь, это изменится. –

+1

Обратитесь к [prolog-dif] (http://stackoverflow.com/tags/prolog-dif/info) за список систем, поддерживающих 'dif/2' напрямую и косвенно. И, пожалуйста, добавьте дополнительные системы, если они станут известны. Любая система соответствия ISO может предоставить ['iso_dif/2'] (http://stackoverflow.com/a/20238931/772868), который является безопасным приближением, которое не имеет логических недостатков как' (\ =)/2' и '(\ ==)/2'. – false

Смежные вопросы