2017-08-22 2 views
3

Ich versuche zu lösen Einstein Riddle in Prolog.Lösen Einstein Rätsel in Prolog

Ich habe eine Schwierigkeit mit dem Programm, das ich schrieb, die grundlegende Methode war, alle Einschränkungen hinzuzufügen und Prolog herauszufinden, die einzig mögliche Lösungen.

Das Problem ist, dass Prolog 0 Lösungen findet. Ich habe die Einschränkung isoliert, die das Programm von einer gegebenen Lösung zu keiner Lösung führt, aber ich verstehe nicht warum.

/*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). 

Die aktuelle Lösung ist dies:

?- 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)). 

und wenn ich die erste Zeile dann Kommentar-, dass gleiche Anweisung gibt false.

Ich möchte helfen zu verstehen, warum dies der Fall ist. Ich bemerkte, dass in der Teillösung der Norweger zweimal erscheint und dass dies auf das Problem hinweisen könnte.

+0

Auch 'nextTo (Haus (weiß, _, _, _, _), Haus (grün, _, _, _, _), Häuser) ist nicht restriktiv genug. Nach dem originalen Puzzle ist das grüne Haus * rechts von * dem weißen Haus, nicht nur * neben *. – lurker

+2

In dieser Zeile (die letzte Zeile in Ihrem 'riddle/1' Prädikat) fehlt ein 'Haus'-Argument:' existiert (Haus (_, japanisch, parlament, _), Häuser) '. Es sollte "existiert" (Haus, (_, japanisch, _, parlament, _), Häuser). – lurker

Antwort

6

Hier ist ein allgemeiner Weg, wie Sie dieses Problem für sich selbst lösen können. Eigentlich hast du wirklich in eine vielversprechende Richtung gestartet: Du hast versucht, Tore zu entfernen. Aber dann, wer war in deinem Fall schuld? Die Zeile, die Sie auskommentiert haben oder den Rest? Das kann man nicht mit Sicherheit sagen, da das resultierende Programm bereits funktioniert hat. Aber es gibt einen sehr ähnlichen und vielversprechenderen Weg: Versuchen Sie, Ihr Programm so weit wie möglich zu verallgemeinern, so dass es immer noch fehlschlägt. Auf diese Weise erhalten Sie ein kleineres Programm, das für den Fehler verantwortlich ist. Das heißt, innerhalb des verbleibenden sichtbaren Teils muss ein Fehler sein!

Hier ist, was ich durch Entfernen von Zielen (Hinzufügen eines * vor) und durch Ersetzen einiger Begriffe durch _.

 
:- 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). 

Dieses Fragment schlägt immer noch fehl, daher muss der Fehler im sichtbaren Teil des Programms liegen.

Es scheint wichtig zu sein, dass alle Hausfarben vorhanden sind. Es gibt nur ein Ziel, das überhaupt keine Hausfarbe enthält ... sehen Sie es?