%% twoarmsplan.lp -- Chapter 9, Section 9.4 %% Last Modified: 2/6/14 %% Planner for blocks world domain with two robotic arms that can %% act concurrently. block(b0). block(b1). block(b2). block(b3). block(b4). block(b5). block(b6). block(b7). location(X) :- block(X). location(t). %% Fluents %% fluent(inertial, on(B,L)) :- block(B), location(L). fluent(defined, above(B,L)) :- block(B), location(L). %% Actions %% %% "Put block B on location L" is a possible action in our %% domain provided we don't try to put a block onto itself. action(put(B,L)) :- block(B), location(L), B != L. #const n = 5. step(0..n). %% Laws %% %% Putting block B on location L at step I %% causes B to be on L at step I+1: %% put(B,L) causes on(B,L) holds(on(B,L),I+1) :- occurs(put(B,L),I), I < n. %% A block cannot be in two locations at once: %% -on(B,L2) if on(B,L1), L1 != L2 -holds(on(B,L2),I) :- holds(on(B,L1),I), location(L2), L1 != L2. %% Only one block can be set directly on top of another: %% -on(B2,B) if on(B1,B), B1 != B2 -holds(on(B2,B),I) :- holds(on(B1,B),I), block(B), block(B2), B1 != B2. %% B is above L if it is directly on top of it or on top of %% another block that is above L: %% above(B,L) if on (B,L) %% above(B,L) if on(B,B1), above(B1,L) holds(above(B2,B1),I) :- holds(on(B2,B1),I). holds(above(B2,B1),I) :- holds(on(B2,B),I), holds(above(B,B1),I). %% It is impossible to move an occupied block: %% impossible put(B,L) if on (B1,B) -occurs(put(B,L),I) :- location(L), holds(on(B1,B),I). %% !! This old constraint was not needed -- overspecification %% It is impossible to move a block onto an occupied block: %% impossible put(B1,B) if on(B2,B). %-occurs(put(B1,B),I) :- block(B1), block(B), % holds(on(B2,B),I). %% !! New restriction for concurrency %% Actions that put B1 on B2 and simultaneously move B2 are impossible: %% impossible put(B1,L), put(B2,B2) -occurs(put(B1,L),I) | -occurs(put(B2,B1),I) :- step(I), action(put(B1,L)), action(put(B2,B1)). %% CWA for Defined Fluents -holds(F,I) :- fluent(defined,F), step(I), not holds(F,I). %% General Inertia Axiom holds(F,I+1) :- fluent(inertial,F), holds(F,I), not -holds(F,I+1), I < n. -holds(F,I+1) :- fluent(inertial,F), -holds(F,I), not holds(F,I+1), I < n. %% CWA for Actions -occurs(A,I) :- action(A), step(I), not occurs(A,I). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Simple Concurrent Planning Module success :- goal(I), I <= n. :- not success. %% The only change from the serial version is the number of actions %% allowed to occur concurrently -- 2 in this case: 1 {occurs(Action,I): action(Action)} 2 :- step(I), not goal(I), I < n. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Initial Situation %% Change at will: %% holds(on(B,L),I): a block B is on location L at step I. holds(on(b0,t),0). holds(on(b3,b0),0). holds(on(b2,b3),0). holds(on(b1,t),0). holds(on(b4,b1),0). holds(on(b5,t),0). holds(on(b6,b5),0). holds(on(b7,b6),0). %% If block B is not known to be on location L at step 0, %% then we assume it is not. -holds(on(B,L),0) :- block(B), location(L), not holds(on(B,L),0). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Specific goal. %% Change at will: goal(I) :- holds(on(b4,t),I), holds(on(b6,t),I), holds(on(b1,t),I), holds(on(b3,b4),I), holds(on(b7,b3),I), holds(on(b2,b6),I), holds(on(b0,b1),I), holds(on(b5,b0),I). #show occurs/2.