You are here: Home Exercises Additional Material … Heap2.java

Heap2.java

Plain Text icon Heap2.java — Plain Text, 3 kB (3296 bytes)

File contents

abstract class HeapElem implements Comparable {
    // The position in the heap.
    /*@ spec_public @*/ int heapPos = -1;
}

class Heap2Solved {
    private /*@ spec_public @*/ HeapElem[] elems;
    private /*@ spec_public @*/ int numElems;

    public Heap2Solved() {
	elems = new HeapElem[5];
	numElems = 0;
    }

    /*@ public invariant (\forall int i; i >= 0 && i < numElems; 
      @                        elems[i] != null && 
      @			       elems[i].heapPos == i);
      @ public invariant 0 <= numElems && numElems <= elems.length;
      @ public invariant elems != null && elems.length > 0;
      @*/
      
    /*@ requires elems != null && elems.length > 0 && 
      @          0 <= numElems && numElems <= elems.length;
      @ ensures elems != null && elems.length > \old(elems.length)
      @       && numElems == \old(numElems)
      @       && (\forall int i; i >= 0 && i < numElems;
      @           elems[i] == \old(elems[i]));
      @ modifies elems;
      @*/
    private void grow() {
	HeapElem[] newElems = new HeapElem[elems.length*2];
	/*@ loop_invariant 0<= i && i <= elems.length;
	  @ loop_invariant (\forall int j; j >= 0 && j < i;
	  @           newElems[j] == \old(elems[j]));
	  @*/
	for (int i = 0; i < numElems; ++i)
	    newElems[i] = elems[i];
	elems = newElems;
    }

    /*@ requires e.heapPos == -1;
      @ ensures e.heapPos >= 0 && e.heapPos < numElems &&
      @         (Object) elems[e.heapPos] == (Object) e &&
      @         (\forall int i; i >= 0 && i < numElems; i == e.heapPos || 
      @                  (Object) elems[i] != (Object) e);
      @*/
    public void enqueue(HeapElem e) {
	if (numElems >= elems.length)
	    grow();
	//@ assert (\forall int i; i >= 0 && i < numElems; elems[i] != null && elems[i].heapPos == i);
	int pos = numElems++;
	int parent = pos / 2;
	/*@ loop_invariant (\forall int i; i >= 0 && i < numElems && i != pos; 
	  @                        elems[i] != null && elems[i] != e &&
	  @			       elems[i].heapPos == i);
	  @ loop_invariant 0 <=  pos && pos < numElems && parent == pos/2;
	  @*/
	while (pos > 0 && elems[parent].compareTo(e) > 0) {
	    elems[parent].heapPos = pos;
	    elems[pos] = elems[parent];
	    pos = parent;
	    parent = pos / 2;
	}
	elems[pos] = e;
	e.heapPos = pos;
    }
    
    /*@
      @ requires e.heapPos >= 0 && e.heapPos < numElems && 
      @          elems[e.heapPos] == e && numElems < 1000000000;
      @*/
    public void remove(HeapElem e) {
	HeapElem last = elems[--numElems];
	int pos = e.heapPos;
	e.heapPos = -1;
	if (last == e) {
	    return;
	}
	int child = 2*pos+1;
	/*@ loop_invariant (\forall int i; i >= 0 && i < numElems && i != pos; 
	  @                        elems[i] != null && elems[i] != last &&
	  @			       elems[i].heapPos == i);
	  @ loop_invariant 0 <=  pos && pos < numElems && child == 2*pos+1;
	  @*/
	while (child < numElems) {
	    if (child + 1 < numElems
		&& elems[child].compareTo(elems[child+1]) > 0) {
		child++;
	    }

	    if (elems[child].compareTo(last) > 0)
		break;

	    elems[pos] = elems[child];
	    elems[pos].heapPos = pos;
	    pos = child;
	    child = 2*pos+1;
	}
	elems[pos] = last;
	last.heapPos = pos;
    }
}