Логическая головоломка в Прологе - использование списков

Я пытаюсь решить следующую проблему в Прологе, и я думаю, что я правильно ее кодировал, но мои запросы просто возвращают false. Любой совет, что изменить? Проблема заключается в следующем:

"Bagel Alley, местный магазин по продаже бубликов, всегда был местом яростной активности во время утренних поездок на работу, когда люди останавливались, чтобы принести кофе и бублик по дороге на работу. Каждое утро свежие бобы изготавливались на месте, бублики были очень популярны, тот факт, что в магазине также был отличный кофе, был как глазурь на торте! Люди, которые работали на Bagel Alley, были веселыми и дружелюбными, а также компетентными, поэтому, несмотря на большое количество покупателей, ожидание никогда не было долгим или неприятным. Четверо из его коллег остановились сегодня утром, чтобы посмотреть, что каждый бредил, и были приятно удивлены, обнаружив, что магазин оправдал свою репутацию. Определите имя каждого сотрудника, какой бублик с его начинкой, какой вкус и размер кофе (маленький, средний или большой) каждый заказал."

  1. Брэд получил свой рогалик, который не был пшеницей, на котором ничего нет. Уолт заказал маленький кофе.

  2. Два сотрудника, которые получили кофе среднего размера, были тем, кто получил аромат лесного ореха, и тем, кто получил его рогалик с арахисовым маслом.

  3. Тот, кто получил бублик с луком, но не с маслом, тоже получил французский ванильный кофе, но не маленького размера.

  4. Пятеро сотрудников были Джо, тот, кто получил большой кофе, тот, кто получил кофе со вкусом амаретто, тот, кто получил бублик пшеницы, и тот, кто получил яйцо и бекон на своем бублике.

  5. Рик не заказывал черничный бублик, но получил колумбийский кофе. Кофе Амаретто был заказан с бубликом чеддер, но не Уолтом.

  6. Сливочный сыр не шел с черничным бубликом, но с большим кофе. Бублик с кунжутом шел с маслом, но Карлос его не заказывал.

Код Пролога, который я написал, находится здесь:

bagels(Sol):-
   Sol = [[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_]],
   member([brad,X,plain,_,_], Sol), X \== wheat,
   member([walt,_,_,small,_], Sol),
   member([_,_,_,medium1,hazelnut], Sol),
   member([_,_,peanut_butter,medium2,_], Sol),
   member([_,onion,Y,Z,french_vanilla], Sol), Y \== butter, Z \== small,
   member([joe,Ja,Jb,Jc,Jd], Sol),Ja\==wheat,Jb\==egg_bacon,Jc\==large,Jd==amaretto,
   member([La,Lb,Lc,large,Ld], Sol), La\==joe,Lb\==wheat,Lc\==egg_bacon,Ld\==amaretto,
   member([Aa,Ab,Ac,Ad,amaretto], Sol), Aa\==joe,Ab\==wheat,Ac\==egg_bacon,Ad\==large,
   member([Wa,wheat,Wb,Wc,Wd], Sol), Wa\==joe,Wb\==egg_bacon,Wc\==large,Wd\==amaretto,
   member([Ea,Eb,egg_bacon,Ec,Ed], Sol), Ea\==joe,Eb\==wheat,Ec\==large,Ed\==amaretto,
   member([rick,R,_,_,columbian], Sol),R\==blueberry,
   member([A,cheddar,_,_,amaretto], Sol), A\==walt,
   member([_,B,cream_cheese,large,_], Sol), B\==blueberry,
   member([C,sesame,butter,_,_], Sol), C \== carlos,
   member([_,_,_,other,_], Sol),
   member([_,_,_,_,other], Sol).

Я считаю, что работает запрос "бублики (X)". должен дать мне решение проблемы, но возвращает false. Я что-то пропустил? Спасибо заранее!

2 ответа

Решение

Во-первых, кажется, что постановка проблемы нуждается в некотором пересмотре - в частности, пункт 4.

Что у вас здесь есть логическая загадка. Таким образом, вам действительно нужно придерживаться логической части Пролога. Тем не менее, в вашем коде я вижу (\==)/2 а также (==)/2 которые оба не полностью осознают логические отношения, которые они притворяются, чтобы представлять. Вместо этого используйте dif/2 а также (=)/2 соответственно.

Но даже после того, как их заменить, дела обстоят не намного лучше, ваша программа все равно не работает. Тем не менее, с чистым определением у вас есть шанс локализовать проблему. Ваша проблема в том, что bagels(Sols) выходит из строя. Таким образом, текущее определение слишком узкое, слишком узкое. Поэтому я постараюсь обобщить это, сняв некоторые ваши требования. Для этого я добавлю * перед некоторыми из ваших целей. Я обобщу их так, что получающаяся в результате программа все равно не будет работать.

Осталось обобщение, показывающее, где вам нужно будет изменить свою программу. В противном случае ошибка будет сохраняться.

Изменить: я выделил то, что выглядит особенно странным для меня: два мужчины пили амаретто.

: - op (950, фу, *).
*_. рогалики (Sol):-
   Sol = [[_,_,_,_,_],[_,_,_,_,_, _],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_]], член ([brad,X,plain,_,_], Sol),
      dif(X, пшеница), член ([walt,_,_, маленький, _], Sol), член ([_,_,_,medium1, фундук], Sol),
   * член ([_, _, peanut_butter, medium2, _], Sol), член ([_, лук, Y, Z, french_vanilla], Sol),
   * dif (Y, масло), dif (Z, маленький), член ([Джо, Ja, Jb, Jc, Jd], Sol), * dif (Ja, пшеница), * dif (Jb, egg_bacon), dif (Jc, large), Jd = amaretto, * member ([La, Lb, Lc, large, Ld], Sol), * dif (La, joe), * dif (Lb, пшеница), * dif (Lc, egg_bacon), * dif (Ld, amaretto), член ([Aa, Ab, Ac, Ad, amaretto], Sol), dif (Aa, joe), * dif (Ab, пшеница), * dif (Ac, egg_bacon), * dif (Ad, large), член ([Wa, пшеница, Wb, Wc, Wd], Sol),
   * dif (Wa, joe), * dif (Wb, egg_bacon), dif (Wc, large), dif (Wd, amaretto), член ([Ea, Eb, egg_bacon, Ec, Ed], Sol),
   * dif (Ea, joe), dif (Eb, пшеница), * dif (Ec, большой), dif (Ed, амаретто), член ([rick,R,_,_, колумбийский], Sol),
   * dif (R, черника), * член ([A, чеддер, _, _, amaretto], Sol), * dif (A, walt), член ([_, B, crea m_cheese, large,_], Sol),
      * dif (B, черника), * member ([C, кунжут, масло, _, _], Sol), * dif (C, carlos), * член ([_, _, _, другие, _], Sol), * член ([_,_,_,_, другие], Sol). 

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

bagels(Sol):-
   Sol = [[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_],[_,_,_,_,_]],
    maplist(Sol+\P^member([P|_], Sol),
          [brad,walt,joe,rick,carlos]),
    maplist(Sol+\D^member([_,_,_,_,D], Sol),
          [amaretto,french_vanilla,hazelnut,columbian,other]),
    ...

Я пытался улучшить читабельность, используя DCG для передачи состояния (см. "Неявное прохождение состояний" на этой странице), поэтому этот фрагмент сильно отличается от вашего решения.

Вы можете видеть, что негативное знание выражается двумя разными способами: там, где участвуют люди, мы можем напрямую использовать \=, поскольку имена всегда создаются, но для других значений, таких как kind(brad, K), Я использую {dif(K, wheat)}, поскольку K еще не был создан.

state(S), [state(T)] --> [state(T)], {member(S, T)}.

kind(P, K)  --> state([P, K, _, _, _]).
topping(P, T)   --> state([P, _, T, _, _]).
flavor(P, F)    --> state([P, _, _, F, _]).
size(P, S)  --> state([P, _, _, _, S]).


hint1 -->
  kind(brad, K), {dif(K, wheat)}, topping(brad, plain), size(walt, small).
hint2 -->
  size(P1, medium), size(P2, medium), {P1 \= P2},
  flavor(P1, hazelnut), topping(P2, peanut_butter).
hint3 -->
  kind(P, onion), flavor(P, french_vanilla), size(P, S), {dif(S, small)}.
hint4 -->
  size(P1, large), flavor(P2, amaretto), kind(P3, wheat), topping(P4, egg_bacon),
  {forall(select(X, [joe,P1,P2,P3,P4], Ps), maplist(\=(X), Ps))}.
hint5 -->
  kind(rick, K), {dif(K, blueberry)}, flavor(rick, columbian),
  kind(P, cheddar), flavor(P, amaretto), {P \= walt}.
hint6 -->
  topping(P1, cream_cheese), kind(P2, blueberry), {P1 \= P2}, size(P1, large),
  kind(P, sesame), topping(P, butter), {P \= carlos}.

bagels(Sol):- Sol =
    [[brad,_,_,_,_],
     [walt,_,_,_,_],
     [joe,_,_,_,_],
     [rick,_,_,_,_],
     [carlos,_,_,_,_]],
  phrase((hint1, hint2, hint3, hint4, hint5, hint6), [state(Sol)], _).

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

?- aggregate(count,S^bagels(S),N).
N = 7.
Другие вопросы по тегам