Skip to content

Prim implementation - #12

Draft
chris-dem wants to merge 7 commits into
sorrachai:mainfrom
chris-dem:mst-impl
Draft

Prim implementation#12
chris-dem wants to merge 7 commits into
sorrachai:mainfrom
chris-dem:mst-impl

Conversation

@chris-dem

Copy link
Copy Markdown

I am working on the prim algorithm and I wanted to make this PR for it. There is still a lot of cleanup to be done but I wanted to add this in case for early feedback

@BasilRohner BasilRohner self-assigned this Jun 12, 2026
@BasilRohner

BasilRohner commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

This is looking nice so far!

A couple of suggestions for once it's had a polishing pass:

  • It might be cleaner to split the changes into separate PRs per module, one each for basic definitions, Kruskal, Prim ect. That makes the PR easier to review once it's ready.
  • I'd also like to move away from the SimpleGraph definition in GraphAlgorithms/SimpleGraph.lean in favour of the SimpleGraph in GraphAlgorithms/Graph/Basic.lean. I'd be glad to help with the migration if that is wanted.
  • Is there a benefit of defining WeightedSimpleGraph if you can provide a SimpleGraph and a weight function separately? This might make it a bit more flexible.

@chris-dem

chris-dem commented Jun 13, 2026

Copy link
Copy Markdown
Author

Thank you for the feedback.

  1. Yeah I can definitely do that.
  2. Should I set my upstream then to the Basil branch? I can't seem to find the Graph/Basic.lean in main
  3. Yeah I can rewrite that with a simple pair as you suggested.

I also wanted to ask if the ParentTree definition is sensible? The main idea is that I want to have a tree where adding edges can be done easily as seen in the following definition:

structure ParentTree (α : Type*) where
  vertexSet : Finset α
  parent : α -> α
  level : α -> ℕ
  incidence : ∀ v ∈ vertexSet, parent v ∈ vertexSet
  ordering : ∀ v ∈ vertexSet, level v > 0 → level (parent v) < level v
  root : ∀  v ∈ vertexSet, level v = 0 ↔ v = parent v

abbrev appendNodes (G : ParentTree α) (new_nodes : Finset α)
  (edges : α → α) (h : ∀ v ∈ new_nodes, edges v ∈ Vₚ(G)) : ParentTree α :=
    {
      vertexSet := G.vertexSet ∪ new_nodes,
      parent :=  fun v => if v ∈ G.vertexSet then G.parent v else edges v,
      level :=  fun v => if v ∈ G.vertexSet then G.level v else (G.level (edges v) + 1),
      incidence := by have := G.incidence; grind,
      root := by have := G.root; grind,
      ordering := by  have := G.ordering; have := G.incidence; grind
    }

I'm finishing the details on the acyclicity proof of it. Should I make a separate PR for that definition alone?

@BasilRohner

Copy link
Copy Markdown
Collaborator

For 2) the graph definitions are already on the main branch here: GraphLib/Graph/Basic.lean.

Your definition of ParentTree looks sensible. A few comments:

  • If you switch to the new graph definitions the vertices are captured by vertexSet : Set α so you might want to restrict your functions on that (by forcing your function to be the identity outside or something).
  • You can maybe generalize to a structure SpanningForest, I hope to add subgraph relations soon and someone else is working on trees and forests.
  • A PR for this separately might be nice

open Finset WeightedSimpleGraph Sym2

def is_connected (G : WeightedSimpleGraph α) : Prop :=
∀ u v: α , u ≠ v → ∃ p: Walk α, Path.IsPathIn G p

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a typo here?
Should have p.head = u && p.tail =v

level : α -> ℕ
incidence : ∀ v ∈ vertexSet, parent v ∈ vertexSet
ordering : ∀ v ∈ vertexSet, level v > 0 → level (parent v) < level v
root : ∀ v ∈ vertexSet, level v = 0 ↔ v = parent v

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ParentTree definition does not require connectedness. It can have many isolated roots. Not sure whether it's deliberate.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could add a Prop of the kind that there exists a unique vertex with that property or maybe have it as a theorem. My original idea was to have a theorem of the sort, if the prim is calculated on a connected graph, then the ParentTree that spans it would also be connected. If you prefer to include it in the definition I can change it.

grind

@[grind →] lemma edge_antisymm_iff (G : ParentTree α) (u v : α) (hu : u ∈ Vₚ(G)) (hv :v ∈ Vₚ(G)):
u ∈ Nₚ(G, v) ↔ u ∈ Nₚ(G, v) := by

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll push a change with the fixed typo. I am finishing now the proof that the tree is acyclic and the fact that each iteration of the prim, adds an edge on the spanning tree

if h : crossing.Nonempty then
let chosen :=
disjointEdges <|
minimumWeightEdges G crossing h

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this step, do you want to select more than one edges with min weight? I think it might be simpler to select one arbitrary edge with min weight in each iteration.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think choosing multiple edges might even be wrong. Will modify it!

(edges : Finset (Edge α)) (acc : Finset (Edge α)) :
Finset (Edge α) :=
if h: edges.Nonempty then
let x := h.choose

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If x is arbitrary in h, we may terminate with selecting only one edge even if h is large.

@chris-dem
chris-dem marked this pull request as draft June 15, 2026 11:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants