Depth-first search
StructureDepth-first traversal record#✓fully proved
A traversal over a vertex type \(V\) consists of three lists: a preorder (discovery order) list of vertices, a postorder (finish order) list of vertices, and a list of parent pairs in \(V \times V\), each stored as \((\text{child}, \text{parent})\).
No condition relating the three lists is imposed by the record itself.
structure Traversal (V : Type u) where
preorder : List V
postorder : List V
parents : List (V × V)
deriving Repr, DecidableEq
Used by 32
DefinitionLeft-first depth-first search#✓fully proved
Given a directed graph \(G\) with ordered adjacency lists and an ordered list of roots, depth-first search processes the roots from left to right, skipping roots already visited. Visiting an unvisited vertex \(v\) marks it visited and records its discovery, then processes the out-neighbours of \(v\) in adjacency-list order, visiting each one not yet visited at that moment and recording \(v\) as its parent, and finally records that \(v\) has finished. The result is the traversal consisting of the vertices in discovery order (preorder), the vertices in finish order (postorder), and the (child, parent) pairs in the order the children were discovered.
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
structure Traversal (V : Type u) where
preorder : List V
postorder : List V
parents : List (V × V)
deriving Repr, DecidableEq
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:40
def finish {V : Type u} [BEq V] [Hashable V] (s : Machine V) : Traversal V where
preorder := s.preorderRev.reverse
postorder := s.postorderRev.reverse
parents := s.parentsRev.reverse
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:74
def loop {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (s : Machine V) : Machine V :=
match _hwork : s.work with
| [] => s
| Frame.exit v :: work =>
loop adj roots { s with work := work, postorderRev := v :: s.postorderRev }
| Frame.enter parent v :: work =>
if _hv : v ∈ s.visited then
loop adj roots { s with work := work }
else
let parentsRev :=
match parent with
⋯
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:79
def initial {V : Type u} [BEq V] [Hashable V] [LawfulBEq V] (roots : List V) : Machine V where
work := enterFrames none roots
visited := ∅
preorderRev := []
postorderRev := []
parentsRev := []
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:67
Uses 2 · Used by 28
AbbreviationSequences of depth-first search machine steps#✓fully proved
Zero or more independent DFS machine steps.
abbrev Steps {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) :=
Relation.ReflTransGen (Step adj roots)
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
inductive Step {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) :
Machine V → Machine V → Prop where
| skip (s : Machine V) (parent : Option V) (v : V) (work : List (Frame V))
(hw : s.work = Frame.enter parent v :: work) (hv : v ∈ s.visited) :
Step adj roots s { s with work := work }
| discover (s : Machine V) (parent : Option V) (v : V) (work : List (Frame V))
(hw : s.work = Frame.enter parent v :: work) (hv : v ∉ s.visited) :
Step adj roots s {
work := enterFrames (some v) (adj.adjacency v) ++ Frame.exit v :: work
visited := s.visited.insert v
preorderRev := v :: s.preorderRev
⋯
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:140
Uses 1 · Used by 14
DefinitionLeft-first depth-first traversals#✓fully proved
Let \(G\) be a finite directed graph given by ordered adjacency lists and let \(r = (r_1, \dots, r_k)\) be a list of root vertices. A traversal \(T\) is a left-first DFS of \(G\) from \(r\) when some finite run of the following machine ends with an empty work list and with recorded preorder, postorder and (child, parent) list equal to those of \(T\).
The machine holds a work list of frames, each either "enter \(v\) with parent \(p\)" (where the parent \(p\) may be absent) or "exit \(v\)", a set of visited vertices, and the three recorded lists. It starts with the frames "enter \(r_1\) with no parent", ..., "enter \(r_k\) with no parent", no visited vertex and empty recorded lists. A step removes the first frame of the work list. For "exit \(v\)" it appends \(v\) to the postorder. For "enter \(v\) with parent \(p\)" it does nothing more if \(v\) is visited; otherwise it marks \(v\) visited, appends \(v\) to the preorder, appends \((v, p)\) to the (child, parent) list if \(p\) is present, and puts in front of the remaining work the frames "enter \(w\) with parent \(v\)" for the entries \(w\) of the adjacency list of \(v\), in order, followed by "exit \(v\)".
def IsLeftFirstDFS {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (traversal : Traversal V) : Prop :=
∃ final, Steps adj roots (initial roots) final ∧ final.work = [] ∧
finish final = traversal
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
structure Traversal (V : Type u) where
preorder : List V
postorder : List V
parents : List (V × V)
deriving Repr, DecidableEq
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:40
abbrev Steps {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) :=
Relation.ReflTransGen (Step adj roots)
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:163
def initial {V : Type u} [BEq V] [Hashable V] [LawfulBEq V] (roots : List V) : Machine V where
work := enterFrames none roots
visited := ∅
preorderRev := []
postorderRev := []
parentsRev := []
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:67
def finish {V : Type u} [BEq V] [Hashable V] (s : Machine V) : Traversal V where
preorder := s.preorderRev.reverse
postorder := s.postorderRev.reverse
parents := s.parentsRev.reverse
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:74
Uses 3 · Used by 3
TheoremExecutable DFS meets the left-first specification#✓fully proved
For every directed graph \(G\) with ordered adjacency lists and every ordered list of roots, the traversal computed by left-first depth-first search of \(G\) from these roots conforms to left-first DFS for \(G\) and these roots.
theorem dfs_is_left_first {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) :
IsLeftFirstDFS adj roots (dfs adj roots)
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def IsLeftFirstDFS {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (traversal : Traversal V) : Prop :=
∃ final, Steps adj roots (initial roots) final ∧ final.work = [] ∧
finish final = traversal
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:420
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
Uses 5 · Used by 1
TheoremThe left-first DFS specification determines the traversal#✓fully proved
Let \(G\) be a directed graph with ordered adjacency lists, fix an ordered list of roots, and let \(T\) be a traversal. If \(T\) conforms to left-first DFS for \(G\) and these roots, then \(T\) equals the traversal computed by left-first depth-first search of \(G\) from these roots.
theorem IsLeftFirstDFS.eq_dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
{adj : DirectedAdjacency V} {roots : List V} {traversal : Traversal V}
(h : IsLeftFirstDFS adj roots traversal) : traversal = dfs adj roots
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
structure Traversal (V : Type u) where
preorder : List V
postorder : List V
parents : List (V × V)
deriving Repr, DecidableEq
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:40
def IsLeftFirstDFS {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (traversal : Traversal V) : Prop :=
∃ final, Steps adj roots (initial roots) final ∧ final.work = [] ∧
finish final = traversal
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:420
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
Uses 5
TheoremDepth-first search discovers only reachable vertices#✓fully proved
Let \(G\) be a finite directed graph given by ordered adjacency lists and let \(R\) be a list of roots. Every vertex in the preorder (discovery order) of the depth-first search of \(G\) from \(R\) is reachable in \(G\) from some root in \(R\) by a directed path (possibly of length zero).
theorem preorder_sound {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (v : V)
(hv : v ∈ (dfs adj roots).preorder) :
∃ root ∈ roots, adj.Reachable root v
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
Uses 6 · Used by 1
TheoremDepth-first search discovers every reachable vertex#✓fully proved
Let \(G\) be a finite directed graph given by ordered adjacency lists and let \(R\) be a list of roots. If a vertex \(v\) is reachable in \(G\) from some root in \(R\) by a directed path (possibly of length zero), then \(v\) occurs in the preorder (discovery order) of the depth-first search of \(G\) from \(R\).
theorem preorder_complete {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (v : V)
(hv : ∃ root ∈ roots, adj.Reachable root v) :
v ∈ (dfs adj roots).preorder
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
Uses 6 · Used by 2
TheoremDepth-first search discovers exactly the reachable vertices#✓fully proved
Let \(G\) be a finite directed graph and \(R\) a list of root vertices. A vertex \(v\) occurs in the discovery order (preorder) of the depth-first search of \(G\) from \(R\) if and only if there is a root \(r\) in \(R\) from which \(v\) is reachable in \(G\) by a directed path of length zero or more.
theorem mem_preorder_iff_reachable {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (v : V) :
v ∈ (dfs adj roots).preorder ↔
∃ root ∈ roots, adj.Reachable root v
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
Uses 6 · Used by 2
TheoremDepth-first search discovers each vertex at most once#✓fully proved
For every finite directed graph \(G\) given by ordered adjacency lists and every list \(R\) of roots, the preorder (discovery order) of the depth-first search of \(G\) from \(R\) contains no vertex twice.
theorem preorder_nodup {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : (dfs adj roots).preorder.Nodup
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
Uses 4 · Used by 4
TheoremDepth-first search finishes exactly the reachable vertices#✓fully proved
Let \(G\) be a finite directed graph and \(R\) a list of root vertices. A vertex \(v\) occurs in the finish order (postorder) of the depth-first search of \(G\) from \(R\) if and only if there is a root \(r\) in \(R\) from which \(v\) is reachable in \(G\) by a directed path of length zero or more.
theorem mem_postorder_iff_reachable {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (v : V) :
v ∈ (dfs adj roots).postorder ↔
∃ root ∈ roots, adj.Reachable root v
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
Uses 6 · Used by 2
TheoremDFS finishes each vertex at most once#✓fully proved
Let \(G\) be a finite directed graph and \(R\) a list of root vertices. The finish order (postorder) of the depth-first search of \(G\) from \(R\) contains no vertex twice.
theorem postorder_nodup {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : (dfs adj roots).postorder.Nodup
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
Uses 4 · Used by 1
DefinitionOccurring before in a list#✓fully proved
For elements \(x\) and \(y\) and a list \(xs\), \(x\) occurs before \(y\) in \(xs\) when there are lists \(a\), \(b\) and \(c\) such that \(xs\) is the concatenation of \(a\), the element \(x\), \(b\), the element \(y\) and \(c\); that is, some occurrence of \(x\) lies at a strictly earlier position than some occurrence of \(y\).
def Before {V : Type u} (x y : V) (xs : List V) : Prop :=
∃ a b c, xs = a ++ x :: b ++ y :: c
Used by 8
DefinitionParent relation of a list of pairs#✓fully proved
Given a list \(P\) of (child, parent) pairs, \(p\) is a parent of \(c\) in \(P\) when the pair \((c, p)\) occurs in \(P\).
def ParentRel {V : Type u} (parents : List (V × V)) (child parent : V) : Prop :=
(child, parent) ∈ parents
DefinitionRoots of a DFS forest#✓fully proved
The forest roots of a traversal \(T\) are the vertices of the preorder of \(T\) that do not occur as the child in any (child, parent) pair recorded by \(T\), listed in the order in which they occur in the preorder.
def Traversal.forestRoots {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(traversal : Traversal V) : List V :=
let parented : Std.HashSet V := Std.HashSet.ofList (traversal.parents.map Prod.fst)
traversal.preorder.filter fun vertex => vertex ∉ parented
structure Traversal (V : Type u) where
preorder : List V
postorder : List V
parents : List (V × V)
deriving Repr, DecidableEq
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:40
TheoremDFS forest roots are distinct#✓fully proved
For every finite directed graph \(G\) given by ordered adjacency lists and every list \(r\) of root vertices, the list of forest roots of the left-first depth-first search of \(G\) from \(r\) contains no vertex twice.
theorem forestRoots_nodup {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) :
(dfs adj roots).forestRoots.Nodup
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
Uses 5
TheoremA DFS forest root has no parent#✓fully proved
Let \(G\) be a finite directed graph given by ordered adjacency lists, let \(r\) be a list of root vertices, and let \(v\) and \(p\) be vertices. If \(v\) is a forest root of the left-first depth-first search of \(G\) from \(r\), then \((v, p)\) is not among the (child, parent) pairs recorded by that search.
theorem forestRoot_has_no_parent {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (root parent : V)
(hroot : root ∈ (dfs adj roots).forestRoots) :
(root, parent) ∉ (dfs adj roots).parents
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
Uses 4 · Used by 1
TheoremDFS parent pairs are graph edges#✓fully proved
Let \(G\) be a finite directed graph and \(R\) a list of root vertices, and run depth-first search on \(G\) from \(R\). If the pair \((c, p)\) occurs in the list of (child, parent) pairs recorded by the search, then \(G\) has a directed edge from \(p\) to \(c\).
theorem parent_edge {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (child parent : V)
(h : (child, parent) ∈ (dfs adj roots).parents) : adj.Edge parent child
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
TheoremNo vertex is recorded twice as a DFS child#✓fully proved
Let \(G\) be a finite directed graph and \(R\) a list of root vertices, and run depth-first search on \(G\) from \(R\). In the list of (child, parent) pairs recorded by the search, no vertex occurs as the child of more than one entry; that is, the list of children has no repeated entries.
theorem parent_children_nodup {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) :
((dfs adj roots).parents.map Prod.fst).Nodup
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
Uses 7 · Used by 1
TheoremEvery discovered vertex is a forest root or has a unique parent#✓fully proved
Let \(G\) be a finite directed graph given by ordered adjacency lists, let \(r\) be a list of root vertices, and let \(v\) be a vertex in the preorder of the left-first depth-first search of \(G\) from \(r\). Then \(v\) is a forest root of that search, or there is exactly one vertex \(p\) such that \((v, p)\) is among the (child, parent) pairs recorded by the search.
theorem mem_forestRoots_or_existsUnique_parent {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (v : V)
(hv : v ∈ (dfs adj roots).preorder) :
v ∈ (dfs adj roots).forestRoots ∨
∃! parent, (v, parent) ∈ (dfs adj roots).parents
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
Uses 5 · Used by 1
TheoremIn preorder, a DFS parent precedes its child#✓fully proved
Let \(G\) be a finite directed graph and \(R\) a list of root vertices, and run depth-first search on \(G\) from \(R\). If the pair \((c, p)\) occurs in the list of (child, parent) pairs recorded by the search, then \(p\) occurs strictly before \(c\) in the discovery order (preorder) of the search.
theorem parent_before_child {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (child parent : V)
(h : (child, parent) ∈ (dfs adj roots).parents) :
Before parent child (dfs adj roots).preorder
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
def Before {V : Type u} (x y : V) (xs : List V) : Prop :=
∃ a b c, xs = a ++ x :: b ++ y :: c
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:593
Uses 7 · Used by 2
TheoremA DFS child finishes before its parent#✓fully proved
Let \(G\) be a directed graph with ordered adjacency lists and fix an ordered list of roots. If \((c, p)\) is one of the (child, parent) pairs recorded by the left-first depth-first search of \(G\) from these roots, then \(c\) occurs before \(p\) in the postorder (finish order) of that search.
theorem child_before_parent_postorder {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (child parent : V)
(h : (child, parent) ∈ (dfs adj roots).parents) :
Before child parent (dfs adj roots).postorder
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
def Before {V : Type u} (x y : V) (xs : List V) : Prop :=
∃ a b c, xs = a ++ x :: b ++ y :: c
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:593
Uses 5 · Used by 1
DefinitionDecreasing finish order#✓fully proved
For a directed graph \(G\) with ordered adjacency lists and an ordered list of roots, the decreasing finish order is the reverse of the postorder of the left-first depth-first search of \(G\) from those roots: the vertices that search visits, listed from the latest finished to the earliest finished.
def decreasingFinish {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : List V :=
(dfs adj roots).postorder.reverse
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
Uses 3 · Used by 5
TheoremIn decreasing finish order, a DFS parent precedes its child#✓fully proved
Let \(G\) be a finite directed graph and \(R\) a list of root vertices, and run depth-first search on \(G\) from \(R\). If the pair \((c, p)\) occurs in the list of (child, parent) pairs recorded by the search, then \(p\) occurs strictly before \(c\) in the decreasing finish order, the reverse of the finish order.
theorem parent_before_child_decreasingFinish {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (child parent : V)
(h : (child, parent) ∈ (dfs adj roots).parents) :
Before parent child (decreasingFinish adj roots)
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
def Before {V : Type u} (x y : V) (xs : List V) : Prop :=
∃ a b c, xs = a ++ x :: b ++ y :: c
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:593
def decreasingFinish {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : List V :=
(dfs adj roots).postorder.reverse
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:1031
Uses 6
TheoremDecreasing finish order lists exactly the vertices reachable from the roots#✓fully proved
Let \(G\) be a finite directed graph given by ordered adjacency lists, let \(r\) be a list of root vertices, and let \(v\) be a vertex. Then \(v\) occurs in the decreasing finish order of the left-first depth-first search of \(G\) from \(r\) if and only if \(v\) is reachable in \(G\) from some vertex of \(r\).
theorem mem_decreasingFinish_iff_reachable {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (v : V) :
v ∈ decreasingFinish adj roots ↔
∃ root ∈ roots, adj.Reachable root v
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def decreasingFinish {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : List V :=
(dfs adj roots).postorder.reverse
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:1031
Uses 6 · Used by 1
TheoremDecreasing finish order has no repeated vertices#✓fully proved
For every directed graph \(G\) with ordered adjacency lists and every ordered list of roots, the decreasing finish order of the depth-first search of \(G\) from those roots contains no vertex twice.
theorem decreasingFinish_nodup {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) :
(decreasingFinish adj roots).Nodup
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def decreasingFinish {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : List V :=
(dfs adj roots).postorder.reverse
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:1031
Uses 5 · Used by 1
TheoremParent chains in a DFS forest end at a forest root#✓fully proved
Let \(G\) be a finite directed graph and \(R\) a list of root vertices, and run depth-first search on \(G\) from \(R\). Say that \(p\) is a recorded parent of \(c\) when the pair \((c, p)\) occurs in the list of (child, parent) pairs recorded by the search, and call a discovered vertex with no recorded parent a forest root. Then for every vertex \(v\) in the discovery order (preorder) there are \(k \ge 0\) and vertices \(v = v_0, v_1, \dots, v_k\) such that each \(v_{i+1}\) is a recorded parent of \(v_i\) and \(v_k\) is a forest root.
theorem parent_chain_reaches_root {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (v : V)
(hv : v ∈ (dfs adj roots).preorder) :
∃ r ∈ (dfs adj roots).forestRoots,
Relation.ReflTransGen (ParentRel (dfs adj roots).parents) v r
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
def ParentRel {V : Type u} (parents : List (V × V)) (child parent : V) : Prop :=
(child, parent) ∈ parents
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:597
TheoremThe DFS parent relation is acyclic#✓fully proved
Let \(G\) be a finite directed graph and \(R\) a list of root vertices, and run depth-first search on \(G\) from \(R\). Say that \(p\) is a recorded parent of \(c\) when the pair \((c, p)\) occurs in the list of (child, parent) pairs recorded by the search. Then there are no \(k \ge 1\) and vertices \(v_0, v_1, \dots, v_k\) with \(v_k = v_0\) such that each \(v_{i+1}\) is a recorded parent of \(v_i\).
theorem parent_relation_acyclic {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (v : V) :
¬ Relation.TransGen (ParentRel (dfs adj roots).parents) v v
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def ParentRel {V : Type u} (parents : List (V × V)) (child parent : V) : Prop :=
(child, parent) ∈ parents
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:597
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
TheoremDFS forest roots are scheduled roots#✓fully proved
Let \(G\) be a finite directed graph given by ordered adjacency lists, let \(r\) be a list of root vertices, and let \(v\) be a vertex. If \(v\) is a forest root of the left-first depth-first search of \(G\) from \(r\), then \(v\) occurs in \(r\).
theorem forestRoot_mem_roots {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) (root : V)
(hroot : root ∈ (dfs adj roots).forestRoots) : root ∈ roots
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
Uses 9
DefinitionDepth-first search of the whole graph#✓fully proved
For a directed graph \(G\) with ordered adjacency lists, the whole-graph traversal is the left-first depth-first search of \(G\) whose roots are all vertices of \(G\), taken in the graph's fixed vertex enumeration order.
def dfsAll {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) : Traversal V :=
dfs adj adj.vertices
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
structure Traversal (V : Type u) where
preorder : List V
postorder : List V
parents : List (V × V)
deriving Repr, DecidableEq
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:40
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
Uses 3 · Used by 3
TheoremWhole-graph DFS discovers every vertex#✓fully proved
For every finite directed graph \(G\) given by ordered adjacency lists and every vertex \(v\) of \(G\), \(v\) occurs in the preorder of the whole-graph depth-first search of \(G\), that is, the left-first depth-first search of \(G\) whose roots are all vertices of \(G\) in the graph's vertex order.
theorem mem_dfsAll_preorder {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (vertex : V) :
vertex ∈ (dfsAll adj).preorder
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfsAll {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) : Traversal V :=
dfs adj adj.vertices
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:1177
Uses 6 · Used by 1
TheoremWhole-graph DFS finishes every vertex#✓fully proved
For every finite directed graph \(G\) given by ordered adjacency lists and every vertex \(v\) of \(G\), \(v\) occurs in the postorder of the whole-graph depth-first search of \(G\), that is, the left-first depth-first search of \(G\) whose roots are all vertices of \(G\) in the graph's vertex order.
theorem mem_dfsAll_postorder {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (vertex : V) :
vertex ∈ (dfsAll adj).postorder
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def dfsAll {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) : Traversal V :=
dfs adj adj.vertices
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:1177
DefinitionWhole-graph decreasing finish order#✓fully proved
For a directed graph \(G\) with ordered adjacency lists, the whole-graph decreasing finish order is the decreasing finish order of the left-first depth-first search of \(G\) whose roots are all vertices of \(G\), taken in the graph's vertex enumeration order; its vertices are listed from the latest finished to the earliest finished.
def decreasingFinishAll {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) : List V :=
decreasingFinish adj adj.vertices
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def decreasingFinish {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : List V :=
(dfs adj roots).postorder.reverse
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:1031
Uses 2 · Used by 10
TheoremWhole-graph decreasing finish order contains every vertex#✓fully proved
For every finite directed graph \(G\) given by ordered adjacency lists and every vertex \(v\) of \(G\), \(v\) occurs in the whole-graph decreasing finish order of \(G\), that is, the decreasing finish order of the left-first depth-first search of \(G\) whose roots are all vertices of \(G\) in the graph's vertex order.
theorem mem_decreasingFinishAll {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (vertex : V) :
vertex ∈ decreasingFinishAll adj
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def decreasingFinishAll {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) : List V :=
decreasingFinish adj adj.vertices
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:1197
Uses 6 · Used by 2
TheoremWhole-graph decreasing finish order has no repeated vertices#✓fully proved
For every directed graph \(G\) with ordered adjacency lists, the whole-graph decreasing finish order of \(G\) contains no vertex twice.
theorem decreasingFinishAll_nodup {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) : (decreasingFinishAll adj).Nodup
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
def decreasingFinishAll {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) : List V :=
decreasingFinish adj adj.vertices
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:1197
Uses 3 · Used by 1
TheoremExact transition count of depth-first search#✓fully proved
Let \(G\) be a finite directed graph with ordered adjacency lists \(N(v)\), whose entries may repeat, and let \(R\) be a list of roots, possibly with repetitions. Run the depth-first search machine from \(R\) (each transition drops a pending vertex that is already visited, discovers a new vertex, or finishes a vertex). Let \(v_1, \dots, v_k\) be the preorder of the depth-first search of \(G\) from \(R\). Then there is a terminal machine state, with no work left, whose recorded output is the depth-first traversal of \(G\) from \(R\) and which is reached from the initial state in exactly \(|R| + k + \sum_{i=1}^{k} |N(v_i)|\) transitions, where \(|R|\) is the length of \(R\) and \(|N(v)|\) is the length of the adjacency list of \(v\).
public theorem dfs_exact_steps
{V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) :
∃ final : Internal.Machine V, final.work = [] ∧
Internal.finish final = dfs adj roots ∧
Relation.RelatesInSteps (Internal.Step adj roots) (Internal.initial roots) final
(roots.length + (dfs adj roots).preorder.length +
((dfs adj roots).preorder.map fun v => (adj.adjacency v).length).sum)
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
structure Machine (V : Type u) [BEq V] [Hashable V] where
work : List (Frame V)
visited : Std.HashSet V
preorderRev : List V
postorderRev : List V
parentsRev : List (V × V)
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:57
def finish {V : Type u} [BEq V] [Hashable V] (s : Machine V) : Traversal V where
preorder := s.preorderRev.reverse
postorder := s.postorderRev.reverse
parents := s.parentsRev.reverse
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:74
def dfs {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) : Traversal V :=
finish (loop adj roots (initial roots))
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:134
inductive Step {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) :
Machine V → Machine V → Prop where
| skip (s : Machine V) (parent : Option V) (v : V) (work : List (Frame V))
(hw : s.work = Frame.enter parent v :: work) (hv : v ∈ s.visited) :
Step adj roots s { s with work := work }
| discover (s : Machine V) (parent : Option V) (v : V) (work : List (Frame V))
(hw : s.work = Frame.enter parent v :: work) (hv : v ∉ s.visited) :
Step adj roots s {
work := enterFrames (some v) (adj.adjacency v) ++ Frame.exit v :: work
visited := s.visited.insert v
preorderRev := v :: s.preorderRev
⋯
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:140
def initial {V : Type u} [BEq V] [Hashable V] [LawfulBEq V] (roots : List V) : Machine V where
work := enterFrames none roots
visited := ∅
preorderRev := []
postorderRev := []
parentsRev := []
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:67
Uses 6 · Used by 1
TheoremExact transition count of whole-graph depth-first search#✓fully proved
Let \(G\) be a finite directed graph whose vertices are listed without repetition as \(v_1, \dots, v_n\), with ordered adjacency lists \(N(v)\) whose entries may repeat. Run the depth-first search machine with roots \(v_1, \dots, v_n\) in this order (each transition drops a pending vertex that is already visited, discovers a new vertex, or finishes a vertex). Then there is a terminal machine state, with no work left, whose recorded output is the whole-graph depth-first traversal of \(G\) and which is reached from the initial state in exactly \(2n + \sum_{i=1}^{n} |N(v_i)|\) transitions, where \(|N(v)|\) is the length of the adjacency list of \(v\), counting repeated entries and self-loops.
public theorem dfsAll_exact_steps
{V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) :
∃ final : Internal.Machine V, final.work = [] ∧
Internal.finish final = dfsAll adj ∧
Relation.RelatesInSteps (Internal.Step adj adj.vertices)
(Internal.initial adj.vertices) final
(2 * adj.vertices.length + (adj.vertices.map fun v => (adj.adjacency v).length).sum)
structure DirectedAdjacency (V : Type u) where
/-- The complete deterministic enumeration of vertices. -/
vertices : List V
/-- The vertex enumeration contains no duplicates. -/
vertices_nodup : vertices.Nodup
/-- Every vertex occurs in the enumeration. -/
vertices_complete : ∀ vertex, vertex ∈ vertices
/-- The ordered outgoing neighbors of each vertex. Entries may repeat. -/
adjacency : V → List V
CSLibExt/Algorithms/Lean/Graph/DirectedAdjacency.lean:32
structure Machine (V : Type u) [BEq V] [Hashable V] where
work : List (Frame V)
visited : Std.HashSet V
preorderRev : List V
postorderRev : List V
parentsRev : List (V × V)
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:57
def finish {V : Type u} [BEq V] [Hashable V] (s : Machine V) : Traversal V where
preorder := s.preorderRev.reverse
postorder := s.postorderRev.reverse
parents := s.parentsRev.reverse
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:74
def dfsAll {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) : Traversal V :=
dfs adj adj.vertices
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:1177
inductive Step {V : Type u} [BEq V] [Hashable V] [LawfulBEq V]
(adj : DirectedAdjacency V) (roots : List V) :
Machine V → Machine V → Prop where
| skip (s : Machine V) (parent : Option V) (v : V) (work : List (Frame V))
(hw : s.work = Frame.enter parent v :: work) (hv : v ∈ s.visited) :
Step adj roots s { s with work := work }
| discover (s : Machine V) (parent : Option V) (v : V) (work : List (Frame V))
(hw : s.work = Frame.enter parent v :: work) (hv : v ∉ s.visited) :
Step adj roots s {
work := enterFrames (some v) (adj.adjacency v) ++ Frame.exit v :: work
visited := s.visited.insert v
preorderRev := v :: s.preorderRev
⋯
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:140
def initial {V : Type u} [BEq V] [Hashable V] [LawfulBEq V] (roots : List V) : Machine V where
work := enterFrames none roots
visited := ∅
preorderRev := []
postorderRev := []
parentsRev := []
CSLibExt/Algorithms/Lean/Graph/DepthFirstSearch.lean:67
Uses 7
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.