Realizing an edge subdivision #
Schoenflies/GeneratedStructure.lean performs the abstract edge subdivision
(CellStructure.subdivideEdge) and states what it means for a realization of the subdivided
structure to refine a realization of the old one (SubdivData.IsRefinement);
Schoenflies/CellulationInvariants.lean propagates assertions (i), (iv) and (vii) across such a
refinement. Nothing built such a realization. This module does.
The construction is the blueprint's own sentence — "the corresponding point is inserted into the
corresponding edge using the edge parametrization" — made into data: pick a parameter
t ∈ (0,1), put the new 0-cell at R.drawing d.edge t, and draw the two new 1-cells with the
two halves of the old parametrization, each rescaled to [0,1].
The orientation of the drawn edge #
IsDrawing.edge_param is deliberately orientation-free: it says
G.IsLink e (drawing e 0) (drawing e 1), so drawing d.edge 0 may be either pos d.left or
pos d.right. But d.newEdge₁ runs from d.left to d.newVertex by definition of
subdivideEdge, so which half of the parametrization draws it is not fixed in advance.
Assuming drawing d.edge 0 = pos d.left would be a false hypothesis for half of all inputs, and
the caller cannot repair it (swapping d.left with d.right in the SubdivData also swaps the
two new edge names, producing a different abstract structure). So the orientation is read off
instead: SubdivData.leftParam is the endpoint parameter, 0 or 1, at which the drawn edge
sits at d.left. Every statement below is orientation-free; only the two lemmas
SubdivData.drawing_leftParam and SubdivData.drawing_rightParam look inside.
Because of that, the construction is phrased with Schoenflies.subarc — the general affine
reparametrization already on main — rather than with firstHalf / secondHalf, which are the
two halves in the standard orientation and are recorded here as the named special case.
No side conditions #
SubdivData.realize takes no geometric hypothesis beyond t ∈ Ioo 0 1. Everything else it
needs — that d.edge is drawn, injectively and continuously, between the positions of d.left
and d.right, and that an interior point of a drawn edge is not a vertex — is already carried by
CellStructure.Realization, and is extracted here rather than assumed.
The transported skeleton homeomorphism is not here, but it exists #
Closed, in Schoenflies/RealizeSubdivHomeo.lean (SubdivData.realizeHomeo), on top of
Schoenflies/ArcMonotone.lean, which supplies the missing fact named at the end of this
section. What follows is the record of why it could not be done here.
SkeletonHomeo.realize is absent from this module. Six of its eight fields are immediate —
skeletonSet_realize below says the realized 1-skeleton is literally the same set after a
subdivision, so the map, its inverse, both continuity clauses and both inverse clauses transport
verbatim, and
pos_apply at the new 0-cell is the statement g.toFun (R₁.drawing d.edge t₁) = R₂.drawing d.edge t₂ that a caller choosing corresponding parameters supplies anyway.
What is missing is edgeArc_image at the two new edges: that g carries the half arc from
R₁.pos d.left to the new source point onto the half arc from R₂.pos d.left to the new target
point. This is true but is not implied by the SkeletonHomeo data pointwise: it needs the fact
that a homeomorphism between two arcs matching their endpoints is monotone, hence carries
initial subarcs to initial subarcs. That fact was not on main when this module was written,
and assuming the two clauses would have been assuming the conclusion, so nothing was stated
here. Schoenflies/ArcMonotone.lean
now proves it — ArcMatch, transferParam, image_image_uIcc — and
Schoenflies/RealizeSubdivHomeo.lean builds the transported homeomorphism from it, orientation
of the two realizations handled rather than assumed.
Blueprint #
def:generated-structure, operation 1 (edge subdivision) — the geometric half of the operation, whose abstract half isCellStructure.subdivideEdge.lem:cellulation-invariants(i) and (iv), the paragraph "Suppose first that an open edgeeis subdivided at a new vertexv":SubdivData.isRefinement_realizeproduces exactly the hypotheses thatSubdivData.IsRefinement.isCellDecomposition_and_isFaceJordanconsumes.
Declarations:
Schoenflies.uIcc_union_uIcc,Schoenflies.uIcc_inter_uIcc— a parameter interval cut at an interior point.Schoenflies.subarc_image_union,Schoenflies.subarc_image_inter— the two subarcs of a cut cover the arc and meet exactly at the cut point.Schoenflies.firstHalf,Schoenflies.secondHalf— the two halves of a drawn edge in the standard orientation, with their endpoint values, continuity, injectivity, images, meet and union.Schoenflies.CellStructure.SubdivData.leftParam/rightParam— the orientation of the drawn edge.Schoenflies.CellStructure.SubdivData.realize— the realization of the subdivided structure.Schoenflies.CellStructure.SubdivData.isRefinement_realize— it refines the given one.Schoenflies.CellStructure.SubdivData.realize_isCellDecomposition_and_isFaceJordan— the induction step oflem:cellulation-invariantsover the first constructor, now constructed with all necessary data constructed here.Schoenflies.CellStructure.SubdivData.skeletonSet_realize— a subdivision does not move the realized 1-skeleton.
Cutting a parameter interval at an interior point #
The two subarcs of a cut #
The two halves of a drawn edge #
The special case a = 0, b = 1 of the previous section, in the notation a consumer holding a
Graph.IsDrawing writes.
The first half of a drawn edge, rescaled to [0, 1].
Equations
- Schoenflies.firstHalf drawing e t = Schoenflies.subarc (drawing e) 0 t
Instances For
The second half of a drawn edge, rescaled to [0, 1].
Equations
- Schoenflies.secondHalf drawing e t = Schoenflies.subarc (drawing e) t 1
Instances For
The two halves cover the drawn edge.
The two halves meet exactly at the cut point.
Each half is an arc between the corresponding endpoint and the cut point.
The orientation of the drawn subdivided edge #
What the realization already knows about the subdivided edge: it is an edge of the drawn skeleton.
The orientation of the drawn subdivided edge: the endpoint parameter, 0 or 1, at
which R.drawing d.edge sits at R.pos d.left.
IsDrawing.edge_param fixes only the unordered pair of endpoint values, so this cannot be read
off the structure; it is decided by a case distinction, once, here.
Instances For
The endpoint parameter at which the drawn subdivided edge sits at R.pos d.right.
Equations
- d.rightParam R = 1 - d.leftParam R
Instances For
The two endpoint parameters land on the two endpoints. The only lemma that looks inside
leftParam; everything downstream is orientation-free.
The two endpoint parameters span the whole parameter interval, in whichever order.
An interior point of a drawn edge is not a vertex. The one geometric fact the
construction needs that is not simply read off a field, and the reason SubdivData.realize
needs no side condition.
Freshness of the three new names, in the forms used below #
The links of the subdivided skeleton #
An old edge other than the subdivided one keeps its ends.
…and gains none: for an old edge the two skeleta have the same links.
The realization of the subdivided structure #
The positions after the subdivision: the new 0-cell goes to the point of the drawn edge at
parameter t, and every old 0-cell stays where it was.
Instances For
The parametrizations after the subdivision: the two new 1-cells are drawn by the two halves
of the old parametrization, cut at t and rescaled to [0, 1]; every old 1-cell keeps its own.
d.newEdge₁ runs from d.left, so the half that draws it starts at d.leftParam R, which is
0 or 1 according to the orientation of the old parametrization.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The open cells after the subdivision: the new 0-cell is the new point, each new open 1-cell is its half arc without its two endpoints, and every surviving cell is unchanged.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The drawn skeleton after the subdivision.
Equations
- d.realizeGraph R t = Graph.map (d.realizePos R t) d.skeleton
Instances For
The two half arcs #
The two cell-shape fields of a realization #
Every 0-cell of the subdivided structure is realized by its point.
Every 1-cell of the subdivided structure is realized by its open arc.
Distinct 0-cells of the subdivided structure sit at distinct points: the new one is an interior point of a drawn edge, so it is none of the old ones.
The two new arcs cover the old one.
The two new arcs meet exactly at the new point.
The far endpoint of the old edge misses the near half.
The new point lies on no old edge but the subdivided one.
The subdivided drawn skeleton #
An edge of the subdivided drawn skeleton that is neither new is an old edge, and not the subdivided one.
For an old edge the two drawn skeleta have the same links.
A vertex on the first new arc is one of its two ends.
A vertex on the second new arc is one of its two ends.
Where two edges of the subdivided drawing meet #
The two new edges meet exactly at the new vertex.
The first new edge meets an old edge only at the position of d.left.
The second new edge meets an old edge only at the position of d.right.
Two old edges meet where they met before.
The subdivided drawing #
The subdivided data really is a drawing.
The two new open edges, as arcs #
The first new edge is drawn as an arc from the position of d.left to the new point.
The second new edge is drawn as an arc from the new point to the position of d.right.
The realization of the subdivided structure #
The realization of an edge subdivision. The new 0-cell goes to the point of the drawn
edge at parameter t, the two new 1-cells are drawn by the two halves of that parametrization,
and every surviving cell is exactly where it was.
There is no geometric side condition: everything the construction needs is already carried by
R, and is extracted by the lemmas above rather than assumed.
Equations
- d.realize R t ht = { pos := d.realizePos R t, drawing := d.realizeDrawing R t, injOn_pos := ⋯, isDrawing := ⋯, cell := d.realizeCell R t, cell_vertex := ⋯, cell_edge := ⋯ }
Instances For
The realization refines the old one #
The old open edge is cut into the two new open edges and the new 0-cell.
The subdivided realization refines the given one — every field of
SubdivData.IsRefinement. With IsRefinement.isCellDecomposition_and_isFaceJordan this hands a
consumer IsCellDecomposition, IsFaceJordan and Refines at the new stage.
The whole induction step over the first constructor, constructed. One edge subdivision of a realization satisfying (i) and (vii) produces a realization satisfying (i) and (vii) and refining it, constructing the refined realization in the conclusion.
The subdivision does not move the skeleton #
Cutting an edge in two adds a point that was already on the drawing and replaces one arc by two whose union is that arc. So the realized 1-skeleton is literally the same set — which is what lets a skeleton homeomorphism be transported across a subdivision without being rebuilt.
An edge subdivision does not move the realized 1-skeleton.