The outer face of a chain of plane graphs #
lem:outer-chain. Let Γ 0, …, Γ n (n ≥ 2, so at least three graphs) be finite 2-connected
polygonal plane graphs, consecutive ones sharing at least two vertices and nonconsecutive ones
disjoint. If a point x is in the outer face of every consecutive pair Γ p ∪ Γ (p+1), then it
is in the outer face of Γ 0 ∪ ⋯ ∪ Γ n.
How the chain is formalised #
The blueprint says "after subdividing common points into vertices". Here that is true by
construction rather than by a theorem: the family shares one ambient edge type β and
one drawing drawing : β → ℝ → Plane, and every member is a subgraph of a single plane
graph G — see Graph.IsPlaneChain. Two members therefore agree about the ends of a shared
edge, meet only where G lets them meet, and Γ p ∪ Γ q is Graph.union with nothing to
check. The ambient G is allowed to be larger than the chain's own union; a consumer that has
built all its pieces inside one polygonal overlay hands that overlay over as G.
Graph.chainUnion Γ i m is the block Γ i ∪ Γ (i+1) ∪ ⋯ ∪ Γ (i+m), indexed by its length
m rather than by its right endpoint, so that the recursion is on m and the blueprint's
"choose i ≤ j with j - i minimum" is a plain strong induction on m. A consecutive pair is
chainUnion Γ p 1.
"x is in the outer face of H" is spelled, as everywhere in this development, as x is off
the drawing and the face through it is unbounded — x ∈ exterior H drawing together with
¬ Bornology.IsBounded (face H drawing x). Graph.unbounded_face_unique is what makes that
"the" outer face, and Graph.beyondSquare_subset_face is how a consumer proves it.
What is proved and what is assumed #
The blueprint's proof is a minimal-counterexample argument on two measures: first the length of
the index interval, then the number of edges of the enclosing cycle lying outside Γ (j-1).
Both minimisations are carried out here, as strong inductions, together with
- the reduction of "
xlies in a bounded face" to "some cycle enclosesx" (Graph.encloses_of_isBounded_face, fromGraph.face_cycles') and back (Graph.isBounded_face_of_encloses); - 2-connectivity of every block, by iterating
Graph.IsTwoConnected.union(lem:union-two-connected); - the base case
j - i ≤ 1, which is the blueprint's paragraph "Ifj-i ≤ 1, choose a consecutive pairHcontaining that union …"; - the two minimality consequences "
Ccontains an edge ofΓ joutsideΓ (j-1)" and "Ccontains an edge of the earlier chain outsideΓ (j-1)", each proved by pushing the cycle down into a shorter block withGraph.IsCycleThrough.anti; - the splicing of a crosscut onto each of the two arcs (
Graph.exists_spliced_cycles, fromGraph.exists_spliced_cycle) and the edge count that makes the splice a strict improvement (Graph.edgesOutside_splice_lt,Graph.exists_cycle_edgesOutside_lt).
Graph.Descent is the middle paragraph of the blueprint's proof — from a cycle C of
Γ i ∪ ⋯ ∪ Γ j enclosing x and having an edge of Γ j and an edge of Γ i ∪ ⋯ ∪ Γ (j-2)
outside Γ (j-1), produce a cycle of the same block enclosing x with strictly fewer edges
outside Γ (j-1). It is a statement about one step, not about the chain's outer face.
It was assumed when this module was written. Both halves are now proved:
Schoenflies/CrosscutExists.lean— combinatorial: build the crosscut, asGraph.IsPlaneChain.crosscutExists. Nothing geometric enters beyondGraph.IsPlaneChain.disjoint_block_far, "Γ jmeets the earlier chain only throughΓ (j-1)".Schoenflies/CrosscutEncloses.lean— geometric: "the pathRlies on one side ofCand is a crosscut there; bythm:polygonal-crosscut, at least one ofR ∪ C₁,R ∪ C₂enclosesx", asGraph.crosscutEnclosesOff. That module also carries the counterexample showing why the clausex ∈ exterior H drawingcannot be dropped — see the comment below, where the false version of it used to stand.
Schoenflies/OuterChainClosed.lean combines the two, and states lem:outer-chain with nothing
assumed.
Blueprint #
Graph.chainUnion—Γ i ∪ ⋯ ∪ Γ (i+m), withchainUnion_le,le_chainUnion,chainUnion_finite,chainUnion_isTwoConnected(the last is repeatedlem:union-two-connected).Graph.Encloses— "that face is the interior of its boundary cycle, which therefore enclosesx", as a property of a graph.Graph.encloses_of_isBounded_face,Graph.isBounded_face_of_encloses— the two directions of that reduction; the second is the blueprint's "the face ofHcontainingx… lies in the bounded setInt(C)and therefore is not the outer face ofH".Graph.IsPlaneChain— the hypotheses oflem:outer-chain;Graph.OuterOnPairs— its hypothesis on consecutive pairs.Graph.IsCycleCrosscut— the crosscutRof the cycleC, with the two arcs it cuts.Graph.exists_spliced_cycles— the two cyclesR ∪ C₁,R ∪ C₂.Graph.edgesOutside,Graph.edgesOutside_splice_lt,Graph.exists_cycle_edgesOutside_lt— "it has fewer edges outsideΓ (j-1)thanC, since one nonempty outside portion ofChas been replaced byR ⊆ Γ (j-1)".Graph.Descent— the crosscut paragraph of the proof; discharged inSchoenflies/CrosscutEncloses.leanfromGraph.CrosscutExistsalone.Graph.IsPlaneChain.not_encloses— the double minimisation.Graph.IsPlaneChain.outer_chain—lem:outer-chain, fromGraph.Descent;Graph.IsPlaneChain.outer_chain'inSchoenflies/OuterChainClosed.leanis the same statement with nothing assumed.
Blocks of a chain #
chainUnion Γ i m is Γ i ∪ Γ (i+1) ∪ ⋯ ∪ Γ (i+m).
Indexed by the length m of the block rather than by its right endpoint: the blueprint
minimises j - i, and with this indexing that is a strong induction on the second argument
with no subtraction anywhere.
Equations
- Graph.chainUnion Γ i 0 = Γ i
- Graph.chainUnion Γ i m.succ = (Graph.chainUnion Γ i m).union (Γ (i + m + 1))
Instances For
Each member of a block is a subgraph of it. The compatibility hypothesis is what makes the
right-hand summand of a Graph.union a subgraph, and it is free once every member lies in one
ambient graph.
lem:union-two-connected, iterated. A block of 2-connected graphs in which consecutive
members share two distinct vertices is 2-connected.
Reading a cycle inside a subgraph #
Graph.IsCycleThrough.anti is the cycle counterpart of Graph.IsPath.anti; it is what turns
"no edge of C is outside this block" into "C is a cycle of this block".
A cycle all of whose edges belong to a subgraph is a cycle of that subgraph.
A cycle of a subgraph is a cycle of the graph.
A crosscut of a cycle, with the two arcs it cuts #
This is the combinatorial output of the blueprint's crosscut paragraph, bundled: the path R in
F = Γ (j-1), its two endpoints a, b on the cycle, and the two arcs D₁, D₂ the endpoints cut
the cycle into. Both arcs are required to carry an edge that F does not have — the blueprint's
"each arc contains an edge outside Γ (j-1), because its endpoints belong to different maximal
subpaths of the intersection" — which is what makes the splice a strict improvement on both
sides, so that it does not matter which of the two spliced cycles turns out to enclose x.
A crosscut of a cycle. R is a path of H between two vertices a ≠ b of the cycle
e :: D, lying in F, using no edge of the cycle and no vertex of it internally; D₁, D₂ are
the two arcs the cycle splits into, each carrying an edge outside F.
The two cut points are distinct.
- arc₁ : H.IsPath a D₁ b
The first arc runs from
atob. - arc₂ : H.IsPath b D₂ a
The second arc runs back.
Together the arcs use every edge of the cycle exactly once.
- isPath : H.IsPath a R b
The crosscut is a path between the two cut points.
The first cut point is on the cycle.
So is the second.
The crosscut lies in
F."No edge of
Ris an edge ofC."- interior (y : α) : y ∈ H.walkVertices a R → y ≠ a → y ≠ b → y ∉ H.walkVertices u D
"Its internal vertices do not lie on
C." - outside₁ : ∃ g ∈ D₁, g ∉ F.edgeSet
"Each arc contains an edge outside
Γ (j-1)." - outside₂ : ∃ g ∈ D₂, g ∉ F.edgeSet
The same for the other arc.
Instances For
The two cycles a crosscut splices, R ∪ C₁ and R ∪ C₂, as cycles of the ambient graph
with their edge lists named. Both are produced by Graph.exists_spliced_cycle, applied to the
cycle's own subgraph and to each arc in turn.
The edges of a walk that the graph H does not have. The second measure of the blueprint's
minimal-counterexample argument is the size of this set for H = Γ (j-1).
Instances For
The count the descent step decreases. Replacing one arc D₂ of a cycle by a list R of
edges the graph H already has strictly lowers the number of edges outside H, provided the
discarded arc had at least one such edge.
The two arcs of a cycle share no edge, which is why the discarded edge is not silently still
present on the arc that was kept: that is what the Nodup hypothesis on the cycle's edge list
supplies. It holds for a cycle because the detour of Graph.IsCycleThrough is a path and does
not contain the named edge.
Enclosing a point #
"That face is the interior of its boundary cycle, which therefore encloses x." A graph
encloses a point when some cycle of it has that point in its interior.
Equations
- H.Encloses drawing x = ∃ (e : β) (u : Schoenflies.Plane) (v : Schoenflies.Plane) (D : List β), H.IsCycleThrough e u v D ∧ x ∈ Schoenflies.inside (Graph.edgesCover drawing (e :: D))
Instances For
A cycle of a subgraph encloses whatever it enclosed.
"The face of H containing x is connected and disjoint from C; since it contains
x ∈ Int(C) it lies in the bounded set Int(C)." An enclosed point has a bounded face.
"By lem:face-cycles, that face is the interior of its boundary cycle." A point in a
bounded face of a finite 2-connected polygonal plane graph is enclosed by a cycle of it.
The last mile of the descent step. Suppose the cycle C = e :: D of H splits at two
of its vertices into arcs carrying D₁ and D₂, each with an edge that the graph F does not
have; suppose R is a list of edges of F; and suppose Z₁, Z₂ are cycles of H carrying
D₁ ++ R and D₂ ++ R. If x is inside one of Z₁, Z₂, then some cycle of H encloses x
with strictly fewer edges outside F than C has.
This is everything in the blueprint's crosscut paragraph after "exactly one of the two cycles
R ∪ C₁, R ∪ C₂ encloses x", so a discharger of Graph.Descent has only to produce the
crosscut and decide which side. The splitting of the cycle is Graph.IsCycleThrough.split_at
and the two spliced cycles are Graph.exists_spliced_cycle; both hand back exactly the
permutation statements assumed here.
The chain #
The hypotheses of lem:outer-chain. Γ 0, …, Γ n are finite 2-connected polygonal
plane graphs, all drawn inside one ambient plane graph G — which is what makes "after
subdividing common points into vertices" true by construction — with consecutive members
sharing at least two vertices and nonconsecutive members disjoint. n ≥ 2 is the blueprint's
k ≥ 3.
At least three graphs.
Every member is drawn inside the ambient plane graph.
- isDrawing : G.IsDrawing drawing
The ambient graph is a plane graph.
- polygonal (g : β) : g ∈ G.edgeSet → Schoenflies.IsPolygonal (edgeArc drawing g)
Its edges are polygonal.
Every member is finite.
- twoConnected (p : ℕ) : p ≤ n → (Γ p).IsTwoConnected
Every member is 2-connected.
- meet (p : ℕ) : p + 1 ≤ n → ∃ (a : Schoenflies.Plane) (b : Schoenflies.Plane), a ≠ b ∧ a ∈ (Γ p).vertexSet ∧ a ∈ (Γ (p + 1)).vertexSet ∧ b ∈ (Γ p).vertexSet ∧ b ∈ (Γ (p + 1)).vertexSet
Consecutive members have at least two vertices in common.
- disjoint (p q : ℕ) : p ≤ n → q ≤ n → p + 1 < q → Disjoint ((Γ p).pointSet drawing) ((Γ q).pointSet drawing)
Nonconsecutive members are disjoint — as point sets, which is what the blueprint means and what the crosscut step of the proof uses.
Instances For
A point of a block's drawing lies on one of its members.
"Γ j meets the earlier chain only through Γ (j-1)." The block Γ i ∪ ⋯ ∪ Γ (i+m) and
the member Γ (i+m+2) are disjoint, every pair of indices involved being nonconsecutive. This
is the form the descent step consumes.
Nonconsecutive members share no vertex.
Nonconsecutive members share no edge: an edge of both would be drawn inside both point sets.
The assumed step #
Everything in the blueprint's proof except this one paragraph is discharged below.
The crosscut step of lem:outer-chain, assumed.
Given a cycle C of the block Γ i ∪ ⋯ ∪ Γ (i+m+2) that encloses x, which has an edge of the
last member Γ (i+m+2) outside Γ (i+m+1) and an edge of the earlier chain
Γ i ∪ ⋯ ∪ Γ (i+m) outside Γ (i+m+1), there is a cycle of the same block that encloses x
and has strictly fewer edges outside Γ (i+m+1).
This is the blueprint's paragraph beginning "Minimality of the interval implies that C
contains an edge of Γ j outside Γ (j-1)": choose points a, b in the interiors of the two
edges; each of the two arcs of C from a to b must meet Γ (j-1), because Γ j meets the
earlier chain only through Γ (j-1); take the two maximal subpaths of C ∩ Γ (j-1) they
contain and a minimum-length path R in Γ (j-1) from one to the other; R is a crosscut of
the side of C it lies in, and thm:polygonal-crosscut says exactly one of R ∪ C₁, R ∪ C₂
encloses x. That cycle stays in the block, and one nonempty outside portion of C has been
replaced by R ⊆ Γ (j-1).
It is a statement about a single descent step, not about outer faces, and it does not mention
n except to keep the block inside the chain. A discharging module has
Graph.IsCycleThrough.split_at, Graph.exists_spliced_cycle, Graph.IsDrawing.arcs_of_split
and Schoenflies.crosscutSplitsRegion available.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Descent, split into a combinatorial and a geometric half #
Graph.Descent is what the main theorem consumes, and Graph.descent_of_crosscut derives it
from the two halves below, doing the splicing and the edge count in between. A module wishing to
discharge Descent may therefore prove these two instead, which is the natural division of
labour: CrosscutExists is a statement about walks in graphs with no geometry in it beyond the
disjointness of nonconsecutive members, and CrosscutEncloses is a statement about one
plane graph, one cycle and one crosscut, with no chain in it at all.
The combinatorial half of the descent step. The blueprint's "choose points a, b in the
relative interiors of these two edges … each of those two arcs must meet Γ (j-1) … choose such
a path R of minimum length": from a cycle of the block enclosing x with an edge of the last
member and an edge of the earlier chain outside Γ (j-1), build a crosscut of that cycle inside
Γ (j-1).
The hypothesis that x is enclosed is carried along because it costs nothing and a discharger
may want it; the construction in the blueprint does not use it.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The hypothesis of lem:outer-chain on consecutive pairs: x is in the outer face of every
Γ p ∪ Γ (p+1) — off its drawing, with an unbounded face through it. A consumer proves the
second clause with Graph.beyondSquare_subset_face, and Graph.unbounded_face_unique is what
makes "an unbounded face" the outer face.
Equations
- Graph.OuterOnPairs Γ drawing n x = ∀ (p : ℕ), p + 1 ≤ n → x ∈ (Graph.chainUnion Γ p 1).exterior drawing ∧ ¬Bornology.IsBounded ((Graph.chainUnion Γ p 1).face drawing x)
Instances For
The base case, j = i + 1. No cycle of a consecutive pair encloses a point of that
pair's outer face.
The base case, j = i. A single member of the chain is contained in a consecutive pair
— the one after it, or, at the far end, the one before it.
The double minimal-counterexample argument. No block of the chain encloses x.
The outer induction is on the length m of the block — the blueprint's "choose indices i ≤ j
with j - i minimum". Inside it, for a block of length at least two, the induction on c is
the blueprint's "choose C so that the number of its edges outside Γ (j-1) is minimum".
x is off the whole chain: it is off every consecutive pair, and every member belongs to
one.
lem:outer-chain (outer face of a chain). If x is in the outer face of every
consecutive pair Γ p ∪ Γ (p+1), then x is in the outer face of Γ 0 ∪ ⋯ ∪ Γ n.
"In the outer face" is x ∈ exterior … ∧ ¬ IsBounded (face … x); by
Graph.unbounded_face_unique there is only one unbounded face, so this really does say x is
in the outer face.