Zulip Chat Archive
Stream: new members
Topic: Graphs in Lean
Simon Daniel (Feb 28 2024 at 14:29):
Hello,
I want to model a network by a set of Nodes (String) and Edges between Nodes (a Subset of cartesian product of Nodes).
i tried
structure Network where
nodes: List String
edges: List (String × String)
p: ∀ (l1 l2: String), edges.contains (l1, l2) -> (nodes.product nodes).contains (l1, l2)
def testNet: Network := Network.mk ["hello", "alice"] [("alice", "hello")] (by sorry)
but somehow i feel like there should be a nicer approach. Is using lists and ignoring duplicates even the way to go?
Timo Carlin-Burns (Feb 28 2024 at 15:38):
Are you looking to write efficient algorithms with this data structure? The problem of data structures to represent networks (AKA graphs) is a well-studied one in computer science
Simon Daniel (Feb 28 2024 at 16:13):
im effectively trying to write a directed graph where my nodes are a finite subset of String. Efficent algorithms are none of my concerns, i need to find (optional) paths from a to b and connected subgraphs.
But the Lean std does not provide a datatype for sets right? i only found https://leanprover-community.github.io/mathlib4_docs/Lean/Data/SSet.html which seems to be for a different purpose. Should i look into Set or FinSet of Mathlib?
or something like this with subtypes
def string_subtype := {s:String // ["alice", "bob", "eve"].contains s}
def node: string_subtype := ⟨"alice", by decide⟩
Timo Carlin-Burns (Feb 28 2024 at 16:26):
Mathlib has docs#SimpleGraph for an undirected graph
Timo Carlin-Burns (Feb 28 2024 at 16:27):
It represents edges with a predicate
Timo Carlin-Burns (Feb 28 2024 at 16:27):
You can also represent edges with a docs#Set
Timo Carlin-Burns (Feb 28 2024 at 16:29):
But predicates and Set
s are computationally useless, so if you want to write an algorithm to find a path, you will need something else. If you just want to proof that some sequence of nodes is a path, then these approaches will work fine
Simon Daniel (Feb 28 2024 at 16:57):
could you elaborate why its useless? i guess because both represent possibly infinite Sets?
Im more used to Sets from other Programming languages that are a (finite) collection of unique items instead of a predicate on a type
Matthew Ballard (Feb 28 2024 at 17:04):
Predicates do not generate executable code by default
Kyle Miller (Feb 28 2024 at 21:01):
There are some computations done on SimpleGraph, but the way these work is that they make use of the Fintype and Decidable typeclasses to register computations for particular SimpleGraphs.
DecidableRel G.Adj
withFintype V
is essentially an adjacency matrix representationFintype (G.neighborSet v)
for allv
gives you an adjacency list representation
In the Connectivity module, there are for example algorithms to compute whether a graph is connected. Horrible algorithms that you never want to evaluate, but they're technically still algorithms.
You may say you're not interested in efficient algorithms, but if you want to compute anything at all, I think you'll say you want an efficient algorithm (there's a difference between efficient and optimal after all).
Kyle Miller (Feb 28 2024 at 21:05):
Using Set
in the definition of SimpleGraph is making SimpleGraph be a sort of abstract definition of a graph, with no concrete data structure, but every data structure for a simple graph can be converted to a SimpleGraph, and they can provide classes for various computations. In Mathlib, we don't have any concrete data structures for graphs.
There's an example data structure in the Königsberg bridge problem in the Archive here, where the graph is created from a list of adjacent vertex pairs.
Simon Daniel (Feb 29 2024 at 10:34):
thanks for the explanation, the example has been useful
Last updated: May 02 2025 at 03:31 UTC