2
ghost method lemma1(A:array<int>)
    requires A.Length>2
    requires forall i:: 0 <= i-1 < i < A.Length ==> A[i-1] <= A[i]
    ensures A[0] <= A[1] <= A[2]
{
}

the code above works, but the following doesn't work

ghost method lemma2(A:array<int>)
    requires A.Length>2
    requires forall i:: 0 <= i-1 < i < A.Length ==> A[i-1] <= A[i]
    ensures A[0] <= A[2]
{
}

ghost method lemma3(A:array<int>)
    requires A.Length>2
    requires forall i:: 0 <= i-1 < i < A.Length ==> A[i-1] <= A[i]
    ensures forall i,j :: 0 <= i < j < A.Length ==> A[i] <= A[j]
{
}

Problem: A postcondition might not hold on this return path.

What extra preconditions does it require?

fed4
  • 21
  • 2

1 Answers1

2

No extra preconditions are required here. Dafny (more correctly underlying Z3) uses heuristics to prove. It looks like dafny need some help here to figure out proofs as heuristics are not able to figure out by itself. You can ask dafny to assert things which makes it first prove it and then add it as part of knowledge base for applying further heuristics to prove latter goals.

ghost method lemma2(A:array<int>)
    requires A.Length>2
    requires forall i:: 0 <= i-1 < i < A.Length ==> A[i-1] <= A[i]
    ensures A[0] <= A[2]
{
    assert A[0] <= A[1];
    assert A[1] <= A[2];
}

For second code snippet, a while loop with single assert inside it is enough to guide dafny towards proof. Earlier loop iteration has proved that forall m, n :: 0 <= m < n < i ==> A[m] <= A[n]. Current loop iteration need to prove forall m, n :: 0 <= m < n < i + 1 ==> A[m] <= A[n] for which assert A[i-1] <= A[i] hint is enough for dafny.

ghost method lemma3(A:array<int>)
    requires A.Length>2
    requires forall i:: 0 <= i-1 < i < A.Length ==> A[i-1] <= A[i]
    ensures forall i,j :: 0 <= i < j < A.Length ==> A[i] <= A[j]
{
     var i := 0;
     
     while i < A.Length
      invariant i <= A.Length
      invariant forall m, n :: 0 <= m < n < i ==> A[m] <= A[n]
     {
        if i >= 1 {
            assert A[i-1] <= A[i];
        }
        i := i + 1;
     }
}
Divyanshu Ranjan
  • 1,015
  • 3
  • 7