recursion - swi prolog simple robot -
i writing program in prolog should interact user. have database of bands , dislike, , can ask prolog these bands. first have
hello.
to prolog, , prolog answers hello , can start asking questions like
do band motorhead?
and prolog should answer
yes band because rock.
then should able ask question.
my initial idea achieve last word of question, check if in 1 of 2 list (liked-list or disliked-list), , recursively call function interact program.
in fact code works well, except 1 annoying detail can't solve. here problem:
?- hello. hello! ask question: band motorhead? band because metal. ask question: don't know band. ask question: band motorhead band because metal.
in fact when add question mark @ end of question, prolog answers question (no problem here), recursively call function ask questions, , adds "i don't know band" , calls once again function ask questions instead of calling once, , waiting me type question.
here current code interacting prolog
hello :- write('hello!'),nl, ask. ask :- write('ask question: '), getsentence(x), last(word, x), process(word). process(stop) :- !. process(hello) :- hello, !. process(x) :- (like-list(likelist), member(x, likelist), type(x, style), write('i band because '), write(style), write('.'), nl ; dislike-list(dislikelist), member(x, dislikelist), write('i don\'t band.'), nl ; write('i don\'t know band.'), nl), ask.
and here current code parsing user types:
getsentence( wordlist) :- get0( char), getrest( char, wordlist). getrest( 46, [] ) :- !. % end of sentence: 46 = ascii '.' getrest( 63, [] ) :- !. % 63 = ascii '?' getrest( 10, [] ) :- !. % 10 = ascii '\n' getrest( 13, [] ) :- !. % 13 = ascii 'cr' getrest( 32, wordlist) :- !, % 32 = ascii blank getsentence( wordlist). % skip blank getrest( letter, [word | wordlist] ) :- getletters( letter, letters, nextchar), % read letters of current word name( word, letters), getrest( nextchar, wordlist). getletters( 46, [], 46) :- !. % end of word: 46 = full stop getletters( 63, [], 63) :- !. getletters( 10, [], 63) :- !. getletters( 13, [], 63) :- !. getletters( 32, [], 32) :- !. % end of word: 32 = blank getletters( let, [let | letters], nextchar) :- get0( char), getletters( char, letters, nextchar). last(item, list) :- append(_, [item], list),!.
ok managed solve problem taking different approach. hope of use anyone.
hello :- write_ln('robot: hello!'), ask. /* read_line_to_codes converts user typed ascii codes, , * atom_codes, reconstruct question list of ascii codes. */ ask :- write('me: '), read_line_to_codes(user_input, codes), atom_codes(x, codes), process(x), !. process(stop) :- !. process(hello) :- hello. process(x) :- ((sub_atom(x, _, _, _, 'do band '), like-list(list), searchforlikes(x, list, band, style), write('robot: '), write('i '), write(band), write(' because '), write(style), write_ln('.') ); (sub_atom(x, _, _, _, 'do band '), dislike-list(list), searchfordislikes(x, list, band, style), write('robot: '), write('i don\'t '), write(band), write(' because '), write(style), write_ln('.') ); (x=='what bands like?', like-list(likelist), write_ln(likelist) ); (x=='what bands don\'t like?', dislike-list(dislikelist), write_ln(dislikelist) ); (sub_atom(x, _, _, _, 'do band '), write('robot: '), write_ln('i don\'t know band.') ); (write('robot: '), write_ln('i don\'t understand question.')) ), ask. /* * term_to_atom transforms example "ac-dc" "'ac-dc'" in order particular atom in string. * lookup done function sub_atom (it searches band in string x). */ searchforlikes(_, [], _) :- !, fail. searchforlikes(x, [head|tail], band, style) :- (term_to_atom(head, band), sub_atom(x, _, _, _, band), type(head, style), !); searchforlikes(x,tail, band, style). searchfordislikes(_, [], _) :- !, fail. searchfordislikes(x, [head|tail], band, style) :- (term_to_atom(head, band), sub_atom(x, _, _, _, band), type(head, style), !); searchfordislikes(x,tail, band, style).
the main difference of code first 1 use of built in functions.
Comments
Post a Comment