2010-12-10 93 views
4

我在爱因斯坦的谜语上实现了一个变体,我遇到了一些麻烦。列表中的唯一元素(Prolog)

当试图计算解决方案,我试试这个:

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朵花。所以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彼此相邻。 提示可以被翻译为:热爱足球的人在有鱼的人旁边生活。

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

回答

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, 
     --... 
+0

听起来像一个逻辑和可以理解的答案,但是我必须做错了什么..我添加了第二个列表中的所有花。我还把“花(街,花)”和排列交给“解决(街道)”。但现在似乎并没有结束。 (通常它会在5分钟内结束,但现在已经超过了15分钟)。我把'permutation'放在哪里有什么关系? – Aerus 2010-12-10 22:19:32

+0

置换对于两个参数都应该是对称的,所以交换参数不应该有帮助。然而,将排列组合置于不同的位置应该非常有帮助,但是:您应该首先考虑那些限制解决方案空间的条件。将写入的调用放入它中,让它跟踪它正在做什么。 – 2010-12-10 22:27:59

+0

当我在它给出的提示末尾的排列周围放置一个调用(写()):置换([天竺葵,hyacint,** lelie **,大丽花,** lelie **],[仙人掌,天竺葵,hyacint,大丽花])。当我把它放在它给我的所有提示面前时:置换([_ 46,_53,_60,_67,_74],[仙人掌,lelie,天竺葵,hyacint,大丽花])。我不确定那是什么意思。输出仍然给我2 x的,但它现在结束了。我是否还需要为其他类型添加排列,以便使这个单一排列有效? – Aerus 2010-12-10 22:53:18