Problem: maxheap_popmax

Your task is to implement the Pop Max operation for a binary max-heap (the maximum value is stored at the root), which removes and returns the root element (the maximum value) of the heap, and verify its correctness in Dafny. To maintain the complete binary tree structure, the value at the last position of the sequence is moved to the root, and the heap size is decremented. Because this "promoted" value likely violates the heap property at the root, you must perform a "bubble-down" (or sift-down) process, iteratively swapping the node with its largest child until the max-heap invariant is restored throughout the tree. Specifically, you must prove the following: (1) Functional Correctness of Maximum: The value returned by the operation must be mathematically proven to be the maximum value in the original heap. This is verified by showing that the returned value is greater than or equal to every element contained in the heap's original multiset view. (2) Multiset Consistency: The resulting multiset of values in the heap must be identical to the original multiset minus exactly one instance of the returned maximum value. (3) Structural Integrity: After the bubble-down process, the heap property must be restored: for every index $i$ with children at $2i + 1$ and $2i + 2$, the value at $i$ must be greater than or equal to both children. This requires careful reasoning about the choice of the "larger child" during each swap to ensure the parent becomes a valid head for both subtrees.

// Following is the block for necessary definitions
// <preamble>
class BinaryMaxHeap {
    var storage: seq<int>
    var len: int

    function max_capacity(): int { 1023 }

    predicate is_heap()
        reads this
    {
        len <= max_capacity() &&
        0 <= len <= |storage| &&
        // Heap Property: Child <= Parent
        // Parent index of i is (i - 1) / 2
        // Fix: Added {:trigger storage[i]} to suppress matching loop warning
        (forall i {:trigger storage[i]} :: 1 <= i < len ==> storage[i] <= storage[(i - 1) / 2])
    }

    function view(): multiset<int>
        reads this
        requires 0 <= len <= |storage|
    {
        multiset(storage[..len])
    }
// </preamble>

// Following is the block for potential helper specifications
// <helpers>

// </helpers>

// Following is the block for proofs of lemmas
// <proofs>

// </proofs>

// Following is the block for the main specification
// <spec>
    method pop_max() returns (max: int)
        requires is_heap()
        requires len > 0
        modifies this
        ensures is_heap()
        ensures len == old(len) - 1
        // (1) Functional Correctness: Returns the maximum
        ensures forall x :: x in old(view()) ==> max >= x
        // (2) Multiset Consistency: One instance of max is removed
        ensures view() == old(view()) - multiset{max}
// </spec>
// <code>
    {
        // Implement and verify the pop_max operation for the max-heap here.
    }
// </code>
}