Problem: string_search_naive

Your task is to implement a Naive String Search algorithm to find all occurrences of a needle (pattern) within a haystack (text) and verify its functional correctness in Lean using Mathlib. Preconditions: You can assume the input text and pattern are arrays of UInt8 (representing bytes) and their lengths are at most 1,000,000. Requirements: Implement the method naive_search which returns an Array Nat containing all starting indices. (1) The method must iterate through every possible starting position in the haystack. (2) For each position, it must perform a character-by-character comparison to check for a match. (3) Soundness & Completeness: You must prove that every index returned is a valid match and that no valid match is omitted. Verification Challenges: (1) Nested Loop Invariants: You must correctly specify the invariant for the inner comparison loop to prove it correctly identifies a match or mismatch. (2) Quantifier Instantiation: Proving completeness involves complex quantifiers (forall indices, if a match exists, it is in the result), which may require manual triggers or ghost code to show the iteration covers the entire search space.


import Mathlib

-- Precondition definitions
@[reducible, simp]
def naive_search_precond (haystack : Array UInt8) (needle : Array UInt8) : Prop :=
  -- !benchmark @start precond
  haystack.size < 1000000 ∧ 
  needle.size < 1000000
  -- !benchmark @end precond

-- !benchmark @start auxcode
-- !benchmark @end auxcode

-- Main function definition
def naive_search (haystack : Array UInt8) (needle : Array UInt8)
    (_ : naive_search_precond haystack needle) : Array Nat :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition auxiliary definitions
def matches_at (haystack needle : Array UInt8) (i : Nat) : Prop :=
  i + needle.size ≤ haystack.size ∧
  (∀ j, j < needle.size → haystack.getD (i + j) 0 = needle.getD j 0)

-- Postcondition definitions
@[reducible, simp]
def naive_search_postcond (haystack : Array UInt8) (needle : Array UInt8)
    (result : Array Nat) (_ : naive_search_precond haystack needle) : Prop :=
  -- !benchmark @start postcond
  (∀ i, i < result.size → matches_at haystack needle (result.getD i 0)) ∧
  (∀ i, matches_at haystack needle i → ∃ k, k < result.size ∧ result.getD k 0 = i)
  -- !benchmark @end postcond

-- !benchmark @start lemma
-- !benchmark @end lemma

-- Proof content
theorem naive_search_postcond_satisfied (haystack : Array UInt8) (needle : Array UInt8)
    (h_precond : naive_search_precond haystack needle) :
    naive_search_postcond haystack needle (naive_search haystack needle h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof