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 Lean using Mathlib. 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 Array (Nat × Nat) (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.

import Mathlib

-- Precondition definitions
@[reducible, simp]
def ac_automata_search_precond (haystack : Array UInt8) (patterns : Array (Array UInt8)) : Prop :=
  -- !benchmark @start precond
  haystack.size < 1000000 ∧
  patterns.size > 0 ∧
  patterns.size < 1000000 ∧
  (∀ i : Nat, i < patterns.size →
    let p := patterns.getD i #[]
    p.size < 1000000)
  -- !benchmark @end precond

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

-- Main function definitions
def ac_automata_search (haystack : Array UInt8) (patterns : Array (Array UInt8))
    (_ : ac_automata_search_precond haystack patterns) :
    Array (Nat × Nat) :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

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

-- Postcondition definitions
@[reducible, simp]
def ac_automata_search_postcond (haystack : Array UInt8) (patterns : Array (Array UInt8))
    (result : Array (Nat × Nat)) (_ : ac_automata_search_precond haystack patterns) : Prop :=
  -- !benchmark @start postcond
  (∀ i : Nat, i < result.size →
      let pair := result.getD i (0, 0)
      let pid := pair.fst
      let idx := pair.snd
      pid < patterns.size ∧
      -- Removed duplicate `pid < patterns.size` check
      matches_at haystack (patterns.getD pid #[]) idx) ∧
  (∀ pid idx : Nat,
      pid < patterns.size →
      matches_at haystack (patterns.getD pid #[]) idx →
      ∃ k : Nat, k < result.size ∧ result.getD k (0, 0) = (pid, idx))
  -- !benchmark @end postcond

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

-- Proof content
theorem ac_automata_search_postcond_satisfied (haystack : Array UInt8) (patterns : Array (Array UInt8))
    (h_precond : ac_automata_search_precond haystack patterns) :
    ac_automata_search_postcond haystack patterns
      (ac_automata_search haystack patterns h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the Bellman-Ford Algorithm and verify its functional correctness in Lean using Mathlib. Unlike Dijkstra, this algorithm must handle graphs with negative edge weights. Preconditions: You can assume the graph contains at most 100,000 nodes and edge weights are between -100,000 and 100,000 (inclusive) to prevent integer overflow. Crucially, the graph is a Simple Graph (no parallel edges between the same two nodes). Requirements: Implement the function bellman_ford which returns Option (List (Option Int)). Case 1 (Success): If the graph contains no negative cycles reachable from the start node, return Some(dists). dists[v] = Some d implies d is the shortest path weight. dists[v] = None implies v is unreachable. Case 2 (Negative Cycle): If the graph contains a reachable negative cycle (a cycle with total weight $< 0$), return None. Verification Challenges: (1) Relaxation Loop: The algorithm runs for $|V|-1$ iterations. You must prove the invariant that after $k$ iterations, dist[v] contains the shortest path weight using at most $k$ edges. (2) Negative Cycle Detection: You must verify the final check (the $|V|$-th iteration). Proving that if any distance can still be improved after $|V|-1$ iterations, a negative cycle effectively exists.

import Mathlib

structure WeightedGraph where
  adj : Array (Array (Nat × Int))

def WeightedGraph.size (g : WeightedGraph) : Nat :=
  g.adj.size

def WeightedGraph.has_edge (g : WeightedGraph) (u v : Nat) (w : Int) : Prop :=
  u < g.size ∧
  ∃ pair, pair ∈ g.adj.getD u #[] ∧ pair.1 = v ∧ pair.2 = w

def WeightedGraph.well_formed (g : WeightedGraph) : Prop :=
  ∀ u, u < g.size →
    -- All targets in range
    (∀ pair, pair ∈ g.adj.getD u #[] → pair.1 < g.size) ∧
    -- Unique targets (simple graph)
    (∀ p1 p2, p1 ∈ g.adj.getD u #[] → p2 ∈ g.adj.getD u #[] → p1.1 = p2.1 → p1 = p2)

def WeightedGraph.path_has_weight (g : WeightedGraph) (p : List Nat) (w_total : Int) : Prop :=
  match p with
  | [] => w_total = 0
  | [_] => w_total = 0
  | u :: v :: rest =>
      ∃ w_edge w_rest,
        g.has_edge u v w_edge ∧
        g.path_has_weight (v :: rest) w_rest ∧
        w_total = w_edge + w_rest

def WeightedGraph.is_path (g : WeightedGraph) (p : List Nat) : Prop :=
  p.length > 0 ∧
  match p with
  | [] => True
  | [_] => True
  | u :: v :: rest =>
      (∃ w, g.has_edge u v w) ∧ g.is_path (v :: rest)

-- Shortest path predicate
def WeightedGraph.is_shortest_dist (g : WeightedGraph) (start target : Nat) (d : Int) : Prop :=
  (∃ p, g.is_path p ∧ p.head? = some start ∧ p.getLast? = some target ∧ g.path_has_weight p d) ∧
  (∀ p w, g.is_path p → p.head? = some start → p.getLast? = some target → g.path_has_weight p w → w >= d)

-- Negative cycle predicate
def WeightedGraph.has_negative_cycle (g : WeightedGraph) : Prop :=
  ∃ p w, g.is_path p ∧ p.length > 1 ∧ p.head? = p.getLast? ∧ g.path_has_weight p w ∧ w < 0

def WeightedGraph.weights_and_size_bounded (g : WeightedGraph) : Prop :=
  g.size ≤ 100000 ∧
  ∀ u v w, g.has_edge u v w → w ≥ -100000 ∧ w ≤ 100000

-- Precondition definitions
@[reducible, simp]
def bellman_ford_precond (graph : WeightedGraph) (start : Nat) : Prop :=
  -- !benchmark @start precond
  graph.well_formed ∧
  start < graph.size ∧
  graph.weights_and_size_bounded
  -- !benchmark @end precond

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

-- Main function definition
def bellman_ford (graph : WeightedGraph) (start : Nat)
    (h_precond : bellman_ford_precond graph start) : Option (List (Option Int)) :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def bellman_ford_postcond (graph : WeightedGraph) (start : Nat)
    (result : Option (List (Option Int)))
    (_ : bellman_ford_precond graph start) : Prop :=
  -- !benchmark @start postcond
  match result with
  | some dists =>
      dists.length = graph.size ∧
      ∀ v, v < graph.size →
        match dists.getD v none with
        | some d => graph.is_shortest_dist start v d
        | none => ¬ ∃ p, graph.is_path p ∧ p.head? = some start ∧ p.getLast? = some v
  | none =>
      graph.has_negative_cycle
  -- !benchmark @end postcond

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

-- Proof content
theorem bellman_ford_postcond_satisfied (graph : WeightedGraph) (start : Nat)
    (h_precond : bellman_ford_precond graph start) :
    bellman_ford_postcond graph start
      (bellman_ford graph start h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement a Breadth First Search (BFS) algorithm to compute the shortest path distance between two nodes and verify its functional correctness in Lean using Mathlib. You need to implement bfs_shortest_path. The function should return Some(distance) if reachable, and None otherwise. There are several verification challenges: (1) Minimality: Unlike DFS, it is not enough to find any path. You must prove that the returned distance is minimal—i.e., no path exists with fewer edges. (2) Queue Invariants: Proving the specific structural properties of the BFS queue. You must verify that the queue always remains sorted by distance (containing only nodes at distance $k$ and $k+1$) and that nodes are processed level-by-level. (3) Reachability: Proving that if None is returned, the target is truly unreachable from the start node, effectively proving that the "frontier" of the search has been exhausted without finding the target.

import Mathlib

structure BFSGraph where
  adj : Array (Array Nat)

def BFSGraph.well_formed (g : BFSGraph) : Prop :=
  ∀ u, u < g.adj.size →
    ∀ v, v ∈ g.adj.getD u #[] → v < g.adj.size

def BFSGraph.size (g : BFSGraph) : Nat :=
  g.adj.size

def BFSGraph.has_edge (g : BFSGraph) (u v : Nat) : Prop :=
  u < g.adj.size ∧
  v ∈ g.adj.getD u #[]

def BFSGraph.is_path (g : BFSGraph) (p : List Nat) : Prop :=
  p.length > 0 ∧
  ∀ i, i + 1 < p.length →
    g.has_edge (p.getD i 0) (p.getD (i + 1) 0)

def BFSGraph.reachable (g : BFSGraph) (start target : Nat) : Prop :=
  ∃ p, g.is_path p ∧ p.head? = some start ∧ p.getLast? = some target

def BFSGraph.is_shortest_distance (g : BFSGraph) (start target : Nat) (d : Nat) : Prop :=
  (∃ p, g.is_path p ∧ p.head? = some start ∧ p.getLast? = some target ∧ p.length = d + 1) ∧
  (∀ p, g.is_path p → p.head? = some start → p.getLast? = some target → p.length ≥ d + 1)

-- Precondition definitions
@[reducible, simp]
def bfs_shortest_path_precond (graph : BFSGraph) (start target : Nat) : Prop :=
  -- !benchmark @start precond
  graph.well_formed ∧ graph.size ≤ 10000 ∧ start < graph.size ∧ target < graph.size
  -- !benchmark @end precond

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

-- Main function definition
def bfs_shortest_path (graph : BFSGraph) (start target : Nat)
    (h_precond : bfs_shortest_path_precond graph start target) : Option Nat :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def bfs_shortest_path_postcond (graph : BFSGraph) (start target : Nat) (result : Option Nat)
    (_ : bfs_shortest_path_precond graph start target) : Prop :=
  -- !benchmark @start postcond
  match result with
  | some dist => graph.is_shortest_distance start target dist
  | none => ¬ graph.reachable start target
  -- !benchmark @end postcond

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

-- Proof content
theorem bfs_shortest_path_postcond_satisfied (graph : BFSGraph) (start target : Nat)
    (h_precond : bfs_shortest_path_precond graph start target) :
    bfs_shortest_path_postcond graph start target
      (bfs_shortest_path graph start target h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the Lower Bound Binary Search algorithm and verify its correctness in Lean. Given a sorted array of integers and a target value, find the first index i such that arr[i] >= target. If no such element exists, return arr.size. Postconditions: Result index 'res' satisfies: (1) res <= arr.size, (2) all elements before 'res' are strictly less than target, and (3) all elements at or after 'res' are greater than or equal to target. Preconditions: Input array is sorted. Array size fits in signed 32-bit integer. Implementation should be iterative or recursive O(log N).

import Mathlib

-- Precondition definitions
@[reducible, simp]
def binary_search_lower_bound_precond (seq : Array Int) (target : Int) : Prop :=
  -- !benchmark @start precond
  seq.size ≤ 0x7FFFFFFF ∧
  (∀ i j : Nat, i < j ∧ j < seq.size → seq.getD i 0 ≤ seq.getD j 0)
  -- !benchmark @end precond

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

-- Main function definitions
def binary_search_lower_bound (seq : Array Int) (target : Int) (h_precond : binary_search_lower_bound_precond seq target) : Nat :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def binary_search_lower_bound_postcond (seq : Array Int) (target : Int) (result : Nat) (h_precond : binary_search_lower_bound_precond seq target) : Prop :=
  -- !benchmark @start postcond
  result ≤ seq.size ∧
  (∀ i : Nat, i < result → seq.getD i 0 < target) ∧
  (∀ i : Nat, result ≤ i ∧ i < seq.size → seq.getD i 0 ≥ target)
  -- !benchmark @end postcond

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

-- Proof content
theorem binary_search_lower_bound_postcond_satisfied (seq : Array Int) (target : Int) (h_precond : binary_search_lower_bound_precond seq target) :
    binary_search_lower_bound_postcond seq target (binary_search_lower_bound seq target h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement an algorithm to check if a graph is Bipartite (2-colorable) and verify its functional correctness in Lean using Mathlib. You need to implement check_bipartite, which attempts to color the graph with two colors (represented as booleans). It should return Some(colors) if successful, and None if the graph is not bipartite. There are several verification challenges: (1) Coloring Validity: If returning Some(colors), you must prove that for every edge $(u, v)$ in the graph, colors[u] != colors[v]. (2) Non-Bipartiteness: If returning None, you must prove that no valid 2-coloring exists. This is the hardest part. It requires proving that the conflict found (e.g., an edge connecting two nodes forced to be the same color) implies a contradiction for any possible valid coloring of the component. (3) Connectivity: Since the graph may be disconnected, you must prove the algorithm correctly handles all connected components, ensuring the property holds globally.

import Mathlib

structure BipartiteGraph where
  adj : Array (Array Nat)

def BipartiteGraph.well_formed (g : BipartiteGraph) : Prop :=
  ∀ u, u < g.adj.size →
    ∀ v, v ∈ g.adj.getD u #[] → v < g.adj.size

def BipartiteGraph.size (g : BipartiteGraph) : Nat :=
  g.adj.size

def BipartiteGraph.has_edge (g : BipartiteGraph) (u v : Nat) : Prop :=
  u < g.adj.size ∧
  v ∈ g.adj.getD u #[]

def BipartiteGraph.is_valid_coloring (g : BipartiteGraph) (colors : Array Bool) : Prop :=
  colors.size = g.size ∧
  ∀ u v, g.has_edge u v →
    u < colors.size → v < colors.size → colors.getD u false ≠ colors.getD v false

def BipartiteGraph.is_bipartite (g : BipartiteGraph) : Prop :=
  ∃ colors, g.is_valid_coloring colors

-- Precondition definitions
@[reducible, simp]
def check_bipartite_precond (graph : BipartiteGraph) : Prop :=
  -- !benchmark @start precond
  graph.well_formed
  -- !benchmark @end precond

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

-- Main function definition
def check_bipartite (graph : BipartiteGraph)
    (h_precond : check_bipartite_precond graph) : Option (Array Bool) :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def check_bipartite_postcond (graph : BipartiteGraph) (result : Option (Array Bool))
    (_ : check_bipartite_precond graph) : Prop :=
  -- !benchmark @start postcond
  match result with
  | some colors => graph.is_valid_coloring colors
  | none => ¬ graph.is_bipartite
  -- !benchmark @end postcond

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

-- Proof content
theorem check_bipartite_postcond_satisfied (graph : BipartiteGraph)
    (h_precond : check_bipartite_precond graph) :
    check_bipartite_postcond graph (check_bipartite graph h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement a linear scan algorithm for Bracket Matching and verify its correctness in Lean using Mathlib. The algorithm determines whether a sequence of characters $s$ (represented as UInt8 arrays) has perfectly balanced parentheses by maintaining a running balance counter. The operation proceeds by iterating through the string index $i$: (1) Initialization: Start with a balance counter variable $c$ set to $0$. (2) Iteration: Traverse the string character by character. Increment $c$ by $1$ for an open bracket '(' (40) and decrement $c$ by $1$ for a closed bracket ')' (41). (3) Early Failure: If $c$ drops below $0$ at any point, immediately return false. This enforces the constraint that a closing bracket must never appear before its corresponding opening bracket. (4) Final Check: After processing the entire string, return true only if $c$ is exactly $0$. Specifically, you must prove the following: (1) Functional Correctness: The executable boolean result must strictly match the formal definition of a valid bracket sequence, which requires that the sum of weights for the entire string is $0$ and the sum of weights for every prefix is non-negative (where '(' is $1$ and ')' is $-1$). (2) Loop Invariants: You must demonstrate that at every step $i$, the current counter value $c$ equals the mathematical summation of weights of the substring processed so far ($s[0..i]$), and that the non-negative prefix property holds for all prefixes within that range.

import Mathlib

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

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

-- Main function definition
def bracket_match (s : Array UInt8) (_ : bracket_match_precond s) : Bool :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Helper definitions
def char_weight (c : UInt8) : Int :=
  if c == 40 then 1      -- '('
  else if c == 41 then -1 -- ')'
  else 0

-- Calculates total weight of a list of characters
def total_weight (s : List UInt8) : Int :=
  (s.map char_weight).sum

-- Prefix property: all prefixes have non-negative total weight
def valid_prefix_weights (s : List UInt8) : Prop :=
  ∀ i, i ≤ s.length → total_weight (s.take i) ≥ 0

-- Correctness predicate
def is_matched (s : List UInt8) : Prop :=
  total_weight s = 0 ∧ valid_prefix_weights s

-- Postcondition definitions
@[reducible, simp]
def bracket_match_postcond (s : Array UInt8) (result : Bool) (_ : bracket_match_precond s) : Prop :=
  -- !benchmark @start postcond
  result = is_matched s.toList
  -- !benchmark @end postcond

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

-- Proof content
theorem bracket_match_postcond_satisfied
    (s : Array UInt8) (h_precond : bracket_match_precond s) :
    bracket_match_postcond s (bracket_match s h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement a Binary Search Tree (BST) and verify that it correctly implements a mathematical Set in Lean. The tree must maintain the BST Invariant: for any node with value $v$, all values in the left subtree are less than $v$ and all values in the right subtree are greater than $v$. Focus on the delete operation. Delete: Prove that (1) the resulting tree maintains the BST invariant, and (2) the new model set is the old set minus the deleted value. You can implement the naive BST delete.

import Mathlib

inductive BinarySearchTree : Type
| Empty : BinarySearchTree
| Node : Int → BinarySearchTree → BinarySearchTree → BinarySearchTree

def view (t : BinarySearchTree) : Set Int :=
  match t with
  | BinarySearchTree.Empty => ∅
  | BinarySearchTree.Node v l r => view l ∪ view r ∪ {v}

def is_bst (t : BinarySearchTree) : Prop :=
  match t with
  | BinarySearchTree.Empty => True
  | BinarySearchTree.Node v l r =>
    (∀ x ∈ view l, x < v) ∧
    is_bst l ∧
    (∀ x ∈ view r, x > v) ∧
    is_bst r

-- Precondition definitions
@[reducible, simp]
def delete_precond (t : BinarySearchTree) (v : Int) : Prop :=
  -- !benchmark @start precond
  is_bst t
  -- !benchmark @end precond

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

-- Main function definition
def delete (t : BinarySearchTree) (v : Int)
    (h_precond : delete_precond t v) : BinarySearchTree :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def delete_postcond (t : BinarySearchTree) (v : Int) (result : BinarySearchTree)
    (_ : delete_precond t v) : Prop :=
  -- !benchmark @start postcond
  is_bst result ∧
  view result = view t \ {v}
  -- !benchmark @end postcond

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

-- Proof content
theorem delete_postcond_satisfied (t : BinarySearchTree) (v : Int)
    (h_precond : delete_precond t v) :
    delete_postcond t v (delete t v h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement a Binary Search Tree (BST) and verify that it correctly implements a mathematical Set in Lean. The tree must maintain the BST Invariant: for any node with value $v$, all values in the left subtree are less than $v$ and all values in the right subtree are greater than $v$. Focus on the insert operation. Insert: Prove that (1) the resulting tree maintains the BST invariant, and (2) the new model set is the union of the old set and the inserted value. You can implement the naive BST insert.

import Mathlib

inductive BinarySearchTree : Type
| Empty : BinarySearchTree
| Node : Int → BinarySearchTree → BinarySearchTree → BinarySearchTree

def view (t : BinarySearchTree) : Set Int :=
  match t with
  | BinarySearchTree.Empty => ∅
  | BinarySearchTree.Node v l r => view l ∪ view r ∪ {v}

def is_bst (t : BinarySearchTree) : Prop :=
  match t with
  | BinarySearchTree.Empty => True
  | BinarySearchTree.Node v l r =>
    (∀ x ∈ view l, x < v) ∧
    is_bst l ∧
    (∀ x ∈ view r, x > v) ∧
    is_bst r

-- Precondition definitions
@[reducible, simp]
def insert_precond (t : BinarySearchTree) (v : Int) : Prop :=
  -- !benchmark @start precond
  is_bst t
  -- !benchmark @end precond

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

-- Main function definition
def insert (t : BinarySearchTree) (v : Int)
    (h_precond : insert_precond t v) : BinarySearchTree :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def insert_postcond (t : BinarySearchTree) (v : Int) (result : BinarySearchTree)
    (_ : insert_precond t v) : Prop :=
  -- !benchmark @start postcond
  is_bst result ∧
  view result = view t ∪ {v}
  -- !benchmark @end postcond

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

-- Proof content
theorem insert_postcond_satisfied (t : BinarySearchTree) (v : Int)
    (h_precond : insert_precond t v) :
    insert_postcond t v (insert t v h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement a Binary Search Tree (BST) and verify that it correctly implements a search operation in Lean. The tree must maintain the BST Invariant: for any node with value $v$, all values in the left subtree are less than $v$ and all values in the right subtree are greater than $v$. Search: Prove that the function returns true if and only if the target value is a member of the mathematical set represented by the tree's view. You can implement the naive BST search.

import Mathlib

inductive BinarySearchTree : Type
| Empty : BinarySearchTree
| Node : Int → BinarySearchTree → BinarySearchTree → BinarySearchTree

def view (t : BinarySearchTree) : Set Int :=
  match t with
  | BinarySearchTree.Empty => ∅
  | BinarySearchTree.Node v l r => view l ∪ view r ∪ {v}

def is_bst (t : BinarySearchTree) : Prop :=
  match t with
  | BinarySearchTree.Empty => True
  | BinarySearchTree.Node v l r =>
    (∀ x ∈ view l, x < v) ∧
    is_bst l ∧
    (∀ x ∈ view r, x > v) ∧
    is_bst r

-- Precondition definitions
@[reducible, simp]
def search_precond (t : BinarySearchTree) (v : Int) : Prop :=
  -- !benchmark @start precond
  is_bst t
  -- !benchmark @end precond

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

-- Main function definition
def search (t : BinarySearchTree) (v : Int)
    (h_precond : search_precond t v) : Bool :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def search_postcond (t : BinarySearchTree) (v : Int) (result : Bool)
    (_ : search_precond t v) : Prop :=
  -- !benchmark @start postcond
  result = (v ∈ view t)
  -- !benchmark @end postcond

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

-- Proof content
theorem search_postcond_satisfied (t : BinarySearchTree) (v : Int)
    (h_precond : search_precond t v) :
    search_postcond t v (search t v h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement a Binary Search Tree (BST) and verify that it correctly implements a mathematical Set in Lean. The tree must maintain the BST Invariant. Focus on the Zig operation (single right rotation). Zig: Prove that (1) the mathematical set of values (view) remains exactly the same, (2) the BST invariant is preserved, and (3) structural correctness: the original left child becomes the new root, and the original root becomes the new right child.

import Mathlib

inductive BinarySearchTree : Type
| Empty : BinarySearchTree
| Node : Int → BinarySearchTree → BinarySearchTree → BinarySearchTree
deriving Inhabited

def view (t : BinarySearchTree) : Set Int :=
  match t with
  | BinarySearchTree.Empty => ∅
  | BinarySearchTree.Node v l r => view l ∪ view r ∪ {v}

def is_bst (t : BinarySearchTree) : Prop :=
  match t with
  | BinarySearchTree.Empty => True
  | BinarySearchTree.Node v l r =>
    (∀ x ∈ view l, x < v) ∧
    is_bst l ∧
    (∀ x ∈ view r, x > v) ∧
    is_bst r

def get_left (t : BinarySearchTree) : Option BinarySearchTree :=
  match t with
  | BinarySearchTree.Node _ l _ => some l
  | _ => none

def get_right (t : BinarySearchTree) : Option BinarySearchTree :=
  match t with
  | BinarySearchTree.Node _ _ r => some r
  | _ => none

def get_val (t : BinarySearchTree) : Option Int :=
  match t with
  | BinarySearchTree.Node v _ _ => some v
  | _ => none

def BinarySearchTree.is_node (t : BinarySearchTree) : Prop :=
  match t with
  | BinarySearchTree.Node _ _ _ => True
  | _ => False

-- Precondition definitions
@[reducible, simp]
def zig_precond (t : BinarySearchTree) : Prop :=
  -- !benchmark @start precond
  is_bst t ∧
  BinarySearchTree.is_node t ∧
  (match get_left t with | some l => BinarySearchTree.is_node l | none => False)
  -- !benchmark @end precond

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

-- Main function definition
def zig (t : BinarySearchTree)
    (h_precond : zig_precond t) : BinarySearchTree :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def zig_postcond (t : BinarySearchTree) (result : BinarySearchTree)
    (_ : zig_precond t) : Prop :=
  -- !benchmark @start postcond
  is_bst result ∧
  view result = view t ∧
  -- Structural properties
  get_val result = get_val (get_left t).get! ∧
  BinarySearchTree.is_node (get_right result).get! ∧
  get_val (get_right result).get! = get_val t
  -- !benchmark @end postcond

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

-- Proof content
theorem zig_postcond_satisfied (t : BinarySearchTree)
    (h_precond : zig_precond t) :
    zig_postcond t (zig t h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the Zig-Zag operation (Left-Right Rotation) in a binary search tree and verify its correctness in Lean. A Zig-Zag is performed when node X lies between parent P and grandparent G (X is right child of P, P is left child of G). Prove: (1) Set Preservation: The tree's view is unchanged. (2) BST Invariant Preservation. (3) Structural Correctness: X becomes the new root, P becomes the left child of X, and G becomes the right child of X.

import Mathlib

inductive BinarySearchTree : Type
| Empty : BinarySearchTree
| Node : Int → BinarySearchTree → BinarySearchTree → BinarySearchTree
deriving Inhabited

def view (t : BinarySearchTree) : Set Int :=
  match t with
  | BinarySearchTree.Empty => ∅
  | BinarySearchTree.Node v l r => view l ∪ view r ∪ {v}

def is_bst (t : BinarySearchTree) : Prop :=
  match t with
  | BinarySearchTree.Empty => True
  | BinarySearchTree.Node v l r =>
    (∀ x ∈ view l, x < v) ∧
    is_bst l ∧
    (∀ x ∈ view r, x > v) ∧
    is_bst r

def get_left (t : BinarySearchTree) : Option BinarySearchTree :=
  match t with
  | BinarySearchTree.Node _ l _ => some l
  | _ => none

def get_right (t : BinarySearchTree) : Option BinarySearchTree :=
  match t with
  | BinarySearchTree.Node _ _ r => some r
  | _ => none

def get_val (t : BinarySearchTree) : Option Int :=
  match t with
  | BinarySearchTree.Node v _ _ => some v
  | _ => none

def BinarySearchTree.is_node (t : BinarySearchTree) : Prop :=
  match t with
  | BinarySearchTree.Node _ _ _ => True
  | _ => False

-- Precondition definitions
@[reducible, simp]
def zigzag_precond (t : BinarySearchTree) : Prop :=
  -- !benchmark @start precond
  is_bst t ∧
  BinarySearchTree.is_node t ∧
  (match get_left t with
   | some p => BinarySearchTree.is_node p ∧
               (match get_right p with
                | some x => BinarySearchTree.is_node x
                | none => False)
   | none => False)
  -- !benchmark @end precond

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

-- Main function definition
def zigzag (t : BinarySearchTree)
    (h_precond : zigzag_precond t) : BinarySearchTree :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def zigzag_postcond (t : BinarySearchTree) (result : BinarySearchTree)
    (_ : zigzag_precond t) : Prop :=
  -- !benchmark @start postcond
  is_bst result ∧
  view result = view t ∧
  -- Structural properties: X (grandchild, originally P's right child) is now root
  get_val result = get_val (get_right (get_left t).get!).get!
  -- !benchmark @end postcond

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

-- Proof content
theorem zigzag_postcond_satisfied (t : BinarySearchTree)
    (h_precond : zigzag_precond t) :
    zigzag_postcond t (zigzag t h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the Zig-Zig operation (Double Right Rotation) in a binary search tree and verify its correctness in Lean. A Zig-Zig is performed when a node X, its parent P, and its grandparent G form a straight line (X is left child of P, P is left child of G). Prove: (1) Set Preservation: The tree's view is unchanged. (2) BST Invariant Preservation. (3) Structural Correctness: X becomes the new root, P becomes the right child of X, and G becomes the right child of P.

import Mathlib

inductive BinarySearchTree : Type
| Empty : BinarySearchTree
| Node : Int → BinarySearchTree → BinarySearchTree → BinarySearchTree
deriving Inhabited

def view (t : BinarySearchTree) : Set Int :=
  match t with
  | BinarySearchTree.Empty => ∅
  | BinarySearchTree.Node v l r => view l ∪ view r ∪ {v}

def is_bst (t : BinarySearchTree) : Prop :=
  match t with
  | BinarySearchTree.Empty => True
  | BinarySearchTree.Node v l r =>
    (∀ x ∈ view l, x < v) ∧
    is_bst l ∧
    (∀ x ∈ view r, x > v) ∧
    is_bst r

def get_left (t : BinarySearchTree) : Option BinarySearchTree :=
  match t with
  | BinarySearchTree.Node _ l _ => some l
  | _ => none

def get_right (t : BinarySearchTree) : Option BinarySearchTree :=
  match t with
  | BinarySearchTree.Node _ _ r => some r
  | _ => none

def get_val (t : BinarySearchTree) : Option Int :=
  match t with
  | BinarySearchTree.Node v _ _ => some v
  | _ => none

def BinarySearchTree.is_node (t : BinarySearchTree) : Prop :=
  match t with
  | BinarySearchTree.Node _ _ _ => True
  | _ => False

-- Precondition definitions
@[reducible, simp]
def zigzig_precond (t : BinarySearchTree) : Prop :=
  -- !benchmark @start precond
  is_bst t ∧
  BinarySearchTree.is_node t ∧
  (match get_left t with
   | some p => BinarySearchTree.is_node p ∧
               (match get_left p with
                | some x => BinarySearchTree.is_node x
                | none => False)
   | none => False)
  -- !benchmark @end precond

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

-- Main function definition
def zigzig (t : BinarySearchTree)
    (h_precond : zigzig_precond t) : BinarySearchTree :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def zigzig_postcond (t : BinarySearchTree) (result : BinarySearchTree)
    (_ : zigzig_precond t) : Prop :=
  -- !benchmark @start postcond
  is_bst result ∧
  view result = view t ∧
  -- Structural properties: X (grandchild) is now root
  get_val result = get_val (get_left (get_left t).get!).get!
  -- !benchmark @end postcond

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

-- Proof content
theorem zigzig_postcond_satisfied (t : BinarySearchTree)
    (h_precond : zigzig_precond t) :
    zigzig_postcond t (zigzig t h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the Bubble Sort algorithm and verify its correctness in Lean. Given a list of integers, return a new list containing the same elements but in non-decreasing order. Postconditions: (1) The output list is sorted. (2) The output list is a permutation of the input list. Preconditions: None (valid for any list which fits in memory). Implementation should use the standard O(N^2) bubble sort logic: repeatedly iterate through the list, swapping adjacent elements if they are in the wrong order, until no swaps are needed.

import Mathlib

-- Precondition definitions
@[reducible, simp]
def bubble_sort_precond (v : List Int) : Prop :=
  -- !benchmark @start precond
  True
  -- !benchmark @end precond

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

-- Main function definitions
def bubble_sort (v : List Int) (h_precond : bubble_sort_precond v) : List Int :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def bubble_sort_postcond (v : List Int) (result : List Int) (h_precond : bubble_sort_precond v) : Prop :=
  -- !benchmark @start postcond
  List.Sorted (· ≤ ·) result ∧ result.Perm v
  -- !benchmark @end postcond

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

-- Proof content
theorem bubble_sort_postcond_satisfied (v : List Int) (h_precond : bubble_sort_precond v) :
    bubble_sort_postcond v (bubble_sort v h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the Coin Change algorithm and verify its correctness in Lean. Given a set of coin denominations and a target amount, find the minimum number of coins needed to make up that amount, or return -1 if impossible. Postconditions: If solvable, result satisfies Existence (valid count of coins yielding amount) and Optimality (minimal count). If impossible (-1), no valid combination exists. Coins are positive.

import Mathlib

-- Precondition definitions
@[reducible, simp]
def coin_change_precond (coins : List Nat) (amount : Nat) : Prop :=
  coins.length > 0 ∧
  coins.length ≤ 100 ∧
  amount ≤ 10000 ∧
  ∀ i, i < coins.length → (coins.getD i 0 > 0 ∧ coins.getD i 0 ≤ 10000)

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

-- Main function definition
def coin_change (coins : List Nat) (amount : Nat)
    (h_precond : coin_change_precond coins amount) : Int :=
  -- !benchmark @start code
  -- A simple placeholder implementation; the detailed DP algorithm is omitted for
  -- brevity and to keep the code easily type‑checkable.
  sorry
  -- !benchmark @end code

/-! ## Postcondition auxiliary definitions -/
def listNatToInt (s : List Nat) : List Int :=
  s.map (fun x => (x : Int))

def total_amount (counts : List Int) (coins : List Int) : Int :=
  (counts.zip coins).foldl (fun acc pair => acc + pair.1 * pair.2) 0

def total_coins (counts : List Int) : Int :=
  counts.foldl (fun acc c => acc + c) 0

def is_valid_change (counts : List Int) (coins : List Int) (amount : Int) : Prop :=
  counts.length = coins.length ∧
  (∀ i, i < counts.length → counts.getD i 0 ≥ 0) ∧
  total_amount counts coins = amount

-- Postcondition definitions
@[reducible, simp]
def coin_change_postcond (coins : List Nat) (amount : Nat) (result : Int)
    (h_precond : coin_change_precond coins amount) : Prop :=
  -- !benchmark @start postcond
  (result ≠ -1 →
    (∃ counts : List Int,
        is_valid_change counts (listNatToInt coins) (amount : Int) ∧
        total_coins counts = result) ∧
    (∀ counts : List Int,
        is_valid_change counts (listNatToInt coins) (amount : Int) →
        total_coins counts ≥ result))
  ∧
  (result = -1 →
    ∀ counts : List Int,
      is_valid_change counts (listNatToInt coins) (amount : Int) → False)
  -- !benchmark @end postcond

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

-- Proof content
theorem coin_change_postcond_satisfied (coins : List Nat) (amount : Nat)
    (h_precond : coin_change_precond coins amount) :
    coin_change_postcond coins amount (coin_change coins amount h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement an algorithm to detect if a directed graph (unweighted) contains a cycle and verify its functional correctness in Lean using Mathlib. You need to implement the function has_cycle, which returns true if the graph contains at least one cycle, and false if it is a Directed Acyclic Graph (DAG). The graph is represented as an Array of Array Nat (adjacency list). There are several verification challenges: (1) Soundness (Cycle Existence): Proving that if the function returns true, there indeed exists a path $p$ starting and ending at the same node with length $>1$. (2) Completeness (Acyclicity): Proving that if the function returns false, no such cycle exists in the entire graph. (3) Termination: Since the goal is to find a cycle, you must prove the algorithm terminates even when cycles are present, typically by tracking a set of visited nodes.

import Mathlib

structure CycleGraph where
  adj : Array (Array Nat)

def CycleGraph.well_formed (g : CycleGraph) : Prop :=
  ∀ u, u < g.adj.size →
    ∀ v, v ∈ g.adj.getD u #[] → v < g.adj.size

def CycleGraph.size (g : CycleGraph) : Nat :=
  g.adj.size

def CycleGraph.has_edge (g : CycleGraph) (u v : Nat) : Prop :=
  u < g.adj.size ∧
  v ∈ g.adj.getD u #[]

def CycleGraph.is_path (g : CycleGraph) (p : List Nat) : Prop :=
  p.length > 0 ∧
  ∀ i, i + 1 < p.length →
    g.has_edge (p.getD i 0) (p.getD (i + 1) 0)

def CycleGraph.is_cycle (g : CycleGraph) (p : List Nat) : Prop :=
  g.is_path p ∧ p.length > 1 ∧ p.head? = p.getLast?

def CycleGraph.graph_has_cycle (g : CycleGraph) : Prop :=
  ∃ p, g.is_cycle p

-- Precondition definitions
@[reducible, simp]
def has_cycle_precond (graph : CycleGraph) : Prop :=
  -- !benchmark @start precond
  graph.well_formed
  -- !benchmark @end precond

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

-- Main function definition
def has_cycle (graph : CycleGraph)
    (h_precond : has_cycle_precond graph) : Bool :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def has_cycle_postcond (graph : CycleGraph) (result : Bool)
    (_ : has_cycle_precond graph) : Prop :=
  -- !benchmark @start postcond
  result = graph.graph_has_cycle
  -- !benchmark @end postcond

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

-- Proof content
theorem has_cycle_postcond_satisfied (graph : CycleGraph)
    (h_precond : has_cycle_precond graph) :
    has_cycle_postcond graph (has_cycle graph h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement a Depth First Search (DFS) algorithm to determine reachability in a directed graph and verify its functional correctness in Lean using Mathlib. The graph is represented as an adjacency list (Array of Array Nat). You need to implement dfs_check_reachability, which returns true if and only if a path exists from the start node to the target node. There are several verification challenges: (1) Soundness (Path Validity): Proving that if the function returns true, a valid sequence of edges actually exists connecting the start to the target. (2) Completeness (Unreachability): Proving that if the function returns false, no such path exists. This is the hardest part; it requires a strong loop invariant relating the visited set to the stack. You typically need to prove that "any path from the start to an unvisited node must pass through a node currently in the stack." (3) Termination: Proving that the algorithm finishes. Since cycles may exist in the graph, you must prove that the visited set grows (or the count of unvisited nodes decreases) to guarantee termination.

import Mathlib

structure DFSGraph where
  adj : Array (Array Nat)

def DFSGraph.well_formed (g : DFSGraph) : Prop :=
  ∀ u, u < g.adj.size →
    ∀ v, v ∈ g.adj.getD u #[] → v < g.adj.size

def DFSGraph.size (g : DFSGraph) : Nat :=
  g.adj.size

def DFSGraph.has_edge (g : DFSGraph) (u v : Nat) : Prop :=
  u < g.adj.size ∧
  v ∈ g.adj.getD u #[]

def DFSGraph.is_path (g : DFSGraph) (p : List Nat) : Prop :=
  p.length > 0 ∧
  ∀ i, i + 1 < p.length →
    g.has_edge (p.getD i 0) (p.getD (i + 1) 0)

def DFSGraph.reachable (g : DFSGraph) (start target : Nat) : Prop :=
  ∃ p, g.is_path p ∧ p.head? = some start ∧ p.getLast? = some target

-- Precondition definitions
@[reducible, simp]
def dfs_check_reachability_precond (graph : DFSGraph) (start target : Nat) : Prop :=
  -- !benchmark @start precond
  graph.well_formed ∧ start < graph.size ∧ target < graph.size
  -- !benchmark @end precond

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

-- Main function definition
def dfs_check_reachability (graph : DFSGraph) (start target : Nat)
    (h_precond : dfs_check_reachability_precond graph start target) : Bool :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def dfs_check_reachability_postcond (graph : DFSGraph) (start target : Nat) (result : Bool)
    (_ : dfs_check_reachability_precond graph start target) : Prop :=
  -- !benchmark @start postcond
  result = graph.reachable start target
  -- !benchmark @end postcond

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

-- Proof content
theorem dfs_check_reachability_postcond_satisfied (graph : DFSGraph) (start target : Nat)
    (h_precond : dfs_check_reachability_precond graph start target) :
    dfs_check_reachability_postcond graph start target
      (dfs_check_reachability graph start target h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement Dijkstra's Algorithm for single-source shortest paths and verify its functional correctness in Lean using Mathlib. The input is a WeightedGraph where edge weights are Int. Preconditions: You can assume the graph contains at most 100,000 nodes and edge weights are between -100,000 and 100,000 (inclusive). Crucially, the graph is a Simple Graph (no parallel edges between the same two nodes) and all edge weights are non-negative ($w \ge 0$). Requirements: Implement the function dijkstra_shortest_paths which returns a list of Option Int. If a node v is reachable, the sequence at index v must contain Some(d), where d is the unique minimal path weight from the start node to v. If a node v is unreachable, the sequence must contain None. Verification Challenges: (1) Relaxation Invariant: Proving that when a node u is extracted from the priority queue, its recorded distance is the true shortest path distance. (2) Queue Invariants: Proving that the priority queue correctly maintains the "frontier" of the search. (3) Path Minimality: Proving that no path exists with weight strictly less than the returned distance.

import Mathlib

structure WeightedGraph where
  adj : Array (Array (Nat × Int))

def WeightedGraph.size (g : WeightedGraph) : Nat :=
  g.adj.size

def WeightedGraph.has_edge (g : WeightedGraph) (u v : Nat) (w : Int) : Prop :=
  u < g.size ∧
  ∃ pair, pair ∈ g.adj.getD u #[] ∧ pair.1 = v ∧ pair.2 = w

def WeightedGraph.well_formed (g : WeightedGraph) : Prop :=
  ∀ u, u < g.size →
    -- All targets in range
    (∀ pair, pair ∈ g.adj.getD u #[] → pair.1 < g.size) ∧
    -- Unique targets (simple graph)
    (∀ p1 p2, p1 ∈ g.adj.getD u #[] → p2 ∈ g.adj.getD u #[] → p1.1 = p2.1 → p1 = p2)

def WeightedGraph.get_edge_weight (g : WeightedGraph) (_ _ : Nat) : Int :=
  -- Since edges are unique, we can abstractly pick the weight
  -- In specification logic, we can use `Classical.choose` or similar if needed.
  -- But since we pass adjacency list, we can just say "w s.t. has_edge"
  -- For simple functional definition:
  0 -- placeholder for helper, spec logic mainly uses has_edge

def WeightedGraph.is_path (g : WeightedGraph) (p : List Nat) : Prop :=
  p.length > 0 ∧
  ∀ i, i + 1 < p.length →
    ∃ w, g.has_edge (p.getD i 0) (p.getD (i + 1) 0) w

def WeightedGraph.path_weight (_ : WeightedGraph) (p : List Nat) : Int :=
  match p with
  | [] => 0
  | [_] => 0
  | _ :: _ :: _ =>
      -- This assumes unique edges logic or we need an explicit path including weights
      -- For simplicity, we assume `has_edge` defines the unique weight
      -- and we sum it up. However, extracting it in logic is annoying.
      -- Let's define path_weight relationally instead.
      0

def WeightedGraph.path_has_weight (g : WeightedGraph) (p : List Nat) (w_total : Int) : Prop :=
  match p with
  | [] => w_total = 0
  | [_] => w_total = 0
  | u :: v :: rest =>
      ∃ w_edge w_rest,
        g.has_edge u v w_edge ∧
        g.path_has_weight (v :: rest) w_rest ∧
        w_total = w_edge + w_rest

def WeightedGraph.is_shortest_dist (g : WeightedGraph) (start target : Nat) (d : Int) : Prop :=
  (∃ p, g.is_path p ∧ p.head? = some start ∧ p.getLast? = some target ∧ g.path_has_weight p d) ∧
  (∀ p w, g.is_path p → p.head? = some start → p.getLast? = some target → g.path_has_weight p w → w >= d)

def WeightedGraph.weights_non_negative (g : WeightedGraph) : Prop :=
  ∀ u v w, g.has_edge u v w → w >= 0

def WeightedGraph.weights_and_size_bounded (g : WeightedGraph) : Prop :=
  g.size ≤ 100000 ∧
  ∀ u v w, g.has_edge u v w → w ≥ -100000 ∧ w ≤ 100000

-- Precondition definitions
@[reducible, simp]
def dijkstra_shortest_paths_precond (graph : WeightedGraph) (start : Nat) : Prop :=
  -- !benchmark @start precond
  graph.well_formed ∧
  start < graph.size ∧
  graph.weights_non_negative ∧
  graph.weights_and_size_bounded
  -- !benchmark @end precond

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

-- Main function definition
def dijkstra_shortest_paths (graph : WeightedGraph) (start : Nat)
    (h_precond : dijkstra_shortest_paths_precond graph start) : List (Option Int) :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def dijkstra_shortest_paths_postcond (graph : WeightedGraph) (start : Nat)
    (result : List (Option Int))
    (_ : dijkstra_shortest_paths_precond graph start) : Prop :=
  -- !benchmark @start postcond
  result.length = graph.size ∧
  ∀ v, v < graph.size →
    match result.getD v none with
    | some d => graph.is_shortest_dist start v d
    | none => ¬ ∃ p, graph.is_path p ∧ p.head? = some start ∧ p.getLast? = some v
  -- !benchmark @end postcond

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

-- Proof content
theorem dijkstra_shortest_paths_postcond_satisfied (graph : WeightedGraph) (start : Nat)
    (h_precond : dijkstra_shortest_paths_precond graph start) :
    dijkstra_shortest_paths_postcond graph start
      (dijkstra_shortest_paths graph start h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement a solver for the Discrete Logarithm Problem and verify its correctness in Lean. Given a base g, a target h, and a modulus p, find the smallest non-negative integer x < p such that g^x ≡ h (mod p), or return none if no such x exists. Algorithm: Use a naive linear search. Iterate `x` from 0 to `p-1`. Maintain a running product for `g^x % p` to avoid recomputing the power from scratch. Minimality: If multiple solutions exist, you must return the smallest `x`. Unsolvable Case: If no such `x` exists in the range `[0, p)`, return `none`. Goal: Find a non-negative integer `x` (where `0 ≤ x < p`) such that `(g.toNat ^ x) % p.toNat = h.toNat % p.toNat`. Preconditions: * Inputs: The generator `g`, target `h`, and modulus `p` are `UInt64`. * Constraint: `p.toNat > 1`. Postconditions: Implement `discrete_log_naive` which returns `Option UInt64`. Verification Challenges: (1) Incremental Modular Exponentiation: You are not calling a power function inside the loop; you are updating `current_val = (current_val * g) % p`. You must prove the invariant that at iteration `i`, `current_val == (Nat.pow g i) % p`. (2) Negative Proof (None): The hardest part is the `none` case. If the loop finishes without returning, you must prove the universal quantifier: `for all k < p, (Nat.pow g k) % p \ne h % p`. (3) Minimality (Some): When you return `some x`, you must prove that no earlier index `k < x` was a solution. Since your loop searches strictly from 0 upwards, this follows from the control flow, but you must capture it in the loop invariant ("for all checked k, g^k % p\ne h % p").

import Mathlib

-- Precondition definitions
@[reducible, simp]
def discrete_log_naive_precond (g h p : UInt64) : Prop :=
  -- !benchmark @start precond
  p.toNat > 1
  -- !benchmark @end precond

def is_discrete_log (g h p : Nat) (x : Nat) : Prop :=
  (Nat.pow g x) % p = h % p

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

-- Main function definitions
def discrete_log_naive (g h p : UInt64) (h_precond : discrete_log_naive_precond g h p) : Option UInt64 :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def discrete_log_naive_postcond (g h p : UInt64) (result : Option UInt64) (h_precond : discrete_log_naive_precond g h p) : Prop :=
  -- !benchmark @start postcond
  match result with
  | some x => is_discrete_log g.toNat h.toNat p.toNat x.toNat ∧ x.toNat < p.toNat ∧
               ∀ k : Nat, k < x.toNat → ¬ is_discrete_log g.toNat h.toNat p.toNat k
  | none => ∀ k : Nat, k < p.toNat → ¬ is_discrete_log g.toNat h.toNat p.toNat k
  -- !benchmark @end postcond

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

-- Proof content
theorem discrete_log_naive_postcond_satisfied (g h p : UInt64) (h_precond : discrete_log_naive_precond g h p) :
    discrete_log_naive_postcond g h p (discrete_log_naive g h p h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the Edmonds-Karp Algorithm to find the maximum flow in a directed graph with edge capacities and verify its functional correctness in Lean using Mathlib. Preconditions: You can assume the graph contains at most 1,000 nodes. You can assume edge capacities are between 0 and 100,000. The Source s and Sink t are valid, distinct nodes. Crucially, the graph is a Simple Graph. Requirements: Implement the function max_flow_value which returns the integer value of the max flow. Algorithm: Edmonds-Karp uses BFS to find augmenting paths. Output: The returned value must be equal to the net flow out of the source in a valid maximum flow assignment. Verification Challenges: (1) Residual Graph Correctness. (2) Termination. (3) Optimality (Min-Cut).

import Mathlib

structure CapacityGraph where
  adj : Array (Array (Nat × Int))

def CapacityGraph.size (g : CapacityGraph) : Nat :=
  g.adj.size

def CapacityGraph.has_capacity (g : CapacityGraph) (u v : Nat) (c : Int) : Prop :=
  u < g.size ∧
  ∃ pair, pair ∈ g.adj.getD u #[] ∧ pair.1 = v ∧ pair.2 = c

def CapacityGraph.well_formed (g : CapacityGraph) : Prop :=
  ∀ u, u < g.size →
    (∀ pair, pair ∈ g.adj.getD u #[] → pair.1 < g.size) ∧
    -- Unique targets
    (∀ p1 p2, p1 ∈ g.adj.getD u #[] → p2 ∈ g.adj.getD u #[] → p1.1 = p2.1 → p1 = p2)

-- A flow map assigns a flow value to each edge (u, v)
-- We can model this as a function or list of entries.
-- Since the result is just the max flow value, we can keep FlowMap abstract in the spec
-- or define it as `Nat -> Nat -> Int`.
-- Dijkstra and others used abstract/implicit paths. here we need explicit flow values.
def FlowMap := Nat → Nat → Int

def FlowMap.get (f : FlowMap) (u v : Nat) : Int := f u v

def CapacityGraph.respects_capacity (g : CapacityGraph) (f : FlowMap) : Prop :=
  ∀ u v,
    (f.get u v > 0 →
      ∃ c, g.has_capacity u v c ∧ f.get u v ≤ c) ∧
    (f.get u v >= 0) -- Non-negative flow

def flow_out (g : CapacityGraph) (f : FlowMap) (u : Nat) : Int :=
  -- Sum of f(u, v) for all v. Hard to define as sum over infinite/large domain without Finset.
  -- But we can sum over the adjacency list of u.
  -- Since well_formed ensures unique neighbors, we can map adj to flow and sum.
  let neighbors := g.adj.getD u #[]
  neighbors.foldl (λ sum pair => sum + f.get u pair.1) 0

def flow_in (g : CapacityGraph) (f : FlowMap) (u : Nat) : Int :=
  -- Sum of f(v, u). This requires iterating over all nodes v that have edge to u.
  -- We can iterate over all nodes v from 0 to size-1.
  -- This is a bit computationally heavy for definition but fine for spec.
  (List.range g.size).foldl (λ sum v => sum + f.get v u) 0

def is_conserved (g : CapacityGraph) (f : FlowMap) (s t : Nat) : Prop :=
  ∀ u, u < g.size → u ≠ s → u ≠ t →
    flow_in g f u = flow_out g f u

def is_valid_flow (g : CapacityGraph) (f : FlowMap) (s t : Nat) : Prop :=
  g.respects_capacity f ∧ is_conserved g f s t

def flow_val (g : CapacityGraph) (f : FlowMap) (s : Nat) : Int :=
  flow_out g f s - flow_in g f s

def is_max_flow (g : CapacityGraph) (f : FlowMap) (s t : Nat) : Prop :=
  is_valid_flow g f s t ∧
  ∀ other, is_valid_flow g other s t → flow_val g f s ≥ flow_val g other s

def CapacityGraph.capacities_bounded (g : CapacityGraph) : Prop :=
  g.size ≤ 1000 ∧
  ∀ u v c, g.has_capacity u v c → c ≥ 0 ∧ c ≤ 100000

-- Precondition definitions
@[reducible, simp]
def max_flow_value_precond (graph : CapacityGraph) (s t : Nat) : Prop :=
  -- !benchmark @start precond
  graph.well_formed ∧
  graph.capacities_bounded ∧
  s < graph.size ∧
  t < graph.size ∧
  s ≠ t
  -- !benchmark @end precond

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

-- Main function definition
def max_flow_value (graph : CapacityGraph) (s t : Nat)
    (h_precond : max_flow_value_precond graph s t) : Int :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def max_flow_value_postcond (graph : CapacityGraph) (s t : Nat) (result : Int)
    (_ : max_flow_value_precond graph s t) : Prop :=
  -- !benchmark @start postcond
  ∃ f, is_max_flow graph f s t ∧ flow_val graph f s = result
  -- !benchmark @end postcond

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

-- Proof content
theorem max_flow_value_postcond_satisfied (graph : CapacityGraph) (s t : Nat)
    (h_precond : max_flow_value_precond graph s t) :
    max_flow_value_postcond graph s t (max_flow_value graph s t h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the Fast Exponentiation Algorithm (Exponentiation by Squaring) and verify its correctness in Lean. Given a base b and a non-negative exponent e, compute b to the power of e in logarithmic time complexity. Preconditions: Result must fit within 64-bit unsigned integer limits (UInt64). Postconditions: Implement the function `exponentiation`. (1) Structure: Implementation should involve `exponentiation_by_squaring_aux`. (2) Functional Correctness: You must verify that your implementation returns exactly `b ^ e` (as defined by `Nat.pow`). (3) Safety: You must prove that neither the accumulator updates nor the squaring of the base ever cause a `UInt64` overflow. Verification Challenges: (1) Algebraic Lemmas: The core logic relies on $(b^2)^k = b^{2k}$. You must state and verify helper lemmas to handle this non-linear arithmetic. (2) Conservation Invariant: You must prove that at every step of the recursion/loop, $current\_res \times current\_base^{current\_exp} = original\_base^{original\_exp}$. (3) Intermediate Overflow Safety: You must prove that the base `b` is never squared if it would exceed `UInt64` limits, or that such squaring is avoided when unnecessary.

import Mathlib

-- Precondition definitions
@[reducible, simp]
def exponentiation_precond (b e : UInt64) : Prop :=
  -- !benchmark @start precond
  b.toNat ^ e.toNat ≤ (2 ^ 64 - 1)
  -- !benchmark @end precond

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

-- Main function definitions
def exponentiation (b e : UInt64) (h_precond : exponentiation_precond b e) : UInt64 :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def exponentiation_postcond (b e : UInt64) (result : UInt64) (h_precond : exponentiation_precond b e) : Prop :=
  -- !benchmark @start postcond
  result.toNat = b.toNat ^ e.toNat
  -- !benchmark @end postcond

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

-- Proof content
theorem exponentiation_postcond_satisfied (b e : UInt64)
    (h_precond : exponentiation_precond b e) :
    exponentiation_postcond b e (exponentiation b e h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the Euclidean Algorithm for Greatest Common Divisor (GCD) and verify its functional correctness in Lean. Given two non-negative integers a and b, compute the largest integer that divides both a and b. Postconditions: Result is a common divisor of a and b, and any other common divisor divides the result. Preconditions: a and b are non-negative. Implementation should use standard Euclidean algorithm (recursive or iterative).

import Mathlib

-- Precondition definitions
@[reducible, simp]
def compute_gcd_precond (a : UInt64) (b : UInt64) : Prop :=
  -- !benchmark @start precond
  True
  -- !benchmark @end precond

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

-- Main function definitions
def compute_gcd (a : UInt64) (b : UInt64) (h_precond : compute_gcd_precond a b) : UInt64 :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def compute_gcd_postcond (a : UInt64) (b : UInt64) (result : UInt64) (h_precond : compute_gcd_precond a b) : Prop :=
  -- !benchmark @start postcond
  result.toNat = Nat.gcd (UInt64.toNat a) (UInt64.toNat b)
  -- !benchmark @end postcond

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

-- Proof content
theorem compute_gcd_postcond_satisfied (a : UInt64) (b : UInt64) (h_precond : compute_gcd_precond a b) :
    compute_gcd_postcond a b (compute_gcd a b h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the House Robber algorithm and verify its correctness in Lean. Given a list of house values, maximize the total loot without robbing adjacent houses. Postconditions: Result is the value of some valid non-adjacent robbery plan, and no valid plan yields a higher value. Values are non-negative.

import Mathlib

def seq_u64_to_int (xs : List Nat) : List Nat := xs

def is_valid_robbery (houses : List Nat) (len : Nat) : Prop :=
  (∀ i, i < houses.length → houses.getD i 0 < len) ∧
  (∀ i, i < houses.length - 1 → houses.getD (i+1) 0 ≥ houses.getD i 0 + 2)

def total_loot (houses : List Nat) (values : List Nat) : Nat :=
  houses.foldl (fun acc i => acc + values.getD i 0) 0

-- Precondition definition
@[simp, reducible]
def rob_precond (nums : List Nat) : Prop :=
  -- !benchmark @start precond
  nums.length ≤ 100 ∧
  ∀ i, i < nums.length → nums.getD i 0 ≤ 10000
  -- !benchmark @end precond

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

-- Main function (dynamic programming solution)
def rob (nums : List Nat) (h_precond : rob_precond nums) : Nat :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definition
@[simp, reducible]
def rob_postcond (nums : List Nat) (result : Nat) (h_precond : rob_precond nums) : Prop :=
  -- !benchmark @start postcond
  (∀ houses : List Nat,
      is_valid_robbery houses nums.length →
        total_loot houses (seq_u64_to_int nums) ≤ result) ∧
    (∃ houses : List Nat,
        is_valid_robbery houses nums.length ∧
          total_loot houses (seq_u64_to_int nums) = result)
  -- !benchmark @end postcond

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

-- Proof that the implementation satisfies the postcondition
theorem rob_postcond_satisfied (nums : List Nat) (h_precond : rob_precond nums) :
    rob_postcond nums (rob nums h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the Insertion Sort algorithm and verify its correctness in Lean. Given a list of integers, return a sorted permutation of the list. Postconditions: (1) Output is sorted. (2) Output is a permutation of input. Preconditions: None. Implementation: Recursive or iterative insertion sort. Insert each element into the sorted prefix.

import Mathlib

-- Precondition definitions
@[reducible, simp]
def insertionSort_precond (v : List Int) : Prop :=
  -- !benchmark @start precond
  True
  -- !benchmark @end precond

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

-- Main function definitions
def insertionSort (v : List Int) (h_precond : insertionSort_precond v) : List Int :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def insertionSort_postcond (v : List Int) (result : List Int) (h_precond : insertionSort_precond v) : Prop :=
  -- !benchmark @start postcond
   List.Sorted (· ≤ ·) result ∧ result.Perm v
  -- !benchmark @end postcond

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

-- Proof content
theorem insertionSort_postcond_satisfied (v : List Int) (h_precond : insertionSort_precond v) :
    insertionSort_postcond v (insertionSort v h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement Integer Exponentiation and verify its correctness in Lean. Given a base b and a non-negative exponent e, compute b to the power of e.  Preconditions: The input base b and exponent e are natural numbers (Nat). Postconditions: Implement the function to compute the exponential. (1) Functional Correctness: You must verify that your implementation returns exactly b ^ e (as strictly defined by Lean's Nat.pow). (2) Termination: You must prove that your recursive implementation terminates. Verification Challenges: (1) Accumulation Invariant: You must prove the invariant (or recursion hypothesis) that ensures the computation correctly builds up to the final power b^e.

import Mathlib

-- Precondition definitions
@[reducible, simp]
def exponentiation_precond (b e : Nat) : Prop :=
  -- !benchmark @start precond
  True
  -- !benchmark @end precond

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

-- Main function definitions
def exponentiation (b e : Nat) (h_precond : exponentiation_precond b e) : Nat :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def exponentiation_postcond (b e result : Nat) (h_precond : exponentiation_precond b e) : Prop :=
  -- !benchmark @start postcond
  result = b ^ e
  -- !benchmark @end postcond

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

-- Proof content
theorem exponentiation_postcond_satisfied (b e : Nat)
    (h_precond : exponentiation_precond b e) :
    exponentiation_postcond b e (exponentiation b e h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the Jump Game algorithm and verify its correctness in Lean. Given an array of non-negative integers where each represents the max jump length from that position, determine if you can reach the last index starting from index 0. Postconditions: Result is true iff there exists a valid sequence of jumps from 0 to last index. A valid jump at i lands on j where i < j <= i + nums[i].

import Mathlib

-- Precondition definition
@[reducible, simp]
def can_jump_precond (nums : List Nat) : Prop :=
  -- !benchmark @start precond
  0 < nums.length ∧
  nums.length ≤ 10000 ∧
  (∀ i, i < nums.length → nums.getD i 0 ≤ 10000)
  -- !benchmark @end precond

def is_valid_jump_path (path : List Nat) (nums : List Nat) : Prop :=
  path.length > 0 ∧
  path.head? = some 0 ∧
  path.getLast? = some (nums.length - 1) ∧
  (∀ i, i < path.length → path.getD i 0 < nums.length) ∧
  (∀ i, i < path.length - 1 →
    let u := path.getD i 0
    let v := path.getD (i+1) 0
    u < v ∧ v ≤ u + nums.getD u 0)

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

-- Main function definition
def can_jump (nums : List Nat) (h_precond : can_jump_precond nums) : Bool :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definition
@[reducible, simp]
def can_jump_postcond (nums : List Nat) (result : Bool) (h_precond : can_jump_precond nums) : Prop :=
  -- !benchmark @start postcond
  (result = true) ↔ ∃ (path : List Nat), is_valid_jump_path path nums
  -- !benchmark @end postcond

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

-- Proof content
theorem can_jump_postcond_satisfied (nums : List Nat) (h_precond : can_jump_precond nums) :
    can_jump_postcond nums (can_jump nums h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the Quick Select algorithm to find the k-th smallest element and verify its correctness in Lean. Given a list of integers and an index k, return the k-th smallest element (0-indexed). Postconditions: The result is the element that would be at index k if the array were sorted. Preconditions: k < array.size. Implementation: Recursive partition-based selection (like Quick Sort partition). Return the element if the pivot index is k, otherwise recurse into the appropriate sub-array. Time complexity should be O(N) on average.

import Mathlib

-- Precondition definitions
@[reducible, simp]
def quick_select_precond (v : Array Int) (k : Nat) : Prop :=
  -- !benchmark @start precond
  k < v.size
  -- !benchmark @end precond

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

-- Main function definitions
def quick_select (v : Array Int) (k : Nat) (h_precond : quick_select_precond v k) : Int :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def quick_select_postcond (v : Array Int) (k : Nat) (result : Int) (h_precond : quick_select_precond v k) : Prop :=
  -- !benchmark @start postcond
  ∃ sorted : List Int,
    sorted.length = v.size ∧
    List.Sorted (· ≤ ·) sorted ∧
    sorted.getD k 0 = result ∧
    sorted.Perm v.toList
  -- !benchmark @end postcond

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

-- Proof content
theorem quick_select_postcond_satisfied (v : Array Int) (k : Nat) (h_precond : quick_select_precond v k) :
    quick_select_postcond v k (quick_select v k h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the Knuth-Morris-Pratt (KMP) algorithm to efficiently 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 kmpSearch which returns an Array Nat. (1) Preprocessing: You must implement a helper to compute the Longest Prefix Suffix (LPS) array (or "next" array), where lps[i] stores the length of the longest proper prefix of the sub-pattern that is also a suffix of that sub-pattern. (2) Search: The main loop must use the LPS array to skip unnecessary comparisons in the text when a mismatch occurs, achieving linear time complexity. (3) Functional Correctness: Prove that despite the optimization, the result is identical to a naive search (Soundness and Completeness). Verification Challenges: (1) LPS Property: Proving that your preprocessing logic actually satisfies the mathematical definition of the LPS table. (2) Safe Skipping: Proving that the "jump" logic (moving the pattern index based on LPS) never skips a valid match. (3) Complex Invariants: The main loop invariant must relate the current state of the pattern index to the prefix of the pattern matched against the text so far.

import Mathlib

-- Precondition definitions
@[reducible, simp]
def kmpSearch_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 kmpSearch (haystack : Array UInt8) (needle : Array UInt8)
    (_ : kmpSearch_precond haystack needle) : Array Nat :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition auxiliary definitions
def matchesAt (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 kmpSearch_postcond (haystack : Array UInt8) (needle : Array UInt8)
    (result : Array Nat) (_ : kmpSearch_precond haystack needle) : Prop :=
  -- !benchmark @start postcond
  (∀ i, i < result.size → matchesAt haystack needle (result.getD i 0)) ∧ -- Soundness
  (∀ i, matchesAt haystack needle i → ∃ k, k < result.size ∧ result.getD k 0 = i) -- Completeness
  -- !benchmark @end postcond

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

-- Proof content
theorem kmpSearch_postcond_satisfied (haystack : Array UInt8) (needle : Array UInt8)
    (h_precond : kmpSearch_precond haystack needle) :
    kmpSearch_postcond haystack needle (kmpSearch haystack needle h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the 0/1 Knapsack algorithm and verify its correctness in Lean. Given weights and values for n items and a capacity W, determine the maximum total value of items that can be selected without exceeding W. Postconditions: Upper Bound (result ≥ value of any valid selection) and Existence (result = value of some valid selection). Valid selection means total weight ≤ W.

import Mathlib

def total_weight (selected : List Bool) (weights : List Nat) : Nat :=
  match selected, weights with
  | [], _ => 0
  | _, [] => 0
  | b :: bs, w :: ws => (if b then w else 0) + total_weight bs ws

def total_value (selected : List Bool) (values : List Nat) : Nat :=
  match selected, values with
  | [], _ => 0
  | _, [] => 0
  | b :: bs, v :: vs => (if b then v else 0) + total_value bs vs

def is_valid_strategy (selected : List Bool) (weights : List Nat) (capacity : Nat) : Prop :=
  selected.length = weights.length ∧
  total_weight selected weights ≤ capacity

-- Precondition definitions
@[reducible, simp]
def knapsack_01_precond (weights values : List Nat) (capacity : Nat) : Prop :=
  -- !benchmark @start precond
  weights.length = values.length
  -- !benchmark @end precond

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

-- Main function definition
def knapsack_01 (weights values : List Nat) (capacity : Nat)
    (h_precond : knapsack_01_precond weights values capacity) : Nat :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def knapsack_01_postcond (weights values : List Nat) (capacity : Nat) (result : Nat)
    (_ : knapsack_01_precond weights values capacity) : Prop :=
  -- !benchmark @start postcond
  (∀ selected, is_valid_strategy selected weights capacity → total_value selected values ≤ result) ∧
  (∃ selected, is_valid_strategy selected weights capacity ∧ total_value selected values = result)
  -- !benchmark @end postcond

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

-- Proof content
theorem knapsack_01_postcond_satisfied (weights values : List Nat) (capacity : Nat)
    (h_precond : knapsack_01_precond weights values capacity) :
    knapsack_01_postcond weights values capacity (knapsack_01 weights values capacity h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the Unbounded Knapsack algorithm and verify its correctness in Lean. Given weights and values for n items and a capacity W, determine the maximum total value of items that can be selected (with replacement) without exceeding W. Postconditions: Upper Bound and Existence of a valid strategy (counts of items). Weights are strictly positive.

import Mathlib

/-! ### Precondition definitions -/

def solve_knapsack_unbounded_precond (weights values : List Nat) (capacity : Nat) : Prop :=
  (weights.length = values.length) ∧
  (weights.length > 0) ∧
  (capacity ≤ 1000) ∧
  (∀ i, i < weights.length → weights.getD i 0 > 0) ∧
  (∀ i, i < weights.length → weights.getD i 0 ≤ 1000) ∧
  (∀ i, i < values.length → values.getD i 0 ≤ 1000)

/-! ### Auxiliary definitions for the post‑condition -/

def list_nat_to_int (l : List Nat) : List Int :=
  l.map (fun x => Int.ofNat x)

def total_weight (counts weights : List Int) : Int :=
  (counts.zip weights).foldl (fun acc p => acc + p.1 * p.2) 0

def total_value (counts values : List Int) : Int :=
  (counts.zip values).foldl (fun acc p => acc + p.1 * p.2) 0

def is_valid_strategy (counts weights : List Int) (capacity : Int) : Prop :=
  counts.length = weights.length ∧
  (∀ i, i < counts.length → counts.getD i 0 ≥ 0) ∧
  total_weight counts weights ≤ capacity

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

-- Main function definition
def solve_knapsack_unbounded
    (weights values : List Nat) (capacity : Nat)
    (h_precond : solve_knapsack_unbounded_precond weights values capacity) : Nat :=
  -- !benchmark @start code
  -- A placeholder implementation; the correctness proof is discharged by `sorry`.
  sorry
  -- !benchmark @end code

-- Postcondition definitions
def solve_knapsack_unbounded_postcond
    (weights values : List Nat) (capacity : Nat) (result : Nat)
    (h_precond : solve_knapsack_unbounded_precond weights values capacity) : Prop :=
  -- !benchmark @start postcond
  (∀ counts : List Int,
        is_valid_strategy counts (list_nat_to_int weights) (Int.ofNat capacity) →
        total_value counts (list_nat_to_int values) ≤ Int.ofNat result) ∧
  (∃ counts : List Int,
        is_valid_strategy counts (list_nat_to_int weights) (Int.ofNat capacity) ∧
        total_value counts (list_nat_to_int values) = Int.ofNat result)
  -- !benchmark @end postcond

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

-- Proof content
theorem solve_knapsack_unbounded_postcond_satisfied
    (weights values : List Nat) (capacity : Nat)
    (h_precond : solve_knapsack_unbounded_precond weights values capacity) :
    solve_knapsack_unbounded_postcond
      weights values capacity
      (solve_knapsack_unbounded weights values capacity h_precond)
      h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement Kruskal's Algorithm to find the Minimum Spanning Tree (MST) of a connected, undirected, weighted graph and verify its functional correctness in Lean using Mathlib. The graph is represented as an adjacency list with Int weights. Preconditions: You can assume the graph is connected (a path exists between any two nodes). You can assume the graph contains at most 100,000 nodes and edge weights are between -100,000 and 100,000 to prevent integer overflow. Crucially, the graph is a Simple Graph (no parallel edges between the same two nodes). Requirements: Implement the function kruskal_mst which returns a list of edges (source, target, weight). (1) The function must sort all edges by weight and iterate through them. (2) It should add an edge to the result only if it connects two previously disconnected components (i.e., does not form a cycle). (3) Global Optimality: You must prove that the sum of weights of your returned edges is less than or equal to the sum of weights of any other possible spanning tree of the graph. Verification Challenges: (1) Union-Find (Disjoint Set): To efficiently implement Kruskal's, you typically use a Union-Find data structure; you must verify that your find and union operations correctly track component connectivity. (2) Cycle Prevention: Proving that your check (typically find(u) != find(v)) correctly predicts whether adding edge $(u, v)$ would create a cycle. (3) Forest Invariant: Unlike Prim's (which grows one tree), Kruskal's grows a forest of trees; you must prove the invariant that this forest eventually merges into a single spanning tree and that every edge added is a "safe edge" for some MST.

import Mathlib

structure WeightedGraph where
  adj : Array (Array (Nat × Int))

def WeightedGraph.size (g : WeightedGraph) : Nat :=
  g.adj.size

def WeightedGraph.has_edge (g : WeightedGraph) (u v : Nat) (w : Int) : Prop :=
  u < g.size ∧
  ∃ pair, pair ∈ g.adj.getD u #[] ∧ pair.1 = v ∧ pair.2 = w

def WeightedGraph.well_formed (g : WeightedGraph) : Prop :=
  ∀ u, u < g.size →
    -- Bounds check
    (∀ pair, pair ∈ g.adj.getD u #[] → pair.1 < g.size) ∧
    -- Simple graph check (matches Dafny)
    (∀ p1 p2, p1 ∈ g.adj.getD u #[] → p2 ∈ g.adj.getD u #[] → p1.1 = p2.1 → p1 = p2)

structure MSTEdge where
  u : Nat
  v : Nat
  w : Int

-- 1. Validity
def MSTEdge.is_valid (e : MSTEdge) (g : WeightedGraph) : Prop :=
  g.has_edge e.u e.v e.w

-- 2. Connectivity for Solution Edges (Undirected View)
-- Dafny: `edge_in_set` checks (u, v) || (v, u)
def edges_contain (edges : List MSTEdge) (u v : Nat) : Prop :=
  ∃ e, e ∈ edges ∧ ((e.u = u ∧ e.v = v) ∨ (e.u = v ∧ e.v = u))

def path_follows_edges (edges : List MSTEdge) (p : List Nat) : Prop :=
  p.length > 0 ∧
  ∀ i, i + 1 < p.length →
    edges_contain edges (p.getD i 0) (p.getD (i + 1) 0)

def is_connected_with_edges (g : WeightedGraph) (edges : List MSTEdge) : Prop :=
  ∀ u v, u < g.size → v < g.size →
    ∃ p, p.head? = some u ∧ p.getLast? = some v ∧ path_follows_edges edges p

-- 3. Spanning Tree Definition
def is_spanning_tree (g : WeightedGraph) (edges : List MSTEdge) : Prop :=
  edges.length = g.size - 1 ∧
  (∀ e, e ∈ edges → e.is_valid g) ∧
  is_connected_with_edges g edges
  -- Note: |V|-1 edges + Connected implies Acyclic (Tree)

def total_weight (edges : List MSTEdge) : Int :=
  edges.foldl (λ sum e => sum + e.w) 0

-- 4. Optimality (MST)
def is_mst (g : WeightedGraph) (edges : List MSTEdge) : Prop :=
  is_spanning_tree g edges ∧
  ∀ other, is_spanning_tree g other → total_weight edges ≤ total_weight other

-- 5. Graph Connectivity (Precondition)
-- Dafny uses directed edges for the graph path check: `graph_has_any_edge`
def path_follows_graph (g : WeightedGraph) (p : List Nat) : Prop :=
  p.length > 0 ∧
  ∀ i, i + 1 < p.length →
    ∃ w, g.has_edge (p.getD i 0) (p.getD (i + 1) 0) w

def WeightedGraph.is_connected (g : WeightedGraph) : Prop :=
  ∀ u v, u < g.size → v < g.size →
    ∃ p, p.head? = some u ∧ p.getLast? = some v ∧ path_follows_graph g p

def WeightedGraph.weights_bounded (g : WeightedGraph) : Prop :=
  g.size ≤ 100000 ∧
  ∀ u v w, g.has_edge u v w → w ≥ -100000 ∧ w ≤ 100000

-- Precondition definitions
@[reducible, simp]
def kruskal_mst_precond (graph : WeightedGraph) : Prop :=
  -- !benchmark @start precond
  graph.well_formed ∧
  graph.size > 0 ∧
  graph.is_connected ∧
  graph.weights_bounded
  -- !benchmark @end precond

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

-- Main function definition
def kruskal_mst (graph : WeightedGraph)
    (h_precond : kruskal_mst_precond graph) : List MSTEdge :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def kruskal_mst_postcond (graph : WeightedGraph) (result : List MSTEdge)
    (_ : kruskal_mst_precond graph) : Prop :=
  -- !benchmark @start postcond
  is_mst graph result
  -- !benchmark @end postcond

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

-- Proof content
theorem kruskal_mst_postcond_satisfied (graph : WeightedGraph)
    (h_precond : kruskal_mst_precond graph) :
    kruskal_mst_postcond graph (kruskal_mst graph h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the Lowest Common Ancestor (LCA) algorithm and verify its correctness in Lean. Given a binary tree with distinct values and two target values p and q that exist in the tree, find the lowest common ancestor node. Postconditions: Result is an ancestor of both p and q, and is the deepest such ancestor. Distinct values are assumed.

import Mathlib

inductive Node where
  | nil
  | node (val : Nat) (left : Node) (right : Node)
deriving Inhabited, Repr

open Node

def view (t : Node) : Set Nat :=
  match t with
  | nil => ∅
  | node v l r => {v} ∪ view l ∪ view r

def tree_contains (t : Node) (target : Nat) : Bool :=
  match t with
  | nil => false
  | node v l r => v == target || tree_contains l target || tree_contains r target

def tree_distinct (t : Node) : Prop :=
  match t with
  | nil => True
  | node v l r =>
      tree_distinct l ∧ tree_distinct r ∧
      v ∉ view l ∧ v ∉ view r ∧
      (view l ∩ view r = ∅)

-- Precondition definitions
@[reducible, simp]
def lowest_common_ancestor_precond (root : Node) (p q : Nat) : Prop :=
  -- !benchmark @start precond
  tree_contains root p ∧ tree_contains root q ∧ tree_distinct root
  -- !benchmark @end precond

def aux (root : Node) (p q : Nat) : Option Nat × Bool × Bool :=
  match root with
  | nil => (none, false, false)
  | node val l r =>
      let (lcaL, hasPL, hasQL) := aux l p q
      let (lcaR, hasPR, hasQR) := aux r p q
      let hasP := (val == p) || hasPL || hasPR
      let hasQ := (val == q) || hasQL || hasQR
      let lca :=
        if lcaL.isSome then lcaL
        else if lcaR.isSome then lcaR
        else if hasP && hasQ then some val else none
      (lca, hasP, hasQ)

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

-- Main function definition
def lowest_common_ancestor (root : Node) (p q : Nat)
    (h_precond : lowest_common_ancestor_precond root p q) : Option Nat :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

def is_ancestor (root : Node) (anc target : Nat) : Prop :=
  match root with
  | nil => False
  | node v l r =>
      if v = anc then tree_contains (node v l r) target = true
      else is_ancestor l anc target ∨ is_ancestor r anc target

-- ADDED: Helper to determine depth for the "Lowest" check
def get_depth (root : Node) (target : Nat) : Option Nat :=
  match root with
  | nil => none
  | node v l r =>
      if v == target then some 0
      else
        match get_depth l target, get_depth r target with
        | some d, _ => some (d + 1)
        | none, some d => some (d + 1)
        | none, none => none

-- Postcondition definitions
@[reducible, simp]
def lowest_common_ancestor_postcond (root : Node) (p q : Nat) (result : Option Nat)
    (_ : lowest_common_ancestor_precond root p q) : Prop :=
  -- !benchmark @start postcond
  match result with
  | some lca =>
      -- 1. Validity: It is a common ancestor
      is_ancestor root lca p ∧
      is_ancestor root lca q ∧
      -- 2. Optimality: It is the LOWEST (Deepest) common ancestor
      (∀ x, is_ancestor root x p → is_ancestor root x q →
         match get_depth root x, get_depth root lca with
         | some dx, some dres => dx ≤ dres
         | _, _ => True) -- Should imply dx and dres exist if is_ancestor is true
  | none => False
  -- !benchmark @end postcond

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

-- Proof content
theorem lowest_common_ancestor_postcond_satisfied (root : Node) (p q : Nat)
    (h_precond : lowest_common_ancestor_precond root p q) :
    lowest_common_ancestor_postcond root p q (lowest_common_ancestor root p q h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement the Linear Search algorithm to find the lower bound index and verify its correctness in Lean. Given a sequence of integers (not necessarily sorted, though typically used with sorting in mind for lower_bound semantics, the spec here just asks for the partition point if it were sorted or just the first element >= target), find the first index k such that seq[k] >= target. Returns seq.size if no such element is found. Postconditions: (1) result <= seq.size. (2) All elements before 'result' are < target. (3) All elements from 'result' onwards (if sorted) or just the element at 'result' matches the condition? Wait, the Dafny spec says "forall i < result ==> s[i] < target" and "forall i >= result ==> s[i] >= target". This implies the array MUST be sorted for this spec to hold for ALL i >= result. However, the Dafny spec provided does NOT explicitly require `is_sorted` in the precondition for `linear_search` in the file view (wait, let me check the file content again... checked: explicitly requires `is_sorted(s)`). So it is Lower Bound on a sorted array using Linear Search. Implementation should be O(N).

import Mathlib

-- Precondition definitions
@[reducible, simp]
def linear_search_lower_bound_precond (seq : Array Int) (target : Int) : Prop :=
  -- !benchmark @start precond
  seq.size ≤ 0x7FFFFFFF ∧
  (∀ i j : Nat, i < j ∧ j < seq.size → seq.getD i 0 ≤ seq.getD j 0)
  -- !benchmark @end precond

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

-- Main function definitions
def linear_search_lower_bound (seq : Array Int) (target : Int) (h_precond : linear_search_lower_bound_precond seq target) : Nat :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def linear_search_lower_bound_postcond (seq : Array Int) (target : Int) (result : Nat) (h_precond : linear_search_lower_bound_precond seq target) : Prop :=
  -- !benchmark @start postcond
  result ≤ seq.size ∧
  (∀ i : Nat, i < result → seq.getD i 0 < target) ∧
  (∀ i : Nat, result ≤ i ∧ i < seq.size → seq.getD i 0 ≥ target)
  -- !benchmark @end postcond

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

-- Proof content
theorem linear_search_lower_bound_postcond_satisfied (seq : Array Int) (target : Int) (h_precond : linear_search_lower_bound_precond seq target) :
    linear_search_lower_bound_postcond seq target (linear_search_lower_bound seq target h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement a Gaussian Elimination solver for linear systems over GF(2) and verify its correctness in Lean. Given a binary matrix A (m x n) and a binary vector b (length m), find a binary vector x (length n) such that Ax = b (modulo 2), or return None if no solution exists. Postconditions: If result is Some(x), then Ax = b (mod 2). If result is None, then no such x exists. Preconditions: Matrix and vector dimensions match. Elements are 0 or 1. Dimensions are small (<= 100) to ensure tractable verification. Implementation should use standard Gaussian elimination with row operations modulo 2.

import Mathlib

-- Precondition definitions
@[reducible, simp]
def solve_linear_system_gf2_precond (matrix : List (List Nat)) (b : List Nat) : Prop :=
  -- !benchmark @start precond
  matrix.length > 0 ∧
  (matrix.getD 0 []).length > 0 ∧
  matrix.length = b.length ∧
  matrix.length ≤ 100 ∧
  (matrix.getD 0 []).length ≤ 100 ∧
  (∀ row, row ∈ matrix → (∀ x, x ∈ row → x = 0 ∨ x = 1)) ∧
  (∀ x, x ∈ b → x = 0 ∨ x = 1)
  -- !benchmark @end precond

def is_solution (matrix : List (List Nat)) (b : List Nat) (x : List Nat) : Prop :=
  x.length = (matrix.getD 0 []).length ∧
  (∀ i, i < matrix.length →
    ( (List.range x.length).foldl (fun acc j => acc + (matrix.getD i []).getD j 0 * x.getD j 0) 0 ) % 2 = b.getD i 0)

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

-- Main function definitions
def solve_linear_system_gf2 (matrix : List (List Nat)) (b : List Nat) (h_precond : solve_linear_system_gf2_precond matrix b) : Option (List Nat) :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def solve_linear_system_gf2_postcond (matrix : List (List Nat)) (b : List Nat) (result : Option (List Nat)) (h_precond : solve_linear_system_gf2_precond matrix b) : Prop :=
  -- !benchmark @start postcond
  match result with
  | some x => is_solution matrix b x
  | none => ∀ x, x.length = (matrix.getD 0 []).length → (∀ v, v ∈ x → v = 0 ∨ v = 1) → ¬ is_solution matrix b x
  -- !benchmark @end postcond

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

-- Proof content
theorem solve_linear_system_gf2_postcond_satisfied (matrix : List (List Nat)) (b : List Nat) (h_precond : solve_linear_system_gf2_precond matrix b) :
    solve_linear_system_gf2_postcond matrix b (solve_linear_system_gf2 matrix b h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement and verify the deletion algorithm for a Left-Leaning Red-Black Tree (LLRBT) in Lean. Verification Specification: (1) Preconditions: The input tree must be a valid LLRBT. (2) Postconditions: Functional Correctness (the resulting view is the original set minus the deleted value v) and Invariant Maintenance (the resulting tree satisfies is_llrbt, maintaining BST order, Black Height, and Color Properties). The deletion involves recursive descent with `move_red_left` or `move_red_right` operations and fixup on the way back up. Note: The root of the resulting subtree may be Red.

import Mathlib

inductive Color
| Red
| Black
deriving Inhabited, BEq

inductive Node
| Empty : Node
| Tree  (color : Color) (val : Int) (left : Node) (right : Node) : Node
deriving Inhabited

def view (t : Node) : Set Int :=
  match t with
  | Node.Empty => ∅
  | Node.Tree _ v l r => view l ∪ view r ∪ {v}

def is_red (t : Node) : Bool :=
  match t with
  | Node.Tree Color.Red _ _ _ => true
  | _ => false

def is_bst (t : Node) : Prop :=
  match t with
  | Node.Empty => True
  | Node.Tree _ v l r =>
    (∀ x ∈ view l, x < v) ∧
    is_bst l ∧
    (∀ x ∈ view r, x > v) ∧
    is_bst r

-- Black Height: Returns -1 if invalid
def black_height (t : Node) : Int :=
  match t with
  | Node.Empty => 1
  | Node.Tree c _ l r =>
    let lh := black_height l
    let rh := black_height r
    if lh ≠ -1 ∧ rh ≠ -1 ∧ lh = rh then
      if c == Color.Black then lh + 1 else lh
    else
      -1

def satisfies_red_props (t : Node) : Prop :=
  match t with
  | Node.Empty => True
  | Node.Tree _ _ l r =>
    satisfies_red_props l ∧
    satisfies_red_props r ∧
    -- Rule: No Right-Leaning Red
    (¬ is_red r) ∧
    -- Rule: No Double Red on Left (left child red AND left.left child red)
    (match l with
     | Node.Tree Color.Red _ ll _ => ¬ is_red ll
     | _ => True)

-- Main Invariant
def is_llrbt (t : Node) : Prop :=
  is_bst t ∧
  black_height t ≠ -1 ∧
  satisfies_red_props t

-- Precondition definitions
@[reducible, simp]
def delete_precond (t : Node) : Prop :=
  -- !benchmark @start precond
  is_llrbt t
  -- !benchmark @end precond

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

-- Main function definition
def delete (t : Node) (v : Int)
    (h_precond : delete_precond t) : Node :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def delete_postcond (t : Node) (v : Int) (result : Node)
    (_ : delete_precond t) : Prop :=
  -- !benchmark @start postcond
  is_llrbt result ∧
  view result = view t \ {v}
  -- !benchmark @end postcond

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

-- Proof content
theorem delete_postcond_satisfied (t : Node) (v : Int)
    (h_precond : delete_precond t) :
    delete_postcond t v (delete t v h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof


Your task is to implement and verify the flip_colors algorithm for a Left-Leaning Red-Black Tree (LLRBT) in Lean. Verification Specification: (1) Preconditions: The inputs (node, left child, right child) must form a valid local cluster where the node has a different color from its children, and both children have the same color. (2) Postconditions: Functional Correctness (view/set is preserved) and Invariant Maintenance (BST order is preserved using is_llrbt predicate, Black Height is preserved meaning the flip effectively pushes redness up or down without changing the black count on any path, and the colors of the node and its children are inverted: if node was Black and children Red, node becomes Red and children Black, and vice-versa).

import Mathlib

inductive Color
| Red
| Black
deriving Inhabited, BEq

inductive Node
| Empty : Node
| Tree  (color : Color) (val : Int) (left : Node) (right : Node) : Node
deriving Inhabited

def view (t : Node) : Set Int :=
  match t with
  | Node.Empty => ∅
  | Node.Tree _ v l r => view l ∪ view r ∪ {v}

def is_red (t : Node) : Bool :=
  match t with
  | Node.Tree Color.Red _ _ _ => true
  | _ => false

def get_color (t : Node) : Color :=
  match t with
  | Node.Tree c _ _ _ => c
  | Node.Empty => Color.Black -- Empty nodes are black

def is_bst (t : Node) : Prop :=
  match t with
  | Node.Empty => True
  | Node.Tree _ v l r =>
    (∀ x ∈ view l, x < v) ∧
    is_bst l ∧
    (∀ x ∈ view r, x > v) ∧
    is_bst r

-- Black Height: Returns -1 if invalid
def black_height (t : Node) : Int :=
  match t with
  | Node.Empty => 1
  | Node.Tree c _ l r =>
    let lh := black_height l
    let rh := black_height r
    if lh ≠ -1 ∧ rh ≠ -1 ∧ lh = rh then
      if c == Color.Black then lh + 1 else lh
    else
      -1

def satisfies_red_props (t : Node) : Prop :=
  match t with
  | Node.Empty => True
  | Node.Tree _ _ l r =>
    satisfies_red_props l ∧
    satisfies_red_props r ∧
    -- Rule: No Right-Leaning Red
    (¬ is_red r) ∧
    -- Rule: No Double Red on Left
    (match l with
     | Node.Tree Color.Red _ ll _ => ¬ is_red ll
     | _ => True)

-- Main Invariant
def is_llrbt (t : Node) : Prop :=
  is_bst t ∧
  black_height t ≠ -1 ∧
  satisfies_red_props t

def get_left (t : Node) : Option Node :=
  match t with | Node.Tree _ _ l _ => some l | _ => none

def get_right (t : Node) : Option Node :=
  match t with | Node.Tree _ _ _ r => some r | _ => none

def get_val (t : Node) : Option Int :=
  match t with | Node.Tree _ v _ _ => some v | _ => none

def is_not_empty (t : Node) : Prop :=
  match t with | Node.Empty => False | _ => True

-- Precondition definitions
@[reducible, simp]
def flip_colors_precond (t : Node) : Prop :=
  -- !benchmark @start precond
  -- t is not empty
  is_not_empty t ∧
  is_bst t ∧
  match t with
  | Node.Tree c _ l r =>
    is_not_empty l ∧ is_not_empty r ∧
    (get_color l = get_color r) ∧
    (c ≠ get_color l)
  | _ => False
  -- !benchmark @end precond

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

-- Main function definition
def flip_colors (t : Node)
    (h_precond : flip_colors_precond t) : Node :=
  -- !benchmark @start code
  sorry
  -- !benchmark @end code

-- Postcondition definitions
@[reducible, simp]
def flip_colors_postcond (t : Node) (result : Node)
    (_ : flip_colors_precond t) : Prop :=
  -- !benchmark @start postcond
  view result = view t ∧
  is_bst result ∧ -- Requirement 1: BST structure preserved
  black_height result = black_height t ∧ -- Requirement 2: Balance preserved (Critical)
  match result, t with
  | Node.Tree c' _ l' r', Node.Tree c _ l r =>
      c' ≠ c ∧
      get_color l' ≠ get_color l ∧
      get_color r' ≠ get_color r
  | _, _ => False
  -- !benchmark @end postcond

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

-- Proof content
theorem flip_colors_postcond_satisfied (t : Node)
    (h_precond : flip_colors_precond t) :
    flip_colors_postcond t (flip_colors t h_precond) h_precond := by
  -- !benchmark @start proof
  sorry
  -- !benchmark @end proof