% =============================================== % ДЕМОНСТРАЦИЯ LAB9 TASK1 % Полная демонстрация всех предикатов % =============================================== % Главная демонстрация demo :- write('=== ДЕМОНСТРАЦИЯ LAB9 TASK1: ОСНОВНЫЕ ПРЕДИКАТЫ PROLOG ==='), nl, nl, % 1. Демонстрация max/4 write('1. ПРЕДИКАТ MAX/4'), nl, write('================'), nl, demo_max, nl, % 2. Демонстрация факториалов write('2. ФАКТОРИАЛЫ (РЕКУРСИЯ ВВЕРХ И ВНИЗ)'), nl, write('===================================='), nl, demo_factorial, nl, % 3. Демонстрация суммы цифр write('3. СУММА ЦИФР ЧИСЛА (РЕКУРСИЯ ВВЕРХ И ВНИЗ)'), nl, write('=========================================='), nl, demo_digit_sum, nl, % 4. Демонстрация square_free write('4. ПРОВЕРКА СВОБОДНОСТИ ОТ КВАДРАТОВ'), nl, write('==================================='), nl, demo_square_free, nl, % 5. Демонстрация операций со списками write('5. ОПЕРАЦИИ СО СПИСКАМИ'), nl, write('======================='), nl, demo_list_operations, nl, % 6. Демонстрация удаления по сумме цифр write('6. УДАЛЕНИЕ ЭЛЕМЕНТОВ ПО СУММЕ ЦИФР'), nl, write('==================================='), nl, demo_remove_by_digit_sum, nl, % 7. Сравнительный анализ рекурсий write('7. СРАВНИТЕЛЬНЫЙ АНАЛИЗ РЕКУРСИЙ'), nl, write('================================'), nl, demo_recursion_comparison, nl, % 8. Практические примеры write('8. ПРАКТИЧЕСКИЕ ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ'), nl, write('===================================='), nl, demo_practical_examples, nl, write('=== ДЕМОНСТРАЦИЯ ЗАВЕРШЕНА ==='), nl. % ----------------------------------------------- % Демонстрация max/4 % ----------------------------------------------- demo_max :- write('Предикат max(+X, +Y, +U, -Z) находит максимальное из трех чисел.'), nl, nl, TestCases = [ (5, 3, 7), (-5, -3, -1), (10, 10, 10), (0, -5, 3), (100, 50, 75) ], forall(member((X, Y, U), TestCases), demo_max_case(X, Y, U)), write('Предикат также можно использовать для проверки:'), nl, (max(10, 20, 15, 20) -> write('✓ max(10, 20, 15, 20) - истина') ; write('✗ max(10, 20, 15, 20) - ложь')), nl, (max(10, 20, 15, 15) -> write('✓ max(10, 20, 15, 15) - истина') ; write('✗ max(10, 20, 15, 15) - ложь')), nl. demo_max_case(X, Y, U) :- max(X, Y, U, Z), write('max('), write(X), write(', '), write(Y), write(', '), write(U), write(') = '), write(Z), nl. % ----------------------------------------------- % Демонстрация факториалов % ----------------------------------------------- demo_factorial :- write('Факториал реализован двумя способами:'), nl, write('- fact_up(+N, -X) использует рекурсию вверх'), nl, write('- fact_down(+N, -X) использует рекурсию вниз с аккумулятором'), nl, nl, TestNumbers = [0, 1, 3, 5, 7, 10], write('Сравнение результатов:'), nl, write('N | Факториал (вверх) | Факториал (вниз) | Время (вверх) | Время (вниз)'), nl, write('-----|-------------------|------------------|---------------|-------------'), nl, forall(member(N, TestNumbers), demo_factorial_case(N)), nl, write('Демонстрация принципа работы:'), nl, write('Рекурсия вверх: fact_up(3) = 3 * fact_up(2) = 3 * 2 * fact_up(1) = 3 * 2 * 1 = 6'), nl, write('Рекурсия вниз: fact_down(3) вызывает helper(3,1) -> helper(2,3) -> helper(1,6) -> helper(0,6) = 6'), nl. demo_factorial_case(N) :- get_time(T1), fact_up(N, F1), get_time(T2), fact_down(N, F2), get_time(T3), TimeUp is T2 - T1, TimeDown is T3 - T2, format('~w~4| | ~w~17| | ~w~16| | ~3f~13| | ~3f~n', [N, F1, F2, TimeUp, TimeDown]). % ----------------------------------------------- % Демонстрация суммы цифр % ----------------------------------------------- demo_digit_sum :- write('Сумма цифр числа реализована двумя способами:'), nl, write('- digit_sum_up(+N, -Sum) использует рекурсию вверх'), nl, write('- digit_sum_down(+N, -Sum) использует рекурсию вниз с аккумулятором'), nl, nl, TestNumbers = [0, 9, 123, 456, 999, 1000, 12345, 987654], write('Сравнение результатов:'), nl, write('Число | Сумма (вверх) | Сумма (вниз) | Время (вверх) | Время (вниз)'), nl, write('--------|---------------|--------------|---------------|-------------'), nl, forall(member(N, TestNumbers), demo_digit_sum_case(N)), nl, write('Демонстрация принципа работы для числа 123:'), nl, write('Рекурсия вверх: digit_sum_up(123) = 3 + digit_sum_up(12) = 3 + 2 + digit_sum_up(1) = 3 + 2 + 1 = 6'), nl, write('Рекурсия вниз: helper(123,0) -> helper(12,3) -> helper(1,5) -> helper(0,6) = 6'), nl. demo_digit_sum_case(N) :- get_time(T1), digit_sum_up(N, S1), get_time(T2), digit_sum_down(N, S2), get_time(T3), TimeUp is T2 - T1, TimeDown is T3 - T2, format('~w~7| | ~w~12| | ~w~11| | ~6f~9| | ~6f~n', [N, S1, S2, TimeUp, TimeDown]). % ----------------------------------------------- % Демонстрация square_free % ----------------------------------------------- demo_square_free :- write('Предикат square_free(+N) проверяет, свободно ли число от квадратов.'), nl, write('Число свободно от квадратов, если оно не делится на квадрат простого числа > 1.'), nl, nl, write('Примеры свободных от квадратов чисел:'), nl, SquareFreeNumbers = [1, 2, 3, 5, 6, 7, 10, 11, 13, 14, 15, 17, 19, 21, 22], demo_square_free_list(SquareFreeNumbers, 'свободны'), nl, write('Примеры НЕ свободных от квадратов чисел:'), nl, NonSquareFreeNumbers = [4, 8, 9, 12, 16, 18, 20, 24, 25, 27, 28, 32, 36], demo_square_free_list(NonSquareFreeNumbers, 'не свободны'), nl, write('Объяснения:'), nl, write('- 12 не свободно от квадратов: 12 = 4 × 3, где 4 = 2²'), nl, write('- 18 не свободно от квадратов: 18 = 9 × 2, где 9 = 3²'), nl, write('- 15 свободно от квадратов: 15 = 3 × 5 (простые множители)'), nl. demo_square_free_list([], _). demo_square_free_list([N|Rest], Description) :- (square_free(N) -> Status = '✓' ; Status = '✗'), write(Status), write(' '), write(N), (Rest = [] -> nl ; (write(', '), demo_square_free_list(Rest, Description))). % ----------------------------------------------- % Демонстрация операций со списками % ----------------------------------------------- demo_list_operations :- write('Операции со списками включают ввод, вывод и вычисление суммы.'), nl, nl, write('Демонстрация предикатов sum_list_down и sum_list_up:'), nl, TestLists = [ [], [5], [1, 2, 3], [10, 20, 30, 40], [-1, 1, -2, 2], [0, 0, 0, 0], [100, -50, 25] ], write('Список | Сумма (вниз) | Сумма (вверх) | Время (вниз) | Время (вверх)'), nl, write('----------------------|--------------|---------------|--------------|-------------'), nl, forall(member(List, TestLists), demo_list_sum_case(List)), nl, write('Принципы работы:'), nl, write('sum_list_down([1,2,3]): sum_list_down([2,3]) + 1 = (sum_list_down([3]) + 2) + 1 = ((0 + 3) + 2) + 1 = 6'), nl, write('sum_list_up([1,2,3]): helper([1,2,3], 0) -> helper([2,3], 1) -> helper([3], 3) -> helper([], 6) = 6'), nl, nl, write('Демонстрация write_list:'), nl, TestListsForDisplay = [[], [1], [1,2,3], [a,b,c,d]], forall(member(List, TestListsForDisplay), (write('write_list('), write(List), write(') выводит: '), write_list(List))). demo_list_sum_case(List) :- get_time(T1), sum_list_down(List, S1), get_time(T2), sum_list_up(List, S2), get_time(T3), TimeDown is T2 - T1, TimeUp is T3 - T2, format('~w~21| | ~w~11| | ~w~12| | ~6f~8| | ~6f~n', [List, S1, S2, TimeDown, TimeUp]). % ----------------------------------------------- % Демонстрация удаления по сумме цифр % ----------------------------------------------- demo_remove_by_digit_sum :- write('Предикат remove_by_digit_sum(+List, +TargetSum, -Result) удаляет'), nl, write('все элементы, сумма цифр которых равна заданной.'), nl, nl, TestCases = [ ([12, 21, 34, 43, 50], 3, 'элементы с суммой цифр 3: 12(1+2=3), 21(2+1=3)'), ([123, 456, 789, 111], 6, 'элементы с суммой цифр 6: 123(1+2+3=6)'), ([10, 20, 30, 101, 110], 2, 'элементы с суммой цифр 2: 20(2+0=2), 101(1+0+1=2), 110(1+1+0=2)'), ([999, 888, 777, 666], 27, 'элементы с суммой цифр 27: 999(9+9+9=27)'), ([1, 11, 111, 1111], 1, 'элементы с суммой цифр 1: 1(1=1)'), ([abc, 12, def, 21, -5], 3, 'целые элементы с суммой цифр 3 (нецелые сохраняются)') ], forall(member((List, TargetSum, Description), TestCases), demo_remove_case(List, TargetSum, Description)), nl, write('Особенности обработки:'), nl, write('- Обрабатываются только неотрицательные целые числа'), nl, write('- Нецелые и отрицательные элементы сохраняются в результате'), nl, write('- Порядок элементов в результирующем списке сохраняется'), nl. demo_remove_case(List, TargetSum, Description) :- remove_by_digit_sum(List, TargetSum, Result), write('Исходный список: '), write(List), nl, write('Удаляем '), write(Description), nl, write('Результат: '), write(Result), nl, write('---'), nl. % ----------------------------------------------- % Сравнительный анализ рекурсий % ----------------------------------------------- demo_recursion_comparison :- write('Сравнение эффективности рекурсии вверх и вниз:'), nl, nl, write('РЕКУРСИЯ ВВЕРХ (традиционная):'), nl, write('+ Простота реализации и понимания'), nl, write('+ Естественная математическая запись'), nl, write('- Использует стек вызовов (может привести к переполнению)'), nl, write('- Вычисления происходят при возврате из рекурсии'), nl, nl, write('РЕКУРСИЯ ВНИЗ (с аккумулятором):'), nl, write('+ Эффективнее по памяти (хвостовая рекурсия)'), nl, write('+ Может быть оптимизирована компилятором'), nl, write('+ Вычисления происходят при погружении в рекурсию'), nl, write('- Менее интуитивная реализация'), nl, nl, write('Практическое сравнение для больших значений:'), nl, TestValues = [15, 20, 25], forall(member(N, TestValues), demo_recursion_performance(N)). demo_recursion_performance(N) :- write('Тестирование для N = '), write(N), write(':'), nl, % Факториал get_time(T1), fact_up(N, F1), get_time(T2), fact_down(N, F2), get_time(T3), TimeFactUp is T2 - T1, TimeFactDown is T3 - T2, write(' Факториал: рекурсия вверх = '), write(TimeFactUp), write('с, '), write('рекурсия вниз = '), write(TimeFactDown), write('с'), nl, % Сумма цифр get_time(T4), digit_sum_up(N, S1), get_time(T5), digit_sum_down(N, S2), get_time(T6), TimeSumUp is T5 - T4, TimeSumDown is T6 - T5, write(' Сумма цифр: рекурсия вверх = '), write(TimeSumUp), write('с, '), write('рекурсия вниз = '), write(TimeSumDown), write('с'), nl, nl. % ----------------------------------------------- % Практические примеры использования % ----------------------------------------------- demo_practical_examples :- write('Практические сценарии использования предикатов:'), nl, nl, write('СЦЕНАРИЙ 1: Анализ числовых данных'), nl, write('--------------------------------'), nl, demo_scenario_analysis, nl, write('СЦЕНАРИЙ 2: Обработка списков чисел'), nl, write('----------------------------------'), nl, demo_scenario_list_processing, nl, write('СЦЕНАРИЙ 3: Математические вычисления'), nl, write('------------------------------------'), nl, demo_scenario_math, nl. demo_scenario_analysis :- Numbers = [12, 45, 123, 7, 89, 456], write('Анализируем числа: '), write(Numbers), nl, % Анализ каждого числа forall(member(N, Numbers), demo_number_analysis(N)), % Фильтрация по сумме цифр remove_by_digit_sum(Numbers, 9, FilteredNums), write('После удаления чисел с суммой цифр 9: '), write(FilteredNums), nl. demo_number_analysis(N) :- digit_sum_up(N, DigitSum), (square_free(N) -> SFStatus = 'свободно' ; SFStatus = 'не свободно'), write(' '), write(N), write(': сумма цифр = '), write(DigitSum), write(', '), write(SFStatus), write(' от квадратов'), nl. demo_scenario_list_processing :- OriginalList = [10, 25, 67, 123, 89, 456, 12, 78], write('Исходный список: '), write(OriginalList), nl, sum_list_up(OriginalList, TotalSum), write('Общая сумма: '), write(TotalSum), nl, % Удаляем элементы с определенной суммой цифр remove_by_digit_sum(OriginalList, 6, Without6), write('Без элементов с суммой цифр 6: '), write(Without6), nl, sum_list_up(Without6, NewSum), write('Новая сумма: '), write(NewSum), nl, Difference is TotalSum - NewSum, write('Разница: '), write(Difference), nl. demo_scenario_math :- write('Математические вычисления для N = 6:'), nl, N = 6, fact_up(N, Factorial), write(' Факториал: '), write(Factorial), nl, digit_sum_up(Factorial, FactDigitSum), write(' Сумма цифр факториала: '), write(FactDigitSum), nl, max(N, Factorial, FactDigitSum, MaxValue), write(' Максимум из (N, N!, сумма_цифр(N!)): '), write(MaxValue), nl, (square_free(N) -> write(' N свободно от квадратов') ; write(' N не свободно от квадратов')), nl. % ----------------------------------------------- % Интерактивные примеры % ----------------------------------------------- demo_interactive_examples :- write('=== ИНТЕРАКТИВНЫЕ ПРИМЕРЫ ==='), nl, write('Вы можете попробовать следующие запросы в интерактивной сессии:'), nl, nl, write('1. Основные предикаты:'), nl, write(' ?- max(10, 5, 15, Z). % Z = 15'), nl, write(' ?- fact_up(6, F). % F = 720'), nl, write(' ?- fact_down(6, F). % F = 720'), nl, write(' ?- digit_sum_up(123, S). % S = 6'), nl, write(' ?- digit_sum_down(123, S). % S = 6'), nl, write(' ?- square_free(15). % true'), nl, write(' ?- square_free(12). % false'), nl, nl, write('2. Работа со списками:'), nl, write(' ?- sum_list_down([1,2,3,4], S). % S = 10'), nl, write(' ?- sum_list_up([1,2,3,4], S). % S = 10'), nl, write(' ?- write_list([a,b,c]). % [a, b, c]'), nl, write(' ?- remove_by_digit_sum([12,21,34], 3, R). % R = [34]'), nl, nl, write('3. Интерактивные программы:'), nl, write(' ?- list_sum_program. % Интерактивная работа со списками'), nl, write(' ?- interactive_demo. % Интерактивное меню'), nl, nl, write('4. Тестирование и анализ:'), nl, write(' ?- test_all_predicates. % Быстрое тестирование'), nl, write(' ?- compare_recursions(10). % Сравнение рекурсий'), nl, write(' ?- benchmark_recursions(15). % Измерение производительности'), nl, nl, write('5. Демонстрационные программы:'), nl, write(' ?- demo. % Полная демонстрация'), nl, write(' ?- run_tests. % Запуск всех тестов'), nl, nl.