Родственные отношения на Prolog

Просмотр 1 ветки ответов
  • Автор
    Сообщения
    • #3266
      @olya1994

      Условие задачи:

      Используя предикаты parent(symbol,symbol), man(symbol), woman(symbol), married(symbol,symbol), записать факты, описывающие вашу семью. Записать 8 правил вывода для любых родственных отношений в вашей семье (например: мать, отец, сестра, брат, племянница, племянник, тетя, дядя, внучка, внук, бабушка, дедушка, двоюродная сестра, двоюродный брат и т.д.).

      Мой вариант решения:

      parent("Alexandr","Olya").
      parent("Masha","Olya").
      parent("Alexandr","Alina").
      parent("Masha","Alina").
      parent("Alexandr","Leha").
      parent("Masha","Leha").
      parent("Leha","Gleb").
      parent("Dasha","Gleb").
      parent("Alina","Maks").
      parent("Leha","Maks").
      
      man("Alexandr").
      man("Leha").
      man("Pavel").
      man("Dima").
      
      woman("Olya").
      woman("Alina").
      woman("Masha").
      
      married("Masha","Pavel").
      married("Alina","Dima").
      
      check_married(X, Y):-
        married(X, Y); married(Y, X).
      
      father(X,Y):-
        parent(X,Y),man(X).
      
      mother(X,Y):-
        parent(X,Y),woman(X).
      
      sister(X,Y):-
        parent(Z,X), parent(Z,Y), woman(X), X\=Y.
      
      brother(X,Y):-
        parent(Z,Y),parent(Z,X),man(X), X\=Y.
      
      son(X,Y):-
        parent(Y,X),man(X).
      
      daughter(X,Y):-
        parent(Y,X),woman(X).
      
      wife(X,Y):-
        check_married(X,Y), woman(X).
      
      husband(X,Y):-
        check_married(X,Y), man(X).
      
      brother_in_law(X, Y):-
        wife(Y, Wife),
        brother(X, Wife).
      
      mother_in_law(X,Y):-
        wife(Y, Wife),
        mother(X, Wife).
      
      uncle(X, Y):-
        parent(Parent, Y), 
        brother(X, Parent).
      
      ?-father(X,"Olya"),write(X),write(" ").
      ?-mother(X,"Alina"),write(X),write(" ").
      ?-married("Alina","Dima"),write(" ").
      ?-husband("Masha",Y),write(Y),write(" ").
      ?-wife(X,"Pavel"),write(X),write(" ").
      ?-sister("Olya","Alina"),write(" ").
      ?-brother_in_law(X,"Dima"),write(X),write(" ").
      ?-mother_in_law(X,"Dima"),write(X),write(" ").
      ?-uncle(X,"Maks"),write(X),write(" ").

      Пояснения к коду:

      Предикатом

      father(X,Y):-
        parent(X,Y),man(X).

      вы говорите, что X отец Y если он является родителем и при этом мужчиной. Очень похоже работает правило mother.

      Функция

      sister(X,Y):-
        parent(Z,X), parent(Z,Y), woman(X), X\=Y.

      значит, что X является сестрой для Y если у них есть общий родитель (Z), X является женщиной и X не равен Y (человек не является сестрой сам себе). Аналогично построено правило brother, но в нем X является мужчиной.

      Предикат

      son(X,Y):-
        parent(Y,X),man(X).

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

      Функции проверки жены и мужа используют не предикат married, а check_married, который проверяет что люди (X и Y) женаты если в базе если запись married(X, Y) или married(Y, X).

      wife(X,Y):-
        check_married(X,Y), woman(X).

      тут говорится, что X является женой Y если они женаты и X — женщина. Аналогично выполняется проверка мужа (но он мужчина).

      Шурин — это брат жены, поэтому для его проверки можно использовать предикаты wife и brother:

      brother_in_law(X, Y):-
        wife(Y, Wife),
        brother(X, Wife).

      Тут мы говорим, что X является шурином для Y если у Y есть жена (Wife), братом которой является X.

      Теща — это мать жены:

      mother_in_law(X,Y):-
        wife(Y, Wife),
        mother(X, Wife).

      Таким образом, X — теща для Y если у Y есть такая жена (Wife), что ее матерью является X.

      Если дядю понимать как брата отца или матери (в более общем случае — это муж тетки, т.е. он может быть не родным), то:

      uncle(X, Y):-
        parent(Parent, Y), brother(X, Parent).

      тут говорится, что X является дядей для Y если у Y есть такой родитель (Parent), что X является его братом.

      Дед — это отец одного из родителей.

      grandfather(X, Y):-
        parent(Parent, Y),
        father(X, Parent).
      
      grandmother(X, Y):-
        parent(Parent, Y),
        mother(X, Parent).
      

      X является дедом для Y если существует Parent, который является родителем для Y и при этом X является отцом Y. Аналогично с бабушкой.

    • #4167
      @admin

      Другие виды родственных отношений в Prolog рассмотрим на следующей базе данных:

      parent(иван, георгий).
      parent(иван, софья). 
      parent(иван, галина).
      parent(дарья, георгий).
      parent(дарья, софья). 
      parent(дарья, галина).
      parent(генадий, николай).
      parent(генадий, сергей). 
      parent(галина, николай).
      parent(галина, сергей).
      parent(ирина, елена). 
      parent(николай, елена).
      parent(татьяна, александр).
      parent(сергей, александр). 
      
      man(георгий).
      man(генадий).
      man(николай).
      man(сергей).
      man(александр).
      
      woman(софья).
      woman(галина).
      woman(дарья).
      woman(ирина).
      woman(елена).
      woman(татьяна).
      
      married(иван, дарья).
      married(генадий, галина).
      married(николай, ирина).
      married(татьяна, сергей).

      На рисунке показан граф родственных отношений, соответствующий базе данных:
      Граф родственных отношений

      Пусть, наша задача: «Найти племянницу сына зятя Дарьи».

      Зять — муж дочери или сестры:

      son_in_low(X, Y):-
        daughter(Z, Y),
        husband(X, Z);
        
        sister(Z, Y),
        husband(X, Z).

      X является зятем (муж дочери) для Y если у Y есть дочь Z такая, что X является мужем для Z.
      Аналогично описывается зять, являющийся мужем сестры.

      В нашем случае, зять Дарьи — это Генадий, проверим:

      ?- son_in_low(X, дарья).
      X = генадий ;

      Предикат поиска сына у нас уже определен, найдем сына зятя Дарьи:

      ?- son_in_low(X, дарья), son(Z, X).
      X = генадий,
      Z = николай ;
      X = генадий,
      Z = сергей ;
      false.
      

      Племянница — дочь брата или сестры:

      niece(X, Y):-
        brother(Z, Y),
        daughter(X, Z);
        
        sister(Z, Y),
        daughter(X, Z).

      Кстати, по образцу описывается племянник (сын брата или сестры):

      nephew(X, Y):-
        brother(Z, Y),
        son(X, Z);
        
        sister(Z, Y),
        son(X, Z).

      X является племянницей Y если Z является братом или сестрой Y, при этом, у Z есть дочь X.

      В нашем примере искомой племянницей сына зятя Дарьи является Елена:

      ?- son_in_low(X, дарья), son(Z, X), niece(Niece, Z).
      X = генадий,
      Z = сергей,
      Niece = елена ;

Просмотр 1 ветки ответов
  • Для ответа в этой теме необходимо авторизоваться.
×