2017-10-30 9 views
2

チェスをした人のグループがあるとします。あなたは決して誰にも負ける(無敗の)プレーヤーが存在するかどうかを判断したい。事実がウォン(ジェームス、トム)として与えられたと仮定しよう。ウォン(ジェイムス、ピーター)、ウォン(クレイグ、トム)。失われた(ピーター、トム)。すると、条件に応じてプレーヤーXが失われたことはありません。相互に排他的な、またはプロローグの作成

undefeated(X) :- \+ won(_, X), \+ lost(X, _). 

ので、無敗(ジェームズ)(クレイグ)真と無敗のですが(ピーター)真が、無敗(トム)と無敗のですfalseです。今、問題は、単にnoを返すので、無敗(X)を呼び出すときに発生します。これを解決するために、開始時に常に真であるステートメントが必要なので、白と黒の部分をそれぞれ再生するプレイヤーに対して、事実whiteplayer()とblackplayer()を追加します。

whiteplayer(james). 
whiteplayer(craig). 
whiteplayer(tom). 
whiteplayer(peter). 
blackplayer(james). 
blackplayer(peter). 
blackplayer(tom). 

との無敗変更:

undefeated(X) :- (whiteplayer(X); blackplayer(X)), \+ won(_, X), \+ lost(X, _). 

しかし、今、私たちは新たな問題に遭遇。無敗の(X)を照会すると、ジェイムズ、クレイグ、ジェイムズのソリューションが得られます。これは、ジェイムズが白黒の両方の作品を再生するためですが、クレイグは白い部分のみを再生するためです。だから、問題は無敗です(ジェイムス)は、ホワイトプレーヤ(ジェイムス)とブラックプレーヤ(ジェイムズ)の両方で続行しています。バックトラック中にこれらの1つのみを処​​理するためにはどうすればいいですか?

+2

データベースに「won/2」と「lost/2」の両方の事実があるのはなぜですか?彼らは重複しており、混乱を招いています。 '(X、Y)'が 'lost(Y、X)'に相当しますか? – lurker

+1

@lurkerはい、それは同等です。残念ながら、私は両者を扱っていません。 – Greg

答えて

3

、あなたは(また、その後、一般的に望ましくない有効なソリューションを、排除)カットを使用しない限り、重複を取得するつもりです、重複を排除するsetof(または「手動」)を使用して冗長サブソリューションを収集することもできます。

だから、このような何かを行うことができます:あなたはそれが任意のプレーヤーのために一度成功し、切断しないvalidplayer/1ように定義することができた場合

validplayer(X) :- whiteplayer(X) ; blackplayer(X). 

undefeated(Player) :- 
    setof(P, validplayer(P), Players), 
    member(Player, Players), 
    \+ won(_, Player), \+ lost(Player, _). 

理想的には、それは良いでしょう。しかし、あなたの現在の事実の定義はこれを有効にしません。

won(X, Y)lost(Y, X)に相当するので、won/2lost/2の両方の事実を必要としないことをお勧めします。どちらか一方に固執するのが最善です。うまくいけば、あなたのデータベースにwon(john, paul)lost(paul, john)の両方が存在しないか、上記の解決策が依然として重複していて、undefeated/1setof(U, undefeated(U), ListOfUndefeatedPlayers)setof/3を実行する必要があるでしょう。

0

Xから勝った人が少なくとも1人いることがわかっている場合、Xは無敗ではありません。単にZのようにZXであることがわかります。これは、プロローグが一致を見つけて、真を返そうとし、その値を偽で反転し、他のすべての枝を切り捨てることを意味します。

同じことは偽造されていない人になります。この場合、プロローグは一致を検出せず、値を反転させることなくfalseを返します。

私はあなたの質問者を理解していれば、これはあなたのコードです。常に何が起きているのかを見るためにguitracerを使うのは良いことです。あなたの事実と規則は、変数の特定のインスタンス化は、複数の方法を成功できるようにする場合は

won(james,tom). 
won(james,peter). 
won(craig,tom). 
lost(peter,tom). 



undefeated(X):- 
    \+ won(_Z,X),!. 
+1

'undefeated(X)'クエリの結果は解決されません。 – lurker

+0

彼はパラメターとして用語で無敗を呼ぶべきでないか、彼は無敗でないすべての人々を見つけることを試みているべきである! –

+1

失われた事実(james、tom)を追加すると、これは失敗します。また、無敗(X)のすべてのソリューションを返すことはありません – Greg

関連する問題