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