Problem: longest_palindrome_substring

Your task is to implement Manacher's algorithm for the Longest Palindromic Substring and verify its correctness in Lean using Mathlib. The algorithm identifies the substring of maximal length in input $s$ that reads the same forwards and backwards. The operation proceeds as follows: (1) Transformation: Construct a modified string $T$ by inserting a unique separator (e.g., '#') between every character of $s$ (and at the outer boundaries) to uniformly handle both odd and even length palindromes. (2) Initialization: Maintain an array $P$ where $P[i]$ represents the radius of the palindrome centered at $T[i]$. Initialize a center variable $C$ and a right boundary variable $R$ to $0$. (3) Iteration: Iterate through each index $i$ of $T$. If $i < R$, initialize $P[i]$ using the properties of symmetry around $C$ via the mirror index $i' = 2C - i$, specifically setting $P[i] = \min(R - i, P[i'])$. Otherwise, initialize $P[i]$ to $0$. (4) Expansion: Attempt to expand the palindrome centered at $i$ by checking if characters at $T[i - 1 - P[i]]$ and $T[i + 1 + P[i]]$ are equal. Increment $P[i]$ repeatedly while they match. (5) Boundary Update: If the newly expanded palindrome at $i$ extends beyond $R$ (i.e., $i + P[i] > R$), update the center $C$ to $i$ and the boundary $R$ to $i + P[i]$. (6) Result Extraction: Find the maximum value in $P$ and map its center and radius back to the corresponding start index and length in original string $s$. Use Array UInt8 for input. Specifically, you must prove the following: (1) Functional Correctness: The returned tuple $(start, len)$ defines a valid subrange of $s$, the substring defined by this range satisfies the formal is_palindrome definition (symmetric characters), and for any other valid palindromic substring in $s$, its length is $\le len$. (2) Loop Invariants: You must demonstrate that for every processed center $k < i$, $P[k]$ stores the correct maximal palindrome radius for that center in $T$, and that the current variables $C$ and $R$ consistently mark the rightmost ending palindrome found so far.


import Mathlib

-- Precondition definitions
@[reducible, simp]
def longest_palindromic_substring_precond (s : Array UInt8) : Prop :=
  -- !benchmark @start precond
  s.size ≤ 1000000
  -- !benchmark @end precond

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

-- Main function definitions
def longest_palindromic_substring (s : Array UInt8)
    (_ : longest_palindromic_substring_precond s) :
    Nat × Nat :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Helper definitions
def is_valid_subrange (s : Array UInt8) (start len : Nat) : Prop :=
  start + len ≤ s.size

-- A sequence slice s[start, start+len) is a palindrome if for all i < len,
-- s[start + i] == s[start + len - 1 - i]
def is_palindrome_slice (s : Array UInt8) (start len : Nat) : Prop :=
  ∀ i, i < len → s.getD (start + i) 0 = s.getD (start + len - 1 - i) 0

-- Postcondition definitions
@[reducible, simp]
def longest_palindromic_substring_postcond
    (s : Array UInt8) (result : Nat × Nat)
    (_ : longest_palindromic_substring_precond s) : Prop :=
  -- !benchmark @start postcond
  let (start, len) := result
  is_valid_subrange s start len ∧
  is_palindrome_slice s start len ∧
  (∀ i l, is_valid_subrange s i l → is_palindrome_slice s i l → l ≤ len)
  -- !benchmark @end postcond

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

-- Proof content
theorem longest_palindromic_substring_postcond_satisfied
    (s : Array UInt8) (h_precond : longest_palindromic_substring_precond s) :
    longest_palindromic_substring_postcond
      s (longest_palindromic_substring s h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof