我在下面的链接中为代码编写了以下证明。 我希望得到一些帮助来推算count2方法。交替证明对我来说不是那么清楚 感谢
http://rise4fun.com/Dafny/ueBY
String givenDateString = "Tue Apr 23 16:08:28 GMT+05:30 2013";
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
try {
Date mDate = sdf.parse(givenDateString);
long timeInMilliseconds = mDate.getTime();
System.out.println("Date in milli :: " + timeInMilliseconds);
} catch (ParseException e) {
e.printStackTrace();
}
答案 0 :(得分:0)
当你向后循环时,你必须减少索引 之前使用它来访问数组
i, c := i0-1, c0
因为您向后循环,所以在访问阵列之前必须递减计数器。您可以通过检查方法前提条件来看到这一点。给定
0 < i0 <= a.Length
数组访问a[i0]
未被限制在范围内,因为i0==a.Length
是可能的。此外,您需要a[0]
包含在产品中,但i0
永远不会0
。
但是,给定相同的前提条件,数组访问a[i0-1]
有意义,因为
0 < i0 <= a.Length ==> 0 <= (i0-1) < a.Length
您还需要增加而不是减少出现次数
c := c + 1;
这是一个验证
的版本http://rise4fun.com/Dafny/GM0vt
我认为如果您使用更简单的间接编程风格(尽管您可能正在对方法前后条件进行练习),您可能会发现验证这些程序更容易。我的经验是,成功验证算法的部分是首先找到一种很好的,清晰的表达算法的方法。
http://rise4fun.com/Dafny/QCgc
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;
}
}