检查 Alloy 中的 Sig 相等性

Checking Sig Equality in Alloy

在以下 Alloy 模型中,我想检查具有 Bool 字段类型的 sig 的两个实例是否相等:

module test

open util/boolean as bool


sig Info {
    active: Bool
}

assert assertion {
    all x1, x2: Info |
        x1.active = True && x2.active = True implies x1 = x2
}

check assertion for 10

如果 x_1x_2active 字段都具有 True,则此模型会检查它们是否相等。 Alloy 返回一个反例,然而,在反例中,x_1x_2 在结构上是相等的,但由于某种原因 Alloy 认为它们不相等。

编辑:

一个建议是使用子类型如下:

sig Info {}

sig ActiveInfo in Info {}

-- i is inactive if i in (Info - ActiveInfo) 

但是,这不适合我的模型。

引自《软件抽象》一书:

相等是结构相等还是引用相等?

A relation has no identity distinct from its value, so this distinction, based on programming notions, doesn’t make sense here. If two relations have the same set of tuples, they aren’t two relations: they’re just one and the same relation. An atom is nothing but its identity; two atoms are equal when they are the same atom. If you have a set of atoms that represent composite objects (using some relations to map the atoms to their contents), you can define any notion of structural equality you want explicitly, by introducing a new relation. (And for those C++ programmers out there: no, you can’t redefine the equals symbol in Alloy.)"

这段我不太明白。我很欣赏关于 Alloy 中平等如何运作的解释。特别是关于如何检查具有不同身份但相同值的原子的相等性?

I know that equality in Alloy is based on values.

这不是真的。 x1x2active 具有相同的值,但在签名中是不同的原子。这类似于许多 OOP 语言中的方式,两个对象可以具有相同的结构值但具有不同的身份。

顺便说一下,我建议使用子类型来表示布尔值。你可以做

sig Info {}

sig ActiveInfo in Info {}

-- i is inactive if i in (Info - ActiveInfo) 

如果愿意,您可以将签名中的字段视为“属于”该签名的一个原子,但最好将字段视为关系。如果两个人有同一个母亲,你不会指望他们是一样的:

sig Person {mother: Parent} 

但是如果您希望您的签名具有 属性 没有两个不同的成员具有相同的字段,您可以将其添加为事实:

sig Coordinate {x, y: Value}
fact {all c, c': Coordinate | (c.x = c'.x and c.y = c'.y) implies c = c'}