Уникальные элементы в списке (Пролог)
Я реализую вариацию "Загадки Эйнштейна", и у меня возникли некоторые проблемы.
При попытке вычислить решение я пытаюсь это:
solve(Street) :- Street = [_House1,_House2,_House3,_House4,_House5],
%hint one goes here
%hint two goes here
%etc.
Затем я могу спросить решение, набрав: решить (улица)
Однако это подходит как решение:
- дом (цветок, еда, домашнее животное, спорт)
- дом (цветок, еда, домашнее животное, спорт)
- дом (х, еда, домашнее животное, спорт)
- дом (цветок, еда, домашнее животное, спорт)
- дом (х, цветок, домашнее животное, спорт)
Как вы можете видеть, есть 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,
--...