Dafny 无法验证集合理解的有界性

Dafny 无法验证集合理解的有界性,dafny,Dafny,Dafny对集合交函数的定义没有问题 function method intersection(A: set<int>, B: set<int>): (r: set<int>) { set x | x in A && x in B } 函数法求交(A:集,B:集):(r:集) { 在A中设置x | x和在B中设置x } 但当谈到并集时,达夫尼抱怨说,“集合理解必须产生有限集合,但达夫尼的启发式算法无法找出如何为‘x’产生一组有界值。

Dafny对集合交函数的定义没有问题

function method intersection(A: set<int>, B: set<int>): (r: set<int>)
{
    set x | x in A && x in B
}
函数法求交(A:集,B:集):(r:集)
{
在A中设置x | x和在B中设置x
}
但当谈到并集时,达夫尼抱怨说,“集合理解必须产生有限集合,但达夫尼的启发式算法无法找出如何为‘x’产生一组有界值。”。A和B是有限的,所以,很明显,联合也是有限的

function method union(A: set<int>, B: set<int>): (r: set<int>)
{
    set x | x in A || x in B
}
函数方法联合(A:set,B:set):(r:set)
{
在A中设置x | x |在B中设置x
}

对于一个看似不一致的初学者来说,是什么解释了这一行为?

这确实可能令人惊讶

首先,让我注意到,在实践中,Dafny有内置的交集和并集操作符,它知道保持有限性。所以你不需要用集合理解来表达这些想法。相反,你可以分别说
A*B
A+B

然而,我的猜测是,你遇到了一个更复杂的例子,在这个例子中,你使用了带析取的集合理解,并且对为什么Dafny不能证明它是有限的感到困惑

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

set x: int | 0 <= x < 10 && ...
在这两种情况下,重要的是相关边界必须是共轭的。Dafny没有证明析取界的语法启发式方法,尽管可以想象添加一个。这就是为什么Dafny不能证明你的
并集
函数是有限的


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

我们的Dafny用例是教育学。所以我们希望能够写出所有通常的定义,比如“联合”在Dafny中的含义,以一种人们实际上也可以运行的方式。能够写出“集合联合”这样一个简单的定义,而不是让Dafny拒绝它,这将是一件好事。实现合理有效的启发式在理论上有什么困难吗?或者这真的只是一个缺失的特性,可以以合理的成本添加到良好的效果中吗?(感谢您的帮助。)没有理论上的困难,只需添加实现即可。事实上,如果表达式首先被重构为析取,那么当前的启发式算法可以在每个析取上运行,然后结果可以组合起来。该实现已经设置为处理不同类型的“有界池”,因此添加一个总体的“析取有界池”是合适的。(这将是一个伟大的学生项目。:)
set x:A | x in S && ...