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) ?
首先,什么序言与回应确实是一个实现细节。 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.