How can an Alloy constraint put a set inside its subset?

136 views Asked by At

The following Alloy code says that each hotel room has a set of keys:

sig Key {}

sig Room {
    keys: set Key
}

The keys relation needs to be constrained. As it stands, it permits instances such as this: key K1 is used in a bunch of rooms. Ouch! We don't want that. We want each key to be used only with one room. Here's a graphic illustrating the universe of valid instances (and the subset of instances that we actually want to allow):

Universe of room/key instances

The set of instances that we actually want is nicely expressed with this Alloy code:

Room lone -> Key

The instances for that Alloy code is depicted in the above graphic by the small circle.

So, how do we constrain keys? One answer is this: create an Alloy fact which says this:

keys in Room lone -> Key

Think about what that is graphically saying. It is saying that the big circle must be inside the little circle (see below). Isn't that weird? How can a circle be inside its sub-circle? Can someone give me some intuition about this please? It seems odd.

Big circle inside small circle

1

There are 1 answers

1
Aleksandar Milicevic On BEST ANSWER
  • if you only have sig Room {keys: set Key} without any additional facts/constraints, the domain for the keys relation is the big circle;

  • you can decide to add some constraints (like keys in Room lone -> Key) exactly for the purpose of shrinking the domain for the keys relation (so that it becomes the small circle).

So the right way to think about it is not that the big circle must be inside the small circle (?!); rather, think of it as using the small circle instead of the big circle as the domain (set of all valid values) for keys.