%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% The gas-diffusion problem: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%A building contains a number of rooms. %%%Each room is connected to (some) other rooms via gates. %%%Initially, all gates are closed and some of the %%%rooms contain certain amounts of gas %%%(the other rooms are assumed to be empty). %%%Each gate can be opened or closed. %%%When a gate between two rooms is opened %%%the gas contained in these rooms flows through the gate. %%%The gas diffusion continue until the pressure reaches an equilibrium. %%%The only condition to be always satisfied is that a gate in a room can be %%%opened only if all other gates are closed. %%%The goal for Diabolik is to move a desired quantity %%%of gas in one specified room (in order to generate an explosion %%%below the central bank). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Invented and Coded by DFP, 2007-2009 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Launch as :-bmap(6). %%% leftmost: 8s %%% left_ffc: 29s %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% The 11 rooms of our instances: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% 10 9 %% 11 8 %% 1 -7- 6 %% 2 5 %% 3 4 %%%% TOPOLOGY description room(N) :- interval(N,1,11). gate(1,2). gate(1,7). gate(1,11). gate(2,3). gate(3,4). gate(4,5). gate(5,6). gate(6,7). gate(6,8). gate(8,9). gate(9,10). gate(10,11). %%%% agent(diabolik). %%%% FLUENTS fluent(contains(N),0,255) :- room(N). fluent(is_open(X,Y),0,1) :- gate(X,Y). %%%% ACTIONS action([diabolik],open(X,Y)) :- gate(X,Y). action([diabolik],close(X,Y)) :- gate(X,Y). %%%% EXECUTABLE executable([diabolik],open(X,Y),L) :- action(open(X,Y)), findall((is_open(X,Z) eq 0), gate(X,Z),L1), findall((is_open(Z,X) eq 0), gate(Z,X),L2,L1), findall((is_open(Y,Z) eq 0), (gate(Y,Z),neq(Z,X)),L3,L2), findall((is_open(Z,Y) eq 0), (gate(Z,Y),neq(Z,X)),L,L3). executable([diabolik],close(X,Y),[is_open(X,Y) eq 1]) :- action([diabolik],close(X,Y)). %%%% EFFECTS causes(contains(Y) eq (contains(X)^(-1)+contains(Y)^(-1))/2, [actocc([diabolik],open(X,Y))]) :- action([diabolik],open(X,Y)). causes(contains(X) eq (contains(X)^(-1)+contains(Y)^(-1))/2, [actocc([diabolik],open(X,Y))]) :- action([diabolik],open(X,Y)). causes(is_open(X,Y) eq 1,[actocc([diabolik],open(X,Y))]) :- action([diabolik],open(X,Y)). causes(close(X,Y), is_open(X,Y) eq 0,[actocc([diabolik],close(X,Y))]) :- action([diabolik],close(X,Y)). %%%% Initial and final states initially(is_open(X,Y) eq 0) :- gate(X,Y). initially(contains(10) eq 128). initially(contains(3) eq 128). initially(contains(A) eq 0) :- room(A), diff(A,3,10). goal(contains(1) gt 50). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%