Проверка потомков родословной в Прологе - PullRequest
0 голосов
/ 26 апреля 2020

Как я могу рекурсивно проверить, является ли X потомком Y, используя рекурсивный метод descendent_of? База фактов состоит из мужчин и женщин, а также высказываний папа-папа-мать.

/* Facts */
male(roy).
male(lee).
...
female(joy).
female(ana).
...

/* Rules */
grandmother_of(X, Z) :- 
        mother_of(X, Y), 
        (mother_of(Y, Z);
                father_of(Y, Z)).


grandfather_of(X, Z) :- 
        father_of(X, Y), 
        (mother_of(Y, Z);
                father_of(Y, Z)).


parent_of(X,Y) :-
    mother_of(X,Y);father_of(X,Y).


descendent_of(X,Y) :-
    */ Recursive method here */

Как настроить условие остановки? Кроме того, как рекурсия работает в прологе, если функции возвращают только логические значения?

Любые комментарии / предложения приветствуются.

Ответы [ 2 ]

0 голосов
/ 27 апреля 2020

Я расширил ваши факты, чтобы привести некоторые рабочие данные.

/* Facts */

male(roy).
male(lee).

female(joy).
female(ana).

parent_of(roy,joy).
parent_of(joy,ana).
parent_of(lee,ana).

Теперь мы можем построить некоторые правила. Давайте начнем с grand_parent_of/2.

grand_parent_of(X,Z) :-
    parent_of(X,Y),
    parent_of(Y,Z).

Это делает правила для grand_father_of/2 и grand_mother_of/2 довольно простыми.

grand_father_of(X,Y) :-
        male(X),
        grand_parent_of(X,Y).

grand_mother_of(X,Y) :-
        female(X),
        grand_parent_of(X,Y).

Теперь, каждый предикат до сих пор был предком слева и потомок справа, поэтому, чтобы сохранить последовательность, давайте сначала определим ancestor_of/2, а не descendent_of/2.

ancestor_of(X,Y) :-
    parent_of(X,Y).

ancestor_of(X,Y) :-
    parent_of(X,Z),
    ancestor_of(Z,Y).

Обратите внимание, что второй предикат является рекурсивным.

Теперь мы можем легко определить descendent_of/2 просто в терминах ancestor_of/2.

descendent_of(X,Y) :-
        ancestor_of(Y,X).

Вот результаты выполнения следующего запроса и запроса пролога, чтобы он продолжал давать мне результаты.

?- descendent_of(X,Y).
X = joy,
Y = roy ;
X = ana,
Y = joy ;
X = ana,
Y = lee ;
X = ana,
Y = roy ;
false.
0 голосов
/ 26 апреля 2020

Если вы посмотрите на descendant_of(X,Y), то будет верно, если X является потомком Y. Значение истинности затем повторно определяется следующим образом: здесь я делаю небольшую хитрость для достижения согласованности с parent_of и вводу предикат ancestor_of/2, поскольку

 descendent_of(X,Y) :- ancestor_of(Y,X)

Знай, X является предком Y если либо

  1. X является родителем Y, либо
  2. X является родителем Z, а Z является потомком Y

(1) является базовым случаем рекурсии, а (2) является рекурсивным определением. Подсказка: вы также можете переопределить рекурсивный регистр следующим образом: Z является потомком Y и X является родителем Z (ключевое слово tail-recursion)

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