列表中的独特元素(Prolog)

时间:2010-12-10 16:00:13

标签: prolog unique zebra-puzzle

我正在对爱因斯坦的谜语实施一个变体,我遇到了一些麻烦。

尝试计算解决方案时,我试试这个:

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

然后我可以输入:solve(Street)

来询问解决方案

然而,这出现了解决方案:

  1. 房子(花,食物,宠物,运动)
  2. 房子(花,食物,宠物,运动)
  3. house( x ,食物,宠物,运动)
  4. 房子(花,食物,宠物,运动)
  5. house( x ,花,宠物,运动)
  6. 你可以看到 x 的2倍,其余的都是各种类型的食物,鲜花,宠物和运动。 但每种类型都是独一无二的:如果一个人喜欢花X,没有人会喜欢X.

    现在,我的解决方案给出2 x的原因很容易看出:我们给出了一些提示但是在所有提示中只提到了4个花。所以Prolog不知道还有另外一朵花,只使用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 个答案:

答案 0 :(得分:2)

为了表示没有花两次报告,并且为了确保所有花都被束缚,你可以使用置换/ 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,
       --...