考虑以下复杂的否定布尔值的方式(取决于short-circuit evaluation):
def negate(a: Boolean) = {
var b = true
a && { b = false; true }
b
} ensuring { res => res != a }
如果我在Scala控制台中测试此代码,它会按预期工作。
但leon --xlang
表示后置条件无效。
这是预期/指定的吗?
答案 0 :(得分:0)
在xlang转换阶段之后查看(简化)编码,我们得到以下结果:
def negate0(a0 : Boolean): Boolean = {
val b1 = true
val b2 = false
b2
} ensuring {
res19 => res19 != a0
}
第一个b1
对应初始化var b = true
。引入第二个b2
以对应于作业b = false
。不幸的是,XLang对&&
和||
运算符没有做任何特殊处理,这意味着它将提取子表达式中的所有副作用并将它们移动到“顶级”级别(因此为什么你有val b2 = false
)。最终返回值为b2
,即b
的最后一个已知名称,显然忽略了a && ...
表达式(副作用除外)。
所以基本上这是Leon的一个限制,我们将考虑修复它。
编辑: 请注意,这在最新版本的Leon中得到修复:https://github.com/epfl-lara/leon/commit/2485477f4e91cba7fe6e0c137817d62f513a3c42