是否有合理的方法来表示n个元素需要彼此不同?具体来说,我有一个类似于这个的信号:
sig Node {
up: lone Node,
left: lone Node,
right: lone Node,
left_down: lone Node,
right_down: lone Node
}
并且想要写一个事实,它将这些定义为对于任何给定节点都是不同的。我相当肯定我可以把它写成NxN矩阵,就像这样:
fact {
all n: Node | n.up != n.left && n.up != n.right && n.up != n.left_down ...
}
但这看起来非常冗长而且相当丑陋。这样做的正确方法是什么?
答案 0 :(得分:2)
你的建议表明每一组应该是不同的,而不是每一组是不相交的。要检查这些集是否不相交,您只需检查它们的交集(&)是否为空。
你可以写:
sig Node {
up: lone Node,
left: lone Node,
right: lone Node,
left_down: lone Node,
right_down: lone Node
}{
up & left=none and
right & left_down=none and
(up + left )& (right + left_down)=none and
(up + left + right + left_down)&right_down=none
}
一种不那么冗长但更丑陋的做事方式是将每个节点与这些集合的交集相加,并确保总和始终为零或一。
sig Node {
up: lone Node,
left: lone Node,
right: lone Node,
left_down: lone Node,
right_down: lone Node
}{
all n:Node | add[add[add[add[#(n&up),#(n&left)],#(n&right)],#(n&left_down)],#(n&right_down)] in 0+1
}