2017-08-22 10 views
3

私はPrologでEinstein Riddleを解決しようとしています。Prologでアインシュタインの謎を解く

私が書いたプログラムには問題がありますが、基本的な方法はすべての制約を追加し、Prologに唯一の解決策を見つけさせることでした。

問題は、Prologが0解決策を見つけることです。私は、プログラムを特定の解決策から解決策に変えるという制約を分けていますが、なぜそれが理解できません。

?- riddle(Houses). 
Houses = list(house(green, norwegian, coffee, marlbero, cat), 
       house(white, spanish, orange, lucky, dog), 
       house(yellow, norwegian, milk, time, fox), 
       house(blue, ukrain, tea, montena, horse), 
       house(_G7257, japanese, parlament, _G7260)). 

と私は、最初の行のコメントを解除した場合、同じ文はfalseを返すこと:

/*There are five houses*/ 
exists(A, list(A,_,_,_,_)). 
exists(A, list(_,A,_,_,_)). 
exists(A, list(_,_,A,_,_)). 
exists(A, list(_,_,_,A,_)). 
exists(A, list(_,_,_,_,A)). 

middle_house(A, list(_,_,A,_,_)). 

first_house(A, list(A,_,_,_,_)). 

nextTo(A, B, list(B,A,_,_,_)). 
nextTo(A, B, list(_,B,A,_,_)). 
nextTo(A, B, list(_,_,B,A,_)). 
nextTo(A, B, list(_,_,_,B,A)). 
nextTo(A, B, list(A,B,_,_,_)). 
nextTo(A, B, list(_,A,B,_,_)). 
nextTo(A, B, list(_,_,A,B,_)). 
nextTo(A, B, list(_,_,_,A,B)). 

/* each statement will be described using the clues 
house conatins: Color,Owner, Drinks, Smokes, Pet*/ 
riddle(Houses):- 
    /*exists(house(red, englishman, _,_,_),Houses),*/ 
    nextTo(house(_,norwegian,_,_,_), house(blue,_,_,_,_), Houses), 
    exists(house(_,spanish,_,_, dog), Houses), 
    exists(house(green, _, coffee, _,_), Houses), 
    exists(house(_, ukrain, tea,_,_), Houses), 
    nextTo(house(white,_,_,_,_), house(green,_,_,_,_), Houses), 
    exists(house(_,_,_,marlbero, cat),Houses), 
    exists(house(yellow,_,_,time,_), Houses), 
    middle_house(house(_,_,milk,_,_), Houses), 
    first_house(house(_,norwegian,_,_,_), Houses), 
    nextTo(house(_,_,_,_,fox), house(_,_,_,montena,_), Houses), 
    nextTo(house(_,_,_,time,_), house(_,_,_,_,horse), Houses), 
     exists(house(_,_,orange,lucky,_), Houses), 
    exists(house(_,japanese,parlament,_), Houses). 

これに対する現在の解決策はこれです。

これがなぜこのようになるか理解していただきたいと思います。 部分解決策では、ノルウェーが2回出現し、これが問題を示している可能性があることに留意しました。

+0

また、 'nextTo(house、white、_、_、_)、house(green、_、_、_、_)、Houses)'は制限がありません。元のパズルによると、緑の家は*の隣に*だけでなく、*白い家の*右です。 – lurker

+2

この行(あなたの 'riddle/1'述語の最後の行)に' house'引数がありません: 'exist(house(_、japanese、parlament、_)、Houses)'です。それは '存在するべきです(家(_、japanese、_、parlament、_)、住宅)。 – lurker

答えて

6

ここでは、この問題を自分で解決する一般的な方法を示します。実際には、あなたは本当に有望な方向から始めました。あなたは目標を取り除こうとしました。しかし、あなたの場合、誰が間違っていたのですか?あなたがコメントアウトした行または残りの行?結果として得られたプログラムは既に働いているので、あなたは確かにそれを言うことはできません。しかし、非常によく似た、より有望な方法があります:あなたのプログラムを可能な限り一般化して、まだ失敗するようにしてください。このようにして、障害の原因となる小さなプログラムを取得します。つまり、可視部分の残りの部分にはエラーでなければなりません!

ここで私はゴールを取り除いて(前に*を付けて)、いくつかの用語を_で置き換えたものです。

 
:- initialization(riddle(_Sol)). 
:- op(950, fy, *). 
*_. 

riddle(Houses):- 
    exists(house(red, _/* englishman */, _,_,_),Houses), 
    nextTo(house(_,_/* norwegian */,_,_,_), house(blue,_,_,_,_), Houses), 
    *exists(house(_,spanish,_,_, dog), Houses), 
    *exists(house(green, _, coffee, _,_), Houses), 
    *exists(house(_, ukrain, tea,_,_), Houses), 
    nextTo(house(white,_,_,_,_), house(green,_,_,_,_), Houses), 
    *exists(house(_,_,_,marlbero, cat),Houses), 
    exists(house(yellow,_,_,_/* time */,_), Houses), 
    *middle_house(house(_,_,milk,_,_), Houses), 
    *first_house(house(_,norwegian,_,_,_), Houses), 
    *nextTo(house(_,_,_,_,fox), house(_,_,_,montena,_), Houses), 
    *nextTo(house(_,_,_,time,_), house(_,_,_,_,horse), Houses), 
    *exists(house(_,_,orange,lucky,_), Houses), 
    exists(house(_,_/* japanese */,_/* parlament */,_), Houses). 

このフラグメントはまだ失敗します。したがって、エラーはプログラムの可視部分になければなりません。

すべての家の色が存在することが必須であるようです。家の色をまったく含まない目標は1つだけです...それを見ますか?