2010-12-10 20 views
4

Ich implementiere eine Variation von Einsteins Rätsel und ich habe einige Probleme.Einzigartige Elemente in der Liste (Prolog)

Wenn die Lösung zu berechnen versucht, ich versuche dies:

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

ich dann die Lösung, indem Sie fragen: solve (Street)

jedoch diese als Lösung kommt:

  1. Haus (Blume, Lebensmittel, Haustier, Sport)
  2. Haus (Blume, Nahrung, Haustier, Sport)
  3. Haus (x, Lebensmittel, Haustier, Sport)
  4. Haus (Blume, Lebensmittel, Tier, Sport)
  5. Haus (x, Blume, Tier, Sport)

Wie Sie können siehe dort ist 2 mal x, der Rest sind alle Arten von Lebensmitteln, Blumen, Haustiere und Sport. Aber jeder Typ ist einzigartig: Wenn eine Person Blume X mag, kann niemand sonst X mögen.

Jetzt ist der Grund, warum meine Lösung gibt 2 X ist leicht zu sehen: Wir sind eine Menge Hinweise gegeben, aber in allen Hinweise dort sind nur 4 Blumen erwähnt. Prolog weiß also nicht, dass es eine andere Blume gibt, und verwendet x zweimal, nur weil es möglich ist und alle anderen Hinweise erfüllt.

Was ich sagen möchte ist, dass alle Arten von Lebensmitteln und Blumen etc. in Street sind einzigartig, so dass er einige leere verlassen sollte, wenn er alle Arten bereits verwendet. 3 würde so aussehen: house(x , food, pet ,sport) und 5 würde wie folgt aussehen: house(_, flower, pet, sport).

Ich habe versucht, auch diese Zugabe die Hinweise: (sagen wir mal „Kaktus“ eine der Blumen ist nicht in den Hinweisen erwähnt) member(house(cactus,_,_,_), Street)

aber dann ist mein Programm nicht zu Ende ...

Ein Hinweis kann wie folgt aussehen: is_neighbour(house(_,_,_,football),house(_,_,fish,_), Street), mit: is_neighbour(A,B,List)true geben, wenn A und B in List nebeneinander sind. Der Hinweis kann übersetzt werden: Die Person, die Fußball liebt, lebt neben der Person, die Fisch hat.

Wenn weitere Informationen zur Verfügung gestellt werden müssen, bin ich bereit zu erarbeiten. :)

Antwort

2

Um auszudrücken, dass keine Blume zweimal gemeldet wird, und um sicherzustellen, dass alle Blumen gebunden sind, können Sie das Permutation/2-Prädikat verwenden: Die Liste aller Blumen sollte eine Permutation der Liste der angegebenen Blumen sein . Dies würde lesen wie [ungetestet]

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

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

bearbeiten: 10 Blumen, Permutationen ist wahrscheinlich zu langsam.Ein alternativer Ansatz ist

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

Klingt wie eine logische und verständliche Antwort, aber ich muss etwas falsch machen .. Ich fügte alle Blumen in der zweiten Liste der Permutation. Ich habe auch 'Blumen (Straße, Blumen)' und die Permutation zum 'lösen (Straße)' gesetzt. Aber jetzt scheint es nicht zu enden. (normalerweise würde es innerhalb von 5 Minuten enden, aber jetzt sind es über 15 Minuten.) Ist es wichtig, wo ich die "Permutation" einsetze? – Aerus

+0

Permutation sollte für beide Argumente symmetrisch sein, daher sollte das Austauschen der Argumente nicht helfen. Die Verwendung des Permutationsaufrufs an einem anderen Ort sollte jedoch sehr hilfreich sein: Sie sollten zuerst die Bedingungen angeben, die den Lösungsraum am stärksten einschränken. Schreibe Anrufe hinein, damit sie verfolgen können, was sie macht. –

+0

Wenn ich einen Aufruf (write()) um die Permutation am Ende der Hinweise gebe es: Permutation ([Geranie, Hyacint, ** Lelie **, Dahlie, ** Lelie **], [Kaktus, Lelie, Geranie, Hyacint, Dahlie]). Wenn ich es vor alle Hinweise stelle, die es mir gibt: Permutation ([_ 46, _53, _60, _67, _74], [Kaktus, Lelie, Geranie, Hyacint, Dahlie]). Ich bin mir nicht sicher, was das zuerst bedeutet. Die Ausgabe gibt mir immer noch 2 x, aber es endet jetzt. Muss ich auch Permutationen für die anderen Typen hinzufügen, damit diese einzelne Permutation funktioniert? – Aerus