检查确保所有酒店客人获得一组唯一钥匙的两种方法的等价性

Check the equivalence of two approaches to ensuring that all hotel guests get a unique set of keys

[更新] 感谢@Loïc Gammaitoni 提供答案。根据 Loïc 的见解,这是我创建的模型,用于测试两种方法的等效性:

sig Key {}

sig Room {
    keys: set Key
}

pred DisjointKeySet_v1 {
    keys in Room lone -> Key
} 

// See page 274 of Software Abstractions.
// It says that this: sig S {f: disj e}
// is equivalent to the constraint:
// all a,b: S | a != b => no a.f & b.f
pred DisjointKeySet_v2 {
    all r, r': Room | r != r' => no  r.keys & r'.keys
} 

assert Equivalent {
    DisjointKeySet_v1  iff DisjointKeySet_v2 
}
check Equivalent

酒店的每位客人都会获得一组钥匙:

sig Key {}

sig Room {
    keys: set Key
}

我们必须限制钥匙组,以便没有两个客人获得相同的钥匙。这是实现该约束的一种方法:

fact DisjointKeySet {
    keys in Room lone -> Key
}

实现约束的第二种方法涉及修改键的声明:

sig Room {
    keys: disj set Key
}

这两种方法是否等效?

我相信他们是。

为了确定,我希望 Alloy 分析器比较这两种方法并搜索反例。

如何做到这一点?如何编写正确的断言?

下面是我创建的断言。我认为它正确地检查了两种方法的等效性。你同意?我的断言似乎迂回。有没有更直接的方式来显示等价性?

sig Key {}

sig Room {
    keys: disj set Key
}

// If each room has a disjoint set of keys,
// then each key may be used with only
// one room
assert Equivalent {
    no k: Key, disj r, r': Room |
        (k in r.keys) and (k in r'.keys)            
}
check Equivalent

关键字 disj 在此上下文中是 all a, b: Room| a!=b implies no a.keys & b.keys 的 shorthand(c.f。软件抽象的附录 B)

要回答您的问题,您可以检查断言:

assert equivalence {
    (keys in Room lone -> Key) <=> (all a, b: Room| a!=b implies no a.keys & b.keys)
}

结果表明这两种方法是等效的。