使用所有已定义关系的子集

Using a subset of all defined relations

module test

sig Foo {}

sig A {
    b: set B,
    foo: one Foo
}

sig B {
    foo: one Foo
}

assert foo {
    all s: (univ - Foo) | all rel: (univ - Foo) -> (univ - Foo) |
    s not in s.*rel
}

check foo for 2

假设我试图在一个断言中定义一个关系,该关系说 "apart from Foo and the relations that include Foo, there are no cycles"(通过此处的检查,这是平凡的)。

上面的断言创建了一些最初未在模型中定义的 $foo_rel 关系。如何将其限制为我在 sig 中指定的关系?

变量 $foo_rel$foo_s 是由于 skolemization 引入的,因为您正在对 arity 2 元组进行量化。 (就个人而言,到目前为止,我一直忽略了 skolemization 的细节,只在它不起作用时才讨厌它。)

不过,我认为这不是你的问题。我 运行 没有整数的模型:

check foo for 2 but 0 int

这给出了以下解决方案:

---INSTANCE---
integers={}
univ={B[=11=], Foo[=11=]}
Int={}
seq/Int={}
String={}
none={}
this/Foo={Foo[=11=]}
this/A={}
this/A<:b={}
this/A<:foo={}
this/B={B[=11=]}
this/B<:foo={B[=11=]->Foo[=11=]}
skolem $foo_s={B[=11=]}
skolem $foo_rel={B[=11=]->B[=11=]}

当我们去评估器时,我们可以逐步进行量化:

> univ-Foo
┌──┐
│B⁰│
└──┘
> (univ - Foo) -> (univ - Foo)
┌──┬──┐
│B⁰│B⁰│
└──┴──┘

很明显,如果您量化超过 all rel: (univ - Foo) -> (univ - Foo),这将包括循环。

> B⁰.*((univ - Foo) -> (univ - Foo))
┌──┐
│B⁰│
└──┘

我认为对 Alloy 模型的工作原理存在一些误解。我希望这有助于更好地探索这些模型?