序言,查询虚假陈述时错误(Prolog, error when querying a false s

2019-08-31 22:43发布

input :-
read_line_to_codes(user_input, Input),
string_to_atom(Input,Atoms),
atomic_list_concat(Alist, ' ', Atoms),
phrase(sentence(S), Alist),
action(S).


statement(Rule) --> [Noun, 'is', 'a', Object], { Rule =.. [Object, Noun]}.
statement1(Rule) --> ['A', Noun, 'is', 'a', Object], { Rule =.. [Object, Noun]}.
query(Fact) --> ['Is', Noun, 'a', Object], { Fact =.. [Object, Noun]}.

sentence(statement(S)) --> statement(S).
sentence(statement1(S))--> statement1(S).
sentence(query(Q)) --> query(Q).


action(statement(S)) :- asserta(S) -> write(ok).
action(statement1(S)) :- asserta(S) -> write(ok).
action(query(Q)) :-( Q -> write(yes); write(unknown)), nl.

分配是创建表单用户输入规则“_是_。” 或 “A _是_。” 这应该用“OK”回应。

然后可以查询“是一个_ _?” 并以“是”或“不知道”回应。 我不知道为什么它给一个错误,如果谓词(我认为这就是它被称为“火腿”)是不是在数据库中,但它与在那里不是另一部分罚款。 任何想法,我做错了什么? 和抱歉,如果我做的东西简直是愚蠢的,第一次用序言。 我使用的是SWI-Prolog的V.6.2.6如果该事项。 我怎么会去忽略在输出中的真或假的回报

   11 ?- input.
   |: john is a dog
   ok
   true .

   12 ?- input.
   |: Is john a dog
   yes
   true.


   13 ?- input.
   |: Is abraham a dog
   unknown
   false.

   14 ?- input.
   |: Is john a ham
   ERROR: action/1: Undefined procedure: ham/1
   Exception: (8) ham(john) ? 

Answer 1:

首先,什么序言与回应确实是一个实现细节。 SWI回应“真”,但一些其他实施方式回应“OK”。 没有什么可以改变你的,因为这些代码,只要你得到affirmatives和底片时,你应该。

第二,你的狗和火腿例子之间的差异。 看看你的数据库试样输入已经被处理后:

?- listing.
⋮ 
:- dynamic dog/1.

dog(john).
⋮

哪里的ham/1 ? 无处。 当你asserta(dog(john))序言中获悉dog/1是谓语,但从来没有发生过与ham/1 。 所以,你必须决定是否良好,形成查询,在这种情况下,你要捕获异常或者与预先声明你的所有可能的谓词dynamic/1 ,或高兴的是,它没有很好地形成。 您的使用情况将决定哪个是适当的。 例如,你可能只是这样做:

?- [user].
|: :- dynamic ham/1.
|: % user://2 compiled 0.00 sec, 1 clauses
true.

?- input.
|: Is john a ham
false.

我怀疑你会想这样做的一切,所以你可能会想看看SWI-Prolog的的捕捉设备 。 看到这个答案底部的编辑对于如何处理它的一个例子。

另外,我可能会返工的DCG一点点,使其多了几分一般和简单的:

article --> [a].
article --> [the].
article --> [].

noun(Noun) --> article, [Noun].

statement(Rule) --> noun(Noun), [is], noun(Object), { Rule =.. [Object, Noun] }.
query(Fact) --> ['Is'], noun(Noun), noun(Object), { Fact =.. [Object, Noun]}.

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

action(statement(S)) :- asserta(S).
action(query(Q)) :- Q.

另外,有没有真正的需要,使statement1 。 你可以有一个以上的身体DCG规则; 即使你确实需要两具尸体,你可以有他们两个产生statement/1结构的匹配action/1 ; 你肯定不需要传播statement1/1下那么远到你的代码的其余部分。

最后一句话,你不需要引用小写原子。 :)

总的来说,我觉得你在这里做了很好的工作! 这是硬的东西要学,材料网上是非常稀疏。 我希望你坚持的话,你可能会开始看到各种很酷的事情,你可以用序言和DCG中呢!

编辑 :您可以捕获错误并通过更换你的最后妥善处理action/1本条款:

action(query(Q)) :- 
    catch((Q -> write(yes) ; write(unknown)), 
          error(existence_error(procedure, _), _), 
          write(unknown)), 
    nl.


文章来源: Prolog, error when querying a false statement
标签: prolog dcg