下面的函数 seqToSet 接受一个元素序列并返回一个包含给定序列中所有(且仅)元素的集合。它通过调用具有相同序列和空集的递归辅助函数 addSeqToSet 来实现这一点。辅助函数将序列中的每个元素添加到给定的集合中并返回结果。它通过对序列的头/尾结构进行递归来做到这一点。它在序列为空时完成,否则使用序列的尾部以及集合与包含序列头部的单例集合的并集递归调用自身。
Dafny 无法自行验证表明结果集包含原始序列中所有元素的后置条件。
帮助它看到这种情况的正确策略是什么?
function method seqToSet(q: seq<int>): set<int>
{
addSeqToSet(q, {})
}
function method addSeqToSet(q: seq<int>, t: set<int>): (r: set<int>)
ensures forall i :: i in q ==> i in r
{
if | q | == 0 then t
else addSeqToSet (q[1..], t + { q[0] })
}