dafny中的无效段计数

时间:2015-12-14 13:21:53

标签: count formal-verification dafny

我在下面的链接中为代码编写了以下证明。 我希望得到一些帮助来推算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();
}

1 个答案:

答案 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;
  }
}