Problem: bipartite_check

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