在编写纯函数代码时,如何在Dafny中对一个集合S进行递归?我可以用:|在命令式代码中,检查了非空虚,选择一个元素s,然后在S - {s}上递归。不太确定如何制作:|确定性并在功能代码中使用它。
答案 0 :(得分:0)
好问题! (我希望downvoters有勇气发表评论......)
这在Rustan的论文"Compiling Hilbert's Epsilon Operator"中得到了深入探讨。
特别是,参见3.2节,它描述了如何通过集合递归来编写确定性函数。由于我不完全清楚的原因,论文的Dafny代码证明引理ThereIsASmallest
在现代Dafny中对我不起作用。这是一个有效的版本(但很难看):
lemma ThereIsASmallest(S: set<int>)
requires S != {}
ensures exists x :: x in S && forall y | y in S :: x <= y
{
var y :| y in S;
if S != {y} {
var S' := S - {y};
assert forall z | z in S :: z in S' || z == y;
ThereIsASmallest(S');
var x' :| x' in S' && forall y | y in S' :: x' <= y;
var x := min2(y, x');
assert x in S;
}
}
最后,请注意,3.2节的技术依赖于对类型的总订单。如果你想做一些完全多态的事情,那么就我所知,这是不可能的。