Einstein Riddle with List of terms

前端 未结 2 1705
栀梦
栀梦 2020-12-12 02:35

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

相关标签:
2条回答
  • 2020-12-12 03:05

    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
    
    0 讨论(0)
  • 2020-12-12 03:25

    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)}.
    
    0 讨论(0)
提交回复
热议问题