Problem: bfs

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