:- ['predicates.pl']. run_tests :- write('=== ЗАПУСК ТЕСТОВ ДЛЯ TASK4 ==='), nl, collect_solutions(Sols), length(Sols, N), write('Найдено решений: '), write(N), nl, (N > 0 -> true ; (write('Нет решений!'), nl, fail)), % Проверим ограничения для всех решений forall(member(S, Sols), test_solution_constraints(S)), % Ожидаемое количество решений (в текущей формализации): 8 ( N =:= 8 -> write('Количество решений соответствует ожидаемому (8).'), nl ; write('ВНИМАНИЕ: количество решений не равно ожидаемому (8).'), nl ), write('=== ТЕСТЫ ЗАВЕРШЕНЫ ==='), nl. collect_solutions(Sols) :- findall(S, solve_puzzle(S), Sols). extract_map([(V1,L1),(V2,L2),(V3,L3),(V4,L4)], Map) :- Map = [V1-L1, V2-L2, V3-L3, V4-L4]. lookup(V, [V-L|_], L) :- !. lookup(V, [_|T], L) :- lookup(V, T, L). positions([(V1,_),(V2,_),(V3,_),(V4,_)], PosMap) :- PosMap = [V1-1, V2-2, V3-3, V4-4]. pos_of(V, [V-P|_], P) :- !. pos_of(V, [_|T], P) :- pos_of(V, T, P). liquid_pos_in_solution(Solution, Liquid, Pos) :- Solution = [(_,L1),(_,L2),(_,L3),(_,L4)], ( L1 = Liquid -> Pos = 1 ; L2 = Liquid -> Pos = 2 ; L3 = Liquid -> Pos = 3 ; L4 = Liquid -> Pos = 4 ). cond1(Map) :- lookup(бутылка, Map, Lb), Lb \= вода, Lb \= молоко. cond2(Solution) :- positions(Solution, PosMap), pos_of(кувшин, PosMap, JugPos), liquid_pos_in_solution(Solution, лимонад, LemonPos), liquid_pos_in_solution(Solution, квас, KvassPos), between_pos(LemonPos, JugPos, KvassPos). cond3(Map) :- lookup(банка, Map, Lj), Lj \= лимонад, Lj \= вода. cond4(Solution) :- positions(Solution, PosMap), pos_of(стакан, PosMap, GPos), pos_of(банка, PosMap, JPos), liquid_pos_in_solution(Solution, молоко, MPos), adjacent(GPos, JPos), adjacent(GPos, MPos). assert_true(Goal, Msg) :- (Goal -> true ; (write('FAIL: '), write(Msg), nl, fail)). test_solution_constraints(Sol) :- extract_map(Sol, Map), assert_true(cond1(Map), 'cond1 (вода/молоко не в бутылке)'), assert_true(cond2(Sol), 'cond2 (лимонад между кувшином и квасом)'), assert_true(cond3(Map), 'cond3 (в банке не лимонад и не вода)'), assert_true(cond4(Sol), 'cond4 (стакан около банки и молока)').