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.

344 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.

% ===============================================
% ТЕСТЫ ДЛЯ LAB9 TASK1
% Автоматические тесты всех предикатов
% ===============================================
% Запуск всех тестов
run_tests :-
write('=== ЗАПУСК АВТОМАТИЧЕСКИХ ТЕСТОВ ==='), nl,
test_max,
test_factorial,
test_digit_sum,
test_square_free,
test_list_operations,
test_remove_by_digit_sum,
write('=== ВСЕ ТЕСТЫ ЗАВЕРШЕНЫ ==='), nl.
% ===============================================
% ТЕСТЫ ДЛЯ MAX/4
% ===============================================
test_max :-
write('--- Тестирование max/4 ---'), nl,
% Тест 1: обычные числа
(max(5, 3, 7, 7) ->
write('✓ max(5,3,7,7) - ПРОЙДЕН') ;
write('✗ max(5,3,7,7) - ПРОВАЛЕН')), nl,
% Тест 2: отрицательные числа
(max(-5, -3, -7, -3) ->
write('✓ max(-5,-3,-7,-3) - ПРОЙДЕН') ;
write('✗ max(-5,-3,-7,-3) - ПРОВАЛЕН')), nl,
% Тест 3: одинаковые числа
(max(5, 5, 5, 5) ->
write('✓ max(5,5,5,5) - ПРОЙДЕН') ;
write('✗ max(5,5,5,5) - ПРОВАЛЕН')), nl,
% Тест 4: генерация максимума
max(10, 20, 15, Z),
(Z =:= 20 ->
write('✓ max(10,20,15,Z) где Z=20 - ПРОЙДЕН') ;
write('✗ max(10,20,15,Z) - ПРОВАЛЕН')), nl,
nl.
% ===============================================
% ТЕСТЫ ДЛЯ ФАКТОРИАЛОВ
% ===============================================
test_factorial :-
write('--- Тестирование факториалов ---'), nl,
% Тест базового случая
(fact_up(0, 1) ->
write('✓ fact_up(0,1) - ПРОЙДЕН') ;
write('✗ fact_up(0,1) - ПРОВАЛЕН')), nl,
(fact_down(0, 1) ->
write('✓ fact_down(0,1) - ПРОЙДЕН') ;
write('✗ fact_down(0,1) - ПРОВАЛЕН')), nl,
% Тест небольших значений
TestValues = [1, 3, 5, 6],
forall(member(N, TestValues), test_factorial_value(N)),
% Тест эквивалентности рекурсий
test_factorial_equivalence([0, 1, 2, 3, 4, 5, 6, 7]),
nl.
test_factorial_value(N) :-
fact_up(N, F1),
fact_down(N, F2),
write('fact_up('), write(N), write(') = '), write(F1),
write(', fact_down('), write(N), write(') = '), write(F2),
(F1 =:= F2 -> write(' ✓') ; write(' ✗')), nl.
test_factorial_equivalence([]).
test_factorial_equivalence([N|Rest]) :-
fact_up(N, F1),
fact_down(N, F2),
(F1 =:= F2 ->
write('✓ Факториалы '), write(N), write(' эквивалентны') ;
write('✗ Факториалы '), write(N), write(' НЕ эквивалентны')), nl,
test_factorial_equivalence(Rest).
% ===============================================
% ТЕСТЫ ДЛЯ СУММЫ ЦИФР
% ===============================================
test_digit_sum :-
write('--- Тестирование суммы цифр ---'), nl,
% Тест базового случая
(digit_sum_up(0, 0) ->
write('✓ digit_sum_up(0,0) - ПРОЙДЕН') ;
write('✗ digit_sum_up(0,0) - ПРОВАЛЕН')), nl,
(digit_sum_down(0, 0) ->
write('✓ digit_sum_down(0,0) - ПРОЙДЕН') ;
write('✗ digit_sum_down(0,0) - ПРОВАЛЕН')), nl,
% Тест известных значений
TestCases = [(123, 6), (456, 15), (999, 27), (1000, 1), (12345, 15)],
forall(member((N, ExpectedSum), TestCases), test_digit_sum_value(N, ExpectedSum)),
% Тест эквивалентности рекурсий
test_digit_sum_equivalence([0, 1, 12, 123, 1234, 12345, 999, 1000]),
nl.
test_digit_sum_value(N, ExpectedSum) :-
digit_sum_up(N, S1),
digit_sum_down(N, S2),
write('digit_sum для '), write(N), write(': up='), write(S1), write(', down='), write(S2),
write(', ожидалось='), write(ExpectedSum),
((S1 =:= ExpectedSum, S2 =:= ExpectedSum) -> write(' ✓') ; write(' ✗')), nl.
test_digit_sum_equivalence([]).
test_digit_sum_equivalence([N|Rest]) :-
digit_sum_up(N, S1),
digit_sum_down(N, S2),
(S1 =:= S2 ->
write('✓ Суммы цифр '), write(N), write(' эквивалентны') ;
write('✗ Суммы цифр '), write(N), write(' НЕ эквивалентны')), nl,
test_digit_sum_equivalence(Rest).
% ===============================================
% ТЕСТЫ ДЛЯ SQUARE_FREE
% ===============================================
test_square_free :-
write('--- Тестирование square_free ---'), nl,
% Числа, свободные от квадратов
SquareFreeNumbers = [1, 2, 3, 5, 6, 7, 10, 11, 13, 14, 15],
forall(member(N, SquareFreeNumbers), test_square_free_positive(N)),
% Числа, НЕ свободные от квадратов
NonSquareFreeNumbers = [4, 8, 9, 12, 16, 18, 20, 24, 25, 27],
forall(member(N, NonSquareFreeNumbers), test_square_free_negative(N)),
nl.
test_square_free_positive(N) :-
(square_free(N) ->
write('✓ '), write(N), write(' корректно определено как свободное от квадратов') ;
write('✗ '), write(N), write(' ошибочно определено как НЕ свободное от квадратов')), nl.
test_square_free_negative(N) :-
(\+ square_free(N) ->
write('✓ '), write(N), write(' корректно определено как НЕ свободное от квадратов') ;
write('✗ '), write(N), write(' ошибочно определено как свободное от квадратов')), nl.
% ===============================================
% ТЕСТЫ ДЛЯ ОПЕРАЦИЙ СО СПИСКАМИ
% ===============================================
test_list_operations :-
write('--- Тестирование операций со списками ---'), nl,
% Тест пустого списка
(sum_list_down([], 0) ->
write('✓ sum_list_down([],0) - ПРОЙДЕН') ;
write('✗ sum_list_down([],0) - ПРОВАЛЕН')), nl,
(sum_list_up([], 0) ->
write('✓ sum_list_up([],0) - ПРОЙДЕН') ;
write('✗ sum_list_up([],0) - ПРОВАЛЕН')), nl,
% Тест одного элемента
(sum_list_down([5], 5) ->
write('✓ sum_list_down([5],5) - ПРОЙДЕН') ;
write('✗ sum_list_down([5],5) - ПРОВАЛЕН')), nl,
(sum_list_up([5], 5) ->
write('✓ sum_list_up([5],5) - ПРОЙДЕН') ;
write('✗ sum_list_up([5],5) - ПРОВАЛЕН')), nl,
% Тест различных списков
TestLists = [
([1, 2, 3], 6),
([10, 20, 30], 60),
([-1, 1, -2, 2], 0),
([0, 0, 0], 0),
([100], 100)
],
forall(member((List, ExpectedSum), TestLists), test_list_sum(List, ExpectedSum)),
% Тест эквивалентности рекурсий
test_list_sum_equivalence([
[],
[1],
[1, 2],
[1, 2, 3],
[1, 2, 3, 4, 5],
[-1, -2, -3],
[0, 0, 0, 0]
]),
nl.
test_list_sum(List, ExpectedSum) :-
sum_list_down(List, S1),
sum_list_up(List, S2),
write('Сумма '), write(List), write(': down='), write(S1), write(', up='), write(S2),
write(', ожидалось='), write(ExpectedSum),
((S1 =:= ExpectedSum, S2 =:= ExpectedSum) -> write(' ✓') ; write(' ✗')), nl.
test_list_sum_equivalence([]).
test_list_sum_equivalence([List|Rest]) :-
sum_list_down(List, S1),
sum_list_up(List, S2),
(S1 =:= S2 ->
write('✓ Суммы списка '), write(List), write(' эквивалентны') ;
write('✗ Суммы списка '), write(List), write(' НЕ эквивалентны')), nl,
test_list_sum_equivalence(Rest).
% ===============================================
% ТЕСТЫ ДЛЯ УДАЛЕНИЯ ПО СУММЕ ЦИФР
% ===============================================
test_remove_by_digit_sum :-
write('--- Тестирование remove_by_digit_sum ---'), nl,
% Тест пустого списка
(remove_by_digit_sum([], 5, []) ->
write('✓ remove_by_digit_sum([],5,[]) - ПРОЙДЕН') ;
write('✗ remove_by_digit_sum([],5,[]) - ПРОВАЛЕН')), nl,
% Тест удаления всех элементов
remove_by_digit_sum([11, 20, 101, 110], 2, Result1),
(Result1 = [] ->
write('✓ Удаление всех элементов с суммой цифр 2 - ПРОЙДЕН') ;
write('✗ Удаление всех элементов с суммой цифр 2 - ПРОВАЛЕН')), nl,
% Тест удаления части элементов
remove_by_digit_sum([12, 21, 34, 43, 50], 3, Result2),
Expected2 = [34, 43, 50],
(Result2 = Expected2 ->
write('✓ Частичное удаление элементов - ПРОЙДЕН') ;
write('✗ Частичное удаление элементов - ПРОВАЛЕН')), nl,
% Тест с нецелыми элементами
remove_by_digit_sum([12, abc, 21, -5, 30], 3, Result3),
Expected3 = [abc, -5],
(Result3 = Expected3 ->
write('✓ Обработка нецелых элементов - ПРОЙДЕН') ;
write('✗ Обработка нецелых элементов - ПРОВАЛЕН')), nl,
% Дополнительные тесты
TestCases = [
(([123, 456, 789], 6), [456, 789]),
(([1, 11, 111, 1111], 1), [11, 111]),
(([0, 10, 100, 1000], 1), [0]),
(([999, 888, 777], 27), [888, 777])
],
forall(member(((List, TargetSum), Expected), TestCases),
test_remove_case(List, TargetSum, Expected)),
nl.
test_remove_case(List, TargetSum, Expected) :-
remove_by_digit_sum(List, TargetSum, Result),
write('remove_by_digit_sum('), write(List), write(', '), write(TargetSum), write(') = '),
write(Result), write(', ожидалось: '), write(Expected),
(Result = Expected -> write(' ✓') ; write(' ✗')), nl.
% ===============================================
% ДОПОЛНИТЕЛЬНЫЕ ТЕСТЫ
% ===============================================
% Тест производительности
performance_test :-
write('--- Тест производительности ---'), nl,
write('Тестирование факториала для больших чисел:'), nl,
TestNumbers = [10, 15, 20],
forall(member(N, TestNumbers), test_factorial_performance(N)),
write('Тестирование суммы цифр для больших чисел:'), nl,
BigNumbers = [12345, 123456, 1234567],
forall(member(N, BigNumbers), test_digit_sum_performance(N)),
nl.
test_factorial_performance(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,
write('Факториал '), write(N), write(': up='), write(TimeUp),
write('с, down='), write(TimeDown), write('с, результат='), write(F1),
(F1 =:= F2 -> write(' ✓') ; write(' ✗')), nl.
test_digit_sum_performance(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,
write('Сумма цифр '), write(N), write(': up='), write(TimeUp),
write('с, down='), write(TimeDown), write('с, результат='), write(S1),
(S1 =:= S2 -> write(' ✓') ; write(' ✗')), nl.
% Стресс-тест
stress_test :-
write('--- Стресс-тест ---'), nl,
write('Тестирование 100 случайных чисел для square_free:'), nl,
stress_test_square_free(100),
write('Тестирование 50 случайных списков для sum_list:'), nl,
stress_test_list_sum(50),
nl.
stress_test_square_free(0) :- !.
stress_test_square_free(N) :-
N > 0,
random(1, 100, TestNumber),
(square_free(TestNumber) -> Result = 'free' ; Result = 'not_free'),
(N mod 10 =:= 0 ->
(write('Тест '), write(N), write(': '), write(TestNumber), write(' - '), write(Result), nl)
; true),
N1 is N - 1,
stress_test_square_free(N1).
stress_test_list_sum(0) :- !.
stress_test_list_sum(N) :-
N > 0,
random(1, 10, ListLength),
generate_random_list(ListLength, TestList),
sum_list_down(TestList, S1),
sum_list_up(TestList, S2),
(N mod 10 =:= 0 ->
(write('Тест '), write(N), write(': '), write(TestList),
write(' - суммы равны: '), (S1 =:= S2 -> write('да') ; write('нет')), nl)
; true),
N1 is N - 1,
stress_test_list_sum(N1).
generate_random_list(0, []) :- !.
generate_random_list(N, [H|T]) :-
N > 0,
random(0, 100, H),
N1 is N - 1,
generate_random_list(N1, T).