【发布时间】:2017-09-05 21:10:52
【问题描述】:
Alloy 中的自反和非自反传递闭包是什么?它们在 Alloy 中有何不同?
谢谢,
【问题讨论】:
Alloy 中的自反和非自反传递闭包是什么?它们在 Alloy 中有何不同?
谢谢,
【问题讨论】:
非自反传递闭包运算符是^。 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
【讨论】:
transitive closure (^) 和reflexive transitive closure (*) 都是一元运算符,只能应用于二元关系的操作数>.
二元关系bar的传递闭包是定义为的二元关系
^bar = bar + bar.bar + bar.bar.bar + ...
二元关系bar的自反传递闭包是定义为的二元关系
*bar = iden + ^bar
其中iden 是身份二元关系。
两个传递闭包运算符最常见的使用模式是它前面有一个关系连接,例如@LEJ 提供的示例:foo.^bar 和foo.*bar。值得注意的是,.^ 和 .* 没有什么神奇之处:点运算符 (.) 是同一个旧的关系连接,^ 和 * 运算符是上面定义的闭包运算符.因此,如果您计算出方程式,您将得到 @LEJ 已经提供的 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 + ...
【讨论】: