2016-07-22 6 views
0

私はSWI-Prologを使っていくつかの相互再帰制約を解決しようとしています。これらの制約は比較的簡単ですが、これらの述語のいずれかを照会することは無限再帰につながる:Prologで相互再帰制約を解く

%If X is an animal, then X is a bird or a mammal, and vice-versa. 
animal(X) :- 
    (mammal(X);bird(X)), 
    (male(X);female(X)). 

male(X) :- animal(X). 
female(X) :- animal(X). 

bird(X) :- (X='parrot';X='pigeon'),animal(X). 

mammal(X) :- (X='cat';X='dog'),animal(X). 

彼ら非再帰的にすることなくPrologで、これらの制約を解決することができるでしょうか?

私はいくつかの基本例と同様のプログラムを書いたが、クエリmammal(X),bird(X)はまだ代わりにfalseを返すの無限再帰につながる:再帰的な制約を解決

%If X is an animal, then X is a bird or a mammal, and vice-versa. 
animal(X) :- 
    (mammal(X);bird(X)). 

bird('parrot'). 
bird('pigeon'). 
bird(X) :- (X='parrot';X='pigeon'),animal(X). 

mammal('cat'). 
mammal('dog'). 
mammal(X) :- (X='cat';X='dog'),animal(X). 
+2

あなたはプロローグ述語が返されないことを実現関数のような値は、そうですか?だから 'dif(哺乳類(X)、鳥(X))'はおそらくあなたが思っていることをしません。実際には、「哺乳動物(X)」と「鳥(X)」という言葉は常に「X」で必ずしも異なるため、常に成功するでしょう。スコットが彼の "答え"で指摘するように、あなたは事実や基本事例を持っていません。 – lurker

+0

@lurkerはい、この場合、 'dif/2'述語は重複しています。私はこの問題を解決するためにプログラムを編集しました。 –

+0

彼らは冗長ではありませんでした。彼らは誤って使用された。 :pあなたの既存のロジックは、スコットが指摘しているように基本ケースが欠けているだけでなく、円形です。 「動物/ 1」は、「男性/ 1」、「女性/ 1」、および「哺乳類/ 1」という用語で定義される。また、「男性/ 1」、「女性/ 1」、「哺乳動物/ 1」は「動物/ 1」で定義される。 – lurker

答えて

3

constraint handling rulesを使用して、相互再帰制約の解を見つけることは可能です。

これは相互再帰的な制約のセットです:

%If X is an animal, then X is a bird or a mammal, and vice-versa. 
:- use_module(library(chr)). 

:- chr_constraint mammal/2,bird/2,animal/1,male/1,female/1,species/2. 

animal(X) <=> 
    (mammal(X,Species);bird(X,Species)), 
    (male(X);female(X)). 

male(X),female(X) ==> false. 

bird(X,Species) <=> member(Species,[parrot,pigeon,crow]),species(X,Species). 
bird(X,Species) ==> animal(X). 

mammal(X,Species) <=> member(Species,[cat,dog,bull]),species(X,Species). 
mammal(X,Species) ==> animal(X). 

species(X,bull) ==> male(X). 

...と、これは、このプログラムのためのクエリの出力です:

?- male(X),mammal(X,Species). 
male(_G67406) 
species(_G67406,cat) 
Species = cat 
3

は、1つまたは複数の基地ケースが必要です。あなたは何も提供していません。問題はPrologではない。その問題の定義を持つ。

+0

もちろん、これらの相互再帰制約を非再帰制約として書き直すことは可能ですが、私の目標は手動で書き直すことなく相互に再帰制約を解決することです。これを簡単にするPrologの[SMTソルバ](https://www.cs.kent.ac.uk/pubs/2012/3136/content.pdf)があります。 –

+1

ベースケースを持たない再帰的な問題を「解決」できるようなソルバはありません。ベースケースを追加しても非再帰的にはなりません。ベースケースは再帰的定義の*一部*です。 –

+0

Q:「Prologでこれらの制約を非再帰的にすることなく解くことは可能でしょうか?私はなぜ問題が悪く形成されたのかを解明できませんでした。 –

2

私はあなたが鳥を持ち、哺乳類を持っているということを考えていると思います。また、鳥や哺乳動物であれば、動物は動物であることを証明しようとしています。

現在、コードは過度に指定されており、循環ロジックを持っています。コードを歩い

は...

animal(X) :- 
    (mammal(X); bird(X)). 

これはXXmammalまたはXbirdであるanimal場合であると述べています。ここまでは順調ですね。

birdの説明が読み取ります

bird('parrot'). 
bird('pigeon'). 

これらはparrotbirdで、pigeonbirdであることを示している事実です。

bird(X) :- (X='parrot';X='pigeon'),animal(X). 

XXはどちらかparrotまたはpigeonされ、X場合animalあるbird場合であると述べている。しかし、このルールがあります。以前の2つの事実は、すでにparrotpigeonが鳥であることを証明しています。このルールはなぜ必要なのですか?また、Xanimalであり、順にbirdmammalという形で定義されているという条件が追加されているため、円形です。

mammalの定義についても同様です。これは、哺乳類のために必要な事実があります。その後、

mammal('cat'). 
mammal('dog'). 

と円形ロジックとoverspecifies

mammal(X) :- (X='cat';X='dog'), animal(X). 

あなたが必要なものの本質は単純です:

bird('parrot'). 
bird('pigeon'). 

mammal('cat'). 
mammal('dog'). 

animal(X) :- 
    mammal(X); bird(X). 

このロジックを定義どの生き物が鳥や哺乳類で事実を使っているのかを知っていれば、鳥や哺乳類であることが知られている場合、それは動物です。

+0

このソリューションはこの場合には機能しますが、私の目標は、非再帰的な形で手動で書き換えることなく、相互に再帰的な制約を解決することです。これを行うには、[CHR](https://en.wikipedia.org/wiki)のような[forward-chaining](https://en.wikipedia.org/wiki/Forward_chaining)推論エンジンを使用する必要があります/ Constraint_Handling_Rules)。 –

2

Prologシステムのテーブルメカニズムを有効にすることが、このような問題の解決策の1つです。 SWI-Prologの(最新の開発版)で例えば

、私は単にあなたのプログラムの開始時に次のディレクティブを追加した場合:

:- use_module(library(tabling)). 

:- table animal/1. 

それから私は、例えば取得:

 
?- animal(X). 
false. 

?- male(X). 
false. 

?- bird(X). 
false. 

したがって、これらのケースではまだ解決策は見つけられませんが、少なくとも回答は得られます。