I implemented Einstein Riddle in Prolog and I\'m trying to find out who had a fish at home.
I can\'t find fault in this code and trace option is not helping with this pr
You had two errors in your clues - the first you fixed already with the light
smoker. The second is that the horse
owner lives next to the yellow
house, not the green
.
Now, my prolog choked on the \+
operator so I recoded your helper predicates. This is what I did:
first(H,[H|_]). on_the_left(X,Y,[X,Y|_]). on_the_left(X,Y,[_|Hs]) :- on_the_left(X,Y,Hs). next_to(X,Y,[X,Y|_]). next_to(X,Y,[Y,X|_]). next_to(X,Y,[_|Hs]) :- next_to(X,Y,Hs). middle(X,[_,_,X,_,_]).
Now the puzzle worked nicely with these clues:
fish(Who) :- Houses = [ house(_Color1, _From1, _Animal1, _Drink1, _Smoke1), house(_Color2, _From2, _Animal2, _Drink2, _Smoke2), house(_Color3, _From3, _Animal3, _Drink3, _Smoke3), house(_Color4, _From4, _Animal4, _Drink4, _Smoke4), house(_Color5, _From5, _Animal5, _Drink5, _Smoke5) ], first(house(_, norway, _, _, _), Houses), %-- hint 1 member(house(red, england, _, _, _), Houses), %-- hint 2 on_the_left(house(green, _, _, _, _), house(white, _, _, _, _), Houses), %-- hint 3 - on_the_left member(house(_, denmark, _, tea, _), Houses), %-- hint 4 next_to(house(_, _, _, _, light), house( _, _, cat, _, _), Houses), %-- hint 5 - next_to member(house(yellow, _, _, _, cigar), Houses), %-- hint 6 member(house(_, germany, _, _, waterpipe), Houses), %-- hint 7 middle(house(_, _, _, milk, _), Houses), %-- hint 8 next_to(house(_, _, _, _, light), house(_, _, _, water, _), Houses), %-- hint 9 - next_to member(house(_, _, bird, _, nofilter), Houses), %-- hint 10 member(house(_, sweden, dog, _, _), Houses), %-- hint 11 next_to(house(_, norway, _, _, _), house(blue, _, _, _, _), Houses), %-- hint 12 - next_to next_to(house(_, _, horse, _, _), house(yellow, _, _, _, _), Houses), %-- hint 13 - next_to member(house(_, _, _, beer, menthol), Houses), %-- hint 14 member(house(green, _, _, coffee, _), Houses), %-- hint 15 member(house(_, Who, fish, _, _), Houses), write(Houses), nl.
I got:
[house(yellow, norway, cat, water, cigar), house(blue, denmark, horse, tea, light), house(red, england, bird, milk, nofilter), house(green, germany, fish, coffee, waterpipe), house(white, sweden, dog, beer, menthol)] germany
just to show an alternative encoding scheme:
solve :- solve(Sol, From), writeln(From), maplist(writeln, Sol).
solve(Sol, From) :-
phrase( (from(1, norway)
,color(red) = from(england)
,color(GREEN, green), color(WHITE, white), {GREEN is WHITE-1}
,from(denmark) = drink(tea)
,smoke(Light, light), animal(Cat, cat), next_to(Light, Cat)
,color(Yellow, yellow), smoke(Yellow, cigar)
,from(germany) = smoke(waterpipe)
,drink(3, milk)
,drink(Water, water), next_to(Light, Water)
,animal(bird) = smoke(nofilter)
,from(sweden) = animal(dog)
,from(NORWAY, norway), color(BLUE, blue), next_to(NORWAY, BLUE)
,animal(HORSE, horse), next_to(HORSE, GREEN) % next_to(HORSE, Yellow)
,drink(beer) = smoke(menthol)
,color(green) = drink(coffee)
,animal(Fish, fish), from(Fish, From)
), [[1,_,_,_,_,_],
[2,_,_,_,_,_],
[3,_,_,_,_,_],
[4,_,_,_,_,_],
[5,_,_,_,_,_]
], Sol).
state(S), [A,B,C,D,E] --> [A,B,C,D,E], {member(S, [A,B,C,D,E])}.
color(A, B) --> state([A,B,_,_,_,_]).
from(A, B) --> state([A,_,B,_,_,_]).
animal(A, B) --> state([A,_,_,B,_,_]).
drink(A, B) --> state([A,_,_,_,B,_]).
smoke(A, B) --> state([A,_,_,_,_,B]).
X = Y --> {
X=..[Fx|Ax], Y=..[Fy|Ay],
Xs=..[Fx,S|Ax], Ys=..[Fy,S|Ay]
}, call(Xs), call(Ys).
next_to(X, Y) --> {1 is abs(X-Y)}.