Dafny:为什么这个断言失败,以及如何解决它

时间:2018-10-27 03:51:43

标签: verification formal-verification dafny

试图证明在Dafny上的简单算法,但我在最后一个断言中仅收到“断言违规”,没有任何额外的细节。谁能发现什么地方出了问题以及如何解决?形式方法不是我的专长。

method  BubbleSort(a: array?<int>)
    modifies a
    requires a != null
    ensures sorted(a, 0, a.Length -1)
{
    var i := a.Length  - 1;
    while(i > 0)
        decreases i
        invariant i < 0 ==> a.Length == 0
        invariant -1 <= i < a.Length
        invariant sorted(a, i, a.Length -1)
        invariant partitioned(a, i)
    {
        var j := 0;
        while(j < i)
            decreases i - j
            invariant 0 < i < a.Length && 0 <= j <= i
            invariant sorted(a, i, a.Length -1)
            invariant partitioned(a, i)
            invariant forall k :: 0 <= k <= j ==> a[k] <= a[j]
        {
            if(a[j] > a[j+1])
            {
                a[j], a[j+1] := a[j+1], a[j];
            }
            j := j + 1;
        }
        i := i - 1;
    }
}

predicate sorted(a: array?<int>, l: int , u: int)
    reads a //Sintaxe do Dafny. PRECISA disso para dizer que vai ler o array
    requires a != null
{
    forall i, j :: 0 <= l <= i <= j <= u < a.Length ==> a[i] <= a[j]
}

predicate partitioned(a: array?<int>, i: int)
    reads a
    requires a != null
{
    forall k, k' :: 0 <= k <= i < k' < a.Length ==> a[k] <= a[k']
}

method testSort()
{
  var b := new int[2];
  b[0], b[1] := 2, 1;
  assert b[0] == 2 && b[1] == 1;
  BubbleSort(b);
  assert b[0] == 1 && b[1] == 2;
}

1 个答案:

答案 0 :(得分:1)

问题在于ensures的后置条件(Sort子句)没有提供有关A的状态的信息。当Dafny进行验证时,它将仅使用其他方法的规范(而非主体)来独立验证每个方法。因此,当Dafny验证testSort时,它不会查看Sort的定义,而只会查看其后置条件true,这不足以证明您的断言。

有关更多信息,请参见FAQtutorial中有关断言的部分。