The subdivided boundary of a square is a cycle #
Schoenflies.SquaresTwoConnected, the last hypothesis between this library and
thm:jordan, discharged.
What has to be built #
Schoenflies.squareGraph pieces points c r is the part of a polygonal overlay lying on the
boundary of the axis-parallel square of ℓ^∞-radius r about c, when the four sides of that
square are among the overlay's source segments. It is the subdivided boundary of the square,
so it is a cycle, and Graph.IsLongCycle.isTwoConnected finishes. What is missing on main
is the cyclic order of the cut points: the graph is presented as a set of edges, with
nothing saying which edge follows which.
The route #
One real-valued coordinate does the whole of it. Schoenflies.sqCoord c r is the perimeter
coordinate: the distance travelled from the north-east corner going counterclockwise round the
boundary, a number in [0, 8r). It is affine on each side, and it is the ordering tool of
Schoenflies/SegmentOrder.lean — distance from the side's first corner — with an offset.
Graph.IsIncWalkis a walk along which a chosen real function strictly increases. Such a walk is automatically a path (Graph.IsIncWalk.isPath): the freshness clause ofGraph.IsPathsays the vertex a step departs from is not visited later, and a vertex visited later has a strictly larger value. This is the only place where "the cut points are in order" is turned into a combinatorial statement, and it replaces every argument about distinctness of vertices.Schoenflies.exists_incWalk_of_chainis the one-dimensional heart: a finite family of nondegenerate segments inside one ambient segment[a, b], with pairwise disjoint interiors, with every end of every one of them interior to none of them, and covering[a, b], is a chain fromatob— anIsIncWalkfor the coordinatedist a ·whose edge list is exactly the family. The induction is on the number of segments, and the step isSchoenflies.exists_next_piece: the piece leaving the current point is the one covering a point just beyond it, "just" being measured by the least end-coordinate strictly ahead.- The four sides are chained separately and concatenated. The concatenation is a closed walk
at the north-east corner, so its last edge is split off (
Graph.IsIncWalk.split_last) and becomes the distinguished edge ofGraph.IsCycleThrough.
Blueprint #
Schoenflies.squaresTwoConnected— the hypothesisSchoenflies.SquaresTwoConnectedofthm:arc-complement, discharged. In the blueprint this is the unstated step of "it follows inductively fromlem:union-two-connectedthatΓ_iis 2-connected": the induction starts from one subdivided square boundary, and that it is a cycle is taken for granted there.Schoenflies.exists_isLongCycle_squareGraph— the cycle itself, with the clause that makes it usable: the cycle graph issquareGraph, not merely a subgraph of it. A consumer wanting the boundary cycle of a square as an object, rather than 2-connectedness, takes it from here.Schoenflies.exists_incWalk_insideEdges— the subdivision of one source segment of a polygonal overlay, as a path.Schoenflies/SquareMeshConnected.leannames exactly this as the theorem missing frommainthat blocksprop:anchored-square-meshfrom being carried over toSchoenflies.squareMesh. Its own ground isSchoenflies.exists_incWalk_of_chain, which knows nothing about overlays either.Graph.IsIncWalk— no blueprint statement; it is the device that makeslem:polygonal-overlay's cut points into an ordered cycle.
Part 1: a walk along which a real function increases #
A walk along which f strictly increases. The point of the definition is
Graph.IsIncWalk.isPath: a walk that cannot come back is a path, and no argument about the
distinctness of the vertices has to be made anywhere else.
- nil
{α : Type u_1}
{β : Type u_2}
{G : Graph α β}
{f : α → ℝ}
{x : α}
(hx : x ∈ G.vertexSet)
: G.IsIncWalk f x [] x
The empty walk, at a vertex of the graph.
- cons
{α : Type u_1}
{β : Type u_2}
{G : Graph α β}
{f : α → ℝ}
{u w v : α}
{e : β}
{W : List β}
(hl : G.IsLink e u w)
(hf : f u < f w)
(hW : G.IsIncWalk f w W v)
: G.IsIncWalk f u (e :: W) v
A step to a vertex of strictly larger value, followed by an increasing walk.
Instances For
An increasing walk is a path. The vertex a step departs from has a strictly smaller value than everything the rest of the walk visits, so it is not among them.
The function may be replaced by any function agreeing with it on the visited vertices.
Shifting the function by a constant changes nothing. Each side of the square carries the distance from its own first corner; the shifts are what glue the four into one coordinate.
Splitting off the last step. An increasing walk between distinct vertices has a last
edge, and what precedes it is again an increasing walk. This is what turns the closed walk
round the square into the edge plus detour that Graph.IsCycleThrough asks for.
Part 2: a tiling of one segment is a chain #
Everything here happens along a single ambient segment [a, b], and the coordinate is the one
Schoenflies/SegmentOrder.lean supplies: the distance from a. A finite family of
nondegenerate pieces inside [a, b], with disjoint interiors, no end interior to any of them,
and covering the part of [a, b] ahead of the current point, is walked through from the current
point to b, one piece at a time, in increasing distance from a.
The two ends of a piece, near end first. Every one-dimensional citation wants them in that order, and which of the two names is the near one is none of the caller's business.
The data of the induction: a finite family of pieces filling the part of [a, b] from
p onwards.
cover asks nothing at b itself, and cannot: at p = b the family is empty, and an empty
family covers nothing.
- finite : E.Finite
Finitely many pieces.
None of them a point.
All of them ahead of
p.The current point is on the ambient segment.
Every end of every piece is interior to none of them — the cut-point condition.
Distinct pieces have disjoint interiors.
Every point ahead of
p, short ofb, is on a piece.
Instances For
The current point is not interior to any piece: every piece lies ahead of it, so its near
end is already at or beyond p.
The piece leaving the current point.
Let m be the least coordinate of an end of a piece strictly ahead of p (the far end b
being counted, so that there is one). A point x strictly between p and m is covered by
some piece; that piece's near end is at or before p, because it is at most x's coordinate,
which is short of m; and it is at or after p, because p is interior to no piece and the
far end is beyond p. So the near end is p.
Stated with explicit hypotheses rather than with Schoenflies.IsPieceChain, because it is
applied once at the current point and once at the point one step ahead, and at the latter
the family is no longer confined to what lies beyond.
A tiling of a segment is a chain. The pieces are walked through from p to b, one
at a time, in increasing distance from a; the walk's edge list is exactly the family.
The induction is on the number of pieces, and the step removes the piece leaving p. Three
of the seven clauses of Schoenflies.IsPieceChain are inherited verbatim by the smaller
family; the work is in re-establishing the other two — that everything left lies beyond the
new point, and that it still covers.
Part 3: the perimeter coordinate of a square boundary #
The four sides of the square are axis-parallel, so on each of them the Euclidean distance from
the side's first corner is the difference of one coordinate. Schoenflies.sqCoord glues the
four into one function on the plane: the distance travelled from the north-east corner going
counterclockwise. It is dist from the side's first corner plus a multiple of 2r, and that
is the only property of it that is ever used.
The distance from a side's first corner, in coordinates #
Where two sides meet #
The perimeter coordinate #
The perimeter coordinate: the distance travelled from the north-east corner going counterclockwise round the boundary of the square. Junk away from the boundary.
The four branches agree at the three corners where consecutive sides meet, so the value is the geometric one on all four sides at once — with the single exception of the north-east corner itself, where the walk both starts and would end. That exception is the whole reason the closing edge of the cycle has to be split off.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Part 4: the overlay edges on one side #
A nondegenerate straight segment inside the boundary of a square lies inside one side: its
midpoint is on the boundary, so one of the two coordinates is extreme there, and an average of
two numbers at most c i + r can only equal c i + r when both are. That is
Schoenflies.exists_side_of_mem_squareEdges, and it is the only genuinely two-dimensional step
in the file.
The edges of the overlay lying on one prescribed side of the square.
Equations
- Schoenflies.sideEdges pieces points c r S = {Q : Schoenflies.Piece | Q ∈ Schoenflies.squareEdges pieces points c r ∧ Q.seg ⊆ S.seg}
Instances For
Every edge of the overlay on a square lies on one of the four sides.
Part 5: the four sides, chained #
Each side of the square is a source segment of the overlay, so the edges lying on it tile it, and Part 2 walks through them. The four walks are then glued at the corners.
Every edge of the graph is drawn where its own name says.
A side of the square lies on its boundary.
The subdivision of one source segment #
Nothing about squares enters here. Schoenflies/SquareMeshConnected.lean records this as the
theorem missing from main — "the subdivision of a segment at a finite point set is a path" —
that blocks prop:anchored-square-mesh from being carried over to Schoenflies.squareMesh.
The edges of an overlay lying inside one of its source segments.
Equations
- Schoenflies.insideEdges pieces points P₀ = {Q : Schoenflies.Piece | Q ∈ Schoenflies.overlayPieces pieces points ∧ Q.seg ⊆ P₀.seg}
Instances For
The edges inside one source segment tile it. Every clause is a property of the
polygonal overlay already on main; the covering clause is the one that needs P₀ to be a
source segment.
The subdivision of one source segment of an overlay is a path, from one end of the segment to the other, taking every overlay edge inside it exactly once, in increasing distance from the first end.
The edges on one side tile it.
The far corner of a side is a vertex: it is an end of a source segment, hence a cut point, and it lies on the boundary.
The walk along one side, from its first corner to its second, taking every edge of the overlay that lies on it exactly once, in increasing distance from the first corner.
What a walk of the square graph visits stays inside anything its edges stay inside.
Part 6: the cycle, and SquaresTwoConnected #
The four walks are concatenated into a closed walk at the north-east corner. The perimeter
coordinate increases along the first three sides and along all of the fourth but its last step,
which returns to the corner where the coordinate is 0; so that step is split off and becomes
the distinguished edge of Graph.IsCycleThrough.
The boundary cycle of a subdivided square. The whole of squareGraph is a cycle: an
edge e, a detour D running the other way round, and a third vertex. The second clause is
what makes the first usable — Graph.IsLongCycle.isTwoConnected proves the cycle graph
2-connected, and here the cycle graph is the graph itself.
The part of a polygonal overlay on the boundary of one of its squares is 2-connected.
It is a cycle through at least four vertices — the corners — so
Graph.IsLongCycle.isTwoConnected finishes.
Schoenflies.SquaresTwoConnected, discharged. Substituting this into
Schoenflies.exists_face_of_notMem_arc makes thm:arc-complement, lem:accessible-dense and
thm:jordan without an auxiliary separation hypothesis.