如何表示一组值应该是不同的?
How to denote that a set of values should be distinct?
有没有一种合理的方式来表示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 ...
}
但这看起来非常冗长而且相当难看。这样做的正确方法是什么?
您的建议表明每组应该不同,而不是每组不相交。要检查集合是否不相交,您可以简单地检查它们的交集 (&) 是否为空。
你可以这样写:
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
}
有没有一种合理的方式来表示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 ...
}
但这看起来非常冗长而且相当难看。这样做的正确方法是什么?
您的建议表明每组应该不同,而不是每组不相交。要检查集合是否不相交,您可以简单地检查它们的交集 (&) 是否为空。
你可以这样写:
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
}