2

I'm trying to prove a simple program in Dafny that finds the maximum element of an integer array. Dafny succeeds in a few seconds proving the program below. When I remove the comments from the last two ensures specifications, Dafny fires error messages saying that

a postcondition might not hold on this return path

This is probably caused by the fact that index is guaranteed to be <= a.Length. However, max_index < a.Length is correct, and I'm having a hard time proving it. I tried writing a nested invariant in the if statement, but Dafny rejected that syntax. Any possible solution? Here is my code:

method FindMax(a: array<int>) returns (max: int, max_index : int)
    requires a.Length > 0
    ensures forall k :: 0 <= k < a.Length ==> a[k] <= max
    ensures 0 <= max_index
    // ensures max_index < a.Length
    // ensures a[max_index] == max
{
    max := 0;
    var index := 0;
    max_index := 0;
    while index < a.Length
        invariant 0 <= index <= a.Length
        invariant forall k :: 0 <= k < index ==> a[k] <= max
    {
        if (max  < a[index])
            // invariant 0 <= index < a.Length
        {
            max := a[index];
            max_index := index;
        }
        index := index + 1;
     }
}
OrenIshShalom
  • 5,974
  • 9
  • 37
  • 87

1 Answers1

2

It turns out my loop invariants needed more careful planning. Here is the correct version:

method FindMax(a: array<int>) returns (max: int, max_index : int)
    requires a.Length > 0
    ensures forall k :: 0 <= k < a.Length ==> a[k] <= max
    ensures 0 <= max_index
    ensures max_index < a.Length
    ensures a[max_index] == max
{
    var index := 0;
    max_index := 0;
    max := a[max_index];
    while index < a.Length
        invariant max_index < a.Length
        invariant 0 <= index <= a.Length
        invariant forall k :: 0 <= k < index ==> a[k] <= max
        invariant a[max_index] == max
    {
        if (max  < a[index])
        {
            max := a[index];
            max_index := index;
        }
        index := index + 1;
     }
}

And it takes Dafny a little over than 10 seconds to prove.

OrenIshShalom
  • 5,974
  • 9
  • 37
  • 87