|
|
|
|
|
:- ['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 (стакан около банки и молока)'). |