简体   繁体   English

列表中的唯一元素(序言)

[英]Unique elements in list (Prolog)

I'm implementing a variation on Einstein's Riddle and i'm having some trouble. 我正在对爱因斯坦的谜语实施一个变体,遇到了一些麻烦。

When trying to calculate the solution i try this: 当尝试计算解决方案时,我尝试这样做:

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

I can then ask the solution by typing: solve(Street) 然后我可以通过键入以下内容来询问解决方案:solve(Street)

However this comes up as solution: 但这是解决方案:

  1. house(flower, food, pet, sport) 房子(花,食物,宠物,运动)
  2. house(flower, food, pet, sport) 房子(花,食物,宠物,运动)
  3. house( x , food, pet, sport) 房子( x ,食物,宠物,运动)
  4. house(flower, food, pet, sport) 房子(花,食物,宠物,运动)
  5. house( x , flower, pet, sport) 房子( x ,花,宠物,运动)

As you can see there's 2 times x , the rest are all types of foods, flowers, pets and sports. 如您所见, x是2倍,其余的是所有类型的食物,花卉,宠物和运动。 But every type is unique: if one person likes flower X, noone else can like X. 但是每种类型都是唯一的:如果一个人喜欢X花,那么没有人会喜欢X。

Now, the reason why my solution gives 2 x's is easy to see: we are given an amount of hints but in all the hints there are only mentioned 4 flowers. 现在,我的解决方案给出2 x的原因很容易理解:我们得到了很多提示,但在所有提示中只提到了4朵花。 So Prolog doesn't know there is another flower, and just uses x twice, just because it's possible and fulfills all the other hints. 因此Prolog不知道还有另一朵花,只使用x两次,只是因为它是可能的并且满足所有其他提示。

What i want to say is that all the types of foods and flowers etc. in Street are unique so he should leave some blank when he used all types already. 我要说的是,街上所有类型的食物和鲜花等都是唯一的,因此当他已经使用所有类型的食物时,他应该留一些空白。 3 would look like: house(x , food, pet ,sport) and 5 would look like: house(_, flower, pet, sport) . 3看起来像: house(x , food, pet ,sport) ,5看起来像: house(_, flower, pet, sport)

I also tried adding this to the hints: (let's say "cactus" is one of the flowers not mentioned in the hints) member(house(cactus,_,_,_), Street) 我还尝试将其添加到提示中:(假设“仙人掌”是提示中未提及的花朵之一) member(house(cactus,_,_,_), Street)

However then my program doesn't end... 但是然后我的程序并没有结束...

A hint may look like this: is_neighbour(house(_,_,_,football),house(_,_,fish,_), Street), with : is_neighbour(A,B,List) giving true when A and B are next to each other in List . 提示可能看起来像这样: is_neighbour(house(_,_,_,football),house(_,_,fish,_), Street),其中: is_neighbour(A,B,List)在A和B时为trueList彼此相邻。 The hint can be translated to: the person who loves football lives next to the person who has fish. 提示可以翻译为:热爱足球的人与有鱼的人住在一起。

If any more info need to be provided i'm willing to elaborate. 如果需要提供更多信息,我愿意详细说明。 :) :)

To express that no flower is reported twice, and also to make sure that all flowers are bound, you can use the permutation/2 predicate: the list of all flowers should be a permutation of the list of specified flowers. 为了表示没有两次报告任何花朵,并确保所有花朵都已绑定,可以使用permutation / 2谓词:所有花朵的列表应该是指定花朵列表的一个排列。 This would read like [untested] 这看起来像[unested]

flowers([], []).
flowers([house(Flower,_,_,_)|Street], [Flower|Rest]) :- flowers(Street, Rest).

-- ...
   flowers(Street, Flowers), 
   permutation(Flowers, [kaktus, tulpe, nelke, rose, fingerhut]),

Edit : for 10 flowers, using permutations is probably too slow. 编辑 :对于10朵花,使用排列可能太慢。 An alternative approach is 另一种方法是

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM