当防止溢出被设置为“是”时,等价性的不一致行为。

时间:2016-02-23 12:31:45

标签: alloy

以下示例显示了两个看似等效的检查,但第二个检查发现了一个反例,而第一个没有。设置'防止溢出'到'否',都返回相同的结果:

sig A {
  x : Int,
  y : Int
 }

 pred f1[a:A] {
   y = x ++ (a -> ((a.x).add[1]))
 }

 pred f2[a:A] {
   a.y = (a.x).add[1]
   y = x ++ (a -> a.y)
 }

check {
  all a : A | {
    f1[a] => f2[a]
    f2[a] => f1[a]
 }
}

check {
  all a:A | {
    f1[a] <=> f2[a]
 }
} 

我在使用sat4j的Ubuntu Linux上使用Alloy 4.2_2015-02_22。

1 个答案:

答案 0 :(得分:1)

我很抱歉不能提供比以下更有用的答案。幸运的是,其他人会做得更好。

我认为,您的模型可能会在Alloy中出现错误。但也许相反,当设置防止溢出标志时,模型表现出合金中整数语义的反直觉结果。 Aleksandar Milicevic和Daniel Jackson在论文Preventing arithmetic overflows in Alloy中描述了这些语义。您可能比我更容易跟踪细节。

以下表达式似乎表明(a)不直观的结果与当对未定义的值应用否定时排除中间的定律不成立的事实有关,以及(b)在ax =的情况下7(或者Int的最大值,在特定范围内),谓词f1和f2表现不同:

pred xm1a[ a : A] { (f1[a] or not(f1[a])) }
pred xm2a[ a : A] { (f2[a] or not(f2[a])) }
pred xm1b[ a : A] { (not (f1[a] and not(f1[a]))) }
pred xm2b[ a : A] { (not (f2[a] and not(f2[a]))) }

// some sensible assertions:  no counterexamples
check x1 { all a : A | a.x = 7 implies xm1a[a] }
check x2 { all a : A | a.x = 7 implies xm2a[a] }
check x3 { all a : A | a.x = 7 implies xm1b[a] }
check x4 { all a : A | a.x = 7 implies xm2b[a] }

// some odd assertions: counterexamples for y2 and y4
check y1 { all a : A | a.x = 7 implies not xm1a[a] }
check y2 { all a : A | a.x = 7 implies not xm2a[a] } 
check y3 { all a : A | a.x = 7 implies not xm1b[a] }
check y4 { all a : A | a.x = 7 implies not xm2b[a] } 

不清楚(对我而言)f1和f2之间的相关差异是f2明确指向a.y,还是f2有两个子句,它们之间有隐式and

如果a.x和a.y之间的算术关系对模型很重要,那么确定如何处理溢出情况将是必不可少的。如果所有问题都是a.x != a.y and y = x ++ (a -> a.y),那么弱化条件将产生良好的副作用,读者不需要理解Alloy的溢出语义。 (我希望你已经意识到这一点;我为了后来的读者的利益而提到它。)