Необязательное связывание в прологе - PullRequest
0 голосов
/ 04 июня 2018

Давайте представим простую базу данных генеалогических фактов, где mother(M, C) и father(F, C) означают, что M / F является матерью / отцом ребенка C.

Я написалправило для поиска известных родителей ребенка (ноль, один или оба):

parents(C, M, F) :-
  (mother(M, C) -> true; true),
  (father(M, C) -> true; true).

, который связывает M и F, если они известны, и оставляет их несвязанными в противном случае.

Он работает нормально, что означает, что для ряда фактов:

mother(m1, c1).
father(f1, c1).
mother(m2, c2).

вызов parents(c1, M, F) возвращает:

M = m1,
F = f1.

, в то время как parents(c2, M, F) возвращает:

M = m2.

но использование стрелочных операторов мне кажется немного странным.Я что-то упустил?Можно ли избежать / упростить вызовы (X -> true ; true)?

Любая помощь приветствуется.

Приветствия,

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Пролог - это настоящий приземленный язык программирования.У него есть чистое подмножество. Оба имеют свое место.

once( (A ; true) ) - это ответ на вопрос «как мы можем упростить (A -> true; true)».

Если вы хотите большей чистоты, вы можете написать (A *-> true ; true ) с «мягким срезом» *->, который допускает все решения из успешной A и переключается только на неудачную ветвьв случае, если A не произвел любой .См. Также, например, мой ответ для дальнейшего обсуждения.

Другой вариант - (A ; \+ A).

0 голосов
/ 04 июня 2018

С логической точки зрения, главная ошибка в этой программе заключается в неполноте .

Рассмотрим, например, самый общий запрос :

?- parents(X, Y, C).
X = c1,
Y = m1.

Итак, не сообщается о решении для c2.

Но такое решение существует, что можно увидеть с помощью:

?- parents(<b>c2</b>, Y, C).
Y = m2.

Итак, что это , есть решение или нет?

Такие ошибки почти неизменно возникают, если вы используете (->)/2 и другие конструкции, которые нарушают логическая чистота вашего кода.Пожалуйста, смотрите для получения дополнительной информации.

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

Вместо этого сосредоточьтесь на четком описании отношений, которые вы хотите описать,и укажите условия, которые делают их правдой.Это позволит вам разумно использовать ваши программы Prolog.

EDIT : я вижу, вы предпочитаете неработающую программу.Для этой цели я рекомендую ignore/1.ignore(Goal) вызывает Goal как once(Goal), а успешно .Вы можете использовать это, чтобы упростить вашу программу и при этом убедиться, что она остается неполной.

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