Problem: bst_zigzag

Your task is to implement the Zig-Zag operation (Left-Right Rotation) in a binary search tree and verify its correctness in Dafny. A Zig-Zag is a "double" rotation performed when a node $X$, its parent $P$, and its grandparent $G$ form a "kink" (e.g., $X$ is the right child of $P$, but $P$ is the left child of $G$).  This operation "straightens" the tree by rotating $X$ around $P$, and then rotating $X$ around $G$. Specifically, you must prove the following: (1) Set Preservation: The mathematical set of values (the tree's "view") remains exactly the same; you must verify that the pointer re-linking correctly accounts for all subtrees originally attached to $X$, $P$, and $G$. (2) BST Invariant Preservation: For any node with value $v$, all values in the left subtree are less than $v$ and all values in the right subtree are greater than $v$. You must prove this holds even as $X$ splits its original children to become the new parent of both $P$ and $G$. (3) Structural Correctness: After the operation, the original grandchild $X$ must be the new root of the subtree, with the original parent $P$ as its left child and the original grandparent $G$ as its right child.

// 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_zag(g: Tree) returns (res: Tree)
    // g corresponds to Box<Node>, so it is non-Empty
    requires g.Node?
    // g.left is Some (P exists)
    requires g.left.Node?
    // g.left.right is Some (X exists - the 'Zig-Zag' shape)
    requires g.left.right.Node?
    requires is_bst(g)
    ensures is_bst(res)
    ensures view(res) == view(g)
    // X (the original grandchild) is now the root
    ensures res.val == g.left.right.val
// </spec>
// <code>
{
    // Implement and verify BST zig-zag rotation algorithm here.
}
// </code>