Problem: ac_automata

Your task is to implement the Aho-Corasick algorithm to find all occurrences of multiple patterns simultaneously within a haystack (text) and verify its functional correctness in Dafny. Preconditions: You can assume the input text and the total length of all patterns are at most 1,000,000 to ensure index arithmetic does not overflow. Requirements: Implement the method ac_automata_search which returns a seq<(int, int)> (pattern ID, start index). (1) Trie Construction: Build a Trie (prefix tree) from the set of input patterns. (2) Failure Links: Implement a BFS to compute "failure links" for each node, pointing to the longest proper suffix of the current string that exists in the Trie. (3) Traversal: Iterate through the text once, following Trie transitions and failure links to report matches. Verification Challenges: (1) Automaton Invariants: Proving that the failure links correctly point to the longest suffix-prefix match. (2) State Validity: Proving the invariant that after processing text character t[i], the current node in the automaton represents the longest suffix of t[0...i] that is a prefix of some pattern. (3) Multi-Pattern Completeness: Ensuring that if a node represents a match, or if its failure-link ancestors represent matches (substring matches), all are correctly added to the results sequence.

// Following is the block for necessary definitions
// <preamble>
predicate matches_at(haystack: seq<int>, needle: seq<int>, start_index: int) {
    && 0 <= start_index
    && start_index + |needle| <= |haystack|
    && forall i :: 0 <= i < |needle| ==> 
        haystack[start_index + i] == needle[i]
}

function patterns_view(patterns: seq<seq<int>>): seq<seq<int>> {
    patterns 
}
// </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 ac_automata_search(haystack: seq<int>, patterns: seq<seq<int>>) returns (results: seq<(int, int)>)
    requires |patterns| > 0
    requires |haystack| < 1000000
    requires |patterns| < 1000000
    requires forall i :: 0 <= i < |patterns| ==> |patterns[i]| < 1000000
    ensures
        // Soundness: Every result returned is a valid match
        forall i :: 0 <= i < |results| ==>
            var (pid, idx) := results[i];
            
            // Check bounds BEFORE accessing patterns[pid]
            && pid >= 0 && idx >= 0 
            && 0 <= pid < |patterns|
            && matches_at(haystack, patterns[pid], idx)

    ensures
        // Completeness: Every valid match for any pattern is contained in the results
        forall pid, idx ::
            0 <= pid < |patterns| && matches_at(haystack, patterns[pid], idx) ==>
            exists k :: 0 <= k < |results| && results[k] == (pid, idx)
// </spec>
// <code>
{
    // Implement and verify the Aho-Corasick algorithm here.
}
// </code>