2016-11-01 12 views
1

カテゴリの束と、それらのカテゴリのアイテムを想定します。いくつかのカテゴリは、他のものの同義語です。たとえば、mobile_phoneやcell_phoneなどです。規則syn(mobile_phone, cell_phone).is_a(iphone, cell_phone).が与えられているので、ナレッジベースにその規則が存在しない場合でも、真を返すためにis_a(iphone, mobile_phone).を呼び出す必要があります。ここで推移プロパティは、プロローグ内で無限ループを引き起こします

は、私が持っているものだ。これは何をしたい

is_syn('antibiotics' , 'antineoplastics'). 

is_a('mitomycin', 'antibiotics'). 
is_a('doxorubicin liposomal', 'antineoplastics'). 
is_a('idarubicin', 'antineoplastics'). 
is_a('pentostatin', 'antibiotics'). 

syn(X, Y) :- 
    ( is_syn(Y, X) 
    ; is_syn(X, Y) 
    ). 

is_a(X, Y) :- 
    syn(Y, Z), 
    is_a(X, Z). 
+0

ファクトを明示的に追加して、問題を再現できるようにしてください。 – false

+0

スニペットを追加しました。はっきりするために、出力されていますが、同じ出力上で繰り返しループします。 – bendl

+0

この例では、私が観察したエラーを再現しています。電話に関しては...もちろん、分かりやすくするためでした。 'is_a( 'idarubicin'、X)のクエリを試してください。それは無限に抗新生物を返します。さらに悪いことに 'is_a(something、X) 'のようなクエリです。何も出力なしで無限ループします。 – bendl

答えて

1

をするのでしょうか?戻る我々はスタート地点へ

[1] is_a(V1,Y) 
[1] syn(V1, V2) 
[2] is_a(V2, Y) 
[2] syn(V2, V1) 
[3] is_a(V1,Y) 

is_syn('antibiotics' , 'antineoplastics'). 

fact_is_a('mitomycin', 'antibiotics'). 
fact_is_a('doxorubicin liposomal', 'antineoplastics'). 
fact_is_a('idarubicin', 'antineoplastics'). 
fact_is_a('pentostatin', 'antibiotics'). 

syn(X,X). % So we don't lose the obvious facts. 
syn(X, Y) :- 
    ( is_syn(Y, X) 
    ; is_syn(X, Y) 
    ). 

is_a(X, Y) :- 
    syn(X,S), 
    fact_is_a(S,Z), 
    syn(Z,Y). % Returns all synonyms of Z 

is_a(X, Y) :- % Does the transitive part of is_a 
    syn(X,S), 
    fact_is_a(S,Z), 
    is_a(Z,Y). 

私はあなたが持っていた問題は、このようなスタックだったと思います。

これと同じように、ファクトを別のもの(これははるかにエレガントなもの)と呼ぶことなく実現することができます。もしあなたがそのようなポイントに達するなら、私はそれを見たいので、投稿してください。

+0

これは完全に機能します。残念ながら、このプロジェクトにはかなりの時間がかかり、誰もコードのこの部分を見ることはありませんので、見た目はそれほど重要ではありません。 – bendl

関連する問題