diff --git a/lab8/Makefile b/lab8/Makefile index a2de9b6..d1ef14a 100644 --- a/lab8/Makefile +++ b/lab8/Makefile @@ -1,4 +1,4 @@ -.PHONY: run build clean task1 build-task1 clean-task1 interactive-task1 test-task1 demo-task1 trace-task1 +.PHONY: run build clean task1 build-task1 clean-task1 interactive-task1 test-task1 demo-task1 trace-task1 info-task1 task2 build-task2 clean-task2 interactive-task2 test-task2 demo-task2 trace-task2 info-task2 # task1 (default) run: @@ -34,17 +34,58 @@ demo-task1: trace-task1: cd task1 && make trace +info-task1: + cd task1 && make info + +# task2 +task2: + cd task2 && make run + +build-task2: + cd task2 && make build + +clean-task2: + cd task2 && make clean + +interactive-task2: + cd task2 && make interactive + +test-task2: + cd task2 && make test + +demo-task2: + cd task2 && make demo + +trace-task2: + cd task2 && make trace + +info-task2: + cd task2 && make info + # Help help: @echo "Available commands for lab8:" - @echo " make task1 - Run task1 (family tree)" - @echo " make build-task1 - Build task1 Docker image" - @echo " make test-task1 - Run task1 tests" + @echo "" + @echo "Task 1 (Family tree basics):" + @echo " make task1 - Run task1 (basic info)" + @echo " make info-task1 - Show detailed task1 info" @echo " make demo-task1 - Run task1 demonstration" + @echo " make test-task1 - Run task1 tests" @echo " make interactive-task1 - Start task1 interactive session" @echo " make trace-task1 - Run task1 with tracing" + @echo " make build-task1 - Build task1 Docker image" @echo " make clean-task1 - Clean task1 Docker images" @echo "" + @echo "Task 2 (Father and wife relationships):" + @echo " make task2 - Run task2 (basic info)" + @echo " make info-task2 - Show detailed task2 info" + @echo " make demo-task2 - Run task2 demonstration" + @echo " make test-task2 - Run task2 tests" + @echo " make interactive-task2 - Start task2 interactive session" + @echo " make trace-task2 - Run task2 with tracing" + @echo " make build-task2 - Build task2 Docker image" + @echo " make clean-task2 - Clean task2 Docker images" + @echo "" @echo "Default commands (task1):" @echo " make run - Run task1" @echo " make build - Build task1" diff --git a/lab8/task1/Makefile b/lab8/task1/Makefile index f7fa7b5..e6c89de 100644 --- a/lab8/task1/Makefile +++ b/lab8/task1/Makefile @@ -4,9 +4,9 @@ build: docker build -t lab8-task1-prolog . -# Run Prolog with family database +# Run Prolog with family database (show basic info and exit) run: build - docker run -it --rm -v $(PWD):/app lab8-task1-prolog swipl -g "consult('family.pl')" -t "halt" + docker run --rm -v $(PWD):/app lab8-task1-prolog swipl -g "consult('family.pl'), family_info, halt" # Interactive Prolog session interactive: build @@ -18,7 +18,11 @@ test: build # Run with tracing enabled trace: build - docker run -it --rm -v $(PWD):/app lab8-task1-prolog swipl -g "consult('family.pl'), trace, men, notrace, halt" + docker run --rm -v $(PWD):/app lab8-task1-prolog swipl -g "consult('family.pl'), trace, men, notrace, halt" + +# Show basic info about task1 +info: build + docker run --rm -v $(PWD):/app lab8-task1-prolog swipl -g "consult('family.pl'), write('=== TASK1 INFO ==='), nl, family_info, show_family, halt" # Run demo demo: build @@ -32,9 +36,10 @@ clean: help: @echo "Available commands for lab8 task1:" @echo " make build - Build Docker image" - @echo " make run - Run Prolog with family database" - @echo " make interactive - Start interactive Prolog session" - @echo " make test - Run test queries" + @echo " make run - Run and show basic family info" + @echo " make info - Show detailed task1 information" @echo " make demo - Run demonstration queries" + @echo " make test - Run test queries" + @echo " make interactive - Start interactive Prolog session" @echo " make trace - Run with tracing enabled" @echo " make clean - Clean Docker images" \ No newline at end of file diff --git a/lab8/task2/Dockerfile b/lab8/task2/Dockerfile new file mode 100644 index 0000000..7553ec6 --- /dev/null +++ b/lab8/task2/Dockerfile @@ -0,0 +1,7 @@ +FROM swipl:stable + +WORKDIR /app + +COPY *.pl ./ + +CMD ["swipl", "-g", "consult('family.pl')", "-t", "halt"] \ No newline at end of file diff --git a/lab8/task2/Makefile b/lab8/task2/Makefile new file mode 100644 index 0000000..ac50eff --- /dev/null +++ b/lab8/task2/Makefile @@ -0,0 +1,45 @@ +.PHONY: build run interactive clean test trace demo + +# Build Docker image +build: + docker build -t lab8-task2-prolog . + +# Run Prolog with family database (show basic info and exit) +run: build + docker run --rm -v $(PWD):/app lab8-task2-prolog swipl -g "consult('family.pl'), family_info_task2, halt" + +# Interactive Prolog session +interactive: build + docker run -it --rm -v $(PWD):/app lab8-task2-prolog swipl family.pl + +# Run test queries +test: build + docker run --rm -v $(PWD):/app lab8-task2-prolog swipl -g "consult('family.pl'), consult('tests.pl'), run_tests, halt" + +# Run with tracing enabled +trace: build + docker run --rm -v $(PWD):/app lab8-task2-prolog swipl -g "consult('family.pl'), trace, fathers, notrace, halt" + +# Show basic info about task2 +info: build + docker run --rm -v $(PWD):/app lab8-task2-prolog swipl -g "consult('family.pl'), write('=== TASK2 INFO ==='), nl, family_info_task2, show_relationships, halt" + +# Run demo +demo: build + docker run --rm -v $(PWD):/app lab8-task2-prolog swipl -g "consult('family.pl'), consult('demo.pl'), demo, halt" + +# Clean Docker images +clean: + docker rmi lab8-task2-prolog || true + +# Help +help: + @echo "Available commands for lab8 task2:" + @echo " make build - Build Docker image" + @echo " make run - Run and show basic family info" + @echo " make info - Show detailed task2 information" + @echo " make demo - Run demonstration queries" + @echo " make test - Run test queries" + @echo " make interactive - Start interactive Prolog session" + @echo " make trace - Run with tracing enabled" + @echo " make clean - Clean Docker images" \ No newline at end of file diff --git a/lab8/task2/demo.pl b/lab8/task2/demo.pl new file mode 100644 index 0000000..a7f91c5 --- /dev/null +++ b/lab8/task2/demo.pl @@ -0,0 +1,209 @@ +% =============================================== +% Демонстрационные запросы для lab8 task2 +% Отцовские и семейные отношения +% =============================================== + +% Запуск демонстрации +demo :- + write('=== ДЕМОНСТРАЦИЯ ЗАДАНИЯ 2: ОТЦОВСКИЕ И СЕМЕЙНЫЕ ОТНОШЕНИЯ ==='), nl, nl, + + % 1. Демонстрация отцовских отношений + write('1. ОТЦОВСКИЕ ОТНОШЕНИЯ'), nl, + write('========================'), nl, + demo_fathers, + nl, + + % 2. Демонстрация семейных отношений (жена) + write('2. СЕМЕЙНЫЕ ОТНОШЕНИЯ (ЖЕНА)'), nl, + write('============================'), nl, + demo_wives, + nl, + + % 3. Демонстрация дополнительных отношений + write('3. ДОПОЛНИТЕЛЬНЫЕ СЕМЕЙНЫЕ ОТНОШЕНИЯ'), nl, + write('===================================='), nl, + demo_additional, + nl, + + % 4. Общая информация о семье + write('4. ИНФОРМАЦИЯ О СЕМЬЕ'), nl, + write('====================='), nl, + demo_family_info, + nl, + + write('=== ДЕМОНСТРАЦИЯ ЗАДАНИЯ 2 ЗАВЕРШЕНА ==='), nl. + +% Вспомогательные предикаты для демонстрации + +demo_fathers :- + write('Проверка отцовства:'), nl, + write('?- father(ivan, petr). -> '), + (father(ivan, petr) -> write('true') ; write('false')), nl, + write('?- father(anna, petr). -> '), + (father(anna, petr) -> write('true') ; write('false')), nl, + write('?- father(petr, dmitry). -> '), + (father(petr, dmitry) -> write('true') ; write('false')), nl, + write('?- father(alex, mikhail). -> '), + (father(alex, mikhail) -> write('true') ; write('false')), nl, + nl, + + write('Поиск отца конкретного человека:'), nl, + write('father(petr):'), nl, + father(petr), + write('father(dmitry):'), nl, + father(dmitry), + write('father(mikhail):'), nl, + father(mikhail), + nl, + + write('Список всех отцов:'), nl, + fathers. + +demo_wives :- + write('Проверка супружеских отношений:'), nl, + write('?- wife(anna, ivan). -> '), + (wife(anna, ivan) -> write('true') ; write('false')), nl, + write('?- wife(elena, petr). -> '), + (wife(elena, petr) -> write('true') ; write('false')), nl, + write('?- wife(maria, alex). -> '), + (wife(maria, alex) -> write('true') ; write('false')), nl, + write('?- wife(ivan, anna). -> '), + (wife(ivan, anna) -> write('true') ; write('false')), nl, + nl, + + write('Поиск жены конкретного человека:'), nl, + write('wife(ivan):'), nl, + wife(ivan), + write('wife(petr):'), nl, + wife(petr), + write('wife(alex):'), nl, + wife(alex), + nl, + + write('Список всех жен:'), nl, + wives. + +demo_additional :- + write('Проверка мужских отношений:'), nl, + write('?- husband(ivan, anna). -> '), + (husband(ivan, anna) -> write('true') ; write('false')), nl, + write('?- husband(petr, elena). -> '), + (husband(petr, elena) -> write('true') ; write('false')), nl, + nl, + + write('Поиск мужа:'), nl, + write('husband(anna):'), nl, + husband(anna), + write('husband(elena):'), nl, + husband(elena), + nl, + + write('Проверка брачных отношений:'), nl, + write('?- married(anna, ivan). -> '), + (married(anna, ivan) -> write('true') ; write('false')), nl, + write('?- married(ivan, anna). -> '), + (married(ivan, anna) -> write('true') ; write('false')), nl, + nl, + + write('Все семейные пары:'), nl, + couples. + +demo_family_info :- + family_info_task2, + + write('Подробная информация о семьях:'), nl, + write('------------------------------'), nl, + + % Показать детей каждой пары + forall( + couple(Wife, Husband), + ( + write('Семья '), write(Wife), write(' и '), write(Husband), write(':'), nl, + findall(Child, (parent(Wife, Child), parent(Husband, Child)), Children), + (Children = [] -> + write(' (детей нет)'), nl + ; + (write(' Дети: '), write_list(Children), nl) + ), + nl + ) + ). + +% Вспомогательный предикат для красивого вывода списка +write_list([]). +write_list([H|T]) :- + write(H), + (T = [] -> true ; (write(', '), write_list(T))). + +% ----------------------------------------------- +% Специальные демонстрационные запросы +% ----------------------------------------------- + +% Показать генеалогическое дерево семьи +show_family_tree :- + write('=== ГЕНЕАЛОГИЧЕСКОЕ ДЕРЕВО ==='), nl, + + % Старшее поколение + write('СТАРШЕЕ ПОКОЛЕНИЕ:'), nl, + forall( + (man(X), \+ parent(_, X)), + (write(' Дедушка: '), write(X), + (wife(W, X) -> (write(' (жена: '), write(W), write(')')) ; true), + nl) + ), + forall( + (woman(X), \+ parent(_, X), \+ wife(X, _)), + (write(' Бабушка: '), write(X), nl) + ), + nl, + + % Среднее поколение + write('СРЕДНЕЕ ПОКОЛЕНИЕ:'), nl, + forall( + couple(Wife, Husband), + (write(' Семья: '), write(Wife), write(' и '), write(Husband), nl) + ), + nl, + + % Младшее поколение + write('МЛАДШЕЕ ПОКОЛЕНИЕ:'), nl, + forall( + (\+ parent(X, _), parent(_, X)), + ( + (man(X) -> write(' Сын: '); write(' Дочь: ')), + write(X), + write(' (родители: '), + father(F, X), write(F), write(' и '), + mother(M, X), write(M), write(')'), + nl + ) + ), + nl. + +% Интерактивные примеры +example_queries :- + write('=== ПРИМЕРЫ ИНТЕРАКТИВНЫХ ЗАПРОСОВ ЗАДАНИЯ 2 ==='), nl, + write('Вы можете выполнить следующие запросы в интерактивной сессии:'), nl, nl, + + write('1. Отцовские отношения:'), nl, + write(' ?- father(ivan, petr). % Проверить, отец ли иван петра'), nl, + write(' ?- father(X, dmitry). % Найти отца дмитрия'), nl, + write(' ?- father(petr). % Показать отца петра'), nl, + write(' ?- fathers. % Показать всех отцов'), nl, nl, + + write('2. Семейные отношения (жена):'), nl, + write(' ?- wife(anna, ivan). % Проверить, жена ли анна ивана'), nl, + write(' ?- wife(X, petr). % Найти жену петра'), nl, + write(' ?- wife(ivan). % Показать жену ивана'), nl, + write(' ?- wives. % Показать всех жен'), nl, nl, + + write('3. Дополнительные отношения:'), nl, + write(' ?- husband(ivan, anna). % Проверить, муж ли иван анны'), nl, + write(' ?- married(anna, ivan). % Проверить, женаты ли анна и иван'), nl, + write(' ?- couple(X, Y). % Найти все пары'), nl, + write(' ?- couples. % Показать все пары'), nl, nl, + + write('4. Информационные запросы:'), nl, + write(' ?- family_info_task2. % Общая информация о семье'), nl, + write(' ?- show_family_tree. % Показать генеалогическое дерево'), nl, + write(' ?- show_relationships. % Показать все отношения'), nl, nl. \ No newline at end of file diff --git a/lab8/task2/family.pl b/lab8/task2/family.pl new file mode 100644 index 0000000..74604f5 --- /dev/null +++ b/lab8/task2/family.pl @@ -0,0 +1,233 @@ +% =============================================== +% Лабораторная работа 8 - Задание 2: SWI-Prolog +% Семейное дерево - Отцовские и семейные отношения +% =============================================== + +% ----------------------------------------------- +% 1. База данных пола всех членов семьи (из task1) +% ----------------------------------------------- + +% Мужчины +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. База данных отношения "является родителем" (из task1) +% ----------------------------------------------- + +% 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. НОВЫЕ ПРЕДИКАТЫ ДЛЯ ЗАДАНИЯ 2 +% ----------------------------------------------- + +% father(X, Y) - проверяет, является ли X отцом Y +father(X, Y) :- + parent(X, Y), + man(X). + +% father(X) - выводит отца X +father(X) :- + write('Отец '), write(X), write(': '), + father(F, X), + write(F), nl. + +% ----------------------------------------------- +% 4. ПРЕДИКАТЫ ДЛЯ СЕМЕЙНЫХ ОТНОШЕНИЙ (ЖЕНА) +% ----------------------------------------------- + +% wife(X, Y) - проверяет, является ли X женой Y +% Логика: X жена Y, если у них есть общий ребенок и X - женщина, Y - мужчина +wife(X, Y) :- + parent(X, Child), + parent(Y, Child), + woman(X), + man(Y), + X \= Y. + +% wife(X) - выводит жену X +wife(X) :- + write('Жена '), write(X), write(': '), + wife(W, X), + write(W), nl. + +% ----------------------------------------------- +% 5. ДОПОЛНИТЕЛЬНЫЕ ПОЛЕЗНЫЕ ПРЕДИКАТЫ +% ----------------------------------------------- + +% husband(X, Y) - проверяет, является ли X мужем Y +husband(X, Y) :- + wife(Y, X). + +% husband(X) - выводит мужа X +husband(X) :- + write('Муж '), write(X), write(': '), + husband(H, X), + write(H), nl. + +% married(X, Y) - проверяет, женаты ли X и Y +married(X, Y) :- + wife(X, Y). +married(X, Y) :- + wife(Y, X). + +% couple(X, Y) - выводит пары (муж и жена) +couple(X, Y) :- + wife(X, Y). + +% ----------------------------------------------- +% 6. ПРЕДИКАТЫ ИЗ TASK1 (для совместимости) +% ----------------------------------------------- + +% 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. + +% 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. + +% b_s(X, Y) - проверяет, являются ли X и Y братьями/сестрами +b_s(X, Y) :- + parent(Z, X), + parent(Z, Y), + X \= Y. + +% ----------------------------------------------- +% 7. ПРЕДИКАТЫ ДЛЯ ВЫВОДА ИНФОРМАЦИИ +% ----------------------------------------------- + +% fathers - выводит всех отцов +fathers :- + write('Все отцы в семье:'), nl, + father(X, _), + write('- '), write(X), nl, + fail. +fathers. + +% wives - выводит всех жен +wives :- + write('Все жены в семье:'), nl, + wife(X, _), + write('- '), write(X), nl, + fail. +wives. + +% couples - выводит все пары +couples :- + write('Все семейные пары:'), nl, + couple(Wife, Husband), + write('- '), write(Wife), write(' и '), write(Husband), nl, + fail. +couples. + +% children(X) - выводит всех детей X +children(X) :- + write('Дети '), write(X), write(':'), nl, + parent(X, Child), + write('- '), write(Child), nl, + fail. +children(_) :- + write('(перечисление завершено)'), nl. + +% ----------------------------------------------- +% 8. ПРЕДИКАТЫ ДЛЯ ОТОБРАЖЕНИЯ СЕМЕЙНОЙ ИНФОРМАЦИИ +% ----------------------------------------------- + +% family_info_task2 - выводит информацию о семье для задания 2 +family_info_task2 :- + write('=== ИНФОРМАЦИЯ О СЕМЬЕ (ЗАДАНИЕ 2) ==='), nl, + findall(X, father(X, _), Fathers), + list_to_set(Fathers, UniqueFathers), + length(UniqueFathers, FathersCount), + write('Всего отцов: '), write(FathersCount), nl, + + findall(Y, wife(Y, _), Wives), + list_to_set(Wives, UniqueWives), + length(UniqueWives, WivesCount), + write('Всего жен: '), write(WivesCount), nl, + + findall(couple(W, H), couple(W, H), Couples), + length(Couples, CouplesCount), + write('Всего семейных пар: '), write(CouplesCount), nl, + nl. + +% show_relationships - показывает все отношения +show_relationships :- + write('=== СЕМЕЙНЫЕ ОТНОШЕНИЯ ==='), nl, + couples, + nl, + fathers, + nl, + wives, + nl. \ No newline at end of file diff --git a/lab8/task2/tests.pl b/lab8/task2/tests.pl new file mode 100644 index 0000000..3183289 --- /dev/null +++ b/lab8/task2/tests.pl @@ -0,0 +1,198 @@ +% =============================================== +% Тестовые запросы для лабораторной работы 8 - Задание 2 +% Отцовские и семейные отношения +% =============================================== + +% Главный предикат для запуска всех тестов +run_tests :- + write('=== ЗАПУСК ТЕСТОВ ЗАДАНИЯ 2 ==='), nl, nl, + + test_father_queries, + test_wife_queries, + test_additional_relationships, + test_family_info, + + write('=== ВСЕ ТЕСТЫ ЗАДАНИЯ 2 ЗАВЕРШЕНЫ ==='), nl. + +% ----------------------------------------------- +% Тесты отцовских отношений +% ----------------------------------------------- +test_father_queries :- + write('1. ТЕСТИРОВАНИЕ ОТЦОВСКИХ ОТНОШЕНИЙ'), nl, + write('-----------------------------------'), nl, + + write('Тест: father(ivan, petr) -> '), + (father(ivan, petr) -> write('PASSED') ; write('FAILED')), nl, + + write('Тест: father(anna, petr) -> '), + (\+ father(anna, petr) -> write('PASSED (false)') ; write('FAILED')), nl, + + write('Тест: father(petr, dmitry) -> '), + (father(petr, dmitry) -> write('PASSED') ; write('FAILED')), nl, + + write('Тест: father(alex, mikhail) -> '), + (father(alex, mikhail) -> write('PASSED') ; write('FAILED')), nl, + + nl, + write('Поиск отца:'), nl, + write('father(petr):'), nl, + father(petr), + nl, + + write('father(dmitry):'), nl, + father(dmitry), + nl, + + write('Все отцы:'), nl, + fathers, + nl. + +% ----------------------------------------------- +% Тесты семейных отношений (жена) +% ----------------------------------------------- +test_wife_queries :- + write('2. ТЕСТИРОВАНИЕ СЕМЕЙНЫХ ОТНОШЕНИЙ (ЖЕНА)'), nl, + write('------------------------------------------'), nl, + + write('Тест: wife(anna, ivan) -> '), + (wife(anna, ivan) -> write('PASSED') ; write('FAILED')), nl, + + write('Тест: wife(elena, petr) -> '), + (wife(elena, petr) -> write('PASSED') ; write('FAILED')), nl, + + write('Тест: wife(maria, alex) -> '), + (wife(maria, alex) -> write('PASSED') ; write('FAILED')), nl, + + write('Тест: wife(ivan, anna) -> '), + (\+ wife(ivan, anna) -> write('PASSED (false)') ; write('FAILED')), nl, + + nl, + write('Поиск жены:'), nl, + write('wife(ivan):'), nl, + wife(ivan), + nl, + + write('wife(petr):'), nl, + wife(petr), + nl, + + write('wife(alex):'), nl, + wife(alex), + nl, + + write('Все жены:'), nl, + wives, + nl. + +% ----------------------------------------------- +% Тесты дополнительных отношений +% ----------------------------------------------- +test_additional_relationships :- + write('3. ТЕСТИРОВАНИЕ ДОПОЛНИТЕЛЬНЫХ ОТНОШЕНИЙ'), nl, + write('----------------------------------------'), nl, + + write('Тест: husband(ivan, anna) -> '), + (husband(ivan, anna) -> write('PASSED') ; write('FAILED')), nl, + + write('Тест: married(anna, ivan) -> '), + (married(anna, ivan) -> write('PASSED') ; write('FAILED')), nl, + + write('Тест: married(ivan, anna) -> '), + (married(ivan, anna) -> write('PASSED') ; write('FAILED')), nl, + + write('Тест: couple(anna, ivan) -> '), + (couple(anna, ivan) -> write('PASSED') ; write('FAILED')), nl, + + nl, + write('Поиск мужа:'), nl, + write('husband(anna):'), nl, + husband(anna), + nl, + + write('husband(elena):'), nl, + husband(elena), + nl, + + write('Все пары:'), nl, + couples, + nl. + +% ----------------------------------------------- +% Тесты информации о семье +% ----------------------------------------------- +test_family_info :- + write('4. ТЕСТИРОВАНИЕ СЕМЕЙНОЙ ИНФОРМАЦИИ'), nl, + write('-----------------------------------'), nl, + + family_info_task2, + show_relationships. + +% ----------------------------------------------- +% Комплексные тесты +% ----------------------------------------------- +test_complex_relationships :- + write('5. КОМПЛЕКСНЫЕ ТЕСТЫ ОТНОШЕНИЙ'), nl, + write('-------------------------------'), nl, + + % Проверка, что у каждого ребенка есть и отец, и мать + write('Проверка полных семей:'), nl, + forall( + parent(_, Child), + ( + (father(F, Child), mother(M, Child)) -> + (write(' '), write(Child), write(': отец '), write(F), + write(', мать '), write(M), nl) + ; + (write(' '), write(Child), write(': неполная семья'), nl) + ) + ), + nl, + + % Проверка пар + write('Проверка семейных пар:'), nl, + forall( + couple(Wife, Husband), + (write(' Пара: '), write(Wife), write(' и '), write(Husband), + write(' - дети: '), + findall(Child, (parent(Wife, Child), parent(Husband, Child)), Children), + write(Children), nl) + ), + nl. + +% ----------------------------------------------- +% Демонстрационные запросы +% ----------------------------------------------- +demo_queries :- + write('=== ДЕМОНСТРАЦИОННЫЕ ЗАПРОСЫ ЗАДАНИЯ 2 ==='), nl, nl, + + write('1. Отцовские отношения:'), nl, + write(' ?- father(ivan, petr).'), nl, + (father(ivan, petr) -> write(' true') ; write(' false')), nl, + write(' ?- father(petr).'), nl, + write(' '), father(petr), + nl, + + write('2. Семейные отношения (жена):'), nl, + write(' ?- wife(anna, ivan).'), nl, + (wife(anna, ivan) -> write(' true') ; write(' false')), nl, + write(' ?- wife(ivan).'), nl, + write(' '), wife(ivan), + nl, + + write('3. Поиск всех отцов:'), nl, + write(' ?- fathers.'), nl, + fathers, + nl, + + write('4. Поиск всех семейных пар:'), nl, + write(' ?- couples.'), nl, + couples, + nl. + +% ----------------------------------------------- +% Предикат для запуска демонстрации +% ----------------------------------------------- +demo :- + write('=== ДЕМОНСТРАЦИЯ ЗАДАНИЯ 2 ==='), nl, nl, + demo_queries, + test_complex_relationships. \ No newline at end of file