Count dafny中的段计数无效
我在下面的链接中为代码编写了以下证明。 我想在提供count2方法方面得到一些帮助。我不太清楚交替证明 谢谢Count dafny中的段计数无效,count,formal-verification,dafny,Count,Formal Verification,Dafny,我在下面的链接中为代码编写了以下证明。 我想在提供count2方法方面得到一些帮助。我不太清楚交替证明 谢谢 methodmain(){ 变量a:数组:=新整数[4]; a[0]:=7; a[1]:=-2; a[2]:=3; a[3]:=-2; 断言a[…]==[7,-2,3,-2]; 变量c:=SumProdAndCount(a,-2); 断言a[0]==7&&a[1]==2&&a[2]==3&&a[3]==2; 断言c==RecursiveCount(-2,a,0);//==2 打印“\n
methodmain(){
变量a:数组:=新整数[4];
a[0]:=7;
a[1]:=-2;
a[2]:=3;
a[3]:=-2;
断言a[…]==[7,-2,3,-2];
变量c:=SumProdAndCount(a,-2);
断言a[0]==7&&a[1]==2&&a[2]==3&&a[3]==2;
断言c==RecursiveCount(-2,a,0);//==2
打印“\n在[7,-2,3,-2]中出现-2的次数为”;
打印c;
}
函数RecursiveCount(键:int,a:array,from:nat):int
读到
需要一个无效的
需要(从0开始)
不变量0当向后循环时,必须先减小索引,然后才能使用它访问数组
i, c := i0-1, c0
因为是向后循环,所以在访问数组之前必须减小计数器。通过检查方法的先决条件可以看到这一点。给定
0 < i0 <= a.Length
您还需要增加而不是减少发生次数
c := c + 1;
下面是一个验证
我认为,如果您使用更清晰的编程风格和更少的间接性,您可能会发现验证这些程序更容易(尽管您可能正在做一个关于方法前置和后置条件的练习)。我的经验是,成功验证算法的一部分首先是找到一种好的、清晰的方法来表达算法
methodmain(){
变量a:数组:=新整数[4];
a[0]:=7;
a[1]:=-2;
a[2]:=3;
a[3]:=-2;
断言a[…]==[7,-2,3,-2];
变量c:=SumProdAndCount(a,-2);
断言a[0]==7&&a[1]==2&&a[2]==3&&a[3]==2;
断言c==RecursiveCount(-2,a,0);//==2
打印“\n在[7,-2,3,-2]中出现-2的次数为”;
打印c;
}
函数RecursiveCount(键:int,a:array,from:nat):int
读到
需要一个无效的
要求来自
0 < i0 <= a.Length ==> 0 <= (i0-1) < a.Length
c := c + 1;
method Main() {
var a: array<int> := new int[4];
a[0] := 7;
a[1] := -2;
a[2] := 3;
a[3] := -2;
assert a[..] == [7,-2,3,-2];
var c := SumProdAndCount(a, -2);
assert a[0] == 7 && a[1] == -2 && a[2] == 3 && a[3] == -2;
assert c == RecursiveCount(-2, a, 0); // == 2
print "\nThe number of occurrences of -2 in [7,-2,3,-2] is ";
print c;
}
function RecursiveCount(key: int, a: array<int>, from: nat) : int
reads a
requires a != null
requires from <= a.Length
decreases a.Length-from
{
if from == a.Length then 0
else if a[from] == key then 1+RecursiveCount(key, a, from+1)
else RecursiveCount(key, a, from+1)
}
method SumProdAndCount(a: array<int>, key: int) returns (c: nat)
requires a != null
ensures c == RecursiveCount(key, a, 0)
{
c := 0;
var i : nat := 0;
ghost var r := RecursiveCount(key, a, 0);
while (i < a.Length)
invariant 0 <= i <= a.Length
invariant r == c + RecursiveCount(key,a,i);
{
i, c := i+1, if a[i]==key then c+1 else c;
}
}