Migrate breadth-first search into AlgoLib - #21
Merged
Merged
Conversation
Add a layer-by-layer BFS on SimpleDiGraph (Algorithms/Graph/Traversal/BFS) with a full correctness proof: it computes reachability and the distance, and its layers are the spheres around the source. Add the directed reachability and distance specifications (Theory/Graph/Connectivity/Directed), the symmetric orientation SimpleGraph.toSimpleDiGraph with transfer lemmas, and define SimpleGraph.dist through it. The connectivity layer's ad-hoc reachability closure is replaced: reachableFinset is now the BFS of the symmetric orientation, so the library has one search. Public API of Computable.lean is preserved; computeDist is added. Also: SimpleDiGraph counterparts in Decidable.lean (decidable adjacency, computeOutNeighborFinset), coe_computeNeighborFinset, SimpleWalk.length_glue, Traversal umbrella module, and blueprint chapters for traversal and connectivity. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
Address the repeated BFS recomputation, the Theory-to-Algorithms dependency, and the incorrect zero-layer blueprint statement.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds a verified directed BFS, graph distance specifications, and BFS-backed connectivity APIs.
Changes:
- Adds BFS layers, reachability, distance computation, and correctness proofs.
- Adds symmetric graph orientation and directed distance specifications.
- Replaces the connectivity closure with BFS and adds supporting APIs.
File summaries
| File | Summary |
|---|---|
blueprint/src/chapters/Theory/Graph/Connectivity/Basic.tex |
Documents connectivity, orientation, and distance. |
blueprint/src/chapters/Algorithms/Graph/Traversal/Basic.tex |
Documents BFS definitions and proofs. |
AlgoLib/Theory/Graph/Structures/SimpleWalk.lean |
Adds length_glue. |
AlgoLib/Theory/Graph/Decidable.lean |
Adds directed decidability and neighbor finsets. |
AlgoLib/Theory/Graph/Connectivity/Directed.lean |
Defines directed distance and orientation transfer lemmas. |
AlgoLib/Theory/Graph/Connectivity/Computable.lean |
Uses BFS for connectivity and distance. |
AlgoLib/Theory/Graph/Connectivity/Basic.lean |
Exposes the connectivity modules. |
AlgoLib/Theory/Graph/Basic.lean |
Adds symmetric graph orientation. |
AlgoLib/Theory/Graph/Adjacency.lean |
Adds orientation adjacency equivalence. |
AlgoLib/Algorithms/Graph/Traversal/BFS.lean |
Implements and proves BFS correctness. |
AlgoLib/Algorithms/Graph/Traversal/Basic.lean |
Provides the traversal umbrella module. |
AlgoLib.lean |
Imports the new modules. |
Review details
Suppressed comments (2)
AlgoLib/Theory/Graph/Connectivity/Computable.lean:8
- This import makes
Theory.Graph.Connectivity.Computabledepend onAlgorithms.Graph.Traversal.BFS; the rest of theAlgoLib/Theorytree has no Theory→Algorithms imports. That reverses the repository's established layer direction and means importing the theory umbrella now pulls an algorithm module, while future algorithm code depending on the computable connectivity API can create cycles. Please keep the BFS/specification bridge in an algorithm-independent layer or move this executable wrapper out ofTheory.
import AlgoLib.Algorithms.Graph.Traversal.BFS
blueprint/src/chapters/Algorithms/Graph/Traversal/Basic.tex:85
- This proof paragraph is false for
k = 0: with natural-number subtraction,k - 1 = 0, while the source inL₀has distance0, not a distance greater than0. Split off the zero-layer case and state the lower-bound argument only fork > 0, matching the separate zero case handled by the Lean proof.
If $v \in L_k$ then $\dist(s, v) \le k$ by soundness, and $\dist(s, v) > k - 1$
because a walk of length at most $k - 1$ would place $v$ in $V_{k-1}$, which $L_k$
avoids by construction. Conversely, if $\dist(s, v) = k$ then a shortest walk places
$v \in V_k$, so $v \in L_j$ for some $j \le k$, and the first part gives $j = k$.
- Files reviewed: 12/12 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Move the executable connectivity layer out of AlgoLib.Theory: the former Theory/Graph/Connectivity/Computable.lean is now Algorithms/Graph/Connectivity/Basic.lean, so no Theory module imports an Algorithms module. Umbrella docs, doc pointers, AlgoLib.lean and the blueprint TOC (new Connectivity section under Graph Algorithms) follow. - bfsDist no longer reruns the search per candidate index: one run collects the layers (bfsLayersFrom / bfsLayers) and bfsDist is the index of the first layer containing the vertex. Correctness restated via bfsDist_eq_coe_iff and eq_of_mem_bfsLayer; Finset.minENat no longer used. - Blueprint: the spheres proof now treats k = 0 separately, matching the Lean proof. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add a layer-by-layer BFS on SimpleDiGraph (Algorithms/Graph/Traversal/BFS) with a full correctness proof: it computes reachability and the distance, and its layers are the spheres around the source. Add the directed reachability and distance specifications (Theory/Graph/Connectivity/Directed), the symmetric orientation SimpleGraph.toSimpleDiGraph with transfer lemmas, and define SimpleGraph.dist through it.
The connectivity layer's ad-hoc reachability closure is replaced: reachableFinset is now the BFS of the symmetric orientation, so the library has one search. Public API of Computable.lean is preserved; computeDist is added.
Also: SimpleDiGraph counterparts in Decidable.lean (decidable adjacency, computeOutNeighborFinset), coe_computeNeighborFinset, SimpleWalk.length_glue, Traversal umbrella module, and blueprint chapters for traversal and connectivity.
Summary
Migrates the directed breadth-first search from the
nnhjy-backup/bfs-alg-diGraphbranch (GraphAlgorithms/.../BreadthFirstSearch.lean) intoAlgoLib, rebuilt on the currentVertexSeq/SimpleWalk/SimpleDiGraph.IsSimpleWalkInstack, and uses it as the only search in the connectivity layer.New modules
AlgoLib/Algorithms/Graph/Traversal/BFS.lean— layer-by-layer BFS onSimpleDiGraph(bfsLayer,bfsVisited,bfsReachableFinset,bfsDist) with a full correctness proof: soundness, completeness, the termination bound (at most|V(G)|non-empty layers),mem_bfsReachableFinset_iff,mem_bfsLayer_iff_dist_eq(layerkis the sphere of radiusk),bfsDist_eq_dist, andDecidable (G.Reachable u v)for digraphs. Kernel-evaluateddecidesmoke tests included.AlgoLib/Theory/Graph/Connectivity/Directed.lean— the specifications BFS is checked against:SimpleDiGraph.Reachable,SimpleDiGraph.dist(nested⨅over realized walks, same shape asgirth/κ, with the infimum API, attainment and the triangle inequality), the symmetric orientation transfer lemmas, andSimpleGraph.distdefined through the symmetric orientation (withdist_comm).Connectivity layer now uses BFS
Theory/Graph/Connectivity/Computable.lean's ad-hocreachStep/reachStartclosure is removed.reachableFinsetis now defined as the BFS ofG.toSimpleDiGraph; its public API (mem_reachableFinset_iff,coe_reachableFinset, theDecidableinstances, …) and all existingdecidetests are unchanged.computeDist/computeDist_eqadded.Supporting changes
Theory/Graph/Basic.lean:SimpleGraph.toSimpleDiGraph(symmetric orientation; deliberately not aCoe).Adjacency.lean:adj_toSimpleDiGraph_iff.Theory/Graph/Decidable.lean:SimpleDiGraphcounterparts (notation bridges,DecidableRel Adj,computeOutNeighborFinset), instances fortoSimpleDiGraph, and the old TODOcoe_computeNeighborFinsetresolved.Structures/SimpleWalk.lean:length_glue.Algorithms/Graph/Traversal/Basic.leanis now an umbrella module;AlgoLib.leanimports the new modules.\lean{}/\leanok).Design notes
|V(G)|times (Nat.iterate) rather than by well-founded recursion, so the definitions reduce anddecideworks — the same choiceComputable.leanalready made. The original termination argument survives as the theoremlt_card_of_nonempty_bfsLayer.α → ℕ∞map; the distance is read off the layers withFinset.minENat.Reachablerationale.Theory/Graph/Connectivity/Computable.leannow importsAlgorithms/Graph/Traversal/BFS.lean. No module cycle, but it is the first Theory → Algorithms edge; happy to restructure if strict layering is preferred.Verification
Full
lake buildsucceeds (3425 jobs), nosorry, no warnings in any touched file.GraphAlgorithms/is untouched.🤖 Generated with Claude Code