You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

404 lines
13 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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