令人惊讶的Dafny未能验证集合理解的有限性

时间:2018-03-14 03:48:34

标签: dafny

Dafny对这个集交集函数的定义没有问题。

function method intersection(A: set<int>, B: set<int>): (r: set<int>)
{
    set x | x in A && x in B
}

但是当谈到结合时,达夫尼抱怨说,“一套理解必须产生一个有限的集合,但是达夫尼的启发式方法无法弄清楚如何为'x'生成一组有界的值”。 A和B是有限的,因此,显然联盟也是如此。

function method union(A: set<int>, B: set<int>): (r: set<int>)
{
    set x | x in A || x in B
}

什么能解释这个,初学者看似不一致的行为?

1 个答案:

答案 0 :(得分:1)

这确实可能令人惊讶!

首先,请注意,在实践中,Dafny有交叉和联合的内置运算符,它知道保持有限性。因此,您不需要使用集合理解来表达这些想法。相反,您可以分别说出A * BA + B

但是,我的猜测是,您正在遇到一个更复杂的例子,在这个例子中,您使用了一个具有分离的集合理解,并且对于为什么Dafny无法证明它是有限的而感到困惑。

Dafny使用句法启发法来确定集合理解是否是有限的。不幸的是,这些启发式方法在任何地方都没有很好的记出于这个问题的目的,关键点在于启发式方法要么取决于理解的绑定变量的类型,要么寻找以某种其他方式约束元素的联合。例如,Dafny可以证明

set x: int | 0 <= x < 10 && ...

有限,以及

set x:A | x in S && ...

在这两种情况下,相关界限必须 conjuncts 。 Dafny没有用于证明分离界限的句法启发式算法,尽管可以想象添加一个。这就是为什么Dafny无法证明你的union函数是有限的。

另外,另一种解决方法是使用潜在的无限集(在Dafny中编写iset)。如果您不需要使用集合的基数,那么这些可能会更好。