:- dynamic(current_state/1).
:- assert(current_state([at(1,1),facing(1)])).

occupied(1,4).
occupied(3,1).
occupied(3,3).
occupied(5,3).

perform(turn, []) :-
	write('turn'), nl,
	current_state([at(X,Y),facing(D)]),
	retract(current_state([at(X,Y),facing(D)])),
	( D < 4 -> D1 is D+1 ; D1 is 1 ),
	assert(current_state([at(X,Y),facing(D1)])).

perform(clean, []) :-
	write('clean'), nl.

perform(go, [Light]) :-
	write('go'), nl,
	current_state([at(X,Y),facing(D)]),
	retract(current_state([at(X,Y),facing(D)])),
	( D = 1 -> X1 is X, Y1 is Y+1 ;
	  D = 3 -> X1 is X, Y1 is Y-1 ;
	  D = 2 -> X1 is X+1, Y1 is Y ;
	  D = 4 -> X1 is X-1, Y1 is Y ),
	assert(current_state([at(X1,Y1),facing(D)])),
	X_east is X1+1, X_west is X1-1, Y_north is Y1+1, Y_south is Y1-1,
	( (occupied(X,Y) ;
           occupied(X_east,Y1) ; occupied(X1,Y_north) ;
           occupied(X_west,Y1) ; occupied(X1,Y_south)) -> Light = true ;
	    Light = false ).
