Graph connectivity #
THIS FILE IS SYNCHRONIZED WITH MATHLIB4. Any changes to this file require a corresponding PR to mathlib4.
In a simple graph,
-
A walk is a finite sequence of adjacent vertices, and can be thought of equally well as a sequence of directed edges.
-
A trail is a walk whose edges each appear no more than once.
-
A path is a trail whose vertices appear no more than once.
-
A cycle is a nonempty trail whose first and last vertices are the same and whose vertices except for the first appear no more than once.
Warning: graph theorists mean something different by "path" than do homotopy theorists. A "walk" in graph theory is a "path" in homotopy theory. Another warning: some graph theorists use "path" and "simple path" for "walk" and "path."
Some definitions and theorems have inspiration from multigraph counterparts in [Cho94].
Main definitions #
-
simple_graph.walk
(with accompanying pattern definitionssimple_graph.walk.nil'
andsimple_graph.walk.cons'
) -
simple_graph.walk.is_trail
,simple_graph.walk.is_path
, andsimple_graph.walk.is_cycle
. -
simple_graph.walk.map
andsimple_graph.path.map
for the induced map on walks, given an (injective) graph homomorphism. -
simple_graph.reachable
for the relation of whether there exists a walk between a given pair of vertices -
simple_graph.preconnected
andsimple_graph.connected
are predicates on simple graphs for whether every vertex can be reached from every other, and in the latter case, whether the vertex type is nonempty. -
simple_graph.subgraph.connected
gives subgraphs the connectivity predicate viasimple_graph.subgraph.coe
. -
simple_graph.connected_component
is the type of connected components of a given graph. -
simple_graph.is_bridge
for whether an edge is a bridge edge
Main statements #
simple_graph.is_bridge_iff_mem_and_forall_cycle_not_mem
characterizes bridge edges in terms of there being no cycle containing them.
Tags #
walks, trails, paths, circuits, cycles, bridge edges
- nil : Π {V : Type u} {G : simple_graph V} {u : V}, G.walk u u
- cons : Π {V : Type u} {G : simple_graph V} {u v w : V}, G.adj u v → G.walk v w → G.walk u w
A walk is a sequence of adjacent vertices. For vertices u v : V
,
the type walk u v
consists of all walks starting at u
and ending at v
.
We say that a walk visits the vertices it contains. The set of vertices a
walk visits is simple_graph.walk.support
.
See simple_graph.walk.nil'
and simple_graph.walk.cons'
for patterns that
can be useful in definitions since they make the vertices explicit.
Instances for simple_graph.walk
- simple_graph.walk.has_sizeof_inst
- simple_graph.walk.inhabited
Equations
The one-edge walk associated to a pair of adjacent vertices.
Equations
Pattern to get walk.nil
with the vertex as an explicit argument.
Pattern to get walk.cons
with the vertices as explicit arguments.
Change the endpoints of a walk using equalities. This is helpful for relaxing
definitional equality constraints and to be able to state otherwise difficult-to-state
lemmas. While this is a simple wrapper around eq.rec
, it gives a canonical way to write it.
The simp-normal form is for the copy
to be pushed outward. That way calculations can
occur within the "copy context."
The length of a walk is the number of edges/darts along it.
Equations
- (simple_graph.walk.cons _x_2 q).length = q.length.succ
- simple_graph.walk.nil.length = 0
The concatenation of two compatible walks.
Equations
- (simple_graph.walk.cons h p).append q = simple_graph.walk.cons h (p.append q)
- simple_graph.walk.nil.append q = q
The reversed version of simple_graph.walk.cons
, concatenating an edge to
the end of a walk.
Equations
- p.concat h = p.append (simple_graph.walk.cons h simple_graph.walk.nil)
The concatenation of the reverse of the first walk with the second walk.
Equations
- (simple_graph.walk.cons h p).reverse_aux q = p.reverse_aux (simple_graph.walk.cons _ q)
- simple_graph.walk.nil.reverse_aux q = q
The walk in reverse.
Equations
Get the n
th vertex from a walk, where n
is generally expected to be
between 0
and p.length
, inclusive.
If n
is greater than or equal to p.length
, the result is the path's endpoint.
Equations
- (simple_graph.walk.cons _x q).get_vert (n + 1) = q.get_vert n
- (simple_graph.walk.cons _x _x_1).get_vert 0 = u
- simple_graph.walk.nil.get_vert _x = u
A non-trivial cons
walk is representable as a concat
walk.
A non-trivial concat
walk is representable as a cons
walk.
Auxiliary definition for simple_graph.walk.concat_rec
Equations
- simple_graph.walk.concat_rec_aux Hnil Hconcat (simple_graph.walk.cons h p) = eq.rec (Hconcat p.reverse _ (simple_graph.walk.concat_rec_aux Hnil Hconcat p)) _
- simple_graph.walk.concat_rec_aux Hnil Hconcat simple_graph.walk.nil = Hnil
Recursor on walks by inducting on simple_graph.walk.concat
.
This is inducting from the opposite end of the walk compared
to simple_graph.walk.rec
, which inducts on simple_graph.walk.cons
.
Equations
- simple_graph.walk.concat_rec Hnil Hconcat p = eq.rec (simple_graph.walk.concat_rec_aux Hnil Hconcat p.reverse) _
The support
of a walk is the list of vertices it visits in order.
Equations
- (simple_graph.walk.cons h p).support = u :: p.support
- simple_graph.walk.nil.support = [u]
The darts
of a walk is the list of darts it visits in order.
The edges
of a walk is the list of edges it visits in order.
This is defined to be the list of edges underlying simple_graph.walk.darts
.
Equations
Every edge in a walk's edge list is an edge of the graph.
It is written in this form (rather than using ⊆
) to avoid unsightly coercions.
Trails, paths, circuits, cycles #
A trail is a walk with no repeating edges.
A path is a walk with no repeating vertices.
Use simple_graph.walk.is_path.mk'
for a simpler constructor.
Instances for simple_graph.walk.is_path
- to_trail : p.is_trail
- ne_nil : p ≠ simple_graph.walk.nil
A circuit at u : V
is a nonempty trail beginning and ending at u
.
- to_circuit : p.is_circuit
- support_nodup : p.support.tail.nodup
A cycle at u : V
is a circuit at u
whose only repeating vertex
is u
(which appears exactly twice).
About paths #
Equations
Walk decompositions #
Given a vertex in the support of a path, give the path up until (and including) that vertex.
Equations
- (simple_graph.walk.cons r p).take_until u h = dite (v = u) (λ (hx : v = u), eq.rec (λ (h : v ∈ (simple_graph.walk.cons r p).support), simple_graph.walk.nil) hx h) (λ (hx : ¬v = u), simple_graph.walk.cons r (p.take_until u _))
- simple_graph.walk.nil.take_until u h = _.mpr simple_graph.walk.nil
Given a vertex in the support of a path, give the path from (and including) that vertex to the end. In other words, drop vertices from the front of a path until (and not including) that vertex.
Equations
- (simple_graph.walk.cons r p).drop_until u h = dite (v = u) (λ (hx : v = u), eq.rec (λ (h : v ∈ (simple_graph.walk.cons r p).support), simple_graph.walk.cons r p) hx h) (λ (hx : ¬v = u), p.drop_until u _)
- simple_graph.walk.nil.drop_until u h = _.mpr simple_graph.walk.nil
The take_until
and drop_until
functions split a walk into two pieces.
The lemma count_support_take_until_eq_one
specifies where this split occurs.
Rotate a loop walk such that it is centered at the given vertex.
Equations
- c.rotate h = (c.drop_until u h).append (c.take_until u h)
Given a set S
and a walk w
from u
to v
such that u ∈ S
but v ∉ S
,
there exists a dart in the walk whose start is in S
but whose end is not.
Type of paths #
The type for paths between two vertices.
The length-0 path at a vertex.
Equations
The length-1 path between a pair of adjacent vertices.
Equations
The reverse of a path is another path. See also simple_graph.walk.reverse
.
Walks to paths #
Given a walk, produces a walk from it by bypassing subwalks between repeated vertices.
The result is a path, as shown in simple_graph.walk.bypass_is_path
.
This is packaged up in simple_graph.walk.to_path
.
Equations
- (simple_graph.walk.cons ha p).bypass = let p' : G.walk a_47 v := p.bypass in dite (u ∈ p'.support) (λ (hs : u ∈ p'.support), p'.drop_until u hs) (λ (hs : u ∉ p'.support), simple_graph.walk.cons ha p')
- simple_graph.walk.nil.bypass = simple_graph.walk.nil
Given a walk, produces a path with the same endpoints using simple_graph.walk.bypass
.
Mapping paths #
Given a graph homomorphism, map walks to walks.
Unlike categories, for graphs vertex equality is an important notion, so needing to be able to to work with equality of graph homomorphisms is a necessary evil.
Alias of the reverse direction of simple_graph.walk.map_is_trail_iff_of_injective
.
Alias of the reverse direction of simple_graph.walk.map_is_cycle_iff_of_injective
.
The specialization of simple_graph.walk.map
for mapping walks to supergraphs.
Equations
Alias of the reverse direction of simple_graph.walk.map_le_is_trail
.
Alias of the forward direction of simple_graph.walk.map_le_is_trail
.
Alias of the forward direction of simple_graph.walk.map_le_is_path
.
Alias of the reverse direction of simple_graph.walk.map_le_is_path
.
Alias of the forward direction of simple_graph.walk.map_le_is_cycle
.
Alias of the reverse direction of simple_graph.walk.map_le_is_cycle
.
Given an injective graph homomorphism, map paths to paths.
Equations
- simple_graph.path.map f hinj p = ⟨simple_graph.walk.map f ↑p, _⟩
Given a graph embedding, map paths to paths.
Equations
Transferring between graphs #
The walk p
transferred to lie in H
, given that H
contains its edges.
Equations
- (simple_graph.walk.cons' u v w a p).transfer H h = simple_graph.walk.cons _ (p.transfer H _)
- simple_graph.walk.nil.transfer H h = simple_graph.walk.nil
Deleting edges #
Given a walk that avoids a set of edges, produce a walk in the graph with those edges deleted.
Equations
- simple_graph.walk.to_delete_edges s p hp = p.transfer (G.delete_edges s) _
Given a walk that avoids an edge, create a walk in the subgraph with that edge deleted.
This is an abbreviation for simple_graph.walk.to_delete_edges
.
reachable
and connected
#
Two vertices are reachable if there is a walk between them.
This is equivalent to relation.refl_trans_gen
of G.adj
.
See simple_graph.reachable_iff_refl_trans_gen
.
Instances for simple_graph.reachable
The equivalence relation on vertices given by simple_graph.reachable
.
A graph is preconnected if every pair of vertices is reachable from one another.
Equations
- G.preconnected = ∀ (u v : V), G.reachable u v
Instances for simple_graph.preconnected
- preconnected : G.preconnected
- nonempty : nonempty V
A graph is connected if it's preconnected and contains at least one vertex. This follows the convention observed by mathlib that something is connected iff it has exactly one connected component.
There is a has_coe_to_fun
instance so that h u v
can be used instead
of h.preconnected u v
.
Instances for simple_graph.connected
Equations
The quotient of V
by the simple_graph.reachable
relation gives the connected
components of a graph.
Equations
- G.connected_component = quot G.reachable
Instances for simple_graph.connected_component
Gives the connected component containing a particular vertex.
Equations
- G.connected_component_mk v = quot.mk G.reachable v
The connected_component
specialization of quot.lift
. Provides the stronger
assumption that the vertices are connected by a path.
Equations
- simple_graph.connected_component.lift f h = quot.lift f _
The map on connected components induced by a graph homomorphism.
Equations
- simple_graph.connected_component.map φ C = simple_graph.connected_component.lift (λ (v : V), G'.connected_component_mk (⇑φ v)) _ C
An isomorphism of graphs induces a bijection of connected components.
Equations
- φ.connected_component_equiv = {to_fun := simple_graph.connected_component.map ↑φ, inv_fun := simple_graph.connected_component.map ↑(φ.symm), left_inv := _, right_inv := _}
The set of vertices in a connected component of a graph.
Equations
- C.supp = {v : V | G.connected_component_mk v = C}
Equations
The equivalence between connected components, induced by an isomorphism of graphs, itself defines an equivalence on the supports of each connected component.
A subgraph is connected if it is connected as a simple graph.
Walks as subgraphs #
The subgraph consisting of the vertices and edges of the walk.
Equations
Walks of a given length #
The finset
of length-n
walks from u
to v
.
This is used to give {p : G.walk u v | p.length = n}
a fintype
instance, and it
can also be useful as a recursive description of this set when V
is finite.
See simple_graph.coe_finset_walk_length_eq
for the relationship between this finset
and
the set of length-n
walks.
Equations
- G.finset_walk_length (n + 1) u v = finset.univ.bUnion (λ (w : ↥(G.neighbor_set u)), finset.map {to_fun := λ (p : G.walk ↑w v), simple_graph.walk.cons _ p, inj' := _} (G.finset_walk_length n ↑w v))
- G.finset_walk_length 0 u v = dite (u = v) (λ (h : u = v), eq.rec {simple_graph.walk.nil} _) (λ (h : ¬u = v), ∅)
Equations
- G.fintype_set_walk_length u v n = fintype.of_finset (G.finset_walk_length n u v) _
Equations
- G.fintype_set_path_length u v n = fintype.of_finset (finset.filter simple_graph.walk.is_path (G.finset_walk_length n u v)) _
Equations
- simple_graph.reachable.decidable_rel G = λ (u v : V), decidable_of_iff' (∃ (n : fin (fintype.card V)), (G.finset_walk_length ↑n u v).nonempty) _
Equations
Bridge edges #
An edge of a graph is a bridge if, after removing it, its incident vertices are no longer reachable from one another.