Trees #
A tree is a connected graph in which no edge lies on a cycle. What the blueprint asks of a tree is always about its leaves, and every such question starts the same way: take a longest path. Neither of its ends can carry a second edge — an edge back onto the path would close a cycle, and an edge off the path would make a longer path — so both ends are leaves.
The three theorems this file exists for #
- deleting a leaf leaves a tree (
Graph.IsTree.delete_leaf), - a tree on
nvertices hasn - 1edges (Graph.IsTree.edge_count), by peeling leaves, - a tree with exactly three leaves has one vertex of degree three
(
Graph.IsTree.three_leaves), which is where the handshake lemma finally pays.
Why a longest path rather than a maximal one #
A longest path is produced by Nat.findGreatest over the lengths of paths, bounded because a
path repeats no edge (Graph.IsPath.nodup) and the graph has finitely many. That needs
Graph.Finite and nothing else — in particular no well-founded recursion and no choice of a
maximal element in an order. The bound is the only place finiteness enters the longest-path
argument.
Vertex deletion #
Graph.deleteVerts is Mathlib's. What this file adds is the transfer lemma every deletion
argument reduces to — Graph.IsWalk.deleteVerts, a walk that never visits a deleted vertex
survives — together with the reason the hypothesis is ever available:
Graph.IsLeaf.path_avoids, a path whose two ends are elsewhere never visits a vertex of
degree one. To pass through such a vertex a path would have to arrive and leave along its
single edge, and a path takes no edge twice.
Blueprint #
Graph.IsTree.three_leaves—lem:three-leaf-tree("a finite tree with exactly three leaves has exactly one vertex of degree at least three; that vertex has degree exactly three, and every other vertex is a leaf or has degree two"), used at the H5 step oflem:two-componentsto produce the three internally disjoint branches of each spanning treeT_i.Graph.IsTree.edge_count— the same lemma's "a finite tree withnvertices has exactlyn - 1edges".Graph.IsTree.has_leaf,Graph.IsTree.delete_leaf— its "a tree with an edge has a leaf, since an endpoint of a maximal simple path has no neighbor off the path, and a second neighbor on the path would close a cycle; deleting a leaf and its edge leaves a tree".Graph.IsTree— the trees oflem:two-components("take a minimal connected subgraphT_ispanning the three terminals. It is a tree").
Namespace #
The root Graph namespace, as in Walk.lean, Degree.lean and Cycle.lean.
Trees #
G.IsTree : a connected graph in which no edge lies on a cycle. Connectedness carries
nonemptiness (Graph.Connected), which is what makes the counting statements below true as
stated.
Instances For
A walk departs along an edge #
A path leaves its source once and for all #
Two edges of a path incident with its source are the same edge: the departing step is the only candidate, since a later edge at the source would put the source back among the vertices the rest of the path visits.
A longest path #
A finite graph with a vertex has a longest path. The lengths of paths are bounded by
the number of edges, so Nat.findGreatest picks the largest length that occurs, and the
witnessing path is longest.
Both ends of a longest path are leaves #
Every edge at the source of a longest path is one of the path's own edges. The two
ways out are both closed: an edge onto a vertex the path visits closes a cycle
(Graph.IsAcyclic.mem_of_isLink_of_mem_walkVertices), and an edge to a vertex it does not
visit extends the path.
The source of a longest path in an acyclic graph is a leaf, as soon as it carries an edge at all: every edge there is one of the path's, and the path leaves the vertex only once, so they are all the same edge.
The target of a longest path in an acyclic graph is a leaf too: reversing a path preserves its length, so the reverse is longest as well.
A tree on two or more vertices has a leaf. Two distinct vertices are joined by a path that takes an edge, so a longest path takes one too, and its source is a leaf.
A path steers clear of a leaf #
A path whose two ends are elsewhere never visits a vertex of degree one. To pass through such a vertex the path would have to arrive and leave along that vertex's single edge, and a path takes no edge twice. This is what makes connectivity survive the deletion of a leaf.
Vertex deletion #
A walk that visits no deleted vertex survives the deletion. Both ends of each of its edges are vertices it visits, so they too survive.
Deleting a vertex removes exactly the edges that meet it.
A tree minus a leaf is a tree. Acyclicity is inherited by every subgraph;
connectedness survives because every path between two surviving vertices already steered
clear of the leaf (Graph.IsLeaf.path_avoids).
A tree has one edge fewer than it has vertices #
A tree with three leaves #
The blueprint's lem:three-leaf-tree, and the one place the handshake lemma is used. Three
leaves contribute one apiece to the degree sum, every other vertex contributes two plus
whatever it carries above two, and the totals leave exactly one degree to carry.
A tree with exactly three leaves has a vertex of degree three, and every other vertex has degree at most two — so it is a leaf or has degree exactly two, and the vertex of degree three is unique.
The count: with k non-leaf vertices the tree has k + 3 vertices, hence k + 2 edges
(Graph.IsTree.edge_count), hence degree sum 2k + 4 (the handshake lemma). The leaves
contribute 3, so the non-leaves contribute 2k + 1; each contributes at least 2, so
between them they carry exactly one degree above two.