Hi,
I tried to model a puzzle in Alloy 6 to get familiar with the new notation of mutable states and temporal logic in Alloy 6.
Usually, I use B and Event-B for modeling and ProB for animation and verification.
The puzzle:
45 chameleons live on an island, 13 of which are blue, 15 green and 17 yellow.
If two chameleons of different colors meet, they change their color to the third color.
Show that this doesn’t make it possible for all chameleons to be yellow at some point.
My attempt in Alloy 6 which does not seem to be correct:
enum colors {blue,green,yellow}
var sig population {
var chameleons: colors -> one Int
}
fact init {
(population.chameleons)[blue] = 13 and
(population.chameleons)[green] = 15 and
(population.chameleons)[yellow] = 17
}
pred meet[c1: colors, c2: colors] {
c1 != c2 and (population.chameleons)[c1] > 0 and (population.chameleons)[c2] > 0 and // guard
after (let c3 = ((colors - c1) - c2) | // action
population'.chameleons' =
(((population.chameleons ++ (c1->(minus[(population.chameleons)[c1],1])))
++ (c2->(minus[(population.chameleons)[c2],1])))
++ (c3->(plus[(population.chameleons)[c3],2]))
))
}
pred skip {
after population'.chameleons' = population.chameleons
}
fact step {
always ((some c1,c2: colors | meet[c1,c2]) or skip)
}
assert invariant {
always (not ((population.chameleons)[blue] = 0 and (population.chameleons)[green] = 0))
}
check invariant for 7 Int, 100 steps
When checking the invariant, I receive the counterexample (population.chameleons)[blue] = 0 and (population.chameleons)[green] = 0 and (population.chameleons)[yellow] = -63
.
I don’t know how this state can be reached. The predicate skip
does not change anything, and the predicate meet[c1,c2]
decrements the amount of chameleons with colors c1 or c2 by one and increments the amount of chameleons with the third color by two.
If I change the “action” of the predicate meet[c1,c2]
to be population'.chameleons' = population.chameleons
there should only be skip actions.
Yet, I receive the counterexample (population.chameleons)[blue] = 0 and (population.chameleons)[green] = 0 and (population.chameleons)[yellow] = 62
.
Again, I don’t understand how this state can be reached when only skip actions are available.
I am obviously missing an important aspect of mutable states in Alloy 6.
Any help is appreciated.
Greetings,
Joshua
Edit: a more detailed description of the puzzle can be found here