Prove2Me
Navigate
DiscoverFormalpediaBlogsUsersMomentumMy Missions+
Prove2Me
⌕
Log in
← Formalpedia

Cycle cuts, dual separation, and side reconstruction

Definition
P2MAssembly_Chapter35Plane_Part2

by xiangyazi24 · Sep 12, 2026 · Mathlib c5ea003 (Lean v4.30.0)

book-chapter-39combinatorial-mapsgraph-theorylean4proofs-from-the-book

This part contains the second cut-and-cap map, the cyclic index shift and its inverse, face-correction permutations, swap-word counting and orbit-compression certificates. It also defines dual relations avoiding a chosen cycle, the corresponding component and face-orbit counts, connectivity within either side and separation of opposite sides, and second-side boundary reconstruction and confinement interfaces. A certificate’s required equalities and connectivity properties are part of its stated data; their presence in a structure definition alone is not a proof of existence.

Definition code
import Init
import Mathlib
import Mathlib.Analysis.LocallyConvex.Separation
import Mathlib.Analysis.InnerProductSpace.Dual
import Mathlib.Analysis.Convex.Topology
import Mathlib.Analysis.Convex.Combination
import Mathlib.Data.Finset.Basic
import Definitions.Def_P2MAssembly_Chapter35Plane_Part1

set_option autoImplicit true


/- Original source header (imports hoisted):
import Mathlib
-/
/- Source module: ProofsInTheBook.PlanarMap -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv



namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]













































end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMap
-/
/- Source module: ProofsInTheBook.PlaneSimpleGraph -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open ProofsInTheBook.PlanarMap



namespace PlaneSimpleGraph

variable {V D : Type*} [Fintype V] [DecidableEq V] [Fintype D] [DecidableEq D]













end PlaneSimpleGraph

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMap
-/
/- Source module: ProofsInTheBook.PlanarMapEuler -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap.CombMap

open ProofsInTheBook.PlanarMap

variable {D : Type*} [Fintype D] [DecidableEq D]

















end ProofsInTheBook.PlanarMap.CombMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapEuler
-/
/- Source module: ProofsInTheBook.PlanarMapSimple -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

























































end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapEuler
-/
/- Source module: ProofsInTheBook.PlanarMapDelete -/
section
set_option autoImplicit true




namespace Equiv.Perm

open Equiv

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace DeleteSet





















end DeleteSet

open DeleteSet











end Equiv.Perm

namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

































































section TwoEdgePathObstruction























end TwoEdgePathObstruction

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapSimple
-/
/- Source module: ProofsInTheBook.PlanarMapBoundary -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]













namespace BoundaryPath

variable {M : CombMap D} {u v : M.Vertex}











end BoundaryPath







namespace BoundaryCycle

variable {M : CombMap D} {f : M.Face}







































namespace Chord

variable {C : BoundaryCycle M f} {u v : M.Vertex}



end Chord

end BoundaryCycle





namespace BoundaryArcSplit

variable {M : CombMap D} {f : M.Face} {C : BoundaryCycle M f} {u v : M.Vertex}









end BoundaryArcSplit



namespace BoundaryCycle

variable {M : CombMap D} {f : M.Face} {C : BoundaryCycle M f} {u v : M.Vertex}











end BoundaryCycle



end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapBoundary
-/
/- Source module: ProofsInTheBook.PlanarMapNearTriangulation -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]















namespace BoundaryCycle

variable {M : CombMap D} {f : M.Face}





end BoundaryCycle







namespace NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)





























end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapNearTriangulation
import ProofsInTheBook.PlanarMapDelete
-/
/- Source module: ProofsInTheBook.PlanarMapFilteredRotation -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace FilteredRotation

variable {D : Type*} [Fintype D] [DecidableEq D]























namespace ContiguousInterval

variable {σ : Equiv.Perm D} {Del : Finset D} {n : ℕ}

















end ContiguousInterval



section FreshDart

variable {K : Type*} [Fintype K] [DecidableEq K]















variable (ρ : Equiv.Perm K) (a₀ a₁ : K)





variable {ρ a₀ a₁}





variable (ρ a₀ a₁)















variable {ρ a₀ a₁}







end FreshDart

end FilteredRotation

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapFilteredRotation
-/
/- Source module: ProofsInTheBook.PlanarMapChordSplitData -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)



section ChordDarts

variable {u v : M.Vertex} (h : hNT.outerCycle.Chord u v)



















end ChordDarts



























namespace ChordSplitData

variable {hNT} {u v : M.Vertex}













































end ChordSplitData







end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapChordSplitData
-/
/- Source module: ProofsInTheBook.PlanarMapChordSplit -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]









namespace BoundaryPath

variable {M : CombMap D} {u v : M.Vertex}









end BoundaryPath

namespace NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)

namespace ChordSplitData

variable {hNT} {u v : M.Vertex}





























































































































end ChordSplitData

end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapChordSplit
-/
/- Source module: ProofsInTheBook.PlanarMapSeparation -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)









namespace ChordSplitData

variable {hNT} {u v : M.Vertex}



















end ChordSplitData



namespace ChordSplitData

variable {hNT} {u v : M.Vertex}









end ChordSplitData

end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap


end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapNearTriangulation
-/
/- Source module: ProofsInTheBook.PlanarMapBoundaryFan -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace NearTriangulation

variable {M : CombMap D}











namespace FanTriangle

variable {hNT : NearTriangulation M} {v0 a b : M.Vertex}









end FanTriangle







namespace BoundaryVertexFan

variable {hNT : NearTriangulation M} {v0 : M.Vertex}









end BoundaryVertexFan

variable (hNT : NearTriangulation M) {v0 : M.Vertex}



















end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapBoundaryFan
import ProofsInTheBook.PlanarMapDelete
-/
/- Source module: ProofsInTheBook.PlanarMapBoundaryDelete -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace NearTriangulation

variable {M : CombMap D}
















namespace BoundaryDeletionData

variable {hNT : NearTriangulation M} {d0 : D}















end BoundaryDeletionData










end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapBoundaryDelete
-/
/- Source module: ProofsInTheBook.PlanarMapFanSurgery -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace NearTriangulation

variable {M : CombMap D}











namespace NeighborRotationOrder

variable {v0 : M.Vertex} {neighbors : List M.Vertex}













end NeighborRotationOrder







namespace FanSurgeryReconstruction

variable {hNT : NearTriangulation M} {d0 : D}

















end FanSurgeryReconstruction









end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
/-
List-coloring primitives (Chapter 35 layer 4).

Design-independent groundwork for the Thomassen five-list-coloring route
(HANDOFF/CH35_DESIGN_ANSWER.md): proper colorings from lists, monotonicity
in the graph and in the lists, and the piecewise gluing lemmas — including
the rooted cut-vertex glue, which is the form that is actually true for
list colorings (naive gluing fails because the two sides may disagree at
the cut vertex).
-/
import Mathlib
-/
/- Source module: ProofsInTheBook.ListColoring -/
section
set_option autoImplicit true


namespace ProofsInTheBook.ListColoring

variable {V α : Type*}



















section Glue

variable {G : SimpleGraph V} {L : V → Finset α} {s t : Set V} {c₁ c₂ : V → α}





end Glue



end ProofsInTheBook.ListColoring

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapSeparation
import ProofsInTheBook.PlanarMapFanSurgery
import ProofsInTheBook.ListColoring
-/
/- Source module: ProofsInTheBook.ThomassenLists -/
section
set_option autoImplicit true




namespace ProofsInTheBook.ThomassenLists

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.ListColoring

variable {D : Type*} [Fintype D] [DecidableEq D]
variable {α : Type*} [DecidableEq α]

namespace CombMap

open ProofsInTheBook.PlanarMap.CombMap





namespace ThomassenLists

variable {M : CombMap D} {hNT : NearTriangulation M}
  {p q : M.Vertex} {L : M.Vertex → Finset α} {cp cq : α}









end ThomassenLists





namespace ChordSplitRegions

variable {M : CombMap D} {hNT : NearTriangulation M}
  {u v p q : M.Vertex} {L : M.Vertex → Finset α} {cp cq : α}















end ChordSplitRegions



section Deletion

variable {M : CombMap D}



























variable {hNT : NearTriangulation M} {d0 : D} {v0 : M.Vertex}







































end Deletion

end CombMap

end ProofsInTheBook.ThomassenLists

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapFanSurgery
-/
/- Source module: ProofsInTheBook.PlanarMapFanConnectivity -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]




















section Reduction

variable (M : CombMap D) (v : D)







end Reduction



namespace NearTriangulation

variable {M : CombMap D}









variable {hNT : NearTriangulation M} {v0 : M.Vertex}

























end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapFanConnectivity
import ProofsInTheBook.PlanarMapFilteredRotation
-/
/- Source module: ProofsInTheBook.PlanarMapFanFaces -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]







namespace NearTriangulation

variable {M : CombMap D} {hNT : NearTriangulation M} {v0 : M.Vertex}











































































end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapFanFaces
-/
/- Source module: ProofsInTheBook.PlanarMapFanMergedOrbit -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

















namespace NearTriangulation

variable {M : CombMap D} {hNT : NearTriangulation M} {v0 : M.Vertex}













































end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapBoundary
-/
/- Source module: ProofsInTheBook.PlanarMapBoundaryArcSplit -/
section
set_option autoImplicit true




set_option maxHeartbeats 1600000
set_option linter.unusedVariables false

namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]



namespace BoundaryCycleData

variable {M : CombMap D} {f : M.Face}













end BoundaryCycleData









namespace DataDartArc

variable {M : CombMap D} {f : M.Face} {K : BoundaryCycleData M f} {u v : M.Vertex}



















end DataDartArc



namespace BoundaryCycleData

variable {M : CombMap D} {f : M.Face}









end BoundaryCycleData



section Casts

variable {M : CombMap D}











end Casts





















namespace BoundaryPath

variable {M : CombMap D} {u v : M.Vertex}







end BoundaryPath



section BPOfDartArc

variable {M : CombMap D}



















end BPOfDartArc



namespace BoundaryCycleData

variable {M : CombMap D} {f : M.Face}







end BoundaryCycleData



namespace BoundaryCycleData

variable {M : CombMap D} {f : M.Face}





end BoundaryCycleData

end CombMap

end ProofsInTheBook.PlanarMap





end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapFanFaces
import ProofsInTheBook.PlanarMapBoundaryArcSplit
-/
/- Source module: ProofsInTheBook.PlanarMapDeletedBoundary -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]





















namespace NearTriangulation

variable {M : CombMap D} {hNT : NearTriangulation M} {v0 : M.Vertex}










namespace DeletedMergedBoundaryCertificate

variable {d0 : D}











end DeletedMergedBoundaryCertificate









end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapFanMergedOrbit
import ProofsInTheBook.PlanarMapDeletedBoundary
-/
/- Source module: ProofsInTheBook.PlanarMapOuterArc -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace NearTriangulation

variable {M : CombMap D} {hNT : NearTriangulation M} {v0 : M.Vertex}




namespace MergedOuterArcData

variable {d0 : D} {r : {d : D // d ∉ M.deleteVertexSet d0}} {outerFace : M.Face}







end MergedOuterArcData















end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapOuterArc
-/
/- Source module: ProofsInTheBook.PlanarMapFanExistence -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]























namespace NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)



















variable {hNT}















end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.ThomassenLists
import ProofsInTheBook.PlanarMapFanExistence
-/
/- Source module: ProofsInTheBook.ThomassenInduction -/
section
set_option autoImplicit true




namespace ProofsInTheBook.ThomassenInduction

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.ListColoring
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap

universe u











section Base

variable {D : Type u} [Fintype D] [DecidableEq D] {α : Type u} [DecidableEq α]
variable {M : CombMap D} {hNT : NearTriangulation M}
variable {p q : M.Vertex} {L : M.Vertex → Finset α} {cp cq : α}



end Base



section Chord

variable {D : Type u} [Fintype D] [DecidableEq D] {α : Type u} [DecidableEq α]
variable {M : CombMap D} {hNT : NearTriangulation M}
variable {p q : M.Vertex} {L : M.Vertex → Finset α} {cp cq : α}



end Chord



section Chordless

variable {D : Type u} [Fintype D] [DecidableEq D] {α : Type u} [DecidableEq α]
variable {M : CombMap D} {hNT : NearTriangulation M}
variable {p q : M.Vertex} {L : M.Vertex → Finset α} {cp cq : α}















end Chordless



section Induction

variable {α : Type u} [DecidableEq α]







end Induction



section Corollaries

variable {D : Type u} [Fintype D] [DecidableEq D] {α : Type u} [DecidableEq α]
variable {M : CombMap D}





end Corollaries



section FiveColor

variable {D : Type u} [Fintype D] [DecidableEq D]
variable {M : CombMap D}



end FiveColor

end ProofsInTheBook.ThomassenInduction

end

/- Original source header (imports hoisted):
import ProofsInTheBook.ThomassenInduction
import ProofsInTheBook.PlanarMapChordSplit
import ProofsInTheBook.PlanarMapSeparation
-/
/- Source module: ProofsInTheBook.ChordSplitNT -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false

namespace ProofsInTheBook.ChordSplitNT

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.ListColoring
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap
open ProofsInTheBook.ThomassenInduction

universe u



variable {D : Type u} [Fintype D] [DecidableEq D] {α : Type u} [DecidableEq α]
variable {M : CombMap D} {hNT : NearTriangulation M}



attribute [instance] ChordSideReconstruction.fintypeDₛ ChordSideReconstruction.decEqDₛ

namespace ChordSideReconstruction

variable {s : Set M.Vertex} {L : M.Vertex → Finset α}

















end ChordSideReconstruction





namespace ChordRecursionData

variable {u v p q : M.Vertex} {L : M.Vertex → Finset α} {cp cq : α}









end ChordRecursionData















end ProofsInTheBook.ChordSplitNT









end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordSplitNT
-/
/- Source module: ProofsInTheBook.ChordSplitEuler -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false

namespace ProofsInTheBook.ChordSplitEuler

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation

universe u

variable {K : Type u} [Fintype K] [DecidableEq K]









section VertexCount

variable (ρ : Equiv.Perm K) {a₀ a₁ : K} (hne : a₀ ≠ a₁)























end VertexCount



section EulerReduction

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)





end EulerReduction



section ChordApplication

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}













end ChordApplication



section NonVacuity













end NonVacuity

end ProofsInTheBook.ChordSplitEuler











end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordSplitEuler
-/
/- Source module: ProofsInTheBook.ChordSideRecon -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false

namespace ProofsInTheBook.ChordSideRecon

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler

universe u

variable {K : Type u} [Fintype K] [DecidableEq K]



section Connectivity

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)
















end Connectivity



section SphereAssembly

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)



end SphereAssembly



section ChordApplication

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}









end ChordApplication



section JordanData

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  (a₀ a₁ : K) (hne : a₀ ≠ a₁)





end JordanData



section NonVacuity







end NonVacuity

end ProofsInTheBook.ChordSideRecon











end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapFilteredRotation
import ProofsInTheBook.PlanarMapSeparation
-/
/- Source module: ProofsInTheBook.PlanarMapCutCap -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]





namespace SimplePrimalCycle

variable {M : CombMap D}



































































end SimplePrimalCycle









namespace SimplePrimalCycle

variable {M : CombMap D}



  -- c_i^- ↦ α (dart i)





















end SimplePrimalCycle





namespace CutCapSurgery

variable {M : CombMap D} {C : SimplePrimalCycle M}









end CutCapSurgery



namespace NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)











end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapCutCap
-/
/- Source module: ProofsInTheBook.PlanarMapCutCapSigma -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}



















































       -- c_i^- ↦ p_i

  -- c_i^- ↦ ℓ_i^- = σ⁻¹ q_i























































end SimplePrimalCycle









end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import Mathlib
-/
/- Source module: ProofsInTheBook.PermTranspositionCycleCount -/
section
set_option autoImplicit true


set_option linter.unusedSectionVars false
set_option linter.unusedSimpArgs false
set_option linter.unnecessarySimpa false
set_option linter.unusedVariables false

open Equiv Equiv.Perm Function

variable {D : Type*} [Fintype D] [DecidableEq D]



namespace PermTranspositionCycleCount

open scoped Finset









































end PermTranspositionCycleCount





end

/- Original source header (imports hoisted):
import Mathlib
-/
/- Source module: ProofsInTheBook.RelationComponentCount -/
section
set_option autoImplicit true


open Classical

universe u

variable {V : Type u} [Fintype V]







































end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapEuler
import ProofsInTheBook.PermTranspositionCycleCount
import ProofsInTheBook.RelationComponentCount
-/
/- Source module: ProofsInTheBook.PlanarMapEulerInequality -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]















































































end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapCutCapSigma
import ProofsInTheBook.PlanarMapEulerInequality
-/
/- Source module: ProofsInTheBook.PlanarMapCutCapCounts -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open Equiv Equiv.Perm Function

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]



namespace CutCapCount

















section SumCongr

variable {α β : Type*} [Fintype α] [DecidableEq α] [Fintype β] [DecidableEq β]



















end SumCongr

end CutCapCount



namespace SimplePrimalCycle

variable {M : CombMap D}

open CutCapCount
















end SimplePrimalCycle

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapCutCapCounts
-/
/- Source module: ProofsInTheBook.PlanarMapCutCapV -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open Equiv Equiv.Perm Function

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}

open CutCapCount
































end SimplePrimalCycle

namespace CutCapCount

variable {E : Type*} [Fintype E] [DecidableEq E]













end CutCapCount

namespace SimplePrimalCycle

variable {M : CombMap D}

open CutCapCount






























































































































































end SimplePrimalCycle

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapCutCapV
-/
/- Source module: ProofsInTheBook.PlanarMapCutCapF -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open Equiv Equiv.Perm Function

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace CutCapCount

variable {E : Type*} [Fintype E] [DecidableEq E]





end CutCapCount

namespace SimplePrimalCycle

variable {M : CombMap D}

open CutCapCount















































end SimplePrimalCycle

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordSideRecon
import ProofsInTheBook.PlanarMapCutCapCounts
import ProofsInTheBook.PlanarMapCutCapF
-/
/- Source module: ProofsInTheBook.ChordFaceCount -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ChordFaceCount

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.PlanarMap.CombMap.CutCapCount

universe u

variable {K : Type u} [Fintype K] [DecidableEq K]



section FacePerm

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)













end FacePerm



section FaceBijection

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)





































end FaceBijection



section Dichotomy

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)











end Dichotomy



section Genus0

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)









end Genus0



section SphereAssembly

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)





end SphereAssembly



section NonVacuity







end NonVacuity



section ChordApplication

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}





end ChordApplication



section Headline

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



end Headline

end ProofsInTheBook.ChordFaceCount















end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordFaceCount
import ProofsInTheBook.PlanarMapEulerInequality
-/
/- Source module: ProofsInTheBook.ChordDisk -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ChordDisk

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.ChordFaceCount

universe u

variable {K : Type u} [Fintype K] [DecidableEq K]



section Facts

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  (a₀ a₁ : K)





end Facts



section LowerHalf

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)





end LowerHalf



section Threading

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)







end Threading



section ChordApplication

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}

















end ChordApplication



section NonVacuity











end NonVacuity



section Headline

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



end Headline



end ProofsInTheBook.ChordDisk
















end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordDisk
-/
/- Source module: ProofsInTheBook.SubmapPlanar -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.SubmapPlanar

open Equiv
open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap

universe u

variable {D : Type u} [Fintype D] [DecidableEq D]





















section OrbitSplit

variable (p : Equiv.Perm D) (S : Finset D)

open scoped Classical















end OrbitSplit





section RawRestrict

variable (M : CombMap D) (Del : Finset D)

open scoped Classical





































variable (hclosed : ∀ d : D, d ∈ Del → M.α d ∈ Del)
  (hsub : ∀ d, d ∈ Del ↔ M.α d ∈ Del)

open scoped Classical













































































end RawRestrict



section ChordThreading

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.ChordSideRecon

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}













end ChordThreading

end ProofsInTheBook.SubmapPlanar

















end

/- Original source header (imports hoisted):
import Mathlib
-/
/- Source module: ProofsInTheBook.TetPearls -/
section
set_option autoImplicit true




noncomputable section

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1000000

open scoped Classical
open Set

namespace ProofsInTheBook.TetPearls







namespace Tet



















end Tet





namespace TetSolid







end TetSolid









namespace Segment3







































































end Segment3



namespace Tet













end Tet





















namespace Pearl








end Pearl





































end ProofsInTheBook.TetPearls

end
end

/- Original source header (imports hoisted):
import Mathlib
-/
/- Source module: ProofsInTheBook.Chapter09 -/
section
set_option autoImplicit true




namespace ProofsInTheBook.Chapter09

open scoped BigOperators TensorProduct
open Polynomial Chebyshev





















































-- (`angleClassQ_arccos_one_third_ne_zero` defined below, after
-- `arccos_one_third_irrational_over_pi`.)












































































































































































































































































end ProofsInTheBook.Chapter09

end

/- Original source header (imports hoisted):
import ProofsInTheBook.TetPearls
import ProofsInTheBook.Chapter09
-/
/- Source module: ProofsInTheBook.TetDihedral -/
section
set_option autoImplicit true




noncomputable section

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000

open scoped RealInnerProductSpace
open ProofsInTheBook.TetPearls

namespace ProofsInTheBook.TetDihedral

























































































end ProofsInTheBook.TetDihedral

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.TetDihedral
-/
/- Source module: ProofsInTheBook.SphericalKernel -/
section
set_option autoImplicit true




noncomputable section

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000

open scoped RealInnerProductSpace
open ProofsInTheBook.TetPearls ProofsInTheBook.TetDihedral

namespace ProofsInTheBook.SphericalKernel




























































































































end ProofsInTheBook.SphericalKernel

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalKernel
-/
/- Source module: ProofsInTheBook.SphericalArm -/
section
set_option autoImplicit true




noncomputable section

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000

open scoped RealInnerProductSpace
open ProofsInTheBook.TetPearls ProofsInTheBook.TetDihedral
open ProofsInTheBook.SphericalKernel

namespace ProofsInTheBook.SphericalArm







































































end ProofsInTheBook.SphericalArm

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalArm
-/
/- Source module: ProofsInTheBook.SphericalRotation -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace
open ProofsInTheBook.TetPearls ProofsInTheBook.TetDihedral
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm

namespace ProofsInTheBook.SphericalRotation






























































































variable {ι : Type*}

























end ProofsInTheBook.SphericalRotation

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalRotation
-/
/- Source module: ProofsInTheBook.SphericalSZ -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.TetPearls ProofsInTheBook.TetDihedral
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm ProofsInTheBook.SphericalRotation

namespace ProofsInTheBook.SphericalSZ


























end ProofsInTheBook.SphericalSZ

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalSZ
-/
/- Source module: ProofsInTheBook.SphericalCore -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.TetPearls ProofsInTheBook.TetDihedral
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ

namespace ProofsInTheBook.SphericalCore

















































end ProofsInTheBook.SphericalCore

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalCore
-/
/- Source module: ProofsInTheBook.SphericalFinish -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.TetPearls ProofsInTheBook.TetDihedral
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore

namespace ProofsInTheBook.SphericalFinish









































end ProofsInTheBook.SphericalFinish

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalFinish
-/
/- Source module: ProofsInTheBook.SphericalOpening -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.TetPearls ProofsInTheBook.TetDihedral
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish

namespace ProofsInTheBook.SphericalOpening

























end ProofsInTheBook.SphericalOpening

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalOpening
-/
/- Source module: ProofsInTheBook.SphericalHinge -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.TetPearls ProofsInTheBook.TetDihedral
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening

namespace ProofsInTheBook.SphericalHinge



















































end ProofsInTheBook.SphericalHinge

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalHinge
-/
/- Source module: ProofsInTheBook.SphericalSZChain -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.TetPearls ProofsInTheBook.TetDihedral
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge

namespace ProofsInTheBook.SphericalSZChain































end ProofsInTheBook.SphericalSZChain

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalSZChain
-/
/- Source module: ProofsInTheBook.SphericalCyclicTriple -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.TetPearls ProofsInTheBook.TetDihedral
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain

namespace ProofsInTheBook.SphericalCyclicTriple









































end ProofsInTheBook.SphericalCyclicTriple

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalCyclicTriple
-/
/- Source module: ProofsInTheBook.SphericalGnomonic -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.TetPearls ProofsInTheBook.TetDihedral
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple

namespace ProofsInTheBook.SphericalGnomonic






















































end ProofsInTheBook.SphericalGnomonic

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalGnomonic
-/
/- Source module: ProofsInTheBook.PlanarConvexDiag -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalArm ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCyclicTriple ProofsInTheBook.SphericalSZChain
open ProofsInTheBook.SphericalGnomonic

namespace ProofsInTheBook.PlanarConvexDiag



























end ProofsInTheBook.PlanarConvexDiag

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarConvexDiag
-/
/- Source module: ProofsInTheBook.SphericalSZStep -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag

namespace ProofsInTheBook.SphericalSZStep































end ProofsInTheBook.SphericalSZStep

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalSZStep
-/
/- Source module: ProofsInTheBook.SphericalHingeCut -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep

namespace ProofsInTheBook.SphericalHingeCut







































end ProofsInTheBook.SphericalHingeCut

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalHingeCut
-/
/- Source module: ProofsInTheBook.SphericalDiagCut -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut

namespace ProofsInTheBook.SphericalDiagCut

















































end ProofsInTheBook.SphericalDiagCut

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalDiagCut
-/
/- Source module: ProofsInTheBook.SphericalOpeningProcess -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut

namespace ProofsInTheBook.SphericalOpeningProcess

























































end ProofsInTheBook.SphericalOpeningProcess

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalOpeningProcess
-/
/- Source module: ProofsInTheBook.SphericalReachStuck -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess

namespace ProofsInTheBook.SphericalReachStuck





































end ProofsInTheBook.SphericalReachStuck

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalReachStuck
-/
/- Source module: ProofsInTheBook.SphericalAdmissibleSup -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalReachStuck

namespace ProofsInTheBook.SphericalAdmissibleSup

































































end ProofsInTheBook.SphericalAdmissibleSup

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalAdmissibleSup
-/
/- Source module: ProofsInTheBook.SphericalArmClose -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalReachStuck ProofsInTheBook.SphericalAdmissibleSup

namespace ProofsInTheBook.SphericalArmClose































































end ProofsInTheBook.SphericalArmClose

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalArmClose
-/
/- Source module: ProofsInTheBook.SphericalArmFinal -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalReachStuck ProofsInTheBook.SphericalAdmissibleSup
open ProofsInTheBook.SphericalArmClose

namespace ProofsInTheBook.SphericalArmFinal























end ProofsInTheBook.SphericalArmFinal

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalArmFinal
-/
/- Source module: ProofsInTheBook.SphericalSZComplete -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalReachStuck ProofsInTheBook.SphericalAdmissibleSup
open ProofsInTheBook.SphericalArmClose

namespace ProofsInTheBook.SphericalSZComplete













































end ProofsInTheBook.SphericalSZComplete

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalSZComplete
-/
/- Source module: ProofsInTheBook.SphericalStuckWitness -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalReachStuck ProofsInTheBook.SphericalAdmissibleSup
open ProofsInTheBook.SphericalArmClose ProofsInTheBook.SphericalSZComplete

namespace ProofsInTheBook.SphericalStuckWitness





















































end ProofsInTheBook.SphericalStuckWitness

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalStuckWitness
-/
/- Source module: ProofsInTheBook.SphericalTerminalVis -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalReachStuck ProofsInTheBook.SphericalAdmissibleSup
open ProofsInTheBook.SphericalArmClose ProofsInTheBook.SphericalSZComplete
open ProofsInTheBook.SphericalStuckWitness

namespace ProofsInTheBook.SphericalTerminalVis































































end ProofsInTheBook.SphericalTerminalVis

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalTerminalVis
-/
/- Source module: ProofsInTheBook.SphericalArmUncond -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalReachStuck ProofsInTheBook.SphericalAdmissibleSup
open ProofsInTheBook.SphericalArmClose ProofsInTheBook.SphericalSZComplete
open ProofsInTheBook.SphericalTerminalVis

namespace ProofsInTheBook.SphericalArmUncond

















































end ProofsInTheBook.SphericalArmUncond

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalArmUncond
-/
/- Source module: ProofsInTheBook.SphericalMatchedCut -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalReachStuck ProofsInTheBook.SphericalAdmissibleSup
open ProofsInTheBook.SphericalArmClose ProofsInTheBook.SphericalSZComplete
open ProofsInTheBook.SphericalTerminalVis ProofsInTheBook.SphericalArmUncond

namespace ProofsInTheBook.SphericalMatchedCut









































































































end ProofsInTheBook.SphericalMatchedCut

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalMatchedCut
-/
/- Source module: ProofsInTheBook.SphericalCornerStep -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalReachStuck ProofsInTheBook.SphericalAdmissibleSup
open ProofsInTheBook.SphericalArmClose ProofsInTheBook.SphericalSZComplete
open ProofsInTheBook.SphericalTerminalVis ProofsInTheBook.SphericalArmUncond
open ProofsInTheBook.SphericalMatchedCut

namespace ProofsInTheBook.SphericalCornerStep















































end ProofsInTheBook.SphericalCornerStep

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalCornerStep
import ProofsInTheBook.PlanarConvexDiag
-/
/- Source module: ProofsInTheBook.SphericalConeMembership -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalReachStuck ProofsInTheBook.SphericalAdmissibleSup
open ProofsInTheBook.SphericalArmClose ProofsInTheBook.SphericalSZComplete
open ProofsInTheBook.SphericalTerminalVis ProofsInTheBook.SphericalArmUncond
open ProofsInTheBook.SphericalMatchedCut ProofsInTheBook.SphericalCornerStep

namespace ProofsInTheBook.SphericalConeMembership













































































end ProofsInTheBook.SphericalConeMembership

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalConeMembership
-/
/- Source module: ProofsInTheBook.SphericalArmDone -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalReachStuck ProofsInTheBook.SphericalAdmissibleSup
open ProofsInTheBook.SphericalArmClose ProofsInTheBook.SphericalSZComplete
open ProofsInTheBook.SphericalTerminalVis ProofsInTheBook.SphericalArmUncond
open ProofsInTheBook.SphericalMatchedCut ProofsInTheBook.SphericalCornerStep
open ProofsInTheBook.SphericalConeMembership

namespace ProofsInTheBook.SphericalArmDone



















































end ProofsInTheBook.SphericalArmDone

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalArmDone
-/
/- Source module: ProofsInTheBook.SphericalArmFinish -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalReachStuck ProofsInTheBook.SphericalAdmissibleSup
open ProofsInTheBook.SphericalArmClose ProofsInTheBook.SphericalSZComplete
open ProofsInTheBook.SphericalTerminalVis ProofsInTheBook.SphericalArmUncond
open ProofsInTheBook.SphericalMatchedCut ProofsInTheBook.SphericalCornerStep
open ProofsInTheBook.SphericalConeMembership ProofsInTheBook.SphericalArmDone

namespace ProofsInTheBook.SphericalArmFinish









































end ProofsInTheBook.SphericalArmFinish

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalArmFinish
-/
/- Source module: ProofsInTheBook.SphericalArmClose2 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalReachStuck ProofsInTheBook.SphericalAdmissibleSup
open ProofsInTheBook.SphericalArmClose ProofsInTheBook.SphericalSZComplete
open ProofsInTheBook.SphericalTerminalVis ProofsInTheBook.SphericalArmUncond
open ProofsInTheBook.SphericalMatchedCut ProofsInTheBook.SphericalCornerStep
open ProofsInTheBook.SphericalConeMembership ProofsInTheBook.SphericalArmDone
open ProofsInTheBook.SphericalArmFinish

namespace ProofsInTheBook.SphericalArmClose2















































end ProofsInTheBook.SphericalArmClose2

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalArmClose2
-/
/- Source module: ProofsInTheBook.SphericalStuckCollinear -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalReachStuck ProofsInTheBook.SphericalAdmissibleSup
open ProofsInTheBook.SphericalArmClose ProofsInTheBook.SphericalSZComplete
open ProofsInTheBook.SphericalTerminalVis ProofsInTheBook.SphericalArmUncond
open ProofsInTheBook.SphericalMatchedCut ProofsInTheBook.SphericalCornerStep
open ProofsInTheBook.SphericalConeMembership ProofsInTheBook.SphericalArmDone
open ProofsInTheBook.SphericalArmFinish ProofsInTheBook.SphericalArmClose2

namespace ProofsInTheBook.SphericalStuckCollinear















































end ProofsInTheBook.SphericalStuckCollinear

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalStuckCollinear
-/
/- Source module: ProofsInTheBook.SphericalOpenedArmCore -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalReachStuck ProofsInTheBook.SphericalAdmissibleSup
open ProofsInTheBook.SphericalArmClose ProofsInTheBook.SphericalSZComplete
open ProofsInTheBook.SphericalTerminalVis ProofsInTheBook.SphericalArmUncond
open ProofsInTheBook.SphericalMatchedCut ProofsInTheBook.SphericalCornerStep
open ProofsInTheBook.SphericalConeMembership ProofsInTheBook.SphericalArmDone
open ProofsInTheBook.SphericalArmFinish ProofsInTheBook.SphericalArmClose2
open ProofsInTheBook.SphericalStuckCollinear

namespace ProofsInTheBook.SphericalOpenedArmCore



























end ProofsInTheBook.SphericalOpenedArmCore

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalStuckCollinear
-/
/- Source module: ProofsInTheBook.SphericalSZInduction -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalDiagCut
open ProofsInTheBook.SphericalSZChain
open ProofsInTheBook.SphericalTerminalVis
open ProofsInTheBook.SphericalArmUncond
open ProofsInTheBook.SphericalStuckCollinear

namespace ProofsInTheBook.SphericalSZInduction

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000































































































end ProofsInTheBook.SphericalSZInduction

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalSZInduction
-/
/- Source module: ProofsInTheBook.SphericalSZStepClose -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCyclicTriple ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZChain
open ProofsInTheBook.SphericalStuckCollinear
open ProofsInTheBook.SphericalSZInduction

namespace ProofsInTheBook.SphericalSZStepClose

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000

















































end ProofsInTheBook.SphericalSZStepClose

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalSZStepClose
-/
/- Source module: ProofsInTheBook.SphericalSZFinal -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCyclicTriple ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalSZChain
open ProofsInTheBook.SphericalDiagCut
open ProofsInTheBook.SphericalSZStep
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose

namespace ProofsInTheBook.SphericalSZFinal

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000

























































end ProofsInTheBook.SphericalSZFinal

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalSZFinal
-/
/- Source module: ProofsInTheBook.SphericalSZClose -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCyclicTriple ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalSZChain
open ProofsInTheBook.SphericalDiagCut
open ProofsInTheBook.SphericalSZStep
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZFinal

namespace ProofsInTheBook.SphericalSZClose

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000



































































end ProofsInTheBook.SphericalSZClose

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalSZClose
-/
/- Source module: ProofsInTheBook.SphericalCutTransport -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZClose

namespace ProofsInTheBook.SphericalCutTransport

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000































end ProofsInTheBook.SphericalCutTransport

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalCutTransport
-/
/- Source module: ProofsInTheBook.ZinanFFCT -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalCutTransport

namespace ProofsInTheBook.ZinanFFCT

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000





























end ProofsInTheBook.ZinanFFCT

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT
-/
/- Source module: ProofsInTheBook.ZinanFFCT2 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.SphericalConeMembership
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.ZinanFFCT

namespace ProofsInTheBook.ZinanFFCT2

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000




































































end ProofsInTheBook.ZinanFFCT2

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT2
-/
/- Source module: ProofsInTheBook.ZinanFFCT3 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.SphericalConeMembership
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.ZinanFFCT
open ProofsInTheBook.ZinanFFCT2

namespace ProofsInTheBook.ZinanFFCT3

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000































end ProofsInTheBook.ZinanFFCT3

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT3
-/
/- Source module: ProofsInTheBook.ZinanFFCT4 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.SphericalConeMembership
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalGnomonic
open ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.ZinanFFCT
open ProofsInTheBook.ZinanFFCT2
open ProofsInTheBook.ZinanFFCT3

namespace ProofsInTheBook.ZinanFFCT4

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000

































end ProofsInTheBook.ZinanFFCT4

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT4
-/
/- Source module: ProofsInTheBook.ZinanFFCT5 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.SphericalConeMembership
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalGnomonic
open ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.ZinanFFCT
open ProofsInTheBook.ZinanFFCT3
open ProofsInTheBook.ZinanFFCT4

namespace ProofsInTheBook.ZinanFFCT5

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000



















end ProofsInTheBook.ZinanFFCT5

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT5
-/
/- Source module: ProofsInTheBook.ZinanFFCT6 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.SphericalConeMembership
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalGnomonic
open ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.ZinanFFCT
open ProofsInTheBook.ZinanFFCT2
open ProofsInTheBook.ZinanFFCT3
open ProofsInTheBook.ZinanFFCT5

namespace ProofsInTheBook.ZinanFFCT6

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000


























end ProofsInTheBook.ZinanFFCT6

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT6
-/
/- Source module: ProofsInTheBook.ZinanFFCT7 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.SphericalConeMembership
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalGnomonic
open ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.ZinanFFCT
open ProofsInTheBook.ZinanFFCT2
open ProofsInTheBook.ZinanFFCT3
open ProofsInTheBook.ZinanFFCT5
open ProofsInTheBook.ZinanFFCT6

namespace ProofsInTheBook.ZinanFFCT7

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000



































end ProofsInTheBook.ZinanFFCT7

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT7
import ProofsInTheBook.PlanarConvexDiag
-/
/- Source module: ProofsInTheBook.ZinanFFCT8 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZ ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalCutTransport ProofsInTheBook.SphericalGnomonic
open ProofsInTheBook.SphericalConeMembership
open ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.ZinanFFCT ProofsInTheBook.ZinanFFCT2 ProofsInTheBook.ZinanFFCT3
open ProofsInTheBook.ZinanFFCT4 ProofsInTheBook.ZinanFFCT5 ProofsInTheBook.ZinanFFCT6
open ProofsInTheBook.ZinanFFCT7

namespace ProofsInTheBook.ZinanFFCT8

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000































end ProofsInTheBook.ZinanFFCT8

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT8
import ProofsInTheBook.SphericalRotation
-/
/- Source module: ProofsInTheBook.ZinanFFCT9 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalConeMembership
open ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.ZinanFFCT8

namespace ProofsInTheBook.ZinanFFCT9

set_option maxHeartbeats 1600000
















































































end ProofsInTheBook.ZinanFFCT9

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT9
-/
/- Source module: ProofsInTheBook.ZinanFFCT10 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace
open ProofsInTheBook.SphericalKernel
open ProofsInTheBook.ZinanFFCT8 ProofsInTheBook.ZinanFFCT9

namespace ProofsInTheBook.ZinanFFCT10

set_option maxHeartbeats 1600000






















































end ProofsInTheBook.ZinanFFCT10








end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT10
-/
/- Source module: ProofsInTheBook.ZinanFFCT17 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.ZinanFFCT10

namespace ProofsInTheBook.ZinanFFCT17

set_option maxHeartbeats 1600000















































































end ProofsInTheBook.ZinanFFCT17

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT17
-/
/- Source module: ProofsInTheBook.ZinanFFCT18 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.ZinanFFCT3 ProofsInTheBook.ZinanFFCT17

namespace ProofsInTheBook.ZinanFFCT18

set_option maxHeartbeats 1600000




















































end ProofsInTheBook.ZinanFFCT18

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalStuckWitness
import ProofsInTheBook.SphericalCutTransport
-/
/- Source module: ProofsInTheBook.SphericalStuckGeneral -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalReachStuck ProofsInTheBook.SphericalAdmissibleSup
open ProofsInTheBook.SphericalArmClose ProofsInTheBook.SphericalSZComplete
open ProofsInTheBook.SphericalStuckWitness ProofsInTheBook.SphericalTerminalVis
open ProofsInTheBook.SphericalSZInduction ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalCutTransport

namespace ProofsInTheBook.SphericalStuckGeneral





































end ProofsInTheBook.SphericalStuckGeneral

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalStuckGeneral
-/
/- Source module: ProofsInTheBook.SphericalLastCornerStuck -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpening ProofsInTheBook.SphericalHinge
open ProofsInTheBook.SphericalSZChain ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalGnomonic ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZStep ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalReachStuck ProofsInTheBook.SphericalAdmissibleSup
open ProofsInTheBook.SphericalArmClose ProofsInTheBook.SphericalSZComplete
open ProofsInTheBook.SphericalCutTransport ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose ProofsInTheBook.SphericalStuckGeneral

namespace ProofsInTheBook.SphericalLastCornerStuck





























end ProofsInTheBook.SphericalLastCornerStuck

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT18
import ProofsInTheBook.SphericalLastCornerStuck
-/
/- Source module: ProofsInTheBook.ZinanFFCT19 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalCutTransport ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.TetDihedral
open ProofsInTheBook.ZinanFFCT18

namespace ProofsInTheBook.ZinanFFCT19

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000


















































end ProofsInTheBook.ZinanFFCT19

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalSZClose
-/
/- Source module: ProofsInTheBook.SphericalMonitoredSup -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalCyclicTriple ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalSZChain
open ProofsInTheBook.SphericalDiagCut
open ProofsInTheBook.SphericalSZStep
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose

namespace ProofsInTheBook.SphericalMonitoredSup

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000









































































end ProofsInTheBook.SphericalMonitoredSup

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalSZClose
-/
/- Source module: ProofsInTheBook.SphericalSpliceTransport -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose

namespace ProofsInTheBook.SphericalSpliceTransport

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000























end ProofsInTheBook.SphericalSpliceTransport

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalRotation
import ProofsInTheBook.SphericalCyclicTriple
-/
/- Source module: ProofsInTheBook.SphericalCongruence -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace
open ProofsInTheBook.TetPearls ProofsInTheBook.TetDihedral
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalCyclicTriple

namespace ProofsInTheBook.SphericalCongruence

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000



























































end ProofsInTheBook.SphericalCongruence

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalMonitoredSup
import ProofsInTheBook.SphericalSpliceTransport
import ProofsInTheBook.SphericalCongruence
-/
/- Source module: ProofsInTheBook.SphericalArmAssembly -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalCyclicTriple ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalSpliceTransport
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalCongruence

namespace ProofsInTheBook.SphericalArmAssembly

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000







































end ProofsInTheBook.SphericalArmAssembly

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalArmAssembly
-/
/- Source module: ProofsInTheBook.SphericalOpeningOutcome -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalArmAssembly

namespace ProofsInTheBook.SphericalOpeningOutcome

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000



























end ProofsInTheBook.SphericalOpeningOutcome


end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT19
import ProofsInTheBook.SphericalSZClose
import ProofsInTheBook.SphericalOpeningOutcome
import ProofsInTheBook.ZinanFFCT18
-/
/- Source module: ProofsInTheBook.ZinanFFCT20 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.ZinanFFCT18

namespace ProofsInTheBook.ZinanFFCT20




















end ProofsInTheBook.ZinanFFCT20

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT10
-/
/- Source module: ProofsInTheBook.ZinanFFCT12 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace
open ProofsInTheBook.SphericalKernel
open ProofsInTheBook.ZinanFFCT8 ProofsInTheBook.ZinanFFCT9 ProofsInTheBook.ZinanFFCT10

namespace ProofsInTheBook.ZinanFFCT12

set_option maxHeartbeats 1600000



























end ProofsInTheBook.ZinanFFCT12

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT20
import ProofsInTheBook.ZinanFFCT12
-/
/- Source module: ProofsInTheBook.ZinanFFCT21 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.ZinanFFCT3 ProofsInTheBook.ZinanFFCT9 ProofsInTheBook.ZinanFFCT10
open ProofsInTheBook.ZinanFFCT12 ProofsInTheBook.ZinanFFCT18

namespace ProofsInTheBook.ZinanFFCT21

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000





















































end ProofsInTheBook.ZinanFFCT21

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT21
-/
/- Source module: ProofsInTheBook.ZinanFFCT22 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.ZinanFFCT3 ProofsInTheBook.ZinanFFCT9 ProofsInTheBook.ZinanFFCT10
open ProofsInTheBook.ZinanFFCT12 ProofsInTheBook.ZinanFFCT18 ProofsInTheBook.ZinanFFCT21

namespace ProofsInTheBook.ZinanFFCT22

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000















































end ProofsInTheBook.ZinanFFCT22

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT22
-/
/- Source module: ProofsInTheBook.ZinanFFCT23 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.ZinanFFCT3 ProofsInTheBook.ZinanFFCT9 ProofsInTheBook.ZinanFFCT10
open ProofsInTheBook.ZinanFFCT12 ProofsInTheBook.ZinanFFCT18 ProofsInTheBook.ZinanFFCT21

namespace ProofsInTheBook.ZinanFFCT23

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000





































end ProofsInTheBook.ZinanFFCT23

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT23
-/
/- Source module: ProofsInTheBook.ZinanFFCT24 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.ZinanFFCT3 ProofsInTheBook.ZinanFFCT9 ProofsInTheBook.ZinanFFCT10
open ProofsInTheBook.ZinanFFCT12 ProofsInTheBook.ZinanFFCT18 ProofsInTheBook.ZinanFFCT21
open ProofsInTheBook.ZinanFFCT22 ProofsInTheBook.ZinanFFCT23

namespace ProofsInTheBook.ZinanFFCT24

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000






















































end ProofsInTheBook.ZinanFFCT24

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT24
-/
/- Source module: ProofsInTheBook.ZinanFFCT25 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction ProofsInTheBook.SphericalRotation
open ProofsInTheBook.ZinanFFCT3 ProofsInTheBook.ZinanFFCT9 ProofsInTheBook.ZinanFFCT10
open ProofsInTheBook.ZinanFFCT12 ProofsInTheBook.ZinanFFCT18 ProofsInTheBook.ZinanFFCT21
open ProofsInTheBook.ZinanFFCT22 ProofsInTheBook.ZinanFFCT23 ProofsInTheBook.ZinanFFCT24

namespace ProofsInTheBook.ZinanFFCT25

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000













































end ProofsInTheBook.ZinanFFCT25

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT25
import ProofsInTheBook.SphericalCore
-/
/- Source module: ProofsInTheBook.ZinanFFCT26 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalCore
open ProofsInTheBook.ZinanFFCT10

namespace ProofsInTheBook.ZinanFFCT26

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000











































end ProofsInTheBook.ZinanFFCT26

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT26
import ProofsInTheBook.SphericalStuckGeneral
-/
/- Source module: ProofsInTheBook.ZinanFFCT27 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalCore
open ProofsInTheBook.ZinanFFCT9 ProofsInTheBook.ZinanFFCT10 ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT26 ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalSZ

namespace ProofsInTheBook.ZinanFFCT27

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000







































end ProofsInTheBook.ZinanFFCT27

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT27
import ProofsInTheBook.ZinanFFCT25
import ProofsInTheBook.SphericalMonitoredSup
import ProofsInTheBook.SphericalOpeningOutcome
-/
/- Source module: ProofsInTheBook.ZinanFFCT28 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.ZinanFFCT18 ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT26 ProofsInTheBook.ZinanFFCT27
open ProofsInTheBook.SphericalStuckGeneral ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.SphericalMonitoredSup ProofsInTheBook.SphericalSZFinal

namespace ProofsInTheBook.ZinanFFCT28

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000



































end ProofsInTheBook.ZinanFFCT28

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalOpeningOutcome
-/
/- Source module: ProofsInTheBook.SphericalOpeningGlue -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalDiagCut
open ProofsInTheBook.SphericalSZChain
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalOpeningOutcome

namespace ProofsInTheBook.SphericalOpeningGlue

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000

































end ProofsInTheBook.SphericalOpeningGlue

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT28
import ProofsInTheBook.SphericalOpeningGlue
-/
/- Source module: ProofsInTheBook.ZinanFFCT30 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalMonitoredSup ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalOpeningGlue

namespace ProofsInTheBook.ZinanFFCT30

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000

























end ProofsInTheBook.ZinanFFCT30

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT30
import ProofsInTheBook.ZinanFFCT22
-/
/- Source module: ProofsInTheBook.ZinanFFCT33 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.ZinanFFCT18 ProofsInTheBook.ZinanFFCT30

namespace ProofsInTheBook.ZinanFFCT33

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000

































end ProofsInTheBook.ZinanFFCT33
end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT33
-/
/- Source module: ProofsInTheBook.ZinanFFCT34 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.ZinanFFCT18 ProofsInTheBook.ZinanFFCT30 ProofsInTheBook.ZinanFFCT33

namespace ProofsInTheBook.ZinanFFCT34

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000





















end ProofsInTheBook.ZinanFFCT34

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT34
import Mathlib.Analysis.LocallyConvex.Separation
import Mathlib.Analysis.InnerProductSpace.Dual
import Mathlib.Analysis.Convex.Topology
import Mathlib.Analysis.Convex.Combination
-/
/- Source module: ProofsInTheBook.ZinanFFCT36 -/
section
set_option autoImplicit true


noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.ZinanFFCT18 ProofsInTheBook.ZinanFFCT30
open ProofsInTheBook.ZinanFFCT33 ProofsInTheBook.ZinanFFCT34

namespace ProofsInTheBook.ZinanFFCT36

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000
























end ProofsInTheBook.ZinanFFCT36
end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT36
-/
/- Source module: ProofsInTheBook.ZinanFFCT44 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalCore
open ProofsInTheBook.ZinanFFCT21 ProofsInTheBook.ZinanFFCT22
open ProofsInTheBook.ZinanFFCT25 ProofsInTheBook.ZinanFFCT30
open ProofsInTheBook.ZinanFFCT36

namespace ProofsInTheBook.ZinanFFCT44

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000





































end ProofsInTheBook.ZinanFFCT44

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT20
import ProofsInTheBook.ZinanFFCT3
import ProofsInTheBook.SphericalOpeningGlue
-/
/- Source module: ProofsInTheBook.ZinanFFCT37 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalOpeningGlue
open ProofsInTheBook.ZinanFFCT20
open ProofsInTheBook.ZinanFFCT3

namespace ProofsInTheBook.ZinanFFCT37

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000





































































end ProofsInTheBook.ZinanFFCT37

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT37
import ProofsInTheBook.ZinanFFCT36
-/
/- Source module: ProofsInTheBook.ZinanFFCT38 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalSpliceTransport
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalOpeningGlue
open ProofsInTheBook.ZinanFFCT30
open ProofsInTheBook.ZinanFFCT36
open ProofsInTheBook.ZinanFFCT37

namespace ProofsInTheBook.ZinanFFCT38

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000



















































end ProofsInTheBook.ZinanFFCT38






end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT38
-/
/- Source module: ProofsInTheBook.ZinanFFCT39 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalOpeningGlue
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.ZinanFFCT37
open ProofsInTheBook.ZinanFFCT38

namespace ProofsInTheBook.ZinanFFCT39

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000













































end ProofsInTheBook.ZinanFFCT39

-- Brick 1 (positive content + assembly + audit)





-- Brick 2 (audit + positive content)




end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT39
-/
/- Source module: ProofsInTheBook.ZinanFFCT40 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalSpliceTransport
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalOpeningGlue
open ProofsInTheBook.SphericalDiagCut
open ProofsInTheBook.ZinanFFCT30
open ProofsInTheBook.ZinanFFCT36
open ProofsInTheBook.ZinanFFCT37
open ProofsInTheBook.ZinanFFCT38
open ProofsInTheBook.ZinanFFCT39

namespace ProofsInTheBook.ZinanFFCT40

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000























































end ProofsInTheBook.ZinanFFCT40

-- §1 the any-h assembler

-- §3 the pure-hemi strict certificate + repaired stuck outcome + repaired clause (iii)



-- §3 the corrected outcome + repaired headline



-- refutation-resistance witnesses


end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT40
-/
/- Source module: ProofsInTheBook.ZinanFFCT41 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalSZChain
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalSpliceTransport
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalOpeningGlue
open ProofsInTheBook.ZinanFFCT3
open ProofsInTheBook.ZinanFFCT20
open ProofsInTheBook.ZinanFFCT30
open ProofsInTheBook.ZinanFFCT36
open ProofsInTheBook.ZinanFFCT37
open ProofsInTheBook.ZinanFFCT38
open ProofsInTheBook.ZinanFFCT39
open ProofsInTheBook.ZinanFFCT40

namespace ProofsInTheBook.ZinanFFCT41

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000







































































































end ProofsInTheBook.ZinanFFCT41

-- §1 the WB family + W-admissibility bridge

-- §2 the base sinusoid

-- §3 the cap by admissibility (the central new content)


-- §5 the WB trichotomy

-- §6/§7 the clauses at the WB sup



-- §8/§9 the base-capped outcome + headline (GlueWBaseCap discharged)


-- refutation-resistance witness


end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT41
-/
/- Source module: ProofsInTheBook.ZinanFFCT42 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalSpliceTransport
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.ZinanFFCT41

namespace ProofsInTheBook.ZinanFFCT42

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000































end ProofsInTheBook.ZinanFFCT42

-- §1 the algebra/index micro-lemmas


-- §2 base-stuck = opened diagonal

-- §3 Brick 1 (the cyclic-identity bridge) + the vanishing-support payload


-- §4 the residual DISCHARGED + the base-stuck-free headline


-- non-vacuity guards


end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT42
-/
/- Source module: ProofsInTheBook.ZinanFFCT45 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalOpeningGlue
open ProofsInTheBook.ZinanFFCT3
open ProofsInTheBook.ZinanFFCT20
open ProofsInTheBook.ZinanFFCT37
open ProofsInTheBook.ZinanFFCT41
open ProofsInTheBook.ZinanFFCT42

namespace ProofsInTheBook.ZinanFFCT45

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000



































































end ProofsInTheBook.ZinanFFCT45

-- §1 the WBS family + closure facts





-- §2 init admissibility

-- §3 deficit bound + base cap



-- §4 the trichotomy + clauses



-- §5 Brick 7: the FFCT42 base-stuck port DISCHARGED



end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT42
-/
/- Source module: ProofsInTheBook.ZinanFFCT43 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalSpliceTransport
open ProofsInTheBook.ZinanFFCT39
open ProofsInTheBook.ZinanFFCT41
open ProofsInTheBook.ZinanFFCT42

namespace ProofsInTheBook.ZinanFFCT43

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000





















end ProofsInTheBook.ZinanFFCT43

-- §1 endpoint positivity

-- §2 closing edge distinct at the WB supremum

-- §3 the residual DISCHARGED + the closing-edge-free headline


-- non-vacuity guards


end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT44
import ProofsInTheBook.ZinanFFCT45
import ProofsInTheBook.ZinanFFCT43
-/
/- Source module: ProofsInTheBook.ZinanFFCT46 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalSpliceTransport
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalOpeningGlue
open ProofsInTheBook.ZinanFFCT3
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT34
open ProofsInTheBook.ZinanFFCT36
open ProofsInTheBook.ZinanFFCT37
open ProofsInTheBook.ZinanFFCT40
open ProofsInTheBook.ZinanFFCT42
open ProofsInTheBook.ZinanFFCT43
open ProofsInTheBook.ZinanFFCT44
open ProofsInTheBook.ZinanFFCT45

namespace ProofsInTheBook.ZinanFFCT46

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000

















































end ProofsInTheBook.ZinanFFCT46

-- §1 the margins-free open-hemisphere production (THE keystone mechanism)

-- §2 brick 4

-- §2′ the opened side / joint geometry



-- §3 bricks 5–6


-- §4 brick 8

-- §5 brick 9 + non-vacuity



end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT46
-/
/- Source module: ProofsInTheBook.ZinanFFCT47 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalSpliceTransport
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.ZinanFFCT21 ProofsInTheBook.ZinanFFCT22
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT36
open ProofsInTheBook.ZinanFFCT42
open ProofsInTheBook.ZinanFFCT43
open ProofsInTheBook.ZinanFFCT44
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46

namespace ProofsInTheBook.ZinanFFCT47

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000



























































end ProofsInTheBook.ZinanFFCT47

-- §1 the open-chain collapse kernel (3 ≤ n)

-- §2 the wrap-edge-free open-hemisphere production

-- §3 wrap ShortArc from the hemisphere

-- §4 the residual discharged


-- §5 the wrap-free headline



end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT47
import ProofsInTheBook.ZinanFFCT28
import ProofsInTheBook.SphericalStuckGeneral
-/
/- Source module: ProofsInTheBook.ZinanFFCT49 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.ZinanFFCT28
open ProofsInTheBook.ZinanFFCT37
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47

namespace ProofsInTheBook.ZinanFFCT49

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000









































end ProofsInTheBook.ZinanFFCT49

-- §0 the opened arm

-- §2 discharged pieces



-- §4 the bridge

-- §5 non-vacuity guards



end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT49
import ProofsInTheBook.ZinanFFCT23
-/
/- Source module: ProofsInTheBook.ZinanFFCT52 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.ZinanFFCT12
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47
open ProofsInTheBook.ZinanFFCT49

namespace ProofsInTheBook.ZinanFFCT52

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000









































































end ProofsInTheBook.ZinanFFCT52

-- §1 component 2


-- §2 reversal infra




-- §3 orientation normalization

-- §4 interval convexity


-- §5 assembly


end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT19
import ProofsInTheBook.ZinanFFCT46
import ProofsInTheBook.ZinanFFCT47
-/
/- Source module: ProofsInTheBook.ZinanFFCT48 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT19
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47

namespace ProofsInTheBook.ZinanFFCT48

set_option maxHeartbeats 1600000



























end ProofsInTheBook.ZinanFFCT48




end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT25
import ProofsInTheBook.ZinanFFCT48
-/
/- Source module: ProofsInTheBook.ZinanFFCT53 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.ZinanFFCT18 ProofsInTheBook.ZinanFFCT19
open ProofsInTheBook.ZinanFFCT23 ProofsInTheBook.ZinanFFCT25

namespace ProofsInTheBook.ZinanFFCT53

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000


















































end ProofsInTheBook.ZinanFFCT53

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT52
import ProofsInTheBook.ZinanFFCT53
-/
/- Source module: ProofsInTheBook.ZinanFFCT54 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.ZinanFFCT18 ProofsInTheBook.ZinanFFCT19
open ProofsInTheBook.ZinanFFCT21 ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT52 ProofsInTheBook.ZinanFFCT53

namespace ProofsInTheBook.ZinanFFCT54

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000

















































































end ProofsInTheBook.ZinanFFCT54

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT54
-/
/- Source module: ProofsInTheBook.ZinanFFCT63 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.ZinanFFCT12
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT53
open ProofsInTheBook.ZinanFFCT54

namespace ProofsInTheBook.ZinanFFCT63

set_option maxHeartbeats 1600000




















































end ProofsInTheBook.ZinanFFCT63

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT28
-/
/- Source module: ProofsInTheBook.ZinanFFCT29 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalSZ
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.ZinanFFCT10 ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT26 ProofsInTheBook.ZinanFFCT27
open ProofsInTheBook.ZinanFFCT28

namespace ProofsInTheBook.ZinanFFCT29

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000





















































end ProofsInTheBook.ZinanFFCT29

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT29
-/
/- Source module: ProofsInTheBook.ZinanFFCT31 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.ZinanFFCT3 ProofsInTheBook.ZinanFFCT9 ProofsInTheBook.ZinanFFCT10
open ProofsInTheBook.ZinanFFCT12 ProofsInTheBook.ZinanFFCT18 ProofsInTheBook.ZinanFFCT21
open ProofsInTheBook.ZinanFFCT22 ProofsInTheBook.ZinanFFCT23 ProofsInTheBook.ZinanFFCT24
open ProofsInTheBook.ZinanFFCT25 ProofsInTheBook.ZinanFFCT27 ProofsInTheBook.ZinanFFCT29

namespace ProofsInTheBook.ZinanFFCT31

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000
























































end ProofsInTheBook.ZinanFFCT31

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT31
-/
/- Source module: ProofsInTheBook.ZinanFFCT32 -/
section
set_option autoImplicit true




noncomputable section
open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.ZinanFFCT3 ProofsInTheBook.ZinanFFCT9 ProofsInTheBook.ZinanFFCT10
open ProofsInTheBook.ZinanFFCT12 ProofsInTheBook.ZinanFFCT18 ProofsInTheBook.ZinanFFCT21
open ProofsInTheBook.ZinanFFCT22 ProofsInTheBook.ZinanFFCT23 ProofsInTheBook.ZinanFFCT24
open ProofsInTheBook.ZinanFFCT25 ProofsInTheBook.ZinanFFCT27 ProofsInTheBook.ZinanFFCT29
open ProofsInTheBook.ZinanFFCT31

namespace ProofsInTheBook.ZinanFFCT32

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000















































end ProofsInTheBook.ZinanFFCT32

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT49
import ProofsInTheBook.ZinanFFCT32
-/
/- Source module: ProofsInTheBook.ZinanFFCT51 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.ZinanFFCT3 ProofsInTheBook.ZinanFFCT18 ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT27 ProofsInTheBook.ZinanFFCT29 ProofsInTheBook.ZinanFFCT31
open ProofsInTheBook.ZinanFFCT32
open ProofsInTheBook.ZinanFFCT45 ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT49

namespace ProofsInTheBook.ZinanFFCT51

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000





























end ProofsInTheBook.ZinanFFCT51

-- §1 the sharp residue

-- §2 the corner sign verification

-- §3 the main near-side line


-- §4 non-vacuity guards



end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT51
-/
/- Source module: ProofsInTheBook.ZinanFFCT55 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.ZinanFFCT26 ProofsInTheBook.ZinanFFCT27
open ProofsInTheBook.ZinanFFCT29
open ProofsInTheBook.ZinanFFCT45 ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT51

namespace ProofsInTheBook.ZinanFFCT55

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000









































end ProofsInTheBook.ZinanFFCT55

-- §R1/R2 the constant-binding contradiction at the WBS family


-- §δ*=0 edge

-- §R3 slot normalization

-- §R4 the derivative + the sign finding



-- §R4′ the forced collapse

-- §5 non-vacuity guards



end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT21
import ProofsInTheBook.ZinanFFCT55
-/
/- Source module: ProofsInTheBook.ZinanFFCT56 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.ZinanFFCT3
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT21
open ProofsInTheBook.ZinanFFCT45 ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT55

namespace ProofsInTheBook.ZinanFFCT56

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000







































end ProofsInTheBook.ZinanFFCT56

-- §A the coefficient bricks


-- §B the master mid-fold kill


-- §C the WBS axis-edge elimination

-- §D the honest dispatch + residue

-- §E the consequence wiring

-- §F non-vacuity guards




end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT48
import ProofsInTheBook.ZinanFFCT56
-/
/- Source module: ProofsInTheBook.ZinanFFCT57 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalSpliceTransport
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT19
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47
open ProofsInTheBook.ZinanFFCT48
open ProofsInTheBook.ZinanFFCT56

namespace ProofsInTheBook.ZinanFFCT57

set_option maxHeartbeats 1600000



































end ProofsInTheBook.ZinanFFCT57









end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT10
import ProofsInTheBook.SphericalSpliceTransport
import ProofsInTheBook.ZinanFFCT48
import ProofsInTheBook.ZinanFFCT57
-/
/- Source module: ProofsInTheBook.ZinanFFCT58 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalSpliceTransport
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.ZinanFFCT10
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT19
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47
open ProofsInTheBook.ZinanFFCT48
open ProofsInTheBook.ZinanFFCT57

namespace ProofsInTheBook.ZinanFFCT58

set_option maxHeartbeats 1600000
set_option linter.unnecessarySeqFocus false























































































end ProofsInTheBook.ZinanFFCT58







end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT58
-/
/- Source module: ProofsInTheBook.ZinanFFCT59 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT19
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47
open ProofsInTheBook.ZinanFFCT48
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT57
open ProofsInTheBook.ZinanFFCT58

namespace ProofsInTheBook.ZinanFFCT59

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000



































end ProofsInTheBook.ZinanFFCT59









end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT54
import ProofsInTheBook.ZinanFFCT59
-/
/- Source module: ProofsInTheBook.ZinanFFCT60 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT21
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT53
open ProofsInTheBook.ZinanFFCT54
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT59

namespace ProofsInTheBook.ZinanFFCT60

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000


























end ProofsInTheBook.ZinanFFCT60

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT60
import ProofsInTheBook.SphericalRotation
-/
/- Source module: ProofsInTheBook.ZinanFFCT61 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.ZinanFFCT12
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT21
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT53
open ProofsInTheBook.ZinanFFCT54
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT59
open ProofsInTheBook.ZinanFFCT60

namespace ProofsInTheBook.ZinanFFCT61

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000


































































































end ProofsInTheBook.ZinanFFCT61

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT61
-/
/- Source module: ProofsInTheBook.ZinanFFCT62 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT19
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT48
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT53
open ProofsInTheBook.ZinanFFCT54
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT57
open ProofsInTheBook.ZinanFFCT58
open ProofsInTheBook.ZinanFFCT59
open ProofsInTheBook.ZinanFFCT61

namespace ProofsInTheBook.ZinanFFCT62

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000





















































end ProofsInTheBook.ZinanFFCT62

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT62
-/
/- Source module: ProofsInTheBook.ZinanFFCT64 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT53
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT57
open ProofsInTheBook.ZinanFFCT61
open ProofsInTheBook.ZinanFFCT62

namespace ProofsInTheBook.ZinanFFCT64

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000





































end ProofsInTheBook.ZinanFFCT64

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT63
import ProofsInTheBook.ZinanFFCT64
-/
/- Source module: ProofsInTheBook.ZinanFFCT65 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalCore ProofsInTheBook.SphericalFinish
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT19
open ProofsInTheBook.ZinanFFCT12
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT53
open ProofsInTheBook.ZinanFFCT54
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT59
open ProofsInTheBook.ZinanFFCT61
open ProofsInTheBook.ZinanFFCT62
open ProofsInTheBook.ZinanFFCT63
open ProofsInTheBook.ZinanFFCT64

namespace ProofsInTheBook.ZinanFFCT65

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000



































































end ProofsInTheBook.ZinanFFCT65

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT65
import ProofsInTheBook.PlanarConvexDiag
-/
/- Source module: ProofsInTheBook.ZinanFFCT66 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.ZinanFFCT3
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT21
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT24
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT53
open ProofsInTheBook.ZinanFFCT54
open ProofsInTheBook.ZinanFFCT63
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT65

namespace ProofsInTheBook.ZinanFFCT66

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000












































end ProofsInTheBook.ZinanFFCT66

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT66
-/
/- Source module: ProofsInTheBook.ZinanFFCT67 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT65
open ProofsInTheBook.ZinanFFCT66

namespace ProofsInTheBook.ZinanFFCT67

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000

















end ProofsInTheBook.ZinanFFCT67

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT67
import ProofsInTheBook.ZinanFFCT26
-/
/- Source module: ProofsInTheBook.ZinanFFCT68 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT19
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT26
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT53
open ProofsInTheBook.ZinanFFCT54
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT65
open ProofsInTheBook.ZinanFFCT66
open ProofsInTheBook.ZinanFFCT67

namespace ProofsInTheBook.ZinanFFCT68

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000









































end ProofsInTheBook.ZinanFFCT68

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT68
-/
/- Source module: ProofsInTheBook.ZinanFFCT69 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.ZinanFFCT12
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT61
open ProofsInTheBook.ZinanFFCT62
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT65
open ProofsInTheBook.ZinanFFCT67
open ProofsInTheBook.ZinanFFCT68

namespace ProofsInTheBook.ZinanFFCT69

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000




































end ProofsInTheBook.ZinanFFCT69

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT69
import ProofsInTheBook.ZinanFFCT32
-/
/- Source module: ProofsInTheBook.ZinanFFCT70 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.ZinanFFCT3
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT31
open ProofsInTheBook.ZinanFFCT32
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT65
open ProofsInTheBook.ZinanFFCT68
open ProofsInTheBook.ZinanFFCT69

namespace ProofsInTheBook.ZinanFFCT70

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000




























end ProofsInTheBook.ZinanFFCT70

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT70
-/
/- Source module: ProofsInTheBook.ZinanFFCT71 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT61
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT66
open ProofsInTheBook.ZinanFFCT68
open ProofsInTheBook.ZinanFFCT69
open ProofsInTheBook.ZinanFFCT70

namespace ProofsInTheBook.ZinanFFCT71

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000






























end ProofsInTheBook.ZinanFFCT71

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT71
-/
/- Source module: ProofsInTheBook.ZinanFFCT72 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT19
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT24
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47
open ProofsInTheBook.ZinanFFCT48
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT57
open ProofsInTheBook.ZinanFFCT58
open ProofsInTheBook.ZinanFFCT61
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT65
open ProofsInTheBook.ZinanFFCT66
open ProofsInTheBook.ZinanFFCT68
open ProofsInTheBook.ZinanFFCT69
open ProofsInTheBook.ZinanFFCT70
open ProofsInTheBook.ZinanFFCT71

namespace ProofsInTheBook.ZinanFFCT72

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000








































end ProofsInTheBook.ZinanFFCT72

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT72
-/
/- Source module: ProofsInTheBook.ZinanFFCT73 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT19
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT24
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47
open ProofsInTheBook.ZinanFFCT48
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT53
open ProofsInTheBook.ZinanFFCT54
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT57
open ProofsInTheBook.ZinanFFCT58
open ProofsInTheBook.ZinanFFCT61
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT65
open ProofsInTheBook.ZinanFFCT66
open ProofsInTheBook.ZinanFFCT68
open ProofsInTheBook.ZinanFFCT69
open ProofsInTheBook.ZinanFFCT70
open ProofsInTheBook.ZinanFFCT71
open ProofsInTheBook.ZinanFFCT72

namespace ProofsInTheBook.ZinanFFCT73

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000










































end ProofsInTheBook.ZinanFFCT73

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT73
-/
/- Source module: ProofsInTheBook.ZinanFFCT74 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT19
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47
open ProofsInTheBook.ZinanFFCT48
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT53
open ProofsInTheBook.ZinanFFCT54
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT57
open ProofsInTheBook.ZinanFFCT58
open ProofsInTheBook.ZinanFFCT61
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT65
open ProofsInTheBook.ZinanFFCT66
open ProofsInTheBook.ZinanFFCT68
open ProofsInTheBook.ZinanFFCT69
open ProofsInTheBook.ZinanFFCT70
open ProofsInTheBook.ZinanFFCT71
open ProofsInTheBook.ZinanFFCT73

namespace ProofsInTheBook.ZinanFFCT74

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000







































































end ProofsInTheBook.ZinanFFCT74

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT74
-/
/- Source module: ProofsInTheBook.ZinanFFCT75 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT70
open ProofsInTheBook.ZinanFFCT71
open ProofsInTheBook.ZinanFFCT74

namespace ProofsInTheBook.ZinanFFCT75

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000






















end ProofsInTheBook.ZinanFFCT75

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT75
import ProofsInTheBook.ZinanFFCT44
-/
/- Source module: ProofsInTheBook.ZinanFFCT76 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.ZinanFFCT3
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT21
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT24
open ProofsInTheBook.ZinanFFCT44
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT70
open ProofsInTheBook.ZinanFFCT71
open ProofsInTheBook.ZinanFFCT74
open ProofsInTheBook.ZinanFFCT75

namespace ProofsInTheBook.ZinanFFCT76

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000





















end ProofsInTheBook.ZinanFFCT76

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT76
-/
/- Source module: ProofsInTheBook.ZinanFFCT77 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT19
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47
open ProofsInTheBook.ZinanFFCT48
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT57
open ProofsInTheBook.ZinanFFCT58
open ProofsInTheBook.ZinanFFCT61
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT65
open ProofsInTheBook.ZinanFFCT66
open ProofsInTheBook.ZinanFFCT68
open ProofsInTheBook.ZinanFFCT69
open ProofsInTheBook.ZinanFFCT70
open ProofsInTheBook.ZinanFFCT71
open ProofsInTheBook.ZinanFFCT74
open ProofsInTheBook.ZinanFFCT76

namespace ProofsInTheBook.ZinanFFCT77

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000


































































end ProofsInTheBook.ZinanFFCT77

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT77
-/
/- Source module: ProofsInTheBook.ZinanFFCT78 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT19
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT61
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT68
open ProofsInTheBook.ZinanFFCT70
open ProofsInTheBook.ZinanFFCT71
open ProofsInTheBook.ZinanFFCT74
open ProofsInTheBook.ZinanFFCT75
open ProofsInTheBook.ZinanFFCT76
open ProofsInTheBook.ZinanFFCT77

namespace ProofsInTheBook.ZinanFFCT78

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000















end ProofsInTheBook.ZinanFFCT78

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT78
-/
/- Source module: ProofsInTheBook.ZinanFFCT79 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT68
open ProofsInTheBook.ZinanFFCT76
open ProofsInTheBook.ZinanFFCT77
open ProofsInTheBook.ZinanFFCT78

namespace ProofsInTheBook.ZinanFFCT79

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000





















end ProofsInTheBook.ZinanFFCT79

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT79
-/
/- Source module: ProofsInTheBook.ZinanFFCT80 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.ZinanFFCT12
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47
open ProofsInTheBook.ZinanFFCT48
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT68
open ProofsInTheBook.ZinanFFCT75
open ProofsInTheBook.ZinanFFCT76
open ProofsInTheBook.ZinanFFCT77
open ProofsInTheBook.ZinanFFCT78
open ProofsInTheBook.ZinanFFCT79

namespace ProofsInTheBook.ZinanFFCT80

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000







































































end ProofsInTheBook.ZinanFFCT80

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT80
-/
/- Source module: ProofsInTheBook.ZinanFFCT81 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.ZinanFFCT12
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT65
open ProofsInTheBook.ZinanFFCT68
open ProofsInTheBook.ZinanFFCT70
open ProofsInTheBook.ZinanFFCT74
open ProofsInTheBook.ZinanFFCT76
open ProofsInTheBook.ZinanFFCT77
open ProofsInTheBook.ZinanFFCT78
open ProofsInTheBook.ZinanFFCT79
open ProofsInTheBook.ZinanFFCT80

namespace ProofsInTheBook.ZinanFFCT81

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000










































end ProofsInTheBook.ZinanFFCT81

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT81
-/
/- Source module: ProofsInTheBook.ZinanFFCT82 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.ZinanFFCT12
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT65
open ProofsInTheBook.ZinanFFCT68
open ProofsInTheBook.ZinanFFCT70
open ProofsInTheBook.ZinanFFCT74
open ProofsInTheBook.ZinanFFCT76
open ProofsInTheBook.ZinanFFCT77
open ProofsInTheBook.ZinanFFCT78
open ProofsInTheBook.ZinanFFCT79
open ProofsInTheBook.ZinanFFCT80
open ProofsInTheBook.ZinanFFCT81

namespace ProofsInTheBook.ZinanFFCT82

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000


































end ProofsInTheBook.ZinanFFCT82

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT82
-/
/- Source module: ProofsInTheBook.ZinanFFCT83 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.ZinanFFCT12
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT22
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT24
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT65
open ProofsInTheBook.ZinanFFCT68
open ProofsInTheBook.ZinanFFCT70
open ProofsInTheBook.ZinanFFCT74
open ProofsInTheBook.ZinanFFCT76
open ProofsInTheBook.ZinanFFCT77
open ProofsInTheBook.ZinanFFCT78
open ProofsInTheBook.ZinanFFCT79
open ProofsInTheBook.ZinanFFCT80
open ProofsInTheBook.ZinanFFCT81
open ProofsInTheBook.ZinanFFCT82

namespace ProofsInTheBook.ZinanFFCT83

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000







































end ProofsInTheBook.ZinanFFCT83

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT83
-/
/- Source module: ProofsInTheBook.ZinanFFCT84 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.ZinanFFCT12
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT22
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT24
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT65
open ProofsInTheBook.ZinanFFCT68
open ProofsInTheBook.ZinanFFCT70
open ProofsInTheBook.ZinanFFCT74
open ProofsInTheBook.ZinanFFCT76
open ProofsInTheBook.ZinanFFCT77
open ProofsInTheBook.ZinanFFCT78
open ProofsInTheBook.ZinanFFCT79
open ProofsInTheBook.ZinanFFCT80
open ProofsInTheBook.ZinanFFCT81
open ProofsInTheBook.ZinanFFCT82
open ProofsInTheBook.ZinanFFCT83

namespace ProofsInTheBook.ZinanFFCT84

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1600000

















end ProofsInTheBook.ZinanFFCT84

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT84
-/
/- Source module: ProofsInTheBook.ZinanFFCT85 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.ZinanFFCT12
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT22
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT24
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT61
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT65
open ProofsInTheBook.ZinanFFCT68
open ProofsInTheBook.ZinanFFCT69
open ProofsInTheBook.ZinanFFCT70
open ProofsInTheBook.ZinanFFCT71
open ProofsInTheBook.ZinanFFCT74
open ProofsInTheBook.ZinanFFCT75
open ProofsInTheBook.ZinanFFCT76
open ProofsInTheBook.ZinanFFCT77
open ProofsInTheBook.ZinanFFCT78
open ProofsInTheBook.ZinanFFCT79
open ProofsInTheBook.ZinanFFCT80
open ProofsInTheBook.ZinanFFCT81
open ProofsInTheBook.ZinanFFCT82
open ProofsInTheBook.ZinanFFCT83
open ProofsInTheBook.ZinanFFCT84

namespace ProofsInTheBook.ZinanFFCT85

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1800000









































end ProofsInTheBook.ZinanFFCT85

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT85
-/
/- Source module: ProofsInTheBook.ZinanFFCT86 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.ZinanFFCT12
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT22
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT24
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT61
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT65
open ProofsInTheBook.ZinanFFCT68
open ProofsInTheBook.ZinanFFCT69
open ProofsInTheBook.ZinanFFCT70
open ProofsInTheBook.ZinanFFCT71
open ProofsInTheBook.ZinanFFCT74
open ProofsInTheBook.ZinanFFCT75
open ProofsInTheBook.ZinanFFCT76
open ProofsInTheBook.ZinanFFCT77
open ProofsInTheBook.ZinanFFCT78
open ProofsInTheBook.ZinanFFCT79
open ProofsInTheBook.ZinanFFCT80
open ProofsInTheBook.ZinanFFCT81
open ProofsInTheBook.ZinanFFCT82
open ProofsInTheBook.ZinanFFCT83
open ProofsInTheBook.ZinanFFCT84
open ProofsInTheBook.ZinanFFCT85

namespace ProofsInTheBook.ZinanFFCT86

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1800000








































end ProofsInTheBook.ZinanFFCT86

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT86
-/
/- Source module: ProofsInTheBook.ZinanFFCT100 -/
section
set_option autoImplicit true




open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT78
open ProofsInTheBook.ZinanFFCT86

namespace ProofsInTheBook.ZinanFFCT100







end ProofsInTheBook.ZinanFFCT100




end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanFFCT100
-/
/- Source module: ProofsInTheBook.ZinanFFCT111 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation
open ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZStepClose
open ProofsInTheBook.SphericalSZFinal
open ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalArmAssembly
open ProofsInTheBook.SphericalMonitoredSup
open ProofsInTheBook.SphericalOpeningOutcome
open ProofsInTheBook.SphericalReachStuck
open ProofsInTheBook.SphericalStuckGeneral
open ProofsInTheBook.SphericalCutTransport
open ProofsInTheBook.PlanarConvexDiag
open ProofsInTheBook.SphericalCyclicTriple
open ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalDiagCut
open ProofsInTheBook.SphericalGnomonic
open ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.ZinanFFCT3
open ProofsInTheBook.ZinanFFCT20
open ProofsInTheBook.ZinanFFCT37
open ProofsInTheBook.ZinanFFCT12
open ProofsInTheBook.ZinanFFCT18
open ProofsInTheBook.ZinanFFCT22
open ProofsInTheBook.ZinanFFCT23
open ProofsInTheBook.ZinanFFCT24
open ProofsInTheBook.ZinanFFCT25
open ProofsInTheBook.ZinanFFCT45
open ProofsInTheBook.ZinanFFCT46
open ProofsInTheBook.ZinanFFCT47
open ProofsInTheBook.ZinanFFCT49
open ProofsInTheBook.ZinanFFCT52
open ProofsInTheBook.ZinanFFCT56
open ProofsInTheBook.ZinanFFCT61
open ProofsInTheBook.ZinanFFCT64
open ProofsInTheBook.ZinanFFCT65
open ProofsInTheBook.ZinanFFCT66
open ProofsInTheBook.ZinanFFCT68
open ProofsInTheBook.ZinanFFCT69
open ProofsInTheBook.ZinanFFCT70
open ProofsInTheBook.ZinanFFCT71
open ProofsInTheBook.ZinanFFCT74
open ProofsInTheBook.ZinanFFCT75
open ProofsInTheBook.ZinanFFCT76
open ProofsInTheBook.ZinanFFCT77
open ProofsInTheBook.ZinanFFCT78
open ProofsInTheBook.ZinanFFCT79
open ProofsInTheBook.ZinanFFCT80
open ProofsInTheBook.ZinanFFCT81
open ProofsInTheBook.ZinanFFCT82
open ProofsInTheBook.ZinanFFCT83
open ProofsInTheBook.ZinanFFCT84
open ProofsInTheBook.ZinanFFCT85
open ProofsInTheBook.ZinanFFCT86
open ProofsInTheBook.ZinanFFCT100

namespace ProofsInTheBook.ZinanFFCT111

set_option synthInstance.maxHeartbeats 400000
set_option maxHeartbeats 1800000













































































end ProofsInTheBook.ZinanFFCT111

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalReachStuck
import ProofsInTheBook.SphericalSZFinal
import ProofsInTheBook.SphericalSZClose
import ProofsInTheBook.ZinanFFCT111
-/
/- Source module: ProofsInTheBook.ZinanFFCT113 -/
section
set_option autoImplicit true




noncomputable section

open scoped RealInnerProductSpace NNReal
open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalRotation ProofsInTheBook.SphericalCore
open ProofsInTheBook.SphericalHinge ProofsInTheBook.SphericalHingeCut
open ProofsInTheBook.SphericalFinish ProofsInTheBook.SphericalSZStep
open ProofsInTheBook.SphericalReachStuck ProofsInTheBook.SphericalSZInduction
open ProofsInTheBook.SphericalSZFinal ProofsInTheBook.SphericalSZClose
open ProofsInTheBook.SphericalMonitoredSup ProofsInTheBook.SphericalOpeningProcess
open ProofsInTheBook.ZinanFFCT78 ProofsInTheBook.ZinanFFCT111

namespace ProofsInTheBook.ZinanFFCT113

set_option maxHeartbeats 1600000































end ProofsInTheBook.ZinanFFCT113

end
end

/- Original source header (imports hoisted):
import ProofsInTheBook.SphericalOpenedArmCore
import ProofsInTheBook.ZinanFFCT111
import ProofsInTheBook.ZinanFFCT113
-/
/- Source module: ProofsInTheBook.ZinanFFCT112 -/
section
set_option autoImplicit true




namespace ProofsInTheBook.ZinanFFCT112

open ProofsInTheBook.SphericalKernel
open ProofsInTheBook.SphericalArm
open ProofsInTheBook.SphericalOpenedArmCore












end ProofsInTheBook.ZinanFFCT112




end

/- Original source header (imports hoisted):
import Mathlib
import ProofsInTheBook.ZinanFFCT112
-/
/- Source module: ProofsInTheBook.Chapter13 -/
section
set_option autoImplicit true




namespace ProofsInTheBook.Chapter13

open ProofsInTheBook.SphericalKernel ProofsInTheBook.SphericalArm



open EdgeSign























namespace StrictTriangleSigns





end StrictTriangleSigns

















namespace CauchyArmOpeningObstruction



end CauchyArmOpeningObstruction



namespace CauchyArmClosingObstruction



end CauchyArmClosingObstruction



namespace CauchyArmFixedChordObstruction



end CauchyArmFixedChordObstruction

















namespace CauchyArmVertex







end CauchyArmVertex



namespace CauchyRigidityCertificate







end CauchyRigidityCertificate











end ProofsInTheBook.Chapter13

end

/- Original source header (imports hoisted):
import Mathlib
import ProofsInTheBook.Chapter13
-/
/- Source module: ProofsInTheBook.Ch13CyclicSigns -/
section
set_option autoImplicit true




namespace ProofsInTheBook.Ch13CyclicSigns

open ProofsInTheBook.Chapter13
open EdgeSign



variable {α : Type*} [DecidableEq α]

























end ProofsInTheBook.Ch13CyclicSigns

end

/- Original source header (imports hoisted):
import Mathlib
import ProofsInTheBook.PlanarMap
import ProofsInTheBook.Chapter13
import ProofsInTheBook.Ch13CyclicSigns
-/
/- Source module: ProofsInTheBook.Ch13MarkedSphere -/
section
set_option autoImplicit true




namespace ProofsInTheBook.Ch13MarkedSphere

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.Chapter13
open ProofsInTheBook.Ch13CyclicSigns

variable {D : Type*} [Fintype D] [DecidableEq D]





























































































end ProofsInTheBook.Ch13MarkedSphere

end

/- Original source header (imports hoisted):
import Mathlib
import ProofsInTheBook.PlanarMap
import ProofsInTheBook.Chapter13
import ProofsInTheBook.Ch13CyclicSigns
import ProofsInTheBook.Ch13MarkedSphere
-/
/- Source module: ProofsInTheBook.Ch13MarkedReduction -/
section
set_option autoImplicit true




namespace ProofsInTheBook.Ch13MarkedReduction

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.Chapter13
open ProofsInTheBook.Ch13CyclicSigns
open ProofsInTheBook.Ch13MarkedSphere
open EdgeSign
open Equiv Equiv.Perm



section ListBridge

variable {α : Type*} [DecidableEq α]







end ListBridge



section OrbitBridge

variable {α : Type*} [DecidableEq α] [Fintype α] {β : Type*} [DecidableEq β]









end OrbitBridge



section StrictBridge

variable {D : Type*} [Fintype D] [DecidableEq D]











end StrictBridge



section ActiveComponent

variable {D : Type*} [Fintype D] [DecidableEq D]













end ActiveComponent



section Obstruction
































end Obstruction

end ProofsInTheBook.Ch13MarkedReduction

end

/- Original source header (imports hoisted):
import Mathlib
import ProofsInTheBook.PlanarMap
import ProofsInTheBook.PlanarMapSimple
import ProofsInTheBook.PlanarMapDelete
import ProofsInTheBook.SubmapPlanar
import ProofsInTheBook.Chapter13
import ProofsInTheBook.Ch13CyclicSigns
import ProofsInTheBook.Ch13MarkedSphere
import ProofsInTheBook.Ch13MarkedReduction
-/
/- Source module: ProofsInTheBook.Ch13ActiveComponent -/
section
set_option autoImplicit true




namespace ProofsInTheBook.Ch13ActiveComponent

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.Chapter13
open ProofsInTheBook.Ch13CyclicSigns
open ProofsInTheBook.Ch13MarkedSphere
open ProofsInTheBook.Ch13MarkedReduction
open EdgeSign

variable {D : Type*} [Fintype D] [DecidableEq D]

















open ProofsInTheBook.SubmapPlanar













  -- unreachable on active darts























end ProofsInTheBook.Ch13ActiveComponent

end

/- Original source header (imports hoisted):
import Mathlib
import ProofsInTheBook.PlanarMap
import ProofsInTheBook.PlanarMapSimple
import ProofsInTheBook.PlanarMapDelete
import ProofsInTheBook.SubmapPlanar
import ProofsInTheBook.Chapter13
import ProofsInTheBook.Ch13CyclicSigns
import ProofsInTheBook.Ch13MarkedSphere
import ProofsInTheBook.Ch13MarkedReduction
import ProofsInTheBook.Ch13ActiveComponent
-/
/- Source module: ProofsInTheBook.Ch13FlipTransport -/
section
set_option autoImplicit true




namespace ProofsInTheBook.Ch13FlipTransport

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.Chapter13
open ProofsInTheBook.Ch13CyclicSigns
open ProofsInTheBook.Ch13MarkedSphere
open ProofsInTheBook.Ch13MarkedReduction
open ProofsInTheBook.Ch13ActiveComponent
open ProofsInTheBook.SubmapPlanar
open EdgeSign
open Equiv Equiv.Perm

variable {D : Type*} [Fintype D] [DecidableEq D]



open ProofsInTheBook -- for DeleteSet.firstOutside via Equiv.Perm namespace









































































end ProofsInTheBook.Ch13FlipTransport

end

/- Original source header (imports hoisted):
import Mathlib
import ProofsInTheBook.PlanarMap
import ProofsInTheBook.PlanarMapSimple
import ProofsInTheBook.PlanarMapEuler
import ProofsInTheBook.PlanarMapDelete
import ProofsInTheBook.SubmapPlanar
import ProofsInTheBook.Chapter13
import ProofsInTheBook.Ch13CyclicSigns
import ProofsInTheBook.Ch13MarkedSphere
import ProofsInTheBook.Ch13MarkedReduction
import ProofsInTheBook.Ch13ActiveComponent
import ProofsInTheBook.Ch13FlipTransport
import ProofsInTheBook.PlanarMapNearTriangulation
-/
/- Source module: ProofsInTheBook.Ch13ComponentClose -/
section
set_option autoImplicit true




namespace ProofsInTheBook.Ch13ComponentClose

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.Chapter13
open ProofsInTheBook.Ch13CyclicSigns
open ProofsInTheBook.Ch13MarkedSphere
open ProofsInTheBook.Ch13MarkedReduction
open ProofsInTheBook.Ch13ActiveComponent
open ProofsInTheBook.Ch13FlipTransport
open ProofsInTheBook.SubmapPlanar
open EdgeSign
open Equiv Equiv.Perm

variable {D : Type*} [Fintype D] [DecidableEq D]

















































variable (M : CombMap D) (es : D → EdgeSign)











































end ProofsInTheBook.Ch13ComponentClose

end

/- Original source header (imports hoisted):
import ProofsInTheBook.Ch13ComponentClose
import ProofsInTheBook.ChordFaceCount
import ProofsInTheBook.PlanarMapSimple
-/
/- Source module: ProofsInTheBook.FaceDiagonalSurgery -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.PlanarMap.CombMap

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordFaceCount
open ProofsInTheBook.ChordSideRecon

universe u

variable {D : Type u} [Fintype D] [DecidableEq D]



namespace FaceDiagonalChoice

variable {M : CombMap D} (c : FaceDiagonalChoice M)



















end FaceDiagonalChoice









namespace FaceDiagonal

variable (M : CombMap D) (c : FaceDiagonalChoice M)



































































end FaceDiagonal



attribute [instance] FaceDiagonalInsertion.fintypeD' FaceDiagonalInsertion.decEqD'

namespace FaceDiagonalInsertion



end FaceDiagonalInsertion

end ProofsInTheBook.PlanarMap.CombMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapChordSplitData
import ProofsInTheBook.PlanarMapCutCap
-/
/- Source module: ProofsInTheBook.ZinanCh35StarRotation -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

















variable {M : CombMap D} (hNT : NearTriangulation M)













































end CombMap

end ProofsInTheBook.PlanarMap

-- Axiom audit for the main brick results (expect: propext, Classical.choice, Quot.sound).









end

/- Original source header (imports hoisted):
import ProofsInTheBook.SubmapPlanar
-/
/- Source module: ProofsInTheBook.ChordSideClose -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ChordSideClose

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.SubmapPlanar

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



section RawPrimitives

variable (M)

open scoped Classical







end RawPrimitives













section RawConnected

























end RawConnected











end ProofsInTheBook.ChordSideClose







end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordSideClose
import ProofsInTheBook.ChordSplitNT
-/
/- Source module: ProofsInTheBook.ChordReconClose -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ChordReconClose

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.ChordSideClose

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}





































end ProofsInTheBook.ChordReconClose










end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordReconClose
import ProofsInTheBook.ChordDisk
-/
/- Source module: ProofsInTheBook.ChordSideNT -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ChordSideNT

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.ChordDisk
open ProofsInTheBook.ChordReconClose

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}

























end ProofsInTheBook.ChordSideNT











end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordSideNT
import ProofsInTheBook.ChordSplitNT
-/
/- Source module: ProofsInTheBook.ChordSplitFinal -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ChordSplitFinal

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.ListColoring
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap
open ProofsInTheBook.ThomassenInduction
open ProofsInTheBook.ChordSplitNT
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ChordSideNT
open ProofsInTheBook.ChordDisk

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {α : Type u} [DecidableEq α]
variable {M : CombMap D} {hNT : NearTriangulation M} {u v : M.Vertex}



























end ProofsInTheBook.ChordSplitFinal



namespace ProofsInTheBook.ChordSplitFinal

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.ListColoring
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap
open ProofsInTheBook.ThomassenInduction
open ProofsInTheBook.ChordSplitNT

variable {α : Type u} [DecidableEq α]





end ProofsInTheBook.ChordSplitFinal












end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordSideNT
-/
/- Source module: ProofsInTheBook.ChordContiguous -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ChordContiguous

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.ChordSideNT

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



































end ProofsInTheBook.ChordContiguous













end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordContiguous
import ProofsInTheBook.ChordFaceCount
-/
/- Source module: ProofsInTheBook.ChordInnerTri -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ChordInnerTri

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.ChordFaceCount

universe u

variable {K : Type u} [Fintype K] [DecidableEq K]







section Splice

variable (β ρ : Equiv.Perm K) {a₀ a₁ : K}











end Splice



section Transfer

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)







end Transfer



section MTransfer

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}

























end MTransfer

open ProofsInTheBook.ChordContiguous

section Discharge

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}

















end Discharge

end ProofsInTheBook.ChordInnerTri















end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordInnerTri
-/
/- Source module: ProofsInTheBook.ChordFaceClass -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ChordFaceClass

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.ChordFaceCount
open ProofsInTheBook.ChordInnerTri
open ProofsInTheBook.ChordContiguous

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



































end ProofsInTheBook.ChordFaceClass













end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordFaceClass
-/
/- Source module: ProofsInTheBook.ChordBoundaryOrbit -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ChordBoundaryOrbit

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.ChordFaceCount
open ProofsInTheBook.ChordInnerTri
open ProofsInTheBook.ChordContiguous
open ProofsInTheBook.ChordFaceClass

universe u

variable {K : Type u} [Fintype K] [DecidableEq K]



section Trace

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)









end Trace



section Membership

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)







end Membership



















section Untouched

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)



end Untouched



section Discharge

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}





















end Discharge

end ProofsInTheBook.ChordBoundaryOrbit



















end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordBoundaryOrbit
-/
/- Source module: ProofsInTheBook.ChordFaceFinal -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ChordFaceFinal

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.ChordFaceCount
open ProofsInTheBook.ChordInnerTri
open ProofsInTheBook.ChordContiguous
open ProofsInTheBook.ChordFaceClass
open ProofsInTheBook.ChordBoundaryOrbit

universe u

variable {K : Type u} [Fintype K] [DecidableEq K]



section Formula

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)













end Formula



section Consequences

variable (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)

include hne







end Consequences



section Discharge

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}

































end Discharge

end ProofsInTheBook.ChordFaceFinal

















end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordFaceFinal
-/
/- Source module: ProofsInTheBook.ChordAnchor -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ChordAnchor

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.ChordFaceCount
open ProofsInTheBook.ChordInnerTri
open ProofsInTheBook.ChordContiguous
open ProofsInTheBook.ChordFaceClass
open ProofsInTheBook.ChordBoundaryOrbit
open ProofsInTheBook.ChordFaceFinal

universe u



section TwoCycle

variable {K : Type u} [DecidableEq K]



variable [Fintype K]





end TwoCycle



section Card

variable {K : Type u} [Fintype K] [DecidableEq K]



end Card



section Discharge

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}































end Discharge

end ProofsInTheBook.ChordAnchor














end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordAnchor
-/
/- Source module: ProofsInTheBook.ChordAnchorInst -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ChordAnchorInst

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.ChordFaceCount
open ProofsInTheBook.ChordInnerTri
open ProofsInTheBook.ChordBoundaryOrbit
open ProofsInTheBook.ChordFaceFinal
open ProofsInTheBook.ChordAnchor

universe u



section Algebra

variable {K : Type u} [Fintype K] [DecidableEq K]





end Algebra



section KeptPhi

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}





end KeptPhi



section Residue

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}

















end Residue

end ProofsInTheBook.ChordAnchorInst













end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordAnchorInst
-/
/- Source module: ProofsInTheBook.ChordBigonWrap -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option linter.dupNamespace false

namespace ProofsInTheBook.ChordBigonWrap

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.ChordFaceCount
open ProofsInTheBook.ChordInnerTri
open ProofsInTheBook.ChordBoundaryOrbit
open ProofsInTheBook.ChordFaceFinal
open ProofsInTheBook.ChordAnchor
open ProofsInTheBook.ChordAnchorInst

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}































end ProofsInTheBook.ChordBigonWrap













end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordBigonWrap
-/
/- Source module: ProofsInTheBook.ChordSigmaContig -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option linter.dupNamespace false

namespace ProofsInTheBook.ChordSigmaContig

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.ChordFaceCount
open ProofsInTheBook.ChordInnerTri
open ProofsInTheBook.ChordBoundaryOrbit
open ProofsInTheBook.ChordFaceFinal
open ProofsInTheBook.ChordAnchor
open ProofsInTheBook.ChordAnchorInst
open ProofsInTheBook.ChordBigonWrap

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}









































end ProofsInTheBook.ChordSigmaContig

















end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordSigmaContig
-/
/- Source module: ProofsInTheBook.ZinanCh35SideAnchors -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ZinanCh35SideAnchors

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.ChordFaceCount
open ProofsInTheBook.ChordInnerTri
open ProofsInTheBook.ChordBoundaryOrbit
open ProofsInTheBook.ChordFaceFinal
open ProofsInTheBook.ChordAnchor
open ProofsInTheBook.ChordAnchorInst
open ProofsInTheBook.ChordSigmaContig

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}































end ProofsInTheBook.ZinanCh35SideAnchors













end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35SideAnchors
-/
/- Source module: ProofsInTheBook.ZinanCh35Hclass -/
section
set_option autoImplicit true


/-!
# The Chapter 35 chord-side `hclass` gluing bricks (the `ContiguousInterval` master glue)

`ZinanCh35SideAnchors.lean` pinned the **canonical** chord-cap anchors `a₀, a₁` of side 1 and
proved, UNCONDITIONALLY, the post-splice `tracePhi` 2-cycle on the two kept `face₁` darts
(`side₁Anchors_trace12`/`trace21`).  This file assembles those anchor facts, together with the
explicit-trace orbit machinery of `ChordBoundaryOrbit` and the correct-anchor structure of
`ChordAnchor`, into the master **per-face classifier** consumed by
`ChordAnchor.contiguousInterval_of_correctAnchor`:

> for every non-outer side face `g`, EITHER `g` has a splice-untouched, side-`₁`,
> non-`face₁` kept-`inl` representative, OR `g` carries a `CorrectAnchorTwoCycle` datum.

and then feeds it into the final `ContiguousInterval` assembler.

## Bricks (design §8 order)

1.  Notation block (`β ρ a₀ a₁ hne S τ`).
2.  `side₁_trace_beta_a0_to_face₁Dart₁` — `τ (β a₀) = face₁Dart₁ data`
    (`tracePhi_b0` + `sideSigma₁_side₁Anchor₁`).
3.  `side₁_chord0_face_eq_face₁_canonical` — `S.dartFace (inr 0) = S.dartFace (inl face₁Dart₁)`
    (`chordDart_face_eq_b0` + `sideFace_inl_eq_iff_tracePhi` via brick 2).
4.  `Side₁OuterTraceData` — the INPUT bundle (outer face + its boundary cycle, the two chord/face
    incidence facts, and the inner-rep avoidance residue).
5.  `side₁Anchors_oneFresh_canonical` — the one-fresh indicator `= 1`.
6.  `side₁_correctAnchor_face₁_canonical` — the `CorrectAnchorTwoCycle` datum for the touched
    `face₁` side face (`correctAnchorTwoCycle_ofFace₁` + bricks 5 & landed trace12/trace21).
7.  `side1_hclass_canonical` — the MASTER per-face classifier (face₁ branch transports brick 6
    across the face equality; no-hit branch uses `spliceUntouched_of_face_ne_chordOrbits`).
8.  `contiguousInterval_canonical` — feed brick 7 into `contiguousInterval_of_correctAnchor`.

**Input-bundle addition (reported per the design's license).**  The design's
`Side₁OuterTraceData` lists `outerFace, outerCycle, outer_simple, outer_len, chord1_is_outer,
face₁_not_outer`.  The no-hit branch's `M.dartFace k.1 ∈ side₁` (`hside`) obligation is the
genuine geometric residue "the side outer face is exactly the `M`-outer-arc orbit, so every other
face's rep avoids the `M`-outer face" — NOT derivable from the abstract `CombMap`.  Rather than
weaken, we carry it as the repo-native field `inner_reps :
ChordBoundaryOrbit.InnerRepsAvoidBoundary …` (which packages exactly "each non-outer side face has
a kept-`inl` rep with `M`-face `≠ M`-outer and `≠ face₁`"), as the design explicitly permits.

No `sorry` / `axiom` / `admit` / `native_decide`.
-/

set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ZinanCh35Hclass

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.ChordFaceCount
open ProofsInTheBook.ChordInnerTri
open ProofsInTheBook.ChordFaceClass
open ProofsInTheBook.ChordBoundaryOrbit
open ProofsInTheBook.ChordFaceFinal
open ProofsInTheBook.ChordAnchor
open ProofsInTheBook.ChordAnchorInst
open ProofsInTheBook.ChordSigmaContig
open ProofsInTheBook.ZinanCh35SideAnchors

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}

































end ProofsInTheBook.ZinanCh35Hclass










end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35Hclass
import ProofsInTheBook.PlanarMapDeletedBoundary
-/
/- Source module: ProofsInTheBook.ZinanCh35OuterTrace -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35OuterTrace

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.ChordFaceCount
open ProofsInTheBook.ChordInnerTri
open ProofsInTheBook.ChordFaceClass
open ProofsInTheBook.ChordBoundaryOrbit
open ProofsInTheBook.ChordFaceFinal
open ProofsInTheBook.ChordAnchor
open ProofsInTheBook.ChordAnchorInst
open ProofsInTheBook.ChordSigmaContig
open ProofsInTheBook.ZinanCh35SideAnchors
open ProofsInTheBook.ZinanCh35Hclass

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

universe u



section PermSplit

variable {D : Type*} [Fintype D] [DecidableEq D]





end PermSplit



section Canonical

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}













end Canonical

end ProofsInTheBook.ZinanCh35OuterTrace









end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordSplitFinal
import ProofsInTheBook.ZinanCh35OuterTrace
-/
/- Source module: ProofsInTheBook.ZinanCh35Iota -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35Iota

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ChordSideNT
open ProofsInTheBook.ChordSplitFinal
open ProofsInTheBook.ChordDisk
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex} {α : Type u} [DecidableEq α]































end ProofsInTheBook.ZinanCh35Iota









end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapCutCapSigma
-/
/- Source module: ProofsInTheBook.PlanarMapCutCapSigma2 -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}



                 -- c_i^- ↦ p_i

             -- c_i^- ↦ ℓ_i^- = σ⁻¹ q_i





































/-- The corrected concrete cut-and-cap combinatorial map. -/
noncomputable def cutCapMap2 (C : SimplePrimalCycle M) : CombMap C.CutDart where
  α := C.cutAlphaPerm
  σ := C.cutSigmaPerm2
  α_invol := by
    ext x
    show C.cutAlpha (C.cutAlpha x) = x
    exact C.cutAlpha_involutive x
  α_no_fixed := by
    intro x
    show C.cutAlpha x ≠ x
    exact C.cutAlpha_no_fixed x

@[simp] lemma cutCapMap2_alpha (C : SimplePrimalCycle M) :
    (C.cutCapMap2).α = C.cutAlphaPerm := rfl

@[simp] lemma cutCapMap2_sigma (C : SimplePrimalCycle M) :
    (C.cutCapMap2).σ = C.cutSigmaPerm2 := rfl







/-- A `+`-bank-end dart `ℓ_i^+ = σ⁻¹ p_i` diverts into the *previous* `+`-cap
`c_{prevIdx i}^+` (the corrected splice). -/
lemma cutSigma2_plusEnd (C : SimplePrimalCycle M) {d : D} {i : Fin C.len}
    (h : M.σ d = C.pDart i) :
    (C.cutCapMap2).σ (Sum.inl d) = Sum.inr (Sum.inl (C.prevIdx i)) :=
  C.cutSigma2_inl_plus (C.divertKind_plus h)

/-- A `−`-bank-end dart `ℓ_i^- = σ⁻¹ q_i` diverts into the `−`-cap `c_i^-`. -/
lemma cutSigma2_minusEnd (C : SimplePrimalCycle M) {d : D} {i : Fin C.len}
    (h : M.σ d = C.qDart i) :
    (C.cutCapMap2).σ (Sum.inl d) = Sum.inr (Sum.inr i) :=
  C.cutSigma2_inl_minus (C.divertKind_minus h)

/-- Away from the bank ends the rotation is unchanged: `σ' (inl d) = inl (σ d)`. -/
lemma cutSigma2_clean (C : SimplePrimalCycle M) {d : D}
    (hp : ∀ i, M.σ d ≠ C.pDart i) (hq : ∀ i, M.σ d ≠ C.qDart i) :
    (C.cutCapMap2).σ (Sum.inl d) = Sum.inl (M.σ d) :=
  C.cutSigma2_inl_none (C.divertKind_none hp hq)

end SimplePrimalCycle





/-- **Edge count of the corrected map** — proved unconditionally, since `α'` is
unchanged.  `cutAlpha` is a fixed-point-free involution, so `E' = E + k`. -/
theorem cutCapMap2_edge_count {M : CombMap D} (C : SimplePrimalCycle M) :
    (C.cutCapMap2).E = M.E + C.len := by
  have hN : 2 * (C.cutCapMap2).E = Fintype.card C.CutDart := (C.cutCapMap2).two_mul_E_eq_card
  have hM : 2 * M.E = Fintype.card D := M.two_mul_E_eq_card
  have hcard : Fintype.card C.CutDart = Fintype.card D + 2 * C.len := by
    simp [CombMap.SimplePrimalCycle.CutDart, Fintype.card_sum, Fintype.card_fin]
    ring
  omega





end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapCutCapF
-/
/- Source module: ProofsInTheBook.PlanarMapCutCapFCore -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open Equiv Equiv.Perm Function

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}

open CutCapCount























end SimplePrimalCycle

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapCutCapSigma2
import ProofsInTheBook.PlanarMapCutCapFCore
-/
/- Source module: ProofsInTheBook.PlanarMapCutCap2Counts -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open Equiv Equiv.Perm Function

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}

open CutCapCount



/-- `nextIdx` as an `Equiv.Perm (Fin C.len)`, with inverse `prevIdx`. -/
def nextIdxEquiv (C : SimplePrimalCycle M) : Equiv.Perm (Fin C.len) where
  toFun := C.nextIdx
  invFun := C.prevIdx
  left_inv := C.prevIdx_nextIdx
  right_inv := C.nextIdx_prevIdx

@[simp] lemma nextIdxEquiv_apply (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.nextIdxEquiv i = C.nextIdx i := rfl

@[simp] lemma nextIdxEquiv_symm_apply (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.nextIdxEquiv.symm i = C.prevIdx i := rfl

/-- The `+`-cap index-shift conjugator: identity on `D` and on the `−`-caps,
`c_i^+ ↦ c_{nextIdx i}^+` on the `+`-caps. -/
def capShift (C : SimplePrimalCycle M) : Equiv.Perm C.CutDart :=
  Equiv.Perm.sumCongr (1 : Equiv.Perm D)
    (Equiv.Perm.sumCongr C.nextIdxEquiv (1 : Equiv.Perm (Fin C.len)))

@[simp] lemma capShift_inl (C : SimplePrimalCycle M) (d : D) :
    C.capShift (Sum.inl d) = Sum.inl d := by simp [capShift]

@[simp] lemma capShift_capP (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.capShift (Sum.inr (Sum.inl i)) = Sum.inr (Sum.inl (C.nextIdx i)) := by
  simp [capShift]

@[simp] lemma capShift_capM (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.capShift (Sum.inr (Sum.inr i)) = Sum.inr (Sum.inr i) := by simp [capShift]









/-- The conjugation intertwiner: `g ∘ σ'₂ = σ' ∘ g`. -/
lemma capShift_cutSigma2 (C : SimplePrimalCycle M) (x : C.CutDart) :
    C.capShift (C.cutSigma2 x) = C.cutSigma (C.capShift x) := by
  rcases x with d | (i | i)
  · -- inl d : classify by divertKind d (shared by cutSigma and cutSigma2)
    rcases hd : C.divertKind d with (i | i) | u
    · -- ℓ_i^+ : σ'₂ ↦ c_{prevIdx i}^+, shifted back to c_i^+ = σ' (inl d)
      rw [C.cutSigma2_inl_plus hd, capShift_capP, C.nextIdx_prevIdx, capShift_inl,
        C.cutSigma_inl_plus hd]
    · -- ℓ_i^- : both ↦ c_i^-, g fixes inl d and c_i^-
      rw [C.cutSigma2_inl_minus hd, capShift_capM, capShift_inl, C.cutSigma_inl_minus hd]
    · -- clean : both ↦ inl (σ d), g fixes both inl darts
      rw [C.cutSigma2_inl_none hd, capShift_inl, capShift_inl, C.cutSigma_inl_none hd]
  · -- c_i^+ : σ'₂ (c_i^+) = inl (dart (nextIdx i)) = inl (q_{nextIdx i})
    rw [C.cutSigma2_capPlus, capShift_inl, capShift_capP, C.cutSigma_capPlus, qDart_def]
  · -- c_i^- : σ'₂ (c_i^-) = inl (p_i); g fixes c_i^- and inl (p_i)
    rw [C.cutSigma2_capMinus, capShift_inl, capShift_capM, C.cutSigma_capMinus]

/-- **The conjugation identity** `σ'₂ = g⁻¹ · σ' · g`. -/
theorem cutSigmaPerm2_eq_conj (C : SimplePrimalCycle M) :
    C.cutSigmaPerm2 = C.capShift⁻¹ * C.cutSigmaPerm * C.capShift := by
  ext x
  rw [cutSigmaPerm2_apply, Equiv.Perm.coe_mul, Equiv.Perm.coe_mul,
    Function.comp_apply, Function.comp_apply, cutSigmaPerm_apply]
  -- goal: cutSigma2 x = capShift⁻¹ (cutSigma (capShift x))
  rw [← C.capShift_cutSigma2 x]
  exact (C.capShift.symm_apply_apply _).symm



/-- **The corrected cut-and-cap rotation has `V + k` cycles.**  By the conjugation
`σ'₂ = g⁻¹ σ' g` and conjugation-invariance of `numCycles`, this equals the buggy
count, already proved to be `V + k`. -/
theorem numCycles_cutSigmaPerm2 (C : SimplePrimalCycle M) :
    _root_.numCycles C.cutSigmaPerm2 = M.V + C.len := by
  rw [cutSigmaPerm2_eq_conj]
  rw [show C.capShift⁻¹ * C.cutSigmaPerm * C.capShift
        = C.capShift⁻¹ * C.cutSigmaPerm * (C.capShift⁻¹)⁻¹ by rw [inv_inv]]
  rw [CutCapCount.numCycles_conj, numCycles_cutSigmaPerm]

/-- **The vertex count of the corrected cut-and-cap map: `V' = V + k`.**  This is
the `vertex_count` field of `CutSigmaCounts2`. -/
theorem cutCapMap2_V (C : SimplePrimalCycle M) :
    (C.cutCapMap2).V = M.V + C.len := by
  rw [CombMap.V_eq_numCycles, cutCapMap2_sigma, numCycles_cutSigmaPerm2]

-- Triangle anchor (`PlanarMapCutCapEval.lean`):  V' = 6 = V + k = 3 + 3.



/-- `φ'₂ x = cutSigma2 (cutAlpha x)`. -/
lemma cutCapPhi2_apply (C : SimplePrimalCycle M) (x : C.CutDart) :
    (C.cutCapMap2).φ x = C.cutSigma2 (C.cutAlpha x) := by
  rw [CombMap.φ, Equiv.Perm.mul_apply, cutCapMap2_alpha, cutCapMap2_sigma,
    cutAlphaPerm_apply, cutSigmaPerm2_apply]

/-- **Corrected forward cycle dart action.**  `φ'₂ (inl (dart i)) = inl (dart
(nextIdx i))`: the forward cycle darts now thread forward (the fix), where in the
buggy map they were fixed points. -/
@[simp] lemma cutCapPhi2_dart (C : SimplePrimalCycle M) (i : Fin C.len) :
    (C.cutCapMap2).φ (Sum.inl (C.dart i)) = Sum.inl (C.dart (C.nextIdx i)) := by
  rw [cutCapPhi2_apply, cutAlpha_dart,
    show (Sum.inr (Sum.inl i) : C.CutDart) = C.capP i from rfl,
    show C.capP i = Sum.inr (Sum.inl i) from rfl, cutSigma2_capPlus]

/-- The reverse cycle dart: `φ'₂ (inl (α (dart i))) = inl (p_i)` (unchanged from the
buggy map, since the `−`-bank wiring is unchanged). -/
@[simp] lemma cutCapPhi2_alpha_dart (C : SimplePrimalCycle M) (i : Fin C.len) :
    (C.cutCapMap2).φ (Sum.inl (M.α (C.dart i))) = Sum.inl (C.pDart i) := by
  rw [cutCapPhi2_apply, cutAlpha_alpha_dart,
    show (Sum.inr (Sum.inr i) : C.CutDart) = C.capM i from rfl,
    show C.capM i = Sum.inr (Sum.inr i) from rfl, cutSigma2_capMinus]

/-- **Generic three-way action of `σ'₂` on an `inl` dart.**  `σ'₂ (inl e)` is either
`inl (σ e)` (clean), diverts into the *previous* `+`-cap when `σ e = p_i`, or into
the `−`-cap when `σ e = q_i`. -/
lemma cutSigma2_inl_cases (C : SimplePrimalCycle M) (e : D) :
    (C.cutCapMap2).σ (Sum.inl e) = Sum.inl (M.σ e) ∨
      (∃ i, M.σ e = C.pDart i ∧
        (C.cutCapMap2).σ (Sum.inl e) = Sum.inr (Sum.inl (C.prevIdx i))) ∨
      (∃ i, M.σ e = C.qDart i ∧
        (C.cutCapMap2).σ (Sum.inl e) = Sum.inr (Sum.inr i)) := by
  by_cases hp : ∃ i, M.σ e = C.pDart i
  · obtain ⟨i, hi⟩ := hp
    exact Or.inr (Or.inl ⟨i, hi, C.cutSigma2_plusEnd hi⟩)
  · by_cases hq : ∃ i, M.σ e = C.qDart i
    · obtain ⟨i, hi⟩ := hq
      exact Or.inr (Or.inr ⟨i, hi, C.cutSigma2_minusEnd hi⟩)
    · exact Or.inl (C.cutSigma2_clean (fun i hi => hp ⟨i, hi⟩) (fun i hi => hq ⟨i, hi⟩))





/-- **Action of `φ'₂` on a non-cycle `inl d`** (`d ∉ dartSet`).  `cutAlpha (inl d) =
inl (α d)`, so `φ'₂ (inl d) = σ'₂ (inl (α d))`: clean `inl (φ d)` or a cap divert. -/
lemma cutCapPhi2_inl_other_cases (C : SimplePrimalCycle M) {d : D} (h : d ∉ C.dartSet) :
    (C.cutCapMap2).φ (Sum.inl d) = Sum.inl (M.φ d) ∨
      (∃ j, M.σ (M.α d) = C.pDart j ∧
        (C.cutCapMap2).φ (Sum.inl d) = Sum.inr (Sum.inl (C.prevIdx j))) ∨
      (∃ j, M.σ (M.α d) = C.qDart j ∧
        (C.cutCapMap2).φ (Sum.inl d) = Sum.inr (Sum.inr j)) := by
  rw [cutCapPhi2_apply, C.cutAlpha_other h, ← cutSigmaPerm2_apply, ← cutCapMap2_sigma]
  have := C.cutSigma2_inl_cases (M.α d)
  rwa [show M.σ (M.α d) = M.φ d from rfl] at this



/-- **The pinned corrected face core.**  `numCycles φ'₂ = F + 2` for the corrected
cut map.  This is the single isolated topological fact of the corrected Chapter 35
face count: the two cap chains are exactly two new `φ'₂`-orbits and every old face
survives (rerouted) as exactly one.  Kernel-anchored at `F' = 4` (triangle),
`F' = 6` (tetrahedron). -/
def NumCyclesCutPhi2 (C : SimplePrimalCycle M) : Prop :=
  _root_.numCycles ((C.cutCapMap2).φ) = M.F + 2



-- Triangle anchor (`PlanarMapCutCapEval.lean`):  F' = 4 = F + 2 = 2 + 2.







end SimplePrimalCycle

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapCutCapSigma
-/
/- Source module: ProofsInTheBook.PlanarMapCutCapEval -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv



section Counters

variable {α : Type*} [DecidableEq α]

















end Counters



namespace TriangleMap

open CombMap



















-- α', σ', φ' cycle counts of the *base* triangle map:
                 -- V = 3 (expected)
                 -- E = 3 (expected)
  -- F = 2 (expected)
-- χ = V - E + F = 3 - 3 + 2 = 2.


-- base-map connectivity: one dartStep component.
        -- c = 1 (connected, expected)

end TriangleMap



namespace TriangleCut

open CombMap TriangleMap

/-- The cut dart type: `6 + (3+3) = 12` darts. -/
abbrev CD := Fin 6 ⊕ (Fin 3 ⊕ Fin 3)

instance : Fintype CD := inferInstance
instance : DecidableEq CD := inferInstance























-- σ' table:  (enc x, enc (σ' x))

-- α' table:

-- φ' = σ' ∘ α' table:




-- E' = number of α'-cycles  (expected 6 = E + k = 3 + 3):

-- V' = number of σ'-cycles  (expected 6 = V + k = 3 + 3):

-- F' = number of φ'-cycles  (φ' = σ' ∘ α'):

-- χ' = V' - E' + F'




-- c = number of dartStep-components of the cut map  (the disputed number):


-- Sanity: cutAlphaC and cutSigmaC are bijections (images have 12 distinct darts).
   -- expect 12
   -- expect 12


  -- F + 2c - 2





              -- c_i^- ↦ p_i

-- corrected σ' table:

-- corrected φ' = σ'₂ ∘ α':


-- CORRECTED verdict numbers:
                              -- E' = 6
                             -- V' = 6
    -- F' = 4  (FIXED)
  -- χ' = 4
               -- c = 2  (FIXED)
-- corrected σ'₂ is a bijection (12 distinct images):
  -- 12

end TriangleCut

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapCutCap2Counts
import ProofsInTheBook.PlanarMapCutCapEval
-/
/- Source module: ProofsInTheBook.PlanarMapCutCap2F -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open Equiv Equiv.Perm Function

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}

open CutCapCount























end SimplePrimalCycle

end CombMap



namespace TriangleCut

open TriangleMap

-- Corrected `φ'₂ = σ'₂ ∘ α'` face-cycle count on the triangle cut:
-- expected `4 = F + 2` (`F = 2`).
   -- 4

-- The explicit `φ'₂`-orbit partition on the triangle (the structural reconnaissance):
-- forward cycle darts `{0,2,4}`, the reverse face `{1,5,3}`, the `+`-caps, the
-- `−`-caps — four orbits, `F' = 4 = F + 2`.


end TriangleCut

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapCutCap2F
-/
/- Source module: ProofsInTheBook.PlanarMapCutCap2FWalk -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open Equiv Equiv.Perm Function

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}

open CutCapCount



/-- The corrected face-correction product `faceCorr₂ := phiLift⁻¹ · φ'₂`. -/
noncomputable def faceCorr2 (C : SimplePrimalCycle M) : Equiv.Perm C.CutDart :=
  C.phiLift⁻¹ * (C.cutCapMap2).φ

/-- **The corrected face permutation factors through `phiLift`:**
`φ'₂ = phiLift * faceCorr₂` (a pure-group identity). -/
theorem cutCapPhi2_eq_phiLift_mul (C : SimplePrimalCycle M) :
    (C.cutCapMap2).φ = C.phiLift * C.faceCorr2 := by
  rw [faceCorr2, ← mul_assoc, mul_inv_cancel, one_mul]



















end SimplePrimalCycle

end CombMap



namespace TriangleCut

open TriangleMap

-- Corrected `φ'₂ = σ'₂ ∘ α'` face-cycle count on the triangle cut: `4 = F + 2`.
   -- 4

-- `phiLift` reference count `F + 2k = 2 + 6 = 8` (caps as 2k singletons):
   -- 8 = F + 2k

-- The two `faceCorr₂` cap chains (here pure caps `{+0,+2,+1}` and `{−0,−1,−2}`):
-- print the `φ'₂`-orbit reps so the `−(k−1)` per chain is anchored.


end TriangleCut

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapCutCap2FWalk
import ProofsInTheBook.PlanarMapEulerInequality
-/
/- Source module: ProofsInTheBook.ForcedSplits -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option maxHeartbeats 1600000

open Equiv Equiv.Perm Function

namespace ForcedSplits



variable {X : Type*} [Fintype X] [DecidableEq X]

/-- **Split step raises `numCycles` by one.**  If `x ≠ y` are in the same `p`-cycle,
multiplying by the transposition `swap x y` splits that cycle, raising the count by
exactly one. -/
theorem numCycles_mul_swap_split (p : Equiv.Perm X) {x y : X}
    (hxy : x ≠ y) (hsc : p.SameCycle x y) :
    numCycles (p * Equiv.swap x y) = numCycles p + 1 := by
  rcases numCycles_mul_swap_dichotomy p hxy with h | h
  · exact h
  · -- the `−1` branch contradicts `SameCycle`-monotonicity
    have hle := PermTranspositionCycleCount.numCycles_le_mul_swap_of_sameCycle p hsc
    omega

/-- **Every swap step lowers `numCycles` by at most one.**  `numCycles (p · swap x y)`
is at least `numCycles p − 1` for any `x, y` (including the degenerate `x = y`, where
`swap x y = 1` and the count is unchanged). -/
theorem numCycles_mul_swap_ge_sub_one (p : Equiv.Perm X) (x y : X) :
    (numCycles (p * Equiv.swap x y) : ℤ) ≥ (numCycles p : ℤ) - 1 := by
  rcases eq_or_ne x y with rfl | hxy
  · have hswap : Equiv.swap x x = (1 : Equiv.Perm X) := by
      ext z
      simp
    rw [hswap, mul_one]
    omega
  · rcases numCycles_mul_swap_dichotomy p hxy with h | h <;> omega



/-- A swap record: an unordered pair of darts presented as an ordered pair. -/
structure Swap (X : Type*) where
  x : X
  y : X

/-- The transposition permutation of a swap record. -/
def Swap.perm [DecidableEq X] (s : Swap X) : Equiv.Perm X :=
  Equiv.swap s.x s.y

/-- The prefix product of the first `j` letters of a transposition word `W`,
applied on the right of the base permutation `p` (recursive form). -/
def prefixPerm [DecidableEq X] (p : Equiv.Perm X) {m : ℕ}
    (W : Fin m → Swap X) : ℕ → Equiv.Perm X
  | 0 => p
  | j + 1 =>
      if h : j < m then
        prefixPerm p W j * (W ⟨j, h⟩).perm
      else
        prefixPerm p W j

@[simp] lemma prefixPerm_zero [DecidableEq X] (p : Equiv.Perm X) {m : ℕ}
    (W : Fin m → Swap X) : prefixPerm p W 0 = p := rfl

/-- The one-step recursion for `prefixPerm` at a valid index. -/
lemma prefixPerm_succ [DecidableEq X] (p : Equiv.Perm X) {m : ℕ}
    (W : Fin m → Swap X) {j : ℕ} (hj : j < m) :
    prefixPerm p W (j + 1) = prefixPerm p W j * (W ⟨j, hj⟩).perm := by
  simp [prefixPerm, hj]

/-- The actual integer `numCycles`-delta of one walk step. -/
noncomputable def stepDelta (p : Equiv.Perm X) {m : ℕ} (W : Fin m → Swap X)
    (j : Fin m) : ℤ :=
  (numCycles (prefixPerm p W (j.val + 1)) : ℤ) - (numCycles (prefixPerm p W j.val) : ℤ)

/-- **Every walk step lowers `numCycles` by at most one**: `stepDelta ≥ −1`,
unconditionally (the degenerate identity swap has delta `0 ≥ −1`). -/
lemma stepDelta_ge_neg_one (p : Equiv.Perm X) {m : ℕ} (W : Fin m → Swap X)
    (j : Fin m) : stepDelta p W j ≥ (-1 : ℤ) := by
  have hj : j.val < m := j.isLt
  rw [stepDelta, prefixPerm_succ p W hj, Swap.perm]
  have := numCycles_mul_swap_ge_sub_one (prefixPerm p W j.val)
    (W ⟨j.val, hj⟩).x (W ⟨j.val, hj⟩).y
  linarith

/-- **A certified split step raises `numCycles` by exactly one**: if the two
endpoints of the `j`-th transposition are distinct and lie in the same cycle of the
prefix product, then `stepDelta = 1`. -/
lemma stepDelta_eq_one_of_forced_split (p : Equiv.Perm X) {m : ℕ} (W : Fin m → Swap X)
    (j : Fin m) (hne : (W j).x ≠ (W j).y)
    (hsc : (prefixPerm p W j.val).SameCycle (W j).x (W j).y) :
    stepDelta p W j = 1 := by
  have hj : j.val < m := j.isLt
  have hj' : (⟨j.val, hj⟩ : Fin m) = j := by ext; rfl
  rw [stepDelta, prefixPerm_succ p W hj, Swap.perm, hj']
  have := numCycles_mul_swap_split (prefixPerm p W j.val) hne hsc
  rw [this]; push_cast; ring

/-- **Telescoping**: the net `numCycles`-change over the whole word is the sum of the
step deltas. -/
lemma numCycles_prefix_telescopes (p : Equiv.Perm X) {m : ℕ} (W : Fin m → Swap X) :
    (numCycles (prefixPerm p W m) : ℤ) - (numCycles p : ℤ)
      = ∑ j : Fin m, stepDelta p W j := by
  induction m with
  | zero => simp
  | succ n ih =>
      -- restrict the word to its first `n` letters
      let W' : Fin n → Swap X := fun i => W ⟨i.val, Nat.lt_succ_of_lt i.isLt⟩
      have hpre : ∀ j : ℕ, j ≤ n → prefixPerm p W j = prefixPerm p W' j := by
        intro j hjn
        induction j with
        | zero => rfl
        | succ i ihj =>
            have hin : i < n := hjn
            have hisn : i < n + 1 := Nat.lt_succ_of_lt hin
            rw [prefixPerm_succ p W hisn, prefixPerm_succ p W' hin,
              ihj (Nat.le_of_lt hin)]
      have hlast : prefixPerm p W (n + 1)
          = prefixPerm p W' n * (W ⟨n, Nat.lt_succ_self n⟩).perm := by
        rw [prefixPerm_succ p W (Nat.lt_succ_self n), hpre n le_rfl]
      -- sum over Fin (n+1) splits into the first `n` and the last term
      rw [Fin.sum_univ_castSucc]
      have hstepCast : ∀ i : Fin n, stepDelta p W i.castSucc = stepDelta p W' i := by
        intro i
        have hi1 : (i.castSucc.val + 1) ≤ n := i.isLt
        have hi0 : i.castSucc.val ≤ n := Nat.le_of_lt i.isLt
        rw [stepDelta, stepDelta, hpre _ hi1, hpre _ hi0]
        rfl
      simp only [hstepCast]
      have ihW' := ih W'
      have hlastDelta : stepDelta p W (Fin.last n)
          = (numCycles (prefixPerm p W (n + 1)) : ℤ)
            - (numCycles (prefixPerm p W' n) : ℤ) := by
        rw [stepDelta]
        simp only [Fin.val_last]
        rw [hpre n le_rfl]
      rw [hlastDelta, ← ihW']
      ring



/-- **Lower bound on the sum of step deltas from `s` forced splits.**  If `s`
distinct indices are certified splits (distinct endpoints, `SameCycle` at the
prefix), the total `numCycles`-change is at least `−m + 2s`: each certified index
contributes `+1`, every other index contributes at least `−1`. -/
lemma sum_stepDelta_lower_of_forced_splits (p : Equiv.Perm X) {m s : ℕ}
    (W : Fin m → Swap X) (splitIdx : Fin s → Fin m)
    (hsinj : Function.Injective splitIdx)
    (hne : ∀ i : Fin s, (W (splitIdx i)).x ≠ (W (splitIdx i)).y)
    (hforced : ∀ i : Fin s,
      (prefixPerm p W (splitIdx i).val).SameCycle
        (W (splitIdx i)).x (W (splitIdx i)).y) :
    (∑ j : Fin m, stepDelta p W j) ≥ (-(m : ℤ) + 2 * (s : ℤ)) := by
  classical
  let S : Finset (Fin m) := Finset.univ.image splitIdx
  have hcardS : S.card = s := by
    rw [Finset.card_image_of_injective _ hsinj, Finset.card_univ, Fintype.card_fin]
  -- on `S` each delta is exactly `1`
  have h_on : ∀ j ∈ S, stepDelta p W j = 1 := by
    intro j hj
    rcases Finset.mem_image.mp hj with ⟨i, _, rfl⟩
    exact stepDelta_eq_one_of_forced_split p W (splitIdx i) (hne i) (hforced i)
  -- everywhere each delta is at least `-1`
  have h_all : ∀ j : Fin m, stepDelta p W j ≥ (-1 : ℤ) := stepDelta_ge_neg_one p W
  -- split the sum over `S` and its complement
  have hsplit : (∑ j : Fin m, stepDelta p W j)
      = (∑ j ∈ S, stepDelta p W j) + (∑ j ∈ Sᶜ, stepDelta p W j) := by
    rw [← Finset.sum_add_sum_compl S]
  have hSsum : (∑ j ∈ S, stepDelta p W j) = (s : ℤ) := by
    rw [Finset.sum_congr rfl h_on, Finset.sum_const, hcardS]
    simp
  have hCsum : (∑ j ∈ Sᶜ, stepDelta p W j) ≥ -((Sᶜ).card : ℤ) := by
    calc (∑ j ∈ Sᶜ, stepDelta p W j) ≥ ∑ _j ∈ Sᶜ, (-1 : ℤ) :=
          Finset.sum_le_sum (fun j _ => h_all j)
      _ = -((Sᶜ).card : ℤ) := by rw [Finset.sum_const]; simp
  have hcompl : (Sᶜ).card = m - s := by
    rw [Finset.card_compl, Fintype.card_fin, hcardS]
  have hsle : s ≤ m := by
    have := hcardS ▸ Finset.card_le_univ S
    simpa [Finset.card_univ, Fintype.card_fin] using this
  rw [hsplit, hSsum]
  have hcomplZ : ((Sᶜ).card : ℤ) = (m : ℤ) - (s : ℤ) := by
    rw [hcompl]; omega
  rw [hcomplZ] at hCsum
  linarith

/-- **The main generic lower bound.**  A word of length `m` with `s` certified forced
splits (distinct endpoints, `SameCycle` at the prefix, distinct indices) raises
`numCycles` by at least `−m + 2s`:
`numCycles (prefixPerm p W m) ≥ numCycles p − m + 2s`. -/
theorem numCycles_lower_of_forced_splits (p : Equiv.Perm X) {m s : ℕ}
    (W : Fin m → Swap X) (splitIdx : Fin s → Fin m)
    (hsinj : Function.Injective splitIdx)
    (hne : ∀ i : Fin s, (W (splitIdx i)).x ≠ (W (splitIdx i)).y)
    (hforced : ∀ i : Fin s,
      (prefixPerm p W (splitIdx i).val).SameCycle
        (W (splitIdx i)).x (W (splitIdx i)).y) :
    (numCycles (prefixPerm p W m) : ℤ)
      ≥ (numCycles p : ℤ) - (m : ℤ) + 2 * (s : ℤ) := by
  have htel := numCycles_prefix_telescopes p W
  have hsum := sum_stepDelta_lower_of_forced_splits p W splitIdx hsinj hne hforced
  linarith






end ForcedSplits



namespace ProofsInTheBook.PlanarMap

open ForcedSplits CombMap CombMap.SimplePrimalCycle

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}

/-- The forced-split lower-bound certificate for `faceCorr₂`: a transposition word `W`
of length `m`, realising `φ'₂ = phiLift · faceCorr₂` as its prefix product, with `s`
certified split steps and the arithmetic constraint `m + 2 ≤ 2·s + 2·len`. -/
structure FaceCorrLowerCert (C : SimplePrimalCycle M) where
  /-- The word length. -/
  m : ℕ
  /-- The number of certified split steps. -/
  s : ℕ
  /-- The arithmetic constraint making the telescope close to `F + 2`:
  `(F + 2·len) − m + 2·s ≥ F + 2`. -/
  hbound : m + 2 ≤ 2 * s + 2 * C.len
  /-- The fixed transposition word. -/
  W : Fin m → ForcedSplits.Swap C.CutDart
  /-- The prefix product realises `φ'₂ = phiLift · faceCorr₂`. -/
  prefix_eq : ForcedSplits.prefixPerm C.phiLift W m = C.phiLift * C.faceCorr2
  /-- The `s` distinguished split indices. -/
  splitIdx : Fin s → Fin m
  splitIdx_injective : Function.Injective splitIdx
  /-- Each split transposition has distinct endpoints. -/
  split_ne : ∀ i : Fin s,
    (W (splitIdx i)).x ≠ (W (splitIdx i)).y
  /-- Each split step's endpoints are `SameCycle` under the prefix product
  (the local forced-split certificate). -/
  forced_split : ∀ i : Fin s,
    (ForcedSplits.prefixPerm C.phiLift W (splitIdx i).val).SameCycle
      (W (splitIdx i)).x (W (splitIdx i)).y



/-- **The corrected face-cycle lower bound from a certificate.**  Telescoping the `s`
forced splits against `numCycles phiLift = F + 2·len` gives, via the constraint
`m + 2 ≤ 2·s + 2·len`, `numCycles φ'₂ ≥ (F + 2·len) − m + 2·s ≥ F + 2`. -/
theorem numCycles_cutCapPhi2_lower (C : SimplePrimalCycle M)
    (cert : C.FaceCorrLowerCert) :
    (_root_.numCycles ((C.cutCapMap2).φ) : ℤ) ≥ (M.F : ℤ) + 2 := by
  -- The generic lower bound on the prefix product.
  have hgen := ForcedSplits.numCycles_lower_of_forced_splits
    C.phiLift cert.W cert.splitIdx cert.splitIdx_injective cert.split_ne cert.forced_split
  -- Identify the full prefix with `φ'₂`.
  rw [cert.prefix_eq, ← cutCapPhi2_eq_phiLift_mul] at hgen
  -- `numCycles phiLift = F + 2·len`.
  have hphi : (_root_.numCycles C.phiLift : ℤ) = (M.F : ℤ) + 2 * (C.len : ℤ) := by
    rw [C.numCycles_phiLift]; push_cast; ring
  rw [hphi] at hgen
  -- The arithmetic constraint, cast to ℤ.
  have hboundZ : (cert.m : ℤ) + 2 ≤ 2 * (cert.s : ℤ) + 2 * (C.len : ℤ) := by
    have := cert.hbound; omega
  -- (F + 2·len) − m + 2·s ≥ F + 2.
  linarith

/-- **The face count of the corrected cut-and-cap map is at least `F + 2`**
(genus-free), from a forced-split certificate.  `(cutCapMap2).F ≥ M.F + 2`. -/
theorem cutCapMap2_F_lower (C : SimplePrimalCycle M) (cert : C.FaceCorrLowerCert) :
    (C.cutCapMap2).F ≥ M.F + 2 := by
  have h := numCycles_cutCapPhi2_lower C cert
  rw [CombMap.F_eq_numCycles]
  -- `(F : ℤ) ≥ F + 2` ⇒ `F ≥ F + 2` in ℕ.
  have : (M.F : ℤ) + 2 ≤ (_root_.numCycles ((C.cutCapMap2).φ) : ℤ) := h
  omega



/-- **From a connected cut map, `F' ≤ F`.**  Pure Euler arithmetic: `V' = V + k`,
`E' = E + k`, and the connected Euler inequality `χ' ≤ 2` with `χ = 2`. -/
theorem cutCapMap2_F_le_of_connected (C : SimplePrimalCycle M)
    (hchi : M.eulerChar = 2)
    (hconn : (C.cutCapMap2).Connected) :
    (C.cutCapMap2).F ≤ M.F := by
  have hle : (C.cutCapMap2).eulerChar ≤ 2 :=
    CombMap.chi_le_two_of_connected _ hconn
  have hV : (C.cutCapMap2).V = M.V + C.len := C.cutCapMap2_V
  have hE : (C.cutCapMap2).E = M.E + C.len := cutCapMap2_edge_count C
  -- expand χ' = V' − E' + F' and χ = V − E + F = 2.
  unfold CombMap.eulerChar at hle hchi
  rw [hV, hE] at hle
  push_cast at hle hchi
  omega

/-- **The lower-bound Jordan / chord-separation theorem.**  Given a forced-split
certificate, the Euler hypothesis `M.eulerChar = 2`, and the per-edge connectivity
parameter, no cut edge of a simple primal cycle on a sphere is straddled by a
cycle-avoiding dual path.  This consumes only the genus-free **lower bound**
`F' ≥ F + 2` (via `cert`), not the exact face count. -/
theorem jordan_simple_cycle2_lower (C : SimplePrimalCycle M)
    (cert : C.FaceCorrLowerCert)
    (hchi : M.eulerChar = 2)
    (hconn : ∀ i : Fin C.len,
      DualReachableAvoidingCycle M C (C.faceLeft i) (C.faceRight i) →
        (C.cutCapMap2).Connected)
    (i : Fin C.len) :
    ¬ DualReachableAvoidingCycle M C (C.faceLeft i) (C.faceRight i) := by
  intro hpath
  have hconnected : (C.cutCapMap2).Connected := hconn i hpath
  have hle : (C.cutCapMap2).F ≤ M.F :=
    C.cutCapMap2_F_le_of_connected hchi hconnected
  have hge : (C.cutCapMap2).F ≥ M.F + 2 := C.cutCapMap2_F_lower cert
  omega

end SimplePrimalCycle

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapCutCap2FWalk
-/
/- Source module: ProofsInTheBook.PlanarMapSeamChain -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option maxHeartbeats 1600000

open Equiv Equiv.Perm Function List

namespace ProofsInTheBook.PlanarMap

namespace SeamChain

variable {X : Type*} [Fintype X] [DecidableEq X]







/-- `cycleOfList` is Mathlib's `List.formPerm`. -/
abbrev cycleOfList (L : List X) : Equiv.Perm X := L.formPerm

/-- **The prefix walk step.**  Extending the prefix `L.take (j+1)` by one element
multiplies `formPerm` on the right by the swap of the two new consecutive elements:

  `formPerm (L.take (j+2)) = formPerm (L.take (j+1)) * swap L[j] L[j+1]`. -/
theorem formPerm_take_succ (L : List X) {j : ℕ} (hj : j + 1 < L.length) :
    cycleOfList (L.take (j + 2))
      = cycleOfList (L.take (j + 1))
        * Equiv.swap (L[j]'(by omega)) (L[j+1]'hj) := by
  -- `L.take (j+2) = L.take j ++ [L[j], L[j+1]]` and `L.take (j+1) = L.take j ++ [L[j]]`.
  have hjlt : j < L.length := by omega
  have h1 : L.take (j + 2) = L.take j ++ [L[j]'hjlt, L[j+1]'hj] := by
    have he : L.take (j + 2) = L.take (j + 1 + 1) := by ring_nf
    rw [he, List.take_add_one, List.take_add_one]
    simp only [List.getElem?_eq_getElem hj, List.getElem?_eq_getElem hjlt,
      Option.toList, List.append_assoc, List.singleton_append]
  have h2 : L.take (j + 1) = L.take j ++ [L[j]'hjlt] := by
    rw [List.take_add_one]
    simp only [List.getElem?_eq_getElem hjlt, Option.toList]
  simp only [cycleOfList]
  rw [h1, List.formPerm_append_pair, ← h2]













































namespace SeamChainData

































































end SeamChainData



namespace SeamChainData













end SeamChainData

end SeamChain

end ProofsInTheBook.PlanarMap
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ForcedSplits
import ProofsInTheBook.PlanarMapSeamChain
-/
/- Source module: ProofsInTheBook.FaceCorrWord -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option maxHeartbeats 1600000

open Equiv Equiv.Perm Function List

namespace ProofsInTheBook.PlanarMap

namespace FaceCorrWord

open ForcedSplits SeamChain

variable {X : Type*} [Fintype X] [DecidableEq X]



/-- The consecutive-transposition word of a list: letter `j` swaps `L[j]` and `L[j+1]`. -/
def wordOfList (L : List X) : Fin (L.length - 1) → ForcedSplits.Swap X :=
  fun j => ⟨L[j.val]'(by have := j.isLt; omega),
            L[j.val + 1]'(by have := j.isLt; omega)⟩

/-- **The list→word prefix identity.**  Building the prefix product of `wordOfList L`
through the first `j` letters reproduces `p * formPerm (L.take (j+1))`, for every
`j < L.length`.  Pure `Equiv.Perm` over any finite `X`, no hypotheses on `L`. -/
lemma prefixPerm_wordOfList (p : Equiv.Perm X) (L : List X) :
    ∀ j : ℕ, j < L.length →
      ForcedSplits.prefixPerm p (wordOfList L) j = p * cycleOfList (L.take (j + 1)) := by
  intro j
  induction j with
  | zero =>
      intro hj
      -- `take 1` of a nonempty list is a singleton; `formPerm` of a singleton is `1`.
      have hone : cycleOfList (L.take 1) = 1 := by
        rcases L with _ | ⟨x, xs⟩
        · simp at hj
        · simp [cycleOfList, List.take_succ_cons, List.formPerm_singleton]
      rw [ForcedSplits.prefixPerm_zero, hone, mul_one]
  | succ i ih =>
      intro hj
      have hi : i < L.length := by omega
      have hiw : i < L.length - 1 := by omega
      -- one step of `prefixPerm`
      rw [ForcedSplits.prefixPerm_succ p (wordOfList L) hiw, ih hi]
      -- `Swap.perm (wordOfList L ⟨i, _⟩) = swap L[i] L[i+1]`
      have hstep : i + 1 < L.length := hj
      have hword : (wordOfList L ⟨i, hiw⟩).perm
          = Equiv.swap (L[i]'hi) (L[i+1]'hstep) := by
        simp only [ForcedSplits.Swap.perm, wordOfList]
      rw [hword]
      -- `formPerm (take (i+2)) = formPerm (take (i+1)) * swap L[i] L[i+1]`
      have hfp := SeamChain.formPerm_take_succ L (j := i) hstep
      rw [show i + 1 + 1 = i + 2 from rfl, hfp, ← mul_assoc]

/-- **The full word realises `p * formPerm L`** (universal).  For a list `L` of length
`≥ 1`, `prefixPerm p (wordOfList L) (L.length − 1) = p * formPerm L`. -/
lemma prefixPerm_wordOfList_full (p : Equiv.Perm X) (L : List X) (hpos : 0 < L.length) :
    ForcedSplits.prefixPerm p (wordOfList L) (L.length - 1) = p * cycleOfList L := by
  have hj : L.length - 1 < L.length := by omega
  rw [prefixPerm_wordOfList p L (L.length - 1) hj]
  have htake : L.take (L.length - 1 + 1) = L := List.take_of_length_le (by omega)
  rw [htake]



/-- The concatenation of two transposition words. -/
def appendWord {m₁ m₂ : ℕ} (W₁ : Fin m₁ → ForcedSplits.Swap X)
    (W₂ : Fin m₂ → ForcedSplits.Swap X) : Fin (m₁ + m₂) → ForcedSplits.Swap X :=
  fun j => if h : j.val < m₁ then W₁ ⟨j.val, h⟩
           else W₂ ⟨j.val - m₁, by have := j.isLt; omega⟩

/-- `prefixPerm` through the first `m₁` letters of `appendWord W₁ W₂` only sees `W₁`. -/
lemma prefixPerm_appendWord_left {m₁ m₂ : ℕ} (p : Equiv.Perm X)
    (W₁ : Fin m₁ → ForcedSplits.Swap X) (W₂ : Fin m₂ → ForcedSplits.Swap X) :
    ∀ j : ℕ, j ≤ m₁ →
      ForcedSplits.prefixPerm p (appendWord W₁ W₂) j = ForcedSplits.prefixPerm p W₁ j := by
  intro j
  induction j with
  | zero => intro _; rfl
  | succ i ih =>
      intro hj
      have hi1 : i < m₁ := by omega
      have hi1' : i < m₁ + m₂ := by omega
      rw [ForcedSplits.prefixPerm_succ p (appendWord W₁ W₂) hi1',
        ForcedSplits.prefixPerm_succ p W₁ hi1, ih (by omega)]
      congr 1
      simp only [appendWord, dif_pos hi1]

/-- `prefixPerm` through all of `appendWord W₁ W₂` composes: it is `W₂` applied on top of
the full `W₁`-prefix. -/
lemma prefixPerm_appendWord {m₁ m₂ : ℕ} (p : Equiv.Perm X)
    (W₁ : Fin m₁ → ForcedSplits.Swap X) (W₂ : Fin m₂ → ForcedSplits.Swap X) :
    ∀ j : ℕ, j ≤ m₂ →
      ForcedSplits.prefixPerm p (appendWord W₁ W₂) (m₁ + j)
        = ForcedSplits.prefixPerm (ForcedSplits.prefixPerm p W₁ m₁) W₂ j := by
  intro j
  induction j with
  | zero =>
      intro _
      rw [Nat.add_zero, ForcedSplits.prefixPerm_zero]
      exact prefixPerm_appendWord_left p W₁ W₂ m₁ le_rfl
  | succ i ih =>
      intro hj
      have hi2 : i < m₂ := by omega
      have hi12 : m₁ + i < m₁ + m₂ := by omega
      rw [show m₁ + (i + 1) = (m₁ + i) + 1 from rfl,
        ForcedSplits.prefixPerm_succ p (appendWord W₁ W₂) hi12,
        ForcedSplits.prefixPerm_succ (ForcedSplits.prefixPerm p W₁ m₁) W₂ hi2,
        ih (by omega)]
      congr 1
      have hnlt : ¬ (m₁ + i < m₁) := by omega
      simp only [appendWord, dif_neg hnlt]
      have hidx : (⟨m₁ + i - m₁, by omega⟩ : Fin m₂) = ⟨i, hi2⟩ :=
        Fin.ext (show m₁ + i - m₁ = i by omega)
      rw [hidx]



/-- Total length of the concatenated word: `Σ_{L ∈ Ls} (L.length − 1)`. -/
def concatLen : List (List X) → ℕ
  | [] => 0
  | L :: rest => (L.length - 1) + concatLen rest

/-- The concatenated consecutive-transposition word of a list-of-lists.  By construction
its index type `Fin (concatLen (L :: rest))` reduces definitionally to
`Fin ((L.length − 1) + concatLen rest)`, so `appendWord` applies with no cast. -/
def concatWord : (Ls : List (List X)) → Fin (concatLen Ls) → ForcedSplits.Swap X
  | [] => fun j => absurd j.isLt (by simp [concatLen])
  | L :: rest => appendWord (wordOfList L) (concatWord rest)

/-- The product of `formPerm` over the lists of `Ls` (the cycle-decomposition product). -/
def cycleListProd : List (List X) → Equiv.Perm X
  | [] => 1
  | L :: rest => cycleOfList L * cycleListProd rest

/-- **The concatenated word realises the cycle-decomposition product.**  For a
list-of-lists `Ls` each of whose members has length `≥ 1`,
`prefixPerm p (concatWord Ls) (concatLen Ls) = p * cycleListProd Ls`. -/
lemma prefixPerm_concatWord (p : Equiv.Perm X) :
    ∀ Ls : List (List X), (∀ L ∈ Ls, 0 < L.length) →
      ForcedSplits.prefixPerm p (concatWord Ls) (concatLen Ls)
        = p * cycleListProd Ls := by
  intro Ls
  induction Ls generalizing p with
  | nil => intro _; simp [concatWord, concatLen, cycleListProd]
  | cons L rest ih =>
      intro hpos
      have hLpos : 0 < L.length := hpos L (List.mem_cons_self ..)
      have hrest : ∀ L' ∈ rest, 0 < L'.length := fun L' hL' => hpos L' (List.mem_cons_of_mem L hL')
      -- `concatWord (L::rest) = appendWord (wordOfList L) (concatWord rest)`,
      -- `concatLen (L::rest) = (L.length-1) + concatLen rest`.
      show ForcedSplits.prefixPerm p (appendWord (wordOfList L) (concatWord rest))
            ((L.length - 1) + concatLen rest) = p * cycleListProd (L :: rest)
      rw [prefixPerm_appendWord p (wordOfList L) (concatWord rest) (concatLen rest) le_rfl,
        prefixPerm_wordOfList_full p L hLpos, ih (p * cycleOfList L) hrest]
      simp only [cycleListProd]
      rw [mul_assoc]



/-- `cycleListProd` is multiplicative over list concatenation. -/
theorem cycleListProd_append (Ls₁ Ls₂ : List (List X)) :
    cycleListProd (Ls₁ ++ Ls₂) = cycleListProd Ls₁ * cycleListProd Ls₂ := by
  induction Ls₁ with
  | nil => simp [cycleListProd]
  | cons L rest ih => simp only [List.cons_append, cycleListProd, ih, mul_assoc]



end FaceCorrWord



namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

open ForcedSplits FaceCorrWord SeamChain

variable {M : CombMap D}

/-- The split-only certificate: the universal cycle-decomposition word data, plus the
`s` split `SameCycle` facts and the arithmetic bound `concatLen Ls + 2 ≤ 2·s + 2·len`. -/
structure FaceCorrSplitCert (C : SimplePrimalCycle M) where
  /-- The cycle-decomposition support lists of `faceCorr₂` (each a nontrivial cycle). -/
  Ls : List (List C.CutDart)
  /-- Each cycle list is nonempty. -/
  Ls_pos : ∀ L ∈ Ls, 0 < L.length
  /-- The cycle-decomposition product reconstructs `faceCorr₂`. -/
  factor : FaceCorrWord.cycleListProd Ls = C.faceCorr2
  /-- The number of certified split steps. -/
  s : ℕ
  /-- The arithmetic constraint making the lower bound close to `F + 2`. -/
  hbound : FaceCorrWord.concatLen Ls + 2 ≤ 2 * s + 2 * C.len
  /-- The `s` distinguished split indices into the concatenated word. -/
  splitIdx : Fin s → Fin (FaceCorrWord.concatLen Ls)
  splitIdx_injective : Function.Injective splitIdx
  /-- Each split transposition has distinct endpoints. -/
  split_ne : ∀ i : Fin s,
    (FaceCorrWord.concatWord Ls (splitIdx i)).x ≠ (FaceCorrWord.concatWord Ls (splitIdx i)).y
  /-- Each split step's endpoints are `SameCycle` under the prefix product. -/
  forced_split : ∀ i : Fin s,
    (ForcedSplits.prefixPerm C.phiLift (FaceCorrWord.concatWord Ls) (splitIdx i).val).SameCycle
      (FaceCorrWord.concatWord Ls (splitIdx i)).x (FaceCorrWord.concatWord Ls (splitIdx i)).y

/-- **The universal word builder.**  A `FaceCorrSplitCert` yields a full
`FaceCorrLowerCert`: the word is `concatWord Ls`, and `prefix_eq` is discharged by
`prefixPerm_concatWord` + the cycle factorisation — no per-cut word construction needed. -/
def FaceCorrSplitCert.toLowerCert {C : SimplePrimalCycle M}
    (cert : C.FaceCorrSplitCert) : C.FaceCorrLowerCert where
  m := FaceCorrWord.concatLen cert.Ls
  s := cert.s
  hbound := cert.hbound
  W := FaceCorrWord.concatWord cert.Ls
  prefix_eq := by
    rw [FaceCorrWord.prefixPerm_concatWord C.phiLift cert.Ls cert.Ls_pos, cert.factor]
  splitIdx := cert.splitIdx
  splitIdx_injective := cert.splitIdx_injective
  split_ne := cert.split_ne
  forced_split := cert.forced_split





/-- **The lower-bound Jordan / chord-separation theorem from a split certificate.**  No
cut edge of a simple primal cycle on a sphere is straddled by a cycle-avoiding dual path,
consuming only the genus-free lower bound (via the split certificate) and the standing
connectivity / Euler parameters. -/
theorem jordan_simple_cycle2_lower_of_splitCert (C : SimplePrimalCycle M)
    (cert : C.FaceCorrSplitCert)
    (hchi : M.eulerChar = 2)
    (hconn : ∀ i : Fin C.len,
      DualReachableAvoidingCycle M C (C.faceLeft i) (C.faceRight i) →
        (C.cutCapMap2).Connected)
    (i : Fin C.len) :
    ¬ DualReachableAvoidingCycle M C (C.faceLeft i) (C.faceRight i) :=
  C.jordan_simple_cycle2_lower cert.toLowerCert hchi hconn i

end SimplePrimalCycle

end CombMap

end ProofsInTheBook.PlanarMap



namespace ProofsInTheBook.PlanarMap

namespace FaceCorrWord



end FaceCorrWord



namespace ProofsInTheBook.PlanarMap

namespace FaceCorrWordEval








section
variable {n : ℕ} (alpha sigma : Fin n → Fin n) (dart : Fin 3 → Fin n)






end






















-- The cycle-list word realises `phiLift · faceCorr₂` across genus (all `true`):



-- The cycle-list shapes (genus-dependent; the word is uniform, the splits are not):




end FaceCorrWordEval










end ProofsInTheBook.PlanarMap

end ProofsInTheBook.PlanarMap
end

/- Original source header (imports hoisted):
import ProofsInTheBook.FaceCorrWord
import ProofsInTheBook.RelationComponentCount
-/
/- Source module: ProofsInTheBook.TouchRank -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option maxHeartbeats 1600000

open Equiv Equiv.Perm Function

namespace ProofsInTheBook.TouchRank

open ForcedSplits

variable {X : Type*} [Fintype X] [DecidableEq X]



/-- The quotient of `X` by the `SameCycle p` relation: the set of `p`-orbits.  This is
*definitionally* the setoid underlying `numCycles p`. -/
def POrb (p : Equiv.Perm X) := Quotient (SameCycle.setoid p)

/-- `POrb p` is finite (quotient of a finite type). -/
instance (p : Equiv.Perm X) : Finite (POrb p) :=
  inferInstanceAs (Finite (Quotient (SameCycle.setoid p)))

noncomputable instance (p : Equiv.Perm X) : Fintype (POrb p) := Fintype.ofFinite _

noncomputable instance (p : Equiv.Perm X) : DecidableEq (POrb p) := Classical.decEq _

/-- The `p`-orbit of an element. -/
def pOrbOf (p : Equiv.Perm X) (x : X) : POrb p := Quotient.mk (SameCycle.setoid p) x









/-- The `p`-orbits met by the word `W`: for each letter, the orbits of its two endpoints. -/
noncomputable def wordTouchedOrbits (p : Equiv.Perm X) {m : ℕ} (W : Fin m → Swap X) :
    Finset (POrb p) :=
  Finset.univ.biUnion fun j : Fin m => {pOrbOf p (W j).x, pOrbOf p (W j).y}









/-- The coloring certificate bounding the touch-rank of `W` by `B`. -/
structure TouchColorCertBound (p : Equiv.Perm X) {m : ℕ} (W : Fin m → Swap X) (B : ℕ) where
  /-- The finite colour type (one colour per touched component). -/
  Color : Type*
  colorFintype : Fintype Color
  colorDecEq : DecidableEq Color
  /-- The partial colouring of `p`-orbits. -/
  color : POrb p → Option Color
  /-- Every touched `p`-orbit is coloured. -/
  color_some_of_touched : ∀ o ∈ wordTouchedOrbits p W, ∃ c, color o = some c
  /-- Every untouched `p`-orbit is uncoloured (colours mark exactly the touched
  components). -/
  color_none_of_untouched : ∀ o ∉ wordTouchedOrbits p W, color o = none
  /-- Every colour is used by some touched `p`-orbit. -/
  color_used : ∀ c : Color, ∃ o ∈ wordTouchedOrbits p W, color o = some c
  /-- Each letter's endpoints share a colour. -/
  endpoint_color_eq : ∀ j : Fin m, color (pOrbOf p (W j).x) = color (pOrbOf p (W j).y)
  /-- The rank bound. -/
  rank_bound : (wordTouchedOrbits p W).card - Fintype.card Color ≤ B

attribute [instance] TouchColorCertBound.colorFintype TouchColorCertBound.colorDecEq

variable {p : Equiv.Perm X} {m B : ℕ} {W : Fin m → Swap X}













































/-- The symmetric edge relation of a generator list `gen : Fin B → POrb p × POrb p`. -/
def genRel {p : Equiv.Perm X} {B : ℕ} (gen : Fin B → POrb p × POrb p)
    (u v : POrb p) : Prop :=
  ∃ i : Fin B, (u = (gen i).1 ∧ v = (gen i).2) ∨ (u = (gen i).2 ∧ v = (gen i).1)

/-- The generator-graph compression certificate: `B` edges on `POrb p` whose reachability
connects every letter's two endpoints. -/
structure TouchCompressionCert (p : Equiv.Perm X) {m : ℕ} (W : Fin m → Swap X) (B : ℕ) where
  /-- The `B` generator edges (ordered pairs of `p`-orbits). -/
  gen : Fin B → POrb p × POrb p
  /-- Every letter's endpoints are connected through the generator edges. -/
  endpoint_reachable : ∀ j : Fin m,
    Relation.EqvGen (genRel gen) (pOrbOf p (W j).x) (pOrbOf p (W j).y)















namespace TouchCompressionCert

variable {p : Equiv.Perm X} {m B : ℕ} {W : Fin m → Swap X}

/-- The component quotient of the generator graph. -/
abbrev comp (K : TouchCompressionCert p W B) := Quotient (compSetoid (genRel K.gen))

/-- The component of a `p`-orbit. -/
def compMk (K : TouchCompressionCert p W B) (o : POrb p) : K.comp :=
  Quotient.mk (compSetoid (genRel K.gen)) o



/-- The colour type: components meeting a touched orbit. -/
def Color (K : TouchCompressionCert p W B) : Type _ :=
  {c : K.comp // ∃ o ∈ wordTouchedOrbits p W, K.compMk o = c}

instance (K : TouchCompressionCert p W B) : Finite K.comp :=
  inferInstanceAs (Finite (Quotient (compSetoid (genRel K.gen))))

noncomputable instance (K : TouchCompressionCert p W B) : Fintype K.comp :=
  Fintype.ofFinite _

noncomputable instance (K : TouchCompressionCert p W B) : DecidableEq K.comp :=
  Classical.decEq _

noncomputable instance (K : TouchCompressionCert p W B) : Fintype K.Color := by
  classical
  have : Finite K.Color := Subtype.finite
  exact Fintype.ofFinite _

noncomputable instance (K : TouchCompressionCert p W B) : DecidableEq K.Color :=
  Classical.decEq _























end TouchCompressionCert









end ProofsInTheBook.TouchRank



namespace ProofsInTheBook.PlanarMap

open ForcedSplits CombMap CombMap.SimplePrimalCycle
open ProofsInTheBook.TouchRank
open ProofsInTheBook.PlanarMap.FaceCorrWord

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}











end SimplePrimalCycle

end CombMap

end ProofsInTheBook.PlanarMap








end

/- Original source header (imports hoisted):
import ProofsInTheBook.TouchRank
-/
/- Source module: ProofsInTheBook.TouchCert -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option maxHeartbeats 1600000

open Equiv Equiv.Perm Function List

namespace ProofsInTheBook

namespace TouchCert

open ForcedSplits ProofsInTheBook.TouchRank
open ProofsInTheBook.PlanarMap.FaceCorrWord
open ProofsInTheBook.PlanarMap.SeamChain

variable {X : Type*} [Fintype X] [DecidableEq X]













end TouchCert



namespace PlanarMap

open ForcedSplits ProofsInTheBook.TouchRank
open ProofsInTheBook.PlanarMap.FaceCorrWord
open ProofsInTheBook.TouchCert

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}









end SimplePrimalCycle

end CombMap

end PlanarMap



namespace TouchCert

open ForcedSplits ProofsInTheBook.PlanarMap.FaceCorrWord
open ProofsInTheBook.PlanarMap.SeamChain







end TouchCert

end ProofsInTheBook








end

/- Original source header (imports hoisted):
import ProofsInTheBook.TouchCert
-/
/- Source module: ProofsInTheBook.SeamStructure -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

open Equiv Equiv.Perm Function

namespace ProofsInTheBook

namespace SeamStructure

open ProofsInTheBook.TouchRank
open ProofsInTheBook.PlanarMap.FaceCorrWord
open ProofsInTheBook.PlanarMap.SeamChain

variable {X : Type*} [Fintype X] [DecidableEq X]















end SeamStructure



namespace PlanarMap

open Equiv Equiv.Perm Function

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}

open CutCapCount





















open ProofsInTheBook.TouchRank
open ProofsInTheBook.PlanarMap.FaceCorrWord









end SimplePrimalCycle

end CombMap

end PlanarMap



namespace SeamStructure

open ProofsInTheBook.TouchRank
open ProofsInTheBook.PlanarMap.FaceCorrWord
open ProofsInTheBook.PlanarMap.SeamChain





end SeamStructure

end ProofsInTheBook











end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapCutCapF
-/
/- Source module: ProofsInTheBook.PlanarMapCutCapConn -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open Equiv Equiv.Perm Function

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}

























/-- A dart with a non-cycle `Sym2`-edge is not a cycle dart. -/
lemma notMem_dartSet_of_dartEdge_notMem (C : SimplePrimalCycle M) {d : D}
    (h : M.dartEdge d ∉ C.edgeSet) : d ∉ C.dartSet := by
  intro hd
  rw [C.mem_dartSet_iff] at hd
  obtain ⟨i, hi | hi⟩ := hd
  · exact h ((C.mem_edgeSet_iff _).2 ⟨i, by rw [hi, edge]⟩)
  · exact h ((C.mem_edgeSet_iff _).2 ⟨i, by rw [hi, edge, M.dartEdge_alpha]⟩)



























end SimplePrimalCycle



namespace NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)



end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapCutCapConn
-/
/- Source module: ProofsInTheBook.PlanarMapDualPathSep -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open Equiv Equiv.Perm Function

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}























































end SimplePrimalCycle



namespace SimplePrimalCycle

variable {M : CombMap D}





end SimplePrimalCycle

namespace NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)



end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapCutCap2FWalk
import ProofsInTheBook.PlanarMapDualPathSep
-/
/- Source module: ProofsInTheBook.PlanarMapBridge -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open Equiv Equiv.Perm Function

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}



/-- `cutReach2 x y`: `x` and `y` are joined by a chain of `cutCapMap2.dartStep`s. -/
def cutReach2 (C : SimplePrimalCycle M) (x y : C.CutDart) : Prop :=
  Relation.ReflTransGen (C.cutCapMap2).dartStep x y

@[refl] lemma cutReach2_rfl (C : SimplePrimalCycle M) (x : C.CutDart) :
    C.cutReach2 x x := Relation.ReflTransGen.refl

lemma cutReach2_trans (C : SimplePrimalCycle M) {x y z : C.CutDart}
    (h₁ : C.cutReach2 x y) (h₂ : C.cutReach2 y z) :
    C.cutReach2 x z := Relation.ReflTransGen.trans h₁ h₂

/-- `cutCapMap2.dartStep` is symmetric. -/
lemma cutDartStep2_symm (C : SimplePrimalCycle M) {x y : C.CutDart}
    (h : (C.cutCapMap2).dartStep x y) :
    (C.cutCapMap2).dartStep y x := by
  rcases h with hσ | hα
  · exact Or.inl hσ.symm
  · refine Or.inr ?_
    rw [hα]
    show x = (C.cutCapMap2).α ((C.cutCapMap2).α x)
    rw [show (C.cutCapMap2).α ((C.cutCapMap2).α x) = x from
      congrArg (fun f : Equiv.Perm C.CutDart => f x) (C.cutCapMap2).α_invol]

lemma cutReach2_symm (C : SimplePrimalCycle M) {x y : C.CutDart} (h : C.cutReach2 x y) :
    C.cutReach2 y x :=
  Relation.ReflTransGen.symmetric (fun _ _ => C.cutDartStep2_symm) h

/-- A single `σ'₂`-step is a reachability. -/
lemma cutReach2_of_sigma (C : SimplePrimalCycle M) {x y : C.CutDart}
    (h : (C.cutCapMap2).σ.SameCycle x y) :
    C.cutReach2 x y :=
  Relation.ReflTransGen.single (Or.inl h)

/-- A single `α'`-step is a reachability. -/
lemma cutReach2_of_alpha (C : SimplePrimalCycle M) (x : C.CutDart) :
    C.cutReach2 x ((C.cutCapMap2).α x) :=
  Relation.ReflTransGen.single (Or.inr rfl)

/-- A single `φ'₂`-step is a reachability (`α'` then `σ'₂`). -/
lemma cutReach2_of_phi_step (C : SimplePrimalCycle M) (x : C.CutDart) :
    C.cutReach2 x ((C.cutCapMap2).φ x) := by
  have h1 : C.cutReach2 x ((C.cutCapMap2).α x) := C.cutReach2_of_alpha x
  have h2 : C.cutReach2 ((C.cutCapMap2).α x) ((C.cutCapMap2).σ ((C.cutCapMap2).α x)) :=
    C.cutReach2_of_sigma ⟨1, by rw [zpow_one]⟩
  refine C.cutReach2_trans h1 ?_
  have : (C.cutCapMap2).φ x = (C.cutCapMap2).σ ((C.cutCapMap2).α x) := by
    rw [CombMap.φ, Equiv.Perm.mul_apply]
  rw [this]; exact h2

lemma cutReach2_of_phi_pow (C : SimplePrimalCycle M) (x : C.CutDart) :
    ∀ n : ℕ, C.cutReach2 x (((C.cutCapMap2).φ ^ n) x)
  | 0 => by simpa using C.cutReach2_rfl x
  | n + 1 => by
      rw [pow_succ, Equiv.Perm.mul_apply]
      exact C.cutReach2_trans (C.cutReach2_of_phi_step x)
        (C.cutReach2_of_phi_pow ((C.cutCapMap2).φ x) n)

/-- Same face (`φ'₂`-cycle) ⇒ reachable. -/
lemma cutReach2_of_phi_sameCycle (C : SimplePrimalCycle M) {x y : C.CutDart}
    (h : (C.cutCapMap2).φ.SameCycle x y) :
    C.cutReach2 x y := by
  obtain ⟨n, hn⟩ := h.exists_nat_pow_eq
  have := C.cutReach2_of_phi_pow x n
  rwa [hn] at this



@[simp] lemma cutCapMap2_alpha_apply (C : SimplePrimalCycle M) (x : C.CutDart) :
    (C.cutCapMap2).α x = C.cutAlpha x := by
  rw [cutCapMap2_alpha, cutAlphaPerm_apply]

/-- **The uncut bridge.**  Across an uncut edge `dartEdge d ∉ E(C)`, the corrected cut
map joins `inl d` to `inl (α d)` by one `α'`-step. -/
lemma cutReach2_uncut_bridge (C : SimplePrimalCycle M) {d : D}
    (h : M.dartEdge d ∉ C.edgeSet) :
    C.cutReach2 (Sum.inl d) (Sum.inl (M.α d)) := by
  have hd : d ∉ C.dartSet := C.notMem_dartSet_of_dartEdge_notMem h
  have : (C.cutCapMap2).α (Sum.inl d) = Sum.inl (M.α d) := by
    rw [cutCapMap2_alpha_apply, C.cutAlpha_other hd]
  rw [← this]
  exact C.cutReach2_of_alpha (Sum.inl d)

/-- `c_i^+` reaches the forward bank dart `inl (dart i)`. -/
lemma cutReach2_capP (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.cutReach2 (Sum.inr (Sum.inl i)) (Sum.inl (C.dart i)) := by
  have : (C.cutCapMap2).α (Sum.inr (Sum.inl i)) = Sum.inl (C.dart i) := by
    rw [cutCapMap2_alpha_apply, cutAlpha_capPlus]
  rw [← this]; exact C.cutReach2_of_alpha _

/-- `c_i^-` reaches the reverse bank dart `inl (α (dart i))`. -/
lemma cutReach2_capM (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.cutReach2 (Sum.inr (Sum.inr i)) (Sum.inl (M.α (C.dart i))) := by
  have : (C.cutCapMap2).α (Sum.inr (Sum.inr i)) = Sum.inl (M.α (C.dart i)) := by
    rw [cutCapMap2_alpha_apply, cutAlpha_capMinus]
  rw [← this]; exact C.cutReach2_of_alpha _



/-- A clean `σ'₂`-step lifts: if `σ d` is not a bank-start, `σ'₂ (inl d) = inl (σ d)`. -/
lemma cutReach2_sigma_clean (C : SimplePrimalCycle M) {d : D}
    (hp : ∀ j, M.σ d ≠ C.pDart j) (hq : ∀ j, M.σ d ≠ C.qDart j) :
    C.cutReach2 (Sum.inl d) (Sum.inl (M.σ d)) := by
  refine C.cutReach2_of_sigma ⟨1, ?_⟩
  rw [zpow_one]
  show (C.cutCapMap2).σ (Sum.inl d) = Sum.inl (M.σ d)
  exact C.cutSigma2_clean hp hq

/-- A `σ'₂`-step diverting at a `+`-bank-end `σ d = p_j` lands on the previous `+`-cap
`c_{prevIdx j}^+`, which reaches the `+`-bank dart `inl (dart (prevIdx j))`. -/
lemma cutReach2_sigma_divertPlus (C : SimplePrimalCycle M) {d : D} {j : Fin C.len}
    (h : M.σ d = C.pDart j) :
    C.cutReach2 (Sum.inl d) (Sum.inl (C.dart (C.prevIdx j))) := by
  have hstep : (C.cutCapMap2).σ.SameCycle (Sum.inl d) (Sum.inr (Sum.inl (C.prevIdx j))) := by
    refine ⟨1, ?_⟩
    rw [zpow_one]
    show (C.cutCapMap2).σ (Sum.inl d) = Sum.inr (Sum.inl (C.prevIdx j))
    exact C.cutSigma2_plusEnd h
  exact (C.cutReach2_of_sigma hstep).trans (C.cutReach2_capP (C.prevIdx j))

/-- A `σ'₂`-step diverting at a `−`-bank-end `σ d = q_j` lands on `c_j^-`, which reaches
the `−`-bank dart `inl (α (dart j))`. -/
lemma cutReach2_sigma_divertMinus (C : SimplePrimalCycle M) {d : D} {j : Fin C.len}
    (h : M.σ d = C.qDart j) :
    C.cutReach2 (Sum.inl d) (Sum.inl (M.α (C.dart j))) := by
  have hstep : (C.cutCapMap2).σ.SameCycle (Sum.inl d) (Sum.inr (Sum.inr j)) := by
    refine ⟨1, ?_⟩
    rw [zpow_one]
    show (C.cutCapMap2).σ (Sum.inl d) = Sum.inr (Sum.inr j)
    exact C.cutSigma2_minusEnd h
  exact (C.cutReach2_of_sigma hstep).trans (C.cutReach2_capM j)



/-- **Side-coherence (the corrected isolated core).**  Every forward cycle bank
`inl (dart j)` reaches the forward bank of `e_i`, and every reverse cycle bank
`inl (α (dart j))` reaches the reverse bank of `e_i`. -/
def SidesReach2 (C : SimplePrimalCycle M) (i : Fin C.len) : Prop :=
  (∀ j : Fin C.len, C.cutReach2 (Sum.inl (C.dart j)) (Sum.inl (C.dart i))) ∧
    (∀ j : Fin C.len, C.cutReach2 (Sum.inl (M.α (C.dart j))) (Sum.inl (M.α (C.dart i))))

/-- Abbreviation: `x` reaches a bank of `e_i` (corrected map). -/
def ReachesBankI2 (C : SimplePrimalCycle M) (i : Fin C.len) (x : C.CutDart) : Prop :=
  C.cutReach2 x (Sum.inl (C.dart i)) ∨ C.cutReach2 x (Sum.inl (M.α (C.dart i)))

lemma reachesBankI2_dartI (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.ReachesBankI2 i (Sum.inl (C.dart i)) := Or.inl (C.cutReach2_rfl _)

/-- A single forward `σ`-step lifts to "reaches a bank of `e_i`" (corrected map). -/
lemma cutReach2_sigma_step_or_bank (C : SimplePrimalCycle M) (i : Fin C.len)
    (hsides : C.SidesReach2 i) (d : D) :
    C.cutReach2 (Sum.inl d) (Sum.inl (M.σ d)) ∨ C.ReachesBankI2 i (Sum.inl d) := by
  by_cases hp : ∃ j, M.σ d = C.pDart j
  · obtain ⟨j, hj⟩ := hp
    refine Or.inr (Or.inl ?_)
    exact (C.cutReach2_sigma_divertPlus hj).trans (hsides.1 (C.prevIdx j))
  · by_cases hq : ∃ j, M.σ d = C.qDart j
    · obtain ⟨j, hj⟩ := hq
      refine Or.inr (Or.inr ?_)
      exact (C.cutReach2_sigma_divertMinus hj).trans (hsides.2 j)
    · exact Or.inl (C.cutReach2_sigma_clean (fun j hj => hp ⟨j, hj⟩) (fun j hj => hq ⟨j, hj⟩))

/-- `σ`-power lift (corrected map). -/
lemma cutReach2_sigma_pow_or_bank (C : SimplePrimalCycle M) (i : Fin C.len)
    (hsides : C.SidesReach2 i) (d : D) :
    ∀ n : ℕ, C.cutReach2 (Sum.inl d) (Sum.inl ((M.σ ^ n) d)) ∨
      C.ReachesBankI2 i (Sum.inl d)
  | 0 => Or.inl (by simpa using C.cutReach2_rfl (Sum.inl d))
  | n + 1 => by
      rcases C.cutReach2_sigma_pow_or_bank i hsides d n with hreach | hbank
      · rcases C.cutReach2_sigma_step_or_bank i hsides ((M.σ ^ n) d) with hstep | hbank'
        · refine Or.inl ?_
          have : (M.σ ^ (n + 1)) d = M.σ ((M.σ ^ n) d) := by
            rw [pow_succ', Equiv.Perm.mul_apply]
          rw [this]
          exact hreach.trans hstep
        · rcases hbank' with h | h
          · exact Or.inr (Or.inl (hreach.trans h))
          · exact Or.inr (Or.inr (hreach.trans h))
      · exact Or.inr hbank

lemma cutReach2_sameCycle_or_bank (C : SimplePrimalCycle M) (i : Fin C.len)
    (hsides : C.SidesReach2 i) {d e : D} (h : M.σ.SameCycle d e) :
    C.cutReach2 (Sum.inl d) (Sum.inl e) ∨ C.ReachesBankI2 i (Sum.inl d) := by
  obtain ⟨n, hn⟩ := h.exists_nat_pow_eq
  rcases C.cutReach2_sigma_pow_or_bank i hsides d n with hreach | hbank
  · left; rwa [hn] at hreach
  · exact Or.inr hbank

/-- An `α`-step lifts (corrected map). -/
lemma cutReach2_alpha_step_or_bank (C : SimplePrimalCycle M) (i : Fin C.len)
    (hsides : C.SidesReach2 i) (d : D) :
    C.cutReach2 (Sum.inl d) (Sum.inl (M.α d)) ∨ C.ReachesBankI2 i (Sum.inl d) := by
  by_cases hd : d ∈ C.dartSet
  · rw [C.mem_dartSet_iff] at hd
    obtain ⟨j, hj | hj⟩ := hd
    · subst hj; exact Or.inr (Or.inl (hsides.1 j))
    · subst hj; exact Or.inr (Or.inr (hsides.2 j))
  · left
    have hα : (C.cutCapMap2).α (Sum.inl d) = Sum.inl (M.α d) := by
      rw [cutCapMap2_alpha_apply, C.cutAlpha_other hd]
    rw [← hα]
    exact C.cutReach2_of_alpha (Sum.inl d)



/-- **Backward closure of the bank-reach invariant** (corrected map). -/
lemma reachesBankI2_backward (C : SimplePrimalCycle M) (i : Fin C.len)
    (hsides : C.SidesReach2 i) {c c' : D} (hcc' : M.dartStep c c')
    (hc' : C.ReachesBankI2 i (Sum.inl c')) :
    C.ReachesBankI2 i (Sum.inl c) := by
  rcases hcc' with hσ | hα
  · rcases C.cutReach2_sameCycle_or_bank i hsides hσ with hreach | hbank
    · rcases hc' with h | h
      · exact Or.inl (hreach.trans h)
      · exact Or.inr (hreach.trans h)
    · exact hbank
  · subst hα
    rcases C.cutReach2_alpha_step_or_bank i hsides c with hreach | hbank
    · rcases hc' with h | h
      · exact Or.inl (hreach.trans h)
      · exact Or.inr (hreach.trans h)
    · exact hbank

/-- Every `inl`-dart reaches a bank of `e_i` (corrected map). -/
lemma inl_reachesBankI2 (C : SimplePrimalCycle M) (i : Fin C.len)
    (hconn : M.Connected) (hsides : C.SidesReach2 i) (c : D) :
    C.ReachesBankI2 i (Sum.inl c) := by
  have hwalk : Relation.ReflTransGen M.dartStep c (C.dart i) := hconn c (C.dart i)
  refine Relation.ReflTransGen.head_induction_on hwalk (C.reachesBankI2_dartI i) ?_
  intro a b hab _ ih
  exact C.reachesBankI2_backward i hsides hab ih

/-- **Part A predicate (corrected map).**  Every cut-dart reaches a bank of `e_i`. -/
def ReachesBank2 (C : SimplePrimalCycle M) (i : Fin C.len) : Prop :=
  ∀ x : C.CutDart,
    C.cutReach2 x (Sum.inl (C.dart i)) ∨ C.cutReach2 x (Sum.inl (M.α (C.dart i)))

/-- **Part A (`ReachesBank2`).**  Every cut-dart reaches a bank of `e_i`, given
`M.Connected` and the side-coherence core. -/
theorem reachesBank2_of_connected (C : SimplePrimalCycle M) (i : Fin C.len)
    (hconn : M.Connected) (hsides : C.SidesReach2 i) :
    C.ReachesBank2 i := by
  intro x
  rcases x with d | (j | j)
  · exact C.inl_reachesBankI2 i hconn hsides d
  · rcases C.inl_reachesBankI2 i hconn hsides (C.dart j) with h | h
    · exact Or.inl ((C.cutReach2_capP j).trans h)
    · exact Or.inr ((C.cutReach2_capP j).trans h)
  · rcases C.inl_reachesBankI2 i hconn hsides (M.α (C.dart j)) with h | h
    · exact Or.inl ((C.cutReach2_capM j).trans h)
    · exact Or.inr ((C.cutReach2_capM j).trans h)

/-- **The connectivity reduction (corrected map).**  Part A + the bridge ⇒ connected. -/
theorem cutCapMap2_connected_of_reachesBank_of_bridge (C : SimplePrimalCycle M)
    (i : Fin C.len)
    (hbank : C.ReachesBank2 i)
    (hbridge : C.cutReach2 (Sum.inl (C.dart i)) (Sum.inl (M.α (C.dart i)))) :
    (C.cutCapMap2).Connected := by
  have hreach_r : ∀ x : C.CutDart, C.cutReach2 x (Sum.inl (C.dart i)) := by
    intro x
    rcases hbank x with h | h
    · exact h
    · exact h.trans (C.cutReach2_symm hbridge)
  intro a b
  exact (hreach_r a).trans (C.cutReach2_symm (hreach_r b))























/-- **Cut-reach across an uncut dual gate** (design §3.1
`cutConn_across_uncut_dual_gate`): one `α'`-step joins the two faces' `inl`-darts. -/
lemma cutReach2_across_uncut_dual_gate (C : SimplePrimalCycle M) {a : D}
    (h : M.dartEdge a ∉ C.edgeSet) :
    C.cutReach2 (Sum.inl a) (Sum.inl (M.α a)) :=
  C.cutReach2_uncut_bridge h





















/-- An **ordinary dual path** with explicit crossing darts (design §7 Option C
`OrdinaryDualPath`).  A bare face sequence augmented with the witnessing darts. -/
structure OrdinaryDualPath2 (C : SimplePrimalCycle M) where
  /-- Number of crossings. -/
  n : ℕ
  /-- The old face at each position. -/
  face : Fin (n + 1) → M.Face
  /-- The uncut crossing dart at each step. -/
  edge : Fin n → D
  /-- Each crossing dart is across an uncut (non-cycle) edge. -/
  edge_uncut : ∀ j, M.dartEdge (edge j) ∉ C.edgeSet
  /-- The crossing dart leaves the left face. -/
  left_face : ∀ j : Fin n, M.dartFace (edge j) = face j.castSucc
  /-- The crossing dart enters the right face. -/
  right_face : ∀ j : Fin n, M.dartFace (M.α (edge j)) = face j.succ



















end SimplePrimalCycle

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapBridge
import ProofsInTheBook.PlanarMapSeparation
-/
/- Source module: ProofsInTheBook.PlanarMapBridgeWitness -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open Equiv Equiv.Perm Function

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}









/-- The trivial `OrdinaryDualPath2` at a single face (`n = 0`, no crossings). -/
def OrdinaryDualPath2.nil (C : SimplePrimalCycle M) (f : M.Face) :
    C.OrdinaryDualPath2 where
  n := 0
  face := fun _ => f
  edge := fun j => absurd j.isLt (by simp)
  edge_uncut := fun j => absurd j.isLt (by simp)
  left_face := fun j => absurd j.isLt (by simp)
  right_face := fun j => absurd j.isLt (by simp)















end SimplePrimalCycle

namespace NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)





end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.SeamStructure
import ProofsInTheBook.PlanarMapBridgeWitness
-/
/- Source module: ProofsInTheBook.SeamApplication -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open Equiv Equiv.Perm Function

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}













end SimplePrimalCycle



namespace NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)





end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap



namespace ProofsInTheBook.PlanarMap.CombMap.SimplePrimalCycle

variable {D : Type*} [Fintype D] [DecidableEq D] {M : CombMap D}





end ProofsInTheBook.PlanarMap.CombMap.SimplePrimalCycle










end

/- Original source header (imports hoisted):
import ProofsInTheBook.SeamApplication
-/
/- Source module: ProofsInTheBook.SeamIncidence -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open Equiv Equiv.Perm Function
open ProofsInTheBook.TouchRank

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}



















end SimplePrimalCycle



namespace NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)





end NearTriangulation



namespace SimplePrimalCycle

variable {M : CombMap D}

open ProofsInTheBook.PlanarMap.FaceCorrWord
open ProofsInTheBook.SeamStructure



namespace ArcChordSeam

variable {C : SimplePrimalCycle M}







end ArcChordSeam

end SimplePrimalCycle



namespace NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)





end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap



namespace ProofsInTheBook.PlanarMap.CombMap.SimplePrimalCycle

open ProofsInTheBook.TouchRank

variable {D : Type*} [Fintype D] [DecidableEq D] {M : CombMap D}





end ProofsInTheBook.PlanarMap.CombMap.SimplePrimalCycle










end

/- Original source header (imports hoisted):
import ProofsInTheBook.SeamIncidence
-/
/- Source module: ProofsInTheBook.DartArc -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open Equiv
open ProofsInTheBook.TouchRank
open ProofsInTheBook.PlanarMap.FaceCorrWord

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]



/-- A dart-level boundary arc from `u` to `v` on the boundary cycle `C`.

`arcDart i` is the `i`-th dart of the arc, `len` of them; they all lie on
`C.darts`, chain head→tail (`chain`), the first dart starts at `u`
(`tail_first`), the last ends at `v` (`head_last`), and the tails together with
the final head form a simple (`Nodup`) vertex sequence. -/
structure DartArc (M : CombMap D) {f : M.Face} (C : BoundaryCycle M f)
    (u v : M.Vertex) where
  /-- Number of darts on the arc. -/
  len : ℕ
  /-- The arc is nonempty (at least one dart). -/
  len_pos : 0 < len
  /-- The directed arc darts `e_0, …, e_{len-1}`. -/
  arcDart : Fin len → D
  /-- Every arc dart lies on the boundary cycle. -/
  boundary : ∀ i : Fin len, arcDart i ∈ C.darts
  /-- Consecutive arc darts chain head→tail (no wraparound — this is a *path*). -/
  chain : ∀ i : Fin len, (h : (i : ℕ) + 1 < len) →
    M.head (arcDart i) = M.tail (arcDart ⟨i + 1, h⟩)
  /-- The first dart's tail is `u`. -/
  tail_first : M.tail (arcDart ⟨0, len_pos⟩) = u
  /-- The last dart's head is `v`. -/
  head_last : M.head (arcDart ⟨len - 1, by omega⟩) = v
  /-- The tail vertices of the arc darts are pairwise distinct (simplicity). -/
  tail_nodup : Function.Injective (fun i : Fin len => M.tail (arcDart i))
  /-- The final head `v` is distinct from every tail (the arc does not revisit its
  endpoint). -/
  head_last_ne_tail : ∀ i : Fin len, v ≠ M.tail (arcDart i)

namespace DartArc

variable {M : CombMap D} {f : M.Face} {C : BoundaryCycle M f} {u v : M.Vertex}

/-- The last index of the arc. -/
def lastIdx (A : DartArc M C u v) : Fin A.len := ⟨A.len - 1, by have := A.len_pos; omega⟩

/-- The first index of the arc. -/
def firstIdx (A : DartArc M C u v) : Fin A.len := ⟨0, A.len_pos⟩

@[simp] lemma tail_firstIdx (A : DartArc M C u v) :
    M.tail (A.arcDart A.firstIdx) = u := A.tail_first

@[simp] lemma head_lastIdx (A : DartArc M C u v) :
    M.head (A.arcDart A.lastIdx) = v := A.head_last

end DartArc







namespace SimplePrimalCycle

variable {M : CombMap D}

/-- The chord∪arc dart family: `Fin.cons c arcDart`, length `A.len + 1`.  Index `0`
is the chord dart, index `i+1` is `arcDart i`. -/
def chordArcDart {f : M.Face} {C : BoundaryCycle M f} {u v : M.Vertex}
    (A : DartArc M C u v) (c : D) : Fin (A.len + 1) → D :=
  Fin.cons c A.arcDart

@[simp] lemma chordArcDart_zero {f : M.Face} {C : BoundaryCycle M f} {u v : M.Vertex}
    (A : DartArc M C u v) (c : D) :
    chordArcDart A c 0 = c := by
  simp [chordArcDart]

@[simp] lemma chordArcDart_succ {f : M.Face} {C : BoundaryCycle M f} {u v : M.Vertex}
    (A : DartArc M C u v) (c : D) (i : Fin A.len) :
    chordArcDart A c i.succ = A.arcDart i := by
  simp [chordArcDart]

/-- **The concrete chord∪arc primal cycle.**  Built from a dart-level arc `A` from
`u` to `v` and a chord dart `c` oriented `v → u` (i.e. `tail c = v`, `head c = u`),
with `A.len ≥ 2` (the arc has an internal vertex).  The three `SimplePrimalCycle`
fields:

* `consecutive` — arc-internal from `A.chain`; the junction at the chord head is
  `head c = u = tail (arc 0)`, the junction at the chord tail is `head (arc last) =
  v = tail c`.
* `tail_inj` — arc tails distinct by `A.tail_nodup`; the chord tail `v` differs
  from every arc tail by `A.head_last_ne_tail`.
* `3 ≤ len` — `len = A.len + 1 ≥ 3` from `A.len ≥ 2`. -/
noncomputable def ofDartArc {f : M.Face} {C : BoundaryCycle M f} {u v : M.Vertex}
    (A : DartArc M C u v) (c : D)
    (harc_len : 2 ≤ A.len)
    (hc_tail : M.tail c = v) (hc_head : M.head c = u) :
    SimplePrimalCycle M where
  len := A.len + 1
  len_ge := by omega
  dart := chordArcDart A c
  tail_inj := by
    -- The tails of `chordArcDart`: index 0 ↦ v, index (i+1) ↦ tail (arcDart i).
    intro i j hij
    -- Reduce to cases on whether each index is 0 or a successor.
    rcases Fin.eq_zero_or_eq_succ i with rfl | ⟨i', rfl⟩
    · rcases Fin.eq_zero_or_eq_succ j with rfl | ⟨j', rfl⟩
      · rfl
      · -- i = 0, j = j'.succ : tail c = v = tail (arcDart j'), impossible.
        exfalso
        simp only [chordArcDart_zero, chordArcDart_succ, hc_tail] at hij
        exact A.head_last_ne_tail j' hij
    · rcases Fin.eq_zero_or_eq_succ j with rfl | ⟨j', rfl⟩
      · exfalso
        simp only [chordArcDart_zero, chordArcDart_succ, hc_tail] at hij
        exact A.head_last_ne_tail i' hij.symm
      · -- both successors: use arc tail injectivity.
        simp only [chordArcDart_succ] at hij
        have := A.tail_nodup hij
        rw [this]
  consecutive := by
    intro i
    -- `nextIdx` index : (i+1) % (A.len + 1).
    rcases Fin.eq_zero_or_eq_succ i with rfl | ⟨i', rfl⟩
    · -- i = 0 (chord dart). Its head is u; next index is 1 = (arcDart 0). tail = u.
      simp only [chordArcDart_zero, hc_head]
      have hnext : ((0 : Fin (A.len + 1)).1 + 1) % (A.len + 1) = 1 := by
        show (0 + 1) % (A.len + 1) = 1
        rw [Nat.zero_add, Nat.mod_eq_of_lt (by omega)]
      have : (⟨((0 : Fin (A.len + 1)).1 + 1) % (A.len + 1),
            Nat.mod_lt _ (by omega)⟩ : Fin (A.len + 1))
          = (A.firstIdx).succ := by
        apply Fin.ext; simp only [hnext, Fin.val_succ]
        show 1 = (A.firstIdx).1 + 1
        simp [DartArc.firstIdx]
      rw [this, chordArcDart_succ, DartArc.tail_firstIdx]
    · -- i = i'.succ (an arc dart, arcDart i'). Two sub-cases: i' is last or not.
      simp only [chordArcDart_succ]
      by_cases hlast : (i' : ℕ) + 1 = A.len
      · -- last arc dart: head = v = tail c; next index wraps to 0 (chord).
        have hhead : M.head (A.arcDart i') = v := by
          have : i' = A.lastIdx := by
            apply Fin.ext; simp [DartArc.lastIdx]; omega
          rw [this, DartArc.head_lastIdx]
        rw [hhead]
        have hnext : ((i'.succ : Fin (A.len + 1)).1 + 1) % (A.len + 1) = 0 := by
          simp only [Fin.val_succ]
          have : (i' : ℕ) + 1 + 1 = A.len + 1 := by omega
          rw [this, Nat.mod_self]
        have hidx : (⟨((i'.succ : Fin (A.len + 1)).1 + 1) % (A.len + 1),
              Nat.mod_lt _ (by omega)⟩ : Fin (A.len + 1)) = 0 := by
          apply Fin.ext
          show ((i'.succ : Fin (A.len + 1)).1 + 1) % (A.len + 1) = 0
          rw [hnext]
        rw [hidx, chordArcDart_zero, hc_tail]
      · -- internal arc step: use A.chain.
        have hlt : (i' : ℕ) + 1 < A.len := by
          have := i'.isLt; omega
        rw [A.chain i' hlt]
        have hnext : ((i'.succ : Fin (A.len + 1)).1 + 1) % (A.len + 1)
            = (i' : ℕ) + 1 + 1 := by
          simp only [Fin.val_succ]
          rw [Nat.mod_eq_of_lt (by omega)]
        have hidx : (⟨((i'.succ : Fin (A.len + 1)).1 + 1) % (A.len + 1),
              Nat.mod_lt _ (by omega)⟩ : Fin (A.len + 1))
            = (⟨(i' : ℕ) + 1, hlt⟩ : Fin A.len).succ := by
          apply Fin.ext
          show ((i'.succ : Fin (A.len + 1)).1 + 1) % (A.len + 1) = (i' : ℕ) + 1 + 1
          rw [hnext]
        rw [hidx, chordArcDart_succ]



@[simp] lemma ofDartArc_dart {f : M.Face} {C : BoundaryCycle M f} {u v : M.Vertex}
    (A : DartArc M C u v) (c : D) (harc_len : 2 ≤ A.len)
    (hc_tail : M.tail c = v) (hc_head : M.head c = u) :
    (ofDartArc A c harc_len hc_tail hc_head).dart = chordArcDart A c := rfl









open ProofsInTheBook.PlanarMap.FaceCorrWord
open ProofsInTheBook.SeamStructure



end SimplePrimalCycle



namespace NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)

open SimplePrimalCycle



end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap



namespace ProofsInTheBook.PlanarMap.CombMap.SimplePrimalCycle

variable {D : Type*} [Fintype D] [DecidableEq D] {M : CombMap D}







end ProofsInTheBook.PlanarMap.CombMap.SimplePrimalCycle









end

/- Original source header (imports hoisted):
import ProofsInTheBook.DartArc
import ProofsInTheBook.PlanarMapBridge
import ProofsInTheBook.PlanarMapBridgeWitness
-/
/- Source module: ProofsInTheBook.WitnessFinal -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open Equiv Equiv.Perm Function
open ProofsInTheBook.TouchRank
open ProofsInTheBook.PlanarMap.FaceCorrWord
open ProofsInTheBook.SeamStructure

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

variable {M : CombMap D}



/-- **Forward `φ'₂`-thread step.**  The forward cycle bank dart at `i` reaches the one at
`nextIdx i` in a single `cutReach2` step (one corrected `φ'₂`-step). -/
lemma cutReach2_dart_nextIdx (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.cutReach2 (Sum.inl (C.dart i)) (Sum.inl (C.dart (C.nextIdx i))) := by
  have hstep := C.cutReach2_of_phi_step (Sum.inl (C.dart i))
  rwa [cutCapPhi2_dart] at hstep

/-- **Reverse `φ'₂`-thread step.**  The reverse cycle bank dart at `i` reaches the one at
`prevIdx i` in a single `cutReach2` step.  (`φ'₂ (inl (α dart i)) = inl (pDart i)` and
`pDart i = α (dart (prevIdx i))`.) -/
lemma cutReach2_alphaDart_prevIdx (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.cutReach2 (Sum.inl (M.α (C.dart i))) (Sum.inl (M.α (C.dart (C.prevIdx i)))) := by
  have hstep := C.cutReach2_of_phi_step (Sum.inl (M.α (C.dart i)))
  rw [cutCapPhi2_alpha_dart] at hstep
  rwa [show C.pDart i = M.α (C.dart (C.prevIdx i)) from rfl] at hstep



/-- The value of `nextIdx` iterated `m` times: `(a + m) % len`. -/
lemma nextIdx_iterate_val (C : SimplePrimalCycle M) (a : Fin C.len) :
    ∀ m : ℕ, ((C.nextIdx^[m] a) : ℕ) = (a.1 + m) % C.len
  | 0 => by simp [Nat.mod_eq_of_lt a.isLt]
  | m + 1 => by
      rw [Function.iterate_succ_apply', nextIdx_val, C.nextIdx_iterate_val a m]
      rw [Nat.mod_add_mod]
      congr 1

/-- The value of `prevIdx` iterated `m` times: `(a + m*(len-1)) % len`. -/
lemma prevIdx_iterate_val (C : SimplePrimalCycle M) (a : Fin C.len) :
    ∀ m : ℕ, ((C.prevIdx^[m] a) : ℕ) = (a.1 + m * (C.len - 1)) % C.len
  | 0 => by simp [Nat.mod_eq_of_lt a.isLt]
  | m + 1 => by
      rw [Function.iterate_succ_apply', prevIdx_val, C.prevIdx_iterate_val a m]
      rw [Nat.mod_add_mod]
      congr 1; ring_nf

/-- **Forward iterate reach.**  Every forward bank dart reaches the `nextIdx`-iterate. -/
lemma cutReach2_dart_nextIdx_iterate (C : SimplePrimalCycle M) (a : Fin C.len) :
    ∀ m : ℕ, C.cutReach2 (Sum.inl (C.dart a)) (Sum.inl (C.dart (C.nextIdx^[m] a)))
  | 0 => by simpa using C.cutReach2_rfl (Sum.inl (C.dart a))
  | m + 1 => by
      rw [Function.iterate_succ_apply']
      exact (C.cutReach2_dart_nextIdx_iterate a m).trans
        (C.cutReach2_dart_nextIdx (C.nextIdx^[m] a))

/-- **Reverse iterate reach.**  Every reverse bank dart reaches the `prevIdx`-iterate. -/
lemma cutReach2_alphaDart_prevIdx_iterate (C : SimplePrimalCycle M) (a : Fin C.len) :
    ∀ m : ℕ, C.cutReach2 (Sum.inl (M.α (C.dart a)))
      (Sum.inl (M.α (C.dart (C.prevIdx^[m] a))))
  | 0 => by simpa using C.cutReach2_rfl (Sum.inl (M.α (C.dart a)))
  | m + 1 => by
      rw [Function.iterate_succ_apply']
      exact (C.cutReach2_alphaDart_prevIdx_iterate a m).trans
        (C.cutReach2_alphaDart_prevIdx (C.prevIdx^[m] a))

/-- **Forward connectivity.**  Any forward bank dart reaches any other.  Pick
`m := (len + b − a) % len` so that `nextIdx^[m] a = b`. -/
lemma cutReach2_dart_all (C : SimplePrimalCycle M) (a b : Fin C.len) :
    C.cutReach2 (Sum.inl (C.dart a)) (Sum.inl (C.dart b)) := by
  set m : ℕ := (C.len + b.1 - a.1) % C.len with hm
  have ha := a.isLt; have hb := b.isLt; have hlen := C.len_pos
  have hval : ((C.nextIdx^[m] a) : ℕ) = b.1 := by
    rw [C.nextIdx_iterate_val a m]
    -- (a + m) % len = b, where m ≡ len + b - a (mod len), so a + m ≡ len + b ≡ b.
    have hmod : (a.1 + m) ≡ b.1 [MOD C.len] := by
      have hmmod : m ≡ C.len + b.1 - a.1 [MOD C.len] := Nat.mod_modEq _ _
      calc a.1 + m ≡ a.1 + (C.len + b.1 - a.1) [MOD C.len] := Nat.ModEq.add_left _ hmmod
        _ = C.len + b.1 := by omega
        _ ≡ b.1 [MOD C.len] := Nat.add_modEq_left
    rw [Nat.ModEq] at hmod
    rwa [Nat.mod_eq_of_lt hb] at hmod
  have hidx : C.nextIdx^[m] a = b := Fin.ext hval
  have := C.cutReach2_dart_nextIdx_iterate a m
  rwa [hidx] at this

/-- **Reverse connectivity.**  Any reverse bank dart reaches any other. -/
lemma cutReach2_alphaDart_all (C : SimplePrimalCycle M) (a b : Fin C.len) :
    C.cutReach2 (Sum.inl (M.α (C.dart a))) (Sum.inl (M.α (C.dart b))) := by
  -- prevIdx^[m] a = b for m := (a + len - b) % len, since prevIdx is −1 mod len.
  set m : ℕ := (a.1 + C.len - b.1) % C.len with hm
  have ha := a.isLt; have hb := b.isLt; have hlen := C.len_pos
  have hval : ((C.prevIdx^[m] a) : ℕ) = b.1 := by
    rw [C.prevIdx_iterate_val a m]
    -- m*(len-1) ≡ -m (mod len); a + m*(len-1) ≡ a - m ≡ b (mod len).
    -- key: (a + m*(len-1)) % len = b.
    have hm_lt : m < C.len := Nat.mod_lt _ hlen
    -- a + m*(len-1) = a + m*len - m, and (a + m*len - m) % len = (a + (len - m % len?)) …
    -- Do it via Nat.ModEq.
    have hmlem : m ≤ C.len * m := Nat.le_mul_of_pos_left m hlen
    have hmm : m * (C.len - 1) = C.len * m - m := by
      rw [Nat.mul_sub_one, Nat.mul_comm]
    have expand : a.1 + m * (C.len - 1) = (a.1 + C.len * m) - m := by
      rw [hmm]; omega
    rw [expand]
    -- (a + len*m - m) ≡ (a - m) (mod len), and we want = b.  Compute via congruence.
    have hge : m ≤ a.1 + C.len * m := by nlinarith
    -- Reduce a + len*m - m modulo len directly to the target b.
    have hmod : (a.1 + C.len * m - m) ≡ b.1 [MOD C.len] := by
      -- a + len*m - m ≡ a - m  and  a - m ≡ a - (a + len - b) ≡ b - len ≡ b
      have h1 : (a.1 + C.len * m - m) + m = a.1 + C.len * m := by omega
      -- (a + len*m - m) ≡ a - m? avoid; use additive form: (X) + m ≡ a (mod len)  where X is LHS
      -- and  b + m ≡ a (mod len).  Then X ≡ b by cancellation.
      have hXm : (a.1 + C.len * m - m) + m ≡ a.1 [MOD C.len] := by
        rw [h1]
        exact (Nat.add_modulus_mul_modEq_iff).mpr (Nat.ModEq.refl _)
      have hbm : b.1 + m ≡ a.1 [MOD C.len] := by
        -- m = (a + len - b) % len ≡ a + len - b ≡ a - b (mod len), so b + m ≡ a.
        have hmmod : m ≡ a.1 + C.len - b.1 [MOD C.len] := (Nat.mod_modEq _ _)
        calc b.1 + m ≡ b.1 + (a.1 + C.len - b.1) [MOD C.len] := Nat.ModEq.add_left _ hmmod
          _ = a.1 + C.len := by omega
          _ ≡ a.1 [MOD C.len] := Nat.add_modEq_right
      -- cancel m: X + m ≡ a ≡ b + m  ⟹ X ≡ b
      have : (a.1 + C.len * m - m) + m ≡ b.1 + m [MOD C.len] := hXm.trans hbm.symm
      exact Nat.ModEq.add_right_cancel' m this
    rw [Nat.ModEq] at hmod
    rwa [Nat.mod_eq_of_lt hb] at hmod
  have hidx : C.prevIdx^[m] a = b := Fin.ext hval
  have := C.cutReach2_alphaDart_prevIdx_iterate a m
  rwa [hidx] at this

/-- **`SidesReach2` for the concrete cycle — UNCONDITIONAL.**  Both the forward and the
reverse cycle bank darts thread into one `cutReach2`-connected loop (the corrected
`φ'₂` wiring), so every forward bank dart reaches the reference forward bank dart and
every reverse bank dart reaches the reference reverse one.  *No appeal to `M.Connected`.*

This refutes the bwitness handoff's "irreducible isolated core" verdict: that verdict was
correct only at the bare `σ'₂` layer; `SidesReach2` lives at the `cutReach2` (= `φ'₂`)
layer, where the corrected fix `cutCapPhi2_dart` threads the cycle darts. -/
theorem sidesReach2_concrete (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.SidesReach2 i :=
  ⟨fun j => C.cutReach2_dart_all j i, fun j => C.cutReach2_alphaDart_all j i⟩

















end SimplePrimalCycle

namespace NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)

open SimplePrimalCycle



end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap



namespace ProofsInTheBook.PlanarMap.CombMap.SimplePrimalCycle

variable {D : Type*} [Fintype D] [DecidableEq D] {M : CombMap D}





end ProofsInTheBook.PlanarMap.CombMap.SimplePrimalCycle











end

/- Original source header (imports hoisted):
import ProofsInTheBook.WitnessFinal
import ProofsInTheBook.PlanarMapEulerInequality
-/
/- Source module: ProofsInTheBook.ChordSeparation -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.PlanarMap

open ProofsInTheBook.PlanarMap.CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace CombMap.SimplePrimalCycle

variable {M : CombMap D}















end CombMap.SimplePrimalCycle



namespace CombMap.SimplePrimalCycle

variable {M : CombMap D}



end CombMap.SimplePrimalCycle

namespace CombMap.NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)

open SimplePrimalCycle





end CombMap.NearTriangulation



namespace CombMap.SimplePrimalCycle

variable {M : CombMap D}





end CombMap.SimplePrimalCycle

namespace CombMap.NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)

open SimplePrimalCycle





end CombMap.NearTriangulation



namespace CombMap.SimplePrimalCycle



variable {M : CombMap D}







end CombMap.SimplePrimalCycle

end ProofsInTheBook.PlanarMap












end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordSeparation
-/
/- Source module: ProofsInTheBook.ChordGateCompat -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open ProofsInTheBook.PlanarMap.CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace CombMap.SimplePrimalCycle

variable {M : CombMap D}



/-- **`dartFace`-equality is `φ`-`SameCycle`.**  `dartFace d = Quotient.mk (cycleSetoid
M.φ) d`, so two darts share a face iff they are `M.φ.SameCycle`. -/
lemma sameCycle_phi_of_dartFace_eq {d e : D} (h : M.dartFace d = M.dartFace e) :
    M.φ.SameCycle d e := by
  have := Quotient.exact h
  exact this

/-- **A `φ`-`3`-cycle element is `d`, `φ d`, or `φ² d`.**  If `M.φ³ d = d` and
`M.φ.SameCycle d e`, then `e ∈ {d, M.φ d, M.φ² d}`.  Proof: the triple is invariant
under both `φ` and `φ⁻¹` (using `φ³ d = d`), so it contains the whole `φ`-orbit of `d`,
hence `e = φ^i d` for some `i : ℤ`. -/
lemma mem_triple_of_sameCycle_phiCube {d e : D} (hcube : M.φ (M.φ (M.φ d)) = d)
    (h : M.φ.SameCycle d e) :
    e = d ∨ e = M.φ d ∨ e = M.φ (M.φ d) := by
  obtain ⟨i, hi⟩ := h
  -- `φ⁻¹ d = φ² d`, `φ⁻¹ (φ d) = d`, `φ⁻¹ (φ² d) = φ d`  (from `φ³ d = d`).
  have hinv0 : M.φ.symm d = M.φ (M.φ d) := by
    rw [Equiv.symm_apply_eq]; exact hcube.symm
  have hinv1 : M.φ.symm (M.φ d) = d := by rw [Equiv.symm_apply_eq]
  have hinv2 : M.φ.symm (M.φ (M.φ d)) = M.φ d := by rw [Equiv.symm_apply_eq]
  -- The predicate "x ∈ triple" is invariant under `φ` and `φ⁻¹`, so `φ^i d` is in it.
  have key : ∀ k : ℤ, (M.φ ^ k) d = d ∨ (M.φ ^ k) d = M.φ d ∨
      (M.φ ^ k) d = M.φ (M.φ d) := by
    intro k
    refine Int.induction_on k ?_ ?_ ?_
    · left; simp
    · intro n ih
      rw [show ((n : ℤ) + 1) = 1 + (n : ℤ) by ring, zpow_add, zpow_one,
        Equiv.Perm.mul_apply]
      rcases ih with h0 | h1 | h2
      · right; left; rw [h0]
      · right; right; rw [h1]
      · left; rw [h2]; exact hcube
    · intro n ih
      have hstep : (M.φ ^ (-(n : ℤ) - 1)) d = M.φ.symm ((M.φ ^ (-(n : ℤ))) d) := by
        rw [show (-(n : ℤ) - 1) = (-1) + (-(n : ℤ)) by ring, zpow_add, Equiv.Perm.mul_apply,
          show (M.φ ^ (-1 : ℤ)) = M.φ.symm from by
            rw [zpow_neg, zpow_one]; rfl]
      rw [hstep]
      rcases ih with h0 | h1 | h2
      · rw [h0]; right; right; exact hinv0
      · rw [h1]; left; exact hinv1
      · rw [h2]; right; left; exact hinv2
  rcases key i with h0 | h1 | h2
  · left; rw [← hi, h0]
  · right; left; rw [← hi, h1]
  · right; right; rw [← hi, h2]

/-- **The triangle lever (`M.φ` form).**  Two distinct darts of the same inner
triangular face (`M.φ³ d = d`) are joined by a single `M.φ`-step (in one direction or
the other). -/
lemma phi_edge_of_sameFace_triangle {d e : D}
    (hcube : M.φ (M.φ (M.φ d)) = d) (hface : M.dartFace d = M.dartFace e)
    (hne : d ≠ e) :
    M.φ d = e ∨ M.φ e = d := by
  have hsc := sameCycle_phi_of_dartFace_eq hface
  rcases mem_triple_of_sameCycle_phiCube hcube hsc with h0 | h1 | h2
  · exact absurd h0.symm hne
  · exact Or.inl h1.symm
  · -- e = φ² d ⇒ φ e = φ³ d = d
    right; rw [h2]; exact hcube



/-- The `p`/`q` bank darts are exactly the cycle darts: `qDart i = dart i`,
`pDart i = α (dart (prevIdx i))`, both in `dartSet`. -/
lemma pDart_mem_dartSet (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.pDart i ∈ C.dartSet := by
  rw [pDart]; exact C.alpha_dart_mem_dartSet _

lemma qDart_mem_dartSet (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.qDart i ∈ C.dartSet := by
  rw [qDart]; exact C.dart_mem_dartSet _

/-- **Clean `φ'₂` on a non-cycle dart whose `M.φ`-image is also non-cycle.**  Then the
cap-divert branches of `cutCapPhi2_inl_other_cases` cannot fire (they require
`M.φ d = M.σ (M.α d)` to be a `p`/`q` cycle dart), so `φ'₂ (inl d) = inl (M.φ d)`. -/
lemma cutCapPhi2_inl_clean (C : SimplePrimalCycle M) {d : D}
    (hd : d ∉ C.dartSet) (hphid : M.φ d ∉ C.dartSet) :
    (C.cutCapMap2).φ (Sum.inl d) = Sum.inl (M.φ d) := by
  rcases C.cutCapPhi2_inl_other_cases hd with hclean | ⟨j, hpj, _⟩ | ⟨j, hqj, _⟩
  · exact hclean
  · refine absurd ?_ hphid
    rw [show M.φ d = M.σ (M.α d) from rfl, hpj]; exact C.pDart_mem_dartSet j
  · refine absurd ?_ hphid
    rw [show M.φ d = M.σ (M.α d) from rfl, hqj]; exact C.qDart_mem_dartSet j

/-- **The recoverable rotation-system contiguity (`φ'₂` form).**  Two distinct
**non-cycle** darts `d`, `e` in one inner triangular face are joined by a single
`φ'₂`-edge of the corrected cut map.  This is the genuine M-lesson recoverable core:
the triangle `φ`-`3`-cycle gives a single `M.φ`-step, which lifts cleanly because both
darts are non-cycle. -/
lemma phiPrime_edge_of_innerGate (C : SimplePrimalCycle M) {d e : D}
    (hcube : M.φ (M.φ (M.φ d)) = d) (hface : M.dartFace d = M.dartFace e)
    (hne : d ≠ e) (hd : d ∉ C.dartSet) (he : e ∉ C.dartSet) :
    (C.cutCapMap2).φ (Sum.inl d) = Sum.inl e ∨
      (C.cutCapMap2).φ (Sum.inl e) = Sum.inl d := by
  rcases phi_edge_of_sameFace_triangle hcube hface hne with hfwd | hbwd
  · -- M.φ d = e: clean lift of d (its image e is non-cycle)
    left
    have := C.cutCapPhi2_inl_clean hd (by rw [hfwd]; exact he)
    rwa [hfwd] at this
  · -- M.φ e = d: clean lift of e (its image d is non-cycle)
    right
    have := C.cutCapPhi2_inl_clean he (by rw [hbwd]; exact hd)
    rwa [hbwd] at this















/-- A crossing dart of an ordinary dual path is non-cycle (`∉ dartSet`), since it
crosses an uncut edge. -/
lemma edge_notMem_dartSet (C : SimplePrimalCycle M) (P : C.OrdinaryDualPath2)
    (j : Fin P.n) : P.edge j ∉ C.dartSet :=
  C.notMem_dartSet_of_dartEdge_notMem (P.edge_uncut j)

/-- The `α`-reverse of a crossing dart is also non-cycle (same edge, still uncut). -/
lemma alpha_edge_notMem_dartSet (C : SimplePrimalCycle M) (P : C.OrdinaryDualPath2)
    (j : Fin P.n) : M.α (P.edge j) ∉ C.dartSet :=
  C.notMem_dartSet_of_dartEdge_notMem (by rw [M.dartEdge_alpha]; exact P.edge_uncut j)

/-- **The geometric residue of the intermediate gates** (the data the *bare* dual path
lacks): for each intermediate position, the entry dart's old face is an inner triangle
(`M.φ³ (α (edge j)) = α (edge j)`) and the entry/exit darts are distinct.  This is the
genuine combinatorial content `gateCompat` must supply for the intermediate gates — and
in a near-triangulation it is *true* (every visited inner face is a triangle), the
recoverable rotation-system contiguity. -/
structure InteriorTriangleGates (C : SimplePrimalCycle M) (P : C.OrdinaryDualPath2) :
    Prop where
  /-- The face at each intermediate gate is an inner triangle (the entry dart's
  `M.φ`-orbit is a `3`-cycle). -/
  tri : ∀ j : Fin P.n, ∀ hj : (j : ℕ) + 1 < P.n,
    M.φ (M.φ (M.φ (M.α (P.edge j)))) = M.α (P.edge j)
  /-- The entry and exit darts of each intermediate gate are distinct. -/
  ne : ∀ j : Fin P.n, ∀ hj : (j : ℕ) + 1 < P.n,
    M.α (P.edge j) ≠ P.edge ⟨(j : ℕ) + 1, hj⟩

/-- **Intermediate-gate `φ'₂`-edge, discharged.**  From the geometric residue
`InteriorTriangleGates`, each intermediate gate is realised by a single `φ'₂`-edge — the
exact `mid_edge` field of `GateFragmentCompatible`. -/
theorem mid_edge_of_interiorTriangleGates (C : SimplePrimalCycle M)
    (P : C.OrdinaryDualPath2) (hg : C.InteriorTriangleGates P)
    (j : Fin P.n) (hj : (j : ℕ) + 1 < P.n) :
    (C.cutCapMap2).φ (Sum.inl (M.α (P.edge j))) = Sum.inl (P.edge ⟨(j : ℕ) + 1, hj⟩) ∨
      (C.cutCapMap2).φ (Sum.inl (P.edge ⟨(j : ℕ) + 1, hj⟩)) = Sum.inl (M.α (P.edge j)) := by
  refine C.phiPrime_edge_of_innerGate (hg.tri j hj) ?_ (hg.ne j hj)
    (C.alpha_edge_notMem_dartSet P j) (C.edge_notMem_dartSet P ⟨(j : ℕ) + 1, hj⟩)
  -- co-facehood: both darts have face `P.face j.succ`.
  rw [P.right_face j]
  have hjs : (⟨(j : ℕ) + 1, hj⟩ : Fin P.n).castSucc = j.succ := by
    apply Fin.ext; simp [Fin.val_succ]
  rw [P.left_face ⟨(j : ℕ) + 1, hj⟩, hjs]







/-- **The minimal endpoint residue: the cap-channel link.**  The genuine remaining
content of `gateCompat` for an ordinary dual path is the *endpoint* connectivity, which
the surgery routes through the cap chain (NOT a within-face `φ'₂`-edge, as
`start_edge_*_false` show): the forward cycle dart `dart i` is `cutReach2`-connected to
the start crossing dart, and the reverse cycle dart `α (dart i)` to the end crossing
dart.  (For `n = 0` both reduce to `cutReach2 (inl (dart i)) (inl (α (dart i)))`.)

This is non-vacuous (`SidesReach2` already threads all cycle darts into one
`cutReach2`-loop) and is the honest discrete-Jordan datum — the analogue of
`ChordSigmaContig`'s `SideTracePhiTwoCycle` (connectivity through the spliced channel,
not the false within-face wrap). -/
def EndpointCapLink (C : SimplePrimalCycle M) (i : Fin C.len) (P : C.OrdinaryDualPath2) :
    Prop :=
  (∀ h : 0 < P.n,
      C.cutReach2 (Sum.inl (C.dart i)) (Sum.inl (P.edge ⟨0, h⟩))) ∧
    (∀ h : 0 < P.n,
      C.cutReach2 (Sum.inl (M.α (C.dart i)))
        (Sum.inl (M.α (P.edge ⟨P.n - 1, by omega⟩)))) ∧
    (P.n = 0 → C.cutReach2 (Sum.inl (C.dart i)) (Sum.inl (M.α (C.dart i))))





/-- **Non-vacuity of the endpoint cap residue (`n = 0`).**  Given a cross-bank
`cutReach2` link (the genuine connectivity datum, e.g. supplied by `M.Connected` through
`reachesBank2`), the nil ordinary path satisfies `EndpointCapLink`.  So the residue is
inhabited — not a hidden `False`. -/
theorem endpointCapLink_nil (C : SimplePrimalCycle M) (i : Fin C.len) (f : M.Face)
    (hcross : C.cutReach2 (Sum.inl (C.dart i)) (Sum.inl (M.α (C.dart i)))) :
    C.EndpointCapLink i (OrdinaryDualPath2.nil C f) := by
  refine ⟨fun h => ?_, fun h => ?_, fun _ => hcross⟩
  · exact absurd h (by show ¬ 0 < 0; omega)
  · exact absurd h (by show ¬ 0 < 0; omega)



end CombMap.SimplePrimalCycle

end ProofsInTheBook.PlanarMap














end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordGateCompat
-/
/- Source module: ProofsInTheBook.ChordSeparationClose -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open ProofsInTheBook.PlanarMap.CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace CombMap.SimplePrimalCycle

variable {M : CombMap D}



/-- A single intermediate gate, lifted to a `cutReach2` step.  From
`mid_edge_of_interiorTriangleGates` (a clean `φ'₂`-edge in either direction) and
`cutReach2_of_phi_step`. -/
lemma cutReach2_midGate (C : SimplePrimalCycle M) (P : C.OrdinaryDualPath2)
    (hg : C.InteriorTriangleGates P) (j : Fin P.n) (hj : (j : ℕ) + 1 < P.n) :
    C.cutReach2 (Sum.inl (M.α (P.edge j))) (Sum.inl (P.edge ⟨(j : ℕ) + 1, hj⟩)) := by
  rcases C.mid_edge_of_interiorTriangleGates P hg j hj with hphi | hphi
  · -- φ'₂ (inl (α (edge j))) = inl (edge (j+1))
    have := C.cutReach2_of_phi_step (Sum.inl (M.α (P.edge j)))
    rwa [hphi] at this
  · -- φ'₂ (inl (edge (j+1))) = inl (α (edge j)) — use the reverse step
    have := C.cutReach2_of_phi_step (Sum.inl (P.edge ⟨(j : ℕ) + 1, hj⟩))
    rw [hphi] at this
    exact C.cutReach2_symm this

/-- A single crossing, lifted to a `cutReach2` step (the `α'`-uncut bridge). -/
lemma cutReach2_cross (C : SimplePrimalCycle M) (P : C.OrdinaryDualPath2) (j : Fin P.n) :
    C.cutReach2 (Sum.inl (P.edge j)) (Sum.inl (M.α (P.edge j))) :=
  C.cutReach2_across_uncut_dual_gate (P.edge_uncut j)

/-- **The interior reach (prefix form).**  For every `k < n`, the first crossing dart
`inl (edge 0)` reaches the reverse crossing dart `inl (α (edge k))`, by chaining `k`
crossings and `k` intermediate gates. -/
lemma interiorReach_prefix (C : SimplePrimalCycle M) (P : C.OrdinaryDualPath2)
    (hg : C.InteriorTriangleGates P) (h0 : 0 < P.n) :
    ∀ k : ℕ, ∀ hk : k < P.n,
      C.cutReach2 (Sum.inl (P.edge ⟨0, h0⟩)) (Sum.inl (M.α (P.edge ⟨k, hk⟩)))
  | 0, hk => by
      -- base: just the first crossing
      have : (⟨0, hk⟩ : Fin P.n) = ⟨0, h0⟩ := rfl
      rw [this]
      exact C.cutReach2_cross P ⟨0, h0⟩
  | k + 1, hk => by
      have hk' : k < P.n := by omega
      have hkj : (k : ℕ) + 1 < P.n := by omega
      -- reach to α (edge k)
      have ih := C.interiorReach_prefix P hg h0 k hk'
      -- gate: α (edge k) ⇝ edge (k+1)
      have hgate := C.cutReach2_midGate P hg ⟨k, hk'⟩ (by simpa using hkj)
      -- crossing: edge (k+1) ⇝ α (edge (k+1))
      have hcross := C.cutReach2_cross P ⟨k + 1, hk⟩
      have hgate' :
          C.cutReach2 (Sum.inl (M.α (P.edge ⟨k, hk'⟩))) (Sum.inl (P.edge ⟨k + 1, hk⟩)) := by
        have he : (⟨(⟨k, hk'⟩ : Fin P.n) + 1, by simpa using hkj⟩ : Fin P.n)
            = ⟨k + 1, hk⟩ := by apply Fin.ext; simp
        rw [he] at hgate; exact hgate
      exact (ih.trans hgate').trans hcross

/-- **The interior reach.**  When `n > 0`, the first crossing dart reaches the last
reverse crossing dart through `cutReach2`. -/
lemma interiorReach_of_gates (C : SimplePrimalCycle M) (P : C.OrdinaryDualPath2)
    (hg : C.InteriorTriangleGates P) (h0 : 0 < P.n) :
    C.cutReach2 (Sum.inl (P.edge ⟨0, h0⟩)) (Sum.inl (M.α (P.edge ⟨P.n - 1, by omega⟩))) :=
  C.interiorReach_prefix P hg h0 (P.n - 1) (by omega)



/-- **The cross-bank bridge.**  From the endpoint cap-channel link and the interior
triangle gates, the forward cycle bank reaches the reverse cycle bank in the corrected
cut map.  (`n = 0`: the endpoint link is the bridge directly; `n > 0`: forward dart ⇝
first crossing ⇝ [interior reach] ⇝ last reverse crossing ⇝ reverse dart.) -/
theorem crossBankBridge_of_endpointCapLink (C : SimplePrimalCycle M) (i : Fin C.len)
    (P : C.OrdinaryDualPath2) (hlink : C.EndpointCapLink i P)
    (hg : C.InteriorTriangleGates P) :
    C.cutReach2 (Sum.inl (C.dart i)) (Sum.inl (M.α (C.dart i))) := by
  obtain ⟨hstart, hend, hnil⟩ := hlink
  by_cases h0 : 0 < P.n
  · -- dart i ⇝ edge 0 ⇝ α (edge (n-1)) ⇝ α (dart i)
    have hs : C.cutReach2 (Sum.inl (C.dart i)) (Sum.inl (P.edge ⟨0, h0⟩)) := hstart h0
    have hmid := C.interiorReach_of_gates P hg h0
    have he : C.cutReach2 (Sum.inl (M.α (C.dart i)))
        (Sum.inl (M.α (P.edge ⟨P.n - 1, by omega⟩))) := hend h0
    exact (hs.trans hmid).trans (C.cutReach2_symm he)
  · -- n = 0: the endpoint link is the cross-bank bridge directly
    have hn0 : P.n = 0 := by omega
    exact hnil hn0



/-- **Connectivity from the corrected gate data** (under the dual-reachability
hypothesis).  Given `M.Connected`, the endpoint cap-channel link, and the interior
triangle gates of *some* extracted ordinary path, the corrected cut map is connected. -/
theorem cutCapMap2_connected_of_corrected (C : SimplePrimalCycle M) (i : Fin C.len)
    (hconn : M.Connected)
    (P : C.OrdinaryDualPath2) (hlink : C.EndpointCapLink i P)
    (hg : C.InteriorTriangleGates P) :
    (C.cutCapMap2).Connected :=
  C.cutCapMap2_connected_of_reachesBank_of_bridge i
    (C.reachesBank2_of_connected i hconn (C.sidesReach2_concrete i))
    (C.crossBankBridge_of_endpointCapLink i P hlink hg)



/-- **The corrected minimal chord-separation residue.** -/
structure ChordJordanInput' (C : SimplePrimalCycle M) : Prop where
  /-- The corrected face count `numCycles φ'₂ = F + 2` (kernel-anchored). -/
  faceCore : C.NumCyclesCutPhi2
  /-- Per-edge supplier: from a cycle-avoiding dual path, an ordinary dual path carrying
  the **cap-channel endpoint link** (`EndpointCapLink`, the genuine discrete-Jordan datum)
  and the **interior triangle gates** (`InteriorTriangleGates`, the recoverable lever). -/
  gateCompat' : ∀ i : Fin C.len,
    DualReachableAvoidingCycle M C (C.faceLeft i) (C.faceRight i) →
      ∃ P : C.OrdinaryDualPath2, C.EndpointCapLink i P ∧ C.InteriorTriangleGates P

/-- The corrected connectivity parameter of `jordan_simple_cycle2_walk`, discharged from
the corrected residue bundle. -/
theorem connectivity_of_input' (C : SimplePrimalCycle M) (hconn : M.Connected)
    (hin : C.ChordJordanInput') (i : Fin C.len)
    (hpath : DualReachableAvoidingCycle M C (C.faceLeft i) (C.faceRight i)) :
    (C.cutCapMap2).Connected := by
  obtain ⟨P, hlink, hg⟩ := hin.gateCompat' i hpath
  exact C.cutCapMap2_connected_of_corrected i hconn P hlink hg

end CombMap.SimplePrimalCycle



namespace CombMap.NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)

open SimplePrimalCycle





end CombMap.NearTriangulation



namespace CombMap.SimplePrimalCycle

variable {M : CombMap D}

/-- **`InteriorTriangleGates` is inhabited on the nil path** (vacuously: no intermediate
gates). -/
theorem interiorTriangleGates_nil (C : SimplePrimalCycle M) (f : M.Face) :
    C.InteriorTriangleGates (OrdinaryDualPath2.nil C f) where
  tri := fun j hj => absurd hj (by
    have : (OrdinaryDualPath2.nil C f).n = 0 := rfl; omega)
  ne := fun j hj => absurd hj (by
    have : (OrdinaryDualPath2.nil C f).n = 0 := rfl; omega)





end CombMap.SimplePrimalCycle

end ProofsInTheBook.PlanarMap











end

/- Original source header (imports hoisted):
import ProofsInTheBook.FaceCorrWord
import ProofsInTheBook.ChordSeparationClose
-/
/- Source module: ProofsInTheBook.ZinanCh35CountRoute -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

open Equiv Equiv.Perm Function List
open scoped Finset

namespace ForcedSplits

variable {X : Type*} [Fintype X] [DecidableEq X]

/-- The actual split indices of a transposition word: the swaps whose endpoints are already
in the same cycle of the prefix permutation. -/
noncomputable def actualSplitFinset (p : Equiv.Perm X) {m : ℕ}
    (W : Fin m → ForcedSplits.Swap X) : Finset (Fin m) :=
  Finset.univ.filter fun j =>
    (ForcedSplits.prefixPerm p W j.val).SameCycle (W j).x (W j).y

/-- A non-split transposition step lowers the cycle count by exactly one. -/
lemma stepDelta_eq_neg_one_of_not_sameCycle (p : Equiv.Perm X) {m : ℕ}
    (W : Fin m → ForcedSplits.Swap X) (j : Fin m)
    (hne : (W j).x ≠ (W j).y)
    (hnot :
      ¬ (ForcedSplits.prefixPerm p W j.val).SameCycle (W j).x (W j).y) :
    ForcedSplits.stepDelta p W j = -1 := by
  classical
  have hj : j.val < m := j.isLt
  rw [ForcedSplits.stepDelta, ForcedSplits.prefixPerm_succ p W hj,
    ForcedSplits.Swap.perm]
  have hnum := numCycles_mul_swap_of_not_sameCycle
    (ForcedSplits.prefixPerm p W j.val) hne hnot
  have hnumZ :
      (numCycles (ForcedSplits.prefixPerm p W j.val *
          Equiv.swap (W j).x (W j).y) : ℤ) + 1 =
        (numCycles (ForcedSplits.prefixPerm p W j.val) : ℤ) := by
    exact_mod_cast hnum
  linarith

/-- The sum of actual step deltas is `-m + 2 * (# actual splits)`. -/
theorem sum_stepDelta_eq_neg_m_add_two_actualSplits (p : Equiv.Perm X) {m : ℕ}
    (W : Fin m → ForcedSplits.Swap X)
    (hne : ∀ j : Fin m, (W j).x ≠ (W j).y) :
    (∑ j : Fin m, ForcedSplits.stepDelta p W j)
      = -(m : ℤ) + 2 * ((ForcedSplits.actualSplitFinset p W).card : ℤ) := by
  classical
  let S : Finset (Fin m) := ForcedSplits.actualSplitFinset p W
  have h_onS : ∀ j ∈ S, ForcedSplits.stepDelta p W j = 1 := by
    intro j hj
    have hsc :
        (ForcedSplits.prefixPerm p W j.val).SameCycle (W j).x (W j).y := by
      simpa [S, ForcedSplits.actualSplitFinset] using (Finset.mem_filter.mp hj).2
    exact ForcedSplits.stepDelta_eq_one_of_forced_split p W j (hne j) hsc
  have h_offS : ∀ j ∈ Sᶜ, ForcedSplits.stepDelta p W j = -1 := by
    intro j hj
    have hjnot : j ∉ S := by simpa using hj
    have hnot :
        ¬ (ForcedSplits.prefixPerm p W j.val).SameCycle (W j).x (W j).y := by
      intro hsc
      exact hjnot (by
        simp [S, ForcedSplits.actualSplitFinset, hsc])
    exact ForcedSplits.stepDelta_eq_neg_one_of_not_sameCycle p W j (hne j) hnot
  calc
    (∑ j : Fin m, ForcedSplits.stepDelta p W j)
        = (∑ j ∈ S, ForcedSplits.stepDelta p W j)
            + (∑ j ∈ Sᶜ, ForcedSplits.stepDelta p W j) := by
          rw [← Finset.sum_add_sum_compl S]
    _ = (∑ _j ∈ S, (1 : ℤ)) + (∑ _j ∈ Sᶜ, (-1 : ℤ)) := by
          congr 1
          · exact Finset.sum_congr rfl (fun j hj => h_onS j hj)
          · exact Finset.sum_congr rfl (fun j hj => h_offS j hj)
    _ = -(m : ℤ) + 2 * ((ForcedSplits.actualSplitFinset p W).card : ℤ) := by
          simp only [Finset.sum_const, nsmul_eq_mul]
          have hcardC : (Sᶜ).card = m - S.card := by
            rw [Finset.card_compl, Fintype.card_fin]
          have hcardCZ : ((Sᶜ).card : ℤ) = (m : ℤ) - (S.card : ℤ) := by
            rw [hcardC]
            have hle : S.card ≤ m := by
              simpa [Finset.card_univ, Fintype.card_fin] using Finset.card_le_univ S
            omega
          rw [hcardCZ]
          dsimp [S]
          ring

end ForcedSplits

namespace ProofsInTheBook.PlanarMap

namespace FaceCorrWord

open ForcedSplits SeamChain

variable {X : Type*} [Fintype X] [DecidableEq X]

/-- A cycle-list decomposition with nodup cycle lists. -/
theorem exists_cycleListProd_nodup (q : Equiv.Perm X) :
    ∃ Ls : List (List X),
      (∀ L ∈ Ls, 2 ≤ L.length ∧ L.Nodup) ∧
      FaceCorrWord.cycleListProd Ls = q := by
  classical
  induction q using Equiv.Perm.cycle_induction_on with
  | base_one =>
      exact ⟨[], by simp, rfl⟩
  | base_cycles σ hσ =>
      obtain ⟨x, hx, -⟩ := id hσ
      have hxs : x ∈ σ.support := by
        rw [Equiv.Perm.mem_support]
        exact hx
      refine ⟨[Equiv.Perm.toList σ x], ?_, ?_⟩
      · intro L hL
        simp only [List.mem_singleton] at hL
        subst hL
        constructor
        · exact Equiv.Perm.two_le_length_toList_iff_mem_support.mpr hxs
        · -- If Mathlib renamed this, alternates: `Equiv.Perm.toList_nodup`,
          -- `Equiv.Perm.nodup_toList`.
          exact Equiv.Perm.nodup_toList σ x
      · simp only [FaceCorrWord.cycleListProd, mul_one, SeamChain.cycleOfList]
        rw [Equiv.Perm.formPerm_toList, Equiv.Perm.IsCycle.cycleOf_eq hσ hx]
  | induction_disjoint σ τ hdisj hσ hστ hτ =>
      obtain ⟨Lσ, hLσ, hfacσ⟩ := hστ
      obtain ⟨Lτ, hLτ, hfacτ⟩ := hτ
      refine ⟨Lσ ++ Lτ, ?_, ?_⟩
      · intro L hL
        rcases List.mem_append.mp hL with h | h
        · exact hLσ L h
        · exact hLτ L h
      · rw [FaceCorrWord.cycleListProd_append, hfacσ, hfacτ]

/-- Consecutive entries in a nodup list are distinct, in the form needed by `wordOfList`. -/
lemma wordOfList_ne_of_nodup (L : List X) (hL : L.Nodup)
    (j : Fin (L.length - 1)) :
    (FaceCorrWord.wordOfList L j).x ≠ (FaceCorrWord.wordOfList L j).y := by
  classical
  dsimp [FaceCorrWord.wordOfList]
  intro h
  have hj0 : j.val < L.length := by
    have := j.isLt
    omega
  have hj1 : j.val + 1 < L.length := by
    have := j.isLt
    omega
  have hidx : j.val = j.val + 1 := by
    -- If Mathlib renamed this, alternates: `List.Nodup.getElem_inj`,
    -- `List.Nodup.getElem_inj_iff`.
    exact (List.Nodup.getElem_inj_iff hL).mp h
  omega

/-- All swaps in a concatenated word of nodup cycle lists have distinct endpoints. -/
lemma concatWord_ne_of_nodup (Ls : List (List X))
    (hpos : ∀ L ∈ Ls, 2 ≤ L.length)
    (hnodup : ∀ L ∈ Ls, L.Nodup)
    (j : Fin (FaceCorrWord.concatLen Ls)) :
    (FaceCorrWord.concatWord Ls j).x ≠ (FaceCorrWord.concatWord Ls j).y := by
  classical
  induction Ls with
  | nil =>
      exact absurd j.isLt (by simp [FaceCorrWord.concatLen])
  | cons L rest ih =>
      have hLpos : 2 ≤ L.length := hpos L List.mem_cons_self
      have hLnodup : L.Nodup := hnodup L List.mem_cons_self
      have hpos_rest : ∀ L' ∈ rest, 2 ≤ L'.length := by
        intro L' hL'
        exact hpos L' (List.mem_cons_of_mem _ hL')
      have hnodup_rest : ∀ L' ∈ rest, L'.Nodup := by
        intro L' hL'
        exact hnodup L' (List.mem_cons_of_mem _ hL')
      by_cases hj : j.val < L.length - 1
      · have hjFin : j.val < (L.length - 1) := hj
        have hcast : (⟨j.val, hjFin⟩ : Fin (L.length - 1)) =
            ⟨j.val, hjFin⟩ := rfl
        simpa [FaceCorrWord.concatWord, FaceCorrWord.concatLen,
          FaceCorrWord.appendWord, hj] using
          FaceCorrWord.wordOfList_ne_of_nodup L hLnodup ⟨j.val, hjFin⟩
      · have hjRest : j.val - (L.length - 1) < FaceCorrWord.concatLen rest := by
          have hlt := j.isLt
          have hcl : FaceCorrWord.concatLen (L :: rest)
              = (L.length - 1) + FaceCorrWord.concatLen rest := rfl
          omega
        have hnot : ¬ j.val < L.length - 1 := hj
        have ihj := ih hpos_rest hnodup_rest
          ⟨j.val - (L.length - 1), hjRest⟩
        simpa [FaceCorrWord.concatWord, FaceCorrWord.concatLen,
          FaceCorrWord.appendWord, hnot] using ihj

end FaceCorrWord

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

open ForcedSplits FaceCorrWord SeamChain

variable {M : CombMap D}

/-- A cycle-list decomposition of `faceCorr₂`, with enough list hygiene for the
consecutive-transposition word. -/
structure FaceCorrCycleLists (C : SimplePrimalCycle M)
    (Ls : List (List C.CutDart)) : Prop where
  pos : ∀ L ∈ Ls, 2 ≤ L.length
  nodup : ∀ L ∈ Ls, L.Nodup
  factor : FaceCorrWord.cycleListProd Ls = C.faceCorr2

/-- The actual split indices of the canonical cycle-list word for `faceCorr₂`. -/
noncomputable def actualSplitFinset (C : SimplePrimalCycle M)
    (Ls : List (List C.CutDart)) :
    Finset (Fin (FaceCorrWord.concatLen Ls)) :=
  ForcedSplits.actualSplitFinset C.phiLift (FaceCorrWord.concatWord Ls)

/-- The concatenated word of a `FaceCorrCycleLists` certificate is nondegenerate. -/
lemma concatWord_ne_of_nodup (C : SimplePrimalCycle M) {Ls : List (List C.CutDart)}
    (H : C.FaceCorrCycleLists Ls) (j : Fin (FaceCorrWord.concatLen Ls)) :
    (FaceCorrWord.concatWord Ls j).x ≠ (FaceCorrWord.concatWord Ls j).y :=
  FaceCorrWord.concatWord_ne_of_nodup Ls H.pos H.nodup j

/-- Every `faceCorr₂` has a nodup cycle-list decomposition. -/
theorem exists_faceCorrCycleLists (C : SimplePrimalCycle M) :
    ∃ Ls : List (List C.CutDart), C.FaceCorrCycleLists Ls := by
  classical
  obtain ⟨Ls, hLs, hfac⟩ := FaceCorrWord.exists_cycleListProd_nodup C.faceCorr2
  refine ⟨Ls, ?_⟩
  exact ⟨fun L hL => (hLs L hL).1, fun L hL => (hLs L hL).2, hfac⟩



/-- Enumerate a finset by `Fin card`, returning elements of the ambient type. -/
noncomputable def splitIdxOfFinset {n : ℕ} (S : Finset (Fin n)) :
    Fin S.card → Fin n :=
  fun i => (S.orderIsoOfFin rfl i : Fin n)
-- If Mathlib renamed this, alternates: `Finset.orderIsoOfFin S`,
-- `Fintype.equivFin {x // x ∈ S}`.

lemma splitIdxOfFinset_mem {n : ℕ} (S : Finset (Fin n)) (i : Fin S.card) :
    splitIdxOfFinset S i ∈ S :=
  (S.orderIsoOfFin rfl i).2

lemma splitIdxOfFinset_injective {n : ℕ} (S : Finset (Fin n)) :
    Function.Injective (splitIdxOfFinset S) := by
  intro i j h
  exact (S.orderIsoOfFin rfl).injective (Subtype.ext h)

/-- Build the repository's split certificate from a cycle-list certificate and the sufficient
actual-split count. -/
noncomputable def faceCorrSplitCert_of_cycleLists (C : SimplePrimalCycle M)
    {Ls : List (List C.CutDart)}
    (H : C.FaceCorrCycleLists Ls)
    (hsplits :
      FaceCorrWord.concatLen Ls + 2 ≤
        2 * (C.actualSplitFinset Ls).card + 2 * C.len) :
    C.FaceCorrSplitCert := by
  classical
  let S : Finset (Fin (FaceCorrWord.concatLen Ls)) := C.actualSplitFinset Ls
  refine
    { Ls := Ls
      Ls_pos := ?_
      factor := H.factor
      s := S.card
      hbound := ?_
      splitIdx := splitIdxOfFinset S
      splitIdx_injective := splitIdxOfFinset_injective S
      split_ne := ?_
      forced_split := ?_ }
  · intro L hL
    have := H.pos L hL
    omega
  · simpa [S]
      using hsplits
  · intro i
    exact C.concatWord_ne_of_nodup H (splitIdxOfFinset S i)
  · intro i
    have hmem : splitIdxOfFinset S i ∈ S := splitIdxOfFinset_mem S i
    simpa [S, SimplePrimalCycle.actualSplitFinset, ForcedSplits.actualSplitFinset]
      using (Finset.mem_filter.mp hmem).2

/-- If every cycle-list decomposition has enough actual splits, then `faceCorr₂` has a
`FaceCorrSplitCert`.  This is the conditional replacement for the unproved geometric
split-count theorem. -/
noncomputable def faceCorrSplitCert_of_splitsEnough (C : SimplePrimalCycle M)
    (hsplitsAll :
      ∀ Ls : List (List C.CutDart), C.FaceCorrCycleLists Ls →
        FaceCorrWord.concatLen Ls + 2 ≤
          2 * (C.actualSplitFinset Ls).card + 2 * C.len) :
    C.FaceCorrSplitCert := by
  classical
  exact C.faceCorrSplitCert_of_cycleLists
    (C.exists_faceCorrCycleLists).choose_spec
    (hsplitsAll _ (C.exists_faceCorrCycleLists).choose_spec)





/-- Corrected lower-bound Jordan input: the face side is a split certificate, and the
connectivity side is exactly the corrected cap-channel endpoint/interior-gate supplier
from `ChordJordanInput'`. -/
structure ChordJordanInputLower' (C : SimplePrimalCycle M) where
  /-- The lower-bound face-count certificate. -/
  faceSplit : C.FaceCorrSplitCert
  /-- The corrected cap-channel endpoint link plus interior triangle gates, matching
  `ChordJordanInput'.gateCompat'`. -/
  gateCompat' : ∀ i : Fin C.len,
    DualReachableAvoidingCycle M C (C.faceLeft i) (C.faceRight i) →
      ∃ P : C.OrdinaryDualPath2, C.EndpointCapLink i P ∧ C.InteriorTriangleGates P

/-- Connectivity of `cutCapMap2` from the lower-bound corrected input. -/
theorem connectivity_of_inputLower' (C : SimplePrimalCycle M) (hconn : M.Connected)
    (hin : C.ChordJordanInputLower') (i : Fin C.len)
    (hpath : DualReachableAvoidingCycle M C (C.faceLeft i) (C.faceRight i)) :
    (C.cutCapMap2).Connected := by
  obtain ⟨P, hlink, hg⟩ := hin.gateCompat' i hpath
  exact C.cutCapMap2_connected_of_corrected i hconn P hlink hg

end SimplePrimalCycle

end CombMap

namespace CombMap.NearTriangulation

variable {D : Type*} [Fintype D] [DecidableEq D]
variable {M : CombMap D} (hNT : NearTriangulation M)

open SimplePrimalCycle

/-- `SphereChordSeparation` from the lower-bound corrected residue. -/
theorem sphereChordSeparation_of_inputLower' {u v : M.Vertex}
    (h : hNT.outerCycle.Chord u v)
    (C : CombMap.SimplePrimalCycle M)
    (hsub : ∀ e ∈ C.edgeSet, e = s(u, v) ∨ hNT.outerCycle.IsBoundaryEdge e)
    (hin : C.ChordJordanInputLower')
    (i₀ : Fin C.len)
    (hleft : C.faceLeft i₀ = M.dartFace (hNT.chordDart h))
    (hright : C.faceRight i₀ = M.dartFace (M.α (hNT.chordDart h))) :
    hNT.SphereChordSeparation h := by
  intro hreach
  have hpath : DualReachableAvoidingCycle M C
      (M.dartFace (hNT.chordDart h))
      (M.dartFace (M.α (hNT.chordDart h))) :=
    hNT.reachable_dualAvoidsCycle_of_chordSplitAdj C hsub hreach
  rw [← hleft, ← hright] at hpath
  exact C.jordan_simple_cycle2_lower_of_splitCert hin.faceSplit
    hNT.sphere.2
    (fun i hp => C.connectivity_of_inputLower' hNT.sphere.1 hin i hp)
    i₀ hpath

/-- `Separates` form from the lower-bound corrected residue. -/
theorem separates_of_inputLower' {u v : M.Vertex}
    (data : hNT.ChordSplitData u v)
    (C : CombMap.SimplePrimalCycle M)
    (hsub : ∀ e ∈ C.edgeSet, e = s(u, v) ∨ hNT.outerCycle.IsBoundaryEdge e)
    (hin : C.ChordJordanInputLower')
    (i₀ : Fin C.len)
    (hleft : C.faceLeft i₀ = M.dartFace (hNT.chordDart data.chord))
    (hright : C.faceRight i₀ = M.dartFace (M.α (hNT.chordDart data.chord))) :
    data.Separates :=
  data.separates_of_nearTriangulation
    (hNT.sphereChordSeparation_of_inputLower'
      data.chord C hsub hin i₀ hleft hright)

end CombMap.NearTriangulation

end ProofsInTheBook.PlanarMap















end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35CountRoute
-/
/- Source module: ProofsInTheBook.ZinanCh35Split -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

open Equiv Equiv.Perm Function

namespace ProofsInTheBook.PlanarMap

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace CutCapCount



section SumCongrTwo

variable {α β : Type*} [Fintype α] [DecidableEq α] [Fintype β] [DecidableEq β]

@[simp] lemma sumCongr_apply_inl (f : Equiv.Perm α) (g : Equiv.Perm β) (a : α) :
    (Equiv.Perm.sumCongr f g) (Sum.inl a) = Sum.inl (f a) := by simp

@[simp] lemma sumCongr_apply_inr (f : Equiv.Perm α) (g : Equiv.Perm β) (b : β) :
    (Equiv.Perm.sumCongr f g) (Sum.inr b) = Sum.inr (g b) := by simp

lemma sumCongr_pow_apply_inl (f : Equiv.Perm α) (g : Equiv.Perm β) (n : ℕ) (a : α) :
    ((Equiv.Perm.sumCongr f g) ^ n) (Sum.inl a) = Sum.inl ((f ^ n) a) := by
  induction n with
  | zero => simp
  | succ n ih => rw [pow_succ', pow_succ', Equiv.Perm.mul_apply, Equiv.Perm.mul_apply,
      ih, sumCongr_apply_inl]

lemma sumCongr_pow_apply_inr (f : Equiv.Perm α) (g : Equiv.Perm β) (n : ℕ) (b : β) :
    ((Equiv.Perm.sumCongr f g) ^ n) (Sum.inr b) = Sum.inr ((g ^ n) b) := by
  induction n with
  | zero => simp
  | succ n ih => rw [pow_succ', pow_succ', Equiv.Perm.mul_apply, Equiv.Perm.mul_apply,
      ih, sumCongr_apply_inr]

lemma sameCycle_sumCongr_inl_inl (f : Equiv.Perm α) (g : Equiv.Perm β) (a a' : α) :
    (Equiv.Perm.sumCongr f g).SameCycle (Sum.inl a) (Sum.inl a')
      ↔ f.SameCycle a a' := by
  constructor
  · intro h
    obtain ⟨m, hm⟩ := h.exists_nat_pow_eq
    rw [sumCongr_pow_apply_inl] at hm
    exact ⟨(m : ℤ), by rw [zpow_natCast]; exact Sum.inl.inj hm⟩
  · intro h
    obtain ⟨m, hm⟩ := h.exists_nat_pow_eq
    exact ⟨(m : ℤ), by rw [zpow_natCast, sumCongr_pow_apply_inl, hm]⟩

lemma sameCycle_sumCongr_inr_inr (f : Equiv.Perm α) (g : Equiv.Perm β) (b b' : β) :
    (Equiv.Perm.sumCongr f g).SameCycle (Sum.inr b) (Sum.inr b')
      ↔ g.SameCycle b b' := by
  constructor
  · intro h
    obtain ⟨m, hm⟩ := h.exists_nat_pow_eq
    rw [sumCongr_pow_apply_inr] at hm
    exact ⟨(m : ℤ), by rw [zpow_natCast]; exact Sum.inr.inj hm⟩
  · intro h
    obtain ⟨m, hm⟩ := h.exists_nat_pow_eq
    exact ⟨(m : ℤ), by rw [zpow_natCast, sumCongr_pow_apply_inr, hm]⟩

lemma not_sameCycle_sumCongr_inl_inr (f : Equiv.Perm α) (g : Equiv.Perm β)
    (a : α) (b : β) :
    ¬ (Equiv.Perm.sumCongr f g).SameCycle (Sum.inl a) (Sum.inr b) := by
  intro h
  obtain ⟨m, hm⟩ := h.exists_nat_pow_eq
  rw [sumCongr_pow_apply_inl] at hm
  exact Sum.inl_ne_inr hm

/-- The orbit-quotient bijection for a two-summand `sumCongr`. -/
noncomputable def sumCongrOrbitEquiv (f : Equiv.Perm α) (g : Equiv.Perm β) :
    Quotient (SameCycle.setoid (Equiv.Perm.sumCongr f g))
      ≃ Quotient (SameCycle.setoid f) ⊕ Quotient (SameCycle.setoid g) := by
  classical
  refine
    { toFun := Quotient.lift
        (fun x => match x with
          | Sum.inl a => Sum.inl (Quotient.mk (SameCycle.setoid f) a)
          | Sum.inr b => Sum.inr (Quotient.mk (SameCycle.setoid g) b)) ?_
      invFun := fun s => match s with
        | Sum.inl q => Quotient.lift
            (fun a => Quotient.mk (SameCycle.setoid (Equiv.Perm.sumCongr f g))
              (Sum.inl a)) ?_ q
        | Sum.inr q => Quotient.lift
            (fun b => Quotient.mk (SameCycle.setoid (Equiv.Perm.sumCongr f g))
              (Sum.inr b)) ?_ q
      left_inv := ?_
      right_inv := ?_ }
  · -- well-defined forward
    intro x y hxy
    change (Equiv.Perm.sumCongr f g).SameCycle x y at hxy
    rcases x with a | b <;> rcases y with a' | b'
    · exact congrArg Sum.inl (Quotient.sound
        ((sameCycle_sumCongr_inl_inl f g a a').mp hxy))
    · exact absurd hxy (not_sameCycle_sumCongr_inl_inr f g a b')
    · exact absurd hxy.symm (not_sameCycle_sumCongr_inl_inr f g a' b)
    · exact congrArg Sum.inr (Quotient.sound
        ((sameCycle_sumCongr_inr_inr f g b b').mp hxy))
  · -- well-defined inverse on the left summand
    intro a a' haa'
    change f.SameCycle a a' at haa'
    exact Quotient.sound ((sameCycle_sumCongr_inl_inl f g a a').mpr haa')
  · -- well-defined inverse on the right summand
    intro b b' hbb'
    change g.SameCycle b b' at hbb'
    exact Quotient.sound ((sameCycle_sumCongr_inr_inr f g b b').mpr hbb')
  · -- left_inv
    intro q
    refine Quotient.inductionOn q ?_
    rintro (a | b) <;> rfl
  · -- right_inv
    rintro (q | q)
    · refine Quotient.inductionOn q ?_; intro a; rfl
    · refine Quotient.inductionOn q ?_; intro b; rfl

/-- **`numCycles` is additive over `sumCongr`** (both summands arbitrary). -/
theorem numCycles_sumCongr (f : Equiv.Perm α) (g : Equiv.Perm β) :
    _root_.numCycles (Equiv.Perm.sumCongr f g)
      = _root_.numCycles f + _root_.numCycles g := by
  classical
  unfold _root_.numCycles
  rw [Fintype.card_congr (sumCongrOrbitEquiv f g), Fintype.card_sum]

end SumCongrTwo

/-- A permutation all of whose points are `SameCycle` has exactly one cycle. -/
lemma numCycles_eq_one_of_forall_sameCycle {γ : Type*} [Fintype γ] [DecidableEq γ]
    [Nonempty γ] (p : Equiv.Perm γ) (h : ∀ x y : γ, p.SameCycle x y) :
    _root_.numCycles p = 1 := by
  classical
  unfold _root_.numCycles
  rw [Fintype.card_eq_one_iff]
  refine ⟨Quotient.mk (SameCycle.setoid p) (Classical.arbitrary γ), ?_⟩
  intro q
  refine Quotient.inductionOn q ?_
  intro x
  exact Quotient.sound (h x (Classical.arbitrary γ))

end CutCapCount

namespace SimplePrimalCycle

open ForcedSplits FaceCorrWord SeamChain CutCapCount

variable {M : CombMap D}



lemma nextIdxEquiv_pow_apply (C : SimplePrimalCycle M) (n : ℕ) (i : Fin C.len) :
    (C.nextIdxEquiv ^ n) i = ⟨(i.1 + n) % C.len, Nat.mod_lt _ C.len_pos⟩ := by
  induction n with
  | zero =>
      apply Fin.ext
      simp [Nat.mod_eq_of_lt i.isLt]
  | succ n ih =>
      apply Fin.ext
      rw [pow_succ', Equiv.Perm.mul_apply, ih, nextIdxEquiv_apply, nextIdx_val,
        Nat.mod_add_mod]
      congr 1

lemma sameCycle_nextIdxEquiv (C : SimplePrimalCycle M) (x y : Fin C.len) :
    C.nextIdxEquiv.SameCycle x y := by
  refine ⟨((y.1 + C.len - x.1 : ℕ) : ℤ), ?_⟩
  rw [zpow_natCast, C.nextIdxEquiv_pow_apply]
  apply Fin.ext
  show (x.1 + (y.1 + C.len - x.1)) % C.len = y.1
  have hx := x.isLt
  have hy := y.isLt
  have hxy : x.1 + (y.1 + C.len - x.1) = y.1 + C.len := by omega
  rw [hxy, Nat.add_mod_right, Nat.mod_eq_of_lt hy]

lemma numCycles_nextIdxEquiv (C : SimplePrimalCycle M) :
    _root_.numCycles C.nextIdxEquiv = 1 := by
  haveI : Nonempty (Fin C.len) := ⟨⟨0, C.len_pos⟩⟩
  exact CutCapCount.numCycles_eq_one_of_forall_sameCycle _ C.sameCycle_nextIdxEquiv

lemma numCycles_nextIdxEquiv_inv (C : SimplePrimalCycle M) :
    _root_.numCycles (C.nextIdxEquiv⁻¹) = 1 := by
  haveI : Nonempty (Fin C.len) := ⟨⟨0, C.len_pos⟩⟩
  exact CutCapCount.numCycles_eq_one_of_forall_sameCycle _
    (fun x y => (Equiv.Perm.sameCycle_inv).mpr (C.sameCycle_nextIdxEquiv x y))



/-- A dart equal to no bank-start (`p`/`q`) dart is not a cycle dart. -/
lemma notMem_dartSet_of_ne_bankStarts (C : SimplePrimalCycle M) {x : D}
    (hp : ∀ i, x ≠ C.pDart i) (hq : ∀ i, x ≠ C.qDart i) : x ∉ C.dartSet := by
  intro hmem
  rw [C.mem_dartSet_iff] at hmem
  obtain ⟨i, hi | hi⟩ := hmem
  · exact hq i (by rw [qDart_def]; exact hi)
  · refine hp (C.nextIdx i) ?_
    rw [pDart_def, C.prevIdx_nextIdx]
    exact hi

open Classical in
/-- Forward map of the seam swap. -/
noncomputable def seamSwapFun (C : SimplePrimalCycle M) : C.CutDart → C.CutDart :=
  fun x => match x with
  | Sum.inl d =>
      match C.cycleKind d with
      | Sum.inl (Sum.inl i) => Sum.inr (Sum.inl i)   -- dart i ↦ c_i⁺
      | Sum.inl (Sum.inr i) => Sum.inr (Sum.inr i)   -- α (dart i) ↦ c_i⁻
      | Sum.inr () => Sum.inl d                      -- ordinary: fixed
  | Sum.inr (Sum.inl i) => Sum.inl (M.α (C.dart i))  -- c_i⁺ ↦ α (dart i)
  | Sum.inr (Sum.inr i) => Sum.inl (C.dart i)        -- c_i⁻ ↦ dart i

open Classical in
/-- Inverse map of the seam swap. -/
noncomputable def seamSwapInvFun (C : SimplePrimalCycle M) : C.CutDart → C.CutDart :=
  fun x => match x with
  | Sum.inl d =>
      match C.cycleKind d with
      | Sum.inl (Sum.inl i) => Sum.inr (Sum.inr i)   -- dart i ↦ c_i⁻
      | Sum.inl (Sum.inr i) => Sum.inr (Sum.inl i)   -- α (dart i) ↦ c_i⁺
      | Sum.inr () => Sum.inl d
  | Sum.inr (Sum.inl i) => Sum.inl (C.dart i)        -- c_i⁺ ↦ dart i
  | Sum.inr (Sum.inr i) => Sum.inl (M.α (C.dart i))  -- c_i⁻ ↦ α (dart i)

lemma seamSwapFun_dart (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.seamSwapFun (Sum.inl (C.dart i)) = Sum.inr (Sum.inl i) := by
  show (match C.cycleKind (C.dart i) with
    | Sum.inl (Sum.inl j) => Sum.inr (Sum.inl j)
    | Sum.inl (Sum.inr j) => Sum.inr (Sum.inr j)
    | Sum.inr () => Sum.inl (C.dart i)) = _
  rw [C.cycleKind_dart]

lemma seamSwapFun_alpha_dart (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.seamSwapFun (Sum.inl (M.α (C.dart i))) = Sum.inr (Sum.inr i) := by
  show (match C.cycleKind (M.α (C.dart i)) with
    | Sum.inl (Sum.inl j) => Sum.inr (Sum.inl j)
    | Sum.inl (Sum.inr j) => Sum.inr (Sum.inr j)
    | Sum.inr () => Sum.inl (M.α (C.dart i))) = _
  rw [C.cycleKind_alpha_dart]

lemma seamSwapFun_other (C : SimplePrimalCycle M) {d : D} (h : d ∉ C.dartSet) :
    C.seamSwapFun (Sum.inl d) = Sum.inl d := by
  show (match C.cycleKind d with
    | Sum.inl (Sum.inl j) => Sum.inr (Sum.inl j)
    | Sum.inl (Sum.inr j) => Sum.inr (Sum.inr j)
    | Sum.inr () => Sum.inl d) = _
  rw [C.cycleKind_other h]

@[simp] lemma seamSwapFun_capP (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.seamSwapFun (Sum.inr (Sum.inl i)) = Sum.inl (M.α (C.dart i)) := rfl

@[simp] lemma seamSwapFun_capM (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.seamSwapFun (Sum.inr (Sum.inr i)) = Sum.inl (C.dart i) := rfl

lemma seamSwapInvFun_dart (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.seamSwapInvFun (Sum.inl (C.dart i)) = Sum.inr (Sum.inr i) := by
  show (match C.cycleKind (C.dart i) with
    | Sum.inl (Sum.inl j) => Sum.inr (Sum.inr j)
    | Sum.inl (Sum.inr j) => Sum.inr (Sum.inl j)
    | Sum.inr () => Sum.inl (C.dart i)) = _
  rw [C.cycleKind_dart]

lemma seamSwapInvFun_alpha_dart (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.seamSwapInvFun (Sum.inl (M.α (C.dart i))) = Sum.inr (Sum.inl i) := by
  show (match C.cycleKind (M.α (C.dart i)) with
    | Sum.inl (Sum.inl j) => Sum.inr (Sum.inr j)
    | Sum.inl (Sum.inr j) => Sum.inr (Sum.inl j)
    | Sum.inr () => Sum.inl (M.α (C.dart i))) = _
  rw [C.cycleKind_alpha_dart]

lemma seamSwapInvFun_other (C : SimplePrimalCycle M) {d : D} (h : d ∉ C.dartSet) :
    C.seamSwapInvFun (Sum.inl d) = Sum.inl d := by
  show (match C.cycleKind d with
    | Sum.inl (Sum.inl j) => Sum.inr (Sum.inr j)
    | Sum.inl (Sum.inr j) => Sum.inr (Sum.inl j)
    | Sum.inr () => Sum.inl d) = _
  rw [C.cycleKind_other h]

@[simp] lemma seamSwapInvFun_capP (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.seamSwapInvFun (Sum.inr (Sum.inl i)) = Sum.inl (C.dart i) := rfl

@[simp] lemma seamSwapInvFun_capM (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.seamSwapInvFun (Sum.inr (Sum.inr i)) = Sum.inl (M.α (C.dart i)) := rfl

lemma seamSwap_leftInverse (C : SimplePrimalCycle M) :
    Function.LeftInverse C.seamSwapInvFun C.seamSwapFun := by
  intro x
  rcases x with d | (i | i)
  · rcases hk : C.cycleKind d with (i | i) | u
    · have hd : d = C.dart i := C.cycleKind_eq_inl_inl hk
      subst hd
      rw [C.seamSwapFun_dart, C.seamSwapInvFun_capP]
    · have hd : d = M.α (C.dart i) := C.cycleKind_eq_inl_inr hk
      subst hd
      rw [C.seamSwapFun_alpha_dart, C.seamSwapInvFun_capM]
    · have hd : d ∉ C.dartSet := C.cycleKind_eq_inr hk
      rw [C.seamSwapFun_other hd, C.seamSwapInvFun_other hd]
  · rw [C.seamSwapFun_capP, C.seamSwapInvFun_alpha_dart]
  · rw [C.seamSwapFun_capM, C.seamSwapInvFun_dart]

lemma seamSwap_rightInverse (C : SimplePrimalCycle M) :
    Function.RightInverse C.seamSwapInvFun C.seamSwapFun := by
  intro x
  rcases x with d | (i | i)
  · rcases hk : C.cycleKind d with (i | i) | u
    · have hd : d = C.dart i := C.cycleKind_eq_inl_inl hk
      subst hd
      rw [C.seamSwapInvFun_dart, C.seamSwapFun_capM]
    · have hd : d = M.α (C.dart i) := C.cycleKind_eq_inl_inr hk
      subst hd
      rw [C.seamSwapInvFun_alpha_dart, C.seamSwapFun_capP]
    · have hd : d ∉ C.dartSet := C.cycleKind_eq_inr hk
      rw [C.seamSwapInvFun_other hd, C.seamSwapFun_other hd]
  · rw [C.seamSwapInvFun_capP, C.seamSwapFun_dart]
  · rw [C.seamSwapInvFun_capM, C.seamSwapFun_alpha_dart]

/-- The seam swap as a permutation of the cut-dart set. -/
noncomputable def seamSwap (C : SimplePrimalCycle M) : Equiv.Perm C.CutDart where
  toFun := C.seamSwapFun
  invFun := C.seamSwapInvFun
  left_inv := C.seamSwap_leftInverse
  right_inv := C.seamSwap_rightInverse

@[simp] lemma seamSwap_apply (C : SimplePrimalCycle M) (x : C.CutDart) :
    C.seamSwap x = C.seamSwapFun x := rfl





/-- The conjugacy model of `φ'₂`: the old face permutation on ordinary darts, with the
two cap slots rotating as the two new seam faces (`+` forward, `−` backward). -/
noncomputable def seamModel (C : SimplePrimalCycle M) : Equiv.Perm C.CutDart :=
  Equiv.Perm.sumCongr M.φ (Equiv.Perm.sumCongr C.nextIdxEquiv C.nextIdxEquiv⁻¹)

@[simp] lemma seamModel_inl (C : SimplePrimalCycle M) (d : D) :
    C.seamModel (Sum.inl d) = Sum.inl (M.φ d) := by
  simp [seamModel]

@[simp] lemma seamModel_capP (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.seamModel (Sum.inr (Sum.inl i)) = Sum.inr (Sum.inl (C.nextIdx i)) := by
  simp [seamModel]

@[simp] lemma seamModel_capM (C : SimplePrimalCycle M) (i : Fin C.len) :
    C.seamModel (Sum.inr (Sum.inr i)) = Sum.inr (Sum.inr (C.prevIdx i)) := by
  simp [seamModel]



/-- **The transport identity.**  For *every* dart `d : D`, the seam swap carries
`σ'₂ (inl d)` to `inl (σ d)`: clean steps are untouched, and the two cap diverts
(`σ d = p_j` ⟹ `σ'₂ (inl d) = c_{prevIdx j}⁺ ↦ inl (α (dart (prevIdx j))) = inl (p_j)`;
`σ d = q_j` ⟹ `σ'₂ (inl d) = c_j⁻ ↦ inl (dart j) = inl (q_j)`) land exactly on the
bank-start the cap stands in for. -/
lemma seamSwapFun_cutSigma2_inl (C : SimplePrimalCycle M) (e : D) :
    C.seamSwapFun (C.cutSigma2 (Sum.inl e)) = Sum.inl (M.σ e) := by
  rcases hd : C.divertKind e with (j | j) | u
  · have hσ : M.σ e = C.pDart j := C.divertKind_eq_plus hd
    rw [C.cutSigma2_inl_plus hd, C.seamSwapFun_capP, hσ, pDart_def]
  · have hσ : M.σ e = C.qDart j := C.divertKind_eq_minus hd
    rw [C.cutSigma2_inl_minus hd, C.seamSwapFun_capM, hσ, qDart_def]
  · obtain ⟨hp, hq⟩ := C.divertKind_eq_none hd
    rw [C.cutSigma2_inl_none hd,
      C.seamSwapFun_other (C.notMem_dartSet_of_ne_bankStarts hp hq)]

/-- **Pointwise intertwining**: `e ∘ φ'₂ = seamModel ∘ e` on every cut dart. -/
lemma seamSwapFun_phi2 (C : SimplePrimalCycle M) (x : C.CutDart) :
    C.seamSwapFun ((C.cutCapMap2).φ x) = C.seamModel (C.seamSwapFun x) := by
  rcases x with d | (i | i)
  · rcases hk : C.cycleKind d with (i | i) | u
    · -- seam dart `dart i`: φ'₂ threads it forward; the model rotates its `+`-slot
      have hd : d = C.dart i := C.cycleKind_eq_inl_inl hk
      subst hd
      rw [cutCapPhi2_dart, C.seamSwapFun_dart, C.seamSwapFun_dart, C.seamModel_capP]
    · -- seam dart `α (dart i)`: φ'₂ threads it backward; the model rotates its `−`-slot
      have hd : d = M.α (C.dart i) := C.cycleKind_eq_inl_inr hk
      subst hd
      rw [cutCapPhi2_alpha_dart, pDart_def, C.seamSwapFun_alpha_dart,
        C.seamSwapFun_alpha_dart, C.seamModel_capM]
    · -- ordinary dart: φ'₂ = (transported) φ
      have hd : d ∉ C.dartSet := C.cycleKind_eq_inr hk
      rw [cutCapPhi2_apply, C.cutAlpha_other hd, C.seamSwapFun_cutSigma2_inl,
        C.seamSwapFun_other hd, C.seamModel_inl, CombMap.φ, Equiv.Perm.mul_apply]
  · -- `c_i⁺` stands in for `α (dart i)`: `φ'₂ (c_i⁺) = σ'₂ (inl (dart i))` transports
    -- to `inl (σ (dart i)) = inl (φ (α (dart i)))`
    rw [cutCapPhi2_apply, cutAlpha_capPlus, C.seamSwapFun_cutSigma2_inl,
      C.seamSwapFun_capP, C.seamModel_inl, CombMap.φ, Equiv.Perm.mul_apply,
      M.alpha_alpha]
  · -- `c_i⁻` stands in for `dart i`: `φ'₂ (c_i⁻) = σ'₂ (inl (α (dart i)))` transports
    -- to `inl (σ (α (dart i))) = inl (φ (dart i))`
    rw [cutCapPhi2_apply, cutAlpha_capMinus, C.seamSwapFun_cutSigma2_inl,
      C.seamSwapFun_capM, C.seamModel_inl, CombMap.φ, Equiv.Perm.mul_apply]

/-- The intertwining as a product identity. -/
theorem seamSwap_mul_phi2 (C : SimplePrimalCycle M) :
    C.seamSwap * (C.cutCapMap2).φ = C.seamModel * C.seamSwap := by
  ext x
  rw [Equiv.Perm.mul_apply, Equiv.Perm.mul_apply]
  simp only [seamSwap_apply]
  exact C.seamSwapFun_phi2 x

/-- **The seam conjugacy**: `e · φ'₂ · e⁻¹ = φ ⊕ (nextIdx ⊕ prevIdx)`. -/
theorem seamSwap_phi2_conj (C : SimplePrimalCycle M) :
    C.seamSwap * (C.cutCapMap2).φ * C.seamSwap⁻¹ = C.seamModel := by
  rw [seamSwap_mul_phi2, mul_assoc, mul_inv_cancel, mul_one]



/-- The model has `F + 2` cycles: `F` old faces plus the two seam rotations. -/
theorem numCycles_seamModel (C : SimplePrimalCycle M) :
    _root_.numCycles C.seamModel = M.F + 2 := by
  rw [seamModel, CutCapCount.numCycles_sumCongr, CutCapCount.numCycles_sumCongr,
    C.numCycles_nextIdxEquiv, C.numCycles_nextIdxEquiv_inv, ← M.F_eq_numCycles]

/-- **The corrected face-cycle count, closed unconditionally and genus-free:**
`numCycles φ'₂ = M.F + 2`.  By conjugation invariance through the seam conjugacy. -/
theorem numCycles_cutCapPhi2 (C : SimplePrimalCycle M) :
    _root_.numCycles ((C.cutCapMap2).φ) = M.F + 2 := by
  have h := CutCapCount.numCycles_conj C.seamSwap ((C.cutCapMap2).φ)
  rw [C.seamSwap_phi2_conj] at h
  rw [← h]
  exact C.numCycles_seamModel

/-- **The previously named open core of the corrected Chapter 35 face count, now a
theorem**: every simple primal cycle satisfies `NumCyclesCutPhi2`. -/
theorem numCyclesCutPhi2_holds (C : SimplePrimalCycle M) : C.NumCyclesCutPhi2 := by
  show _root_.numCycles ((C.cutCapMap2).φ) = M.F + 2
  exact C.numCycles_cutCapPhi2



/-- The factored form consumed by the telescope. -/
theorem numCycles_phiLift_mul_faceCorr2 (C : SimplePrimalCycle M) :
    _root_.numCycles (C.phiLift * C.faceCorr2) = M.F + 2 := by
  rw [← C.cutCapPhi2_eq_phiLift_mul]
  exact C.numCycles_cutCapPhi2



/-- **The exact split-count identity**: for every cycle-list certificate,
`concatLen Ls + 2 = 2 · #(actual splits) + 2 · len` — the hsplits bound holds with
slack `0`, for every cut, every genus. -/
theorem concatLen_add_two_eq_splits (C : SimplePrimalCycle M)
    {Ls : List (List C.CutDart)} (H : C.FaceCorrCycleLists Ls) :
    FaceCorrWord.concatLen Ls + 2
      = 2 * (C.actualSplitFinset Ls).card + 2 * C.len := by
  classical
  let W : Fin (FaceCorrWord.concatLen Ls) → ForcedSplits.Swap C.CutDart :=
    FaceCorrWord.concatWord Ls
  have hpos0 : ∀ L ∈ Ls, 0 < L.length := by
    intro L hL
    have := H.pos L hL
    omega
  have hprefix :
      ForcedSplits.prefixPerm C.phiLift W (FaceCorrWord.concatLen Ls)
        = C.phiLift * C.faceCorr2 := by
    dsimp [W]
    rw [FaceCorrWord.prefixPerm_concatWord C.phiLift Ls hpos0, H.factor]
  have htel := ForcedSplits.numCycles_prefix_telescopes C.phiLift W
  have hsum := ForcedSplits.sum_stepDelta_eq_neg_m_add_two_actualSplits
    C.phiLift W (fun j => C.concatWord_ne_of_nodup H j)
  have hdiff :
      (numCycles (ForcedSplits.prefixPerm C.phiLift W (FaceCorrWord.concatLen Ls)) : ℤ)
        - (numCycles C.phiLift : ℤ)
        =
      -(FaceCorrWord.concatLen Ls : ℤ)
        + 2 * ((C.actualSplitFinset Ls).card : ℤ) := by
    rw [SimplePrimalCycle.actualSplitFinset, htel, hsum]
  rw [hprefix] at hdiff
  rw [C.numCycles_phiLift_mul_faceCorr2, C.numCycles_phiLift] at hdiff
  push_cast at hdiff
  omega

/-- **The hsplits bound** (the exact statement consumed by
`numCycles_phiLift_faceCorr2_lower_of_splitsEnough`), unconditional. -/
theorem splitsEnough (C : SimplePrimalCycle M)
    {Ls : List (List C.CutDart)} (H : C.FaceCorrCycleLists Ls) :
    FaceCorrWord.concatLen Ls + 2
      ≤ 2 * (C.actualSplitFinset Ls).card + 2 * C.len :=
  le_of_eq (C.concatLen_add_two_eq_splits H)

/-- The `∀`-form consumed by the `_all` count-route plumbing. -/
theorem splitsEnough_all (C : SimplePrimalCycle M) :
    ∀ Ls : List (List C.CutDart), C.FaceCorrCycleLists Ls →
      FaceCorrWord.concatLen Ls + 2
        ≤ 2 * (C.actualSplitFinset Ls).card + 2 * C.len :=
  fun _ H => C.splitsEnough H





/-- **Every simple primal cycle carries a split certificate** — the
`FaceCorrSplitCert` residue of `FaceCorrWord.lean`, discharged. -/
noncomputable def faceCorrSplitCertUnconditional (C : SimplePrimalCycle M) :
    C.FaceCorrSplitCert :=
  C.faceCorrSplitCert_of_splitsEnough C.splitsEnough_all

/-- The lower-bound Jordan theorem, now conditional only on the Euler hypothesis and
the connectivity gates (the split certificate is supplied unconditionally). -/
theorem jordan_simple_cycle2_of_gates (C : SimplePrimalCycle M)
    (hchi : M.eulerChar = 2)
    (hconn : ∀ i : Fin C.len,
      DualReachableAvoidingCycle M C (C.faceLeft i) (C.faceRight i) →
        (C.cutCapMap2).Connected)
    (i : Fin C.len) :
    ¬ DualReachableAvoidingCycle M C (C.faceLeft i) (C.faceRight i) :=
  C.jordan_simple_cycle2_lower_of_splitCert C.faceCorrSplitCertUnconditional
    hchi hconn i

end SimplePrimalCycle

end CombMap

namespace CombMap.NearTriangulation

variable {D : Type*} [Fintype D] [DecidableEq D]
variable {M : CombMap D} (hNT : NearTriangulation M)

open SimplePrimalCycle



/-- `Separates` from the corrected gate data alone. -/
theorem separates_of_gates {u v : M.Vertex}
    (data : hNT.ChordSplitData u v)
    (C : CombMap.SimplePrimalCycle M)
    (hsub : ∀ e ∈ C.edgeSet, e = s(u, v) ∨ hNT.outerCycle.IsBoundaryEdge e)
    (hgate : ∀ i : Fin C.len,
      DualReachableAvoidingCycle M C (C.faceLeft i) (C.faceRight i) →
        ∃ P : C.OrdinaryDualPath2, C.EndpointCapLink i P ∧ C.InteriorTriangleGates P)
    (i₀ : Fin C.len)
    (hleft : C.faceLeft i₀ = M.dartFace (hNT.chordDart data.chord))
    (hright : C.faceRight i₀ = M.dartFace (M.α (hNT.chordDart data.chord))) :
    data.Separates :=
  hNT.separates_of_inputLower' data C hsub
    ⟨C.faceCorrSplitCertUnconditional, hgate⟩ i₀ hleft hright

end CombMap.NearTriangulation

end ProofsInTheBook.PlanarMap




















end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35Split
-/
/- Source module: ProofsInTheBook.ZinanCh35Gates -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

open Equiv Equiv.Perm Function

namespace ProofsInTheBook.PlanarMap

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace SimplePrimalCycle

open CutCapCount

variable {M : CombMap D}



/-- `φ'₂` as an explicit conjugate of the seam model (the inverted form of
`seamSwap_phi2_conj`, shaped for `conj_pow`). -/
lemma cutCapPhi2_eq_conj (C : SimplePrimalCycle M) :
    (C.cutCapMap2).φ = C.seamSwap⁻¹ * C.seamModel * C.seamSwap⁻¹⁻¹ := by
  rw [inv_inv, ← C.seamSwap_phi2_conj]
  group

/-- **`SameCycle` transport through the seam conjugacy**: a `seamModel`-orbit relation
between the `e`-images is a `φ'₂`-orbit relation. -/
lemma cutCapPhi2_sameCycle_of_seamModel (C : SimplePrimalCycle M) {x y : C.CutDart}
    (h : C.seamModel.SameCycle (C.seamSwap x) (C.seamSwap y)) :
    ((C.cutCapMap2).φ).SameCycle x y := by
  obtain ⟨m, hm⟩ := h.exists_nat_pow_eq
  refine ⟨(m : ℤ), ?_⟩
  rw [zpow_natCast, C.cutCapPhi2_eq_conj, conj_pow, inv_inv,
    Equiv.Perm.mul_apply, Equiv.Perm.mul_apply, hm]
  exact inv_eq_iff_eq.mpr rfl

/-- `seamModel` restricted to the `inl` (ordinary-dart) summand is the old face
permutation `φ`. -/
lemma seamModel_sameCycle_inl_iff (C : SimplePrimalCycle M) (d₁ d₂ : D) :
    C.seamModel.SameCycle (Sum.inl d₁) (Sum.inl d₂) ↔ M.φ.SameCycle d₁ d₂ := by
  unfold seamModel
  exact CutCapCount.sameCycle_sumCongr_inl_inl _ _ _ _



/-- **Same old face ⇒ same φ'₂-cycle of the seam carriers ⇒ `cutReach2`.**  This is the
within-face connectivity that the corrected surgery *does* provide at the global
reachability layer (the `SameFragment`-layer version is false; this one is a theorem). -/
lemma cutReach2_seamCarrier_of_dartFace_eq (C : SimplePrimalCycle M) {d₁ d₂ : D}
    (h : M.dartFace d₁ = M.dartFace d₂) :
    C.cutReach2 (C.seamSwapInvFun (Sum.inl d₁)) (C.seamSwapInvFun (Sum.inl d₂)) := by
  apply C.cutReach2_of_phi_sameCycle
  apply C.cutCapPhi2_sameCycle_of_seamModel
  rw [seamSwap_apply, seamSwap_apply,
    C.seamSwap_rightInverse (Sum.inl d₁), C.seamSwap_rightInverse (Sum.inl d₂)]
  exact (C.seamModel_sameCycle_inl_iff d₁ d₂).mpr (sameCycle_phi_of_dartFace_eq h)





/-- **Carrier reach along a bare cycle-avoiding dual path.**  If `f` and `g` are
dual-reachable avoiding the cycle edges, then the seam carriers of *any* dart of `f`
and *any* dart of `g` are `cutReach2`-connected. -/
lemma cutReach2_seamCarrier_of_dualReachable (C : SimplePrimalCycle M) {f g : M.Face}
    (hpath : DualReachableAvoidingCycle M C f g) :
    ∀ {d₁ d₂ : D}, M.dartFace d₁ = f → M.dartFace d₂ = g →
      C.cutReach2 (C.seamSwapInvFun (Sum.inl d₁)) (C.seamSwapInvFun (Sum.inl d₂)) := by
  have hpath' : Relation.ReflTransGen (DualAvoidsCycleStep M C) f g := hpath
  clear hpath
  induction hpath' with
  | refl =>
      intro d₁ d₂ h₁ h₂
      exact C.cutReach2_seamCarrier_of_dartFace_eq (h₁.trans h₂.symm)
  | tail hstep hcross ih =>
      intro d₁ d₂ h₁ h₂
      obtain ⟨c, hcut, hcf, hcg⟩ := hcross
      have hc : c ∉ C.dartSet := C.notMem_dartSet_of_dartEdge_notMem hcut
      have hαc : M.α c ∉ C.dartSet := C.alpha_notMem_dartSet hc
      -- carrier d₁ ⇝ carrier c (induction hypothesis up to the previous face)
      have h1 := ih h₁ hcf
      -- inl c ⇝ inl (α c): one α'-step across the uncut crossing edge
      have h2 : C.cutReach2 (Sum.inl c) (Sum.inl (M.α c)) :=
        C.cutReach2_across_uncut_dual_gate hcut
      -- carrier (α c) ⇝ carrier d₂ (same final face)
      have h3 := C.cutReach2_seamCarrier_of_dartFace_eq (d₁ := M.α c) (d₂ := d₂)
        (hcg.trans h₂.symm)
      rw [C.seamSwapInvFun_other hc] at h1
      rw [C.seamSwapInvFun_other hαc] at h3
      exact C.cutReach2_trans (C.cutReach2_trans h1 h2) h3



/-- **The cross-bank bridge from bare dual reachability** — the genuine connectivity
content of the Chapter 35 gates, with no triangle or fragment input.  (It is *not*
provable without `hpath`: on the sphere the cut map has two components.) -/
theorem crossBankBridge_of_dualReachable (C : SimplePrimalCycle M) (i : Fin C.len)
    (hpath : DualReachableAvoidingCycle M C (C.faceLeft i) (C.faceRight i)) :
    C.cutReach2 (Sum.inl (C.dart i)) (Sum.inl (M.α (C.dart i))) := by
  -- carrier (dart i) = c_i⁻ ⇝ carrier (α (dart i)) = c_i⁺
  have hmid := C.cutReach2_seamCarrier_of_dualReachable hpath
    (d₁ := C.dart i) (d₂ := M.α (C.dart i)) rfl rfl
  rw [C.seamSwapInvFun_dart, C.seamSwapInvFun_alpha_dart] at hmid
  -- inl (dart i) ⇝ c_i⁺ (one α'-step)
  have h1 : C.cutReach2 (Sum.inl (C.dart i)) (Sum.inr (Sum.inl i)) := by
    have := C.cutReach2_of_alpha (Sum.inl (C.dart i))
    rwa [cutCapMap2_alpha_apply, C.cutAlpha_dart] at this
  -- c_i⁻ ⇝ inl (α (dart i)) (one α'-step, reversed)
  have h3 : C.cutReach2 (Sum.inr (Sum.inr i)) (Sum.inl (M.α (C.dart i))) := by
    have := C.cutReach2_of_alpha (Sum.inl (M.α (C.dart i)))
    rw [cutCapMap2_alpha_apply, C.cutAlpha_alpha_dart] at this
    exact C.cutReach2_symm this
  exact C.cutReach2_trans (C.cutReach2_trans h1 (C.cutReach2_symm hmid)) h3



/-- **`EndpointCapLink`, supplied** from bare dual reachability (on the nil path). -/
theorem endpointCapLink_of_dualReachable (C : SimplePrimalCycle M) (i : Fin C.len)
    (hpath : DualReachableAvoidingCycle M C (C.faceLeft i) (C.faceRight i)) :
    C.EndpointCapLink i (OrdinaryDualPath2.nil C (C.faceLeft i)) :=
  C.endpointCapLink_nil i (C.faceLeft i) (C.crossBankBridge_of_dualReachable i hpath)

/-- **The connectivity gate `gateCompat'`, closed**: for every cycle edge, bare dual
reachability of its two sides yields an ordinary dual path carrying both
`EndpointCapLink` and `InteriorTriangleGates`. -/
theorem gateCompat'_of_dualReachable (C : SimplePrimalCycle M) (i : Fin C.len)
    (hpath : DualReachableAvoidingCycle M C (C.faceLeft i) (C.faceRight i)) :
    ∃ P : C.OrdinaryDualPath2, C.EndpointCapLink i P ∧ C.InteriorTriangleGates P :=
  ⟨OrdinaryDualPath2.nil C (C.faceLeft i),
    C.endpointCapLink_of_dualReachable i hpath,
    C.interiorTriangleGates_nil (C.faceLeft i)⟩

/-- **`ChordJordanInput'` is a theorem** for every simple primal cycle on every
combinatorial map: the face core is `numCyclesCutPhi2_holds`
(`ZinanCh35Split.lean`), the gate supplier is `gateCompat'_of_dualReachable`. -/
theorem chordJordanInput'_holds (C : SimplePrimalCycle M) : C.ChordJordanInput' :=
  ⟨C.numCyclesCutPhi2_holds, fun i hpath => C.gateCompat'_of_dualReachable i hpath⟩



/-- **The discrete Jordan separation for the corrected surgery, with all gates
discharged**: on a connected map of Euler characteristic `2`, the two sides of every
edge of a simple primal cycle are *not* dual-connected avoiding the cycle.
Conditional only on `M.Connected` and `M.eulerChar = 2`. -/
theorem jordan_simple_cycle2_unconditional (C : SimplePrimalCycle M)
    (hchi : M.eulerChar = 2) (hconn : M.Connected) (i : Fin C.len) :
    ¬ DualReachableAvoidingCycle M C (C.faceLeft i) (C.faceRight i) :=
  C.jordan_simple_cycle2_of_gates hchi
    (fun j hp => C.connectivity_of_input' hconn C.chordJordanInput'_holds j hp) i



end SimplePrimalCycle

end CombMap

namespace CombMap.NearTriangulation

variable {D : Type*} [Fintype D] [DecidableEq D]
variable {M : CombMap D} (hNT : NearTriangulation M)

open SimplePrimalCycle



/-- **`Separates` with the connectivity gates discharged.** -/
theorem separates_closed {u v : M.Vertex}
    (data : hNT.ChordSplitData u v)
    (C : CombMap.SimplePrimalCycle M)
    (hsub : ∀ e ∈ C.edgeSet, e = s(u, v) ∨ hNT.outerCycle.IsBoundaryEdge e)
    (i₀ : Fin C.len)
    (hleft : C.faceLeft i₀ = M.dartFace (hNT.chordDart data.chord))
    (hright : C.faceRight i₀ = M.dartFace (M.α (hNT.chordDart data.chord))) :
    data.Separates :=
  hNT.separates_of_gates data C hsub
    (fun i hp => C.gateCompat'_of_dualReachable i hp) i₀ hleft hright

end CombMap.NearTriangulation



namespace ProofsInTheBook.PlanarMap.CombMap.SimplePrimalCycle

variable {D : Type*} [Fintype D] [DecidableEq D] {M : CombMap D}



end ProofsInTheBook.PlanarMap.CombMap.SimplePrimalCycle

















end ProofsInTheBook.PlanarMap
end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35Iota
import ProofsInTheBook.ZinanCh35Gates
-/
/- Source module: ProofsInTheBook.ZinanCh35Confinement -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35Confinement

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ChordSideNT
open ProofsInTheBook.ChordSplitFinal
open ProofsInTheBook.ZinanCh35Iota
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex} {α : Type u} [DecidableEq α]







/-- **`homit` ⟺ a vertex outside the side-1 region.**  Via `sideVertexToM₁_range`
(`Set.range ι = sideRegion₁`), the abstract omitted-vertex witness is equivalent to the concrete
region-omission residue `∃ w : M.Vertex, w ∉ sideRegion₁ data`. -/
theorem homit_iff_exists_notMem_sideRegion₁ (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₁}) (hne : a₀ ≠ a₁) :
    (∃ w : M.Vertex, w ∉ Set.range (sideVertexToM₁ data hsep a₀ a₁ hne))
      ↔ (∃ w : M.Vertex, w ∉ sideRegion₁ data) := by
  rw [sideVertexToM₁_range data hsep a₀ a₁ hne]















end ProofsInTheBook.ZinanCh35Confinement









end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35StarRotation
import ProofsInTheBook.ZinanCh35Confinement
-/
/- Source module: ProofsInTheBook.ZinanCh35Schoenflies -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35Schoenflies

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ChordSideNT
open ProofsInTheBook.ChordSplitFinal
open ProofsInTheBook.ZinanCh35Iota
open ProofsInTheBook.ZinanCh35Confinement
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex} {α : Type u} [DecidableEq α]



/-- **Side-region membership, unfolded.**  `w ∈ sideRegion₁` exactly when `w` has an incident
dart (tail `w`) distinct from the chord dart that is *kept* by side 1: either its own face is in
`side₁` (an inner side-1 dart), or it is an outer dart whose reverse face is in `side₁` (a
boundary dart of the side-1 arc). -/
theorem mem_sideRegion₁_iff (data : hNT.ChordSplitData u v) (w : M.Vertex) :
    w ∈ sideRegion₁ data ↔
      ∃ d : D, M.tail d = w ∧ d ≠ data.dart ∧
        (M.dartFace d ∈ data.side₁ ∨
          (M.dartFace d = hNT.outerFace ∧ M.dartFace (M.α d) ∈ data.side₁)) := by
  constructor
  · rintro ⟨d, hd, htail⟩
    rw [data.mem_keptDel₁_iff] at hd
    obtain ⟨hU, hne⟩ := hd
    simp only [Set.mem_singleton_iff] at hne
    refine ⟨d, htail, hne, ?_⟩
    rcases hU with hin | hout
    · exact Or.inl hin
    · exact Or.inr ⟨hout.1, hout.2⟩
  · rintro ⟨d, htail, hne, hkept⟩
    refine ⟨d, ?_, htail⟩
    rw [data.mem_keptDel₁_iff]
    refine ⟨?_, by simp only [Set.mem_singleton_iff]; exact hne⟩
    rcases hkept with hin | hout
    · exact Or.inl hin
    · exact Or.inr hout

/-- **Side-region OMISSION, unfolded** (the form `homit` needs).  A vertex `w` is *outside* the
side-1 region exactly when *every* dart tailed at `w` is deleted by side 1: it is the chord dart,
or its face is not in `side₁` and it is not a side-1 boundary dart.  This is the vertex-star
confinement statement. -/
theorem notMem_sideRegion₁_iff (data : hNT.ChordSplitData u v) (w : M.Vertex) :
    w ∉ sideRegion₁ data ↔
      ∀ d : D, M.tail d = w →
        (d = data.dart ∨
          (M.dartFace d ∉ data.side₁ ∧
            ¬ (M.dartFace d = hNT.outerFace ∧ M.dartFace (M.α d) ∈ data.side₁))) := by
  rw [mem_sideRegion₁_iff]
  constructor
  · intro hnot d htail
    -- If `d` were a kept side-1 dart, `w` would be in the region.
    by_cases hne : d = data.dart
    · exact Or.inl hne
    · right
      refine ⟨?_, ?_⟩
      · intro hin
        exact hnot ⟨d, htail, hne, Or.inl hin⟩
      · intro hout
        exact hnot ⟨d, htail, hne, Or.inr hout⟩
  · rintro hall ⟨d, htail, hne, hkept⟩
    rcases hall d htail with hchord | ⟨hface, houter⟩
    · exact hne hchord
    · rcases hkept with hin | hout
      · exact hface hin
      · exact houter hout

/-- **Star witness ⟹ region membership (inner case).**  If `w` has a star dart `d` (tail `w`)
distinct from the chord dart whose face is in `side₁`, then `w ∈ sideRegion₁`. -/
theorem mem_sideRegion₁_of_star_side₁ (data : hNT.ChordSplitData u v) {w : M.Vertex}
    {d : D} (htail : M.tail d = w) (hne : d ≠ data.dart) (hface : M.dartFace d ∈ data.side₁) :
    w ∈ sideRegion₁ data :=
  (mem_sideRegion₁_iff data w).2 ⟨d, htail, hne, Or.inl hface⟩

/-- **Star witness ⟹ region membership (boundary case).**  If `w` has a star dart `d` (tail `w`)
distinct from the chord dart that is an outer dart whose reverse face is in `side₁`, then
`w ∈ sideRegion₁`. -/
theorem mem_sideRegion₁_of_star_outerArc₁ (data : hNT.ChordSplitData u v) {w : M.Vertex}
    {d : D} (htail : M.tail d = w) (hne : d ≠ data.dart)
    (houter : M.dartFace d = hNT.outerFace) (hrev : M.dartFace (M.α d) ∈ data.side₁) :
    w ∈ sideRegion₁ data :=
  (mem_sideRegion₁_iff data w).2 ⟨d, htail, hne, Or.inr ⟨houter, hrev⟩⟩



/-- **The side-1 vertex-star anchoring residual.**  The discrete-Schoenflies confinement fact that
the landed *face*-dual separation does not supply, isolated sharply:

* `edge_core` — *region edge-confinement core*: an ambient non-chord edge `e` whose two endpoints
  are both side-1-region vertices has its own face in `side₁` (so the edge is realised by an inner
  side-1 dart).  This is the geometric content of `Side₁SchoenfliesConfinement.edge_confined` once
  the chord case and the `α`-closure reduction are peeled off.

* `oppArc_star_core` — *opposite-arc star confinement*: every dart `d` tailed at a strictly
  internal vertex `w` of the *opposite* boundary arc `path₂` is deleted by side 1 (it is the chord
  dart, or its face is outside `side₁` and it is not a side-1 boundary dart).  This is precisely
  the vertex-star-confinement form of `opposite_arc_omitted`.

Both fields are inhabited statements about the concrete map; neither is vacuous (the opposite arc
carries an internal vertex by `data.arc₂_internal`, and the region is inhabited by
`sideRegion₁_nonempty`). -/
structure Side₁StarConfinement (data : hNT.ChordSplitData u v) : Prop where
  /-- Region edge-confinement core (geometric heart of `edge_confined`).  The
  `M.dartFace e ≠ hNT.outerFace` hypothesis (the **bounded-dart** restriction) is essential:
  the outward dart of an outer-arc₁ boundary edge has both endpoints in `sideRegion₁` and is
  non-chord, but its face is the outer face (`∉ side₁`).  Such outer darts are kept via
  `outerArc₁`, not via their face being in `side₁`, and are handled separately by the consumer
  (`vertexStar_confined_of_starConfinement`) through the `outerArc₁` route. -/
  edge_core : ∀ {e : D},
    M.dartEdge e ≠ s(u, v) →
    M.dartFace e ≠ hNT.outerFace →
    M.tail e ∈ sideRegion₁ data →
    M.head e ∈ sideRegion₁ data →
      M.dartFace e ∈ data.side₁
  /-- Opposite-arc vertex-star confinement (geometric heart of `opposite_arc_omitted`). -/
  oppArc_star_core : ∀ {w : M.Vertex},
    w ∈ data.arc.path₂.internalVertices →
    ∀ d : D, M.tail d = w →
      (d = data.dart ∨
        (M.dartFace d ∉ data.side₁ ∧
          ¬ (M.dartFace d = hNT.outerFace ∧ M.dartFace (M.α d) ∈ data.side₁)))



/-- **The design's master confinement structure (design §2).**  `edge_confined` and
`opposite_arc_omitted` in the exact shapes the `hreflect`/`homit` producers consume. -/
structure Side₁SchoenfliesConfinement (data : hNT.ChordSplitData u v) : Prop where
  /-- Any ambient edge whose two endpoints are in the side-1 vertex region is either represented
  in the side-1 carve (both `e` and `α e` kept) or is the chord. -/
  edge_confined : ∀ {e : D},
    M.tail e ∈ sideRegion₁ data →
    M.head e ∈ sideRegion₁ data →
      ((e ∉ data.keptDel₁ ∧ M.α e ∉ data.keptDel₁) ∨ M.dartEdge e = s(u, v))
  /-- A strict internal vertex of the opposite boundary arc is omitted by side 1. -/
  opposite_arc_omitted : ∀ {w : M.Vertex},
    w ∈ data.arc.path₂.internalVertices → w ∉ sideRegion₁ data

/-- **The chord dart's edge is `s(u, v)`.**  Bookkeeping for the chord case of `edge_confined`. -/
lemma dart_edge (data : hNT.ChordSplitData u v) : M.dartEdge data.dart = s(u, v) :=
  hNT.chordDart_edge data.chord



/-- **The outer-dart arc residual.**  For a non-chord dart `e` whose face is the outer face and
whose two endpoints are both side-1-region vertices, the reverse face `dartFace (α e)` lies in
`side₁` (so `e ∈ outerArc₁`).  This is the boundary-incidence content of the outer-dart case of
`edge_confined`; everything else in the consumer is combinatorial. -/
def OuterDartArc₁ (data : hNT.ChordSplitData u v) : Prop :=
  ∀ {e : D},
    M.dartEdge e ≠ s(u, v) →
    M.dartFace e = hNT.outerFace →
    M.tail e ∈ sideRegion₁ data →
    M.head e ∈ sideRegion₁ data →
      M.dartFace (M.α e) ∈ data.side₁

/-- **Master confinement from the star residual (Brick 5).**  Produces the design's
`Side₁SchoenfliesConfinement` from `Side₁StarConfinement`, performing the `edge_confined`
`α`-reduction with the landed `Separates`-conditional `α`-closure.  The `edge_confined` derivation
**case-splits** on whether `e` is an outer dart: a bounded dart (`dartFace e ≠ outerFace`) is kept
via the corrected `edge_core`; an outer dart (`dartFace e = outerFace`) is kept via the `outerArc₁`
route, supplied by the boundary-incidence residual `OuterDartArc₁`. -/
theorem vertexStar_confined_of_starConfinement (data : hNT.ChordSplitData u v)
    (hsep : data.Separates) (conf : Side₁StarConfinement data)
    (houter : OuterDartArc₁ data) :
    Side₁SchoenfliesConfinement data where
  edge_confined := by
    intro e htail hhead
    by_cases hchord : M.dartEdge e = s(u, v)
    · exact Or.inr hchord
    · -- non-chord: split on whether `e` is an outer dart.
      left
      -- `e ≠ dart` (else `dartEdge e = dartEdge dart = s(u,v)`).
      have hne : e ≠ data.dart := by
        intro h; exact hchord (by rw [h]; exact dart_edge data)
      -- In both cases we produce `e ∈ keptSet₁`, then close under `α`.
      have hkept : e ∈ data.keptSet₁ := by
        by_cases hof : M.dartFace e = hNT.outerFace
        · -- outer dart: kept via `outerArc₁` (face = outerFace, reverse face ∈ side₁).
          have hrev : M.dartFace (M.α e) ∈ data.side₁ := houter hchord hof htail hhead
          refine ⟨Or.inr ⟨hof, hrev⟩, ?_⟩
          simp only [Set.mem_singleton_iff]; exact hne
        · -- bounded dart: corrected `edge_core` gives `dartFace e ∈ side₁`, hence `∈ sideDarts₁`.
          have hface : M.dartFace e ∈ data.side₁ := conf.edge_core hchord hof htail hhead
          refine ⟨Or.inl hface, ?_⟩
          simp only [Set.mem_singleton_iff]; exact hne
      refine ⟨?_, ?_⟩
      · rw [data.mem_keptDel₁_iff]; exact hkept
      · rw [data.mem_keptDel₁_iff]
        exact (data.mem_keptSet₁_alpha_iff hsep e).2 hkept
  opposite_arc_omitted := by
    intro w hw
    rw [notMem_sideRegion₁_iff]
    exact conf.oppArc_star_core hw











end ProofsInTheBook.ZinanCh35Schoenflies











end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35Schoenflies
-/
/- Source module: ProofsInTheBook.ZinanCh35EdgeCore -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35EdgeCore

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ZinanCh35Schoenflies

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



/-- **The side-2 region.**  The set of `M`-vertices that are the tail of some kept side-2 dart
(`d ∉ keptDel₂`); the `side₂`-analogue of `sideRegion₁`. -/
def sideRegion₂ (data : hNT.ChordSplitData u v) : Set M.Vertex :=
  {w : M.Vertex | ∃ d : D, d ∉ data.keptDel₂ ∧ M.tail d = w}

/-- A kept side-2 dart's tail is in the side-2 region. -/
lemma tail_mem_sideRegion₂ (data : hNT.ChordSplitData u v) {d : D}
    (hd : d ∉ data.keptDel₂) : M.tail d ∈ sideRegion₂ data :=
  ⟨d, hd, rfl⟩



/-- **Bridge 1 — bounded-face coverage.**  Every non-outer face lies in `side₁` or `side₂`.
This is the coverage half of the face partition; disjointness is the proven separation.  Coverage
is the missing cut-component ↔ `ChordSplitAdj`-reachability identification. -/
def BoundedFacePartition (data : hNT.ChordSplitData u v) : Prop :=
  ∀ {f : M.Face}, f ≠ hNT.outerFace → f ∈ data.side₁ ∨ f ∈ data.side₂

/-- **Bridge 2 — vertex-region intersection (vertex-level Schoenflies).**  A vertex lying in both
side regions is a chord endpoint.  The two closed side disks meet only at the chord ends `{u, v}`. -/
def SideRegionInterChordEnds (data : hNT.ChordSplitData u v) : Prop :=
  ∀ {w : M.Vertex}, w ∈ sideRegion₁ data → w ∈ sideRegion₂ data → w = u ∨ w = v



/-- The side-2 seam dart `α dart` has chord edge `s(u, v)`. -/
lemma alpha_dart_edge (data : hNT.ChordSplitData u v) :
    M.dartEdge (M.α data.dart) = s(u, v) := by
  rw [M.dartEdge_alpha]; exact hNT.chordDart_edge data.chord

/-- **Both endpoints of a non-chord side-2 face-dart are in `sideRegion₂`** (unconditional in
`hsep`-free combinatorics apart from the `α`-closure, which needs `Separates`). -/
theorem endpoints_mem_sideRegion₂_of_face (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    {e : D} (hchord : M.dartEdge e ≠ s(u, v)) (hface : M.dartFace e ∈ data.side₂) :
    M.tail e ∈ sideRegion₂ data ∧ M.head e ∈ sideRegion₂ data := by
  -- `e ≠ α dart` (else its edge would be the chord).
  have hne : e ≠ M.α data.dart := by
    intro h; exact hchord (by rw [h]; exact alpha_dart_edge data)
  -- `e ∈ sideDarts₂ ⊆ keptSet₂`.
  have hkept : e ∈ data.keptSet₂ := by
    refine ⟨Or.inl hface, ?_⟩
    simp only [Set.mem_singleton_iff]; exact hne
  have htail : M.tail e ∈ sideRegion₂ data :=
    tail_mem_sideRegion₂ data ((data.mem_keptDel₂_iff e).2 hkept)
  -- head `e = tail (α e)`; `α e ∈ keptSet₂` by the `α`-closure.
  have hkeptα : M.α e ∈ data.keptSet₂ := (data.mem_keptSet₂_alpha_iff hsep e).2 hkept
  have hhead : M.head e ∈ sideRegion₂ data :=
    tail_mem_sideRegion₂ data ((data.mem_keptDel₂_iff (M.α e)).2 hkeptα)
  exact ⟨htail, hhead⟩



/-- **A non-loop edge with both endpoints in `{u, v}` is the chord.**  The simple-map no-loop
fact gives `tail e ≠ head e`; two distinct members of `{u, v}` are exactly `u, v` (in some order),
so `dartEdge e = s(tail e, head e) = s(u, v)`. -/
theorem edge_eq_chord_of_endpoints_chordEnds (data : hNT.ChordSplitData u v) {e : D}
    (htail : M.tail e = u ∨ M.tail e = v) (hhead : M.head e = u ∨ M.head e = v) :
    M.dartEdge e = s(u, v) := by
  have hloop : M.tail e ≠ M.head e := hNT.simpleGraph.no_loop e
  show s(M.tail e, M.head e) = s(u, v)
  rcases htail with ht | ht <;> rcases hhead with hh | hh
  · -- both `= u`: contradicts non-loop.
    exact absurd (ht.trans hh.symm) hloop
  · rw [ht, hh]
  · rw [ht, hh, Sym2.eq_swap]
  · -- both `= v`: contradicts non-loop.
    exact absurd (ht.trans hh.symm) hloop



/-- **The corrected (bounded) `edge_core`, via closure-intersection.**  For a non-chord, bounded
dart `e` (`dartFace e ≠ outerFace`) whose two endpoints are both in `sideRegion₁`, the face of `e`
lies in `side₁`.

Proof: `bounded_face_partition` places `dartFace e` in `side₁` or `side₂`.  In the `side₂` case,
`endpoints_mem_sideRegion₂_of_face` puts both endpoints in `sideRegion₂`; combined with the
`sideRegion₁` hypotheses, `sideRegion_inter_subset_chordEnds` forces both endpoints into `{u, v}`,
whence `edge_eq_chord_of_endpoints_chordEnds` makes `e` the chord — contradicting non-chordness.
So `dartFace e ∈ side₁`.

Clean-3 conditional on exactly the two isolated planar bridges. -/
theorem edge_core_holds (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (hpart : BoundedFacePartition data) (hinter : SideRegionInterChordEnds data)
    {e : D} (hchord : M.dartEdge e ≠ s(u, v)) (houter : M.dartFace e ≠ hNT.outerFace)
    (htail : M.tail e ∈ sideRegion₁ data) (hhead : M.head e ∈ sideRegion₁ data) :
    M.dartFace e ∈ data.side₁ := by
  rcases hpart houter with hside₁ | hside₂
  · exact hside₁
  · -- `dartFace e ∈ side₂`: derive `e = chord`, contradiction.
    exfalso
    obtain ⟨htail₂, hhead₂⟩ := endpoints_mem_sideRegion₂_of_face data hsep hchord hside₂
    have htchord : M.tail e = u ∨ M.tail e = v := hinter htail htail₂
    have hhchord : M.head e = u ∨ M.head e = v := hinter hhead hhead₂
    exact hchord (edge_eq_chord_of_endpoints_chordEnds data htchord hhchord)





end ProofsInTheBook.ZinanCh35EdgeCore








end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35EdgeCore
-/
/- Source module: ProofsInTheBook.ZinanCh35Coverage -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35Coverage

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.ZinanCh35EdgeCore

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



section Abstract

variable {V : Type*} (r : V → V → Prop)

/-- `r` with the single undirected edge `{a, b}` removed. -/
def removeEdge (a b : V) : V → V → Prop :=
  fun x y => r x y ∧ ¬ ((x = a ∧ y = b) ∨ (x = b ∧ y = a))

/-- **One-edge removal.**  If `w` is reachable from `a` in `r`, then `w` is reachable from `a` or
from `b` in `r` with the edge `{a, b}` removed. -/
theorem reflTransGen_removeEdge {a b : V} {w : V}
    (h : Relation.ReflTransGen r a w) :
    Relation.ReflTransGen (removeEdge r a b) a w ∨
      Relation.ReflTransGen (removeEdge r a b) b w := by
  induction h with
  | refl => exact Or.inl Relation.ReflTransGen.refl
  | @tail x w hax hxw ih =>
      by_cases hedge : (x = a ∧ w = b) ∨ (x = b ∧ w = a)
      · -- The last step is exactly the removed edge `{a, b}`.
        rcases hedge with ⟨hxa, hwb⟩ | ⟨hxb, hwa⟩
        · subst hwb; exact Or.inr Relation.ReflTransGen.refl
        · subst hwa; exact Or.inl Relation.ReflTransGen.refl
      · -- The last step survives in `removeEdge`.
        have hstep : removeEdge r a b x w := ⟨hxw, hedge⟩
        rcases ih with hA | hB
        · exact Or.inl (hA.tail hstep)
        · exact Or.inr (hB.tail hstep)

end Abstract



/-- **Inner-face dual adjacency.**  Two faces share an edge that is not a boundary edge. -/
def InnerAdj (hNT : NearTriangulation M) (f g : M.Face) : Prop :=
  ∃ d : D,
    M.dartFace d = f ∧ M.dartFace (M.α d) = g ∧
      ¬ hNT.outerCycle.IsBoundaryEdge (M.dartEdge d)





/-- A dart with the chord edge is `data.dart` or `M.α data.dart`. -/
lemma eq_dart_or_alpha_of_chordEdge (data : hNT.ChordSplitData u v) {d : D}
    (hd : M.dartEdge d = s(u, v)) : d = data.dart ∨ d = M.α data.dart := by
  have hsame : M.dartEdge d = M.dartEdge data.dart := by
    rw [hd]; exact (hNT.chordDart_edge data.chord).symm
  have hsc : M.α.SameCycle data.dart d :=
    M.alpha_sameCycle_of_dartEdge_eq hNT.simpleGraph hsame.symm
  exact (M.alpha_sameCycle_iff data.dart d).1 hsc

/-- **The chord `InnerAdj`-edge runs between `face₁` and `face₂`.**  If `d` witnesses an
`InnerAdj`-step `f → g` and carries the chord edge, then `{f, g} = {face₁, face₂}` (as the ordered
pair `(face₁, face₂)` or `(face₂, face₁)`). -/
lemma face_pair_of_chordEdge (data : hNT.ChordSplitData u v) {d : D} {f g : M.Face}
    (hdf : M.dartFace d = f) (hdg : M.dartFace (M.α d) = g)
    (hd : M.dartEdge d = s(u, v)) :
    (f = data.face₁ ∧ g = data.face₂) ∨ (f = data.face₂ ∧ g = data.face₁) := by
  rcases eq_dart_or_alpha_of_chordEdge data hd with hcase | hcase
  · -- `d = dart`: `f = face₁`, `g = face₂`.
    left
    refine ⟨?_, ?_⟩
    · rw [← hdf, hcase]; rfl
    · rw [← hdg, hcase]; rfl
  · -- `d = α dart`: `f = face₂`, `g = face₁`.
    right
    refine ⟨?_, ?_⟩
    · rw [← hdf, hcase]; rfl
    · rw [← hdg, hcase, M.alpha_alpha]; rfl

/-- **`InnerAdj` minus the `{face₁, face₂}` edge is `ChordSplitAdj`.**  An `InnerAdj`-step whose
ordered face-pair is neither `(face₁, face₂)` nor `(face₂, face₁)` is a genuine `ChordSplitAdj`-step
(its edge cannot be the chord). -/
lemma chordSplitAdj_of_removeEdge_innerAdj (data : hNT.ChordSplitData u v) {f g : M.Face}
    (h : removeEdge (InnerAdj hNT) data.face₁ data.face₂ f g) :
    hNT.ChordSplitAdj u v f g := by
  obtain ⟨⟨d, hdf, hdg, hbe⟩, hne⟩ := h
  refine ⟨d, hdf, hdg, hbe, ?_⟩
  intro hchord
  -- chord edge ⟹ `(f, g)` is `(face₁, face₂)` or `(face₂, face₁)`, contradicting `hne`.
  exact hne (face_pair_of_chordEdge data hdf hdg hchord)



/-- A `removeEdge InnerAdj`-walk lifts to a `ChordSplitAdj`-walk (pointwise inclusion of steps). -/
lemma reflTransGen_chordSplitAdj_of_removeEdge (data : hNT.ChordSplitData u v) {s g : M.Face}
    (h : Relation.ReflTransGen (removeEdge (InnerAdj hNT) data.face₁ data.face₂) s g) :
    Relation.ReflTransGen (hNT.ChordSplitAdj u v) s g := by
  induction h with
  | refl => exact Relation.ReflTransGen.refl
  | tail _ hstep ih =>
      exact ih.tail (chordSplitAdj_of_removeEdge_innerAdj data hstep)



/-- **The sharp residual: inner-face dual connectivity from `face₁`.**  Every non-outer face is
`InnerAdj`-reachable from `face₁` (the inner-face dual graph is connected, seeded at the chord-face
`face₁`).  This is the only genuinely-missing planar input behind face coverage. -/
def InnerFaceConnectedFromFace₁ (data : hNT.ChordSplitData u v) : Prop :=
  ∀ {f : M.Face}, f ≠ hNT.outerFace →
    Relation.ReflTransGen (InnerAdj hNT) data.face₁ f

/-- **`BoundedFacePartition` from inner-face dual connectivity (the reduction).**
Given that every non-outer face is `InnerAdj`-reachable from `face₁`, every non-outer face is
`ChordSplitAdj`-reachable from `face₁` or `face₂`.  Proof: `InnerAdj`-reach `face₁ → f`, remove the
`{face₁, face₂}` edge (`reflTransGen_removeEdge`) to get `removeEdge`-reach from `face₁` or `face₂`,
then lift through `removeEdge InnerAdj ⊆ ChordSplitAdj`. -/
theorem boundedFacePartition_of_innerConnected (data : hNT.ChordSplitData u v)
    (hconn : InnerFaceConnectedFromFace₁ data) :
    BoundedFacePartition data := by
  intro f hf
  -- `InnerAdj`-reach `face₁ → f`.
  have hreach : Relation.ReflTransGen (InnerAdj hNT) data.face₁ f := hconn hf
  -- remove the chord dual edge `{face₁, face₂}`.
  rcases reflTransGen_removeEdge (InnerAdj hNT) (a := data.face₁) (b := data.face₂) hreach with
    hA | hB
  · -- `removeEdge`-reach from `face₁` ⟹ `ChordSplitAdj`-reach from `face₁` ⟹ `f ∈ side₁`.
    exact Or.inl (reflTransGen_chordSplitAdj_of_removeEdge data hA)
  · -- `removeEdge`-reach from `face₂` ⟹ `ChordSplitAdj`-reach from `face₂` ⟹ `f ∈ side₂`.
    exact Or.inr (reflTransGen_chordSplitAdj_of_removeEdge data hB)





end ProofsInTheBook.ZinanCh35Coverage









end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35StarRotation
import ProofsInTheBook.ZinanCh35Coverage
-/
/- Source module: ProofsInTheBook.ZinanCh35InnerConn -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35InnerConn

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ZinanCh35Coverage
open ProofsInTheBook.ZinanCh35EdgeCore

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M}







/-- **The α-step.**  If the edge of `d` is not a boundary edge, then `dartFace d` and
`dartFace (α d)` are `InnerAdj`-adjacent (the dart `d` itself is the witness). -/
lemma innerAdj_alpha {d : D} (hbe : ¬ hNT.outerCycle.IsBoundaryEdge (M.dartEdge d)) :
    InnerAdj hNT (M.dartFace d) (M.dartFace (M.α d)) :=
  ⟨d, rfl, rfl, hbe⟩





/-- For a boundary edge, at least one of its two darts lies on the outer face. -/
lemma boundaryEdge_dart_outer {e : D}
    (hbe : hNT.outerCycle.IsBoundaryEdge (M.dartEdge e)) :
    M.dartFace e = hNT.outerFace ∨ M.dartFace (M.α e) = hNT.outerFace := by
  rw [BoundaryCycle.IsBoundaryEdge, hNT.outerCycle.edges_eq, List.mem_map] at hbe
  obtain ⟨b, hb, hbe⟩ := hbe
  have hbface : M.dartFace b = hNT.outerFace := (hNT.outerCycle.mem_darts_iff b).mp hb
  have hsc : M.α.SameCycle e b :=
    M.alpha_sameCycle_of_dartEdge_eq hNT.simpleGraph hbe.symm
  rcases (M.alpha_sameCycle_iff b e).mp hsc.symm with h | h
  · exact Or.inl (by rw [h]; exact hbface)
  · right; rw [h, M.alpha_alpha]; exact hbface

/-- **No interior bridge: an edge with both faces inner is non-boundary.**  Contrapositive of
`boundaryEdge_dart_outer`. -/
lemma not_boundaryEdge_of_both_inner {d : D}
    (h1 : M.dartFace d ≠ hNT.outerFace) (h2 : M.dartFace (M.α d) ≠ hNT.outerFace) :
    ¬ hNT.outerCycle.IsBoundaryEdge (M.dartEdge d) := by
  intro hbe
  rcases boundaryEdge_dart_outer hbe with h | h
  · exact h1 h
  · exact h2 h



/-- The clean inner-dart link: same face, or the reverse dart across a non-boundary edge. -/
def InnerLink (hNT : NearTriangulation M) (d e : D) : Prop :=
  M.dartFace d = M.dartFace e ∨
    (e = M.α d ∧ ¬ hNT.outerCycle.IsBoundaryEdge (M.dartEdge d))

/-- **A single `InnerLink`-step lifts to face `InnerAdj`-reachability.** -/
lemma reflTransGen_innerAdj_of_innerLink {d e : D} (h : InnerLink hNT d e) :
    Relation.ReflTransGen (InnerAdj hNT) (M.dartFace d) (M.dartFace e) := by
  rcases h with hface | ⟨hαd, hbe⟩
  · rw [hface]
  · subst hαd
    exact Relation.ReflTransGen.single (innerAdj_alpha hbe)

/-- **An `InnerLink`-walk lifts to an `InnerAdj`-walk on faces.** -/
lemma reflTransGen_innerAdj_of_innerLink_walk {d e : D}
    (h : Relation.ReflTransGen (InnerLink hNT) d e) :
    Relation.ReflTransGen (InnerAdj hNT) (M.dartFace d) (M.dartFace e) := by
  induction h with
  | refl => exact Relation.ReflTransGen.refl
  | @tail x y hxy hstep ih =>
      exact ih.trans (reflTransGen_innerAdj_of_innerLink hstep)











/-- **The sharp residual: inner-dart connectivity.**  Any two darts whose faces are inner are
joined by an `InnerLink`-walk (same-face or non-boundary-reverse steps), staying inside the
inner-dart graph.  This is the dart-level form of inner-face dual connectivity. -/
def InnerDartConnected (hNT : NearTriangulation M) : Prop :=
  ∀ a b : D, M.dartFace a ≠ hNT.outerFace → M.dartFace b ≠ hNT.outerFace →
    Relation.ReflTransGen (InnerLink hNT) a b

variable {u v : M.Vertex}

/-- **The keystone from inner-dart connectivity (the reduction).**  Given that the inner-dart
graph is `InnerLink`-connected, every non-outer face is `InnerAdj`-reachable from `face₁`.

Proof: `face₁ = dartFace data.dart` with `data.dart` inner; a non-outer face `f` is a triangle,
so it has a dart `d_f` (any orbit representative) with `dartFace d_f = f`, also inner; an
`InnerLink`-walk `data.dart → d_f` (`InnerDartConnected`) lifts to an `InnerAdj`-walk
`face₁ → f`. -/
theorem innerFaceConnectedFromFace₁_of_innerDartConnected
    (data : hNT.ChordSplitData u v) (hconn : InnerDartConnected hNT) :
    InnerFaceConnectedFromFace₁ data := by
  intro f hf
  -- A representative dart `d_f` of the triangular face `f`.
  have hd_f : ∃ d : D, M.dartFace d = f := by
    refine ⟨Quotient.out f, ?_⟩
    show Quotient.mk (cycleSetoid M.φ) (Quotient.out f) = f
    exact Quotient.out_eq f
  obtain ⟨d_f, hd_f⟩ := hd_f
  -- `face₁ = dartFace data.dart`, inner; `f = dartFace d_f`, inner.
  have hface₁ : data.face₁ = M.dartFace data.dart := rfl
  have hdart_inner : M.dartFace data.dart ≠ hNT.outerFace := by
    rw [← hface₁]; exact data.face₁_not_outer
  have hd_f_inner : M.dartFace d_f ≠ hNT.outerFace := by rw [hd_f]; exact hf
  -- Lift the inner-dart walk.
  have hwalk : Relation.ReflTransGen (InnerLink hNT) data.dart d_f :=
    hconn data.dart d_f hdart_inner hd_f_inner
  have hlift := reflTransGen_innerAdj_of_innerLink_walk hwalk
  rw [hd_f] at hlift
  rw [hface₁]
  exact hlift



/-- **The Chapter 35 keystone (conditional on inner-dart connectivity).**  Every non-outer face of
a near-triangulation is `InnerAdj`-reachable from the chord face `face₁`, given the sharp residual
`InnerDartConnected hNT` (inner-dart `InnerLink`-connectivity).  Cascades through
`boundedFacePartition_of_innerConnected` to close the coverage half of `edge_core`. -/
theorem innerFaceConnectedFromFace₁_holds
    (data : hNT.ChordSplitData u v) (hconn : InnerDartConnected hNT) :
    InnerFaceConnectedFromFace₁ data :=
  innerFaceConnectedFromFace₁_of_innerDartConnected data hconn

/-- **End-to-end cascade: `BoundedFacePartition` from inner-dart connectivity.**  Composes the
keystone with `boundedFacePartition_of_innerConnected` (`ZinanCh35Coverage`). -/
theorem boundedFacePartition_of_innerDartConnected
    (data : hNT.ChordSplitData u v) (hconn : InnerDartConnected hNT) :
    BoundedFacePartition data :=
  boundedFacePartition_of_innerConnected data
    (innerFaceConnectedFromFace₁_holds data hconn)

end ProofsInTheBook.ZinanCh35InnerConn












end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35InnerConn
-/
/- Source module: ProofsInTheBook.ZinanCh35OuterDual -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35OuterDual

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ZinanCh35InnerConn
open ProofsInTheBook.ZinanCh35Coverage
open ProofsInTheBook.ZinanCh35EdgeCore

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M}



/-- **The outer dual step.**  Faces `f`, `g` are adjacent across a primal edge that is
*not* a boundary edge of the outer cycle: there is a dart `d` with `dartFace d = f`,
`dartFace (α d) = g`, and `dartEdge d` non-boundary.  This is exactly
`DualAvoidsCycleStep M Couter` for the outer cycle `Couter` (whose edge set is the outer
boundary), phrased without packaging the whole outer cycle as a `SimplePrimalCycle`. -/
def OuterDualStep (hNT : NearTriangulation M) (f g : M.Face) : Prop :=
  ∃ d : D, M.dartFace d = f ∧ M.dartFace (M.α d) = g ∧
    ¬ hNT.outerCycle.IsBoundaryEdge (M.dartEdge d)

/-- `OuterDualStep` is symmetric: the reverse dart `α d` witnesses the reverse step
(`dartEdge (α d) = dartEdge d` is still non-boundary). -/
lemma outerDualStep_symm {f g : M.Face} (h : OuterDualStep hNT f g) :
    OuterDualStep hNT g f := by
  obtain ⟨d, hdf, hdg, hbe⟩ := h
  refine ⟨M.α d, hdg, ?_, ?_⟩
  · rw [M.alpha_alpha]; exact hdf
  · rw [M.dartEdge_alpha]; exact hbe

/-- Symmetry transports to the reflexive-transitive closure. -/
lemma reflTransGen_outerDualStep_symm {f g : M.Face}
    (h : Relation.ReflTransGen (OuterDualStep hNT) f g) :
    Relation.ReflTransGen (OuterDualStep hNT) g f :=
  Relation.ReflTransGen.symmetric (fun _ _ hstep => outerDualStep_symm hstep) h



/-- A dart whose face is the outer face lies on the outer cycle, hence its edge is a
boundary edge. -/
lemma boundaryEdge_of_dartFace_outer {d : D} (hd : M.dartFace d = hNT.outerFace) :
    hNT.outerCycle.IsBoundaryEdge (M.dartEdge d) := by
  have hmem : d ∈ hNT.outerCycle.darts := (hNT.outerCycle.mem_darts_iff d).mpr hd
  show M.dartEdge d ∈ hNT.outerCycle.edges
  rw [hNT.outerCycle.edges_eq]
  exact List.mem_map_of_mem hmem

/-- **No `OuterDualStep` starts at the outer face.**  Such a step would need a
non-boundary edge whose dart carries the outer face — impossible. -/
lemma not_outerDualStep_outerFace {g : M.Face} :
    ¬ OuterDualStep hNT hNT.outerFace g := by
  rintro ⟨d, hdf, _, hbe⟩
  exact hbe (boundaryEdge_of_dartFace_outer hdf)

/-- **Outer isolation.**  The only face `OuterDualStep`-reachable from `outerFace` is
`outerFace` itself: the first step out is impossible. -/
lemma outerFace_isolated {f : M.Face}
    (h : Relation.ReflTransGen (OuterDualStep hNT) hNT.outerFace f) :
    f = hNT.outerFace := by
  induction h with
  | refl => rfl
  | @tail x y _ hstep ih =>
      -- `ih : x = outerFace`; then `OuterDualStep outerFace y` is impossible.
      subst ih
      exact (not_outerDualStep_outerFace hstep).elim

/-- Consequently, an `OuterDualStep`-walk that *reaches* the outer face must have started
there (by symmetry).  Useful for confining inner reachability to non-outer faces. -/
lemma eq_outerFace_of_reachesOuter {f : M.Face}
    (h : Relation.ReflTransGen (OuterDualStep hNT) f hNT.outerFace) :
    f = hNT.outerFace :=
  outerFace_isolated (reflTransGen_outerDualStep_symm h)



/-- Two darts on the **same face** are `InnerLink`-adjacent (the `Or.inl` clause). -/
lemma innerLink_of_sameFace {a b : D} (h : M.dartFace a = M.dartFace b) :
    InnerLink hNT a b := Or.inl h

/-- **The lift of one `OuterDualStep`.**  Given `OuterDualStep f g` and any darts `a, b`
with `dartFace a = f`, `dartFace b = g`, there is an `InnerLink`-walk `a → b`. -/
lemma outerDualStep_lifts_to_innerLink {f g : M.Face} {a b : D}
    (hstep : OuterDualStep hNT f g) (ha : M.dartFace a = f) (hb : M.dartFace b = g) :
    Relation.ReflTransGen (InnerLink hNT) a b := by
  obtain ⟨d, hdf, hdg, hbe⟩ := hstep
  -- a —(same face f)→ d
  have h1 : InnerLink hNT a d := innerLink_of_sameFace (by rw [ha, hdf])
  -- d —(non-boundary α-crossing)→ α d
  have h2 : InnerLink hNT d (M.α d) := Or.inr ⟨rfl, hbe⟩
  -- α d —(same face g)→ b
  have h3 : InnerLink hNT (M.α d) b := innerLink_of_sameFace (by rw [hdg, hb])
  exact (Relation.ReflTransGen.single h1).trans
    ((Relation.ReflTransGen.single h2).trans (Relation.ReflTransGen.single h3))

/-- **An `OuterDualStep`-walk lifts to an `InnerLink`-walk.**  Carrying along, at each
position, a dart representative of the current face, each `OuterDualStep` lifts (Step 4)
and the representatives are chained by `InnerLink`-walks. -/
lemma reflTransGen_innerLink_of_outerDualStep_walk {f g : M.Face} {a b : D}
    (hwalk : Relation.ReflTransGen (OuterDualStep hNT) f g)
    (ha : M.dartFace a = f) (hb : M.dartFace b = g) :
    Relation.ReflTransGen (InnerLink hNT) a b := by
  induction hwalk generalizing b with
  | refl =>
      -- f = g; `a` and `b` carry the same face.
      exact Relation.ReflTransGen.single (innerLink_of_sameFace (by rw [ha, hb]))
  | @tail x y hwxy hstep ih =>
      -- Pick a representative dart `c` of the intermediate face `x`.
      obtain ⟨c, hc⟩ : ∃ c : D, M.dartFace c = x := by
        refine ⟨Quotient.out x, ?_⟩
        show Quotient.mk (cycleSetoid M.φ) (Quotient.out x) = x
        exact Quotient.out_eq x
      have hac : Relation.ReflTransGen (InnerLink hNT) a c := ih hc
      have hcb : Relation.ReflTransGen (InnerLink hNT) c b :=
        outerDualStep_lifts_to_innerLink hstep hc hb
      exact hac.trans hcb



/-- **The isolated crux: inner-face dual connectivity.**  Every two non-outer faces are
`OuterDualStep`-reachable from one another. -/
def InnerFacesDualConnected (hNT : NearTriangulation M) : Prop :=
  ∀ f g : M.Face, f ≠ hNT.outerFace → g ≠ hNT.outerFace →
    Relation.ReflTransGen (OuterDualStep hNT) f g



/-- **`InnerDartConnected` from inner-face dual connectivity.**  Two inner darts `a, b`
carry inner faces `dartFace a`, `dartFace b`; the crux supplies an `OuterDualStep`-walk
between these faces, which lifts (Steps 3–4) to an `InnerLink`-walk `a → b`. -/
theorem innerDartConnected_of_innerFacesDualConnected
    (hcrux : InnerFacesDualConnected hNT) :
    InnerDartConnected hNT := by
  intro a b ha hb
  have hwalk : Relation.ReflTransGen (OuterDualStep hNT) (M.dartFace a) (M.dartFace b) :=
    hcrux (M.dartFace a) (M.dartFace b) ha hb
  exact reflTransGen_innerLink_of_outerDualStep_walk hwalk rfl rfl



variable {u v : M.Vertex}



/-- **End-to-end cascade**: `BoundedFacePartition` via the outer-dual route, conditional
on `InnerFacesDualConnected`. -/
theorem boundedFacePartition_via_outerDual
    (data : hNT.ChordSplitData u v) (hcrux : InnerFacesDualConnected hNT) :
    BoundedFacePartition data :=
  boundedFacePartition_of_innerDartConnected data
    (innerDartConnected_of_innerFacesDualConnected hcrux)

end ProofsInTheBook.ZinanCh35OuterDual















end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35OuterDual
import ProofsInTheBook.RelationComponentCount
import ProofsInTheBook.PlanarMapEulerInequality
-/
/- Source module: ProofsInTheBook.ZinanCh35OuterCount -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35OuterCount

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ZinanCh35InnerConn
open ProofsInTheBook.ZinanCh35Coverage
open ProofsInTheBook.ZinanCh35EdgeCore
open ProofsInTheBook.ZinanCh35OuterDual

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M}



/-- `OuterDualStep` packaged as a plain symmetry statement (`∀ a b, r a b → r b a`),
the form `eqvGen_iff_reflTransGen` wants. -/
lemma outerDualStep_symm' :
    ∀ a b : M.Face, OuterDualStep hNT a b → OuterDualStep hNT b a :=
  fun _ _ h => outerDualStep_symm h

/-- `EqvGen (OuterDualStep)` coincides with `ReflTransGen (OuterDualStep)`. -/
lemma eqvGen_outerDualStep_iff {f g : M.Face} :
    Relation.EqvGen (OuterDualStep hNT) f g ↔
      Relation.ReflTransGen (OuterDualStep hNT) f g :=
  eqvGen_iff_reflTransGen (outerDualStep_symm' (hNT := hNT)) f g



/-- If a face's quotient class equals `outerFace`'s class, the face IS `outerFace`. -/
lemma eq_outerFace_of_class_eq {f : M.Face}
    (h : Quotient.mk (compSetoid (OuterDualStep hNT)) f
        = Quotient.mk (compSetoid (OuterDualStep hNT)) hNT.outerFace) :
    f = hNT.outerFace := by
  have hEqv : Relation.EqvGen (OuterDualStep hNT) f hNT.outerFace := Quotient.exact h
  have hReach : Relation.ReflTransGen (OuterDualStep hNT) f hNT.outerFace :=
    (eqvGen_outerDualStep_iff (hNT := hNT)).1 hEqv
  exact eq_outerFace_of_reachesOuter hReach

/-- Contrapositive form: a non-outer face's class differs from `outerFace`'s class. -/
lemma class_ne_outerFace_class {f : M.Face} (hf : f ≠ hNT.outerFace) :
    Quotient.mk (compSetoid (OuterDualStep hNT)) f
      ≠ Quotient.mk (compSetoid (OuterDualStep hNT)) hNT.outerFace :=
  fun h => hf (eq_outerFace_of_class_eq (hNT := hNT) h)



/-- **Two elements of a 2-element Fintype, both different from a fixed `c`, are equal.** -/
lemma eq_of_card_two_of_ne {α : Type*} [Fintype α] [DecidableEq α]
    (hcard : Fintype.card α = 2) {x y c : α} (hx : x ≠ c) (hy : y ≠ c) : x = y := by
  by_contra hxy
  -- `x, y, c` would be three distinct elements, forcing `card ≥ 3`.
  have h3 : ({x, y, c} : Finset α).card = 3 := by
    rw [Finset.card_insert_of_notMem, Finset.card_insert_of_notMem,
      Finset.card_singleton]
    · simp [hy]
    · simp only [Finset.mem_insert, Finset.mem_singleton, not_or]
      exact ⟨hxy, hx⟩
  have hle : ({x, y, c} : Finset α).card ≤ Fintype.card α := Finset.card_le_univ _
  omega

/-- **The two quotient classes of non-outer faces coincide.**  Under `numComp = 2`, any
two non-outer faces lie in the same component class. -/
lemma class_eq_of_numComp_two
    (hnum : numComp (OuterDualStep hNT) = 2)
    {f g : M.Face} (hf : f ≠ hNT.outerFace) (hg : g ≠ hNT.outerFace) :
    Quotient.mk (compSetoid (OuterDualStep hNT)) f
      = Quotient.mk (compSetoid (OuterDualStep hNT)) g := by
  classical
  haveI : Fintype (Quotient (compSetoid (OuterDualStep hNT))) :=
    Quotient.fintype (compSetoid (OuterDualStep hNT))
  have hcard : Fintype.card (Quotient (compSetoid (OuterDualStep hNT))) = 2 := by
    have := hnum
    unfold numComp at this
    rwa [Nat.card_eq_fintype_card] at this
  exact eq_of_card_two_of_ne hcard
    (class_ne_outerFace_class (hNT := hNT) hf)
    (class_ne_outerFace_class (hNT := hNT) hg)



/-- **Easy half (unconditional, clean-3).**  If the outer-dual component count is `2`,
then the inner faces are dual-connected. -/
theorem innerFacesDualConnected_of_outerDual_numComp_two
    (hnum : numComp (OuterDualStep hNT) = 2) :
    InnerFacesDualConnected hNT := by
  intro f g hf hg
  -- equal quotient classes ⟹ `EqvGen` ⟹ `ReflTransGen`
  have hclass := class_eq_of_numComp_two (hNT := hNT) hnum hf hg
  have hEqv : Relation.EqvGen (OuterDualStep hNT) f g := Quotient.exact hclass
  exact (eqvGen_outerDualStep_iff (hNT := hNT)).1 hEqv



/-- **The single isolated residual** : the outer-dual component count is `2`.  This is the
Euler/Jordan fact (the weak dual of a triangulated disk = the inner component ⊔ outer
face).  The cut-cap Euler machinery is the intended supplier; it is **not** discharged in
this file. -/
def OuterDualNumCompTwo (hNT : NearTriangulation M) : Prop :=
  numComp (OuterDualStep hNT) = 2

variable {u v : M.Vertex}

/-- **The keystone via the dual component count**, conditional on the single residual
`OuterDualNumCompTwo`.  Combines the easy half proved here with the lift assembled in
`ZinanCh35OuterDual.lean`. -/
theorem innerFacesDualConnected_via_numComp
    (hnum : OuterDualNumCompTwo hNT) :
    InnerFacesDualConnected hNT :=
  innerFacesDualConnected_of_outerDual_numComp_two hnum



/-- **End-to-end cascade** : `BoundedFacePartition` via the dual count, conditional on
`OuterDualNumCompTwo`. -/
theorem boundedFacePartition_via_numComp
    (data : hNT.ChordSplitData u v) (hnum : OuterDualNumCompTwo hNT) :
    BoundedFacePartition data :=
  boundedFacePartition_via_outerDual data
    (innerFacesDualConnected_via_numComp hnum)

end ProofsInTheBook.ZinanCh35OuterCount













end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35OuterCount
-/
/- Source module: ProofsInTheBook.ZinanCh35OuterSlack -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35OuterSlack

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ZinanCh35OuterDual
open ProofsInTheBook.ZinanCh35OuterCount
open ProofsInTheBook.SubmapPlanar

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}



/-- The **dual combinatorial map**: same edge involution `α`, but the vertex rotation is the
primal face permutation `φ = σ * α`.  Then `dualMap.φ = φ * α = σ`, so vertices/faces swap. -/
def dualMap (M : CombMap D) : CombMap D where
  α := M.α
  σ := M.φ
  α_invol := M.α_invol
  α_no_fixed := M.α_no_fixed

@[simp] lemma dualMap_σ (M : CombMap D) : (dualMap M).σ = M.φ := rfl
@[simp] lemma dualMap_α (M : CombMap D) : (dualMap M).α = M.α := rfl

lemma dualMap_φ (M : CombMap D) : (dualMap M).φ = M.σ := by
  show M.φ * M.α = M.σ
  rw [CombMap.φ, mul_assoc, M.α_invol, mul_one]

/-- `M.σ` equals `M.φ ∘ M.α` (the dual `φ`-step composed with one `α`-step). -/
lemma sigma_eq_phi_alpha (M : CombMap D) (d : D) : M.σ d = M.φ (M.α d) := by
  show M.σ d = (M.σ * M.α) (M.α d)
  simp [Equiv.Perm.mul_apply, M.alpha_alpha]

/-- One primal `σ`-step is a two-step dual walk: `a —(α-edge)→ α a —(φ same-cycle)→ σ a`. -/
lemma reflTransGen_dualStep_sigma (M : CombMap D) (a : D) :
    Relation.ReflTransGen (dualMap M).dartStep a (M.σ a) := by
  have h1 : (dualMap M).dartStep a (M.α a) := Or.inr (by simp [dualMap])
  have h2 : (dualMap M).dartStep (M.α a) (M.σ a) := by
    refine Or.inl ?_
    show M.φ.SameCycle (M.α a) (M.σ a)
    rw [sigma_eq_phi_alpha]
    exact ⟨1, by simp⟩
  exact Relation.ReflTransGen.tail (Relation.ReflTransGen.single h1) h2

/-- Iterating: `ReflTransGen (dualMap.dartStep) a ((M.σ)^k a)`. -/
lemma reflTransGen_dualStep_sigma_pow (M : CombMap D) (a : D) :
    ∀ k : ℕ, Relation.ReflTransGen (dualMap M).dartStep a ((M.σ ^ k) a) := by
  intro k
  induction k with
  | zero => simpa using Relation.ReflTransGen.refl
  | succ n ih =>
    have hstep : Relation.ReflTransGen (dualMap M).dartStep ((M.σ ^ n) a)
        (M.σ ((M.σ ^ n) a)) := reflTransGen_dualStep_sigma M _
    have : (M.σ ^ (n + 1)) a = M.σ ((M.σ ^ n) a) := by
      rw [pow_succ']; rfl
    rw [this]
    exact ih.trans hstep

/-- Dual `dartStep` is symmetric. -/
lemma dualStep_symm (M : CombMap D) {a b : D}
    (h : (dualMap M).dartStep a b) : (dualMap M).dartStep b a := by
  rcases h with hsc | hαe
  · exact Or.inl hsc.symm
  · refine Or.inr ?_
    subst hαe
    show a = (dualMap M).α ((dualMap M).α a)
    rw [(dualMap M).alpha_alpha]

/-- A primal `σ`-same-cycle pair is dual-reachable. -/
lemma reflTransGen_dualStep_of_sigma_sameCycle (M : CombMap D) {a b : D}
    (h : M.σ.SameCycle a b) : Relation.ReflTransGen (dualMap M).dartStep a b := by
  obtain ⟨i, hi⟩ := h
  have hsymm : ∀ x y : D, (dualMap M).dartStep x y → (dualMap M).dartStep y x :=
    fun x y hxy => dualStep_symm M hxy
  rcases i.lt_or_le 0 with hneg | hpos
  · -- negative power: `a = (M.σ ^ (-i)) b` with `-i ≥ 0`; reach `b → a`, then symmetrize.
    have hi' : (M.σ ^ (-i)) b = a := by
      rw [← hi, ← Equiv.Perm.mul_apply, ← zpow_add]; simp
    set n := (-i).toNat with hn
    have hcast : (n : ℤ) = -i := Int.toNat_of_nonneg (by omega)
    have hzpow : (M.σ ^ (n : ℤ)) b = a := by rw [hcast]; exact hi'
    rw [zpow_natCast] at hzpow
    have hreach : Relation.ReflTransGen (dualMap M).dartStep b a := by
      rw [← hzpow]; exact reflTransGen_dualStep_sigma_pow M b n
    exact reflTransGen_symm hsymm hreach
  · set n := i.toNat with hn
    have hcast : (n : ℤ) = i := Int.toNat_of_nonneg hpos
    have hzpow : (M.σ ^ (n : ℤ)) a = b := by rw [hcast]; exact hi
    rw [zpow_natCast] at hzpow
    rw [← hzpow]
    exact reflTransGen_dualStep_sigma_pow M a n

/-- The dual map is connected (the dual of a connected map is connected). -/
lemma dualMap_connected (M : CombMap D) (hconn : M.Connected) :
    (dualMap M).Connected := by
  intro a b
  have h := hconn a b
  -- lift each primal `dartStep` to a dual `ReflTransGen`
  induction h with
  | refl => exact Relation.ReflTransGen.refl
  | @tail x y _ hstep ih =>
    have hlift : Relation.ReflTransGen (dualMap M).dartStep x y := by
      rcases hstep with hsc | hαe
      · exact reflTransGen_dualStep_of_sigma_sameCycle M hsc
      · exact Relation.ReflTransGen.single (Or.inr (by simpa [dualMap] using hαe))
    exact ih.trans hlift

lemma dualMap_eulerChar (M : CombMap D) : (dualMap M).eulerChar = M.eulerChar := by
  unfold CombMap.eulerChar
  rw [CombMap.V_eq_numCycles, CombMap.E_eq_numCycles, CombMap.F_eq_numCycles,
      CombMap.V_eq_numCycles, CombMap.E_eq_numCycles, CombMap.F_eq_numCycles,
      dualMap_σ, dualMap_α, dualMap_φ]
  ring

/-- The dual map is a sphere map whenever `M` is. -/
lemma dualMap_isSphereMap (M : CombMap D) (h : M.IsSphereMap) :
    (dualMap M).IsSphereMap :=
  ⟨dualMap_connected M h.1, by rw [dualMap_eulerChar]; exact h.2⟩



variable {hNT : NearTriangulation M}

/-- The darts to delete from `M.α`: the outer-boundary darts together with their
`α`-partners.  This is `α`-closed by construction. -/
noncomputable def OuterDel (hNT : NearTriangulation M) : Finset D :=
  hNT.outerCycle.darts.toFinset ∪ hNT.outerCycle.darts.toFinset.image M.α

lemma mem_outerDel_iff {d : D} :
    d ∈ OuterDel hNT ↔ d ∈ hNT.outerCycle.darts ∨ M.α d ∈ hNT.outerCycle.darts := by
  unfold OuterDel
  simp only [Finset.mem_union, List.mem_toFinset, Finset.mem_image]
  constructor
  · rintro (hd | ⟨x, hx, hxd⟩)
    · exact Or.inl hd
    · exact Or.inr (by rw [← hxd, M.alpha_alpha]; exact hx)
  · rintro (hd | hd)
    · exact Or.inl hd
    · exact Or.inr ⟨M.α d, hd, M.alpha_alpha d⟩

/-- `OuterDel` is `α`-closed. -/
lemma outerDel_alpha_closed :
    ∀ d : D, d ∈ OuterDel hNT → M.α d ∈ OuterDel hNT := by
  intro d hd
  rw [mem_outerDel_iff] at hd ⊢
  rcases hd with hd | hd
  · exact Or.inr (by rw [M.alpha_alpha]; exact hd)
  · exact Or.inl hd

/-- The restricted dual involution: fixes the outer darts and their partners, `= M.α`
elsewhere. -/
noncomputable def outerDualAlpha (hNT : NearTriangulation M) : Equiv.Perm D :=
  rawAlpha M (OuterDel hNT) (outerDel_alpha_closed (hNT := hNT))

lemma outerDualAlpha_eq_self_of_mem {d : D} (hd : d ∈ OuterDel hNT) :
    outerDualAlpha hNT d = d :=
  rawAlpha_eq_self_of_mem M (OuterDel hNT) _ hd

lemma outerDualAlpha_eq_alpha_of_notMem {d : D} (hd : d ∉ OuterDel hNT) :
    outerDualAlpha hNT d = M.α d :=
  rawAlpha_eq_alpha_of_notMem M (OuterDel hNT) _ hd



/-- For a boundary dart `d`, its `α`-partner is **not** a boundary dart.  Otherwise
`σ d = φ(α d)` would also be a boundary dart with `tail (σ d) = tail d`, forcing
`σ d = d` (boundary tails are distinct), contradicting `boundary_dart_sigma_ne`. -/
lemma alpha_notMem_darts_of_mem {d : D} (hd : d ∈ hNT.outerCycle.darts) :
    M.α d ∉ hNT.outerCycle.darts := by
  intro hαd
  -- `φ (α d) = σ d`, and `φ (α d)` is a boundary dart since `α d` is.
  have hface : M.dartFace (M.α d) = hNT.outerFace :=
    (hNT.outerCycle.mem_darts_iff (M.α d)).mp hαd
  have hσd_mem : M.σ d ∈ hNT.outerCycle.darts := by
    rw [hNT.outerCycle.mem_darts_iff]
    have : M.σ d = M.φ (M.α d) := by
      show M.σ d = (M.σ * M.α) (M.α d); simp [Equiv.Perm.mul_apply, M.alpha_alpha]
    rw [this, M.dartFace_phi]; exact hface
  have htail : M.tail (M.σ d) = M.tail d := by simp
  have heq : M.σ d = d :=
    hNT.outerCycle.tail_injective_on_darts hNT.outer_simple hσd_mem hd htail
  exact hNT.boundary_dart_sigma_ne hd heq



/-- The two halves of `OuterDel` are disjoint: a boundary dart is never the `α`-image of a
boundary dart. -/
lemma outerDel_card (hNT : NearTriangulation M) :
    (OuterDel hNT).card = 2 * hNT.outerCycle.length := by
  classical
  have hdisj : Disjoint hNT.outerCycle.darts.toFinset
      (hNT.outerCycle.darts.toFinset.image M.α) := by
    rw [Finset.disjoint_left]
    intro d hd himg
    simp only [List.mem_toFinset] at hd
    simp only [Finset.mem_image, List.mem_toFinset] at himg
    obtain ⟨e, he, hed⟩ := himg
    -- `d = M.α e` with `e, d ∈ darts`; then `M.α e ∈ darts` contradicts the partner lemma.
    exact alpha_notMem_darts_of_mem (hNT := hNT) he (by rw [hed]; exact hd)
  have hcardD : hNT.outerCycle.darts.toFinset.card = hNT.outerCycle.length := by
    rw [List.toFinset_card_of_nodup hNT.outerCycle.darts_nodup]; rfl
  have hcardImg : (hNT.outerCycle.darts.toFinset.image M.α).card
      = hNT.outerCycle.length := by
    rw [Finset.card_image_of_injective _ M.α.injective, hcardD]
  unfold OuterDel
  rw [Finset.card_union_of_disjoint hdisj, hcardD, hcardImg]
  ring

/-- The support of `outerDualAlpha` is exactly the non-deleted darts. -/
lemma support_outerDualAlpha (hNT : NearTriangulation M) :
    (outerDualAlpha hNT).support = Finset.univ \ OuterDel hNT := by
  classical
  ext d
  simp only [Equiv.Perm.mem_support, Finset.mem_sdiff, Finset.mem_univ, true_and]
  constructor
  · intro hd hmem
    exact hd (outerDualAlpha_eq_self_of_mem (hNT := hNT) hmem)
  · intro hd
    rw [outerDualAlpha_eq_alpha_of_notMem (hNT := hNT) hd]
    exact M.α_no_fixed d

/-- The outer boundary length is at most the number of edges. -/
lemma outerCycle_length_le_E (hNT : NearTriangulation M) :
    hNT.outerCycle.length ≤ M.E := by
  have h2B : (OuterDel hNT).card = 2 * hNT.outerCycle.length := outerDel_card hNT
  have hle : (OuterDel hNT).card ≤ Fintype.card D := Finset.card_le_univ _
  have hcard : 2 * M.E = Fintype.card D := two_mul_E_eq_card M
  omega

/-- The outer boundary length is at most the number of vertices (boundary vertices are
distinct). -/
lemma outerCycle_length_le_V (hNT : NearTriangulation M) :
    hNT.outerCycle.length ≤ M.V := by
  classical
  -- the boundary vertex list has `B` distinct entries, all in `M.Vertex`
  have hnodup : hNT.outerCycle.vertices.Nodup := hNT.outer_simple
  have hlen : hNT.outerCycle.vertices.length = hNT.outerCycle.length := by
    rw [hNT.outerCycle.vertices_eq, List.length_map]; rfl
  have hcard : hNT.outerCycle.vertices.toFinset.card = hNT.outerCycle.length := by
    rw [List.toFinset_card_of_nodup hnodup, hlen]
  have hle : hNT.outerCycle.vertices.toFinset.card ≤ Fintype.card M.Vertex :=
    Finset.card_le_univ _
  rw [hcard] at hle
  -- `M.V = Fintype.card M.Vertex`
  have : M.V = Fintype.card M.Vertex := rfl
  omega

/-- **Step 5.**  `Ehalf (outerDualAlpha hNT) = M.E − B`, `B = outerCycle.length`. -/
lemma Ehalf_outerDualAlpha (hNT : NearTriangulation M) :
    Ehalf (outerDualAlpha hNT) = M.E - hNT.outerCycle.length := by
  classical
  -- `2 * Ehalf α = card support α` for any involution; here support = univ \ OuterDel.
  have hsupp := support_outerDualAlpha (hNT := hNT)
  have hα : M.α.support = Finset.univ := by
    rw [Finset.eq_univ_iff_forall]
    intro d
    rw [Equiv.Perm.mem_support]; exact M.α_no_fixed d
  -- card support outerDualAlpha = card univ − card OuterDel
  have hsubset : OuterDel hNT ⊆ Finset.univ := Finset.subset_univ _
  have hcard : (outerDualAlpha hNT).support.card
      = Fintype.card D - (OuterDel hNT).card := by
    rw [hsupp, Finset.card_univ_diff]
  -- `M.E = card univ / 2`, `Ehalf outerDualAlpha = (card univ - 2B)/2`
  have hEval : M.E = Fintype.card D / 2 := by
    have : Ehalf M.α = M.E := Ehalf_eq_E M
    rw [Ehalf, hα, Finset.card_univ] at this
    omega
  have hEhalf : Ehalf (outerDualAlpha hNT) = (outerDualAlpha hNT).support.card / 2 := rfl
  rw [hEhalf, hcard, outerDel_card (hNT := hNT)]
  omega

/-- `genusSlack (M.φ) (outerDualAlpha hNT) = 0`: deleting the outer edges from the
genus-0 dual map keeps the slack at zero. -/
lemma genusSlack_outerDualAlpha_eq_zero (hNT : NearTriangulation M) :
    genusSlack M.φ (outerDualAlpha hNT) = 0 := by
  -- `rawAlpha` for the dual map `dualMap M`: its `σ = M.φ`, `α = M.α`, so `rawAlpha`
  -- on the dual map is definitionally the same perm as `outerDualAlpha`.
  have hclosedD : ∀ d : D, d ∈ OuterDel hNT → (dualMap M).α d ∈ OuterDel hNT := by
    simpa [dualMap_α] using (outerDel_alpha_closed (hNT := hNT))
  have hraw : rawAlpha (dualMap M) (OuterDel hNT) hclosedD = outerDualAlpha hNT := by
    ext d
    by_cases hd : d ∈ OuterDel hNT
    · rw [rawAlpha_eq_self_of_mem (dualMap M) (OuterDel hNT) hclosedD hd,
          outerDualAlpha_eq_self_of_mem (hNT := hNT) hd]
    · rw [rawAlpha_eq_alpha_of_notMem (dualMap M) (OuterDel hNT) hclosedD hd,
          outerDualAlpha_eq_alpha_of_notMem (hNT := hNT) hd, dualMap_α]
  -- need a witness dart; `outerCycle` has positive length
  obtain ⟨d₀⟩ : Nonempty D :=
    ⟨hNT.outerCycle.root⟩
  have hsphere : (dualMap M).IsSphereMap := dualMap_isSphereMap M hNT.sphere
  have h0 := genusSlack_rawAlpha_eq_zero (dualMap M) (OuterDel hNT) hclosedD hsphere d₀
  rw [hraw] at h0
  rwa [dualMap_σ] at h0



/-- The complementary restricted involution `τ := M.α * outerDualAlpha`: identity off
`OuterDel`, `= M.α` on `OuterDel`. -/
noncomputable def outerTau (hNT : NearTriangulation M) : Equiv.Perm D :=
  M.α * outerDualAlpha hNT

lemma outerTau_eq_alpha_of_mem {d : D} (hd : d ∈ OuterDel hNT) :
    outerTau hNT d = M.α d := by
  show M.α (outerDualAlpha hNT d) = M.α d
  rw [outerDualAlpha_eq_self_of_mem (hNT := hNT) hd]

lemma outerTau_eq_self_of_notMem {d : D} (hd : d ∉ OuterDel hNT) :
    outerTau hNT d = d := by
  show M.α (outerDualAlpha hNT d) = d
  rw [outerDualAlpha_eq_alpha_of_notMem (hNT := hNT) hd, M.alpha_alpha]

/-- **The algebraic reduction.**  `M.φ * outerDualAlpha = M.σ * outerTau`. -/
lemma phi_outerDualAlpha_eq_sigma_outerTau (hNT : NearTriangulation M) :
    M.φ * outerDualAlpha hNT = M.σ * outerTau hNT := by
  -- `M.σ * outerTau = M.σ * M.α * outerDualAlpha = M.φ * outerDualAlpha`.
  show M.φ * outerDualAlpha hNT = M.σ * (M.α * outerDualAlpha hNT)
  rw [← mul_assoc]; rfl

/-- **Step 6 (the boundary-bank orbit count) — the single isolated residual.**
`numCycles (M.φ * outerDualAlpha hNT) = M.V − B + 2`, `B = outerCycle.length`.

This is the genuine combinatorial content the route isolates.  By
`phi_outerDualAlpha_eq_sigma_outerTau` it is equivalent to the boundary-bank swap count
`numCycles (M.σ * outerTau hNT) = M.V − B + 2`: the `B` disjoint outer transpositions of
`outerTau` merge the `B` boundary-vertex `σ`-cycles into the two bank cycles (`B − 1`
merges and one closing split).  It is a TRUE statement (forced by `genusSlack = 0` together
with the proved `numComp (OuterDualStep) = 2`), is **clean** (about `M.φ`, `outerDualAlpha`,
`M.V`, and the boundary length only — no reference to the conclusion `numComp = 2`), and is
**not** posited as proved: it is carried as the single named residual `BoundaryBankCount`. -/
def BoundaryBankCount (hNT : NearTriangulation M) : Prop :=
  numCycles (M.φ * outerDualAlpha hNT) = M.V - hNT.outerCycle.length + 2



/-- A dart lies in `OuterDel` iff its edge is a boundary edge. -/
lemma mem_outerDel_iff_boundaryEdge (hNT : NearTriangulation M) {d : D} :
    d ∈ OuterDel hNT ↔ hNT.outerCycle.IsBoundaryEdge (M.dartEdge d) := by
  rw [mem_outerDel_iff]
  constructor
  · rintro (hd | hd)
    · -- `d ∈ darts` ⟹ `dartEdge d ∈ edges`
      show M.dartEdge d ∈ hNT.outerCycle.edges
      rw [hNT.outerCycle.edges_eq]
      exact List.mem_map_of_mem hd
    · -- `α d ∈ darts` ⟹ `dartEdge (α d) = dartEdge d ∈ edges`
      show M.dartEdge d ∈ hNT.outerCycle.edges
      rw [hNT.outerCycle.edges_eq, ← M.dartEdge_alpha d]
      exact List.mem_map_of_mem hd
  · intro hbe
    -- `dartEdge d ∈ edges = darts.map dartEdge`: some boundary dart `e` has `dartEdge e = dartEdge d`.
    have hmem : M.dartEdge d ∈ hNT.outerCycle.darts.map M.dartEdge := by
      rw [← hNT.outerCycle.edges_eq]; exact hbe
    rcases List.mem_map.mp hmem with ⟨e, he, hee⟩
    -- `α.SameCycle d e` ⟹ `d = e ∨ d = α e`
    have hsc : M.α.SameCycle d e :=
      hNT.simpleGraph.no_parallel (by rw [hee])
    rcases (M.alpha_sameCycle_iff d e).mp hsc with hde | hde
    · exact Or.inl (by rw [← hde]; exact he)
    · exact Or.inr (by rw [← hde]; exact he)

/-- A dart lies off `OuterDel` iff its edge is non-boundary. -/
lemma notMem_outerDel_iff_not_boundaryEdge (hNT : NearTriangulation M) {d : D} :
    d ∉ OuterDel hNT ↔ ¬ hNT.outerCycle.IsBoundaryEdge (M.dartEdge d) :=
  not_congr (mem_outerDel_iff_boundaryEdge hNT)

/-- Same face ⟺ `M.φ.SameCycle`. -/
lemma sameFace_iff_phi_sameCycle {a b : D} :
    M.dartFace a = M.dartFace b ↔ M.φ.SameCycle a b := by
  constructor
  · intro h; exact Quotient.exact h
  · intro h; exact Quotient.sound h

/-- The relation `dartStepRel M.φ αout`. -/
abbrev RDart (hNT : NearTriangulation M) : D → D → Prop :=
  dartStepRel M.φ (outerDualAlpha hNT)

/-- A single `RDart`-step descends to `EqvGen (OuterDualStep)` on faces. -/
lemma eqvGen_outerDualStep_of_RDart_step (hNT : NearTriangulation M) {a b : D}
    (h : RDart hNT a b) :
    Relation.EqvGen (OuterDualStep hNT) (M.dartFace a) (M.dartFace b) := by
  rcases h with hsc | hαe
  · -- same face
    have : M.dartFace a = M.dartFace b := sameFace_iff_phi_sameCycle.mpr hsc
    rw [this]; exact Relation.EqvGen.refl _
  · -- `b = αout a`
    by_cases hd : a ∈ OuterDel hNT
    · -- αout a = a so b = a
      rw [hαe, outerDualAlpha_eq_self_of_mem (hNT := hNT) hd]
      exact Relation.EqvGen.refl _
    · -- αout a = M.α a, edge non-boundary ⟹ OuterDualStep
      have hba : b = M.α a := by
        rw [hαe, outerDualAlpha_eq_alpha_of_notMem (hNT := hNT) hd]
      have hnb : ¬ hNT.outerCycle.IsBoundaryEdge (M.dartEdge a) :=
        (notMem_outerDel_iff_not_boundaryEdge hNT).mp hd
      have hstep : OuterDualStep hNT (M.dartFace a) (M.dartFace b) :=
        ⟨a, rfl, by rw [hba], hnb⟩
      exact Relation.EqvGen.rel _ _ hstep

/-- A single `OuterDualStep` lifts to `EqvGen RDart` on any dart reps. -/
lemma eqvGen_RDart_of_outerDualStep (hNT : NearTriangulation M) {f g : M.Face} {a b : D}
    (hstep : OuterDualStep hNT f g) (ha : M.dartFace a = f) (hb : M.dartFace b = g) :
    Relation.EqvGen (RDart hNT) a b := by
  obtain ⟨d, hdf, hdg, hbe⟩ := hstep
  -- d ∉ OuterDel since its edge is non-boundary
  have hdDel : d ∉ OuterDel hNT := (notMem_outerDel_iff_not_boundaryEdge hNT).mpr hbe
  -- a ~ d (same face f)
  have h1 : Relation.EqvGen (RDart hNT) a d :=
    Relation.EqvGen.rel _ _ (Or.inl (sameFace_iff_phi_sameCycle.mp (by rw [ha, hdf])))
  -- d ~ α d (non-boundary α-crossing): `αout d = M.α d`
  have h2 : Relation.EqvGen (RDart hNT) d (M.α d) :=
    Relation.EqvGen.rel _ _ (Or.inr (by
      rw [outerDualAlpha_eq_alpha_of_notMem (hNT := hNT) hdDel]))
  -- α d ~ b (same face g)
  have h3 : Relation.EqvGen (RDart hNT) (M.α d) b :=
    Relation.EqvGen.rel _ _ (Or.inl (sameFace_iff_phi_sameCycle.mp (by rw [hdg, hb])))
  exact (h1.trans _ _ _ h2).trans _ _ _ h3

/-- An `OuterDualStep`-walk lifts to `EqvGen RDart`. -/
lemma eqvGen_RDart_of_outerDualStep_walk (hNT : NearTriangulation M) {f g : M.Face} {a b : D}
    (hwalk : Relation.ReflTransGen (OuterDualStep hNT) f g)
    (ha : M.dartFace a = f) (hb : M.dartFace b = g) :
    Relation.EqvGen (RDart hNT) a b := by
  induction hwalk generalizing b with
  | refl =>
    exact Relation.EqvGen.rel _ _ (Or.inl (sameFace_iff_phi_sameCycle.mp (by rw [ha, hb])))
  | @tail x y hwxy hstep ih =>
    obtain ⟨c, hc⟩ : ∃ c : D, M.dartFace c = x := ⟨Quotient.out x, Quotient.out_eq x⟩
    have hac : Relation.EqvGen (RDart hNT) a c := ih hc
    have hcb : Relation.EqvGen (RDart hNT) c b :=
      eqvGen_RDart_of_outerDualStep hNT hstep hc hb
    exact hac.trans _ _ _ hcb

/-- The full `EqvGen RDart`-walk descends to `EqvGen OuterDualStep` on faces. -/
lemma eqvGen_outerDualStep_of_RDart_eqv (hNT : NearTriangulation M) {a b : D}
    (hab : Relation.EqvGen (RDart hNT) a b) :
    Relation.EqvGen (OuterDualStep hNT) (M.dartFace a) (M.dartFace b) := by
  induction hab with
  | rel x y h => exact eqvGen_outerDualStep_of_RDart_step hNT h
  | refl x => exact Relation.EqvGen.refl _
  | symm x y _ ih => exact ih.symm _ _
  | trans x y z _ _ ih1 ih2 => exact ih1.trans _ _ _ ih2

/-- The face quotient map descends from the dart component quotient. -/
noncomputable def faceQuotMap (hNT : NearTriangulation M) :
    Quotient (compSetoid (RDart hNT)) → Quotient (compSetoid (OuterDualStep hNT)) :=
  Quotient.lift (fun d => Quotient.mk (compSetoid (OuterDualStep hNT)) (M.dartFace d))
    (by
      intro a b hab
      apply Quotient.sound
      exact eqvGen_outerDualStep_of_RDart_eqv hNT hab)

/-- **Step 3 (the dart-face quotient bridge).**  The component count of the dual
sub-involution pair equals the dual-face component count `numComp (OuterDualStep hNT)`. -/
lemma numComponents_eq_numComp_outerDualStep (hNT : NearTriangulation M) :
    numComponents M.φ (outerDualAlpha hNT) = numComp (OuterDualStep hNT) := by
  classical
  rw [numComponents_def]
  show numComp (RDart hNT) = numComp (OuterDualStep hNT)
  unfold numComp
  apply Nat.card_congr
  -- build the equiv via `faceQuotMap`
  refine Equiv.ofBijective (faceQuotMap hNT) ⟨?_, ?_⟩
  · -- injective
    intro x y hxy
    refine Quotient.inductionOn₂ x y (fun a b hab => ?_) hxy
    -- hab : faceQuotMap ⟦a⟧ = faceQuotMap ⟦b⟧, i.e. EqvGen OuterDualStep (dartFace a) (dartFace b)
    apply Quotient.sound
    have heqf : Relation.EqvGen (OuterDualStep hNT) (M.dartFace a) (M.dartFace b) :=
      Quotient.exact hab
    -- convert to ReflTransGen then lift
    have hwalk : Relation.ReflTransGen (OuterDualStep hNT) (M.dartFace a) (M.dartFace b) :=
      (eqvGen_outerDualStep_iff (hNT := hNT)).1 heqf
    exact eqvGen_RDart_of_outerDualStep_walk hNT hwalk rfl rfl
  · -- surjective
    intro q
    refine Quotient.inductionOn q (fun f => ?_)
    obtain ⟨d, hd⟩ : ∃ d : D, M.dartFace d = f := ⟨Quotient.out f, Quotient.out_eq f⟩
    exact ⟨Quotient.mk (compSetoid (RDart hNT)) d, by
      show Quotient.mk _ (M.dartFace d) = Quotient.mk _ f
      rw [hd]⟩



/-- **The crux of Chapter 35, conditional on the single boundary-bank residual.**  Given
the boundary-bank face count (Step 6), the outer-dual component count is `2`.  All of
Steps 1–5 and the dart-face bridge (Step 3) plus the Euler arithmetic are proved
unconditionally and clean-3; only `BoundaryBankCount` is carried as a hypothesis. -/
theorem outerDualNumCompTwo_of_boundaryBankCount (hNT : NearTriangulation M)
    (h6 : BoundaryBankCount hNT) :
    numComp (OuterDualStep hNT) = 2 := by
  -- expand `genusSlack M.φ αout = 0` with Steps 3, 5, 6 and Euler.
  have h0 : genusSlack M.φ (outerDualAlpha hNT) = 0 :=
    genusSlack_outerDualAlpha_eq_zero hNT
  have hE5 : Ehalf (outerDualAlpha hNT) = M.E - hNT.outerCycle.length :=
    Ehalf_outerDualAlpha hNT
  have h6 : numCycles (M.φ * outerDualAlpha hNT)
      = M.V - hNT.outerCycle.length + 2 := h6
  have hbridge : numComponents M.φ (outerDualAlpha hNT) = numComp (OuterDualStep hNT) :=
    numComponents_eq_numComp_outerDualStep hNT
  -- `numCycles M.φ = M.F`
  have hF : numCycles M.φ = M.F := (M.F_eq_numCycles).symm
  -- Euler `V − E + F = 2`
  have hEuler : (M.V : ℤ) - (M.E : ℤ) + (M.F : ℤ) = 2 := hNT.sphere.2
  -- bounds so the ℕ-subtractions in Steps 5/6 are genuine
  set B := hNT.outerCycle.length with hB
  have hBE : B ≤ M.E := outerCycle_length_le_E hNT
  -- expand genusSlack
  unfold genusSlack at h0
  rw [hbridge, hF, hE5, h6] at h0
  -- now h0 : 2 * c - F + (E - B) - (V - B + 2) = 0  over ℤ with ℕ-subtractions cast
  -- turn ℕ-subtraction casts into honest ℤ using hBE and (V-B+2)
  have hcast5 : ((M.E - B : ℕ) : ℤ) = (M.E : ℤ) - (B : ℤ) := by
    rw [Nat.cast_sub hBE]
  have hcast6 : ((M.V - B + 2 : ℕ) : ℤ) = (M.V : ℤ) - (B : ℤ) + 2 := by
    have hBV : B ≤ M.V := outerCycle_length_le_V hNT
    push_cast [Nat.cast_sub hBV]; ring
  rw [hcast5, hcast6] at h0
  -- solve for c with Euler
  have hc : (numComp (OuterDualStep hNT) : ℤ) = 2 := by linarith
  exact_mod_cast hc

/-- **Discharge of the Chapter-35 residual `OuterDualNumCompTwo`, conditional on the single
boundary-bank face count.**  `OuterDualNumCompTwo hNT` is definitionally
`numComp (OuterDualStep hNT) = 2`, so this follows from
`outerDualNumCompTwo_of_boundaryBankCount`.  Combined with the easy half
`innerFacesDualConnected_of_outerDual_numComp_two` (already in `ZinanCh35OuterCount`), it
cascades the whole chapter once `BoundaryBankCount` is supplied. -/
theorem outerDualNumCompTwo_of_boundaryBankCount' (hNT : NearTriangulation M)
    (h6 : BoundaryBankCount hNT) :
    OuterDualNumCompTwo hNT :=
  outerDualNumCompTwo_of_boundaryBankCount hNT h6

end ProofsInTheBook.ZinanCh35OuterSlack













end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35OuterSlack
-/
/- Source module: ProofsInTheBook.ZinanCh35BankCount -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option linter.unnecessarySimpa false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35BankCount

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ZinanCh35OuterDual
open ProofsInTheBook.ZinanCh35OuterSlack
open Equiv Equiv.Perm

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}

variable {hNT : NearTriangulation M}



/-- The boundary length `B`. -/
local notation3 "B" => hNT.outerCycle.length

/-- The `i`-th boundary dart `q i`. -/
noncomputable def qd (hNT : NearTriangulation M) (i : Fin hNT.outerCycle.length) : D :=
  hNT.outerCycle.darts.get ⟨i.1, by simpa [BoundaryCycle.length] using i.2⟩

/-- The `α`-partner `r i := M.α (q i)`. -/
noncomputable def rd (hNT : NearTriangulation M) (i : Fin hNT.outerCycle.length) : D :=
  M.α (qd hNT i)

/-- Cyclic successor index on `Fin B`. -/
noncomputable def nextIdx (hNT : NearTriangulation M) (i : Fin hNT.outerCycle.length) :
    Fin hNT.outerCycle.length :=
  ⟨(i.1 + 1) % hNT.outerCycle.length,
    Nat.mod_lt _ (by simpa [BoundaryCycle.length] using hNT.outerCycle.darts_length_pos)⟩

lemma nextIdx_val (i : Fin hNT.outerCycle.length) :
    (nextIdx hNT i).1 = (i.1 + 1) % hNT.outerCycle.length := rfl

/-- `q i` is a boundary dart. -/
lemma qd_mem (i : Fin hNT.outerCycle.length) : qd hNT i ∈ hNT.outerCycle.darts := by
  unfold qd
  exact List.get_mem _ _

/-- `q i ∈ OuterDel`. -/
lemma qd_mem_outerDel (i : Fin hNT.outerCycle.length) : qd hNT i ∈ OuterDel hNT := by
  rw [mem_outerDel_iff]; exact Or.inl (qd_mem i)

/-- `r i ∈ OuterDel`. -/
lemma rd_mem_outerDel (i : Fin hNT.outerCycle.length) : rd hNT i ∈ OuterDel hNT := by
  rw [mem_outerDel_iff]; right
  show M.α (M.α (qd hNT i)) ∈ hNT.outerCycle.darts
  rw [M.alpha_alpha]; exact qd_mem i



lemma qd_inj {i j : Fin hNT.outerCycle.length} (h : qd hNT i = qd hNT j) : i = j := by
  unfold qd at h
  have := (hNT.outerCycle.darts_nodup.getElem_inj_iff).mp h
  exact Fin.ext (by simpa using this)



lemma rd_inj {i j : Fin hNT.outerCycle.length} (h : rd hNT i = rd hNT j) : i = j :=
  qd_inj (M.α.injective h)

lemma qd_ne_rd (i j : Fin hNT.outerCycle.length) : qd hNT i ≠ rd hNT j := by
  intro h
  -- q i ∈ darts, r j = α (q j) ∉ darts (partner of boundary dart).
  have hmem : M.α (qd hNT j) ∈ hNT.outerCycle.darts := by
    show rd hNT j ∈ hNT.outerCycle.darts
    rw [← h]; exact qd_mem i
  exact alpha_notMem_darts_of_mem (hNT := hNT) (qd_mem j) hmem

lemma rd_ne_qd (i j : Fin hNT.outerCycle.length) : rd hNT i ≠ qd hNT j :=
  fun h => qd_ne_rd j i h.symm

lemma qd_ne_rd_self (i : Fin hNT.outerCycle.length) : qd hNT i ≠ rd hNT i := qd_ne_rd i i



/-- `M.σ (r i) = q (next i)`: because `σ = φ ∘ α` and the boundary darts cycle under `φ`. -/
lemma sigma_rd_eq_qd_next (i : Fin hNT.outerCycle.length) :
    M.σ (rd hNT i) = qd hNT (nextIdx hNT i) := by
  -- σ (α (q i)) = φ (q i) = darts.get (cyclicNext i)
  have hσ : M.σ (rd hNT i) = M.φ (qd hNT i) := by
    show M.σ (M.α (qd hNT i)) = M.φ (qd hNT i)
    show M.σ (M.α (qd hNT i)) = (M.σ * M.α) (qd hNT i)
    rw [Equiv.Perm.mul_apply]
  rw [hσ]
  -- consecutive_phi: darts.get (cyclicNext i₀) = φ (darts.get i₀)
  set i₀ : Fin hNT.outerCycle.darts.length :=
    ⟨i.1, by simpa [BoundaryCycle.length] using i.2⟩ with hi₀
  have hcp := hNT.outerCycle.consecutive_phi i₀
  show M.φ (hNT.outerCycle.darts.get i₀) = qd hNT (nextIdx hNT i)
  rw [← hcp]
  -- both sides are `darts.get` at index (i+1) % B
  unfold qd nextIdx
  congr 1



/-- `M.σ.SameCycle a b` is `M.tail a = M.tail b`. -/
lemma sigma_sameCycle_iff_tail (a b : D) :
    M.σ.SameCycle a b ↔ M.tail a = M.tail b := by
  show M.σ.SameCycle a b ↔
    (Quotient.mk (cycleSetoid M.σ) a : Quotient (cycleSetoid M.σ)) = Quotient.mk _ b
  rw [Quotient.eq]
  rfl

/-- Distinct boundary darts are in distinct `σ`-cycles: `σ.SameCycle (q i) (q j) ↔ i = j`. -/
lemma sigma_sameCycle_qd_qd (i j : Fin hNT.outerCycle.length) :
    M.σ.SameCycle (qd hNT i) (qd hNT j) ↔ i = j := by
  rw [sigma_sameCycle_iff_tail]
  constructor
  · intro h
    have := hNT.outerCycle.tail_injective_on_darts hNT.outer_simple (qd_mem i) (qd_mem j) h
    exact qd_inj this
  · intro h; rw [h]



/-- The embedding `Fin (B−1) ↪ Fin B`. -/
noncomputable def emb (hNT : NearTriangulation M) (j : Fin (hNT.outerCycle.length - 1)) :
    Fin hNT.outerCycle.length :=
  ⟨j.1, by have := j.2; omega⟩

/-- The ordered list of the first `B−1` outer transposition pairs `(q j, r j)`. -/
noncomputable def mergePairs (hNT : NearTriangulation M) : List (D × D) :=
  (List.finRange (hNT.outerCycle.length - 1)).map (fun j => (qd hNT (emb hNT j), rd hNT (emb hNT j)))

/-- The partial product permutation after the first `k` merge swaps. -/
noncomputable def pPrefix (hNT : NearTriangulation M) (k : ℕ) : Equiv.Perm D :=
  M.σ * (((mergePairs hNT).take k).map (fun w => Equiv.swap w.1 w.2)).prod

lemma pPrefix_zero : pPrefix hNT 0 = M.σ := by simp [pPrefix]

/-- The dart at block position `m < B` (the `m`-th `q`). -/
lemma mergePairs_get_fst (k : ℕ) (hk : k < hNT.outerCycle.length - 1) :
    (mergePairs hNT).get ⟨k, by simpa [mergePairs] using hk⟩
      = (qd hNT ⟨k, by omega⟩, rd hNT ⟨k, by omega⟩) := by
  unfold mergePairs
  rw [List.get_eq_getElem, List.getElem_map, List.getElem_finRange]
  rfl

/-- Length of `mergePairs` is `B − 1`. -/
lemma mergePairs_length : (mergePairs hNT).length = hNT.outerCycle.length - 1 := by
  simp [mergePairs]

/-- One-step recurrence for the partial products: appending the `k`-th merge swap. -/
lemma pPrefix_succ (k : ℕ) (hk : k < hNT.outerCycle.length - 1) :
    pPrefix hNT (k + 1)
      = pPrefix hNT k * Equiv.swap (qd hNT ⟨k, by omega⟩) (rd hNT ⟨k, by omega⟩) := by
  unfold pPrefix
  have hlen : k < (mergePairs hNT).length := by rw [mergePairs_length]; exact hk
  -- take (k+1) = take k ++ [get k]
  have htake : (mergePairs hNT).take (k + 1)
      = (mergePairs hNT).take k ++ [(mergePairs hNT).get ⟨k, hlen⟩] := by
    rw [List.get_eq_getElem]
    exact List.take_succ_eq_append_getElem hlen
  rw [htake, List.map_append, List.prod_append, mergePairs_get_fst k hk]
  simp [mul_assoc]



/-- For a non-final index, `nextIdx` increments the value (no wraparound). -/
lemma nextIdx_val_of_lt {i : Fin hNT.outerCycle.length} (hi : i.1 < hNT.outerCycle.length - 1) :
    (nextIdx hNT i).1 = i.1 + 1 := by
  rw [nextIdx_val, Nat.mod_eq_of_lt (by omega)]

/-- `nextIdx` is injective. -/
lemma nextIdx_inj {i j : Fin hNT.outerCycle.length} (h : nextIdx hNT i = nextIdx hNT j) :
    i = j := by
  have hpos : 0 < hNT.outerCycle.length := by
    simpa [BoundaryCycle.length] using hNT.outerCycle.darts_length_pos
  have hval := congrArg Fin.val h
  rw [nextIdx_val, nextIdx_val] at hval
  apply Fin.ext
  have hi := i.2; have hj := j.2
  -- both (i+1) and (j+1) lie in [1, B]; equal mod B ⟹ equal
  rcases Nat.lt_or_ge (i.1 + 1) hNT.outerCycle.length with hi1 | hi1
  · rw [Nat.mod_eq_of_lt hi1] at hval
    rcases Nat.lt_or_ge (j.1 + 1) hNT.outerCycle.length with hj1 | hj1
    · rw [Nat.mod_eq_of_lt hj1] at hval; omega
    · have : j.1 + 1 = hNT.outerCycle.length := by omega
      rw [this, Nat.mod_self] at hval; omega
  · have hib : i.1 + 1 = hNT.outerCycle.length := by omega
    rw [hib, Nat.mod_self] at hval
    rcases Nat.lt_or_ge (j.1 + 1) hNT.outerCycle.length with hj1 | hj1
    · rw [Nat.mod_eq_of_lt hj1] at hval; omega
    · have : j.1 + 1 = hNT.outerCycle.length := by omega
      omega



/-- The simultaneous invariant after `k` merges (`q i` joins the block once `i.1 ≤ k`). -/
lemma bankInvariant :
    ∀ k : ℕ, k + 1 ≤ hNT.outerCycle.length →
      (∀ i j : Fin hNT.outerCycle.length,
          (pPrefix hNT k).SameCycle (qd hNT i) (qd hNT j)
            ↔ i = j ∨ (i.1 ≤ k ∧ j.1 ≤ k)) ∧
      (∀ i j : Fin hNT.outerCycle.length,
          (pPrefix hNT k).SameCycle (qd hNT i) (rd hNT j)
            ↔ i = nextIdx hNT j ∨ (i.1 ≤ k ∧ (nextIdx hNT j).1 ≤ k)) ∧
      (∀ i j : Fin hNT.outerCycle.length,
          (pPrefix hNT k).SameCycle (rd hNT i) (rd hNT j)
            ↔ i = j ∨ ((nextIdx hNT i).1 ≤ k ∧ (nextIdx hNT j).1 ≤ k)) := by
  intro k
  induction k with
  | zero =>
      intro _
      rw [pPrefix_zero]
      refine ⟨?_, ?_, ?_⟩
      · -- q-q base: σ.SameCycle (q i)(q j) ↔ i = j
        intro i j
        rw [sigma_sameCycle_qd_qd]
        constructor
        · exact Or.inl
        · rintro (h | ⟨hi, hj⟩)
          · exact h
          · exact Fin.ext (by omega)
      · -- q-r base: σ.SameCycle (q i)(r j) ↔ i = next j
        intro i j
        have hr : M.σ.SameCycle (rd hNT j) (qd hNT (nextIdx hNT j)) := by
          rw [← sigma_rd_eq_qd_next]; exact ⟨1, by simp⟩
        constructor
        · intro h
          have : M.σ.SameCycle (qd hNT i) (qd hNT (nextIdx hNT j)) := h.trans hr
          left; exact (sigma_sameCycle_qd_qd i (nextIdx hNT j)).mp this
        · rintro (h | ⟨hi, hcon⟩)
          · subst h; exact hr.symm
          · -- i ≤ 0 ∧ (next j) ≤ 0 ⟹ i = next j
            have : i = nextIdx hNT j := Fin.ext (by omega)
            subst this; exact hr.symm
      · -- r-r base
        intro i j
        have hri : M.σ.SameCycle (rd hNT i) (qd hNT (nextIdx hNT i)) := by
          rw [← sigma_rd_eq_qd_next]; exact ⟨1, by simp⟩
        have hrj : M.σ.SameCycle (rd hNT j) (qd hNT (nextIdx hNT j)) := by
          rw [← sigma_rd_eq_qd_next]; exact ⟨1, by simp⟩
        constructor
        · intro h
          have : M.σ.SameCycle (qd hNT (nextIdx hNT i)) (qd hNT (nextIdx hNT j)) :=
            (hri.symm.trans h).trans hrj
          left; exact nextIdx_inj ((sigma_sameCycle_qd_qd _ _).mp this)
        · rintro (h | ⟨hci, hcj⟩)
          · subst h; exact SameCycle.rfl
          · have : nextIdx hNT i = nextIdx hNT j := Fin.ext (by omega)
            rw [nextIdx_inj this]
  | succ k ih =>
      intro hk1
      have hkB1 : k < hNT.outerCycle.length - 1 := by omega
      have hkB : k < hNT.outerCycle.length := by omega
      obtain ⟨ihqq, ihqr, ihrr⟩ := ih (by omega)
      set a := qd hNT ⟨k, hkB⟩ with ha
      set b := rd hNT ⟨k, hkB⟩ with hb
      have hnextk : (nextIdx hNT ⟨k, hkB⟩).1 = k + 1 := nextIdx_val_of_lt (by simpa using hkB1)
      have hak : (⟨k, hkB⟩ : Fin hNT.outerCycle.length).1 = k := rfl
      have hnsc : ¬ (pPrefix hNT k).SameCycle a b := by
        rw [ha, hb, ihqr ⟨k, hkB⟩ ⟨k, hkB⟩]
        rintro (hcon | ⟨_, hcon⟩)
        · have := congrArg Fin.val hcon; rw [hnextk] at this; simp at this
        · rw [hnextk] at hcon; omega
      have hstep := pPrefix_succ (hNT := hNT) k hkB1
      have engine : ∀ x y : D,
          (pPrefix hNT (k + 1)).SameCycle x y ↔
            (pPrefix hNT k).SameCycle x y ∨
              ((pPrefix hNT k).SameCycle x a ∧ (pPrefix hNT k).SameCycle y b) ∨
              ((pPrefix hNT k).SameCycle x b ∧ (pPrefix hNT k).SameCycle y a) := by
        intro x y
        rw [hstep]
        exact PermTranspositionCycleCount.sameCycle_mul_swap_iff_mergeRel_of_not_sameCycle
          (pPrefix hNT k) hnsc (x := x) (y := y)
      -- abbreviation: q i ~ a (= q ⟨k⟩) iff i.1 ≤ k
      have hqa : ∀ i : Fin hNT.outerCycle.length,
          (pPrefix hNT k).SameCycle (qd hNT i) a ↔ i.1 ≤ k := by
        intro i; rw [ha, ihqq i ⟨k, hkB⟩]
        constructor
        · rintro (h | ⟨hi, _⟩)
          · exact le_of_eq (congrArg Fin.val h)
          · exact hi
        · intro hi
          rcases Nat.lt_or_ge i.1 k with h | h
          · exact Or.inr ⟨by omega, le_refl k⟩
          · exact Or.inl (Fin.ext (le_antisymm hi h))
      -- q i ~ b (= r ⟨k⟩) iff i = next ⟨k⟩ (= ⟨k+1⟩) [block bound k+1 ≤ k impossible]
      have hqb : ∀ i : Fin hNT.outerCycle.length,
          (pPrefix hNT k).SameCycle (qd hNT i) b ↔ i.1 = k + 1 := by
        intro i; rw [hb, ihqr i ⟨k, hkB⟩, hnextk]
        constructor
        · rintro (h | ⟨_, hcon⟩)
          · have := congrArg Fin.val h; rw [hnextk] at this; exact this
          · omega
        · intro hi; left; exact Fin.ext (by rw [hnextk]; exact hi)
      -- r i ~ b (= r ⟨k⟩) iff i = ⟨k⟩, i.e. (next i).1 = k+1
      have hrb : ∀ i : Fin hNT.outerCycle.length,
          (pPrefix hNT k).SameCycle (rd hNT i) b ↔ (nextIdx hNT i).1 = k + 1 := by
        intro i; rw [hb, ihrr i ⟨k, hkB⟩, hnextk]
        constructor
        · rintro (h | ⟨hi, hcon⟩)
          · subst h; rw [hnextk]
          · omega
        · intro hi; left; exact nextIdx_inj (Fin.ext (by rw [hnextk]; omega))
      refine ⟨?_, ?_, ?_⟩
      · -- q-q at k+1
        intro i j
        rw [engine (qd hNT i) (qd hNT j), ihqq i j, hqa i, hqb j, hqb i, hqa j]
        constructor
        · rintro (h | ⟨hi, hj⟩ | ⟨hi, hj⟩)
          · rcases h with h | ⟨hi, hj⟩
            · exact Or.inl h
            · exact Or.inr ⟨by omega, by omega⟩
          · -- i ≤ k, j.1 = k+1
            right; refine ⟨by omega, by omega⟩
          · right; refine ⟨by omega, by omega⟩
        · rintro (h | ⟨hi, hj⟩)
          · exact Or.inl (Or.inl h)
          · -- i ≤ k+1, j ≤ k+1
            rcases Nat.lt_or_ge i.1 (k+1) with hik | hik
            · rcases Nat.lt_or_ge j.1 (k+1) with hjk | hjk
              · exact Or.inl (Or.inr ⟨by omega, by omega⟩)
              · -- j.1 = k+1, i ≤ k
                right; left; exact ⟨by omega, by omega⟩
            · -- i.1 = k+1
              rcases Nat.lt_or_ge j.1 (k+1) with hjk | hjk
              · right; right; exact ⟨by omega, by omega⟩
              · -- both = k+1 ⟹ i = j
                exact Or.inl (Or.inl (Fin.ext (by omega)))
      · -- q-r at k+1
        intro i j
        rw [engine (qd hNT i) (rd hNT j), ihqr i j, hqa i, hrb j, hqb i]
        -- (pPrefix k).SameCycle (r j) a = (q-a symm): r j ~ q⟨k⟩ ↔ (next j).1 ≤ k
        have hrja : (pPrefix hNT k).SameCycle (rd hNT j) a ↔ (nextIdx hNT j).1 ≤ k := by
          rw [ha, Equiv.Perm.sameCycle_comm, ihqr ⟨k, hkB⟩ j]
          constructor
          · rintro (h | ⟨_, hj⟩)
            · have : (nextIdx hNT j).1 = k := (congrArg Fin.val h).symm
              omega
            · exact hj
          · intro hj
            rcases Nat.lt_or_ge (nextIdx hNT j).1 k with h | h
            · exact Or.inr ⟨by omega, by omega⟩
            · left; exact Fin.ext (by omega)
        rw [hrja]
        constructor
        · rintro (h | ⟨hi, hj⟩ | ⟨hi, hj⟩)
          · rcases h with h | ⟨hi, hj⟩
            · exact Or.inl h
            · exact Or.inr ⟨by omega, by omega⟩
          · -- i ≤ k ∧ (next j).1 ≤ k+1
            right; exact ⟨by omega, by omega⟩
          · -- i.1 = k+1 ∧ (next j).1 ≤ k
            right; exact ⟨by omega, by omega⟩
        · rintro (h | ⟨hi, hnj⟩)
          · exact Or.inl (Or.inl h)
          · rcases Nat.lt_or_ge i.1 (k+1) with hik | hik
            · rcases Nat.lt_or_ge (nextIdx hNT j).1 (k+1) with hnjk | hnjk
              · exact Or.inl (Or.inr ⟨by omega, by omega⟩)
              · right; left; exact ⟨by omega, by omega⟩
            · -- i.1 = k+1
              rcases Nat.lt_or_ge (nextIdx hNT j).1 (k+1) with hnjk | hnjk
              · -- (next j) ≤ k
                right; right; exact ⟨by omega, by omega⟩
              · -- i.1 = k+1 and (next j).1 = k+1 ⟹ i = next j
                exact Or.inl (Or.inl (Fin.ext (by omega)))
      · -- r-r at k+1
        intro i j
        rw [engine (rd hNT i) (rd hNT j), ihrr i j, hrb j, hrb i]
        have hria : (pPrefix hNT k).SameCycle (rd hNT i) a ↔ (nextIdx hNT i).1 ≤ k := by
          rw [ha, Equiv.Perm.sameCycle_comm, ihqr ⟨k, hkB⟩ i]
          constructor
          · rintro (h | ⟨_, hi⟩)
            · have := congrArg Fin.val h; omega
            · exact hi
          · intro hi
            rcases Nat.lt_or_ge (nextIdx hNT i).1 k with h | h
            · exact Or.inr ⟨by omega, by omega⟩
            · left; exact Fin.ext (by omega)
        have hrja : (pPrefix hNT k).SameCycle (rd hNT j) a ↔ (nextIdx hNT j).1 ≤ k := by
          rw [ha, Equiv.Perm.sameCycle_comm, ihqr ⟨k, hkB⟩ j]
          constructor
          · rintro (h | ⟨_, hj⟩)
            · have := congrArg Fin.val h; omega
            · exact hj
          · intro hj
            rcases Nat.lt_or_ge (nextIdx hNT j).1 k with h | h
            · exact Or.inr ⟨by omega, by omega⟩
            · left; exact Fin.ext (by omega)
        rw [hria, hrja]
        constructor
        · rintro (h | ⟨hi, hj⟩ | ⟨hi, hj⟩)
          · rcases h with h | ⟨hi, hj⟩
            · exact Or.inl h
            · exact Or.inr ⟨by omega, by omega⟩
          · right; exact ⟨by omega, by omega⟩
          · right; exact ⟨by omega, by omega⟩
        · rintro (h | ⟨hni, hnj⟩)
          · exact Or.inl (Or.inl h)
          · rcases Nat.lt_or_ge (nextIdx hNT i).1 (k+1) with hnik | hnik
            · rcases Nat.lt_or_ge (nextIdx hNT j).1 (k+1) with hnjk | hnjk
              · exact Or.inl (Or.inr ⟨by omega, by omega⟩)
              · right; left; exact ⟨by omega, by omega⟩
            · rcases Nat.lt_or_ge (nextIdx hNT j).1 (k+1) with hnjk | hnjk
              · right; right; exact ⟨by omega, by omega⟩
              · -- both next = k+1 ⟹ i = j
                have : nextIdx hNT i = nextIdx hNT j := Fin.ext (by omega)
                exact Or.inl (Or.inl (nextIdx_inj this))



/-- The fully-merged permutation after all `B−1` merges. -/
noncomputable def pMerge (hNT : NearTriangulation M) : Equiv.Perm D :=
  pPrefix hNT (hNT.outerCycle.length - 1)

/-- The `B−1` merge swaps each merge two distinct cycles of the running product. -/
lemma mergePairs_merge_condition :
    ∀ j : Fin (mergePairs hNT).length,
      ((mergePairs hNT).get j).1 ≠ ((mergePairs hNT).get j).2 ∧
        ¬ (M.σ * (((mergePairs hNT).take j).map (fun w => Equiv.swap w.1 w.2)).prod).SameCycle
            ((mergePairs hNT).get j).1 ((mergePairs hNT).get j).2 := by
  intro j
  have he : (mergePairs hNT).length = hNT.outerCycle.length - 1 := mergePairs_length
  have hjlen : (j : ℕ) < hNT.outerCycle.length - 1 := by have := j.2; omega
  have hjB : (j : ℕ) < hNT.outerCycle.length := by omega
  rw [mergePairs_get_fst (j : ℕ) hjlen]
  -- the running product is pPrefix j
  have hpp : M.σ * (((mergePairs hNT).take (j : ℕ)).map (fun w => Equiv.swap w.1 w.2)).prod
      = pPrefix hNT (j : ℕ) := rfl
  refine ⟨?_, ?_⟩
  · -- q ⟨j⟩ ≠ r ⟨j⟩
    exact qd_ne_rd_self ⟨(j : ℕ), hjB⟩
  · rw [hpp]
    obtain ⟨_, ihqr, _⟩ := bankInvariant (hNT := hNT) (j : ℕ) (by omega)
    rw [ihqr ⟨(j : ℕ), hjB⟩ ⟨(j : ℕ), hjB⟩]
    have hnext : (nextIdx hNT ⟨(j : ℕ), hjB⟩).1 = (j : ℕ) + 1 :=
      nextIdx_val_of_lt (by simpa using hjlen)
    rintro (hcon | ⟨_, hcon⟩)
    · have := congrArg Fin.val hcon; rw [hnext] at this; simp at this
    · rw [hnext] at hcon; omega

/-- After all `B−1` merges, the cycle count is `V − (B−1)`. -/
lemma numCycles_pMerge_add :
    _root_.numCycles (pMerge hNT) + (hNT.outerCycle.length - 1) = M.V := by
  have hmerge := CombMap.CutCapCount.numCycles_mul_listSwap_merges M.σ (mergePairs hNT)
    (mergePairs_merge_condition (hNT := hNT))
  rw [mergePairs_length] at hmerge
  -- pMerge = M.σ * swapProd mergePairs = pPrefix (B-1) (since take (B-1) = whole list)
  have hpm : pMerge hNT = M.σ * ((mergePairs hNT).map (fun w => Equiv.swap w.1 w.2)).prod := by
    unfold pMerge pPrefix
    rw [List.take_of_length_le (by rw [mergePairs_length])]
  rw [hpm, hmerge, M.V_eq_numCycles]

lemma length_pos' : 0 < hNT.outerCycle.length :=
  hNT.outerCycle.darts_length_pos

/-- The last boundary pair `(q last, r last)`, `last = ⟨B−1⟩`. -/
noncomputable def lastIdx (hNT : NearTriangulation M) : Fin hNT.outerCycle.length :=
  ⟨hNT.outerCycle.length - 1, by have := length_pos' (hNT := hNT); omega⟩

/-- In `pMerge`, the last pair lies in the same cycle (so the closing swap splits). -/
lemma pMerge_lastPair_sameCycle :
    (pMerge hNT).SameCycle (qd hNT (lastIdx hNT)) (rd hNT (lastIdx hNT)) := by
  unfold pMerge
  have hBpos : 0 < hNT.outerCycle.length := hNT.outerCycle.darts_length_pos
  obtain ⟨_, ihqr, _⟩ := bankInvariant (hNT := hNT) (hNT.outerCycle.length - 1) (by omega)
  rw [ihqr (lastIdx hNT) (lastIdx hNT)]
  -- last.1 = B-1 ≤ B-1 and (next last).1 = 0 ≤ B-1
  right
  have hnl : (nextIdx hNT (lastIdx hNT)).1 = 0 := by
    rw [nextIdx_val]
    show ((hNT.outerCycle.length - 1) + 1) % hNT.outerCycle.length = 0
    rw [Nat.sub_add_cancel (by omega), Nat.mod_self]
  refine ⟨?_, ?_⟩
  · show (hNT.outerCycle.length - 1) ≤ hNT.outerCycle.length - 1; exact le_refl _
  · rw [hnl]; exact Nat.zero_le _



/-- Evaluation of the disjoint-swap product at a `q`-dart whose index is in the (nodup) list. -/
lemma listSwapQR_apply_qd (m : Fin hNT.outerCycle.length) :
    ∀ L : List (Fin hNT.outerCycle.length), L.Nodup → m ∈ L →
      ((L.map (fun i => (qd hNT i, rd hNT i))).map (fun w => Equiv.swap w.1 w.2)).prod
          (qd hNT m) = rd hNT m := by
  intro L
  induction L with
  | nil => intro _ hm; simp only [List.not_mem_nil] at hm
  | cons c t ih =>
      intro hnd hm
      rw [List.map_cons, List.map_cons, List.prod_cons, Equiv.Perm.mul_apply]
      have hndt := (List.nodup_cons.mp hnd)
      by_cases hmt : m ∈ t
      · -- m ∈ t, so c ≠ m (nodup); tail moves q m ↦ r m, head fixes r m
        have hcm : c ≠ m := fun h => hndt.1 (h ▸ hmt)
        rw [ih hndt.2 hmt]
        show Equiv.swap (qd hNT c) (rd hNT c) (rd hNT m) = rd hNT m
        rw [Equiv.swap_apply_of_ne_of_ne (rd_ne_qd m c) (fun h => hcm (rd_inj h).symm)]
      · -- m = c
        have hmc : m = c := by
          rcases List.mem_cons.mp hm with h | h
          · exact h
          · exact absurd h hmt
        subst hmc
        -- tail fixes q m
        have htail : ((t.map (fun i => (qd hNT i, rd hNT i))).map (fun w => Equiv.swap w.1 w.2)).prod
            (qd hNT m) = qd hNT m := by
          apply CombMap.CutCapCount.listSwap_prod_apply_of_notMem
          intro w hw
          rw [List.mem_map] at hw
          obtain ⟨i, hi, hwi⟩ := hw
          have hineq : i ≠ m := fun h => hmt (h ▸ hi)
          subst hwi
          exact ⟨fun h => hineq (qd_inj h).symm, qd_ne_rd m i⟩
        rw [htail]
        show Equiv.swap (qd hNT m) (rd hNT m) (qd hNT m) = rd hNT m
        rw [Equiv.swap_apply_left]

/-- Evaluation of the disjoint-swap product at an `r`-dart whose index is in the (nodup) list. -/
lemma listSwapQR_apply_rd (m : Fin hNT.outerCycle.length) :
    ∀ L : List (Fin hNT.outerCycle.length), L.Nodup → m ∈ L →
      ((L.map (fun i => (qd hNT i, rd hNT i))).map (fun w => Equiv.swap w.1 w.2)).prod
          (rd hNT m) = qd hNT m := by
  intro L
  induction L with
  | nil => intro _ hm; simp only [List.not_mem_nil] at hm
  | cons c t ih =>
      intro hnd hm
      rw [List.map_cons, List.map_cons, List.prod_cons, Equiv.Perm.mul_apply]
      have hndt := (List.nodup_cons.mp hnd)
      by_cases hmt : m ∈ t
      · have hcm : c ≠ m := fun h => hndt.1 (h ▸ hmt)
        rw [ih hndt.2 hmt]
        show Equiv.swap (qd hNT c) (rd hNT c) (qd hNT m) = qd hNT m
        rw [Equiv.swap_apply_of_ne_of_ne (fun h => hcm (qd_inj h).symm) (qd_ne_rd m c)]
      · have hmc : m = c := by
          rcases List.mem_cons.mp hm with h | h
          · exact h
          · exact absurd h hmt
        subst hmc
        have htail : ((t.map (fun i => (qd hNT i, rd hNT i))).map (fun w => Equiv.swap w.1 w.2)).prod
            (rd hNT m) = rd hNT m := by
          apply CombMap.CutCapCount.listSwap_prod_apply_of_notMem
          intro w hw
          rw [List.mem_map] at hw
          obtain ⟨i, hi, hwi⟩ := hw
          have hineq : i ≠ m := fun h => hmt (h ▸ hi)
          subst hwi
          exact ⟨rd_ne_qd m i, fun h => hineq (rd_inj h).symm⟩
        rw [htail]
        show Equiv.swap (qd hNT m) (rd hNT m) (rd hNT m) = qd hNT m
        rw [Equiv.swap_apply_right]

/-- Evaluation at a dart that is neither a `q`- nor `r`-dart of the list: it is fixed. -/
lemma listSwapQR_apply_other (d : D)
    (L : List (Fin hNT.outerCycle.length))
    (hd : ∀ i ∈ L, d ≠ qd hNT i ∧ d ≠ rd hNT i) :
    ((L.map (fun i => (qd hNT i, rd hNT i))).map (fun w => Equiv.swap w.1 w.2)).prod d = d := by
  apply CombMap.CutCapCount.listSwap_prod_apply_of_notMem
  intro w hw
  rw [List.mem_map] at hw
  obtain ⟨i, hi, hwi⟩ := hw
  subst hwi
  exact hd i hi

/-- A boundary dart is some `qd m`. -/
lemma exists_qd_of_mem_darts {d : D} (hd : d ∈ hNT.outerCycle.darts) :
    ∃ m : Fin hNT.outerCycle.length, d = qd hNT m := by
  obtain ⟨n, hgn⟩ := List.get_of_mem hd
  refine ⟨⟨n.1, by simpa [BoundaryCycle.length] using n.2⟩, ?_⟩
  unfold qd; rw [← hgn]

/-- The full pair list over all `B` indices. -/
noncomputable def allPairs (hNT : NearTriangulation M) : List (D × D) :=
  (List.finRange hNT.outerCycle.length).map (fun i => (qd hNT i, rd hNT i))

/-- `outerTau` is the product of the `B` disjoint outer transpositions. -/
lemma outerTau_eq_swapProd :
    outerTau hNT = ((allPairs hNT).map (fun w => Equiv.swap w.1 w.2)).prod := by
  have hnd : (List.finRange hNT.outerCycle.length).Nodup := List.nodup_finRange _
  ext d
  unfold allPairs
  by_cases hd : d ∈ OuterDel hNT
  · rw [outerTau_eq_alpha_of_mem (hNT := hNT) hd]
    rw [mem_outerDel_iff] at hd
    rcases hd with hdd | hαd
    · -- d = qd m, α d = rd m
      obtain ⟨m, rfl⟩ := exists_qd_of_mem_darts (hNT := hNT) hdd
      rw [listSwapQR_apply_qd m _ hnd (List.mem_finRange m)]; rfl
    · -- α d ∈ darts ⟹ d = rd m (where α d = qd m)
      obtain ⟨m, hm⟩ := exists_qd_of_mem_darts (hNT := hNT) hαd
      have hdrm : d = rd hNT m := by
        rw [rd]; rw [← hm, M.alpha_alpha]
      subst hdrm
      show M.α (rd hNT m) = _
      rw [listSwapQR_apply_rd m _ hnd (List.mem_finRange m)]
      show M.α (M.α (qd hNT m)) = qd hNT m
      rw [M.alpha_alpha]
  · rw [outerTau_eq_self_of_notMem (hNT := hNT) hd]
    refine (listSwapQR_apply_other d _ ?_).symm
    intro i _
    refine ⟨?_, ?_⟩
    · intro h; exact hd (h ▸ qd_mem_outerDel i)
    · intro h; exact hd (h ▸ rd_mem_outerDel i)

/-- `allPairs = mergePairs ++ [last pair]`. -/
lemma allPairs_eq_append :
    allPairs hNT = mergePairs hNT ++ [(qd hNT (lastIdx hNT), rd hNT (lastIdx hNT))] := by
  have hBpos : 0 < hNT.outerCycle.length := hNT.outerCycle.darts_length_pos
  have hlenA : (allPairs hNT).length = hNT.outerCycle.length := by
    simp [allPairs, List.length_map, List.length_finRange]
  have hmlen : (mergePairs hNT).length = hNT.outerCycle.length - 1 := mergePairs_length
  have hlenR : (mergePairs hNT ++ [(qd hNT (lastIdx hNT), rd hNT (lastIdx hNT))]).length
      = hNT.outerCycle.length := by
    rw [List.length_append, hmlen, List.length_singleton]; omega
  apply List.ext_getElem (by rw [hlenA, hlenR])
  intro n hn1 hn2
  rw [hlenA] at hn1
  -- LHS
  have hLHS : (allPairs hNT)[n] = (qd hNT ⟨n, hn1⟩, rd hNT ⟨n, hn1⟩) := by
    simp only [allPairs]
    rw [List.getElem_map, List.getElem_finRange]
    congr 1
  rw [hLHS]
  by_cases hnlast : n < hNT.outerCycle.length - 1
  · -- left part
    rw [List.getElem_append_left (by rw [hmlen]; exact hnlast)]
    simp only [mergePairs]
    rw [List.getElem_map, List.getElem_finRange]
    show (qd hNT ⟨n, hn1⟩, rd hNT ⟨n, hn1⟩)
      = (qd hNT (emb hNT _), rd hNT (emb hNT _))
    congr 1
  · -- right part: n = B-1
    rw [List.getElem_append_right (by rw [hmlen]; omega)]
    have hidx : (⟨n, hn1⟩ : Fin hNT.outerCycle.length) = lastIdx hNT :=
      Fin.ext (by simp only [lastIdx]; omega)
    rw [hidx, List.getElem_singleton]



/-- `M.σ * outerTau = pMerge * swap (q last) (r last)`. -/
lemma sigma_outerTau_eq :
    M.σ * outerTau hNT
      = pMerge hNT * Equiv.swap (qd hNT (lastIdx hNT)) (rd hNT (lastIdx hNT)) := by
  rw [outerTau_eq_swapProd, allPairs_eq_append, List.map_append, List.prod_append]
  unfold pMerge pPrefix
  rw [List.take_of_length_le (by rw [mergePairs_length]), List.map_singleton, List.prod_cons,
      List.prod_nil, mul_one, ← mul_assoc]

/-- **Step 6 (the boundary-bank face count) — UNCONDITIONAL.**
`numCycles (M.φ * outerDualAlpha hNT) = M.V − B + 2`. -/
theorem boundaryBankCount_holds (hNT : NearTriangulation M) : BoundaryBankCount hNT := by
  -- reduce to numCycles (M.σ * outerTau) = V - B + 2
  unfold BoundaryBankCount
  rw [phi_outerDualAlpha_eq_sigma_outerTau, sigma_outerTau_eq]
  -- split count: numCycles (pMerge * swap) = numCycles pMerge + 1
  have hsplit : _root_.numCycles
      (pMerge hNT * Equiv.swap (qd hNT (lastIdx hNT)) (rd hNT (lastIdx hNT)))
      = _root_.numCycles (pMerge hNT) + 1 :=
    CombMap.CutCapCount.numCycles_mul_swap_of_sameCycle (pMerge hNT)
      (qd_ne_rd_self (lastIdx hNT)) (pMerge_lastPair_sameCycle (hNT := hNT))
  rw [hsplit]
  -- merge count: numCycles pMerge + (B-1) = V
  have hmerge := numCycles_pMerge_add (hNT := hNT)
  have hBpos : 0 < hNT.outerCycle.length := hNT.outerCycle.darts_length_pos
  have hBV : hNT.outerCycle.length ≤ M.V := outerCycle_length_le_V hNT
  omega

/-- **Discharge of `OuterDualNumCompTwo` — UNCONDITIONAL.**  Supplying the now-proved
boundary-bank count to the genus-slack assembly closes the Chapter-35 coverage atom. -/
theorem outerDualNumCompTwo_holds (hNT : NearTriangulation M) :
    ZinanCh35OuterCount.OuterDualNumCompTwo hNT :=
  ZinanCh35OuterSlack.outerDualNumCompTwo_of_boundaryBankCount' hNT
    (boundaryBankCount_holds hNT)

end ProofsInTheBook.ZinanCh35BankCount






end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35EdgeCore
-/
/- Source module: ProofsInTheBook.ZinanCh35StarConn -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35StarConn

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ZinanCh35EdgeCore

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



/-- `dartFace (σ x) = dartFace (α x)`: because `φ (α x) = σ x` and `dartFace` is `φ`-invariant. -/
lemma dartFace_sigma_eq_alpha (x : D) :
    M.dartFace (M.σ x) = M.dartFace (M.α x) := by
  have hφ : M.φ (M.α x) = M.σ x := by
    show (M.σ * M.α) (M.α x) = M.σ x
    simp [Equiv.Perm.coe_mul, Function.comp_apply, M.alpha_alpha]
  calc M.dartFace (M.σ x) = M.dartFace (M.φ (M.α x)) := by rw [hφ]
    _ = M.dartFace (M.α x) := M.dartFace_phi _

/-- `σ.SameCycle a b` is exactly `tail a = tail b`. -/
lemma sigma_sameCycle_iff_tail (a b : D) :
    M.σ.SameCycle a b ↔ M.tail a = M.tail b := by
  show M.σ.SameCycle a b ↔
    (Quotient.mk (cycleSetoid M.σ) a : Quotient (cycleSetoid M.σ)) = Quotient.mk _ b
  rw [Quotient.eq]
  rfl



/-- Two faces are adjacent *avoiding* a forbidden edge predicate when they share a dart whose
edge is not forbidden.  Instantiating `Forbidden e := IsBoundaryEdge e ∨ e = s(u,v)` gives
`ChordSplitAdj`. -/
def FaceAdjAvoiding (M : CombMap D) (Forbidden : Sym2 M.Vertex → Prop) (f g : M.Face) : Prop :=
  ∃ d : D, M.dartFace d = f ∧ M.dartFace (M.α d) = g ∧ ¬ Forbidden (M.dartEdge d)

/-- **One σ-step.**  If `dartEdge x` is not forbidden, then `dartFace x` and `dartFace (σ x)`
are `FaceAdjAvoiding`-adjacent (witness `x`, using `dartFace (α x) = dartFace (σ x)`). -/
lemma sigma_step_faceAdjAvoiding {Forbidden : Sym2 M.Vertex → Prop} {x : D}
    (hx : ¬ Forbidden (M.dartEdge x)) :
    FaceAdjAvoiding M Forbidden (M.dartFace x) (M.dartFace (M.σ x)) :=
  ⟨x, rfl, (dartFace_sigma_eq_alpha x).symm, hx⟩

/-- **σ-orbit connectivity, no-forbidden version.**  If `x` and `y` are in the same σ-cycle and
*every* dart in that σ-cycle has a non-forbidden edge, then `dartFace x` reaches `dartFace y`
through `FaceAdjAvoiding`.  (Induction on the σ-power connecting `x` to `y`.) -/
lemma star_connected_avoiding {Forbidden : Sym2 M.Vertex → Prop} {x y : D}
    (hσ : M.σ.SameCycle x y)
    (havoid : ∀ z, M.σ.SameCycle x z → ¬ Forbidden (M.dartEdge z)) :
    Relation.ReflTransGen (FaceAdjAvoiding M Forbidden) (M.dartFace x) (M.dartFace y) := by
  obtain ⟨i, hi⟩ := hσ.exists_nat_pow_eq
  -- prove a powered version by induction on `i`, then rewrite `y`.
  subst hi
  clear hσ
  induction i with
  | zero => simpa using Relation.ReflTransGen.refl
  | succ k ih =>
    -- `σ^(k+1) x = σ (σ^k x)`.
    have hstep : (M.σ ^ (k + 1)) x = M.σ ((M.σ ^ k) x) := by
      rw [pow_succ']; rfl
    rw [hstep]
    refine ih.tail ?_
    -- one step from `dartFace (σ^k x)` to `dartFace (σ (σ^k x))`.
    have hsc : M.σ.SameCycle x ((M.σ ^ k) x) := ⟨k, by rw [zpow_natCast]⟩
    exact sigma_step_faceAdjAvoiding (havoid _ hsc)



/-- The chord-split forbidden-edge predicate. -/
def ChordForbidden (hNT : NearTriangulation M) (u v : M.Vertex) (e : Sym2 M.Vertex) : Prop :=
  hNT.outerCycle.IsBoundaryEdge e ∨ e = s(u, v)

/-- `FaceAdjAvoiding` with `ChordForbidden` is definitionally `ChordSplitAdj`. -/
lemma faceAdjAvoiding_chordForbidden_iff {f g : M.Face} :
    FaceAdjAvoiding M (ChordForbidden hNT u v) f g ↔ hNT.ChordSplitAdj u v f g := by
  constructor
  · rintro ⟨d, hdf, hdg, hF⟩
    exact ⟨d, hdf, hdg, fun hb => hF (Or.inl hb), fun hc => hF (Or.inr hc)⟩
  · rintro ⟨d, hdf, hdg, hbe, hch⟩
    refine ⟨d, hdf, hdg, ?_⟩
    rintro (hb | hc)
    · exact hbe hb
    · exact hch hc

/-- Transport a `FaceAdjAvoiding (ChordForbidden …)` reachability into `ChordSplitAdj`
reachability. -/
lemma reflTransGen_chordSplitAdj_of_avoiding {f g : M.Face}
    (h : Relation.ReflTransGen (FaceAdjAvoiding M (ChordForbidden hNT u v)) f g) :
    Relation.ReflTransGen (hNT.ChordSplitAdj u v) f g := by
  induction h with
  | refl => exact Relation.ReflTransGen.refl
  | tail _ hstep ih => exact ih.tail (faceAdjAvoiding_chordForbidden_iff.mp hstep)



/-- **Side-1 extraction.**  A vertex in `sideRegion₁` is the tail of a dart whose face is in
`side₁`. -/
theorem incident_side₁_of_mem_sideRegion₁ (data : hNT.ChordSplitData u v)
    {w : M.Vertex} (hw : w ∈ sideRegion₁ data) :
    ∃ d : D, M.tail d = w ∧ M.dartFace d ∈ data.side₁ := by
  obtain ⟨d, hd, htail⟩ := hw
  -- `d ∈ keptSet₁`.
  have hkept : d ∈ data.keptSet₁ := (data.mem_keptDel₁_iff d).1 hd
  obtain ⟨hU, _⟩ := hkept
  rcases hU with hin | hout
  · -- `d ∈ sideDarts₁`: `dartFace d ∈ side₁`, tail `d = w`.
    exact ⟨d, htail, hin⟩
  · -- `d ∈ outerArc₁`: face of `σ d = α-face ∈ side₁`, tail `σ d = w`.
    obtain ⟨_houter, hαside⟩ := hout
    refine ⟨M.σ d, ?_, ?_⟩
    · rw [M.tail_sigma]; exact htail
    · rw [dartFace_sigma_eq_alpha]; exact hαside

/-- **Side-2 extraction.**  A vertex in `sideRegion₂` is the tail of a dart whose face is in
`side₂`. -/
theorem incident_side₂_of_mem_sideRegion₂ (data : hNT.ChordSplitData u v)
    {w : M.Vertex} (hw : w ∈ sideRegion₂ data) :
    ∃ d : D, M.tail d = w ∧ M.dartFace d ∈ data.side₂ := by
  obtain ⟨d, hd, htail⟩ := hw
  have hkept : d ∈ data.keptSet₂ := (data.mem_keptDel₂_iff d).1 hd
  obtain ⟨hU, _⟩ := hkept
  rcases hU with hin | hout
  · exact ⟨d, htail, hin⟩
  · obtain ⟨_houter, hαside⟩ := hout
    refine ⟨M.σ d, ?_, ?_⟩
    · rw [M.tail_sigma]; exact htail
    · rw [dartFace_sigma_eq_alpha]; exact hαside



/-- A dart whose tail is not a chord endpoint does not carry the chord edge. -/
lemma dartEdge_ne_chord_of_tail_ne (data : hNT.ChordSplitData u v) {z : D}
    (htail : M.tail z = u → False) (htail' : M.tail z = v → False) :
    M.dartEdge z ≠ s(u, v) := by
  intro hz
  -- `dartEdge z = s(tail z, head z) = s(u, v)`, so `tail z ∈ {u, v}`.
  have hmem : M.tail z ∈ (s(u, v) : Sym2 M.Vertex) := by
    rw [← hz]; exact Sym2.mem_mk_left _ _
  rcases Sym2.mem_iff.1 hmem with h | h
  · exact htail h
  · exact htail' h

/-- **The non-outer σ-step.**  If `tail z ≠ u, v` and both `dartFace z`, `dartFace (σ z)` are
non-outer, then `ChordSplitAdj (dartFace z) (dartFace (σ z))`. -/
lemma chordSplitAdj_sigma_step_of_nonouter (data : hNT.ChordSplitData u v) {z : D}
    (hzu : M.tail z ≠ u) (hzv : M.tail z ≠ v)
    (hz : M.dartFace z ≠ hNT.outerFace) (hσz : M.dartFace (M.σ z) ≠ hNT.outerFace) :
    hNT.ChordSplitAdj u v (M.dartFace z) (M.dartFace (M.σ z)) := by
  refine ⟨z, rfl, (dartFace_sigma_eq_alpha z).symm, ?_, ?_⟩
  · -- non-boundary: a boundary edge would force `z` or `α z` onto the outer face.
    intro hbe
    rcases data.boundaryEdge_dart_outer hbe with h | h
    · exact hz h
    · exact hσz (by rw [dartFace_sigma_eq_alpha]; exact h)
  · exact dartEdge_ne_chord_of_tail_ne data hzu hzv



/-- An outer-face dart's tail is a boundary vertex. -/
lemma isBoundaryVertex_tail_of_outer {z : D} (hz : M.dartFace z = hNT.outerFace) :
    hNT.outerCycle.IsBoundaryVertex (M.tail z) := by
  have hmem : z ∈ hNT.outerCycle.darts := (hNT.outerCycle.mem_darts_iff z).2 hz
  show M.tail z ∈ hNT.outerCycle.vertices
  rw [hNT.outerCycle.vertices_eq]
  exact List.mem_map_of_mem hmem

/-- **Interior star connectivity.**  At a non-boundary vertex `w ≠ u, v`, all incident faces are
non-outer and pairwise `ChordSplitAdj`-connected. -/
theorem interior_star_nonouter_connected (data : hNT.ChordSplitData u v)
    {w : M.Vertex} (hw_not_boundary : ¬ hNT.outerCycle.IsBoundaryVertex w)
    (hwu : w ≠ u) (hwv : w ≠ v) {d₁ d₂ : D}
    (h₁tail : M.tail d₁ = w) (h₂tail : M.tail d₂ = w) :
    Relation.ReflTransGen (hNT.ChordSplitAdj u v) (M.dartFace d₁) (M.dartFace d₂) := by
  -- `σ.SameCycle d₁ d₂` from equal tails.
  have hσ : M.σ.SameCycle d₁ d₂ := (sigma_sameCycle_iff_tail d₁ d₂).2 (h₁tail.trans h₂tail.symm)
  -- every dart `z` σ-same-cycle with `d₁` has tail `w` (non-outer face, non-forbidden edge).
  have hconn :
      Relation.ReflTransGen (FaceAdjAvoiding M (ChordForbidden hNT u v))
        (M.dartFace d₁) (M.dartFace d₂) := by
    refine star_connected_avoiding hσ ?_
    intro z hz
    -- `tail z = w`.
    have hzw : M.tail z = w := by
      have := (sigma_sameCycle_iff_tail d₁ z).1 hz
      rw [← this]; exact h₁tail
    -- `z` is not on the outer face (else `w` boundary).
    have hzouter : M.dartFace z ≠ hNT.outerFace := by
      intro h; exact hw_not_boundary (hzw ▸ isBoundaryVertex_tail_of_outer h)
    -- and neither is `σ z` (its tail is also `w`).
    have hσzouter : M.dartFace (M.σ z) ≠ hNT.outerFace := by
      intro h
      have : M.tail (M.σ z) = w := by rw [M.tail_sigma]; exact hzw
      exact hw_not_boundary (this ▸ isBoundaryVertex_tail_of_outer h)
    -- forbidden = boundary ∨ chord; both excluded.
    rintro (hbe | hch)
    · rcases data.boundaryEdge_dart_outer hbe with h | h
      · exact hzouter h
      · exact hσzouter (by rw [dartFace_sigma_eq_alpha]; exact h)
    · exact dartEdge_ne_chord_of_tail_ne data (fun h => hwu (hzw ▸ h))
        (fun h => hwv (hzw ▸ h)) hch
  exact reflTransGen_chordSplitAdj_of_avoiding hconn



/-- **Uniqueness of the outer dart at a vertex.**  Two outer-face darts with the same tail are
equal (the boundary vertex list is `Nodup`). -/
lemma outer_dart_unique {z₁ z₂ : D}
    (h₁ : M.dartFace z₁ = hNT.outerFace) (h₂ : M.dartFace z₂ = hNT.outerFace)
    (ht : M.tail z₁ = M.tail z₂) : z₁ = z₂ :=
  hNT.outerCycle.tail_injective_on_darts hNT.outer_simple
    ((hNT.outerCycle.mem_darts_iff z₁).2 h₁) ((hNT.outerCycle.mem_darts_iff z₂).2 h₂) ht

/-- A dart sharing `b`'s tail but distinct from the outer dart `b` is non-outer. -/
lemma nonouter_of_ne_outer {b z : D} (hb : M.dartFace b = hNT.outerFace)
    (htz : M.tail z = M.tail b) (hzb : z ≠ b) : M.dartFace z ≠ hNT.outerFace :=
  fun hz => hzb (outer_dart_unique hz hb htz)

/-- `σ^m b ≠ b` for `0 < m < L` (`L = #(σ.cycleOf b).support`), provided `b ∈ σ.support`. -/
lemma sigma_pow_ne_self_of_lt {b : D} (hb : b ∈ M.σ.support) {m : ℕ}
    (hm0 : 0 < m) (hmL : m < (M.σ.cycleOf b).support.card) : (M.σ ^ m) b ≠ b := by
  set c := M.σ.cycleOf b with hc
  have hIsCycle : c.IsCycle := Equiv.Perm.isCycle_cycleOf M.σ (Equiv.Perm.mem_support.1 hb)
  have hord : orderOf c = c.support.card := hIsCycle.orderOf
  -- `b ∈ c.support`.
  have hbsupp : b ∈ c.support := by
    rw [hc, Equiv.Perm.mem_support, Equiv.Perm.cycleOf_apply_self, ← Equiv.Perm.mem_support]
    exact hb
  -- `(c^m).support = c.support` since `0 < m < L = orderOf c`.
  have hsupp_pow : (c ^ m).support = c.support :=
    hIsCycle.support_pow_of_pos_of_lt_orderOf hm0 (by rw [hord]; exact hmL)
  -- so `b ∈ (c^m).support`, i.e. `(c^m) b ≠ b`; and `(c^m) b = (σ^m) b`.
  have hbpow : b ∈ (c ^ m).support := by rw [hsupp_pow]; exact hbsupp
  have hne : (c ^ m) b ≠ b := Equiv.Perm.mem_support.1 hbpow
  intro hpow
  apply hne
  rw [hc, Equiv.Perm.cycleOf_pow_apply_self]; exact hpow

/-- `tail (σ^m b) = tail b`. -/
lemma tail_sigma_pow (b : D) (m : ℕ) : M.tail ((M.σ ^ m) b) = M.tail b := by
  induction m with
  | zero => simp
  | succ k ih =>
    rw [pow_succ', Equiv.Perm.mul_apply, M.tail_sigma]; exact ih

/-- `dartFace (σ^m b) ≠ outerFace` for `0 < m < L`, where `b` is the outer dart at `w`. -/
lemma sigma_pow_nonouter {b : D} (hb_outer : M.dartFace b = hNT.outerFace)
    (hb_supp : b ∈ M.σ.support) {m : ℕ}
    (hm0 : 0 < m) (hmL : m < (M.σ.cycleOf b).support.card) :
    M.dartFace ((M.σ ^ m) b) ≠ hNT.outerFace :=
  nonouter_of_ne_outer hb_outer (tail_sigma_pow b m)
    (sigma_pow_ne_self_of_lt hb_supp hm0 hmL)

/-- **Anchor reachability.**  For `w ≠ u, v` and the outer dart `b` at `w`, every power
`σ^m b` with `1 ≤ m < L` has `dartFace (σ b)` reaching `dartFace (σ^m b)` in `ChordSplitAdj`. -/
lemma anchor_reaches (data : hNT.ChordSplitData u v) {b : D}
    (hb_outer : M.dartFace b = hNT.outerFace) (hb_supp : b ∈ M.σ.support)
    (hwu : M.tail b ≠ u) (hwv : M.tail b ≠ v) :
    ∀ m : ℕ, 1 ≤ m → m < (M.σ.cycleOf b).support.card →
      Relation.ReflTransGen (hNT.ChordSplitAdj u v)
        (M.dartFace (M.σ b)) (M.dartFace ((M.σ ^ m) b)) := by
  intro m
  induction m with
  | zero => intro h; omega
  | succ k ih =>
    intro _hk1 hkL
    rcases Nat.eq_zero_or_pos k with hk0 | hkpos
    · -- `m = 1`: `σ^1 b = σ b`, refl.
      subst hk0
      simpa using Relation.ReflTransGen.refl
    · -- `m = k+1`, `k ≥ 1`: IH to `σ^k b`, then one step to `σ^(k+1) b`.
      have hkL' : k < (M.σ.cycleOf b).support.card := by omega
      have hreach := ih hkpos hkL'
      refine hreach.tail ?_
      -- one `ChordSplitAdj` step from `dartFace (σ^k b)` to `dartFace (σ^(k+1) b)`.
      have htail : M.tail ((M.σ ^ k) b) = M.tail b := tail_sigma_pow b k
      have hz_nonouter : M.dartFace ((M.σ ^ k) b) ≠ hNT.outerFace :=
        sigma_pow_nonouter hb_outer hb_supp hkpos hkL'
      have hσz_nonouter : M.dartFace (M.σ ((M.σ ^ k) b)) ≠ hNT.outerFace := by
        have heq : M.σ ((M.σ ^ k) b) = (M.σ ^ (k + 1)) b := by rw [pow_succ']; rfl
        rw [heq]
        exact sigma_pow_nonouter hb_outer hb_supp (by omega) hkL
      have hstep := chordSplitAdj_sigma_step_of_nonouter data
        (z := (M.σ ^ k) b) (by rw [htail]; exact hwu) (by rw [htail]; exact hwv)
        hz_nonouter hσz_nonouter
      -- rewrite `σ (σ^k b) = σ^(k+1) b`.
      have heq : M.σ ((M.σ ^ k) b) = (M.σ ^ (k + 1)) b := by rw [pow_succ']; rfl
      rwa [heq] at hstep

/-- **Boundary star connectivity.**  At a boundary vertex `w ≠ u, v`, any two non-outer darts
`d₁, d₂` with tail `w` have `ChordSplitAdj`-connected faces (both reach the anchor `dartFace (σ b)`
where `b` is the unique outer dart at `w`). -/
theorem boundary_star_nonouter_connected (data : hNT.ChordSplitData u v)
    {w : M.Vertex} (hw_boundary : hNT.outerCycle.IsBoundaryVertex w)
    (hwu : w ≠ u) (hwv : w ≠ v) {d₁ d₂ : D}
    (h₁tail : M.tail d₁ = w) (h₂tail : M.tail d₂ = w)
    (h₁nonouter : M.dartFace d₁ ≠ hNT.outerFace) (h₂nonouter : M.dartFace d₂ ≠ hNT.outerFace) :
    Relation.ReflTransGen (hNT.ChordSplitAdj u v) (M.dartFace d₁) (M.dartFace d₂) := by
  -- the outer dart `b` at `w`.
  obtain ⟨b, hb_darts, hb_tail⟩ : ∃ b, b ∈ hNT.outerCycle.darts ∧ M.tail b = w := by
    have : w ∈ hNT.outerCycle.darts.map M.tail := by
      rw [← hNT.outerCycle.vertices_eq]; exact hw_boundary
    rcases List.mem_map.1 this with ⟨b, hb, hbw⟩; exact ⟨b, hb, hbw⟩
  have hb_outer : M.dartFace b = hNT.outerFace := (hNT.outerCycle.mem_darts_iff b).1 hb_darts
  have hb_supp : b ∈ M.σ.support :=
    Equiv.Perm.mem_support.2 (hNT.boundary_dart_sigma_ne hb_darts)
  -- both `d₁, d₂` reach `dartFace (σ b)`.
  set L := (M.σ.cycleOf b).support.card with hL
  have hbu : M.tail b ≠ u := by rw [hb_tail]; exact hwu
  have hbv : M.tail b ≠ v := by rw [hb_tail]; exact hwv
  have reach : ∀ {d : D}, M.tail d = w → M.dartFace d ≠ hNT.outerFace →
      Relation.ReflTransGen (hNT.ChordSplitAdj u v) (M.dartFace (M.σ b)) (M.dartFace d) := by
    intro d hdtail hdnonouter
    -- `σ.SameCycle b d` (equal tails), and `b ∈ support`.
    have hsc : M.σ.SameCycle b d :=
      (sigma_sameCycle_iff_tail b d).2 (by rw [hb_tail, hdtail])
    obtain ⟨m, hmL, hmd⟩ := hsc.exists_pow_eq_of_mem_support hb_supp
    -- `m ≠ 0` (else `d = b` is outer).
    have hm0 : 1 ≤ m := by
      rcases Nat.eq_zero_or_pos m with h | h
      · exfalso; apply hdnonouter; rw [← hmd, h]; simpa using hb_outer
      · exact h
    have := anchor_reaches data hb_outer hb_supp hbu hbv m hm0 hmL
    rwa [hmd] at this
  have r₁ := reach h₁tail h₁nonouter
  have r₂ := reach h₂tail h₂nonouter
  -- `d₁ ~* anchor ~* d₂`.
  exact (Relation.ReflTransGen.symmetric (fun _ _ h => hNT.chordSplitAdj_symm h) r₁).trans r₂



/-- **Core star connectivity away from chord ends.**  For `w ≠ u, v`, any two non-outer darts
`d₁, d₂` with common tail `w` have `ChordSplitAdj`-connected faces.  Case split on whether `w`
is a boundary vertex: interior → `interior_star_nonouter_connected`; boundary →
`boundary_star_nonouter_connected`. -/
theorem star_nonouter_connected_away_from_chordEnds (data : hNT.ChordSplitData u v)
    {w : M.Vertex} (hwu : w ≠ u) (hwv : w ≠ v) {d₁ d₂ : D}
    (h₁tail : M.tail d₁ = w) (h₂tail : M.tail d₂ = w)
    (h₁nonouter : M.dartFace d₁ ≠ hNT.outerFace) (h₂nonouter : M.dartFace d₂ ≠ hNT.outerFace) :
    Relation.ReflTransGen (hNT.ChordSplitAdj u v) (M.dartFace d₁) (M.dartFace d₂) := by
  by_cases hw_boundary : hNT.outerCycle.IsBoundaryVertex w
  · exact boundary_star_nonouter_connected data hw_boundary hwu hwv h₁tail h₂tail
      h₁nonouter h₂nonouter
  · exact interior_star_nonouter_connected data hw_boundary hwu hwv h₁tail h₂tail



/-- **`SideRegionInterChordEnds`, discharged unconditionally.**  A vertex `w` in both side regions
is a chord endpoint.  Proof by contradiction: extract incident side-1 / side-2 faces at `w`,
connect them via the core star-connectivity lemma (`w ≠ u, v`), and contradict `Separates`. -/
theorem sideRegionInterChordEnds_holds (data : hNT.ChordSplitData u v) (hsep : data.Separates) :
    SideRegionInterChordEnds data := by
  intro w hw1 hw2
  by_contra hnot
  have hwu : w ≠ u := fun h => hnot (Or.inl h)
  have hwv : w ≠ v := fun h => hnot (Or.inr h)
  -- extract incident side-1 and side-2 faces at `w`.
  obtain ⟨d₁, ht₁, hf₁⟩ := incident_side₁_of_mem_sideRegion₁ data hw1
  obtain ⟨d₂, ht₂, hf₂⟩ := incident_side₂_of_mem_sideRegion₂ data hw2
  have ho₁ : M.dartFace d₁ ≠ hNT.outerFace := data.side₁_subset_nonouter hf₁
  have ho₂ : M.dartFace d₂ ≠ hNT.outerFace := data.side₂_subset_nonouter hf₂
  -- connect the two faces.
  have hconn : Relation.ReflTransGen (hNT.ChordSplitAdj u v) (M.dartFace d₁) (M.dartFace d₂) :=
    star_nonouter_connected_away_from_chordEnds data hwu hwv ht₁ ht₂ ho₁ ho₂
  -- `face₂ ∈ side₁`, contradicting `Separates`.
  have hf₂_to_face₂ : data.face₂ ∈ hNT.Side u v (M.dartFace d₂) := side_mem_symm hf₂
  have : data.face₂ ∈ data.side₁ := (hf₁.trans hconn).trans hf₂_to_face₂
  exact hsep this

end ProofsInTheBook.ZinanCh35StarConn








end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35BankCount
import ProofsInTheBook.ZinanCh35StarConn
-/
/- Source module: ProofsInTheBook.ZinanCh35CycleBank -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option linter.unnecessarySimpa false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35CycleBank

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ZinanCh35OuterSlack
open Equiv Equiv.Perm

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}



variable (C : SimplePrimalCycle M)

/-- `C.dartSet` is `α`-closed: it is symmetric under `M.α` by construction
(`d = C.dart i` ↦ `α d = α (C.dart i)`, and `d = α (C.dart i)` ↦ `α d = C.dart i`). -/
lemma dartSet_alpha_closed :
    ∀ d : D, d ∈ C.dartSet → M.α d ∈ C.dartSet := by
  intro d hd
  rw [C.mem_dartSet_iff] at hd ⊢
  obtain ⟨i, hi | hi⟩ := hd
  · exact ⟨i, Or.inr (by rw [hi])⟩
  · exact ⟨i, Or.inl (by rw [hi, M.alpha_alpha])⟩

/-- The restricted dual involution for the cycle: fixes the cycle darts, `= M.α` elsewhere. -/
noncomputable def cycleDualAlpha (C : SimplePrimalCycle M) : Equiv.Perm D :=
  SubmapPlanar.rawAlpha M C.dartSet (dartSet_alpha_closed C)

lemma cycleDualAlpha_eq_self_of_mem {d : D} (hd : d ∈ C.dartSet) :
    cycleDualAlpha C d = d :=
  SubmapPlanar.rawAlpha_eq_self_of_mem M C.dartSet _ hd

lemma cycleDualAlpha_eq_alpha_of_notMem {d : D} (hd : d ∉ C.dartSet) :
    cycleDualAlpha C d = M.α d :=
  SubmapPlanar.rawAlpha_eq_alpha_of_notMem M C.dartSet _ hd



/-- The forward and reverse darts are disjoint families, so `C.dartSet` has `2·C.len`
elements: `C.len` forward darts `C.dart i` and `C.len` reverse darts `M.α (C.dart i)`. -/
lemma dartSet_card : (C.dartSet).card = 2 * C.len := by
  classical
  -- `C.dartSet = image C.dart ∪ image (α ∘ C.dart)`; the two images are disjoint.
  have hset : C.dartSet
      = (Finset.univ.image C.dart) ∪ (Finset.univ.image (fun i => M.α (C.dart i))) := by
    ext d
    rw [C.mem_dartSet_iff]
    simp only [Finset.mem_union, Finset.mem_image, Finset.mem_univ, true_and]
    constructor
    · rintro ⟨i, hi | hi⟩
      · exact Or.inl ⟨i, hi.symm⟩
      · exact Or.inr ⟨i, hi.symm⟩
    · rintro (⟨i, hi⟩ | ⟨i, hi⟩)
      · exact ⟨i, Or.inl hi.symm⟩
      · exact ⟨i, Or.inr hi.symm⟩
  have hdisj : Disjoint (Finset.univ.image C.dart)
      (Finset.univ.image (fun i => M.α (C.dart i))) := by
    rw [Finset.disjoint_left]
    intro d hd himg
    simp only [Finset.mem_image, Finset.mem_univ, true_and] at hd himg
    obtain ⟨i, hi⟩ := hd
    obtain ⟨j, hj⟩ := himg
    exact C.dart_ne_alpha_dart i j (hi.trans hj.symm)
  have hcardF : (Finset.univ.image C.dart).card = C.len := by
    rw [Finset.card_image_of_injective _ C.dart_inj, Finset.card_univ, Fintype.card_fin]
  have hcardR : (Finset.univ.image (fun i => M.α (C.dart i))).card = C.len := by
    rw [Finset.card_image_of_injective _ C.alpha_dart_inj, Finset.card_univ, Fintype.card_fin]
  rw [hset, Finset.card_union_of_disjoint hdisj, hcardF, hcardR]; ring



/-- `genusSlack (M.φ) (cycleDualAlpha C) = 0`: deleting the cycle edges from the genus-0 dual
map keeps the slack at zero.  Reuses the `dualMap` machinery from `ZinanCh35OuterSlack`. -/
lemma genusSlack_cycleDualAlpha_eq_zero (hsphere : M.IsSphereMap) :
    genusSlack M.φ (cycleDualAlpha C) = 0 := by
  have hclosedD : ∀ d : D, d ∈ C.dartSet → (dualMap M).α d ∈ C.dartSet := by
    simpa [dualMap_α] using (dartSet_alpha_closed C)
  have hraw : SubmapPlanar.rawAlpha (dualMap M) C.dartSet hclosedD = cycleDualAlpha C := by
    ext d
    by_cases hd : d ∈ C.dartSet
    · rw [SubmapPlanar.rawAlpha_eq_self_of_mem (dualMap M) C.dartSet hclosedD hd,
          cycleDualAlpha_eq_self_of_mem C hd]
    · rw [SubmapPlanar.rawAlpha_eq_alpha_of_notMem (dualMap M) C.dartSet hclosedD hd,
          cycleDualAlpha_eq_alpha_of_notMem C hd, dualMap_α]
  obtain ⟨d₀⟩ : Nonempty D := ⟨C.dart ⟨0, C.len_pos⟩⟩
  have hsphereD : (dualMap M).IsSphereMap := dualMap_isSphereMap M hsphere
  have h0 := SubmapPlanar.genusSlack_rawAlpha_eq_zero (dualMap M) C.dartSet hclosedD hsphereD d₀
  rw [hraw] at h0
  rwa [dualMap_σ] at h0



/-- The support of `cycleDualAlpha C` is exactly the non-deleted darts. -/
lemma support_cycleDualAlpha :
    (cycleDualAlpha C).support = Finset.univ \ C.dartSet := by
  classical
  ext d
  simp only [Equiv.Perm.mem_support, Finset.mem_sdiff, Finset.mem_univ, true_and]
  constructor
  · intro hd hmem
    exact hd (cycleDualAlpha_eq_self_of_mem C hmem)
  · intro hd
    rw [cycleDualAlpha_eq_alpha_of_notMem C hd]
    exact M.α_no_fixed d

/-- The cycle length is at most the number of edges. -/
lemma len_le_E : C.len ≤ M.E := by
  have h2 : (C.dartSet).card = 2 * C.len := dartSet_card C
  have hle : (C.dartSet).card ≤ Fintype.card D := Finset.card_le_univ _
  have hcard : 2 * M.E = Fintype.card D := two_mul_E_eq_card M
  omega

/-- The cycle length is at most the number of vertices (the tails are distinct). -/
lemma len_le_V : C.len ≤ M.V := by
  classical
  have hinj : Function.Injective (fun i => M.tail (C.dart i)) := C.tail_inj
  have hcard : (Finset.univ.image (fun i => M.tail (C.dart i))).card = C.len := by
    rw [Finset.card_image_of_injective _ hinj, Finset.card_univ, Fintype.card_fin]
  have hle : (Finset.univ.image (fun i => M.tail (C.dart i))).card
      ≤ Fintype.card M.Vertex := Finset.card_le_univ _
  rw [hcard] at hle
  have : M.V = Fintype.card M.Vertex := rfl
  omega

/-- **`Ehalf (cycleDualAlpha C) = M.E − C.len`.** -/
lemma Ehalf_cycleDualAlpha : Ehalf (cycleDualAlpha C) = M.E - C.len := by
  classical
  have hsupp := support_cycleDualAlpha C
  have hsubset : C.dartSet ⊆ Finset.univ := Finset.subset_univ _
  have hcard : (cycleDualAlpha C).support.card = Fintype.card D - (C.dartSet).card := by
    rw [hsupp, Finset.card_univ_diff]
  have hEval : M.E = Fintype.card D / 2 := by
    have hα : M.α.support = Finset.univ := by
      rw [Finset.eq_univ_iff_forall]; intro d
      rw [Equiv.Perm.mem_support]; exact M.α_no_fixed d
    have : Ehalf M.α = M.E := Ehalf_eq_E M
    rw [Ehalf, hα, Finset.card_univ] at this
    omega
  have hEhalf : Ehalf (cycleDualAlpha C) = (cycleDualAlpha C).support.card / 2 := rfl
  rw [hEhalf, hcard, dartSet_card C]
  omega



/-- The complementary restricted involution `cycleTau C := M.α * cycleDualAlpha C`:
identity off `C.dartSet`, `= M.α` on `C.dartSet`. -/
noncomputable def cycleTau (C : SimplePrimalCycle M) : Equiv.Perm D :=
  M.α * cycleDualAlpha C

lemma cycleTau_eq_alpha_of_mem {d : D} (hd : d ∈ C.dartSet) :
    cycleTau C d = M.α d := by
  show M.α (cycleDualAlpha C d) = M.α d
  rw [cycleDualAlpha_eq_self_of_mem C hd]

lemma cycleTau_eq_self_of_notMem {d : D} (hd : d ∉ C.dartSet) :
    cycleTau C d = d := by
  show M.α (cycleDualAlpha C d) = d
  rw [cycleDualAlpha_eq_alpha_of_notMem C hd, M.alpha_alpha]

/-- **The algebraic reduction.**  `M.φ * cycleDualAlpha = M.σ * cycleTau`. -/
lemma phi_cycleDualAlpha_eq_sigma_cycleTau :
    M.φ * cycleDualAlpha C = M.σ * cycleTau C := by
  show M.φ * cycleDualAlpha C = M.σ * (M.α * cycleDualAlpha C)
  rw [← mul_assoc]; rfl





/-- `M.σ.SameCycle a b ↔ M.tail a = M.tail b`. -/
lemma sigma_sameCycle_iff_tail (a b : D) :
    M.σ.SameCycle a b ↔ M.tail a = M.tail b := by
  show M.σ.SameCycle a b ↔
    (Quotient.mk (cycleSetoid M.σ) a : Quotient (cycleSetoid M.σ)) = Quotient.mk _ b
  rw [Quotient.eq]
  rfl

/-- Distinct forward cycle darts lie in distinct `σ`-cycles: their tails are distinct. -/
lemma sigma_sameCycle_dart_dart (i j : Fin C.len) :
    M.σ.SameCycle (C.dart i) (C.dart j) ↔ i = j := by
  rw [sigma_sameCycle_iff_tail]
  constructor
  · intro h; exact C.tail_inj h
  · intro h; rw [h]

/-- **The key dynamical fact:** `M.σ.SameCycle (M.α (C.dart i)) (C.dart (nextIdx i))`.
`tail (α (C.dart i)) = head (C.dart i) = tail (C.dart (nextIdx i))`. -/
lemma sigma_sameCycle_alphaDart_dart_next (i : Fin C.len) :
    M.σ.SameCycle (M.α (C.dart i)) (C.dart (C.nextIdx i)) := by
  rw [sigma_sameCycle_iff_tail, M.tail_alpha]
  exact (C.tail_dart_nextIdx i).symm



lemma dart_ne_alphaDart_self (i : Fin C.len) : C.dart i ≠ M.α (C.dart i) :=
  C.dart_ne_alpha_self i

lemma dart_ne_alphaDart (i j : Fin C.len) : C.dart i ≠ M.α (C.dart j) :=
  C.dart_ne_alpha_dart i j

lemma alphaDart_ne_dart (i j : Fin C.len) : M.α (C.dart i) ≠ C.dart j :=
  fun h => C.dart_ne_alpha_dart j i h.symm



/-- For a non-final index, `nextIdx` increments the value (no wraparound). -/
lemma nextIdx_val_of_lt {i : Fin C.len} (hi : i.1 < C.len - 1) :
    (C.nextIdx i).1 = i.1 + 1 := by
  rw [SimplePrimalCycle.nextIdx_val, Nat.mod_eq_of_lt (by omega)]



/-- The embedding `Fin (C.len − 1) ↪ Fin C.len`. -/
noncomputable def emb (j : Fin (C.len - 1)) : Fin C.len :=
  ⟨j.1, by have := j.2; omega⟩

/-- The ordered list of the first `C.len − 1` transposition pairs `(C.dart j, α (C.dart j))`. -/
noncomputable def mergePairs (C : SimplePrimalCycle M) : List (D × D) :=
  (List.finRange (C.len - 1)).map (fun j => (C.dart (emb C j), M.α (C.dart (emb C j))))

/-- The partial product permutation after the first `k` merge swaps. -/
noncomputable def pPrefix (C : SimplePrimalCycle M) (k : ℕ) : Equiv.Perm D :=
  M.σ * (((mergePairs C).take k).map (fun w => Equiv.swap w.1 w.2)).prod

lemma pPrefix_zero : pPrefix C 0 = M.σ := by simp [pPrefix]

lemma mergePairs_get_fst (k : ℕ) (hk : k < C.len - 1) :
    (mergePairs C).get ⟨k, by simpa [mergePairs] using hk⟩
      = (C.dart ⟨k, by omega⟩, M.α (C.dart ⟨k, by omega⟩)) := by
  unfold mergePairs
  rw [List.get_eq_getElem, List.getElem_map, List.getElem_finRange]
  rfl

lemma mergePairs_length : (mergePairs C).length = C.len - 1 := by
  simp [mergePairs]

/-- One-step recurrence for the partial products. -/
lemma pPrefix_succ (k : ℕ) (hk : k < C.len - 1) :
    pPrefix C (k + 1)
      = pPrefix C k * Equiv.swap (C.dart ⟨k, by omega⟩) (M.α (C.dart ⟨k, by omega⟩)) := by
  unfold pPrefix
  have hlen : k < (mergePairs C).length := by rw [mergePairs_length]; exact hk
  have htake : (mergePairs C).take (k + 1)
      = (mergePairs C).take k ++ [(mergePairs C).get ⟨k, hlen⟩] := by
    rw [List.get_eq_getElem]
    exact List.take_succ_eq_append_getElem hlen
  rw [htake, List.map_append, List.prod_append, mergePairs_get_fst C k hk]
  simp [mul_assoc]

/-- `nextIdx` is injective (restated locally for convenience). -/
lemma nextIdx_inj {i j : Fin C.len} (h : C.nextIdx i = C.nextIdx j) : i = j :=
  C.nextIdx_inj h



/-- The simultaneous invariant after `k` merges.  At each cycle vertex `v_m`, the partial
product groups the forward dart `C.dart m` with the reverse dart `M.α (C.dart (prevIdx m))`
(whose tail is also `v_m`); after `k` merges the chain `v_0, …, v_k` is one cycle.

We phrase everything via `nextIdx`: `M.α (C.dart i)` sits in the `σ`-orbit of vertex
`v_{nextIdx i}` (by `sigma_sameCycle_alphaDart_dart_next`).  So the index controlling whether
`M.α (C.dart j)` has joined the block is `(nextIdx j).1 ≤ k`, exactly as in the outer-cycle
proof. -/
lemma bankInvariant :
    ∀ k : ℕ, k + 1 ≤ C.len →
      (∀ i j : Fin C.len,
          (pPrefix C k).SameCycle (C.dart i) (C.dart j)
            ↔ i = j ∨ (i.1 ≤ k ∧ j.1 ≤ k)) ∧
      (∀ i j : Fin C.len,
          (pPrefix C k).SameCycle (C.dart i) (M.α (C.dart j))
            ↔ i = C.nextIdx j ∨ (i.1 ≤ k ∧ (C.nextIdx j).1 ≤ k)) ∧
      (∀ i j : Fin C.len,
          (pPrefix C k).SameCycle (M.α (C.dart i)) (M.α (C.dart j))
            ↔ i = j ∨ ((C.nextIdx i).1 ≤ k ∧ (C.nextIdx j).1 ≤ k)) := by
  intro k
  induction k with
  | zero =>
      intro _
      rw [pPrefix_zero]
      refine ⟨?_, ?_, ?_⟩
      · -- dart-dart base
        intro i j
        rw [sigma_sameCycle_dart_dart]
        constructor
        · exact Or.inl
        · rintro (h | ⟨hi, hj⟩)
          · exact h
          · exact Fin.ext (by omega)
      · -- dart-α base
        intro i j
        have hr : M.σ.SameCycle (M.α (C.dart j)) (C.dart (C.nextIdx j)) :=
          sigma_sameCycle_alphaDart_dart_next C j
        constructor
        · intro h
          have : M.σ.SameCycle (C.dart i) (C.dart (C.nextIdx j)) := h.trans hr
          left; exact (sigma_sameCycle_dart_dart C i (C.nextIdx j)).mp this
        · rintro (h | ⟨hi, hcon⟩)
          · subst h; exact hr.symm
          · have : i = C.nextIdx j := Fin.ext (by omega)
            subst this; exact hr.symm
      · -- α-α base
        intro i j
        have hri : M.σ.SameCycle (M.α (C.dart i)) (C.dart (C.nextIdx i)) :=
          sigma_sameCycle_alphaDart_dart_next C i
        have hrj : M.σ.SameCycle (M.α (C.dart j)) (C.dart (C.nextIdx j)) :=
          sigma_sameCycle_alphaDart_dart_next C j
        constructor
        · intro h
          have : M.σ.SameCycle (C.dart (C.nextIdx i)) (C.dart (C.nextIdx j)) :=
            (hri.symm.trans h).trans hrj
          left; exact nextIdx_inj C ((sigma_sameCycle_dart_dart C _ _).mp this)
        · rintro (h | ⟨hci, hcj⟩)
          · subst h; exact SameCycle.rfl
          · have : C.nextIdx i = C.nextIdx j := Fin.ext (by omega)
            rw [nextIdx_inj C this]
  | succ k ih =>
      intro hk1
      have hkB1 : k < C.len - 1 := by omega
      have hkB : k < C.len := by omega
      obtain ⟨ihqq, ihqr, ihrr⟩ := ih (by omega)
      set a := C.dart ⟨k, hkB⟩ with ha
      set b := M.α (C.dart ⟨k, hkB⟩) with hb
      have hak : (⟨k, hkB⟩ : Fin C.len).1 = k := rfl
      have hnextk : (C.nextIdx ⟨k, hkB⟩).1 = k + 1 := nextIdx_val_of_lt C (by simpa using hkB1)
      have hnsc : ¬ (pPrefix C k).SameCycle a b := by
        rw [ha, hb, ihqr ⟨k, hkB⟩ ⟨k, hkB⟩]
        rintro (hcon | ⟨_, hcon⟩)
        · have := congrArg Fin.val hcon; rw [hnextk] at this; simp at this
        · rw [hnextk] at hcon; omega
      have hstep := pPrefix_succ C k hkB1
      have engine : ∀ x y : D,
          (pPrefix C (k + 1)).SameCycle x y ↔
            (pPrefix C k).SameCycle x y ∨
              ((pPrefix C k).SameCycle x a ∧ (pPrefix C k).SameCycle y b) ∨
              ((pPrefix C k).SameCycle x b ∧ (pPrefix C k).SameCycle y a) := by
        intro x y
        rw [hstep]
        exact PermTranspositionCycleCount.sameCycle_mul_swap_iff_mergeRel_of_not_sameCycle
          (pPrefix C k) hnsc (x := x) (y := y)
      have hqa : ∀ i : Fin C.len,
          (pPrefix C k).SameCycle (C.dart i) a ↔ i.1 ≤ k := by
        intro i; rw [ha, ihqq i ⟨k, hkB⟩]
        constructor
        · rintro (h | ⟨hi, _⟩)
          · exact le_of_eq (congrArg Fin.val h)
          · exact hi
        · intro hi
          rcases Nat.lt_or_ge i.1 k with h | h
          · exact Or.inr ⟨by omega, le_refl k⟩
          · exact Or.inl (Fin.ext (le_antisymm hi h))
      have hqb : ∀ i : Fin C.len,
          (pPrefix C k).SameCycle (C.dart i) b ↔ i.1 = k + 1 := by
        intro i; rw [hb, ihqr i ⟨k, hkB⟩, hnextk]
        constructor
        · rintro (h | ⟨_, hcon⟩)
          · have := congrArg Fin.val h; rw [hnextk] at this; exact this
          · omega
        · intro hi; left; exact Fin.ext (by rw [hnextk]; exact hi)
      have hrb : ∀ i : Fin C.len,
          (pPrefix C k).SameCycle (M.α (C.dart i)) b ↔ (C.nextIdx i).1 = k + 1 := by
        intro i; rw [hb, ihrr i ⟨k, hkB⟩, hnextk]
        constructor
        · rintro (h | ⟨hi, hcon⟩)
          · subst h; rw [hnextk]
          · omega
        · intro hi; left; exact nextIdx_inj C (Fin.ext (by rw [hnextk]; omega))
      refine ⟨?_, ?_, ?_⟩
      · -- dart-dart at k+1
        intro i j
        rw [engine (C.dart i) (C.dart j), ihqq i j, hqa i, hqb j, hqb i, hqa j]
        constructor
        · rintro (h | ⟨hi, hj⟩ | ⟨hi, hj⟩)
          · rcases h with h | ⟨hi, hj⟩
            · exact Or.inl h
            · exact Or.inr ⟨by omega, by omega⟩
          · right; refine ⟨by omega, by omega⟩
          · right; refine ⟨by omega, by omega⟩
        · rintro (h | ⟨hi, hj⟩)
          · exact Or.inl (Or.inl h)
          · rcases Nat.lt_or_ge i.1 (k+1) with hik | hik
            · rcases Nat.lt_or_ge j.1 (k+1) with hjk | hjk
              · exact Or.inl (Or.inr ⟨by omega, by omega⟩)
              · right; left; exact ⟨by omega, by omega⟩
            · rcases Nat.lt_or_ge j.1 (k+1) with hjk | hjk
              · right; right; exact ⟨by omega, by omega⟩
              · exact Or.inl (Or.inl (Fin.ext (by omega)))
      · -- dart-α at k+1
        intro i j
        rw [engine (C.dart i) (M.α (C.dart j)), ihqr i j, hqa i, hrb j, hqb i]
        have hrja : (pPrefix C k).SameCycle (M.α (C.dart j)) a ↔ (C.nextIdx j).1 ≤ k := by
          rw [ha, Equiv.Perm.sameCycle_comm, ihqr ⟨k, hkB⟩ j]
          constructor
          · rintro (h | ⟨_, hj⟩)
            · have : (C.nextIdx j).1 = k := (congrArg Fin.val h).symm
              omega
            · exact hj
          · intro hj
            rcases Nat.lt_or_ge (C.nextIdx j).1 k with h | h
            · exact Or.inr ⟨by omega, by omega⟩
            · left; exact Fin.ext (by omega)
        rw [hrja]
        constructor
        · rintro (h | ⟨hi, hj⟩ | ⟨hi, hj⟩)
          · rcases h with h | ⟨hi, hj⟩
            · exact Or.inl h
            · exact Or.inr ⟨by omega, by omega⟩
          · right; exact ⟨by omega, by omega⟩
          · right; exact ⟨by omega, by omega⟩
        · rintro (h | ⟨hi, hnj⟩)
          · exact Or.inl (Or.inl h)
          · rcases Nat.lt_or_ge i.1 (k+1) with hik | hik
            · rcases Nat.lt_or_ge (C.nextIdx j).1 (k+1) with hnjk | hnjk
              · exact Or.inl (Or.inr ⟨by omega, by omega⟩)
              · right; left; exact ⟨by omega, by omega⟩
            · rcases Nat.lt_or_ge (C.nextIdx j).1 (k+1) with hnjk | hnjk
              · right; right; exact ⟨by omega, by omega⟩
              · exact Or.inl (Or.inl (Fin.ext (by omega)))
      · -- α-α at k+1
        intro i j
        rw [engine (M.α (C.dart i)) (M.α (C.dart j)), ihrr i j, hrb j, hrb i]
        have hria : (pPrefix C k).SameCycle (M.α (C.dart i)) a ↔ (C.nextIdx i).1 ≤ k := by
          rw [ha, Equiv.Perm.sameCycle_comm, ihqr ⟨k, hkB⟩ i]
          constructor
          · rintro (h | ⟨_, hi⟩)
            · have := congrArg Fin.val h; omega
            · exact hi
          · intro hi
            rcases Nat.lt_or_ge (C.nextIdx i).1 k with h | h
            · exact Or.inr ⟨by omega, by omega⟩
            · left; exact Fin.ext (by omega)
        have hrja : (pPrefix C k).SameCycle (M.α (C.dart j)) a ↔ (C.nextIdx j).1 ≤ k := by
          rw [ha, Equiv.Perm.sameCycle_comm, ihqr ⟨k, hkB⟩ j]
          constructor
          · rintro (h | ⟨_, hj⟩)
            · have := congrArg Fin.val h; omega
            · exact hj
          · intro hj
            rcases Nat.lt_or_ge (C.nextIdx j).1 k with h | h
            · exact Or.inr ⟨by omega, by omega⟩
            · left; exact Fin.ext (by omega)
        rw [hria, hrja]
        constructor
        · rintro (h | ⟨hi, hj⟩ | ⟨hi, hj⟩)
          · rcases h with h | ⟨hi, hj⟩
            · exact Or.inl h
            · exact Or.inr ⟨by omega, by omega⟩
          · right; exact ⟨by omega, by omega⟩
          · right; exact ⟨by omega, by omega⟩
        · rintro (h | ⟨hni, hnj⟩)
          · exact Or.inl (Or.inl h)
          · rcases Nat.lt_or_ge (C.nextIdx i).1 (k+1) with hnik | hnik
            · rcases Nat.lt_or_ge (C.nextIdx j).1 (k+1) with hnjk | hnjk
              · exact Or.inl (Or.inr ⟨by omega, by omega⟩)
              · right; left; exact ⟨by omega, by omega⟩
            · rcases Nat.lt_or_ge (C.nextIdx j).1 (k+1) with hnjk | hnjk
              · right; right; exact ⟨by omega, by omega⟩
              · have : C.nextIdx i = C.nextIdx j := Fin.ext (by omega)
                exact Or.inl (Or.inl (nextIdx_inj C this))



lemma len_pos' : 0 < C.len := C.len_pos

/-- The fully-merged permutation after all `C.len − 1` merges. -/
noncomputable def pMerge (C : SimplePrimalCycle M) : Equiv.Perm D :=
  pPrefix C (C.len - 1)

/-- The `C.len − 1` merge swaps each merge two distinct cycles of the running product. -/
lemma mergePairs_merge_condition :
    ∀ j : Fin (mergePairs C).length,
      ((mergePairs C).get j).1 ≠ ((mergePairs C).get j).2 ∧
        ¬ (M.σ * (((mergePairs C).take j).map (fun w => Equiv.swap w.1 w.2)).prod).SameCycle
            ((mergePairs C).get j).1 ((mergePairs C).get j).2 := by
  intro j
  have he : (mergePairs C).length = C.len - 1 := mergePairs_length C
  have hjlen : (j : ℕ) < C.len - 1 := by have := j.2; omega
  have hjB : (j : ℕ) < C.len := by omega
  rw [mergePairs_get_fst C (j : ℕ) hjlen]
  have hpp : M.σ * (((mergePairs C).take (j : ℕ)).map (fun w => Equiv.swap w.1 w.2)).prod
      = pPrefix C (j : ℕ) := rfl
  refine ⟨?_, ?_⟩
  · exact dart_ne_alphaDart_self C ⟨(j : ℕ), hjB⟩
  · rw [hpp]
    obtain ⟨_, ihqr, _⟩ := bankInvariant C (j : ℕ) (by omega)
    rw [ihqr ⟨(j : ℕ), hjB⟩ ⟨(j : ℕ), hjB⟩]
    have hnext : (C.nextIdx ⟨(j : ℕ), hjB⟩).1 = (j : ℕ) + 1 :=
      nextIdx_val_of_lt C (by simpa using hjlen)
    rintro (hcon | ⟨_, hcon⟩)
    · have := congrArg Fin.val hcon; rw [hnext] at this; simp at this
    · rw [hnext] at hcon; omega

/-- After all `C.len − 1` merges, the cycle count is `V − (C.len − 1)`. -/
lemma numCycles_pMerge_add :
    _root_.numCycles (pMerge C) + (C.len - 1) = M.V := by
  have hmerge := CombMap.CutCapCount.numCycles_mul_listSwap_merges M.σ (mergePairs C)
    (mergePairs_merge_condition C)
  rw [mergePairs_length] at hmerge
  have hpm : pMerge C = M.σ * ((mergePairs C).map (fun w => Equiv.swap w.1 w.2)).prod := by
    unfold pMerge pPrefix
    rw [List.take_of_length_le (by rw [mergePairs_length])]
  rw [hpm, hmerge, M.V_eq_numCycles]

/-- The last cycle pair `(C.dart last, α (C.dart last))`, `last = ⟨C.len−1⟩`. -/
noncomputable def lastIdx (C : SimplePrimalCycle M) : Fin C.len :=
  ⟨C.len - 1, by have := len_pos' C; omega⟩

/-- In `pMerge`, the last pair lies in the same cycle (so the closing swap splits). -/
lemma pMerge_lastPair_sameCycle :
    (pMerge C).SameCycle (C.dart (lastIdx C)) (M.α (C.dart (lastIdx C))) := by
  unfold pMerge
  have hBpos : 0 < C.len := len_pos' C
  obtain ⟨_, ihqr, _⟩ := bankInvariant C (C.len - 1) (by omega)
  rw [ihqr (lastIdx C) (lastIdx C)]
  right
  have hnl : (C.nextIdx (lastIdx C)).1 = 0 := by
    rw [SimplePrimalCycle.nextIdx_val]
    show ((C.len - 1) + 1) % C.len = 0
    rw [Nat.sub_add_cancel (by omega), Nat.mod_self]
  refine ⟨?_, ?_⟩
  · show (C.len - 1) ≤ C.len - 1; exact le_refl _
  · rw [hnl]; exact Nat.zero_le _



/-- A cycle dart is some `C.dart m` or `M.α (C.dart m)`; the forward case here. -/
lemma listSwapQR_apply_dart (m : Fin C.len) :
    ∀ L : List (Fin C.len), L.Nodup → m ∈ L →
      ((L.map (fun i => (C.dart i, M.α (C.dart i)))).map (fun w => Equiv.swap w.1 w.2)).prod
          (C.dart m) = M.α (C.dart m) := by
  intro L
  induction L with
  | nil => intro _ hm; simp only [List.not_mem_nil] at hm
  | cons c t ih =>
      intro hnd hm
      rw [List.map_cons, List.map_cons, List.prod_cons, Equiv.Perm.mul_apply]
      have hndt := (List.nodup_cons.mp hnd)
      by_cases hmt : m ∈ t
      · have hcm : c ≠ m := fun h => hndt.1 (h ▸ hmt)
        rw [ih hndt.2 hmt]
        show Equiv.swap (C.dart c) (M.α (C.dart c)) (M.α (C.dart m)) = M.α (C.dart m)
        rw [Equiv.swap_apply_of_ne_of_ne (alphaDart_ne_dart C m c)
          (fun h => hcm (C.alpha_dart_inj h).symm)]
      · have hmc : m = c := by
          rcases List.mem_cons.mp hm with h | h
          · exact h
          · exact absurd h hmt
        subst hmc
        have htail : ((t.map (fun i => (C.dart i, M.α (C.dart i)))).map
            (fun w => Equiv.swap w.1 w.2)).prod (C.dart m) = C.dart m := by
          apply CombMap.CutCapCount.listSwap_prod_apply_of_notMem
          intro w hw
          rw [List.mem_map] at hw
          obtain ⟨i, hi, hwi⟩ := hw
          have hineq : i ≠ m := fun h => hmt (h ▸ hi)
          subst hwi
          exact ⟨fun h => hineq (C.dart_inj h).symm, dart_ne_alphaDart C m i⟩
        rw [htail]
        show Equiv.swap (C.dart m) (M.α (C.dart m)) (C.dart m) = M.α (C.dart m)
        rw [Equiv.swap_apply_left]

/-- The reverse case: at an `α`-dart whose index is in the (nodup) list. -/
lemma listSwapQR_apply_alphaDart (m : Fin C.len) :
    ∀ L : List (Fin C.len), L.Nodup → m ∈ L →
      ((L.map (fun i => (C.dart i, M.α (C.dart i)))).map (fun w => Equiv.swap w.1 w.2)).prod
          (M.α (C.dart m)) = C.dart m := by
  intro L
  induction L with
  | nil => intro _ hm; simp only [List.not_mem_nil] at hm
  | cons c t ih =>
      intro hnd hm
      rw [List.map_cons, List.map_cons, List.prod_cons, Equiv.Perm.mul_apply]
      have hndt := (List.nodup_cons.mp hnd)
      by_cases hmt : m ∈ t
      · have hcm : c ≠ m := fun h => hndt.1 (h ▸ hmt)
        rw [ih hndt.2 hmt]
        show Equiv.swap (C.dart c) (M.α (C.dart c)) (C.dart m) = C.dart m
        rw [Equiv.swap_apply_of_ne_of_ne (fun h => hcm (C.dart_inj h).symm) (dart_ne_alphaDart C m c)]
      · have hmc : m = c := by
          rcases List.mem_cons.mp hm with h | h
          · exact h
          · exact absurd h hmt
        subst hmc
        have htail : ((t.map (fun i => (C.dart i, M.α (C.dart i)))).map
            (fun w => Equiv.swap w.1 w.2)).prod (M.α (C.dart m)) = M.α (C.dart m) := by
          apply CombMap.CutCapCount.listSwap_prod_apply_of_notMem
          intro w hw
          rw [List.mem_map] at hw
          obtain ⟨i, hi, hwi⟩ := hw
          have hineq : i ≠ m := fun h => hmt (h ▸ hi)
          subst hwi
          exact ⟨alphaDart_ne_dart C m i, fun h => hineq (C.alpha_dart_inj h).symm⟩
        rw [htail]
        show Equiv.swap (C.dart m) (M.α (C.dart m)) (M.α (C.dart m)) = C.dart m
        rw [Equiv.swap_apply_right]

/-- Evaluation at a dart that is neither a forward nor reverse cycle dart: it is fixed. -/
lemma listSwapQR_apply_other (d : D)
    (L : List (Fin C.len))
    (hd : ∀ i ∈ L, d ≠ C.dart i ∧ d ≠ M.α (C.dart i)) :
    ((L.map (fun i => (C.dart i, M.α (C.dart i)))).map (fun w => Equiv.swap w.1 w.2)).prod d = d := by
  apply CombMap.CutCapCount.listSwap_prod_apply_of_notMem
  intro w hw
  rw [List.mem_map] at hw
  obtain ⟨i, hi, hwi⟩ := hw
  subst hwi
  exact hd i hi

/-- The full pair list over all `C.len` indices. -/
noncomputable def allPairs (C : SimplePrimalCycle M) : List (D × D) :=
  (List.finRange C.len).map (fun i => (C.dart i, M.α (C.dart i)))

/-- `cycleTau` is the product of the `C.len` disjoint cycle transpositions. -/
lemma cycleTau_eq_swapProd :
    cycleTau C = ((allPairs C).map (fun w => Equiv.swap w.1 w.2)).prod := by
  have hnd : (List.finRange C.len).Nodup := List.nodup_finRange _
  ext d
  unfold allPairs
  by_cases hd : d ∈ C.dartSet
  · rw [cycleTau_eq_alpha_of_mem C hd]
    rw [C.mem_dartSet_iff] at hd
    obtain ⟨m, hm | hm⟩ := hd
    · -- d = C.dart m
      subst hm
      rw [listSwapQR_apply_dart C m _ hnd (List.mem_finRange m)]
    · -- d = α (C.dart m)
      subst hm
      rw [listSwapQR_apply_alphaDart C m _ hnd (List.mem_finRange m), M.alpha_alpha]
  · rw [cycleTau_eq_self_of_notMem C hd]
    refine (listSwapQR_apply_other C d _ ?_).symm
    intro i _
    refine ⟨?_, ?_⟩
    · intro h; exact hd (h ▸ C.dart_mem_dartSet i)
    · intro h; exact hd (h ▸ C.alpha_dart_mem_dartSet i)

/-- `allPairs = mergePairs ++ [last pair]`. -/
lemma allPairs_eq_append :
    allPairs C = mergePairs C ++ [(C.dart (lastIdx C), M.α (C.dart (lastIdx C)))] := by
  have hBpos : 0 < C.len := len_pos' C
  have hlenA : (allPairs C).length = C.len := by
    simp [allPairs, List.length_map, List.length_finRange]
  have hmlen : (mergePairs C).length = C.len - 1 := mergePairs_length C
  have hlenR : (mergePairs C ++ [(C.dart (lastIdx C), M.α (C.dart (lastIdx C)))]).length
      = C.len := by
    rw [List.length_append, hmlen, List.length_singleton]; omega
  apply List.ext_getElem (by rw [hlenA, hlenR])
  intro n hn1 hn2
  rw [hlenA] at hn1
  have hLHS : (allPairs C)[n] = (C.dart ⟨n, hn1⟩, M.α (C.dart ⟨n, hn1⟩)) := by
    simp only [allPairs]
    rw [List.getElem_map, List.getElem_finRange]
    congr 1
  rw [hLHS]
  by_cases hnlast : n < C.len - 1
  · rw [List.getElem_append_left (by rw [hmlen]; exact hnlast)]
    simp only [mergePairs]
    rw [List.getElem_map, List.getElem_finRange]
    show (C.dart ⟨n, hn1⟩, M.α (C.dart ⟨n, hn1⟩))
      = (C.dart (emb C _), M.α (C.dart (emb C _)))
    congr 1
  · rw [List.getElem_append_right (by rw [hmlen]; omega)]
    have hidx : (⟨n, hn1⟩ : Fin C.len) = lastIdx C :=
      Fin.ext (by simp only [lastIdx]; omega)
    rw [hidx, List.getElem_singleton]

/-- `M.σ * cycleTau = pMerge * swap (C.dart last) (α (C.dart last))`. -/
lemma sigma_cycleTau_eq :
    M.σ * cycleTau C
      = pMerge C * Equiv.swap (C.dart (lastIdx C)) (M.α (C.dart (lastIdx C))) := by
  rw [cycleTau_eq_swapProd, allPairs_eq_append, List.map_append, List.prod_append]
  unfold pMerge pPrefix
  rw [List.take_of_length_le (by rw [mergePairs_length]), List.map_singleton, List.prod_cons,
      List.prod_nil, mul_one, ← mul_assoc]

/-- **The bank count — UNCONDITIONAL.**
`numCycles (M.φ * cycleDualAlpha C) = M.V − C.len + 2`. -/
theorem bankCount_holds :
    _root_.numCycles (M.φ * cycleDualAlpha C) = M.V - C.len + 2 := by
  rw [phi_cycleDualAlpha_eq_sigma_cycleTau, sigma_cycleTau_eq]
  have hsplit : _root_.numCycles
      (pMerge C * Equiv.swap (C.dart (lastIdx C)) (M.α (C.dart (lastIdx C))))
      = _root_.numCycles (pMerge C) + 1 :=
    CombMap.CutCapCount.numCycles_mul_swap_of_sameCycle (pMerge C)
      (dart_ne_alphaDart_self C (lastIdx C)) (pMerge_lastPair_sameCycle C)
  rw [hsplit]
  have hmerge := numCycles_pMerge_add C
  have hBpos : 0 < C.len := len_pos' C
  have hBV : C.len ≤ M.V := len_le_V C
  omega



/-- A dart lies in `C.dartSet` iff its edge lies in `C.edgeSet`. -/
lemma mem_dartSet_iff_edgeSet (hsimple : M.IsSimpleGraph) {d : D} :
    d ∈ C.dartSet ↔ M.dartEdge d ∈ C.edgeSet := by
  constructor
  · intro hd
    rw [C.mem_dartSet_iff] at hd
    obtain ⟨i, hi | hi⟩ := hd
    · exact (C.mem_edgeSet_iff _).2 ⟨i, by rw [hi, SimplePrimalCycle.edge]⟩
    · exact (C.mem_edgeSet_iff _).2 ⟨i, by rw [hi, SimplePrimalCycle.edge, M.dartEdge_alpha]⟩
  · intro he
    rw [C.mem_edgeSet_iff] at he
    obtain ⟨i, hi⟩ := he
    -- `dartEdge d = C.edge i = dartEdge (C.dart i)` ⟹ `α.SameCycle d (C.dart i)`
    have hsc : M.α.SameCycle d (C.dart i) :=
      hsimple.no_parallel (by rw [hi, SimplePrimalCycle.edge])
    rcases (M.alpha_sameCycle_iff d (C.dart i)).mp hsc with hde | hde
    · exact (C.mem_dartSet_iff d).2 ⟨i, Or.inl (by rw [hde])⟩
    · exact (C.mem_dartSet_iff d).2 ⟨i, Or.inr (by rw [hde, M.alpha_alpha])⟩

lemma notMem_dartSet_iff_not_edgeSet (hsimple : M.IsSimpleGraph) {d : D} :
    d ∉ C.dartSet ↔ M.dartEdge d ∉ C.edgeSet :=
  not_congr (mem_dartSet_iff_edgeSet C hsimple)

/-- Same face ⟺ `M.φ.SameCycle`. -/
lemma sameFace_iff_phi_sameCycle {a b : D} :
    M.dartFace a = M.dartFace b ↔ M.φ.SameCycle a b := by
  constructor
  · intro h; exact Quotient.exact h
  · intro h; exact Quotient.sound h

/-- The relation `dartStepRel M.φ (cycleDualAlpha C)`. -/
abbrev RDart (C : SimplePrimalCycle M) : D → D → Prop :=
  dartStepRel M.φ (cycleDualAlpha C)

/-- A single `RDart`-step descends to `EqvGen (DualAvoidsCycleStep)` on faces. -/
lemma eqvGen_dualStep_of_RDart_step (hsimple : M.IsSimpleGraph) {a b : D}
    (h : RDart C a b) :
    Relation.EqvGen (DualAvoidsCycleStep M C) (M.dartFace a) (M.dartFace b) := by
  rcases h with hsc | hαe
  · have : M.dartFace a = M.dartFace b := sameFace_iff_phi_sameCycle.mpr hsc
    rw [this]; exact Relation.EqvGen.refl _
  · by_cases hd : a ∈ C.dartSet
    · rw [hαe, cycleDualAlpha_eq_self_of_mem C hd]
      exact Relation.EqvGen.refl _
    · have hba : b = M.α a := by
        rw [hαe, cycleDualAlpha_eq_alpha_of_notMem C hd]
      have hnb : M.dartEdge a ∉ C.edgeSet :=
        (notMem_dartSet_iff_not_edgeSet C hsimple).mp hd
      have hstep : DualAvoidsCycleStep M C (M.dartFace a) (M.dartFace b) :=
        ⟨a, hnb, rfl, by rw [hba]⟩
      exact Relation.EqvGen.rel _ _ hstep

/-- A single `DualAvoidsCycleStep` lifts to `EqvGen RDart` on any dart reps. -/
lemma eqvGen_RDart_of_dualStep {f g : M.Face} {a b : D}
    (hstep : DualAvoidsCycleStep M C f g) (ha : M.dartFace a = f) (hb : M.dartFace b = g) :
    Relation.EqvGen (RDart C) a b := by
  obtain ⟨d, hbe, hdf, hdg⟩ := hstep
  have hdDel : d ∉ C.dartSet := C.notMem_dartSet_of_dartEdge_notMem hbe
  have h1 : Relation.EqvGen (RDart C) a d :=
    Relation.EqvGen.rel _ _ (Or.inl (sameFace_iff_phi_sameCycle.mp (by rw [ha, hdf])))
  have h2 : Relation.EqvGen (RDart C) d (M.α d) :=
    Relation.EqvGen.rel _ _ (Or.inr (by
      rw [cycleDualAlpha_eq_alpha_of_notMem C hdDel]))
  have h3 : Relation.EqvGen (RDart C) (M.α d) b :=
    Relation.EqvGen.rel _ _ (Or.inl (sameFace_iff_phi_sameCycle.mp (by rw [hdg, hb])))
  exact (h1.trans _ _ _ h2).trans _ _ _ h3

/-- A `DualAvoidsCycleStep`-walk lifts to `EqvGen RDart`. -/
lemma eqvGen_RDart_of_dualStep_walk {f g : M.Face} {a b : D}
    (hwalk : Relation.ReflTransGen (DualAvoidsCycleStep M C) f g)
    (ha : M.dartFace a = f) (hb : M.dartFace b = g) :
    Relation.EqvGen (RDart C) a b := by
  induction hwalk generalizing b with
  | refl =>
    exact Relation.EqvGen.rel _ _ (Or.inl (sameFace_iff_phi_sameCycle.mp (by rw [ha, hb])))
  | @tail x y hwxy hstep ih =>
    obtain ⟨c, hc⟩ : ∃ c : D, M.dartFace c = x := ⟨Quotient.out x, Quotient.out_eq x⟩
    have hac : Relation.EqvGen (RDart C) a c := ih hc
    have hcb : Relation.EqvGen (RDart C) c b :=
      eqvGen_RDart_of_dualStep C hstep hc hb
    exact hac.trans _ _ _ hcb

/-- The full `EqvGen RDart`-walk descends to `EqvGen DualAvoidsCycleStep` on faces. -/
lemma eqvGen_dualStep_of_RDart_eqv (hsimple : M.IsSimpleGraph) {a b : D}
    (hab : Relation.EqvGen (RDart C) a b) :
    Relation.EqvGen (DualAvoidsCycleStep M C) (M.dartFace a) (M.dartFace b) := by
  induction hab with
  | rel x y h => exact eqvGen_dualStep_of_RDart_step C hsimple h
  | refl x => exact Relation.EqvGen.refl _
  | symm x y _ ih => exact ih.symm _ _
  | trans x y z _ _ ih1 ih2 => exact ih1.trans _ _ _ ih2

/-- `DualAvoidsCycleStep` is symmetric (the reverse dart witnesses the reverse step). -/
lemma dualAvoidsCycleStep_symm {f g : M.Face} (h : DualAvoidsCycleStep M C f g) :
    DualAvoidsCycleStep M C g f := by
  obtain ⟨d, hbe, hdf, hdg⟩ := h
  refine ⟨M.α d, ?_, hdg, ?_⟩
  · rw [M.dartEdge_alpha]; exact hbe
  · rw [M.alpha_alpha]; exact hdf

/-- `EqvGen (DualAvoidsCycleStep)` coincides with `ReflTransGen` (symmetric relation). -/
lemma eqvGen_dualStep_iff {f g : M.Face} :
    Relation.EqvGen (DualAvoidsCycleStep M C) f g ↔
      Relation.ReflTransGen (DualAvoidsCycleStep M C) f g :=
  eqvGen_iff_reflTransGen (fun _ _ => dualAvoidsCycleStep_symm C) f g

/-- The face quotient map descends from the dart component quotient. -/
noncomputable def faceQuotMap (hsimple : M.IsSimpleGraph) :
    Quotient (compSetoid (RDart C)) → Quotient (compSetoid (DualAvoidsCycleStep M C)) :=
  Quotient.lift (fun d => Quotient.mk (compSetoid (DualAvoidsCycleStep M C)) (M.dartFace d))
    (by
      intro a b hab
      apply Quotient.sound
      exact eqvGen_dualStep_of_RDart_eqv C hsimple hab)

/-- **The dart-face quotient bridge.**  The component count of the dual sub-involution pair
equals the dual-face component count `numComp (DualAvoidsCycleStep M C)`. -/
lemma numComponents_eq_numComp_dualStep (hsimple : M.IsSimpleGraph) :
    numComponents M.φ (cycleDualAlpha C) = numComp (DualAvoidsCycleStep M C) := by
  classical
  rw [numComponents_def]
  show numComp (RDart C) = numComp (DualAvoidsCycleStep M C)
  unfold numComp
  apply Nat.card_congr
  refine Equiv.ofBijective (faceQuotMap C hsimple) ⟨?_, ?_⟩
  · intro x y hxy
    refine Quotient.inductionOn₂ x y (fun a b hab => ?_) hxy
    apply Quotient.sound
    have heqf : Relation.EqvGen (DualAvoidsCycleStep M C) (M.dartFace a) (M.dartFace b) :=
      Quotient.exact hab
    have hwalk : Relation.ReflTransGen (DualAvoidsCycleStep M C) (M.dartFace a) (M.dartFace b) :=
      (eqvGen_dualStep_iff C).1 heqf
    exact eqvGen_RDart_of_dualStep_walk C hwalk rfl rfl
  · intro q
    refine Quotient.inductionOn q (fun f => ?_)
    obtain ⟨d, hd⟩ : ∃ d : D, M.dartFace d = f := ⟨Quotient.out f, Quotient.out_eq f⟩
    exact ⟨Quotient.mk (compSetoid (RDart C)) d, by
      show Quotient.mk _ (M.dartFace d) = Quotient.mk _ f
      rw [hd]⟩



/-- **The two-component count for an arbitrary simple primal cycle — UNCONDITIONAL** (given
sphere + simple-graph).  Expanding `genusSlack M.φ (cycleDualAlpha C) = 0` with the bank
count, the `Ehalf`, the dart-face bridge, and Euler `V − E + F = 2`. -/
theorem dualAvoidsCycle_numComp_two (hsphere : M.IsSphereMap) (hsimple : M.IsSimpleGraph) :
    numComp (DualAvoidsCycleStep M C) = 2 := by
  have h0 : genusSlack M.φ (cycleDualAlpha C) = 0 :=
    genusSlack_cycleDualAlpha_eq_zero C hsphere
  have hE5 : Ehalf (cycleDualAlpha C) = M.E - C.len := Ehalf_cycleDualAlpha C
  have h6 : _root_.numCycles (M.φ * cycleDualAlpha C) = M.V - C.len + 2 := bankCount_holds C
  have hbridge : numComponents M.φ (cycleDualAlpha C) = numComp (DualAvoidsCycleStep M C) :=
    numComponents_eq_numComp_dualStep C hsimple
  have hF : _root_.numCycles M.φ = M.F := (M.F_eq_numCycles).symm
  have hEuler : (M.V : ℤ) - (M.E : ℤ) + (M.F : ℤ) = 2 := hsphere.2
  set B := C.len with hB
  have hBE : B ≤ M.E := len_le_E C
  unfold genusSlack at h0
  rw [hbridge, hF, hE5, h6] at h0
  have hcast5 : ((M.E - B : ℕ) : ℤ) = (M.E : ℤ) - (B : ℤ) := by
    rw [Nat.cast_sub hBE]
  have hcast6 : ((M.V - B + 2 : ℕ) : ℤ) = (M.V : ℤ) - (B : ℤ) + 2 := by
    have hBV : B ≤ M.V := len_le_V C
    push_cast [Nat.cast_sub hBV]; ring
  rw [hcast5, hcast6] at h0
  have hc : (numComp (DualAvoidsCycleStep M C) : ℤ) = 2 := by linarith
  exact_mod_cast hc







/-- **The local σ-star classifier at a cycle vertex.**  A dart `z` in the σ-orbit of
`M.α (C.dart i)` (i.e. `tail z = v_{nextIdx i}`) has its edge in `C.edgeSet` iff `z` is one
of the two cycle darts `M.α (C.dart i)` or `C.dart (nextIdx i)`.

We package the "iff" as the contrapositive we actually use: if `z` shares the σ-orbit and is
neither of the two cycle darts, then `dartEdge z ∉ C.edgeSet`. -/
lemma not_mem_edgeSet_of_star_not_cycleDart (hsimple : M.IsSimpleGraph) {i : Fin C.len} {z : D}
    (hσ : M.σ.SameCycle (M.α (C.dart i)) z)
    (hz1 : z ≠ M.α (C.dart i)) (hz2 : z ≠ C.dart (C.nextIdx i)) :
    M.dartEdge z ∉ C.edgeSet := by
  rw [← notMem_dartSet_iff_not_edgeSet C hsimple]
  intro hmem
  rw [C.mem_dartSet_iff] at hmem
  -- `tail z = tail (α (C.dart i)) = head (C.dart i) = v_{nextIdx i}`.
  have htail : M.tail z = M.tail (C.dart (C.nextIdx i)) := by
    rw [(sigma_sameCycle_iff_tail (M.α (C.dart i)) z).mp hσ |>.symm, M.tail_alpha,
        C.tail_dart_nextIdx i]
  obtain ⟨j, hj | hj⟩ := hmem
  · -- z = C.dart j, tail = tail (C.dart j) = v_{nextIdx i} ⟹ j = nextIdx i.
    apply hz2
    rw [hj]; congr 1
    apply C.tail_inj
    show M.tail (C.dart j) = M.tail (C.dart (C.nextIdx i))
    rw [← hj]; exact htail
  · -- z = α (C.dart j), tail = head (C.dart j) = v_{nextIdx i} = head (C.dart i) ⟹ j = i.
    apply hz1
    -- `tail (α (C.dart j)) = tail (α (C.dart i))` ⟹ `j = i` ⟹ `z = α (C.dart j) = α (C.dart i)`.
    have hheadj : M.tail (M.α (C.dart j)) = M.tail (C.dart (C.nextIdx i)) := by
      rw [← hj]; exact htail
    have hi : M.head (C.dart i) = M.tail (C.dart (C.nextIdx i)) := C.consecutive' i
    -- head (C.dart j) = head (C.dart i): chase through nextIdx tails.
    have hheadeq : M.head (C.dart j) = M.head (C.dart i) := hheadj.trans hi.symm
    have hnext : M.tail (C.dart (C.nextIdx j)) = M.tail (C.dart (C.nextIdx i)) := by
      rw [C.tail_dart_nextIdx j, C.tail_dart_nextIdx i, hheadeq]
    have hnij : C.nextIdx j = C.nextIdx i := C.tail_inj hnext
    have hji : j = i := nextIdx_inj C hnij
    rw [hj, hji]



/-- **The general simple-cycle bank theorem (R6 §4).**  Packages the two-bank structure of an
arbitrary simple primal cycle: the unconditional two-component count, plus the bank labels
(left/right connectivity and separation).  The `dual_numComp_two`, `bankOrbitCount`,
`slack_zero` fields are filled **unconditionally** by `cycleBankTheorem_core`; the bank-label
fields are carried as the residual. -/
structure SimpleCycleBankTheorem (M : CombMap D) (C : SimplePrimalCycle M) where
  dual_numComp_two : numComp (DualAvoidsCycleStep M C) = 2
  bankOrbitCount : _root_.numCycles (M.φ * cycleDualAlpha C) = M.V - C.len + 2
  slack_zero : genusSlack M.φ (cycleDualAlpha C) = 0
  left_bank : ∀ i j : Fin C.len,
    Relation.ReflTransGen (DualAvoidsCycleStep M C) (C.faceLeft i) (C.faceLeft j)
  right_bank : ∀ i j : Fin C.len,
    Relation.ReflTransGen (DualAvoidsCycleStep M C) (C.faceRight i) (C.faceRight j)
  left_right_sep : ∀ i j : Fin C.len,
    ¬ Relation.ReflTransGen (DualAvoidsCycleStep M C) (C.faceLeft i) (C.faceRight j)





end ProofsInTheBook.ZinanCh35CycleBank











end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35CycleBank
import ProofsInTheBook.ZinanCh35Gates
-/
/- Source module: ProofsInTheBook.ZinanCh35BankLabels -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35BankLabels

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ZinanCh35CycleBank
open Equiv Equiv.Perm

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
variable (C : SimplePrimalCycle M)



/-- One σ-step is a `DualAvoidsCycleStep` step when `dartEdge z ∉ C.edgeSet`. -/
lemma dualStep_sigma (hsimple : M.IsSimpleGraph) {z : D}
    (hz : M.dartEdge z ∉ C.edgeSet) :
    DualAvoidsCycleStep M C (M.dartFace z) (M.dartFace (M.σ z)) := by
  refine ⟨z, hz, rfl, ?_⟩
  rw [ZinanCh35StarConn.dartFace_sigma_eq_alpha]

/-- **The σ-arc walker.**  If every dart `σ^j a` for `0 ≤ j < p` is non-cycle, then
`dartFace a` reaches `dartFace ((σ^p) a)` by a `DualAvoidsCycleStep`-walk. -/
lemma reflTransGen_dualStep_sigma_pow (hsimple : M.IsSimpleGraph) (a : D) :
    ∀ p : ℕ, (∀ j : ℕ, j < p → M.dartEdge ((M.σ ^ j) a) ∉ C.edgeSet) →
      Relation.ReflTransGen (DualAvoidsCycleStep M C)
        (M.dartFace a) (M.dartFace ((M.σ ^ p) a)) := by
  intro p
  induction p with
  | zero => intro _; simpa using Relation.ReflTransGen.refl
  | succ k ih =>
      intro havoid
      have hreach := ih (fun j hj => havoid j (by omega))
      refine hreach.tail ?_
      have heq : M.σ ((M.σ ^ k) a) = (M.σ ^ (k + 1)) a := by rw [pow_succ']; rfl
      have hstep := dualStep_sigma C hsimple (z := (M.σ ^ k) a) (havoid k (by omega))
      rwa [heq] at hstep



/-- `(σ^m) b ≠ b` for `0 < m < L` (`L = #(σ.cycleOf b).support`), `b ∈ σ.support`. -/
lemma sigma_pow_ne_self {b : D} (hb : b ∈ M.σ.support) {m : ℕ}
    (hm0 : 0 < m) (hmL : m < (M.σ.cycleOf b).support.card) : (M.σ ^ m) b ≠ b :=
  ZinanCh35StarConn.sigma_pow_ne_self_of_lt hb hm0 hmL

/-- Within one orbit period the powers are injective: `(σ^j) b = (σ^p) b` with `j, p < L`
forces `j = p`. -/
lemma sigma_pow_inj_of_lt {b : D} (hb : b ∈ M.σ.support) {j p : ℕ}
    (hjL : j < (M.σ.cycleOf b).support.card) (hpL : p < (M.σ.cycleOf b).support.card)
    (h : (M.σ ^ j) b = (M.σ ^ p) b) : j = p := by
  -- `cycleOf` and support card are invariant along the orbit; reduce to `sigma_pow_ne_self`
  -- on the element `c := (σ^j) b`, which `(σ^(p-j))` (resp. `(σ^(j-p))`) fixes.
  by_contra hne
  rcases le_or_gt j p with hjp | hjp
  · -- `(σ^(p-j))` fixes `c = (σ^j) b`.
    set c := (M.σ ^ j) b with hc
    have hscbc : M.σ.SameCycle b c := ⟨(j : ℤ), by rw [zpow_natCast]⟩
    have hcsupp : c ∈ M.σ.support := (SameCycle.mem_support_iff hscbc).mp hb
    have hcard : (M.σ.cycleOf c).support.card = (M.σ.cycleOf b).support.card := by
      rw [hscbc.cycleOf_eq]
    have hpos : 0 < p - j := by omega
    have hlt : p - j < (M.σ.cycleOf c).support.card := by rw [hcard]; omega
    apply sigma_pow_ne_self (M := M) hcsupp hpos hlt
    rw [hc, ← Equiv.Perm.mul_apply, ← pow_add, show p - j + j = p by omega, ← h]
  · set c := (M.σ ^ p) b with hc
    have hscbc : M.σ.SameCycle b c := ⟨(p : ℤ), by rw [zpow_natCast]⟩
    have hcsupp : c ∈ M.σ.support := (SameCycle.mem_support_iff hscbc).mp hb
    have hcard : (M.σ.cycleOf c).support.card = (M.σ.cycleOf b).support.card := by
      rw [hscbc.cycleOf_eq]
    have hpos : 0 < j - p := by omega
    have hlt : j - p < (M.σ.cycleOf c).support.card := by rw [hcard]; omega
    apply sigma_pow_ne_self (M := M) hcsupp hpos hlt
    rw [hc, ← Equiv.Perm.mul_apply, ← pow_add, show j - p + p = j by omega, h]



/-- The reverse anchor `α (C.dart i)` is in `σ.support`: its σ-orbit also contains the distinct
forward dart `C.dart (nextIdx i)` (same tail), so the orbit is nontrivial. -/
lemma rev_mem_support (i : Fin C.len) : M.α (C.dart i) ∈ M.σ.support := by
  rw [Equiv.Perm.mem_support]
  intro hfix
  -- if `σ (α (C.dart i)) = α (C.dart i)`, the σ-orbit of `α (C.dart i)` is a singleton, but it
  -- must also contain `C.dart (nextIdx i)` (same tail), which is distinct.
  have hsc : M.σ.SameCycle (M.α (C.dart i)) (C.dart (C.nextIdx i)) :=
    sigma_sameCycle_alphaDart_dart_next C i
  obtain ⟨n, hn⟩ := hsc
  -- `σ` fixes `α (C.dart i)`, so `(σ^n) (α (C.dart i)) = α (C.dart i)`.
  have hpow : ∀ k : ℤ, (M.σ ^ k) (M.α (C.dart i)) = M.α (C.dart i) := by
    intro k
    have : ∀ m : ℕ, (M.σ ^ m) (M.α (C.dart i)) = M.α (C.dart i) := by
      intro m
      induction m with
      | zero => simp
      | succ t iht => rw [pow_succ', Equiv.Perm.mul_apply, iht, hfix]
    rcases k with k | k
    · simpa using this k
    · -- negative powers: `σ⁻¹` also fixes it.
      have hinv : M.σ⁻¹ (M.α (C.dart i)) = M.α (C.dart i) := by
        rw [Equiv.Perm.inv_eq_iff_eq, hfix]
      have : ∀ m : ℕ, (M.σ⁻¹ ^ m) (M.α (C.dart i)) = M.α (C.dart i) := by
        intro m
        induction m with
        | zero => simp
        | succ t iht => rw [pow_succ', Equiv.Perm.mul_apply, iht, hinv]
      have hk := this (k + 1)
      rw [zpow_negSucc, ← inv_pow]
      exact hk
  have : C.dart (C.nextIdx i) = M.α (C.dart i) := by rw [← hn]; exact hpow n
  exact (dart_ne_alphaDart C (C.nextIdx i) i) this



/-- **Left-bank step.**  `faceLeft i ↝ faceLeft (nextIdx i)` via the σ-arc from
`α (C.dart i)` to `C.dart (nextIdx i)`. -/
lemma left_bank_step (hsimple : M.IsSimpleGraph) (i : Fin C.len) :
    Relation.ReflTransGen (DualAvoidsCycleStep M C)
      (C.faceLeft i) (C.faceLeft (C.nextIdx i)) := by
  set b := M.α (C.dart i) with hb
  have hbsupp : b ∈ M.σ.support := rev_mem_support C i
  set L := (M.σ.cycleOf b).support.card with hL
  -- `fwd = C.dart (nextIdx i)` is in the σ-orbit of `b`, at some power `p`, `0 < p < L`.
  have hsc : M.σ.SameCycle b (C.dart (C.nextIdx i)) := sigma_sameCycle_alphaDart_dart_next C i
  obtain ⟨p, hpL, hp⟩ := hsc.exists_pow_eq_of_mem_support hbsupp
  have hpos : 0 < p := by
    rcases Nat.eq_zero_or_pos p with h0 | h0
    · exfalso; rw [h0, pow_zero] at hp; simp only [Equiv.Perm.coe_one, id] at hp
      exact (dart_ne_alphaDart C (C.nextIdx i) i) hp.symm
    · exact h0
  -- the walk from `σ b` to `(σ^p) b = fwd`: re-anchor at `σ b = (σ^1) b`.
  -- Express as: `dartFace (σ b) ↝ dartFace ((σ^p) b)` using powers `1..p-1` of `b` from `σ b`.
  -- We walk `(σ^j) (σ b) = (σ^(j+1)) b` for `0 ≤ j < p-1`.
  have hwalk :
      Relation.ReflTransGen (DualAvoidsCycleStep M C)
        (M.dartFace (M.σ b)) (M.dartFace ((M.σ ^ (p - 1)) (M.σ b))) := by
    apply reflTransGen_dualStep_sigma_pow C hsimple (M.σ b)
    intro j hj
    -- `(σ^j) (σ b) = (σ^(j+1)) b`, a non-cycle dart (strictly between the two anchors).
    have hjp1 : j + 1 < p := by omega
    have heq : (M.σ ^ j) (M.σ b) = (M.σ ^ (j + 1)) b := by
      rw [← Equiv.Perm.mul_apply, ← pow_succ]
    rw [heq]
    -- non-cycle via the classifier: same σ-cycle as `b`, ≠ `b`, ≠ `fwd`.
    apply not_mem_edgeSet_of_star_not_cycleDart C hsimple (i := i)
    · -- `σ.SameCycle (α (C.dart i)) ((σ^(j+1)) b)`
      exact ⟨(j + 1 : ℕ), by rw [zpow_natCast]⟩
    · -- `(σ^(j+1)) b ≠ b = α (C.dart i)`
      exact sigma_pow_ne_self (M := M) hbsupp (by omega) (by omega)
    · -- `(σ^(j+1)) b ≠ C.dart (nextIdx i) = (σ^p) b`
      intro hcon
      have : j + 1 = p := sigma_pow_inj_of_lt (M := M) hbsupp (by omega) hpL (by rw [hcon, hp])
      omega
  -- rewrite both endpoints.
  have hstart : M.dartFace (M.σ b) = C.faceLeft i := by
    rw [ZinanCh35StarConn.dartFace_sigma_eq_alpha, hb, M.alpha_alpha]; rfl
  have hend : M.dartFace ((M.σ ^ (p - 1)) (M.σ b)) = C.faceLeft (C.nextIdx i) := by
    have heq : (M.σ ^ (p - 1)) (M.σ b) = (M.σ ^ p) b := by
      rw [← Equiv.Perm.mul_apply, ← pow_succ, show (p - 1) + 1 = p by omega]
    rw [heq, hp]; rfl
  rw [hstart, hend] at hwalk
  exact hwalk

/-- **Right-bank step.**  `faceRight (nextIdx i) ↝ faceRight i` via the σ-arc from
`C.dart (nextIdx i)` to `α (C.dart i)`. -/
lemma right_bank_step (hsimple : M.IsSimpleGraph) (i : Fin C.len) :
    Relation.ReflTransGen (DualAvoidsCycleStep M C)
      (C.faceRight (C.nextIdx i)) (C.faceRight i) := by
  set b := C.dart (C.nextIdx i) with hb
  -- `b ∈ σ.support`: its orbit contains `α (C.dart i) ≠ b` (same tail).
  have hbsupp : b ∈ M.σ.support := by
    rw [Equiv.Perm.mem_support]
    intro hfix
    have hsc : M.σ.SameCycle b (M.α (C.dart i)) :=
      (sigma_sameCycle_alphaDart_dart_next C i).symm
    obtain ⟨n, hn⟩ := hsc
    have hpow : ∀ k : ℤ, (M.σ ^ k) b = b := by
      intro k
      have hnat : ∀ m : ℕ, (M.σ ^ m) b = b := by
        intro m; induction m with
        | zero => simp
        | succ t iht => rw [pow_succ', Equiv.Perm.mul_apply, iht, hfix]
      rcases k with k | k
      · simpa using hnat k
      · have hinv : M.σ⁻¹ b = b := by rw [Equiv.Perm.inv_eq_iff_eq, hfix]
        have hinvm : ∀ m : ℕ, (M.σ⁻¹ ^ m) b = b := by
          intro m; induction m with
          | zero => simp
          | succ t iht => rw [pow_succ', Equiv.Perm.mul_apply, iht, hinv]
        have hk := hinvm (k + 1); rw [zpow_negSucc, ← inv_pow]; exact hk
    have : M.α (C.dart i) = b := by rw [← hn]; exact hpow n
    exact (dart_ne_alphaDart C (C.nextIdx i) i) (hb ▸ this.symm)
  set L := (M.σ.cycleOf b).support.card with hL
  have hsc : M.σ.SameCycle b (M.α (C.dart i)) :=
    (sigma_sameCycle_alphaDart_dart_next C i).symm
  obtain ⟨p, hpL, hp⟩ := hsc.exists_pow_eq_of_mem_support hbsupp
  have hpos : 0 < p := by
    rcases Nat.eq_zero_or_pos p with h0 | h0
    · exfalso; rw [h0, pow_zero] at hp; simp only [Equiv.Perm.coe_one, id] at hp
      exact (dart_ne_alphaDart C (C.nextIdx i) i) (hb ▸ hp)
    · exact h0
  have hwalk :
      Relation.ReflTransGen (DualAvoidsCycleStep M C)
        (M.dartFace (M.σ b)) (M.dartFace ((M.σ ^ (p - 1)) (M.σ b))) := by
    apply reflTransGen_dualStep_sigma_pow C hsimple (M.σ b)
    intro j hj
    have hjp1 : j + 1 < p := by omega
    have heq : (M.σ ^ j) (M.σ b) = (M.σ ^ (j + 1)) b := by
      rw [← Equiv.Perm.mul_apply, ← pow_succ]
    rw [heq]
    -- non-cycle: `(σ^(j+1)) b` is in σ-orbit of `α (C.dart i)`, distinct from both anchors.
    apply not_mem_edgeSet_of_star_not_cycleDart C hsimple (i := i)
    · -- `σ.SameCycle (α (C.dart i)) ((σ^(j+1)) b)`: both same-cycle as `b`.
      have h1 : M.σ.SameCycle (M.α (C.dart i)) b :=
        (sigma_sameCycle_alphaDart_dart_next C i)
      exact h1.trans ⟨(j + 1 : ℕ), by rw [zpow_natCast]⟩
    · -- `(σ^(j+1)) b ≠ α (C.dart i) = (σ^p) b`
      intro hcon
      have : j + 1 = p := sigma_pow_inj_of_lt (M := M) hbsupp (by omega) hpL (by rw [hcon, hp])
      omega
    · -- `(σ^(j+1)) b ≠ C.dart (nextIdx i) = b`
      have hne : (M.σ ^ (j + 1)) b ≠ b :=
        sigma_pow_ne_self (M := M) hbsupp (by omega) (by omega)
      rw [hb]; exact hne
  have hstart : M.dartFace (M.σ b) = C.faceRight (C.nextIdx i) := by
    rw [ZinanCh35StarConn.dartFace_sigma_eq_alpha, hb]; rfl
  have hend : M.dartFace ((M.σ ^ (p - 1)) (M.σ b)) = C.faceRight i := by
    have heq : (M.σ ^ (p - 1)) (M.σ b) = (M.σ ^ p) b := by
      rw [← Equiv.Perm.mul_apply, ← pow_succ, show (p - 1) + 1 = p by omega]
    rw [heq, hp]; rfl
  rw [hstart, hend] at hwalk
  exact hwalk



/-- The forward face at any index reaches the forward face at index `0`. -/
lemma left_reaches_zero (hsimple : M.IsSimpleGraph) (i : Fin C.len) :
    Relation.ReflTransGen (DualAvoidsCycleStep M C)
      (C.faceLeft i) (C.faceLeft ⟨0, C.len_pos⟩) := by
  -- strong induction on the index value, quantified over the bound.
  suffices H : ∀ n : ℕ, ∀ hn : n < C.len,
      Relation.ReflTransGen (DualAvoidsCycleStep M C)
        (C.faceLeft ⟨n, hn⟩) (C.faceLeft ⟨0, C.len_pos⟩) from H i.1 i.2
  intro n
  induction n using Nat.strong_induction_on with
  | _ n ih =>
    intro hn
    rcases Nat.eq_zero_or_pos n with h0 | hpos
    · subst h0; exact Relation.ReflTransGen.refl
    · set i : Fin C.len := ⟨n, hn⟩ with hi
      have hprev : (C.prevIdx i).1 = n - 1 := by
        rw [SimplePrimalCycle.prevIdx_val, hi]
        have : n + (C.len - 1) = (n - 1) + C.len := by have := C.len_pos; omega
        rw [this, Nat.add_mod_right, Nat.mod_eq_of_lt (by omega)]
      have hnext : C.nextIdx (C.prevIdx i) = i := C.nextIdx_prevIdx i
      have hstep := left_bank_step C hsimple (C.prevIdx i)
      rw [hnext] at hstep
      have hih := ih (n - 1) (by omega) (by omega)
      have hsymm : Relation.ReflTransGen (DualAvoidsCycleStep M C)
          (C.faceLeft i) (C.faceLeft (C.prevIdx i)) :=
        Relation.ReflTransGen.symmetric (fun _ _ h => dualAvoidsCycleStep_symm C h) hstep
      have hih' : Relation.ReflTransGen (DualAvoidsCycleStep M C)
          (C.faceLeft (C.prevIdx i)) (C.faceLeft ⟨0, C.len_pos⟩) := by
        have hpe : (C.prevIdx i) = ⟨n - 1, by omega⟩ := Fin.ext hprev
        rw [hpe]; exact hih
      exact hsymm.trans hih'

/-- The reverse face at any index reaches the reverse face at index `0`. -/
lemma right_reaches_zero (hsimple : M.IsSimpleGraph) (i : Fin C.len) :
    Relation.ReflTransGen (DualAvoidsCycleStep M C)
      (C.faceRight i) (C.faceRight ⟨0, C.len_pos⟩) := by
  suffices H : ∀ n : ℕ, ∀ hn : n < C.len,
      Relation.ReflTransGen (DualAvoidsCycleStep M C)
        (C.faceRight ⟨n, hn⟩) (C.faceRight ⟨0, C.len_pos⟩) from H i.1 i.2
  intro n
  induction n using Nat.strong_induction_on with
  | _ n ih =>
    intro hn
    rcases Nat.eq_zero_or_pos n with h0 | hpos
    · subst h0; exact Relation.ReflTransGen.refl
    · set i : Fin C.len := ⟨n, hn⟩ with hi
      have hprev : (C.prevIdx i).1 = n - 1 := by
        rw [SimplePrimalCycle.prevIdx_val, hi]
        have : n + (C.len - 1) = (n - 1) + C.len := by have := C.len_pos; omega
        rw [this, Nat.add_mod_right, Nat.mod_eq_of_lt (by omega)]
      have hnext : C.nextIdx (C.prevIdx i) = i := C.nextIdx_prevIdx i
      have hstep := right_bank_step C hsimple (C.prevIdx i)
      rw [hnext] at hstep
      have hih := ih (n - 1) (by omega) (by omega)
      have hih' : Relation.ReflTransGen (DualAvoidsCycleStep M C)
          (C.faceRight (C.prevIdx i)) (C.faceRight ⟨0, C.len_pos⟩) := by
        have hpe : (C.prevIdx i) = ⟨n - 1, by omega⟩ := Fin.ext hprev
        rw [hpe]; exact hih
      exact hstep.trans hih'



/-- **`left_bank`.**  Any two forward faces are `DualAvoidsCycleStep`-connected. -/
theorem left_bank_holds (hsimple : M.IsSimpleGraph) (i j : Fin C.len) :
    Relation.ReflTransGen (DualAvoidsCycleStep M C) (C.faceLeft i) (C.faceLeft j) := by
  have hi := left_reaches_zero C hsimple i
  have hj := left_reaches_zero C hsimple j
  exact hi.trans
    (Relation.ReflTransGen.symmetric (fun _ _ h => dualAvoidsCycleStep_symm C h) hj)

/-- **`right_bank`.**  Any two reverse faces are `DualAvoidsCycleStep`-connected. -/
theorem right_bank_holds (hsimple : M.IsSimpleGraph) (i j : Fin C.len) :
    Relation.ReflTransGen (DualAvoidsCycleStep M C) (C.faceRight i) (C.faceRight j) := by
  have hi := right_reaches_zero C hsimple i
  have hj := right_reaches_zero C hsimple j
  exact hi.trans
    (Relation.ReflTransGen.symmetric (fun _ _ h => dualAvoidsCycleStep_symm C h) hj)



/-- **`left_right_sep`.**  No forward face reaches any reverse face avoiding the cycle.  If it
did, chaining through the two bank classes yields `faceLeft j ↝ faceRight j`, contradicting the
discharged Jordan gate `jordan_simple_cycle2_unconditional`. -/
theorem left_right_sep_holds (hsphere : M.IsSphereMap) (hsimple : M.IsSimpleGraph)
    (i j : Fin C.len) :
    ¬ Relation.ReflTransGen (DualAvoidsCycleStep M C) (C.faceLeft i) (C.faceRight j) := by
  intro hreach
  -- `faceLeft j ↝ faceLeft i ↝ faceRight j ↝ faceRight j` (j↝j trivial), giving the forbidden pair.
  have hLj : Relation.ReflTransGen (DualAvoidsCycleStep M C) (C.faceLeft j) (C.faceLeft i) :=
    left_bank_holds C hsimple j i
  have hchain : Relation.ReflTransGen (DualAvoidsCycleStep M C) (C.faceLeft j) (C.faceRight j) :=
    hLj.trans hreach
  -- this IS `DualReachableAvoidingCycle M C (faceLeft j) (faceRight j)`.
  have hbad : DualReachableAvoidingCycle M C (C.faceLeft j) (C.faceRight j) := hchain
  exact (C.jordan_simple_cycle2_unconditional hsphere.2 hsphere.1 j) hbad



/-- **The full general simple-cycle bank theorem.**  For an arbitrary `SimplePrimalCycle` on a
sphere simple-graph map, all six fields of `SimpleCycleBankTheorem` are discharged: the count
core (`numComp = 2`, the bank orbit count, `genusSlack = 0`) unconditionally from
`ZinanCh35CycleBank`, and the three bank labels (`left_bank`, `right_bank`, `left_right_sep`)
from the σ-arc walker + the discharged Jordan gate. -/
def simpleCycleBankTheorem_holds (hsphere : M.IsSphereMap) (hsimple : M.IsSimpleGraph) :
    SimpleCycleBankTheorem M C where
  dual_numComp_two := dualAvoidsCycle_numComp_two C hsphere hsimple
  bankOrbitCount := bankCount_holds C
  slack_zero := genusSlack_cycleDualAlpha_eq_zero C hsphere
  left_bank := left_bank_holds C hsimple
  right_bank := right_bank_holds C hsimple
  left_right_sep := left_right_sep_holds C hsphere hsimple

end ProofsInTheBook.ZinanCh35BankLabels








end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35Gates
-/
/- Source module: ProofsInTheBook.ZinanCh35ChordCycle -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace BoundaryCycle

variable {M : CombMap D} {f : M.Face}


noncomputable def cyclicDartArc (C : BoundaryCycle M f) (hC : C.VertexNodup)
    (p k : ℕ) (hk : 1 ≤ k) (hkL : k < C.darts.length)
    (hp : p < C.darts.length) :
    DartArc M C (M.tail (C.darts[p]'hp))
      (M.tail (C.darts[(p + k) % C.darts.length]'(Nat.mod_lt _ (by omega)))) where
  len := k
  len_pos := hk
  arcDart j := C.darts[(p + j.1) % C.darts.length]'(Nat.mod_lt _ (by omega))
  boundary j := List.getElem_mem _
  chain j hj := by
    -- head (darts[(p+j)%L]) = tail (darts[((p+j)+1)%L]) = tail (darts[(p+(j+1))%L]).
    set L := C.darts.length with hL
    have hLpos : 0 < L := C.darts_length_pos
    have hpos : (p + (j : ℕ)) % L < L := Nat.mod_lt _ hLpos
    have hcv := C.consecutive_vertex ⟨(p + (j : ℕ)) % L, hpos⟩
    -- cyclicNext of ((p+j)%L) is (((p+j)%L)+1)%L = ((p+j)+1)%L = (p+(j+1))%L.
    have hcyc : (cyclicNext C.normalized.length_pos ⟨(p + (j : ℕ)) % L, hpos⟩ : Fin L)
        = ⟨(p + ((j : ℕ) + 1)) % L, Nat.mod_lt _ hLpos⟩ := by
      apply Fin.ext
      show ((p + (j : ℕ)) % L + 1) % L = (p + ((j : ℕ) + 1)) % L
      rw [Nat.mod_add_mod]
      congr 1
    rw [hcyc] at hcv
    -- Translate `.get` to `[…]` and conclude.
    show M.head (C.darts[(p + (j : ℕ)) % L]'_)
        = M.tail (C.darts[(p + ((j : ℕ) + 1)) % L]'_)
    rw [show (C.darts.get ⟨(p + (j : ℕ)) % L, hpos⟩) = C.darts[(p + (j : ℕ)) % L]'hpos from rfl,
      show (C.darts.get ⟨(p + ((j : ℕ) + 1)) % L, Nat.mod_lt _ hLpos⟩)
          = C.darts[(p + ((j : ℕ) + 1)) % L]'(Nat.mod_lt _ hLpos) from rfl] at hcv
    exact hcv.symm
  tail_first := by
    have hLpos : 0 < C.darts.length := C.darts_length_pos
    have heq : (p + (0 : ℕ)) % C.darts.length = p := by
      rw [Nat.add_zero, Nat.mod_eq_of_lt hp]
    show M.tail (C.darts[(p + (0 : ℕ)) % C.darts.length]'_) = M.tail (C.darts[p]'hp)
    simp only [heq]
  head_last := by
    set L := C.darts.length with hL
    have hLpos : 0 < L := C.darts_length_pos
    -- head (darts[(p+(k-1))%L]) = tail (darts[(p+k)%L]) via consecutive_vertex.
    have hpos : (p + (k - 1)) % L < L := Nat.mod_lt _ hLpos
    have hcv := C.consecutive_vertex ⟨(p + (k - 1)) % L, hpos⟩
    have hcyc : (cyclicNext C.normalized.length_pos ⟨(p + (k - 1)) % L, hpos⟩ : Fin L)
        = ⟨(p + k) % L, Nat.mod_lt _ hLpos⟩ := by
      apply Fin.ext
      show ((p + (k - 1)) % L + 1) % L = (p + k) % L
      rw [Nat.mod_add_mod]
      congr 1
      omega
    rw [hcyc] at hcv
    show M.head (C.darts[(p + ((k : ℕ) - 1)) % L]'_) = M.tail (C.darts[(p + k) % L]'_)
    rw [show (C.darts.get ⟨(p + (k - 1)) % L, hpos⟩) = C.darts[(p + (k - 1)) % L]'hpos from rfl,
      show (C.darts.get ⟨(p + k) % L, Nat.mod_lt _ hLpos⟩)
          = C.darts[(p + k) % L]'(Nat.mod_lt _ hLpos) from rfl] at hcv
    exact hcv.symm
  tail_nodup := by
    -- positions (p+i)%L (i < k ≤ L) are pairwise distinct, so darts and tails are.
    set L := C.darts.length with hL
    have hmap : (C.darts.map M.tail).Nodup := by
      simpa [BoundaryCycle.VertexNodup, C.vertices_eq] using hC
    intro i₁ i₂ htail
    have hi₁ : (i₁ : ℕ) < k := i₁.isLt
    have hi₂ : (i₂ : ℕ) < k := i₂.isLt
    have h1 : (p + (i₁ : ℕ)) % L < L := Nat.mod_lt _ C.darts_length_pos
    have h2 : (p + (i₂ : ℕ)) % L < L := Nat.mod_lt _ C.darts_length_pos
    have hdarts : C.darts[(p + (i₁ : ℕ)) % L]'h1 = C.darts[(p + (i₂ : ℕ)) % L]'h2 := by
      have hinj := List.inj_on_of_nodup_map hmap (List.getElem_mem h1) (List.getElem_mem h2)
      exact hinj htail
    have hpos_eq : (p + (i₁ : ℕ)) % L = (p + (i₂ : ℕ)) % L :=
      (C.normalized.nodup.getElem_inj_iff).mp hdarts
    -- both residues equal and both `< L` with `i < k ≤ L`: the `i`'s coincide.
    have hi₁L0 : (i₁ : ℕ) < L := lt_of_lt_of_le hi₁ (le_of_lt hkL)
    have hi₂L0 : (i₂ : ℕ) < L := lt_of_lt_of_le hi₂ (le_of_lt hkL)
    have hmodeq : Nat.ModEq L (p + (i₁ : ℕ)) (p + (i₂ : ℕ)) := hpos_eq
    have hcancel : Nat.ModEq L (i₁ : ℕ) (i₂ : ℕ) :=
      Nat.ModEq.add_left_cancel' p hmodeq
    have hi₁L : (i₁ : ℕ) % L = (i₁ : ℕ) := Nat.mod_eq_of_lt hi₁L0
    have hi₂L : (i₂ : ℕ) % L = (i₂ : ℕ) := Nat.mod_eq_of_lt hi₂L0
    apply Fin.ext
    have := hcancel
    rw [Nat.ModEq, hi₁L, hi₂L] at this
    exact this
  head_last_ne_tail := by
    set L := C.darts.length with hL
    have hmap : (C.darts.map M.tail).Nodup := by
      simpa [BoundaryCycle.VertexNodup, C.vertices_eq] using hC
    intro i htail
    -- v = tail darts[(p+k)%L]; tail darts[(p+i)%L] with i < k.  Positions distinct.
    have hi : (i : ℕ) < k := i.isLt
    have hposk : (p + k) % L < L := Nat.mod_lt _ C.darts_length_pos
    have hposi : (p + (i : ℕ)) % L < L := Nat.mod_lt _ C.darts_length_pos
    have hdarts : C.darts[(p + k) % L]'hposk = C.darts[(p + (i : ℕ)) % L]'hposi := by
      have hinj := List.inj_on_of_nodup_map hmap (List.getElem_mem hposk) (List.getElem_mem hposi)
      exact hinj htail
    have hpos_eq : (p + k) % L = (p + (i : ℕ)) % L :=
      (C.normalized.nodup.getElem_inj_iff).mp hdarts
    -- residues equal ⟹ k ≡ i [MOD L]; but i < k < L: contradiction.
    have hiltL : (i : ℕ) < L := lt_trans hi hkL
    have hmodeq : Nat.ModEq L (p + k) (p + (i : ℕ)) := hpos_eq
    have hcancel : Nat.ModEq L k (i : ℕ) := Nat.ModEq.add_left_cancel' p hmodeq
    have hkL' : k % L = k := Nat.mod_eq_of_lt hkL
    have hiL : (i : ℕ) % L = (i : ℕ) := Nat.mod_eq_of_lt hiltL
    rw [Nat.ModEq, hkL', hiL] at hcancel
    omega



@[simp] lemma cyclicDartArc_arcDart (C : BoundaryCycle M f) (hC : C.VertexNodup)
    (p k : ℕ) (hk : 1 ≤ k) (hkL : k < C.darts.length) (hp : p < C.darts.length)
    (j : Fin k) :
    (cyclicDartArc C hC p k hk hkL hp).arcDart j
      = C.darts[(p + j.1) % C.darts.length]'(Nat.mod_lt _ (by omega)) := rfl

end BoundaryCycle



namespace BoundaryCycle

variable {M : CombMap D} {f : M.Face}

/-- The position of a boundary vertex on the cyclic dart list (as the tail of a
listed dart), as a single existential over `Fin`. -/
lemma exists_pos_of_isBoundaryVertex (C : BoundaryCycle M f) {a : M.Vertex}
    (ha : C.IsBoundaryVertex a) :
    ∃ p : Fin C.darts.length, M.tail (C.darts[p.1]'p.2) = a := by
  have ha' : a ∈ C.darts.map M.tail := by
    simpa [BoundaryCycle.IsBoundaryVertex, C.vertices_eq] using ha
  rw [List.mem_iff_getElem] at ha'
  obtain ⟨p, hp, hget⟩ := ha'
  rw [List.length_map] at hp
  refine ⟨⟨p, hp⟩, ?_⟩
  rwa [List.getElem_map] at hget

/-- **The boundary arc of a non-boundary edge.**  From two distinct boundary
vertices `a, b` with `s(a, b)` not a boundary edge, the forward cyclic dart run
from `a` to `b` is a `DartArc … a b` of length `≥ 2`. -/
noncomputable def dartArcOfNonBoundaryEdge (C : BoundaryCycle M f) (hC : C.VertexNodup)
    {a b : M.Vertex} (hab : a ≠ b) (ha : C.IsBoundaryVertex a) (hb : C.IsBoundaryVertex b)
    (hnbe : ¬ C.IsBoundaryEdge s(a, b)) :
    { A : DartArc M C a b // 2 ≤ A.len } := by
  classical
  set L := C.darts.length with hL
  have hLpos : 0 < L := C.darts_length_pos
  -- positions of a, b (extracted as data via choice).
  set paF := (C.exists_pos_of_isBoundaryVertex ha).choose with hpaF
  have hpaeq0 := (C.exists_pos_of_isBoundaryVertex ha).choose_spec
  set pbF := (C.exists_pos_of_isBoundaryVertex hb).choose with hpbF
  have hpbeq0 := (C.exists_pos_of_isBoundaryVertex hb).choose_spec
  set pa := paF.1 with hpaval
  set pb := pbF.1 with hpbval
  have hpa : pa < C.darts.length := paF.2
  have hpb : pb < C.darts.length := pbF.2
  have hpaeq : M.tail (C.darts[pa]'hpa) = a := hpaeq0
  have hpbeq : M.tail (C.darts[pb]'hpb) = b := hpbeq0
  -- forward cyclic distance from pa to pb.
  set k := (pb + L - pa) % L with hk
  have hkL : k < L := Nat.mod_lt _ hLpos
  have hkpos : 1 ≤ k := by
    rcases Nat.eq_zero_or_pos k with h0 | h0
    · -- k = 0 ⟹ L ∣ (pb+L-pa) ⟹ (since 0 < pb+L-pa < 2L) pb = pa ⟹ a = b.
      exfalso
      have hmod0 : (pb + L - pa) % L = 0 := by rw [← hk]; exact h0
      have hdvd : L ∣ (pb + L - pa) := Nat.dvd_of_mod_eq_zero hmod0
      obtain ⟨m, hm⟩ := hdvd
      have hpapb : pa = pb := by
        have hb1 : pb + L - pa < 2 * L := by omega
        have hb2 : 0 < pb + L - pa := by omega
        -- L*m = pb+L-pa, 0 < L*m < 2L ⟹ m = 1 ⟹ pb+L-pa = L ⟹ pa = pb.
        have hm1 : m = 1 := by nlinarith [hm, hb1, hb2, hLpos]
        rw [hm1, Nat.mul_one] at hm; omega
      apply hab
      have hgeteq : C.darts.get ⟨pa, hpa⟩ = C.darts.get ⟨pb, hpb⟩ := by
        congr 1; exact Fin.ext hpapb
      calc a = M.tail (C.darts[pa]'hpa) := hpaeq.symm
        _ = M.tail (C.darts.get ⟨pa, hpa⟩) := rfl
        _ = M.tail (C.darts.get ⟨pb, hpb⟩) := by rw [hgeteq]
        _ = M.tail (C.darts[pb]'hpb) := rfl
        _ = b := hpbeq
    · exact h0
  -- endpoints: tail darts[pa] = a, tail darts[(pa+k)%L] = b.
  have hend : (pa + k) % L = pb := by
    rw [hk]
    -- (pa + (pb+L-pa)%L) % L = (pa + (pb+L-pa)) % L = (pb+L) % L = pb.
    conv_lhs => rw [Nat.add_mod, Nat.mod_mod_of_dvd _ (dvd_refl L)]
    rw [← Nat.add_mod]
    have h1 : pa + (pb + L - pa) = pb + L := by omega
    rw [h1, Nat.add_mod_right, Nat.mod_eq_of_lt hpb]
  -- length k ≥ 2: if k = 1 then darts[pa] has head b, so s(a,b) is a boundary edge.
  have hk2 : 2 ≤ k := by
    by_contra hlt
    have hlt' : k < 2 := Nat.lt_of_not_le hlt
    have hk1 : k = 1 := by omega
    -- tail darts[(pa+1)%L] = head darts[pa] by consecutive_vertex; (pa+1)%L = (pa+k)%L = pb.
    have hcv := C.consecutive_vertex ⟨pa, hpa⟩
    have hcyc : (cyclicNext C.normalized.length_pos ⟨pa, hpa⟩ : Fin L)
        = ⟨pb, hpb⟩ := by
      apply Fin.ext
      show (pa + 1) % L = pb
      have hkk : (pa + k) % L = pb := hend
      rw [hk1] at hkk; exact hkk
    rw [hcyc] at hcv
    -- hcv : tail darts[pb] = head darts[pa].  So s(a,b) = dartEdge darts[pa] ∈ edges.
    apply hnbe
    show s(a, b) ∈ C.edges
    rw [C.edges_eq]
    have hge : C.darts.get ⟨pa, hpa⟩ = C.darts[pa]'hpa := rfl
    have hgb : C.darts.get ⟨pb, hpb⟩ = C.darts[pb]'hpb := rfl
    rw [hge, hgb] at hcv
    -- M.dartEdge (darts[pa]) = s(tail darts[pa], head darts[pa]) = s(a, b).
    have hedge2 : M.dartEdge (C.darts[pa]'hpa) = s(a, b) := by
      show s(M.tail (C.darts[pa]'hpa), M.head (C.darts[pa]'hpa)) = s(a, b)
      rw [hpaeq, ← hcv, hpbeq]
    rw [← hedge2]
    exact List.mem_map_of_mem (List.getElem_mem hpa)
  -- The arc's head endpoint is `tail darts[(pa+k)%L] = tail darts[pb] = b`.
  have hbend : M.tail (C.darts[(pa + k) % C.darts.length]'(Nat.mod_lt _ hLpos)) = b := by
    have hcongr : C.darts.get ⟨(pa + k) % C.darts.length, Nat.mod_lt _ hLpos⟩
        = C.darts.get ⟨pb, hpb⟩ := by
      congr 1
      apply Fin.ext
      show (pa + k) % C.darts.length = pb
      simpa [hL] using hend
    have h1 : C.darts[(pa + k) % C.darts.length]'(Nat.mod_lt _ hLpos)
        = C.darts.get ⟨(pa + k) % C.darts.length, Nat.mod_lt _ hLpos⟩ := rfl
    have h2 : C.darts[pb]'hpb = C.darts.get ⟨pb, hpb⟩ := rfl
    rw [h1, hcongr, ← h2]; exact hpbeq
  -- Rewrite the goal's endpoints `a`, `b` back to the tail expressions and bundle.
  rw [show a = M.tail (C.darts[pa]'hpa) from hpaeq.symm,
      show b = M.tail (C.darts[(pa + k) % C.darts.length]'(Nat.mod_lt _ hLpos)) from hbend.symm]
  exact ⟨C.cyclicDartArc hC pa k hkpos hkL hpa, hk2⟩

end BoundaryCycle



namespace NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M)

open SimplePrimalCycle

/-- **Chord-cycle datum.**  The exact bundle `separates_closed` consumes: a simple
primal cycle made of the chord edge `s(u,v)` plus a boundary arc (`hsub`), with an
index `i₀` whose two incident faces are the two chord-dart faces. -/
structure ChordCycleData {u v : M.Vertex} (h : hNT.outerCycle.Chord u v) where
  /-- The chord ∪ arc simple primal cycle. -/
  C : CombMap.SimplePrimalCycle M
  /-- Every cycle edge is the chord or a boundary edge. -/
  hsub : ∀ e ∈ C.edgeSet, e = s(u, v) ∨ hNT.outerCycle.IsBoundaryEdge e
  /-- The chord index. -/
  i₀ : Fin C.len
  /-- The left face at `i₀` is the chord-dart face. -/
  hleft : C.faceLeft i₀ = M.dartFace (hNT.chordDart h)
  /-- The right face at `i₀` is the reverse-chord-dart face. -/
  hright : C.faceRight i₀ = M.dartFace (M.α (hNT.chordDart h))

variable {u v : M.Vertex}

/-- **The chord-cycle datum exists.**  Built from the boundary arc between the two
endpoints of the chord dart `c₀ := hNT.chordDart h`, with `c₀` placed at index `0`
of `ofDartArc`.  Then `dart 0 = c₀`, so the two `i₀ = 0` faces are *definitionally*
the chord-dart faces. -/
noncomputable def chordCycleData (h : hNT.outerCycle.Chord u v) :
    hNT.ChordCycleData h := by
  classical
  -- The chord dart and its (boundary) endpoints.  We keep `M.tail c₀`/`M.head c₀`
  -- inline (no `set`) to avoid reverting let-bound variables in rewrites.
  set c₀ := hNT.chordDart h with hc₀
  -- c₀ has edge s(u, v); its endpoints are the two boundary chord endpoints.
  have hedge : M.dartEdge c₀ = s(u, v) := hNT.chordDart_edge h
  have hxy_edge : s(M.tail c₀, M.head c₀) = s(u, v) := hedge
  -- the endpoints are distinct and both boundary vertices.
  have hxy_ne : M.tail c₀ ≠ M.head c₀ := by
    intro hcontra
    have h1 : s(M.head c₀, M.head c₀) = s(u, v) := hcontra ▸ hxy_edge
    have huv : u = v := by
      rcases Sym2.eq_iff.mp h1.symm with ⟨hl, hr⟩ | ⟨hl, hr⟩
      · rw [hl, hr]
      · rw [hl, hr]
    exact h.endpoints_ne huv
  have hx_bv : hNT.outerCycle.IsBoundaryVertex (M.tail c₀) := by
    rcases Sym2.eq_iff.mp hxy_edge with ⟨hxu, _⟩ | ⟨hxv, _⟩
    · rw [hxu]; exact h.left_boundary
    · rw [hxv]; exact h.right_boundary
  have hy_bv : hNT.outerCycle.IsBoundaryVertex (M.head c₀) := by
    rcases Sym2.eq_iff.mp hxy_edge with ⟨_, hyv⟩ | ⟨_, hyu⟩
    · rw [hyv]; exact h.right_boundary
    · rw [hyu]; exact h.left_boundary
  -- s(head, tail) = s(tail, head) = s(u, v) is not a boundary edge.
  have hnbe : ¬ hNT.outerCycle.IsBoundaryEdge s(M.head c₀, M.tail c₀) := by
    rw [show (s(M.head c₀, M.tail c₀) : Sym2 M.Vertex) = s(M.tail c₀, M.head c₀) from Sym2.eq_swap,
      hxy_edge]
    exact h.not_boundary_edge
  -- Build the boundary arc from `head c₀` to `tail c₀` (so c₀ : tail→...→head closes it).
  obtain ⟨A, hAlen⟩ := hNT.outerCycle.dartArcOfNonBoundaryEdge hNT.outer_simple
    (Ne.symm hxy_ne) hy_bv hx_bv hnbe
  -- The chord ∪ arc cycle: dart 0 = c₀.  ofDartArc needs tail c₀ = (arc's `v`-end),
  -- head c₀ = (arc's `u`-end); the arc `A : DartArc … (head c₀) (tail c₀)` matches.
  have hc_tail : M.tail c₀ = M.tail c₀ := rfl
  have hc_head : M.head c₀ = M.head c₀ := rfl
  -- index 0 (the chord dart) of the chord∪arc cycle.  `dart 0 = c₀` definitionally.
  have hi0 : (0 : ℕ) < (SimplePrimalCycle.ofDartArc A c₀ hAlen hc_tail hc_head).len :=
    (SimplePrimalCycle.ofDartArc A c₀ hAlen hc_tail hc_head).len_pos
  have hdart0 : (SimplePrimalCycle.ofDartArc A c₀ hAlen hc_tail hc_head).dart ⟨0, hi0⟩ = c₀ := by
    show SimplePrimalCycle.chordArcDart A c₀ ⟨0, hi0⟩ = c₀
    exact SimplePrimalCycle.chordArcDart_zero A c₀
  refine
    { C := SimplePrimalCycle.ofDartArc A c₀ hAlen hc_tail hc_head
      hsub := ?_
      i₀ := ⟨0, hi0⟩
      hleft := ?_
      hright := ?_ }
  · -- hsub: every cycle edge is the chord or a boundary edge.
    intro e he
    rw [SimplePrimalCycle.mem_edgeSet_iff] at he
    obtain ⟨i, hi⟩ := he
    rw [hi]
    -- edge i = dartEdge (dart i); dart i is either c₀ (i = 0) or an arc dart.
    have hedge_i : (SimplePrimalCycle.ofDartArc A c₀ hAlen hc_tail hc_head).edge i
        = M.dartEdge ((SimplePrimalCycle.ofDartArc A c₀ hAlen hc_tail hc_head).dart i) := rfl
    rw [hedge_i, SimplePrimalCycle.ofDartArc_dart]
    rcases Fin.eq_zero_or_eq_succ i with rfl | ⟨i', rfl⟩
    · -- chord edge.
      left
      rw [SimplePrimalCycle.chordArcDart_zero]
      exact hedge
    · -- arc dart: lies on the outer cycle, so its edge is a boundary edge.
      right
      rw [SimplePrimalCycle.chordArcDart_succ]
      show M.dartEdge (A.arcDart i') ∈ hNT.outerCycle.edges
      rw [hNT.outerCycle.edges_eq]
      exact List.mem_map_of_mem (A.boundary i')
  · -- hleft: faceLeft 0 = dartFace (dart 0) = dartFace c₀ = dartFace (chordDart h).
    show M.dartFace ((SimplePrimalCycle.ofDartArc A c₀ hAlen hc_tail hc_head).dart ⟨0, hi0⟩)
        = M.dartFace (hNT.chordDart h)
    rw [hdart0]
  · -- hright: faceRight 0 = dartFace (α (dart 0)) = dartFace (α c₀) = dartFace (α (chordDart h)).
    show M.dartFace (M.α ((SimplePrimalCycle.ofDartArc A c₀ hAlen hc_tail hc_head).dart ⟨0, hi0⟩))
        = M.dartFace (M.α (hNT.chordDart h))
    rw [hdart0]



/-- **The chord separates, from a chord-cycle datum.**  Composes `ChordCycleData`
with `separates_closed` (the connectivity-gate-discharged separation). -/
theorem separates_of_chord (data : hNT.ChordSplitData u v)
    (cc : hNT.ChordCycleData data.chord) : data.Separates :=
  hNT.separates_closed data cc.C cc.hsub cc.i₀ cc.hleft cc.hright

/-- **The chord separates, unconditionally on the chord-cycle datum** (built
internally). -/
theorem separates_of_chordSplitData (data : hNT.ChordSplitData u v) :
    data.Separates :=
  hNT.separates_of_chord data (hNT.chordCycleData data.chord)

end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap








end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35EdgeCore
-/
/- Source module: ProofsInTheBook.ZinanCh35Schoenflies2 -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35Schoenflies2

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ZinanCh35Schoenflies
open ProofsInTheBook.ZinanCh35EdgeCore

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



/-- If a dart's face is the outer face, its reverse's face is **not** the outer face: an edge
cannot have both of its darts on the simple outer boundary cycle (that would force a length-2
boundary, contradicting `outer_len`). -/
theorem alpha_dartFace_ne_outer_of_outer {e : D}
    (hNT : NearTriangulation M) (he : M.dartFace e = hNT.outerFace) :
    M.dartFace (M.α e) ≠ hNT.outerFace := by
  intro hαe
  -- both `e` and `α e` are boundary darts.
  have he_mem : e ∈ hNT.outerCycle.darts := (hNT.outerCycle.mem_darts_iff e).2 he
  have hαe_mem : M.α e ∈ hNT.outerCycle.darts := (hNT.outerCycle.mem_darts_iff (M.α e)).2 hαe
  -- `φ e` is a boundary dart (same outer face), with `tail (φ e) = head e = tail (α e)`.
  have hφe_mem : M.φ e ∈ hNT.outerCycle.darts := by
    rw [hNT.outerCycle.mem_darts_iff]
    show M.dartFace (M.φ e) = hNT.outerFace
    rw [M.dartFace_phi]; exact he
  have htail_eq : M.tail (M.φ e) = M.tail (M.α e) := by
    rw [M.tail_phi, M.tail_alpha]
  -- two boundary darts with the same tail are equal: `φ e = α e`.
  have hφα : M.φ e = M.α e :=
    hNT.outerCycle.tail_injective_on_darts hNT.outer_simple hφe_mem hαe_mem htail_eq
  -- Then `φ (φ e) = φ (α e)`, whose tail is `head (α e) = tail e = tail e`.
  have htail2 : M.tail (M.φ (M.φ e)) = M.tail e := by
    rw [hφα, M.tail_phi, M.head_alpha]
  -- `φ² e` is a boundary dart with the same tail as `e`, hence `φ² e = e`.
  have hφ2_mem : M.φ (M.φ e) ∈ hNT.outerCycle.darts := by
    rw [hNT.outerCycle.mem_darts_iff]
    show M.dartFace (M.φ (M.φ e)) = hNT.outerFace
    rw [M.dartFace_phi, M.dartFace_phi]; exact he
  have hφ2 : M.φ (M.φ e) = e :=
    hNT.outerCycle.tail_injective_on_darts hNT.outer_simple hφ2_mem he_mem htail2
  -- So the outer-face orbit has support card 2, i.e. `faceLen outerFace = 2 < 3`.
  have hφ : M.φ e ≠ e := phi_ne_self_of_isSimpleGraph M hNT.simpleGraph e
  have hcard2 : (M.φ.cycleOf e).support.card = 2 :=
    card_support_cycleOf_eq_two_of_apply_apply_eq_self M.φ hφ hφ2
  have hface2 : M.faceLen hNT.outerFace = 2 := by
    have hsupport := faceLen_dartFace_eq_card_support_cycleOf M hφ
    rw [he, hcard2] at hsupport; exact hsupport
  have hlen2 : hNT.outerCycle.length = 2 :=
    hNT.outerCycle.faceLen_eq_length.symm.trans hface2
  have hge : 3 ≤ hNT.outerCycle.length := hNT.outer_len
  omega



/-- **Bridge 2 (`OuterDartArc₁`), conditional on the two planar bridges.**  Clean-3 conditional on
exactly `Separates`, `BoundedFacePartition`, and `SideRegionInterChordEnds` (the latter is Bridge 1,
proved/isolated separately; the prompt sanctions stating Bridge 2 conditional on it). -/
theorem outerDartArc₁_holds (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (hpart : BoundedFacePartition data) (hinter : SideRegionInterChordEnds data) :
    OuterDartArc₁ data := by
  intro e hchord hface htail hhead
  -- The reverse inner face is non-outer.
  have hαe_not_outer : M.dartFace (M.α e) ≠ hNT.outerFace :=
    alpha_dartFace_ne_outer_of_outer hNT hface
  -- Partition it into side₁ or side₂.
  rcases hpart hαe_not_outer with h₁ | h₂
  · exact h₁
  · -- `dartFace (α e) ∈ side₂`: derive `e = chord`, contradiction.
    exfalso
    -- `α e` is a non-chord side₂ face dart.
    have hαe_chord : M.dartEdge (M.α e) ≠ s(u, v) := by
      rw [M.dartEdge_alpha]; exact hchord
    -- both endpoints of `α e` are in `sideRegion₂`.
    obtain ⟨htail₂, hhead₂⟩ :=
      endpoints_mem_sideRegion₂_of_face data hsep hαe_chord h₂
    -- `tail (α e) = head e`, `head (α e) = tail e`.
    rw [M.tail_alpha] at htail₂
    rw [M.head_alpha] at hhead₂
    -- so both endpoints of `e` are in `sideRegion₂`; combine with `sideRegion₁`.
    have htchord : M.tail e = u ∨ M.tail e = v := hinter htail hhead₂
    have hhchord : M.head e = u ∨ M.head e = v := hinter hhead htail₂
    exact hchord (edge_eq_chord_of_endpoints_chordEnds data htchord hhchord)

























end ProofsInTheBook.ZinanCh35Schoenflies2












end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35BankCount
import ProofsInTheBook.ZinanCh35StarConn
import ProofsInTheBook.ZinanCh35Schoenflies2
-/
/- Source module: ProofsInTheBook.ZinanCh35EdgeCoreFinal -/
section
set_option autoImplicit true




namespace ProofsInTheBook.ZinanCh35EdgeCoreFinal

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ZinanCh35EdgeCore
open ProofsInTheBook.ZinanCh35OuterCount
open ProofsInTheBook.ZinanCh35BankCount
open ProofsInTheBook.ZinanCh35StarConn
open ProofsInTheBook.ZinanCh35Schoenflies
open ProofsInTheBook.ZinanCh35Schoenflies2

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}

/-- **`BoundedFacePartition` is UNCONDITIONAL** — the coverage atom is discharged
(`outerDualNumCompTwo_holds`). -/
theorem boundedFacePartition_uncond (data : hNT.ChordSplitData u v) :
    BoundedFacePartition data :=
  boundedFacePartition_via_numComp data (outerDualNumCompTwo_holds hNT)

/-- **`OuterDartArc₁` is UNCONDITIONAL** (given the chord split + `Separates`): both its bridges
(`BoundedFacePartition` from the coverage atom, `SideRegionInterChordEnds` from σ-star) are proven. -/
theorem outerDartArc₁_uncond (data : hNT.ChordSplitData u v) (hsep : data.Separates) :
    OuterDartArc₁ data :=
  outerDartArc₁_holds data hsep (boundedFacePartition_uncond data)
    (sideRegionInterChordEnds_holds data hsep)

/-- **The corrected bounded `edge_core` is UNCONDITIONAL** (given the chord split + `Separates`):
both bridges are now proven, so the formerly-residual `edge_core` field of `Side₁StarConfinement`
is dischargeable.  Stated via the landed `edge_core_holds` shape. -/
theorem edge_core_uncond (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    {e : D} (hchord : M.dartEdge e ≠ s(u, v)) (houter : M.dartFace e ≠ hNT.outerFace)
    (htail : M.tail e ∈ sideRegion₁ data) (hhead : M.head e ∈ sideRegion₁ data) :
    M.dartFace e ∈ data.side₁ :=
  edge_core_holds data hsep (boundedFacePartition_uncond data)
    (sideRegionInterChordEnds_holds data hsep) hchord houter htail hhead

end ProofsInTheBook.ZinanCh35EdgeCoreFinal

end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35Schoenflies
import ProofsInTheBook.ZinanCh35StarConn
import ProofsInTheBook.ZinanCh35EdgeCoreFinal
-/
/- Source module: ProofsInTheBook.ZinanCh35Side1Confine -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35Side1Confine

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ZinanCh35Schoenflies
open ProofsInTheBook.ZinanCh35StarConn
open ProofsInTheBook.ZinanCh35EdgeCore
open ProofsInTheBook.ZinanCh35EdgeCoreFinal
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



/-- **The chord-arc bank-orientation datum.**  The second listed boundary arc `path₂` is the
side-2 boundary arc: every strictly-internal vertex of `path₂` lies in the side-2 region.

This is the weakest honest orientation statement the direct `oppArc_star_core` route needs; in
the current `ChordSplitData` layer it is a free input (reversing `data.chord` swaps
`side₁ ↔ side₂` while fixing `path₂`, flipping its truth value), so it is isolated here rather
than faked. -/
structure ChordArcBankOrientation (data : hNT.ChordSplitData u v) : Prop where
  /-- A strictly-internal vertex of the opposite boundary arc `path₂` is in the side-2 region. -/
  path₂_internal_mem_sideRegion₂ : ∀ {w : M.Vertex},
    w ∈ data.arc.path₂.internalVertices → w ∈ sideRegion₂ data



/-- **The opposite-arc vertex-star confinement, via the direct route.**  Conditional on the single
bank-orientation datum, every dart `d` tailed at a `path₂`-internal vertex `w` is the chord dart,
or its face is outside `side₁` and it is not a side-1 boundary dart. -/
theorem oppArc_star_core_direct (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (hbank : ChordArcBankOrientation data) {w : M.Vertex}
    (hw : w ∈ data.arc.path₂.internalVertices) (d : D) (htail : M.tail d = w) :
    d = data.dart ∨
      (M.dartFace d ∉ data.side₁ ∧
        ¬ (M.dartFace d = hNT.outerFace ∧ M.dartFace (M.α d) ∈ data.side₁)) := by
  by_cases hd : d = data.dart
  · exact Or.inl hd
  · right
    -- `w` lies in the side-2 region (bank datum) and is `≠ u, v` (path₂-internal).
    have hw₂ : w ∈ sideRegion₂ data := hbank.path₂_internal_mem_sideRegion₂ hw
    -- `path₂ : BoundaryPath v u`, so `_ne_start` gives `≠ v` and `_ne_end` gives `≠ u`.
    have hw_ne_v : w ≠ v := data.arc.path₂.internalVertex_ne_start hw
    have hw_ne_u : w ≠ u := data.arc.path₂.internalVertex_ne_end hw
    -- Hence `w ∉ sideRegion₁`: otherwise it is a chord endpoint, contradicting `≠ u, v`.
    have no_sideRegion₁ : w ∉ sideRegion₁ data := by
      intro hw₁
      rcases sideRegionInterChordEnds_holds data hsep hw₁ hw₂ with h | h
      · exact hw_ne_u h
      · exact hw_ne_v h
    refine ⟨?_, ?_⟩
    · -- Conjunct 1: if `dartFace d ∈ side₁`, then `d` is a kept inner side-1 dart, so
      -- `w ∈ sideRegion₁` — contradiction.
      intro hface1
      exact no_sideRegion₁ (mem_sideRegion₁_of_star_side₁ data htail hd hface1)
    · -- Conjunct 2: if `d` is an outer dart with reverse face in `side₁`, it is a kept side-1
      -- boundary dart, so `w ∈ sideRegion₁` — contradiction.
      rintro ⟨hd_outer, hα_side1⟩
      exact no_sideRegion₁ (mem_sideRegion₁_of_star_outerArc₁ data htail hd hd_outer hα_side1)



/-- **`Side₁StarConfinement`, discharged conditional on the single bank-orientation datum.**

* The `edge_core` field is **unconditional** clean-3 (`edge_core_uncond`).
* The `oppArc_star_core` field is discharged via the direct R7 route, conditional **only** on the
  minimal `ChordArcBankOrientation` datum (the one genuinely-free orientation fact; see the module
  header for why it is not derivable from the bare `ChordSplitData`).

This completes the side-1 confinement modulo that single bank-orientation input. -/
theorem side₁StarConfinement_holds (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (hbank : ChordArcBankOrientation data) :
    Side₁StarConfinement data where
  edge_core := fun {e} hchord houter htail hhead =>
    edge_core_uncond data hsep hchord houter htail hhead
  oppArc_star_core := fun {w} hw d htail =>
    oppArc_star_core_direct data hsep hbank hw d htail

end ProofsInTheBook.ZinanCh35Side1Confine






end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35ChordCycle
import ProofsInTheBook.ZinanCh35EdgeCore
import ProofsInTheBook.ZinanCh35Side1Confine
-/
/- Source module: ProofsInTheBook.ZinanCh35ArcDartRun -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35ArcDartRun

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ZinanCh35EdgeCore

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}





namespace BoundaryPathDartRun

variable {f : M.Face} {C : BoundaryCycle M f} {a b : M.Vertex}





end BoundaryPathDartRun



section DartArcHelpers

variable {f : M.Face} {C : BoundaryCycle M f} {a b : M.Vertex}

/-- The explicit `List D` of a `DartArc`'s darts, `[arcDart 0, …, arcDart (len-1)]`. -/
def _root_.ProofsInTheBook.PlanarMap.CombMap.DartArc.dartList (A : DartArc M C a b) : List D :=
  (List.finRange A.len).map A.arcDart

@[simp] lemma _root_.ProofsInTheBook.PlanarMap.CombMap.DartArc.dartList_length
    (A : DartArc M C a b) : A.dartList.length = A.len := by
  simp [DartArc.dartList]

lemma _root_.ProofsInTheBook.PlanarMap.CombMap.DartArc.dartList_ne_nil
    (A : DartArc M C a b) : A.dartList ≠ [] := by
  rw [← List.length_pos_iff_ne_nil, DartArc.dartList_length]; exact A.len_pos

lemma _root_.ProofsInTheBook.PlanarMap.CombMap.DartArc.dartList_getElem
    (A : DartArc M C a b) (j : ℕ) (hj : j < A.len) :
    A.dartList[j]'(by rw [DartArc.dartList_length]; exact hj) = A.arcDart ⟨j, hj⟩ := by
  simp only [DartArc.dartList, List.getElem_map, List.getElem_finRange]
  congr 1

lemma _root_.ProofsInTheBook.PlanarMap.CombMap.DartArc.mem_dartList
    (A : DartArc M C a b) {d : D} (hd : d ∈ A.dartList) :
    ∃ i : Fin A.len, A.arcDart i = d := by
  rw [DartArc.dartList, List.mem_map] at hd
  obtain ⟨i, _, hi⟩ := hd
  exact ⟨i, hi⟩

end DartArcHelpers





namespace NearTriangulation

variable {hNT : NearTriangulation M} {u v : M.Vertex}





end NearTriangulation



namespace NearTriangulation

variable (hNT : NearTriangulation M) {u v : M.Vertex}

open ProofsInTheBook.PlanarMap.CombMap.BoundaryCycle





end NearTriangulation



namespace NearTriangulation

variable {hNT : NearTriangulation M} {u v : M.Vertex}

/-- **The bank-route per-dart bridge.**  If `e` is a non-chord boundary dart whose *reverse* face
lies in `side₂`, then `tail e ∈ sideRegion₂`.

Apply `endpoints_mem_sideRegion₂_of_face` to `M.α e`: its face is `dartFace (M.α e) ∈ side₂`, its
edge is non-chord (same edge as `e`), so both its endpoints — in particular `head (M.α e) = tail
e` — lie in `sideRegion₂`. -/
theorem dartRun_tail_mem_sideRegion₂_of_face (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    {e : D} (hchord : M.dartEdge e ≠ s(u, v)) (hface : M.dartFace (M.α e) ∈ data.side₂) :
    M.tail e ∈ sideRegion₂ data := by
  have hchord' : M.dartEdge (M.α e) ≠ s(u, v) := by rwa [M.dartEdge_alpha]
  obtain ⟨_, hhead⟩ := endpoints_mem_sideRegion₂_of_face data hsep hchord' hface
  -- head (α e) = tail e.
  rwa [M.head_alpha] at hhead

/-- Symmetric variant: the *forward* face in `side₂` gives the **head** in `sideRegion₂`. -/
theorem dartRun_head_mem_sideRegion₂_of_face (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    {e : D} (hchord : M.dartEdge e ≠ s(u, v)) (hface : M.dartFace (M.α e) ∈ data.side₂) :
    M.head e ∈ sideRegion₂ data := by
  have hchord' : M.dartEdge (M.α e) ≠ s(u, v) := by rwa [M.dartEdge_alpha]
  obtain ⟨htail, _⟩ := endpoints_mem_sideRegion₂_of_face data hsep hchord' hface
  rwa [M.tail_alpha] at htail

end NearTriangulation



namespace NearTriangulation

variable {hNT : NearTriangulation M} {u v : M.Vertex}





end NearTriangulation

end ProofsInTheBook.ZinanCh35ArcDartRun











end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35ArcDartRun
import ProofsInTheBook.ZinanCh35ChordCycle
-/
/- Source module: ProofsInTheBook.ZinanCh35Contiguity -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35Contiguity

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ZinanCh35ArcDartRun

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



























end ProofsInTheBook.ZinanCh35Contiguity












end

/- Original source header (imports hoisted):
import Mathlib
-/
/- Source module: ProofsInTheBook.Chapter35 -/
section
set_option autoImplicit true




namespace ProofsInTheBook.Chapter35

open scoped BigOperators







section KempeChains







end KempeChains

section FiveColorInduction

universe u























end FiveColorInduction









end ProofsInTheBook.Chapter35

end

/- Original source header (imports hoisted):
import ProofsInTheBook.ThomassenInduction
import ProofsInTheBook.WitnessFinal
-/
/- Source module: ProofsInTheBook.JordanOracleConstruct -/
section
set_option autoImplicit true




namespace ProofsInTheBook.JordanOracleConstruct

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap
open ProofsInTheBook.ThomassenInduction
open ProofsInTheBook.ListColoring

universe u











variable {D : Type u} [Fintype D] [DecidableEq D] {α : Type u} [DecidableEq α]
variable {M : CombMap D}





end ProofsInTheBook.JordanOracleConstruct



namespace ProofsInTheBook.JordanOracleConstruct

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.ThomassenLists.CombMap
open ProofsInTheBook.ThomassenInduction

universe u





end ProofsInTheBook.JordanOracleConstruct








end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35Schoenflies
-/
/- Source module: ProofsInTheBook.ZinanCh35FinalClose -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35FinalClose

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ChordSideNT
open ProofsInTheBook.ChordSplitFinal
open ProofsInTheBook.ChordDisk
open ProofsInTheBook.ZinanCh35Iota
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex} {α : Type u} [DecidableEq α]



/-- **The minimal side-1 confinement input bundle (verdict §4).**  Exactly the two discrete-
Schoenflies facts the `homit`/`hreflect` producers need, in their sharpest concrete shapes:

* `oppArcStarSeed` — a strictly internal vertex of the *opposite* boundary arc `path₂` is omitted
  by side 1 (`w ∉ sideRegion₁ data`).  This is the `homit` content, concretised.

* `edge_core` — an ambient dart `e` whose two endpoints are both side-1-region vertices is either
  represented in the side-1 carve (`e ∉ keptDel₁ ∧ α e ∉ keptDel₁`) or is the chord
  (`dartEdge e = s(u, v)`).  This is the region edge-confinement core, with the `α`-closure folded
  into the conclusion so the `hreflect` producer consumes it directly. -/
structure Side₁SchoenfliesConfinementInput (data : hNT.ChordSplitData u v)
    (hsep : data.Separates) : Prop where
  /-- Opposite-arc omission: a `path₂`-internal vertex is not in the side-1 region. -/
  oppArcStarSeed : ∀ {w : M.Vertex},
    w ∈ data.arc.path₂.internalVertices → w ∉ sideRegion₁ data
  /-- Region edge-confinement core: an ambient edge between two side-1-region vertices is kept by
  side 1 (both `e` and `α e`), or is the chord. -/
  edge_core : ∀ {e : D},
    M.tail e ∈ sideRegion₁ data →
    M.head e ∈ sideRegion₁ data →
      ((e ∉ data.keptDel₁ ∧ M.α e ∉ data.keptDel₁) ∨ M.dartEdge e = s(u, v))



/-- **Brick 2 — `homit_of_confinementInput`.**  The opposite boundary arc carries an internal
vertex (`data.arc₂_internal`); that vertex is omitted by side 1 (`oppArcStarSeed`), witnessing the
concrete region-omission residue `∃ w, w ∉ sideRegion₁ data`. -/
theorem homit_of_confinementInput (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (H : Side₁SchoenfliesConfinementInput data hsep) :
    ∃ w : M.Vertex, w ∉ sideRegion₁ data := by
  obtain ⟨w, hw⟩ := List.exists_mem_of_ne_nil _ data.arc₂_internal
  exact ⟨w, H.oppArcStarSeed hw⟩



/-- **Brick 3 — `side_adj_of_kept_edge`.**  Let `e ∉ keptDel₁` be a kept dart with
`M.tail e = ι x` and `M.head e = ι y` (`x ≠ y`).  Then `sideMap₁.toSimpleGraph.Adj x y`, witnessed
by the side dart `Sum.inl ⟨e, he⟩`, with endpoints identified to `x`, `y` through the proved
injectivity of `ι`. -/
theorem side_adj_of_kept_edge (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₁}) (hne : a₀ ≠ a₁)
    {x y : (data.sideMap₁ hsep a₀ a₁ hne).Vertex} (hxy : x ≠ y)
    {e : D} (he : e ∉ data.keptDel₁)
    (htail : M.tail e = sideVertexToM₁ data hsep a₀ a₁ hne x)
    (hhead : M.head e = sideVertexToM₁ data hsep a₀ a₁ hne y) :
    (data.sideMap₁ hsep a₀ a₁ hne).toSimpleGraph.Adj x y := by
  classical
  -- the kept side dart and its two side endpoints (as classes).
  set dS : {d : D // d ∉ data.keptDel₁} ⊕ Fin 2 := Sum.inl ⟨e, he⟩ with hdS
  set xS : (data.sideMap₁ hsep a₀ a₁ hne).Vertex :=
    Quotient.mk (cycleSetoid (freshSigma data.sideSigma₁ a₀ a₁ hne)) dS with hxS
  set yS : (data.sideMap₁ hsep a₀ a₁ hne).Vertex :=
    Quotient.mk (cycleSetoid (freshSigma data.sideSigma₁ a₀ a₁ hne))
      ((freshAlpha (data.sideAlpha₁ hsep)) dS) with hyS
  -- `ι xS = M.tail e = ι x` and `ι yS = M.head e = ι y`, so by injectivity `xS = x`, `yS = y`.
  have hιx : sideVertexToM₁ data hsep a₀ a₁ hne xS
      = sideVertexToM₁ data hsep a₀ a₁ hne x := by
    rw [hxS, hdS, sideVertexToM₁_inl data hsep a₀ a₁ hne ⟨e, he⟩, htail]
  have hιy : sideVertexToM₁ data hsep a₀ a₁ hne yS
      = sideVertexToM₁ data hsep a₀ a₁ hne y := by
    rw [hyS, hdS, sideVertexToM₁_head_inl data hsep a₀ a₁ hne ⟨e, he⟩, hhead]
  have hxSx : xS = x := sideVertexToM₁_injective_canonical data hsep a₀ a₁ hne hιx
  have hySy : yS = y := sideVertexToM₁_injective_canonical data hsep a₀ a₁ hne hιy
  -- the side dart realises the edge `s(xS, yS) = s(x, y)`.
  rw [toSimpleGraph_adj]
  refine ⟨hxy, ?_⟩
  refine ⟨dS, ?_⟩
  -- `sideMap₁.dartEdge dS = s(sideMap₁.tail dS, sideMap₁.head dS) = s(xS, yS)`.
  show (data.sideMap₁ hsep a₀ a₁ hne).dartEdge dS = s(x, y)
  rw [← hxSx, ← hySy]
  -- `sideMap₁.tail dS = xS` and `sideMap₁.head dS = yS` definitionally
  -- (`head d = tail (α d)`, `sideMap₁.α = freshAlpha (sideAlpha₁)`).
  rfl



/-- **Brick 4 — `side_adj_of_chord_edge`.**  In the chord case `s(ι x, ι y) = s(u, v)`, with the
canonical anchor-tail identification `M.tail a₀.1 = u`, `M.tail a₁.1 = v` supplied as `ha₀`/`ha₁`,
the fresh chord side dart `Sum.inr 0` realises `s(x, y)`, giving `sideMap₁.toSimpleGraph.Adj x y`. -/
theorem side_adj_of_chord_edge (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₁}) (hne : a₀ ≠ a₁)
    {x y : (data.sideMap₁ hsep a₀ a₁ hne).Vertex} (hxy : x ≠ y)
    (ha₀ : M.tail a₀.1 = u) (ha₁ : M.tail a₁.1 = v)
    (hx : sideVertexToM₁ data hsep a₀ a₁ hne x = u)
    (hy : sideVertexToM₁ data hsep a₀ a₁ hne y = v) :
    (data.sideMap₁ hsep a₀ a₁ hne).toSimpleGraph.Adj x y := by
  classical
  -- the fresh chord side dart `inr 0` and its endpoints.
  set dS : {d : D // d ∉ data.keptDel₁} ⊕ Fin 2 := Sum.inr 0 with hdS
  set xS : (data.sideMap₁ hsep a₀ a₁ hne).Vertex :=
    Quotient.mk (cycleSetoid (freshSigma data.sideSigma₁ a₀ a₁ hne)) dS with hxS
  set yS : (data.sideMap₁ hsep a₀ a₁ hne).Vertex :=
    Quotient.mk (cycleSetoid (freshSigma data.sideSigma₁ a₀ a₁ hne))
      ((freshAlpha (data.sideAlpha₁ hsep)) dS) with hyS
  -- `ι xS = M.tail a₀.1 = u = ι x`, `ι yS = M.tail a₁.1 = v = ι y`.
  have hιx : sideVertexToM₁ data hsep a₀ a₁ hne xS
      = sideVertexToM₁ data hsep a₀ a₁ hne x := by
    rw [hxS, hdS, sideVertexToM₁_tail_inr data hsep a₀ a₁ hne 0]
    simp only [if_true]
    rw [ha₀, hx]
  have hιy : sideVertexToM₁ data hsep a₀ a₁ hne yS
      = sideVertexToM₁ data hsep a₀ a₁ hne y := by
    rw [hyS, hdS, sideVertexToM₁_head_inr data hsep a₀ a₁ hne 0]
    simp only [if_true]
    rw [ha₁, hy]
  have hxSx : xS = x := sideVertexToM₁_injective_canonical data hsep a₀ a₁ hne hιx
  have hySy : yS = y := sideVertexToM₁_injective_canonical data hsep a₀ a₁ hne hιy
  rw [toSimpleGraph_adj]
  refine ⟨hxy, dS, ?_⟩
  show (data.sideMap₁ hsep a₀ a₁ hne).dartEdge dS = s(x, y)
  rw [← hxSx, ← hySy]
  rfl



/-- **Brick 5 — `hreflect_of_confinementInput`** (master).  Produces the region edge-confinement
field `hreflect` (`M`-adjacency on `ι`-images ⟹ side adjacency) from the bundle's `edge_core`,
threading the canonical anchor-tail identification `ha₀ : M.tail a₀.1 = u`, `ha₁ : M.tail a₁.1 = v`
(canonical-anchor geometry, the chord-case analogue of `ZinanCh35Iota`'s `hchord`). -/
theorem hreflect_of_confinementInput (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₁}) (hne : a₀ ≠ a₁)
    (ha₀ : M.tail a₀.1 = u) (ha₁ : M.tail a₁.1 = v)
    (H : Side₁SchoenfliesConfinementInput data hsep) :
    ∀ ⦃x y : (data.sideMap₁ hsep a₀ a₁ hne).Vertex⦄,
      M.toSimpleGraph.Adj (sideVertexToM₁ data hsep a₀ a₁ hne x)
          (sideVertexToM₁ data hsep a₀ a₁ hne y) →
        (data.sideMap₁ hsep a₀ a₁ hne).toSimpleGraph.Adj x y := by
  classical
  intro x y hAdj
  rw [toSimpleGraph_adj] at hAdj
  obtain ⟨hne_ι, e, hde⟩ := hAdj
  -- `x ≠ y` from injectivity (`ι x ≠ ι y`).
  have hxy : x ≠ y := fun h => hne_ι (by rw [h])
  -- both endpoints are side-1-region vertices.
  have hx_mem : sideVertexToM₁ data hsep a₀ a₁ hne x ∈ sideRegion₁ data :=
    sideVertexToM₁_mem data hsep a₀ a₁ hne x
  have hy_mem : sideVertexToM₁ data hsep a₀ a₁ hne y ∈ sideRegion₁ data :=
    sideVertexToM₁_mem data hsep a₀ a₁ hne y
  -- `dartEdge e = s(tail e, head e)`, so `s(tail e, head e) = s(ι x, ι y)`.
  have hde' : s(M.tail e, M.head e)
      = s(sideVertexToM₁ data hsep a₀ a₁ hne x, sideVertexToM₁ data hsep a₀ a₁ hne y) := hde
  rcases Sym2.eq_iff.1 hde' with ⟨ht, hh⟩ | ⟨ht, hh⟩
  · -- `tail e = ι x`, `head e = ι y`.
    have htail_mem : M.tail e ∈ sideRegion₁ data := by rw [ht]; exact hx_mem
    have hhead_mem : M.head e ∈ sideRegion₁ data := by rw [hh]; exact hy_mem
    rcases H.edge_core htail_mem hhead_mem with ⟨hkept, _⟩ | hchord
    · exact side_adj_of_kept_edge data hsep a₀ a₁ hne hxy hkept ht hh
    · -- chord case: `dartEdge e = s(u, v)` and `dartEdge e = s(ι x, ι y)`, so `{ι x, ι y} = {u, v}`.
      have hsuv : s(sideVertexToM₁ data hsep a₀ a₁ hne x, sideVertexToM₁ data hsep a₀ a₁ hne y)
          = s(u, v) := by
        rw [← hde]; exact hchord
      rcases Sym2.eq_iff.1 hsuv with ⟨hxu, hyv⟩ | ⟨hxv, hyu⟩
      · exact side_adj_of_chord_edge data hsep a₀ a₁ hne hxy ha₀ ha₁ hxu hyv
      · exact ((data.sideMap₁ hsep a₀ a₁ hne).toSimpleGraph.symm
          (side_adj_of_chord_edge data hsep a₀ a₁ hne hxy.symm ha₀ ha₁ hyu hxv))
  · -- `tail e = ι y`, `head e = ι x` (`e` oriented the other way).
    have htail_mem : M.tail e ∈ sideRegion₁ data := by rw [ht]; exact hy_mem
    have hhead_mem : M.head e ∈ sideRegion₁ data := by rw [hh]; exact hx_mem
    rcases H.edge_core htail_mem hhead_mem with ⟨hkept, _⟩ | hchord
    · exact (data.sideMap₁ hsep a₀ a₁ hne).toSimpleGraph.symm
        (side_adj_of_kept_edge data hsep a₀ a₁ hne hxy.symm hkept ht hh)
    · have hsuv : s(sideVertexToM₁ data hsep a₀ a₁ hne y, sideVertexToM₁ data hsep a₀ a₁ hne x)
          = s(u, v) := by
        rw [Sym2.eq_swap, ← hde]; exact hchord
      rcases Sym2.eq_iff.1 hsuv with ⟨hyu, hxv⟩ | ⟨hyv, hxu⟩
      · exact (data.sideMap₁ hsep a₀ a₁ hne).toSimpleGraph.symm
          (side_adj_of_chord_edge data hsep a₀ a₁ hne hxy.symm ha₀ ha₁ hyu hxv)
      · exact side_adj_of_chord_edge data hsep a₀ a₁ hne hxy ha₀ ha₁ hxu hyv



/-- **Brick 6 — `chordSideResidue₁_final`** (master).  The full side-1 reconstruction residue
`ChordSideResidue`, closed modulo the minimal bundle `Side₁SchoenfliesConfinementInput` (the genuine
discrete-Schoenflies content) plus the upstream non-confinement inputs.

The chapter's complete remaining planar-input surface (documented in the deliverable report):

* `ci : ContiguousInterval …` — supplied for canonical anchors by `ZinanCh35Hclass`/`OuterTrace`;
* `hshare : Side₁AnchorsShareFace …` — ditto;
* `hchord : M.Adj (M.tail a₀.1) (M.tail a₁.1)` — the chord edge `u–v` (`ι_adj` fresh half);
* `ha₀ : M.tail a₀.1 = u`, `ha₁ : M.tail a₁.1 = v` — canonical anchor-tail geometry (chord-case
  `hreflect`);
* `pₛ qₛ cpₛ cqₛ` + `hLₛ : ThomassenLists …` — the side Thomassen lists transport;
* `H : Side₁SchoenfliesConfinementInput data hsep` — the genuine discrete-Schoenflies confinement
  (`oppArcStarSeed` + `edge_core`).

Everything else (`ι_inj`, the kept half of `ι_adj`, the `homit`/`hreflect` *producers*, the strict
decrease) is proved unconditionally here and upstream. -/
def chordSideResidue₁_final (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₁}) (hne : a₀ ≠ a₁) (L : M.Vertex → Finset α)
    (ci : ContiguousInterval data hsep a₀ a₁ hne)
    (hshare : ProofsInTheBook.ChordDisk.Side₁AnchorsShareFace data hsep a₀ a₁)
    (hchord : M.Adj (M.tail a₀.1) (M.tail a₁.1))
    (ha₀ : M.tail a₀.1 = u) (ha₁ : M.tail a₁.1 = v)
    (pₛ qₛ : (data.sideMap₁ hsep a₀ a₁ hne).Vertex) (cpₛ cqₛ : α)
    (hLₛ : ThomassenLists
      (chordSideNearTriangulation_of_share data hsep a₀ a₁ hne hshare ci)
      pₛ qₛ (fun x => L (sideVertexToM₁ data hsep a₀ a₁ hne x)) cpₛ cqₛ)
    (H : Side₁SchoenfliesConfinementInput data hsep) :
    ChordSideResidue data hsep a₀ a₁ hne L :=
  chordSideResidue₁_partial data hsep a₀ a₁ hne L ci hshare hchord
    (hreflect_of_confinementInput data hsep a₀ a₁ hne ha₀ ha₁ H)
    pₛ qₛ cpₛ cqₛ hLₛ
    ((ProofsInTheBook.ZinanCh35Confinement.homit_iff_exists_notMem_sideRegion₁
        data hsep a₀ a₁ hne).2
      (homit_of_confinementInput data hsep H))



/-- **Non-vacuity / satisfiability witness.**  The minimal bundle is *implied by* the landed,
documented-satisfiable `ZinanCh35Schoenflies.Side₁SchoenfliesConfinement` (whose `edge_confined`
yields `edge_core` modulo region-membership of the endpoints, and whose `opposite_arc_omitted` is
`oppArcStarSeed` verbatim).  Hence `Side₁SchoenfliesConfinementInput` is a genuine consequence of an
inhabited structure — it is NOT propositionally `False`. -/
theorem confinementInput_of_schoenflies (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (H : ProofsInTheBook.ZinanCh35Schoenflies.Side₁SchoenfliesConfinement data) :
    Side₁SchoenfliesConfinementInput data hsep where
  oppArcStarSeed := fun hw => H.opposite_arc_omitted hw
  edge_core := fun htail hhead => H.edge_confined htail hhead

end ProofsInTheBook.ZinanCh35FinalClose










end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapFanFaces
import ProofsInTheBook.ThomassenInduction
-/
/- Source module: ProofsInTheBook.ChordlessClose -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ChordlessClose

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {v0 : M.Vertex}













/-- **The chordless reconstruction, assembled from the fan + the residue datum.**  This is
`fanSurgeryReconstruction`: the three structural fields come from the fan, the boundary
data (`bdry`) supplies the merged outer face, its boundary cycle, and `inner_tri`. -/
noncomputable def chordlessRecon_of_bdry (fan : BoundaryVertexFan hNT v0) {d0 : D}
    (htail0 : M.tail d0 = v0) (hmerge : DeleteVertexMergedFaceSingleOrbit M d0)
    (bdry : DeletedOuterBoundary hNT d0) :
    FanSurgeryReconstruction hNT d0 :=
  fanSurgeryReconstruction fan htail0 hmerge bdry









end ProofsInTheBook.ChordlessClose












end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapFanFaces
import ProofsInTheBook.ChordlessClose
-/
/- Source module: ProofsInTheBook.ChordlessFinal -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ChordlessFinal

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ChordlessClose

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {v0 : M.Vertex}



/-- A dart whose `M`-face avoids `v0` survives the star deletion.  (The face-incidence
characterization `dartFace_mem_vertexFaces_iff`, re-derived with `htail0`.) -/
lemma survives_of_clean {d0 : D} (htail0 : M.tail d0 = v0)
    {d : D} (hf : M.dartFace d ∉ M.vertexFaces d0) :
    d ∉ M.deleteVertexSet d0 := by
  classical
  rw [mem_deleteVertexSet_iff]
  push_neg
  rw [mem_vertexDarts, mem_vertexDarts]
  -- helper: `dartFace e ∈ vertexFaces d0` whenever `tail ((φ^k) e) = v0`.
  have key : ∀ (e : D) (k : ℤ), M.tail ((M.φ ^ k) e) = v0 → M.dartFace e ∈ M.vertexFaces d0 := by
    intro e k hk
    rw [vertexFaces, Finset.mem_image]
    refine ⟨(M.φ ^ k) e, ?_, ?_⟩
    · rw [mem_vertexDarts]
      exact Quotient.exact (show M.tail d0 = M.tail ((M.φ ^ k) e) by rw [htail0, hk])
    · exact Quotient.sound (⟨-k, by simp⟩ : M.φ.SameCycle ((M.φ ^ k) e) e)
  refine ⟨fun h => hf ?_, fun h => hf ?_⟩
  · -- `tail d = v0`: take `k = 0`.
    apply key d 0
    simp only [zpow_zero, Equiv.Perm.coe_one, id_eq]
    have heq : M.tail d0 = M.tail d := Quotient.sound h
    rw [← heq, htail0]
  · -- `tail (α d) = v0` i.e. `head d = v0 = tail (φ d)`: take `k = 1`.
    apply key d 1
    rw [zpow_one, tail_phi]
    have heq : M.tail d0 = M.tail (M.α d) := Quotient.sound h
    rw [tail_alpha] at heq
    rw [← heq, htail0]

/-- A clean dart's `M.φ`-successor survives. -/
lemma phi_survives_of_clean {d0 : D} (htail0 : M.tail d0 = v0)
    {d : D} (hf : M.dartFace d ∉ M.vertexFaces d0) :
    M.φ d ∉ M.deleteVertexSet d0 := by
  apply survives_of_clean htail0
  have hface : M.dartFace (M.φ d) = M.dartFace d :=
    Quotient.sound (⟨-1, by simp⟩ : M.φ.SameCycle (M.φ d) d)
  rw [hface]; exact hf

/-- **On a clean dart, the deleted `φ'` agrees with `M.φ`, and the result is again clean.** -/
lemma cleanStep {d0 : D} (htail0 : M.tail d0 = v0)
    (x : {d : D // d ∉ M.deleteVertexSet d0})
    (hf : M.dartFace x.1 ∉ M.vertexFaces d0) :
    ((M.deleteVertex d0).φ x : D) = M.φ x.1 ∧
      M.dartFace ((M.deleteVertex d0).φ x).1 ∉ M.vertexFaces d0 := by
  have hkept : M.φ x.1 ∉ M.deleteVertexSet d0 := phi_survives_of_clean htail0 hf
  have hagree : ((M.deleteVertex d0).φ x : D) = M.φ x.1 :=
    deleteVertex_phi_apply_of_next_kept M d0 x hkept
  refine ⟨hagree, ?_⟩
  rw [hagree]
  have hface : M.dartFace (M.φ x.1) = M.dartFace x.1 :=
    Quotient.sound (⟨-1, by simp⟩ : M.φ.SameCycle (M.φ x.1) x.1)
  rw [hface]; exact hf

/-- **Iterating the clean step**: the `n`-th `φ'`-iterate of a clean dart has underlying dart
`(M.φ)^[n] x.1` and stays clean. -/
lemma cleanIterate {d0 : D} (htail0 : M.tail d0 = v0)
    (x : {d : D // d ∉ M.deleteVertexSet d0})
    (hf : M.dartFace x.1 ∉ M.vertexFaces d0) (n : ℕ) :
    (((M.deleteVertex d0).φ)^[n] x : D) = (M.φ)^[n] x.1 ∧
      M.dartFace (((M.deleteVertex d0).φ)^[n] x).1 ∉ M.vertexFaces d0 := by
  induction n with
  | zero => exact ⟨rfl, by simpa using hf⟩
  | succ n ih =>
      obtain ⟨hval, hcln⟩ := ih
      have hstep := cleanStep htail0 (((M.deleteVertex d0).φ)^[n] x) hcln
      constructor
      · rw [Function.iterate_succ_apply', Function.iterate_succ_apply', hstep.1, hval]
      · rw [Function.iterate_succ_apply']; exact hstep.2

/-- **`φ'` and `M.φ` define the same cycle on a clean orbit.** -/
lemma cleanSameCycle_iff {d0 : D} (htail0 : M.tail d0 = v0)
    (x : {d : D // d ∉ M.deleteVertexSet d0})
    (hf : M.dartFace x.1 ∉ M.vertexFaces d0)
    (y : {d : D // d ∉ M.deleteVertexSet d0}) :
    (M.deleteVertex d0).φ.SameCycle x y ↔ M.φ.SameCycle x.1 y.1 := by
  constructor
  · intro hsc
    obtain ⟨n, hn⟩ := hsc.exists_nat_pow_eq
    refine ⟨(n : ℤ), ?_⟩
    rw [zpow_natCast, Equiv.Perm.coe_pow]
    rw [Equiv.Perm.coe_pow] at hn
    have := congrArg Subtype.val hn
    rw [(cleanIterate htail0 x hf n).1] at this
    exact this
  · intro hsc
    obtain ⟨n, hn⟩ := hsc.exists_nat_pow_eq
    refine ⟨(n : ℤ), ?_⟩
    rw [zpow_natCast, Equiv.Perm.coe_pow]
    rw [Equiv.Perm.coe_pow] at hn
    apply Subtype.ext
    rw [(cleanIterate htail0 x hf n).1]
    exact hn

/-- Every dart on the `M.φ`-orbit of a clean dart survives (it has the same `M`-face). -/
lemma clean_orbit_survives {d0 : D} (htail0 : M.tail d0 = v0)
    {x : {d : D // d ∉ M.deleteVertexSet d0}} (hf : M.dartFace x.1 ∉ M.vertexFaces d0)
    {d : D} (hd : M.φ.SameCycle x.1 d) : d ∉ M.deleteVertexSet d0 := by
  apply survives_of_clean htail0
  -- `d` has the same `M`-face as `x.1`.
  have hface : M.dartFace d = M.dartFace x.1 := (Quotient.sound hd).symm
  rw [hface]; exact hf



/-- **Clean face-SIZE transfer (UNCONDITIONAL).**  The deleted face length of a clean survivor
`x` equals the `M`-face length of `x.1`.  The deletion re-routes only the `v0`-incident
(merged outer) face; every clean face is an untouched `M.φ`-orbit. -/
theorem deleteVertex_cleanFaceLen_eq_M {d0 : D} (htail0 : M.tail d0 = v0)
    (x : {d : D // d ∉ M.deleteVertexSet d0})
    (hf : M.dartFace x.1 ∉ M.vertexFaces d0) :
    (M.deleteVertex d0).faceLen ((M.deleteVertex d0).dartFace x)
      = M.faceLen (M.dartFace x.1) := by
  classical
  show (Finset.univ.filter (fun z => Quotient.mk _ z
      = Quotient.mk (cycleSetoid (M.deleteVertex d0).φ) x)).card
    = (Finset.univ.filter (fun d => Quotient.mk _ d
      = Quotient.mk (cycleSetoid M.φ) x.1)).card
  -- the deleted filter maps bijectively via `Subtype.val` onto the M filter.
  rw [show (Finset.univ.filter (fun z => Quotient.mk _ z
      = Quotient.mk (cycleSetoid (M.deleteVertex d0).φ) x)).card
      = ((Finset.univ.filter (fun z : {d : D // d ∉ M.deleteVertexSet d0} =>
          Quotient.mk _ z = Quotient.mk (cycleSetoid (M.deleteVertex d0).φ) x)).map
          ⟨Subtype.val, Subtype.val_injective⟩).card from (Finset.card_map _).symm]
  congr 1
  ext d
  simp only [Finset.mem_map, Finset.mem_filter, Finset.mem_univ, true_and,
    Function.Embedding.coeFn_mk]
  constructor
  · rintro ⟨z, hz, rfl⟩
    have hsc : (M.deleteVertex d0).φ.SameCycle z x := Quotient.exact hz
    -- transfer to M via clean SameCycle (orbit clean since `x` clean and same cycle).
    have hsc' : M.φ.SameCycle x.1 z.1 :=
      (cleanSameCycle_iff htail0 x hf z).1 hsc.symm
    exact Quotient.sound hsc'.symm
  · intro hd
    have hsc : M.φ.SameCycle x.1 d := Quotient.exact hd.symm
    have hsurv : d ∉ M.deleteVertexSet d0 := clean_orbit_survives htail0 hf hsc
    refine ⟨⟨d, hsurv⟩, ?_, rfl⟩
    apply Quotient.sound
    show (M.deleteVertex d0).φ.SameCycle (⟨d, hsurv⟩ : {d : D // d ∉ M.deleteVertexSet d0}) x
    refine Equiv.Perm.SameCycle.symm ?_
    rw [cleanSameCycle_iff htail0 x hf ⟨d, hsurv⟩]
    exact hsc



/-- **A clean survivor whose `M`-face is non-outer has deleted face length `3`.** -/
theorem deleteVertex_cleanFace_eq_three {d0 : D} (htail0 : M.tail d0 = v0)
    (x : {d : D // d ∉ M.deleteVertexSet d0})
    (hf : M.dartFace x.1 ∉ M.vertexFaces d0)
    (hMinner : M.dartFace x.1 ≠ hNT.outerFace) :
    (M.deleteVertex d0).faceLen ((M.deleteVertex d0).dartFace x) = 3 := by
  rw [deleteVertex_cleanFaceLen_eq_M htail0 x hf]
  exact hNT.inner_tri (M.dartFace x.1) hMinner



/-- **The clean-face classification** (the single named residue).  Relative to the merged outer
face `outerFace`, every *other* deleted face is represented by a survivor `x` whose `M`-face is
**clean** (avoids `v0`) and **non-outer** in `M`.  This is the fan analogue of
`InnerFacesSide₁`: the merged outer face captures exactly the `v0`-incident orbit, leaving every
other deleted face an intact `M`-triangle. -/
def CleanFaceClass {d0 : D} (outerFace : (M.deleteVertex d0).Face) : Prop :=
  ∀ f : (M.deleteVertex d0).Face, f ≠ outerFace →
    ∃ x : {d : D // d ∉ M.deleteVertexSet d0},
      (M.deleteVertex d0).dartFace x = f ∧
      M.dartFace x.1 ∉ M.vertexFaces d0 ∧
      M.dartFace x.1 ≠ hNT.outerFace

/-- **`inner_tri` is discharged from the clean-face classification.**  Every non-outer deleted
face is represented by a clean, `M`-non-outer survivor (the classification), and Section 3 makes
its deleted face length `3`.  This is the chordless inner triangulation, via the same face-SIZE
route as the chord side — sidestepping the `CutFaceLabel` COUNT refutation. -/
theorem deleteVertex_inner_tri_of_cleanFaceClass {d0 : D} (htail0 : M.tail d0 = v0)
    (outerFace : (M.deleteVertex d0).Face)
    (hcl : CleanFaceClass (hNT := hNT) outerFace) :
    ∀ f : (M.deleteVertex d0).Face, f ≠ outerFace →
      (M.deleteVertex d0).faceLen f = 3 := by
  intro f hf
  obtain ⟨x, hxf, hclean, hMinner⟩ := hcl f hf
  rw [← hxf]
  exact deleteVertex_cleanFace_eq_three htail0 x hclean hMinner



/-- **`DeletedOuterBoundary` from the merged outer-boundary cycle + the clean-face
classification.**  The `inner_tri` field is discharged via the face-SIZE route
(`deleteVertex_inner_tri_of_cleanFaceClass`); the boundary-cycle fields are the genuine
merged-face normalization (supplied as input, as in `DeletedOuterBoundary.ofMergedFace`). -/
noncomputable def deletedOuterBoundary_of_cleanFaceClass {d0 : D} (htail0 : M.tail d0 = v0)
    (outerFace : (M.deleteVertex d0).Face)
    (outerCycle : BoundaryCycle (M.deleteVertex d0) outerFace)
    (outer_simple : outerCycle.VertexNodup)
    (outer_len_ge_three : 3 ≤ outerCycle.length)
    (hcl : CleanFaceClass (hNT := hNT) outerFace) :
    DeletedOuterBoundary hNT d0 where
  outerFace := outerFace
  outerCycle := outerCycle
  outer_simple := outer_simple
  outer_len_ge_three := outer_len_ge_three
  inner_tri := deleteVertex_inner_tri_of_cleanFaceClass htail0 outerFace hcl









end ProofsInTheBook.ChordlessFinal












end

/- Original source header (imports hoisted):
import ProofsInTheBook.Chapter35
import ProofsInTheBook.JordanOracleConstruct
import ProofsInTheBook.ChordSplitFinal
import ProofsInTheBook.ZinanCh35FinalClose
import ProofsInTheBook.ChordlessFinal
-/
/- Source module: ProofsInTheBook.ZinanCh35Cert -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false

namespace ProofsInTheBook.ZinanCh35Cert

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ChordSideNT
open ProofsInTheBook.ChordSplitFinal
open ProofsInTheBook.ChordSplitNT
open ProofsInTheBook.ChordDisk
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap
open ProofsInTheBook.ListColoring

universe u

variable {D : Type u} [Fintype D] [DecidableEq D]
variable {M : CombMap D} {hNT : NearTriangulation M}
variable {u v : M.Vertex} {α : Type u} [DecidableEq α]



/-- The exact side-1 input list consumed by
`ZinanCh35FinalClose.chordSideResidue₁_final`.

This is deliberately side-1 only.  A side-2 mirror would need the same kind of
final residue producer for `sideMap₂`; no such theorem is landed in this checkout.
-/
structure Side₁CertificateInputs (data : hNT.ChordSplitData u v)
    (hsep : data.Separates) (a₀ a₁ : {d : D // d ∉ data.keptDel₁})
    (hne : a₀ ≠ a₁) (L : M.Vertex → Finset α) where
  ci : ContiguousInterval data hsep a₀ a₁ hne
  hshare : Side₁AnchorsShareFace data hsep a₀ a₁
  hchord : M.Adj (M.tail a₀.1) (M.tail a₁.1)
  ha₀ : M.tail a₀.1 = u
  ha₁ : M.tail a₁.1 = v
  pₛ : (data.sideMap₁ hsep a₀ a₁ hne).Vertex
  qₛ : (data.sideMap₁ hsep a₀ a₁ hne).Vertex
  cpₛ : α
  cqₛ : α
  hLₛ : ThomassenLists
    (chordSideNearTriangulation_of_share data hsep a₀ a₁ hne hshare ci)
    pₛ qₛ (fun x => L (sideVertexToM₁ data hsep a₀ a₁ hne x)) cpₛ cqₛ
  confinement :
    ProofsInTheBook.ZinanCh35FinalClose.Side₁SchoenfliesConfinementInput data hsep

/-- The campaign's closed side-1 residue, repackaged with its exact input list. -/
def side₁Residue_of_certificateInputs (data : hNT.ChordSplitData u v)
    (hsep : data.Separates) (a₀ a₁ : {d : D // d ∉ data.keptDel₁})
    (hne : a₀ ≠ a₁) (L : M.Vertex → Finset α)
    (I : Side₁CertificateInputs data hsep a₀ a₁ hne L) :
    ChordSideResidue data hsep a₀ a₁ hne L :=
  ProofsInTheBook.ZinanCh35FinalClose.chordSideResidue₁_final data hsep a₀ a₁ hne L
    I.ci I.hshare I.hchord I.ha₀ I.ha₁ I.pₛ I.qₛ I.cpₛ I.cqₛ I.hLₛ I.confinement

/-- The landed side-1 certificate in the exact `ChordSideReconstruction` shape
consumed by the recursive chord induction. -/
noncomputable def side₁Reconstruction_of_certificateInputs
    (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₁}) (hne : a₀ ≠ a₁)
    (L : M.Vertex → Finset α)
    (I : Side₁CertificateInputs data hsep a₀ a₁ hne L) :
    ChordSideReconstruction hNT (sideRegion₁ data) L :=
  chordSideReconstruction_of_chord data hsep a₀ a₁ hne L
    (side₁Residue_of_certificateInputs data hsep a₀ a₁ hne L I)



/-- The exact remaining Chapter-35 planar input at the induction level.

It is a uniform supplier, for every recursive near-triangulation with Thomassen
lists, of either:

* a chord recursion datum, which includes both side reconstructions; or
* a chordless oracle, including the fan/deletion reconstruction and deleted-list
  bookkeeping.
-/
structure PlanarInputs (α : Type u) [DecidableEq α] : Type (u + 1) where
  recursiveDichotomy : ChordRecursiveDichotomy α

















end ProofsInTheBook.ZinanCh35Cert









end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35Cert
import ProofsInTheBook.ZinanCh35EdgeCore
-/
/- Source module: ProofsInTheBook.ZinanCh35Side2 -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35Side2

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ChordSideNT
open ProofsInTheBook.ChordSplitNT
open ProofsInTheBook.ChordSplitFinal
open ProofsInTheBook.ChordDisk
open ProofsInTheBook.ZinanCh35EdgeCore
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex} {α : Type u} [DecidableEq α]



/-- **The side-2 vertex correspondence `ι₂`.**  Mirror of `ChordReconClose.sideVertexToM₁`:
a side-2 vertex (a `freshSigma sideSigma₂`-orbit `⟦y⟧`) is sent to `M.tail (proj a₀ a₁ y).val`.
Well-defined: a `freshSigma`-orbit restricts to a `sideSigma₂`-orbit (`freshSigma_sameCycle_iff`)
and then to an `M.σ`-orbit (`filteredRotation_sameCycle_iff` over `keptDel₂`). -/
noncomputable def sideVertexToM₂ (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁) :
    (data.sideMap₂ hsep a₀ a₁ hne).Vertex → M.Vertex :=
  Quotient.lift
    (fun y : {d : D // d ∉ data.keptDel₂} ⊕ Fin 2 =>
      M.tail (proj a₀ a₁ y).1)
    (by
      intro x y hxy
      have hfs : (freshSigma data.sideSigma₂ a₀ a₁ hne).SameCycle x y := hxy
      have hss : data.sideSigma₂.SameCycle (proj a₀ a₁ x) (proj a₀ a₁ y) :=
        (freshSigma_sameCycle_iff data.sideSigma₂ hne x y).1 hfs
      have hM : M.σ.SameCycle (proj a₀ a₁ x).1 (proj a₀ a₁ y).1 :=
        (filteredRotation_sameCycle_iff M.σ data.keptDel₂ _ _).1 hss
      show M.tail (proj a₀ a₁ x).1 = M.tail (proj a₀ a₁ y).1
      exact Quotient.sound hM)

/-- `ι₂` on the class of a representative `y` is `M.tail (proj a₀ a₁ y).1` (the `Quotient.lift`
computation). -/
lemma sideVertexToM₂_mk (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁)
    (y : {d : D // d ∉ data.keptDel₂} ⊕ Fin 2) :
    sideVertexToM₂ data hsep a₀ a₁ hne
        (Quotient.mk (cycleSetoid (freshSigma data.sideSigma₂ a₀ a₁ hne)) y)
      = M.tail (proj a₀ a₁ y).1 :=
  rfl

/-- `ι₂` on the class of an `inl`-dart `⟨d, …⟩` is `M.tail d`. -/
lemma sideVertexToM₂_inl (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁)
    (x : {d : D // d ∉ data.keptDel₂}) :
    sideVertexToM₂ data hsep a₀ a₁ hne
        (Quotient.mk (cycleSetoid (freshSigma data.sideSigma₂ a₀ a₁ hne)) (Sum.inl x))
      = M.tail x.1 := by
  show M.tail (proj a₀ a₁ (Sum.inl x)).1 = M.tail x.1
  rw [proj_inl]

/-- `ι₂` of the head of an `inl`-dart `x` is `M.head x.val` (`sideAlpha₂` restricts `M.α`). -/
lemma sideVertexToM₂_head_inl (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁)
    (x : {d : D // d ∉ data.keptDel₂}) :
    sideVertexToM₂ data hsep a₀ a₁ hne
        (Quotient.mk (cycleSetoid (freshSigma data.sideSigma₂ a₀ a₁ hne))
          ((freshAlpha (data.sideAlpha₂ hsep)) (Sum.inl x)))
      = M.head x.1 := by
  rw [freshAlpha_inl]
  rw [sideVertexToM₂_inl data hsep a₀ a₁ hne (data.sideAlpha₂ hsep x)]
  rw [data.sideAlpha₂_apply_coe hsep x]
  rfl

/-- **`ι₂` lands in the side-2 region.**  Every side-2 vertex is the orbit of a kept dart, whose
tail is in `sideRegion₂` by definition. -/
theorem sideVertexToM₂_mem (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁)
    (V : (data.sideMap₂ hsep a₀ a₁ hne).Vertex) :
    sideVertexToM₂ data hsep a₀ a₁ hne V ∈ sideRegion₂ data := by
  refine Quotient.inductionOn V (fun y => ?_)
  show M.tail (proj a₀ a₁ y).1 ∈ sideRegion₂ data
  exact tail_mem_sideRegion₂ data (proj a₀ a₁ y).2

/-- **`ι₂` is surjective onto the side-2 region (`ι_surj`).**  Every region vertex `w = M.tail d`
(kept `d ∉ keptDel₂`) is `ι₂ ⟦inl ⟨d, …⟩⟧`. -/
theorem sideVertexToM₂_surjective (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁) :
    ∀ ⦃w : M.Vertex⦄, w ∈ sideRegion₂ data →
      ∃ V : (data.sideMap₂ hsep a₀ a₁ hne).Vertex,
        sideVertexToM₂ data hsep a₀ a₁ hne V = w := by
  rintro w ⟨d, hd, rfl⟩
  refine ⟨Quotient.mk (cycleSetoid (freshSigma data.sideSigma₂ a₀ a₁ hne))
    (Sum.inl ⟨d, hd⟩), ?_⟩
  exact sideVertexToM₂_inl data hsep a₀ a₁ hne ⟨d, hd⟩

/-- **The image of `ι₂` is exactly the side-2 region.** -/
theorem sideVertexToM₂_range (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁) :
    Set.range (sideVertexToM₂ data hsep a₀ a₁ hne) = sideRegion₂ data := by
  apply Set.eq_of_subset_of_subset
  · rintro w ⟨V, rfl⟩
    exact sideVertexToM₂_mem data hsep a₀ a₁ hne V
  · intro w hw
    obtain ⟨V, hV⟩ := sideVertexToM₂_surjective data hsep a₀ a₁ hne hw
    exact ⟨V, hV⟩

/-- **The inner-edge correspondence (`ι_adj_of_inl₂`).**  The side-2 edge of an `inl`-dart `x`
maps under `ι₂` to the `M`-edge `s(M.tail x.val, M.head x.val)`; the two `ι₂`-endpoints are
`M`-adjacent via the dart `x.val`. -/
theorem ι_adj_of_inl₂ (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁)
    (x : {d : D // d ∉ data.keptDel₂}) :
    M.Adj
      (sideVertexToM₂ data hsep a₀ a₁ hne
        (Quotient.mk (cycleSetoid (freshSigma data.sideSigma₂ a₀ a₁ hne)) (Sum.inl x)))
      (sideVertexToM₂ data hsep a₀ a₁ hne
        (Quotient.mk (cycleSetoid (freshSigma data.sideSigma₂ a₀ a₁ hne))
          ((freshAlpha (data.sideAlpha₂ hsep)) (Sum.inl x)))) := by
  rw [sideVertexToM₂_inl data hsep a₀ a₁ hne x,
    sideVertexToM₂_head_inl data hsep a₀ a₁ hne x]
  exact M.adj_of_dart x.1







/-- **The side-2 boundary classification residue.**  Mirror of `ChordSideNT.ContiguousInterval`
against `sideMap₂`: the side outer face/cycle (arc-plus-duplicated-chord), its simplicity, length
`≥ 3`, and the inner-triangle condition.  These are the `NearTriangulation (sideMap₂)` fields
beyond `IsSphereMap`. -/
structure ContiguousInterval₂ (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁) where
  /-- The side-2 map is a simple graph. -/
  simpleGraph : (data.sideMap₂ hsep a₀ a₁ hne).IsSimpleGraph
  /-- The side-2 outer face (the chord face). -/
  outerFace : (data.sideMap₂ hsep a₀ a₁ hne).Face
  /-- The side-2 outer boundary cycle. -/
  outerCycle : BoundaryCycle (data.sideMap₂ hsep a₀ a₁ hne) outerFace
  /-- The side-2 boundary vertex list is simple. -/
  outer_simple : outerCycle.VertexNodup
  /-- The side-2 boundary has length at least three. -/
  outer_len : 3 ≤ outerCycle.length
  /-- Every non-outer side-2 face is a triangle. -/
  inner_tri : ∀ f : (data.sideMap₂ hsep a₀ a₁ hne).Face, f ≠ outerFace →
    (data.sideMap₂ hsep a₀ a₁ hne).faceLen f = 3

/-- **The side-2 near-triangulation, assembled.**  Mirror of
`ChordSideNT.chordSideNearTriangulation`: `sphere` from the supplied side-2 sphere fact,
everything else from `ContiguousInterval₂`. -/
def chordSideNearTriangulation₂ (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁)
    (hsphere : (data.sideMap₂ hsep a₀ a₁ hne).IsSphereMap)
    (ci : ContiguousInterval₂ data hsep a₀ a₁ hne) :
    NearTriangulation (data.sideMap₂ hsep a₀ a₁ hne) where
  sphere := hsphere
  simpleGraph := ci.simpleGraph
  outerFace := ci.outerFace
  outerCycle := ci.outerCycle
  outer_simple := ci.outer_simple
  outer_len := ci.outer_len
  inner_tri := ci.inner_tri

/-- **The side-2 near-triangulation from the disk facts + the boundary classification.**  Mirror
of `chordSideNearTriangulation_of_share`: the `sphere` field is discharged by
`ChordDisk.side₂_isSphereMap_of_disk` from the side-2 disk fact `Side₂IsDisk` and the
anchor-incidence fact `Side₂AnchorsShareFace`.  (`sideKeptMap₂_connected` was not mirrored
upstream, so `Side₂IsDisk` is a named input — the one genuine asymmetry, see the header.) -/
def chordSideNearTriangulation₂_of_share (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁)
    (hdisk : ProofsInTheBook.ChordDisk.Side₂IsDisk data hsep)
    (hshare : ProofsInTheBook.ChordDisk.Side₂AnchorsShareFace data hsep a₀ a₁)
    (ci : ContiguousInterval₂ data hsep a₀ a₁ hne) :
    NearTriangulation (data.sideMap₂ hsep a₀ a₁ hne) :=
  chordSideNearTriangulation₂ data hsep a₀ a₁ hne
    (ProofsInTheBook.ChordDisk.side₂_isSphereMap_of_disk data hsep a₀ a₁ hne hdisk hshare) ci

/-- **`ContiguousInterval₂` is satisfiable from a side-2 near-triangulation** (non-vacuity).  Any
`NearTriangulation (sideMap₂)` projects onto a `ContiguousInterval₂` (its boundary fields).  So
the predicate is not unsatisfiable: it holds exactly when the side is a near-triangulation. -/
def contiguousInterval₂_of_nearTriangulation (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁)
    (N : NearTriangulation (data.sideMap₂ hsep a₀ a₁ hne)) :
    ContiguousInterval₂ data hsep a₀ a₁ hne where
  simpleGraph := N.simpleGraph
  outerFace := N.outerFace
  outerCycle := N.outerCycle
  outer_simple := N.outer_simple
  outer_len := N.outer_len
  inner_tri := N.inner_tri



/-- **Brick 1 — `ι₂` is injective.**  Mirror of `sideVertexToM₁_injective_canonical`:
`ι₂ ⟦y⟧ = ι₂ ⟦z⟧` gives `M.σ.SameCycle (proj y).1 (proj z).1` (`Quotient.exact`), transported
back to a `sideSigma₂`-SameCycle (`filteredRotation_sameCycle_iff`) and then a `freshSigma`-
SameCycle (`freshSigma_sameCycle_iff` backward), i.e. `⟦y⟧ = ⟦z⟧`.  Purely combinatorial. -/
theorem sideVertexToM₂_injective_canonical (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁) :
    Function.Injective (sideVertexToM₂ data hsep a₀ a₁ hne) := by
  refine fun X Y => ?_
  refine Quotient.inductionOn₂ X Y (fun y z hYZ => ?_)
  have hM : M.σ.SameCycle (proj a₀ a₁ y).1 (proj a₀ a₁ z).1 := Quotient.exact hYZ
  have hss : data.sideSigma₂.SameCycle (proj a₀ a₁ y) (proj a₀ a₁ z) :=
    (FilteredRotation.filteredRotation_sameCycle_iff M.σ data.keptDel₂
      (proj a₀ a₁ y) (proj a₀ a₁ z)).2 hM
  have hfs : (freshSigma data.sideSigma₂ a₀ a₁ hne).SameCycle y z :=
    (freshSigma_sameCycle_iff data.sideSigma₂ hne y z).2 hss
  exact Quotient.sound hfs

/-- `ι₂ (sideMap₂.tail (inr j))` is `M.tail a₀.1` (`j = 0`) or `M.tail a₁.1` (`j = 1`).  Mirror of
`sideVertexToM₁_tail_inr`. -/
lemma sideVertexToM₂_tail_inr (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁) (j : Fin 2) :
    sideVertexToM₂ data hsep a₀ a₁ hne
        (Quotient.mk (cycleSetoid (freshSigma data.sideSigma₂ a₀ a₁ hne)) (Sum.inr j))
      = M.tail (if j = 0 then a₀.1 else a₁.1) := by
  rw [sideVertexToM₂_mk data hsep a₀ a₁ hne (Sum.inr j)]
  fin_cases j
  · simp [proj]
  · simp [proj]

/-- The fresh chord dart `inr j` has `ι₂`-head the *other* anchor's tail.  Mirror of
`sideVertexToM₁_head_inr`. -/
lemma sideVertexToM₂_head_inr (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁) (j : Fin 2) :
    sideVertexToM₂ data hsep a₀ a₁ hne
        (Quotient.mk (cycleSetoid (freshSigma data.sideSigma₂ a₀ a₁ hne))
          ((freshAlpha (data.sideAlpha₂ hsep)) (Sum.inr j)))
      = M.tail (if j = 0 then a₁.1 else a₀.1) := by
  rw [freshAlpha_inr]
  rw [sideVertexToM₂_tail_inr data hsep a₀ a₁ hne (Equiv.swap (0 : Fin 2) 1 j)]
  fin_cases j
  · simp [Equiv.swap_apply_left]
  · simp [Equiv.swap_apply_right]

/-- **The `ι₂`-edge of any side-2 dart.**  Mirror of `ZinanCh35Iota.ι_adj_of_dart`: an `inl x'`
dart gives the proved `M`-edge of `x'` (`ι_adj_of_inl₂`); a fresh chord dart gives the anchor-tail
pair (`M`-adjacent by `hchord`). -/
lemma ι_adj_of_dart₂ (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁)
    (hchord : M.Adj (M.tail a₀.1) (M.tail a₁.1))
    (d : {d : D // d ∉ data.keptDel₂} ⊕ Fin 2) :
    M.Adj
      (sideVertexToM₂ data hsep a₀ a₁ hne
        (Quotient.mk (cycleSetoid (freshSigma data.sideSigma₂ a₀ a₁ hne)) d))
      (sideVertexToM₂ data hsep a₀ a₁ hne
        (Quotient.mk (cycleSetoid (freshSigma data.sideSigma₂ a₀ a₁ hne))
          ((freshAlpha (data.sideAlpha₂ hsep)) d))) := by
  cases d with
  | inl x' => exact ι_adj_of_inl₂ data hsep a₀ a₁ hne x'
  | inr j =>
      rw [sideVertexToM₂_tail_inr data hsep a₀ a₁ hne j,
        sideVertexToM₂_head_inr data hsep a₀ a₁ hne j]
      fin_cases j
      · simpa using hchord
      · simpa using M.adj_symm hchord

/-- **Brick 2 — `ι₂_adj`.**  Mirror of `sideVertexToM₁_adj_canonical`: side-2 adjacency carries
to `M`-adjacency on `ι₂`-images, with the chord edge `hchord` discharging the fresh-dart half and
injectivity (Brick 1) the `≠` half. -/
theorem sideVertexToM₂_adj_canonical (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁)
    (hchord : M.Adj (M.tail a₀.1) (M.tail a₁.1)) :
    ∀ ⦃x y : (data.sideMap₂ hsep a₀ a₁ hne).Vertex⦄,
      (data.sideMap₂ hsep a₀ a₁ hne).toSimpleGraph.Adj x y →
        M.toSimpleGraph.Adj (sideVertexToM₂ data hsep a₀ a₁ hne x)
          (sideVertexToM₂ data hsep a₀ a₁ hne y) := by
  intro x y hxy
  rw [toSimpleGraph_adj] at hxy ⊢
  obtain ⟨hne_xy, d, hd⟩ := hxy
  refine ⟨fun h => hne_xy (sideVertexToM₂_injective_canonical data hsep a₀ a₁ hne h), ?_⟩
  have hM := ι_adj_of_dart₂ data hsep a₀ a₁ hne hchord d
  have hd' : s((data.sideMap₂ hsep a₀ a₁ hne).tail d, (data.sideMap₂ hsep a₀ a₁ hne).head d)
      = s(x, y) := hd
  rcases Sym2.eq_iff.1 hd' with ⟨hx, hy⟩ | ⟨hx, hy⟩
  · rw [← hx, ← hy]; exact hM
  · rw [← hx, ← hy]; exact M.adj_symm hM

/-- **Brick 5 — `smaller`.**  Mirror of `side₁_smaller_canonical`: from injectivity of `ι₂` and an
explicit omitted `M`-vertex `w ∉ Set.range ι₂` (the opposite-arc internal vertex side 2 drops —
the named region-confinement residue `homit`), the side has strictly fewer vertices than `M`. -/
theorem side₂_smaller_canonical (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁)
    (homit : ∃ w : M.Vertex, w ∉ Set.range (sideVertexToM₂ data hsep a₀ a₁ hne)) :
    (data.sideMap₂ hsep a₀ a₁ hne).V < M.V := by
  classical
  obtain ⟨w, hw⟩ := homit
  show Fintype.card (data.sideMap₂ hsep a₀ a₁ hne).Vertex < Fintype.card M.Vertex
  have hinj := sideVertexToM₂_injective_canonical data hsep a₀ a₁ hne
  have hcard_le : Fintype.card (data.sideMap₂ hsep a₀ a₁ hne).Vertex
      = (Finset.univ.image (sideVertexToM₂ data hsep a₀ a₁ hne)).card := by
    rw [Finset.card_image_of_injective _ hinj, Finset.card_univ]
  rw [hcard_le]
  have hsub : Finset.univ.image (sideVertexToM₂ data hsep a₀ a₁ hne) ⊂ Finset.univ := by
    refine Finset.ssubset_univ_iff.2 ?_
    intro hfull
    apply hw
    have hmem : w ∈ Finset.univ.image (sideVertexToM₂ data hsep a₀ a₁ hne) := by
      rw [hfull]; exact Finset.mem_univ w
    obtain ⟨V, _, hV⟩ := Finset.mem_image.1 hmem
    exact ⟨V, hV⟩
  calc (Finset.univ.image (sideVertexToM₂ data hsep a₀ a₁ hne)).card
      < (Finset.univ : Finset M.Vertex).card := Finset.card_lt_card hsub
    _ = Fintype.card M.Vertex := Finset.card_univ



/-- **The side-2 residue datum.**  Mirror of `ChordSplitFinal.ChordSideResidue`: the
genuinely-unbuilt `ChordSideReconstruction` fields for the side-2 instantiation. -/
structure ChordSideResidue₂ (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁)
    (L : M.Vertex → Finset α) where
  /-- The side-2 disk core (for the `sphere` field). -/
  hdisk : ProofsInTheBook.ChordDisk.Side₂IsDisk data hsep
  /-- The side-2 anchor-incidence fact. -/
  hshare : ProofsInTheBook.ChordDisk.Side₂AnchorsShareFace data hsep a₀ a₁
  /-- The side-2 boundary/inner-triangulation classification. -/
  ci : ContiguousInterval₂ data hsep a₀ a₁ hne
  /-- The vertex correspondence is injective. -/
  ι_inj : Function.Injective (sideVertexToM₂ data hsep a₀ a₁ hne)
  /-- Side-2 adjacency carries to `M`-adjacency. -/
  ι_adj : ∀ ⦃x y : (data.sideMap₂ hsep a₀ a₁ hne).Vertex⦄,
    (data.sideMap₂ hsep a₀ a₁ hne).toSimpleGraph.Adj x y →
      M.toSimpleGraph.Adj (sideVertexToM₂ data hsep a₀ a₁ hne x)
        (sideVertexToM₂ data hsep a₀ a₁ hne y)
  /-- The vertex correspondence reflects `M`-adjacency on the region. -/
  ι_adj_reflect : ∀ ⦃x y : (data.sideMap₂ hsep a₀ a₁ hne).Vertex⦄,
    M.toSimpleGraph.Adj (sideVertexToM₂ data hsep a₀ a₁ hne x)
        (sideVertexToM₂ data hsep a₀ a₁ hne y) →
      (data.sideMap₂ hsep a₀ a₁ hne).toSimpleGraph.Adj x y
  /-- The side's precolored boundary edge. -/
  pₛ : (data.sideMap₂ hsep a₀ a₁ hne).Vertex
  /-- The side's precolored boundary edge. -/
  qₛ : (data.sideMap₂ hsep a₀ a₁ hne).Vertex
  /-- The side's precolors. -/
  cpₛ : α
  /-- The side's precolors. -/
  cqₛ : α
  /-- The side Thomassen list hypotheses (with the pullback lists). -/
  hLₛ : ThomassenLists
    (chordSideNearTriangulation₂_of_share data hsep a₀ a₁ hne hdisk hshare ci)
    pₛ qₛ (fun x => L (sideVertexToM₂ data hsep a₀ a₁ hne x)) cpₛ cqₛ
  /-- The strict vertex decrease (the recursion fuel). -/
  smaller : (data.sideMap₂ hsep a₀ a₁ hne).V < M.V

/-- **The side-2 reconstruction in the generic recursion framing.**  Mirror of
`ChordSplitFinal.chordSideReconstruction_of_chord`: assembles
`ChordSplitNT.ChordSideReconstruction hNT (sideRegion₂ data) L` with `N := sideMap₂`,
`hN :=` the proved side-2 near-triangulation, `ι := sideVertexToM₂`, `ι_mem`/`ι_surj` proved in
Tier A and baked in directly, and the residue datum supplying the remaining fields. -/
noncomputable def chordSideReconstruction₂_of_chord (data : hNT.ChordSplitData u v)
    (hsep : data.Separates) (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁)
    (L : M.Vertex → Finset α)
    (res : ChordSideResidue₂ data hsep a₀ a₁ hne L) :
    ChordSplitNT.ChordSideReconstruction hNT (sideRegion₂ data) L where
  Dₛ := {d : D // d ∉ data.keptDel₂} ⊕ Fin 2
  N := data.sideMap₂ hsep a₀ a₁ hne
  hN := chordSideNearTriangulation₂_of_share data hsep a₀ a₁ hne res.hdisk res.hshare res.ci
  ι := sideVertexToM₂ data hsep a₀ a₁ hne
  ι_inj := res.ι_inj
  ι_mem := fun x => sideVertexToM₂_mem data hsep a₀ a₁ hne x
  ι_surj := fun _ hw => sideVertexToM₂_surjective data hsep a₀ a₁ hne hw
  ι_adj := res.ι_adj
  ι_adj_reflect := res.ι_adj_reflect
  Lₛ := fun x => L (sideVertexToM₂ data hsep a₀ a₁ hne x)
  Lₛ_eq := fun _ => rfl
  pₛ := res.pₛ
  qₛ := res.qₛ
  cpₛ := res.cpₛ
  cqₛ := res.cqₛ
  hLₛ := res.hLₛ
  smaller := res.smaller





/-- **The minimal side-2 confinement input bundle.**  Mirror of
`ZinanCh35FinalClose.Side₁SchoenfliesConfinementInput` with the side₁/side₂ roles swapped:

* `oppArcStarSeed₂` — a strictly internal vertex of the *opposite* boundary arc `path₁` is omitted
  by side 2 (`w ∉ sideRegion₂ data`).  (For side 2 the opposite arc is `path₁`, the mirror of
  side 1's `path₂`.)

* `edge_core₂` — an ambient dart `e` whose two endpoints are both side-2-region vertices is either
  represented in the side-2 carve (`e ∉ keptDel₂ ∧ α e ∉ keptDel₂`) or is the chord.  This is the
  side-2 region edge-confinement core; it reduces to the SAME two bridges as side 1
  (`BoundedFacePartition` + `SideRegionInterChordEnds`, both side-symmetric), which
  `ZinanCh35EdgeCore.edge_core_holds` discharges with the side roles swapped. -/
structure Side₂SchoenfliesConfinementInput (data : hNT.ChordSplitData u v)
    (hsep : data.Separates) : Prop where
  /-- Opposite-arc omission: a `path₁`-internal vertex is not in the side-2 region. -/
  oppArcStarSeed₂ : ∀ {w : M.Vertex},
    w ∈ data.arc.path₁.internalVertices → w ∉ sideRegion₂ data
  /-- Region edge-confinement core: an ambient edge between two side-2-region vertices is kept by
  side 2 (both `e` and `α e`), or is the chord. -/
  edge_core₂ : ∀ {e : D},
    M.tail e ∈ sideRegion₂ data →
    M.head e ∈ sideRegion₂ data →
      ((e ∉ data.keptDel₂ ∧ M.α e ∉ data.keptDel₂) ∨ M.dartEdge e = s(u, v))

/-- **Brick 2 — `homit_of_confinementInput₂`.**  The opposite boundary arc `path₁` carries an
internal vertex (`data.arc₁_internal`); that vertex is omitted by side 2 (`oppArcStarSeed₂`),
witnessing `∃ w, w ∉ sideRegion₂ data`.  Mirror of `homit_of_confinementInput`. -/
theorem homit_of_confinementInput₂ (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (H : Side₂SchoenfliesConfinementInput data hsep) :
    ∃ w : M.Vertex, w ∉ sideRegion₂ data := by
  obtain ⟨w, hw⟩ := List.exists_mem_of_ne_nil _ data.arc₁_internal
  exact ⟨w, H.oppArcStarSeed₂ hw⟩

/-- **Brick 3 — `side₂_adj_of_kept_edge`.**  Mirror of `ZinanCh35FinalClose.side_adj_of_kept_edge`:
a kept dart `e ∉ keptDel₂` with `M.tail e = ι₂ x`, `M.head e = ι₂ y` (`x ≠ y`) yields
`sideMap₂.toSimpleGraph.Adj x y`, witnessed by the side dart `Sum.inl ⟨e, he⟩`. -/
theorem side₂_adj_of_kept_edge (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁)
    {x y : (data.sideMap₂ hsep a₀ a₁ hne).Vertex} (hxy : x ≠ y)
    {e : D} (he : e ∉ data.keptDel₂)
    (htail : M.tail e = sideVertexToM₂ data hsep a₀ a₁ hne x)
    (hhead : M.head e = sideVertexToM₂ data hsep a₀ a₁ hne y) :
    (data.sideMap₂ hsep a₀ a₁ hne).toSimpleGraph.Adj x y := by
  classical
  set dS : {d : D // d ∉ data.keptDel₂} ⊕ Fin 2 := Sum.inl ⟨e, he⟩ with hdS
  set xS : (data.sideMap₂ hsep a₀ a₁ hne).Vertex :=
    Quotient.mk (cycleSetoid (freshSigma data.sideSigma₂ a₀ a₁ hne)) dS with hxS
  set yS : (data.sideMap₂ hsep a₀ a₁ hne).Vertex :=
    Quotient.mk (cycleSetoid (freshSigma data.sideSigma₂ a₀ a₁ hne))
      ((freshAlpha (data.sideAlpha₂ hsep)) dS) with hyS
  have hιx : sideVertexToM₂ data hsep a₀ a₁ hne xS
      = sideVertexToM₂ data hsep a₀ a₁ hne x := by
    rw [hxS, hdS, sideVertexToM₂_inl data hsep a₀ a₁ hne ⟨e, he⟩, htail]
  have hιy : sideVertexToM₂ data hsep a₀ a₁ hne yS
      = sideVertexToM₂ data hsep a₀ a₁ hne y := by
    rw [hyS, hdS, sideVertexToM₂_head_inl data hsep a₀ a₁ hne ⟨e, he⟩, hhead]
  have hxSx : xS = x := sideVertexToM₂_injective_canonical data hsep a₀ a₁ hne hιx
  have hySy : yS = y := sideVertexToM₂_injective_canonical data hsep a₀ a₁ hne hιy
  rw [toSimpleGraph_adj]
  refine ⟨hxy, ?_⟩
  refine ⟨dS, ?_⟩
  show (data.sideMap₂ hsep a₀ a₁ hne).dartEdge dS = s(x, y)
  rw [← hxSx, ← hySy]
  rfl

/-- **Brick 4 — `side₂_adj_of_chord_edge`.**  Mirror of
`ZinanCh35FinalClose.side_adj_of_chord_edge`: in the chord case `s(ι₂ x, ι₂ y) = s(u, v)`, with the
canonical anchor-tail identification `M.tail a₀.1 = u`, `M.tail a₁.1 = v`, the fresh chord side
dart `Sum.inr 0` realises `s(x, y)`. -/
theorem side₂_adj_of_chord_edge (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁)
    {x y : (data.sideMap₂ hsep a₀ a₁ hne).Vertex} (hxy : x ≠ y)
    (ha₀ : M.tail a₀.1 = u) (ha₁ : M.tail a₁.1 = v)
    (hx : sideVertexToM₂ data hsep a₀ a₁ hne x = u)
    (hy : sideVertexToM₂ data hsep a₀ a₁ hne y = v) :
    (data.sideMap₂ hsep a₀ a₁ hne).toSimpleGraph.Adj x y := by
  classical
  set dS : {d : D // d ∉ data.keptDel₂} ⊕ Fin 2 := Sum.inr 0 with hdS
  set xS : (data.sideMap₂ hsep a₀ a₁ hne).Vertex :=
    Quotient.mk (cycleSetoid (freshSigma data.sideSigma₂ a₀ a₁ hne)) dS with hxS
  set yS : (data.sideMap₂ hsep a₀ a₁ hne).Vertex :=
    Quotient.mk (cycleSetoid (freshSigma data.sideSigma₂ a₀ a₁ hne))
      ((freshAlpha (data.sideAlpha₂ hsep)) dS) with hyS
  have hιx : sideVertexToM₂ data hsep a₀ a₁ hne xS
      = sideVertexToM₂ data hsep a₀ a₁ hne x := by
    rw [hxS, hdS, sideVertexToM₂_tail_inr data hsep a₀ a₁ hne 0]
    simp only [if_true]
    rw [ha₀, hx]
  have hιy : sideVertexToM₂ data hsep a₀ a₁ hne yS
      = sideVertexToM₂ data hsep a₀ a₁ hne y := by
    rw [hyS, hdS, sideVertexToM₂_head_inr data hsep a₀ a₁ hne 0]
    simp only [if_true]
    rw [ha₁, hy]
  have hxSx : xS = x := sideVertexToM₂_injective_canonical data hsep a₀ a₁ hne hιx
  have hySy : yS = y := sideVertexToM₂_injective_canonical data hsep a₀ a₁ hne hιy
  rw [toSimpleGraph_adj]
  refine ⟨hxy, dS, ?_⟩
  show (data.sideMap₂ hsep a₀ a₁ hne).dartEdge dS = s(x, y)
  rw [← hxSx, ← hySy]
  rfl

/-- **Brick 5 — `hreflect_of_confinementInput₂`** (master).  Mirror of
`ZinanCh35FinalClose.hreflect_of_confinementInput`: produces the region edge-confinement field
`ι_adj_reflect` from `edge_core₂`, threading the canonical anchor-tail identification
`ha₀ : M.tail a₀.1 = u`, `ha₁ : M.tail a₁.1 = v`. -/
theorem hreflect_of_confinementInput₂ (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁)
    (ha₀ : M.tail a₀.1 = u) (ha₁ : M.tail a₁.1 = v)
    (H : Side₂SchoenfliesConfinementInput data hsep) :
    ∀ ⦃x y : (data.sideMap₂ hsep a₀ a₁ hne).Vertex⦄,
      M.toSimpleGraph.Adj (sideVertexToM₂ data hsep a₀ a₁ hne x)
          (sideVertexToM₂ data hsep a₀ a₁ hne y) →
        (data.sideMap₂ hsep a₀ a₁ hne).toSimpleGraph.Adj x y := by
  classical
  intro x y hAdj
  rw [toSimpleGraph_adj] at hAdj
  obtain ⟨hne_ι, e, hde⟩ := hAdj
  have hxy : x ≠ y := fun h => hne_ι (by rw [h])
  have hx_mem : sideVertexToM₂ data hsep a₀ a₁ hne x ∈ sideRegion₂ data :=
    sideVertexToM₂_mem data hsep a₀ a₁ hne x
  have hy_mem : sideVertexToM₂ data hsep a₀ a₁ hne y ∈ sideRegion₂ data :=
    sideVertexToM₂_mem data hsep a₀ a₁ hne y
  have hde' : s(M.tail e, M.head e)
      = s(sideVertexToM₂ data hsep a₀ a₁ hne x, sideVertexToM₂ data hsep a₀ a₁ hne y) := hde
  rcases Sym2.eq_iff.1 hde' with ⟨ht, hh⟩ | ⟨ht, hh⟩
  · have htail_mem : M.tail e ∈ sideRegion₂ data := by rw [ht]; exact hx_mem
    have hhead_mem : M.head e ∈ sideRegion₂ data := by rw [hh]; exact hy_mem
    rcases H.edge_core₂ htail_mem hhead_mem with ⟨hkept, _⟩ | hchord
    · exact side₂_adj_of_kept_edge data hsep a₀ a₁ hne hxy hkept ht hh
    · have hsuv : s(sideVertexToM₂ data hsep a₀ a₁ hne x, sideVertexToM₂ data hsep a₀ a₁ hne y)
          = s(u, v) := by
        rw [← hde]; exact hchord
      rcases Sym2.eq_iff.1 hsuv with ⟨hxu, hyv⟩ | ⟨hxv, hyu⟩
      · exact side₂_adj_of_chord_edge data hsep a₀ a₁ hne hxy ha₀ ha₁ hxu hyv
      · exact ((data.sideMap₂ hsep a₀ a₁ hne).toSimpleGraph.symm
          (side₂_adj_of_chord_edge data hsep a₀ a₁ hne hxy.symm ha₀ ha₁ hyu hxv))
  · have htail_mem : M.tail e ∈ sideRegion₂ data := by rw [ht]; exact hy_mem
    have hhead_mem : M.head e ∈ sideRegion₂ data := by rw [hh]; exact hx_mem
    rcases H.edge_core₂ htail_mem hhead_mem with ⟨hkept, _⟩ | hchord
    · exact (data.sideMap₂ hsep a₀ a₁ hne).toSimpleGraph.symm
        (side₂_adj_of_kept_edge data hsep a₀ a₁ hne hxy.symm hkept ht hh)
    · have hsuv : s(sideVertexToM₂ data hsep a₀ a₁ hne y, sideVertexToM₂ data hsep a₀ a₁ hne x)
          = s(u, v) := by
        rw [Sym2.eq_swap, ← hde]; exact hchord
      rcases Sym2.eq_iff.1 hsuv with ⟨hyu, hxv⟩ | ⟨hyv, hxu⟩
      · exact (data.sideMap₂ hsep a₀ a₁ hne).toSimpleGraph.symm
          (side₂_adj_of_chord_edge data hsep a₀ a₁ hne hxy.symm ha₀ ha₁ hyu hxv)
      · exact side₂_adj_of_chord_edge data hsep a₀ a₁ hne hxy ha₀ ha₁ hxu hyv

/-- **Brick 6 — `chordSideResidue₂_partial`.**  Mirror of `ZinanCh35Iota.chordSideResidue₁_partial`
composed with the side-2 confinement producers: assembles the full `ChordSideResidue₂` from the
boundary classification `ci`, the disk/anchor facts, the chord edge `hchord`, the canonical
anchor-tail identification `ha₀`/`ha₁`, the side Thomassen lists `hLₛ`, and the side-2 confinement
bundle `H` (which supplies `ι_adj_reflect` via Brick 5 and the omitted-vertex witness via Brick 2).

The proved fields: `ι_inj` (Tier C Brick 1), the kept-dart half of `ι_adj` (Brick 2), the strict
decrease (Brick 5).  The genuine planar residue is exactly `H` (the confinement bundle), `ci`,
`hdisk`/`hshare`, `hchord`, and the list field `hLₛ` — mirroring side 1 field-for-field. -/
def chordSideResidue₂_partial (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁) (L : M.Vertex → Finset α)
    (hdisk : ProofsInTheBook.ChordDisk.Side₂IsDisk data hsep)
    (hshare : ProofsInTheBook.ChordDisk.Side₂AnchorsShareFace data hsep a₀ a₁)
    (ci : ContiguousInterval₂ data hsep a₀ a₁ hne)
    (hchord : M.Adj (M.tail a₀.1) (M.tail a₁.1))
    (ha₀ : M.tail a₀.1 = u) (ha₁ : M.tail a₁.1 = v)
    (pₛ qₛ : (data.sideMap₂ hsep a₀ a₁ hne).Vertex) (cpₛ cqₛ : α)
    (hLₛ : ThomassenLists
      (chordSideNearTriangulation₂_of_share data hsep a₀ a₁ hne hdisk hshare ci)
      pₛ qₛ (fun x => L (sideVertexToM₂ data hsep a₀ a₁ hne x)) cpₛ cqₛ)
    (H : Side₂SchoenfliesConfinementInput data hsep) :
    ChordSideResidue₂ data hsep a₀ a₁ hne L where
  hdisk := hdisk
  hshare := hshare
  ci := ci
  ι_inj := sideVertexToM₂_injective_canonical data hsep a₀ a₁ hne
  ι_adj := sideVertexToM₂_adj_canonical data hsep a₀ a₁ hne hchord
  ι_adj_reflect := hreflect_of_confinementInput₂ data hsep a₀ a₁ hne ha₀ ha₁ H
  pₛ := pₛ
  qₛ := qₛ
  cpₛ := cpₛ
  cqₛ := cqₛ
  hLₛ := hLₛ
  smaller := side₂_smaller_canonical data hsep a₀ a₁ hne
    (by
      -- transport `homit_of_confinementInput₂` through `Set.range ι₂ = sideRegion₂`.
      obtain ⟨w, hw⟩ := homit_of_confinementInput₂ data hsep H
      refine ⟨w, ?_⟩
      rw [sideVertexToM₂_range data hsep a₀ a₁ hne]
      exact hw)

/-- **`chordSideResidue₂_final`.**  Mirror of `ZinanCh35FinalClose.chordSideResidue₁_final`: the
full side-2 reconstruction residue `ChordSideResidue₂`, closed modulo the minimal bundle
`Side₂SchoenfliesConfinementInput` (the genuine side-2 discrete-Schoenflies content) plus the
upstream non-confinement inputs (`hdisk`/`hshare`/`ci`/`hchord`/`ha₀`/`ha₁`/`hLₛ`).  This is
exactly `chordSideResidue₂_partial`, recorded under the FinalClose name for parity with side 1. -/
def chordSideResidue₂_final (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁) (L : M.Vertex → Finset α)
    (hdisk : ProofsInTheBook.ChordDisk.Side₂IsDisk data hsep)
    (hshare : ProofsInTheBook.ChordDisk.Side₂AnchorsShareFace data hsep a₀ a₁)
    (ci : ContiguousInterval₂ data hsep a₀ a₁ hne)
    (hchord : M.Adj (M.tail a₀.1) (M.tail a₁.1))
    (ha₀ : M.tail a₀.1 = u) (ha₁ : M.tail a₁.1 = v)
    (pₛ qₛ : (data.sideMap₂ hsep a₀ a₁ hne).Vertex) (cpₛ cqₛ : α)
    (hLₛ : ThomassenLists
      (chordSideNearTriangulation₂_of_share data hsep a₀ a₁ hne hdisk hshare ci)
      pₛ qₛ (fun x => L (sideVertexToM₂ data hsep a₀ a₁ hne x)) cpₛ cqₛ)
    (H : Side₂SchoenfliesConfinementInput data hsep) :
    ChordSideResidue₂ data hsep a₀ a₁ hne L :=
  chordSideResidue₂_partial data hsep a₀ a₁ hne L hdisk hshare ci hchord ha₀ ha₁
    pₛ qₛ cpₛ cqₛ hLₛ H



/-- **The exact side-2 input list** consumed by `chordSideResidue₂_final`.  Mirror of
`ZinanCh35Cert.Side₁CertificateInputs` against the side-2 data; the genuine planar content is the
field `confinement : Side₂SchoenfliesConfinementInput` plus the boundary/disk classification. -/
structure Side₂CertificateInputs (data : hNT.ChordSplitData u v)
    (hsep : data.Separates) (a₀ a₁ : {d : D // d ∉ data.keptDel₂})
    (hne : a₀ ≠ a₁) (L : M.Vertex → Finset α) where
  hdisk : ProofsInTheBook.ChordDisk.Side₂IsDisk data hsep
  hshare : ProofsInTheBook.ChordDisk.Side₂AnchorsShareFace data hsep a₀ a₁
  ci : ContiguousInterval₂ data hsep a₀ a₁ hne
  hchord : M.Adj (M.tail a₀.1) (M.tail a₁.1)
  ha₀ : M.tail a₀.1 = u
  ha₁ : M.tail a₁.1 = v
  pₛ : (data.sideMap₂ hsep a₀ a₁ hne).Vertex
  qₛ : (data.sideMap₂ hsep a₀ a₁ hne).Vertex
  cpₛ : α
  cqₛ : α
  hLₛ : ThomassenLists
    (chordSideNearTriangulation₂_of_share data hsep a₀ a₁ hne hdisk hshare ci)
    pₛ qₛ (fun x => L (sideVertexToM₂ data hsep a₀ a₁ hne x)) cpₛ cqₛ
  confinement : Side₂SchoenfliesConfinementInput data hsep

/-- The side-2 residue, repackaged with its exact input list.  Mirror of
`ZinanCh35Cert.side₁Residue_of_certificateInputs`. -/
def side₂Residue_of_certificateInputs (data : hNT.ChordSplitData u v)
    (hsep : data.Separates) (a₀ a₁ : {d : D // d ∉ data.keptDel₂})
    (hne : a₀ ≠ a₁) (L : M.Vertex → Finset α)
    (I : Side₂CertificateInputs data hsep a₀ a₁ hne L) :
    ChordSideResidue₂ data hsep a₀ a₁ hne L :=
  chordSideResidue₂_final data hsep a₀ a₁ hne L
    I.hdisk I.hshare I.ci I.hchord I.ha₀ I.ha₁ I.pₛ I.qₛ I.cpₛ I.cqₛ I.hLₛ I.confinement

/-- **The deliverable: the side-2 reconstruction in the exact `ChordSideReconstruction` shape.**
Mirror of `ZinanCh35Cert.side₁Reconstruction_of_certificateInputs`: threads the side-2 final
residue into `ChordSideReconstruction hNT (sideRegion₂ data) L`, the side-2 half the
`ChordBranchSupplier` needs to assemble a `ChordSplitFinal.ChordBranchResidue`. -/
noncomputable def side₂Reconstruction_of_certificateInputs
    (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    (a₀ a₁ : {d : D // d ∉ data.keptDel₂}) (hne : a₀ ≠ a₁)
    (L : M.Vertex → Finset α)
    (I : Side₂CertificateInputs data hsep a₀ a₁ hne L) :
    ChordSplitNT.ChordSideReconstruction hNT (sideRegion₂ data) L :=
  chordSideReconstruction₂_of_chord data hsep a₀ a₁ hne L
    (side₂Residue_of_certificateInputs data hsep a₀ a₁ hne L I)





end ProofsInTheBook.ZinanCh35Side2














end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35Side2
import ProofsInTheBook.ZinanCh35Side1Confine
import ProofsInTheBook.ZinanCh35EdgeCoreFinal
import ProofsInTheBook.ZinanCh35Schoenflies2
-/
/- Source module: ProofsInTheBook.ZinanCh35Side2Confine -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35Side2Confine

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ZinanCh35EdgeCore
open ProofsInTheBook.ZinanCh35EdgeCoreFinal
open ProofsInTheBook.ZinanCh35StarConn
open ProofsInTheBook.ZinanCh35Schoenflies2
open ProofsInTheBook.ZinanCh35Side2

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



/-- **The chord-arc bank-orientation datum (side-2 mirror).**  The first listed boundary arc
`path₁` is the side-1 boundary arc: every strictly-internal vertex of `path₁` lies in the side-1
region.  Symmetric counterpart of `ZinanCh35Side1Confine.ChordArcBankOrientation`'s
`path₂_internal_mem_sideRegion₂`; isolated here rather than faked, for the same reason. -/
structure ChordArcBankOrientation (data : hNT.ChordSplitData u v) : Prop where
  /-- A strictly-internal vertex of the boundary arc `path₁` is in the side-1 region. -/
  path₁_internal_mem_sideRegion₁ : ∀ {w : M.Vertex},
    w ∈ data.arc.path₁.internalVertices → w ∈ sideRegion₁ data



/-- **Both endpoints of a non-chord side-1 face-dart are in `sideRegion₁`.**  Mirror of
`endpoints_mem_sideRegion₂_of_face` with the side roles swapped: `e` is a side-1 face-dart, hence in
`keptSet₁` (it is not the side-1 seam dart `dart`, since that has chord edge), so its tail is in the
region; the `α`-closure of `keptSet₁` puts `head e = tail (α e)` in the region too. -/
theorem endpoints_mem_sideRegion₁_of_face (data : hNT.ChordSplitData u v) (hsep : data.Separates)
    {e : D} (hchord : M.dartEdge e ≠ s(u, v)) (hface : M.dartFace e ∈ data.side₁) :
    M.tail e ∈ sideRegion₁ data ∧ M.head e ∈ sideRegion₁ data := by
  -- `e ≠ dart` (else its edge would be the chord).
  have hne : e ≠ data.dart := by
    intro h; exact hchord (by rw [h]; exact hNT.chordDart_edge data.chord)
  -- `e ∈ sideDarts₁ ⊆ keptSet₁`.
  have hkept : e ∈ data.keptSet₁ := by
    refine ⟨Or.inl hface, ?_⟩
    simp only [Set.mem_singleton_iff]; exact hne
  have htail : M.tail e ∈ sideRegion₁ data :=
    ⟨e, (data.mem_keptDel₁_iff e).2 hkept, rfl⟩
  -- head `e = tail (α e)`; `α e ∈ keptSet₁` by the `α`-closure.
  have hkeptα : M.α e ∈ data.keptSet₁ := (data.mem_keptSet₁_alpha_iff hsep e).2 hkept
  have hhead : M.head e ∈ sideRegion₁ data :=
    ⟨M.α e, (data.mem_keptDel₁_iff (M.α e)).2 hkeptα, rfl⟩
  exact ⟨htail, hhead⟩

























end ProofsInTheBook.ZinanCh35Side2Confine











end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35Side1Confine
import ProofsInTheBook.ZinanCh35Side2Confine
-/
/- Source module: ProofsInTheBook.ZinanCh35BankOrient -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35BankOrient

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ZinanCh35EdgeCore

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



































end ProofsInTheBook.ZinanCh35BankOrient















end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35BankLabels
import ProofsInTheBook.ZinanCh35ChordCycle
import ProofsInTheBook.ZinanCh35Contiguity
import ProofsInTheBook.ZinanCh35BankOrient
import ProofsInTheBook.ZinanCh35InnerConn
-/
/- Source module: ProofsInTheBook.ZinanCh35ArcSide -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35ArcSide

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ZinanCh35EdgeCore
open ProofsInTheBook.ZinanCh35CycleBank
open ProofsInTheBook.ZinanCh35BankLabels

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}











































































































end ProofsInTheBook.ZinanCh35ArcSide



-- The UNCONDITIONAL bank-side facts (the real new content of R8's chain A–F):








-- The honest assembly over the single isolated orientation input:






end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35ArcSide
-/
/- Source module: ProofsInTheBook.ZinanCh35Aligned -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35Aligned

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ZinanCh35EdgeCore
open ProofsInTheBook.ZinanCh35CycleBank
open ProofsInTheBook.ZinanCh35BankLabels
open ProofsInTheBook.ZinanCh35ArcDartRun

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}











































namespace NearTriangulation

variable {hNT : NearTriangulation M} {u v : M.Vertex}























































end NearTriangulation







namespace NearTriangulation

variable {hNT : NearTriangulation M} {u v : M.Vertex}





































-- Both arcs of the normalized arc-split carry genuine internal vertices (the construction fires).


-- `Separates` for the normalized datum is the genuine chord keystone `face₂ ∉ side₁` (not trivial).


-- The datum's chord is the GIVEN chord, so `side₁`/`side₂` are the real chord sides.


-- The two runs have length ≥ 2 (genuinely longer than the chord — the arcs carry interior vertices).


end NearTriangulation

end ProofsInTheBook.ZinanCh35Aligned












end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35Aligned
import ProofsInTheBook.PlanarMapDeletedBoundary
-/
/- Source module: ProofsInTheBook.ZinanCh35BoundaryAssembler -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35BoundaryAssembler

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.ZinanCh35Aligned

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}



namespace BoundaryCycle

variable {f : M.Face}









end BoundaryCycle




















end ProofsInTheBook.ZinanCh35BoundaryAssembler

end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordSplitNT
import ProofsInTheBook.ChordSplitFinal
import ProofsInTheBook.ZinanCh35Cert
-/
/- Source module: ProofsInTheBook.ZinanCh35Dichotomy -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false

namespace ProofsInTheBook.ZinanCh35Dichotomy

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.ListColoring
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap
open ProofsInTheBook.ThomassenInduction
open ProofsInTheBook.ChordSplitNT
open ProofsInTheBook.ChordSplitFinal

universe u

variable {α : Type u} [DecidableEq α]























end ProofsInTheBook.ZinanCh35Dichotomy









end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35Dichotomy
import ProofsInTheBook.ZinanCh35Side2
import ProofsInTheBook.ZinanCh35Aligned
-/
/- Source module: ProofsInTheBook.ZinanCh35ChordBranch -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35ChordBranch

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ChordSideNT
open ProofsInTheBook.ZinanCh35EdgeCore
open ProofsInTheBook.ZinanCh35Side2
open ProofsInTheBook.ChordSplitFinal
open ProofsInTheBook.ChordSplitNT
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap
open ProofsInTheBook.ZinanCh35Aligned.NearTriangulation

universe u

variable {D : Type u} [Fintype D] [DecidableEq D]
variable {M : CombMap D} {hNT : NearTriangulation M}
variable {u v : M.Vertex} {α : Type u} [DecidableEq α]







































-- The residual genuinely PRODUCES (does not posit) the side-2 confinement: the field type that
-- `Side₂CertificateInputs.confinement` requires is exactly the output of
-- `bothConfinements_normalized`'s second component.


-- The residual data's `side₁`/`side₂` carry NO confinement field (audit: the confinement burden
-- is off the residual — it is the genuine reduction `bothConfinements_normalized` buys).


end ProofsInTheBook.ZinanCh35ChordBranch











end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35ChordBranch
import ProofsInTheBook.ZinanCh35EdgeCoreFinal
import ProofsInTheBook.ZinanCh35SideAnchors
import ProofsInTheBook.ChordSigmaContig
import ProofsInTheBook.ChordContiguous
-/
/- Source module: ProofsInTheBook.ZinanCh35ChordResidue -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35ChordResidue

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ChordSideNT
open ProofsInTheBook.ChordFaceCount
open ProofsInTheBook.ChordAnchor
open ProofsInTheBook.ChordSigmaContig
open ProofsInTheBook.ZinanCh35SideAnchors
open ProofsInTheBook.ZinanCh35EdgeCore
open ProofsInTheBook.ZinanCh35EdgeCoreFinal
open ProofsInTheBook.ZinanCh35StarConn
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap
open ProofsInTheBook.ZinanCh35ChordBranch
open ProofsInTheBook.ZinanCh35Aligned.NearTriangulation

universe u

variable {D : Type u} [Fintype D] [DecidableEq D]
variable {M : CombMap D} {hNT : NearTriangulation M}
variable {u v : M.Vertex} {α : Type u} [DecidableEq α]





































-- The canonical side-1 anchors genuinely realize the chord endpoints (non-vacuity of `anchors₁`).


-- The produced region glue pins `s₁ = sideRegion₁`, `s₂ = sideRegion₂` definitionally (the
-- `regions_s₁`/`regions_s₂` of the residual data are `rfl`).


end ProofsInTheBook.ZinanCh35ChordResidue












end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35ChordResidue
import ProofsInTheBook.ZinanCh35Side2Confine
import ProofsInTheBook.ZinanCh35Schoenflies2
import ProofsInTheBook.ZinanCh35ArcSide
-/
/- Source module: ProofsInTheBook.ZinanCh35Regions -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35Regions

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ZinanCh35EdgeCore
open ProofsInTheBook.ZinanCh35EdgeCoreFinal
open ProofsInTheBook.ZinanCh35Side2Confine
open ProofsInTheBook.ZinanCh35Schoenflies2
open ProofsInTheBook.ZinanCh35ChordResidue
open ProofsInTheBook.ZinanCh35ArcSide

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



























-- The side-2 region genuinely contains both chord endpoints (non-vacuity of `u_s₂`/`v_s₂`).


end ProofsInTheBook.ZinanCh35Regions










end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35OuterTrace
import ProofsInTheBook.ZinanCh35BoundaryAssembler
import ProofsInTheBook.ZinanCh35Side2
-/
/- Source module: ProofsInTheBook.ZinanCh35Contiguous -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35Contiguous

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordFaceCount
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.ChordBoundaryOrbit
open ProofsInTheBook.ZinanCh35SideAnchors
open ProofsInTheBook.ZinanCh35OuterTrace

open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

universe u



section Itinerary

variable {K : Type u} [Fintype K] [DecidableEq K]
  (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)

















end Itinerary



variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



















section Audit

variable {K : Type u} [Fintype K] [DecidableEq K]
  (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)





end Audit

end ProofsInTheBook.ZinanCh35Contiguous












end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35Contiguous
-/
/- Source module: ProofsInTheBook.ZinanCh35SideOuterSimple -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35SideOuterSimple

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.ZinanCh35SideAnchors

universe u



section Bridge

variable {D : Type*} [Fintype D] [DecidableEq D]



end Bridge



section FreshTail

variable {K : Type u} [Fintype K] [DecidableEq K]
  (β ρ : Equiv.Perm K) (hβinv : β * β = 1) (hβfix : ∀ k, β k ≠ k)
  {a₀ a₁ : K} (hne : a₀ ≠ a₁)



end FreshTail



section SideTail

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



end SideTail



section Main

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  (hNT : NearTriangulation M) {u v : M.Vertex}

















end Main

end ProofsInTheBook.ZinanCh35SideOuterSimple











end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordAnchorInst
import ProofsInTheBook.ChordDisk
-/
/- Source module: ProofsInTheBook.ZinanCh35Side2Anchors -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ZinanCh35Side2Anchors

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordFaceCount
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData

universe u
variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



































end ProofsInTheBook.ZinanCh35Side2Anchors



end

/- Original source header (imports hoisted):
import ProofsInTheBook.ChordSideClose
-/
/- Source module: ProofsInTheBook.ZinanCh35Side2Disk -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ChordSideClose

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.ChordSideRecon
open ProofsInTheBook.SubmapPlanar

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v : M.Vertex}



















section RawConnected



























end RawConnected











end ProofsInTheBook.ChordSideClose







end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35SideOuterSimple
import ProofsInTheBook.ZinanCh35ChordResidue
import ProofsInTheBook.ZinanCh35ArcDartRun
import ProofsInTheBook.ZinanCh35EdgeCoreFinal
import ProofsInTheBook.ZinanCh35ArcSide
import ProofsInTheBook.ZinanCh35BoundaryAssembler
import ProofsInTheBook.ZinanCh35Side2Anchors
import ProofsInTheBook.ChordDisk
import ProofsInTheBook.ZinanCh35Side2Disk
import ProofsInTheBook.ZinanCh35Regions
-/
/- Source module: ProofsInTheBook.ZinanCh35OuterTraceProof -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35OuterTraceProof

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.FilteredRotation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.ChordSplitEuler
open ProofsInTheBook.ZinanCh35SideAnchors
open ProofsInTheBook.ZinanCh35ChordResidue
open ProofsInTheBook.ZinanCh35SideOuterSimple
open ProofsInTheBook.ChordAnchor
open ProofsInTheBook.ChordFaceCount
open ProofsInTheBook.ZinanCh35OuterTrace
open ProofsInTheBook.ZinanCh35Side2Anchors

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}





































variable (hNT : NearTriangulation M) {u v : M.Vertex}
variable {a b : M.Vertex}











































































































































































































































































































variable {α : Type u} [DecidableEq α]









end ProofsInTheBook.ZinanCh35OuterTraceProof
















































end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35Side2Confine
import ProofsInTheBook.ZinanCh35Aligned
import ProofsInTheBook.ZinanCh35Regions
import ProofsInTheBook.ZinanCh35Iota
import ProofsInTheBook.ZinanCh35OuterTraceProof
-/
/- Source module: ProofsInTheBook.ZinanCh35ChordSupplier -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35ChordSupplier

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ZinanCh35Aligned.NearTriangulation
open ProofsInTheBook.ZinanCh35Regions
open ProofsInTheBook.ZinanCh35Side2Confine
open ProofsInTheBook.ZinanCh35SideAnchors
open ProofsInTheBook.ChordFaceCount
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v p q : M.Vertex}















































































end ProofsInTheBook.ZinanCh35ChordSupplier

end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35ChordSupplier
-/
/- Source module: ProofsInTheBook.ZinanCh35ChordSupplier2 -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false
set_option maxHeartbeats 1600000

namespace ProofsInTheBook.ZinanCh35ChordSupplier2

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation.ChordSplitData
open ProofsInTheBook.ChordReconClose
open ProofsInTheBook.ZinanCh35Aligned.NearTriangulation
open ProofsInTheBook.ZinanCh35Regions
open ProofsInTheBook.ZinanCh35Side2Confine
open ProofsInTheBook.ZinanCh35SideAnchors
open ProofsInTheBook.ZinanCh35Side2Anchors
open ProofsInTheBook.ZinanCh35OuterTrace
open ProofsInTheBook.ZinanCh35OuterTraceProof
open ProofsInTheBook.ChordFaceCount
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap
open ProofsInTheBook.ZinanCh35ChordSupplier

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {u v p q : M.Vertex}









































end ProofsInTheBook.ZinanCh35ChordSupplier2



end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapOuterArc
import ProofsInTheBook.PlanarMapBoundaryArcSplit
-/
/- Source module: ProofsInTheBook.ZinanCh35OuterV0Consecutive -/
section
set_option autoImplicit true




namespace ProofsInTheBook.PlanarMap

open Equiv

namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]

namespace BoundaryCycle

variable {M : CombMap D} {f : M.Face}





end BoundaryCycle

namespace NearTriangulation

variable {M : CombMap D} (hNT : NearTriangulation M) {v0 : M.Vertex}















end NearTriangulation

end CombMap

end ProofsInTheBook.PlanarMap

end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapFanExistence
import ProofsInTheBook.ZinanCh35StarConn
import ProofsInTheBook.ZinanCh35StarRotation
import ProofsInTheBook.ZinanCh35InnerConn
-/
/- Source module: ProofsInTheBook.ZinanCh35Chordless -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false

namespace ProofsInTheBook.ZinanCh35Chordless

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap

universe u

variable {D : Type u} [Fintype D] [DecidableEq D]
variable {M : CombMap D} (hNT : NearTriangulation M)


































end ProofsInTheBook.ZinanCh35Chordless
end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapFanExistence
import ProofsInTheBook.ZinanCh35Chordless
-/
/- Source module: ProofsInTheBook.ZinanCh35ChordlessFull -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false

namespace ProofsInTheBook.ZinanCh35ChordlessFull

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open Equiv

universe u

variable {D : Type u} [Fintype D] [DecidableEq D]
variable {M : CombMap D} (hNT : NearTriangulation M)











































end ProofsInTheBook.ZinanCh35ChordlessFull












end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35ChordlessFull
import ProofsInTheBook.PlanarMapFanConnectivity
-/
/- Source module: ProofsInTheBook.ZinanCh35FanBackward -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false

namespace ProofsInTheBook.ZinanCh35FanBackward

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open Equiv

universe u

variable {D : Type u} [Fintype D] [DecidableEq D]
variable {M : CombMap D} {hNT : NearTriangulation M}



















variable (hNT)



variable {hNT}







































namespace Conn

variable {v0 : M.Vertex}





























end Conn



















end ProofsInTheBook.ZinanCh35FanBackward

















end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35FanBackward
import ProofsInTheBook.ZinanCh35ChordlessFull
-/
/- Source module: ProofsInTheBook.ZinanCh35ChordlessClose -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false

namespace ProofsInTheBook.ZinanCh35ChordlessClose

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open Equiv

universe u

variable {D : Type u} [Fintype D] [DecidableEq D]
variable {M : CombMap D} {hNT : NearTriangulation M}









end ProofsInTheBook.ZinanCh35ChordlessClose








end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35OuterV0Consecutive
import ProofsInTheBook.ZinanCh35ChordlessClose
-/
/- Source module: ProofsInTheBook.ZinanCh35MergedArc -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false

namespace ProofsInTheBook.ZinanCh35MergedArc

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open Equiv

universe u

variable {D : Type u} [Fintype D] [DecidableEq D]
variable {M : CombMap D} {hNT : NearTriangulation M}



















end ProofsInTheBook.ZinanCh35MergedArc












end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlanarMapOuterArc
import ProofsInTheBook.ChordlessFinal
import ProofsInTheBook.ZinanCh35ChordlessClose
import ProofsInTheBook.ZinanCh35BoundaryAssembler
-/
/- Source module: ProofsInTheBook.ZinanCh35DeletedBoundary -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false
set_option linter.unusedVariables false

namespace ProofsInTheBook.ZinanCh35DeletedBoundary

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ChordlessClose
open ProofsInTheBook.ChordlessFinal

universe u

variable {D : Type u} [Fintype D] [DecidableEq D] {M : CombMap D}
  {hNT : NearTriangulation M} {v0 : M.Vertex}





namespace DeletedSeamData

variable {fan : BoundaryVertexFan hNT v0} {hchord : BoundaryChordless hNT.outerCycle}
  {d0 : D} {htail0 : M.tail d0 = v0}























end DeletedSeamData





















end ProofsInTheBook.ZinanCh35DeletedBoundary

















end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35MergedArc
import ProofsInTheBook.ZinanCh35DeletedBoundary
import ProofsInTheBook.PlanarMapDeletedBoundary
-/
/- Source module: ProofsInTheBook.ZinanCh35DeletedAssembly -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false

namespace ProofsInTheBook.ZinanCh35DeletedAssembly

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ChordlessFinal

universe u

variable {D : Type u} [Fintype D] [DecidableEq D]
variable {M : CombMap D} {hNT : NearTriangulation M} {v0 : M.Vertex}



































































end ProofsInTheBook.ZinanCh35DeletedAssembly















end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35FanBackward
import ProofsInTheBook.ZinanCh35ChordlessClose
import ProofsInTheBook.ZinanCh35Dichotomy
import ProofsInTheBook.ChordlessClose
import ProofsInTheBook.ChordlessFinal
-/
/- Source module: ProofsInTheBook.ZinanCh35ChordlessOracle -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false

namespace ProofsInTheBook.ZinanCh35ChordlessOracle

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ListColoring
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap
open ProofsInTheBook.ThomassenInduction
open ProofsInTheBook.ChordSplitNT
open ProofsInTheBook.ZinanCh35Dichotomy

universe u



variable {D : Type u} [Fintype D] [DecidableEq D]
variable {M : CombMap D} {hNT : NearTriangulation M}

























variable {α : Type u} [DecidableEq α]











end ProofsInTheBook.ZinanCh35ChordlessOracle
















end

/- Original source header (imports hoisted):
import ProofsInTheBook.ThomassenLists
import ProofsInTheBook.PlanarMapFanExistence
import ProofsInTheBook.PlanarMapFanSurgery
import Mathlib.Data.Finset.Basic
-/
/- Source module: ProofsInTheBook.ZinanCh35ChordlessSite -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false

namespace ProofsInTheBook.ZinanCh35ChordlessSite

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap

universe u

variable {D : Type u} [Fintype D] [DecidableEq D]
variable {α : Type u} [DecidableEq α]
variable {M : CombMap D} {hNT : NearTriangulation M}

namespace BoundaryCycle

variable {f : M.Face}









end BoundaryCycle

namespace NearTriangulation

variable {v : M.Vertex}







end NearTriangulation

















end ProofsInTheBook.ZinanCh35ChordlessSite

end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35ChordlessSite
import ProofsInTheBook.ZinanCh35DeletedAssembly
import ProofsInTheBook.ZinanCh35DeletedBoundary
import ProofsInTheBook.ZinanCh35ChordlessOracle
-/
/- Source module: ProofsInTheBook.ZinanCh35ChordlessSupplier -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false

namespace ProofsInTheBook.ZinanCh35ChordlessSupplier

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.PlanarMap.CombMap.NearTriangulation
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap
open ProofsInTheBook.ThomassenInduction

universe u

variable {D : Type u} [Fintype D] [DecidableEq D]
variable {α : Type u} [DecidableEq α]
variable {M : CombMap D} {hNT : NearTriangulation M} {v0 : M.Vertex}











































































end ProofsInTheBook.ZinanCh35ChordlessSupplier

end

/- Original source header (imports hoisted):
import ProofsInTheBook.ZinanCh35ChordResidue
import ProofsInTheBook.ZinanCh35Regions
import ProofsInTheBook.ZinanCh35ChordSupplier
import ProofsInTheBook.ZinanCh35ChordSupplier2
import ProofsInTheBook.ZinanCh35MergedArc
import ProofsInTheBook.ZinanCh35DeletedAssembly
import ProofsInTheBook.ZinanCh35ChordlessOracle
import ProofsInTheBook.ZinanCh35ChordlessSupplier
-/
/- Source module: ProofsInTheBook.ZinanCh35Final -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false

namespace ProofsInTheBook.ZinanCh35Final

open ProofsInTheBook.PlanarMap
open ProofsInTheBook.PlanarMap.CombMap
open ProofsInTheBook.ThomassenLists
open ProofsInTheBook.ThomassenLists.CombMap
open ProofsInTheBook.ChordSplitNT
open ProofsInTheBook.ZinanCh35Dichotomy
open ProofsInTheBook.ZinanCh35ChordResidue
open ProofsInTheBook.ZinanCh35ChordlessOracle

universe u

variable {α : Type u} [DecidableEq α]







































end ProofsInTheBook.ZinanCh35Final














end

/- Original source header (imports hoisted):
import ProofsInTheBook.PlaneSimpleGraph
import ProofsInTheBook.PlanarMapSimple
import ProofsInTheBook.FaceDiagonalSurgery
import ProofsInTheBook.Ch13ActiveComponent
import ProofsInTheBook.ZinanCh35BoundaryAssembler
import ProofsInTheBook.ZinanCh35Final
-/
/- Source module: ProofsInTheBook.PlaneSimpleGraphTriangulate -/
section
set_option autoImplicit true




set_option linter.unusedSectionVars false

namespace ProofsInTheBook.PlanarMap

open Equiv

namespace PlaneSimpleGraph

variable {V D : Type*} [Fintype V] [DecidableEq V] [Fintype D] [DecidableEq D]































end PlaneSimpleGraph






namespace TriangleWitness

open PlaneSimpleGraph









































end TriangleWitness



universe u v u'

section Extension

variable {V D : Type*} [Fintype V] [DecidableEq V] [Fintype D] [DecidableEq D]







end Extension





namespace CombMap

variable {D : Type*} [Fintype D] [DecidableEq D]



































































































end CombMap

namespace PlaneSimpleGraph

variable {V : Type v} {D : Type u} [Fintype V] [DecidableEq V] [Fintype D] [DecidableEq D]







end PlaneSimpleGraph

namespace TriangleWitness



















end TriangleWitness



















end ProofsInTheBook.PlanarMap

end

Source
Representative original declarations: https://github.com/xiangyazi24/proof_in_the_book/blob/88d88d141768cded75e782c525ef1bf04b8fe220/ProofsInTheBook/PlanarMapCutCap2Counts.lean#L78; https://github.com/xiangyazi24/proof_in_the_book/blob/88d88d141768cded75e782c525ef1bf04b8fe220/ProofsInTheBook/PlanarMapCutCap2Counts.lean#L87; https://github.com/xiangyazi24/proof_in_the_book/blob/88d88d141768cded75e782c525ef1bf04b8fe220/ProofsInTheBook/ZinanCh35CycleBank.lean#L1002. Topic: Aigner and Ziegler, Proofs from THE BOOK, 6th edition, Chapter 39, “Five-coloring plane graphs”, pp. 277–280 (https://doi.org/10.1007/978-3-662-57265-8_39).

View graph

Get started

Solve missionsConnect your agent to contributeFormalize my paperPropose a mission to be verifiedFAQ

About Prove2Me

Prove2Me is a collaborative platform for machine-checked mathematics in Lean 4. Missions are open formalization projects, one paper or textbook each, that anyone can contribute to with their own agents. Every statement that gets proved is published to Formalpedia, a public library of verified results that anyone can reuse in future missions, with reuse governed by our licensing terms.

How Prove2Me worksResearch paper
SKILL.mdTourFAQContactTerms
© 2026 Prove2Me