Уникальные элементы в списке (Пролог) - PullRequest
4 голосов
/ 10 декабря 2010

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

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

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

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

Однако это выглядит как решение:

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

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

Теперь, причина, по которой мое решение дает 2 x, легко увидеть: нам дано количество подсказок, но во всехПодсказки там только 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, когда A и Bрядом друг с другом в List.Подсказка может быть переведена следующим образом: человек, который любит футбол, живет рядом с человеком, у которого есть рыба.

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

1 Ответ

2 голосов
/ 10 декабря 2010

Чтобы выразить, что ни один цветок не сообщается дважды, а также чтобы убедиться, что все цветы связаны, вы можете использовать предикат 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,
       --...
...