%   WARPLAN - cube worlds

:-   op( 50,  xfx,  on ).

add(  U on W,  move( U,  _V,  W )  ).
add(  clear( V ),  move( _U,  V,  _W )  ).

del(  U on _Z,  move( U,  _V,  _W )  ).
del(  clear( W ),  move( _U,  _V,  W )  ).

can(  move( U,  V,  floor ),
      U on V  &  notequal( V,  floor )  &  clear( U )  ).
can(  move( U,  V,  W ),
      clear( W )  &  U on V  &  notequal( U,  W )  &  clear( U )  ).

imposs(  _X on Y  &  clear( Y )  ).
imposs(  X on Y  &  X on Z  &  notequal( Y,  Z )  ).
imposs(  X on Z  &  Y on Z  &  notequal( Z,  floor )  &  notequal( X,  Y )  ).
imposs(  Cycle  )   :-   cycle(  Cycle  ).

cycle(  X on X  ).
cycle(  X on Y  &  CycRest  )   :-   cycle(  X,  Y,  CycRest,  2  ).

cycle(  X,  Y,  Y on X,  _  ).
cycle(  X,  Y,  Y on Z  &  CycRest,  Limit  )   :-
	Limit1  is  Limit - 1,
	Limit1  >  0,
	cycle(  X,  Z,  CycRest,  Limit1  ).

% The three blocks problem.
given(  cubes1,  a on floor  ).
given(  cubes1,  b on floor  ).
given(  cubes1,  c on a  ).
given(  cubes1,  clear( b )  ).
given(  cubes1,  clear( c )  ).

wait :-   see( user ),  display( '<press "return" to continue>' ),
          rdch( _ ),    seen.

:-   plans( c on a  &  a on b,  cubes1 ), wait.
:-   plans( a on b  &  b on c,  cubes1 ), wait.

end.
