|
|
% ===============================================
|
|
|
% Лабораторная работа 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. |