Pith. sign in

IndisputableMonolith.Gravity.SevenGaps.Gap2GluingDerivation

IndisputableMonolith/Gravity/SevenGaps/Gap2GluingDerivation.lean · 2070 lines · 181 declarations

show as:
view math explainer →

open module explainer GitHub source

Explainer status: pending

   1import IndisputableMonolith.Gravity.SevenGaps.Gap2GaugeVolume
   2
   3/-!
   4# Gap 2: deriving the gluing law instead of assuming it
   5
   6`Gap2GaugeVolume` §6d proves that a gluing law forces the inverse factorial and
   7hence implies the gauge-counting principle.  The gluing law was assumed there.
   8This module attempts to derive it, following the route the 2026-07-28 adversarial
   9panel's judge selected as the only candidate that closes rather than relocates.
  10
  11The route needs a disjoint union on the carrier, which `MeasureInvarianceNoGo`
  12explicitly records as missing ("the existing `BoundedComplex` machinery carries no
  13disjoint-union operation to state it against").  §1 supplies it.
  14
  15## The shape of the derivation
  16
  17Two premises, neither mentioning `mu`, `Aut`, factorials, or the counting
  18principle:
  19
  20* **(i) size-blindness**: the labeled weight depends only on the three index
  21  sizes.  This, and not independence, is what excludes the known decoy
  22  `1/orbitCard`, whose class mass is identically one and is therefore trivially
  23  multiplicative.
  24* **(ii) gluing multiplicativity**: class mass multiplies over disjoint unions.
  25
  26Given those, the *orbit counts* supply a binomial interleaving factor on their
  27own, and cancelling them turns (ii) into the three-variable shuffle identity,
  28whose solutions are `f(a,b,c) = x^a y^b z^c / (a! b! c!)`.  So the premise is
  29reduced from a normalization to a locality statement plus three couplings.
  30-/
  31
  32namespace IndisputableMonolith
  33namespace Gravity
  34namespace SevenGaps
  35namespace Gap2GluingDerivation
  36
  37open PathSumMeasure ExactShellGaugePreflight Gap2GaugeVolume
  38
  39/-! ## §1. Disjoint union on the carrier
  40
  41The union of a `BoundedComplex B` and a `BoundedComplex B'` lives at cap `B + B'`.
  42Index sets add, and the incidence maps are the two originals pushed into the two
  43halves of the summed index sets by `finSumFinEquiv`. -/
  44
  45/-- Push a vertex of the left summand into the union's vertex set. -/
  46abbrev inlV {m n : ℕ} (i : Fin m) : Fin (m + n) := finSumFinEquiv (Sum.inl i)
  47
  48/-- Push a vertex of the right summand into the union's vertex set. -/
  49abbrev inrV {m n : ℕ} (i : Fin n) : Fin (m + n) := finSumFinEquiv (Sum.inr i)
  50
  51/-- The **disjoint union** of two bounded complexes, at the summed cap. -/
  52def dunion {B B' : ℕ} (K : BoundedComplex B) (L : BoundedComplex B') :
  53    BoundedComplex (B + B') where
  54  nV := K.nV + L.nV
  55  nE := K.nE + L.nE
  56  nT := K.nT + L.nT
  57  hV := Nat.add_le_add K.hV L.hV
  58  hE := Nat.add_le_add K.hE L.hE
  59  hT := Nat.add_le_add K.hT L.hT
  60  edgeVerts := fun e =>
  61    Sum.elim
  62      (fun e' : Fin K.nE => (inlV (K.edgeVerts e').1, inlV (K.edgeVerts e').2))
  63      (fun e' : Fin L.nE => (inrV (L.edgeVerts e').1, inrV (L.edgeVerts e').2))
  64      (finSumFinEquiv.symm e)
  65  tetVerts := fun t i =>
  66    Sum.elim
  67      (fun t' : Fin K.nT => inlV (K.tetVerts t' i))
  68      (fun t' : Fin L.nT => inrV (L.tetVerts t' i))
  69      (finSumFinEquiv.symm t)
  70
  71@[simp] theorem dunion_nV {B B' : ℕ} (K : BoundedComplex B) (L : BoundedComplex B') :
  72    (dunion K L).nV = K.nV + L.nV := rfl
  73
  74@[simp] theorem dunion_nE {B B' : ℕ} (K : BoundedComplex B) (L : BoundedComplex B') :
  75    (dunion K L).nE = K.nE + L.nE := rfl
  76
  77@[simp] theorem dunion_nT {B B' : ℕ} (K : BoundedComplex B) (L : BoundedComplex B') :
  78    (dunion K L).nT = K.nT + L.nT := rfl
  79
  80/-! ## §2. The gauge volume of a union, and where the binomial comes from
  81
  82This is pure factorial arithmetic and it is the reason the interleaving count is
  83binomial: the gauge volume of the union exceeds the product of the parts' gauge
  84volumes by exactly the three binomial coefficients counting how the label blocks
  85can be interleaved. -/
  86
  87/-- The three-way interleaving count for a pair of size triples. -/
  88def interleave (a b c a' b' c' : ℕ) : ℕ :=
  89  Nat.choose (a + a') a * (Nat.choose (b + b') b * Nat.choose (c + c') c)
  90
  91/-- The gauge volume of a size triple. -/
  92def gaugeVol (a b c : ℕ) : ℕ :=
  93  Nat.factorial a * (Nat.factorial b * Nat.factorial c)
  94
  95/-- **THEOREM (the interleaving count is binomial).**  The gauge volume of a sum
  96of size triples is the interleaving count times the product of the parts' gauge
  97volumes.  Pure arithmetic, no complexes involved. -/
  98theorem gaugeVol_add (a b c a' b' c' : ℕ) :
  99    gaugeVol (a + a') (b + b') (c + c')
 100      = interleave a b c a' b' c' * (gaugeVol a b c * gaugeVol a' b' c') := by
 101  have key : ∀ m n : ℕ,
 102      Nat.factorial (m + n)
 103        = Nat.choose (m + n) m * (Nat.factorial m * Nat.factorial n) := by
 104    intro m n
 105    have h := Nat.choose_mul_factorial_mul_factorial (Nat.le_add_right m n)
 106    have hsub : m + n - m = n := Nat.add_sub_cancel_left m n
 107    rw [hsub] at h
 108    rw [← h, mul_assoc]
 109  unfold gaugeVol interleave
 110  rw [key a a', key b b', key c c']
 111  ring
 112
 113/-- The gauge volume of a union, in the module's own terms. -/
 114theorem gaugeVol_dunion {B B' : ℕ} (K : BoundedComplex B) (L : BoundedComplex B') :
 115    gaugeVol (dunion K L).nV (dunion K L).nE (dunion K L).nT
 116      = interleave K.nV K.nE K.nT L.nV L.nE L.nT
 117        * (gaugeVol K.nV K.nE K.nT * gaugeVol L.nV L.nE L.nT) := by
 118  simp only [dunion_nV, dunion_nE, dunion_nT]
 119  exact gaugeVol_add _ _ _ _ _ _
 120
 121/-- `pairCount` is the gauge volume of the index sizes, in the notation of this
 122module. -/
 123theorem pairCount_eq_gaugeVol {B : ℕ} (K : BoundedComplex B) :
 124    pairCount K = gaugeVol K.nV K.nE K.nT :=
 125  pairCount_eq_factorials K
 126
 127/-- The interleaving count is positive. -/
 128theorem interleave_pos (a b c a' b' c' : ℕ) : 0 < interleave a b c a' b' c' := by
 129  unfold interleave
 130  have h1 : 0 < Nat.choose (a + a') a := Nat.choose_pos (Nat.le_add_right a a')
 131  have h2 : 0 < Nat.choose (b + b') b := Nat.choose_pos (Nat.le_add_right b b')
 132  have h3 : 0 < Nat.choose (c + c') c := Nat.choose_pos (Nat.le_add_right c c')
 133  positivity
 134
 135/-- The gauge volume is positive. -/
 136theorem gaugeVol_pos (a b c : ℕ) : 0 < gaugeVol a b c := by
 137  unfold gaugeVol
 138  have := Nat.factorial_pos a
 139  have := Nat.factorial_pos b
 140  have := Nat.factorial_pos c
 141  positivity
 142
 143/-! ## §3. Dust, and the refutation of unrestricted gluing multiplicativity
 144
 145Before using premise (ii) it must be checked against the intended answer.  It
 146fails.  `dust n` is `n` isolated vertices; its automorphism group is the full
 147symmetric group, so `mu (dust n) = 1/n!`, while dust glues to dust.  Unrestricted
 148multiplicativity would demand `1/(a+b)! = 1/a! · 1/b!`, which is false as soon as
 149both parts are nonempty.  So premise (ii) is not a free lunch: it must carry a
 150side condition excluding repeated isomorphic pieces, and that side condition is
 151mandatory rather than a convenience. -/
 152
 153/-- `n` isolated vertices: no edges, no tetrahedra. -/
 154def dust (n : ℕ) : BoundedComplex n where
 155  nV := n
 156  nE := 0
 157  nT := 0
 158  hV := le_refl n
 159  hE := Nat.zero_le n
 160  hT := Nat.zero_le n
 161  edgeVerts := Fin.elim0
 162  tetVerts := Fin.elim0
 163
 164@[simp] theorem dust_nV (n : ℕ) : (dust n).nV = n := rfl
 165@[simp] theorem dust_nE (n : ℕ) : (dust n).nE = 0 := rfl
 166@[simp] theorem dust_nT (n : ℕ) : (dust n).nT = 0 := rfl
 167
 168/-- **The automorphism group of dust is the full symmetric group.**  With no
 169incidence data, both commutation conditions are vacuous, so every vertex
 170permutation is an automorphism. -/
 171def autDustEquiv (n : ℕ) : Aut (dust n) ≃ Equiv.Perm (Fin n) where
 172  toFun := fun r => r.vEquiv
 173  invFun := fun v =>
 174    { vEquiv := v
 175      eEquiv := Equiv.refl _
 176      tEquiv := Equiv.refl _
 177      edge_comm := fun e => Fin.elim0 e
 178      tet_comm := fun t _ => Fin.elim0 t }
 179  left_inv := by
 180    intro r
 181    have he : r.eEquiv = Equiv.refl (Fin (dust n).nE) := Equiv.ext fun e => Fin.elim0 e
 182    have ht : r.tEquiv = Equiv.refl (Fin (dust n).nT) := Equiv.ext fun t => Fin.elim0 t
 183    cases r
 184    simp_all
 185  right_inv := by intro v; rfl
 186
 187/-- `|Aut (dust n)| = n!`. -/
 188theorem autCard_dust (n : ℕ) : Nat.card (Aut (dust n)) = Nat.factorial n := by
 189  rw [Nat.card_congr (autDustEquiv n), Nat.card_eq_fintype_card, Fintype.card_perm,
 190    Fintype.card_fin]
 191
 192/-- The RS measure on dust is the reciprocal factorial. -/
 193theorem mu_dust (n : ℕ) : mu (dust n) = 1 / (Nat.factorial n : ℝ) := by
 194  unfold mu
 195  rw [autCard_dust]
 196
 197/-- Dust glues to dust: the union of `a` and `b` isolated vertices is `a + b`
 198isolated vertices. -/
 199def dunionDustRelabel (a b : ℕ) : Relabel (dunion (dust a) (dust b)) (dust (a + b)) where
 200  vEquiv := Equiv.refl _
 201  eEquiv := Equiv.refl _
 202  tEquiv := Equiv.refl _
 203  edge_comm := fun e => Fin.elim0 e
 204  tet_comm := fun t _ => Fin.elim0 t
 205
 206theorem dunion_dust_equivalent (a b : ℕ) :
 207    Equivalent (dunion (dust a) (dust b)) (dust (a + b)) :=
 208  ⟨dunionDustRelabel a b⟩
 209
 210/-- **THEOREM (unrestricted gluing multiplicativity is FALSE).**  There is no
 211version of premise (ii) that applies to every disjoint union, because the
 212intended answer `mu` itself violates it.  Witness: one vertex glued to one
 213vertex.  `mu` of the union is `1/2`; the product of the parts' `mu` is `1`. -/
 214theorem unrestricted_gluing_multiplicativity_false :
 215    ¬ (∀ (B B' : ℕ) (K : BoundedComplex B) (L : BoundedComplex B'),
 216        mu (dunion K L) = mu K * mu L) := by
 217  intro h
 218  have hd := h 1 1 (dust 1) (dust 1)
 219  rw [mu_congr (dunion_dust_equivalent 1 1)] at hd
 220  rw [mu_dust, mu_dust] at hd
 221  norm_num at hd
 222
 223/-- The same failure, quantified: `mu` of a dust union undershoots the product of
 224the parts by exactly the interleaving count, which is the binomial coefficient.
 225This is the extra symmetry that repeated isomorphic pieces create. -/
 226theorem mu_dust_union_off_by_binomial (a b : ℕ) :
 227    mu (dunion (dust a) (dust b)) * (Nat.choose (a + b) a : ℝ)
 228      = mu (dust a) * mu (dust b) := by
 229  rw [mu_congr (dunion_dust_equivalent a b), mu_dust, mu_dust, mu_dust]
 230  have hfac : (Nat.factorial (a + b) : ℝ)
 231      = (Nat.choose (a + b) a : ℝ) * ((Nat.factorial a : ℝ) * (Nat.factorial b : ℝ)) := by
 232    have h := Nat.choose_mul_factorial_mul_factorial (Nat.le_add_right a b)
 233    have hsub : a + b - a = b := Nat.add_sub_cancel_left a b
 234    rw [hsub] at h
 235    have : ((Nat.choose (a + b) a * Nat.factorial a * Nat.factorial b : ℕ) : ℝ)
 236        = ((Nat.factorial (a + b) : ℕ) : ℝ) := by exact_mod_cast h
 237    push_cast at this
 238    linarith [this]
 239  rw [hfac]
 240  have hca : (0 : ℝ) < (Nat.choose (a + b) a : ℝ) := by
 241    have := Nat.choose_pos (Nat.le_add_right a b)
 242    exact_mod_cast this
 243  have ha : (0 : ℝ) < (Nat.factorial a : ℝ) := by
 244    have := Nat.factorial_pos a; exact_mod_cast this
 245  have hb : (0 : ℝ) < (Nat.factorial b : ℝ) := by
 246    have := Nat.factorial_pos b; exact_mod_cast this
 247  field_simp
 248
 249/-! ## §4. What the interleaving count is, at the level of orbit counts
 250
 251Kill condition 1 of the pre-registered gate asks whether the interleaving count is
 252binomial.  §2 settles that for the gauge volume unconditionally.  Transporting it
 253to orbit counts costs exactly one thing: multiplicativity of the automorphism
 254count.  This section proves the transport, so the residue is isolated to a single
 255identity about `Aut`. -/
 256
 257/-- **THEOREM (the interleaving count is binomial, given `Aut` multiplicativity).**
 258If the automorphism count multiplies over a union, the orbit counts satisfy the
 259binomial interleaving identity.  No other hypothesis. -/
 260theorem orbitCard_dunion_of_autMul {B B' : ℕ}
 261    (K : BoundedComplex B) (L : BoundedComplex B')
 262    (haut : Nat.card (Aut (dunion K L)) = Nat.card (Aut K) * Nat.card (Aut L)) :
 263    gaugeOrbitCard (dunion K L)
 264      = interleave K.nV K.nE K.nT L.nV L.nE L.nT
 265        * (gaugeOrbitCard K * gaugeOrbitCard L) := by
 266  have hU : pairCount (dunion K L)
 267      = gaugeOrbitCard (dunion K L) * Nat.card (Aut (dunion K L)) :=
 268    pairCount_eq_orbitCard_mul_autCard _
 269  have hK : pairCount K = gaugeOrbitCard K * Nat.card (Aut K) :=
 270    pairCount_eq_orbitCard_mul_autCard _
 271  have hL : pairCount L = gaugeOrbitCard L * Nat.card (Aut L) :=
 272    pairCount_eq_orbitCard_mul_autCard _
 273  have hvol : pairCount (dunion K L)
 274      = interleave K.nV K.nE K.nT L.nV L.nE L.nT * (pairCount K * pairCount L) := by
 275    rw [pairCount_eq_gaugeVol, pairCount_eq_gaugeVol, pairCount_eq_gaugeVol]
 276    exact gaugeVol_dunion K L
 277  rw [hU, haut, hK, hL] at hvol
 278  have hpos : 0 < Nat.card (Aut K) * Nat.card (Aut L) :=
 279    Nat.mul_pos (autCard_pos K) (autCard_pos L)
 280  have hcancel : gaugeOrbitCard (dunion K L) * (Nat.card (Aut K) * Nat.card (Aut L))
 281      = (interleave K.nV K.nE K.nT L.nV L.nE L.nT
 282          * (gaugeOrbitCard K * gaugeOrbitCard L))
 283        * (Nat.card (Aut K) * Nat.card (Aut L)) := by
 284    rw [hvol]; ring
 285  exact Nat.eq_of_mul_eq_mul_right hpos hcancel
 286
 287/-! ## §5. Premise (i): size-blindness, and the transport to a shuffle identity -/
 288
 289/-- **Premise (i), size-blindness.**  A single function of the three index sizes,
 290used as the labeled weight at every cap.  Nothing here mentions `mu`, `Aut`,
 291factorials, or the counting principle. -/
 292def sizeWeight (f : ℕ → ℕ → ℕ → ℝ) {B : ℕ} (K : BoundedComplex B) : ℝ :=
 293  f K.nV K.nE K.nT
 294
 295/-- A size-blind weight is relabeling-invariant, since a relabeling preserves the
 296three index sizes. -/
 297theorem sizeWeight_invariant (f : ℕ → ℕ → ℕ → ℝ) {B : ℕ} {K K' : BoundedComplex B}
 298    (h : Equivalent K K') : sizeWeight f K = sizeWeight f K' := by
 299  obtain ⟨r⟩ := h
 300  unfold sizeWeight
 301  rw [size_v r, size_e r, size_t r]
 302
 303/-- The class mass of a size-blind weight is the orbit count times the size value.
 304This is where the orbit counts enter, and they are the only thing that does. -/
 305theorem classMass_sizeWeight (f : ℕ → ℕ → ℕ → ℝ) {B : ℕ} (K : BoundedComplex B) :
 306    classMass (sizeWeight f) (Quotient.mk (relabelSetoid B) K)
 307      = (gaugeOrbitCard K : ℝ) * f K.nV K.nE K.nT := by
 308  rw [classMass_of_invariant _ (fun _ _ h => sizeWeight_invariant f h)]
 309  have hout : sizeWeight f (Quotient.out (Quotient.mk (relabelSetoid B) K))
 310      = sizeWeight f K :=
 311    sizeWeight_invariant f (equivalent_out K)
 312  rw [hout, orbitCardClass_mk]
 313  rfl
 314
 315/-- **Premise (ii), gluing multiplicativity, at one pair.**  The class mass of a
 316union is the product of the parts' class masses.  Stated with no reference to
 317`mu`, `Aut`, factorials, the gauge volume, or the counting principle: only the
 318class mass of the size-blind weight and the disjoint union. -/
 319def GluesAt (f : ℕ → ℕ → ℕ → ℝ) {B B' : ℕ}
 320    (K : BoundedComplex B) (L : BoundedComplex B') : Prop :=
 321  classMass (sizeWeight f) (Quotient.mk (relabelSetoid (B + B')) (dunion K L))
 322    = classMass (sizeWeight f) (Quotient.mk (relabelSetoid B) K)
 323      * classMass (sizeWeight f) (Quotient.mk (relabelSetoid B') L)
 324
 325/-- **THEOREM (the transport).**  At any pair where the automorphism count
 326multiplies, premise (ii) for a size-blind weight is *exactly* the shuffle identity
 327on the size function.  The orbit counts cancel; their entire contribution is the
 328binomial interleaving factor.  This is the step that converts a locality premise
 329into a normalization identity, and it is where the compiled arithmetic of §2 and
 330§4 is spent. -/
 331theorem shuffle_of_gluesAt (f : ℕ → ℕ → ℕ → ℝ) {B B' : ℕ}
 332    (K : BoundedComplex B) (L : BoundedComplex B')
 333    (haut : Nat.card (Aut (dunion K L)) = Nat.card (Aut K) * Nat.card (Aut L))
 334    (hglue : GluesAt f K L) :
 335    f (K.nV + L.nV) (K.nE + L.nE) (K.nT + L.nT)
 336        * (interleave K.nV K.nE K.nT L.nV L.nE L.nT : ℝ)
 337      = f K.nV K.nE K.nT * f L.nV L.nE L.nT := by
 338  have hob := orbitCard_dunion_of_autMul K L haut
 339  unfold GluesAt at hglue
 340  rw [classMass_sizeWeight, classMass_sizeWeight, classMass_sizeWeight] at hglue
 341  simp only [dunion_nV, dunion_nE, dunion_nT] at hglue
 342  rw [hob] at hglue
 343  push_cast at hglue
 344  have hK : (0 : ℝ) < (gaugeOrbitCard K : ℝ) := by
 345    exact_mod_cast gaugeOrbitCard_pos K
 346  have hL : (0 : ℝ) < (gaugeOrbitCard L : ℝ) := by
 347    exact_mod_cast gaugeOrbitCard_pos L
 348  have hprod : (gaugeOrbitCard K : ℝ) * (gaugeOrbitCard L : ℝ) ≠ 0 :=
 349    (mul_pos hK hL).ne'
 350  refine mul_right_cancel₀ hprod ?_
 351  calc f (K.nV + L.nV) (K.nE + L.nE) (K.nT + L.nT)
 352        * (interleave K.nV K.nE K.nT L.nV L.nE L.nT : ℝ)
 353        * ((gaugeOrbitCard K : ℝ) * (gaugeOrbitCard L : ℝ))
 354      = (interleave K.nV K.nE K.nT L.nV L.nE L.nT : ℝ)
 355          * ((gaugeOrbitCard K : ℝ) * (gaugeOrbitCard L : ℝ))
 356          * f (K.nV + L.nV) (K.nE + L.nE) (K.nT + L.nT) := by ring
 357    _ = (gaugeOrbitCard K : ℝ) * f K.nV K.nE K.nT
 358          * ((gaugeOrbitCard L : ℝ) * f L.nV L.nE L.nT) := hglue
 359    _ = f K.nV K.nE K.nT * f L.nV L.nE L.nT
 360          * ((gaugeOrbitCard K : ℝ) * (gaugeOrbitCard L : ℝ)) := by ring
 361
 362/-! ## §6. What the two premises force
 363
 364The premise supplies the shuffle identity only at pairs the carrier can realize
 365with non-mixing automorphisms.  §3 proves this restriction is mandatory.  Four
 366families suffice, and each is a union of two complexes sharing no isomorphic
 367component:
 368
 369* `dust a` glued to a **bouquet**: one vertex carrying `b` loops and `c`
 370  degenerate tetrahedra, with at least one incidence.  The bouquet vertex has an
 371  incidence and the dust vertices do not, so no automorphism exchanges them.
 372* `dust a` glued to a single **edge**.
 373* a bouquet glued to a single **edge** (one vertex versus two).
 374* a bouquet glued to a single **tetrahedron** (one vertex versus four).
 375
 376Nothing below mentions `mu`, `Aut`, factorials, or the counting principle: the
 377input is four instances of premise (ii) transported through
 378`shuffle_of_gluesAt`. -/
 379
 380/-- Two times a middle binomial, in closed form.  Needed because the dust-edge
 381instance carries `C(a+2, a)` rather than a linear factor. -/
 382theorem two_mul_choose (a : ℕ) : 2 * Nat.choose (a + 2) a = (a + 2) * (a + 1) := by
 383  have h := Nat.choose_mul_factorial_mul_factorial (show a ≤ a + 2 by omega)
 384  have h2 : a + 2 - a = 2 := by omega
 385  rw [h2] at h
 386  have hf : Nat.factorial (a + 2) = (a + 2) * ((a + 1) * Nat.factorial a) := by
 387    rw [Nat.factorial_succ, Nat.factorial_succ]
 388  rw [hf] at h
 389  have hfac : Nat.factorial 2 = 2 := rfl
 390  rw [hfac] at h
 391  have hcancel : (2 * Nat.choose (a + 2) a) * Nat.factorial a
 392      = ((a + 2) * (a + 1)) * Nat.factorial a := by
 393    calc (2 * Nat.choose (a + 2) a) * Nat.factorial a
 394        = Nat.choose (a + 2) a * Nat.factorial a * 2 := by ring
 395      _ = (a + 2) * ((a + 1) * Nat.factorial a) := h
 396      _ = ((a + 2) * (a + 1)) * Nat.factorial a := by ring
 397  exact Nat.eq_of_mul_eq_mul_right (Nat.factorial_pos a) hcancel
 398
 399@[simp] theorem interleave_pt (a b c : ℕ) : interleave a 0 0 1 b c = a + 1 := by
 400  unfold interleave
 401  simp
 402
 403@[simp] theorem interleave_edge (a : ℕ) : interleave a 0 0 2 1 0 = Nat.choose (a + 2) a := by
 404  unfold interleave
 405  simp
 406
 407@[simp] theorem interleave_bqEdge (b c : ℕ) : interleave 1 b c 2 1 0 = 3 * (b + 1) := by
 408  unfold interleave
 409  simp [Nat.choose_one_right]
 410
 411@[simp] theorem interleave_bqTet (b c : ℕ) : interleave 1 b c 4 0 1 = 5 * (c + 1) := by
 412  unfold interleave
 413  simp [Nat.choose_one_right]
 414
 415/-- **The four gluing instances the carrier supplies**, written purely as
 416identities on the size function.  Each is premise (ii) at one family of pairs,
 417already transported through `shuffle_of_gluesAt`. -/
 418structure CarrierShuffle (f : ℕ → ℕ → ℕ → ℝ) : Prop where
 419  /-- A weight is a positive number. -/
 420  pos : ∀ a b c, 0 < f a b c
 421  /-- The empty complex has unit weight (the normalization of the sum). -/
 422  unit : f 0 0 0 = 1
 423  /-- `dust a ⊔ bouquet(b,c)`, the bouquet carrying at least one incidence. -/
 424  dust_bouquet : ∀ a b c, 1 ≤ b + c →
 425    f (a + 1) b c * (interleave a 0 0 1 b c : ℝ) = f a 0 0 * f 1 b c
 426  /-- `dust a ⊔ edge`. -/
 427  dust_edge : ∀ a,
 428    f (a + 2) 1 0 * (interleave a 0 0 2 1 0 : ℝ) = f a 0 0 * f 2 1 0
 429  /-- `bouquet(b,c) ⊔ edge`. -/
 430  bouquet_edge : ∀ b c,
 431    f 3 (b + 1) c * (interleave 1 b c 2 1 0 : ℝ) = f 1 b c * f 2 1 0
 432  /-- `bouquet(b,c) ⊔ tetrahedron`. -/
 433  bouquet_tet : ∀ b c,
 434    f 5 b (c + 1) * (interleave 1 b c 4 0 1 : ℝ) = f 1 b c * f 4 0 1
 435
 436namespace CarrierShuffle
 437
 438variable {f : ℕ → ℕ → ℕ → ℝ}
 439
 440/-- The single-edge weight, from the loop-plus-point realization of the same size
 441triple.  This is the step where size-blindness does real work: the size triple
 442`(2,1,0)` is realized both by the indecomposable edge and by the decomposable
 443`loop ⊔ point`, and premise (i) identifies them. -/
 444theorem edgeWeight (h : CarrierShuffle f) : f 2 1 0 * 2 = f 1 0 0 * f 1 1 0 := by
 445  have hd := h.dust_bouquet 1 1 0 (by omega)
 446  rw [interleave_pt] at hd
 447  push_cast at hd
 448  linarith [hd]
 449
 450/-- **The vertex recursion.**  Adding one isolated vertex divides the weight by the
 451new vertex count.  Derived from the dust-bouquet and dust-edge instances; the
 452binomial `C(a+2,a)` cancels against the linear factors. -/
 453theorem vertexRec (h : CarrierShuffle f) (a : ℕ) :
 454    f (a + 1) 0 0 * ((a : ℝ) + 1) = f a 0 0 * f 1 0 0 := by
 455  have hP1 := h.dust_bouquet (a + 1) 1 0 (by omega)
 456  rw [interleave_pt] at hP1
 457  have hQ := h.dust_edge a
 458  rw [interleave_edge] at hQ
 459  have hR := edgeWeight h
 460  have hC : (2 : ℝ) * (Nat.choose (a + 2) a : ℝ) = ((a : ℝ) + 2) * ((a : ℝ) + 1) := by
 461    have := two_mul_choose a
 462    have hcast : ((2 * Nat.choose (a + 2) a : ℕ) : ℝ) = (((a + 2) * (a + 1) : ℕ) : ℝ) := by
 463      exact_mod_cast congrArg (fun n : ℕ => (n : ℝ)) this
 464    push_cast at hcast
 465    linarith [hcast]
 466  push_cast at hP1
 467  have hq : f 1 1 0 ≠ 0 := (h.pos 1 1 0).ne'
 468  refine mul_right_cancel₀ hq ?_
 469  linear_combination (-((a : ℝ) + 1)) * hP1 + (-(f (a + 2) 1 0)) * hC + 2 * hQ
 470    + (f a 0 0) * hR
 471
 472/-- **The dust row.**  Iterating the vertex recursion: `f(a,0,0) · a! = x^a`. -/
 473theorem dustRow (h : CarrierShuffle f) (a : ℕ) :
 474    f a 0 0 * (Nat.factorial a : ℝ) = (f 1 0 0) ^ a := by
 475  induction a with
 476  | zero => simpa using h.unit
 477  | succ n ih =>
 478      have hv := vertexRec h n
 479      have hfac : (Nat.factorial (n + 1) : ℝ)
 480          = ((n : ℝ) + 1) * (Nat.factorial n : ℝ) := by
 481        rw [Nat.factorial_succ]; push_cast; ring
 482      calc f (n + 1) 0 0 * (Nat.factorial (n + 1) : ℝ)
 483          = (f (n + 1) 0 0 * ((n : ℝ) + 1)) * (Nat.factorial n : ℝ) := by
 484            rw [hfac]; ring
 485        _ = (f n 0 0 * f 1 0 0) * (Nat.factorial n : ℝ) := by rw [hv]
 486        _ = (f n 0 0 * (Nat.factorial n : ℝ)) * f 1 0 0 := by ring
 487        _ = (f 1 0 0) ^ n * f 1 0 0 := by rw [ih]
 488        _ = (f 1 0 0) ^ (n + 1) := by ring
 489
 490/-- **The edge recursion.**  Adding one loop to a bouquet divides by the new edge
 491count, with the edge fugacity `f(1,1,0)/f(1,0,0)` as the ratio. -/
 492theorem bRec (h : CarrierShuffle f) (b c : ℕ) :
 493    f 1 (b + 1) c * ((b : ℝ) + 1) * f 1 0 0 = f 1 b c * f 1 1 0 := by
 494  have hi := h.bouquet_edge b c
 495  rw [interleave_bqEdge] at hi
 496  have hii := h.dust_bouquet 2 (b + 1) c (by omega)
 497  rw [interleave_pt] at hii
 498  have hiii : f 2 0 0 * 2 = (f 1 0 0) ^ 2 := by
 499    have := dustRow h 2
 500    have hf2 : (Nat.factorial 2 : ℝ) = 2 := by norm_num [Nat.factorial]
 501    rw [hf2] at this
 502    linarith [this]
 503  have hiv := edgeWeight h
 504  push_cast at hi hii
 505  have hx : f 1 0 0 ≠ 0 := (h.pos 1 0 0).ne'
 506  refine mul_right_cancel₀ hx ?_
 507  linear_combination (-(f 1 (b + 1) c * ((b : ℝ) + 1))) * hiii
 508    + (-2 * ((b : ℝ) + 1)) * hii + 2 * hi + (f 1 b c) * hiv
 509
 510/-- The four-vertex tetrahedron weight, from the point-plus-tetrahedron
 511realization. -/
 512theorem tetWeight (h : CarrierShuffle f) : f 4 0 1 * 4 = f 3 0 0 * f 1 0 1 := by
 513  have hd := h.dust_bouquet 3 0 1 (by omega)
 514  rw [interleave_pt] at hd
 515  push_cast at hd
 516  linarith [hd]
 517
 518/-- **The tetrahedron recursion.**  Adding one degenerate tetrahedron to a bouquet
 519divides by the new tetrahedron count, with fugacity `f(1,0,1)/f(1,0,0)`. -/
 520theorem cRec (h : CarrierShuffle f) (b c : ℕ) :
 521    f 1 b (c + 1) * ((c : ℝ) + 1) * f 1 0 0 = f 1 b c * f 1 0 1 := by
 522  have hi := h.bouquet_tet b c
 523  rw [interleave_bqTet] at hi
 524  have hii := h.dust_bouquet 4 b (c + 1) (by omega)
 525  rw [interleave_pt] at hii
 526  have hiii := tetWeight h
 527  have hF3 : f 3 0 0 * 6 = (f 1 0 0) ^ 3 := by
 528    have := dustRow h 3
 529    have hf3 : (Nat.factorial 3 : ℝ) = 6 := by norm_num [Nat.factorial]
 530    rw [hf3] at this
 531    linarith [this]
 532  have hF4 : f 4 0 0 * 24 = (f 1 0 0) ^ 4 := by
 533    have := dustRow h 4
 534    have hf4 : (Nat.factorial 4 : ℝ) = 24 := by norm_num [Nat.factorial]
 535    rw [hf4] at this
 536    linarith [this]
 537  push_cast at hi hii
 538  have hx3 : (f 1 0 0) ^ 3 ≠ 0 := pow_ne_zero _ (h.pos 1 0 0).ne'
 539  refine mul_right_cancel₀ hx3 ?_
 540  linear_combination (-(f 1 b (c + 1) * ((c : ℝ) + 1))) * hF4
 541    + (-24 * ((c : ℝ) + 1)) * hii + 24 * hi + (6 * f 1 b c) * hiii
 542    + (f 1 b c * f 1 0 1) * hF3
 543
 544/-- The bouquet column: iterating the tetrahedron recursion at `b = 0`. -/
 545theorem bouquetTetCol (h : CarrierShuffle f) (c : ℕ) :
 546    f 1 0 c * (Nat.factorial c : ℝ) * (f 1 0 0) ^ c
 547      = f 1 0 0 * (f 1 0 1) ^ c := by
 548  induction c with
 549  | zero => simp
 550  | succ n ih =>
 551      have hc := cRec h 0 n
 552      have hfac : (Nat.factorial (n + 1) : ℝ)
 553          = ((n : ℝ) + 1) * (Nat.factorial n : ℝ) := by
 554        rw [Nat.factorial_succ]; push_cast; ring
 555      calc f 1 0 (n + 1) * (Nat.factorial (n + 1) : ℝ) * (f 1 0 0) ^ (n + 1)
 556          = (f 1 0 (n + 1) * ((n : ℝ) + 1) * f 1 0 0)
 557              * ((Nat.factorial n : ℝ) * (f 1 0 0) ^ n) := by
 558            rw [hfac]; ring
 559        _ = (f 1 0 n * f 1 0 1) * ((Nat.factorial n : ℝ) * (f 1 0 0) ^ n) := by rw [hc]
 560        _ = (f 1 0 n * (Nat.factorial n : ℝ) * (f 1 0 0) ^ n) * f 1 0 1 := by ring
 561        _ = (f 1 0 0 * (f 1 0 1) ^ n) * f 1 0 1 := by rw [ih]
 562        _ = f 1 0 0 * (f 1 0 1) ^ (n + 1) := by ring
 563
 564/-- **The bouquet weight in closed form.**  A one-vertex bouquet with `b` loops and
 565`c` degenerate tetrahedra: the two fugacities appear as powers over factorials. -/
 566theorem bouquetRow (h : CarrierShuffle f) (b c : ℕ) :
 567    f 1 b c * ((Nat.factorial b : ℝ) * (Nat.factorial c : ℝ))
 568        * (f 1 0 0) ^ (b + c)
 569      = f 1 0 0 * (f 1 1 0) ^ b * (f 1 0 1) ^ c := by
 570  induction b with
 571  | zero =>
 572      have hcol := bouquetTetCol h c
 573      simp only [Nat.factorial_zero, Nat.cast_one, one_mul, zero_add, pow_zero, mul_one]
 574      exact hcol
 575  | succ n ih =>
 576      have hb := bRec h n c
 577      have hfac : (Nat.factorial (n + 1) : ℝ)
 578          = ((n : ℝ) + 1) * (Nat.factorial n : ℝ) := by
 579        rw [Nat.factorial_succ]; push_cast; ring
 580      calc f 1 (n + 1) c * ((Nat.factorial (n + 1) : ℝ) * (Nat.factorial c : ℝ))
 581              * (f 1 0 0) ^ (n + 1 + c)
 582          = (f 1 (n + 1) c * ((n : ℝ) + 1) * f 1 0 0)
 583              * ((Nat.factorial n : ℝ) * (Nat.factorial c : ℝ) * (f 1 0 0) ^ (n + c)) := by
 584            rw [hfac]
 585            have : (f 1 0 0) ^ (n + 1 + c) = (f 1 0 0) ^ (n + c) * f 1 0 0 := by
 586              rw [show n + 1 + c = (n + c) + 1 by omega, pow_succ]
 587            rw [this]; ring
 588        _ = (f 1 n c * f 1 1 0)
 589              * ((Nat.factorial n : ℝ) * (Nat.factorial c : ℝ) * (f 1 0 0) ^ (n + c)) := by
 590            rw [hb]
 591        _ = (f 1 n c * ((Nat.factorial n : ℝ) * (Nat.factorial c : ℝ))
 592              * (f 1 0 0) ^ (n + c)) * f 1 1 0 := by ring
 593        _ = (f 1 0 0 * (f 1 1 0) ^ n * (f 1 0 1) ^ c) * f 1 1 0 := by rw [ih]
 594        _ = f 1 0 0 * (f 1 1 0) ^ (n + 1) * (f 1 0 1) ^ c := by ring
 595
 596/-- **THEOREM (the two premises determine the weight up to three constants).**
 597On every size triple the carrier can realize, the size-blind weight is the inverse
 598gauge volume times three fugacities: one per index type.  The infinite-dimensional
 599residue of `Gap2GaugeVolume` §6c (an arbitrary `a : ℕ³ → ℝ`) collapses to three
 600real numbers. -/
 601theorem closedForm (h : CarrierShuffle f) (a b c : ℕ) (ha : 1 ≤ a) :
 602    f a b c * ((Nat.factorial a : ℝ) * (Nat.factorial b : ℝ) * (Nat.factorial c : ℝ))
 603        * (f 1 0 0) ^ (b + c)
 604      = (f 1 0 0) ^ a * (f 1 1 0) ^ b * (f 1 0 1) ^ c := by
 605  obtain ⟨a', rfl⟩ : ∃ a', a = a' + 1 := ⟨a - 1, by omega⟩
 606  rcases Nat.eq_zero_or_pos (b + c) with hbc | hbc
 607  · -- No edges and no tetrahedra: the dust row already settles it.
 608    have hb : b = 0 := by omega
 609    have hc : c = 0 := by omega
 610    subst hb; subst hc
 611    have := dustRow h (a' + 1)
 612    simpa using this
 613  · -- At least one incidence: the dust-bouquet instance plus the bouquet row.
 614    have hd := h.dust_bouquet a' b c hbc
 615    rw [interleave_pt] at hd
 616    push_cast at hd
 617    have hrow := dustRow h a'
 618    have hbq := bouquetRow h b c
 619    have hfac : (Nat.factorial (a' + 1) : ℝ)
 620        = ((a' : ℝ) + 1) * (Nat.factorial a' : ℝ) := by
 621      rw [Nat.factorial_succ]; push_cast; ring
 622    have hx : f 1 0 0 ≠ 0 := (h.pos 1 0 0).ne'
 623    calc f (a' + 1) b c
 624            * ((Nat.factorial (a' + 1) : ℝ) * (Nat.factorial b : ℝ) * (Nat.factorial c : ℝ))
 625            * (f 1 0 0) ^ (b + c)
 626        = (f (a' + 1) b c * ((a' : ℝ) + 1)) * (Nat.factorial a' : ℝ)
 627            * (f 1 b c * ((Nat.factorial b : ℝ) * (Nat.factorial c : ℝ))
 628                * (f 1 0 0) ^ (b + c)) / f 1 b c := by
 629          rw [hfac]
 630          field_simp [(h.pos 1 b c).ne']
 631      _ = (f a' 0 0 * f 1 b c) * (Nat.factorial a' : ℝ)
 632            * (f 1 0 0 * (f 1 1 0) ^ b * (f 1 0 1) ^ c) / f 1 b c := by
 633          rw [hd, hbq]
 634      _ = (f a' 0 0 * (Nat.factorial a' : ℝ))
 635            * (f 1 0 0 * (f 1 1 0) ^ b * (f 1 0 1) ^ c) := by
 636          field_simp [(h.pos 1 b c).ne']
 637      _ = (f 1 0 0) ^ a' * (f 1 0 0 * (f 1 1 0) ^ b * (f 1 0 1) ^ c) := by rw [hrow]
 638      _ = (f 1 0 0) ^ (a' + 1) * (f 1 1 0) ^ b * (f 1 0 1) ^ c := by ring
 639
 640/-- **THEOREM (the Gibbs weight, from the two premises plus three unit
 641normalizations).**  If a single labeled vertex, a single labeled loop, and a
 642single labeled degenerate tetrahedron each carry unit weight, the size-blind
 643weight is forced to be the inverse gauge volume: exactly `gibbsWeight`.  By
 644`Gap2GaugeVolume.gibbsWeight_gives_gaugeCounting` the counting principle then
 645follows, so the measure is derived. -/
 646theorem gibbs_of_unit_fugacities (h : CarrierShuffle f) (hx : f 1 0 0 = 1) (hy : f 1 1 0 = 1)
 647    (hz : f 1 0 1 = 1) (a b c : ℕ) (ha : 1 ≤ a) :
 648    f a b c
 649      = 1 / ((Nat.factorial a : ℝ) * (Nat.factorial b : ℝ) * (Nat.factorial c : ℝ)) := by
 650  have hcf := closedForm h a b c ha
 651  rw [hx, hy, hz] at hcf
 652  simp only [one_pow, mul_one] at hcf
 653  have hpos : (0 : ℝ) < (Nat.factorial a : ℝ) * (Nat.factorial b : ℝ)
 654      * (Nat.factorial c : ℝ) := by
 655    have h1 : (0 : ℝ) < (Nat.factorial a : ℝ) := by
 656      have := Nat.factorial_pos a; exact_mod_cast this
 657    have h2 : (0 : ℝ) < (Nat.factorial b : ℝ) := by
 658      have := Nat.factorial_pos b; exact_mod_cast this
 659    have h3 : (0 : ℝ) < (Nat.factorial c : ℝ) := by
 660      have := Nat.factorial_pos c; exact_mod_cast this
 661    positivity
 662  field_simp at hcf ⊢
 663  linarith [hcf]
 664
 665end CarrierShuffle
 666
 667/-! ## §7. Availability: the gluing instances are not vacuous
 668
 669§6 assumes the four gluing instances.  They are legitimate only if the pairs
 670really do have multiplicative automorphism counts, since §4 shows that is what the
 671binomial interleaving needs and §3 shows it genuinely fails for repeated
 672isomorphic pieces.  This section compiles the check on a nontrivial slice of
 673family (a): `dust 1` glued to a bouquet with `b` loops and `c` degenerate
 674tetrahedra.  The automorphism groups involved have order `b! · c!`, so this is not
 675a rigid or trivial-group witness; it is unbounded in both index directions.
 676
 677The general theorem (parts sharing no isomorphic component have multiplicative
 678`Aut`) is not formalized here.  That is the remaining formalization debt and it is
 679recorded in the certificate rather than assumed away. -/
 680
 681/-- A **bouquet**: one vertex carrying `b` loops and `c` degenerate tetrahedra
 682(every corner of every tetrahedron at the same vertex). -/
 683def bouquet (b c : ℕ) : BoundedComplex (1 + b + c) where
 684  nV := 1
 685  nE := b
 686  nT := c
 687  hV := by omega
 688  hE := by omega
 689  hT := by omega
 690  edgeVerts := fun _ => (0, 0)
 691  tetVerts := fun _ _ => 0
 692
 693@[simp] theorem bouquet_nV (b c : ℕ) : (bouquet b c).nV = 1 := rfl
 694@[simp] theorem bouquet_nE (b c : ℕ) : (bouquet b c).nE = b := rfl
 695@[simp] theorem bouquet_nT (b c : ℕ) : (bouquet b c).nT = c := rfl
 696
 697/-- A **cone**: `a` isolated vertices plus one apex carrying `b` loops and `c`
 698degenerate tetrahedra.  The cap matches `dunion (dust a) (bouquet b c)` so the two
 699are comparable. -/
 700def cone (a b c : ℕ) : BoundedComplex (a + (1 + b + c)) where
 701  nV := a + 1
 702  nE := b
 703  nT := c
 704  hV := by omega
 705  hE := by omega
 706  hT := by omega
 707  edgeVerts := fun _ => (Fin.last a, Fin.last a)
 708  tetVerts := fun _ _ => Fin.last a
 709
 710@[simp] theorem cone_nV (a b c : ℕ) : (cone a b c).nV = a + 1 := rfl
 711@[simp] theorem cone_nE (a b c : ℕ) : (cone a b c).nE = b := rfl
 712@[simp] theorem cone_nT (a b c : ℕ) : (cone a b c).nT = c := rfl
 713
 714/-- The right-hand injection of the single bouquet vertex lands on the apex. -/
 715theorem inrV_zero (a : ℕ) : (inrV (0 : Fin 1) : Fin (a + 1)) = Fin.last a := by
 716  apply Fin.ext
 717  simp [inrV]
 718
 719/-- In a union whose left part has no edges, every edge comes from the right part.
 720Stated for a right part whose edges all sit on one vertex. -/
 721theorem dunion_dust_edgeVerts {B' : ℕ} (a : ℕ) (L : BoundedComplex B') (v : Fin L.nV)
 722    (hL : ∀ e, L.edgeVerts e = (v, v)) (e : Fin (dunion (dust a) L).nE) :
 723    (dunion (dust a) L).edgeVerts e
 724      = ((inrV v : Fin (a + L.nV)), (inrV v : Fin (a + L.nV))) := by
 725  simp only [dunion]
 726  cases hsum : finSumFinEquiv.symm e with
 727  | inl i => exact Fin.elim0 i
 728  | inr e' => simp [hL e']
 729
 730/-- The same for tetrahedra. -/
 731theorem dunion_dust_tetVerts {B' : ℕ} (a : ℕ) (L : BoundedComplex B') (v : Fin L.nV)
 732    (hL : ∀ t i, L.tetVerts t i = v) (t : Fin (dunion (dust a) L).nT) (i : Fin 4) :
 733    (dunion (dust a) L).tetVerts t i = (inrV v : Fin (a + L.nV)) := by
 734  simp only [dunion]
 735  cases hsum : finSumFinEquiv.symm t with
 736  | inl j => exact Fin.elim0 j
 737  | inr t' => simp [hL t']
 738
 739/-- **The union of dust and a bouquet is the cone.**  Every edge and tetrahedron of
 740the union comes from the bouquet, since dust carries none, and the bouquet's single
 741vertex sits at the apex. -/
 742def dunionConeRelabel (a b c : ℕ) :
 743    Relabel (dunion (dust a) (bouquet b c)) (cone a b c) where
 744  vEquiv := Equiv.refl _
 745  eEquiv := finCongr (Nat.zero_add b)
 746  tEquiv := finCongr (Nat.zero_add c)
 747  edge_comm := by
 748    intro e
 749    rw [dunion_dust_edgeVerts a (bouquet b c)
 750      (show Fin (bouquet b c).nV from (0 : Fin 1)) (fun _ => rfl) e]
 751    simp [cone]
 752    apply Fin.ext
 753    simp
 754  tet_comm := by
 755    intro t i
 756    rw [dunion_dust_tetVerts a (bouquet b c)
 757      (show Fin (bouquet b c).nV from (0 : Fin 1)) (fun _ _ => rfl) t i]
 758    simp [cone]
 759    apply Fin.ext
 760    simp
 761
 762theorem dunion_cone_equivalent (a b c : ℕ) :
 763    Equivalent (dunion (dust a) (bouquet b c)) (cone a b c) :=
 764  ⟨dunionConeRelabel a b c⟩
 765
 766/-- **The automorphism group of a bouquet.**  The single vertex has no choice, and
 767both incidence maps are constant, so every permutation of loops and of
 768tetrahedra is an automorphism and nothing else is required. -/
 769def autBouquetEquiv (b c : ℕ) :
 770    Aut (bouquet b c) ≃ Equiv.Perm (Fin b) × Equiv.Perm (Fin c) where
 771  toFun := fun r => (r.eEquiv, r.tEquiv)
 772  invFun := fun p =>
 773    { vEquiv := Equiv.refl _
 774      eEquiv := p.1
 775      tEquiv := p.2
 776      edge_comm := fun e => by simp [bouquet]
 777      tet_comm := fun t i => by simp [bouquet] }
 778  left_inv := by
 779    intro r
 780    have hv : r.vEquiv = Equiv.refl (Fin (bouquet b c).nV) := by
 781      refine Equiv.ext fun i => ?_
 782      simp only [Equiv.refl_apply]
 783      apply Fin.ext
 784      have h1 := (r.vEquiv i).isLt
 785      have h2 := i.isLt
 786      simp only [bouquet_nV] at h1 h2
 787      omega
 788    cases r
 789    simp_all
 790  right_inv := by intro p; rfl
 791
 792theorem autCard_bouquet (b c : ℕ) :
 793    Nat.card (Aut (bouquet b c)) = Nat.factorial b * Nat.factorial c := by
 794  rw [Nat.card_congr (autBouquetEquiv b c), Nat.card_eq_fintype_card,
 795    Fintype.card_prod, Fintype.card_perm, Fintype.card_perm, Fintype.card_fin,
 796    Fintype.card_fin]
 797
 798/-- A permutation of a two-element index set that fixes one point is the identity. -/
 799theorem perm_fin_two_fixes (σ : Equiv.Perm (Fin 2)) (h : σ (Fin.last 1) = Fin.last 1) :
 800    σ = Equiv.refl (Fin 2) := by
 801  revert h
 802  revert σ
 803  decide
 804
 805/-- **The automorphism group of a one-dust cone.**  The apex is the only vertex
 806carrying an incidence, so it is fixed; with only two vertices the remaining vertex
 807is fixed too, and the loops and tetrahedra permute freely.  Hence
 808`|Aut| = b! · c!`, which equals `|Aut (dust 1)| · |Aut (bouquet b c)|`. -/
 809def autConeOneEquiv (b c : ℕ) (hbc : 1 ≤ b + c) :
 810    Aut (cone 1 b c) ≃ Equiv.Perm (Fin b) × Equiv.Perm (Fin c) where
 811  toFun := fun r => (r.eEquiv, r.tEquiv)
 812  invFun := fun p =>
 813    { vEquiv := Equiv.refl _
 814      eEquiv := p.1
 815      tEquiv := p.2
 816      edge_comm := fun e => by simp [cone]
 817      tet_comm := fun t i => by simp [cone] }
 818  left_inv := by
 819    intro r
 820    have hfix : r.vEquiv (Fin.last 1) = Fin.last 1 := by
 821      rcases Nat.eq_zero_or_pos b with hb | hb
 822      · -- no loops, so there is at least one tetrahedron
 823        have hc : 0 < c := by omega
 824        have ht := r.tet_comm ⟨0, hc⟩ 0
 825        simpa [cone] using ht.symm
 826      · have he := r.edge_comm ⟨0, hb⟩
 827        have := congrArg Prod.fst he
 828        simpa [cone] using this.symm
 829    have hv : r.vEquiv = Equiv.refl (Fin (cone 1 b c).nV) := by
 830      have : r.vEquiv = Equiv.refl (Fin 2) := perm_fin_two_fixes r.vEquiv hfix
 831      exact this
 832    cases r
 833    simp_all
 834  right_inv := by intro p; rfl
 835
 836theorem autCard_cone_one (b c : ℕ) (hbc : 1 ≤ b + c) :
 837    Nat.card (Aut (cone 1 b c)) = Nat.factorial b * Nat.factorial c := by
 838  rw [Nat.card_congr (autConeOneEquiv b c hbc), Nat.card_eq_fintype_card,
 839    Fintype.card_prod, Fintype.card_perm, Fintype.card_perm, Fintype.card_fin,
 840    Fintype.card_fin]
 841
 842/-- The permutations of a vertex set fixing one distinguished vertex number the
 843permutations of the rest. -/
 844theorem stab_card (a : ℕ) :
 845    Nat.card {σ : Equiv.Perm (Fin (a + 1)) // σ (Fin.last a) = Fin.last a}
 846      = Nat.factorial a := by
 847  classical
 848  have hiff : ∀ f : Equiv.Perm (Fin (a + 1)),
 849      f (Fin.last a) = Fin.last a ↔ ∀ x, ¬(x ≠ Fin.last a) → f x = x := by
 850    intro f
 851    constructor
 852    · intro h x hx
 853      have hxe : x = Fin.last a := by by_contra hc; exact hx hc
 854      rw [hxe]; exact h
 855    · intro h; exact h _ (by simp)
 856  have e2 : {σ : Equiv.Perm (Fin (a + 1)) // σ (Fin.last a) = Fin.last a}
 857      ≃ {f : Equiv.Perm (Fin (a + 1)) // ∀ x, ¬(x ≠ Fin.last a) → f x = x} :=
 858    Equiv.subtypeEquivRight (fun f => hiff f)
 859  have e1 : {f : Equiv.Perm (Fin (a + 1)) // ∀ x, ¬(x ≠ Fin.last a) → f x = x}
 860      ≃ Equiv.Perm {y : Fin (a + 1) // y ≠ Fin.last a} :=
 861    (Equiv.Perm.subtypeEquivSubtypePerm (fun y : Fin (a + 1) => y ≠ Fin.last a)).symm
 862  have hc : Fintype.card {y : Fin (a + 1) // y ≠ Fin.last a} = a := by
 863    have h := Fintype.card_subtype_compl (p := fun y : Fin (a + 1) => y = Fin.last a)
 864    rw [Fintype.card_subtype_eq, Fintype.card_fin] at h
 865    simpa using h
 866  rw [Nat.card_congr (e2.trans e1), Nat.card_eq_fintype_card, Fintype.card_perm, hc]
 867
 868/-- **The automorphism group of a cone, for every amount of dust.**  The apex is the
 869only vertex carrying an incidence, so it is fixed; the remaining vertices permute
 870freely, and so do the loops and the tetrahedra. -/
 871def autConeEquiv (a b c : ℕ) (hbc : 1 ≤ b + c) :
 872    Aut (cone a b c)
 873      ≃ {σ : Equiv.Perm (Fin (a + 1)) // σ (Fin.last a) = Fin.last a}
 874          × (Equiv.Perm (Fin b) × Equiv.Perm (Fin c)) where
 875  toFun := fun r =>
 876    (⟨r.vEquiv, by
 877        rcases Nat.eq_zero_or_pos b with hb | hb
 878        · have hc : 0 < c := by omega
 879          have ht := r.tet_comm ⟨0, hc⟩ 0
 880          simpa [cone] using ht.symm
 881        · have he := r.edge_comm ⟨0, hb⟩
 882          have h1 := congrArg Prod.fst he
 883          simpa [cone] using h1.symm⟩,
 884      (r.eEquiv, r.tEquiv))
 885  invFun := fun p =>
 886    { vEquiv := p.1.val
 887      eEquiv := p.2.1
 888      tEquiv := p.2.2
 889      edge_comm := fun e => by simp [cone, p.1.property]
 890      tet_comm := fun t i => by simp [cone, p.1.property] }
 891  left_inv := by intro r; rfl
 892  right_inv := by intro p; rfl
 893
 894theorem autCard_cone (a b c : ℕ) (hbc : 1 ≤ b + c) :
 895    Nat.card (Aut (cone a b c))
 896      = Nat.factorial a * (Nat.factorial b * Nat.factorial c) := by
 897  classical
 898  rw [Nat.card_congr (autConeEquiv a b c hbc), Nat.card_eq_fintype_card,
 899    Fintype.card_prod, Fintype.card_prod, Fintype.card_perm, Fintype.card_perm,
 900    Fintype.card_fin, Fintype.card_fin]
 901  have hs : Fintype.card {σ : Equiv.Perm (Fin (a + 1)) // σ (Fin.last a) = Fin.last a}
 902      = Nat.factorial a := by
 903    have := stab_card a
 904    rwa [Nat.card_eq_fintype_card] at this
 905  rw [hs]
 906
 907/-- **THEOREM (family (a) is available in full).**  For every amount of dust and every
 908bouquet carrying at least one incidence, the automorphism count multiplies over the
 909union.  This is the family that carries the vertex, edge and tetrahedron recursions
 910of §6, so the most-used gluing instance is verified rather than assumed. -/
 911theorem autMul_dust_bouquet (a b c : ℕ) (hbc : 1 ≤ b + c) :
 912    Nat.card (Aut (dunion (dust a) (bouquet b c)))
 913      = Nat.card (Aut (dust a)) * Nat.card (Aut (bouquet b c)) := by
 914  rw [autCard_congr (dunion_cone_equivalent a b c), autCard_cone a b c hbc,
 915    autCard_dust, autCard_bouquet]
 916
 917/-- The orbit-count form: the interleaving factor is `a + 1`, and each part has a
 918single labeled presentation. -/
 919theorem orbitCard_dust_bouquet (a b c : ℕ) (hbc : 1 ≤ b + c) :
 920    gaugeOrbitCard (dunion (dust a) (bouquet b c))
 921      = interleave a 0 0 1 b c
 922        * (gaugeOrbitCard (dust a) * gaugeOrbitCard (bouquet b c)) :=
 923  orbitCard_dunion_of_autMul _ _ (autMul_dust_bouquet a b c hbc)
 924
 925/-- **THEOREM (family (a) is available at `a = 1`, for every `b` and `c`).**  The
 926automorphism count multiplies over `dust 1 ⊔ bouquet(b,c)`.  Together with §4 this
 927means the orbit counts there satisfy the binomial interleaving identity, so the
 928gluing instance used in §6 is a real instance and not an assumption with no
 929models.  The groups have order `b! · c!`, unbounded in both directions. -/
 930theorem autMul_dust_one_bouquet (b c : ℕ) (hbc : 1 ≤ b + c) :
 931    Nat.card (Aut (dunion (dust 1) (bouquet b c)))
 932      = Nat.card (Aut (dust 1)) * Nat.card (Aut (bouquet b c)) := by
 933  rw [autCard_congr (dunion_cone_equivalent 1 b c), autCard_cone_one b c hbc,
 934    autCard_dust, autCard_bouquet]
 935  simp [Nat.factorial]
 936
 937/-- The corresponding orbit-count identity, spelled out: the interleaving factor is
 938exactly `2`, which is `C(1+1, 1)`, and both parts have a single labeled
 939presentation. -/
 940theorem orbitCard_dust_one_bouquet (b c : ℕ) (hbc : 1 ≤ b + c) :
 941    gaugeOrbitCard (dunion (dust 1) (bouquet b c))
 942      = interleave 1 0 0 1 b c
 943        * (gaugeOrbitCard (dust 1) * gaugeOrbitCard (bouquet b c)) :=
 944  orbitCard_dunion_of_autMul _ _ (autMul_dust_one_bouquet b c hbc)
 945
 946/-! ### §7b. Families (b), (c) and (d): the rigid parts
 947
 948Family (a) is dust glued to a bouquet, and its availability is above.  The other three
 949instances glue something to a *rigid* part, meaning a part with no automorphisms: a
 950single edge with distinct endpoints, or a single nondegenerate tetrahedron.  Rigidity is
 951what makes those parts contribute a factor of one, and it is a consequence of the
 952incidence data being *ordered*: a relabeling must match the endpoint pair in order, so it
 953cannot reverse an edge or rotate a tetrahedron.
 954
 955The no-mixing argument is the same in all three cases and rests on invariants of the
 956incidence pattern rather than on any count.  Whether an edge's two endpoints coincide is
 957preserved by relabeling, so a loop can never map to a proper edge; whether a
 958tetrahedron's four corners coincide is preserved likewise.  So the parts cannot exchange
 959cells, every vertex carrying an incidence is pinned, and the remaining vertices permute
 960freely. -/
 961
 962/-- A permutation fixing every point but one fixes that one too, by injectivity. -/
 963theorem perm_fix_of_fixes_others {α : Type*} (σ : Equiv.Perm α) (x : α)
 964    (h : ∀ y, y ≠ x → σ y = y) : σ x = x := by
 965  by_contra hx
 966  exact hx (σ.injective (h (σ x) hx))
 967
 968/-- The permutations of an index set fixing one distinguished point number the
 969permutations of the rest.  The `Fin.last` case is `stab_card`; this is the general one,
 970needed because the distinguished point of a union is an injection image. -/
 971theorem stab1_card {m : ℕ} (p : Fin (m + 1)) :
 972    Nat.card {σ : Equiv.Perm (Fin (m + 1)) // σ p = p} = Nat.factorial m := by
 973  classical
 974  have hiff : ∀ f : Equiv.Perm (Fin (m + 1)),
 975      f p = p ↔ ∀ x, ¬(x ≠ p) → f x = x := by
 976    intro f
 977    constructor
 978    · intro h x hx
 979      rw [not_not.mp hx]; exact h
 980    · intro h; exact h _ (by simp)
 981  have e2 : {σ : Equiv.Perm (Fin (m + 1)) // σ p = p}
 982      ≃ {f : Equiv.Perm (Fin (m + 1)) // ∀ x, ¬(x ≠ p) → f x = x} :=
 983    Equiv.subtypeEquivRight (fun f => hiff f)
 984  have e1 : {f : Equiv.Perm (Fin (m + 1)) // ∀ x, ¬(x ≠ p) → f x = x}
 985      ≃ Equiv.Perm {y : Fin (m + 1) // y ≠ p} :=
 986    (Equiv.Perm.subtypeEquivSubtypePerm (fun y : Fin (m + 1) => y ≠ p)).symm
 987  have hc : Fintype.card {y : Fin (m + 1) // y ≠ p} = m := by
 988    have h := Fintype.card_subtype_compl (p := fun y : Fin (m + 1) => y = p)
 989    rw [Fintype.card_subtype_eq, Fintype.card_fin] at h
 990    simpa using h
 991  rw [Nat.card_congr (e2.trans e1), Nat.card_eq_fintype_card, Fintype.card_perm, hc]
 992
 993/-! The four accessors for a union's incidence maps.  Every cell of the union is the
 994image of a cell of one part, and these say what its vertices are. -/
 995
 996theorem dunion_edgeVerts_inl {B B' : ℕ} (K : BoundedComplex B) (L : BoundedComplex B')
 997    (e : Fin K.nE) :
 998    (dunion K L).edgeVerts (finSumFinEquiv (Sum.inl e))
 999      = ((inlV (K.edgeVerts e).1 : Fin (K.nV + L.nV)), inlV (K.edgeVerts e).2) := by
1000  simp only [dunion, Equiv.symm_apply_apply, Sum.elim_inl]
1001
1002theorem dunion_edgeVerts_inr {B B' : ℕ} (K : BoundedComplex B) (L : BoundedComplex B')
1003    (e : Fin L.nE) :
1004    (dunion K L).edgeVerts (finSumFinEquiv (Sum.inr e))
1005      = ((inrV (L.edgeVerts e).1 : Fin (K.nV + L.nV)), inrV (L.edgeVerts e).2) := by
1006  simp only [dunion, Equiv.symm_apply_apply, Sum.elim_inr]
1007
1008theorem dunion_tetVerts_inl {B B' : ℕ} (K : BoundedComplex B) (L : BoundedComplex B')
1009    (t : Fin K.nT) (i : Fin 4) :
1010    (dunion K L).tetVerts (finSumFinEquiv (Sum.inl t)) i
1011      = (inlV (K.tetVerts t i) : Fin (K.nV + L.nV)) := by
1012  simp only [dunion, Equiv.symm_apply_apply, Sum.elim_inl]
1013
1014theorem dunion_tetVerts_inr {B B' : ℕ} (K : BoundedComplex B) (L : BoundedComplex B')
1015    (t : Fin L.nT) (i : Fin 4) :
1016    (dunion K L).tetVerts (finSumFinEquiv (Sum.inr t)) i
1017      = (inrV (L.tetVerts t i) : Fin (K.nV + L.nV)) := by
1018  simp only [dunion, Equiv.symm_apply_apply, Sum.elim_inr]
1019
1020/-- A **single edge** with distinct endpoints: two vertices, one edge joining them. -/
1021def edge : BoundedComplex 2 where
1022  nV := 2
1023  nE := 1
1024  nT := 0
1025  hV := le_refl 2
1026  hE := by omega
1027  hT := by omega
1028  edgeVerts := fun _ => (0, Fin.last 1)
1029  tetVerts := fun t _ => Fin.elim0 t
1030
1031@[simp] theorem edge_nV : edge.nV = 2 := rfl
1032@[simp] theorem edge_nE : edge.nE = 1 := rfl
1033@[simp] theorem edge_nT : edge.nT = 0 := rfl
1034
1035/-- A permutation of a one-element index set is the identity. -/
1036theorem perm_fin_one (σ : Equiv.Perm (Fin 1)) : σ = Equiv.refl (Fin 1) := by
1037  refine Equiv.ext fun i => ?_
1038  apply Fin.ext
1039  have h1 := (σ i).isLt
1040  have h2 := i.isLt
1041  omega
1042
1043/-- A permutation of an empty index set is the identity. -/
1044theorem perm_fin_zero (σ : Equiv.Perm (Fin 0)) : σ = Equiv.refl (Fin 0) :=
1045  Equiv.ext fun t => Fin.elim0 t
1046
1047/-- The permutations of a vertex set fixing two distinguished vertices number the
1048permutations of the rest.  Used by all three rigid families. -/
1049theorem stab2_card {m : ℕ} (p q : Fin (m + 2)) (hpq : p ≠ q) :
1050    Nat.card {σ : Equiv.Perm (Fin (m + 2)) // σ p = p ∧ σ q = q} = Nat.factorial m := by
1051  classical
1052  have hiff : ∀ f : Equiv.Perm (Fin (m + 2)),
1053      (f p = p ∧ f q = q) ↔ ∀ x, ¬(x ≠ p ∧ x ≠ q) → f x = x := by
1054    intro f
1055    constructor
1056    · intro h x hx
1057      rcases not_and_or.mp hx with hxp | hxq
1058      · rw [not_not.mp hxp]; exact h.1
1059      · rw [not_not.mp hxq]; exact h.2
1060    · intro h
1061      exact ⟨h p (by simp), h q (by simp)⟩
1062  have e2 : {σ : Equiv.Perm (Fin (m + 2)) // σ p = p ∧ σ q = q}
1063      ≃ {f : Equiv.Perm (Fin (m + 2)) // ∀ x, ¬(x ≠ p ∧ x ≠ q) → f x = x} :=
1064    Equiv.subtypeEquivRight (fun f => hiff f)
1065  have e1 : {f : Equiv.Perm (Fin (m + 2)) // ∀ x, ¬(x ≠ p ∧ x ≠ q) → f x = x}
1066      ≃ Equiv.Perm {y : Fin (m + 2) // y ≠ p ∧ y ≠ q} :=
1067    (Equiv.Perm.subtypeEquivSubtypePerm (fun y : Fin (m + 2) => y ≠ p ∧ y ≠ q)).symm
1068  have hc : Fintype.card {y : Fin (m + 2) // y ≠ p ∧ y ≠ q} = m := by
1069    rw [Fintype.card_subtype]
1070    have hfil : (Finset.univ.filter (fun y : Fin (m + 2) => y ≠ p ∧ y ≠ q))
1071        = Finset.univ \ {p, q} := by
1072      ext y
1073      simp only [Finset.mem_filter, Finset.mem_univ, true_and, Finset.mem_sdiff,
1074        Finset.mem_insert, Finset.mem_singleton]
1075      tauto
1076    rw [hfil, Finset.card_sdiff, Finset.inter_univ, Finset.card_univ, Fintype.card_fin,
1077      Finset.card_insert_of_notMem (by simpa using hpq), Finset.card_singleton]
1078    omega
1079  rw [Nat.card_congr (e2.trans e1), Nat.card_eq_fintype_card, Fintype.card_perm, hc]
1080
1081/-- The single edge is **rigid**: ordered endpoints leave no automorphism. -/
1082def autEdgeEquiv : Aut edge ≃ Unit where
1083  toFun := fun _ => ()
1084  invFun := fun _ =>
1085    { vEquiv := Equiv.refl _
1086      eEquiv := Equiv.refl _
1087      tEquiv := Equiv.refl _
1088      edge_comm := fun e => by simp [edge]
1089      tet_comm := fun t _ => Fin.elim0 t }
1090  left_inv := by
1091    intro r
1092    have hsnd : r.vEquiv (Fin.last 1) = Fin.last 1 := by
1093      have he := r.edge_comm (show Fin edge.nE from (0 : Fin 1))
1094      have h2 := congrArg Prod.snd he
1095      simpa [edge] using h2.symm
1096    have hv : r.vEquiv = Equiv.refl (Fin edge.nV) := perm_fin_two_fixes r.vEquiv hsnd
1097    have he : r.eEquiv = Equiv.refl (Fin edge.nE) := perm_fin_one r.eEquiv
1098    have ht : r.tEquiv = Equiv.refl (Fin edge.nT) := perm_fin_zero r.tEquiv
1099    cases r
1100    simp_all
1101  right_inv := by intro _; rfl
1102
1103theorem autCard_edge : Nat.card (Aut edge) = 1 := by
1104  rw [Nat.card_congr autEdgeEquiv, Nat.card_eq_fintype_card, Fintype.card_unit]
1105
1106/-- In a union of dust with the single edge, the one edge is the pushed-in edge of the
1107right part, so its endpoints are the two pushed-in vertices. -/
1108theorem dunion_dust_edge_edgeVerts (a : ℕ) (e : Fin (dunion (dust a) edge).nE) :
1109    (dunion (dust a) edge).edgeVerts e
1110      = ((inrV (0 : Fin 2) : Fin (a + 2)), (inrV (Fin.last 1) : Fin (a + 2))) := by
1111  simp only [dunion]
1112  cases hsum : finSumFinEquiv.symm e with
1113  | inl i => exact Fin.elim0 i
1114  | inr e' => simp [edge]
1115
1116/-- The two pushed-in endpoints are distinct, since the injection is injective. -/
1117theorem inrV_edge_ne (a : ℕ) :
1118    (inrV (0 : Fin 2) : Fin (a + 2)) ≠ (inrV (Fin.last 1) : Fin (a + 2)) := by
1119  intro h
1120  have hv := congrArg Fin.val h
1121  simp [inrV] at hv
1122
1123/-- **The automorphism group of dust glued to an edge.**  The two endpoints are the only
1124vertices carrying an incidence and the edge is ordered, so both are pinned; the dust
1125permutes freely. -/
1126def autDustEdgeEquiv (a : ℕ) :
1127    Aut (dunion (dust a) edge)
1128      ≃ {σ : Equiv.Perm (Fin (a + 2)) //
1129          σ (inrV (0 : Fin 2)) = inrV (0 : Fin 2)
1130            ∧ σ (inrV (Fin.last 1)) = inrV (Fin.last 1)} where
1131  toFun := fun r =>
1132    ⟨r.vEquiv, by
1133      have he := r.edge_comm (show Fin (dunion (dust a) edge).nE from (0 : Fin 1))
1134      rw [dunion_dust_edge_edgeVerts, dunion_dust_edge_edgeVerts] at he
1135      simp only [Prod.map, Prod.mk.injEq] at he
1136      exact ⟨he.1.symm, he.2.symm⟩⟩
1137  invFun := fun σ =>
1138    { vEquiv := σ.val
1139      eEquiv := Equiv.refl _
1140      tEquiv := Equiv.refl _
1141      edge_comm := fun e => by
1142        rw [dunion_dust_edge_edgeVerts, dunion_dust_edge_edgeVerts]
1143        simp only [Prod.map, Prod.mk.injEq]
1144        exact ⟨σ.property.1.symm, σ.property.2.symm⟩
1145      tet_comm := fun t _ => Fin.elim0 t }
1146  left_inv := by
1147    intro r
1148    have he : r.eEquiv = Equiv.refl (Fin (dunion (dust a) edge).nE) :=
1149      perm_fin_one r.eEquiv
1150    have ht : r.tEquiv = Equiv.refl (Fin (dunion (dust a) edge).nT) :=
1151      perm_fin_zero r.tEquiv
1152    cases r
1153    simp_all
1154  right_inv := by intro _; rfl
1155
1156theorem autCard_dust_edge (a : ℕ) :
1157    Nat.card (Aut (dunion (dust a) edge)) = Nat.factorial a := by
1158  rw [Nat.card_congr (autDustEdgeEquiv a)]
1159  exact stab2_card _ _ (inrV_edge_ne a)
1160
1161/-- **THEOREM (family (b) is available).**  The automorphism count multiplies over dust
1162glued to a single edge, for every amount of dust. -/
1163theorem autMul_dust_edge (a : ℕ) :
1164    Nat.card (Aut (dunion (dust a) edge))
1165      = Nat.card (Aut (dust a)) * Nat.card (Aut edge) := by
1166  rw [autCard_dust_edge, autCard_dust, autCard_edge, mul_one]
1167
1168/-- The orbit-count form of family (b). -/
1169theorem orbitCard_dust_edge (a : ℕ) :
1170    gaugeOrbitCard (dunion (dust a) edge)
1171      = interleave a 0 0 2 1 0
1172        * (gaugeOrbitCard (dust a) * gaugeOrbitCard edge) :=
1173  orbitCard_dunion_of_autMul _ _ (autMul_dust_edge a)
1174
1175/-! ### Family (c): a bouquet glued to an edge
1176
1177Three vertices: the bouquet vertex, and the edge's two ends.  The proper edge cannot map
1178to a loop, because a relabeling carries the two endpoints of an edge to the two endpoints
1179of its image *in order*, so it preserves whether those endpoints coincide.  That pins both
1180ends of the proper edge, and then the bouquet vertex is pinned because a permutation
1181fixing all but one point fixes that one.  Loops and tetrahedra then permute freely. -/
1182
1183/-- The bouquet vertex of the union. -/
1184def bqeV (b c : ℕ) : Fin (dunion (bouquet b c) edge).nV := inlV (0 : Fin 1)
1185/-- The first endpoint of the proper edge. -/
1186def bqeV0 (b c : ℕ) : Fin (dunion (bouquet b c) edge).nV := inrV (0 : Fin 2)
1187/-- The second endpoint of the proper edge. -/
1188def bqeV1 (b c : ℕ) : Fin (dunion (bouquet b c) edge).nV := inrV (Fin.last 1)
1189/-- The index of the proper edge. -/
1190def bqePE (b c : ℕ) : Fin (dunion (bouquet b c) edge).nE := finSumFinEquiv (Sum.inr (0 : Fin 1))
1191
1192theorem bqeV_val (b c : ℕ) : (bqeV b c).val = 0 := rfl
1193theorem bqeV0_val (b c : ℕ) : (bqeV0 b c).val = 1 := rfl
1194theorem bqeV1_val (b c : ℕ) : (bqeV1 b c).val = 2 := rfl
1195
1196/-- The proper edge joins the two pushed-in endpoints. -/
1197theorem bqe_edgeVerts_pE (b c : ℕ) :
1198    (dunion (bouquet b c) edge).edgeVerts (bqePE b c) = (bqeV0 b c, bqeV1 b c) := by
1199  rw [bqePE, dunion_edgeVerts_inr]
1200  rfl
1201
1202/-- Every other edge of the union is a loop at the bouquet vertex. -/
1203theorem bqe_edgeVerts_loop (b c : ℕ) (e : Fin (dunion (bouquet b c) edge).nE)
1204    (h : e ≠ bqePE b c) :
1205    (dunion (bouquet b c) edge).edgeVerts e = (bqeV b c, bqeV b c) := by
1206  cases hsum : finSumFinEquiv.symm e with
1207  | inl i =>
1208      have he : e = finSumFinEquiv (Sum.inl i) := by rw [← hsum, Equiv.apply_symm_apply]
1209      rw [he, dunion_edgeVerts_inl]
1210      rfl
1211  | inr j =>
1212      exfalso
1213      apply h
1214      apply finSumFinEquiv.symm.injective
1215      rw [hsum, bqePE, Equiv.symm_apply_apply]
1216      congr 1
1217      apply Fin.ext
1218      have h1 : edge.nE = 1 := rfl
1219      have h2 := j.isLt
1220      have h3 : ((0 : Fin 1) : ℕ) = 0 := rfl
1221      omega
1222
1223/-- Every tetrahedron of the union sits at the bouquet vertex, the edge having none. -/
1224theorem bqe_tetVerts (b c : ℕ) (t : Fin (dunion (bouquet b c) edge).nT) (i : Fin 4) :
1225    (dunion (bouquet b c) edge).tetVerts t i = bqeV b c := by
1226  cases hsum : finSumFinEquiv.symm t with
1227  | inl t' =>
1228      have ht : t = finSumFinEquiv (Sum.inl t') := by rw [← hsum, Equiv.apply_symm_apply]
1229      rw [ht, dunion_tetVerts_inl]
1230      rfl
1231  | inr t' => exact Fin.elim0 t'
1232
1233/-- **The proper edge is fixed.**  If it mapped to a loop its two distinct endpoints
1234would have the same image. -/
1235theorem bqe_eEquiv_fixes (b c : ℕ) (r : Aut (dunion (bouquet b c) edge)) :
1236    r.eEquiv (bqePE b c) = bqePE b c := by
1237  by_contra hne
1238  have he := r.edge_comm (bqePE b c)
1239  rw [bqe_edgeVerts_loop b c _ hne, bqe_edgeVerts_pE] at he
1240  simp only [Prod.map, Prod.mk.injEq] at he
1241  have hcoll : bqeV0 b c = bqeV1 b c := r.vEquiv.injective (he.1.symm.trans he.2)
1242  have h0 := bqeV0_val b c
1243  rw [hcoll] at h0
1244  rw [bqeV1_val] at h0
1245  omega
1246
1247/-- **Every vertex is pinned.** -/
1248theorem bqe_vEquiv_refl (b c : ℕ) (r : Aut (dunion (bouquet b c) edge)) :
1249    r.vEquiv = Equiv.refl _ := by
1250  have he := r.edge_comm (bqePE b c)
1251  rw [bqe_eEquiv_fixes, bqe_edgeVerts_pE] at he
1252  simp only [Prod.map, Prod.mk.injEq] at he
1253  have h0 : r.vEquiv (bqeV0 b c) = bqeV0 b c := he.1.symm
1254  have h1 : r.vEquiv (bqeV1 b c) = bqeV1 b c := he.2.symm
1255  have hother : ∀ y, y ≠ bqeV b c → r.vEquiv y = y := by
1256    intro y hy
1257    have hlt : y.val < 3 := by
1258      have := y.isLt
1259      simpa using this
1260    have hne0 : y.val ≠ 0 := fun hc => hy (Fin.ext (by rw [hc, bqeV_val]))
1261    rcases (show y.val = 1 ∨ y.val = 2 by omega) with h | h
1262    · have hy0 : y = bqeV0 b c := Fin.ext (by rw [h, bqeV0_val])
1263      rw [hy0]; exact h0
1264    · have hy1 : y = bqeV1 b c := Fin.ext (by rw [h, bqeV1_val])
1265      rw [hy1]; exact h1
1266  have hb := perm_fix_of_fixes_others r.vEquiv (bqeV b c) hother
1267  refine Equiv.ext fun y => ?_
1268  by_cases hy : y = bqeV b c
1269  · rw [hy]; exact hb
1270  · exact hother y hy
1271
1272/-- **The automorphism group of a bouquet glued to an edge.**  The edge contributes
1273nothing; the loops and the tetrahedra permute freely. -/
1274def autBqEdgeEquiv (b c : ℕ) :
1275    Aut (dunion (bouquet b c) edge)
1276      ≃ {σ : Equiv.Perm (Fin (dunion (bouquet b c) edge).nE) // σ (bqePE b c) = bqePE b c}
1277          × Equiv.Perm (Fin (dunion (bouquet b c) edge).nT) where
1278  toFun := fun r => (⟨r.eEquiv, bqe_eEquiv_fixes b c r⟩, r.tEquiv)
1279  invFun := fun p =>
1280    { vEquiv := Equiv.refl _
1281      eEquiv := p.1.val
1282      tEquiv := p.2
1283      edge_comm := fun e => by
1284        by_cases he : e = bqePE b c
1285        · rw [he, p.1.property, bqe_edgeVerts_pE]; rfl
1286        · have hne : p.1.val e ≠ bqePE b c := fun hc =>
1287            he (p.1.val.injective (hc.trans p.1.property.symm))
1288          rw [bqe_edgeVerts_loop b c _ hne, bqe_edgeVerts_loop b c e he]; rfl
1289      tet_comm := fun t i => by rw [bqe_tetVerts, bqe_tetVerts]; rfl }
1290  left_inv := by
1291    intro r
1292    have hv := bqe_vEquiv_refl b c r
1293    cases r
1294    simp_all
1295  right_inv := by intro _; rfl
1296
1297theorem autCard_bouquet_edge (b c : ℕ) :
1298    Nat.card (Aut (dunion (bouquet b c) edge))
1299      = Nat.factorial b * Nat.factorial c := by
1300  classical
1301  rw [Nat.card_congr (autBqEdgeEquiv b c), Nat.card_eq_fintype_card, Fintype.card_prod,
1302    Fintype.card_perm, Fintype.card_fin]
1303  have hs : Fintype.card {σ : Equiv.Perm (Fin (dunion (bouquet b c) edge).nE) //
1304      σ (bqePE b c) = bqePE b c} = Nat.factorial b := by
1305    have := stab1_card (bqePE b c)
1306    rwa [Nat.card_eq_fintype_card] at this
1307  rw [hs]
1308  simp
1309
1310/-- **THEOREM (family (c) is available).**  The automorphism count multiplies over a
1311bouquet glued to a single edge, for every number of loops and tetrahedra. -/
1312theorem autMul_bouquet_edge (b c : ℕ) :
1313    Nat.card (Aut (dunion (bouquet b c) edge))
1314      = Nat.card (Aut (bouquet b c)) * Nat.card (Aut edge) := by
1315  rw [autCard_bouquet_edge, autCard_bouquet, autCard_edge, mul_one]
1316
1317/-- The orbit-count form of family (c). -/
1318theorem orbitCard_bouquet_edge (b c : ℕ) :
1319    gaugeOrbitCard (dunion (bouquet b c) edge)
1320      = interleave 1 b c 2 1 0
1321        * (gaugeOrbitCard (bouquet b c) * gaugeOrbitCard edge) :=
1322  orbitCard_dunion_of_autMul _ _ (autMul_bouquet_edge b c)
1323
1324/-! ### Family (d): a bouquet glued to a tetrahedron
1325
1326Five vertices.  A nondegenerate tetrahedron cannot map to a degenerate one, because a
1327relabeling carries the four corners of a tetrahedron to the four corners of its image in
1328order, so it preserves whether they coincide.  That pins all four corners, and the
1329bouquet vertex follows. -/
1330
1331/-- A **single nondegenerate tetrahedron**: four vertices, one tetrahedron on them. -/
1332def tetra : BoundedComplex 4 where
1333  nV := 4
1334  nE := 0
1335  nT := 1
1336  hV := le_refl 4
1337  hE := by omega
1338  hT := by omega
1339  edgeVerts := Fin.elim0
1340  tetVerts := fun _ i => i
1341
1342@[simp] theorem tetra_nV : tetra.nV = 4 := rfl
1343@[simp] theorem tetra_nE : tetra.nE = 0 := rfl
1344@[simp] theorem tetra_nT : tetra.nT = 1 := rfl
1345
1346/-- The tetrahedron is **rigid**: ordered corners leave no automorphism. -/
1347def autTetraEquiv : Aut tetra ≃ Unit where
1348  toFun := fun _ => ()
1349  invFun := fun _ =>
1350    { vEquiv := Equiv.refl _
1351      eEquiv := Equiv.refl _
1352      tEquiv := Equiv.refl _
1353      edge_comm := fun e => Fin.elim0 e
1354      tet_comm := fun t i => by simp [tetra] }
1355  left_inv := by
1356    intro r
1357    have hv : r.vEquiv = Equiv.refl (Fin tetra.nV) := by
1358      refine Equiv.ext fun i => ?_
1359      have ht := r.tet_comm (show Fin tetra.nT from (0 : Fin 1)) i
1360      simpa [tetra] using ht.symm
1361    have he : r.eEquiv = Equiv.refl (Fin tetra.nE) := perm_fin_zero r.eEquiv
1362    have ht : r.tEquiv = Equiv.refl (Fin tetra.nT) := perm_fin_one r.tEquiv
1363    cases r
1364    simp_all
1365  right_inv := by intro _; rfl
1366
1367theorem autCard_tetra : Nat.card (Aut tetra) = 1 := by
1368  rw [Nat.card_congr autTetraEquiv, Nat.card_eq_fintype_card, Fintype.card_unit]
1369
1370/-- The bouquet vertex of the union. -/
1371def bqtV (b c : ℕ) : Fin (dunion (bouquet b c) tetra).nV := inlV (0 : Fin 1)
1372/-- The `i`-th corner of the tetrahedron, in the union. -/
1373def bqtVR (b c : ℕ) (i : Fin 4) : Fin (dunion (bouquet b c) tetra).nV := inrV i
1374/-- The index of the nondegenerate tetrahedron. -/
1375def bqtPT (b c : ℕ) : Fin (dunion (bouquet b c) tetra).nT := finSumFinEquiv (Sum.inr (0 : Fin 1))
1376
1377theorem bqtV_val (b c : ℕ) : (bqtV b c).val = 0 := rfl
1378theorem bqtVR_val (b c : ℕ) (i : Fin 4) : (bqtVR b c i).val = 1 + i.val := rfl
1379
1380/-- The nondegenerate tetrahedron has the four pushed-in corners. -/
1381theorem bqt_tetVerts_pT (b c : ℕ) (i : Fin 4) :
1382    (dunion (bouquet b c) tetra).tetVerts (bqtPT b c) i = bqtVR b c i := by
1383  rw [bqtPT, dunion_tetVerts_inr]
1384  rfl
1385
1386/-- Every other tetrahedron sits at the bouquet vertex. -/
1387theorem bqt_tetVerts_deg (b c : ℕ) (t : Fin (dunion (bouquet b c) tetra).nT)
1388    (h : t ≠ bqtPT b c) (i : Fin 4) :
1389    (dunion (bouquet b c) tetra).tetVerts t i = bqtV b c := by
1390  cases hsum : finSumFinEquiv.symm t with
1391  | inl t' =>
1392      have ht : t = finSumFinEquiv (Sum.inl t') := by rw [← hsum, Equiv.apply_symm_apply]
1393      rw [ht, dunion_tetVerts_inl]
1394      rfl
1395  | inr t' =>
1396      exfalso
1397      apply h
1398      apply finSumFinEquiv.symm.injective
1399      rw [hsum, bqtPT, Equiv.symm_apply_apply]
1400      congr 1
1401      apply Fin.ext
1402      have h1 : tetra.nT = 1 := rfl
1403      have h2 := t'.isLt
1404      have h3 : ((0 : Fin 1) : ℕ) = 0 := rfl
1405      omega
1406
1407/-- Every edge of the union is a loop at the bouquet vertex, the tetrahedron having none. -/
1408theorem bqt_edgeVerts (b c : ℕ) (e : Fin (dunion (bouquet b c) tetra).nE) :
1409    (dunion (bouquet b c) tetra).edgeVerts e = (bqtV b c, bqtV b c) := by
1410  cases hsum : finSumFinEquiv.symm e with
1411  | inl i =>
1412      have he : e = finSumFinEquiv (Sum.inl i) := by rw [← hsum, Equiv.apply_symm_apply]
1413      rw [he, dunion_edgeVerts_inl]
1414      rfl
1415  | inr j => exact Fin.elim0 j
1416
1417/-- **The nondegenerate tetrahedron is fixed.**  If it mapped to a degenerate one, its
1418four distinct corners would all have the same image. -/
1419theorem bqt_tEquiv_fixes (b c : ℕ) (r : Aut (dunion (bouquet b c) tetra)) :
1420    r.tEquiv (bqtPT b c) = bqtPT b c := by
1421  by_contra hne
1422  have h0 := r.tet_comm (bqtPT b c) 0
1423  have h1 := r.tet_comm (bqtPT b c) 1
1424  rw [bqt_tetVerts_deg b c _ hne, bqt_tetVerts_pT] at h0
1425  rw [bqt_tetVerts_deg b c _ hne, bqt_tetVerts_pT] at h1
1426  have hcoll : bqtVR b c 0 = bqtVR b c 1 := r.vEquiv.injective (h0.symm.trans h1)
1427  have hv := bqtVR_val b c 0
1428  rw [hcoll, bqtVR_val] at hv
1429  simp at hv
1430
1431/-- **Every vertex is pinned.** -/
1432theorem bqt_vEquiv_refl (b c : ℕ) (r : Aut (dunion (bouquet b c) tetra)) :
1433    r.vEquiv = Equiv.refl _ := by
1434  have hcorner : ∀ i : Fin 4, r.vEquiv (bqtVR b c i) = bqtVR b c i := by
1435    intro i
1436    have ht := r.tet_comm (bqtPT b c) i
1437    rw [bqt_tEquiv_fixes, bqt_tetVerts_pT] at ht
1438    exact ht.symm
1439  have hother : ∀ y, y ≠ bqtV b c → r.vEquiv y = y := by
1440    intro y hy
1441    have hlt : y.val < 5 := by
1442      have := y.isLt
1443      simpa using this
1444    have hne0 : y.val ≠ 0 := fun hc => hy (Fin.ext (by rw [hc, bqtV_val]))
1445    have hyi : y = bqtVR b c ⟨y.val - 1, by omega⟩ := by
1446      apply Fin.ext
1447      rw [bqtVR_val]
1448      show y.val = 1 + (y.val - 1)
1449      omega
1450    rw [hyi]
1451    exact hcorner _
1452  have hb := perm_fix_of_fixes_others r.vEquiv (bqtV b c) hother
1453  refine Equiv.ext fun y => ?_
1454  by_cases hy : y = bqtV b c
1455  · rw [hy]; exact hb
1456  · exact hother y hy
1457
1458/-- **The automorphism group of a bouquet glued to a tetrahedron.** -/
1459def autBqTetEquiv (b c : ℕ) :
1460    Aut (dunion (bouquet b c) tetra)
1461      ≃ Equiv.Perm (Fin (dunion (bouquet b c) tetra).nE)
1462          × {τ : Equiv.Perm (Fin (dunion (bouquet b c) tetra).nT) //
1463              τ (bqtPT b c) = bqtPT b c} where
1464  toFun := fun r => (r.eEquiv, ⟨r.tEquiv, bqt_tEquiv_fixes b c r⟩)
1465  invFun := fun p =>
1466    { vEquiv := Equiv.refl _
1467      eEquiv := p.1
1468      tEquiv := p.2.val
1469      edge_comm := fun e => by rw [bqt_edgeVerts, bqt_edgeVerts]; rfl
1470      tet_comm := fun t i => by
1471        by_cases ht : t = bqtPT b c
1472        · rw [ht, p.2.property, bqt_tetVerts_pT]; rfl
1473        · have hne : p.2.val t ≠ bqtPT b c := fun hc =>
1474            ht (p.2.val.injective (hc.trans p.2.property.symm))
1475          rw [bqt_tetVerts_deg b c _ hne, bqt_tetVerts_deg b c t ht]; rfl }
1476  left_inv := by
1477    intro r
1478    have hv := bqt_vEquiv_refl b c r
1479    cases r
1480    simp_all
1481  right_inv := by intro _; rfl
1482
1483theorem autCard_bouquet_tetra (b c : ℕ) :
1484    Nat.card (Aut (dunion (bouquet b c) tetra))
1485      = Nat.factorial b * Nat.factorial c := by
1486  classical
1487  rw [Nat.card_congr (autBqTetEquiv b c), Nat.card_eq_fintype_card, Fintype.card_prod,
1488    Fintype.card_perm, Fintype.card_fin]
1489  have hs : Fintype.card {τ : Equiv.Perm (Fin (dunion (bouquet b c) tetra).nT) //
1490      τ (bqtPT b c) = bqtPT b c} = Nat.factorial c := by
1491    have := stab1_card (bqtPT b c)
1492    rwa [Nat.card_eq_fintype_card] at this
1493  rw [hs]
1494  simp
1495
1496/-- **THEOREM (family (d) is available).**  The automorphism count multiplies over a
1497bouquet glued to a single nondegenerate tetrahedron. -/
1498theorem autMul_bouquet_tetra (b c : ℕ) :
1499    Nat.card (Aut (dunion (bouquet b c) tetra))
1500      = Nat.card (Aut (bouquet b c)) * Nat.card (Aut tetra) := by
1501  rw [autCard_bouquet_tetra, autCard_bouquet, autCard_tetra, mul_one]
1502
1503/-- The orbit-count form of family (d). -/
1504theorem orbitCard_bouquet_tetra (b c : ℕ) :
1505    gaugeOrbitCard (dunion (bouquet b c) tetra)
1506      = interleave 1 b c 4 0 1
1507        * (gaugeOrbitCard (bouquet b c) * gaugeOrbitCard tetra) :=
1508  orbitCard_dunion_of_autMul _ _ (autMul_bouquet_tetra b c)
1509
1510/-- **THEOREM (all four gluing instances of the premise set are available).**  Each of
1511the four unions used by `CarrierShuffle` has automorphism counts that multiply, so the
1512premise set is not an assumption about instances that might fail to exist: it is a
1513statement about four verified families, each unbounded in the sizes it ranges over. -/
1514theorem all_four_families_available :
1515    (∀ a b c : ℕ, 1 ≤ b + c →
1516        Nat.card (Aut (dunion (dust a) (bouquet b c)))
1517          = Nat.card (Aut (dust a)) * Nat.card (Aut (bouquet b c)))
1518      ∧ (∀ a : ℕ, Nat.card (Aut (dunion (dust a) edge))
1519          = Nat.card (Aut (dust a)) * Nat.card (Aut edge))
1520      ∧ (∀ b c : ℕ, Nat.card (Aut (dunion (bouquet b c) edge))
1521          = Nat.card (Aut (bouquet b c)) * Nat.card (Aut edge))
1522      ∧ (∀ b c : ℕ, Nat.card (Aut (dunion (bouquet b c) tetra))
1523          = Nat.card (Aut (bouquet b c)) * Nat.card (Aut tetra)) :=
1524  ⟨fun a b c h => autMul_dust_bouquet a b c h, autMul_dust_edge,
1525    autMul_bouquet_edge, autMul_bouquet_tetra⟩
1526
1527/-! ## §8. How much each premise does: the strength measurement
1528
1529A hostile panel run on §1-§7 converged on one correction: the headline "two premises
1530force the measure" hides the fact that the two premises are not equal partners.  This
1531section measures them, because a premise set is only worth what its weakest member
1532excludes.
1533
1534The first theorem is a decoy: a relabeling-invariant weight that satisfies premise (ii)
1535at **every** pair, with no side condition whatsoever, and is not the RS measure.  So
1536premise (ii) alone excludes nothing at all, and every bit of the derivation's force
1537comes from premise (i).
1538
1539The second is the converse receipt.  Premise (ii) is *silent* on `dust a ⊔ dust b`,
1540because the parts share a component; C3 shows why it must be.  The weight the two
1541premises force nonetheless satisfies the binomial-corrected identity there, as a
1542theorem rather than a premise.  A premise fitted to produce a wanted answer would
1543have its bodies buried exactly in the region it declines to speak about; this one
1544predicts that region correctly.  That is the non-circularity receipt. -/
1545
1546/-- The **uniform weight**: unit mass per class, spread evenly over the labeled
1547complexes presenting it.  This is the honest "labels are physical, every class counts
1548once" alternative to the RS measure. -/
1549noncomputable def uniformWeight {B : ℕ} (K : BoundedComplex B) : ℝ :=
1550  1 / (gaugeOrbitCard K : ℝ)
1551
1552/-- The gauge orbit count is relabeling-invariant: it is determined by the index sizes
1553and the automorphism count, and a relabeling preserves both. -/
1554theorem gaugeOrbitCard_congr {B : ℕ} {K K' : BoundedComplex B} (h : Equivalent K K') :
1555    gaugeOrbitCard K = gaugeOrbitCard K' := by
1556  have hK := orbitCard_mul_autCard K
1557  have hK' := orbitCard_mul_autCard K'
1558  obtain ⟨r⟩ := h
1559  rw [size_v r, size_e r, size_t r] at hK
1560  rw [autCard_congr ⟨r⟩] at hK
1561  exact Nat.eq_of_mul_eq_mul_right (autCard_pos K') (hK.trans hK'.symm)
1562
1563theorem uniformWeight_invariant {B : ℕ} {K K' : BoundedComplex B} (h : Equivalent K K') :
1564    uniformWeight K = uniformWeight K' := by
1565  unfold uniformWeight
1566  rw [gaugeOrbitCard_congr h]
1567
1568/-- **Every class carries unit mass under the uniform weight.** -/
1569theorem classMass_uniform {B : ℕ} (K : BoundedComplex B) :
1570    classMass uniformWeight (Quotient.mk (relabelSetoid B) K) = 1 := by
1571  rw [classMass_of_invariant _ (fun _ _ h => uniformWeight_invariant h) _,
1572    uniformWeight_invariant (equivalent_out K), orbitCardClass_mk]
1573  unfold uniformWeight
1574  have hpos : (0 : ℝ) < (gaugeOrbitCard K : ℝ) := by
1575    exact_mod_cast gaugeOrbitCard_pos K
1576  field_simp
1577
1578/-- **Premise (ii), stated for a family of labeled weights**, one at each size cap:
1579the class mass of a union is the product of the class masses of the parts.  This is
1580the unrestricted form, with no side condition on the parts. -/
1581def GluesGenerally (W : ∀ B : ℕ, BoundedComplex B → ℝ) : Prop :=
1582  ∀ {B B' : ℕ} (K : BoundedComplex B) (L : BoundedComplex B'),
1583    classMass (W (B + B')) (Quotient.mk (relabelSetoid (B + B')) (dunion K L))
1584      = classMass (W B) (Quotient.mk (relabelSetoid B) K)
1585        * classMass (W B') (Quotient.mk (relabelSetoid B') L)
1586
1587/-- The uniform weight satisfies unrestricted gluing, at every pair, trivially. -/
1588theorem uniform_gluesGenerally :
1589    GluesGenerally (fun B => (uniformWeight : BoundedComplex B → ℝ)) := by
1590  intro B B' K L
1591  rw [classMass_uniform, classMass_uniform, classMass_uniform]
1592  norm_num
1593
1594/-- The uniform weight's class mass is not the RS measure: a bouquet with two loops
1595has automorphism count two, so `mu` there is one half, while uniform mass is one. -/
1596theorem uniform_classMass_ne_mu :
1597    classMass uniformWeight (Quotient.mk (relabelSetoid (1 + 2 + 0)) (bouquet 2 0))
1598      ≠ mu (bouquet 2 0) := by
1599  rw [classMass_uniform]
1600  unfold mu
1601  rw [autCard_bouquet]
1602  norm_num [Nat.factorial]
1603
1604/-- **THEOREM (premise (ii) alone excludes nothing).**  There is a relabeling-invariant
1605labeled weight whose class mass multiplies over *every* disjoint union, with no side
1606condition, and which is not the RS measure.  So the gluing premise carries no
1607discriminating power by itself: all of it is contributed by size-blindness, premise (i).
1608
1609This is the strength measurement the honest-tag discipline requires, and it corrects
1610the framing of §5-§6: the two premises are not equal partners. -/
1611theorem gluing_alone_does_not_force_mu :
1612    GluesGenerally (fun B => (uniformWeight : BoundedComplex B → ℝ))
1613      ∧ classMass uniformWeight (Quotient.mk (relabelSetoid (1 + 2 + 0)) (bouquet 2 0))
1614          ≠ mu (bouquet 2 0) :=
1615  ⟨uniform_gluesGenerally, uniform_classMass_ne_mu⟩
1616
1617/-- Dust has a single labeled presentation per class: with no incidence data to move,
1618every relabeling returns the same complex. -/
1619theorem orbitCard_dust (n : ℕ) : gaugeOrbitCard (dust n) = 1 := by
1620  have h := orbitCard_mul_autCard (dust n)
1621  rw [autCard_dust] at h
1622  have hd : (dust n).nV = n ∧ (dust n).nE = 0 ∧ (dust n).nT = 0 := ⟨rfl, rfl, rfl⟩
1623  rw [hd.1, hd.2.1, hd.2.2] at h
1624  simp only [Nat.factorial_zero, mul_one, one_mul] at h
1625  exact Nat.eq_of_mul_eq_mul_right (Nat.factorial_pos n) (by simpa using h)
1626
1627/-- The class mass of a size-blind weight on dust is just its value at that size. -/
1628theorem classMass_sizeWeight_dust (f : ℕ → ℕ → ℕ → ℝ) (n : ℕ) :
1629    classMass (sizeWeight f) (Quotient.mk (relabelSetoid n) (dust n)) = f n 0 0 := by
1630  rw [classMass_of_invariant _ (fun _ _ h => sizeWeight_invariant f h) _,
1631    sizeWeight_invariant f (equivalent_out (dust n)), orbitCardClass_mk, orbitCard_dust]
1632  unfold sizeWeight
1633  norm_num
1634
1635namespace CarrierShuffle
1636
1637variable {f : ℕ → ℕ → ℕ → ℝ}
1638
1639/-- **THEOREM (the derived weight predicts the region the premise excludes).**  Premise
1640(ii) says nothing about `dust a ⊔ dust b`, since the two parts share a component.  The
1641weight forced by the two premises satisfies the binomial-corrected gluing identity
1642there anyway, matching `mu`'s own behaviour from C3 exactly.
1643
1644This is the non-circularity receipt.  Had the side condition been reverse-engineered to
1645carve out the cases where the wanted answer fails, the excluded region would be where
1646the derivation breaks.  Instead it is where the derivation is confirmed. -/
1647theorem excludedRegion_predicted (h : CarrierShuffle f) (a b : ℕ) :
1648    classMass (sizeWeight f) (Quotient.mk (relabelSetoid (a + b)) (dust (a + b)))
1649        * (Nat.choose (a + b) a : ℝ)
1650      = classMass (sizeWeight f) (Quotient.mk (relabelSetoid a) (dust a))
1651        * classMass (sizeWeight f) (Quotient.mk (relabelSetoid b) (dust b)) := by
1652  rw [classMass_sizeWeight_dust, classMass_sizeWeight_dust, classMass_sizeWeight_dust]
1653  have hA := dustRow h a
1654  have hB := dustRow h b
1655  have hAB := dustRow h (a + b)
1656  have hchoose : (Nat.choose (a + b) a : ℝ) * (Nat.factorial a : ℝ) * (Nat.factorial b : ℝ)
1657      = (Nat.factorial (a + b) : ℝ) := by
1658    have hn : a ≤ a + b := Nat.le_add_right a b
1659    have hsub : a + b - a = b := by omega
1660    have := Nat.choose_mul_factorial_mul_factorial hn
1661    rw [hsub] at this
1662    exact_mod_cast congrArg (fun n : ℕ => (n : ℝ)) this
1663  have hfa : (Nat.factorial a : ℝ) ≠ 0 := by
1664    exact_mod_cast (Nat.factorial_pos a).ne'
1665  have hfb : (Nat.factorial b : ℝ) ≠ 0 := by
1666    exact_mod_cast (Nat.factorial_pos b).ne'
1667  refine mul_right_cancel₀ (mul_ne_zero hfa hfb) ?_
1668  calc f (a + b) 0 0 * (Nat.choose (a + b) a : ℝ)
1669        * ((Nat.factorial a : ℝ) * (Nat.factorial b : ℝ))
1670      = f (a + b) 0 0 * ((Nat.choose (a + b) a : ℝ) * (Nat.factorial a : ℝ)
1671          * (Nat.factorial b : ℝ)) := by ring
1672    _ = f (a + b) 0 0 * (Nat.factorial (a + b) : ℝ) := by rw [hchoose]
1673    _ = (f 1 0 0) ^ (a + b) := hAB
1674    _ = (f 1 0 0) ^ a * (f 1 0 0) ^ b := by rw [pow_add]
1675    _ = (f a 0 0 * (Nat.factorial a : ℝ)) * (f b 0 0 * (Nat.factorial b : ℝ)) := by
1676        rw [hA, hB]
1677    _ = f a 0 0 * f b 0 0 * ((Nat.factorial a : ℝ) * (Nat.factorial b : ℝ)) := by ring
1678
1679end CarrierShuffle
1680
1681/-! ## §9. The side condition is forced, not chosen
1682
1683The sharpest charge against §5 is that the side condition on premise (ii) was
1684reverse-engineered: keep the pairs where the wanted answer survives, drop the rest.
1685Two compiled facts answer it, in place of an argument.
1686
1687First, the premise set is **satisfiable**, and satisfied at the intended point: the
1688inverse gauge volume, which is the size function of `gibbsWeight`, meets all four
1689gluing instances with all three constants equal to one.  So §6 is not vacuously true.
1690
1691Second, the **unrestricted** premise is *inconsistent* with size-blindness and
1692positivity.  Not "inconsistent with `mu`", which is §3 and invites the reply that the
1693cases where the answer fails were deleted.  Inconsistent full stop, on a statement
1694mentioning no measure, no automorphism count, and no factorial.  The four instances
1695the carrier supplies force the vertex recursion, which divides by the new vertex
1696count; unrestricted gluing applied to two piles of dust does not divide.
1697
1698Together: the restriction is the boundary of consistency of the two premises, fixed
1699before any measure enters.  It could not have been chosen otherwise, so it cannot have
1700been fitted to an answer. -/
1701
1702/-- The size function of the Gibbs weight: the inverse gauge volume. -/
1703noncomputable def gibbsSize (a b c : ℕ) : ℝ :=
1704  1 / ((Nat.factorial a : ℝ) * (Nat.factorial b : ℝ) * (Nat.factorial c : ℝ))
1705
1706theorem factorial_cast_pos (n : ℕ) : (0 : ℝ) < (Nat.factorial n : ℝ) := by
1707  exact_mod_cast Nat.factorial_pos n
1708
1709theorem gibbsSize_pos (a b c : ℕ) : 0 < gibbsSize a b c := by
1710  unfold gibbsSize
1711  have := factorial_cast_pos a
1712  have := factorial_cast_pos b
1713  have := factorial_cast_pos c
1714  positivity
1715
1716theorem gibbsSize_eq_inv_gaugeVol (a b c : ℕ) :
1717    gibbsSize a b c = 1 / (gaugeVol a b c : ℝ) := by
1718  unfold gibbsSize gaugeVol
1719  push_cast
1720  ring
1721
1722theorem gaugeVol_cast_pos (a b c : ℕ) : (0 : ℝ) < (gaugeVol a b c : ℝ) := by
1723  exact_mod_cast gaugeVol_pos a b c
1724
1725/-- **THEOREM (the inverse gauge volume satisfies the shuffle identity at every
1726pair).**  This is `gaugeVol_add` read as a statement about weights: the gauge volume
1727of a sum of size triples exceeds the product by exactly the interleaving count, so its
1728reciprocal shuffles.  No side condition and no hypothesis. -/
1729theorem gibbsSize_shuffle (a b c a' b' c' : ℕ) :
1730    gibbsSize (a + a') (b + b') (c + c') * (interleave a b c a' b' c' : ℝ)
1731      = gibbsSize a b c * gibbsSize a' b' c' := by
1732  rw [gibbsSize_eq_inv_gaugeVol, gibbsSize_eq_inv_gaugeVol, gibbsSize_eq_inv_gaugeVol,
1733    gaugeVol_add a b c a' b' c']
1734  have h1 := gaugeVol_cast_pos a b c
1735  have h2 := gaugeVol_cast_pos a' b' c'
1736  have h3 : (0 : ℝ) < (interleave a b c a' b' c' : ℝ) := by
1737    exact_mod_cast interleave_pos a b c a' b' c'
1738  push_cast
1739  field_simp
1740
1741/-- **THEOREM (the premise set is satisfiable, at the intended point).**  The inverse
1742gauge volume satisfies all four gluing instances.  Since `gibbsSize 1 0 0`,
1743`gibbsSize 1 1 0` and `gibbsSize 1 0 1` are all one, §6's three constants are attained
1744at unity, so `gibbs_of_unit_fugacities` has a witness and the derivation is not
1745vacuously true. -/
1746theorem gibbsSize_carrierShuffle : CarrierShuffle gibbsSize where
1747  pos := gibbsSize_pos
1748  unit := by norm_num [gibbsSize]
1749  dust_bouquet := by
1750    intro a b c _
1751    simpa [Nat.zero_add] using gibbsSize_shuffle a 0 0 1 b c
1752  dust_edge := by
1753    intro a
1754    simpa [Nat.zero_add] using gibbsSize_shuffle a 0 0 2 1 0
1755  bouquet_edge := by
1756    intro b c
1757    simpa [Nat.add_zero] using gibbsSize_shuffle 1 b c 2 1 0
1758  bouquet_tet := by
1759    intro b c
1760    simpa [Nat.add_zero] using gibbsSize_shuffle 1 b c 4 0 1
1761
1762/-- **Premise (ii) with no side condition**: class mass multiplies over every disjoint
1763union, whatever the parts. -/
1764def GluesEverywhere (f : ℕ → ℕ → ℕ → ℝ) : Prop :=
1765  ∀ {B B' : ℕ} (K : BoundedComplex B) (L : BoundedComplex B'), GluesAt f K L
1766
1767/-- Under the unrestricted premise, dust glues with no binomial correction at all. -/
1768theorem dust_glues_plainly (f : ℕ → ℕ → ℕ → ℝ) (hplain : GluesEverywhere f) (a b : ℕ) :
1769    f (a + b) 0 0 = f a 0 0 * f b 0 0 := by
1770  have h := hplain (dust a) (dust b)
1771  unfold GluesAt at h
1772  rw [show Quotient.mk (relabelSetoid (a + b)) (dunion (dust a) (dust b))
1773        = Quotient.mk (relabelSetoid (a + b)) (dust (a + b)) from
1774      Quotient.sound (dunion_dust_equivalent a b)] at h
1775  rw [classMass_sizeWeight_dust, classMass_sizeWeight_dust,
1776    classMass_sizeWeight_dust] at h
1777  exact h
1778
1779/-- **THEOREM (the unrestricted premise is inconsistent, and the statement never
1780mentions the measure).**  No positive size-blind weight satisfies the four gluing
1781instances the carrier supplies *and* gluing at every pair.  The first forces
1782`f(a+1,0,0)·(a+1) = f(a,0,0)·f(1,0,0)`; the second forces
1783`f(a+b,0,0) = f(a,0,0)·f(b,0,0)`; at `a = b = 1` these give `2x² = x²`, so `x = 0`,
1784against positivity.
1785
1786This is the receipt that the side condition is forced rather than fitted.  §3 showed
1787that `mu` fails unrestricted gluing, which leaves open the reply that the failing cases
1788were simply excluded.  This shows the *premises* fail unrestricted gluing, with no
1789measure named, so the exclusion is prior to any answer. -/
1790theorem unrestricted_gluing_inconsistent (f : ℕ → ℕ → ℕ → ℝ)
1791    (h : CarrierShuffle f) (hplain : GluesEverywhere f) : False := by
1792  have h1 := CarrierShuffle.vertexRec h 1
1793  have h2 := dust_glues_plainly f hplain 1 1
1794  have hpos := h.pos 1 0 0
1795  norm_num at h1 h2
1796  nlinarith [h1, h2, hpos]
1797
1798/-- **THEOREM (some restriction is mandatory).**  The restricted premise is
1799satisfiable, by the inverse gauge volume; the unrestricted premise is satisfied by
1800nothing.  So a restriction on premise (ii) is not a convenience: dropping it entirely
1801makes the premise set empty.
1802
1803Read the scope exactly.  This says a restriction is *necessary*.  It does not say the
1804particular restriction used here is the *only* one that would restore consistency, and
1805several others plainly would.  What removes the remaining worry is not this theorem but
1806`all_four_families_available`: the derivation consumes four named instances, each of
1807them proved, so it never depends on where the general boundary is drawn. -/
1808theorem restriction_is_mandatory :
1809    CarrierShuffle gibbsSize ∧ (∀ f : ℕ → ℕ → ℕ → ℝ, CarrierShuffle f → ¬ GluesEverywhere f) :=
1810  ⟨gibbsSize_carrierShuffle, fun f h hp => unrestricted_gluing_inconsistent f h hp⟩
1811
1812/-! ## §9a. The transport runs both ways, and which size triples exist
1813
1814Two gaps a second hostile read found in the write-up, both closed here rather than
1815hedged in prose.  The first: `shuffle_of_gluesAt` proves the premise implies the
1816shuffle identity, so `CarrierShuffle` was only known to be *implied by* premise (ii),
1817and a reader was entitled to say the structure is four algebraic equations rather than
1818the premise.  At an eligible pair the transport is an equivalence, so the converse is
1819the same algebra run backwards.  The second: `closedForm` says nothing at triples with
1820no vertex, which is harmless only because the carrier cannot realize them, and that
1821fact was assumed rather than proved. -/
1822
1823/-- **THEOREM (the transport is an equivalence at an eligible pair).**  Converse of
1824`shuffle_of_gluesAt`.  Together they say that at a pair where automorphism counts
1825multiply, the shuffle identity on the size function and premise (ii) on the class mass
1826are the same statement, so `CarrierShuffle` is the premise at those four families and
1827not merely a consequence of it. -/
1828theorem gluesAt_of_shuffle (f : ℕ → ℕ → ℕ → ℝ) {B B' : ℕ}
1829    (K : BoundedComplex B) (L : BoundedComplex B')
1830    (haut : Nat.card (Aut (dunion K L)) = Nat.card (Aut K) * Nat.card (Aut L))
1831    (hsh : f (K.nV + L.nV) (K.nE + L.nE) (K.nT + L.nT)
1832            * (interleave K.nV K.nE K.nT L.nV L.nE L.nT : ℝ)
1833          = f K.nV K.nE K.nT * f L.nV L.nE L.nT) :
1834    GluesAt f K L := by
1835  have hob := orbitCard_dunion_of_autMul K L haut
1836  unfold GluesAt
1837  rw [classMass_sizeWeight, classMass_sizeWeight, classMass_sizeWeight]
1838  simp only [dunion_nV, dunion_nE, dunion_nT]
1839  rw [hob]
1840  push_cast
1841  calc (interleave K.nV K.nE K.nT L.nV L.nE L.nT : ℝ)
1842        * ((gaugeOrbitCard K : ℝ) * (gaugeOrbitCard L : ℝ))
1843        * f (K.nV + L.nV) (K.nE + L.nE) (K.nT + L.nT)
1844      = (f (K.nV + L.nV) (K.nE + L.nE) (K.nT + L.nT)
1845          * (interleave K.nV K.nE K.nT L.nV L.nE L.nT : ℝ))
1846        * ((gaugeOrbitCard K : ℝ) * (gaugeOrbitCard L : ℝ)) := by ring
1847    _ = (f K.nV K.nE K.nT * f L.nV L.nE L.nT)
1848        * ((gaugeOrbitCard K : ℝ) * (gaugeOrbitCard L : ℝ)) := by rw [hsh]
1849    _ = (gaugeOrbitCard K : ℝ) * f K.nV K.nE K.nT
1850        * ((gaugeOrbitCard L : ℝ) * f L.nV L.nE L.nT) := by ring
1851
1852/-- **THEOREM (any incidence needs a vertex to carry it).**  A complex with an edge or
1853a tetrahedron has at least one vertex, since both incidence maps land in `Fin nV` and
1854that type is empty when `nV = 0`.  So the size triples the carrier realizes all have
1855`1 ≤ nV`, which is exactly the hypothesis `closedForm` carries: the closed form pins
1856the size function at every triple that any complex actually has, and its silence at
1857`(0, b, c)` with `b + c ≥ 1` is silence about sizes nothing can have. -/
1858theorem vertex_of_incidence {B : ℕ} (K : BoundedComplex B) (h : 1 ≤ K.nE + K.nT) :
1859    1 ≤ K.nV := by
1860  by_contra hv
1861  push_neg at hv
1862  have hv0 : K.nV = 0 := by omega
1863  rcases Nat.lt_or_ge 0 K.nE with he | he
1864  · have hx := (K.edgeVerts ⟨0, he⟩).1.isLt
1865    omega
1866  · have ht : 0 < K.nT := by omega
1867    have hx := (K.tetVerts ⟨0, ht⟩ 0).isLt
1868    omega
1869
1870/-- The closed form applies to every complex the carrier contains: either it has a
1871vertex, or it is the empty complex, where `unit` already gives the value. -/
1872theorem closedForm_or_empty {f : ℕ → ℕ → ℕ → ℝ} (h : CarrierShuffle f) {B : ℕ}
1873    (K : BoundedComplex B) :
1874    (1 ≤ K.nV) ∨ (K.nV = 0 ∧ K.nE = 0 ∧ K.nT = 0) := by
1875  rcases Nat.lt_or_ge 0 (K.nE + K.nT) with hi | hi
1876  · exact Or.inl (vertex_of_incidence K hi)
1877  · rcases Nat.lt_or_ge 0 K.nV with hv | hv
1878    · exact Or.inl hv
1879    · exact Or.inr ⟨by omega, by omega, by omega⟩
1880
1881/-! ## §9b. Where the symmetry factor actually comes from
1882
1883Added 2026-07-28 after a hostile read of the write-up located a misattribution in
1884the headline, not in any proof.  The natural summary of this module, "two premises
1885force the class measure to `1/|Aut|` up to three constants", credits the wrong
1886premise with the `1/|Aut|`.  The two theorems below measure it instead of asserting
1887it, and the first of them deflates the headline.  Keep them next to the derivation
1888so the next reader cannot restate it the old way. -/
1889
1890/-- The **sector fugacity** of a size-blind weight: the gauge volume of a size triple
1891times the weight there.  It is everything about a size-blind weight that
1892orbit-stabilizer has not already fixed. -/
1893noncomputable def fugacityOf (f : ℕ → ℕ → ℕ → ℝ) (a b c : ℕ) : ℝ :=
1894  (gaugeVol a b c : ℝ) * f a b c
1895
1896/-- **THEOREM (premise (i) alone already produces the symmetry factor).**  For *any*
1897size-blind weight whatever, positive or not, normalized or not, the class mass of a
1898class is its sector fugacity divided by the automorphism count.  The only inputs are
1899premise (i) and `orbitCard_mul_autCard`, which the carrier had before this module
1900existed.  No gluing premise is used, and none is even available at this point.
1901
1902The consequence for the derivation is worth stating flatly, because it is easy to
1903claim the opposite.  The `1/|Aut K|` dependence is a consequence of size-blindness.
1904Premise (ii) does not produce it and could not, since it is already here before
1905premise (ii) is stated.  What premise (ii) does is force `fugacityOf f` to be a
1906character rather than an arbitrary function of the three sizes, which is the content
1907of `closedForm`; and the unit character is what makes the constant one. -/
1908theorem classMass_sizeWeight_eq_fugacity_div_autCard
1909    (f : ℕ → ℕ → ℕ → ℝ) {B : ℕ} (K : BoundedComplex B) :
1910    classMass (sizeWeight f) (Quotient.mk (relabelSetoid B) K)
1911      = fugacityOf f K.nV K.nE K.nT / (Nat.card (Aut K) : ℝ) := by
1912  have hmul : (gaugeOrbitCard K : ℝ) * (Nat.card (Aut K) : ℝ)
1913      = (gaugeVol K.nV K.nE K.nT : ℝ) := by
1914    have h := orbitCard_mul_autCard K
1915    unfold gaugeVol
1916    exact_mod_cast h
1917  have hA : (0 : ℝ) < (Nat.card (Aut K) : ℝ) := by
1918    exact_mod_cast autCard_pos K
1919  rw [classMass_sizeWeight, eq_div_iff hA.ne', fugacityOf]
1920  calc (gaugeOrbitCard K : ℝ) * f K.nV K.nE K.nT * (Nat.card (Aut K) : ℝ)
1921      = ((gaugeOrbitCard K : ℝ) * (Nat.card (Aut K) : ℝ)) * f K.nV K.nE K.nT := by ring
1922    _ = (gaugeVol K.nV K.nE K.nT : ℝ) * f K.nV K.nE K.nT := by rw [hmul]
1923
1924/-- The **character weights**: one positive number per index type, spread over the
1925gauge volume.  `gibbsSize` is the member with all three equal to one. -/
1926noncomputable def characterSize (u v w : ℝ) (a b c : ℕ) : ℝ :=
1927  (u ^ a * v ^ b * w ^ c) / (gaugeVol a b c : ℝ)
1928
1929theorem characterSize_shuffle (u v w : ℝ) (a b c a' b' c' : ℕ) :
1930    characterSize u v w (a + a') (b + b') (c + c') * (interleave a b c a' b' c' : ℝ)
1931      = characterSize u v w a b c * characterSize u v w a' b' c' := by
1932  unfold characterSize
1933  rw [gaugeVol_add a b c a' b' c']
1934  have h1 := gaugeVol_cast_pos a b c
1935  have h2 := gaugeVol_cast_pos a' b' c'
1936  have h3 : (0 : ℝ) < (interleave a b c a' b' c' : ℝ) := by
1937    exact_mod_cast interleave_pos a b c a' b' c'
1938  push_cast
1939  field_simp
1940  ring
1941
1942theorem characterSize_carrierShuffle {u v w : ℝ} (hu : 0 < u) (hv : 0 < v) (hw : 0 < w) :
1943    CarrierShuffle (characterSize u v w) where
1944  pos := by
1945    intro a b c
1946    unfold characterSize
1947    have := gaugeVol_cast_pos a b c
1948    positivity
1949  unit := by norm_num [characterSize, gaugeVol]
1950  dust_bouquet := by
1951    intro a b c _
1952    simpa [Nat.zero_add] using characterSize_shuffle u v w a 0 0 1 b c
1953  dust_edge := by
1954    intro a
1955    simpa [Nat.zero_add] using characterSize_shuffle u v w a 0 0 2 1 0
1956  bouquet_edge := by
1957    intro b c
1958    simpa [Nat.add_zero] using characterSize_shuffle u v w 1 b c 2 1 0
1959  bouquet_tet := by
1960    intro b c
1961    simpa [Nat.add_zero] using characterSize_shuffle u v w 1 b c 4 0 1
1962
1963theorem gibbsSize_eq_characterSize_one : gibbsSize = characterSize 1 1 1 := by
1964  funext a b c
1965  rw [gibbsSize_eq_inv_gaugeVol]
1966  unfold characterSize
1967  norm_num
1968
1969/-- **THEOREM (the residue is exactly three positive constants, not at most three).**
1970Forward, `closedForm`: every solution of the premise set has the three-constant form.
1971Backward: every positive triple is realized by an actual solution.  Both directions
1972are needed before the residue can be called a three-parameter family, and the
1973backward one also settles a question about strategy: no further gluing family can
1974ever shrink the residue, because the whole three-parameter family satisfies the
1975shuffle identity at every pair unconditionally, by `characterSize_shuffle`. -/
1976theorem residue_is_exactly_three_positive_constants :
1977    (∀ f : ℕ → ℕ → ℕ → ℝ, CarrierShuffle f → ∀ a b c : ℕ, 1 ≤ a →
1978        f a b c * ((Nat.factorial a : ℝ) * (Nat.factorial b : ℝ) * (Nat.factorial c : ℝ))
1979            * (f 1 0 0) ^ (b + c)
1980          = (f 1 0 0) ^ a * (f 1 1 0) ^ b * (f 1 0 1) ^ c)
1981      ∧ (∀ u v w : ℝ, 0 < u → 0 < v → 0 < w → CarrierShuffle (characterSize u v w)) :=
1982  ⟨fun _ h a b c ha => h.closedForm a b c ha,
1983    fun _ _ _ hu hv hw => characterSize_carrierShuffle hu hv hw⟩
1984
1985/-! ## §10. Certificate: what is derived, what is assumed, what remains -/
1986
1987/-- The state of the gluing route after this module. -/
1988structure GluingStatus where
1989  /-- The carrier now carries a disjoint union (previously recorded as missing). -/
1990  dunion_exists : Bool
1991  /-- The interleaving count is binomial, as pure arithmetic on gauge volumes. -/
1992  interleaving_binomial : Bool
1993  /-- Unrestricted gluing multiplicativity is refuted against `mu` itself. -/
1994  unrestricted_gluing_refuted : Bool
1995  /-- Automorphism multiplicativity is the exact residue for transporting the
1996  binomial identity to orbit counts. -/
1997  autmul_is_the_residue : Bool
1998  /-- Size-blindness plus gluing is exactly the shuffle identity where `Aut`
1999  multiplies. -/
2000  premises_give_shuffle : Bool
2001  /-- The two premises force the weight up to three constants. -/
2002  three_constants : Bool
2003  /-- Unit values for those three constants give exactly `gibbsWeight`. -/
2004  units_give_gibbs : Bool
2005  /-- One nontrivial family of gluing instances is verified available. -/
2006  availability_witnessed : Bool
2007  /-- All four gluing instances the premise set uses are verified available, each over
2008  an unbounded family. -/
2009  all_four_families_available : Bool
2010  /-- Measured: premise (ii) alone excludes nothing, so premise (i) carries the force. -/
2011  gluing_alone_is_empty : Bool
2012  /-- Measured: the derived weight predicts the region premise (ii) declines to
2013  speak about, which is the non-circularity receipt. -/
2014  excluded_region_predicted : Bool
2015  /-- The premise set is satisfiable, and satisfied at the intended unit point. -/
2016  premises_satisfiable : Bool
2017  /-- The unrestricted premise is satisfied by nothing, so some restriction on
2018  premise (ii) is mandatory rather than a carve-out. -/
2019  restriction_is_mandatory : Bool
2020  /-- NOT proved: the general no-mixing theorem for parts sharing no isomorphic
2021  component. -/
2022  general_autmul_formalized : Bool
2023  /-- NOT proved: that the three constants must equal one. -/
2024  three_constants_forced : Bool
2025
2026/-- Status after this module. -/
2027def gluingStatus : GluingStatus where
2028  dunion_exists := true
2029  interleaving_binomial := true
2030  unrestricted_gluing_refuted := true
2031  autmul_is_the_residue := true
2032  premises_give_shuffle := true
2033  three_constants := true
2034  units_give_gibbs := true
2035  availability_witnessed := true
2036  all_four_families_available := true
2037  gluing_alone_is_empty := true
2038  excluded_region_predicted := true
2039  premises_satisfiable := true
2040  restriction_is_mandatory := true
2041  general_autmul_formalized := false
2042  three_constants_forced := false
2043
2044theorem status_dunion : gluingStatus.dunion_exists = true := rfl
2045theorem status_binomial : gluingStatus.interleaving_binomial = true := rfl
2046theorem status_refuted : gluingStatus.unrestricted_gluing_refuted = true := rfl
2047theorem status_residue : gluingStatus.autmul_is_the_residue = true := rfl
2048theorem status_shuffle : gluingStatus.premises_give_shuffle = true := rfl
2049theorem status_three : gluingStatus.three_constants = true := rfl
2050theorem status_units : gluingStatus.units_give_gibbs = true := rfl
2051theorem status_witness : gluingStatus.availability_witnessed = true := rfl
2052theorem status_all_four : gluingStatus.all_four_families_available = true := rfl
2053theorem status_gluing_empty : gluingStatus.gluing_alone_is_empty = true := rfl
2054theorem status_excluded : gluingStatus.excluded_region_predicted = true := rfl
2055theorem status_satisfiable : gluingStatus.premises_satisfiable = true := rfl
2056theorem status_forced : gluingStatus.restriction_is_mandatory = true := rfl
2057
2058/-- **The two honest negatives.**  The general no-mixing theorem is not formalized,
2059and nothing here forces the three constants to equal one.  Both flags are `false`
2060by construction, so the certificate cannot drift into claiming them. -/
2061theorem status_open :
2062    gluingStatus.general_autmul_formalized = false ∧
2063    gluingStatus.three_constants_forced = false :=
2064  ⟨rfl, rfl⟩
2065
2066end Gap2GluingDerivation
2067end SevenGaps
2068end Gravity
2069end IndisputableMonolith
2070

source mirrored from github.com/jonwashburn/shape-of-logic