0
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.

割り当ては、「_ is a _.」という形式のユーザー入力からルールを作成することです。または「 _ は _ です。」これは「OK」で応答するはずです。

そして、「Is _ a _?」をクエリできるようにします。そして、「はい」または「不明」で応答します。述語(「ハム」と呼ばれるものだと思います)がデータベースにない場合にエラーが発生する理由はわかりませんが、他の部分がそこになくても問題ありません。私が間違っていることについてのアイデアはありますか?そして、プロローグで初めて、単純にばかげたことをしている場合は申し訳ありません。問題がある場合は、SWI-Prolog V.6.2.6 を使用しています。そして、出力で true または false の戻り値を省略するにはどうすればよいでしょうか

   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) ? 
4

1 に答える 1

0

まず、Prolog が応答するのは、実際には実装の詳細です。SWI は「true」と応答しますが、他の一部の実装は「ok」と応答します。そのため、必要なときに肯定と否定を取得している限り、コードを変更する必要はありません。

第二に、犬とハムの例には違いがあります。サンプル入力が処理された後、データベースを確認します。

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

dog(john).
⋮

どこham/1ですか?どこにもない。するとasserta(dog(john))、Prolog は が述語であることに気づきます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 のcatch 機能を見たいと思うでしょう。処理方法の例については、この回答の下部にある編集を参照してください。

また、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 ルールを持つことができます。2 つのボディが必要な場合でも、両方statement/1で一致する構造を生成することができaction/1ます。statement1/1コードの残りの部分にそこまで伝播する必要はありません。

最後に、小文字のアトムを引用する必要はありません。:)

全体的に、あなたはここでかなり良い仕事をしていると思います!これは学ぶのが難しいことであり、オンラインの資料はかなりまばらです。Prolog と DCG でできるクールなことに気付き始めていることでしょう。

編集action/1:最後の句を次のように置き換えることで、エラーをキャッチして適切に処理できます。

action(query(Q)) :- 
    catch((Q -> write(yes) ; write(unknown)), 
          error(existence_error(procedure, _), _), 
          write(unknown)), 
    nl.
于 2013-04-23T16:48:06.293 に答える