Recursion 简单机器人
我正在用prolog编写一个程序,它应该与用户交互。我有一个我喜欢和不喜欢的乐队的数据库,我可以问prolog关于这些乐队的情况。首先我得说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. 那么我应该可以问另一个问题了 我最初的想法是得到问题的最后一个字,检查它是否在两个列表中的一个喜
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).
这段代码与第一段代码的主要区别在于使用了内置函数