简体   繁体   中英

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)

However this comes up as solution:

  1. house(flower, food, pet, sport)
  2. house(flower, food, pet, sport)
  3. house( x , food, pet, sport)
  4. house(flower, food, pet, sport)
  5. house( x , flower, pet, sport)

As you can see there's 2 times x , the rest are all types of foods, flowers, pets and sports. But every type is unique: if one person likes flower X, noone else can like 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. 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.

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

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)

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 . 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. This would read like [untested]

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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