【问题标题】:Prolog Logic Puzzle Failure [duplicate]Prolog逻辑拼图失败[重复]
【发布时间】:2020-04-01 11:07:18
【问题描述】:

我正在尝试解决这里发现的逻辑难题:https://www.braingle.com/brainteasers/teaser.php?id=23826&op=2&comm=1#c

这些是线索:

  1. 这些花的购买顺序如下:郁金香、办公室的花、紫色的花、公园的玫瑰、茱莉亚买的白花。

  2. Bethany 喜欢花,但她对花过敏,所以她绝不会把它们放在室内。

  3. 周三和周五下雨,因此婚礼和生日派对不得不搬到室内。

  4. 艾米在瑞秋之后买了她的花,但在克里斯汀之前。

  5. Rachel 需要为她的办公室添加更多东西,所以她选择了桃花来搭配她的窗帘。

  6. 星期三,花店里唯一可以买到的紫色花朵是雏菊。

  7. 粉红色的花朵是在康乃馨之后,百合之前买的。

  8. 生日花是在办公室花之后,婚礼花之前买的。

我已尝试使用以下代码在 prolog 中实现这一点:

/*
Use a nested predicate of flowers to store the solution

flowers(
  f(Woman1,Flower1,Color1,Place1,Day1),
  f(Woman2,Flower2,Color2,Place2,Day2),
  f(Woman3,Flower3,Color3,Place3,Day3),
  f(Woman4,Flower4,Color4,Place4,Day4),
  f(Woman5,Flower5,Color5,Place5,Day5)
).
*/

/* The flowers predicate contains a given flower X */
has(X,F) :- F=flowers(X,_,_,_,_).
has(X,F) :- F=flowers(_,X,_,_,_).
has(X,F) :- F=flowers(_,_,X,_,_).
has(X,F) :- F=flowers(_,_,_,X,_).
has(X,F) :- F=flowers(_,_,_,_,X).

/*Defines that X occurs on an earlier day than Y */
before(X,Y,F) :- append(_,[X|Tail], F), append(_,[Y|_],Tail).


solve(F) :-
  F = flowers(A,B,C,D,E),
/*clue 1 */
  A = f(_,tulips,yellow,_,monday),
  B = f(_,_,_,office,tuesday),
  C = f(_,_,purple,_,wednesday),
  D = f(_,roses,_,park,thursday),
  E = f(julia,_,white,_,friday),
/* Clue 2 --> Look @ clue 3, Bethany can only have flowers in backyard or park */
  has(f(bethany,_,_,backyard,_),F), 
  has(f(bethany,_,_,_,park,_),F),
/* Clue #4, Amy before Kristen, Rachel before Amy */
  before(f(amy,_,_,_,_),f(kristen,_,_,_,_),F),
  before(f(rachel,_,_,_,_),f(amy,_,_,_,_),F),
/* Clue #5 */
  has(f(rachel,_,peach,office,_),F),
/* Clue #6 */
  has(f(_,daisies,purple,_,wednesday),F),
/* Clue #7, pink before lillies, carnations before pink */
  before(f(_,_,pink,_,_),f(_,lilies,_,_,_),F),
  before(f(_,carnations,_,_,_),f(_,_,pink,_,_),F),
/* Clue #8 */
  before(f(_,_,_,birthday,_),f(_,_,_,wedding,_),F),
  before(f(_,_,_,office,_),f(_,_,_,birthday,_),F).

这似乎不起作用。我认为问题在于我的代码在定义一朵花之前发生在另一朵花之前,但我不确定这是否是问题以及如何解决它。另外,我认为说 Bethany 为后院或公园买花(不是婚礼、生日或办公室)是有问题的。

这是谜题的答案:

朱莉娅:百合,白色,婚礼,星期五

艾米:雏菊,紫色,生日,星期三

Bethany:郁金香,黄色,后院,星期一

瑞秋:康乃馨,桃子,办公室,星期二

克里斯汀:玫瑰,粉红,公园,星期四

【问题讨论】:

  • 你是说has(f(bethany,_,_,backyard,_),F) & has(f(bethany,_,_,_,park,_),F) 必须成功 - 两者都成功。
  • 不要将您的问题单条化,尤其是在已经解决的情况下。 (我不明白为什么 Stackoverflow 在上次编辑时没有“回滚”操作。这有什么意义?这可能是 UI 故障,应该说“回滚到”而不是隐含的“回滚”)
  • @DavidTonhofer 你是对的,文本 令人困惑。它的意思是“回滚到这个”。
  • has(X,F):- functor( F, flowers, 5), arg( _, F, X).。如果您确实以F = flowers(A,B,C,D,E), 开头solve/1,您甚至可以省略正文中的第一个目标。然后,before(X,Y,F) :- arg( I, F, X), arg( J, F, Y), I < J.

标签: prolog zebra-puzzle


【解决方案1】:

before/3 谓词试图处理flowers(A,B,C,D,E),就好像它是一个列表一样。它总是失败。您需要将其定义为 [A,B,C,D,E] 才能正常工作。

如果将flowers(A,B,C,D,E) 更改为[A,B,C,D,E] 实际上会更好,这样您就可以使用内置谓词member/2 而不是has/2

所以,首先我是这样做的:

writeln(X) :- write(X), nl.

writelist([]).
writelist([H|T]) :- writeln(H), writelist(T).

/*Defines that X occurs on an earlier day than Y */
before(X,Y,F) :- append(F0, F1, F), member(X, F0), member(Y, F1).

您还试图在后院和公园里说伯大尼。它必须是 or 关系。

这是我的solve/1 版本:

solve(F) :-
/*clue 1 */
    F = [
        f(_,tulips,yellow,_,monday),
        f(_,_,_,office,tuesday),
        f(_,_,purple,_,wednesday),
        f(_,roses,_,park,thursday),
        f(julia,_,white,_,friday)
    ],
/* Clue 2 --> Look @ clue 3, Bethany can only have flowers in backyard or park */
    (member(f(bethany,_,_,backyard,_),F);
        member(f(bethany,_,_,_,park,_),F)),
/* Clue #4, Amy before Kristen, Rachel before Amy */
    before(f(amy,_,_,_,_),f(kristen,_,_,_,_),F),
    before(f(rachel,_,_,_,_),f(amy,_,_,_,_),F),
/* Clue #5 */
    member(f(rachel,_,peach,office,_),F),
/* Clue #6 */
    member(f(_,daisies,purple,_,wednesday),F),
/* Clue #7, pink before lillies, carnations before pink */
    before(f(_,_,pink,_,_),f(_,lilies,_,_,_),F),
    before(f(_,carnations,_,_,_),f(_,_,pink,_,_),F),
/* Clue #8 */
    before(f(_,_,_,birthday,_),f(_,_,_,wedding,_),F),
    before(f(_,_,_,office,_),f(_,_,_,birthday,_),F),
    true.

现在当我查询 ?- solve(F), writelist(F). 时,我得到了这个:

f(伯大尼,郁金香,黄色,后院,星期一) f(瑞秋,康乃馨,桃子,办公室,星期二) f(艾米,雏菊,紫色,生日,星期三) f(克里斯汀,玫瑰,粉红色,公园,星期四) f(朱莉娅,百合,白色,婚礼,星期五) 是的。

【讨论】:

    猜你喜欢
    • 2018-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-20
    • 2012-09-20
    • 2012-06-11
    • 1970-01-01
    相关资源
    最近更新 更多