-
Notifications
You must be signed in to change notification settings - Fork 184
feat: graph definitions (#Attempts 3) #810
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sorrachai
wants to merge
37
commits into
leanprover:main
Choose a base branch
from
sorrachai:graph_def
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+161
−0
Open
Changes from all commits
Commits
Show all changes
37 commits
Select commit
Hold shift + click to select a range
8ae7095
basic graph PR
sorrachai 05ded56
update
sorrachai edd657d
update
sorrachai 8f690dd
update
sorrachai c2a452c
up
sorrachai e5d1be2
typo
sorrachai 794208f
update
sorrachai a807a8a
clean
sorrachai 64e7750
update
sorrachai 4e39303
minor
sorrachai a7a5c33
minor
sorrachai fc57b05
minor
sorrachai bb36d72
minor
sorrachai 61fc076
minor
sorrachai 6da55e5
revise
sorrachai 1ea0bbb
update
sorrachai 55984df
update
sorrachai aeaa186
update
sorrachai 7dde507
update
sorrachai de3f7ba
fix_ci
sorrachai e4a102f
Merge branch 'main' into graph_def
sorrachai 8fcdb1d
docstring
sorrachai fe8b5da
typeclass HasEndpoints
sorrachai cf9c263
Update to reflect comments
sorrachai 7ad8448
Update Cslib/Algorithms/Lean/Graph/Basic.lean
sorrachai 11d9fd5
Update Cslib/Algorithms/Lean/Graph/Basic.lean
sorrachai 75b99fc
Update Cslib/Algorithms/Lean/Graph/Basic.lean
sorrachai 2a6097f
Update Cslib/Algorithms/Lean/Graph/Basic.lean
sorrachai 68df648
Update Cslib/Algorithms/Lean/Graph/Basic.lean
sorrachai 357b021
Update Cslib/Algorithms/Lean/Graph/Basic.lean
sorrachai 59f9446
update to reflect comments
sorrachai fc3ad94
add partial function
sorrachai e5fb456
replace arc with edge
sorrachai 0500dd4
Change Graph to MultiGraph
sorrachai ee137b4
Remove redundant fields of MultiDiGraph
sorrachai e00fd44
minor
sorrachai f938381
isLink_imp_left_mem_vertexSet
sorrachai File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,160 @@ | ||
| /- | ||
| Copyright (c) 2026 Basil Rohner. All rights reserved. | ||
| Released under Apache 2.0 license as described in the file LICENSE. | ||
| Authors: Basil Rohner, Sorrachai Yingchareonthawornchai | ||
| -/ | ||
|
|
||
| module | ||
|
|
||
| public import Cslib.Foundations.Semantics.LTS.Basic | ||
| public import Mathlib.Combinatorics.Digraph.Basic | ||
| public import Mathlib.Combinatorics.Graph.Basic | ||
| public import Mathlib.Combinatorics.SimpleGraph.Basic | ||
| public import Mathlib.Data.PFun | ||
|
|
||
|
|
||
| /-! | ||
| # Graph structures | ||
|
|
||
| Vertex and edge sets are `Set`-valued, following the design of | ||
| `Mathlib.Combinatorics.Graph`: a subgraph of `G : Graph V E` is another term of | ||
| `Graph V E` rather than a separate type, so no coercion maps are needed. | ||
|
|
||
| Four structures are provided, in two pairs. `MultiGraph` and `MultiDigraph` are multigraphs whose | ||
| edges carry labels in `E`, so parallel edges and loops are permitted. `SimpleGraph` and | ||
| `SimpleDigraph` have `Prop`-valued adjacency and therefore disallowing parallel edges. | ||
|
|
||
| ## Main definitions | ||
|
|
||
| We use the following definition of a multigraph. | ||
| A multigraph is a triple (V,E,f) where V is a vertex set, E is an edge set, | ||
| and f is a function from an edge to an (ordered/unordered) pair of vertices. | ||
| In particular, f is a computable function. We reuse the definitions from Mathlib as much as we can. | ||
|
|
||
| * `MultiGraph V E`: an undirected multigraph (abbrev for Mathlib's `Graph V E`). | ||
| * `MultiDigraph V E`: a directed multigraph; the directed counterpart of Mathlib's `Graph V E`. | ||
| * `SimpleGraph V`: a simple graph with a vertex set, extending Mathlib's `SimpleGraph V`. | ||
| * `SimpleDigraph V`: a loopless directed graph with adjacency `Adj : V → V → Prop` and a | ||
| vertex set, extending Mathlib's `Digraph V`. | ||
|
|
||
| ## Main API | ||
|
|
||
| * `MultiGraph.endpoints`, `MultiDigraph.endpoints`: the ends of an edge. | ||
| * `SimpleDigraph.edgeSet`: the edge set of a `SimpleDigraph`, derived from its adjacency | ||
| relation. The corresponding `SimpleGraph.edgeSet` is inherited from Mathlib rather than | ||
| redefined here. | ||
|
|
||
| ## Implementation notes | ||
|
|
||
| `IsLink` are `Prop`-valued, so nothing about them is executable. To recover | ||
| computation, `MultiGraph` and `Digraph` each carry an `endpoints : E →. _` field together | ||
| with `endpoints_spec`. That specification pins the value of `endpoints` at *every* label — | ||
| `some` on the edge set, and `none` otherwise. | ||
|
|
||
| -/ | ||
|
|
||
| @[expose] public section | ||
|
|
||
| namespace Cslib.Algorithms.Lean | ||
|
|
||
| /-- An undirected multigraph on vertex type `V` with edge labels in `E`. | ||
|
|
||
| This is Mathlib's `Graph V E` — so parallel edges and loops are permitted, and both the | ||
| vertex and edge sets may be infinite. -/ | ||
| abbrev MultiGraph (V E : Type*) := _root_.Graph V E | ||
|
|
||
| /-- A map from an edge label of `G` to its ends. -/ | ||
| class MultiGraph.HasEndpoints {V E : Type*} (G : MultiGraph V E) where | ||
| /-- The ends of the edge labelled `e`, or `none` if `e` is not an edge of `G`. -/ | ||
| endpoints : E →. (Sym2 V) | ||
| /-- `endpoints` computes `Graph.IsLink`. -/ | ||
| endpoints_spec : ∀ e x y, G.IsLink e x y ↔ s(x, y) ∈ endpoints e | ||
|
|
||
| /-- The ends of `e` in `G`; undefined when `e ∉ E(G)`. -/ | ||
| def MultiGraph.endpoints (G : MultiGraph V E) [inst : G.HasEndpoints] : E →. Sym2 V := | ||
| inst.endpoints | ||
|
|
||
| theorem isLink_iff_endpoints (G : MultiGraph V E) [G.HasEndpoints] : | ||
| G.IsLink e x y ↔ s(x, y) ∈ G.endpoints e := | ||
| MultiGraph.HasEndpoints.endpoints_spec e x y | ||
|
|
||
| /-- A directed multigraph on vertex type `V` with edge labels in `E`, given by a partial | ||
| function from an edge label to its ends. -/ | ||
| structure MultiDigraph (V E : Type*) where | ||
| /-- The set of vertices. -/ | ||
| vertexSet : Set V | ||
| /-- The ends of the edge labelled `e`; undefined when `e` is not an edge of `G`. -/ | ||
| endpoints : E →. (V × V) | ||
| /-- The tail of every edge is a vertex. -/ | ||
| left_endpoint_mem_vertexSet ⦃e x y⦄ : (x, y) ∈ endpoints e → x ∈ vertexSet := by grind | ||
| /-- The head of every edge is a vertex. -/ | ||
| right_endpoint_mem_vertexSet ⦃e x y⦄ : (x, y) ∈ endpoints e → y ∈ vertexSet := by grind | ||
|
|
||
| namespace MultiDigraph | ||
| variable {V E : Type*} {G : MultiDigraph V E} {e : E} {x y x' y' : V} | ||
|
|
||
| /-- The set of edge labels. -/ | ||
| def edgeSet (G : MultiDigraph V E) : Set E := G.endpoints.Dom | ||
|
|
||
| /-- `IsLink e x y` states that the edge labelled `e` runs from `x` to `y`. -/ | ||
| def IsLink (G : MultiDigraph V E) (e : E) (x y : V) : Prop := (x, y) ∈ G.endpoints e | ||
|
|
||
| @[simp] lemma isLink_iff : G.IsLink e x y ↔ (x, y) ∈ G.endpoints e := Iff.rfl | ||
| @[simp] lemma mem_edgeSet_iff : e ∈ G.edgeSet ↔ (G.endpoints e).Dom := Iff.rfl | ||
|
|
||
| lemma mem_edgeSet_iff_exists_isLink : e ∈ G.edgeSet ↔ ∃ x y, G.IsLink e x y := by | ||
| rw [mem_edgeSet_iff, Part.dom_iff_mem] | ||
| exact ⟨fun ⟨p, hp⟩ => ⟨p.1, p.2, hp⟩, fun ⟨_, _, h⟩ => ⟨_, h⟩⟩ | ||
|
|
||
| lemma IsLink.mem_edgeSet (h : G.IsLink e x y) : e ∈ G.edgeSet := | ||
| mem_edgeSet_iff_exists_isLink.2 ⟨x, y, h⟩ | ||
|
|
||
| /-- An edge is incident with at most one ordered pair of vertices. -/ | ||
| lemma eq_and_eq_of_isLink_of_isLink (h : G.IsLink e x y) (h' : G.IsLink e x' y') : | ||
| x = x' ∧ y = y' := | ||
| have hp : (x, y) = (x', y') := Part.mem_unique h h' | ||
| ⟨congrArg Prod.fst hp, congrArg Prod.snd hp⟩ | ||
|
|
||
| lemma isLink_imp_left_mem_vertexSet : ∀ ⦃e x y⦄, G.IsLink e x y → x ∈ G.vertexSet := | ||
| fun _ _ _ a => G.left_endpoint_mem_vertexSet a | ||
| lemma isLink_imp_right_mem_vertexSet : ∀ ⦃e x y⦄, G.IsLink e x y → y ∈ G.vertexSet := | ||
| fun _ _ _ a => G.right_endpoint_mem_vertexSet a | ||
|
|
||
| end MultiDigraph | ||
|
|
||
|
|
||
| /-- A simple graph on `V` — irreflexive and symmetric adjacency, hence no loops and no | ||
| parallel edges — together with a vertex set containing every end of an adjacent pair. | ||
|
|
||
| Extends Mathlib's `SimpleGraph V`, so its API is available through `toSimpleGraph`; in | ||
| particular `edgeSet`, the unordered pairs of adjacent vertices, is inherited rather than | ||
| redefined. -/ | ||
| structure SimpleGraph (V : Type*) extends _root_.SimpleGraph V where | ||
| /-- The set of vertices. -/ | ||
| vertexSet : Set V | ||
| /-- The left end of every adjacent pair is a vertex. The right end then follows by | ||
| symmetry of `Adj`. -/ | ||
| adj_imp_left_mem_vertexSet : ∀ ⦃x y⦄, Adj x y → x ∈ vertexSet := by grind | ||
|
|
||
| /-- A simple directed graph on `V` — adjacency `Adj : V → V → Prop`, hence no parallel | ||
| edges — with loops explicitly excluded, together with a vertex set containing every end of | ||
| an adjacent pair. | ||
|
|
||
| Extends Mathlib's `Digraph V`, which is a bare adjacency relation and does permit loops; | ||
| `loopless` is what rules them out here. -/ | ||
| structure SimpleDigraph (V : Type*) extends _root_.Digraph V where | ||
| /-- The set of vertices. -/ | ||
| vertexSet : Set V | ||
| /-- No vertex is adjacent to itself. -/ | ||
| irrefl_adj : Std.Irrefl Adj | ||
| /-- Both ends of every adjacent pair are vertices. Unlike `SimpleGraph`, `Adj` is not | ||
| symmetric, so neither direction follows from the other. -/ | ||
| adj_imp_left_mem_vertexSet : ∀ ⦃x y⦄, Adj x y → x ∈ vertexSet := by grind | ||
| adj_imp_right_mem_vertexSet : ∀ ⦃x y⦄, Adj x y → y ∈ vertexSet := by grind | ||
|
|
||
| /-- The edge set of a `SimpleDigraph`, as ordered pairs of adjacent vertices. -/ | ||
| def SimpleDigraph.edgeSet (G : SimpleDigraph V) : Set (V × V) := | ||
| {p | G.Adj p.1 p.2} | ||
|
|
||
|
|
||
| end Cslib.Algorithms.Lean | ||
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if it is possible to define
MultiGraph.endpointsdirectly. Unfortunately, all definitions I can think of usesClassical.choosesomewhere and hence must be marked asnoncomputable. But if we accept that, then we can get rid of the assumption[G.HasEndpoints], which currently needs to be assumed wheneverMultiGraph.endpointsis used. Perhaps that can be considered an improvement and a small price to pay for using mathlib'sGraph.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatively, one could extend Mathlib's Graph with field endpoints and endpoints_spec, but this seems redundant, since it subsumes IsLink. I am happy with the current price to pay if we cannot define MultiGraph ourselves.