Alloy中的自反和非自反传递闭包是什么?它们在Alloy中有何不同?
谢谢,
答案 0 :(得分:4)
非自反传递闭包运算符为^
。 foo.^bar
是foo
相对于bar
的非自反传递闭包。这将通过将.bar
应用于foo
一次或多次来返回您可以生成的所有内容。例如,foo.^bar
等于以下表达式的并集:
foo.bar
foo.bar.bar
foo.bar.bar.bar
foo.bar.bar.bar.bar
...
此列表无限。
自反传递闭包运算符为*
。 foo.*bar
是foo
相对于bar
的自反传递闭包。通过将.bar
应用于foo
零次或多次,这将返回您可以生成的所有内容集。例如,foo.*bar
等于以下表达式的并集:
foo
foo.bar
foo.bar.bar
foo.bar.bar.bar
...
此列表也是无限的。这相当于foo + foo.^bar
答案 1 :(得分:0)
transitive closure
(^
)和reflexive transitive closure
(*
)都是一元运算符,它们只能应用于一个操作数二元关系。
二元关系bar
的传递闭包是定义为
^bar = bar + bar.bar + bar.bar.bar + ...
二元关系bar
的自反传递闭包是定义为
*bar = iden + ^bar
其中iden
是标识二元关系。
两个传递闭包运算符的最常见用法模式是它之前是关系连接,如@LEJ:foo.^bar
和foo.*bar
提供的示例。值得注意的是.^
和.*
中没有魔法:点运算符(.
)是旧的关系连接,^
和{{1运算符是上面定义的闭包运算符。因此,如果您计算出方程式,您将得到*
和foo.^bar
已经提供的foo.*bar
的相同表达式:
foo.^bar = foo.(^bar) = foo.(bar + bar.bar + ...) = foo.bar + foo.bar.bar + ...
foo.*bar = foo.(*bar) = foo.(iden + bar + bar.bar + ...) = foo + foo.bar + foo.bar.bar + ...