Prolog简单程序

时间:2012-10-14 17:51:28

标签: prolog dcg

我正在写一个小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'

有人可以帮我看一下这个问题,谢谢。

1 个答案:

答案 0 :(得分: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'不同 - 如果可以接受的话)

编辑:对于更通用的解决方案:它实际上取决于您要解析的句子类型以及用户可以做出的妥协。例如,有可能让他给你一些prolog原子的话;如果请求以大写字母开头的单词,则必须使用''。否则,最好只用字符串/原子('Is allan a name'"Is allan a name")给出它们。将它与单个原子分开很容易:use atomic_list_concat/3。对于what is allan,你仍然不需要做一些特殊的事情;这是一个3个字的句子,其余的是4个,所以你可以立即分开。