Alloy 约束如何将集合放入其子集中?

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

下面的Alloy代码表示每个旅馆房间都有一组钥匙:

sig Key {}

sig Room {
    keys: set Key
}

keys关系需要约束。就目前而言,它允许这样的情况:密钥 K1 在一堆房间中使用。哎哟!我们不想要那样。我们希望每把钥匙只能用于一个房间。下图说明了有效实例的范围(以及我们实际想要允许的实例子集):

我们实际想要的实例集可以用 Alloy 代码很好地表达:

Room lone -> Key

该 Alloy 代码的实例在上图中用小圆圈表示。

那么,我们如何约束keys?一个答案是这样的:创建一个 Alloy 事实,上面写着:

keys in Room lone -> Key

想一想图形上说的是什么。它是说大圆圈必须在小圆圈内(见下文)。这不是很奇怪吗?一个圆怎么能在它的子圆里面呢?有人可以给我一些直觉吗?好像有点奇怪。

  • 如果你只有sig Room {keys: set Key}没有任何额外的facts/constraints,keys关系的定义域是大圆;

  • 你可以决定添加一些约束(如keys in Room lone -> Key),正是为了缩小keys关系的域(使其成为小圆圈) .

所以正确的思考方式并不是大圆一定在小圆里面(?!);相反,可以将其视为使用小圆圈而不是大圆圈作为 keys.

的域(所有有效值的集合)