%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% read_line %%% Similar to read_sent in Pereira and Shieber, Prolog and %%% Natural Language Analysis, CSLI, 1987. %%% %%% Examples: %%% % read_line(L). %%% The sky was blue, after the rain. %%% L = [the,sky,was,blue,',',after,the,rain,'.'] %%% % read_line(L). %%% Which way to the beach? %%% L = [which,way,to,the, beach,'?'] %%% read_line(Words) :- get0(C), read_rest(C,Words). /* A period or question mark ends the input. */ read_rest(46,['.']) :- !. read_rest(63,['?']) :- !. /* Spaces and newlines between words are ignored. */ read_rest(C,Words) :- ( C=32 ; C=10 ) , !, get0(C1), read_rest(C1,Words). /* Commas between words are absorbed. */ read_rest(44,[','|Words]) :- !, get0(C1), read_rest(C1,Words). /* Otherwise get all of the next word. */ read_rest(C,[Word|Words]) :- lower_case(C,LC), read_word(LC,Chars,Next), name(Word,Chars), read_rest(Next,Words). /* Space, comma, newline, period or question mark separate words. */ read_word(C,[],C) :- ( C=32 ; C=44 ; C=10 ; C=46 ; C=63 ) , !. /* Otherwise, get characters, convert alpha to lower case. */ read_word(C,[LC|Chars],Last) :- lower_case(C,LC), get0(Next), read_word(Next,Chars,Last). /* Convert to lower case if necessary. */ lower_case(C,C) :- ( C < 65 ; C > 90 ) , !. lower_case(C,LC) :- LC is C + 32. /* for reference ... newline(10). comma(44). space(32). period(46). question_mark(63). */ % initial state tilebox([[1,2,3],[4,5,6],[7,8,' ']]). % Call the parser. move_tiles :- repeat, write('?? '), read_line(X), ( c(F,X,[]), assert_list(F), write('ok.'), nl | q(F,X,[]) ), answer(F), nl, fail. % Assert each item in the list. assert_list([]). assert_list([H|T]) :- assert_item(H), assert_list(T). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Command idiom c: % {Please} move {tile} X % I want you to move {tile} X {up/down/left/right} % Can you {please} move X {up/down/left/right}, ... c(L) --> lead_in,arrange(L),end. end --> ['.'] | ['?']. lead_in --> please, move. lead_in --> [i], [want] | [i], [would], [like], you_to_put. lead_in --> ([can] | [could] | [would]), [you], please, move. you_to_move --> [] | [you], [to], move. %%% partially optional please --> [] | [please]. %%% optional word move --> [move] | [push]. %%% alternate words arrange([ON]) --> slide(ON). arrange([ON|R]) --> slide(ON), comma, arrange(R). comma --> [','] | ['and'] | [','],[and]. %%% alternate words slide(slide(X,Direction)) --> tile, [X], [Direction]. tile --> [] | [tile]. %%% optional word % Move tile A. assert_item(slide(X,Direction)) :- write('I am not Implemented: '), write(slide(X,Direction)), fail . %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Question idiom q: % Which tile is at X,Y ? % % the question q q(check(X,Y)) --> [which],[tile],[is],[at],[X],[,],[Y],end. % How to answer q answer(check(X,Y)) :- tilebox(L), grabA(Res,X,Y,L), write('Tile '), write(Res), write('.'), nl. %%%%%%%%%%%%%% % Utilities %Pretty Prints a list of lists to the console prettyprint([]). prettyprint([H|L]) :- printhelp(H), prettyprint(L). printhelp([]) :- nl. printhelp([H|T]) :- write(H),write(' '), printhelp(T). % Replace and replacegrid have as their first argument a copy of their fourth argument, with % instances of the second argument replaced with instances of the first argument. Replace % Takes in lists and replacegrid takes in lists of lists. % replacegrid(Res, 2, 7, [[1,2,3,4]]) would set Res to [[1,7,3,4]]. % Take note that the tilebox assertion is a list of lists. replace([],_,_,[]). replace(Res,In,Out,[H|L]) :- In = H, replace(FRes,In,Out,L), Res=[Out|FRes] . replace(Res,In,Out,[H|L]) :- not(In = H), replace(FRes,In,Out,L), Res=[H|FRes] . replacegrid([],_,_,[]). replacegrid(Res,In,Out,[H|T]) :- replace(HRes,In,Out,H), replacegrid(TRes,In,Out,T), Res=[HRes|TRes]. % grabA find an element at coordinate Xpos,Ypos within a list of lists. grabB is finds an % element at coordinate Xpos within a list (i.e. the Xpos element). grabA(Res,Xpos,1,[H|_]) :- !,grabB(Res,Xpos,H). grabA(Res, Xpos,Ypos,[_|T]) :- Yposnew is Ypos - 1, grabA(Res, Xpos, Yposnew, T) . grabB(Res, 1 ,[H|_]) :- !,Res = H. grabB(Res, Xpos ,[_|T]) :- Xposnew is Xpos - 1, grabB(Res, Xposnew, T). % This function is not implemented. If it was, Res would be equal to L, excepting that all % instances of A would be replaced by B and visa versa. switch(Res,A,B,L) :- write('Not implemented'), nl, fail. % Move utility function % Move from C,D into A,B, so long as A,B is empty. % Makes the valid assumption that tile names are unique. move(Res,L,A,B,C,D) :- grabA(' ',A,B,L), grabA(E,C,D,L), switch(Res,' ',E,L).