2

i have to create the pre and pos conditions for the method insert of a heap class, the heap as to be a minHeap and has to be completed, my invariant has an error that says: "this loop invariant might not be maintained by the loop."

    class Heap {
var size: nat
var heap: array<int>
method insert (x: int)
    modifies heap
    requires 0 < size < heap.Length - 1
    requires minHeap(heap, size)
    requires x > 0
    requires isComplete(heap, size)
    ensures minHeap(heap, size + 1)
    ensures isComplete(heap, size + 1)
    ensures exists i :: 0 < i < size + 1 && x == heap[i]
    {
        // Insert the new item at the end of the array 
        var pos:= size + 1;
        // Percolate up
        while pos > 1 && x < heap[pos/2]
        invariant 1 <= pos < heap.Length
        invariant forall i :: pos < i <= size + 1 ==> heap[i] < heap[i/2]
        {

            heap[pos] := heap[pos/2];
            pos:= pos/2;
        }
        heap[pos] := x;
    }

    predicate minHeap(h: array<int>, index: nat)
    reads h
    requires 0 < index < h.Length 
    {
        forall i :: 1 < i < index ==> h[i/2] < h[i]
    } 

    predicate isComplete(h: array<int>, index: nat)
    reads h 
    requires 0 < index < h.Length
    {
        forall i :: 1 <= i <= index ==> h[i] > 0
    }
  }   

Can anyone help me?

1 Answers1

0

Suppose the loop invariant holds at the beginning of an iteration when pos is 100. Then you know

forall i :: 100 < i <= size+1 ==> heap[i] < heap[i/2]

at the beginning of the loop iteration. That is, you know something about heap[i] for all i greater than 100 (up to size+1). The loop iteration now sets heap[100] to the value of heap[50], and sets pos to 50. To prove that the loop invariant is maintained, you would now need to show:

forall i :: 50 < i <= size+1 ==> heap[i] < heap[i/2]

But this condition certainly does not hold. One problem is that it does not hold for i == 100, because heap[100] is equal to heap[50], not strictly less than heap[50] as your loop invariant states. The other problem is that you have no information about the values of heap[51], ..., heap[99], and your loop invariant says that you intend each of these to satisfy heap[i] < heap[i/2] as well.

So, you need to rethink either your program or the invariant, or both.

Rustan Leino
  • 1,954
  • 11
  • 8