0

我正在编写一个小 Prolog 程序,预计将执行以下操作:

?-input([allan,is,a,name]).
 true.
?-input([Is,allan,a,name]).
 true.

这是我的代码:

% Simple answering agent

input(Text) :-
phrase(sentence(S), Text), 
perform(S).

sentence(statement(S)) --> statement(S).

sentence(query(Q))     --> query(Q).

statement(Statement) --> 
    [Thing, 'is', 'a', Category],
    { Statement =.. [Category, Thing]}.

query(Query) --> 
   ['Is', Thing, 'a', Category],
   { Query =.. [Category, Thing]}.

perform(statement(S)) :- asserta(S).

perform(query(Q))     :- Q.

input([allan,is,a,name]).部分似乎工作正常,但查询部分有问题,如果我输入input([Is,allan,a,name]).,它会打印

Is = 'Is'

谁能帮我看看这个问题,谢谢。

4

1 回答 1

2

好吧,问题在于它Is是一个变量,因此 prolog 实例化它(使用'Is')。确保列表的所有成员都是原子是一种很好的做法,但为了快速修复,您可以这样做:

query(Query) --> 
[_, Thing, 'a', Category],
{ Query =.. [Category, Thing]}.

这样,Is不会被实例化,prolog 只会说真。唯一的问题是一个语句可以被解释为一个查询:

9 ?- input([allan, is, a, name]).
true ;                                   
false.                                   

10 ?- input([is, is, a, name]).       
true .                                   

11 ?- input([allan, is, a, name]).       
true ;                                   
true.

可以通过一些削减来修复(或者说Thing应该不同于'is'- 如果可以接受的话)

编辑:对于更通用的解决方案:这实际上取决于您要解析的句子类型以及用户可以做出的妥协。例如,也许可以让他给你一些序言原子的词;如果请求以大写字母开头的单词,他将不得不使用''. 否则,最好将它们放在字符串/原子('Is allan a name'"Is allan a name")中。将其分离为单个原子很容易:使用 atomic_list_concat/3。因为what is allan你仍然不需要做一些特别的事情;这是一个 3 个单词的句子,而其余的是 4 个单词,因此您可以立即将其分开。

于 2012-10-14T18:10:31.800 回答