mathlib documentation

combinatorics.simple_graph.connectivity

Graph connectivity #

In a simple graph,

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 #

Tags #

walks, trails, paths, circuits, cycles

inductive simple_graph.walk {V : Type u} (G : simple_graph V) :
V → V → Type u

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
@[protected, instance]
def simple_graph.walk.decidable_eq {V : Type u} [a : decidable_eq V] (G : simple_graph V) (ᾰ ᾰ_1 : V) :
decidable_eq (G.walk ᾰ_1)
@[protected, instance]
def simple_graph.walk.inhabited {V : Type u} (G : simple_graph V) (v : V) :
inhabited (G.walk v v)
Equations
@[reducible]
def simple_graph.walk.nil' {V : Type u} {G : simple_graph V} (u : V) :
G.walk u u

Pattern to get walk.nil with the vertex as an explicit argument.

@[reducible]
def simple_graph.walk.cons' {V : Type u} {G : simple_graph V} (u v w : V) (h : G.adj u v) (p : G.walk v w) :
G.walk u w

Pattern to get walk.cons with the vertices as explicit arguments.

@[protected]
def simple_graph.walk.copy {V : Type u} {G : simple_graph V} {u v u' v' : V} (p : G.walk u v) (hu : u = u') (hv : v = v') :
G.walk u' v'

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."

Equations
  • p.copy hu hv = eq.rec (eq.rec p hv) hu
@[simp]
theorem simple_graph.walk.copy_rfl_rfl {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
@[simp]
theorem simple_graph.walk.copy_copy {V : Type u} {G : simple_graph V} {u v u' v' u'' v'' : V} (p : G.walk u v) (hu : u = u') (hv : v = v') (hu' : u' = u'') (hv' : v' = v'') :
(p.copy hu hv).copy hu' hv' = p.copy _ _
@[simp]
theorem simple_graph.walk.copy_nil {V : Type u} {G : simple_graph V} {u u' : V} (hu : u = u') :
theorem simple_graph.walk.copy_cons {V : Type u} {G : simple_graph V} {u v w u' w' : V} (h : G.adj u v) (p : G.walk v w) (hu : u = u') (hw : w = w') :
@[simp]
theorem simple_graph.walk.cons_copy {V : Type u} {G : simple_graph V} {u v w v' w' : V} (h : G.adj u v) (p : G.walk v' w') (hv : v' = v) (hw : w' = w) :
theorem simple_graph.walk.exists_eq_cons_of_ne {V : Type u} {G : simple_graph V} {u v : V} (hne : u v) (p : G.walk u v) :
∃ (w : V) (h : G.adj u w) (p' : G.walk w v), p = simple_graph.walk.cons h p'
def simple_graph.walk.length {V : Type u} {G : simple_graph V} {u v : V} :
G.walk u v

The length of a walk is the number of edges/darts along it.

Equations
@[trans]
def simple_graph.walk.append {V : Type u} {G : simple_graph V} {u v w : V} :
G.walk u vG.walk v wG.walk u w

The concatenation of two compatible walks.

Equations
@[protected]
def simple_graph.walk.reverse_aux {V : Type u} {G : simple_graph V} {u v w : V} :
G.walk u vG.walk u wG.walk v w

The concatenation of the reverse of the first walk with the second walk.

Equations
@[symm]
def simple_graph.walk.reverse {V : Type u} {G : simple_graph V} {u v : V} (w : G.walk u v) :
G.walk v u

The walk in reverse.

Equations
def simple_graph.walk.get_vert {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) (n : ) :
V

Get the nth 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
@[simp]
theorem simple_graph.walk.get_vert_zero {V : Type u} {G : simple_graph V} {u v : V} (w : G.walk u v) :
w.get_vert 0 = u
theorem simple_graph.walk.get_vert_of_length_le {V : Type u} {G : simple_graph V} {u v : V} (w : G.walk u v) {i : } (hi : w.length i) :
w.get_vert i = v
@[simp]
theorem simple_graph.walk.get_vert_length {V : Type u} {G : simple_graph V} {u v : V} (w : G.walk u v) :
theorem simple_graph.walk.adj_get_vert_succ {V : Type u} {G : simple_graph V} {u v : V} (w : G.walk u v) {i : } (hi : i < w.length) :
G.adj (w.get_vert i) (w.get_vert (i + 1))
@[simp]
theorem simple_graph.walk.cons_append {V : Type u} {G : simple_graph V} {u v w x : V} (h : G.adj u v) (p : G.walk v w) (q : G.walk w x) :
@[simp]
theorem simple_graph.walk.cons_nil_append {V : Type u} {G : simple_graph V} {u v w : V} (h : G.adj u v) (p : G.walk v w) :
@[simp]
theorem simple_graph.walk.append_nil {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
@[simp]
theorem simple_graph.walk.nil_append {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.append_assoc {V : Type u} {G : simple_graph V} {u v w x : V} (p : G.walk u v) (q : G.walk v w) (r : G.walk w x) :
p.append (q.append r) = (p.append q).append r
@[simp]
theorem simple_graph.walk.append_copy_copy {V : Type u} {G : simple_graph V} {u v w u' v' w' : V} (p : G.walk u v) (q : G.walk v w) (hu : u = u') (hv : v = v') (hw : w = w') :
(p.copy hu hv).append (q.copy hv hw) = (p.append q).copy hu hw
@[simp]
theorem simple_graph.walk.cons_reverse_aux {V : Type u} {G : simple_graph V} {u v w x : V} (p : G.walk u v) (q : G.walk w x) (h : G.adj w u) :
@[protected, simp]
theorem simple_graph.walk.append_reverse_aux {V : Type u} {G : simple_graph V} {u v w x : V} (p : G.walk u v) (q : G.walk v w) (r : G.walk u x) :
@[protected, simp]
theorem simple_graph.walk.reverse_aux_append {V : Type u} {G : simple_graph V} {u v w x : V} (p : G.walk u v) (q : G.walk u w) (r : G.walk w x) :
@[protected]
theorem simple_graph.walk.reverse_aux_eq_reverse_append {V : Type u} {G : simple_graph V} {u v w : V} (p : G.walk u v) (q : G.walk u w) :
@[simp]
theorem simple_graph.walk.reverse_cons {V : Type u} {G : simple_graph V} {u v w : V} (h : G.adj u v) (p : G.walk v w) :
@[simp]
theorem simple_graph.walk.reverse_copy {V : Type u} {G : simple_graph V} {u v u' v' : V} (p : G.walk u v) (hu : u = u') (hv : v = v') :
(p.copy hu hv).reverse = p.reverse.copy hv hu
@[simp]
theorem simple_graph.walk.reverse_append {V : Type u} {G : simple_graph V} {u v w : V} (p : G.walk u v) (q : G.walk v w) :
@[simp]
theorem simple_graph.walk.reverse_reverse {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
@[simp]
theorem simple_graph.walk.length_nil {V : Type u} {G : simple_graph V} {u : V} :
@[simp]
theorem simple_graph.walk.length_cons {V : Type u} {G : simple_graph V} {u v w : V} (h : G.adj u v) (p : G.walk v w) :
@[simp]
theorem simple_graph.walk.length_copy {V : Type u} {G : simple_graph V} {u v u' v' : V} (p : G.walk u v) (hu : u = u') (hv : v = v') :
(p.copy hu hv).length = p.length
@[simp]
theorem simple_graph.walk.length_append {V : Type u} {G : simple_graph V} {u v w : V} (p : G.walk u v) (q : G.walk v w) :
@[protected, simp]
theorem simple_graph.walk.length_reverse_aux {V : Type u} {G : simple_graph V} {u v w : V} (p : G.walk u v) (q : G.walk u w) :
@[simp]
theorem simple_graph.walk.length_reverse {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.eq_of_length_eq_zero {V : Type u} {G : simple_graph V} {u v : V} {p : G.walk u v} :
p.length = 0u = v
@[simp]
theorem simple_graph.walk.exists_length_eq_zero_iff {V : Type u} {G : simple_graph V} {u v : V} :
(∃ (p : G.walk u v), p.length = 0) u = v
@[simp]
theorem simple_graph.walk.length_eq_zero_iff {V : Type u} {G : simple_graph V} {u : V} {p : G.walk u u} :
def simple_graph.walk.support {V : Type u} {G : simple_graph V} {u v : V} :
G.walk u vlist V

The support of a walk is the list of vertices it visits in order.

Equations
def simple_graph.walk.darts {V : Type u} {G : simple_graph V} {u v : V} :
G.walk u vlist G.dart

The darts of a walk is the list of darts it visits in order.

Equations
def simple_graph.walk.edges {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :

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
@[simp]
theorem simple_graph.walk.support_nil {V : Type u} {G : simple_graph V} {u : V} :
@[simp]
theorem simple_graph.walk.support_cons {V : Type u} {G : simple_graph V} {u v w : V} (h : G.adj u v) (p : G.walk v w) :
@[simp]
theorem simple_graph.walk.support_copy {V : Type u} {G : simple_graph V} {u v u' v' : V} (p : G.walk u v) (hu : u = u') (hv : v = v') :
(p.copy hu hv).support = p.support
theorem simple_graph.walk.support_append {V : Type u} {G : simple_graph V} {u v w : V} (p : G.walk u v) (p' : G.walk v w) :
@[simp]
theorem simple_graph.walk.support_reverse {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.support_ne_nil {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.tail_support_append {V : Type u} {G : simple_graph V} {u v w : V} (p : G.walk u v) (p' : G.walk v w) :
theorem simple_graph.walk.support_eq_cons {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
@[simp]
theorem simple_graph.walk.start_mem_support {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
@[simp]
theorem simple_graph.walk.end_mem_support {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.mem_support_iff {V : Type u} {G : simple_graph V} {u v w : V} (p : G.walk u v) :
@[simp]
theorem simple_graph.walk.mem_tail_support_append_iff {V : Type u} {G : simple_graph V} {t u v w : V} (p : G.walk u v) (p' : G.walk v w) :
@[simp]
theorem simple_graph.walk.end_mem_tail_support_of_ne {V : Type u} {G : simple_graph V} {u v : V} (h : u v) (p : G.walk u v) :
@[simp]
theorem simple_graph.walk.mem_support_append_iff {V : Type u} {G : simple_graph V} {t u v w : V} (p : G.walk u v) (p' : G.walk v w) :
@[simp]
theorem simple_graph.walk.subset_support_append_left {V : Type u} {G : simple_graph V} {u v w : V} (p : G.walk u v) (q : G.walk v w) :
@[simp]
theorem simple_graph.walk.subset_support_append_right {V : Type u} {G : simple_graph V} {u v w : V} (p : G.walk u v) (q : G.walk v w) :
theorem simple_graph.walk.coe_support {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.coe_support_append {V : Type u} {G : simple_graph V} {u v w : V} (p : G.walk u v) (p' : G.walk v w) :
theorem simple_graph.walk.coe_support_append' {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w : V} (p : G.walk u v) (p' : G.walk v w) :
((p.append p').support) = (p.support) + (p'.support) - {v}
theorem simple_graph.walk.chain_adj_support {V : Type u} {G : simple_graph V} {u v w : V} (h : G.adj u v) (p : G.walk v w) :
theorem simple_graph.walk.chain'_adj_support {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.chain_dart_adj_darts {V : Type u} {G : simple_graph V} {d : G.dart} {v w : V} (h : d.to_prod.snd = v) (p : G.walk v w) :
theorem simple_graph.walk.chain'_dart_adj_darts {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.edges_subset_edge_set {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) ⦃e : sym2 V⦄ (h : e p.edges) :

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.

@[simp]
@[simp]
theorem simple_graph.walk.darts_cons {V : Type u} {G : simple_graph V} {u v w : V} (h : G.adj u v) (p : G.walk v w) :
@[simp]
theorem simple_graph.walk.darts_copy {V : Type u} {G : simple_graph V} {u v u' v' : V} (p : G.walk u v) (hu : u = u') (hv : v = v') :
(p.copy hu hv).darts = p.darts
@[simp]
theorem simple_graph.walk.darts_append {V : Type u} {G : simple_graph V} {u v w : V} (p : G.walk u v) (p' : G.walk v w) :
(p.append p').darts = p.darts ++ p'.darts
@[simp]
theorem simple_graph.walk.darts_reverse {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.mem_darts_reverse {V : Type u} {G : simple_graph V} {u v : V} {d : G.dart} {p : G.walk u v} :
theorem simple_graph.walk.cons_map_snd_darts {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.map_snd_darts {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.map_fst_darts_append {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.map_fst_darts {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
@[simp]
@[simp]
theorem simple_graph.walk.edges_cons {V : Type u} {G : simple_graph V} {u v w : V} (h : G.adj u v) (p : G.walk v w) :
@[simp]
theorem simple_graph.walk.edges_copy {V : Type u} {G : simple_graph V} {u v u' v' : V} (p : G.walk u v) (hu : u = u') (hv : v = v') :
(p.copy hu hv).edges = p.edges
@[simp]
theorem simple_graph.walk.edges_append {V : Type u} {G : simple_graph V} {u v w : V} (p : G.walk u v) (p' : G.walk v w) :
(p.append p').edges = p.edges ++ p'.edges
@[simp]
theorem simple_graph.walk.edges_reverse {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
@[simp]
theorem simple_graph.walk.length_support {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
@[simp]
theorem simple_graph.walk.length_darts {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
@[simp]
theorem simple_graph.walk.length_edges {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.dart_fst_mem_support_of_mem_darts {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) {d : G.dart} :
theorem simple_graph.walk.dart_snd_mem_support_of_mem_darts {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) {d : G.dart} (h : d p.darts) :
theorem simple_graph.walk.fst_mem_support_of_mem_edges {V : Type u} {G : simple_graph V} {t u v w : V} (p : G.walk v w) (he : (t, u) p.edges) :
theorem simple_graph.walk.snd_mem_support_of_mem_edges {V : Type u} {G : simple_graph V} {t u v w : V} (p : G.walk v w) (he : (t, u) p.edges) :
theorem simple_graph.walk.darts_nodup_of_support_nodup {V : Type u} {G : simple_graph V} {u v : V} {p : G.walk u v} (h : p.support.nodup) :
theorem simple_graph.walk.edges_nodup_of_support_nodup {V : Type u} {G : simple_graph V} {u v : V} {p : G.walk u v} (h : p.support.nodup) :

Trails, paths, circuits, cycles #

structure simple_graph.walk.is_trail {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
Prop

A trail is a walk with no repeating edges.

structure simple_graph.walk.is_path {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
Prop

A path is a walk with no repeating vertices. Use simple_graph.walk.is_path.mk' for a simpler constructor.

structure simple_graph.walk.is_circuit {V : Type u} {G : simple_graph V} {u : V} (p : G.walk u u) :
Prop

A circuit at u : V is a nonempty trail beginning and ending at u.

structure simple_graph.walk.is_cycle {V : Type u} {G : simple_graph V} {u : V} (p : G.walk u u) :
Prop

A cycle at u : V is a circuit at u whose only repeating vertex is u (which appears exactly twice).

theorem simple_graph.walk.is_trail_def {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
@[simp]
theorem simple_graph.walk.is_trail_copy {V : Type u} {G : simple_graph V} {u v u' v' : V} (p : G.walk u v) (hu : u = u') (hv : v = v') :
theorem simple_graph.walk.is_path.mk' {V : Type u} {G : simple_graph V} {u v : V} {p : G.walk u v} (h : p.support.nodup) :
theorem simple_graph.walk.is_path_def {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
@[simp]
theorem simple_graph.walk.is_path_copy {V : Type u} {G : simple_graph V} {u v u' v' : V} (p : G.walk u v) (hu : u = u') (hv : v = v') :
(p.copy hu hv).is_path p.is_path
theorem simple_graph.walk.is_circuit_def {V : Type u} {G : simple_graph V} {u : V} (p : G.walk u u) :
@[simp]
theorem simple_graph.walk.is_circuit_copy {V : Type u} {G : simple_graph V} {u u' : V} (p : G.walk u u) (hu : u = u') :
@[simp]
theorem simple_graph.walk.is_cycle_copy {V : Type u} {G : simple_graph V} {u u' : V} (p : G.walk u u) (hu : u = u') :
@[simp]
theorem simple_graph.walk.is_trail.of_cons {V : Type u} {G : simple_graph V} {u v w : V} {h : G.adj u v} {p : G.walk v w} :
@[simp]
theorem simple_graph.walk.cons_is_trail_iff {V : Type u} {G : simple_graph V} {u v w : V} (h : G.adj u v) (p : G.walk v w) :
theorem simple_graph.walk.is_trail.reverse {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) (h : p.is_trail) :
@[simp]
theorem simple_graph.walk.reverse_is_trail_iff {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.is_trail.of_append_left {V : Type u} {G : simple_graph V} {u v w : V} {p : G.walk u v} {q : G.walk v w} (h : (p.append q).is_trail) :
theorem simple_graph.walk.is_trail.of_append_right {V : Type u} {G : simple_graph V} {u v w : V} {p : G.walk u v} {q : G.walk v w} (h : (p.append q).is_trail) :
theorem simple_graph.walk.is_trail.count_edges_le_one {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} {p : G.walk u v} (h : p.is_trail) (e : sym2 V) :
theorem simple_graph.walk.is_trail.count_edges_eq_one {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} {p : G.walk u v} (h : p.is_trail) {e : sym2 V} (he : e p.edges) :
@[simp]
theorem simple_graph.walk.is_path.of_cons {V : Type u} {G : simple_graph V} {u v w : V} {h : G.adj u v} {p : G.walk v w} :
@[simp]
theorem simple_graph.walk.cons_is_path_iff {V : Type u} {G : simple_graph V} {u v w : V} (h : G.adj u v) (p : G.walk v w) :
theorem simple_graph.walk.is_path.reverse {V : Type u} {G : simple_graph V} {u v : V} {p : G.walk u v} (h : p.is_path) :
@[simp]
theorem simple_graph.walk.is_path_reverse_iff {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.is_path.of_append_left {V : Type u} {G : simple_graph V} {u v w : V} {p : G.walk u v} {q : G.walk v w} :
(p.append q).is_path → p.is_path
theorem simple_graph.walk.is_path.of_append_right {V : Type u} {G : simple_graph V} {u v w : V} {p : G.walk u v} {q : G.walk v w} (h : (p.append q).is_path) :

Walk decompositions #

def simple_graph.walk.take_until {V : Type u} {G : simple_graph V} [decidable_eq V] {v w : V} (p : G.walk v w) (u : V) (h : u p.support) :
G.walk v u

Given a vertex in the support of a path, give the path up until (and including) that vertex.

Equations
def simple_graph.walk.drop_until {V : Type u} {G : simple_graph V} [decidable_eq V] {v w : V} (p : G.walk v w) (u : V) (h : u p.support) :
G.walk u w

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
@[simp]
theorem simple_graph.walk.take_spec {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w : V} (p : G.walk v w) (h : u p.support) :
(p.take_until u h).append (p.drop_until u h) = p

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.

theorem simple_graph.walk.mem_support_iff_exists_append {V : Type u} {G : simple_graph V} {u v w : V} {p : G.walk u v} :
w p.support ∃ (q : G.walk u w) (r : G.walk w v), p = q.append r
@[simp]
theorem simple_graph.walk.count_support_take_until_eq_one {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w : V} (p : G.walk v w) (h : u p.support) :
theorem simple_graph.walk.count_edges_take_until_le_one {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w : V} (p : G.walk v w) (h : u p.support) (x : V) :
@[simp]
theorem simple_graph.walk.take_until_copy {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w v' w' : V} (p : G.walk v w) (hv : v = v') (hw : w = w') (h : u (p.copy hv hw).support) :
(p.copy hv hw).take_until u h = (p.take_until u _).copy hv rfl
@[simp]
theorem simple_graph.walk.drop_until_copy {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w v' w' : V} (p : G.walk v w) (hv : v = v') (hw : w = w') (h : u (p.copy hv hw).support) :
(p.copy hv hw).drop_until u h = (p.drop_until u _).copy rfl hw
theorem simple_graph.walk.support_take_until_subset {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w : V} (p : G.walk v w) (h : u p.support) :
theorem simple_graph.walk.support_drop_until_subset {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w : V} (p : G.walk v w) (h : u p.support) :
theorem simple_graph.walk.darts_take_until_subset {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w : V} (p : G.walk v w) (h : u p.support) :
theorem simple_graph.walk.darts_drop_until_subset {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w : V} (p : G.walk v w) (h : u p.support) :
theorem simple_graph.walk.edges_take_until_subset {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w : V} (p : G.walk v w) (h : u p.support) :
theorem simple_graph.walk.edges_drop_until_subset {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w : V} (p : G.walk v w) (h : u p.support) :
theorem simple_graph.walk.length_take_until_le {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w : V} (p : G.walk v w) (h : u p.support) :
theorem simple_graph.walk.length_drop_until_le {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w : V} (p : G.walk v w) (h : u p.support) :
@[protected]
theorem simple_graph.walk.is_trail.take_until {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w : V} {p : G.walk v w} (hc : p.is_trail) (h : u p.support) :
@[protected]
theorem simple_graph.walk.is_trail.drop_until {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w : V} {p : G.walk v w} (hc : p.is_trail) (h : u p.support) :
@[protected]
theorem simple_graph.walk.is_path.take_until {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w : V} {p : G.walk v w} (hc : p.is_path) (h : u p.support) :
@[protected]
theorem simple_graph.walk.is_path.drop_until {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w : V} (p : G.walk v w) (hc : p.is_path) (h : u p.support) :
def simple_graph.walk.rotate {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} (c : G.walk v v) (h : u c.support) :
G.walk u u

Rotate a loop walk such that it is centered at the given vertex.

Equations
@[simp]
theorem simple_graph.walk.support_rotate {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} (c : G.walk v v) (h : u c.support) :
theorem simple_graph.walk.rotate_darts {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} (c : G.walk v v) (h : u c.support) :
theorem simple_graph.walk.rotate_edges {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} (c : G.walk v v) (h : u c.support) :
@[protected]
theorem simple_graph.walk.is_trail.rotate {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} {c : G.walk v v} (hc : c.is_trail) (h : u c.support) :
@[protected]
theorem simple_graph.walk.is_circuit.rotate {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} {c : G.walk v v} (hc : c.is_circuit) (h : u c.support) :
@[protected]
theorem simple_graph.walk.is_cycle.rotate {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} {c : G.walk v v} (hc : c.is_cycle) (h : u c.support) :

Type of paths #

@[reducible]
def simple_graph.path {V : Type u} (G : simple_graph V) (u v : V) :
Type u

The type for paths between two vertices.

@[protected, simp]
theorem simple_graph.path.is_path {V : Type u} {G : simple_graph V} {u v : V} (p : G.path u v) :
@[protected, simp]
theorem simple_graph.path.is_trail {V : Type u} {G : simple_graph V} {u v : V} (p : G.path u v) :
@[protected, refl]
def simple_graph.path.nil {V : Type u} {G : simple_graph V} {u : V} :
G.path u u

The length-0 path at a vertex.

Equations
def simple_graph.path.singleton {V : Type u} {G : simple_graph V} {u v : V} (h : G.adj u v) :
G.path u v

The length-1 path between a pair of adjacent vertices.

Equations
theorem simple_graph.path.mk_mem_edges_singleton {V : Type u} {G : simple_graph V} {u v : V} (h : G.adj u v) :
@[simp]
theorem simple_graph.path.reverse_coe {V : Type u} {G : simple_graph V} {u v : V} (p : G.path u v) :
@[symm]
def simple_graph.path.reverse {V : Type u} {G : simple_graph V} {u v : V} (p : G.path u v) :
G.path v u

The reverse of a path is another path. See also simple_graph.walk.reverse.

Equations
theorem simple_graph.path.count_support_eq_one {V : Type u} {G : simple_graph V} [decidable_eq V] {u v w : V} {p : G.path u v} (hw : w p.support) :
theorem simple_graph.path.count_edges_eq_one {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} {p : G.path u v} (e : sym2 V) (hw : e p.edges) :
@[simp]
theorem simple_graph.path.nodup_support {V : Type u} {G : simple_graph V} {u v : V} (p : G.path u v) :
theorem simple_graph.path.loop_eq {V : Type u} {G : simple_graph V} {v : V} (p : G.path v v) :
theorem simple_graph.path.not_mem_edges_of_loop {V : Type u} {G : simple_graph V} {v : V} {e : sym2 V} {p : G.path v v} :
theorem simple_graph.path.cons_is_cycle {V : Type u} {G : simple_graph V} {u v : V} (p : G.path v u) (h : G.adj u v) (he : (u, v) p.edges) :

Walks to paths #

def simple_graph.walk.bypass {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} :
G.walk u vG.walk u v

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
@[simp]
theorem simple_graph.walk.bypass_copy {V : Type u} {G : simple_graph V} [decidable_eq V] {u v u' v' : V} (p : G.walk u v) (hu : u = u') (hv : v = v') :
(p.copy hu hv).bypass = p.bypass.copy hu hv
theorem simple_graph.walk.bypass_is_path {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.length_bypass_le {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} (p : G.walk u v) :
def simple_graph.walk.to_path {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} (p : G.walk u v) :
G.path u v

Given a walk, produces a path with the same endpoints using simple_graph.walk.bypass.

Equations
theorem simple_graph.walk.support_bypass_subset {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.support_to_path_subset {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.darts_bypass_subset {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.edges_bypass_subset {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.darts_to_path_subset {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.edges_to_path_subset {V : Type u} {G : simple_graph V} [decidable_eq V] {u v : V} (p : G.walk u v) :

Mapping paths #

@[protected]
def simple_graph.walk.map {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} (f : G →g G') {u v : V} :
G.walk u vG'.walk (f u) (f v)

Given a graph homomorphism, map walks to walks.

Equations
@[simp]
theorem simple_graph.walk.map_nil {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} (f : G →g G') {u : V} :
@[simp]
theorem simple_graph.walk.map_cons {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} (f : G →g G') {u v : V} (p : G.walk u v) {w : V} (h : G.adj w u) :
@[simp]
theorem simple_graph.walk.map_copy {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} (f : G →g G') {u v u' v' : V} (p : G.walk u v) (hu : u = u') (hv : v = v') :
@[simp]
theorem simple_graph.walk.map_id {V : Type u} {G : simple_graph V} {u v : V} (p : G.walk u v) :
@[simp]
theorem simple_graph.walk.map_map {V : Type u} {V' : Type v} {V'' : Type w} {G : simple_graph V} {G' : simple_graph V'} {G'' : simple_graph V''} (f : G →g G') (f' : G' →g G'') {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.map_eq_of_eq {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} {u v : V} (p : G.walk u v) {f : G →g G'} (f' : G →g G') (h : f = f') :

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.

@[simp]
theorem simple_graph.walk.length_map {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} (f : G →g G') {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.map_append {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} (f : G →g G') {u v w : V} (p : G.walk u v) (q : G.walk v w) :
@[simp]
theorem simple_graph.walk.reverse_map {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} (f : G →g G') {u v : V} (p : G.walk u v) :
@[simp]
theorem simple_graph.walk.support_map {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} (f : G →g G') {u v : V} (p : G.walk u v) :
@[simp]
theorem simple_graph.walk.darts_map {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} (f : G →g G') {u v : V} (p : G.walk u v) :
@[simp]
theorem simple_graph.walk.edges_map {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} (f : G →g G') {u v : V} (p : G.walk u v) :
theorem simple_graph.walk.map_is_path_of_injective {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} {f : G →g G'} {u v : V} {p : G.walk u v} (hinj : function.injective f) (hp : p.is_path) :
@[protected]
theorem simple_graph.walk.is_path.of_map {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} {u v : V} {p : G.walk u v} {f : G →g G'} (hp : (simple_graph.walk.map f p).is_path) :
theorem simple_graph.walk.map_is_path_iff_of_injective {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} {f : G →g G'} {u v : V} {p : G.walk u v} (hinj : function.injective f) :
theorem simple_graph.walk.map_injective_of_injective {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} {f : G →g G'} (hinj : function.injective f) (u v : V) :
@[simp]
theorem simple_graph.path.map_coe {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} (f : G →g G') (hinj : function.injective f) {u v : V} (p : G.path u v) :
@[protected]
def simple_graph.path.map {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} (f : G →g G') (hinj : function.injective f) {u v : V} (p : G.path u v) :
G'.path (f u) (f v)

Given an injective graph homomorphism, map paths to paths.

Equations
theorem simple_graph.path.map_injective {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} {f : G →g G'} (hinj : function.injective f) (u v : V) :
@[protected]
def simple_graph.path.map_embedding {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} (f : G ↪g G') {u v : V} (p : G.path u v) :
G'.path (f u) (f v)

Given a graph embedding, map paths to paths.

Equations
@[simp]
theorem simple_graph.path.map_embedding_coe {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} (f : G ↪g G') {u v : V} (p : G.path u v) :
theorem simple_graph.path.map_embedding_injective {V : Type u} {V' : Type v} {G : simple_graph V} {G' : simple_graph V'} (f : G ↪g G') (u v : V) :

Deleting edges #

@[simp]
def simple_graph.walk.to_delete_edges {V : Type u} {G : simple_graph V} (s : set (sym2 V)) {v w : V} (p : G.walk v w) (hp : ∀ (e : sym2 V), e p.edgese s) :
(G.delete_edges s).walk v w

Given a walk that avoids a set of edges, produce a walk in the graph with those edges deleted.

Equations
@[reducible]
def simple_graph.walk.to_delete_edge {V : Type u} {G : simple_graph V} {v w : V} (e : sym2 V) (p : G.walk v w) (hp : e p.edges) :
(G.delete_edges {e}).walk v w

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.

@[simp]
theorem simple_graph.walk.map_to_delete_edges_eq {V : Type u} {G : simple_graph V} (s : set (sym2 V)) {v w : V} {p : G.walk v w} (hp : ∀ (e : sym2 V), e p.edgese s) :
theorem simple_graph.walk.is_path.to_delete_edges {V : Type u} {G : simple_graph V} (s : set (sym2 V)) {v w : V} {p : G.walk v w} (h : p.is_path) (hp : ∀ (e : sym2 V), e p.edgese s) :
@[simp]
theorem simple_graph.walk.to_delete_edges_copy {V : Type u} {G : simple_graph V} (s : set (sym2 V)) {u v u' v' : V} (p : G.walk u v) (hu : u = u') (hv : v = v') (h : ∀ (e : sym2 V), e (p.copy hu hv).edgese s) :

reachable and connected #

def simple_graph.reachable {V : Type u} (G : simple_graph V) (u v : V) :
Prop

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.

Equations
@[protected]
theorem simple_graph.reachable.elim {V : Type u} {G : simple_graph V} {p : Prop} {u v : V} (h : G.reachable u v) (hp : G.walk u v → p) :
p
@[protected]
theorem simple_graph.reachable.elim_path {V : Type u} {G : simple_graph V} {p : Prop} {u v : V} (h : G.reachable u v) (hp : G.path u v → p) :
p
@[protected, refl]
theorem simple_graph.reachable.refl {V : Type u} {G : simple_graph V} (u : V) :
G.reachable u u
@[protected]
theorem simple_graph.reachable.rfl {V : Type u} {G : simple_graph V} {u : V} :
G.reachable u u
@[protected, symm]
theorem simple_graph.reachable.symm {V : Type u} {G : simple_graph V} {u v : V} (huv : G.reachable u v) :
G.reachable v u
@[protected, trans]
theorem simple_graph.reachable.trans {V : Type u} {G : simple_graph V} {u v w : V} (huv : G.reachable u v) (hvw : G.reachable v w) :
G.reachable u w
def simple_graph.reachable_setoid {V : Type u} (G : simple_graph V) :

The equivalence relation on vertices given by simple_graph.reachable.

Equations
def simple_graph.preconnected {V : Type u} (G : simple_graph V) :
Prop

A graph is preconnected if every pair of vertices is reachable from one another.

Equations
theorem simple_graph.preconnected.map {V : Type u} {V' : Type v} {G : simple_graph V} {H : simple_graph V'} (f : G →g H) (hf : function.surjective f) (hG : G.preconnected) :
theorem simple_graph.iso.preconnected_iff {V : Type u} {V' : Type v} {G : simple_graph V} {H : simple_graph V'} (e : G ≃g H) :
structure simple_graph.connected {V : Type u} (G : simple_graph V) :
Prop

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
@[protected, instance]
def simple_graph.connected.has_coe_to_fun {V : Type u} (G : simple_graph V) :
has_coe_to_fun G.connected (λ (_x : G.connected), ∀ (u v : V), G.reachable u v)
Equations
theorem simple_graph.connected.map {V : Type u} {V' : Type v} {G : simple_graph V} {H : simple_graph V'} (f : G →g H) (hf : function.surjective f) (hG : G.connected) :
theorem simple_graph.iso.connected_iff {V : Type u} {V' : Type v} {G : simple_graph V} {H : simple_graph V'} (e : G ≃g H) :
def simple_graph.connected_component {V : Type u} (G : simple_graph V) :
Type u

The quotient of V by the simple_graph.reachable relation gives the connected components of a graph.

Equations
Instances for simple_graph.connected_component

Gives the connected component containing a particular vertex.

Equations
@[protected]
theorem simple_graph.connected_component.ind {V : Type u} {G : simple_graph V} {β : G.connected_component → Prop} (h : ∀ (v : V), β (G.connected_component_mk v)) (c : G.connected_component) :
β c
@[protected]
theorem simple_graph.connected_component.ind₂ {V : Type u} {G : simple_graph V} {β : G.connected_componentG.connected_component → Prop} (h : ∀ (v w : V), β (G.connected_component_mk v) (G.connected_component_mk w)) (c d : G.connected_component) :
β c d
@[protected]
@[protected]
@[protected, simp]
@[protected]
def simple_graph.connected_component.lift {V : Type u} {G : simple_graph V} {β : Sort u_1} (f : V → β) (h : ∀ (v w : V) (p : G.walk v w), p.is_pathf v = f w) :

The connected_component specialization of quot.lift. Provides the stronger assumption that the vertices are connected by a path.

Equations
@[protected, simp]
theorem simple_graph.connected_component.lift_mk {V : Type u} {G : simple_graph V} {β : Sort u_1} {f : V → β} {h : ∀ (v w : V) (p : G.walk v w), p.is_pathf v = f w} {v : V} :
@[protected]
theorem simple_graph.connected_component.exists {V : Type u} {G : simple_graph V} {p : G.connected_component → Prop} :
(∃ (c : G.connected_component), p c) ∃ (v : V), p (G.connected_component_mk v)
@[protected]
theorem simple_graph.connected_component.forall {V : Type u} {G : simple_graph V} {p : G.connected_component → Prop} :
(∀ (c : G.connected_component), p c) ∀ (v : V), p (G.connected_component_mk v)
@[reducible]
def simple_graph.subgraph.connected {V : Type u} {G : simple_graph V} (H : G.subgraph) :
Prop

A subgraph is connected if it is connected as a simple graph.

theorem simple_graph.connected.set_univ_walk_nonempty {V : Type u} {G : simple_graph V} (hconn : G.connected) (u v : V) :

Walks of a given length #

theorem simple_graph.set_walk_self_length_zero_eq {V : Type u} {G : simple_graph V} (u : V) :
{p : G.walk u u | p.length = 0} = {simple_graph.walk.nil}
theorem simple_graph.set_walk_length_zero_eq_of_ne {V : Type u} {G : simple_graph V} {u v : V} (h : u v) :
{p : G.walk u v | p.length = 0} =
theorem simple_graph.set_walk_length_succ_eq {V : Type u} {G : simple_graph V} (u v : V) (n : ) :
{p : G.walk u v | p.length = n.succ} = ⋃ (w : V) (h : G.adj u w), simple_graph.walk.cons h '' {p' : G.walk w v | p'.length = n}
def simple_graph.finset_walk_length {V : Type u} (G : simple_graph V) [fintype V] [decidable_rel G.adj] [decidable_eq V] (n : ) (u v : V) :
finset (G.walk u v)

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
theorem simple_graph.coe_finset_walk_length_eq {V : Type u} (G : simple_graph V) [fintype V] [decidable_rel G.adj] [decidable_eq V] (n : ) (u v : V) :
(G.finset_walk_length n u v) = {p : G.walk u v | p.length = n}
theorem simple_graph.walk.length_eq_of_mem_finset_walk_length {V : Type u} {G : simple_graph V} [fintype V] [decidable_rel G.adj] [decidable_eq V] {n : } {u v : V} (p : G.walk u v) :
p G.finset_walk_length n u vp.length = n
@[protected, instance]
def simple_graph.fintype_set_walk_length {V : Type u} (G : simple_graph V) [fintype V] [decidable_rel G.adj] [decidable_eq V] (u v : V) (n : ) :
fintype {p : G.walk u v | p.length = n}
Equations
theorem simple_graph.set_walk_length_to_finset_eq {V : Type u} (G : simple_graph V) [fintype V] [decidable_rel G.adj] [decidable_eq V] (n : ) (u v : V) :
{p : G.walk u v | p.length = n}.to_finset = G.finset_walk_length n u v
theorem simple_graph.card_set_walk_length_eq {V : Type u} (G : simple_graph V) [fintype V] [decidable_rel G.adj] [decidable_eq V] (u v : V) (n : ) :
fintype.card {p : G.walk u v | p.length = n} = (G.finset_walk_length n u v).card