/* Derived from prolog tutorial 7_3.pl */

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Command idiom c:
%  {Please} place <put> {block} X on <onto >{block} Y, W on Z, ...
%  I want <would like> X on Y, W on Z, ...
%  I want <would like> you to put <place> ...
%  Can <could> <would> you {please} put <place> X on Y, ...

c(L) --> lead_in,arrange(L),end.

end --> ['.'] | ['?'].

lead_in --> please, putplace.
lead_in --> [i], [want] | [i], [would], [like], you_to_put.
lead_in --> ([can] | [could] | [would]), [you], please, putplace.

you_to_put --> [] | [you], [to], putplace.   %%% partially optional

please --> [] | [please].    %%% optional word

putplace --> [put] | [place].   %%% alternate words

arrange([ON]) --> on(ON).
arrange([ON|R]) --> on(ON), comma, arrange(R).

comma --> [','] | ['and'] | [','],[and].   %%% alternate words

on(place(X,Y)) --> block, [X], ([on] | [onto] | [on],[top],[of]), block, [Y].
on(place(X,table)) --> block, [X],([on] | [onto]), [the], [table].

block --> [] | [block].   %%% optional word


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Question idiom q:
%   Which block is on top of X?
%   What is on top of X?
%

% the question q
q(is_on_top_of(_, A)) --> [which],[block],[is],[on],[top],[of],[A],end.
q(is_on_top_of(_, A)) --> [what],[is],[on],[top],[of],[A],end.
   
% How to answer q
is_on_top_of(B, A) :- on(B,A), !.
is_on_top_of('Nothing',_).

answer(is_on_top_of(X,A)) :- call(is_on_top_of(X,A)),
                            say([X,is,on,top,of,A]).

say([X|R]) :- write(X), write(' '), say(R).
say([]).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Load blocks world definition

:- [blocks1].	%%% replace this with your world definition


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% run the interactive world

:- [read_line].  %%% include code to parse user input into list of words

test_parser :- repeat,
               write('?? '), 
               read_line(X),
               ( c(F,X,[])   | q(F,X,[])  ),
               nl, write(X), nl, write(F), nl, fail.


run_world :- repeat,
             write('?? '), 
	     read_line(X),
	     ( c(F,X,[])   | q(F,X,[])  ),
	     answer(F), nl, fail.

