3

これは、誰がjohnと互換性があるかを調べる必要があるプログラムです。私はPrologを初めて使用します。Prologに知らせるために例えば。met(X、Y)= met(Y、X)たくさんのコードが書かれています。クエリを開始すると

?- compatible(john, X)

それは無限のループに入ります...

ソースコード:

compatible(X,Y) :- reading(X), reading(Y).
compatible(X,Y) :- football(X), football(Y).
compatible(X,Y) :- friends(X,Y).
compatible(X,Y) :- mutual(X,Y).
friends(X,Y) :- havemet(X,Y), compatible(X,Y).
havemet(X,Y) :- met(X,Y).
havemet(X,Y) :- met(Y,X).
mutual(X,Y) :- friends(X,Temp), friends(Y,Temp).
mutual(X,Y) :- friends(Temp,X), friends(Y,Temp).
mutual(X,Y) :- friends(X,Temp), friends(Temp,Y).
mutual(X,Y) :- friends(Temp,X), friends(Temp,Y).

football(john).
football(james).
friends(john, carl).
friends(carl, john).
reading(carl).
reading(fred).
reading(emily).
met(carl, emily).
met(fred, james).
met(fred, emily).

私はこれまで多くのことを研究してきましたが、何が問題で、どのようにそれを修正するのかまだわかりません。私を助けてくれるといいですね。

4

3 に答える 3

2

あなたが無限ループに陥ったのは驚きではありません。compatibleに依存しますがfriendsfriends依存しcompatibleます。これがあなたが望むものであると確信していますか?

ルールを再帰的にしたい場合は、停止条件が必要になることに注意してください。しかし、アフィニティマッチングなどの単純な問題に対して、なぜ再帰が必要になるのかわかりません。

于 2013-01-27T14:05:09.340 に答える
2

それで、あなたのプログラムの問題は何ですか?これがあなたが抱えている問題を特定する方法です。ゴールを挿入することにより、失敗スライスfalseを取得します。これは、元のプログラムとまだ多くのプロパティを共有しているフラグメントです。特に、失敗スライスがループする場合、元のプログラムもループします。したがって、失敗スライスは、元の問題を克服するために変更する必要があるプログラムの一部を示しています。あなたのクエリに対して、私はまだ終了しない次のフラグメントを取得します:

?-互換性(john、X)、false互換性(X、Y):- false、reading(X)、reading(Y)互換性(X、Y):- false、football(X)、football(Y)互換性(X、Y):- false、friends(X、Y)。
互換性(X、Y):-相互(X、Y)、false。

friends(X、Y):-havemet(X、Y)、compatible(X、Y)。
友達(ジョン、カール):- false。
友達(カール、ジョン)。

havemet(X、Y):- false、met(X、Y)。
havemet(X、Y):-met(Y、X)。

相互(X、Y):- false、friends(X、Temp)、friends(Y、Temp)。
相互(X、Y):-フレンズ(Temp、X)、フレンズ(Y、Temp)、false。
相互(X、Y):-友達(X、Temp)、空似言葉友達(Temp、Y)相互(X、Y):- false、friends(Temp、X)、friends(Temp、Y)。

会った(カール、エミリー)。
met(fred、james):- falsemet(fred、emily):- false

compatible/2しかし、終了するためのクエリだけではいけませんか?最も一般的なクエリの場合、失敗スライスをさらに減らすことができます。

?-互換性(X、Y)、false互換性(X、Y):- false、reading(X)、reading(Y)互換性(X、Y):- false、football(X)、football(Y)互換性(X、Y):- false、friends(X、Y)。
互換性(X、Y):-相互(X、Y)、false。

friends(X、Y):-havemet(X、Y)、compatible(X、Y)。
友達(ジョン、カール):- falseフレンズ(カール、ジョン):- falsehavemet(X、Y):- false、met(X、Y)。
havemet(X、Y):-met(Y、X)。

相互(X、Y):- false、friends(X、Temp)、friends(Y、Temp)相互(X、Y):- false、friends(Temp、X)、friends(Y、Temp)。
相互(X、Y):-友達(X、Temp)、空似言葉友達(Temp、Y)相互(X、Y):- false、friends(Temp、X)、friends(Temp、Y)。

会った(カール、エミリー)。
met(fred、james):- falsemet(fred、emily):- false

なんとかして問題を修正しなければならないのは、ここの残りの部分です。非終了にはさらに理由があるかもしれません。ただし、いずれの場合もこれを修正する必要があります。

それでも十分でない場合はV = const、プログラムに目標を追加することができます。しかし、これで十分だと思います...

于 2013-01-27T20:27:05.810 に答える
2

どのPrologシステムを使用していますか?特定のシステムを使用する必要がありますか?

プログラムはそのままでは標準のPrologで終了しませんが、XSB-Prologhttp://xsb.sourceforge.net/やB-Prologhttp://www.probp.comなどのタブリングサポート付きのPrologで終了ます。 /:- auto_table. -プログラムの最初の行として追加するだけです。

| ?- compatible(john, X).
compatible(john, X).
X = john ?;
X = james ?;
X = carl ?;
X = emily ?;
no
于 2013-01-27T21:18:22.810 に答える