Imports
import MathlibSection 20.1 - Representing Graphs
This section defines the finite-graph model used by the Chapter 20 algorithm track. A graph is a finite vertex set together with an adjacency function. Undirected graphs are obtained by requiring symmetric adjacency.
The main concepts are:
-
Graph V: a directed graph on vertex typeV. -
Graph.Adj u v: there is a directed edge fromutov. -
Graph.IsWalk p:pis a non-empty list of vertices where each consecutive pair is an edge. -
Graph.IsPath p: a walk with no repeated vertices. -
Graph.IsCycle p u v: a non-trivial closed path built from a path fromutovplus the edgev → u. -
Graph.Reachable u v: the reflexive-transitive closure of adjacency. -
Graph.ConnectedComponent u: the set of vertices reachable fromu.
We define reachability as the reflexive-transitive closure of adjacency; this makes reflexivity and transitivity immediate and keeps the first pass simple. The equivalence with the existence of a walk will be proved once the model is stable.
namespace CLRSnamespace Chapter22A finite directed graph: a vertex set plus an adjacency function.
We require adjacency to be empty outside the vertex set, so every edge has both
endpoints in vertices.
structure Graph (V : Type) [DecidableEq V] where
vertices : Finset V
adj : V → Finset V
adj_sub : ∀ v ∈ vertices, adj v ⊆ vertices
adj_outside : ∀ v ∉ vertices, adj v = ∅namespace Graphvariable {V : Type} [DecidableEq V] (G : Graph V)
Directed adjacency: v is a neighbor of u.
def Adj (u v : V) : Prop := v ∈ G.adj u
If u is adjacent to v, then u is a vertex of the graph.
theorem adj_mem_left {u v : V} (hadj : G.Adj u v) : u ∈ G.vertices := by
by_contra h
have : G.adj u = ∅ := G.adj_outside u h
simp [Adj, this] at hadj
If u is adjacent to v, then v is a vertex of the graph.
theorem adj_mem_right {u v : V} (hadj : G.Adj u v) : v ∈ G.vertices := by
have hu := G.adj_mem_left hadj
exact G.adj_sub u hu hadjA walk is a non-empty vertex list where each consecutive pair is an edge.
def IsWalk (p : List V) : Prop :=
p ≠ [] ∧ (∀ v ∈ p, v ∈ G.vertices) ∧ List.IsChain (fun x y => y ∈ G.adj x) p
p is a walk from u to v.
def IsWalkFromTo (p : List V) (u v : V) : Prop :=
G.IsWalk p ∧ p.head? = some u ∧ p.getLast? = some vA path is a walk with no repeated vertices.
def IsPath (p : List V) : Prop :=
G.IsWalk p ∧ p.Nodup
A cycle is a non-trivial closed path: at least one edge and no repeated
internal vertices. We represent it as a path from u to v together with an
edge v → u.
def IsCycle (p : List V) (u v : V) : Prop :=
G.IsPath p ∧ p.head? = some u ∧ p.getLast? = some v ∧ v ≠ u ∧ u ∈ G.adj vReachability: reflexive-transitive closure of the adjacency relation.
def Reachable (u v : V) : Prop :=
Relation.ReflTransGen G.Adj u v
The connected component of u is the set of vertices reachable from u.
It is a Set rather than a Finset because the decidable
characterisation of reachability will come from an explicit graph-search
algorithm in later sections.
A single-vertex list is a walk iff the vertex belongs to the graph.
-- Basic facts about walks.
theorem isWalk_singleton {u : V} (hu : u ∈ G.vertices) : G.IsWalk [u] := by
constructor
· simp
constructor
· intro v hv
simp at hv
rwa [hv]
· simpAdjacency implies a two-vertex walk.
theorem isWalk_pair {u v : V} (hu : u ∈ G.vertices) (hadj : G.Adj u v) :
G.IsWalk [u, v] := by
have hv : v ∈ G.vertices := G.adj_sub u hu hadj
constructor
· simp
constructor
· intro a ha
simp at ha
cases ha with
| inl h => rwa [h]
| inr h => rwa [h]
· simp [Adj] at hadj ⊢
exact hadjReachability is reflexive.
-- Reachability is a preorder on vertices.
theorem reachable_refl (u : V) : G.Reachable u u :=
Relation.ReflTransGen.reflReachability is transitive.
theorem reachable_trans {u v w : V}
(huv : G.Reachable u v) (hvw : G.Reachable v w) : G.Reachable u w :=
Relation.ReflTransGen.trans huv hvwAn edge implies reachability in one step.
theorem reachable_adj {u v : V} (hadj : G.Adj u v) : G.Reachable u v :=
Relation.ReflTransGen.tail Relation.ReflTransGen.refl hadjAn undirected graph has symmetric adjacency.
In an undirected graph, reachability is symmetric.
theorem reachable_symm {G : Graph V} (hund : G.Undirected)
{u v : V} (huv : G.Reachable u v) : G.Reachable v u := by
induction huv with
| refl =>
exact Relation.ReflTransGen.refl
| tail hxy hyz ih =>
have hadj' : G.Adj _ _ := (hund _ _).mp hyz
exact Relation.ReflTransGen.trans
(Relation.ReflTransGen.tail Relation.ReflTransGen.refl hadj') ihend Graphend Chapter22end CLRS