Я реализовал Загадку Эйнштейна на Прологе и пытаюсь выяснить, у кого дома была рыба.
Я не могу придраться к этому коду, и опция трассировки не помогает с этой проблемой;)

Правила:

  1. Норвежец живет в первом доме
  2. Англичанин живет в красном доме.
  3. Оранжерея находится прямо с левой стороны от белого дома.
  4. Датчанин пьет чай.
  5. Легкий курильщик живет рядом с заводчиками кошек.
  6. Жительница желтого дома курит сигару.
  7. Немец курит кальян.
  8. Жительница дома центра пьет молоко.
  9. У заядлого курильщика есть соседи, пьющие воду.
  10. Курите сигареты без фильтра.
  11. Швед разводил собак.
  12. Норвежец живет рядом с синим домом.
  13. Рядом с желтым домом живет заводчик лошадей.
  14. Курите ментол, пейте пиво.
  15. В теплице пьют кофе.

Вот мой код:

on_the_left(X, Y, N) :-
    Y is X - 1,
    \+ Y < 1,
    \+ X > N.

next_to(X, Y, N) :-
    ( Y is X + 1;
      Y is X - 1),
    \+ X > N,
    \+ Y > N,
    \+ X < 1,
    \+ Y < 1.

fish(Who) :-
    Houses = [
        house(1, _Color1, _From1, _Animal1, _Drink1, _Smoke1),
        house(2, _Color2, _From2, _Animal2, _Drink2, _Smoke2),
        house(3, _Color3, _From3, _Animal3, _Drink3, _Smoke3),
        house(4, _Color4, _From4, _Animal4, _Drink4, _Smoke4),
        house(5, _Color5, _From5, _Animal5, _Drink5, _Smoke5) ],
    N is 5,
    %-- hint 1
    member(house(1, _, norway, _, _, _), Houses),
    %-- hint 2
    member(house(_, red, england, _, _, _), Houses),
    %-- hint 3 - on_the_left
    member(house(GREEN, green, _, _, _, _), Houses),
    member(house(WHITE, white, _, _, _, _), Houses),
    on_the_left(GREEN, WHITE, N),
    %-- hint 4
    member(house(_, _, denmark, _, tea, _), Houses),
    %-- hint 5 - next_to
    member(house(LIGHT, _, _, _, _, light), Houses),
    member(house(CAT, _, _, cat, _, light), Houses),
    next_to(LIGHT, CAT, N),
    %-- hint 6
    member(house(_, yellow, _, _, _, cigar), Houses),
    %-- hint 7
    member(house(_, _, germany, _, _, waterpipe), Houses),
    %-- hint 8
    member(house(3, _, _, _, milk, _), Houses),
    %-- hint 9 - next_to
    member(house(WATER, _, _, _, water, _), Houses),
    next_to(LIGHT, WATER, N),
    %-- hint 10
    member(house(_, _, _, bird, _, nofilter), Houses),
    %-- hint 11
    member(house(_, _, sweden, dog, _, _), Houses),
    %-- hint 12 - next_to
    member(house(NORWAY, _, norway, _, _, _), Houses),
    member(house(BLUE, blue, _, _, _, _), Houses),
    next_to(NORWAY, BLUE, N),
    %-- hint 13 - next_to
    member(house(HORSE, _, _, horse, _, _), Houses),
    next_to(HORSE, GREEN, N),
    %-- hint 14
    member(house(_, _, _, _, beer, menthol), Houses),
    %-- hint 15
    member(house(_, green, _, _, coffee, _), Houses),

    %-- FINAL QUESTION - WHO LET THE FISH OUT?
    member(house(_, _, _, fish, _, _), Houses),
    member(house(_, _, Who, fish, _, _), Houses).

Я пробовал много комбинаций, но:

? - рыба (Кто).
ложный.

Изменить:
Код сейчас работает, что я изменил:

1 * От:

%-- hint 5 - next_to
member(house(LIGHT, _, _, _, _, light), Houses),
member(house(CAT, _, _, cat, _, light), Houses),

Кому:

%-- hint 5 - next_to
    member(house(LIGHT, _, _, _, _, light), Houses),
    member(house(CAT, _, _, cat, _, _), Houses),

2 * От:

%-- hint 13 - next_to   
member(house(HORSE, _, _, horse, _, _), Houses),
next_to(HORSE, GREEN, N),

Кому:

%-- hint 13 - next_to
member(house(YELLOW, yellow, _, _, _, _), Houses),
member(house(HORSE, _, _, horse, _, _), Houses),
next_to(HORSE, YELLOW, N),

Если вы читаете это, посмотрите комментарий @Enigmativity о структурах во вспомогательных предикатах.

2
CryptoNewbie 20 Апр 2016 в 15:15

2 ответа

Лучший ответ

В ваших подсказках было две ошибки - первую вы исправили уже с курильщиком light. Во-вторых, владелец horse живет рядом с домом yellow, а не green.

Теперь мой пролог подавился оператором \+, поэтому я перекодировал ваши вспомогательные предикаты. Вот что я сделал:

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,_,_]).

Теперь загадка отлично работала с этими подсказками:

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.

Я получил:

[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
3
Enigmativity 20 Апр 2016 в 13:11

Просто чтобы показать альтернативную схему кодирования:

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)}.
1
CapelliC 20 Апр 2016 в 19:38