% =============================================== % Лабораторная работа 8 - Задание 3: SWI-Prolog % Семейное дерево - Расширенные семейные отношения % =============================================== % ----------------------------------------------- % 1. База данных пола всех членов семьи % ----------------------------------------------- % Мужчины man(ivan). man(petr). man(alex). man(sergey). man(dmitry). man(mikhail). man(nikolay). man(andrey). man(vladimir). % Женщины woman(anna). woman(elena). woman(maria). woman(olga). woman(svetlana). woman(natasha). woman(irina). woman(victoria). woman(katya). % ----------------------------------------------- % 2. База данных отношения "является родителем" % ----------------------------------------------- % parent(Родитель, Ребенок) % Старшее поколение (дедушки и бабушки) parent(ivan, petr). parent(ivan, elena). parent(anna, petr). parent(anna, elena). parent(sergey, maria). parent(sergey, alex). parent(olga, maria). parent(olga, alex). % Среднее поколение (родители) parent(petr, dmitry). parent(petr, svetlana). parent(elena, dmitry). parent(elena, svetlana). parent(alex, mikhail). parent(alex, irina). parent(maria, mikhail). parent(maria, irina). % Младшее поколение parent(dmitry, nikolay). parent(dmitry, victoria). parent(svetlana, nikolay). parent(svetlana, victoria). parent(mikhail, andrey). parent(mikhail, katya). parent(irina, andrey). parent(irina, katya). parent(nikolay, vladimir). parent(victoria, vladimir). % ----------------------------------------------- % 3. ОСНОВНЫЕ ПРЕДИКАТЫ (из предыдущих заданий) % ----------------------------------------------- % father(X, Y) - проверяет, является ли X отцом Y father(X, Y) :- parent(X, Y), man(X). % mother(X, Y) - проверяет, является ли X матерью Y mother(X, Y) :- parent(X, Y), woman(X). % wife(X, Y) - проверяет, является ли X женой Y wife(X, Y) :- parent(X, Child), parent(Y, Child), woman(X), man(Y), X \= Y. % husband(X, Y) - проверяет, является ли X мужем Y husband(X, Y) :- wife(Y, X). % brother(X, Y) - проверяет, является ли X братом Y brother(X, Y) :- parent(Z, X), parent(Z, Y), man(X), X \= Y. % sister(X, Y) - проверяет, является ли X сестрой Y sister(X, Y) :- parent(Z, X), parent(Z, Y), woman(X), X \= Y. % grandparent(X, Y) - проверяет, является ли X дедушкой/бабушкой Y grandparent(X, Y) :- parent(X, Z), parent(Z, Y). % ----------------------------------------------- % 4. НОВЫЕ ПРЕДИКАТЫ ДЛЯ ЗАДАНИЯ 3 % ----------------------------------------------- % =============================================== % 4.1. ВНУЧКА - ВЕРСИЯ 1 (только базовые факты) % =============================================== % grand_da_facts(X, Y) - X внучка Y (используя только факты parent и woman) grand_da_facts(X, Y) :- parent(Y, Z), % Y родитель Z parent(Z, X), % Z родитель X woman(X). % X женщина % =============================================== % 4.2. ВНУЧКА - ВЕРСИЯ 2 (используя готовые предикаты) % =============================================== % grand_da(X, Y) - X внучка Y (используя готовые предикаты) grand_da(X, Y) :- grandparent(Y, X), % Y дедушка/бабушка X woman(X). % X женщина % grand_dats(X) - выводит всех внучек X grand_dats(X) :- write('Внучки '), write(X), write(':'), nl, grand_da(Granddaughter, X), write('- '), write(Granddaughter), nl, fail. grand_dats(_) :- write('(перечисление завершено)'), nl. % =============================================== % 4.3. ДЕДУШКА И ВНУЧКА (двунаправленный предикат) % =============================================== % grand_pa_and_da(X, Y) - X дедушка и Y внучка ИЛИ Y дедушка и X внучка grand_pa_and_da(X, Y) :- grandfather(X, Y), % X дедушка Y woman(Y). % Y женщина (внучка) grand_pa_and_da(X, Y) :- grandfather(Y, X), % Y дедушка X woman(X). % X женщина (внучка) % grandfather(X, Y) - X дедушка Y grandfather(X, Y) :- grandparent(X, Y), man(X). % =============================================== % 4.4. ТЕТЯ - ВЕРСИЯ 1 (только базовые факты) % =============================================== % aunt_facts(X, Y) - X тетя Y (используя только факты) aunt_facts(X, Y) :- parent(Z, Y), % Z родитель Y parent(W, Z), % W родитель Z (дедушка/бабушка Y) parent(W, X), % W родитель X (X и Z братья/сестры) woman(X), % X женщина X \= Z. % X не тот же человек что Z % =============================================== % 4.5. ТЕТЯ - ВЕРСИЯ 2 (используя готовые предикаты) % =============================================== % aunt(X, Y) - X тетя Y (используя готовые предикаты) aunt(X, Y) :- parent(Parent, Y), % Parent родитель Y sister(X, Parent). % X сестра Parent % aunts(X) - выводит всех теть X aunts(X) :- write('Тети '), write(X), write(':'), nl, aunt(Aunt, X), write('- '), write(Aunt), nl, fail. aunts(_) :- write('(перечисление завершено)'), nl. % =============================================== % 4.6. ДОПОЛНИТЕЛЬНЫЕ ПОЛЕЗНЫЕ ПРЕДИКАТЫ % =============================================== % grandson(X, Y) - X внук Y grandson(X, Y) :- grandparent(Y, X), man(X). % grandsons(X) - выводит всех внуков X grandsons(X) :- write('Внуки '), write(X), write(':'), nl, grandson(Grandson, X), write('- '), write(Grandson), nl, fail. grandsons(_) :- write('(перечисление завершено)'), nl. % uncle(X, Y) - X дядя Y uncle(X, Y) :- parent(Parent, Y), brother(X, Parent). % uncles(X) - выводит всех дядей X uncles(X) :- write('Дяди '), write(X), write(':'), nl, uncle(Uncle, X), write('- '), write(Uncle), nl, fail. uncles(_) :- write('(перечисление завершено)'), nl. % nephew(X, Y) - X племянник Y nephew(X, Y) :- aunt(Y, X), man(X). nephew(X, Y) :- uncle(Y, X), man(X). % niece(X, Y) - X племянница Y niece(X, Y) :- aunt(Y, X), woman(X). niece(X, Y) :- uncle(Y, X), woman(X). % ----------------------------------------------- % 5. ПРЕДИКАТЫ ДЛЯ ВЫВОДА ИНФОРМАЦИИ % ----------------------------------------------- % grandparents - выводит всех дедушек и бабушек grandparents :- write('Все дедушки и бабушки:'), nl, grandparent(X, _), write('- '), write(X), nl, fail. grandparents. % all_grand_das - выводит всех внучек all_grand_das :- write('Все внучки:'), nl, grand_da(X, _), write('- '), write(X), nl, fail. all_grand_das. % all_aunts - выводит всех теть all_aunts :- write('Все тети:'), nl, aunt(X, _), write('- '), write(X), nl, fail. all_aunts. % ----------------------------------------------- % 6. ИНФОРМАЦИОННЫЕ ПРЕДИКАТЫ ДЛЯ TASK3 % ----------------------------------------------- % family_info_task3 - выводит информацию о семье для задания 3 family_info_task3 :- write('=== ИНФОРМАЦИЯ О СЕМЬЕ (ЗАДАНИЕ 3) ==='), nl, findall(X, grandparent(X, _), Grandparents), list_to_set(Grandparents, UniqueGrandparents), length(UniqueGrandparents, GrandparentsCount), write('Всего дедушек и бабушек: '), write(GrandparentsCount), nl, findall(Y, grand_da(Y, _), Granddaughters), list_to_set(Granddaughters, UniqueGranddaughters), length(UniqueGranddaughters, GranddaughtersCount), write('Всего внучек: '), write(GranddaughtersCount), nl, findall(Z, aunt(Z, _), Aunts), list_to_set(Aunts, UniqueAunts), length(UniqueAunts, AuntsCount), write('Всего теть: '), write(AuntsCount), nl, findall(W, uncle(W, _), Uncles), list_to_set(Uncles, UniqueUncles), length(UniqueUncles, UnclesCount), write('Всего дядей: '), write(UnclesCount), nl, nl. % show_extended_relationships - показывает расширенные отношения show_extended_relationships :- write('=== РАСШИРЕННЫЕ СЕМЕЙНЫЕ ОТНОШЕНИЯ ==='), nl, grandparents, nl, all_grand_das, nl, all_aunts, nl. % show_family_generations - показывает поколения с расширенной информацией show_family_generations :- write('=== ПОКОЛЕНИЯ СЕМЬИ (РАСШИРЕННАЯ ИНФОРМАЦИЯ) ==='), nl, write('СТАРШЕЕ ПОКОЛЕНИЕ (дедушки и бабушки):'), nl, forall( grandparent(GP, _), ( write(' '), (man(GP) -> write('Дедушка: '); write('Бабушка: ')), write(GP), write(' (внуки: '), findall(GC, grandson(GC, GP), Grandsons), write(Grandsons), write(', внучки: '), findall(GD, grand_da(GD, GP), Granddaughters), write(Granddaughters), write(')'), nl ) ), nl, write('СРЕДНЕЕ ПОКОЛЕНИЕ (тети и дяди):'), nl, forall( (aunt(A, _); uncle(U, _)), ( (aunt(Person, _) -> (write(' Тетя: '), write(Person)) ; (write(' Дядя: '), write(Person)) ), write(' (племянники/племянницы: '), findall(N, (nephew(N, Person); niece(N, Person)), Nephews_Nieces), write(Nephews_Nieces), write(')'), nl ) ), nl. % ----------------------------------------------- % 7. ДЕМОНСТРАЦИОННЫЕ ЗАПРОСЫ % ----------------------------------------------- % demo_relationships_task3 - демонстрация отношений задания 3 demo_relationships_task3 :- write('=== ДЕМОНСТРАЦИЯ ОТНОШЕНИЙ ЗАДАНИЯ 3 ==='), nl, nl, write('1. Внучки (grand_da):'), nl, write(' grand_da(svetlana, ivan) -> '), (grand_da(svetlana, ivan) -> write('true') ; write('false')), nl, write(' grand_da(victoria, anna) -> '), (grand_da(victoria, anna) -> write('true') ; write('false')), nl, nl, write('2. Дедушка и внучка (grand_pa_and_da):'), nl, write(' grand_pa_and_da(ivan, svetlana) -> '), (grand_pa_and_da(ivan, svetlana) -> write('true') ; write('false')), nl, write(' grand_pa_and_da(svetlana, ivan) -> '), (grand_pa_and_da(svetlana, ivan) -> write('true') ; write('false')), nl, nl, write('3. Тети (aunt):'), nl, write(' aunt(elena, mikhail) -> '), (aunt(elena, mikhail) -> write('true') ; write('false')), nl, write(' aunt(maria, dmitry) -> '), (aunt(maria, dmitry) -> write('true') ; write('false')), nl, nl. % ----------------------------------------------- % 8. СРАВНЕНИЕ РЕАЛИЗАЦИЙ % ----------------------------------------------- % compare_implementations - сравнивает реализации через факты и предикаты compare_implementations :- write('=== СРАВНЕНИЕ РЕАЛИЗАЦИЙ ==='), nl, write('Внучки через факты (grand_da_facts):'), nl, forall(grand_da_facts(X, ivan), (write(' '), write(X), nl)), nl, write('Внучки через предикаты (grand_da):'), nl, forall(grand_da(X, ivan), (write(' '), write(X), nl)), nl, write('Тети через факты (aunt_facts):'), nl, forall(aunt_facts(X, dmitry), (write(' '), write(X), nl)), nl, write('Тети через предикаты (aunt):'), nl, forall(aunt(X, dmitry), (write(' '), write(X), nl)), nl.