% =============================================== % Лабораторная работа 8: 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. Предикаты для вывода всех мужчин и женщин % ----------------------------------------------- % Предикат men - выводит всех мужчин men :- write('Все мужчины в семье:'), nl, man(X), write('- '), write(X), nl, fail. men. % Предикат women - выводит всех женщин women :- write('Все женщины в семье:'), nl, woman(X), write('- '), write(X), nl, fail. women. % ----------------------------------------------- % 3. База данных отношения "является родителем" % ----------------------------------------------- % 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). % ----------------------------------------------- % 4. Предикат children(X) - выводит всех детей X % ----------------------------------------------- children(X) :- write('Дети '), write(X), write(':'), nl, parent(X, Child), write('- '), write(Child), nl, fail. children(_) :- write('(перечисление завершено)'), nl. % ----------------------------------------------- % 5. Предикаты mother(X, Y) и mother(X) % ----------------------------------------------- % mother(X, Y) - проверяет, является ли X матерью Y mother(X, Y) :- parent(X, Y), woman(X). % mother(X) - выводит маму X mother(X) :- write('Мать '), write(X), write(': '), mother(M, X), write(M), nl. % ----------------------------------------------- % 6. Предикаты brother(X, Y) и brothers(X) % ----------------------------------------------- % brother(X, Y) - проверяет, является ли X братом Y brother(X, Y) :- parent(Z, X), parent(Z, Y), man(X), X \= Y. % brothers(X) - выводит всех братьев X brothers(X) :- write('Братья '), write(X), write(':'), nl, brother(Brother, X), write('- '), write(Brother), nl, fail. brothers(_) :- write('(перечисление завершено)'), nl. % ----------------------------------------------- % 7. Предикаты b_s(X, Y) и b_s(X) для братьев и сестер % ----------------------------------------------- % b_s(X, Y) - проверяет, являются ли X и Y братьями/сестрами b_s(X, Y) :- parent(Z, X), parent(Z, Y), X \= Y. % b_s(X) - выводит всех братьев и сестер X b_s(X) :- write('Братья и сестры '), write(X), write(':'), nl, b_s(Sibling, X), write('- '), write(Sibling), nl, fail. b_s(_) :- write('(перечисление завершено)'), nl. % ----------------------------------------------- % 8. Дополнительные полезные предикаты % ----------------------------------------------- % father(X, Y) - проверяет, является ли X отцом Y father(X, Y) :- parent(X, Y), man(X). % 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). % ancestor(X, Y) - проверяет, является ли X предком Y ancestor(X, Y) :- parent(X, Y). ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y). % ----------------------------------------------- % 9. Предикаты для отображения информации о семье % ----------------------------------------------- % family_info - выводит общую информацию о семье family_info :- write('=== ИНФОРМАЦИЯ О СЕМЬЕ ==='), nl, findall(X, man(X), Men), length(Men, MenCount), write('Всего мужчин: '), write(MenCount), nl, findall(Y, woman(Y), Women), length(Women, WomenCount), write('Всего женщин: '), write(WomenCount), nl, findall(Z, parent(Z, _), Parents), list_to_set(Parents, UniqueParents), length(UniqueParents, ParentsCount), write('Всего родителей: '), write(ParentsCount), nl, nl. % show_family - показывает структуру семьи по поколениям show_family :- write('=== СТРУКТУРА СЕМЬИ ==='), nl, write('СТАРШЕЕ ПОКОЛЕНИЕ:'), nl, forall( (man(X), \+ parent(_, X)), (write(' Дед: '), write(X), nl) ), forall( (woman(X), \+ parent(_, X)), (write(' Бабушка: '), write(X), nl) ), nl, write('СРЕДНЕЕ ПОКОЛЕНИЕ:'), nl, forall( (parent(X, _), parent(_, X)), (write(' '), (man(X) -> write('Отец: '); write('Мать: ')), write(X), nl) ), nl, write('МЛАДШЕЕ ПОКОЛЕНИЕ:'), nl, forall( (\+ parent(X, _), parent(_, X)), (write(' '), (man(X) -> write('Сын: '); write('Дочь: ')), write(X), nl) ), nl. % ----------------------------------------------- % 10. Примеры запросов для тестирования % ----------------------------------------------- % demo_queries - демонстрационные запросы demo_queries :- write('=== ДЕМОНСТРАЦИОННЫЕ ЗАПРОСЫ ==='), nl, nl, write('1. Проверка пола:'), nl, write('?- man(ivan).'), nl, (man(ivan) -> write('true') ; write('false')), nl, write('?- woman(anna).'), nl, (woman(anna) -> write('true') ; write('false')), nl, nl, write('2. Поиск детей:'), nl, write('?- children(ivan).'), nl, children(ivan), nl, write('3. Поиск матери:'), nl, write('?- mother(petr).'), nl, mother(petr), nl, write('4. Поиск братьев:'), nl, write('?- brothers(dmitry).'), nl, brothers(dmitry), nl, write('5. Поиск братьев и сестер:'), nl, write('?- b_s(elena).'), nl, b_s(elena), nl.