Problem: bst_zigzig

Your task is to implement the Zig-Zig operation (Double Right Rotation) in a binary search tree and verify its correctness in Dafny. A Zig-Zig is a "double" rotation performed when a node $X$, its parent $P$, and its grandparent $G$ form a straight line (e.g., $X$ is the left child of $P$, and $P$ is the left child of $G$). In a Splay Tree, this operation is used to move $X$ up two levels by first rotating the edge between the parent and grandparent, and then rotating the edge between the node and its parent. Specifically, you must prove the following: (1) Set Preservation: The mathematical set of values (the tree's "view") remains exactly the same before and after the double rotation; the transformation must not lose or duplicate any nodes. (2) BST Invariant Preservation: For every node in the resulting structure, all values in the left subtree must be less than the node's value, and all values in the right subtree must be greater. This is critical as subtrees are shifted across three different levels. (3) Structural Correctness: After the operation, the original grandchild $X$ must be the new root of the subtree, the original parent $P$ must be the right child of $X$, and the original grandparent $G$ must be the right child of $P$.

// Following is the block for necessary definitions
// <preamble>
datatype Tree = Empty | Node(val: int, left: Tree, right: Tree)

function view(tree: Tree): set<int>
    decreases tree
{
    match tree
    case Empty => {}
    case Node(val, left, right) => view(left) + view(right) + {val}
}

predicate is_bst(tree: Tree)
    decreases tree
{
    match tree
    case Empty => true
    case Node(val, left, right) =>
        (forall x :: x in view(left) ==> x < val) &&
        is_bst(left) &&
        (forall x :: x in view(right) ==> x > val) &&
        is_bst(right)
}
// </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 zig_zig(g: Tree) returns (res: Tree)
    // g corresponds to Box<Node>, so it is non-Empty
    requires g.Node?
    // g.left.is_some()
    requires g.left.Node?
    // g.left.get_Some_0().left.is_some()
    requires g.left.left.Node?
    requires is_bst(g)
    ensures is_bst(res)
    ensures view(res) == view(g)
    // X (grandchild) is now root
    ensures res.val == g.left.left.val 
// </spec>
// <code>
{
    // Implement and verify BST zig-zig rotation algorithm here.
}
// </code>