I am trying to solve the below puzzle in Mozart oz.
Susie loved animals and had a large collection of stuffed animals. However, there were several that were her favorites. She decided this morning to rearrange her stuffed animals and give each of her favorites a special place in her room. Along with a name, each of her favorite stuffed animals also had an age and all were younger than her, of course. Determine the names of her favorite stuffed animals, the type of each animal, how old she deemed each of the animals (from one to five years), and where in her room she placed each of her favorites.
The skunk was two years old. The tiger was a year younger than the animal placed on the bookshelf, but the tiger was also a year older than Cuddles.
The animal placed on the chair was two years older than Willie and a year younger than the whale.
Cuddles wasn't the skunk. Boo wasn't five years old.
The cat was placed on the bed.
The bear was two years older than Spot. Amee was the whale but she wasn't placed on the pillow.
Cuddles wasn't placed on the bench.
This puzzle was taking from http://www.puzzles.com/Projects/LogicProblems/SusiesAnimals.htm
and my code is -
declare
proc {Tiger Nb}
Groups = [ [cuddles willies boo spot amee]
[skunk tiger whale cat bear]
[bookshelf chair bed pillow bench]]
Properties = {FoldR Groups Append nil}
proc {Partition Group}
{FD.distinct {Map Group fun {$ P} Nb.P end}}
end
in
%% Nb maps all properties to age
{FD.record number Properties 1#5 Nb}
{ForAll Groups Partition}
Nb.skunk = 2
Nb.tiger =(1 - Nb.bookshelf)+
Nb.tiger = 1 + Nb.cuddles
Nb.chair = 2 + Nb.willies
Nb.chair = 1 - Nb.whale
Nb.cuddles \=: Nb.skunk
Nb.boo \=: 5
Nb.cat = Nb.bed
Nb.bear = 2 + Nb.spot
Nb.amee = Nb.whale
Nb.amee \=: Nb.pillow
Nb.cuddles \=: Nb.bench
{FD.distribute ff Nb}
end
{Browse {SearchAll Tiger}}
I am trying to solve it by using the age numbers as the header and expecting the result with the age numbers. Similar to the Zebra problem http://doc.uh.cz/Mozart-oz/doc/fdt/node23.html
I am getting this output which is not what I was expecting and I don't understand it:
Can you tell me where I am going wrong?
The problem is that =
is not a propagator and if for Nb.cat = Nb.bed
there is no difference, in case of Nb.tiger = 1 + Nb.cuddles
it plays crucial role.
While you write something like Nb.tiger = 1 + Nb.cuddles
, Nb.cuddles
must be already calculated, but for now, all we know is that it belongs to interval 1#5
.
There are two possibilities: either force calculation of Nb.cuddles
or use a propagator FD.plus
(or equivalently =:
). Of course being legal, first possibility is not a recommended way of handling this because it ruins the whole idea of constraints over finite domain, as it equivalent to simple enumeration of all possible values for Nb.cuddles
.
Also note that instead of Nb.tiger =(1 - Nb.bookshelf)+
it must be Nb.tiger =: Nb.bookshelf - 1
and instead of Nb.chair = 1 - Nb.whale
-- Nb.chair =: Nb.whale - 1
.
Thus, the correct solution:
declare proc {Tiger Nb} Groups = [ [cuddles willies boo spot amee] [skunk tiger whale cat bear] [bookshelf chair bed pillow bench]] Properties = {FoldR Groups Append nil} proc {Partition Group} {FD.distinct {Map Group fun {$ P} Nb.P end}} end in %% Nb maps all properties to age {FD.record number Properties 1#5 Nb} {ForAll Groups Partition} Nb.skunk = 2 Nb.cuddles \=: Nb.skunk Nb.boo \=: 5 Nb.cat = Nb.bed Nb.amee = Nb.whale Nb.amee \=: Nb.pillow Nb.cuddles \=: Nb.bench {FD.distribute ff Nb} end {Browse {SearchAll Tiger}}
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.