简单 Alloy 约束没有按预期工作

Simple Alloy constraint doesn't work as expected

当 Books 的数量限制为 1 时,以下模型生成恰好具有 2 个地址关系的实例,但是,如果允许更多的 Books,它将创建具有 0-3 个地址关系的实例。我对 Alloy 工作原理的误解?

sig Name{}
sig Addr{}
sig Book { addr: Name -> lone Addr }
pred show(b:Book) { #b.addr = 2 } 
// nr. of address relations in every Book should be 2
run show for 3 but 2 Book 
// works as expected with 1 Book

show 的每个实例都应包括一本书,标记为 showb,它有两个地址对。但是 show 并没有说 每本 书必须有两个地址对,只是说至少一本必须有两个地址对。

[后记]

当你要求 Alloy 向你展示一个谓词的实例时,例如通过命令 run show,那么 Alloy 应该向你展示一个实例:即(引用部分软件抽象 的 5.2.1,你已经打开了)"an assignment of values to the variables of the constraint for which the constraint evaluates to true." 在任何给定的宇宙中,可能有许多其他可能的值分配给约束评估的变量假的;在任何多于一个原子的宇宙中,这种可能的不合适分配的存在是不可避免的。

通俗地说,我们可以将带有参数 X、Y、Z 的谓词 P 的 run 命令视为请求 Alloy 向我们展示满足表达式

的宇宙
some X, Y, Z : univ | P[X, Y, Z]

run命令等于表达式

all X, Y, Z : univ | P[X, Y, Z]

如果您只想查看 每本 书在其 addr 关系中有两对的宇宙,那么这样说:

pred all_books_have_2 { all b : Book | #b.addr = 2 }

我认为 run 具有隐式存在量化比隐式通用量化更好。了解原因的一种方法是想象一个定义树的模型,例如:

sig Node { parent : lone Node }
fact parent_acyclic { no n : Node | n in n.^parent }

假设我们厌倦了看到每棵树都是微不足道的并且包含单个节点的宇宙。我希望能够通过编写

来定义一个谓词,该谓词保证至少有一棵深度大于 1 的树
pred nontrivial[n : Node]{ some n.parent }

鉴于树是非循环的约束,永远不会有一个非空的宇宙,其中谓词 nontrivial 对所有节点都成立。因此,如果 runpred 具有您一直假设的语义,我们就无法使用 nontrivial 找到包含非平凡树的宇宙。

希望对您有所帮助。