Альтернатива выражению "коммутативности" в прологе?
Будучи новичком в Прологе, я обнаружил, что коммутативное выражение в Прологе не совсем интуитивно понятно.
например, если я хочу выразить 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).