dafny - Dafny,如果在循环的进入和退出时断言为真,它是否是不变量
问题描述
在 Dafny 中,我正在尝试为递归规范编写迭代实现。更具体地说,当 a 是序列的元素predicate containsMe<T (==)>(l:seq<T>, me:T)
时返回 true 。me
l
最近被引导到http://leino.science/papers/krml275.html我可以看到其他方法可能会更好,但是我偶然发现了一个有趣的问题。
我有一个部分解决方案(如下所示),可以验证在循环开始和结束时给出的断言,但它不是不变量。我错过了什么,这是一个错误还是有办法帮助 Dafny 建立我不理解的不变量?
predicate method containsMe<T (==)>(l:seq<T>, me:T)
decreases l
{
if l== [] then false
else if l[0] == me then true else containsMe(l[1..],me)
}
lemma {:induction l} cont<T (==)>(l:seq<T>, me:T)
ensures (exists i:nat :: i<|l| && l[i] == me) <==> containsMe(l,me) { }
lemma {:induction l} conti<T (==)>(l:seq<T>, me:T, i:nat)
ensures ( i<|l| && l[i] == me) ==> containsMe(l,me) {
calc {
i<|l| && l[i] == me ;
==>
exists i:nat :: i<|l| && l[i] == me;
==> {cont(l,me);}
containsMe(l,me);
}
}
lemma ping<T (==)>(l:seq<T>, me:T, i:nat)
ensures ( i<|l| && l[i] == me) ==> containsMe(l[..i+1],me)
{
calc {
i<|l| && l[i] == me;
==>
(i< |l[..i+1]| && l[..i+1][i] == me);
==> {conti(l[..i+1],me,i);}
containsMe(l[..i+1],me);
}
}
method contains<T (==)>(l:seq<T>, el:T) returns (r:bool)
//ensures r == containsMe(l,el)
{
print "contains ",l," , ",el,"\n";
var i:nat:= 0;
r := false;
while (i < |l| && r ==false)
decreases |l| -i ,!r
invariant (r ==> containsMe(l[..i+1],el) ) /*fails to verify */
{
assert (r ==> containsMe(l[..i+1],el) ); /* true on entry */
var b:bool := containsMe(l[..i+1],el);
print " ",i, " ", l[i], " ", b, "\n";
if l[i] == el {
r:=true; }
else {i := i+1;}
calc {
(r==> i<|l| && l[i] == el);
==> {ping(l,el,i);}
(r ==> containsMe(l[..i+1],el)) ;
}
assert (r ==> containsMe(l[..i+1],el) ); /* true on exit */
}
}
解决方案
Dafny 并没有抱怨不变量不正确。它抱怨它的格式不正确,因为它认为索引i+1
可能大于数组的长度。添加
invariant r ==> i < |l|
在其他不变量应该解决问题之前。
推荐阅读
- reactjs - React propType 指定允许的 props 值
- r - 我可以将我的 ggplot2 图例放在横轴标签旁边吗?
- r - 错误:R中的意外字符串常量“} else {”
- ios - 如何在 Xcode 中列出一个目标的所有文件
- javascript - websocket over spring4 和 spring security SockJS /info?t=
- oracle - 如何检测 ORACLE 数据库中表列中的数据类型(可能是 blob 或 clob)?
- html - 即使在 Bootstrap Grid Columns 丢失的情况下也可以向右拉
- python - 从被测方法中导入的模块中修补方法
- bytecode - 为什么字节码序列号不连续
- c - C 接受关于传递关系的输入