Альтернатива выражению "коммутативности" в прологе?

Будучи новичком в Прологе, я обнаружил, что коммутативное выражение в Прологе не совсем интуитивно понятно.

например, если я хочу выразить X и Y в одной семье, например:

family(X,Y) :-
      married(X,Y);
      relative(X,Y);
      father_son(X,Y).

Я должен также добавить следующее к определению, чтобы сделать его "коммутативным":

      married(Y,X);
      relative(Y,X);
      father_son(Y,X).

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

      family(Y,X).

Вот ТОЧКА. это ведет к бесконечности! почему пролог не такой "логичный"? и есть ли альтернатива этому аккуратному однострочному выражению, которое не ведет к неопределенности?

Хорошие выходные! ватт

2 ответа

Решение

Проблема с family(X,Y) :- family(Y,X). Частью правила является то, что оно продолжает безоговорочно объединяться с самим собой на каждом уровне и продолжает возвращаться вниз; нет выхода из этой рекурсии.

Вы должны сделать аргумент подкачки на уровне выше:

family(X,Y) :-
    is_family(X,Y);
    is_family(Y,X).

is_family(X,Y) :-
    married(X,Y);
    relative(X,Y);
    father_son(X,Y).

В качестве альтернативы вы можете сделать базовые правила ниже симметричных, если это имеет смысл:

is_married(X,Y) :-
    married(X,Y);
    married(Y,X).

is_relative(X,Y) :-
    relative(X,Y);
    relative(Y,X).

Теперь вы можете переписать свой family Правило следующим образом:

family(X,Y) :-
    is_married(X,Y);
    is_relative(X,Y);
    father_son(X,Y);
    father_son(Y,X).

Как насчет:

relatives(X,Y) :-
  married(X,Y);
  relative(X,Y);
  father_son(X,Y).

family(X,Y) :-
  relatives(X,Y);
  relatives(Y,X).
Другие вопросы по тегам