Alloy中关系运算的域和范围

时间:2014-08-20 23:39:45

标签: dns range relation alloy model-checking

是否有任何操作返回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
 }

任何想法? :)

2 个答案:

答案 0 :(得分:5)

您将分别在名称random下的库模块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范围。

希望这有帮助。