是否有任何操作返回Alloy中关系的范围和域。
假设我在Alloy中定义了一个sig:
sig A {r : B }
sig B {}
我正在寻找和操作应用于r并给我B(可能像r [B]返回B)
上述情况可能看起来很愚蠢,因为r [B]会返回B,所以我为什么不在第一时间使用B!实际上我发现有一个范围和域操作(如果它们存在)在编写事实(约束)时非常有用。 e.g:
sig O {sup:O}
sig M{mid: O, sup:O} {mid.sup=sup}
sig F{fid:O, sup:O}{fid.sup=sup}
fact K{
all o:O | lone so:M | so.mid=o
all o:O | lone so:F | so.fid=o
all o:O | one i:(fid+mid) | o in i[O] //I want to say fid+mid is injective, so expecting i[O] return range of i
}
任何想法? :)
答案 0 :(得分:5)
您将分别在名称ran
和dom
下的库模块relation.als中找到二进制关系的范围和域函数。丹尼尔杰克逊关于软件抽象的书中的第3.2.5和3.4.3.6节进行了简短的讨论。
另一方面,您也可以不使用库函数。对于任何二元关系 r , r 的域和范围也可以轻松表示为 r.univ 和 univ.r < / em>,分别。使用box运算符而不是dot,范围也可以表示为 r [univ] 。 (请注意,您的示例 r [B] 不会返回任何内容,因为它等同于 Br ,B中的任何内容都不匹配R中任何一对的第一项(因为第一项都在A中,而不是B,在示例中A和B是不相交的。如果你想要在r对中出现B的子集,你想写 Ar ,或等效 r [A] 。在这种情况下,由于 r 中的第一项始终是 A 的元素, Ar 相当于 univ.r 。
请注意,域和范围这两个词有多种用法。术语域有时用于表示作为关系对中第一项出现的事物的集合(和范围类似地表示出现的事物集合)任何一对中的第二项),有时表示可能出现的一组事物作为一对中的第一(第二)项。库函数和表达式 r.univ 和 univ.r 在第一种意义上评估域和范围,而不是第二种。就您的第一个示例而言,在Alloy中,关系 r 的域不一定等于集合 B ;它也可以是 B 的适当子集。
[附录]要检查关系fid + mid
是否是单射的,一种简单的方法就是写
fact {
all o : O | lone x : M + F | x.mid = o or x.fid = o
}
如果您要声明one
总数超过lone
,请使用fid + mid
代替M + F
;我不理解内心的&#39;需要这个。
terser公式可能需要更多的关系&#39;式:
lone (mid + fid).o
重新演绎这个成语,你的事实会读到
fact mid_fid_injective {
all o : O | lone mid.o
all o : O | lone fid.o
all o : O | lone (mid + fid).o
}
但是当然第三和第二个陈述是由第三个暗示的,所以你可以用
来完成fact mid_fid_injective {
all o : O | lone (mid + fid).o
}
答案 1 :(得分:1)
我想添加一些关于点运算符的注释,这有助于理解为什么r.univ和unive.r分别返回域和关系r的范围。
Alloy中的点操作类似于合成操作。为了描述它,假设以下设置:
a1 is an arrow /relation from A to B
a2 is and arrow/ relation from B to C
然后a1.a2是从A到C的箭头/关系。在a1.a2中,省略了属于B并且在a1的范围和a2的域中的中间元素。
在Alloy中,点操作也可用于集合。 在上面的示例中,如果a2变为 univ ( univ 是包含模型中所有元素的一元集常量),则a1.univ包含参与的A的元素关系a1(即a1的域)。原因是中间元素(即,univ中与a1的范围匹配的元素)都被移除。请注意,在a1.univ中,所有a1范围都匹配并被删除,因为univ包含模型中的所有元素,包括a1范围。
希望这有帮助。