Problem: splaytree_splay

Your task is to implement the Splay operation in a splay tree (a binary search tree) and verify its correctness in Dafny. Splaying is a self-adjusting process that moves a specific target node $X$ to the root of the tree through a series of structured rotations.  The operation proceeds from the target node $X$ upward to the root, applying one of three cases at each step: (1) Zig Case (Terminal Step): If the parent of $X$ is the root, apply a single rotation (Zig) to move $X$ to the root. (2) Zig-Zig Case (Parallel Step): If $X$ and its parent $P$ are both left children (or both right children), first rotate the edge $(P, G)$, then rotate the edge $(X, P)$. (3) Zig-Zag Case (Offset Step): If $X$ is a right child and $P$ is a left child (or vice versa), first rotate the edge $(X, P)$, then rotate the edge $(X, G)$. Specifically, you must prove the following: (1) Root Property: After the operation, the node with the target value $v$ (or the node closest to it, if $v$ is not present) must be the new root of the tree. (2) Set Invariance: The mathematical set of values (the view()) before and after splaying must be identical. No elements should be added or removed. (3) BST Preservation: The Binary Search Tree invariant must hold for every node in the tree throughout the sequence of transformations.

// 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 splay(tree: Tree, v: int) returns (res: Tree)
    // tree is Box<Node>, so it cannot be Empty
    requires tree.Node?
    requires is_bst(tree)
    // res is Box<Node>, so it cannot be Empty
    ensures res.Node?
    ensures is_bst(res)
    ensures view(res) == view(tree)
    // Postcondition: If v was in the tree, it is now at the root.
    ensures v in view(tree) ==> res.val == v
    // Postcondition: If v was NOT in the tree, the new root is 
    // the last node accessed (implicitly true if res.Node?, but kept for fidelity)
    ensures v !in view(tree) ==> res.val in view(res)
// </spec>
// <code>
{
    // Implement and verify the splay operation for the splay tree here.
}
// </code>