Решение загадки Эйнштейна на Прологе

Я пытаюсь разгадать Загадку Эйнштейна на Прологе.

У меня возникли трудности с программой, которую я написал, основной метод заключался в том, чтобы добавить все ограничения и позволить Prolog выяснить единственные возможные решения.

Проблема в том, что Prolog находит 0 решений. Я выделил ограничение, которое заставляет программу переходить от данного решения к отсутствию решений, но я не понимаю, почему.

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

Текущее решение этой проблемы таково:

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

и если я раскомментирую первую строку, то тот же оператор вернет false.

Я хотел бы помочь понять, почему это так. Я заметил, что в частичном решении норвежский язык появляется дважды, и это может указывать на проблему.


person Belgi    schedule 22.08.2017    source источник
comment
Кроме того, nextTo(house(white,_,_,_,_), house(green,_,_,_,_), Houses) недостаточно ограничивает. Согласно оригинальной головоломке, зеленый дом находится справа от белого дома, а не только рядом.   -  person lurker    schedule 22.08.2017
comment
В этой строке (последняя строка в вашем предикате riddle/1) отсутствует один house аргумент: exists(house(_,japanese,parlament,_), Houses). Должно быть exists(house(_,japanese,_,parlament,_), Houses).   -  person lurker    schedule 22.08.2017


Ответы (1)


Вот общий способ, как вы можете решить эту проблему самостоятельно. На самом деле, вы действительно начали в довольно многообещающем направлении: вы пытались убрать цели. Но тогда кто был виноват в вашем случае? Строку, которую вы закомментировали, или остальное? Точно этого нельзя сказать, так как получившаяся программа уже работала. Но есть очень похожий и гораздо более многообещающий способ: постарайтесь максимально обобщить вашу программу, чтобы она по-прежнему терпела неудачу. Таким образом вы получите меньшую программу, которая ответственна за сбой. То есть в оставшейся видимой части должна быть ошибка!

Вот что я получил, удалив цели (добавив * впереди) и заменив некоторые термины на _.

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

Этот фрагмент по-прежнему не работает, поэтому ошибка должна быть в видимой части программы.

Вроде бы важно, чтобы присутствовали все цвета дома. Есть только одна цель, в которой вообще нет цвета дома ... видите?

person false    schedule 22.08.2017