Уникальные элементы в списке (Пролог)

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

При попытке вычислить решение я пытаюсь это:

solve(Street) :- Street = [_House1,_House2,_House3,_House4,_House5],
%hint one goes here
%hint two goes here
%etc.

Затем я могу спросить решение, набрав: решить (улица)

Однако это подходит как решение:

  1. дом (цветок, еда, домашнее животное, спорт)
  2. дом (цветок, еда, домашнее животное, спорт)
  3. дом (х, еда, домашнее животное, спорт)
  4. дом (цветок, еда, домашнее животное, спорт)
  5. дом (х, цветок, домашнее животное, спорт)

Как вы можете видеть, есть 2 раза x, остальные - это все виды пищи, цветов, домашних животных и спорта. Но каждый тип уникален: если один человек любит цветок X, никто другой не может понравиться X.

Теперь, причина, по которой мое решение дает 2 х, легко понять: нам дано количество подсказок, но во всех подсказках упоминаются только 4 цветка. Таким образом, Пролог не знает, что есть другой цветок, и просто использует x дважды, просто потому, что это возможно, и выполняет все другие подсказки.

Что я хочу сказать, так это то, что все виды еды, цветов и т. Д. На улице уникальны, поэтому он должен оставить пустым, когда уже использовал все типы. 3 будет выглядеть так: house(x , food, pet ,sport) и 5 будет выглядеть так: house(_, flower, pet, sport),

Я также попытался добавить это к подсказкам: (скажем, "кактус" - один из цветов, не упомянутых в подсказках) member(house(cactus,_,_,_), Street)

Однако тогда моя программа не заканчивается...

Подсказка может выглядеть так:is_neighbour(house(_,_,_,football),house(_,_,fish,_), Street),с: is_neighbour(A,B,List) дающий true когда А и В находятся рядом друг с другом в List, Подсказка может быть переведена на: человек, который любит футбол, живет рядом с человеком, у которого есть рыба.

Если какая-либо дополнительная информация должна быть предоставлена, я готов уточнить.:)

1 ответ

Решение

Чтобы выразить, что ни о каком цветке не сообщается дважды, а также чтобы убедиться, что все цветы связаны, вы можете использовать предикат permutation/2: список всех цветов должен быть перестановкой списка указанных цветов. Это будет читать как [не проверено]

flowers([], []).
flowers([house(Flower,_,_,_)|Street], [Flower|Rest]) :- flowers(Street, Rest).

-- ...
   flowers(Street, Flowers), 
   permutation(Flowers, [kaktus, tulpe, nelke, rose, fingerhut]),

Изменить: для 10 цветов, использование перестановок, вероятно, слишком медленно. Альтернативный подход

flower(kaktus).
flower(tulpe).
flower(nelke).
--...

       flowers(Street,[F1,F2,F3,F4,F5,F6,F7,F8,F9,F10]),
       flower(F1), flower(F2), F1\=F2,
       flower(F3), F3\=F1, F3\=F2,
       flower(F4), F4\=F1, F4\=F2, F4\=F3,
       --...
Другие вопросы по тегам