Problem: trie_search

Your task is to implement the Search operation for a Byte-based Trie data structure (Prefix Tree) and verify its correctness in Dafny. The Trie represents keys as sequences of integers (representing bytes), where each node contains a boolean flag is_end and a sequence of 256 children. The search operation must traverse the tree according to the "bytes" in the input key. Specifically, you must prove the following: (1) Functional Correctness: The method must return true if and only if the key exists in the abstract set representation of the tree (the tree's "view"). If the tree is empty (None) or the path does not exist, it must return false. (2) Precondition Validity: The operation assumes the input tree satisfies the opt_well_formed invariant, meaning the tree structure is valid (children sequences are size 256) and contains no "useless" (empty) nodes.

// Following is the block for necessary definitions
// <preamble>
datatype Option<T> = Some(value: T) | None

datatype Node = Node(
    is_end: bool,
    // A sequence of children, representing bytes 0..255
    children: seq<Option<Node>>
) {
    // A node is "empty" (useless) if it marks no key and leads to no keys.
    // Added requirement that children sequence must be size 256 for this check to be valid.
    predicate is_empty() 
        requires |this.children| == 256
    {
        !this.is_end && (forall i: int {:trigger this.children[i]} :: 0 <= i < 256 ==> this.children[i].None?)
    }

    // Standard structural integrity + The Pruning Invariant
    predicate well_formed() 
        decreases this
    {
        // 1. Must have exactly 256 slots (for u8)
        && |this.children| == 256
        // 2. Recursive check for all children
        && (forall i: int {:trigger this.children[i]} :: 0 <= i < 256 ==> 
            match this.children[i] {
                case Some(child) => 
                    // The child must be structurally valid
                    && child.well_formed()
                    // CRITICAL: The child must not be useless.
                    // Note: child.well_formed() guarantees |child.children| == 256, satisfying is_empty's precondition
                    && !child.is_empty()
                case None => true
            }
        )
    }

    // Recursive definition of containment
    function contains(key: seq<int>): bool
        decreases |key|
    {
        if |key| == 0 then
            this.is_end
        else
            var char_idx := key[0];
            if 0 <= char_idx < |this.children| then
                match this.children[char_idx] {
                    case Some(child) => child.contains(key[1..])
                    case None => false
                }
            else
                false
    }

    // View as a Set of byte sequences
    // Note: Using iset (infinite set) because Dafny 'set' is finite
    ghost function view(): iset<seq<int>> {
        iset key: seq<int> | this.contains(key)
    }
}

ghost function opt_view(node: Option<Node>): iset<seq<int>> {
    match node {
        case Some(n) => n.view()
        case None => iset{}
    }
}

predicate opt_well_formed(node: Option<Node>) {
    match node {
        case Some(n) => 
            // The node structure is valid
            && n.well_formed() 
            // The root itself must not be useless (if it is, the tree should be None)
            && !n.is_empty()
        case None => true
    }
}
// </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 search(tree: Option<Node>, key: seq<int>) returns (res: bool)
    requires opt_well_formed(tree)
    // Constraint: Input key elements must represent bytes (u8)
    requires forall k :: k in key ==> 0 <= k < 256 
    ensures res == (key in opt_view(tree))
// </spec>
// <code>
{
    // Implement and verify the trie search operation here.
}
// </code>

method main() {}