Auch wird hier eine Art der Ausgabe vorgestellt, die es ermöglicht, die Ergebnisse sofort abzulesen, ohne jegliche Zuordnungen im nachhinein treffen zu müssen.
Kürzlich spielten also Timo und drei andere Angestellte eine 18 Loch Runde auf dem Platz. Zum Abschluss gingen alle vier - einschließlich Herrn Becker - zum Clubhaus, um ihrer Ergebnisse zusammenzurechnen. Jeder der vier hat einen anderen Beruf (einer ist Koch) und jeder erzielte ein anderes Ergebnis auf der Runde. Niemand benötigte weniger als 70 Schläge oder mehr als 85. Ist es möglich aus folgenden Hinweisen von jedem Angestellten den vollen Namen, seinen Beruf und seine Schläge zu ermitteln?
VN = [Sven, Ole, Klaus, Timo], NN = [Budde, Krug, Mueller, Becker], Jobs = [Gaertner, Caddy, Verkaeufer, Koch], |
Diesen Listen lässt sich durch die Aufgabenstellung als Domain sehr schnell ein Integerintervall von 70 bis 85 zuweisen, welches allerdings aufgrund des fünften Hinweises den Wert 81 ausschließt.
VN :: [70..80,82..85], NN ::[70..80,82..85], Jobs :: [70..80, 82..85], |
Aufgrund der Aussage, dass alle Spieler ein unterschiedliches Ergebnis erzielten, kann festgestellt werden, dass alle Variablen einer Liste unterschiedliche Werte annehmen müssen. Dies erreichen wir, indem wir die alldifferent-Regel der fd-Bibliothek anwenden.
alldifferent(VN), alldifferent(NN), alldifferent(Jobs), |
Um eine komfortable Ausgabe zu ermöglichen, bei der keine nachträgliche Zuordnung einzelner Werte zueinander über Zahlen erfolgen muss, wird hier
kurz ein Konzept vorgestellt, welches mit sogenannten Units arbeitet. Hierbei werden zwei Listen definiert, deren Elemente (unit) die gleiche Struktur haben.
Ein Element besteht aus Schlägen, Vorname, Nachname und Beruf.
Die erste Liste namens Units enthält genau vier Elemente - wir haben vier Spieler - mit der beschriebenen Struktur. Alle Variablen darin sind anonym, dass
heißt, sie enthalten noch keine Werte.
Units = [ unit(_,_,_,_), unit(_,_,_,_), unit(_,_,_,_), unit(_,_,_,_)], |
Die zweite Liste namens Constraints verknüpft die oben eingeführten Variablen mit den zum jetzigen Zeitpunkt bekannten Werten, nämlich den Vornamen, Namen und Berufen. Wie bereits erwähnt haben die Elemente dieser Liste die gleiche Struktur wie die Elemente in der Liste Units.
Constraints = [ unit(Sven, sven, _,_), unit(Ole, ole, _,_), unit(Klaus, klaus,_,_), unit(Timo, timo, _,_), unit(Budde, _, budde, _), unit(Krug, _, krug,_), unit(Mueller, _, mueller, _), unit(Becker, _, becker, _), unit(Gaertner, _,_,gaertner), unit(Caddy, _,_,caddy), unit(Verkaeufer, _,_,verkaeufer), unit(Koch, _,_,koch)], |
Im nächsten Schritt werden die Einschränkungen, welche sich aus den fünf Hinweisen herleiten lassen, definiert.
Sven ## Gaertner, Sven #< Ole, Sven #< Klaus, Sven #< Timo, Budde ## Ole, Budde #= Verkaeufer + 10, (Klaus #= Mueller + 7, Caddy #= Mueller + 4; Klaus #= Mueller + 4, Caddy #= Mueller + 7), Krug #= 78, Klaus #< Krug, |
Zum Abschluss wird die Regel "psubset" aufgerufen, welche den Elementen in der Liste Units die Werte zuweist. Dies geschieht indem nach der Auswertung der Bedingungen überprüft wird, ob die Elemente der Liste Constraints in der Liste Units enthalten sind. Dies ist der Fall, wenn die Anzahl der Schläge identisch ist und die im Element der Liste Constraints belegte weitere Variable in der Liste Units noch nicht belegt, also anonym ist. Sollte dies nicht der Fall sein, erfolgt ein Rückschritt gemäß des Backtrackingalgorithmus. Auf diese Weise wird die komplette Liste Constraints abgearbeitet.
Dem interessierten Leser sei an dieser Stelle auch der komplette Quelltext zur Verfügung gestellt.
Als Lösung erhält man:
Schläge | Vorname | Nachname | Beruf |
---|---|---|---|
71 | Sven | Mueller | Koch |
78 | Ole | Krug | Caddy |
75 | Klaus | Becker | Verkaeufer |
85 | Timo | Budde | Gaertner |