instances dir u,d,l,r. coord r,c. static valid_pos : ext_row x ext_col -> boolean = false. is_goal : row x col -> boolean = false. static inc: coord x dir -> {-1..1} = 0. rules inc(r,u)= -1. inc(r,d)= 1. inc(c,l)= -1. inc(c,r)= 1. fluents has_stone : row x col -> boolean = false. robot : coord -> row+col. actions push : row x col -> dir. events push_dir : dir. from, to : coord -> row+col. reachable : ext_row x ext_col -> boolean = false. vars R:row. C:col. D:dir. X:coord. rules %%% Attributes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Action attributes: the pushed stone position and the push direction from(r)=R :- push(R,C)=D. from(c)=C :- push(R,C)=D. push_dir=push(R,C). % Derived action attribute: the target position for the stone to(X)=from(X)+inc(X,push_dir). %%% Action executability %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % The source position must contain a stone :- not has_stone(from(r),from(c)). % The target position must be valid :- not valid_pos(to(r),to(c)). % The robot must push from a reachable position reachable(robot(r),robot(c)). reachable(R,C) :- valid_pos(R,C), not has_stone(R,C), reachable(R+inc(r,D),C+inc(c,D)). :- not reachable(from(r)-inc(r,push_dir),from(c)-inc(c,push_dir)). %%% Action effects %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % The stone is removed from its old position not has_stone'(from(r),from(c)). % The stone will be at the target position has_stone'(to(r),to(c)). % The robot will be at the (old) pushed stone position robot'(X)=from(X). goals has_stone(R,C) :- is_goal(R,C). % SCENARIO /* 012345 #### 0 # .# 1 # ###2 #*@ #3 # $ #4 # ###5 #### 6 */ instances row 1..5. col 1..4. ext_row 0..6. % include the surrounding borders ext_col 0..5. rules valid_pos(1,1). valid_pos(1,2). valid_pos(2,1). valid_pos(2,2). valid_pos(3,1). valid_pos(3,2). valid_pos(3,3). valid_pos(3,4). valid_pos(4,1). valid_pos(4,2). valid_pos(4,3). valid_pos(4,4). valid_pos(5,1). valid_pos(5,2). is_goal(1,2). is_goal(3,1). initially has_stone(3,1). has_stone(4,3). robot(r)=3. robot(c)=2.