Recursion 简单机器人

Recursion 简单机器人,recursion,io,prolog,Recursion,Io,Prolog,我正在用prolog编写一个程序,它应该与用户交互。我有一个我喜欢和不喜欢的乐队的数据库,我可以问prolog关于这些乐队的情况。首先我得说 hello. 到prolog,prolog回答hello,我可以开始问这样的问题 do you like the band motorhead? prolog应该回答这个问题 yes i like the band because it is rock. 那么我应该可以问另一个问题了 我最初的想法是得到问题的最后一个字,检查它是否在两个列表中的一个喜

我正在用prolog编写一个程序,它应该与用户交互。我有一个我喜欢和不喜欢的乐队的数据库,我可以问prolog关于这些乐队的情况。首先我得说

hello.
到prolog,prolog回答hello,我可以开始问这样的问题

do you like the band motorhead?
prolog应该回答这个问题

yes i like the band because it is rock.
那么我应该可以问另一个问题了

我最初的想法是得到问题的最后一个字,检查它是否在两个列表中的一个喜欢的列表或不喜欢的列表中,然后递归调用函数与程序交互

事实上,我的代码运行良好,除了一个我无法解决的恼人细节。我的问题是:

?- hello.
hello!
Ask your question: do you like the band motorhead?
I like the band because it is metal.
Ask your question: I don't know that band.
Ask your question: do you like the band motorhead
I like the band because it is metal.
事实上,当我在问题的末尾添加一个问号时,prolog在这里回答问题“没问题”,递归调用函数提问,然后添加“我不知道那个波段”,并再次调用函数提问,而不是调用一次,然后等待我键入另一个问题

下面是我当前与prolog交互的代码

hello :- write('hello!'),nl, ask.
ask :- write('Ask your 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 like the band because it is '), write(Style), write('.'), nl
   ;
   dislike-list(DisLikeList), member(X, DisLikeList),
   write('I don\'t like that band.'), nl
   ;
   write('I don\'t know that band.'), nl),
  ask.
下面是我当前用于解析用户类型的代码:

getsentence( Wordlist)  :-
  get0( Char),
  getrest( Char, Wordlist).

getrest( 46, [] )  :-  !.               % End of sentence: 46 = ASCII for '.'
getrest( 63, [] )  :-  !.               % 63 = ASCII for '?'
getrest( 10, [] )  :-  !.               % 10 = ASCII for '\n'
getrest( 13, [] )  :-  !.               % 13 = ASCII for 'CR'

getrest( 32, Wordlist)  :-  !,          % 32 = ASCII for blank   
 getsentence( Wordlist).                % Skip the 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),!.

好的,我通过采取不同的方法解决了我的问题。 我希望这对任何人都有用

hello :-
  write_ln('Robot: Hello!'),
  ask.

/* read_line_to_codes converts what the user typed to ASCII codes, and then
 * with atom_codes, I reconstruct the question from the 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 you like the band '),
   like-list(List),
   searchForLikes(X, List, Band, Style),
   write('Robot: '),
   write('I like '),
   write(Band),
   write(' because it is '),
   write(Style), write_ln('.')
  );
   (sub_atom(X, _, _, _, 'do you like the band '),
    dislike-list(List),
   searchForDislikes(X, List, Band, Style),
   write('Robot: '),
   write('I don\'t like '),
   write(Band),
   write(' because it is '),
   write(Style), write_ln('.')
  );
  (X=='what bands do you like?',
   like-list(LikeList),
   write_ln(LikeList)
  );
  (X=='what bands don\'t you like?',
   dislike-list(DislikeList),
   write_ln(DislikeList)
  );
  (sub_atom(X, _, _, _, 'do you like the band '),
   write('Robot: '),
   write_ln('I don\'t know that band.')
  );
  (write('Robot: '),
  write_ln('I don\'t understand the question.'))
  ),
  ask.

/* 
 * term_to_atom transforms for example "ac-dc" to "'ac-dc'" in order to look for that particular atom in the String. 
 * The lookup is done with the function sub_atom (it searches the Band in the 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).
这段代码与第一段代码的主要区别在于使用了内置函数