%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                              BOMB IN THE TOILET                            %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% packages
package(1).
package(2).
package(3).
package(4).
package(5).

% actions
action(dunk(X)):- package(X).
action(detect_metal(X)) :- package(X).
action(sniff(X)) :- package(X).

% fluents
fluent(in(X)):- package(X).
fluent(armed).
fluent(clogged).

% noninertial fluents
noninertial(armed).

% effects
causes(dunk(X), neg(in(X)), [in(X)]) :- package(X).
causes(dunk(X), clogged, [neg(in(X))]) :- package(X).

determines(detect_metal(X), in(X)) :- package(X).
determines(detect_metal(X), neg(in(X))) :- package(X).

determines(sniff(X), in(X)) :- package(X).
determines(sniff(X), neg(in(X))) :- package(X).
 
% preconditions
executable(dunk(X), [neg(clogged)]):- package(X).
executable(detect_metal(X), []) :- package(X).
executable(sniff(X), []) :- package(X).

% initially: one of packages has bomb
initially(armed).
initially(neg(clogged)).

% static laws
caused([in(X)], armed) :- package(X).

caused([neg(in(1)), neg(in(2)), neg(in(3)), neg(in(4)), neg(in(5))], neg(armed)).

caused(L, F):- 
       member(F, [in(1), in(2), in(3), in(4), in(5)]),
       select(F, [in(1), in(2), in(3), in(4), in(5)],
              Q),
       neq_I(Q, L).

neq_I([],[armed]).

neq_I([H|L],[neg(H)|L1]):- neq_I(L,L1).

caused([in(I)], neg(in(J))):- package(I), package(J), neq(I, J).

% goal
sgoal(neg(armed)).
sgoal(neg(clogged)).

