4

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

在尝试计算解决方案时,我尝试这样做:

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

然后我可以通过键入以下内容来询问解决方案:solve(Street)

然而,这作为解决方案出现:

  1. 房子(花、食物、宠物、运动)
  2. 房子(花、食物、宠物、运动)
  3. 房子(x ,食物,宠物,运动)
  4. 房子(花、食物、宠物、运动)
  5. 房子(x,花,宠物,运动)

如您所见,有 2 次x,其余的是所有类型的食物、鲜花、宠物和运动。但每一种类型都是独一无二的:如果一个人喜欢花 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), with :当 A 和 B 在 中彼此相邻时is_neighbour(A,B,List)给出。提示可以翻译为:热爱足球的人住在有鱼的人旁边。trueList

如果需要提供更多信息,我愿意详细说明。:)

4

1 回答 1

2

为了表示没有花被报告两次,并且确保所有花都被绑定,可以使用 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,
       --...
于 2010-12-10T16:17:54.113 回答