%% s_blocks2.sp -- SPARC version of blocks2.lp from Chapter 8, Section 8.1 %% Last Modified: 2/21/2014 %% FOR EXPERIMENTATION ONLY %% Description of a basic block world domain but with defined %% fluent above. Demonstrates problem that necessitates two types of %% fluents -- inertial and defined. %% This program is meant to be experimented with in conjunction with %% the text. See blocks3.lp for the finished version. %% %% The basic blocks world consists of a robotic arm that can manipulate %% configurations of same-sized cubic blocks on a table. There are %% limitations to what the robotic arm can do. It can move %% unoccupied blocks, one at a time, onto other unoccupied blocks or %% onto the table. (An unoccupied block is one that does not have another %% block stacked on it.) At any given step, a block can be in at most %% one location; in other words, a block can be directly on top of one %% other block, or on the table. We do not impose a limit on how tall %% our towers can be. Our table is big enough to hold all the blocks, %% even if they are not stacked. We do not take into account spatial %% relationships of towers, just which blocks are on top %% of each other and which blocks are on the table. #const n = 2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% sorts %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #block = [b][0..7]. #location = #block + {t}. #fluent = on(#block(X),#location(Y)):X!=Y + above(#block(X),#location(Y)):X!=Y. #action = put(#block(X),#location(Y)):X!=Y. #step = 0..n. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% predicates %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% holds(#fluent,#step). occurs(#action,#step). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% rules %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% holds(on(B,L),I): a block B is on location L at step I. %% This is a particular intial configuration. %% It can be changed at will: 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) :- not holds(on(B,L),0). %% Putting block B on location L at step I %% causes B to be on L at step I+1: holds(on(B,L),I+1) :- occurs(put(B,L),I). %% A block cannot be in two locations at once: -holds(on(B,L2),I) :- holds(on(B,L1),I), L1 != L2. %% Only one block can be set directly on top of another: -holds(on(B2,B),I) :- #block(B), holds(on(B1,B),I), B1 != B2. % Inertia: holds(F,I+1) :- holds(F,I), not -holds(F,I+1). -holds(F,I+1) :- -holds(F,I), not holds(F,I+1). %% It is impossible to move an occupied block: -occurs(put(B,L),I) :- holds(on(B1,B),I). %% It is impossible to move a block onto an occupied block: -occurs(put(B1,B),I) :- #block(B), holds(on(B2,B),I). %% Specific actions for testing. %% Change these at will: occurs(put(b2,t),0). occurs(put(b7,b2),1). %% Block B is located above location L: holds(above(B,L),I) :- holds(on(B,L),I). holds(above(B,L),I) :- holds(on(B,B1),I), holds(above(B1,L),I). %% CWA for above: -holds(above(B,L),I) :- not holds(above(B,L),I). %% The statement that illustrates the problem: :- -holds(above(b2,b0),1).