我正在prolog中编写一个应该与用户交互的程序。我有一个我喜欢的乐队数据库,我不喜欢,我可以问这些乐队的序言。首先我要说
hello.
到prolog,prolog回答你好,我可以开始问像
这样的问题了do you like the band motorhead?
和prolog应该回答
yes i like the band because it is rock.
然后我应该能够提出另一个问题。
我最初的想法是获得问题的最后一句话,检查它是否在两个列表之一(likes-list或disliked-list)中,然后递归调用该函数与程序交互
事实上我的代码效果很好,除了一个我无法解决的烦人细节。这是我的问题:
?- 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),!.
答案 0 :(得分:0)
好的,我设法通过采用不同的方法来解决我的问题。 我希望这对任何人都有用。
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).
此代码与第一个代码的主要区别在于使用内置函数。