Documentation

LeanPool.Schoenflies.OverlayGraph

The polygonal overlay, assembled into a plane graph #

Schoenflies/Overlay.lean does the separating half of lem:polygonal-overlay: after cutting at the right points, two pieces of the subdivision whose interiors meet are the same segment, in one order or the other. This module turns that into a plane graph.

The only thing standing between "the same segment" and "the same edge" is that a segment has two names, (a, b) and (b, a). orientPiece removes the choice by fixing a total order on plane points — Precedes, lexicographic in the coordinates — and putting the smaller end first. Two names for one segment then orient to the same name, so "represent each duplicated subsegment once" stops being deduplication up to reversal and becomes deduplication up to equality, which List.dedup does without knowing any geometry. Nothing geometric rests on which order it is: only precedes_total and eq_of_precedes_of_precedes are ever used.

The graph is overlayGraph, a Graph Plane Piece: its edges are the oriented, deduplicated pieces, and its vertices are their ends. IsLink P x y says that P is an edge and that x and y are its two ends in one order or the other — which is why eq_or_eq_of_isLink_of_isLink is a two-line case split rather than an argument.

The three clauses of Graph.IsDrawing come out as follows.

Blueprint #

A total order on plane points #

It exists to pick one of two points canonically. Only two facts about it are used: that it compares any two points, and that it cannot rank two distinct points both ways round.

The lexicographic order on plane points: first coordinate, then second.

Equations
Instances For
    theorem Schoenflies.eq_of_precedes_of_precedes {p q : Plane} (h : Precedes p q) (h' : Precedes q p) :
    p = q

    The canonical orientation of a piece #

    noncomputable def Schoenflies.orientPiece (P : Piece) :

    A piece with its ends in lexicographic order. Two names for one segment orient to the same name; that is the whole purpose.

    Equations
    Instances For
      @[simp]

      Orienting does not move the segment.

      @[simp]

      Nor the interior.

      theorem Schoenflies.orientPiece_ends (P : Piece) (z : Plane) :
      z = (orientPiece P).1 ∨ z = (orientPiece P).2 ↔ z = P.1 ∨ z = P.2

      Nor which points are its ends.

      The output is oriented — which is what makes orientPiece idempotent.

      @[simp]

      Orienting forgets the name it was given. This is the fact that makes deduplication carry no geometry.

      Deduplication #

      cover only sees which pieces are in the list, so both steps of the assembly — orienting and deduplicating — leave it alone.

      theorem Schoenflies.cover_eq_of_mem_iff {l₁ l₂ : List Piece} (h : ∀ (P : Piece), P ∈ l₁ ↔ P ∈ l₂) :
      cover l₁ = cover l₂
      noncomputable def Schoenflies.overlayPieces (pieces : List Piece) (points : List Plane) :

      The edges of the overlay: the pieces of the subdivision, oriented and then deduplicated. Orienting is what makes the deduplication a plain list operation.

      Equations
      Instances For
        theorem Schoenflies.mem_overlayPieces {pieces : List Piece} {points : List Plane} {P : Piece} :
        P ∈ overlayPieces pieces points ↔ ∃ Q ∈ subdivide pieces points, orientPiece Q = P
        theorem Schoenflies.overlayPieces_nodup (pieces : List Piece) (points : List Plane) :
        (overlayPieces pieces points).Nodup

        The list of edges has no duplicates.

        theorem Schoenflies.overlayPieces_cover (pieces : List Piece) (points : List Plane) :
        cover (overlayPieces pieces points) = cover pieces

        Neither orienting nor deduplicating changes what the pieces occupy.

        theorem Schoenflies.overlayPieces_nondeg {pieces : List Piece} (points : List Plane) (hnd : ∀ P ∈ pieces, P.Nondeg) (P : Piece) :
        P ∈ overlayPieces pieces points → P.Nondeg
        theorem Schoenflies.overlayPieces_ends_cut {pieces : List Piece} {points : List Plane} (hEnds : EndsAreCut pieces points) (P : Piece) :
        P ∈ overlayPieces pieces points → ∀ (z : Plane), z = P.1 ∨ z = P.2 → z ∈ points

        Every end of every edge is a cut point: orienting does not change which points are ends, and subdivide_ends_are_cuts covers the subdivision.

        theorem Schoenflies.overlayPieces_avoids {pieces : List Piece} {points : List Plane} (hnd : ∀ P ∈ pieces, P.Nondeg) (p : Plane) :
        p ∈ points → ∀ P ∈ overlayPieces pieces points, p ∉ P.interior

        And a cut point is interior to no edge.

        theorem Schoenflies.overlayPieces_disjoint_interiors {pieces : List Piece} {points : List Plane} (hnd : ∀ P ∈ pieces, P.Nondeg) (hEnds : EndsAreCut pieces points) (hMeets : MeetsAreCut pieces points) {P Q : Piece} (hP : P ∈ overlayPieces pieces points) (hQ : Q ∈ overlayPieces pieces points) (hPQ : P ≠ Q) {x : Plane} (hxP : x ∈ P.interior) :
        x ∉ Q.interior

        Distinct edges have disjoint interiors. This is where separation is spent: two pieces sharing an interior point are the same segment, so after orienting they are the same name, and a deduplicated list holds a name once.

        The graph #

        The ends of a list of pieces.

        Equations
        Instances For
          noncomputable def Schoenflies.overlayGraph (pieces : List Piece) (points : List Plane) :

          The overlay graph: the oriented deduplicated pieces as edges, their ends as vertices.

          An edge links x and y exactly when they are its two ends in one order or the other, which is what makes eq_or_eq_of_isLink_of_isLink a case split with no content.

          Equations
          • One or more equations did not get rendered due to their size.
          Instances For
            @[simp]
            theorem Schoenflies.overlayGraph_vertexSet {pieces : List Piece} {points : List Plane} :
            (overlayGraph pieces points).vertexSet = endSet (overlayPieces pieces points)
            @[simp]
            theorem Schoenflies.overlayGraph_mem_edgeSet {pieces : List Piece} {points : List Plane} {P : Piece} :
            P ∈ (overlayGraph pieces points).edgeSet ↔ P ∈ overlayPieces pieces points
            theorem Schoenflies.overlayGraph_mem_vertexSet {pieces : List Piece} {points : List Plane} {v : Plane} :
            v ∈ (overlayGraph pieces points).vertexSet ↔ ∃ P ∈ overlayPieces pieces points, v = P.1 ∨ v = P.2
            theorem Schoenflies.overlayGraph_inc {pieces : List Piece} {points : List Plane} {P : Piece} {v : Plane} (hP : P ∈ overlayPieces pieces points) (h : v = P.1 ∨ v = P.2) :
            (overlayGraph pieces points).Inc P v

            An end of an edge is a vertex.

            The drawing #

            A straight edge is drawn by the affine parametrization of its segment, so the arc clause of IsDrawing is isArcBetween_segment and nothing else.

            noncomputable def Schoenflies.segmentDrawing (P : Piece) :

            Every piece is drawn by the affine parametrization of its segment.

            Equations
            Instances For
              theorem Schoenflies.overlayGraph_isDrawing (pieces : List Piece) (points : List Plane) (hnd : ∀ P ∈ pieces, P.Nondeg) (hEnds : EndsAreCut pieces points) (hMeets : MeetsAreCut pieces points) :

              The overlay graph is a plane graph.

              theorem Schoenflies.overlayGraph_pointSet (pieces : List Piece) (points : List Plane) :
              (overlayGraph pieces points).pointSet segmentDrawing = cover pieces

              What the graph occupies is what its edges occupy: every vertex is an end of an edge, so the vertices add nothing.

              Finiteness #

              Without this the whole face and outer-face machinery of Schoenflies/Graph/Drawing.lean and Schoenflies/Graph/OuterFace.lean is inapplicable to the overlay, since every statement there carries a [G.Finite] instance. Both sets come from one finite list, so it is immediate — but it has to be said, and the instance has to be found by typeclass search at the call site.

              instance Schoenflies.overlayGraph_finite (pieces : List Piece) (points : List Plane) :
              (overlayGraph pieces points).Finite
              theorem Schoenflies.polygonal_overlay (pieces : List Piece) (hnd : ∀ P ∈ pieces, P.Nondeg) :

              Lemma 3.7 (polygonal overlay). Finitely many nondegenerate segments are the point set of a finite plane graph.

              The finiteness clause is not decoration. Every statement about faces and about the outer face carries a [G.Finite] instance, and an existential that produced only IsDrawing would hide the graph behind a binder with no way to recover the instance — so the overlay could not be fed to the face machinery at all.