【问题标题】:Prolog simple programProlog 简单程序
【发布时间】:2014-02-03 06:22:50
【问题描述】:

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

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

【问题讨论】:

    标签: prolog dcg


    【解决方案1】:

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

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

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

    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")。很容易将其分离为单个原子:use atomic_list_concat/3。对于what is allan,你仍然不需要做一些特别的事情;这是一个 3 个单词的句子,其余的是 4 个,所以你可以立即将它分开。

    【讨论】:

    • 您好,谢谢您的回答。这是一个很好的解决方法,但如果我想在这个程序中添加一些其他功能,比如input([What,is,allan]).,这个通配符会带来麻烦。你能帮我解决这个问题的更通用的方法吗?谢谢
    • @AllanJiang 检查我的编辑;但是,解析任何句子的解决方案都非常困难:p
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-02
    • 1970-01-01
    相关资源
    最近更新 更多