Предикат Пролог, где два элемента связаны, но не эквивалентны - PullRequest
1 голос
/ 09 февраля 2020

Я не программировал на Прологе уже несколько лет и борюсь с простым блоком тестового кода (я пытаюсь разгадать логическую c головоломку для удовольствия ...):

aboard(jack, blackbird).
aboard(jim, blackbird).
aboard(donna, blackbird).
aboard(david, north_star).
aboard(sandy, north_star).

shipmates(A, B) :- A \= B, aboard(A, X), aboard(B, X).

shipmates1(A, A) :- !, fail.
shipmates1(A, B) :- aboard(A, X), aboard(B, X).

Правила shipmates и shipmates1 - это две разные попытки выполнить sh следующее: я хочу соединить всех пассажиров, которые находятся на одном судне, но не эквивалентны друг другу.

Например, я хочу, чтобы shipmates(jack, jack). было false.

Когда я запрашиваю это с полностью квалифицированными аргументами, я получаю ожидаемые ответы:

3 ?- shipmates(jack, david).
false.

4 ?- shipmates(jack, jack).
false.

5 ?- shipmates(jack, jim).
true.

Однако, когда я хочу всех товарищей по кораблю Донны, это не работает:

6 ?- shipmates(donna, X).
false.

Я ожидал:

X = jack ;
X = jim ;

ПРИМЕЧАНИЕ: я получаю то же самое неверные результаты с shipmates1.

Поэтому, пожалуйста, пожалейте очень программиста-пролога-любителя (который не делает домашнюю работу для класса!) Что совершенно очевидно, что я делаю неправильно?

Версия: SWI-Prolog (с резьбой, 64 бита, версия 8.0.2)

1 Ответ

1 голос
/ 09 февраля 2020

Попробуйте:

shipmates(A, B) :-
    aboard(A, X),
    aboard(B, X),
    A \= B.

Вызывая предикат aboard/2 перед целью A \= B, вы гарантируете, что экземпляры A и B будут созданы, что делает сравнение значимым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...