prologzebra-puzzle

Using Prolog to solve The Jindosh Riddle from Dishonored 2


I am playing the game Dishonored 2

There is a puzzle in the game, see the picture below (no spoilers).

Riddle

Naturally I wanted to solve this using Prolog. I have looked around and other people have made Prolog programs to solve the riddle, but I would like to know why my solution does not work. In particular, it gives a Warning: Goal (directive) failed, and returns true with no other output.

The code:

% dishonered 2 jindosh riddle

exists(A,(A,_,_,_,_)).
exists(A,(_,A,_,_,_)).
exists(A,(_,_,A,_,_)).
exists(A,(_,_,_,A,_)).
exists(A,(_,_,_,_,A)).

rightOf(A, B, (B,A,_,_,_)).
rightOf(A, B, (_,B,A,_,_)).
rightOf(A, B, (_,_,B,A,_)).
rightOf(A, B, (_,_,_,B,A)).

middlePerson(A,(_,_,A,_,_)).

firstPerson(A, (A,_,_,_,_)).
second(A,(_,A,_,_,_)).
third(A,(_,_,A,_,_)).
fourth(A,(_,_,_,A,_)).
lastPerson(A,(_,_,_,_,A)).

nextTo(A,B,H) :- rightOf(A,B,H).
nextTo(A,B,H) :- rightOf(B,A,H).

:-  exists(person(winslow,green,_,_,_), People),
    firstPerson(person(contee,_,_,_,_), People),
    nextTo(person(contee,_,_,_,_),person(_,white,_,_,_,_), People),
    rightOf(person(_,blue,_,_,_,_),person(_,purple,_,_,_,_), People),
    exists(person(_,purple,absinthe,_,_), People),
    exists(person(_,red,_,dabokva,_), People),
    nextTo(person(_,_,_,_,_,snufftin),person(_,_,_,_,dabokva,_), People),
    exists(person(finch,_,_,_,ring), People),
    exists(person(_,_,_,karnaca,bird), People),
    nextTo(person(_,_,_,_,diamond),person(_,_,_,dunwall,_), People),
    nextTo(person(_,_,_,dunwall,_),person(_,_,wine,_,_), People),
    exists(person(marcolla,_,whiskey,_,_), People),
    exists(person(_,_,rum,fraeport,_), People),
    middlePerson(person(_,_,beer,_,_), People),
    exists(person(natsiou,_,_,baleton,_), People),
    exists(person(_,_,_,_,warmedal), People),
    firstPerson(person(Aperson,Acolour,Adrink,Aloc,Aheir), People),
    second(person(Bperson,Bcolour,Bdrink,Bloc,Bheir), People),
    third(person(Cperson,Ccolour,Cdrink,Cloc,Cheir), People),
    fourth(person(Dperson,Dcolour,Ddrink,Dloc,Dheir), People),
    lastPerson(person(Eperson,Ecolour,Edrink,Eloc,Eheir), People),
    format('The first person is the ~w person~n', (Aperson,Acolour,Adrink,Aloc,Aheir)),
    format('The second person is the ~w person~n', (Bperson,Bcolour,Bdrink,Bloc,Bheir)),
    format('The third person is the ~w person~n', (Cperson,Ccolour,Cdrink,Cloc,Cheir)),
    format('The fourth person is the ~w person~n', (Dperson,Dcolour,Ddrink,Dloc,Dheir)),
    format('The last person is the ~w person~n', (Eperson,Ecolour,Edrink,Eloc,Eheir)).

The command and output:

?- [dishonored].
Warning: c:/users/<USERNAME>/documents/prolog/dishonored.pl:25:
Warning:    Goal (directive) failed: user:(exists(person(winslow,green,_7036,_7058,_7080),_7102),firstPerson(person(contee,_7198,_7220,_7242,_7264),_7102),nextTo(person(contee,_7392,_7414,_7436,_7458),person(_7480,white,_7502,_7524,_7546,_7568),_7102),rightOf(person(_7702,blue,_7724,_7746,_7768,_7790),person(_7812,purple,_7834,_7856,_7878,_7900),_7102),exists(person(_7992,purple,absinthe,_8014,_8036),_7102),exists(person(_8128,red,_8150,dabokva,_8172),_7102),nextTo(person(_8306,_8328,_8350,_8372,_8394,snufftin),person(_8416,_8438,_8460,_8482,dabokva,_8504),_7102),exists(person(finch,_8596,_8618,_8640,ring),_7102),exists(person(_8732,_8754,_8776,karnaca,bird),_7102),nextTo(person(_8898,_8920,_8942,_8964,diamond),person(_8986,_9008,_9030,dunwall,_9052),_7102),nextTo(person(_9174,_9196,_9218,dunwall,_9240),person(_9262,_9284,wine,_9306,_9328),_7102),exists(person(marcolla,_9420,whiskey,_9442,_9464),_7102),exists(person(_9556,_9578,rum,fraeport,_9600),_7102),middlePerson(person(_9698,_9720,beer,_9742,_9764),_7102),exists(person(natsiou,_9856,_9878,baleton,_9900),_7102),exists(person(_9998,_10020,_10042,_10064,warmedal),_7102),firstPerson(person(_10168,_10190,_10212,_10234,_10256),_7102),second(person(_10360,_10382,_10404,_10426,_10448),_7102),third(person(_10552,_10574,_10596,_10618,_10640),_7102),fourth(person(_10744,_10766,_10788,_10810,_10832),_7102),lastPerson(person(_10936,_10958,_10980,_11002,_11024),_7102),format('The first person is the ~w person~n',(_10168,_10190,_10212,_10234,_10256)),format('The second person is the ~w person~n',(_10360,_10382,_10404,_10426,_10448)),format('The third person is the ~w person~n',(_10552,_10574,_10596,_10618,_10640)),format('The fourth person is the ~w person~n',(_10744,_10766,_10788,_10810,_10832)),format('The last person is the ~w person~n',(_10936,_10958,_10980,_11002,_11024)))
**true.**

I am running SWIPL.

My format for the 5-tuple is (name, colour, drink, location, heirloom).

I have looked for what Goal (directive) failed means, finding this, but my error does not occur during importing the file. There is also another SO post but the solution does not apply to me.

I have seen SO user false give answers to some zebra-puzzle related SO questions, but I do not understand them.

I asked ChatGPT, but it spouted nonsense. (It did fix a few typos though!)

I have solved a zebra puzzle using Prolog before, using very similar structure, so am particularly confused as to why this doesn't work. If it as simple as I mistranslated the rules I will be sad.


Solution

  • First problem: 6 elements rather than 5, in:

    nextTo(person(_,_,_,_,_,snufftin),person(_,_,_,_,dabokva,_), People),
    

    Also 6 in:

    nextTo(person(contee,_,_,_,_),person(_,white,_,_,_,_), People)
    

    Also 6 in:

    rightOf(person(_,blue,_,_,_,_),person(_,purple,_,_,_,_), People),
    

    Fixing those 3 issues, it produces 1 solution.