diff --git a/Graphon.lean b/Graphon.lean index 2f1fb1f..943c7a9 100644 --- a/Graphon.lean +++ b/Graphon.lean @@ -22,8 +22,6 @@ import Graphon.Lovasz import Graphon.SimpleRank import Graphon.CycleKrylov import Graphon.MatrixDetermination -import Graphon.CaiGovorovOrbit -import Graphon.SimpleOrbitRank import Graphon.InverseCounting import Graphon.Convergence @@ -46,12 +44,10 @@ in Lean 4 using Mathlib. * `Graphon.Counting` — Homomorphism density, counting lemma * `Graphon.Compactness` — Total boundedness, completeness * `Graphon.CaiGovorov` — Graph-free Vandermonde argument (Cai–Govorov §4), for #70 orbit separation -* `Graphon.Lovasz` — Connection-matrix algebra scaffolding (Lovász §3) +* `Graphon.Lovasz` — Connection-matrix algebra scaffolding (Lovász §3), incl. the Cai–Govorov #70 orbit theorem and rank theorem * `Graphon.SimpleRank` — K=1 simple-graph rank theorem, algebra-atom framing (#70) * `Graphon.CycleKrylov` — spectral slice of the cycle–Krylov square-moment proof (#70) * `Graphon.MatrixDetermination` — Algebraic determination of step graphons -* `Graphon.CaiGovorovOrbit` — Cai–Govorov test graphs, super-surjective orbit theorem, eq. (10) (#70) -* `Graphon.SimpleOrbitRank` — #70 rank theorem: simple-eval span = orbit-invariant functions * `Graphon.InverseCounting` — Inverse counting lemma, convergence equivalence * `Graphon.Convergence` — Top-level convergence characterization diff --git a/Graphon/CaiGovorovOrbit.lean b/Graphon/CaiGovorovOrbit.lean deleted file mode 100644 index 233393a..0000000 --- a/Graphon/CaiGovorovOrbit.lean +++ /dev/null @@ -1,2054 +0,0 @@ -/- -Copyright (c) 2026 Cameron Freer. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Cameron Freer --/ -import Graphon.CycleKrylov -import Graphon.CaiGovorov -import Mathlib.Combinatorics.Pigeonhole - -/-! -# The Cai–Govorov simple-graph orbit theorem (#70) - -The full Cai–Govorov orbit-separation route for `#70`, culminating in the general -**`tupleEquivSimple_implies_orbit_general`**: equal simple-graph evaluations imply -weighted-automorphism orbit equivalence, with no surjectivity hypothesis. - -* **Test graphs + closed forms**: `starTestGraph S` (Gχ, one unlabeled vertex joined to - `S ⊆ Fin K`; eval `= ∑ₜ W t · ∏_{i∈S} B (ξ i) t`) and `edgeTestGraph Sₗ Sτ` (Gλτ, two - adjacent unlabeled vertices; the double-sum closed form). -* **Chunk 3A / 4A** — the super-surjective case, moment form - (`testEvalEq_implies_orbit_super` from the `TestEvalEq` star/edge interface, with the - `tupleEquivSimple_implies_orbit_super` wrapper): pigeonhole + bounded Vandermonde build - `superMap`/`superPerm`, edge moments certify it as a weighted automorphism, one-extra-label - moments reconcile all labels. -* **Chunk 3B** — eq. (10) `extension_sum_identity` (extension-family sums collapse via the - iterated trace) with the `superExt`/`coverExtra` super-surjective extension (plus the - documented separation corollary `not_tupleEquivSimple_of_not_orbit`, not on the live path). -* **Chunks 4B–4E** — the mult ≤ 1 `toSimple` bridge and `glueList` product law realize - test-moment powers as single simple graphs (`expTestGraph`), so eq. (10) yields the - power-moment identity `extension_power_moments`. -* **Chunks 4F–4G** — the descent: two-family Vandermonde matches an extension of `ξ'` - against `superExt ξ` (`exists_matching_extension`), the super-case runs at level - `K + T·2T²`, and restriction gives the general theorem. - -The rank endgame (`simpleEvalSubmodule_finrank_ge_orbitClass` and the collapse -`simpleEvalSubmodule = orbitInvariantSubmodule`) lives downstream in -`Graphon.SimpleOrbitRank`. The upstream `Lovasz.lean` sorry `tupleEquivSimple_implies_orbit` -(§3.10) states this file's general theorem; filling it in place would require relocating -this stack above Lovász §3.10 — a separate refactor, off the #70 critical path. --/ - -open Finset - -namespace Graphon.Lovasz - -variable {K : ℕ} - -/-- Embed label `i : Fin K` as the vertex of value `i` in `Fin (1 + K)`. -/ -def labVertex (i : Fin K) : Fin (1 + K) := ⟨(i : ℕ), by have := i.isLt; omega⟩ - -/-- The single unlabeled vertex (value `K`) in `Fin (1 + K)`. -/ -def unlVertex : Fin (1 + K) := ⟨K, by omega⟩ - -/-- **Cai–Govorov test graph Gχ**: the unlabeled vertex is joined to exactly the -labels in `S ⊆ Fin K`. -/ -def starTestGraph (S : Finset (Fin K)) : SimpleGraph (Fin (1 + K)) := - SimpleGraph.fromEdgeSet - ((S.image (fun i => s(labVertex i, unlVertex))) : Set (Sym2 (Fin (1 + K)))) - -noncomputable instance (S : Finset (Fin K)) : DecidableRel (starTestGraph S).Adj := - Classical.decRel _ - -theorem labVertex_ne_unlVertex (i : Fin K) : labVertex i ≠ unlVertex := by - intro h - have := congrArg Fin.val h - simp only [labVertex, unlVertex] at this - have := i.isLt; omega - -theorem starTestGraph_edge_injOn (S : Finset (Fin K)) : - ∀ i ∈ S, ∀ i' ∈ S, s(labVertex i, unlVertex) = s(labVertex i', unlVertex) → i = i' := by - intro i _ i' _ heq - rw [Sym2.eq_iff] at heq - rcases heq with ⟨h1, _⟩ | ⟨h1, _⟩ - · apply Fin.ext - have := congrArg Fin.val h1 - simpa [labVertex] using this - · exact absurd h1 (labVertex_ne_unlVertex i) - -theorem starTestGraph_edgeFinset (S : Finset (Fin K)) : - (starTestGraph S).edgeFinset = S.image (fun i => s(labVertex i, unlVertex)) := by - ext e - simp only [SimpleGraph.mem_edgeFinset, starTestGraph, SimpleGraph.edgeSet_fromEdgeSet, - Set.mem_sdiff, Finset.coe_image, Set.mem_image, Finset.mem_coe, Sym2.mem_diagSet, - Finset.mem_image] - constructor - · rintro ⟨⟨i, hi, rfl⟩, _⟩; exact ⟨i, hi, rfl⟩ - · rintro ⟨i, hi, rfl⟩ - refine ⟨⟨i, hi, rfl⟩, ?_⟩ - rw [Sym2.mk_isDiag_iff] - exact labVertex_ne_unlVertex i - -/-- The `simpleEvalAt` label map sends `labVertex i` to `ξ i` (stated in the -beta-reduced `dite` form produced by `out_pair_eq'`). -/ -theorem tau_apply_labVertex {T : ℕ} (ξ : Fin K → Fin T) (σ : Fin 1 → Fin T) (i : Fin K) : - (if h : ((labVertex i : Fin (1 + K)) : ℕ) < K then ξ ⟨↑(labVertex i), h⟩ - else σ ⟨↑(labVertex i) - K, by have := (labVertex i).isLt; omega⟩) = ξ i := by - rw [dif_pos (show ((labVertex i : Fin (1 + K)) : ℕ) < K from i.isLt)] - congr 1 - -/-- The `simpleEvalAt` label map sends `unlVertex` to `σ 0` (beta-reduced `dite` form). -/ -theorem tau_apply_unlVertex {T : ℕ} (ξ : Fin K → Fin T) (σ : Fin 1 → Fin T) : - (if h : ((unlVertex : Fin (1 + K)) : ℕ) < K then ξ ⟨↑(unlVertex : Fin (1 + K)), h⟩ - else σ ⟨↑(unlVertex : Fin (1 + K)) - K, by have := (unlVertex : Fin (1 + K)).isLt; omega⟩) - = σ 0 := by - rw [dif_neg (show ¬ ((unlVertex : Fin (1 + K)) : ℕ) < K from by simp [unlVertex])] - congr 1 - apply Fin.ext - simp [unlVertex] - -/-- **Closed form for Gχ**: `simpleEvalAt B W (starTestGraph S) ξ = ∑ₜ W t · ∏_{i∈S} B (ξ i) t`. -/ -theorem simpleEvalAt_starTestGraph {T : ℕ} (B : Fin T → Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (S : Finset (Fin K)) (ξ : Fin K → Fin T) : - simpleEvalAt B W (starTestGraph S) ξ = ∑ t, W t * ∏ i ∈ S, B (ξ i) t := by - rw [show (∑ t, W t * ∏ i ∈ S, B (ξ i) t) - = ∑ σ : Fin 1 → Fin T, W (σ 0) * ∏ i ∈ S, B (ξ i) (σ 0) from - (Equiv.sum_comp (Equiv.funUnique (Fin 1) (Fin T)) - (fun t => W t * ∏ i ∈ S, B (ξ i) t)).symm] - unfold simpleEvalAt - refine Finset.sum_congr rfl fun σ _ => ?_ - rw [starTestGraph_edgeFinset] - show (∏ v : Fin 1, W (σ v)) * - ∏ e ∈ S.image (fun i => s(labVertex i, unlVertex)), - B ((fun v : Fin (1 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩) (Quot.out e).1) - ((fun v : Fin (1 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩) (Quot.out e).2) - = W (σ 0) * ∏ i ∈ S, B (ξ i) (σ 0) - rw [Fin.prod_univ_one, Finset.prod_image (starTestGraph_edge_injOn S)] - congr 1 - refine Finset.prod_congr rfl fun i _ => ?_ - rw [out_pair_eq' B hB (fun v : Fin (1 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩) (labVertex i) unlVertex, - tau_apply_labVertex ξ σ i, tau_apply_unlVertex ξ σ] - -/-! ## Cai–Govorov edge-test graph Gλτ (two unlabeled vertices) -/ - -/-- Embed label `i : Fin K` as the vertex of value `i` in `Fin (2 + K)`. -/ -def labVertex2 (i : Fin K) : Fin (2 + K) := ⟨(i : ℕ), by have := i.isLt; omega⟩ - -/-- The first unlabeled vertex (value `K`, mapped to `σ 0`) in `Fin (2 + K)`. -/ -def unlVertex0 : Fin (2 + K) := ⟨K, by omega⟩ - -/-- The second unlabeled vertex (value `K + 1`, mapped to `σ 1`) in `Fin (2 + K)`. -/ -def unlVertex1 : Fin (2 + K) := ⟨K + 1, by omega⟩ - -/-- **Cai–Govorov edge-test graph Gλτ**: the two unlabeled vertices are joined to each -other, vertex `0` is joined to the labels in `Sₗ`, and vertex `1` to the labels in `Sτ`. -/ -def edgeTestGraph (Sₗ Sτ : Finset (Fin K)) : SimpleGraph (Fin (2 + K)) := - SimpleGraph.fromEdgeSet - ((insert s(unlVertex0, unlVertex1) - (Sₗ.image (fun i => s(labVertex2 i, unlVertex0)) ∪ - Sτ.image (fun i => s(labVertex2 i, unlVertex1)))) : Set (Sym2 (Fin (2 + K)))) - -noncomputable instance (Sₗ Sτ : Finset (Fin K)) : - DecidableRel (edgeTestGraph Sₗ Sτ).Adj := Classical.decRel _ - -theorem labVertex2_ne_unlVertex0 (i : Fin K) : labVertex2 i ≠ unlVertex0 := by - intro h - have := congrArg Fin.val h - simp only [labVertex2, unlVertex0] at this - have := i.isLt; omega - -theorem labVertex2_ne_unlVertex1 (i : Fin K) : labVertex2 i ≠ unlVertex1 := by - intro h - have := congrArg Fin.val h - simp only [labVertex2, unlVertex1] at this - have := i.isLt; omega - -theorem unlVertex0_ne_unlVertex1 : (unlVertex0 : Fin (2 + K)) ≠ unlVertex1 := by - intro h - have := congrArg Fin.val h - simp only [unlVertex0, unlVertex1] at this - omega - -theorem edgeTestGraph_edge_injOn_Sₗ (Sₗ : Finset (Fin K)) : - ∀ i ∈ Sₗ, ∀ i' ∈ Sₗ, - s(labVertex2 i, unlVertex0) = s(labVertex2 i', unlVertex0) → i = i' := by - intro i _ i' _ heq - rw [Sym2.eq_iff] at heq - rcases heq with ⟨h1, _⟩ | ⟨h1, _⟩ - · apply Fin.ext - have := congrArg Fin.val h1 - simpa [labVertex2] using this - · exact absurd h1 (labVertex2_ne_unlVertex0 i) - -theorem edgeTestGraph_edge_injOn_Sτ (Sτ : Finset (Fin K)) : - ∀ i ∈ Sτ, ∀ i' ∈ Sτ, - s(labVertex2 i, unlVertex1) = s(labVertex2 i', unlVertex1) → i = i' := by - intro i _ i' _ heq - rw [Sym2.eq_iff] at heq - rcases heq with ⟨h1, _⟩ | ⟨h1, _⟩ - · apply Fin.ext - have := congrArg Fin.val h1 - simpa [labVertex2] using this - · exact absurd h1 (labVertex2_ne_unlVertex1 i) - -theorem edgeTestGraph_edgeFinset (Sₗ Sτ : Finset (Fin K)) : - (edgeTestGraph Sₗ Sτ).edgeFinset = - insert s(unlVertex0, unlVertex1) - (Sₗ.image (fun i => s(labVertex2 i, unlVertex0)) ∪ - Sτ.image (fun i => s(labVertex2 i, unlVertex1))) := by - ext e - simp only [SimpleGraph.mem_edgeFinset, edgeTestGraph, SimpleGraph.edgeSet_fromEdgeSet, - Set.mem_sdiff, Set.mem_insert_iff, Set.mem_union, Finset.coe_image, Set.mem_image, - Finset.mem_coe, Sym2.mem_diagSet, Finset.mem_insert, Finset.mem_union, Finset.mem_image] - constructor - · rintro ⟨h, -⟩; exact h - · intro h - refine ⟨h, ?_⟩ - rcases h with heq | ⟨i, _, heq⟩ | ⟨i, _, heq⟩ - · rw [heq, Sym2.mk_isDiag_iff]; exact unlVertex0_ne_unlVertex1 - · rw [← heq, Sym2.mk_isDiag_iff]; exact labVertex2_ne_unlVertex0 i - · rw [← heq, Sym2.mk_isDiag_iff]; exact labVertex2_ne_unlVertex1 i - -/-- `simpleEvalAt` label map: `labVertex2 i ↦ ξ i` (beta-reduced `dite` form). -/ -theorem tau2_apply_labVertex2 {T : ℕ} (ξ : Fin K → Fin T) (σ : Fin 2 → Fin T) (i : Fin K) : - (if h : ((labVertex2 i : Fin (2 + K)) : ℕ) < K then ξ ⟨↑(labVertex2 i), h⟩ - else σ ⟨↑(labVertex2 i) - K, by have := (labVertex2 i).isLt; omega⟩) = ξ i := by - rw [dif_pos (show ((labVertex2 i : Fin (2 + K)) : ℕ) < K from i.isLt)] - congr 1 - -/-- `simpleEvalAt` label map: `unlVertex0 ↦ σ 0` (beta-reduced `dite` form). -/ -theorem tau2_apply_unlVertex0 {T : ℕ} (ξ : Fin K → Fin T) (σ : Fin 2 → Fin T) : - (if h : ((unlVertex0 : Fin (2 + K)) : ℕ) < K then ξ ⟨↑(unlVertex0 : Fin (2 + K)), h⟩ - else σ ⟨↑(unlVertex0 : Fin (2 + K)) - K, - by have := (unlVertex0 : Fin (2 + K)).isLt; omega⟩) = σ 0 := by - rw [dif_neg (show ¬ ((unlVertex0 : Fin (2 + K)) : ℕ) < K from by simp [unlVertex0])] - congr 1 - apply Fin.ext - simp [unlVertex0] - -/-- `simpleEvalAt` label map: `unlVertex1 ↦ σ 1` (beta-reduced `dite` form). -/ -theorem tau2_apply_unlVertex1 {T : ℕ} (ξ : Fin K → Fin T) (σ : Fin 2 → Fin T) : - (if h : ((unlVertex1 : Fin (2 + K)) : ℕ) < K then ξ ⟨↑(unlVertex1 : Fin (2 + K)), h⟩ - else σ ⟨↑(unlVertex1 : Fin (2 + K)) - K, - by have := (unlVertex1 : Fin (2 + K)).isLt; omega⟩) = σ 1 := by - rw [dif_neg (show ¬ ((unlVertex1 : Fin (2 + K)) : ℕ) < K from by simp [unlVertex1])] - congr 1 - apply Fin.ext - simp [unlVertex1] - -/-- **Closed form for Gλτ**: -`simpleEvalAt B W (edgeTestGraph Sₗ Sτ) ξ - = ∑ₜ ∑ₜ' W t · W t' · B t t' · ∏_{i∈Sₗ} B (ξ i) t · ∏_{i∈Sτ} B (ξ i) t'`. -/ -theorem simpleEvalAt_edgeTestGraph {T : ℕ} (B : Fin T → Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) - (Sₗ Sτ : Finset (Fin K)) (ξ : Fin K → Fin T) : - simpleEvalAt B W (edgeTestGraph Sₗ Sτ) ξ - = ∑ t, ∑ t', W t * W t' * B t t' - * (∏ i ∈ Sₗ, B (ξ i) t) * (∏ i ∈ Sτ, B (ξ i) t') := by - have h_notin : s(unlVertex0, unlVertex1) ∉ - (Sₗ.image (fun i => s(labVertex2 i, unlVertex0)) ∪ - Sτ.image (fun i => s(labVertex2 i, unlVertex1))) := by - simp only [Finset.mem_union, Finset.mem_image, not_or] - refine ⟨?_, ?_⟩ - · rintro ⟨i, _, heq⟩ - rw [Sym2.eq_iff] at heq - rcases heq with ⟨h1, _⟩ | ⟨h1, _⟩ - · exact labVertex2_ne_unlVertex0 i h1 - · exact labVertex2_ne_unlVertex1 i h1 - · rintro ⟨i, _, heq⟩ - rw [Sym2.eq_iff] at heq - rcases heq with ⟨h1, _⟩ | ⟨h1, _⟩ - · exact labVertex2_ne_unlVertex0 i h1 - · exact labVertex2_ne_unlVertex1 i h1 - have h_disj : Disjoint (Sₗ.image (fun i => s(labVertex2 i, unlVertex0))) - (Sτ.image (fun i => s(labVertex2 i, unlVertex1))) := by - rw [Finset.disjoint_left] - intro e he1 he2 - simp only [Finset.mem_image] at he1 he2 - obtain ⟨i, _, rfl⟩ := he1 - obtain ⟨j, _, heq⟩ := he2 - rw [Sym2.eq_iff] at heq - rcases heq with ⟨_, h2⟩ | ⟨h1, _⟩ - · exact unlVertex0_ne_unlVertex1 h2.symm - · exact labVertex2_ne_unlVertex0 j h1 - have hsum : (∑ t, ∑ t', W t * W t' * B t t' - * (∏ i ∈ Sₗ, B (ξ i) t) * (∏ i ∈ Sτ, B (ξ i) t')) - = ∑ σ : Fin 2 → Fin T, W (σ 0) * W (σ 1) * B (σ 0) (σ 1) - * (∏ i ∈ Sₗ, B (ξ i) (σ 0)) * (∏ i ∈ Sτ, B (ξ i) (σ 1)) := - (Fintype.sum_prod_type (fun p : Fin T × Fin T => W p.1 * W p.2 * B p.1 p.2 - * (∏ i ∈ Sₗ, B (ξ i) p.1) * (∏ i ∈ Sτ, B (ξ i) p.2))).symm.trans - (Equiv.sum_comp (piFinTwoEquiv (fun _ => Fin T)) - (fun p => W p.1 * W p.2 * B p.1 p.2 - * (∏ i ∈ Sₗ, B (ξ i) p.1) * (∏ i ∈ Sτ, B (ξ i) p.2))).symm - rw [hsum] - unfold simpleEvalAt - refine Finset.sum_congr rfl fun σ _ => ?_ - rw [edgeTestGraph_edgeFinset] - show (∏ v : Fin 2, W (σ v)) * - ∏ e ∈ insert s(unlVertex0, unlVertex1) - (Sₗ.image (fun i => s(labVertex2 i, unlVertex0)) ∪ - Sτ.image (fun i => s(labVertex2 i, unlVertex1))), - B ((fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩) (Quot.out e).1) - ((fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩) (Quot.out e).2) - = W (σ 0) * W (σ 1) * B (σ 0) (σ 1) - * (∏ i ∈ Sₗ, B (ξ i) (σ 0)) * (∏ i ∈ Sτ, B (ξ i) (σ 1)) - rw [Fin.prod_univ_two, Finset.prod_insert h_notin, Finset.prod_union h_disj, - Finset.prod_image (edgeTestGraph_edge_injOn_Sₗ Sₗ), - Finset.prod_image (edgeTestGraph_edge_injOn_Sτ Sτ), - out_pair_eq' B hB (fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩) unlVertex0 unlVertex1, - tau2_apply_unlVertex0 ξ σ, tau2_apply_unlVertex1 ξ σ] - rw [show (∏ i ∈ Sₗ, B ((fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩) (Quot.out s(labVertex2 i, unlVertex0)).1) - ((fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩) (Quot.out s(labVertex2 i, unlVertex0)).2)) - = ∏ i ∈ Sₗ, B (ξ i) (σ 0) from - Finset.prod_congr rfl fun i _ => by - rw [out_pair_eq' B hB (fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩) (labVertex2 i) unlVertex0, - tau2_apply_labVertex2 ξ σ i, tau2_apply_unlVertex0 ξ σ]] - rw [show (∏ i ∈ Sτ, B ((fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩) (Quot.out s(labVertex2 i, unlVertex1)).1) - ((fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩) (Quot.out s(labVertex2 i, unlVertex1)).2)) - = ∏ i ∈ Sτ, B (ξ i) (σ 1) from - Finset.prod_congr rfl fun i _ => by - rw [out_pair_eq' B hB (fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩) (labVertex2 i) unlVertex1, - tau2_apply_labVertex2 ξ σ i, tau2_apply_unlVertex1 ξ σ]] - ring - -/-! ## Chunk 3A: super-surjective orbit separation (Cai–Govorov Lemma 5.1, base case) -/ - -/-- `ξ : Fin K → Fin T` is **super-surjective** when every host vertex `v` is the image of -at least `2·T²` labels. This Cai–Govorov hypothesis provides the room to realize every -bounded exponent vector in the Vandermonde argument (by pigeonhole it yields, inside each -`ξ`-fibre, a `ξ'`-constant subset of size `≥ 2T`, aligning the exponents on both sides). -/ -def SuperSurjective {T : ℕ} (ξ : Fin K → Fin T) : Prop := - ∀ v : Fin T, 2 * T * T ≤ (univ.filter (fun i => ξ i = v)).card - -/-- Regroup a product over labels into a product over host vertices weighted by multiplicity: -`∏_{i∈S} B (ξ i) t = ∏_v (B v t) ^ |{i∈S : ξ i = v}|`. -/ -theorem prod_label_eq_prod_mult {T : ℕ} (B : Fin T → Fin T → ℝ) (ξ : Fin K → Fin T) - (S : Finset (Fin K)) (t : Fin T) : - ∏ i ∈ S, B (ξ i) t = ∏ v, (B v t) ^ (S.filter (fun i => ξ i = v)).card := by - rw [Finset.prod_comp (fun v => B v t) ξ] - refine Finset.prod_subset (Finset.subset_univ _) ?_ - intro v _ hv - rw [Finset.mem_image] at hv - have hempty : S.filter (fun i => ξ i = v) = ∅ := by - rw [Finset.filter_eq_empty_iff] - exact fun i hi heq => hv ⟨i, hi, heq⟩ - rw [hempty, Finset.card_empty, pow_zero] - -/-- **Multiplicity form of the Gχ equation.** Simple-equivalence makes the two -host-multiplicity-weighted moment sums agree, for every label subset `S`. - -NB not on the live path: the working bridge to the Vandermonde input is -`aligned_moments_of_testEvalEq_super`, which derives the moment identity directly from -`TestEvalEq.star`. Kept as the standalone multiplicity-form record of the Gχ equation. -/ -theorem tupleEquivSimple_starTestGraph_mult {T : ℕ} (B : Fin T → Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} - (h : tupleEquivSimple B W ξ ξ') (S : Finset (Fin K)) : - ∑ t, W t * ∏ v, (B v t) ^ (S.filter (fun i => ξ i = v)).card - = ∑ t, W t * ∏ v, (B v t) ^ (S.filter (fun i => ξ' i = v)).card := by - have heq : simpleEvalAt B W (starTestGraph S) ξ = simpleEvalAt B W (starTestGraph S) ξ' := - h 1 (starTestGraph S) - rw [simpleEvalAt_starTestGraph B hB W S ξ, simpleEvalAt_starTestGraph B hB W S ξ'] at heq - simp only [prod_label_eq_prod_mult] at heq - exact heq - -/-- **Test-graph evaluation equality** — the moment-level interface to the chunk-3A engine. -Records exactly the two families of simple-graph equalities the super-surjective argument -consumes: the star tests `Gχ` and the edge tests `Gλτ`. Weaker than `tupleEquivSimple` -(which quantifies over ALL simple graphs); the descent step (chunk 4F) produces instances -of this interface from eq. (10) moment matching, where full `tupleEquivSimple` is not -available. -/ -structure TestEvalEq {T : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (ξ ξ' : Fin K → Fin T) : Prop where - star : ∀ S : Finset (Fin K), - simpleEvalAt B W (starTestGraph S) ξ = simpleEvalAt B W (starTestGraph S) ξ' - edge : ∀ Sₗ Sτ : Finset (Fin K), - simpleEvalAt B W (edgeTestGraph Sₗ Sτ) ξ = simpleEvalAt B W (edgeTestGraph Sₗ Sτ) ξ' - -/-- Full simple-equivalence yields the test-graph interface. -/ -theorem TestEvalEq.of_tupleEquivSimple {T : ℕ} {B : Fin T → Fin T → ℝ} {W : Fin T → ℝ} - {ξ ξ' : Fin K → Fin T} (h : tupleEquivSimple B W ξ ξ') : TestEvalEq B W ξ ξ' := - ⟨fun S => h 1 (starTestGraph S), fun Sₗ Sτ => h 2 (edgeTestGraph Sₗ Sτ)⟩ - -/-- **Aligned-Vandermonde extraction** (graph-free core of chunk 3A). If the moment sums of -two profile families `x`, `y` (weighted by `a`, `b`) agree for every exponent vector bounded -by `2·T`, then the `a`-mass and `b`-mass over each profile level set agree. The combined index -`Fin T ⊕ Fin T` turns the equality into a single multivariate Vandermonde cancellation -(`Graphon.CaiGovorov.multivariate_vandermonde_class_sums_zero`). - -NB the exponent bound is `2·T`, not `T+1`: the combined index has `2T` points, and with only -`T+1` moments the statement is already false at `T = 2` (3 equations cannot pin a signed measure -on 4 points). This matches Cai–Govorov's range `0 ≤ k_j < 2m`. -/ -theorem aligned_moments_class_balance {T : ℕ} - (x y : Fin T → (Fin T → ℝ)) (a b : Fin T → ℝ) - (hmom : ∀ k : Fin T → ℕ, (∀ j, k j < 2 * T) → - ∑ t, a t * ∏ j, (x t j) ^ k j = ∑ t, b t * ∏ j, (y t j) ^ k j) - (z : Fin T → ℝ) : - ∑ t ∈ univ.filter (fun t => x t = z), a t - = ∑ t ∈ univ.filter (fun t => y t = z), b t := by - classical - set bb : (Fin T ⊕ Fin T) → Fin T → ℝ := Sum.elim x y with hbb - set aa : (Fin T ⊕ Fin T) → ℝ := Sum.elim a (fun t => - b t) with haa - have hcard : Fintype.card (Fin T ⊕ Fin T) = 2 * T := by - rw [Fintype.card_sum, Fintype.card_fin, two_mul] - have hmoments : ∀ ℓ : Fin T → ℕ, (∀ j, ℓ j < Fintype.card (Fin T ⊕ Fin T)) → - ∑ i, aa i * ∏ j, bb i j ^ ℓ j = 0 := by - intro ℓ hℓ - have hb : ∀ j, ℓ j < 2 * T := fun j => hcard ▸ hℓ j - rw [Fintype.sum_sum_type] - simp only [hbb, haa, Sum.elim_inl, Sum.elim_inr] - rw [hmom ℓ hb, ← Finset.sum_add_distrib] - exact Finset.sum_eq_zero fun t _ => by ring - have key := CaiGovorov.multivariate_vandermonde_class_sums_zero bb aa hmoments z - rw [Finset.sum_filter, Fintype.sum_sum_type] at key - simp only [hbb, haa, Sum.elim_inl, Sum.elim_inr, ← Finset.sum_filter] at key - have hneg : ∑ t ∈ univ.filter (fun t => y t = z), -b t - = -∑ t ∈ univ.filter (fun t => y t = z), b t := Finset.sum_neg_distrib b - rw [hneg] at key - linarith - -/-- **Bounded-exponent aligned-Vandermonde extraction.** The bounded analogue of -`aligned_moments_class_balance`: an explicit per-coordinate distinct-value bound `N` replaces the -implicit cardinality `|ι|`, and the cancellation runs through the bounded multivariate Vandermonde -(`Graphon.CaiGovorov.multivariate_vandermonde_class_sums_zero_of_bound`). The combined index has at -most `2·N` distinct values per coordinate, matching the exponent range `0 ≤ k_c < 2·N`. -/ -theorem aligned_moments_class_balance_of_bound {ι : Type*} [Fintype ι] {s : ℕ} - (x y : ι → (Fin s → ℝ)) (a b : ι → ℝ) (N : ℕ) - (hNx : ∀ c, (univ.image (fun i => x i c)).card ≤ N) - (hNy : ∀ c, (univ.image (fun i => y i c)).card ≤ N) - (hmom : ∀ k : Fin s → ℕ, (∀ c, k c < 2 * N) → - ∑ i, a i * ∏ c, (x i c) ^ k c = ∑ i, b i * ∏ c, (y i c) ^ k c) - (z : Fin s → ℝ) : - ∑ i ∈ univ.filter (fun i => x i = z), a i - = ∑ i ∈ univ.filter (fun i => y i = z), b i := by - classical - set bb : (ι ⊕ ι) → Fin s → ℝ := Sum.elim x y with hbb - set aa : (ι ⊕ ι) → ℝ := Sum.elim a (fun i => - b i) with haa - have hbound : ∀ c, (univ.image (fun p => bb p c)).card ≤ 2 * N := by - intro c - have hsub : univ.image (fun p => bb p c) - ⊆ (univ.image (fun i => x i c)) ∪ (univ.image (fun i => y i c)) := by - rw [Finset.image_subset_iff] - rintro (i | i) _ - · simp only [hbb, Sum.elim_inl] - exact Finset.mem_union_left _ (Finset.mem_image_of_mem _ (mem_univ i)) - · simp only [hbb, Sum.elim_inr] - exact Finset.mem_union_right _ (Finset.mem_image_of_mem _ (mem_univ i)) - calc (univ.image (fun p => bb p c)).card - ≤ ((univ.image (fun i => x i c)) ∪ (univ.image (fun i => y i c))).card := - Finset.card_le_card hsub - _ ≤ (univ.image (fun i => x i c)).card + (univ.image (fun i => y i c)).card := - Finset.card_union_le _ _ - _ ≤ N + N := Nat.add_le_add (hNx c) (hNy c) - _ = 2 * N := (two_mul N).symm - have hmoments : ∀ ℓ : Fin s → ℕ, (∀ c, ℓ c < 2 * N) → - ∑ p, aa p * ∏ c, bb p c ^ ℓ c = 0 := by - intro ℓ hb - rw [Fintype.sum_sum_type] - simp only [hbb, haa, Sum.elim_inl, Sum.elim_inr] - rw [hmom ℓ hb, ← Finset.sum_add_distrib] - exact Finset.sum_eq_zero fun i _ => by ring - have key := CaiGovorov.multivariate_vandermonde_class_sums_zero_of_bound bb aa (2 * N) - hbound hmoments z - rw [Finset.sum_filter, Fintype.sum_sum_type] at key - simp only [hbb, haa, Sum.elim_inl, Sum.elim_inr, ← Finset.sum_filter] at key - have hneg : ∑ i ∈ univ.filter (fun i => y i = z), -b i - = -∑ i ∈ univ.filter (fun i => y i = z), b i := Finset.sum_neg_distrib b - rw [hneg] at key - linarith - -/-- Profile-balance specialization: with `x t = B · t` (the profile/column of `t`), -`y t = B (s ·) t`, and weights `a = b = W`, the aligned moments force the `W`-mass over each -profile level set to match. -/ -theorem aligned_star_moments_profile_balance {T : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (s : Fin T → Fin T) - (haligned : ∀ k : Fin T → ℕ, (∀ j, k j < 2 * T) → - ∑ t, W t * ∏ j, (B j t) ^ k j = ∑ t, W t * ∏ j, (B (s j) t) ^ k j) - (z : Fin T → ℝ) : - ∑ t ∈ univ.filter (fun t => (fun j => B j t) = z), W t - = ∑ t ∈ univ.filter (fun t => (fun j => B (s j) t) = z), W t := - aligned_moments_class_balance (fun t j => B j t) (fun t j => B (s j) t) W W haligned z - -/-- **Weight balance.** Twin-freeness collapses the left profile level set of `t` to the -singleton `{t}`, so the aligned Vandermonde output is exactly `W t = ∑_{u : B·t = B(s·)u} W u`. -/ -theorem aligned_star_moments_weight_balance {T : ℕ} (B : Fin T → Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (s : Fin T → Fin T) - (haligned : ∀ k : Fin T → ℕ, (∀ j, k j < 2 * T) → - ∑ t, W t * ∏ j, (B j t) ^ k j = ∑ t, W t * ∏ j, (B (s j) t) ^ k j) - (t : Fin T) : - W t = ∑ u ∈ univ.filter (fun u => ∀ j, B j t = B (s j) u), W u := by - have hbal := aligned_star_moments_profile_balance B W s haligned (fun j => B j t) - have hsingle : (univ.filter (fun t' => (fun j => B j t') = fun j => B j t)) = {t} := by - ext t' - simp only [Finset.mem_filter, Finset.mem_univ, true_and, Finset.mem_singleton] - constructor - · intro hprof - by_contra hne - refine htwin t' t hne ?_ - funext j - rw [hB t' j, hB t j] - exact congrFun hprof j - · rintro rfl; rfl - rw [hsingle, Finset.sum_singleton] at hbal - rw [hbal] - refine Finset.sum_congr ?_ (fun _ _ => rfl) - apply Finset.filter_congr - intro u _ - constructor - · intro h j; exact (congrFun h j).symm - · intro h; funext j; exact (h j).symm - -/-- **Support.** From weight balance and positivity, every host vertex `t` is matched: there is a -`u` with `B j t = B (s j) u` for all `j`. (The Vandermonde engine builds the matching.) -/ -theorem aligned_star_moments_support {T : ℕ} (B : Fin T → Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) - (htwin : ∀ i j, i ≠ j → B i ≠ B j) (s : Fin T → Fin T) - (haligned : ∀ k : Fin T → ℕ, (∀ j, k j < 2 * T) → - ∑ t, W t * ∏ j, (B j t) ^ k j = ∑ t, W t * ∏ j, (B (s j) t) ^ k j) - (t : Fin T) : - ∃ u, ∀ j, B j t = B (s j) u := by - have hbal := aligned_star_moments_weight_balance B hB W htwin s haligned t - have hne : (univ.filter (fun u => ∀ j, B j t = B (s j) u)).Nonempty := by - rw [Finset.nonempty_iff_ne_empty] - intro hempty - rw [hempty, Finset.sum_empty] at hbal - exact (hW t).ne' hbal - obtain ⟨u, hu⟩ := hne - rw [Finset.mem_filter] at hu - exact ⟨u, hu.2⟩ - -/-! ### Chunk 3A.2: pigeonhole and the preliminary map `s` -/ - -/-- **Pigeonhole.** Super-surjectivity gives, inside each `ξ`-fibre over `j`, a subset `J` of -size `≥ 2T` on which `ξ'` is constant (value `s_j`). (`ξ'` takes ≤ T values on the fibre of -size `≥ 2T²`, so some value is hit `≥ 2T` times.) -/ -theorem exists_large_const_image_subset {T : ℕ} (ξ ξ' : Fin K → Fin T) - (hξ : SuperSurjective ξ) (j : Fin T) : - ∃ (s_j : Fin T) (J : Finset (Fin K)), - J ⊆ univ.filter (fun i => ξ i = j) ∧ 2 * T ≤ J.card ∧ (∀ i ∈ J, ξ' i = s_j) := by - classical - have hmaps : ∀ i ∈ univ.filter (fun i => ξ i = j), ξ' i ∈ (univ : Finset (Fin T)) := - fun i _ => mem_univ _ - have hcard : (univ : Finset (Fin T)).card * (2 * T) - ≤ (univ.filter (fun i => ξ i = j)).card := by - rw [Finset.card_univ, Fintype.card_fin] - calc T * (2 * T) = 2 * T * T := by ring - _ ≤ (univ.filter (fun i => ξ i = j)).card := hξ j - obtain ⟨s_j, _, hsj⟩ := - Finset.exists_le_card_fiber_of_mul_le_card_of_maps_to hmaps ⟨j, mem_univ j⟩ hcard - exact ⟨s_j, (univ.filter (fun i => ξ i = j)).filter (fun i => ξ' i = s_j), - Finset.filter_subset _ _, hsj, fun i hi => (Finset.mem_filter.mp hi).2⟩ - -/-- The preliminary Cai–Govorov map `s : Fin T → Fin T`: the constant `ξ'`-value on a large -subset of each `ξ`-fibre. -/ -noncomputable def superMap {T : ℕ} (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (j : Fin T) : - Fin T := - (exists_large_const_image_subset ξ ξ' hξ j).choose - -/-- The chosen large `ξ'`-constant subset of the `ξ`-fibre over `j`. -/ -noncomputable def superFiberSubset {T : ℕ} (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) - (j : Fin T) : Finset (Fin K) := - (exists_large_const_image_subset ξ ξ' hξ j).choose_spec.choose - -theorem superFiberSubset_subset {T : ℕ} (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) - (j : Fin T) : superFiberSubset ξ ξ' hξ j ⊆ univ.filter (fun i => ξ i = j) := - (exists_large_const_image_subset ξ ξ' hξ j).choose_spec.choose_spec.1 - -theorem superFiberSubset_card {T : ℕ} (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) - (j : Fin T) : 2 * T ≤ (superFiberSubset ξ ξ' hξ j).card := - (exists_large_const_image_subset ξ ξ' hξ j).choose_spec.choose_spec.2.1 - -theorem superFiberSubset_mem_left {T : ℕ} (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) - (j : Fin T) {i : Fin K} (hi : i ∈ superFiberSubset ξ ξ' hξ j) : ξ i = j := by - have := superFiberSubset_subset ξ ξ' hξ j hi - rw [Finset.mem_filter] at this - exact this.2 - -theorem superFiberSubset_image_const {T : ℕ} (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) - (j : Fin T) : ∀ i ∈ superFiberSubset ξ ξ' hξ j, ξ' i = superMap ξ ξ' hξ j := - (exists_large_const_image_subset ξ ξ' hξ j).choose_spec.choose_spec.2.2 - -/-- Distinct fibres give disjoint chosen subsets (each lies in a distinct `ξ`-fibre). -/ -theorem superFiberSubset_disjoint {T : ℕ} (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) - {j j' : Fin T} (hjj : j ≠ j') : - Disjoint (superFiberSubset ξ ξ' hξ j) (superFiberSubset ξ ξ' hξ j') := by - apply Finset.disjoint_left.mpr - intro i hi hi' - exact hjj ((superFiberSubset_mem_left ξ ξ' hξ j hi).symm.trans - (superFiberSubset_mem_left ξ ξ' hξ j' hi')) - -/-! ### Chunk 3A.3: aligned moments from selected labels -/ - -/-- For any bounded exponent vector `k`, select inside each `ξ`-fibre's distinguished subset a -sub-subset of size exactly `k j`. -/ -theorem exists_exponent_label_set {T : ℕ} (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) - (k : Fin T → ℕ) (hk : ∀ j, k j < 2 * T) : - ∃ Kf : Fin T → Finset (Fin K), - (∀ j, Kf j ⊆ superFiberSubset ξ ξ' hξ j) ∧ (∀ j, (Kf j).card = k j) := by - choose Kf hsub hcard using fun j => - Finset.exists_subset_card_eq (s := superFiberSubset ξ ξ' hξ j) (n := k j) - (lt_of_lt_of_le (hk j) (superFiberSubset_card ξ ξ' hξ j)).le - exact ⟨Kf, hsub, hcard⟩ - -/-- **Aligned-moment bridge.** From the star-test equalities (`TestEvalEq.star`) and -super-surjectivity, the aligned moment identity holds for every bounded exponent vector, with the -right-hand side reindexed by `superMap`. -This consumes the `starTestGraph` closed form: the label set `S = ⋃ⱼ Kⱼ` has `ξ ≡ j` on `Kⱼ` (giving -`(B j t)^{k j}` on the left) and `ξ' ≡ superMap j` on `Kⱼ` (giving `(B (superMap j) t)^{k j}` on the -right) — no injectivity of `superMap` is needed. -/ -theorem aligned_moments_of_testEvalEq_super {T : ℕ} (B : Fin T → Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (ξ ξ' : Fin K → Fin T) - (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : - ∀ k : Fin T → ℕ, (∀ j, k j < 2 * T) → - ∑ t, W t * ∏ j, (B j t) ^ k j - = ∑ t, W t * ∏ j, (B (superMap ξ ξ' hξ j) t) ^ k j := by - intro k hk - classical - obtain ⟨Kf, hKf_sub, hKf_card⟩ := exists_exponent_label_set ξ ξ' hξ k hk - set S := univ.biUnion Kf with hS - have hdisj : Set.PairwiseDisjoint (↑(univ : Finset (Fin T))) Kf := - fun j _ j' _ hjj => Finset.disjoint_of_subset_left (hKf_sub j) - (Finset.disjoint_of_subset_right (hKf_sub j') (superFiberSubset_disjoint ξ ξ' hξ hjj)) - have hLHS : ∀ t, ∏ i ∈ S, B (ξ i) t = ∏ j, (B j t) ^ k j := by - intro t - rw [hS, Finset.prod_biUnion hdisj] - refine Finset.prod_congr rfl fun j _ => ?_ - have hconst : ∏ i ∈ Kf j, B (ξ i) t = ∏ i ∈ Kf j, B j t := - Finset.prod_congr rfl fun i hi => by - rw [superFiberSubset_mem_left ξ ξ' hξ j (hKf_sub j hi)] - rw [hconst, Finset.prod_const, hKf_card j] - have hRHS : ∀ t, ∏ i ∈ S, B (ξ' i) t = ∏ j, (B (superMap ξ ξ' hξ j) t) ^ k j := by - intro t - rw [hS, Finset.prod_biUnion hdisj] - refine Finset.prod_congr rfl fun j _ => ?_ - have hconst : ∏ i ∈ Kf j, B (ξ' i) t = ∏ i ∈ Kf j, B (superMap ξ ξ' hξ j) t := - Finset.prod_congr rfl fun i hi => by - rw [superFiberSubset_image_const ξ ξ' hξ j i (hKf_sub j hi)] - rw [hconst, Finset.prod_const, hKf_card j] - have heq : simpleEvalAt B W (starTestGraph S) ξ = simpleEvalAt B W (starTestGraph S) ξ' := - h.star S - rw [simpleEvalAt_starTestGraph B hB W S ξ, simpleEvalAt_starTestGraph B hB W S ξ'] at heq - calc ∑ t, W t * ∏ j, (B j t) ^ k j - = ∑ t, W t * ∏ i ∈ S, B (ξ i) t := by - refine Finset.sum_congr rfl fun t _ => ?_; rw [hLHS t] - _ = ∑ t, W t * ∏ i ∈ S, B (ξ' i) t := heq - _ = ∑ t, W t * ∏ j, (B (superMap ξ ξ' hξ j) t) ^ k j := by - refine Finset.sum_congr rfl fun t _ => ?_; rw [hRHS t] - -/-- **`superMap` support**: every host vertex `t` is matched -by the preliminary map — there is a `u` with `B j t = B (superMap … j) u` for all `j`. Combines the -aligned-moment bridge with the proved aligned-Vandermonde support lemma. -/ -theorem superMap_support {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (t : Fin T) : - ∃ u, ∀ j, B j t = B (superMap ξ ξ' hξ j) u := - aligned_star_moments_support B hB W hW htwin (superMap ξ ξ' hξ) - (aligned_moments_of_testEvalEq_super B hB W ξ ξ' hξ h) t - -/-! ### Chunk 3A.4: `superMap` is bijective -/ - -/-- **`superMap` is injective.** If `superMap a = superMap b`, then for every `t` the support -witness `u` gives `B a t = B (superMap a) u = B (superMap b) u = B b t`, so the rows `B a`, `B b` -agree; twin-freeness forces `a = b`. (No edge tests needed.) -/ -theorem superMap_injective {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : - Function.Injective (superMap ξ ξ' hξ) := by - intro a b hab - by_contra hne - refine htwin a b hne ?_ - funext t - obtain ⟨u, hu⟩ := superMap_support B hB W hW htwin ξ ξ' hξ h t - rw [hu a, hu b, hab] - -/-- **`superMap` is bijective** (injective endomap of a finite type). -/ -theorem superMap_bijective {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : - Function.Bijective (superMap ξ ξ' hξ) := - Finite.injective_iff_bijective.mp (superMap_injective B hB W hW htwin ξ ξ' hξ h) - -/-- The preliminary map as a permutation of `Fin T`. The orbit-defining automorphism `σ` will be -exactly this permutation (since `ξ' i = superMap (ξ i)` on the selected labels, `σ = superMap`, -not its inverse); edge/weight preservation are established next (3A.5) via `edgeTestGraph`. -/ -noncomputable def superPerm {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : - Equiv.Perm (Fin T) := - Equiv.ofBijective (superMap ξ ξ' hξ) (superMap_bijective B hB W hW htwin ξ ξ' hξ h) - -@[simp] theorem superPerm_apply {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (j : Fin T) : - superPerm B hB W hW htwin ξ ξ' hξ h j = superMap ξ ξ' hξ j := rfl - -/-! ### Chunk 3A.5: aligned edge moments (`edgeTestGraph`) -/ - -/-- Regroup a product over a pairwise-disjoint union `⋃ⱼ Kf j` of a function that is constant -(`= c j`) on each block `Kf j` into `∏ⱼ (c j) ^ (k j)`, where `(Kf j).card = k j`. -/ -private theorem prod_biUnion_const {T : ℕ} {Kf : Fin T → Finset (Fin K)} - (hdisj : Set.PairwiseDisjoint (↑(univ : Finset (Fin T))) Kf) - {f : Fin K → ℝ} {c : Fin T → ℝ} (hc : ∀ j, ∀ i ∈ Kf j, f i = c j) - {k : Fin T → ℕ} (hcard : ∀ j, (Kf j).card = k j) : - ∏ i ∈ univ.biUnion Kf, f i = ∏ j, (c j) ^ k j := by - rw [Finset.prod_biUnion hdisj] - refine Finset.prod_congr rfl fun j _ => ?_ - have hconst : ∏ i ∈ Kf j, f i = ∏ i ∈ Kf j, c j := - Finset.prod_congr rfl fun i hi => hc j i hi - rw [hconst, Finset.prod_const, hcard j] - -/-- **Aligned edge-moment bridge** (pair analogue of `aligned_moments_of_testEvalEq_super`). -From the edge-test equalities (`TestEvalEq.edge`) and super-surjectivity, the aligned -*edge*-moment identity holds for every pair of bounded exponent vectors `k`, `l`, with the -right-hand side reindexed by `superMap`. This -consumes the `edgeTestGraph` closed form: with `Sₗ = ⋃ⱼ Klⱼ`, `Sτ = ⋃ⱼ Ktⱼ` one has `ξ ≡ j` on -each block (giving `(B j ·)^{k j}`/`(B j ·)^{l j}`) and `ξ' ≡ superMap j` (giving the reindexed -right-hand side) — no injectivity of `superMap` is needed. -/ -theorem aligned_edge_moments_of_testEvalEq_super {T : ℕ} (B : Fin T → Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (ξ ξ' : Fin K → Fin T) - (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : - ∀ k l : Fin T → ℕ, (∀ j, k j < 2 * T) → (∀ j, l j < 2 * T) → - ∑ x, ∑ y, W x * W y * B x y * (∏ j, (B j x) ^ k j) * (∏ j, (B j y) ^ l j) - = ∑ x, ∑ y, W x * W y * B x y - * (∏ j, (B (superMap ξ ξ' hξ j) x) ^ k j) * (∏ j, (B (superMap ξ ξ' hξ j) y) ^ l j) := by - intro k l hk hl - classical - obtain ⟨Kl, hKl_sub, hKl_card⟩ := exists_exponent_label_set ξ ξ' hξ k hk - obtain ⟨Kt, hKt_sub, hKt_card⟩ := exists_exponent_label_set ξ ξ' hξ l hl - have hdisj_l : Set.PairwiseDisjoint (↑(univ : Finset (Fin T))) Kl := - fun j _ j' _ hjj => Finset.disjoint_of_subset_left (hKl_sub j) - (Finset.disjoint_of_subset_right (hKl_sub j') (superFiberSubset_disjoint ξ ξ' hξ hjj)) - have hdisj_t : Set.PairwiseDisjoint (↑(univ : Finset (Fin T))) Kt := - fun j _ j' _ hjj => Finset.disjoint_of_subset_left (hKt_sub j) - (Finset.disjoint_of_subset_right (hKt_sub j') (superFiberSubset_disjoint ξ ξ' hξ hjj)) - have hLl : ∀ x, ∏ i ∈ univ.biUnion Kl, B (ξ i) x = ∏ j, (B j x) ^ k j := fun x => - prod_biUnion_const hdisj_l - (fun j i hi => by rw [superFiberSubset_mem_left ξ ξ' hξ j (hKl_sub j hi)]) hKl_card - have hLl' : ∀ x, ∏ i ∈ univ.biUnion Kl, B (ξ' i) x - = ∏ j, (B (superMap ξ ξ' hξ j) x) ^ k j := fun x => - prod_biUnion_const hdisj_l - (fun j i hi => by rw [superFiberSubset_image_const ξ ξ' hξ j i (hKl_sub j hi)]) hKl_card - have hTt : ∀ y, ∏ i ∈ univ.biUnion Kt, B (ξ i) y = ∏ j, (B j y) ^ l j := fun y => - prod_biUnion_const hdisj_t - (fun j i hi => by rw [superFiberSubset_mem_left ξ ξ' hξ j (hKt_sub j hi)]) hKt_card - have hTt' : ∀ y, ∏ i ∈ univ.biUnion Kt, B (ξ' i) y - = ∏ j, (B (superMap ξ ξ' hξ j) y) ^ l j := fun y => - prod_biUnion_const hdisj_t - (fun j i hi => by rw [superFiberSubset_image_const ξ ξ' hξ j i (hKt_sub j hi)]) hKt_card - have heq : simpleEvalAt B W (edgeTestGraph (univ.biUnion Kl) (univ.biUnion Kt)) ξ - = simpleEvalAt B W (edgeTestGraph (univ.biUnion Kl) (univ.biUnion Kt)) ξ' := - h.edge (univ.biUnion Kl) (univ.biUnion Kt) - rw [simpleEvalAt_edgeTestGraph B hB W _ _ ξ, - simpleEvalAt_edgeTestGraph B hB W _ _ ξ'] at heq - calc ∑ x, ∑ y, W x * W y * B x y * (∏ j, (B j x) ^ k j) * (∏ j, (B j y) ^ l j) - = ∑ x, ∑ y, W x * W y * B x y - * (∏ i ∈ univ.biUnion Kl, B (ξ i) x) * (∏ i ∈ univ.biUnion Kt, B (ξ i) y) := by - refine Finset.sum_congr rfl fun x _ => Finset.sum_congr rfl fun y _ => ?_ - rw [hLl x, hTt y] - _ = ∑ x, ∑ y, W x * W y * B x y - * (∏ i ∈ univ.biUnion Kl, B (ξ' i) x) * (∏ i ∈ univ.biUnion Kt, B (ξ' i) y) := heq - _ = ∑ x, ∑ y, W x * W y * B x y - * (∏ j, (B (superMap ξ ξ' hξ j) x) ^ k j) - * (∏ j, (B (superMap ξ ξ' hξ j) y) ^ l j) := by - refine Finset.sum_congr rfl fun x _ => Finset.sum_congr rfl fun y _ => ?_ - rw [hLl' x, hTt' y] - -/-- **Aligned edge-moment pair balance.** Specializing the bounded extraction engine -`aligned_moments_class_balance_of_bound` at `ι = Fin T × Fin T` and coordinate dimension `T + T` -(gluing the two `B`-columns of a pair via `Fin.append`), the aligned edge moments force the -`W·W·B`-mass over each pair of column profiles `(z₁, z₂)` to match between the original labelling and -the `superMap`-reindexed one. -/ -theorem aligned_edge_moments_pair_balance {T : ℕ} (B : Fin T → Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (ξ ξ' : Fin K → Fin T) - (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (z₁ z₂ : Fin T → ℝ) : - ∑ p : Fin T × Fin T, - (if (fun j => B j p.1) = z₁ ∧ (fun j => B j p.2) = z₂ - then W p.1 * W p.2 * B p.1 p.2 else 0) - = ∑ p : Fin T × Fin T, - (if (fun j => B (superMap ξ ξ' hξ j) p.1) = z₁ ∧ - (fun j => B (superMap ξ ξ' hξ j) p.2) = z₂ - then W p.1 * W p.2 * B p.1 p.2 else 0) := by - set x : Fin T × Fin T → (Fin (T + T) → ℝ) := - fun p => Fin.append (fun j => B j p.1) (fun j => B j p.2) with hx - set y : Fin T × Fin T → (Fin (T + T) → ℝ) := - fun p => Fin.append (fun j => B (superMap ξ ξ' hξ j) p.1) - (fun j => B (superMap ξ ξ' hξ j) p.2) with hy - set a : Fin T × Fin T → ℝ := fun p => W p.1 * W p.2 * B p.1 p.2 with ha - -- Per-coordinate distinct-value bound (≤ T) for the left profiles. - have hNx : ∀ c, (univ.image (fun p => x p c)).card ≤ T := by - intro c - refine Fin.addCases (fun j => ?_) (fun j => ?_) c - · have hsub : univ.image (fun p : Fin T × Fin T => x p (Fin.castAdd T j)) - ⊆ univ.image (fun u : Fin T => B j u) := by - intro val hval - rw [mem_image] at hval ⊢ - obtain ⟨p, -, hp⟩ := hval - refine ⟨p.1, mem_univ _, ?_⟩ - rw [← hp]; simp only [hx, Fin.append_left] - calc (univ.image (fun p : Fin T × Fin T => x p (Fin.castAdd T j))).card - ≤ (univ.image (fun u : Fin T => B j u)).card := Finset.card_le_card hsub - _ ≤ (univ : Finset (Fin T)).card := Finset.card_image_le - _ = T := by rw [Finset.card_univ, Fintype.card_fin] - · have hsub : univ.image (fun p : Fin T × Fin T => x p (Fin.natAdd T j)) - ⊆ univ.image (fun u : Fin T => B j u) := by - intro val hval - rw [mem_image] at hval ⊢ - obtain ⟨p, -, hp⟩ := hval - refine ⟨p.2, mem_univ _, ?_⟩ - rw [← hp]; simp only [hx, Fin.append_right] - calc (univ.image (fun p : Fin T × Fin T => x p (Fin.natAdd T j))).card - ≤ (univ.image (fun u : Fin T => B j u)).card := Finset.card_le_card hsub - _ ≤ (univ : Finset (Fin T)).card := Finset.card_image_le - _ = T := by rw [Finset.card_univ, Fintype.card_fin] - have hNy : ∀ c, (univ.image (fun p => y p c)).card ≤ T := by - intro c - refine Fin.addCases (fun j => ?_) (fun j => ?_) c - · have hsub : univ.image (fun p : Fin T × Fin T => y p (Fin.castAdd T j)) - ⊆ univ.image (fun u : Fin T => B (superMap ξ ξ' hξ j) u) := by - intro val hval - rw [mem_image] at hval ⊢ - obtain ⟨p, -, hp⟩ := hval - refine ⟨p.1, mem_univ _, ?_⟩ - rw [← hp]; simp only [hy, Fin.append_left] - calc (univ.image (fun p : Fin T × Fin T => y p (Fin.castAdd T j))).card - ≤ (univ.image (fun u : Fin T => B (superMap ξ ξ' hξ j) u)).card := - Finset.card_le_card hsub - _ ≤ (univ : Finset (Fin T)).card := Finset.card_image_le - _ = T := by rw [Finset.card_univ, Fintype.card_fin] - · have hsub : univ.image (fun p : Fin T × Fin T => y p (Fin.natAdd T j)) - ⊆ univ.image (fun u : Fin T => B (superMap ξ ξ' hξ j) u) := by - intro val hval - rw [mem_image] at hval ⊢ - obtain ⟨p, -, hp⟩ := hval - refine ⟨p.2, mem_univ _, ?_⟩ - rw [← hp]; simp only [hy, Fin.append_right] - calc (univ.image (fun p : Fin T × Fin T => y p (Fin.natAdd T j))).card - ≤ (univ.image (fun u : Fin T => B (superMap ξ ξ' hξ j) u)).card := - Finset.card_le_card hsub - _ ≤ (univ : Finset (Fin T)).card := Finset.card_image_le - _ = T := by rw [Finset.card_univ, Fintype.card_fin] - -- The bounded moment identity, fed by the edge-moment bridge. - have hmom : ∀ k : Fin (T + T) → ℕ, (∀ c, k c < 2 * T) → - ∑ p, a p * ∏ c, (x p c) ^ k c = ∑ p, a p * ∏ c, (y p c) ^ k c := by - intro k hk - have hbridge := aligned_edge_moments_of_testEvalEq_super B hB W ξ ξ' hξ h - (fun j => k (Fin.castAdd T j)) (fun j => k (Fin.natAdd T j)) - (fun j => hk (Fin.castAdd T j)) (fun j => hk (Fin.natAdd T j)) - have hxprod : ∀ p : Fin T × Fin T, ∏ c, (x p c) ^ k c - = (∏ j, (B j p.1) ^ k (Fin.castAdd T j)) * (∏ j, (B j p.2) ^ k (Fin.natAdd T j)) := by - intro p - rw [Fin.prod_univ_add] - congr 1 - · refine Finset.prod_congr rfl (fun i _ => ?_); simp only [hx, Fin.append_left] - · refine Finset.prod_congr rfl (fun i _ => ?_); simp only [hx, Fin.append_right] - have hyprod : ∀ p : Fin T × Fin T, ∏ c, (y p c) ^ k c - = (∏ j, (B (superMap ξ ξ' hξ j) p.1) ^ k (Fin.castAdd T j)) - * (∏ j, (B (superMap ξ ξ' hξ j) p.2) ^ k (Fin.natAdd T j)) := by - intro p - rw [Fin.prod_univ_add] - congr 1 - · refine Finset.prod_congr rfl (fun i _ => ?_); simp only [hy, Fin.append_left] - · refine Finset.prod_congr rfl (fun i _ => ?_); simp only [hy, Fin.append_right] - calc ∑ p, a p * ∏ c, (x p c) ^ k c - = ∑ p : Fin T × Fin T, W p.1 * W p.2 * B p.1 p.2 - * (∏ j, (B j p.1) ^ k (Fin.castAdd T j)) - * (∏ j, (B j p.2) ^ k (Fin.natAdd T j)) := by - refine Finset.sum_congr rfl (fun p _ => ?_) - rw [hxprod p]; simp only [ha]; ring - _ = ∑ p : Fin T × Fin T, W p.1 * W p.2 * B p.1 p.2 - * (∏ j, (B (superMap ξ ξ' hξ j) p.1) ^ k (Fin.castAdd T j)) - * (∏ j, (B (superMap ξ ξ' hξ j) p.2) ^ k (Fin.natAdd T j)) := by - rw [Fintype.sum_prod_type, Fintype.sum_prod_type]; exact hbridge - _ = ∑ p, a p * ∏ c, (y p c) ^ k c := by - refine Finset.sum_congr rfl (fun p _ => ?_) - rw [hyprod p]; simp only [ha]; ring - -- Apply the bounded extraction engine at `z = Fin.append z₁ z₂`. - have key := aligned_moments_class_balance_of_bound x y a a T hNx hNy hmom (Fin.append z₁ z₂) - -- `Fin.append`-injectivity: a glued profile equals `append z₁ z₂` iff its halves are `z₁`, `z₂`. - have happend : ∀ f g : Fin T → ℝ, - (Fin.append f g = Fin.append z₁ z₂) ↔ (f = z₁ ∧ g = z₂) := by - intro f g - constructor - · intro happ - refine ⟨?_, ?_⟩ - · funext j - have hj := congrFun happ (Fin.castAdd T j) - rwa [Fin.append_left, Fin.append_left] at hj - · funext j - have hj := congrFun happ (Fin.natAdd T j) - rwa [Fin.append_right, Fin.append_right] at hj - · rintro ⟨rfl, rfl⟩; rfl - have hfiltL : univ.filter (fun p : Fin T × Fin T => - (fun j => B j p.1) = z₁ ∧ (fun j => B j p.2) = z₂) - = univ.filter (fun p => x p = Fin.append z₁ z₂) := by - refine Finset.filter_congr (fun p _ => ?_) - exact (happend (fun j => B j p.1) (fun j => B j p.2)).symm - have hfiltR : univ.filter (fun p : Fin T × Fin T => - (fun j => B (superMap ξ ξ' hξ j) p.1) = z₁ ∧ - (fun j => B (superMap ξ ξ' hξ j) p.2) = z₂) - = univ.filter (fun p => y p = Fin.append z₁ z₂) := by - refine Finset.filter_congr (fun p _ => ?_) - exact (happend (fun j => B (superMap ξ ξ' hξ j) p.1) - (fun j => B (superMap ξ ξ' hξ j) p.2)).symm - rw [← Finset.sum_filter, ← Finset.sum_filter, hfiltL, hfiltR] - exact key - -/-! ### Chunk 3A.5 steps 2–7: the support-witness map and the weighted automorphism -/ - -/-- The support-witness map `r = superInv`: `r t` is the unique `u` with -`∀ j, B j t = B (superMap j) u`. It turns out to be the orbit automorphism (`= superMap`). -/ -noncomputable def superInv {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (t : Fin T) : - Fin T := - (superMap_support B hB W hW htwin ξ ξ' hξ h t).choose - -theorem superInv_spec {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (t : Fin T) : - ∀ j, B j t = B (superMap ξ ξ' hξ j) (superInv B hB W hW htwin ξ ξ' hξ h t) := - (superMap_support B hB W hW htwin ξ ξ' hξ h t).choose_spec - -theorem superInv_unique {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') {t u : Fin T} - (hu : ∀ j, B j t = B (superMap ξ ξ' hξ j) u) : - u = superInv B hB W hW htwin ξ ξ' hξ h t := by - by_contra hne - refine htwin u (superInv B hB W hW htwin ξ ξ' hξ h t) hne ?_ - funext w - obtain ⟨j, hj⟩ := (superMap_bijective B hB W hW htwin ξ ξ' hξ h).surjective w - rw [← hj, hB u (superMap ξ ξ' hξ j), - hB (superInv B hB W hW htwin ξ ξ' hξ h t) (superMap ξ ξ' hξ j), - ← hu j, superInv_spec B hB W hW htwin ξ ξ' hξ h t j] - -theorem superInv_injective {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : - Function.Injective (superInv B hB W hW htwin ξ ξ' hξ h) := by - intro a b hab - by_contra hne - refine htwin a b hne ?_ - funext j - rw [hB a j, superInv_spec B hB W hW htwin ξ ξ' hξ h a j, hab, - ← superInv_spec B hB W hW htwin ξ ξ' hξ h b j, ← hB b j] - -theorem superInv_bijective {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : - Function.Bijective (superInv B hB W hW htwin ξ ξ' hξ h) := - Finite.injective_iff_bijective.mp (superInv_injective B hB W hW htwin ξ ξ' hξ h) - -/-- **Weight preservation for `superInv`.** The support fibre of `t` is the singleton -`{superInv t}`, so weight balance gives `W (superInv t) = W t`. -/ -theorem superInv_preserves_W {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (t : Fin T) : - W (superInv B hB W hW htwin ξ ξ' hξ h t) = W t := by - have hbal := aligned_star_moments_weight_balance B hB W htwin (superMap ξ ξ' hξ) - (aligned_moments_of_testEvalEq_super B hB W ξ ξ' hξ h) t - have hfib : (univ.filter (fun u => ∀ j, B j t = B (superMap ξ ξ' hξ j) u)) - = {superInv B hB W hW htwin ξ ξ' hξ h t} := by - ext u - simp only [Finset.mem_filter, Finset.mem_univ, true_and, Finset.mem_singleton] - exact ⟨fun hu => superInv_unique B hB W hW htwin ξ ξ' hξ h hu, - fun hu => hu ▸ superInv_spec B hB W hW htwin ξ ξ' hξ h t⟩ - rw [hfib, Finset.sum_singleton] at hbal - exact hbal.symm - -/-- **Edge preservation for `superInv`.** Plugging the pair balance at `z₁ = B·a`, `z₂ = B·b`: -the left fibre is `{(a,b)}` (twin-free) and the right fibre is `{(superInv a, superInv b)}` -(`superInv_unique`); positivity cancels the weights. So `superInv` preserves `B`. -/ -theorem superInv_preserves_B {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (a b : Fin T) : - B (superInv B hB W hW htwin ξ ξ' hξ h a) (superInv B hB W hW htwin ξ ξ' hξ h b) = B a b := by - classical - have hcol : ∀ u v : Fin T, (fun j => B j u) = (fun j => B j v) → u = v := by - intro u v huv - by_contra hne - refine htwin u v hne ?_ - funext j - have hj := congrFun huv j - rw [hB u j, hB v j]; exact hj - have hLHS : (∑ p : Fin T × Fin T, - if (fun j => B j p.1) = (fun j => B j a) ∧ (fun j => B j p.2) = (fun j => B j b) - then W p.1 * W p.2 * B p.1 p.2 else 0) = W a * W b * B a b := by - rw [Finset.sum_eq_single (a, b)] - · simp - · intro p _ hp - have hfalse : ¬ ((fun j => B j p.1) = (fun j => B j a) ∧ - (fun j => B j p.2) = (fun j => B j b)) := by - rintro ⟨hp1, hp2⟩ - exact hp (Prod.ext (hcol p.1 a hp1) (hcol p.2 b hp2)) - rw [if_neg hfalse] - · intro hc; exact absurd (Finset.mem_univ _) hc - have hRHS : (∑ p : Fin T × Fin T, - if (fun j => B (superMap ξ ξ' hξ j) p.1) = (fun j => B j a) ∧ - (fun j => B (superMap ξ ξ' hξ j) p.2) = (fun j => B j b) - then W p.1 * W p.2 * B p.1 p.2 else 0) - = W (superInv B hB W hW htwin ξ ξ' hξ h a) * W (superInv B hB W hW htwin ξ ξ' hξ h b) - * B (superInv B hB W hW htwin ξ ξ' hξ h a) (superInv B hB W hW htwin ξ ξ' hξ h b) := by - rw [Finset.sum_eq_single (superInv B hB W hW htwin ξ ξ' hξ h a, - superInv B hB W hW htwin ξ ξ' hξ h b)] - · rw [if_pos] - exact ⟨funext fun j => (superInv_spec B hB W hW htwin ξ ξ' hξ h a j).symm, - funext fun j => (superInv_spec B hB W hW htwin ξ ξ' hξ h b j).symm⟩ - · intro p _ hp - have hfalse : ¬ ((fun j => B (superMap ξ ξ' hξ j) p.1) = (fun j => B j a) ∧ - (fun j => B (superMap ξ ξ' hξ j) p.2) = (fun j => B j b)) := by - rintro ⟨hp1, hp2⟩ - exact hp (Prod.ext - (superInv_unique B hB W hW htwin ξ ξ' hξ h (fun j => (congrFun hp1 j).symm)) - (superInv_unique B hB W hW htwin ξ ξ' hξ h (fun j => (congrFun hp2 j).symm))) - rw [if_neg hfalse] - · intro hc; exact absurd (Finset.mem_univ _) hc - have hpb := aligned_edge_moments_pair_balance B hB W ξ ξ' hξ h (fun j => B j a) (fun j => B j b) - rw [hLHS, hRHS, superInv_preserves_W B hB W hW htwin ξ ξ' hξ h a, - superInv_preserves_W B hB W hW htwin ξ ξ' hξ h b] at hpb - have hpos : W a * W b ≠ 0 := ne_of_gt (mul_pos (hW a) (hW b)) - exact (mul_left_cancel₀ hpos hpb).symm - -/-- **`superInv = superMap`.** Support gives `B a b = B (superMap a) (superInv b)`, and edge -preservation gives `B a b = B (superInv a) (superInv b)`; comparing over all columns -(`superInv` surjective) and applying twin-freeness identifies the two maps. -/ -theorem superInv_eq_superMap {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : - superInv B hB W hW htwin ξ ξ' hξ h = superMap ξ ξ' hξ := by - funext a - have hrow : B (superMap ξ ξ' hξ a) = B (superInv B hB W hW htwin ξ ξ' hξ h a) := by - funext w - obtain ⟨b, hb⟩ := (superInv_bijective B hB W hW htwin ξ ξ' hξ h).surjective w - rw [← hb, ← superInv_spec B hB W hW htwin ξ ξ' hξ h b a] - exact (superInv_preserves_B B hB W hW htwin ξ ξ' hξ h a b).symm - by_contra hne - exact (htwin (superMap ξ ξ' hξ a) (superInv B hB W hW htwin ξ ξ' hξ h a) - (fun heq => hne heq.symm)) hrow - -/-! ### Chunk 3A.5 exports: superMap is a weighted automorphism -/ - -theorem superMap_preserves_B {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (a b : Fin T) : - B (superMap ξ ξ' hξ a) (superMap ξ ξ' hξ b) = B a b := by - rw [← superInv_eq_superMap B hB W hW htwin ξ ξ' hξ h] - exact superInv_preserves_B B hB W hW htwin ξ ξ' hξ h a b - -theorem superMap_preserves_W {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (a : Fin T) : - W (superMap ξ ξ' hξ a) = W a := by - rw [← superInv_eq_superMap B hB W hW htwin ξ ξ' hξ h] - exact superInv_preserves_W B hB W hW htwin ξ ξ' hξ h a - -/-- **The super-surjective orbit automorphism.** `superPerm` is a weighted automorphism of -`(B, W)` — the certified output of chunk 3A.5. -/ -theorem superMap_isWeightedAutomorphism {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : - IsWeightedAutomorphism B W (superPerm B hB W hW htwin ξ ξ' hξ h) := by - refine ⟨fun i => ?_, fun i j => ?_⟩ - · rw [superPerm_apply]; exact superMap_preserves_W B hB W hW htwin ξ ξ' hξ h i - · rw [superPerm_apply, superPerm_apply]; exact superMap_preserves_B B hB W hW htwin ξ ξ' hξ h i j - -/-- **One-extra-label raw moment identity.** Attaching a single distinguished label `i₀` to a -star-test graph and selecting disjoint exponent blocks inside the (large) super-fibres minus -`{i₀}`, the `tupleEquivSimple` equality on the star graph yields the raw moment identity with one -extra `B (ξ i₀) t` / `B (ξ' i₀) t` factor. Reindexing the right-hand side by the orbit permutation -`superMap` (which preserves `W` and `B`) turns `B (ξ' i₀) t` into `B (ξ' i₀) (superMap t)` while -restoring the aligned exponent product `∏ⱼ (B j t) ^ k j`. -/ -theorem one_extra_label_moment {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (i₀ : Fin K) - (k : Fin T → ℕ) (hk : ∀ j, k j < T) : - ∑ t, W t * B (ξ i₀) t * ∏ j, (B j t) ^ k j - = ∑ t, W t * B (ξ' i₀) (superMap ξ ξ' hξ t) * ∏ j, (B j t) ^ k j := by - classical - -- Each super-fibre minus `{i₀}` is still large enough to hold `k j` labels. - have hbound : ∀ j, k j ≤ (superFiberSubset ξ ξ' hξ j \ {i₀}).card := by - intro j - have h1 := superFiberSubset_card ξ ξ' hξ j - have h2 : (superFiberSubset ξ ξ' hξ j).card - ≤ (superFiberSubset ξ ξ' hξ j \ {i₀}).card + ({i₀} : Finset (Fin K)).card := - Finset.card_le_card_sdiff_add_card - have h3 : ({i₀} : Finset (Fin K)).card = 1 := Finset.card_singleton i₀ - have h4 := hk j - omega - choose Kf hKf_sub hKf_card using fun j => - Finset.exists_subset_card_eq (s := superFiberSubset ξ ξ' hξ j \ {i₀}) (n := k j) (hbound j) - have hKf_sub' : ∀ j, Kf j ⊆ superFiberSubset ξ ξ' hξ j := - fun j => (hKf_sub j).trans Finset.sdiff_subset - have hi₀ : i₀ ∉ univ.biUnion Kf := by - intro hmem - rw [Finset.mem_biUnion] at hmem - obtain ⟨j, -, hj⟩ := hmem - have hj' := hKf_sub j hj - rw [Finset.mem_sdiff] at hj' - exact hj'.2 (Finset.mem_singleton_self i₀) - have hdisj : Set.PairwiseDisjoint (↑(univ : Finset (Fin T))) Kf := - fun j _ j' _ hjj => Finset.disjoint_of_subset_left (hKf_sub' j) - (Finset.disjoint_of_subset_right (hKf_sub' j') (superFiberSubset_disjoint ξ ξ' hξ hjj)) - have hLHS : ∀ t, ∏ i ∈ univ.biUnion Kf, B (ξ i) t = ∏ j, (B j t) ^ k j := fun t => - prod_biUnion_const hdisj - (fun j i hi => by rw [superFiberSubset_mem_left ξ ξ' hξ j (hKf_sub' j hi)]) hKf_card - have hRHS : ∀ t, ∏ i ∈ univ.biUnion Kf, B (ξ' i) t - = ∏ j, (B (superMap ξ ξ' hξ j) t) ^ k j := fun t => - prod_biUnion_const hdisj - (fun j i hi => by rw [superFiberSubset_image_const ξ ξ' hξ j i (hKf_sub' j hi)]) hKf_card - -- The star-test equality on `S = insert i₀ (⋃ⱼ Kf j)`. - have heq : simpleEvalAt B W (starTestGraph (insert i₀ (univ.biUnion Kf))) ξ - = simpleEvalAt B W (starTestGraph (insert i₀ (univ.biUnion Kf))) ξ' := - h.star (insert i₀ (univ.biUnion Kf)) - rw [simpleEvalAt_starTestGraph B hB W _ ξ, simpleEvalAt_starTestGraph B hB W _ ξ'] at heq - -- Phase A: raw moment identity with one extra `i₀` factor. - have phaseA : ∑ t, W t * B (ξ i₀) t * ∏ j, (B j t) ^ k j - = ∑ t, W t * B (ξ' i₀) t * ∏ j, (B (superMap ξ ξ' hξ j) t) ^ k j := by - calc ∑ t, W t * B (ξ i₀) t * ∏ j, (B j t) ^ k j - = ∑ t, W t * ∏ i ∈ insert i₀ (univ.biUnion Kf), B (ξ i) t := by - refine Finset.sum_congr rfl fun t _ => ?_ - rw [Finset.prod_insert hi₀, hLHS t]; ring - _ = ∑ t, W t * ∏ i ∈ insert i₀ (univ.biUnion Kf), B (ξ' i) t := heq - _ = ∑ t, W t * B (ξ' i₀) t * ∏ j, (B (superMap ξ ξ' hξ j) t) ^ k j := by - refine Finset.sum_congr rfl fun t _ => ?_ - rw [Finset.prod_insert hi₀, hRHS t]; ring - -- Phase B: reindex the right-hand side by the orbit permutation `superMap`. - have phaseB : ∑ t, W t * B (ξ' i₀) t * ∏ j, (B (superMap ξ ξ' hξ j) t) ^ k j - = ∑ t, W t * B (ξ' i₀) (superMap ξ ξ' hξ t) * ∏ j, (B j t) ^ k j := by - rw [← Equiv.sum_comp (superPerm B hB W hW htwin ξ ξ' hξ h) - (fun t => W t * B (ξ' i₀) t * ∏ j, (B (superMap ξ ξ' hξ j) t) ^ k j)] - refine Finset.sum_congr rfl fun u _ => ?_ - simp only [superPerm_apply] - rw [superMap_preserves_W B hB W hW htwin ξ ξ' hξ h u] - congr 1 - refine Finset.prod_congr rfl fun j _ => ?_ - rw [superMap_preserves_B B hB W hW htwin ξ ξ' hξ h j u] - exact phaseA.trans phaseB - -/-- **Full-fibre reconciliation (3A.6).** Every label `i` maps under `ξ'` to `superMap (ξ i)` — -not only the labels in the selected subsets. The one-extra-label moment identity feeds the -(graph-free) Vandermonde class-sum over `Fin T`: twin-freeness makes each profile fibre a -singleton, positivity gives `B (ξ i₀) t = B (ξ' i₀) (superMap t)` for all `t`, and applying the -automorphism property identifies `ξ' i₀ = superMap (ξ i₀)`. -/ -theorem superMap_agrees_on_all_labels {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : - ∀ i : Fin K, ξ' i = superMap ξ ξ' hξ (ξ i) := by - intro i₀ - have hmom : ∀ k : Fin T → ℕ, (∀ j, k j < T) → - ∑ t, (W t * (B (ξ i₀) t - B (ξ' i₀) (superMap ξ ξ' hξ t))) * ∏ j, (B j t) ^ k j = 0 := by - intro k hk - have heq := one_extra_label_moment B hB W hW htwin ξ ξ' hξ h i₀ k hk - have hsplit : ∑ t, (W t * (B (ξ i₀) t - B (ξ' i₀) (superMap ξ ξ' hξ t))) * ∏ j, (B j t) ^ k j - = (∑ t, W t * B (ξ i₀) t * ∏ j, (B j t) ^ k j) - - (∑ t, W t * B (ξ' i₀) (superMap ξ ξ' hξ t) * ∏ j, (B j t) ^ k j) := by - rw [← Finset.sum_sub_distrib] - refine Finset.sum_congr rfl (fun t _ => ?_); ring - rw [hsplit, heq, sub_self] - have hstar : ∀ t, B (ξ i₀) t = B (ξ' i₀) (superMap ξ ξ' hξ t) := by - intro t₀ - have hclass := CaiGovorov.multivariate_vandermonde_class_sums_zero - (fun t => fun j => B j t) - (fun t => W t * (B (ξ i₀) t - B (ξ' i₀) (superMap ξ ξ' hξ t))) - (fun ℓ hℓ => hmom ℓ (fun j => Fintype.card_fin T ▸ hℓ j)) (fun j => B j t₀) - have hfilt : (univ.filter (fun t => (fun j => B j t) = (fun j => B j t₀))) = {t₀} := by - ext t - simp only [Finset.mem_filter, Finset.mem_univ, true_and, Finset.mem_singleton] - constructor - · intro hcol - by_contra hne - refine htwin t t₀ hne ?_ - funext j; have hj := congrFun hcol j; rw [hB t j, hB t₀ j]; exact hj - · rintro rfl; rfl - rw [hfilt, Finset.sum_singleton] at hclass - rcases mul_eq_zero.mp hclass with h0 | h0 - · exact absurd h0 (ne_of_gt (hW t₀)) - · exact sub_eq_zero.mp h0 - by_contra hne - refine htwin (superMap ξ ξ' hξ (ξ i₀)) (ξ' i₀) (fun heq => hne heq.symm) ?_ - funext u - obtain ⟨t, ht⟩ := (superMap_bijective B hB W hW htwin ξ ξ' hξ h).surjective u - rw [← ht, superMap_preserves_B B hB W hW htwin ξ ξ' hξ h (ξ i₀) t] - exact hstar t - -/-- **Chunk 3A core — the super-surjective Cai–Govorov orbit separation, moment form.** If `ξ` -is super-surjective and the star/edge test evaluations agree (`TestEvalEq`), then `ξ'` is in the -weighted-automorphism orbit of `ξ`. Combines `superMap_isWeightedAutomorphism` with the -full-fibre reconciliation. The `TestEvalEq` interface (rather than full `tupleEquivSimple`) is -what the eq. (10) descent step can supply for matched extensions. -/ -theorem testEvalEq_implies_orbit_super {T : ℕ} (B : Fin T → Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) - (htwin : ∀ i j, i ≠ j → B i ≠ B j) (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) - (h : TestEvalEq B W ξ ξ') : - tupleOrbitRel B W ξ ξ' := - ⟨superPerm B hB W hW htwin ξ ξ' hξ h, - superMap_isWeightedAutomorphism B hB W hW htwin ξ ξ' hξ h, - fun i => by rw [superPerm_apply]; exact superMap_agrees_on_all_labels B hB W hW htwin ξ ξ' hξ h i⟩ - -/-- **Chunk 3A — the super-surjective Cai–Govorov orbit separation.** If `ξ` is super-surjective -and `ξ ≈ ξ'` (equal simple-graph evaluations), then `ξ'` is in the weighted-automorphism orbit of -`ξ`. Wrapper around the moment-form core `testEvalEq_implies_orbit_super`. -/ -theorem tupleEquivSimple_implies_orbit_super {T : ℕ} (B : Fin T → Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) - (htwin : ∀ i j, i ≠ j → B i ≠ B j) (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) - (h : tupleEquivSimple B W ξ ξ') : - tupleOrbitRel B W ξ ξ' := - testEvalEq_implies_orbit_super B hB W hW htwin ξ ξ' hξ (.of_tupleEquivSimple h) - -/-! ## Chunk 3B.1b: iterating the trace over the extra labels - -The trace operator `MultiLabeledGraph.trace` folds the *last* label into a new unlabeled -vertex. Iterating it `m` times folds the last `m` labels of a `(K+m)`-labeled multigraph, -yielding a `K`-labeled multigraph on `n + m` unlabeled vertices. The closure identity -`multiLabeledEvalK_sum_last_label` then accumulates into a `W`-weighted sum over the `m` -folded label values (`ρ : Fin m → Fin T`). -/ - -/-- **Unlabeled re-cast of a multigraph.** Reindex the vertex space `Fin (b + K)` of a target -multigraph onto `Fin (a + K)` through the val-preserving `Fin.cast`, when `a = b`. Used to -reconcile `(n + 1) + m` with `n + (m + 1)` in `traceIterExtraLabels`. -/ -def MultiLabeledGraph.castUnlabeled {K a b : ℕ} (hab : a = b) (M : MultiLabeledGraph K a) : - MultiLabeledGraph K b where - mult e := M.mult (Sym2.map (Fin.cast (by rw [hab])) e) - multNoLoop x := by rw [Sym2.map_mk]; exact M.multNoLoop _ - -/-- The multigraph evaluation is invariant under the val-preserving unlabeled re-cast. -/ -theorem multiLabeledEvalK_castUnlabeled {T K a b : ℕ} (hab : a = b) - (M : MultiLabeledGraph K a) (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) (φ : Fin K → Fin T) : - multiLabeledEvalK K b (M.castUnlabeled hab) B W φ = multiLabeledEvalK K a M B W φ := by - subst hab - have hmult : ∀ e : Sym2 (Fin (a + K)), (M.castUnlabeled (rfl : a = a)).mult e = M.mult e := by - intro e - refine congrArg M.mult ?_ - refine Sym2.ind (fun x y => ?_) e - rw [Sym2.map_mk, Fin.cast_eq_self, Fin.cast_eq_self] - simp only [multiLabeledEvalK] - refine Finset.sum_congr rfl fun σ _ => ?_ - congr 1 - refine Finset.prod_congr rfl fun e _ => ?_ - rw [hmult e] - -/-- **Iterated trace** over the last `m` labels. Folds the last `m` labels of a `(K+m)`-labeled -multigraph into `m` new unlabeled vertices, yielding a `K`-labeled multigraph on `n + m` -unlabeled vertices. Recurses on `m`, threading `MultiLabeledGraph.trace` and reconciling the -`(n+1)+m = n+(m+1)` vertex-count mismatch with `castUnlabeled`. -/ -def traceIterExtraLabels {K : ℕ} : ∀ {n : ℕ} (m : ℕ), - MultiLabeledGraph (K + m) n → MultiLabeledGraph K (n + m) - | _, 0, M => M - | n, m + 1, M => - (traceIterExtraLabels m M.trace).castUnlabeled (by omega : (n + 1) + m = n + (m + 1)) - -/-- **Eq. (10) core** (3B.1 pillar). Unpinning the last `m` labels: summing the `(K+m)`-labeled -evaluation over the extra label values `ρ`, weighted by `∏ⱼ W(ρ j)`, equals the `K`-labeled -evaluation of the `m`-fold trace `traceIterExtraLabels m M`. Induction on `m`, peeling the last -label each step via `multiLabeledEvalK_sum_last_label`. Purely multigraph-side; bridged to simple -graphs by `traceIterExtraLabels_ofSimple_eq` and fed into `extension_sum_identity`. -/ -theorem multiLabeledEvalK_sum_extra_labels {K m n T : ℕ} - (M : MultiLabeledGraph (K + m) n) (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (φ : Fin K → Fin T) : - ∑ ρ : Fin m → Fin T, - (∏ j : Fin m, W (ρ j)) * multiLabeledEvalK (K + m) n M B W (Fin.append φ ρ) - = multiLabeledEvalK K (n + m) (traceIterExtraLabels m M) B W φ := by - induction m generalizing n with - | zero => - rw [Fintype.sum_unique, Fin.prod_univ_zero, one_mul] - have happ : Fin.append φ (default : Fin 0 → Fin T) = φ := by - rw [Fin.append_right_nil φ _ rfl] - funext v - exact congrArg φ (Fin.ext rfl) - rw [happ] - rfl - | succ m ih => - have hcast : multiLabeledEvalK K (n + (m + 1)) (traceIterExtraLabels (m + 1) M) B W φ - = multiLabeledEvalK K ((n + 1) + m) (traceIterExtraLabels m M.trace) B W φ := by - rw [show traceIterExtraLabels (m + 1) M - = (traceIterExtraLabels m M.trace).castUnlabeled - (by omega : (n + 1) + m = n + (m + 1)) from rfl] - rw [multiLabeledEvalK_castUnlabeled] - rw [hcast, ← ih M.trace] - -- Normalize the label count `K + (m+1)` to `K + m + 1` to align with `sum_last_label`. - show ∑ ρ : Fin (m + 1) → Fin T, - (∏ j : Fin (m + 1), W (ρ j)) * - multiLabeledEvalK (K + m + 1) n M B W (@Fin.append K (m + 1) (Fin T) φ ρ) - = ∑ ρ : Fin m → Fin T, - (∏ j : Fin m, W (ρ j)) * - multiLabeledEvalK (K + m) (n + 1) M.trace B W (Fin.append φ ρ) - -- Split the last folded label `x` off `ρ = Fin.snoc ρ₀ x`. - have hsnocEq : ∀ p : Fin T × (Fin m → Fin T), - (Fin.snocEquiv (fun _ : Fin (m + 1) => Fin T)) p = Fin.snoc p.2 p.1 := - fun p => funext fun x => Fin.snocEquiv_apply (fun _ : Fin (m + 1) => Fin T) p x - rw [← Equiv.sum_comp (Fin.snocEquiv (fun _ : Fin (m + 1) => Fin T)), - Fintype.sum_prod_type] - simp only [hsnocEq] - rw [Finset.sum_comm] - refine Finset.sum_congr rfl fun ρ₀ _ => ?_ - simp only [Fin.prod_univ_castSucc, Fin.snoc_castSucc, Fin.snoc_last, Fin.append_snoc] - have hlast : ∑ x : Fin T, - W x * multiLabeledEvalK (K + m + 1) n M B W (Fin.snoc (Fin.append φ ρ₀) x) - = multiLabeledEvalK (K + m) (n + 1) M.trace B W (Fin.append φ ρ₀) := - multiLabeledEvalK_sum_last_label M B hB W (Fin.append φ ρ₀) - rw [← hlast, Finset.mul_sum] - refine Finset.sum_congr rfl fun x _ => ?_ - ring - -/-! ## Chunk 3B.1c step 2: the trace-to-simple eval bridge -/ - -/-- Local (public) connector: `simpleEvalAt` is `multiLabeledEvalK` on `ofSimple` -(the file-local analog of the private `simpleEvalAt_eq_multi` in `Lovasz`). -/ -theorem simpleEvalAt_eq_multi' {T K n : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (F : SimpleGraph (Fin (n + K))) [DecidableRel F.Adj] (ξ : Fin K → Fin T) : - simpleEvalAt B W F ξ = multiLabeledEvalK K n (MultiLabeledGraph.ofSimple F) B W ξ := by - rw [multiLabeledEvalK_ofSimple]; rfl - -/-- **Unlabel-extras simple graph.** Comap of `G` along the val-preserving cast -`Fin ((n + m) + K) → Fin (n + (K + m))`, moving the last `m` labels back into unlabeled -position. The trace bridge (`traceIterExtraLabels_ofSimple_eq`) identifies -`traceIterExtraLabels m (ofSimple G)` with `ofSimple (unlabelExtras G)`. -/ -def unlabelExtras {K m n : ℕ} (G : SimpleGraph (Fin (n + (K + m)))) : - SimpleGraph (Fin ((n + m) + K)) := - SimpleGraph.comap (Fin.cast (by omega : (n + m) + K = n + (K + m))) G - -noncomputable instance {K m n} (G : SimpleGraph (Fin (n + (K + m)))) [DecidableRel G.Adj] : - DecidableRel (unlabelExtras G).Adj := Classical.decRel _ - -/-- **Net-cast lemma** (the crux). The iterated `trace`/`castUnlabeled` reindexing collapses to -a single val-preserving `Fin.cast`: reading a multiplicity of `traceIterExtraLabels m M` at `e` -equals reading `M`'s multiplicity at the cast of `e`. -/ -theorem traceIterExtraLabels_mult {K : ℕ} : ∀ {n : ℕ} (m : ℕ) (M : MultiLabeledGraph (K + m) n) - (e : Sym2 (Fin ((n + m) + K))), - (traceIterExtraLabels m M).mult e - = M.mult (Sym2.map (Fin.cast (by omega : (n + m) + K = n + (K + m))) e) := by - intro n m - induction m generalizing n with - | zero => - intro M e - refine e.ind fun x y => ?_ - show M.mult s(x, y) = M.mult (Sym2.map (Fin.cast _) s(x, y)) - rw [Sym2.map_mk] - congr 1 - | succ m ih => - intro M e - rw [show traceIterExtraLabels (m + 1) M - = (traceIterExtraLabels m M.trace).castUnlabeled - (by omega : (n + 1) + m = n + (m + 1)) from rfl] - refine e.ind fun x y => ?_ - show (traceIterExtraLabels m M.trace).mult (Sym2.map (Fin.cast _) s(x, y)) - = M.mult (Sym2.map (Fin.cast _) s(x, y)) - rw [ih M.trace] - show M.mult (Sym2.map (Fin.cast _) (Sym2.map (Fin.cast _) (Sym2.map (Fin.cast _) s(x, y)))) - = M.mult (Sym2.map (Fin.cast _) s(x, y)) - rw [Sym2.map_mk, Sym2.map_mk, Sym2.map_mk, Sym2.map_mk] - congr 1 - -/-- **Graph bridge.** Iterating the trace over the extra labels of an `ofSimple` multigraph -yields the `ofSimple` multigraph of the unlabel-extras simple graph. -/ -theorem traceIterExtraLabels_ofSimple_eq {K m n : ℕ} (G : SimpleGraph (Fin (n + (K + m)))) - [DecidableRel G.Adj] : - traceIterExtraLabels m (MultiLabeledGraph.ofSimple G) - = MultiLabeledGraph.ofSimple (unlabelExtras G) := by - have hiff : ∀ e : Sym2 (Fin ((n + m) + K)), - (Sym2.map (Fin.cast (by omega : (n + m) + K = n + (K + m))) e) ∈ G.edgeFinset - ↔ e ∈ (unlabelExtras G).edgeFinset := by - refine fun e => e.ind fun u v => ?_ - rw [Sym2.map_mk] - simp only [SimpleGraph.mem_edgeFinset, SimpleGraph.mem_edgeSet, unlabelExtras, - SimpleGraph.comap_adj] - have hmult : ∀ e, (traceIterExtraLabels m (MultiLabeledGraph.ofSimple G)).mult e - = (MultiLabeledGraph.ofSimple (unlabelExtras G)).mult e := by - intro e - rw [traceIterExtraLabels_mult] - show (if (Sym2.map (Fin.cast _) e) ∈ G.edgeFinset then (1 : ℕ) else 0) - = (if e ∈ (unlabelExtras G).edgeFinset then (1 : ℕ) else 0) - rw [if_congr (hiff e) rfl rfl] - rcases hG : MultiLabeledGraph.ofSimple (unlabelExtras G) with ⟨mu, mnu⟩ - rcases hT : traceIterExtraLabels m (MultiLabeledGraph.ofSimple G) with ⟨mt, mnt⟩ - show MultiLabeledGraph.mk _ _ = MultiLabeledGraph.mk _ _ - congr 1 - funext e - have := hmult e - rw [hG, hT] at this - exact this - -/-- **Eval bridge** (the step-2 target). Evaluating the traced `ofSimple G` multigraph equals the -simple-graph evaluation of the unlabel-extras graph. -/ -theorem traceIterExtraLabels_ofSimple_eval {T K m n : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (G : SimpleGraph (Fin (n + (K + m)))) [DecidableRel G.Adj] (ξ : Fin K → Fin T) : - multiLabeledEvalK K (n + m) (traceIterExtraLabels m (MultiLabeledGraph.ofSimple G)) B W ξ - = simpleEvalAt B W (unlabelExtras G) ξ := by - rw [traceIterExtraLabels_ofSimple_eq, ← simpleEvalAt_eq_multi'] - -/-! ### Chunk 3B.1c steps 3–5: extension family (extras-last) and equation (10) -/ - -/-- `μ : Fin (K + m) → Fin T` extends `ξ` if it agrees with `ξ` on the first `K` labels. -(`abbrev` so the subtype `{μ // ExtendsFin ξ μ}` gets `DecidablePred`/`Fintype` automatically.) -/ -abbrev ExtendsFin {T m : ℕ} (ξ : Fin K → Fin T) (μ : Fin (K + m) → Fin T) : Prop := - ∀ i : Fin K, μ (Fin.castAdd m i) = ξ i - -/-- The `W`-product over the `m` extra label values of `μ`. -/ -noncomputable def extensionWeightFin {T m : ℕ} (W : Fin T → ℝ) (μ : Fin (K + m) → Fin T) : ℝ := - ∏ j : Fin m, W (μ (Fin.natAdd K j)) - -/-- Extensions of `ξ` are exactly `Fin.append ξ ρ` for the free extra-value tuple `ρ`. -/ -def appendExtensionEquiv {T m : ℕ} (ξ : Fin K → Fin T) : - (Fin m → Fin T) ≃ {μ : Fin (K + m) → Fin T // ExtendsFin ξ μ} where - toFun ρ := ⟨Fin.append ξ ρ, by intro i; rw [Fin.append_left]⟩ - invFun μ := fun j => μ.1 (Fin.natAdd K j) - left_inv ρ := by - funext j - show Fin.append ξ ρ (Fin.natAdd K j) = ρ j - rw [Fin.append_right] - right_inv μ := by - apply Subtype.ext - funext k - show Fin.append ξ (fun j => μ.1 (Fin.natAdd K j)) k = μ.1 k - refine Fin.addCases (fun i => ?_) (fun j => ?_) k - · rw [Fin.append_left]; exact (μ.2 i).symm - · rw [Fin.append_right] - -theorem sum_extensions_eq_sum_rho {T m n : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (G : SimpleGraph (Fin (n + (K + m)))) [DecidableRel G.Adj] (ξ : Fin K → Fin T) : - ∑ μ : {μ : Fin (K + m) → Fin T // ExtendsFin ξ μ}, - extensionWeightFin W μ.1 * simpleEvalAt B W G μ.1 - = ∑ ρ : Fin m → Fin T, (∏ j, W (ρ j)) * simpleEvalAt B W G (Fin.append ξ ρ) := by - rw [← Equiv.sum_comp (appendExtensionEquiv ξ) - (fun μ => extensionWeightFin W μ.1 * simpleEvalAt B W G μ.1)] - refine Finset.sum_congr rfl (fun ρ _ => ?_) - show extensionWeightFin W (Fin.append ξ ρ) * simpleEvalAt B W G (Fin.append ξ ρ) - = (∏ j, W (ρ j)) * simpleEvalAt B W G (Fin.append ξ ρ) - congr 1 - unfold extensionWeightFin - exact Finset.prod_congr rfl (fun j _ => by rw [Fin.append_right]) - -/-- **Extension-sum collapse** (one side of eq. (10)). The weighted sum of `simpleEvalAt G` -over ALL extensions of `ζ` collapses to a single simple evaluation at `ζ` — of the -unlabel-extras graph. Extracted from `extension_sum_identity`; reused by the rank-residue -annihilator argument (chunk 5B). -/ -theorem sum_extensions_eval {T m n : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (G : SimpleGraph (Fin (n + (K + m)))) [DecidableRel G.Adj] - (ζ : Fin K → Fin T) : - ∑ μ : {μ : Fin (K + m) → Fin T // ExtendsFin ζ μ}, - extensionWeightFin W μ.1 * simpleEvalAt B W G μ.1 - = simpleEvalAt B W (unlabelExtras G) ζ := by - rw [sum_extensions_eq_sum_rho B W G ζ, - show (∑ ρ : Fin m → Fin T, (∏ j, W (ρ j)) * simpleEvalAt B W G (Fin.append ζ ρ)) - = ∑ ρ : Fin m → Fin T, (∏ j, W (ρ j)) * - multiLabeledEvalK (K + m) n (MultiLabeledGraph.ofSimple G) B W (Fin.append ζ ρ) from - Finset.sum_congr rfl (fun ρ _ => by rw [simpleEvalAt_eq_multi']), - multiLabeledEvalK_sum_extra_labels (MultiLabeledGraph.ofSimple G) B hB W ζ, - traceIterExtraLabels_ofSimple_eval B W G ζ] - -/-- **Equation (10)** (Cai–Govorov, the extension-family sum identity). Simple-equivalence at -level `K` lifts to an equality of extension-family sums at level `K + m`: unpinning the extra -labels (trace-to-simple bridge) reduces both sides to `simpleEvalAt` of `unlabelExtras G`, where -`h` applies. -/ -theorem extension_sum_identity {T m n : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} (h : tupleEquivSimple B W ξ ξ') - (G : SimpleGraph (Fin (n + (K + m)))) [DecidableRel G.Adj] : - ∑ μ : {μ : Fin (K + m) → Fin T // ExtendsFin ξ μ}, - extensionWeightFin W μ.1 * simpleEvalAt B W G μ.1 - = ∑ ν : {ν : Fin (K + m) → Fin T // ExtendsFin ξ' ν}, - extensionWeightFin W ν.1 * simpleEvalAt B W G ν.1 := by - rw [sum_extensions_eval B hB W G ξ, sum_extensions_eval B hB W G ξ'] - exact h (n + m) (unlabelExtras G) - -/-! ### Chunk 3B.2a: the concrete super-surjective extension of `ξ` (extras-last) -/ - -/-- The extra-value tuple that maps `2*T²` labels to each host vertex. Uses the product equiv -`Fin T × Fin (2*T²) ≃ Fin (T * (2*T²))`: label `j` maps to the vertex component of `j`. -/ -noncomputable def coverExtra (T : ℕ) : Fin (T * (2 * T ^ 2)) → Fin T := - fun j => (finProdFinEquiv.symm j).1 - -/-- The canonical super-surjective extension of `ξ`: keep `ξ` on the first `K` labels, then add -`T * (2*T²)` extra labels covering every host vertex `2*T²` times. -/ -noncomputable def superExt {T : ℕ} (ξ : Fin K → Fin T) : - Fin (K + T * (2 * T ^ 2)) → Fin T := - Fin.append ξ (coverExtra T) - -theorem superExt_extends {T : ℕ} (ξ : Fin K → Fin T) : - ExtendsFin ξ (superExt ξ) := by - intro i; rw [superExt, Fin.append_left] - -theorem coverExtra_fiber_card {T : ℕ} (v : Fin T) : - (univ.filter (fun j => coverExtra T j = v)).card = 2 * T ^ 2 := by - classical - have hg_inj : Function.Injective - (fun c : Fin (2 * T ^ 2) => finProdFinEquiv (v, c)) := by - intro c₁ c₂ h - exact congrArg Prod.snd (finProdFinEquiv.injective h) - have hset : univ.filter (fun j => coverExtra T j = v) - = univ.image (fun c : Fin (2 * T ^ 2) => finProdFinEquiv (v, c)) := by - ext j - simp only [Finset.mem_filter, Finset.mem_univ, true_and, Finset.mem_image] - constructor - · intro hj - simp only [coverExtra] at hj - refine ⟨(finProdFinEquiv.symm j).2, ?_⟩ - rw [← hj] - exact finProdFinEquiv.apply_symm_apply j - · rintro ⟨c, rfl⟩ - simp only [coverExtra, Equiv.symm_apply_apply] - rw [hset, Finset.card_image_of_injective _ hg_inj, Finset.card_univ, Fintype.card_fin] - -theorem superExt_superSurjective {T : ℕ} (ξ : Fin K → Fin T) : - SuperSurjective (superExt ξ) := by - intro v - classical - have hsub : (univ.filter (fun j => coverExtra T j = v)).image (Fin.natAdd K) - ⊆ univ.filter (fun i => superExt ξ i = v) := by - intro i hi - rw [Finset.mem_image] at hi - obtain ⟨j, hj, rfl⟩ := hi - rw [Finset.mem_filter] at hj ⊢ - refine ⟨Finset.mem_univ _, ?_⟩ - show superExt ξ (Fin.natAdd K j) = v - rw [superExt, Fin.append_right] - exact hj.2 - have hcard : ((univ.filter (fun j => coverExtra T j = v)).image (Fin.natAdd K)).card - = 2 * T ^ 2 := by - rw [Finset.card_image_of_injective _ (Fin.natAdd_injective (T * (2 * T ^ 2)) K), - coverExtra_fiber_card] - have hle : 2 * T ^ 2 ≤ (univ.filter (fun i => superExt ξ i = v)).card := by - have hcle := Finset.card_le_card hsub - rwa [hcard] at hcle - calc 2 * T * T = 2 * T ^ 2 := by ring - _ ≤ _ := hle - -/-! ### Chunk 3B.2b: separation (contrapositive of the super-surjective case) -/ - -/-- **Separation at the super-surjective reference** (contrapositive of -`tupleEquivSimple_implies_orbit_super` at `η = superExt ξ`): any extension `μ` not in the -weighted-automorphism orbit of `superExt ξ` is *not* simple-equivalent to it — some simple -graph separates them. - -NB not on the live descent path: the paper's plan built a finite separating family from this -oracle, but the formalized descent (chunk 4F, `exists_matching_extension`) runs the -class-balance Vandermonde directly and never consumes this statement. Kept as the documented -separation form of the super-case. -/ -theorem not_tupleEquivSimple_of_not_orbit {T : ℕ} (B : Fin T → Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) - (htwin : ∀ i j, i ≠ j → B i ≠ B j) (ξ : Fin K → Fin T) - (μ : Fin (K + T * (2 * T ^ 2)) → Fin T) - (hnotorbit : ¬ tupleOrbitRel B W (superExt ξ) μ) : - ¬ tupleEquivSimple B W (superExt ξ) μ := - fun heq => hnotorbit (tupleEquivSimple_implies_orbit_super B hB W hW htwin (superExt ξ) μ - (superExt_superSurjective ξ) heq) - -/-! ## Chunk 4B: the mult ≤ 1 bridge — multigraphs that are secretly simple - -Products of test evaluations are realized (chunks 4C/4D) as `glue`s of `ofSimple` test -multigraphs. Since the test graphs have no label-label edges, the glued multiplicities never -exceed 1, and such a multigraph converts back to an honest `SimpleGraph` with the same -evaluation. This section provides the invariants (`SimpleMult`, `NoLabelPairs`), the -conversion (`toSimple` with `ofSimple_toSimple`/`simpleEvalAt_toSimple`), and preservation of -the invariants under `glue` — where label-label pairs are the ONLY place multiplicities add, -which is exactly what `NoLabelPairs` forbids. -/ - -/-- All multiplicities are at most 1 — the multigraph is (the `ofSimple` image of) a simple -graph. -/ -def MultiLabeledGraph.SimpleMult {K n : ℕ} (M : MultiLabeledGraph K n) : Prop := - ∀ e, M.mult e ≤ 1 - -/-- No edge joins two labeled vertices (labels sit at values `< K`). Under `glue`, label-label -pairs are the only place multiplicities ADD; this invariant keeps the glue multiplicity-safe. -/ -def MultiLabeledGraph.NoLabelPairs {K n : ℕ} (M : MultiLabeledGraph K n) : Prop := - ∀ a b : Fin (n + K), (a : ℕ) < K → (b : ℕ) < K → M.mult s(a, b) = 0 - -/-- Convert a multigraph back to a simple graph: edges are the multiplicity-1 pairs. Inverse to -`MultiLabeledGraph.ofSimple` on multiplicity-≤-1 multigraphs (`ofSimple_toSimple`). -/ -noncomputable def MultiLabeledGraph.toSimple {K n : ℕ} (M : MultiLabeledGraph K n) : - SimpleGraph (Fin (n + K)) := - SimpleGraph.fromEdgeSet {e | M.mult e = 1} - -noncomputable instance {K n : ℕ} (M : MultiLabeledGraph K n) : DecidableRel M.toSimple.Adj := - Classical.decRel _ - -theorem MultiLabeledGraph.mem_toSimple_edgeFinset {K n : ℕ} (M : MultiLabeledGraph K n) - (e : Sym2 (Fin (n + K))) : e ∈ M.toSimple.edgeFinset ↔ M.mult e = 1 := by - refine Sym2.ind (fun x y => ?_) e - simp only [SimpleGraph.mem_edgeFinset, MultiLabeledGraph.toSimple, - SimpleGraph.edgeSet_fromEdgeSet, Set.mem_sdiff, Set.mem_setOf_eq, Sym2.mem_diagSet, - Sym2.mk_isDiag_iff] - refine ⟨fun h => h.1, fun he => ⟨he, fun hxy => ?_⟩⟩ - subst hxy - rw [M.multNoLoop x] at he - exact one_ne_zero he.symm - -/-- Multigraphs with equal multiplicity functions are equal (`multNoLoop` is a proposition). -/ -theorem MultiLabeledGraph.ext' {K n : ℕ} {M₁ M₂ : MultiLabeledGraph K n} - (h : M₁.mult = M₂.mult) : M₁ = M₂ := by - cases M₁; cases M₂; subst h; rfl - -/-- `toSimple` is a section of `ofSimple` on multiplicity-≤-1 multigraphs. -/ -theorem MultiLabeledGraph.ofSimple_toSimple {K n : ℕ} (M : MultiLabeledGraph K n) - (hM : M.SimpleMult) : MultiLabeledGraph.ofSimple M.toSimple = M := by - refine MultiLabeledGraph.ext' (funext fun e => ?_) - show (if e ∈ M.toSimple.edgeFinset then 1 else 0) = M.mult e - by_cases he : e ∈ M.toSimple.edgeFinset - · rw [if_pos he, (M.mem_toSimple_edgeFinset e).mp he] - · rw [if_neg he] - have h1 : M.mult e ≠ 1 := fun h1 => he ((M.mem_toSimple_edgeFinset e).mpr h1) - have h2 := hM e - omega - -/-- Evaluating the simple graph `M.toSimple` agrees with the multigraph evaluation of `M`, -provided all multiplicities are ≤ 1. -/ -theorem simpleEvalAt_toSimple {T K n : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (M : MultiLabeledGraph K n) (hM : M.SimpleMult) (ξ : Fin K → Fin T) : - simpleEvalAt B W M.toSimple ξ = multiLabeledEvalK K n M B W ξ := by - rw [simpleEvalAt_eq_multi', M.ofSimple_toSimple hM] - -/-! ### Invariant suppliers: `ofSimple`, the test graphs, and `empty` -/ - -theorem MultiLabeledGraph.ofSimple_simpleMult {K n : ℕ} (F : SimpleGraph (Fin (n + K))) - [DecidableRel F.Adj] : (MultiLabeledGraph.ofSimple F).SimpleMult := fun e => by - show (if e ∈ F.edgeFinset then 1 else 0) ≤ 1 - split_ifs <;> omega - -theorem MultiLabeledGraph.ofSimple_noLabelPairs {K n : ℕ} (F : SimpleGraph (Fin (n + K))) - [DecidableRel F.Adj] - (hF : ∀ a b : Fin (n + K), (a : ℕ) < K → (b : ℕ) < K → s(a, b) ∉ F.edgeFinset) : - (MultiLabeledGraph.ofSimple F).NoLabelPairs := fun a b ha hb => by - show (if s(a, b) ∈ F.edgeFinset then 1 else 0) = 0 - rw [if_neg (hF a b ha hb)] - -theorem MultiLabeledGraph.empty_simpleMult {K n : ℕ} : - (MultiLabeledGraph.empty K n).SimpleMult := fun _ => Nat.zero_le 1 - -theorem MultiLabeledGraph.empty_noLabelPairs {K n : ℕ} : - (MultiLabeledGraph.empty K n).NoLabelPairs := fun _ _ _ _ => rfl - -/-- Every `starTestGraph` edge touches the unlabeled vertex (value `K`), so there are no -label-label edges. -/ -theorem starTestGraph_noLabelPairs (S : Finset (Fin K)) : - (MultiLabeledGraph.ofSimple (starTestGraph S)).NoLabelPairs := by - refine MultiLabeledGraph.ofSimple_noLabelPairs _ fun a b ha hb hmem => ?_ - rw [starTestGraph_edgeFinset, Finset.mem_image] at hmem - obtain ⟨i, -, heq⟩ := hmem - rw [Sym2.eq_iff] at heq - rcases heq with ⟨-, h2⟩ | ⟨-, h2⟩ <;> - (have := congrArg Fin.val h2; simp only [unlVertex] at this; omega) - -/-- Every `edgeTestGraph` edge touches an unlabeled vertex (values `K`, `K+1`), so there are no -label-label edges. -/ -theorem edgeTestGraph_noLabelPairs (Sₗ Sτ : Finset (Fin K)) : - (MultiLabeledGraph.ofSimple (edgeTestGraph Sₗ Sτ)).NoLabelPairs := by - refine MultiLabeledGraph.ofSimple_noLabelPairs _ fun a b ha hb hmem => ?_ - rw [edgeTestGraph_edgeFinset, Finset.mem_insert, Finset.mem_union] at hmem - rcases hmem with heq | hmem | hmem - · rw [Sym2.eq_iff] at heq - rcases heq with ⟨h1, -⟩ | ⟨h1, -⟩ <;> - (have := congrArg Fin.val h1; simp only [unlVertex0, unlVertex1] at this; omega) - all_goals - rw [Finset.mem_image] at hmem - obtain ⟨i, -, heq⟩ := hmem - rw [Sym2.eq_iff] at heq - rcases heq with ⟨-, h2⟩ | ⟨-, h2⟩ <;> - (have := congrArg Fin.val h2; simp only [unlVertex0, unlVertex1] at this; omega) - -/-! ### `glueCast` characterizations and invariant preservation under `glue` -/ - -theorem glueCast₁_some_val {K n₁ n₂ : ℕ} {v : Fin ((n₁ + n₂) + K)} {u : Fin (n₁ + K)} - (h : glueCast₁ K n₁ n₂ v = some u) : (u : ℕ) = (v : ℕ) ∧ (v : ℕ) < n₁ + K := by - unfold glueCast₁ at h - split_ifs at h with hv - exact ⟨congrArg Fin.val (Option.some.inj h).symm, hv⟩ - -theorem glueCast₂_some_val {K n₁ n₂ : ℕ} {v : Fin ((n₁ + n₂) + K)} {u : Fin (n₂ + K)} - (h : glueCast₂ K n₁ n₂ v = some u) : - ((v : ℕ) < K ∧ (u : ℕ) = (v : ℕ)) ∨ (n₁ + K ≤ (v : ℕ) ∧ (u : ℕ) = (v : ℕ) - n₁) := by - unfold glueCast₂ at h - split_ifs at h with h1 h2 - · exact Or.inl ⟨h1, congrArg Fin.val (Option.some.inj h).symm⟩ - · exact Or.inr ⟨h2, congrArg Fin.val (Option.some.inj h).symm⟩ - -theorem glueCast₁_ne_none_of_lt {K n₁ n₂ : ℕ} {v : Fin ((n₁ + n₂) + K)} - (hv : (v : ℕ) < n₁ + K) : glueCast₁ K n₁ n₂ v ≠ none := by - unfold glueCast₁; rw [dif_pos hv]; simp - -theorem glueCast₂_ne_none_of_lt {K n₁ n₂ : ℕ} {v : Fin ((n₁ + n₂) + K)} - (hv : (v : ℕ) < K) : glueCast₂ K n₁ n₂ v ≠ none := by - unfold glueCast₂; rw [dif_pos hv]; simp - -/-- `glue` preserves multiplicity ≤ 1, given `NoLabelPairs` on the second factor: the only -pairs where the two `glue` contributions can BOTH be nonzero are label-label pairs, and there -the `M₂` contribution vanishes. -/ -theorem MultiLabeledGraph.glue_simpleMult {K n₁ n₂ : ℕ} - {M₁ : MultiLabeledGraph K n₁} {M₂ : MultiLabeledGraph K n₂} - (h₁ : M₁.SimpleMult) (h₂ : M₂.SimpleMult) (hlp₂ : M₂.NoLabelPairs) : - (M₁.glue M₂).SimpleMult := by - intro e - refine Sym2.ind (fun a b => ?_) e - rw [MultiLabeledGraph.glue_mult_pair] - rcases hc1a : glueCast₁ K n₁ n₂ a with _ | u₁a <;> - rcases hc1b : glueCast₁ K n₁ n₂ b with _ | u₁b <;> - rcases hc2a : glueCast₂ K n₁ n₂ a with _ | u₂a <;> - rcases hc2b : glueCast₂ K n₁ n₂ b with _ | u₂b <;> - dsimp only <;> - first - | omega - | simpa using h₁ s(u₁a, u₁b) - | simpa using h₂ s(u₂a, u₂b) - | (obtain ⟨hu1a, hva⟩ := glueCast₁_some_val hc1a - obtain ⟨hu1b, hvb⟩ := glueCast₁_some_val hc1b - rcases glueCast₂_some_val hc2a with ⟨haK, hu2a⟩ | ⟨haK, -⟩ - · rcases glueCast₂_some_val hc2b with ⟨hbK, hu2b⟩ | ⟨hbK, -⟩ - · rw [hlp₂ u₂a u₂b (by omega) (by omega)] - simpa using h₁ s(u₁a, u₁b) - · omega - · omega) - -/-- `glue` preserves the no-label-pairs invariant. -/ -theorem MultiLabeledGraph.glue_noLabelPairs {K n₁ n₂ : ℕ} - {M₁ : MultiLabeledGraph K n₁} {M₂ : MultiLabeledGraph K n₂} - (h₁ : M₁.NoLabelPairs) (h₂ : M₂.NoLabelPairs) : (M₁.glue M₂).NoLabelPairs := by - intro a b ha hb - rw [MultiLabeledGraph.glue_mult_pair] - rcases hc1a : glueCast₁ K n₁ n₂ a with _ | u₁a - · exact absurd hc1a (glueCast₁_ne_none_of_lt (by omega)) - rcases hc1b : glueCast₁ K n₁ n₂ b with _ | u₁b - · exact absurd hc1b (glueCast₁_ne_none_of_lt (by omega)) - rcases hc2a : glueCast₂ K n₁ n₂ a with _ | u₂a - · exact absurd hc2a (glueCast₂_ne_none_of_lt ha) - rcases hc2b : glueCast₂ K n₁ n₂ b with _ | u₂b - · exact absurd hc2b (glueCast₂_ne_none_of_lt hb) - dsimp only - obtain ⟨hu1a, -⟩ := glueCast₁_some_val hc1a - obtain ⟨hu1b, -⟩ := glueCast₁_some_val hc1b - rcases glueCast₂_some_val hc2a with ⟨-, hu2a⟩ | ⟨haK, -⟩ - · rcases glueCast₂_some_val hc2b with ⟨-, hu2b⟩ | ⟨hbK, -⟩ - · rw [h₁ u₁a u₁b (by omega) (by omega), h₂ u₂a u₂b (by omega) (by omega)] - · omega - · omega - -/-! ## Chunk 4C: gluing lists of multigraphs — the iterated product law - -`glueList` folds a list of `K`-labeled multigraphs (of varying unlabeled sizes, packaged in a -sigma type) into one by repeated disjoint gluing; its evaluation is the product of the -component evaluations (iterating `multiLabeledEvalK_glue`), and it inherits the chunk-4B -invariants from its components. -/ - -/-- Sigma-packaged disjoint glue of two multigraphs with arbitrary unlabeled sizes. -/ -def glueSigma (p q : Σ n, MultiLabeledGraph K n) : Σ n, MultiLabeledGraph K n := - ⟨p.1 + q.1, p.2.glue q.2⟩ - -/-- Fold a list of multigraphs into one by repeated disjoint gluing (empty multigraph base). -/ -def glueList (l : List (Σ n, MultiLabeledGraph K n)) : Σ n, MultiLabeledGraph K n := - l.foldr glueSigma ⟨0, MultiLabeledGraph.empty K 0⟩ - -/-- **Iterated glue factorization**: the evaluation of `glueList l` is the product of the -component evaluations. -/ -theorem multiLabeledEvalK_glueList {T : ℕ} (B : Fin T → Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) - (l : List (Σ n, MultiLabeledGraph K n)) (μ : Fin K → Fin T) : - multiLabeledEvalK K (glueList l).1 (glueList l).2 B W μ - = (l.map fun p => multiLabeledEvalK K p.1 p.2 B W μ).prod := by - induction l with - | nil => - show multiLabeledEvalK K 0 (MultiLabeledGraph.empty K 0) B W μ = 1 - rw [multiLabeledEvalK_empty] - simp - | cons p l ih => - rw [List.map_cons, List.prod_cons, ← ih] - exact multiLabeledEvalK_glue B hB W p.2 (glueList l).2 μ - -/-- `glueList` inherits `NoLabelPairs` from its components. -/ -theorem glueList_noLabelPairs (l : List (Σ n, MultiLabeledGraph K n)) - (hlp : ∀ p ∈ l, p.2.NoLabelPairs) : (glueList l).2.NoLabelPairs := by - induction l with - | nil => exact MultiLabeledGraph.empty_noLabelPairs - | cons p l ih => - exact MultiLabeledGraph.glue_noLabelPairs (hlp p (by simp)) - (ih fun q hq => hlp q (List.mem_cons_of_mem p hq)) - -/-- `glueList` inherits `SimpleMult` from components that also satisfy `NoLabelPairs`. -/ -theorem glueList_simpleMult (l : List (Σ n, MultiLabeledGraph K n)) - (hs : ∀ p ∈ l, p.2.SimpleMult) (hlp : ∀ p ∈ l, p.2.NoLabelPairs) : - (glueList l).2.SimpleMult := by - induction l with - | nil => exact MultiLabeledGraph.empty_simpleMult - | cons p l ih => - exact MultiLabeledGraph.glue_simpleMult (hs p (by simp)) - (ih (fun q hq => hs q (List.mem_cons_of_mem p hq)) - (fun q hq => hlp q (List.mem_cons_of_mem p hq))) - (glueList_noLabelPairs l fun q hq => hlp q (List.mem_cons_of_mem p hq)) - -/-! ## Chunk 4D: the test-moment profile and its exponent graphs - -The Vandermonde step classifies extensions by their vector of star/edge test moments -(`testMoment`). The moment products `∏_c moment_c^{k c}` demanded by the multivariate -Vandermonde are realized as `simpleEvalAt` of a single simple graph `expTestGraph k`: -glue `k c` copies of each coordinate's test graph (a multigraph a priori, but mult ≤ 1 by -chunk 4B since test graphs have no label-label edges) and convert back via `toSimple`. -/ - -/-- Test-moment coordinates: `inl S` is the star test `Gχ S`; `inr (Sₗ, Sτ)` the edge test. -/ -abbrev TestCoord (L : ℕ) := Finset (Fin L) ⊕ (Finset (Fin L) × Finset (Fin L)) - -/-- The closed-form moment of a test coordinate at the tuple `μ` (the `simpleEvalAt` value of -the corresponding test graph, see `coordGraph_eval`). -/ -noncomputable def testMoment {T : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (c : TestCoord K) (μ : Fin K → Fin T) : ℝ := - Sum.elim (fun S => ∑ t, W t * ∏ i ∈ S, B (μ i) t) - (fun p => ∑ t, ∑ t', W t * W t' * B t t' - * (∏ i ∈ p.1, B (μ i) t) * (∏ i ∈ p.2, B (μ i) t')) c - -/-- The test coordinate's graph, as a sigma-packaged `ofSimple` multigraph. -/ -noncomputable def coordGraph (c : TestCoord K) : Σ n, MultiLabeledGraph K n := - Sum.elim (fun S => ⟨1, MultiLabeledGraph.ofSimple (starTestGraph S)⟩) - (fun p => ⟨2, MultiLabeledGraph.ofSimple (edgeTestGraph p.1 p.2)⟩) c - -theorem coordGraph_eval {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (c : TestCoord K) (μ : Fin K → Fin T) : - multiLabeledEvalK K (coordGraph c).1 (coordGraph c).2 B W μ = testMoment B W c μ := by - cases c with - | inl S => - show multiLabeledEvalK K 1 (MultiLabeledGraph.ofSimple (starTestGraph S)) B W μ = _ - rw [← simpleEvalAt_eq_multi', simpleEvalAt_starTestGraph B hB W S μ] - rfl - | inr p => - show multiLabeledEvalK K 2 (MultiLabeledGraph.ofSimple (edgeTestGraph p.1 p.2)) B W μ = _ - rw [← simpleEvalAt_eq_multi', simpleEvalAt_edgeTestGraph B hB W p.1 p.2 μ] - rfl - -theorem coordGraph_simpleMult (c : TestCoord K) : (coordGraph c).2.SimpleMult := by - cases c with - | inl S => exact MultiLabeledGraph.ofSimple_simpleMult _ - | inr p => exact MultiLabeledGraph.ofSimple_simpleMult _ - -theorem coordGraph_noLabelPairs (c : TestCoord K) : (coordGraph c).2.NoLabelPairs := by - cases c with - | inl S => exact starTestGraph_noLabelPairs S - | inr p => exact edgeTestGraph_noLabelPairs p.1 p.2 - -/-- Product bookkeeping for replicated flatMaps (self-contained; avoids hunting for a -flatMap-product lemma). -/ -private theorem prod_map_flatMap_replicate {α β γ : Type*} [CommMonoid γ] (l : List α) - (k : α → ℕ) (g : α → β) (f : β → γ) : - ((l.flatMap fun a => List.replicate (k a) (g a)).map f).prod - = (l.map fun a => f (g a) ^ k a).prod := by - induction l with - | nil => rfl - | cons a l ih => - rw [List.flatMap_cons, List.map_append, List.prod_append, ih, List.map_cons, List.prod_cons, - List.map_replicate, List.prod_replicate] - -/-- The **exponent graph**: glue `k c` copies of each test coordinate's graph. -/ -noncomputable def expGraph (k : TestCoord K → ℕ) : Σ n, MultiLabeledGraph K n := - glueList ((Finset.univ : Finset (TestCoord K)).toList.flatMap - fun c => List.replicate (k c) (coordGraph c)) - -/-- Every component list element of `expGraph` is a `coordGraph`. -/ -private theorem expGraph_mem {k : TestCoord K → ℕ} {p : Σ n, MultiLabeledGraph K n} - (hp : p ∈ (Finset.univ : Finset (TestCoord K)).toList.flatMap - fun c => List.replicate (k c) (coordGraph c)) : ∃ c, p = coordGraph c := by - rw [List.mem_flatMap] at hp - obtain ⟨c, -, hmem⟩ := hp - exact ⟨c, List.eq_of_mem_replicate hmem⟩ - -theorem expGraph_simpleMult (k : TestCoord K → ℕ) : (expGraph k).2.SimpleMult := by - refine glueList_simpleMult _ (fun p hp => ?_) (fun p hp => ?_) <;> - obtain ⟨c, rfl⟩ := expGraph_mem hp - · exact coordGraph_simpleMult c - · exact coordGraph_noLabelPairs c - -/-- **Closed form of the exponent graph**: its evaluation is the product of test-moment -powers. -/ -theorem expGraph_eval {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (k : TestCoord K → ℕ) (μ : Fin K → Fin T) : - multiLabeledEvalK K (expGraph k).1 (expGraph k).2 B W μ - = ∏ c : TestCoord K, (testMoment B W c μ) ^ k c := by - rw [expGraph, multiLabeledEvalK_glueList B hB W, - prod_map_flatMap_replicate _ k coordGraph (fun p => multiLabeledEvalK K p.1 p.2 B W μ)] - rw [show ((Finset.univ : Finset (TestCoord K)).toList.map - fun c => multiLabeledEvalK K (coordGraph c).1 (coordGraph c).2 B W μ ^ k c) - = ((Finset.univ : Finset (TestCoord K)).toList.map - fun c => testMoment B W c μ ^ k c) from - List.map_congr_left fun c _ => by rw [coordGraph_eval B hB W c μ]] - exact Finset.prod_map_toList _ _ - -/-- The exponent graph, converted back to an honest simple graph (chunk 4B). -/ -noncomputable def expTestGraph (k : TestCoord K → ℕ) : - SimpleGraph (Fin ((expGraph k).1 + K)) := - (expGraph k).2.toSimple - -noncomputable instance (k : TestCoord K → ℕ) : DecidableRel (expTestGraph k).Adj := - Classical.decRel _ - -/-- **The moment-power realization**: `simpleEvalAt` of the exponent test graph is the -product of test-moment powers. This is the input eq. (10) consumes in chunk 4E. -/ -theorem simpleEvalAt_expTestGraph {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (k : TestCoord K → ℕ) (μ : Fin K → Fin T) : - simpleEvalAt B W (expTestGraph k) μ = ∏ c : TestCoord K, (testMoment B W c μ) ^ k c := by - have h := simpleEvalAt_toSimple B W (expGraph k).2 (expGraph_simpleMult k) μ - rw [expGraph_eval B hB W k μ] at h - exact h - -/-- The `TestEvalEq` interface is equivalent to matching of all test moments. -/ -theorem testEvalEq_iff_moments {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} : - TestEvalEq B W ξ ξ' ↔ ∀ c : TestCoord K, testMoment B W c ξ = testMoment B W c ξ' := by - constructor - · intro h c - cases c with - | inl S => - have := h.star S - rwa [simpleEvalAt_starTestGraph B hB W S ξ, simpleEvalAt_starTestGraph B hB W S ξ'] at this - | inr p => - have := h.edge p.1 p.2 - rwa [simpleEvalAt_edgeTestGraph B hB W p.1 p.2 ξ, - simpleEvalAt_edgeTestGraph B hB W p.1 p.2 ξ'] at this - · intro h - refine ⟨fun S => ?_, fun Sₗ Sτ => ?_⟩ - · rw [simpleEvalAt_starTestGraph B hB W S ξ, simpleEvalAt_starTestGraph B hB W S ξ'] - exact h (Sum.inl S) - · rw [simpleEvalAt_edgeTestGraph B hB W Sₗ Sτ ξ, simpleEvalAt_edgeTestGraph B hB W Sₗ Sτ ξ'] - exact h (Sum.inr (Sₗ, Sτ)) - -/-! ## Chunk 4E: the power-moment identity for extension families - -Equation (10) instantiated at the exponent test graphs: simple-equivalence at level `K` -forces every weighted moment of the level-`(K+m)` test profile over the extension family of -`ξ` to match that of `ξ'`. This is the `hmom` input for the two-family Vandermonde in the -descent step (chunk 4F). -/ - -/-- **Power-moment identity** (eq. (10) at `G := expTestGraph k`). -/ -theorem extension_power_moments {T m : ℕ} (B : Fin T → Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} - (h : tupleEquivSimple B W ξ ξ') (k : TestCoord (K + m) → ℕ) : - ∑ ρ : Fin m → Fin T, (∏ j, W (ρ j)) - * ∏ c : TestCoord (K + m), (testMoment B W c (Fin.append ξ ρ)) ^ k c - = ∑ ρ : Fin m → Fin T, (∏ j, W (ρ j)) - * ∏ c : TestCoord (K + m), (testMoment B W c (Fin.append ξ' ρ)) ^ k c := by - have hid := extension_sum_identity B hB W h (expTestGraph k) - rw [sum_extensions_eq_sum_rho B W (expTestGraph k) ξ, - sum_extensions_eq_sum_rho B W (expTestGraph k) ξ'] at hid - simp only [simpleEvalAt_expTestGraph B hB W k] at hid - exact hid - -/-! ## Chunk 4F: matching a super-surjective extension of `ξ` inside the `ξ'`-family - -Two-family bounded Vandermonde over the extension families: the power-moment identity -(chunk 4E) matches all weighted test-moment powers, so the class-balance engine equates, at -each profile value, the two weighted masses. At the profile of `superExt ξ` the `ξ`-side mass -is positive (it contains `ρ = coverExtra T`, and `W > 0`), so the `ξ'`-side class is -nonempty: some extension of `ξ'` matches ALL test moments of `superExt ξ`. -/ - -/-- The test-moment profile as a `Fin`-indexed vector (transport along `Fintype.equivFin`), -for the graph-free Vandermonde engines. -/ -noncomputable def testProfile {T : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (μ : Fin K → Fin T) : Fin (Fintype.card (TestCoord K)) → ℝ := - fun c => testMoment B W ((Fintype.equivFin (TestCoord K)).symm c) μ - -theorem testProfile_eq_iff {T : ℕ} {B : Fin T → Fin T → ℝ} {W : Fin T → ℝ} - {μ ν : Fin K → Fin T} : - testProfile B W μ = testProfile B W ν - ↔ ∀ c : TestCoord K, testMoment B W c μ = testMoment B W c ν := by - constructor - · intro h c - have := congrFun h (Fintype.equivFin (TestCoord K) c) - simpa only [testProfile, Equiv.symm_apply_apply] using this - · intro h - funext c - exact h _ - -/-- **Matching extension** (the 4F pivot). If `ξ ≈ ξ'` (equal simple evaluations), some -extension `Fin.append ξ' ρ'` of `ξ'` matches `superExt ξ` on every test moment. -/ -theorem exists_matching_extension {T : ℕ} (B : Fin T → Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) - {ξ ξ' : Fin K → Fin T} (h : tupleEquivSimple B W ξ ξ') : - ∃ ρ' : Fin (T * (2 * T ^ 2)) → Fin T, - ∀ c : TestCoord (K + T * (2 * T ^ 2)), - testMoment B W c (Fin.append ξ' ρ') = testMoment B W c (superExt ξ) := by - classical - set e := Fintype.equivFin (TestCoord (K + T * (2 * T ^ 2))) with he - -- Profile-form conversion of the power products. - have hconv : ∀ (μ : Fin (K + T * (2 * T ^ 2)) → Fin T) - (k : Fin (Fintype.card (TestCoord (K + T * (2 * T ^ 2)))) → ℕ), - ∏ c : TestCoord (K + T * (2 * T ^ 2)), (testMoment B W c μ) ^ k (e c) - = ∏ c, (testProfile B W μ c) ^ k c := by - intro μ k - calc ∏ c : TestCoord (K + T * (2 * T ^ 2)), (testMoment B W c μ) ^ k (e c) - = ∏ c : TestCoord (K + T * (2 * T ^ 2)), (testProfile B W μ (e c)) ^ k (e c) := by - refine Finset.prod_congr rfl fun c _ => ?_ - congr 1 - show testMoment B W c μ = testMoment B W (e.symm (e c)) μ - rw [Equiv.symm_apply_apply] - _ = ∏ c, (testProfile B W μ c) ^ k c := - Equiv.prod_comp e (fun c => (testProfile B W μ c) ^ k c) - -- The moment feed for the class-balance engine (no exponent bound needed). - have hmom : ∀ k : Fin (Fintype.card (TestCoord (K + T * (2 * T ^ 2)))) → ℕ, - (∀ c, k c < 2 * Fintype.card (Fin (T * (2 * T ^ 2)) → Fin T)) → - ∑ ρ : Fin (T * (2 * T ^ 2)) → Fin T, (∏ j, W (ρ j)) - * ∏ c, (testProfile B W (Fin.append ξ ρ) c) ^ k c - = ∑ ρ : Fin (T * (2 * T ^ 2)) → Fin T, (∏ j, W (ρ j)) - * ∏ c, (testProfile B W (Fin.append ξ' ρ) c) ^ k c := by - intro k _ - have hpm := extension_power_moments B hB W h (fun c => k (e c)) - calc ∑ ρ : Fin (T * (2 * T ^ 2)) → Fin T, (∏ j, W (ρ j)) - * ∏ c, (testProfile B W (Fin.append ξ ρ) c) ^ k c - = ∑ ρ : Fin (T * (2 * T ^ 2)) → Fin T, (∏ j, W (ρ j)) - * ∏ c : TestCoord (K + T * (2 * T ^ 2)), - (testMoment B W c (Fin.append ξ ρ)) ^ k (e c) := by - refine Finset.sum_congr rfl fun ρ _ => ?_ - rw [hconv] - _ = ∑ ρ : Fin (T * (2 * T ^ 2)) → Fin T, (∏ j, W (ρ j)) - * ∏ c : TestCoord (K + T * (2 * T ^ 2)), - (testMoment B W c (Fin.append ξ' ρ)) ^ k (e c) := hpm - _ = ∑ ρ : Fin (T * (2 * T ^ 2)) → Fin T, (∏ j, W (ρ j)) - * ∏ c, (testProfile B W (Fin.append ξ' ρ) c) ^ k c := by - refine Finset.sum_congr rfl fun ρ _ => ?_ - rw [hconv] - -- Class balance at the profile of `superExt ξ`. - have hbal := aligned_moments_class_balance_of_bound - (fun ρ : Fin (T * (2 * T ^ 2)) → Fin T => testProfile B W (Fin.append ξ ρ)) - (fun ρ => testProfile B W (Fin.append ξ' ρ)) - (fun ρ => ∏ j, W (ρ j)) (fun ρ => ∏ j, W (ρ j)) - (Fintype.card (Fin (T * (2 * T ^ 2)) → Fin T)) - (fun _ => Finset.card_image_le.trans (by simp)) - (fun _ => Finset.card_image_le.trans (by simp)) - hmom (testProfile B W (superExt ξ)) - -- The ξ-side mass is positive: `coverExtra T` lies in the class, and all weights are > 0. - have hmem : coverExtra T ∈ univ.filter (fun ρ : Fin (T * (2 * T ^ 2)) → Fin T => - testProfile B W (Fin.append ξ ρ) = testProfile B W (superExt ξ)) := - Finset.mem_filter.mpr ⟨Finset.mem_univ _, rfl⟩ - have hpos : (0 : ℝ) < ∑ ρ ∈ univ.filter (fun ρ : Fin (T * (2 * T ^ 2)) → Fin T => - testProfile B W (Fin.append ξ ρ) = testProfile B W (superExt ξ)), ∏ j, W (ρ j) := - Finset.sum_pos (fun ρ _ => Finset.prod_pos fun j _ => hW _) ⟨coverExtra T, hmem⟩ - rw [hbal] at hpos - obtain ⟨ρ', hρ'mem⟩ := Finset.nonempty_of_sum_ne_zero (ne_of_gt hpos) - exact ⟨ρ', fun c => testProfile_eq_iff.mp (Finset.mem_filter.mp hρ'mem).2 c⟩ - -/-! ## Chunk 4G: the general descent theorem -/ - -/-- **The Cai–Govorov descent — the general simple-graph orbit theorem (#70).** If all -simple-graph evaluations at `ξ` and `ξ'` agree, then `ξ'` is in the weighted-automorphism -orbit of `ξ` — with NO surjectivity hypothesis on either tuple. Route: match an extension of -`ξ'` against the super-surjective `superExt ξ` on all test moments (chunk 4F), run the -moment-form super-case (chunk 4A) at level `K + T·2T²`, and restrict the resulting -automorphism to the first `K` labels. This is the statement of the sorry'd -`tupleEquivSimple_implies_orbit` (`Lovasz.lean` §3.10), proved downstream. -/ -theorem tupleEquivSimple_implies_orbit_general {T : ℕ} (B : Fin T → Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) - (htwin : ∀ i j, i ≠ j → B i ≠ B j) (ξ ξ' : Fin K → Fin T) - (h : tupleEquivSimple B W ξ ξ') : tupleOrbitRel B W ξ ξ' := by - obtain ⟨ρ', hρ'⟩ := exists_matching_extension B hB W hW h - have hTE : TestEvalEq B W (superExt ξ) (Fin.append ξ' ρ') := - (testEvalEq_iff_moments B hB W).mpr fun c => (hρ' c).symm - obtain ⟨σ, hσ_aut, hσ⟩ := testEvalEq_implies_orbit_super B hB W hW htwin (superExt ξ) - (Fin.append ξ' ρ') (superExt_superSurjective ξ) hTE - refine ⟨σ, hσ_aut, fun i => ?_⟩ - have hi := hσ (Fin.castAdd (T * (2 * T ^ 2)) i) - rw [Fin.append_left, superExt_extends ξ i] at hi - exact hi - -end Graphon.Lovasz diff --git a/Graphon/CycleKrylov.lean b/Graphon/CycleKrylov.lean index 737a3a7..9f54594 100644 --- a/Graphon/CycleKrylov.lean +++ b/Graphon/CycleKrylov.lean @@ -1966,15 +1966,8 @@ theorem k2kArmsStructured_edgeFinset (k : ℕ) (armLen : Fin k → ℕ) : /-! #### Commit 1 — Fin/structured edge transport + edge-product factorization -/ -/-- `Quot.out` resolver on a literal `Sym2` pair over an ARBITRARY vertex type -(the `out_pair_eq` generalization needed for the structured graph). -/ -theorem out_pair_eq' {T' : ℕ} {V : Type*} (Bm : Fin T' → Fin T' → ℝ) - (hB : ∀ i j, Bm i j = Bm j i) (g : V → Fin T') (x y : V) : - Bm (g (Quot.out s(x, y)).1) (g (Quot.out s(x, y)).2) = Bm (g x) (g y) := by - have hout : s((Quot.out s(x, y)).1, (Quot.out s(x, y)).2) = s(x, y) := Quot.out_eq _ - rcases Sym2.eq_iff.mp hout with ⟨h1, h2⟩ | ⟨h1, h2⟩ - · rw [h1, h2] - · rw [h1, h2, hB] +-- `out_pair_eq'` MOVED upstream to `Lovasz.lean` (2026-07-02), where the Cai–Govorov +-- stack also needs it; all uses below resolve through the import chain. /-- Arm index of a vertex (anchors/internals carry their arm; root/hub `none`). Used to recover `(l, s)` from a chain endpoint in `k2kEdge_injective`. -/ @@ -4017,228 +4010,14 @@ theorem InRootedProfileSpan.of_const_on_orbit_noncircular {T : ℕ} InRootedProfileSpan.of_const_on_rpe B hB W f (fun i j hij => hf i j (vertexOrbitRel_of_rootedProfileEquiv B hB W hW htwin hij)) -/-! ### Eval spans as `Submodule`s (Phase A — foundation for the §3 rank/finrank work) - -The K-tuple simple- and multigraph-eval spans, currently bare existential predicates -(`InTupleSimpleEvalSpan` / `InTupleMultiEvalSpan` in `Lovasz.lean`), are repackaged here -as honest `Submodule ℝ`s. This unlocks `finrank`/`Basis`/`≤` for the rank argument that -isolates the sole #70 residue `InTupleMultiEvalSpan.toSimple`. The membership-`iff`s tie -the new submodules back to the existing predicate API, which stays the interface for -construction. -/ - -/-- The K-tuple **simple-eval span** as a submodule: spanned by the simple-graph -evaluation functions `ξ ↦ simpleEvalAt B W F ξ`. -/ -noncomputable def simpleEvalSubmodule {T : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (K : ℕ) : Submodule ℝ ((Fin K → Fin T) → ℝ) := - Submodule.span ℝ - (Set.range (fun p : Σ (n : ℕ) (F : SimpleGraph (Fin (n + K))), DecidableRel F.Adj => - (fun ξ => @simpleEvalAt T K p.1 B W p.2.1 p.2.2 ξ))) - -/-- The K-tuple **multigraph-eval span** as a submodule: spanned by the multigraph -evaluation functions `ξ ↦ multiLabeledEvalK K n M B W ξ`. -/ -noncomputable def multiEvalSubmodule {T : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (K : ℕ) : Submodule ℝ ((Fin K → Fin T) → ℝ) := - Submodule.span ℝ - (Set.range (fun p : Σ (n : ℕ), MultiLabeledGraph K n => - (fun ξ => multiLabeledEvalK K p.1 p.2 B W ξ))) - -/-- Submodule membership coincides with the existing simple-eval span predicate -`InTupleSimpleEvalSpan`. -/ -theorem mem_simpleEvalSubmodule_iff {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (f : (Fin K → Fin T) → ℝ) : - f ∈ simpleEvalSubmodule B W K ↔ InTupleSimpleEvalSpan B W f := by - constructor - · intro hf - unfold simpleEvalSubmodule at hf - induction hf using Submodule.span_induction with - | mem x hx => - obtain ⟨p, rfl⟩ := hx - exact @InTupleSimpleEvalSpan.of_simple T K p.1 B W p.2.1 p.2.2 - | zero => exact InTupleSimpleEvalSpan.zero B W - | add x y _ _ hx hy => exact hx.add hy - | smul a x _ hx => exact InTupleSimpleEvalSpan.smul a hx - · intro hf - obtain ⟨N, g, c, rfl⟩ := hf - have hsum : - (fun ξ => ∑ k : Fin N, c k * @simpleEvalAt T K (g k).1 B W (g k).2.1 (g k).2.2 ξ) - = ∑ k : Fin N, c k • - (fun ξ => @simpleEvalAt T K (g k).1 B W (g k).2.1 (g k).2.2 ξ) := by - funext ξ - rw [Finset.sum_apply] - exact Finset.sum_congr rfl fun k _ => by rw [Pi.smul_apply, smul_eq_mul] - rw [hsum] - exact Submodule.sum_mem _ fun k _ => - Submodule.smul_mem _ _ (Submodule.subset_span ⟨g k, rfl⟩) - -/-- Submodule membership coincides with the existing multigraph-eval span predicate -`InTupleMultiEvalSpan`. -/ -theorem mem_multiEvalSubmodule_iff {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (f : (Fin K → Fin T) → ℝ) : - f ∈ multiEvalSubmodule B W K ↔ InTupleMultiEvalSpan B W f := by - constructor - · intro hf - unfold multiEvalSubmodule at hf - induction hf using Submodule.span_induction with - | mem x hx => - obtain ⟨p, rfl⟩ := hx - exact InTupleMultiEvalSpan.of_multi B W p.2 - | zero => exact InTupleMultiEvalSpan.zero B W - | add x y _ _ hx hy => exact hx.add hy - | smul a x _ hx => exact InTupleMultiEvalSpan.smul a hx - · intro hf - obtain ⟨N, g, c, rfl⟩ := hf - have hsum : - (fun ξ => ∑ k : Fin N, c k * multiLabeledEvalK K (g k).1 (g k).2 B W ξ) - = ∑ k : Fin N, c k • (fun ξ => multiLabeledEvalK K (g k).1 (g k).2 B W ξ) := by - funext ξ - rw [Finset.sum_apply] - exact Finset.sum_congr rfl fun k _ => by rw [Pi.smul_apply, smul_eq_mul] - rw [hsum] - exact Submodule.sum_mem _ fun k _ => - Submodule.smul_mem _ _ (Submodule.subset_span ⟨g k, rfl⟩) - -/-! ### Orbit-invariant submodule and `multiEvalSubmodule = orbitInvariant` (Phase B) - -The genuinely informative half of the rank framework, and **non-circular**: the -multigraph-eval submodule equals the submodule of automorphism-invariant functions. The -`≥` direction rests on the directly-proved (toSimple-free) `tupleOrbitIndicator_mem_multiEvalSpan`. -This pins the sole #70 residue to exactly `simpleEvalSubmodule = orbitInvariantSubmodule`. -/ - -/-- The submodule of `(B, W)`-automorphism-invariant functions of a K-tuple. -/ -def orbitInvariantSubmodule {T : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) (K : ℕ) : - Submodule ℝ ((Fin K → Fin T) → ℝ) where - carrier := { f | ∀ σ : Equiv.Perm (Fin T), IsWeightedAutomorphism B W σ → - ∀ ξ, f (σ ∘ ξ) = f ξ } - add_mem' := by - intro a b hf hg σ hσ ξ - simp only [Pi.add_apply]; rw [hf σ hσ ξ, hg σ hσ ξ] - zero_mem' := by intro σ hσ ξ; rfl - smul_mem' := by - intro c a hf σ hσ ξ - simp only [Pi.smul_apply, smul_eq_mul]; rw [hf σ hσ ξ] - -/-- **Automorphism-invariant ⟹ multigraph-eval span** (the multi analog of -`tupleSimpleEval_span_aut_invariant`, but NON-circular — it consumes the directly-proved -`tupleOrbitIndicator_mem_multiEvalSpan`, never `InTupleMultiEvalSpan.toSimple`). Orbit -indicators are a basis of the invariant functions, and each lies in the multi span. -/ -theorem tupleMultiEval_span_aut_invariant {T K : ℕ} - (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) - (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (f : (Fin K → Fin T) → ℝ) - (h_aut_inv : ∀ (σ : Equiv.Perm (Fin T)), - IsWeightedAutomorphism B W σ → ∀ ξ, f (σ ∘ ξ) = f ξ) : - InTupleMultiEvalSpan B W f := by - classical - let S : Setoid (Fin K → Fin T) := - ⟨tupleOrbitRel B W, tupleOrbitRel_refl B W, - fun h => tupleOrbitRel_symm B W h, - fun h₁ h₂ => tupleOrbitRel_trans B W h₁ h₂⟩ - haveI : Fintype (Quotient S) := Quotient.fintype S - have h_decomp : f = fun ξ => - ∑ q : Quotient S, f (Quotient.out q) * orbitIndicator B W (Quotient.out q) ξ := by - funext ξ - let q₀ : Quotient S := Quotient.mk S ξ - have hq₀_out : tupleOrbitRel B W (Quotient.out q₀) ξ := by - have := Quotient.mk_out (s := S) ξ - exact this - rw [show - (∑ q : Quotient S, - f (Quotient.out q) * orbitIndicator B W (Quotient.out q) ξ) = - f (Quotient.out q₀) * orbitIndicator B W (Quotient.out q₀) ξ + - ∑ q ∈ Finset.univ.erase q₀, - f (Quotient.out q) * orbitIndicator B W (Quotient.out q) ξ from - (Finset.add_sum_erase _ _ (Finset.mem_univ q₀)).symm] - have h_other_zero : ∀ q ∈ Finset.univ.erase q₀, - f (Quotient.out q) * orbitIndicator B W (Quotient.out q) ξ = 0 := by - intro q hq - rw [Finset.mem_erase] at hq - have h_q_ne : q ≠ q₀ := hq.1 - have h_not_orbit : ¬ tupleOrbitRel B W (Quotient.out q) ξ := by - intro h_orbit - apply h_q_ne - rw [← Quotient.out_eq q, ← Quotient.out_eq q₀] - exact Quotient.sound (Setoid.trans h_orbit (Setoid.symm hq₀_out)) - rw [orbitIndicator_of_not_orbit B W h_not_orbit, mul_zero] - rw [Finset.sum_eq_zero h_other_zero, add_zero] - have h_f_eq : f (Quotient.out q₀) = f ξ := by - obtain ⟨σ, hσ, hσeq⟩ := hq₀_out - have hξ : ξ = σ ∘ Quotient.out q₀ := funext hσeq - rw [hξ, h_aut_inv σ hσ] - have h_ind_one : orbitIndicator B W (Quotient.out q₀) ξ = 1 := by - unfold orbitIndicator - rw [if_pos hq₀_out] - rw [h_f_eq, h_ind_one, mul_one] - rw [h_decomp] - apply InTupleMultiEvalSpan.finset_sum - intro q _ - exact InTupleMultiEvalSpan.smul (f (Quotient.out q)) - (tupleOrbitIndicator_mem_multiEvalSpan B hB W hW htwin (Quotient.out q)) - -/-- **`≤`: multigraph evaluations are automorphism-invariant.** -/ -theorem multiEvalSubmodule_le_orbitInvariantSubmodule {T K : ℕ} - (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) : - multiEvalSubmodule B W K ≤ orbitInvariantSubmodule B W K := by - intro f hf - rw [mem_multiEvalSubmodule_iff] at hf - exact fun σ hσ ξ => InTupleMultiEvalSpan.aut_invariant B W hf σ hσ ξ - -/-- **`≥`: every automorphism-invariant function lies in the multigraph-eval span** -(non-circular, via `tupleMultiEval_span_aut_invariant`). -/ -theorem orbitInvariantSubmodule_le_multiEvalSubmodule {T K : ℕ} - (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) - (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) : - orbitInvariantSubmodule B W K ≤ multiEvalSubmodule B W K := by - intro f hf - rw [mem_multiEvalSubmodule_iff] - exact tupleMultiEval_span_aut_invariant B hB W hW htwin f hf - -/-- **The multigraph-eval submodule is exactly the automorphism-invariant submodule.** -The clean, non-circular pillar of the §3 rank framework: the residue is now precisely -`simpleEvalSubmodule = orbitInvariantSubmodule`. -/ -theorem multiEvalSubmodule_eq_orbitInvariantSubmodule {T K : ℕ} - (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) - (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) : - multiEvalSubmodule B W K = orbitInvariantSubmodule B W K := - le_antisymm (multiEvalSubmodule_le_orbitInvariantSubmodule B W) - (orbitInvariantSubmodule_le_multiEvalSubmodule B hB W hW htwin) - -/-- **Easy inclusion `simpleEvalSubmodule ≤ orbitInvariantSubmodule`**: simple-graph -evaluations are automorphism-invariant (`simpleEvalAt_aut_invariant`). Completes the -clean frame `simpleEvalSubmodule ≤ orbitInvariantSubmodule = multiEvalSubmodule`; the -sole #70 residue is the reverse inclusion. -/ -theorem simpleEvalSubmodule_le_orbitInvariantSubmodule {T K : ℕ} - (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) : - simpleEvalSubmodule B W K ≤ orbitInvariantSubmodule B W K := by - intro f hf - rw [mem_simpleEvalSubmodule_iff] at hf - intro σ hσ ξ - obtain ⟨N, g, c, hfeq⟩ := hf - rw [congr_fun hfeq (σ ∘ ξ), congr_fun hfeq ξ] - refine Finset.sum_congr rfl fun k _ => ?_ - rw [@simpleEvalAt_aut_invariant T K (g k).1 B hB W (g k).2.1 (g k).2.2 σ hσ ξ] - -/-- **Corollary `simpleEvalSubmodule ≤ multiEvalSubmodule`** (the never-in-doubt -inclusion), directly via `InTupleSimpleEvalSpan.toMulti`. -/ -theorem simpleEvalSubmodule_le_multiEvalSubmodule {T K : ℕ} - (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) : - simpleEvalSubmodule B W K ≤ multiEvalSubmodule B W K := by - intro f hf - rw [mem_simpleEvalSubmodule_iff] at hf - rw [mem_multiEvalSubmodule_iff] - exact hf.toMulti - -/-! ### Phase C1 + D — finrank skeleton of the rank theorem - -MOVED to `Graphon/SimpleOrbitRank.lean` (2026-07-02): the residue -`simpleEvalSubmodule_finrank_ge_orbitClass` and its dependents -(`simpleEvalSubmodule_eq_orbitInvariantSubmodule`, -`orbitInvariantSubmodule_le_simpleEvalSubmodule`) need the Cai–Govorov machinery of -`Graphon/CaiGovorovOrbit.lean`, which imports THIS file — so the rank endgame lives -downstream. The self-contained prefix (`instFintypeOrbitClass`, `orbitInvariantToClassFun`, -`orbitInvariantEquiv`, `finrank_orbitInvariantSubmodule`) moved with it to keep the section -in one place; NB importers of this file alone no longer get the `Fintype (OrbitClass …)` -instance — import `Graphon.SimpleOrbitRank` for it. (A pending relocation refactor moves the -whole stack upstream into `Lovasz.lean`, dissolving this split.) -/ +/-! ### Eval spans as `Submodule`s + Phase C1+D rank skeleton + +MOVED upstream to `Lovasz.lean` (§ the rank-theorem section, 2026-07-02): the submodule +packaging (`simpleEvalSubmodule`/`multiEvalSubmodule`/`orbitInvariantSubmodule` + membership +iffs and inclusions) and the full rank skeleton (incl. `instFintypeOrbitClass` and the PROVED +`simpleEvalSubmodule_eq_orbitInvariantSubmodule`) now live directly after +`simpleEvalAt_aut_invariant` in `Lovasz.lean`, where the Cai–Govorov machinery they need is +in scope. All names resolve through the import chain. -/ end Weighted diff --git a/Graphon/Lovasz.lean b/Graphon/Lovasz.lean index 68f5f94..1372e1c 100644 --- a/Graphon/Lovasz.lean +++ b/Graphon/Lovasz.lean @@ -3,14 +3,17 @@ Copyright (c) 2026 Cameron Freer. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Cameron Freer -/ +import Graphon.CaiGovorov import Mathlib.Algebra.BigOperators.Fin import Mathlib.Algebra.BigOperators.Ring.Finset import Mathlib.Algebra.Order.BigOperators.Group.Finset import Mathlib.Algebra.Polynomial.Eval.Degree +import Mathlib.Combinatorics.Pigeonhole import Mathlib.Combinatorics.SimpleGraph.Finite import Mathlib.Data.Fintype.BigOperators import Mathlib.Data.Real.Basic import Mathlib.Data.Sym.Sym2 +import Mathlib.LinearAlgebra.Dual.Lemmas import Mathlib.Logic.Equiv.Fin.Basic import Mathlib.Tactic.Linarith import Mathlib.Tactic.Ring @@ -2694,60 +2697,8 @@ theorem label_unlabeled_square_with_background_descends {T K : ℕ} refine Finset.prod_congr rfl fun b _ => ?_ rw [hσξ b, hB_σ t (ξ b)] -/-- **CANONICAL PAPER-ROOT** — unlabeled-excess descent (the final Lovász §3 -core). After polynomial decomposition handles all label-label multiplicities -(via `multigraphEval_LL_excess_descends_aux`), the remaining residue is -the case where some mult≥2 edge touches at least one unlabeled vertex. -Polynomial decomposition does NOT apply directly: the B-factor at such -an edge depends on σ (the unlabeled coloring), so it cannot be pulled -out of the σ-sum. - -**Hypotheses**: - - `B` symmetric. - - `h_simple`: the inlined `tupleEquivSimple` hypothesis at level K. - - `h_unlabeled_excess`: there exists an edge with multiplicity ≥ 2 - that touches at least one unlabeled vertex (val ≥ K). - -**Conclusion**: `multiLabeledEvalK K n M B W ξ = multiLabeledEvalK K n M B W ξ'`. - -**Status** (2026-05-19): this is the residual Lovász §3 content of #86, -the canonical paper-root for #62. Closing requires the connection-matrix -/ idempotent decomposition of the multigraph algebra `𝒜_K` (~300-500 LOC -of new spectral/rank infrastructure). - -**Smallest non-trivial subcase** (next target): "one doubled edge involving -an unlabeled vertex" — even that requires the substantive Lovász §3 -algebra. If that subcase reduces, general multiplicities follow by -products (per Lovász §3.3). - -**Architecture note**: this is the general unlabeled-excess case. The -**final paper-root** is the smaller doubled-edge subcase -`multigraphEval_one_doubled_unlabeled_edge_descends` (see below), which -isolates the K=1 square moment as the genuine Lovász §3 residue. -/ -private theorem multigraphEval_unlabeled_excess_descends {T K n : ℕ} - (B : Fin T → Fin T → ℝ) (_hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) - (_hW : ∀ i, 0 < W i) (_htwin : ∀ i j, i ≠ j → B i ≠ B j) - (M : MultiLabeledGraph K n) - (_h_unlabeled_excess : - ∃ e : Sym2 (Fin (n + K)), ¬ isLLEdge e ∧ 2 ≤ M.mult e) - {ξ ξ' : Fin K → Fin T} - (_h_simple : ∀ (n' : ℕ) (F : SimpleGraph (Fin (n' + K))) [DecidableRel F.Adj], - ∑ σ : Fin n' → Fin T, - (let τ : Fin (n' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = - ∑ σ : Fin n' → Fin T, - (let τ : Fin (n' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ' ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) - (_h_sq_moment : ∀ (c : Fin K), - ∑ t : Fin T, W t * B (ξ c) t ^ 2 = ∑ t : Fin T, W t * B (ξ' c) t ^ 2) : - multiLabeledEvalK K n M B W ξ = multiLabeledEvalK K n M B W ξ' := by - sorry +-- `multigraphEval_unlabeled_excess_descends` MOVED below § CaiGovorovStack (2026-07-02) +-- and PROVED there via the Cai–Govorov orbit route. -- **FINAL PAPER-ROOT** `label_unlabeled_square_moment_descends` lives -- AFTER the K=1 rank theorem (`InRootedProfileSpan.of_const_on_orbit`) @@ -3900,38 +3851,8 @@ private theorem multigraphEval_label_unlabeled_isolated_descends have h_compat : F_rest_eval ξ = F_rest_eval ξ' := h_simple_F_rest rw [h_norm ξ, h_norm ξ', h_scalar, h_compat] -/-- **Label-unlabeled non-isolated reduction**: same orientation as above -but with other edges touching `b`. Reduces to the isolated case via peeling -those other edges. BLOCKED BY: label_unlabeled_square_moment_descends + -non-LL peel infrastructure. -/ -private theorem multigraphEval_label_unlabeled_nonisolated_descends - {T K n : ℕ} (B : Fin T → Fin T → ℝ) (_hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (_hW : ∀ i, 0 < W i) - (_htwin : ∀ i j, i ≠ j → B i ≠ B j) - (M : MultiLabeledGraph K n) - (a b : Fin (n + K)) - (_ha : a.val < K) (_hb : K ≤ b.val) (_hab : a ≠ b) - (_h_doubled : M.mult s(a, b) = 2) - (_h_others_le_one : ∀ e, e ≠ s(a, b) → M.mult e ≤ 1) - (_h_b_not_iso : ¬ ∀ e, e ≠ s(a, b) → b ∈ e → M.mult e = 0) - {ξ ξ' : Fin K → Fin T} - (_h_simple : ∀ (n' : ℕ) (F : SimpleGraph (Fin (n' + K))) [DecidableRel F.Adj], - ∑ σ : Fin n' → Fin T, - (let τ : Fin (n' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = - ∑ σ : Fin n' → Fin T, - (let τ : Fin (n' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ' ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) - (_h_sq_moment : ∀ (c : Fin K), - ∑ t : Fin T, W t * B (ξ c) t ^ 2 = ∑ t : Fin T, W t * B (ξ' c) t ^ 2) : - multiLabeledEvalK K n M B W ξ = multiLabeledEvalK K n M B W ξ' := by - sorry +-- `multigraphEval_label_unlabeled_nonisolated_descends` MOVED below § CaiGovorovStack +-- (2026-07-02) and PROVED there via the Cai–Govorov orbit route. /-- **Unlabeled-label isolated reduction**: symmetric to label-unlabeled isolated via Sym2.eq_swap. Same dependency: `label_unlabeled_square_moment_descends`. -/ @@ -3975,1215 +3896,3339 @@ private theorem multigraphEval_unlabeled_label_isolated_descends · exact h_simple · exact h_sq_moment -/-- **Unlabeled-label non-isolated reduction**: symmetric to -label-unlabeled non-isolated via Sym2.eq_swap. -/ -private theorem multigraphEval_unlabeled_label_nonisolated_descends - {T K n : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (hW : ∀ i, 0 < W i) - (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (M : MultiLabeledGraph K n) - (a b : Fin (n + K)) - (ha : K ≤ a.val) (hb : b.val < K) (hab : a ≠ b) - (h_doubled : M.mult s(a, b) = 2) - (h_others_le_one : ∀ e, e ≠ s(a, b) → M.mult e ≤ 1) - (h_a_not_iso : ¬ ∀ e, e ≠ s(a, b) → a ∈ e → M.mult e = 0) - {ξ ξ' : Fin K → Fin T} - (h_simple : ∀ (n' : ℕ) (F : SimpleGraph (Fin (n' + K))) [DecidableRel F.Adj], - ∑ σ : Fin n' → Fin T, - (let τ : Fin (n' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = - ∑ σ : Fin n' → Fin T, - (let τ : Fin (n' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ' ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) - (h_sq_moment : ∀ (c : Fin K), - ∑ t : Fin T, W t * B (ξ c) t ^ 2 = ∑ t : Fin T, W t * B (ξ' c) t ^ 2) : - multiLabeledEvalK K n M B W ξ = multiLabeledEvalK K n M B W ξ' := by - have h_swap : s(a, b) = (s(b, a) : Sym2 (Fin (n + K))) := Sym2.eq_swap - apply multigraphEval_label_unlabeled_nonisolated_descends B hB W hW htwin M b a hb ha hab.symm - · rw [← h_swap]; exact h_doubled - · intro e he - exact h_others_le_one e (by rw [h_swap]; exact he) - · intro h_b_iso - apply h_a_not_iso - intro e he hae - exact h_b_iso e (by rw [← h_swap]; exact he) hae - · exact h_simple - · exact h_sq_moment +-- `multigraphEval_unlabeled_label_nonisolated_descends` MOVED below § CaiGovorovStack +-- (2026-07-02), following its dependency. +-- `multigraphEval_unlabeled_unlabeled_nonisolated_descends` MOVED below § CaiGovorovStack +-- (2026-07-02) and PROVED there (with `hW`/`htwin` added) via the Cai–Govorov orbit route. -/-- **UU non-isolated reduction**: doubled edge between two unlabeled vertices -with at least one OTHER edge touching `a` or `b`. +-- `multigraphEval_one_doubled_unlabeled_edge_descends` MOVED below § CaiGovorovStack +-- (2026-07-02), following its dependencies. +-- `multigraphEval_in_simpleProfileClosure` MOVED below § CaiGovorovStack (2026-07-02), +-- following its dependencies; now sorry-free. +-- `multiLabeledEvalK_tupleEquiv_invariant` MOVED below § CaiGovorovStack (2026-07-02) +-- and rewired to the Cai–Govorov orbit route; now sorry-free. -**Note**: simple "peel reduction" to UU isolated does NOT work cleanly because -the extra edge has at least one unlabeled endpoint (a or b), so the -B-factor depends on σ and cannot be pulled out of the σ-sum. +/-! ### §3.8 — Equivalence predicates and Lovász Lemma 2.5 -Honest proof structure: requires its own ~800 LOC parallel to UU isolated. -σ-sum factorization captures the (σ_a, σ_b)-coupled prefactor +This section introduces the two equivalence relations on label-tuples +that bracket the bridge theorem: - ∑_{s, t} W(s)·W(t)·B(s,t)² · (∏_{incident e} B(s/t, τ_e_other_endpoint)) +* `tupleEquivSimple` — agreement of all **simple-graph** evaluations + (Lovász TR-2004-82 §2, p. 6). This is the simple-graph `tupleEquiv` + inlined here so this module needs no dependency on + `Graphon/MatrixDetermination.lean`. +* `tupleEquivMulti` — agreement of all **multigraph** evaluations + (the natural multigraph generalization). -times an F_rest_eval ξ for the remaining (non-touching) edges. +The bridge theorem (§4 below) is exactly `tupleEquivSimple → tupleEquivMulti`. +The reverse direction `tupleEquivMulti → tupleEquivSimple` is trivial +because `multiLabeledEvalK` of `MultiLabeledGraph.ofSimple F` recovers +the simple-graph evaluation (`multiLabeledEvalK_ofSimple`). -**Sub-case structure**: - - If no incident edge has a label endpoint, the prefactor is ξ-independent - (sum over σ_other interpretation) and the proof closes via h_simple. - - If some incident edge has a label endpoint, the prefactor involves ξ - via the label coordinate. Reduces to label_unlabeled_square_moment_descends - (the K=1 square moment generalization). +**Lovász Lemma 2.5** (informal): if `B` is twin-free, then +`tupleEquivMulti ξ ξ'` if and only if `ξ` and `ξ'` lie in the same +`(B, W)`-automorphism orbit. -Dependency: substantial new work; may ultimately depend on -`label_unlabeled_square_moment_descends` for label-touching sub-cases. -/ -private theorem multigraphEval_unlabeled_unlabeled_nonisolated_descends - {T K n : ℕ} (B : Fin T → Fin T → ℝ) (_hB : ∀ i j, B i j = B j i) - (W : Fin T → ℝ) (M : MultiLabeledGraph K n) - (a b : Fin (n + K)) - (_ha : K ≤ a.val) (_hb : K ≤ b.val) (_hab : a ≠ b) - (_h_doubled : M.mult s(a, b) = 2) - (_h_others_le_one : ∀ e, e ≠ s(a, b) → M.mult e ≤ 1) - (_h_not_iso : ¬ ∀ e, e ≠ s(a, b) → (a ∈ e ∨ b ∈ e) → M.mult e = 0) - {ξ ξ' : Fin K → Fin T} - (_h_simple : ∀ (n' : ℕ) (F : SimpleGraph (Fin (n' + K))) [DecidableRel F.Adj], - ∑ σ : Fin n' → Fin T, - (let τ : Fin (n' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = - ∑ σ : Fin n' → Fin T, - (let τ : Fin (n' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ' ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) : - multiLabeledEvalK K n M B W ξ = multiLabeledEvalK K n M B W ξ' := by - -- BLOCKED BY: peel reduction to isolated UU case - -- (`multigraphEval_isolated_unlabeled_unlabeled_doubled_edge_descends` is proved). - -- Each peel removes one other edge touching `a` or `b`. Peel must handle - -- non-LL edges (since other edges have at least one unlabeled endpoint — - -- specifically `a` or `b`). Requires new non-LL peel infrastructure. - sorry +* The **forward direction** (orbit ⟹ multi-equivalence) is the + trivial corollary `multiLabeledEvalK_orbit_invariant` (already proved + above): aut-invariance of multigraph evaluation gives equality on every + multigraph automatically. +* The **reverse direction** (multi-equivalence ⟹ orbit) is the deep paper + content. Lovász's proof goes through the connection-matrix rank / + idempotent decomposition argument (TR-2004-82 §3): the connection + matrix `M(B, W) ∈ ℝ^{T^k × T^k}` factors through twin-free quotients, + and equal multi-eval rows are exactly orbit equivalences. -/ -/-- **FINAL PAPER-ROOT** — smallest unlabeled-excess subcase: one doubled -edge involving an unlabeled vertex, all other multiplicities ≤ 1. +/-- **Simple-graph tuple equivalence** (Lovász §2, p. 6). -**Algebraic analysis** (2026-05-19): given the above hypotheses, with -`e₀ = s(a, b)` the unique mult-2 edge having at least one endpoint -with `val ≥ K`, the σ-sum body of `multiLabeledEvalK M ξ` carries the -factor `B(τ_a, τ_b)²`. Three sub-sub-cases: +Two label maps `ξ, ξ' : Fin K → Fin T` are simple-equivalent iff every +level-`K` **simple** graph (with any number `n'` of unlabeled vertices) +evaluates equally on them. This is the simple-graph `tupleEquiv` +inlined to avoid a `MatrixDetermination` dependency. -/ +def tupleEquivSimple {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (ξ ξ' : Fin K → Fin T) : Prop := + ∀ (n' : ℕ) (F : SimpleGraph (Fin (n' + K))) [DecidableRel F.Adj], + ∑ σ : Fin n' → Fin T, + (let τ : Fin (n' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = + ∑ σ : Fin n' → Fin T, + (let τ : Fin (n' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ' ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) -1. **Unlabeled-unlabeled, isolated endpoints** (no other edges touch - `a` or `b`): - `multiLabeledEvalK M ξ = (∑_{s,t} W(s)W(t) B(s,t)²) · labeledEvalK F' ξ` - where the prefactor is **ξ-INDEPENDENT** and `F'` is the simple graph - on the remaining vertices. Both factors match at ξ vs ξ' (the - prefactor trivially, F' via `h_simple`). **Closable** via direct - σ-sum factorization. +/-- **Multigraph tuple equivalence**. -2. **Label-unlabeled, isolated unlabeled endpoint** (no other edges - touch the unlabeled vertex `j`): the σ_j-sum reduces to the K=1 - square moment `∑_t W(t) · B(ξ_a, t)²`. This is **NOT** a polynomial - in single-edge simple-graph evaluations (no simple graph evaluates - to `B(ξ_a, t)²`). Its ξ-invariance under `tupleEquivSimple` is - exactly the substantive Lovász §3 content (Lemma 2.5: every - auto-invariant function is in the simple-graph eval span; the - square moment is auto-invariant). +Two label maps `ξ, ξ' : Fin K → Fin T` are multi-equivalent iff every +level-`K` **multigraph** (with any number `n` of unlabeled vertices) +evaluates equally on them. This is the natural multigraph generalization +of `tupleEquivSimple`. -/ +def tupleEquivMulti {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (ξ ξ' : Fin K → Fin T) : Prop := + ∀ (n : ℕ) (M : MultiLabeledGraph K n), + multiLabeledEvalK K n M B W ξ = multiLabeledEvalK K n M B W ξ' -3. **General doubled edge with other edges touching the endpoint(s)**: - the σ-sum involves mixed moments combining `B(?,t)²` with other - `B(t, ?)¹` factors. Strictly harder than case 2; reducible to - case 2 after handling the label-touching contributions, but the - reduction is itself non-trivial. +/-- **Loop-multigraph tuple equivalence**. -**Conclusion**: the **smallest genuine paper-root** is the K=1 square -moment identity (case 2 — the simplest case requiring genuine Lovász §3 -content). Closing it requires the connection-matrix / idempotent -decomposition of the multigraph algebra `𝒜_K`. ~300-500 LOC of new -spectral/rank infrastructure. +Two label maps `ξ, ξ' : Fin K → Fin T` are loop-multi-equivalent iff +every level-`K` **multigraph with self-loops** evaluates equally on +them. Strictly stronger than `tupleEquivMulti` (loop case includes +diagonal contributions). The target of task #79: prove +`tupleEquivSimple → tupleEquivLoop` via the Lovász §3 rank theorem. -/ +def tupleEquivLoop {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (ξ ξ' : Fin K → Fin T) : Prop := + ∀ (n : ℕ) (M : MultiLabeledGraphLoop K n), + multiLabeledEvalKLoop K n M B W ξ = multiLabeledEvalKLoop K n M B W ξ' -**Status** (2026-05-19): PROMOTED as the final paper-root per directive. -The unlabeled-unlabeled isolated case (1) is algebraically closable but -is not the bottleneck. The label-unlabeled isolated case (2) — the K=1 -square moment — IS the bottleneck. -/ -private theorem multigraphEval_one_doubled_unlabeled_edge_descends {T K n : ℕ} - (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) - (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (M : MultiLabeledGraph K n) - (e₀ : Sym2 (Fin (n + K))) - (he₀_unlabeled : ¬ isLLEdge e₀) - (he₀_doubled : M.mult e₀ = 2) - (h_others_le_one : ∀ e, e ≠ e₀ → M.mult e ≤ 1) - {ξ ξ' : Fin K → Fin T} - (h_simple : ∀ (n' : ℕ) (F : SimpleGraph (Fin (n' + K))) [DecidableRel F.Adj], - ∑ σ : Fin n' → Fin T, - (let τ : Fin (n' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = - ∑ σ : Fin n' → Fin T, - (let τ : Fin (n' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ' ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) - (h_sq_moment : ∀ (c : Fin K), - ∑ t : Fin T, W t * B (ξ c) t ^ 2 = ∑ t : Fin T, W t * B (ξ' c) t ^ 2) : - multiLabeledEvalK K n M B W ξ = multiLabeledEvalK K n M B W ξ' := by +/-- **Loop ⟹ multi** (trivial direction via the `toLoop` injection). -/ +theorem tupleEquivMulti_of_tupleEquivLoop {T K : ℕ} + (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} + (h : tupleEquivLoop B W ξ ξ') : + tupleEquivMulti B W ξ ξ' := by + intro n M + have hL := h n M.toLoop + rw [multiLabeledEvalKLoop_of_toLoop, multiLabeledEvalKLoop_of_toLoop] at hL + exact hL + +/-- **Lovász Lemma 2.5 (loop), forward direction** (orbit ⟹ loop equiv). -/ +theorem tupleEquivLoop_of_orbit {T K : ℕ} + (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} + (h : ∃ σ : Equiv.Perm (Fin T), + (∀ i, W (σ i) = W i) ∧ (∀ i j, B (σ i) (σ j) = B i j) ∧ + (∀ i, ξ' i = σ (ξ i))) : + tupleEquivLoop B W ξ ξ' := by + intro n M + exact multiLabeledEvalKLoop_orbit_invariant B W M h + +/-! **Diagonal observable** (#79, 2026-05-17 / 2026-05-18). + +The theorem `diagonal_observable_of_tupleEquivSimple` is defined LATER +in this file (after `diagonal_observable_K1`), at the position where +all required dependencies (`tupleEquivSimple_restrict_along`, +`rooted_profiles_separate_vertex_orbits`) are in scope. + +**Mathematical content**: `η ↦ B(η a, η a)` is orbit-invariant. The +proof reduces to the K=1 case (via `tupleEquivSimple_restrict_along`) +which routes through `rooted_profiles_separate_vertex_orbits` (#77 +paper-root). This collapses #79's diagonal observable into the #77 +spectral chain, more direct than the rank-theorem route. -/ + +-- The n=0 loop bridge from `tupleEquivSimple` follows by combining: +-- 1. existing `multiLabeledEvalK_tupleEquiv_invariant_n_zero` (off-diagonal), +-- 2. `diagonal_observable_of_tupleEquivSimple` (closed modulo #77), +-- 3. `multiLabeledEvalKLoop_n_zero_of_diag` (assembly). +-- Wiring deferred (avoids motive-not-type-correct issues with naive rw +-- on Fin.mk constructions during off-diagonal extraction). + +/-- **Multi ⟹ simple** (trivial direction). + +If `ξ ξ'` agree on every multigraph evaluation, they agree on every +simple-graph evaluation, since `MultiLabeledGraph.ofSimple F` reduces +to the simple-graph form (`multiLabeledEvalK_ofSimple`). -/ +theorem tupleEquivSimple_of_tupleEquivMulti {T K : ℕ} + (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} + (h : tupleEquivMulti B W ξ ξ') : + tupleEquivSimple B W ξ ξ' := by + intro n' F _ + have hM := h n' (MultiLabeledGraph.ofSimple F) + rw [multiLabeledEvalK_ofSimple, multiLabeledEvalK_ofSimple] at hM + exact hM + +/-- **Lovász Lemma 2.5, forward direction** (orbit ⟹ multi-equivalence). + +If `ξ` and `ξ'` lie in the same `(B, W)`-automorphism orbit +(`ξ' i = σ (ξ i)` for some weighted automorphism `σ`), then they agree +on every multigraph evaluation. Immediate corollary of +`multiLabeledEvalK_orbit_invariant`. -/ +theorem tupleEquivMulti_of_orbit {T K : ℕ} + (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} + (h : ∃ σ : Equiv.Perm (Fin T), + (∀ i, W (σ i) = W i) ∧ (∀ i j, B (σ i) (σ j) = B i j) ∧ + (∀ i, ξ' i = σ (ξ i))) : + tupleEquivMulti B W ξ ξ' := by + intro n M + exact multiLabeledEvalK_orbit_invariant B W M h + +/-! ### §3.9 — Lovász Lemma 2.4 scaffolding (Claims 4.1–4.4) + +This subsection introduces the named helpers and Claims used in Lovász +TR-2004-82's proof of Lemma 2.4. The chain mirrors the (private) chain +already proved in `Graphon/MatrixDetermination.lean` as +`tupleEquiv_restrict` / `tupleEquiv_extend` / `tupleEquiv_bijective_case` +/ `tupleEquiv_surjective_case` / `tupleEquiv_implies_tupleOrbitRel`, but +adapted to the inline `tupleEquivSimple` predicate to avoid the import +cycle with `MatrixDetermination`. The current status: + +* **Claim 4.1** (`tupleEquivSimple_restrict`) — proved. +* **Claim 4.2** (`tupleEquivSimple_extend`) — proved MODULO the named + sub-sorry `product_trace_identity_simple` (the LIST-product trace + identity; the Lovász §3 deep content). The class-constancy step + `coeffRestrictSimple_equiv` is now proved as a wrapper around + `functional_span_zero` + `product_trace_identity_simple`. The + single-graph trace identity case is fully proved here. +* **Claim 4.3** (`tupleEquivSimple_bijective_case`) — proved (restriction + + IH at `T-1` + bijection-uniqueness). +* **Claim 4.4** (`tupleEquivSimple_surjective_case`) — proved via the + helpers `tupleEquivSimple_restrict_along` (restriction along an arbitrary + label-index injection) and `tupleEquivSimple_id_bijective` (twin-free + W>0 + forces `tupleEquivSimple B W id χ` to make `χ` bijective). + +The main theorem `tupleEquivSimple_implies_orbit` is wired below via +strong induction on `K`, with the architectural sorry localized to the +non-surjective branch (mirroring `tupleEquiv_implies_tupleOrbitRel`). -/ + +/-- **Weighted automorphism predicate**. + +A permutation `σ : Equiv.Perm (Fin T)` is a `(B, W)`-automorphism iff it +preserves both the weight vector `W` and the matrix `B` entrywise. -/ +def IsWeightedAutomorphism {T : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (σ : Equiv.Perm (Fin T)) : Prop := + (∀ i, W (σ i) = W i) ∧ (∀ i j, B (σ i) (σ j) = B i j) + +/-- **Tuple-orbit relation** (Lovász TR-2004-82 §2, p. 5). + +Two tuples `ξ ξ' : Fin K → Fin T` are orbit-related iff some +`(B, W)`-automorphism `σ` conjugates one to the other: `ξ' i = σ (ξ i)`. +This is the explicit-σ form of the existential conclusion of +`tupleEquivSimple_implies_orbit`. -/ +def tupleOrbitRel {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (ξ ξ' : Fin K → Fin T) : Prop := + ∃ σ : Equiv.Perm (Fin T), + IsWeightedAutomorphism B W σ ∧ ∀ i, ξ' i = σ (ξ i) + +/-- Restriction of a `(k+1)`-tuple to its first `k` coordinates via +`Fin.castSucc`. Lovász's `φ'` notation (TR-2004-82 §4). -/ +def restrictTuple {T k : ℕ} (ξ : Fin (k + 1) → Fin T) : Fin k → Fin T := + fun i => ξ i.castSucc + +/-- Range of a tuple `φ : Fin k → Fin T` as a `Finset (Fin T)`. + +Used as the well-founded measure in the deficit-induction proof of +`tupleEquivSimple_implies_orbit`'s non-surjective branch. -/ +noncomputable def rangeFinset {T k : ℕ} (φ : Fin k → Fin T) : Finset (Fin T) := + Finset.image φ Finset.univ + +/-- Deficit of `φ : Fin k → Fin T`: `T - |range φ|`. Zero iff `φ` is +surjective. The deficit strictly decreases when extending by a fresh +element (see `deficit_lt_of_not_mem`), giving the well-founded measure +used in Lovász's "extend-and-recurse" plan for Lemma 2.4's +non-surjective branch. -/ +noncomputable def deficit {T k : ℕ} (φ : Fin k → Fin T) : ℕ := + T - (rangeFinset φ).card + +lemma rangeFinset_card_le {T k : ℕ} (φ : Fin k → Fin T) : + (rangeFinset φ).card ≤ T := by classical - -- Case analysis on the orientation of `e₀`. - induction e₀ using Sym2.ind with - | h a b => - -- `M.mult e₀ = 2` ⟹ `a ≠ b` (no self-loop). - have hab_ne : a ≠ b := by - intro h_eq - have h_loop : M.mult s(a, b) = 0 := by rw [h_eq]; exact M.multNoLoop b - rw [he₀_doubled] at h_loop; omega - by_cases ha_lab : a.val < K - · by_cases hb_lab : b.val < K - · -- Both labels: contradicts `he₀_unlabeled`. - exact absurd (show a.val < K ∧ b.val < K from ⟨ha_lab, hb_lab⟩) he₀_unlabeled - · -- `a` label, `b` unlabeled. Label-unlabeled case. - push Not at hb_lab - by_cases h_b_iso : ∀ e, e ≠ s(a, b) → b ∈ e → M.mult e = 0 - · exact multigraphEval_label_unlabeled_isolated_descends - B hB W hW htwin M a b ha_lab hb_lab hab_ne he₀_doubled h_others_le_one - h_b_iso h_simple h_sq_moment - · exact multigraphEval_label_unlabeled_nonisolated_descends - B hB W hW htwin M a b ha_lab hb_lab hab_ne he₀_doubled h_others_le_one - h_b_iso h_simple h_sq_moment - · push Not at ha_lab - by_cases hb_lab : b.val < K - · -- `a` unlabeled, `b` label. - by_cases h_a_iso : ∀ e, e ≠ s(a, b) → a ∈ e → M.mult e = 0 - · exact multigraphEval_unlabeled_label_isolated_descends - B hB W hW htwin M a b ha_lab hb_lab hab_ne he₀_doubled h_others_le_one - h_a_iso h_simple h_sq_moment - · exact multigraphEval_unlabeled_label_nonisolated_descends - B hB W hW htwin M a b ha_lab hb_lab hab_ne he₀_doubled h_others_le_one - h_a_iso h_simple h_sq_moment - · -- Both unlabeled. - push Not at hb_lab - by_cases h_iso : ∀ e, e ≠ s(a, b) → (a ∈ e ∨ b ∈ e) → M.mult e = 0 - · -- **Isolated unlabeled-unlabeled doubled edge** — CLOSED via - -- `multigraphEval_isolated_unlabeled_unlabeled_doubled_edge_descends` (proved). - exact multigraphEval_isolated_unlabeled_unlabeled_doubled_edge_descends - B hB W M a b ha_lab hb_lab hab_ne he₀_doubled h_others_le_one h_iso h_simple - · -- **Non-isolated unlabeled-unlabeled** — dispatch to named reduction. - exact multigraphEval_unlabeled_unlabeled_nonisolated_descends - B hB W M a b ha_lab hb_lab hab_ne he₀_doubled h_others_le_one h_iso h_simple + have := Finset.card_le_univ (rangeFinset φ) + simpa [Fintype.card_fin] using this -/-- **Canonical paper-root for #62**: every multigraph evaluation is in -the simple-profile closure. +lemma rangeFinset_snoc {T k : ℕ} (φ : Fin k → Fin T) (a : Fin T) : + rangeFinset (Fin.snoc φ a : Fin (k + 1) → Fin T) = + insert a (rangeFinset φ) := by + classical + ext x + simp only [rangeFinset, Finset.mem_image, Finset.mem_univ, true_and, + Finset.mem_insert] + constructor + · rintro ⟨i, hi⟩ + by_cases h : (i : ℕ) < k + · refine Or.inr ⟨⟨i, h⟩, ?_⟩ + rw [show i = (⟨i, h⟩ : Fin k).castSucc from Fin.ext rfl, + Fin.snoc_castSucc] at hi + exact hi + · have hi_last : i = Fin.last k := by + apply Fin.ext + have := i.isLt + simp [Fin.val_last] + omega + subst hi_last + rw [Fin.snoc_last] at hi + exact Or.inl hi.symm + · rintro (rfl | ⟨i, rfl⟩) + · exact ⟨Fin.last k, Fin.snoc_last (α := fun _ => Fin T) _ _⟩ + · refine ⟨i.castSucc, ?_⟩ + exact Fin.snoc_castSucc (α := fun _ => Fin T) a φ i -**Proof outline** (Lovász §3 substantive content, ~300-500 LOC): -The space of functions on `tupleEquivSimple`-classes forms a finite- -dimensional ℝ-algebra. Simple-graph evaluations span this algebra (by -the rank theorem). Multigraph evaluations factor through this algebra -via the connection-matrix idempotent decomposition. The "subgraph -counts" of all multigraphs are polynomial combinations of subgraph -counts of simple graphs. +/-- **Deficit strictly decreases on snoc with a fresh element.** -**Status** (2026-05-19): #86 is now a clean wrapper over three cases: +If `a ∉ range φ`, then `deficit (Fin.snoc φ a) < deficit φ`. This is the +key well-founded measure decrease that drives Lovász's +"extend-and-recurse" argument in `tupleEquivSimple_implies_orbit`. -/ +lemma deficit_lt_of_not_mem {T k : ℕ} (φ : Fin k → Fin T) (a : Fin T) + (ha : a ∉ rangeFinset φ) : + deficit (Fin.snoc φ a : Fin (k + 1) → Fin T) < deficit φ := by + classical + simp only [deficit, rangeFinset_snoc] + rw [Finset.card_insert_of_notMem ha] + -- a ∉ range and a ∈ univ ⟹ range.card < |univ| = T. + have hstrict : (rangeFinset φ).card < T := by + have hsub : rangeFinset φ ⊂ Finset.univ := by + refine ⟨Finset.subset_univ _, ?_⟩ + intro hsuper + exact ha (hsuper (Finset.mem_univ a)) + have := Finset.card_lt_card hsub + simpa [Fintype.card_fin] using this + omega - 1. **n = 0 / mults ≤ 1**: dispatched in-line via existing infrastructure - (`multiLabeledEvalK_tupleEquiv_invariant_n_zero` / simple-graph - correspondence + `h_equiv`). +/-- Surjectivity reads off `rangeFinset = univ`. -/ +lemma surjective_iff_rangeFinset_eq_univ {T k : ℕ} (φ : Fin k → Fin T) : + Function.Surjective φ ↔ rangeFinset φ = Finset.univ := by + classical + refine ⟨fun hsurj => ?_, fun heq y => ?_⟩ + · apply Finset.eq_univ_iff_forall.mpr + intro y + obtain ⟨i, hi⟩ := hsurj y + exact Finset.mem_image.mpr ⟨i, Finset.mem_univ _, hi⟩ + · have : y ∈ rangeFinset φ := heq ▸ Finset.mem_univ y + obtain ⟨i, _, hi⟩ := Finset.mem_image.mp this + exact ⟨i, hi⟩ - 2. **LL-excess sub-case** (every mult≥2 edge is label-label): - **CLOSED** via `multigraphEval_LL_excess_descends_aux` (strong - induction on `M.LLSum`; iterated single-edge peel; base case - reduces to a simple graph). Polynomial decomposition à la - Lovász §3.2 (F₁F₂-product). +/-- Surjectivity iff deficit = 0. -/ +lemma deficit_eq_zero_iff_surjective {T k : ℕ} (φ : Fin k → Fin T) : + deficit φ = 0 ↔ Function.Surjective φ := by + classical + rw [surjective_iff_rangeFinset_eq_univ, deficit] + have hle : (rangeFinset φ).card ≤ T := rangeFinset_card_le φ + constructor + · intro h + have hcard : (rangeFinset φ).card = T := by omega + apply Finset.eq_univ_of_card + rw [Fintype.card_fin] + exact hcard + · intro h + have : (rangeFinset φ).card = T := by + rw [h, Finset.card_univ, Fintype.card_fin] + omega - 3. **Unlabeled-excess sub-case** (some mult≥2 edge touches an - unlabeled vertex): **DISPATCHED** to the named paper-root - `multigraphEval_unlabeled_excess_descends` (the final residual - Lovász §3 content; ~300-500 LOC of new spectral/rank - infrastructure for the multigraph algebra `𝒜_K`). +/-- If `φ` is not surjective, some `a : Fin T` is missing from the +range. -/ +lemma exists_not_mem_rangeFinset {T k : ℕ} (φ : Fin k → Fin T) + (h : ¬ Function.Surjective φ) : + ∃ a, a ∉ rangeFinset φ := by + classical + rw [surjective_iff_rangeFinset_eq_univ] at h + by_contra hcontra + push Not at hcontra + apply h + exact Finset.eq_univ_iff_forall.mpr hcontra -Step 1 (`of_const_on_tupleEquivSimple`, Lagrange fullness) is PROVED. -The only remaining sorry is inside `multigraphEval_unlabeled_excess_descends`. -/ -theorem multigraphEval_in_simpleProfileClosure {T K n : ℕ} - (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) - (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (M : MultiLabeledGraph K n) - (h_sq_moment : ∀ {ξ₀ ξ₀' : Fin K → Fin T}, - (∀ (n' : ℕ) (F : SimpleGraph (Fin (n' + K))) [DecidableRel F.Adj], - ∑ σ : Fin n' → Fin T, - (let τ : Fin (n' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ₀ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = - ∑ σ : Fin n' → Fin T, - (let τ : Fin (n' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ₀' ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) → - ∀ (c : Fin K), - ∑ t : Fin T, W t * B (ξ₀ c) t ^ 2 = ∑ t : Fin T, W t * B (ξ₀' c) t ^ 2) : - InSimpleProfileClosure B W K (fun ξ => multiLabeledEvalK K n M B W ξ) := by - apply InSimpleProfileClosure.of_const_on_tupleEquivSimple - intro ξ ξ' h_equiv - -- Descent: multiLabeledEvalK is constant on inlined-tupleEquivSimple classes. - -- Case split on n and multiplicities, matching the existing - -- `multiLabeledEvalK_tupleEquiv_invariant` (#62) wrapper structure. - -- The mult ≥ 2 case is the substantive Lovász §3 content (sorry'd here). - match n, M with - | 0, M => exact multiLabeledEvalK_tupleEquiv_invariant_n_zero B hB W M - (fun n' F hF => h_equiv n' F) - | n + 1, M => - by_cases h_mult_le_one : ∀ e, M.mult e ≤ 1 - · classical - let F : SimpleGraph (Fin ((n + 1) + K)) := - { Adj := fun a b => a ≠ b ∧ M.mult s(a, b) = 1 - symm.symm := fun a b ⟨hne, hmult⟩ => - ⟨hne.symm, by rwa [Sym2.eq_swap]⟩ - loopless.irrefl := fun a ⟨hne, _⟩ => hne rfl } - haveI : DecidableRel F.Adj := Classical.decRel _ - have hmult_eq : ∀ e, M.mult e = (MultiLabeledGraph.ofSimple F).mult e := by - intro e - induction e with - | h a b => - show M.mult s(a, b) = if s(a, b) ∈ F.edgeFinset then 1 else 0 - by_cases hM : M.mult s(a, b) = 0 - · rw [hM] - have : ¬ s(a, b) ∈ F.edgeFinset := by - rw [SimpleGraph.mem_edgeFinset, SimpleGraph.mem_edgeSet] - intro ⟨_, hmult⟩ - rw [hM] at hmult; exact absurd hmult (by omega) - rw [if_neg this] - · have hM_one : M.mult s(a, b) = 1 := by - have := h_mult_le_one s(a, b); omega - rw [hM_one] - have : s(a, b) ∈ F.edgeFinset := by - rw [SimpleGraph.mem_edgeFinset, SimpleGraph.mem_edgeSet] - refine ⟨?_, hM_one⟩ - intro hab; rw [hab] at hM_one - have := M.multNoLoop b; omega - rw [if_pos this] - have hev : ∀ ζ : Fin K → Fin T, - multiLabeledEvalK K (n + 1) M B W ζ = - multiLabeledEvalK K (n + 1) (MultiLabeledGraph.ofSimple F) B W ζ := by - intro ζ - unfold multiLabeledEvalK - refine Finset.sum_congr rfl fun σ _ => ?_ - simp_rw [hmult_eq] - rw [hev ξ, hev ξ', multiLabeledEvalK_ofSimple, multiLabeledEvalK_ofSimple] - exact h_equiv (n + 1) F - · -- Multiplicity ≥ 2 sub-case. Architectural refinement: split on - -- whether the excess multiplicity sits at label-label edges (LL, - -- handled by polynomial decomposition) or at edges touching some - -- unlabeled vertex (the genuinely hard Lovász §3 content). - classical - -- LL predicate on Sym2 pairs of vertices in `Fin ((n+1)+K)`: - -- both endpoints have val < K (i.e., are labels). - let isLL : Sym2 (Fin ((n + 1) + K)) → Prop := fun e => - Sym2.lift ⟨fun a b => (a.val < K ∧ b.val < K), - fun a b => propext ⟨fun ⟨h1, h2⟩ => ⟨h2, h1⟩, fun ⟨h1, h2⟩ => ⟨h2, h1⟩⟩⟩ e - haveI : DecidablePred isLL := fun e => - Quot.recOnSubsingleton (motive := fun e => Decidable (isLL e)) e - (fun p => (inferInstance : Decidable (p.1.val < K ∧ p.2.val < K))) - by_cases h_LL_excess : ∀ e, M.mult e ≥ 2 → isLL e - · -- **LL-excess sub-case** — CLOSED via `multigraphEval_LL_excess_descends_aux`. - -- Strong induction on M.LLSum: each iteration peels a single LL edge - -- via `multiLabeledEvalK_decAt_LL_peel`, applying h_equiv on the - -- single-edge LL graph to match B(ξ_a, ξ_b) at ξ vs ξ'. Base case: - -- all LL mults zero → M has all mults ≤ 1 → simple graph case. - have h_nonLL_le_one : ∀ e, ¬ isLLEdge e → M.mult e ≤ 1 := by - intro e he - by_contra h_ge - push Not at h_ge - have hLL := h_LL_excess e (by omega) - exact he hLL - exact multigraphEval_LL_excess_descends_aux B hB W - (fun n' F _ => h_equiv n' F) M.LLSum M h_nonLL_le_one rfl - · -- **Unlabeled-excess sub-case** — dispatched to the canonical - -- paper-root `multigraphEval_unlabeled_excess_descends`. The - -- hypothesis `h_LL_excess` is false here, so some mult≥2 edge - -- is non-LL (touches an unlabeled vertex). - have h_unlabeled_excess : - ∃ e : Sym2 (Fin ((n + 1) + K)), ¬ isLLEdge e ∧ 2 ≤ M.mult e := by - push Not at h_LL_excess - obtain ⟨e, he_mult, he_notLL⟩ := h_LL_excess - refine ⟨e, ?_, he_mult⟩ - -- The local `isLL` and the global `isLLEdge` are definitionally equal. - intro h_isLL - exact he_notLL h_isLL - exact multigraphEval_unlabeled_excess_descends B hB W hW htwin M h_unlabeled_excess - (fun n' F _ => h_equiv n' F) (h_sq_moment h_equiv) +/-- **Orbit ⟹ simple-equivalence** (forward direction of Lemma 2.5, +specialized to simple graphs). If `ξ ξ'` are `(B, W)`-orbit related, +they agree on every simple-graph evaluation. Used inside the strong +induction to normalize `ψ` by `σ⁻¹` before extending the base. + +This is the simple-graph specialization of `tupleEquivMulti_of_orbit` +(via `tupleEquivSimple_of_tupleEquivMulti`). Direct proof here avoids +the multigraph detour. -/ +theorem tupleEquivSimple_of_tupleOrbitRel {T K : ℕ} + (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} + (h : tupleOrbitRel B W ξ ξ') : + tupleEquivSimple B W ξ ξ' := by + -- Pass through tupleEquivMulti, then descend to simple via the + -- trivial direction. + obtain ⟨σ, ⟨hW, hB⟩, hconj⟩ := h + refine tupleEquivSimple_of_tupleEquivMulti B W ?_ + intro n M + exact multiLabeledEvalK_orbit_invariant B W M ⟨σ, hW, hB, hconj⟩ + +/-- **Claim 4.1 — Restriction preserves `tupleEquivSimple`** +(Lovász TR-2004-82 §4, p. 6, "first paragraph"). + +If `ξ ξ' : Fin (k+1) → Fin T` are simple-equivalent, then their +restrictions to the first `k` coordinates (via `Fin.castSucc`) are +also simple-equivalent. + +**Proof**: any simple graph `F'` on `Fin (n + k)` lifts to a simple +graph `F` on `Fin (n + (k + 1))` via the embedding `Fin.succAboveEmb p` +with `p = ⟨k, _⟩` (skip the pivot position `k`). The level-`(k+1)` +evaluation of `F` at `ξ` equals the level-`k` evaluation of `F'` at +`restrictTuple ξ`, because the embedding leaves the unlabeled vertices +untouched while reindexing the label slot. The hypothesis applied at +`F` then transfers to `F'`. + +This is the simple-graph analog of `tupleEquiv_restrict` (line 4461 of +`MatrixDetermination.lean`). -/ +theorem tupleEquivSimple_restrict {T k : ℕ} + (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) + {ξ ξ' : Fin (k + 1) → Fin T} + (h : tupleEquivSimple B W ξ ξ') : + tupleEquivSimple B W (restrictTuple ξ) (restrictTuple ξ') := by + classical + intro n F' hdec + -- Helper: edge-product term is independent of the Sym2 representative + -- thanks to `hB`. Stated for both target sizes. + have h_edge_rep : ∀ {m : ℕ} (ν : Fin m → Fin T) (a b : Fin m), + B (ν (Quot.out (s(a, b) : Sym2 (Fin m))).1) + (ν (Quot.out (s(a, b) : Sym2 (Fin m))).2) = B (ν a) (ν b) := by + intro m ν a b + have h_out_eq : s((Quot.out (s(a, b) : Sym2 (Fin m))).1, + (Quot.out (s(a, b) : Sym2 (Fin m))).2) = s(a, b) := + Quot.out_eq _ + rcases Sym2.eq_iff.mp h_out_eq with ⟨h1, h2⟩ | ⟨h1, h2⟩ + · rw [h1, h2] + · rw [h1, h2]; exact hB _ _ + -- Pivot at position k; shift = succAboveEmb p maps Fin (n+k) → Fin (n+(k+1)). + have hk : k < n + (k + 1) := by omega + let p : Fin (n + (k + 1)) := ⟨k, hk⟩ + let shift : Fin (n + k) ↪ Fin (n + (k + 1)) := Fin.succAboveEmb p + let F : SimpleGraph (Fin (n + (k + 1))) := SimpleGraph.map shift F' + haveI hF_dec : DecidableRel F.Adj := Classical.decRel _ + -- Core translation. The sum on the LHS of `tupleEquivSimple` at + -- `(restrictTuple ξ, F')` equals the sum on the LHS at `(ξ, F)`. + suffices trans : ∀ (θ : Fin (k + 1) → Fin T), + (∑ σ : Fin n → Fin T, + (let τ : Fin (n + (k + 1)) → Fin T := fun v => + if h : (v : ℕ) < k + 1 then θ ⟨v, h⟩ + else σ ⟨v - (k + 1), by have := v.isLt; omega⟩ + (∏ v : Fin n, W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) = + (∑ σ : Fin n → Fin T, + (let τ : Fin (n + k) → Fin T := fun v => + if h : (v : ℕ) < k then (restrictTuple θ) ⟨v, h⟩ + else σ ⟨v - k, by have := v.isLt; omega⟩ + (∏ v : Fin n, W (σ v)) * + ∏ e ∈ F'.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) by + -- Apply trans on both sides, then h at F. + rw [← trans ξ, ← trans ξ'] + exact h n F + intro θ + refine Finset.sum_congr rfl fun σ _ => ?_ + -- Both sides have the form (∏ W σ) * (edge prod). The W-prods agree + -- definitionally; reduce to edge-product equality. + simp only + refine congrArg (fun x => (∏ v : Fin n, W (σ v)) * x) ?_ + -- Edge product: Finset.prod_bij with shift.sym2Map. + symm + refine Finset.prod_bij (fun e _ => shift.sym2Map e) ?_ ?_ ?_ ?_ + · -- 1. Map lands in F.edgeFinset. + intro e he + change shift.sym2Map e ∈ (SimpleGraph.map shift F').edgeFinset + rw [SimpleGraph.mem_edgeFinset] at he ⊢ + induction e using Sym2.ind with + | _ a b => + simp only [Function.Embedding.sym2Map_apply, Sym2.map_mk] at * + rw [SimpleGraph.mem_edgeSet] at he ⊢ + rw [SimpleGraph.map_adj] + exact ⟨a, b, he, rfl, rfl⟩ + · -- 2. Injective. + intro e1 _ e2 _ hij + exact shift.sym2Map.injective hij + · -- 3. Surjective. + intro e he + change e ∈ (SimpleGraph.map shift F').edgeFinset at he + rw [SimpleGraph.mem_edgeFinset] at he + induction e using Sym2.ind with + | _ x y => + rw [SimpleGraph.mem_edgeSet] at he + rw [SimpleGraph.map_adj] at he + obtain ⟨a, b, hab, hax, hby⟩ := he + refine ⟨s(a, b), ?_, ?_⟩ + · rw [SimpleGraph.mem_edgeFinset, SimpleGraph.mem_edgeSet]; exact hab + · simp only [Function.Embedding.sym2Map_apply, Sym2.map_mk] + rw [hax, hby] + · -- 4. Term-by-term equality. + intro e _ + set ν' : Fin (n + k) → Fin T := fun v => + if h : (v : ℕ) < k then (restrictTuple θ) ⟨v, h⟩ + else σ ⟨(v : Fin (n + k)).val - k, by have := v.isLt; omega⟩ with hν'_def + set ν : Fin (n + (k + 1)) → Fin T := fun v => + if h : (v : ℕ) < k + 1 then θ ⟨v, h⟩ + else σ ⟨(v : Fin (n + (k + 1))).val - (k + 1), + by have := v.isLt; omega⟩ with hν_def + induction e using Sym2.ind with + | _ a b => + simp only [Function.Embedding.sym2Map_apply, Sym2.map_mk] + change B (ν' (Quot.out s(a, b)).1) (ν' (Quot.out s(a, b)).2) = + B (ν (Quot.out s(shift a, shift b)).1) + (ν (Quot.out s(shift a, shift b)).2) + rw [h_edge_rep ν' a b, h_edge_rep ν (shift a) (shift b)] + -- Reduces to ν ∘ shift = ν' pointwise. + have hτ : ∀ v : Fin (n + k), ν (shift v) = ν' v := by + intro v + by_cases hv : (v : ℕ) < k + · -- Below the pivot: shift v = v.castSucc, .val preserved. + have h_shift_val : (shift v : Fin (n + (k + 1))).val = v.val := by + show (p.succAboveEmb v : Fin (n + (k + 1))).val = v.val + simp only [Fin.coe_succAboveEmb] + rw [Fin.succAbove_of_castSucc_lt] + · rfl + · show v.castSucc < p + simp only [Fin.lt_def, Fin.val_castSucc] + exact hv + have h_lt : ((shift v : Fin (n + (k + 1))) : ℕ) < k + 1 := by + rw [h_shift_val]; omega + simp only [hν_def, hν'_def, dif_pos h_lt, dif_pos hv, restrictTuple] + congr 1 + apply Fin.ext + simp only [Fin.val_castSucc] + exact h_shift_val + · -- Above the pivot: shift v = v.succ, .val = v.val + 1. + have h_shift_val : (shift v : Fin (n + (k + 1))).val = v.val + 1 := by + show (p.succAboveEmb v : Fin (n + (k + 1))).val = v.val + 1 + simp only [Fin.coe_succAboveEmb] + rw [Fin.succAbove_of_le_castSucc] + · rfl + · show p ≤ v.castSucc + simp only [Fin.le_def, Fin.val_castSucc] + show k ≤ v.val + omega + have h_nlt : ¬ ((shift v : Fin (n + (k + 1))) : ℕ) < k + 1 := by + rw [h_shift_val]; omega + have h_nlt' : ¬ (v : ℕ) < k := hv + simp only [hν_def, hν'_def, dif_neg h_nlt, dif_neg h_nlt'] + congr 1 + apply Fin.ext + show (shift v : Fin (n + (k + 1))).val - (k + 1) = v.val - k + rw [h_shift_val]; omega + rw [hτ a, hτ b] -/-- **The multigraph bridge — SECONDARY paper root** (general, -non-twin-free version). +/-! ### §3.9.1 — Restriction-weight coefficient (Claim 4.2 architecture) -**Dependency hierarchy** (post-2026-05-12 architectural decision): - - **PRIMARY ROOT**: `connection_matrix_rank_theorem` (later in this file; - Lovász §3 Theorem 2.2, simple-graph form, requires twin-free). - - **SECONDARY**: this bridge (no twin-free hypothesis; strictly - stronger statement). +The proof of Claim 4.2 (`tupleEquivSimple_extend`) below routes through +a `coeffRestrictSimple` "restriction weight" coefficient: -For the twin-free version that downstream consumers actually need, -use `multiLabeledEvalK_tupleEquiv_invariant_twinFree` (already proved -modulo `connection_matrix_rank_theorem`). This general bridge can be -treated as off-axis if all consumers can use the twin-free variant. + `coeffRestrictSimple B W μ ξ := ∑ t : Fin T, [tupleEquivSimple B W μ (snoc ξ t)] · W t` -Every multigraph evaluation descends through the simple-graph version -of `tupleEquiv`. This is the Lovász §3 content (Theorem 2.2 / Lemma 2.5) -translated to our framework: simple-graph `tupleEquiv` ⟹ all -multigraph evaluations agree. +i.e., the total `W`-mass of extensions `t` of `ξ` that are +simple-equivalent (at level `k + 1`) to the given `(k + 1)`-tuple `μ`. -**Hypothesis form** (`h_simple`): for every level-K simple graph -`F : SimpleGraph (Fin (n' + K))` (with any `n'` unlabeled vertices), -the simple-graph evaluations at `ξ` and `ξ'` agree. This is the -inlined definition of `tupleEquiv B W ξ ξ'`. +Three lemmas drive the assembly: -**Status** (2026-05-17): designated PRIMARY PAPER-ROOT theorem -(Lovász TR-2004-82 Theorem 2.2 / Lemma 2.5 content). The n = 0 case -is dispatched via `multiLabeledEvalK_tupleEquiv_invariant_n_zero`. -The general n case requires the connection-matrix / idempotent- -decomposition argument from Lovász §3 — substantial spectral/rank -infrastructure (~300-500 LOC) beyond a quick closure. Natural -induction on n via `promote_unfold` needs a "lifted simple-equivalence" -hypothesis at level K + 1, which does NOT follow from the level-K -`h_simple` alone. +* `coeffRestrictSimple_pos_at_restrict` — the coefficient is positive + at `ξ = restrictTuple μ` (witnessed by `t = μ (Fin.last k)`, which + makes the indicator `tupleEquivSimple μ μ` true by reflexivity). +* `coeffRestrictSimple_equiv` — class constancy: simple-equivalence + of `ξ` and `ξ'` transfers `coeffRestrictSimple B W μ ξ = + coeffRestrictSimple B W μ ξ'`. PROVED via `functional_span_zero` + + `product_trace_identity_simple` (the latter is a focused + sub-sorry capturing the Lovász §3 deep content). +* `exists_extension_of_coeffRestrictSimple_pos` — from positivity, some + `t` makes the indicator true, yielding the extension. -**Downstream impact** (closes #62 ⟹ unlocks): -- IH-free Claims 4.3/4.4 (via multigraph evaluations giving - B-diagonal + W-pointwise data, currently unavailable in - simple-graph framework alone). -- Task #70 (`orbit_separation_by_simple_graph`). -- Remaining MatrixDetermination chain. +The class-constancy step is now proved structurally. The single +remaining architectural hurdle is the LIST-product trace identity +`product_trace_identity_simple` (Lovász §3 / DecLabeledGraph). -/ -Treat as foundational citation for downstream consumers until a -dedicated paper-root formalization project is undertaken. -/ -theorem multiLabeledEvalK_tupleEquiv_invariant {T K n : ℕ} - (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) - (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) - (M : MultiLabeledGraph K n) - (h_sq_moment : ∀ {ξ₀ ξ₀' : Fin K → Fin T}, - (∀ (n'' : ℕ) (F : SimpleGraph (Fin (n'' + K))) [DecidableRel F.Adj], - ∑ σ : Fin n'' → Fin T, - (let τ : Fin (n'' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ₀ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n'', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = - ∑ σ : Fin n'' → Fin T, - (let τ : Fin (n'' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ₀' ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n'', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) → - ∀ (c : Fin K), - ∑ t : Fin T, W t * B (ξ₀ c) t ^ 2 = ∑ t : Fin T, W t * B (ξ₀' c) t ^ 2) - {ξ ξ' : Fin K → Fin T} - (h_simple : ∀ (n' : ℕ) (F : SimpleGraph (Fin (n' + K))) - [DecidableRel F.Adj], - ∑ σ : Fin n' → Fin T, - (let τ : Fin (n' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = - ∑ σ : Fin n' → Fin T, - (let τ : Fin (n' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ' ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) : - multiLabeledEvalK K n M B W ξ = multiLabeledEvalK K n M B W ξ' := by - -- Dispatch the n=0 case via the dedicated lemma. - match n, M with - | 0, M => exact multiLabeledEvalK_tupleEquiv_invariant_n_zero B hB W M h_simple - | n + 1, M => - -- Sub-case: if all multiplicities are ≤ 1, M corresponds to a simple - -- graph and the invariance follows directly from h_simple via - -- multiLabeledEvalK_ofSimple. Otherwise the standard approach - -- (Lovász §3 rank theorem / connection-matrix idempotent - -- decomposition) is required. - by_cases h_mult_le_one : ∀ e, M.mult e ≤ 1 - · -- Build the corresponding simple graph and reduce. - classical - let F : SimpleGraph (Fin ((n + 1) + K)) := - { Adj := fun a b => a ≠ b ∧ M.mult s(a, b) = 1 - symm.symm := fun a b ⟨hne, hmult⟩ => - ⟨hne.symm, by rwa [Sym2.eq_swap]⟩ - loopless.irrefl := fun a ⟨hne, _⟩ => hne rfl } - haveI : DecidableRel F.Adj := Classical.decRel _ - -- Show M.mult = (MultiLabeledGraph.ofSimple F).mult pointwise. - have hmult_eq : ∀ e, M.mult e = (MultiLabeledGraph.ofSimple F).mult e := by - intro e - induction e with - | h a b => - show M.mult s(a, b) = if s(a, b) ∈ F.edgeFinset then 1 else 0 - by_cases hM : M.mult s(a, b) = 0 - · rw [hM] - have : ¬ s(a, b) ∈ F.edgeFinset := by - rw [SimpleGraph.mem_edgeFinset, SimpleGraph.mem_edgeSet] - show ¬ F.Adj a b - intro ⟨_, hmult⟩ - rw [hM] at hmult - exact absurd hmult (by omega) - rw [if_neg this] - · have hM_one : M.mult s(a, b) = 1 := by - have := h_mult_le_one s(a, b); omega - rw [hM_one] - have : s(a, b) ∈ F.edgeFinset := by - rw [SimpleGraph.mem_edgeFinset, SimpleGraph.mem_edgeSet] - show F.Adj a b - refine ⟨?_, hM_one⟩ - intro hab - rw [hab] at hM_one - have := M.multNoLoop b - omega - rw [if_pos this] - -- Rewrite multiLabeledEvalK using pointwise equality of mult. - have hev : ∀ ζ : Fin K → Fin T, - multiLabeledEvalK K (n + 1) M B W ζ = - multiLabeledEvalK K (n + 1) (MultiLabeledGraph.ofSimple F) B W ζ := by - intro ζ - unfold multiLabeledEvalK - refine Finset.sum_congr rfl fun σ _ => ?_ - simp_rw [hmult_eq] - rw [hev ξ, hev ξ', multiLabeledEvalK_ofSimple, multiLabeledEvalK_ofSimple] - exact h_simple (n + 1) F - · -- Multiplicity ≥ 2 sub-case: routes through the canonical paper-root - -- `multigraphEval_in_simpleProfileClosure` (#86, declared above in §3.7). - -- The closure inductive's `descends` reduces this to the `h_simple` - -- hypothesis directly. - exact (multigraphEval_in_simpleProfileClosure B hB W hW htwin M h_sq_moment).descends h_simple +/-- **Restriction-weight coefficient** for a `(k+1)`-tuple `μ` +at a level-`k` base `ξ`. Sums `W t` over `t : Fin T` such that the +extended tuple `Fin.snoc ξ t` is simple-equivalent to `μ`. -/ +noncomputable def coeffRestrictSimple {T k : ℕ} + (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (μ : Fin (k + 1) → Fin T) (ξ : Fin k → Fin T) : ℝ := + ∑ t : Fin T, + haveI : Decidable (tupleEquivSimple B W μ (Fin.snoc ξ t)) := Classical.dec _ + if tupleEquivSimple B W μ (Fin.snoc ξ t) then W t else 0 + +/-- `μ` is `Fin.snoc`-canonical at its own restriction: any tuple +equals `Fin.snoc` of its restriction with its last coordinate. -/ +private theorem snoc_restrict_eq {T k : ℕ} (μ : Fin (k + 1) → Fin T) : + Fin.snoc (restrictTuple μ) (μ (Fin.last k)) = μ := by + funext i + by_cases hi : (i : ℕ) < k + · rw [show i = (⟨i, hi⟩ : Fin k).castSucc from Fin.ext rfl, + Fin.snoc_castSucc] + rfl + · rw [show i = Fin.last k from Fin.ext (show i.val = k by omega), + Fin.snoc_last] + +/-- Reflexivity of `tupleEquivSimple`. -/ +private theorem tupleEquivSimple_refl {T K : ℕ} + (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) (ξ : Fin K → Fin T) : + tupleEquivSimple B W ξ ξ := + fun _ _ _ => rfl -/-! ### §3.8 — Equivalence predicates and Lovász Lemma 2.5 +/-- **Positivity of `coeffRestrictSimple` at its own restriction**. -This section introduces the two equivalence relations on label-tuples -that bracket the bridge theorem: +Under `0 < W`, the coefficient `coeffRestrictSimple B W μ +(restrictTuple μ)` is strictly positive: the term `t = μ (Fin.last k)` +contributes `W t > 0` (the indicator `tupleEquivSimple μ μ` holds by +reflexivity), and all other terms are nonneg. -/ +theorem coeffRestrictSimple_pos_at_restrict {T k : ℕ} + (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) (hW : ∀ i, 0 < W i) + (μ : Fin (k + 1) → Fin T) : + 0 < coeffRestrictSimple B W μ (restrictTuple μ) := by + classical + unfold coeffRestrictSimple + -- Witness term: t = μ (Fin.last k). + set t₀ : Fin T := μ (Fin.last k) with ht₀ + -- Indicator at t₀ is true: snoc (restrictTuple μ) t₀ = μ, then refl. + have h_snoc_eq : Fin.snoc (restrictTuple μ) t₀ = μ := snoc_restrict_eq μ + have h_indicator : tupleEquivSimple B W μ (Fin.snoc (restrictTuple μ) t₀) := by + rw [h_snoc_eq]; exact tupleEquivSimple_refl B W μ + -- Apply Finset.sum_pos' (nonneg + exists-positive). + refine Finset.sum_pos' ?_ ⟨t₀, Finset.mem_univ _, ?_⟩ + · intro i _ + by_cases hi : tupleEquivSimple B W μ (Fin.snoc (restrictTuple μ) i) + · rw [if_pos hi]; exact (hW i).le + · rw [if_neg hi] + · rw [if_pos h_indicator]; exact hW t₀ -* `tupleEquivSimple` — agreement of all **simple-graph** evaluations - (Lovász TR-2004-82 §2, p. 6). This is the simple-graph `tupleEquiv` - inlined here so this module needs no dependency on - `Graphon/MatrixDetermination.lean`. -* `tupleEquivMulti` — agreement of all **multigraph** evaluations - (the natural multigraph generalization). +/-- **Existence of an extension witness from positive coefficient**. -The bridge theorem (§4 below) is exactly `tupleEquivSimple → tupleEquivMulti`. -The reverse direction `tupleEquivMulti → tupleEquivSimple` is trivial -because `multiLabeledEvalK` of `MultiLabeledGraph.ofSimple F` recovers -the simple-graph evaluation (`multiLabeledEvalK_ofSimple`). +If the restriction-weight coefficient `coeffRestrictSimple B W μ ψ` is +strictly positive (under `0 ≤ W`), then there is some `a : Fin T` such +that `Fin.snoc ψ a` is simple-equivalent to `μ` at level `k + 1`. -/ +theorem exists_extension_of_coeffRestrictSimple_pos {T k : ℕ} + (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (μ : Fin (k + 1) → Fin T) (ψ : Fin k → Fin T) + (hpos : 0 < coeffRestrictSimple B W μ ψ) : + ∃ a : Fin T, tupleEquivSimple B W μ (Fin.snoc ψ a) := by + classical + by_contra h_no + push Not at h_no + -- Every term vanishes, so the sum is 0, contradicting positivity. + have h_all_zero : ∀ t : Fin T, + (if tupleEquivSimple B W μ (Fin.snoc ψ t) then W t else 0) = 0 := by + intro t + rw [if_neg (h_no t)] + have h_sum_zero : coeffRestrictSimple B W μ ψ = 0 := by + unfold coeffRestrictSimple + exact Finset.sum_eq_zero (fun t _ => h_all_zero t) + rw [h_sum_zero] at hpos + exact lt_irrefl 0 hpos -**Lovász Lemma 2.5** (informal): if `B` is twin-free, then -`tupleEquivMulti ξ ξ'` if and only if `ξ` and `ξ'` lie in the same -`(B, W)`-automorphism orbit. +/-! ### §3.9.2 — Functional-span machinery (port of MD `functional_span_zero`) -* The **forward direction** (orbit ⟹ multi-equivalence) is the - trivial corollary `multiLabeledEvalK_orbit_invariant` (already proved - above): aut-invariance of multigraph evaluation gives equality on every - multigraph automatically. -* The **reverse direction** (multi-equivalence ⟹ orbit) is the deep paper - content. Lovász's proof goes through the connection-matrix rank / - idempotent decomposition argument (TR-2004-82 §3): the connection - matrix `M(B, W) ∈ ℝ^{T^k × T^k}` factors through twin-free quotients, - and equal multi-eval rows are exactly orbit equivalences. -/ +To prove `coeffRestrictSimple_equiv` we use the standard finite +Stone-Weierstrass-style lemma: given a separating, unital, +multiplicatively closed family `f : I → Q → ℝ` and a `d : Q → ℝ` that +is orthogonal to every `f i` (under the counting measure), `d = 0`. -/-- **Simple-graph tuple equivalence** (Lovász §2, p. 6). +This is a verbatim port of `MatrixDetermination.functional_span_zero` +(L5004) — self-contained, ~100 lines of finite induction on the support +of `d`. Used below to conclude that the class-weight difference between +`ξ` and `ξ'` over the level-`(k+1)` `tupleEquivSimple`-quotient +vanishes, given orthogonality from a product trace identity. -/ -Two label maps `ξ, ξ' : Fin K → Fin T` are simple-equivalent iff every -level-`K` **simple** graph (with any number `n'` of unlabeled vertices) -evaluates equally on them. This is the simple-graph `tupleEquiv` -inlined to avoid a `MatrixDetermination` dependency. -/ -def tupleEquivSimple {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (ξ ξ' : Fin K → Fin T) : Prop := - ∀ (n' : ℕ) (F : SimpleGraph (Fin (n' + K))) [DecidableRel F.Adj], - ∑ σ : Fin n' → Fin T, - (let τ : Fin (n' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = - ∑ σ : Fin n' → Fin T, - (let τ : Fin (n' + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ' ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n', W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) +/-- **Functional span zero**: if a function `d : Q → ℝ` on a finite +type is orthogonal (w.r.t. counting measure) to every member of a +separating, unital, multiplicatively closed family `f : I → Q → ℝ`, +then `d` vanishes pointwise. -/-- **Multigraph tuple equivalence**. +Port of `MatrixDetermination.functional_span_zero`. -/ +private theorem functional_span_zero {Q : Type*} [Fintype Q] [DecidableEq Q] + {I : Type*} (f : I → Q → ℝ) (d : Q → ℝ) + (hconst : ∃ i₀ : I, ∀ q, f i₀ q = 1) + (hmul : ∀ i j : I, ∃ k : I, ∀ q, f k q = f i q * f j q) + (hsep : ∀ q₁ q₂ : Q, q₁ ≠ q₂ → ∃ i : I, f i q₁ ≠ f i q₂) + (hortho : ∀ i : I, ∑ q, d q * f i q = 0) : + ∀ q, d q = 0 := by + -- Strong induction on |support(d)|. + suffices key : ∀ (m : ℕ) (d : Q → ℝ), + (Finset.univ.filter (fun q => d q ≠ 0)).card ≤ m → + (∀ i : I, ∑ q, d q * f i q = 0) → + ∀ q, d q = 0 by + exact key (Finset.univ.filter (fun q => d q ≠ 0)).card d le_rfl hortho + intro m + induction m with + | zero => + intro d hm _ q + by_contra hq + have hmem : q ∈ Finset.univ.filter (fun q => d q ≠ 0) := + Finset.mem_filter.mpr ⟨Finset.mem_univ _, hq⟩ + have := Finset.card_pos.mpr ⟨q, hmem⟩ + omega + | succ m IH => + intro d hm hd_ortho + by_cases h_all_zero : ∀ q, d q = 0 + · exact h_all_zero + push Not at h_all_zero + obtain ⟨q₀, hq₀⟩ := h_all_zero + by_cases h_unique : ∀ q, q ≠ q₀ → d q = 0 + · obtain ⟨i₀, hi₀⟩ := hconst + have h := hd_ortho i₀ + simp only [hi₀, mul_one] at h + rw [show ∑ q, d q = d q₀ + ∑ q ∈ Finset.univ.erase q₀, d q from by + rw [Finset.add_sum_erase _ _ (Finset.mem_univ _)]] at h + have hzero : ∑ q ∈ Finset.univ.erase q₀, d q = 0 := + Finset.sum_eq_zero fun q hq => h_unique q (Finset.ne_of_mem_erase hq) + rw [hzero, add_zero] at h + exact absurd h hq₀ + · push Not at h_unique + obtain ⟨q₁, hq₁_ne, hq₁⟩ := h_unique + obtain ⟨i_sep, hi_sep⟩ := hsep q₀ q₁ hq₁_ne.symm + let d' : Q → ℝ := fun q => d q * (f i_sep q - f i_sep q₀) + have hd'_ortho : ∀ j : I, ∑ q, d' q * f j q = 0 := by + intro j + obtain ⟨k, hk⟩ := hmul i_sep j + show ∑ q, d q * (f i_sep q - f i_sep q₀) * f j q = 0 + have h1 : ∑ q, d q * (f i_sep q - f i_sep q₀) * f j q = + ∑ q, d q * f i_sep q * f j q - + ∑ q, d q * (f i_sep q₀ * f j q) := by + rw [(Finset.sum_sub_distrib + (f := fun q => d q * f i_sep q * f j q) + (g := fun q => d q * (f i_sep q₀ * f j q))).symm] + congr 1; ext q; ring + rw [h1] + rw [show ∑ q, d q * f i_sep q * f j q = ∑ q, d q * f k q by + congr 1; ext q; rw [hk]; ring] + rw [hd_ortho k] + rw [show ∑ q, d q * (f i_sep q₀ * f j q) = + f i_sep q₀ * ∑ q, d q * f j q by + rw [Finset.mul_sum]; congr 1; ext q; ring] + rw [hd_ortho j, mul_zero, sub_self] + have hd'q₀ : d' q₀ = 0 := by + show d q₀ * (f i_sep q₀ - f i_sep q₀) = 0; simp + have hd'_card : (Finset.univ.filter (fun q => d' q ≠ 0)).card ≤ m := by + have hsub : Finset.univ.filter (fun q => d' q ≠ 0) ⊆ + (Finset.univ.filter (fun q => d q ≠ 0)).erase q₀ := by + intro q hq + simp only [Finset.mem_filter, Finset.mem_univ, true_and] at hq + rw [Finset.mem_erase] + refine ⟨fun heq => ?_, Finset.mem_filter.mpr + ⟨Finset.mem_univ _, fun habs => ?_⟩⟩ + · subst heq; exact hq hd'q₀ + · exact hq (show d' q = 0 by + show d q * (f i_sep q - f i_sep q₀) = 0 + rw [habs, zero_mul]) + calc (Finset.univ.filter (fun q => d' q ≠ 0)).card + ≤ ((Finset.univ.filter (fun q => d q ≠ 0)).erase q₀).card := + Finset.card_le_card hsub + _ ≤ (Finset.univ.filter (fun q => d q ≠ 0)).card - 1 := + Nat.le_sub_one_of_lt (Finset.card_erase_lt_of_mem + (Finset.mem_filter.mpr ⟨Finset.mem_univ _, hq₀⟩)) + _ ≤ m := by omega + have hkey := IH d' hd'_card hd'_ortho q₁ + change d q₁ * (f i_sep q₁ - f i_sep q₀) = 0 at hkey + rcases mul_eq_zero.mp hkey with hcase | hcase + · exact absurd hcase hq₁ + · exact absurd (sub_eq_zero.mp hcase) hi_sep.symm -Two label maps `ξ, ξ' : Fin K → Fin T` are multi-equivalent iff every -level-`K` **multigraph** (with any number `n` of unlabeled vertices) -evaluates equally on them. This is the natural multigraph generalization -of `tupleEquivSimple`. -/ -def tupleEquivMulti {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (ξ ξ' : Fin K → Fin T) : Prop := - ∀ (n : ℕ) (M : MultiLabeledGraph K n), - multiLabeledEvalK K n M B W ξ = multiLabeledEvalK K n M B W ξ' +/-! ### §3.9.3 — Simple-graph evaluation, single-graph trace identity, and + the product trace identity (named focused sorry). -/-- **Loop-multigraph tuple equivalence**. +We package the simple-graph evaluation body that appears inside +`tupleEquivSimple` as a noncomputable definition `simpleEvalAt`, prove +the single-graph trace identity directly from +`multiLabeledEvalK_sum_last_label`, and state the LIST-product trace +identity as a focused sorry. The product identity is the genuine +Lovász §3 content (it requires the connection-matrix / DecLabeledGraph +machinery in `MatrixDetermination.lean`, ~3000 lines), and is the SOLE +remaining gap for `coeffRestrictSimple_equiv` below. -/ -Two label maps `ξ, ξ' : Fin K → Fin T` are loop-multi-equivalent iff -every level-`K` **multigraph with self-loops** evaluates equally on -them. Strictly stronger than `tupleEquivMulti` (loop case includes -diagonal contributions). The target of task #79: prove -`tupleEquivSimple → tupleEquivLoop` via the Lovász §3 rank theorem. -/ -def tupleEquivLoop {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (ξ ξ' : Fin K → Fin T) : Prop := - ∀ (n : ℕ) (M : MultiLabeledGraphLoop K n), - multiLabeledEvalKLoop K n M B W ξ = multiLabeledEvalKLoop K n M B W ξ' +/-- Simple-graph evaluation extracted as a named definition (matching the +body of `tupleEquivSimple` and the RHS of `multiLabeledEvalK_ofSimple`). -/ +noncomputable def simpleEvalAt {T K n : ℕ} + (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (F : SimpleGraph (Fin (n + K))) [DecidableRel F.Adj] + (ξ : Fin K → Fin T) : ℝ := + ∑ σ : Fin n → Fin T, + (let τ : Fin (n + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n, W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) -/-- **Loop ⟹ multi** (trivial direction via the `toLoop` injection). -/ -theorem tupleEquivMulti_of_tupleEquivLoop {T K : ℕ} - (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} - (h : tupleEquivLoop B W ξ ξ') : - tupleEquivMulti B W ξ ξ' := by - intro n M - have hL := h n M.toLoop - rw [multiLabeledEvalKLoop_of_toLoop, multiLabeledEvalKLoop_of_toLoop] at hL - exact hL +/-- `simpleEvalAt` is `multiLabeledEvalK` on `MultiLabeledGraph.ofSimple`. -/ +private theorem simpleEvalAt_eq_multi {T K n : ℕ} + (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (F : SimpleGraph (Fin (n + K))) [DecidableRel F.Adj] + (ξ : Fin K → Fin T) : + simpleEvalAt B W F ξ = + multiLabeledEvalK K n (MultiLabeledGraph.ofSimple F) B W ξ := by + rw [multiLabeledEvalK_ofSimple]; rfl + +/-- `Quot.out` resolver on a literal `Sym2` pair over an ARBITRARY vertex type +(the `out_pair_eq` generalization needed for structured graphs). Moved here from +`CycleKrylov.lean` (2026-07-02) so the Cai–Govorov stack below can use it. -/ +theorem out_pair_eq' {T' : ℕ} {V : Type*} (Bm : Fin T' → Fin T' → ℝ) + (hB : ∀ i j, Bm i j = Bm j i) (g : V → Fin T') (x y : V) : + Bm (g (Quot.out s(x, y)).1) (g (Quot.out s(x, y)).2) = Bm (g x) (g y) := by + have hout : s((Quot.out s(x, y)).1, (Quot.out s(x, y)).2) = s(x, y) := Quot.out_eq _ + rcases Sym2.eq_iff.mp hout with ⟨h1, h2⟩ | ⟨h1, h2⟩ + · rw [h1, h2] + · rw [h1, h2, hB] -/-- **Lovász Lemma 2.5 (loop), forward direction** (orbit ⟹ loop equiv). -/ -theorem tupleEquivLoop_of_orbit {T K : ℕ} - (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} - (h : ∃ σ : Equiv.Perm (Fin T), - (∀ i, W (σ i) = W i) ∧ (∀ i j, B (σ i) (σ j) = B i j) ∧ - (∀ i, ξ' i = σ (ξ i))) : - tupleEquivLoop B W ξ ξ' := by - intro n M - exact multiLabeledEvalKLoop_orbit_invariant B W M h +section CaiGovorovStack -/-! **Diagonal observable** (#79, 2026-05-17 / 2026-05-18). +/-! +## The Cai–Govorov stack (formerly `Graphon/CaiGovorovOrbit.lean`, dissolved 2026-07-02) + + +The full Cai–Govorov orbit-separation route for `#70`, culminating in the general +**`tupleEquivSimple_implies_orbit_general`**: equal simple-graph evaluations imply +weighted-automorphism orbit equivalence, with no surjectivity hypothesis. + +* **Test graphs + closed forms**: `starTestGraph S` (Gχ, one unlabeled vertex joined to + `S ⊆ Fin K`; eval `= ∑ₜ W t · ∏_{i∈S} B (ξ i) t`) and `edgeTestGraph Sₗ Sτ` (Gλτ, two + adjacent unlabeled vertices; the double-sum closed form). +* **Chunk 3A / 4A** — the super-surjective case, moment form + (`testEvalEq_implies_orbit_super` from the `TestEvalEq` star/edge interface, with the + `tupleEquivSimple_implies_orbit_super` wrapper): pigeonhole + bounded Vandermonde build + `superMap`/`superPerm`, edge moments certify it as a weighted automorphism, one-extra-label + moments reconcile all labels. +* **Chunk 3B** — eq. (10) `extension_sum_identity` (extension-family sums collapse via the + iterated trace) with the `superExt`/`coverExtra` super-surjective extension (plus the + documented separation corollary `not_tupleEquivSimple_of_not_orbit`, not on the live path). +* **Chunks 4B–4E** — the mult ≤ 1 `toSimple` bridge and `glueList` product law realize + test-moment powers as single simple graphs (`expTestGraph`), so eq. (10) yields the + power-moment identity `extension_power_moments`. +* **Chunks 4F–4G** — the descent: two-family Vandermonde matches an extension of `ξ'` + against `superExt ξ` (`exists_matching_extension`), the super-case runs at level + `K + T·2T²`, and restriction gives the general theorem. + +Downstream in this file, the stack fills `orbit_separation_by_simple_graph` and the +"both non-surjective" branch of `tupleEquivSimple_implies_orbit` (§3.10), and powers the +rank endgame (`simpleEvalSubmodule_finrank_ge_orbitClass` and the collapse +`simpleEvalSubmodule = orbitInvariantSubmodule`, § RankTheorem after +`simpleEvalAt_aut_invariant`). +-/ -The theorem `diagonal_observable_of_tupleEquivSimple` is defined LATER -in this file (after `diagonal_observable_K1`), at the position where -all required dependencies (`tupleEquivSimple_restrict_along`, -`rooted_profiles_separate_vertex_orbits`) are in scope. +open Finset -**Mathematical content**: `η ↦ B(η a, η a)` is orbit-invariant. The -proof reduces to the K=1 case (via `tupleEquivSimple_restrict_along`) -which routes through `rooted_profiles_separate_vertex_orbits` (#77 -paper-root). This collapses #79's diagonal observable into the #77 -spectral chain, more direct than the rank-theorem route. -/ +variable {K : ℕ} --- The n=0 loop bridge from `tupleEquivSimple` follows by combining: --- 1. existing `multiLabeledEvalK_tupleEquiv_invariant_n_zero` (off-diagonal), --- 2. `diagonal_observable_of_tupleEquivSimple` (closed modulo #77), --- 3. `multiLabeledEvalKLoop_n_zero_of_diag` (assembly). --- Wiring deferred (avoids motive-not-type-correct issues with naive rw --- on Fin.mk constructions during off-diagonal extraction). -/-- **Multi ⟹ simple** (trivial direction). +/-- Embed label `i : Fin K` as the vertex of value `i` in `Fin (1 + K)`. -/ +def labVertex (i : Fin K) : Fin (1 + K) := ⟨(i : ℕ), by have := i.isLt; omega⟩ -If `ξ ξ'` agree on every multigraph evaluation, they agree on every -simple-graph evaluation, since `MultiLabeledGraph.ofSimple F` reduces -to the simple-graph form (`multiLabeledEvalK_ofSimple`). -/ -theorem tupleEquivSimple_of_tupleEquivMulti {T K : ℕ} - (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} - (h : tupleEquivMulti B W ξ ξ') : - tupleEquivSimple B W ξ ξ' := by - intro n' F _ - have hM := h n' (MultiLabeledGraph.ofSimple F) - rw [multiLabeledEvalK_ofSimple, multiLabeledEvalK_ofSimple] at hM - exact hM +/-- The single unlabeled vertex (value `K`) in `Fin (1 + K)`. -/ +def unlVertex : Fin (1 + K) := ⟨K, by omega⟩ -/-- **Lovász Lemma 2.5, forward direction** (orbit ⟹ multi-equivalence). +/-- **Cai–Govorov test graph Gχ**: the unlabeled vertex is joined to exactly the +labels in `S ⊆ Fin K`. -/ +def starTestGraph (S : Finset (Fin K)) : SimpleGraph (Fin (1 + K)) := + SimpleGraph.fromEdgeSet + ((S.image (fun i => s(labVertex i, unlVertex))) : Set (Sym2 (Fin (1 + K)))) -If `ξ` and `ξ'` lie in the same `(B, W)`-automorphism orbit -(`ξ' i = σ (ξ i)` for some weighted automorphism `σ`), then they agree -on every multigraph evaluation. Immediate corollary of -`multiLabeledEvalK_orbit_invariant`. -/ -theorem tupleEquivMulti_of_orbit {T K : ℕ} - (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} - (h : ∃ σ : Equiv.Perm (Fin T), - (∀ i, W (σ i) = W i) ∧ (∀ i j, B (σ i) (σ j) = B i j) ∧ - (∀ i, ξ' i = σ (ξ i))) : - tupleEquivMulti B W ξ ξ' := by - intro n M - exact multiLabeledEvalK_orbit_invariant B W M h +noncomputable instance (S : Finset (Fin K)) : DecidableRel (starTestGraph S).Adj := + Classical.decRel _ -/-! ### §3.9 — Lovász Lemma 2.4 scaffolding (Claims 4.1–4.4) +theorem labVertex_ne_unlVertex (i : Fin K) : labVertex i ≠ unlVertex := by + intro h + have := congrArg Fin.val h + simp only [labVertex, unlVertex] at this + have := i.isLt; omega + +theorem starTestGraph_edge_injOn (S : Finset (Fin K)) : + ∀ i ∈ S, ∀ i' ∈ S, s(labVertex i, unlVertex) = s(labVertex i', unlVertex) → i = i' := by + intro i _ i' _ heq + rw [Sym2.eq_iff] at heq + rcases heq with ⟨h1, _⟩ | ⟨h1, _⟩ + · apply Fin.ext + have := congrArg Fin.val h1 + simpa [labVertex] using this + · exact absurd h1 (labVertex_ne_unlVertex i) + +theorem starTestGraph_edgeFinset (S : Finset (Fin K)) : + (starTestGraph S).edgeFinset = S.image (fun i => s(labVertex i, unlVertex)) := by + ext e + simp only [SimpleGraph.mem_edgeFinset, starTestGraph, SimpleGraph.edgeSet_fromEdgeSet, + Set.mem_sdiff, Finset.coe_image, Set.mem_image, Finset.mem_coe, Sym2.mem_diagSet, + Finset.mem_image] + constructor + · rintro ⟨⟨i, hi, rfl⟩, _⟩; exact ⟨i, hi, rfl⟩ + · rintro ⟨i, hi, rfl⟩ + refine ⟨⟨i, hi, rfl⟩, ?_⟩ + rw [Sym2.mk_isDiag_iff] + exact labVertex_ne_unlVertex i + +/-- The `simpleEvalAt` label map sends `labVertex i` to `ξ i` (stated in the +beta-reduced `dite` form produced by `out_pair_eq'`). -/ +theorem tau_apply_labVertex {T : ℕ} (ξ : Fin K → Fin T) (σ : Fin 1 → Fin T) (i : Fin K) : + (if h : ((labVertex i : Fin (1 + K)) : ℕ) < K then ξ ⟨↑(labVertex i), h⟩ + else σ ⟨↑(labVertex i) - K, by have := (labVertex i).isLt; omega⟩) = ξ i := by + rw [dif_pos (show ((labVertex i : Fin (1 + K)) : ℕ) < K from i.isLt)] + congr 1 -This subsection introduces the named helpers and Claims used in Lovász -TR-2004-82's proof of Lemma 2.4. The chain mirrors the (private) chain -already proved in `Graphon/MatrixDetermination.lean` as -`tupleEquiv_restrict` / `tupleEquiv_extend` / `tupleEquiv_bijective_case` -/ `tupleEquiv_surjective_case` / `tupleEquiv_implies_tupleOrbitRel`, but -adapted to the inline `tupleEquivSimple` predicate to avoid the import -cycle with `MatrixDetermination`. The current status: +/-- The `simpleEvalAt` label map sends `unlVertex` to `σ 0` (beta-reduced `dite` form). -/ +theorem tau_apply_unlVertex {T : ℕ} (ξ : Fin K → Fin T) (σ : Fin 1 → Fin T) : + (if h : ((unlVertex : Fin (1 + K)) : ℕ) < K then ξ ⟨↑(unlVertex : Fin (1 + K)), h⟩ + else σ ⟨↑(unlVertex : Fin (1 + K)) - K, by have := (unlVertex : Fin (1 + K)).isLt; omega⟩) + = σ 0 := by + rw [dif_neg (show ¬ ((unlVertex : Fin (1 + K)) : ℕ) < K from by simp [unlVertex])] + congr 1 + apply Fin.ext + simp [unlVertex] + +/-- **Closed form for Gχ**: `simpleEvalAt B W (starTestGraph S) ξ = ∑ₜ W t · ∏_{i∈S} B (ξ i) t`. -/ +theorem simpleEvalAt_starTestGraph {T : ℕ} (B : Fin T → Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (S : Finset (Fin K)) (ξ : Fin K → Fin T) : + simpleEvalAt B W (starTestGraph S) ξ = ∑ t, W t * ∏ i ∈ S, B (ξ i) t := by + rw [show (∑ t, W t * ∏ i ∈ S, B (ξ i) t) + = ∑ σ : Fin 1 → Fin T, W (σ 0) * ∏ i ∈ S, B (ξ i) (σ 0) from + (Equiv.sum_comp (Equiv.funUnique (Fin 1) (Fin T)) + (fun t => W t * ∏ i ∈ S, B (ξ i) t)).symm] + unfold simpleEvalAt + refine Finset.sum_congr rfl fun σ _ => ?_ + rw [starTestGraph_edgeFinset] + show (∏ v : Fin 1, W (σ v)) * + ∏ e ∈ S.image (fun i => s(labVertex i, unlVertex)), + B ((fun v : Fin (1 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩) (Quot.out e).1) + ((fun v : Fin (1 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩) (Quot.out e).2) + = W (σ 0) * ∏ i ∈ S, B (ξ i) (σ 0) + rw [Fin.prod_univ_one, Finset.prod_image (starTestGraph_edge_injOn S)] + congr 1 + refine Finset.prod_congr rfl fun i _ => ?_ + rw [out_pair_eq' B hB (fun v : Fin (1 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩) (labVertex i) unlVertex, + tau_apply_labVertex ξ σ i, tau_apply_unlVertex ξ σ] -* **Claim 4.1** (`tupleEquivSimple_restrict`) — proved. -* **Claim 4.2** (`tupleEquivSimple_extend`) — proved MODULO the named - sub-sorry `product_trace_identity_simple` (the LIST-product trace - identity; the Lovász §3 deep content). The class-constancy step - `coeffRestrictSimple_equiv` is now proved as a wrapper around - `functional_span_zero` + `product_trace_identity_simple`. The - single-graph trace identity case is fully proved here. -* **Claim 4.3** (`tupleEquivSimple_bijective_case`) — proved (restriction + - IH at `T-1` + bijection-uniqueness). -* **Claim 4.4** (`tupleEquivSimple_surjective_case`) — proved via the - helpers `tupleEquivSimple_restrict_along` (restriction along an arbitrary - label-index injection) and `tupleEquivSimple_id_bijective` (twin-free + W>0 - forces `tupleEquivSimple B W id χ` to make `χ` bijective). +/-! ## Cai–Govorov edge-test graph Gλτ (two unlabeled vertices) -/ -The main theorem `tupleEquivSimple_implies_orbit` is wired below via -strong induction on `K`, with the architectural sorry localized to the -non-surjective branch (mirroring `tupleEquiv_implies_tupleOrbitRel`). -/ +/-- Embed label `i : Fin K` as the vertex of value `i` in `Fin (2 + K)`. -/ +def labVertex2 (i : Fin K) : Fin (2 + K) := ⟨(i : ℕ), by have := i.isLt; omega⟩ -/-- **Weighted automorphism predicate**. +/-- The first unlabeled vertex (value `K`, mapped to `σ 0`) in `Fin (2 + K)`. -/ +def unlVertex0 : Fin (2 + K) := ⟨K, by omega⟩ -A permutation `σ : Equiv.Perm (Fin T)` is a `(B, W)`-automorphism iff it -preserves both the weight vector `W` and the matrix `B` entrywise. -/ -def IsWeightedAutomorphism {T : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (σ : Equiv.Perm (Fin T)) : Prop := - (∀ i, W (σ i) = W i) ∧ (∀ i j, B (σ i) (σ j) = B i j) +/-- The second unlabeled vertex (value `K + 1`, mapped to `σ 1`) in `Fin (2 + K)`. -/ +def unlVertex1 : Fin (2 + K) := ⟨K + 1, by omega⟩ -/-- **Tuple-orbit relation** (Lovász TR-2004-82 §2, p. 5). +/-- **Cai–Govorov edge-test graph Gλτ**: the two unlabeled vertices are joined to each +other, vertex `0` is joined to the labels in `Sₗ`, and vertex `1` to the labels in `Sτ`. -/ +def edgeTestGraph (Sₗ Sτ : Finset (Fin K)) : SimpleGraph (Fin (2 + K)) := + SimpleGraph.fromEdgeSet + ((insert s(unlVertex0, unlVertex1) + (Sₗ.image (fun i => s(labVertex2 i, unlVertex0)) ∪ + Sτ.image (fun i => s(labVertex2 i, unlVertex1)))) : Set (Sym2 (Fin (2 + K)))) -Two tuples `ξ ξ' : Fin K → Fin T` are orbit-related iff some -`(B, W)`-automorphism `σ` conjugates one to the other: `ξ' i = σ (ξ i)`. -This is the explicit-σ form of the existential conclusion of -`tupleEquivSimple_implies_orbit`. -/ -def tupleOrbitRel {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (ξ ξ' : Fin K → Fin T) : Prop := - ∃ σ : Equiv.Perm (Fin T), - IsWeightedAutomorphism B W σ ∧ ∀ i, ξ' i = σ (ξ i) +noncomputable instance (Sₗ Sτ : Finset (Fin K)) : + DecidableRel (edgeTestGraph Sₗ Sτ).Adj := Classical.decRel _ -/-- Restriction of a `(k+1)`-tuple to its first `k` coordinates via -`Fin.castSucc`. Lovász's `φ'` notation (TR-2004-82 §4). -/ -def restrictTuple {T k : ℕ} (ξ : Fin (k + 1) → Fin T) : Fin k → Fin T := - fun i => ξ i.castSucc +theorem labVertex2_ne_unlVertex0 (i : Fin K) : labVertex2 i ≠ unlVertex0 := by + intro h + have := congrArg Fin.val h + simp only [labVertex2, unlVertex0] at this + have := i.isLt; omega -/-- Range of a tuple `φ : Fin k → Fin T` as a `Finset (Fin T)`. +theorem labVertex2_ne_unlVertex1 (i : Fin K) : labVertex2 i ≠ unlVertex1 := by + intro h + have := congrArg Fin.val h + simp only [labVertex2, unlVertex1] at this + have := i.isLt; omega -Used as the well-founded measure in the deficit-induction proof of -`tupleEquivSimple_implies_orbit`'s non-surjective branch. -/ -noncomputable def rangeFinset {T k : ℕ} (φ : Fin k → Fin T) : Finset (Fin T) := - Finset.image φ Finset.univ +theorem unlVertex0_ne_unlVertex1 : (unlVertex0 : Fin (2 + K)) ≠ unlVertex1 := by + intro h + have := congrArg Fin.val h + simp only [unlVertex0, unlVertex1] at this + omega -/-- Deficit of `φ : Fin k → Fin T`: `T - |range φ|`. Zero iff `φ` is -surjective. The deficit strictly decreases when extending by a fresh -element (see `deficit_lt_of_not_mem`), giving the well-founded measure -used in Lovász's "extend-and-recurse" plan for Lemma 2.4's -non-surjective branch. -/ -noncomputable def deficit {T k : ℕ} (φ : Fin k → Fin T) : ℕ := - T - (rangeFinset φ).card +theorem edgeTestGraph_edge_injOn_Sₗ (Sₗ : Finset (Fin K)) : + ∀ i ∈ Sₗ, ∀ i' ∈ Sₗ, + s(labVertex2 i, unlVertex0) = s(labVertex2 i', unlVertex0) → i = i' := by + intro i _ i' _ heq + rw [Sym2.eq_iff] at heq + rcases heq with ⟨h1, _⟩ | ⟨h1, _⟩ + · apply Fin.ext + have := congrArg Fin.val h1 + simpa [labVertex2] using this + · exact absurd h1 (labVertex2_ne_unlVertex0 i) + +theorem edgeTestGraph_edge_injOn_Sτ (Sτ : Finset (Fin K)) : + ∀ i ∈ Sτ, ∀ i' ∈ Sτ, + s(labVertex2 i, unlVertex1) = s(labVertex2 i', unlVertex1) → i = i' := by + intro i _ i' _ heq + rw [Sym2.eq_iff] at heq + rcases heq with ⟨h1, _⟩ | ⟨h1, _⟩ + · apply Fin.ext + have := congrArg Fin.val h1 + simpa [labVertex2] using this + · exact absurd h1 (labVertex2_ne_unlVertex1 i) + +theorem edgeTestGraph_edgeFinset (Sₗ Sτ : Finset (Fin K)) : + (edgeTestGraph Sₗ Sτ).edgeFinset = + insert s(unlVertex0, unlVertex1) + (Sₗ.image (fun i => s(labVertex2 i, unlVertex0)) ∪ + Sτ.image (fun i => s(labVertex2 i, unlVertex1))) := by + ext e + simp only [SimpleGraph.mem_edgeFinset, edgeTestGraph, SimpleGraph.edgeSet_fromEdgeSet, + Set.mem_sdiff, Set.mem_insert_iff, Set.mem_union, Finset.coe_image, Set.mem_image, + Finset.mem_coe, Sym2.mem_diagSet, Finset.mem_insert, Finset.mem_union, Finset.mem_image] + constructor + · rintro ⟨h, -⟩; exact h + · intro h + refine ⟨h, ?_⟩ + rcases h with heq | ⟨i, _, heq⟩ | ⟨i, _, heq⟩ + · rw [heq, Sym2.mk_isDiag_iff]; exact unlVertex0_ne_unlVertex1 + · rw [← heq, Sym2.mk_isDiag_iff]; exact labVertex2_ne_unlVertex0 i + · rw [← heq, Sym2.mk_isDiag_iff]; exact labVertex2_ne_unlVertex1 i + +/-- `simpleEvalAt` label map: `labVertex2 i ↦ ξ i` (beta-reduced `dite` form). -/ +theorem tau2_apply_labVertex2 {T : ℕ} (ξ : Fin K → Fin T) (σ : Fin 2 → Fin T) (i : Fin K) : + (if h : ((labVertex2 i : Fin (2 + K)) : ℕ) < K then ξ ⟨↑(labVertex2 i), h⟩ + else σ ⟨↑(labVertex2 i) - K, by have := (labVertex2 i).isLt; omega⟩) = ξ i := by + rw [dif_pos (show ((labVertex2 i : Fin (2 + K)) : ℕ) < K from i.isLt)] + congr 1 -lemma rangeFinset_card_le {T k : ℕ} (φ : Fin k → Fin T) : - (rangeFinset φ).card ≤ T := by +/-- `simpleEvalAt` label map: `unlVertex0 ↦ σ 0` (beta-reduced `dite` form). -/ +theorem tau2_apply_unlVertex0 {T : ℕ} (ξ : Fin K → Fin T) (σ : Fin 2 → Fin T) : + (if h : ((unlVertex0 : Fin (2 + K)) : ℕ) < K then ξ ⟨↑(unlVertex0 : Fin (2 + K)), h⟩ + else σ ⟨↑(unlVertex0 : Fin (2 + K)) - K, + by have := (unlVertex0 : Fin (2 + K)).isLt; omega⟩) = σ 0 := by + rw [dif_neg (show ¬ ((unlVertex0 : Fin (2 + K)) : ℕ) < K from by simp [unlVertex0])] + congr 1 + apply Fin.ext + simp [unlVertex0] + +/-- `simpleEvalAt` label map: `unlVertex1 ↦ σ 1` (beta-reduced `dite` form). -/ +theorem tau2_apply_unlVertex1 {T : ℕ} (ξ : Fin K → Fin T) (σ : Fin 2 → Fin T) : + (if h : ((unlVertex1 : Fin (2 + K)) : ℕ) < K then ξ ⟨↑(unlVertex1 : Fin (2 + K)), h⟩ + else σ ⟨↑(unlVertex1 : Fin (2 + K)) - K, + by have := (unlVertex1 : Fin (2 + K)).isLt; omega⟩) = σ 1 := by + rw [dif_neg (show ¬ ((unlVertex1 : Fin (2 + K)) : ℕ) < K from by simp [unlVertex1])] + congr 1 + apply Fin.ext + simp [unlVertex1] + +/-- **Closed form for Gλτ**: +`simpleEvalAt B W (edgeTestGraph Sₗ Sτ) ξ + = ∑ₜ ∑ₜ' W t · W t' · B t t' · ∏_{i∈Sₗ} B (ξ i) t · ∏_{i∈Sτ} B (ξ i) t'`. -/ +theorem simpleEvalAt_edgeTestGraph {T : ℕ} (B : Fin T → Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) + (Sₗ Sτ : Finset (Fin K)) (ξ : Fin K → Fin T) : + simpleEvalAt B W (edgeTestGraph Sₗ Sτ) ξ + = ∑ t, ∑ t', W t * W t' * B t t' + * (∏ i ∈ Sₗ, B (ξ i) t) * (∏ i ∈ Sτ, B (ξ i) t') := by + have h_notin : s(unlVertex0, unlVertex1) ∉ + (Sₗ.image (fun i => s(labVertex2 i, unlVertex0)) ∪ + Sτ.image (fun i => s(labVertex2 i, unlVertex1))) := by + simp only [Finset.mem_union, Finset.mem_image, not_or] + refine ⟨?_, ?_⟩ + · rintro ⟨i, _, heq⟩ + rw [Sym2.eq_iff] at heq + rcases heq with ⟨h1, _⟩ | ⟨h1, _⟩ + · exact labVertex2_ne_unlVertex0 i h1 + · exact labVertex2_ne_unlVertex1 i h1 + · rintro ⟨i, _, heq⟩ + rw [Sym2.eq_iff] at heq + rcases heq with ⟨h1, _⟩ | ⟨h1, _⟩ + · exact labVertex2_ne_unlVertex0 i h1 + · exact labVertex2_ne_unlVertex1 i h1 + have h_disj : Disjoint (Sₗ.image (fun i => s(labVertex2 i, unlVertex0))) + (Sτ.image (fun i => s(labVertex2 i, unlVertex1))) := by + rw [Finset.disjoint_left] + intro e he1 he2 + simp only [Finset.mem_image] at he1 he2 + obtain ⟨i, _, rfl⟩ := he1 + obtain ⟨j, _, heq⟩ := he2 + rw [Sym2.eq_iff] at heq + rcases heq with ⟨_, h2⟩ | ⟨h1, _⟩ + · exact unlVertex0_ne_unlVertex1 h2.symm + · exact labVertex2_ne_unlVertex0 j h1 + have hsum : (∑ t, ∑ t', W t * W t' * B t t' + * (∏ i ∈ Sₗ, B (ξ i) t) * (∏ i ∈ Sτ, B (ξ i) t')) + = ∑ σ : Fin 2 → Fin T, W (σ 0) * W (σ 1) * B (σ 0) (σ 1) + * (∏ i ∈ Sₗ, B (ξ i) (σ 0)) * (∏ i ∈ Sτ, B (ξ i) (σ 1)) := + (Fintype.sum_prod_type (fun p : Fin T × Fin T => W p.1 * W p.2 * B p.1 p.2 + * (∏ i ∈ Sₗ, B (ξ i) p.1) * (∏ i ∈ Sτ, B (ξ i) p.2))).symm.trans + (Equiv.sum_comp (piFinTwoEquiv (fun _ => Fin T)) + (fun p => W p.1 * W p.2 * B p.1 p.2 + * (∏ i ∈ Sₗ, B (ξ i) p.1) * (∏ i ∈ Sτ, B (ξ i) p.2))).symm + rw [hsum] + unfold simpleEvalAt + refine Finset.sum_congr rfl fun σ _ => ?_ + rw [edgeTestGraph_edgeFinset] + show (∏ v : Fin 2, W (σ v)) * + ∏ e ∈ insert s(unlVertex0, unlVertex1) + (Sₗ.image (fun i => s(labVertex2 i, unlVertex0)) ∪ + Sτ.image (fun i => s(labVertex2 i, unlVertex1))), + B ((fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩) (Quot.out e).1) + ((fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩) (Quot.out e).2) + = W (σ 0) * W (σ 1) * B (σ 0) (σ 1) + * (∏ i ∈ Sₗ, B (ξ i) (σ 0)) * (∏ i ∈ Sτ, B (ξ i) (σ 1)) + rw [Fin.prod_univ_two, Finset.prod_insert h_notin, Finset.prod_union h_disj, + Finset.prod_image (edgeTestGraph_edge_injOn_Sₗ Sₗ), + Finset.prod_image (edgeTestGraph_edge_injOn_Sτ Sτ), + out_pair_eq' B hB (fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩) unlVertex0 unlVertex1, + tau2_apply_unlVertex0 ξ σ, tau2_apply_unlVertex1 ξ σ] + rw [show (∏ i ∈ Sₗ, B ((fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩) (Quot.out s(labVertex2 i, unlVertex0)).1) + ((fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩) (Quot.out s(labVertex2 i, unlVertex0)).2)) + = ∏ i ∈ Sₗ, B (ξ i) (σ 0) from + Finset.prod_congr rfl fun i _ => by + rw [out_pair_eq' B hB (fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩) (labVertex2 i) unlVertex0, + tau2_apply_labVertex2 ξ σ i, tau2_apply_unlVertex0 ξ σ]] + rw [show (∏ i ∈ Sτ, B ((fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩) (Quot.out s(labVertex2 i, unlVertex1)).1) + ((fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩) (Quot.out s(labVertex2 i, unlVertex1)).2)) + = ∏ i ∈ Sτ, B (ξ i) (σ 1) from + Finset.prod_congr rfl fun i _ => by + rw [out_pair_eq' B hB (fun v : Fin (2 + K) => if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩) (labVertex2 i) unlVertex1, + tau2_apply_labVertex2 ξ σ i, tau2_apply_unlVertex1 ξ σ]] + ring + +/-! ## Chunk 3A: super-surjective orbit separation (Cai–Govorov Lemma 5.1, base case) -/ + +/-- `ξ : Fin K → Fin T` is **super-surjective** when every host vertex `v` is the image of +at least `2·T²` labels. This Cai–Govorov hypothesis provides the room to realize every +bounded exponent vector in the Vandermonde argument (by pigeonhole it yields, inside each +`ξ`-fibre, a `ξ'`-constant subset of size `≥ 2T`, aligning the exponents on both sides). -/ +def SuperSurjective {T : ℕ} (ξ : Fin K → Fin T) : Prop := + ∀ v : Fin T, 2 * T * T ≤ (univ.filter (fun i => ξ i = v)).card + +/-- Regroup a product over labels into a product over host vertices weighted by multiplicity: +`∏_{i∈S} B (ξ i) t = ∏_v (B v t) ^ |{i∈S : ξ i = v}|`. -/ +theorem prod_label_eq_prod_mult {T : ℕ} (B : Fin T → Fin T → ℝ) (ξ : Fin K → Fin T) + (S : Finset (Fin K)) (t : Fin T) : + ∏ i ∈ S, B (ξ i) t = ∏ v, (B v t) ^ (S.filter (fun i => ξ i = v)).card := by + rw [Finset.prod_comp (fun v => B v t) ξ] + refine Finset.prod_subset (Finset.subset_univ _) ?_ + intro v _ hv + rw [Finset.mem_image] at hv + have hempty : S.filter (fun i => ξ i = v) = ∅ := by + rw [Finset.filter_eq_empty_iff] + exact fun i hi heq => hv ⟨i, hi, heq⟩ + rw [hempty, Finset.card_empty, pow_zero] + +/-- **Multiplicity form of the Gχ equation.** Simple-equivalence makes the two +host-multiplicity-weighted moment sums agree, for every label subset `S`. + +NB not on the live path: the working bridge to the Vandermonde input is +`aligned_moments_of_testEvalEq_super`, which derives the moment identity directly from +`TestEvalEq.star`. Kept as the standalone multiplicity-form record of the Gχ equation. -/ +theorem tupleEquivSimple_starTestGraph_mult {T : ℕ} (B : Fin T → Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} + (h : tupleEquivSimple B W ξ ξ') (S : Finset (Fin K)) : + ∑ t, W t * ∏ v, (B v t) ^ (S.filter (fun i => ξ i = v)).card + = ∑ t, W t * ∏ v, (B v t) ^ (S.filter (fun i => ξ' i = v)).card := by + have heq : simpleEvalAt B W (starTestGraph S) ξ = simpleEvalAt B W (starTestGraph S) ξ' := + h 1 (starTestGraph S) + rw [simpleEvalAt_starTestGraph B hB W S ξ, simpleEvalAt_starTestGraph B hB W S ξ'] at heq + simp only [prod_label_eq_prod_mult] at heq + exact heq + +/-- **Test-graph evaluation equality** — the moment-level interface to the chunk-3A engine. +Records exactly the two families of simple-graph equalities the super-surjective argument +consumes: the star tests `Gχ` and the edge tests `Gλτ`. Weaker than `tupleEquivSimple` +(which quantifies over ALL simple graphs); the descent step (chunk 4F) produces instances +of this interface from eq. (10) moment matching, where full `tupleEquivSimple` is not +available. -/ +structure TestEvalEq {T : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (ξ ξ' : Fin K → Fin T) : Prop where + star : ∀ S : Finset (Fin K), + simpleEvalAt B W (starTestGraph S) ξ = simpleEvalAt B W (starTestGraph S) ξ' + edge : ∀ Sₗ Sτ : Finset (Fin K), + simpleEvalAt B W (edgeTestGraph Sₗ Sτ) ξ = simpleEvalAt B W (edgeTestGraph Sₗ Sτ) ξ' + +/-- Full simple-equivalence yields the test-graph interface. -/ +theorem TestEvalEq.of_tupleEquivSimple {T : ℕ} {B : Fin T → Fin T → ℝ} {W : Fin T → ℝ} + {ξ ξ' : Fin K → Fin T} (h : tupleEquivSimple B W ξ ξ') : TestEvalEq B W ξ ξ' := + ⟨fun S => h 1 (starTestGraph S), fun Sₗ Sτ => h 2 (edgeTestGraph Sₗ Sτ)⟩ + +/-- **Aligned-Vandermonde extraction** (graph-free core of chunk 3A). If the moment sums of +two profile families `x`, `y` (weighted by `a`, `b`) agree for every exponent vector bounded +by `2·T`, then the `a`-mass and `b`-mass over each profile level set agree. The combined index +`Fin T ⊕ Fin T` turns the equality into a single multivariate Vandermonde cancellation +(`Graphon.CaiGovorov.multivariate_vandermonde_class_sums_zero`). + +NB the exponent bound is `2·T`, not `T+1`: the combined index has `2T` points, and with only +`T+1` moments the statement is already false at `T = 2` (3 equations cannot pin a signed measure +on 4 points). This matches Cai–Govorov's range `0 ≤ k_j < 2m`. -/ +theorem aligned_moments_class_balance {T : ℕ} + (x y : Fin T → (Fin T → ℝ)) (a b : Fin T → ℝ) + (hmom : ∀ k : Fin T → ℕ, (∀ j, k j < 2 * T) → + ∑ t, a t * ∏ j, (x t j) ^ k j = ∑ t, b t * ∏ j, (y t j) ^ k j) + (z : Fin T → ℝ) : + ∑ t ∈ univ.filter (fun t => x t = z), a t + = ∑ t ∈ univ.filter (fun t => y t = z), b t := by classical - have := Finset.card_le_univ (rangeFinset φ) - simpa [Fintype.card_fin] using this + set bb : (Fin T ⊕ Fin T) → Fin T → ℝ := Sum.elim x y with hbb + set aa : (Fin T ⊕ Fin T) → ℝ := Sum.elim a (fun t => - b t) with haa + have hcard : Fintype.card (Fin T ⊕ Fin T) = 2 * T := by + rw [Fintype.card_sum, Fintype.card_fin, two_mul] + have hmoments : ∀ ℓ : Fin T → ℕ, (∀ j, ℓ j < Fintype.card (Fin T ⊕ Fin T)) → + ∑ i, aa i * ∏ j, bb i j ^ ℓ j = 0 := by + intro ℓ hℓ + have hb : ∀ j, ℓ j < 2 * T := fun j => hcard ▸ hℓ j + rw [Fintype.sum_sum_type] + simp only [hbb, haa, Sum.elim_inl, Sum.elim_inr] + rw [hmom ℓ hb, ← Finset.sum_add_distrib] + exact Finset.sum_eq_zero fun t _ => by ring + have key := CaiGovorov.multivariate_vandermonde_class_sums_zero bb aa hmoments z + rw [Finset.sum_filter, Fintype.sum_sum_type] at key + simp only [hbb, haa, Sum.elim_inl, Sum.elim_inr, ← Finset.sum_filter] at key + have hneg : ∑ t ∈ univ.filter (fun t => y t = z), -b t + = -∑ t ∈ univ.filter (fun t => y t = z), b t := Finset.sum_neg_distrib b + rw [hneg] at key + linarith -lemma rangeFinset_snoc {T k : ℕ} (φ : Fin k → Fin T) (a : Fin T) : - rangeFinset (Fin.snoc φ a : Fin (k + 1) → Fin T) = - insert a (rangeFinset φ) := by +/-- **Bounded-exponent aligned-Vandermonde extraction.** The bounded analogue of +`aligned_moments_class_balance`: an explicit per-coordinate distinct-value bound `N` replaces the +implicit cardinality `|ι|`, and the cancellation runs through the bounded multivariate Vandermonde +(`Graphon.CaiGovorov.multivariate_vandermonde_class_sums_zero_of_bound`). The combined index has at +most `2·N` distinct values per coordinate, matching the exponent range `0 ≤ k_c < 2·N`. -/ +theorem aligned_moments_class_balance_of_bound {ι : Type*} [Fintype ι] {s : ℕ} + (x y : ι → (Fin s → ℝ)) (a b : ι → ℝ) (N : ℕ) + (hNx : ∀ c, (univ.image (fun i => x i c)).card ≤ N) + (hNy : ∀ c, (univ.image (fun i => y i c)).card ≤ N) + (hmom : ∀ k : Fin s → ℕ, (∀ c, k c < 2 * N) → + ∑ i, a i * ∏ c, (x i c) ^ k c = ∑ i, b i * ∏ c, (y i c) ^ k c) + (z : Fin s → ℝ) : + ∑ i ∈ univ.filter (fun i => x i = z), a i + = ∑ i ∈ univ.filter (fun i => y i = z), b i := by classical - ext x - simp only [rangeFinset, Finset.mem_image, Finset.mem_univ, true_and, - Finset.mem_insert] + set bb : (ι ⊕ ι) → Fin s → ℝ := Sum.elim x y with hbb + set aa : (ι ⊕ ι) → ℝ := Sum.elim a (fun i => - b i) with haa + have hbound : ∀ c, (univ.image (fun p => bb p c)).card ≤ 2 * N := by + intro c + have hsub : univ.image (fun p => bb p c) + ⊆ (univ.image (fun i => x i c)) ∪ (univ.image (fun i => y i c)) := by + rw [Finset.image_subset_iff] + rintro (i | i) _ + · simp only [hbb, Sum.elim_inl] + exact Finset.mem_union_left _ (Finset.mem_image_of_mem _ (mem_univ i)) + · simp only [hbb, Sum.elim_inr] + exact Finset.mem_union_right _ (Finset.mem_image_of_mem _ (mem_univ i)) + calc (univ.image (fun p => bb p c)).card + ≤ ((univ.image (fun i => x i c)) ∪ (univ.image (fun i => y i c))).card := + Finset.card_le_card hsub + _ ≤ (univ.image (fun i => x i c)).card + (univ.image (fun i => y i c)).card := + Finset.card_union_le _ _ + _ ≤ N + N := Nat.add_le_add (hNx c) (hNy c) + _ = 2 * N := (two_mul N).symm + have hmoments : ∀ ℓ : Fin s → ℕ, (∀ c, ℓ c < 2 * N) → + ∑ p, aa p * ∏ c, bb p c ^ ℓ c = 0 := by + intro ℓ hb + rw [Fintype.sum_sum_type] + simp only [hbb, haa, Sum.elim_inl, Sum.elim_inr] + rw [hmom ℓ hb, ← Finset.sum_add_distrib] + exact Finset.sum_eq_zero fun i _ => by ring + have key := CaiGovorov.multivariate_vandermonde_class_sums_zero_of_bound bb aa (2 * N) + hbound hmoments z + rw [Finset.sum_filter, Fintype.sum_sum_type] at key + simp only [hbb, haa, Sum.elim_inl, Sum.elim_inr, ← Finset.sum_filter] at key + have hneg : ∑ i ∈ univ.filter (fun i => y i = z), -b i + = -∑ i ∈ univ.filter (fun i => y i = z), b i := Finset.sum_neg_distrib b + rw [hneg] at key + linarith + +/-- Profile-balance specialization: with `x t = B · t` (the profile/column of `t`), +`y t = B (s ·) t`, and weights `a = b = W`, the aligned moments force the `W`-mass over each +profile level set to match. -/ +theorem aligned_star_moments_profile_balance {T : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (s : Fin T → Fin T) + (haligned : ∀ k : Fin T → ℕ, (∀ j, k j < 2 * T) → + ∑ t, W t * ∏ j, (B j t) ^ k j = ∑ t, W t * ∏ j, (B (s j) t) ^ k j) + (z : Fin T → ℝ) : + ∑ t ∈ univ.filter (fun t => (fun j => B j t) = z), W t + = ∑ t ∈ univ.filter (fun t => (fun j => B (s j) t) = z), W t := + aligned_moments_class_balance (fun t j => B j t) (fun t j => B (s j) t) W W haligned z + +/-- **Weight balance.** Twin-freeness collapses the left profile level set of `t` to the +singleton `{t}`, so the aligned Vandermonde output is exactly `W t = ∑_{u : B·t = B(s·)u} W u`. -/ +theorem aligned_star_moments_weight_balance {T : ℕ} (B : Fin T → Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (s : Fin T → Fin T) + (haligned : ∀ k : Fin T → ℕ, (∀ j, k j < 2 * T) → + ∑ t, W t * ∏ j, (B j t) ^ k j = ∑ t, W t * ∏ j, (B (s j) t) ^ k j) + (t : Fin T) : + W t = ∑ u ∈ univ.filter (fun u => ∀ j, B j t = B (s j) u), W u := by + have hbal := aligned_star_moments_profile_balance B W s haligned (fun j => B j t) + have hsingle : (univ.filter (fun t' => (fun j => B j t') = fun j => B j t)) = {t} := by + ext t' + simp only [Finset.mem_filter, Finset.mem_univ, true_and, Finset.mem_singleton] + constructor + · intro hprof + by_contra hne + refine htwin t' t hne ?_ + funext j + rw [hB t' j, hB t j] + exact congrFun hprof j + · rintro rfl; rfl + rw [hsingle, Finset.sum_singleton] at hbal + rw [hbal] + refine Finset.sum_congr ?_ (fun _ _ => rfl) + apply Finset.filter_congr + intro u _ constructor - · rintro ⟨i, hi⟩ - by_cases h : (i : ℕ) < k - · refine Or.inr ⟨⟨i, h⟩, ?_⟩ - rw [show i = (⟨i, h⟩ : Fin k).castSucc from Fin.ext rfl, - Fin.snoc_castSucc] at hi - exact hi - · have hi_last : i = Fin.last k := by - apply Fin.ext - have := i.isLt - simp [Fin.val_last] - omega - subst hi_last - rw [Fin.snoc_last] at hi - exact Or.inl hi.symm - · rintro (rfl | ⟨i, rfl⟩) - · exact ⟨Fin.last k, Fin.snoc_last (α := fun _ => Fin T) _ _⟩ - · refine ⟨i.castSucc, ?_⟩ - exact Fin.snoc_castSucc (α := fun _ => Fin T) a φ i + · intro h j; exact (congrFun h j).symm + · intro h; funext j; exact (h j).symm + +/-- **Support.** From weight balance and positivity, every host vertex `t` is matched: there is a +`u` with `B j t = B (s j) u` for all `j`. (The Vandermonde engine builds the matching.) -/ +theorem aligned_star_moments_support {T : ℕ} (B : Fin T → Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) + (htwin : ∀ i j, i ≠ j → B i ≠ B j) (s : Fin T → Fin T) + (haligned : ∀ k : Fin T → ℕ, (∀ j, k j < 2 * T) → + ∑ t, W t * ∏ j, (B j t) ^ k j = ∑ t, W t * ∏ j, (B (s j) t) ^ k j) + (t : Fin T) : + ∃ u, ∀ j, B j t = B (s j) u := by + have hbal := aligned_star_moments_weight_balance B hB W htwin s haligned t + have hne : (univ.filter (fun u => ∀ j, B j t = B (s j) u)).Nonempty := by + rw [Finset.nonempty_iff_ne_empty] + intro hempty + rw [hempty, Finset.sum_empty] at hbal + exact (hW t).ne' hbal + obtain ⟨u, hu⟩ := hne + rw [Finset.mem_filter] at hu + exact ⟨u, hu.2⟩ + +/-! ### Chunk 3A.2: pigeonhole and the preliminary map `s` -/ + +/-- **Pigeonhole.** Super-surjectivity gives, inside each `ξ`-fibre over `j`, a subset `J` of +size `≥ 2T` on which `ξ'` is constant (value `s_j`). (`ξ'` takes ≤ T values on the fibre of +size `≥ 2T²`, so some value is hit `≥ 2T` times.) -/ +theorem exists_large_const_image_subset {T : ℕ} (ξ ξ' : Fin K → Fin T) + (hξ : SuperSurjective ξ) (j : Fin T) : + ∃ (s_j : Fin T) (J : Finset (Fin K)), + J ⊆ univ.filter (fun i => ξ i = j) ∧ 2 * T ≤ J.card ∧ (∀ i ∈ J, ξ' i = s_j) := by + classical + have hmaps : ∀ i ∈ univ.filter (fun i => ξ i = j), ξ' i ∈ (univ : Finset (Fin T)) := + fun i _ => mem_univ _ + have hcard : (univ : Finset (Fin T)).card * (2 * T) + ≤ (univ.filter (fun i => ξ i = j)).card := by + rw [Finset.card_univ, Fintype.card_fin] + calc T * (2 * T) = 2 * T * T := by ring + _ ≤ (univ.filter (fun i => ξ i = j)).card := hξ j + obtain ⟨s_j, _, hsj⟩ := + Finset.exists_le_card_fiber_of_mul_le_card_of_maps_to hmaps ⟨j, mem_univ j⟩ hcard + exact ⟨s_j, (univ.filter (fun i => ξ i = j)).filter (fun i => ξ' i = s_j), + Finset.filter_subset _ _, hsj, fun i hi => (Finset.mem_filter.mp hi).2⟩ + +/-- The preliminary Cai–Govorov map `s : Fin T → Fin T`: the constant `ξ'`-value on a large +subset of each `ξ`-fibre. -/ +noncomputable def superMap {T : ℕ} (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (j : Fin T) : + Fin T := + (exists_large_const_image_subset ξ ξ' hξ j).choose + +/-- The chosen large `ξ'`-constant subset of the `ξ`-fibre over `j`. -/ +noncomputable def superFiberSubset {T : ℕ} (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) + (j : Fin T) : Finset (Fin K) := + (exists_large_const_image_subset ξ ξ' hξ j).choose_spec.choose + +theorem superFiberSubset_subset {T : ℕ} (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) + (j : Fin T) : superFiberSubset ξ ξ' hξ j ⊆ univ.filter (fun i => ξ i = j) := + (exists_large_const_image_subset ξ ξ' hξ j).choose_spec.choose_spec.1 + +theorem superFiberSubset_card {T : ℕ} (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) + (j : Fin T) : 2 * T ≤ (superFiberSubset ξ ξ' hξ j).card := + (exists_large_const_image_subset ξ ξ' hξ j).choose_spec.choose_spec.2.1 + +theorem superFiberSubset_mem_left {T : ℕ} (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) + (j : Fin T) {i : Fin K} (hi : i ∈ superFiberSubset ξ ξ' hξ j) : ξ i = j := by + have := superFiberSubset_subset ξ ξ' hξ j hi + rw [Finset.mem_filter] at this + exact this.2 + +theorem superFiberSubset_image_const {T : ℕ} (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) + (j : Fin T) : ∀ i ∈ superFiberSubset ξ ξ' hξ j, ξ' i = superMap ξ ξ' hξ j := + (exists_large_const_image_subset ξ ξ' hξ j).choose_spec.choose_spec.2.2 + +/-- Distinct fibres give disjoint chosen subsets (each lies in a distinct `ξ`-fibre). -/ +theorem superFiberSubset_disjoint {T : ℕ} (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) + {j j' : Fin T} (hjj : j ≠ j') : + Disjoint (superFiberSubset ξ ξ' hξ j) (superFiberSubset ξ ξ' hξ j') := by + apply Finset.disjoint_left.mpr + intro i hi hi' + exact hjj ((superFiberSubset_mem_left ξ ξ' hξ j hi).symm.trans + (superFiberSubset_mem_left ξ ξ' hξ j' hi')) + +/-! ### Chunk 3A.3: aligned moments from selected labels -/ + +/-- For any bounded exponent vector `k`, select inside each `ξ`-fibre's distinguished subset a +sub-subset of size exactly `k j`. -/ +theorem exists_exponent_label_set {T : ℕ} (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) + (k : Fin T → ℕ) (hk : ∀ j, k j < 2 * T) : + ∃ Kf : Fin T → Finset (Fin K), + (∀ j, Kf j ⊆ superFiberSubset ξ ξ' hξ j) ∧ (∀ j, (Kf j).card = k j) := by + choose Kf hsub hcard using fun j => + Finset.exists_subset_card_eq (s := superFiberSubset ξ ξ' hξ j) (n := k j) + (lt_of_lt_of_le (hk j) (superFiberSubset_card ξ ξ' hξ j)).le + exact ⟨Kf, hsub, hcard⟩ + +/-- **Aligned-moment bridge.** From the star-test equalities (`TestEvalEq.star`) and +super-surjectivity, the aligned moment identity holds for every bounded exponent vector, with the +right-hand side reindexed by `superMap`. +This consumes the `starTestGraph` closed form: the label set `S = ⋃ⱼ Kⱼ` has `ξ ≡ j` on `Kⱼ` (giving +`(B j t)^{k j}` on the left) and `ξ' ≡ superMap j` on `Kⱼ` (giving `(B (superMap j) t)^{k j}` on the +right) — no injectivity of `superMap` is needed. -/ +theorem aligned_moments_of_testEvalEq_super {T : ℕ} (B : Fin T → Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (ξ ξ' : Fin K → Fin T) + (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : + ∀ k : Fin T → ℕ, (∀ j, k j < 2 * T) → + ∑ t, W t * ∏ j, (B j t) ^ k j + = ∑ t, W t * ∏ j, (B (superMap ξ ξ' hξ j) t) ^ k j := by + intro k hk + classical + obtain ⟨Kf, hKf_sub, hKf_card⟩ := exists_exponent_label_set ξ ξ' hξ k hk + set S := univ.biUnion Kf with hS + have hdisj : Set.PairwiseDisjoint (↑(univ : Finset (Fin T))) Kf := + fun j _ j' _ hjj => Finset.disjoint_of_subset_left (hKf_sub j) + (Finset.disjoint_of_subset_right (hKf_sub j') (superFiberSubset_disjoint ξ ξ' hξ hjj)) + have hLHS : ∀ t, ∏ i ∈ S, B (ξ i) t = ∏ j, (B j t) ^ k j := by + intro t + rw [hS, Finset.prod_biUnion hdisj] + refine Finset.prod_congr rfl fun j _ => ?_ + have hconst : ∏ i ∈ Kf j, B (ξ i) t = ∏ i ∈ Kf j, B j t := + Finset.prod_congr rfl fun i hi => by + rw [superFiberSubset_mem_left ξ ξ' hξ j (hKf_sub j hi)] + rw [hconst, Finset.prod_const, hKf_card j] + have hRHS : ∀ t, ∏ i ∈ S, B (ξ' i) t = ∏ j, (B (superMap ξ ξ' hξ j) t) ^ k j := by + intro t + rw [hS, Finset.prod_biUnion hdisj] + refine Finset.prod_congr rfl fun j _ => ?_ + have hconst : ∏ i ∈ Kf j, B (ξ' i) t = ∏ i ∈ Kf j, B (superMap ξ ξ' hξ j) t := + Finset.prod_congr rfl fun i hi => by + rw [superFiberSubset_image_const ξ ξ' hξ j i (hKf_sub j hi)] + rw [hconst, Finset.prod_const, hKf_card j] + have heq : simpleEvalAt B W (starTestGraph S) ξ = simpleEvalAt B W (starTestGraph S) ξ' := + h.star S + rw [simpleEvalAt_starTestGraph B hB W S ξ, simpleEvalAt_starTestGraph B hB W S ξ'] at heq + calc ∑ t, W t * ∏ j, (B j t) ^ k j + = ∑ t, W t * ∏ i ∈ S, B (ξ i) t := by + refine Finset.sum_congr rfl fun t _ => ?_; rw [hLHS t] + _ = ∑ t, W t * ∏ i ∈ S, B (ξ' i) t := heq + _ = ∑ t, W t * ∏ j, (B (superMap ξ ξ' hξ j) t) ^ k j := by + refine Finset.sum_congr rfl fun t _ => ?_; rw [hRHS t] + +/-- **`superMap` support**: every host vertex `t` is matched +by the preliminary map — there is a `u` with `B j t = B (superMap … j) u` for all `j`. Combines the +aligned-moment bridge with the proved aligned-Vandermonde support lemma. -/ +theorem superMap_support {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (t : Fin T) : + ∃ u, ∀ j, B j t = B (superMap ξ ξ' hξ j) u := + aligned_star_moments_support B hB W hW htwin (superMap ξ ξ' hξ) + (aligned_moments_of_testEvalEq_super B hB W ξ ξ' hξ h) t + +/-! ### Chunk 3A.4: `superMap` is bijective -/ + +/-- **`superMap` is injective.** If `superMap a = superMap b`, then for every `t` the support +witness `u` gives `B a t = B (superMap a) u = B (superMap b) u = B b t`, so the rows `B a`, `B b` +agree; twin-freeness forces `a = b`. (No edge tests needed.) -/ +theorem superMap_injective {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : + Function.Injective (superMap ξ ξ' hξ) := by + intro a b hab + by_contra hne + refine htwin a b hne ?_ + funext t + obtain ⟨u, hu⟩ := superMap_support B hB W hW htwin ξ ξ' hξ h t + rw [hu a, hu b, hab] + +/-- **`superMap` is bijective** (injective endomap of a finite type). -/ +theorem superMap_bijective {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : + Function.Bijective (superMap ξ ξ' hξ) := + Finite.injective_iff_bijective.mp (superMap_injective B hB W hW htwin ξ ξ' hξ h) + +/-- The preliminary map as a permutation of `Fin T`. The orbit-defining automorphism `σ` will be +exactly this permutation (since `ξ' i = superMap (ξ i)` on the selected labels, `σ = superMap`, +not its inverse); edge/weight preservation are established next (3A.5) via `edgeTestGraph`. -/ +noncomputable def superPerm {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : + Equiv.Perm (Fin T) := + Equiv.ofBijective (superMap ξ ξ' hξ) (superMap_bijective B hB W hW htwin ξ ξ' hξ h) + +@[simp] theorem superPerm_apply {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (j : Fin T) : + superPerm B hB W hW htwin ξ ξ' hξ h j = superMap ξ ξ' hξ j := rfl + +/-! ### Chunk 3A.5: aligned edge moments (`edgeTestGraph`) -/ + +/-- Regroup a product over a pairwise-disjoint union `⋃ⱼ Kf j` of a function that is constant +(`= c j`) on each block `Kf j` into `∏ⱼ (c j) ^ (k j)`, where `(Kf j).card = k j`. -/ +private theorem prod_biUnion_const {T : ℕ} {Kf : Fin T → Finset (Fin K)} + (hdisj : Set.PairwiseDisjoint (↑(univ : Finset (Fin T))) Kf) + {f : Fin K → ℝ} {c : Fin T → ℝ} (hc : ∀ j, ∀ i ∈ Kf j, f i = c j) + {k : Fin T → ℕ} (hcard : ∀ j, (Kf j).card = k j) : + ∏ i ∈ univ.biUnion Kf, f i = ∏ j, (c j) ^ k j := by + rw [Finset.prod_biUnion hdisj] + refine Finset.prod_congr rfl fun j _ => ?_ + have hconst : ∏ i ∈ Kf j, f i = ∏ i ∈ Kf j, c j := + Finset.prod_congr rfl fun i hi => hc j i hi + rw [hconst, Finset.prod_const, hcard j] + +/-- **Aligned edge-moment bridge** (pair analogue of `aligned_moments_of_testEvalEq_super`). +From the edge-test equalities (`TestEvalEq.edge`) and super-surjectivity, the aligned +*edge*-moment identity holds for every pair of bounded exponent vectors `k`, `l`, with the +right-hand side reindexed by `superMap`. This +consumes the `edgeTestGraph` closed form: with `Sₗ = ⋃ⱼ Klⱼ`, `Sτ = ⋃ⱼ Ktⱼ` one has `ξ ≡ j` on +each block (giving `(B j ·)^{k j}`/`(B j ·)^{l j}`) and `ξ' ≡ superMap j` (giving the reindexed +right-hand side) — no injectivity of `superMap` is needed. -/ +theorem aligned_edge_moments_of_testEvalEq_super {T : ℕ} (B : Fin T → Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (ξ ξ' : Fin K → Fin T) + (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : + ∀ k l : Fin T → ℕ, (∀ j, k j < 2 * T) → (∀ j, l j < 2 * T) → + ∑ x, ∑ y, W x * W y * B x y * (∏ j, (B j x) ^ k j) * (∏ j, (B j y) ^ l j) + = ∑ x, ∑ y, W x * W y * B x y + * (∏ j, (B (superMap ξ ξ' hξ j) x) ^ k j) * (∏ j, (B (superMap ξ ξ' hξ j) y) ^ l j) := by + intro k l hk hl + classical + obtain ⟨Kl, hKl_sub, hKl_card⟩ := exists_exponent_label_set ξ ξ' hξ k hk + obtain ⟨Kt, hKt_sub, hKt_card⟩ := exists_exponent_label_set ξ ξ' hξ l hl + have hdisj_l : Set.PairwiseDisjoint (↑(univ : Finset (Fin T))) Kl := + fun j _ j' _ hjj => Finset.disjoint_of_subset_left (hKl_sub j) + (Finset.disjoint_of_subset_right (hKl_sub j') (superFiberSubset_disjoint ξ ξ' hξ hjj)) + have hdisj_t : Set.PairwiseDisjoint (↑(univ : Finset (Fin T))) Kt := + fun j _ j' _ hjj => Finset.disjoint_of_subset_left (hKt_sub j) + (Finset.disjoint_of_subset_right (hKt_sub j') (superFiberSubset_disjoint ξ ξ' hξ hjj)) + have hLl : ∀ x, ∏ i ∈ univ.biUnion Kl, B (ξ i) x = ∏ j, (B j x) ^ k j := fun x => + prod_biUnion_const hdisj_l + (fun j i hi => by rw [superFiberSubset_mem_left ξ ξ' hξ j (hKl_sub j hi)]) hKl_card + have hLl' : ∀ x, ∏ i ∈ univ.biUnion Kl, B (ξ' i) x + = ∏ j, (B (superMap ξ ξ' hξ j) x) ^ k j := fun x => + prod_biUnion_const hdisj_l + (fun j i hi => by rw [superFiberSubset_image_const ξ ξ' hξ j i (hKl_sub j hi)]) hKl_card + have hTt : ∀ y, ∏ i ∈ univ.biUnion Kt, B (ξ i) y = ∏ j, (B j y) ^ l j := fun y => + prod_biUnion_const hdisj_t + (fun j i hi => by rw [superFiberSubset_mem_left ξ ξ' hξ j (hKt_sub j hi)]) hKt_card + have hTt' : ∀ y, ∏ i ∈ univ.biUnion Kt, B (ξ' i) y + = ∏ j, (B (superMap ξ ξ' hξ j) y) ^ l j := fun y => + prod_biUnion_const hdisj_t + (fun j i hi => by rw [superFiberSubset_image_const ξ ξ' hξ j i (hKt_sub j hi)]) hKt_card + have heq : simpleEvalAt B W (edgeTestGraph (univ.biUnion Kl) (univ.biUnion Kt)) ξ + = simpleEvalAt B W (edgeTestGraph (univ.biUnion Kl) (univ.biUnion Kt)) ξ' := + h.edge (univ.biUnion Kl) (univ.biUnion Kt) + rw [simpleEvalAt_edgeTestGraph B hB W _ _ ξ, + simpleEvalAt_edgeTestGraph B hB W _ _ ξ'] at heq + calc ∑ x, ∑ y, W x * W y * B x y * (∏ j, (B j x) ^ k j) * (∏ j, (B j y) ^ l j) + = ∑ x, ∑ y, W x * W y * B x y + * (∏ i ∈ univ.biUnion Kl, B (ξ i) x) * (∏ i ∈ univ.biUnion Kt, B (ξ i) y) := by + refine Finset.sum_congr rfl fun x _ => Finset.sum_congr rfl fun y _ => ?_ + rw [hLl x, hTt y] + _ = ∑ x, ∑ y, W x * W y * B x y + * (∏ i ∈ univ.biUnion Kl, B (ξ' i) x) * (∏ i ∈ univ.biUnion Kt, B (ξ' i) y) := heq + _ = ∑ x, ∑ y, W x * W y * B x y + * (∏ j, (B (superMap ξ ξ' hξ j) x) ^ k j) + * (∏ j, (B (superMap ξ ξ' hξ j) y) ^ l j) := by + refine Finset.sum_congr rfl fun x _ => Finset.sum_congr rfl fun y _ => ?_ + rw [hLl' x, hTt' y] + +/-- **Aligned edge-moment pair balance.** Specializing the bounded extraction engine +`aligned_moments_class_balance_of_bound` at `ι = Fin T × Fin T` and coordinate dimension `T + T` +(gluing the two `B`-columns of a pair via `Fin.append`), the aligned edge moments force the +`W·W·B`-mass over each pair of column profiles `(z₁, z₂)` to match between the original labelling and +the `superMap`-reindexed one. -/ +theorem aligned_edge_moments_pair_balance {T : ℕ} (B : Fin T → Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (ξ ξ' : Fin K → Fin T) + (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (z₁ z₂ : Fin T → ℝ) : + ∑ p : Fin T × Fin T, + (if (fun j => B j p.1) = z₁ ∧ (fun j => B j p.2) = z₂ + then W p.1 * W p.2 * B p.1 p.2 else 0) + = ∑ p : Fin T × Fin T, + (if (fun j => B (superMap ξ ξ' hξ j) p.1) = z₁ ∧ + (fun j => B (superMap ξ ξ' hξ j) p.2) = z₂ + then W p.1 * W p.2 * B p.1 p.2 else 0) := by + set x : Fin T × Fin T → (Fin (T + T) → ℝ) := + fun p => Fin.append (fun j => B j p.1) (fun j => B j p.2) with hx + set y : Fin T × Fin T → (Fin (T + T) → ℝ) := + fun p => Fin.append (fun j => B (superMap ξ ξ' hξ j) p.1) + (fun j => B (superMap ξ ξ' hξ j) p.2) with hy + set a : Fin T × Fin T → ℝ := fun p => W p.1 * W p.2 * B p.1 p.2 with ha + -- Per-coordinate distinct-value bound (≤ T) for the left profiles. + have hNx : ∀ c, (univ.image (fun p => x p c)).card ≤ T := by + intro c + refine Fin.addCases (fun j => ?_) (fun j => ?_) c + · have hsub : univ.image (fun p : Fin T × Fin T => x p (Fin.castAdd T j)) + ⊆ univ.image (fun u : Fin T => B j u) := by + intro val hval + rw [mem_image] at hval ⊢ + obtain ⟨p, -, hp⟩ := hval + refine ⟨p.1, mem_univ _, ?_⟩ + rw [← hp]; simp only [hx, Fin.append_left] + calc (univ.image (fun p : Fin T × Fin T => x p (Fin.castAdd T j))).card + ≤ (univ.image (fun u : Fin T => B j u)).card := Finset.card_le_card hsub + _ ≤ (univ : Finset (Fin T)).card := Finset.card_image_le + _ = T := by rw [Finset.card_univ, Fintype.card_fin] + · have hsub : univ.image (fun p : Fin T × Fin T => x p (Fin.natAdd T j)) + ⊆ univ.image (fun u : Fin T => B j u) := by + intro val hval + rw [mem_image] at hval ⊢ + obtain ⟨p, -, hp⟩ := hval + refine ⟨p.2, mem_univ _, ?_⟩ + rw [← hp]; simp only [hx, Fin.append_right] + calc (univ.image (fun p : Fin T × Fin T => x p (Fin.natAdd T j))).card + ≤ (univ.image (fun u : Fin T => B j u)).card := Finset.card_le_card hsub + _ ≤ (univ : Finset (Fin T)).card := Finset.card_image_le + _ = T := by rw [Finset.card_univ, Fintype.card_fin] + have hNy : ∀ c, (univ.image (fun p => y p c)).card ≤ T := by + intro c + refine Fin.addCases (fun j => ?_) (fun j => ?_) c + · have hsub : univ.image (fun p : Fin T × Fin T => y p (Fin.castAdd T j)) + ⊆ univ.image (fun u : Fin T => B (superMap ξ ξ' hξ j) u) := by + intro val hval + rw [mem_image] at hval ⊢ + obtain ⟨p, -, hp⟩ := hval + refine ⟨p.1, mem_univ _, ?_⟩ + rw [← hp]; simp only [hy, Fin.append_left] + calc (univ.image (fun p : Fin T × Fin T => y p (Fin.castAdd T j))).card + ≤ (univ.image (fun u : Fin T => B (superMap ξ ξ' hξ j) u)).card := + Finset.card_le_card hsub + _ ≤ (univ : Finset (Fin T)).card := Finset.card_image_le + _ = T := by rw [Finset.card_univ, Fintype.card_fin] + · have hsub : univ.image (fun p : Fin T × Fin T => y p (Fin.natAdd T j)) + ⊆ univ.image (fun u : Fin T => B (superMap ξ ξ' hξ j) u) := by + intro val hval + rw [mem_image] at hval ⊢ + obtain ⟨p, -, hp⟩ := hval + refine ⟨p.2, mem_univ _, ?_⟩ + rw [← hp]; simp only [hy, Fin.append_right] + calc (univ.image (fun p : Fin T × Fin T => y p (Fin.natAdd T j))).card + ≤ (univ.image (fun u : Fin T => B (superMap ξ ξ' hξ j) u)).card := + Finset.card_le_card hsub + _ ≤ (univ : Finset (Fin T)).card := Finset.card_image_le + _ = T := by rw [Finset.card_univ, Fintype.card_fin] + -- The bounded moment identity, fed by the edge-moment bridge. + have hmom : ∀ k : Fin (T + T) → ℕ, (∀ c, k c < 2 * T) → + ∑ p, a p * ∏ c, (x p c) ^ k c = ∑ p, a p * ∏ c, (y p c) ^ k c := by + intro k hk + have hbridge := aligned_edge_moments_of_testEvalEq_super B hB W ξ ξ' hξ h + (fun j => k (Fin.castAdd T j)) (fun j => k (Fin.natAdd T j)) + (fun j => hk (Fin.castAdd T j)) (fun j => hk (Fin.natAdd T j)) + have hxprod : ∀ p : Fin T × Fin T, ∏ c, (x p c) ^ k c + = (∏ j, (B j p.1) ^ k (Fin.castAdd T j)) * (∏ j, (B j p.2) ^ k (Fin.natAdd T j)) := by + intro p + rw [Fin.prod_univ_add] + congr 1 + · refine Finset.prod_congr rfl (fun i _ => ?_); simp only [hx, Fin.append_left] + · refine Finset.prod_congr rfl (fun i _ => ?_); simp only [hx, Fin.append_right] + have hyprod : ∀ p : Fin T × Fin T, ∏ c, (y p c) ^ k c + = (∏ j, (B (superMap ξ ξ' hξ j) p.1) ^ k (Fin.castAdd T j)) + * (∏ j, (B (superMap ξ ξ' hξ j) p.2) ^ k (Fin.natAdd T j)) := by + intro p + rw [Fin.prod_univ_add] + congr 1 + · refine Finset.prod_congr rfl (fun i _ => ?_); simp only [hy, Fin.append_left] + · refine Finset.prod_congr rfl (fun i _ => ?_); simp only [hy, Fin.append_right] + calc ∑ p, a p * ∏ c, (x p c) ^ k c + = ∑ p : Fin T × Fin T, W p.1 * W p.2 * B p.1 p.2 + * (∏ j, (B j p.1) ^ k (Fin.castAdd T j)) + * (∏ j, (B j p.2) ^ k (Fin.natAdd T j)) := by + refine Finset.sum_congr rfl (fun p _ => ?_) + rw [hxprod p]; simp only [ha]; ring + _ = ∑ p : Fin T × Fin T, W p.1 * W p.2 * B p.1 p.2 + * (∏ j, (B (superMap ξ ξ' hξ j) p.1) ^ k (Fin.castAdd T j)) + * (∏ j, (B (superMap ξ ξ' hξ j) p.2) ^ k (Fin.natAdd T j)) := by + rw [Fintype.sum_prod_type, Fintype.sum_prod_type]; exact hbridge + _ = ∑ p, a p * ∏ c, (y p c) ^ k c := by + refine Finset.sum_congr rfl (fun p _ => ?_) + rw [hyprod p]; simp only [ha]; ring + -- Apply the bounded extraction engine at `z = Fin.append z₁ z₂`. + have key := aligned_moments_class_balance_of_bound x y a a T hNx hNy hmom (Fin.append z₁ z₂) + -- `Fin.append`-injectivity: a glued profile equals `append z₁ z₂` iff its halves are `z₁`, `z₂`. + have happend : ∀ f g : Fin T → ℝ, + (Fin.append f g = Fin.append z₁ z₂) ↔ (f = z₁ ∧ g = z₂) := by + intro f g + constructor + · intro happ + refine ⟨?_, ?_⟩ + · funext j + have hj := congrFun happ (Fin.castAdd T j) + rwa [Fin.append_left, Fin.append_left] at hj + · funext j + have hj := congrFun happ (Fin.natAdd T j) + rwa [Fin.append_right, Fin.append_right] at hj + · rintro ⟨rfl, rfl⟩; rfl + have hfiltL : univ.filter (fun p : Fin T × Fin T => + (fun j => B j p.1) = z₁ ∧ (fun j => B j p.2) = z₂) + = univ.filter (fun p => x p = Fin.append z₁ z₂) := by + refine Finset.filter_congr (fun p _ => ?_) + exact (happend (fun j => B j p.1) (fun j => B j p.2)).symm + have hfiltR : univ.filter (fun p : Fin T × Fin T => + (fun j => B (superMap ξ ξ' hξ j) p.1) = z₁ ∧ + (fun j => B (superMap ξ ξ' hξ j) p.2) = z₂) + = univ.filter (fun p => y p = Fin.append z₁ z₂) := by + refine Finset.filter_congr (fun p _ => ?_) + exact (happend (fun j => B (superMap ξ ξ' hξ j) p.1) + (fun j => B (superMap ξ ξ' hξ j) p.2)).symm + rw [← Finset.sum_filter, ← Finset.sum_filter, hfiltL, hfiltR] + exact key + +/-! ### Chunk 3A.5 steps 2–7: the support-witness map and the weighted automorphism -/ + +/-- The support-witness map `r = superInv`: `r t` is the unique `u` with +`∀ j, B j t = B (superMap j) u`. It turns out to be the orbit automorphism (`= superMap`). -/ +noncomputable def superInv {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (t : Fin T) : + Fin T := + (superMap_support B hB W hW htwin ξ ξ' hξ h t).choose + +theorem superInv_spec {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (t : Fin T) : + ∀ j, B j t = B (superMap ξ ξ' hξ j) (superInv B hB W hW htwin ξ ξ' hξ h t) := + (superMap_support B hB W hW htwin ξ ξ' hξ h t).choose_spec + +theorem superInv_unique {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') {t u : Fin T} + (hu : ∀ j, B j t = B (superMap ξ ξ' hξ j) u) : + u = superInv B hB W hW htwin ξ ξ' hξ h t := by + by_contra hne + refine htwin u (superInv B hB W hW htwin ξ ξ' hξ h t) hne ?_ + funext w + obtain ⟨j, hj⟩ := (superMap_bijective B hB W hW htwin ξ ξ' hξ h).surjective w + rw [← hj, hB u (superMap ξ ξ' hξ j), + hB (superInv B hB W hW htwin ξ ξ' hξ h t) (superMap ξ ξ' hξ j), + ← hu j, superInv_spec B hB W hW htwin ξ ξ' hξ h t j] + +theorem superInv_injective {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : + Function.Injective (superInv B hB W hW htwin ξ ξ' hξ h) := by + intro a b hab + by_contra hne + refine htwin a b hne ?_ + funext j + rw [hB a j, superInv_spec B hB W hW htwin ξ ξ' hξ h a j, hab, + ← superInv_spec B hB W hW htwin ξ ξ' hξ h b j, ← hB b j] + +theorem superInv_bijective {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : + Function.Bijective (superInv B hB W hW htwin ξ ξ' hξ h) := + Finite.injective_iff_bijective.mp (superInv_injective B hB W hW htwin ξ ξ' hξ h) + +/-- **Weight preservation for `superInv`.** The support fibre of `t` is the singleton +`{superInv t}`, so weight balance gives `W (superInv t) = W t`. -/ +theorem superInv_preserves_W {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (t : Fin T) : + W (superInv B hB W hW htwin ξ ξ' hξ h t) = W t := by + have hbal := aligned_star_moments_weight_balance B hB W htwin (superMap ξ ξ' hξ) + (aligned_moments_of_testEvalEq_super B hB W ξ ξ' hξ h) t + have hfib : (univ.filter (fun u => ∀ j, B j t = B (superMap ξ ξ' hξ j) u)) + = {superInv B hB W hW htwin ξ ξ' hξ h t} := by + ext u + simp only [Finset.mem_filter, Finset.mem_univ, true_and, Finset.mem_singleton] + exact ⟨fun hu => superInv_unique B hB W hW htwin ξ ξ' hξ h hu, + fun hu => hu ▸ superInv_spec B hB W hW htwin ξ ξ' hξ h t⟩ + rw [hfib, Finset.sum_singleton] at hbal + exact hbal.symm + +/-- **Edge preservation for `superInv`.** Plugging the pair balance at `z₁ = B·a`, `z₂ = B·b`: +the left fibre is `{(a,b)}` (twin-free) and the right fibre is `{(superInv a, superInv b)}` +(`superInv_unique`); positivity cancels the weights. So `superInv` preserves `B`. -/ +theorem superInv_preserves_B {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (a b : Fin T) : + B (superInv B hB W hW htwin ξ ξ' hξ h a) (superInv B hB W hW htwin ξ ξ' hξ h b) = B a b := by + classical + have hcol : ∀ u v : Fin T, (fun j => B j u) = (fun j => B j v) → u = v := by + intro u v huv + by_contra hne + refine htwin u v hne ?_ + funext j + have hj := congrFun huv j + rw [hB u j, hB v j]; exact hj + have hLHS : (∑ p : Fin T × Fin T, + if (fun j => B j p.1) = (fun j => B j a) ∧ (fun j => B j p.2) = (fun j => B j b) + then W p.1 * W p.2 * B p.1 p.2 else 0) = W a * W b * B a b := by + rw [Finset.sum_eq_single (a, b)] + · simp + · intro p _ hp + have hfalse : ¬ ((fun j => B j p.1) = (fun j => B j a) ∧ + (fun j => B j p.2) = (fun j => B j b)) := by + rintro ⟨hp1, hp2⟩ + exact hp (Prod.ext (hcol p.1 a hp1) (hcol p.2 b hp2)) + rw [if_neg hfalse] + · intro hc; exact absurd (Finset.mem_univ _) hc + have hRHS : (∑ p : Fin T × Fin T, + if (fun j => B (superMap ξ ξ' hξ j) p.1) = (fun j => B j a) ∧ + (fun j => B (superMap ξ ξ' hξ j) p.2) = (fun j => B j b) + then W p.1 * W p.2 * B p.1 p.2 else 0) + = W (superInv B hB W hW htwin ξ ξ' hξ h a) * W (superInv B hB W hW htwin ξ ξ' hξ h b) + * B (superInv B hB W hW htwin ξ ξ' hξ h a) (superInv B hB W hW htwin ξ ξ' hξ h b) := by + rw [Finset.sum_eq_single (superInv B hB W hW htwin ξ ξ' hξ h a, + superInv B hB W hW htwin ξ ξ' hξ h b)] + · rw [if_pos] + exact ⟨funext fun j => (superInv_spec B hB W hW htwin ξ ξ' hξ h a j).symm, + funext fun j => (superInv_spec B hB W hW htwin ξ ξ' hξ h b j).symm⟩ + · intro p _ hp + have hfalse : ¬ ((fun j => B (superMap ξ ξ' hξ j) p.1) = (fun j => B j a) ∧ + (fun j => B (superMap ξ ξ' hξ j) p.2) = (fun j => B j b)) := by + rintro ⟨hp1, hp2⟩ + exact hp (Prod.ext + (superInv_unique B hB W hW htwin ξ ξ' hξ h (fun j => (congrFun hp1 j).symm)) + (superInv_unique B hB W hW htwin ξ ξ' hξ h (fun j => (congrFun hp2 j).symm))) + rw [if_neg hfalse] + · intro hc; exact absurd (Finset.mem_univ _) hc + have hpb := aligned_edge_moments_pair_balance B hB W ξ ξ' hξ h (fun j => B j a) (fun j => B j b) + rw [hLHS, hRHS, superInv_preserves_W B hB W hW htwin ξ ξ' hξ h a, + superInv_preserves_W B hB W hW htwin ξ ξ' hξ h b] at hpb + have hpos : W a * W b ≠ 0 := ne_of_gt (mul_pos (hW a) (hW b)) + exact (mul_left_cancel₀ hpos hpb).symm + +/-- **`superInv = superMap`.** Support gives `B a b = B (superMap a) (superInv b)`, and edge +preservation gives `B a b = B (superInv a) (superInv b)`; comparing over all columns +(`superInv` surjective) and applying twin-freeness identifies the two maps. -/ +theorem superInv_eq_superMap {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : + superInv B hB W hW htwin ξ ξ' hξ h = superMap ξ ξ' hξ := by + funext a + have hrow : B (superMap ξ ξ' hξ a) = B (superInv B hB W hW htwin ξ ξ' hξ h a) := by + funext w + obtain ⟨b, hb⟩ := (superInv_bijective B hB W hW htwin ξ ξ' hξ h).surjective w + rw [← hb, ← superInv_spec B hB W hW htwin ξ ξ' hξ h b a] + exact (superInv_preserves_B B hB W hW htwin ξ ξ' hξ h a b).symm + by_contra hne + exact (htwin (superMap ξ ξ' hξ a) (superInv B hB W hW htwin ξ ξ' hξ h a) + (fun heq => hne heq.symm)) hrow + +/-! ### Chunk 3A.5 exports: superMap is a weighted automorphism -/ + +theorem superMap_preserves_B {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (a b : Fin T) : + B (superMap ξ ξ' hξ a) (superMap ξ ξ' hξ b) = B a b := by + rw [← superInv_eq_superMap B hB W hW htwin ξ ξ' hξ h] + exact superInv_preserves_B B hB W hW htwin ξ ξ' hξ h a b + +theorem superMap_preserves_W {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (a : Fin T) : + W (superMap ξ ξ' hξ a) = W a := by + rw [← superInv_eq_superMap B hB W hW htwin ξ ξ' hξ h] + exact superInv_preserves_W B hB W hW htwin ξ ξ' hξ h a + +/-- **The super-surjective orbit automorphism.** `superPerm` is a weighted automorphism of +`(B, W)` — the certified output of chunk 3A.5. -/ +theorem superMap_isWeightedAutomorphism {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : + IsWeightedAutomorphism B W (superPerm B hB W hW htwin ξ ξ' hξ h) := by + refine ⟨fun i => ?_, fun i j => ?_⟩ + · rw [superPerm_apply]; exact superMap_preserves_W B hB W hW htwin ξ ξ' hξ h i + · rw [superPerm_apply, superPerm_apply]; exact superMap_preserves_B B hB W hW htwin ξ ξ' hξ h i j + +/-- **One-extra-label raw moment identity.** Attaching a single distinguished label `i₀` to a +star-test graph and selecting disjoint exponent blocks inside the (large) super-fibres minus +`{i₀}`, the `tupleEquivSimple` equality on the star graph yields the raw moment identity with one +extra `B (ξ i₀) t` / `B (ξ' i₀) t` factor. Reindexing the right-hand side by the orbit permutation +`superMap` (which preserves `W` and `B`) turns `B (ξ' i₀) t` into `B (ξ' i₀) (superMap t)` while +restoring the aligned exponent product `∏ⱼ (B j t) ^ k j`. -/ +theorem one_extra_label_moment {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') (i₀ : Fin K) + (k : Fin T → ℕ) (hk : ∀ j, k j < T) : + ∑ t, W t * B (ξ i₀) t * ∏ j, (B j t) ^ k j + = ∑ t, W t * B (ξ' i₀) (superMap ξ ξ' hξ t) * ∏ j, (B j t) ^ k j := by + classical + -- Each super-fibre minus `{i₀}` is still large enough to hold `k j` labels. + have hbound : ∀ j, k j ≤ (superFiberSubset ξ ξ' hξ j \ {i₀}).card := by + intro j + have h1 := superFiberSubset_card ξ ξ' hξ j + have h2 : (superFiberSubset ξ ξ' hξ j).card + ≤ (superFiberSubset ξ ξ' hξ j \ {i₀}).card + ({i₀} : Finset (Fin K)).card := + Finset.card_le_card_sdiff_add_card + have h3 : ({i₀} : Finset (Fin K)).card = 1 := Finset.card_singleton i₀ + have h4 := hk j + omega + choose Kf hKf_sub hKf_card using fun j => + Finset.exists_subset_card_eq (s := superFiberSubset ξ ξ' hξ j \ {i₀}) (n := k j) (hbound j) + have hKf_sub' : ∀ j, Kf j ⊆ superFiberSubset ξ ξ' hξ j := + fun j => (hKf_sub j).trans Finset.sdiff_subset + have hi₀ : i₀ ∉ univ.biUnion Kf := by + intro hmem + rw [Finset.mem_biUnion] at hmem + obtain ⟨j, -, hj⟩ := hmem + have hj' := hKf_sub j hj + rw [Finset.mem_sdiff] at hj' + exact hj'.2 (Finset.mem_singleton_self i₀) + have hdisj : Set.PairwiseDisjoint (↑(univ : Finset (Fin T))) Kf := + fun j _ j' _ hjj => Finset.disjoint_of_subset_left (hKf_sub' j) + (Finset.disjoint_of_subset_right (hKf_sub' j') (superFiberSubset_disjoint ξ ξ' hξ hjj)) + have hLHS : ∀ t, ∏ i ∈ univ.biUnion Kf, B (ξ i) t = ∏ j, (B j t) ^ k j := fun t => + prod_biUnion_const hdisj + (fun j i hi => by rw [superFiberSubset_mem_left ξ ξ' hξ j (hKf_sub' j hi)]) hKf_card + have hRHS : ∀ t, ∏ i ∈ univ.biUnion Kf, B (ξ' i) t + = ∏ j, (B (superMap ξ ξ' hξ j) t) ^ k j := fun t => + prod_biUnion_const hdisj + (fun j i hi => by rw [superFiberSubset_image_const ξ ξ' hξ j i (hKf_sub' j hi)]) hKf_card + -- The star-test equality on `S = insert i₀ (⋃ⱼ Kf j)`. + have heq : simpleEvalAt B W (starTestGraph (insert i₀ (univ.biUnion Kf))) ξ + = simpleEvalAt B W (starTestGraph (insert i₀ (univ.biUnion Kf))) ξ' := + h.star (insert i₀ (univ.biUnion Kf)) + rw [simpleEvalAt_starTestGraph B hB W _ ξ, simpleEvalAt_starTestGraph B hB W _ ξ'] at heq + -- Phase A: raw moment identity with one extra `i₀` factor. + have phaseA : ∑ t, W t * B (ξ i₀) t * ∏ j, (B j t) ^ k j + = ∑ t, W t * B (ξ' i₀) t * ∏ j, (B (superMap ξ ξ' hξ j) t) ^ k j := by + calc ∑ t, W t * B (ξ i₀) t * ∏ j, (B j t) ^ k j + = ∑ t, W t * ∏ i ∈ insert i₀ (univ.biUnion Kf), B (ξ i) t := by + refine Finset.sum_congr rfl fun t _ => ?_ + rw [Finset.prod_insert hi₀, hLHS t]; ring + _ = ∑ t, W t * ∏ i ∈ insert i₀ (univ.biUnion Kf), B (ξ' i) t := heq + _ = ∑ t, W t * B (ξ' i₀) t * ∏ j, (B (superMap ξ ξ' hξ j) t) ^ k j := by + refine Finset.sum_congr rfl fun t _ => ?_ + rw [Finset.prod_insert hi₀, hRHS t]; ring + -- Phase B: reindex the right-hand side by the orbit permutation `superMap`. + have phaseB : ∑ t, W t * B (ξ' i₀) t * ∏ j, (B (superMap ξ ξ' hξ j) t) ^ k j + = ∑ t, W t * B (ξ' i₀) (superMap ξ ξ' hξ t) * ∏ j, (B j t) ^ k j := by + rw [← Equiv.sum_comp (superPerm B hB W hW htwin ξ ξ' hξ h) + (fun t => W t * B (ξ' i₀) t * ∏ j, (B (superMap ξ ξ' hξ j) t) ^ k j)] + refine Finset.sum_congr rfl fun u _ => ?_ + simp only [superPerm_apply] + rw [superMap_preserves_W B hB W hW htwin ξ ξ' hξ h u] + congr 1 + refine Finset.prod_congr rfl fun j _ => ?_ + rw [superMap_preserves_B B hB W hW htwin ξ ξ' hξ h j u] + exact phaseA.trans phaseB + +/-- **Full-fibre reconciliation (3A.6).** Every label `i` maps under `ξ'` to `superMap (ξ i)` — +not only the labels in the selected subsets. The one-extra-label moment identity feeds the +(graph-free) Vandermonde class-sum over `Fin T`: twin-freeness makes each profile fibre a +singleton, positivity gives `B (ξ i₀) t = B (ξ' i₀) (superMap t)` for all `t`, and applying the +automorphism property identifies `ξ' i₀ = superMap (ξ i₀)`. -/ +theorem superMap_agrees_on_all_labels {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) (h : TestEvalEq B W ξ ξ') : + ∀ i : Fin K, ξ' i = superMap ξ ξ' hξ (ξ i) := by + intro i₀ + have hmom : ∀ k : Fin T → ℕ, (∀ j, k j < T) → + ∑ t, (W t * (B (ξ i₀) t - B (ξ' i₀) (superMap ξ ξ' hξ t))) * ∏ j, (B j t) ^ k j = 0 := by + intro k hk + have heq := one_extra_label_moment B hB W hW htwin ξ ξ' hξ h i₀ k hk + have hsplit : ∑ t, (W t * (B (ξ i₀) t - B (ξ' i₀) (superMap ξ ξ' hξ t))) * ∏ j, (B j t) ^ k j + = (∑ t, W t * B (ξ i₀) t * ∏ j, (B j t) ^ k j) + - (∑ t, W t * B (ξ' i₀) (superMap ξ ξ' hξ t) * ∏ j, (B j t) ^ k j) := by + rw [← Finset.sum_sub_distrib] + refine Finset.sum_congr rfl (fun t _ => ?_); ring + rw [hsplit, heq, sub_self] + have hstar : ∀ t, B (ξ i₀) t = B (ξ' i₀) (superMap ξ ξ' hξ t) := by + intro t₀ + have hclass := CaiGovorov.multivariate_vandermonde_class_sums_zero + (fun t => fun j => B j t) + (fun t => W t * (B (ξ i₀) t - B (ξ' i₀) (superMap ξ ξ' hξ t))) + (fun ℓ hℓ => hmom ℓ (fun j => Fintype.card_fin T ▸ hℓ j)) (fun j => B j t₀) + have hfilt : (univ.filter (fun t => (fun j => B j t) = (fun j => B j t₀))) = {t₀} := by + ext t + simp only [Finset.mem_filter, Finset.mem_univ, true_and, Finset.mem_singleton] + constructor + · intro hcol + by_contra hne + refine htwin t t₀ hne ?_ + funext j; have hj := congrFun hcol j; rw [hB t j, hB t₀ j]; exact hj + · rintro rfl; rfl + rw [hfilt, Finset.sum_singleton] at hclass + rcases mul_eq_zero.mp hclass with h0 | h0 + · exact absurd h0 (ne_of_gt (hW t₀)) + · exact sub_eq_zero.mp h0 + by_contra hne + refine htwin (superMap ξ ξ' hξ (ξ i₀)) (ξ' i₀) (fun heq => hne heq.symm) ?_ + funext u + obtain ⟨t, ht⟩ := (superMap_bijective B hB W hW htwin ξ ξ' hξ h).surjective u + rw [← ht, superMap_preserves_B B hB W hW htwin ξ ξ' hξ h (ξ i₀) t] + exact hstar t + +/-- **Chunk 3A core — the super-surjective Cai–Govorov orbit separation, moment form.** If `ξ` +is super-surjective and the star/edge test evaluations agree (`TestEvalEq`), then `ξ'` is in the +weighted-automorphism orbit of `ξ`. Combines `superMap_isWeightedAutomorphism` with the +full-fibre reconciliation. The `TestEvalEq` interface (rather than full `tupleEquivSimple`) is +what the eq. (10) descent step can supply for matched extensions. -/ +theorem testEvalEq_implies_orbit_super {T : ℕ} (B : Fin T → Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) + (htwin : ∀ i j, i ≠ j → B i ≠ B j) (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) + (h : TestEvalEq B W ξ ξ') : + tupleOrbitRel B W ξ ξ' := + ⟨superPerm B hB W hW htwin ξ ξ' hξ h, + superMap_isWeightedAutomorphism B hB W hW htwin ξ ξ' hξ h, + fun i => by rw [superPerm_apply]; exact superMap_agrees_on_all_labels B hB W hW htwin ξ ξ' hξ h i⟩ + +/-- **Chunk 3A — the super-surjective Cai–Govorov orbit separation.** If `ξ` is super-surjective +and `ξ ≈ ξ'` (equal simple-graph evaluations), then `ξ'` is in the weighted-automorphism orbit of +`ξ`. Wrapper around the moment-form core `testEvalEq_implies_orbit_super`. -/ +theorem tupleEquivSimple_implies_orbit_super {T : ℕ} (B : Fin T → Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) + (htwin : ∀ i j, i ≠ j → B i ≠ B j) (ξ ξ' : Fin K → Fin T) (hξ : SuperSurjective ξ) + (h : tupleEquivSimple B W ξ ξ') : + tupleOrbitRel B W ξ ξ' := + testEvalEq_implies_orbit_super B hB W hW htwin ξ ξ' hξ (.of_tupleEquivSimple h) + +/-! ## Chunk 3B.1b: iterating the trace over the extra labels + +The trace operator `MultiLabeledGraph.trace` folds the *last* label into a new unlabeled +vertex. Iterating it `m` times folds the last `m` labels of a `(K+m)`-labeled multigraph, +yielding a `K`-labeled multigraph on `n + m` unlabeled vertices. The closure identity +`multiLabeledEvalK_sum_last_label` then accumulates into a `W`-weighted sum over the `m` +folded label values (`ρ : Fin m → Fin T`). -/ + +/-- **Unlabeled re-cast of a multigraph.** Reindex the vertex space `Fin (b + K)` of a target +multigraph onto `Fin (a + K)` through the val-preserving `Fin.cast`, when `a = b`. Used to +reconcile `(n + 1) + m` with `n + (m + 1)` in `traceIterExtraLabels`. -/ +def MultiLabeledGraph.castUnlabeled {K a b : ℕ} (hab : a = b) (M : MultiLabeledGraph K a) : + MultiLabeledGraph K b where + mult e := M.mult (Sym2.map (Fin.cast (by rw [hab])) e) + multNoLoop x := by rw [Sym2.map_mk]; exact M.multNoLoop _ -/-- **Deficit strictly decreases on snoc with a fresh element.** +/-- The multigraph evaluation is invariant under the val-preserving unlabeled re-cast. -/ +theorem multiLabeledEvalK_castUnlabeled {T K a b : ℕ} (hab : a = b) + (M : MultiLabeledGraph K a) (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) (φ : Fin K → Fin T) : + multiLabeledEvalK K b (M.castUnlabeled hab) B W φ = multiLabeledEvalK K a M B W φ := by + subst hab + have hmult : ∀ e : Sym2 (Fin (a + K)), (M.castUnlabeled (rfl : a = a)).mult e = M.mult e := by + intro e + refine congrArg M.mult ?_ + refine Sym2.ind (fun x y => ?_) e + rw [Sym2.map_mk, Fin.cast_eq_self, Fin.cast_eq_self] + simp only [multiLabeledEvalK] + refine Finset.sum_congr rfl fun σ _ => ?_ + congr 1 + refine Finset.prod_congr rfl fun e _ => ?_ + rw [hmult e] + +/-- **Iterated trace** over the last `m` labels. Folds the last `m` labels of a `(K+m)`-labeled +multigraph into `m` new unlabeled vertices, yielding a `K`-labeled multigraph on `n + m` +unlabeled vertices. Recurses on `m`, threading `MultiLabeledGraph.trace` and reconciling the +`(n+1)+m = n+(m+1)` vertex-count mismatch with `castUnlabeled`. -/ +def traceIterExtraLabels {K : ℕ} : ∀ {n : ℕ} (m : ℕ), + MultiLabeledGraph (K + m) n → MultiLabeledGraph K (n + m) + | _, 0, M => M + | n, m + 1, M => + (traceIterExtraLabels m M.trace).castUnlabeled (by omega : (n + 1) + m = n + (m + 1)) + +/-- **Eq. (10) core** (3B.1 pillar). Unpinning the last `m` labels: summing the `(K+m)`-labeled +evaluation over the extra label values `ρ`, weighted by `∏ⱼ W(ρ j)`, equals the `K`-labeled +evaluation of the `m`-fold trace `traceIterExtraLabels m M`. Induction on `m`, peeling the last +label each step via `multiLabeledEvalK_sum_last_label`. Purely multigraph-side; bridged to simple +graphs by `traceIterExtraLabels_ofSimple_eq` and fed into `extension_sum_identity`. -/ +theorem multiLabeledEvalK_sum_extra_labels {K m n T : ℕ} + (M : MultiLabeledGraph (K + m) n) (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (φ : Fin K → Fin T) : + ∑ ρ : Fin m → Fin T, + (∏ j : Fin m, W (ρ j)) * multiLabeledEvalK (K + m) n M B W (Fin.append φ ρ) + = multiLabeledEvalK K (n + m) (traceIterExtraLabels m M) B W φ := by + induction m generalizing n with + | zero => + rw [Fintype.sum_unique, Fin.prod_univ_zero, one_mul] + have happ : Fin.append φ (default : Fin 0 → Fin T) = φ := by + rw [Fin.append_right_nil φ _ rfl] + funext v + exact congrArg φ (Fin.ext rfl) + rw [happ] + rfl + | succ m ih => + have hcast : multiLabeledEvalK K (n + (m + 1)) (traceIterExtraLabels (m + 1) M) B W φ + = multiLabeledEvalK K ((n + 1) + m) (traceIterExtraLabels m M.trace) B W φ := by + rw [show traceIterExtraLabels (m + 1) M + = (traceIterExtraLabels m M.trace).castUnlabeled + (by omega : (n + 1) + m = n + (m + 1)) from rfl] + rw [multiLabeledEvalK_castUnlabeled] + rw [hcast, ← ih M.trace] + -- Normalize the label count `K + (m+1)` to `K + m + 1` to align with `sum_last_label`. + show ∑ ρ : Fin (m + 1) → Fin T, + (∏ j : Fin (m + 1), W (ρ j)) * + multiLabeledEvalK (K + m + 1) n M B W (@Fin.append K (m + 1) (Fin T) φ ρ) + = ∑ ρ : Fin m → Fin T, + (∏ j : Fin m, W (ρ j)) * + multiLabeledEvalK (K + m) (n + 1) M.trace B W (Fin.append φ ρ) + -- Split the last folded label `x` off `ρ = Fin.snoc ρ₀ x`. + have hsnocEq : ∀ p : Fin T × (Fin m → Fin T), + (Fin.snocEquiv (fun _ : Fin (m + 1) => Fin T)) p = Fin.snoc p.2 p.1 := + fun p => funext fun x => Fin.snocEquiv_apply (fun _ : Fin (m + 1) => Fin T) p x + rw [← Equiv.sum_comp (Fin.snocEquiv (fun _ : Fin (m + 1) => Fin T)), + Fintype.sum_prod_type] + simp only [hsnocEq] + rw [Finset.sum_comm] + refine Finset.sum_congr rfl fun ρ₀ _ => ?_ + simp only [Fin.prod_univ_castSucc, Fin.snoc_castSucc, Fin.snoc_last, Fin.append_snoc] + have hlast : ∑ x : Fin T, + W x * multiLabeledEvalK (K + m + 1) n M B W (Fin.snoc (Fin.append φ ρ₀) x) + = multiLabeledEvalK (K + m) (n + 1) M.trace B W (Fin.append φ ρ₀) := + multiLabeledEvalK_sum_last_label M B hB W (Fin.append φ ρ₀) + rw [← hlast, Finset.mul_sum] + refine Finset.sum_congr rfl fun x _ => ?_ + ring + +/-! ## Chunk 3B.1c step 2: the trace-to-simple eval bridge -/ + +/-- Local (public) connector: `simpleEvalAt` is `multiLabeledEvalK` on `ofSimple` +(the file-local analog of the private `simpleEvalAt_eq_multi` in `Lovasz`). -/ +theorem simpleEvalAt_eq_multi' {T K n : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (F : SimpleGraph (Fin (n + K))) [DecidableRel F.Adj] (ξ : Fin K → Fin T) : + simpleEvalAt B W F ξ = multiLabeledEvalK K n (MultiLabeledGraph.ofSimple F) B W ξ := by + rw [multiLabeledEvalK_ofSimple]; rfl -If `a ∉ range φ`, then `deficit (Fin.snoc φ a) < deficit φ`. This is the -key well-founded measure decrease that drives Lovász's -"extend-and-recurse" argument in `tupleEquivSimple_implies_orbit`. -/ -lemma deficit_lt_of_not_mem {T k : ℕ} (φ : Fin k → Fin T) (a : Fin T) - (ha : a ∉ rangeFinset φ) : - deficit (Fin.snoc φ a : Fin (k + 1) → Fin T) < deficit φ := by - classical - simp only [deficit, rangeFinset_snoc] - rw [Finset.card_insert_of_notMem ha] - -- a ∉ range and a ∈ univ ⟹ range.card < |univ| = T. - have hstrict : (rangeFinset φ).card < T := by - have hsub : rangeFinset φ ⊂ Finset.univ := by - refine ⟨Finset.subset_univ _, ?_⟩ - intro hsuper - exact ha (hsuper (Finset.mem_univ a)) - have := Finset.card_lt_card hsub - simpa [Fintype.card_fin] using this - omega +/-- **Unlabel-extras simple graph.** Comap of `G` along the val-preserving cast +`Fin ((n + m) + K) → Fin (n + (K + m))`, moving the last `m` labels back into unlabeled +position. The trace bridge (`traceIterExtraLabels_ofSimple_eq`) identifies +`traceIterExtraLabels m (ofSimple G)` with `ofSimple (unlabelExtras G)`. -/ +def unlabelExtras {K m n : ℕ} (G : SimpleGraph (Fin (n + (K + m)))) : + SimpleGraph (Fin ((n + m) + K)) := + SimpleGraph.comap (Fin.cast (by omega : (n + m) + K = n + (K + m))) G + +noncomputable instance {K m n} (G : SimpleGraph (Fin (n + (K + m)))) [DecidableRel G.Adj] : + DecidableRel (unlabelExtras G).Adj := Classical.decRel _ + +/-- **Net-cast lemma** (the crux). The iterated `trace`/`castUnlabeled` reindexing collapses to +a single val-preserving `Fin.cast`: reading a multiplicity of `traceIterExtraLabels m M` at `e` +equals reading `M`'s multiplicity at the cast of `e`. -/ +theorem traceIterExtraLabels_mult {K : ℕ} : ∀ {n : ℕ} (m : ℕ) (M : MultiLabeledGraph (K + m) n) + (e : Sym2 (Fin ((n + m) + K))), + (traceIterExtraLabels m M).mult e + = M.mult (Sym2.map (Fin.cast (by omega : (n + m) + K = n + (K + m))) e) := by + intro n m + induction m generalizing n with + | zero => + intro M e + refine e.ind fun x y => ?_ + show M.mult s(x, y) = M.mult (Sym2.map (Fin.cast _) s(x, y)) + rw [Sym2.map_mk] + congr 1 + | succ m ih => + intro M e + rw [show traceIterExtraLabels (m + 1) M + = (traceIterExtraLabels m M.trace).castUnlabeled + (by omega : (n + 1) + m = n + (m + 1)) from rfl] + refine e.ind fun x y => ?_ + show (traceIterExtraLabels m M.trace).mult (Sym2.map (Fin.cast _) s(x, y)) + = M.mult (Sym2.map (Fin.cast _) s(x, y)) + rw [ih M.trace] + show M.mult (Sym2.map (Fin.cast _) (Sym2.map (Fin.cast _) (Sym2.map (Fin.cast _) s(x, y)))) + = M.mult (Sym2.map (Fin.cast _) s(x, y)) + rw [Sym2.map_mk, Sym2.map_mk, Sym2.map_mk, Sym2.map_mk] + congr 1 -/-- Surjectivity reads off `rangeFinset = univ`. -/ -lemma surjective_iff_rangeFinset_eq_univ {T k : ℕ} (φ : Fin k → Fin T) : - Function.Surjective φ ↔ rangeFinset φ = Finset.univ := by +/-- **Graph bridge.** Iterating the trace over the extra labels of an `ofSimple` multigraph +yields the `ofSimple` multigraph of the unlabel-extras simple graph. -/ +theorem traceIterExtraLabels_ofSimple_eq {K m n : ℕ} (G : SimpleGraph (Fin (n + (K + m)))) + [DecidableRel G.Adj] : + traceIterExtraLabels m (MultiLabeledGraph.ofSimple G) + = MultiLabeledGraph.ofSimple (unlabelExtras G) := by + have hiff : ∀ e : Sym2 (Fin ((n + m) + K)), + (Sym2.map (Fin.cast (by omega : (n + m) + K = n + (K + m))) e) ∈ G.edgeFinset + ↔ e ∈ (unlabelExtras G).edgeFinset := by + refine fun e => e.ind fun u v => ?_ + rw [Sym2.map_mk] + simp only [SimpleGraph.mem_edgeFinset, SimpleGraph.mem_edgeSet, unlabelExtras, + SimpleGraph.comap_adj] + have hmult : ∀ e, (traceIterExtraLabels m (MultiLabeledGraph.ofSimple G)).mult e + = (MultiLabeledGraph.ofSimple (unlabelExtras G)).mult e := by + intro e + rw [traceIterExtraLabels_mult] + show (if (Sym2.map (Fin.cast _) e) ∈ G.edgeFinset then (1 : ℕ) else 0) + = (if e ∈ (unlabelExtras G).edgeFinset then (1 : ℕ) else 0) + rw [if_congr (hiff e) rfl rfl] + rcases hG : MultiLabeledGraph.ofSimple (unlabelExtras G) with ⟨mu, mnu⟩ + rcases hT : traceIterExtraLabels m (MultiLabeledGraph.ofSimple G) with ⟨mt, mnt⟩ + show MultiLabeledGraph.mk _ _ = MultiLabeledGraph.mk _ _ + congr 1 + funext e + have := hmult e + rw [hG, hT] at this + exact this + +/-- **Eval bridge** (the step-2 target). Evaluating the traced `ofSimple G` multigraph equals the +simple-graph evaluation of the unlabel-extras graph. -/ +theorem traceIterExtraLabels_ofSimple_eval {T K m n : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (G : SimpleGraph (Fin (n + (K + m)))) [DecidableRel G.Adj] (ξ : Fin K → Fin T) : + multiLabeledEvalK K (n + m) (traceIterExtraLabels m (MultiLabeledGraph.ofSimple G)) B W ξ + = simpleEvalAt B W (unlabelExtras G) ξ := by + rw [traceIterExtraLabels_ofSimple_eq, ← simpleEvalAt_eq_multi'] + +/-! ### Chunk 3B.1c steps 3–5: extension family (extras-last) and equation (10) -/ + +/-- `μ : Fin (K + m) → Fin T` extends `ξ` if it agrees with `ξ` on the first `K` labels. +(`abbrev` so the subtype `{μ // ExtendsFin ξ μ}` gets `DecidablePred`/`Fintype` automatically.) -/ +abbrev ExtendsFin {T m : ℕ} (ξ : Fin K → Fin T) (μ : Fin (K + m) → Fin T) : Prop := + ∀ i : Fin K, μ (Fin.castAdd m i) = ξ i + +/-- The `W`-product over the `m` extra label values of `μ`. -/ +noncomputable def extensionWeightFin {T m : ℕ} (W : Fin T → ℝ) (μ : Fin (K + m) → Fin T) : ℝ := + ∏ j : Fin m, W (μ (Fin.natAdd K j)) + +/-- Extensions of `ξ` are exactly `Fin.append ξ ρ` for the free extra-value tuple `ρ`. -/ +def appendExtensionEquiv {T m : ℕ} (ξ : Fin K → Fin T) : + (Fin m → Fin T) ≃ {μ : Fin (K + m) → Fin T // ExtendsFin ξ μ} where + toFun ρ := ⟨Fin.append ξ ρ, by intro i; rw [Fin.append_left]⟩ + invFun μ := fun j => μ.1 (Fin.natAdd K j) + left_inv ρ := by + funext j + show Fin.append ξ ρ (Fin.natAdd K j) = ρ j + rw [Fin.append_right] + right_inv μ := by + apply Subtype.ext + funext k + show Fin.append ξ (fun j => μ.1 (Fin.natAdd K j)) k = μ.1 k + refine Fin.addCases (fun i => ?_) (fun j => ?_) k + · rw [Fin.append_left]; exact (μ.2 i).symm + · rw [Fin.append_right] + +theorem sum_extensions_eq_sum_rho {T m n : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (G : SimpleGraph (Fin (n + (K + m)))) [DecidableRel G.Adj] (ξ : Fin K → Fin T) : + ∑ μ : {μ : Fin (K + m) → Fin T // ExtendsFin ξ μ}, + extensionWeightFin W μ.1 * simpleEvalAt B W G μ.1 + = ∑ ρ : Fin m → Fin T, (∏ j, W (ρ j)) * simpleEvalAt B W G (Fin.append ξ ρ) := by + rw [← Equiv.sum_comp (appendExtensionEquiv ξ) + (fun μ => extensionWeightFin W μ.1 * simpleEvalAt B W G μ.1)] + refine Finset.sum_congr rfl (fun ρ _ => ?_) + show extensionWeightFin W (Fin.append ξ ρ) * simpleEvalAt B W G (Fin.append ξ ρ) + = (∏ j, W (ρ j)) * simpleEvalAt B W G (Fin.append ξ ρ) + congr 1 + unfold extensionWeightFin + exact Finset.prod_congr rfl (fun j _ => by rw [Fin.append_right]) + +/-- **Extension-sum collapse** (one side of eq. (10)). The weighted sum of `simpleEvalAt G` +over ALL extensions of `ζ` collapses to a single simple evaluation at `ζ` — of the +unlabel-extras graph. Extracted from `extension_sum_identity`; reused by the rank-residue +annihilator argument (chunk 5B). -/ +theorem sum_extensions_eval {T m n : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (G : SimpleGraph (Fin (n + (K + m)))) [DecidableRel G.Adj] + (ζ : Fin K → Fin T) : + ∑ μ : {μ : Fin (K + m) → Fin T // ExtendsFin ζ μ}, + extensionWeightFin W μ.1 * simpleEvalAt B W G μ.1 + = simpleEvalAt B W (unlabelExtras G) ζ := by + rw [sum_extensions_eq_sum_rho B W G ζ, + show (∑ ρ : Fin m → Fin T, (∏ j, W (ρ j)) * simpleEvalAt B W G (Fin.append ζ ρ)) + = ∑ ρ : Fin m → Fin T, (∏ j, W (ρ j)) * + multiLabeledEvalK (K + m) n (MultiLabeledGraph.ofSimple G) B W (Fin.append ζ ρ) from + Finset.sum_congr rfl (fun ρ _ => by rw [simpleEvalAt_eq_multi']), + multiLabeledEvalK_sum_extra_labels (MultiLabeledGraph.ofSimple G) B hB W ζ, + traceIterExtraLabels_ofSimple_eval B W G ζ] + +/-- **Equation (10)** (Cai–Govorov, the extension-family sum identity). Simple-equivalence at +level `K` lifts to an equality of extension-family sums at level `K + m`: unpinning the extra +labels (trace-to-simple bridge) reduces both sides to `simpleEvalAt` of `unlabelExtras G`, where +`h` applies. -/ +theorem extension_sum_identity {T m n : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} (h : tupleEquivSimple B W ξ ξ') + (G : SimpleGraph (Fin (n + (K + m)))) [DecidableRel G.Adj] : + ∑ μ : {μ : Fin (K + m) → Fin T // ExtendsFin ξ μ}, + extensionWeightFin W μ.1 * simpleEvalAt B W G μ.1 + = ∑ ν : {ν : Fin (K + m) → Fin T // ExtendsFin ξ' ν}, + extensionWeightFin W ν.1 * simpleEvalAt B W G ν.1 := by + rw [sum_extensions_eval B hB W G ξ, sum_extensions_eval B hB W G ξ'] + exact h (n + m) (unlabelExtras G) + +/-! ### Chunk 3B.2a: the concrete super-surjective extension of `ξ` (extras-last) -/ + +/-- The extra-value tuple that maps `2*T²` labels to each host vertex. Uses the product equiv +`Fin T × Fin (2*T²) ≃ Fin (T * (2*T²))`: label `j` maps to the vertex component of `j`. -/ +noncomputable def coverExtra (T : ℕ) : Fin (T * (2 * T ^ 2)) → Fin T := + fun j => (finProdFinEquiv.symm j).1 + +/-- The canonical super-surjective extension of `ξ`: keep `ξ` on the first `K` labels, then add +`T * (2*T²)` extra labels covering every host vertex `2*T²` times. -/ +noncomputable def superExt {T : ℕ} (ξ : Fin K → Fin T) : + Fin (K + T * (2 * T ^ 2)) → Fin T := + Fin.append ξ (coverExtra T) + +theorem superExt_extends {T : ℕ} (ξ : Fin K → Fin T) : + ExtendsFin ξ (superExt ξ) := by + intro i; rw [superExt, Fin.append_left] + +theorem coverExtra_fiber_card {T : ℕ} (v : Fin T) : + (univ.filter (fun j => coverExtra T j = v)).card = 2 * T ^ 2 := by classical - refine ⟨fun hsurj => ?_, fun heq y => ?_⟩ - · apply Finset.eq_univ_iff_forall.mpr - intro y - obtain ⟨i, hi⟩ := hsurj y - exact Finset.mem_image.mpr ⟨i, Finset.mem_univ _, hi⟩ - · have : y ∈ rangeFinset φ := heq ▸ Finset.mem_univ y - obtain ⟨i, _, hi⟩ := Finset.mem_image.mp this - exact ⟨i, hi⟩ + have hg_inj : Function.Injective + (fun c : Fin (2 * T ^ 2) => finProdFinEquiv (v, c)) := by + intro c₁ c₂ h + exact congrArg Prod.snd (finProdFinEquiv.injective h) + have hset : univ.filter (fun j => coverExtra T j = v) + = univ.image (fun c : Fin (2 * T ^ 2) => finProdFinEquiv (v, c)) := by + ext j + simp only [Finset.mem_filter, Finset.mem_univ, true_and, Finset.mem_image] + constructor + · intro hj + simp only [coverExtra] at hj + refine ⟨(finProdFinEquiv.symm j).2, ?_⟩ + rw [← hj] + exact finProdFinEquiv.apply_symm_apply j + · rintro ⟨c, rfl⟩ + simp only [coverExtra, Equiv.symm_apply_apply] + rw [hset, Finset.card_image_of_injective _ hg_inj, Finset.card_univ, Fintype.card_fin] + +theorem superExt_superSurjective {T : ℕ} (ξ : Fin K → Fin T) : + SuperSurjective (superExt ξ) := by + intro v + classical + have hsub : (univ.filter (fun j => coverExtra T j = v)).image (Fin.natAdd K) + ⊆ univ.filter (fun i => superExt ξ i = v) := by + intro i hi + rw [Finset.mem_image] at hi + obtain ⟨j, hj, rfl⟩ := hi + rw [Finset.mem_filter] at hj ⊢ + refine ⟨Finset.mem_univ _, ?_⟩ + show superExt ξ (Fin.natAdd K j) = v + rw [superExt, Fin.append_right] + exact hj.2 + have hcard : ((univ.filter (fun j => coverExtra T j = v)).image (Fin.natAdd K)).card + = 2 * T ^ 2 := by + rw [Finset.card_image_of_injective _ (Fin.natAdd_injective (T * (2 * T ^ 2)) K), + coverExtra_fiber_card] + have hle : 2 * T ^ 2 ≤ (univ.filter (fun i => superExt ξ i = v)).card := by + have hcle := Finset.card_le_card hsub + rwa [hcard] at hcle + calc 2 * T * T = 2 * T ^ 2 := by ring + _ ≤ _ := hle + +/-! ### Chunk 3B.2b: separation (contrapositive of the super-surjective case) -/ + +/-- **Separation at the super-surjective reference** (contrapositive of +`tupleEquivSimple_implies_orbit_super` at `η = superExt ξ`): any extension `μ` not in the +weighted-automorphism orbit of `superExt ξ` is *not* simple-equivalent to it — some simple +graph separates them. + +NB not on the live descent path: the paper's plan built a finite separating family from this +oracle, but the formalized descent (chunk 4F, `exists_matching_extension`) runs the +class-balance Vandermonde directly and never consumes this statement. Kept as the documented +separation form of the super-case. -/ +theorem not_tupleEquivSimple_of_not_orbit {T : ℕ} (B : Fin T → Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) + (htwin : ∀ i j, i ≠ j → B i ≠ B j) (ξ : Fin K → Fin T) + (μ : Fin (K + T * (2 * T ^ 2)) → Fin T) + (hnotorbit : ¬ tupleOrbitRel B W (superExt ξ) μ) : + ¬ tupleEquivSimple B W (superExt ξ) μ := + fun heq => hnotorbit (tupleEquivSimple_implies_orbit_super B hB W hW htwin (superExt ξ) μ + (superExt_superSurjective ξ) heq) + +/-! ## Chunk 4B: the mult ≤ 1 bridge — multigraphs that are secretly simple + +Products of test evaluations are realized (chunks 4C/4D) as `glue`s of `ofSimple` test +multigraphs. Since the test graphs have no label-label edges, the glued multiplicities never +exceed 1, and such a multigraph converts back to an honest `SimpleGraph` with the same +evaluation. This section provides the invariants (`SimpleMult`, `NoLabelPairs`), the +conversion (`toSimple` with `ofSimple_toSimple`/`simpleEvalAt_toSimple`), and preservation of +the invariants under `glue` — where label-label pairs are the ONLY place multiplicities add, +which is exactly what `NoLabelPairs` forbids. -/ + +/-- All multiplicities are at most 1 — the multigraph is (the `ofSimple` image of) a simple +graph. -/ +def MultiLabeledGraph.SimpleMult {K n : ℕ} (M : MultiLabeledGraph K n) : Prop := + ∀ e, M.mult e ≤ 1 + +/-- No edge joins two labeled vertices (labels sit at values `< K`). Under `glue`, label-label +pairs are the only place multiplicities ADD; this invariant keeps the glue multiplicity-safe. -/ +def MultiLabeledGraph.NoLabelPairs {K n : ℕ} (M : MultiLabeledGraph K n) : Prop := + ∀ a b : Fin (n + K), (a : ℕ) < K → (b : ℕ) < K → M.mult s(a, b) = 0 + +/-- Convert a multigraph back to a simple graph: edges are the multiplicity-1 pairs. Inverse to +`MultiLabeledGraph.ofSimple` on multiplicity-≤-1 multigraphs (`ofSimple_toSimple`). -/ +noncomputable def MultiLabeledGraph.toSimple {K n : ℕ} (M : MultiLabeledGraph K n) : + SimpleGraph (Fin (n + K)) := + SimpleGraph.fromEdgeSet {e | M.mult e = 1} + +noncomputable instance {K n : ℕ} (M : MultiLabeledGraph K n) : DecidableRel M.toSimple.Adj := + Classical.decRel _ + +theorem MultiLabeledGraph.mem_toSimple_edgeFinset {K n : ℕ} (M : MultiLabeledGraph K n) + (e : Sym2 (Fin (n + K))) : e ∈ M.toSimple.edgeFinset ↔ M.mult e = 1 := by + refine Sym2.ind (fun x y => ?_) e + simp only [SimpleGraph.mem_edgeFinset, MultiLabeledGraph.toSimple, + SimpleGraph.edgeSet_fromEdgeSet, Set.mem_sdiff, Set.mem_setOf_eq, Sym2.mem_diagSet, + Sym2.mk_isDiag_iff] + refine ⟨fun h => h.1, fun he => ⟨he, fun hxy => ?_⟩⟩ + subst hxy + rw [M.multNoLoop x] at he + exact one_ne_zero he.symm + +/-- Multigraphs with equal multiplicity functions are equal (`multNoLoop` is a proposition). -/ +theorem MultiLabeledGraph.ext' {K n : ℕ} {M₁ M₂ : MultiLabeledGraph K n} + (h : M₁.mult = M₂.mult) : M₁ = M₂ := by + cases M₁; cases M₂; subst h; rfl + +/-- `toSimple` is a section of `ofSimple` on multiplicity-≤-1 multigraphs. -/ +theorem MultiLabeledGraph.ofSimple_toSimple {K n : ℕ} (M : MultiLabeledGraph K n) + (hM : M.SimpleMult) : MultiLabeledGraph.ofSimple M.toSimple = M := by + refine MultiLabeledGraph.ext' (funext fun e => ?_) + show (if e ∈ M.toSimple.edgeFinset then 1 else 0) = M.mult e + by_cases he : e ∈ M.toSimple.edgeFinset + · rw [if_pos he, (M.mem_toSimple_edgeFinset e).mp he] + · rw [if_neg he] + have h1 : M.mult e ≠ 1 := fun h1 => he ((M.mem_toSimple_edgeFinset e).mpr h1) + have h2 := hM e + omega + +/-- Evaluating the simple graph `M.toSimple` agrees with the multigraph evaluation of `M`, +provided all multiplicities are ≤ 1. -/ +theorem simpleEvalAt_toSimple {T K n : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (M : MultiLabeledGraph K n) (hM : M.SimpleMult) (ξ : Fin K → Fin T) : + simpleEvalAt B W M.toSimple ξ = multiLabeledEvalK K n M B W ξ := by + rw [simpleEvalAt_eq_multi', M.ofSimple_toSimple hM] + +/-! ### Invariant suppliers: `ofSimple`, the test graphs, and `empty` -/ + +theorem MultiLabeledGraph.ofSimple_simpleMult {K n : ℕ} (F : SimpleGraph (Fin (n + K))) + [DecidableRel F.Adj] : (MultiLabeledGraph.ofSimple F).SimpleMult := fun e => by + show (if e ∈ F.edgeFinset then 1 else 0) ≤ 1 + split_ifs <;> omega + +theorem MultiLabeledGraph.ofSimple_noLabelPairs {K n : ℕ} (F : SimpleGraph (Fin (n + K))) + [DecidableRel F.Adj] + (hF : ∀ a b : Fin (n + K), (a : ℕ) < K → (b : ℕ) < K → s(a, b) ∉ F.edgeFinset) : + (MultiLabeledGraph.ofSimple F).NoLabelPairs := fun a b ha hb => by + show (if s(a, b) ∈ F.edgeFinset then 1 else 0) = 0 + rw [if_neg (hF a b ha hb)] + +theorem MultiLabeledGraph.empty_simpleMult {K n : ℕ} : + (MultiLabeledGraph.empty K n).SimpleMult := fun _ => Nat.zero_le 1 + +theorem MultiLabeledGraph.empty_noLabelPairs {K n : ℕ} : + (MultiLabeledGraph.empty K n).NoLabelPairs := fun _ _ _ _ => rfl + +/-- Every `starTestGraph` edge touches the unlabeled vertex (value `K`), so there are no +label-label edges. -/ +theorem starTestGraph_noLabelPairs (S : Finset (Fin K)) : + (MultiLabeledGraph.ofSimple (starTestGraph S)).NoLabelPairs := by + refine MultiLabeledGraph.ofSimple_noLabelPairs _ fun a b ha hb hmem => ?_ + rw [starTestGraph_edgeFinset, Finset.mem_image] at hmem + obtain ⟨i, -, heq⟩ := hmem + rw [Sym2.eq_iff] at heq + rcases heq with ⟨-, h2⟩ | ⟨-, h2⟩ <;> + (have := congrArg Fin.val h2; simp only [unlVertex] at this; omega) + +/-- Every `edgeTestGraph` edge touches an unlabeled vertex (values `K`, `K+1`), so there are no +label-label edges. -/ +theorem edgeTestGraph_noLabelPairs (Sₗ Sτ : Finset (Fin K)) : + (MultiLabeledGraph.ofSimple (edgeTestGraph Sₗ Sτ)).NoLabelPairs := by + refine MultiLabeledGraph.ofSimple_noLabelPairs _ fun a b ha hb hmem => ?_ + rw [edgeTestGraph_edgeFinset, Finset.mem_insert, Finset.mem_union] at hmem + rcases hmem with heq | hmem | hmem + · rw [Sym2.eq_iff] at heq + rcases heq with ⟨h1, -⟩ | ⟨h1, -⟩ <;> + (have := congrArg Fin.val h1; simp only [unlVertex0, unlVertex1] at this; omega) + all_goals + rw [Finset.mem_image] at hmem + obtain ⟨i, -, heq⟩ := hmem + rw [Sym2.eq_iff] at heq + rcases heq with ⟨-, h2⟩ | ⟨-, h2⟩ <;> + (have := congrArg Fin.val h2; simp only [unlVertex0, unlVertex1] at this; omega) + +/-! ### `glueCast` characterizations and invariant preservation under `glue` -/ + +theorem glueCast₁_some_val {K n₁ n₂ : ℕ} {v : Fin ((n₁ + n₂) + K)} {u : Fin (n₁ + K)} + (h : glueCast₁ K n₁ n₂ v = some u) : (u : ℕ) = (v : ℕ) ∧ (v : ℕ) < n₁ + K := by + unfold glueCast₁ at h + split_ifs at h with hv + exact ⟨congrArg Fin.val (Option.some.inj h).symm, hv⟩ + +theorem glueCast₂_some_val {K n₁ n₂ : ℕ} {v : Fin ((n₁ + n₂) + K)} {u : Fin (n₂ + K)} + (h : glueCast₂ K n₁ n₂ v = some u) : + ((v : ℕ) < K ∧ (u : ℕ) = (v : ℕ)) ∨ (n₁ + K ≤ (v : ℕ) ∧ (u : ℕ) = (v : ℕ) - n₁) := by + unfold glueCast₂ at h + split_ifs at h with h1 h2 + · exact Or.inl ⟨h1, congrArg Fin.val (Option.some.inj h).symm⟩ + · exact Or.inr ⟨h2, congrArg Fin.val (Option.some.inj h).symm⟩ + +theorem glueCast₁_ne_none_of_lt {K n₁ n₂ : ℕ} {v : Fin ((n₁ + n₂) + K)} + (hv : (v : ℕ) < n₁ + K) : glueCast₁ K n₁ n₂ v ≠ none := by + unfold glueCast₁; rw [dif_pos hv]; simp + +theorem glueCast₂_ne_none_of_lt {K n₁ n₂ : ℕ} {v : Fin ((n₁ + n₂) + K)} + (hv : (v : ℕ) < K) : glueCast₂ K n₁ n₂ v ≠ none := by + unfold glueCast₂; rw [dif_pos hv]; simp + +/-- `glue` preserves multiplicity ≤ 1, given `NoLabelPairs` on the second factor: the only +pairs where the two `glue` contributions can BOTH be nonzero are label-label pairs, and there +the `M₂` contribution vanishes. -/ +theorem MultiLabeledGraph.glue_simpleMult {K n₁ n₂ : ℕ} + {M₁ : MultiLabeledGraph K n₁} {M₂ : MultiLabeledGraph K n₂} + (h₁ : M₁.SimpleMult) (h₂ : M₂.SimpleMult) (hlp₂ : M₂.NoLabelPairs) : + (M₁.glue M₂).SimpleMult := by + intro e + refine Sym2.ind (fun a b => ?_) e + rw [MultiLabeledGraph.glue_mult_pair] + rcases hc1a : glueCast₁ K n₁ n₂ a with _ | u₁a <;> + rcases hc1b : glueCast₁ K n₁ n₂ b with _ | u₁b <;> + rcases hc2a : glueCast₂ K n₁ n₂ a with _ | u₂a <;> + rcases hc2b : glueCast₂ K n₁ n₂ b with _ | u₂b <;> + dsimp only <;> + first + | omega + | simpa using h₁ s(u₁a, u₁b) + | simpa using h₂ s(u₂a, u₂b) + | (obtain ⟨hu1a, hva⟩ := glueCast₁_some_val hc1a + obtain ⟨hu1b, hvb⟩ := glueCast₁_some_val hc1b + rcases glueCast₂_some_val hc2a with ⟨haK, hu2a⟩ | ⟨haK, -⟩ + · rcases glueCast₂_some_val hc2b with ⟨hbK, hu2b⟩ | ⟨hbK, -⟩ + · rw [hlp₂ u₂a u₂b (by omega) (by omega)] + simpa using h₁ s(u₁a, u₁b) + · omega + · omega) + +/-- `glue` preserves the no-label-pairs invariant. -/ +theorem MultiLabeledGraph.glue_noLabelPairs {K n₁ n₂ : ℕ} + {M₁ : MultiLabeledGraph K n₁} {M₂ : MultiLabeledGraph K n₂} + (h₁ : M₁.NoLabelPairs) (h₂ : M₂.NoLabelPairs) : (M₁.glue M₂).NoLabelPairs := by + intro a b ha hb + rw [MultiLabeledGraph.glue_mult_pair] + rcases hc1a : glueCast₁ K n₁ n₂ a with _ | u₁a + · exact absurd hc1a (glueCast₁_ne_none_of_lt (by omega)) + rcases hc1b : glueCast₁ K n₁ n₂ b with _ | u₁b + · exact absurd hc1b (glueCast₁_ne_none_of_lt (by omega)) + rcases hc2a : glueCast₂ K n₁ n₂ a with _ | u₂a + · exact absurd hc2a (glueCast₂_ne_none_of_lt ha) + rcases hc2b : glueCast₂ K n₁ n₂ b with _ | u₂b + · exact absurd hc2b (glueCast₂_ne_none_of_lt hb) + dsimp only + obtain ⟨hu1a, -⟩ := glueCast₁_some_val hc1a + obtain ⟨hu1b, -⟩ := glueCast₁_some_val hc1b + rcases glueCast₂_some_val hc2a with ⟨-, hu2a⟩ | ⟨haK, -⟩ + · rcases glueCast₂_some_val hc2b with ⟨-, hu2b⟩ | ⟨hbK, -⟩ + · rw [h₁ u₁a u₁b (by omega) (by omega), h₂ u₂a u₂b (by omega) (by omega)] + · omega + · omega + +/-! ## Chunk 4C: gluing lists of multigraphs — the iterated product law + +`glueList` folds a list of `K`-labeled multigraphs (of varying unlabeled sizes, packaged in a +sigma type) into one by repeated disjoint gluing; its evaluation is the product of the +component evaluations (iterating `multiLabeledEvalK_glue`), and it inherits the chunk-4B +invariants from its components. -/ + +/-- Sigma-packaged disjoint glue of two multigraphs with arbitrary unlabeled sizes. -/ +def glueSigma (p q : Σ n, MultiLabeledGraph K n) : Σ n, MultiLabeledGraph K n := + ⟨p.1 + q.1, p.2.glue q.2⟩ + +/-- Fold a list of multigraphs into one by repeated disjoint gluing (empty multigraph base). -/ +def glueList (l : List (Σ n, MultiLabeledGraph K n)) : Σ n, MultiLabeledGraph K n := + l.foldr glueSigma ⟨0, MultiLabeledGraph.empty K 0⟩ -/-- Surjectivity iff deficit = 0. -/ -lemma deficit_eq_zero_iff_surjective {T k : ℕ} (φ : Fin k → Fin T) : - deficit φ = 0 ↔ Function.Surjective φ := by - classical - rw [surjective_iff_rangeFinset_eq_univ, deficit] - have hle : (rangeFinset φ).card ≤ T := rangeFinset_card_le φ +/-- **Iterated glue factorization**: the evaluation of `glueList l` is the product of the +component evaluations. -/ +theorem multiLabeledEvalK_glueList {T : ℕ} (B : Fin T → Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) + (l : List (Σ n, MultiLabeledGraph K n)) (μ : Fin K → Fin T) : + multiLabeledEvalK K (glueList l).1 (glueList l).2 B W μ + = (l.map fun p => multiLabeledEvalK K p.1 p.2 B W μ).prod := by + induction l with + | nil => + show multiLabeledEvalK K 0 (MultiLabeledGraph.empty K 0) B W μ = 1 + rw [multiLabeledEvalK_empty] + simp + | cons p l ih => + rw [List.map_cons, List.prod_cons, ← ih] + exact multiLabeledEvalK_glue B hB W p.2 (glueList l).2 μ + +/-- `glueList` inherits `NoLabelPairs` from its components. -/ +theorem glueList_noLabelPairs (l : List (Σ n, MultiLabeledGraph K n)) + (hlp : ∀ p ∈ l, p.2.NoLabelPairs) : (glueList l).2.NoLabelPairs := by + induction l with + | nil => exact MultiLabeledGraph.empty_noLabelPairs + | cons p l ih => + exact MultiLabeledGraph.glue_noLabelPairs (hlp p (by simp)) + (ih fun q hq => hlp q (List.mem_cons_of_mem p hq)) + +/-- `glueList` inherits `SimpleMult` from components that also satisfy `NoLabelPairs`. -/ +theorem glueList_simpleMult (l : List (Σ n, MultiLabeledGraph K n)) + (hs : ∀ p ∈ l, p.2.SimpleMult) (hlp : ∀ p ∈ l, p.2.NoLabelPairs) : + (glueList l).2.SimpleMult := by + induction l with + | nil => exact MultiLabeledGraph.empty_simpleMult + | cons p l ih => + exact MultiLabeledGraph.glue_simpleMult (hs p (by simp)) + (ih (fun q hq => hs q (List.mem_cons_of_mem p hq)) + (fun q hq => hlp q (List.mem_cons_of_mem p hq))) + (glueList_noLabelPairs l fun q hq => hlp q (List.mem_cons_of_mem p hq)) + +/-! ## Chunk 4D: the test-moment profile and its exponent graphs + +The Vandermonde step classifies extensions by their vector of star/edge test moments +(`testMoment`). The moment products `∏_c moment_c^{k c}` demanded by the multivariate +Vandermonde are realized as `simpleEvalAt` of a single simple graph `expTestGraph k`: +glue `k c` copies of each coordinate's test graph (a multigraph a priori, but mult ≤ 1 by +chunk 4B since test graphs have no label-label edges) and convert back via `toSimple`. -/ + +/-- Test-moment coordinates: `inl S` is the star test `Gχ S`; `inr (Sₗ, Sτ)` the edge test. -/ +abbrev TestCoord (L : ℕ) := Finset (Fin L) ⊕ (Finset (Fin L) × Finset (Fin L)) + +/-- The closed-form moment of a test coordinate at the tuple `μ` (the `simpleEvalAt` value of +the corresponding test graph, see `coordGraph_eval`). -/ +noncomputable def testMoment {T : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (c : TestCoord K) (μ : Fin K → Fin T) : ℝ := + Sum.elim (fun S => ∑ t, W t * ∏ i ∈ S, B (μ i) t) + (fun p => ∑ t, ∑ t', W t * W t' * B t t' + * (∏ i ∈ p.1, B (μ i) t) * (∏ i ∈ p.2, B (μ i) t')) c + +/-- The test coordinate's graph, as a sigma-packaged `ofSimple` multigraph. -/ +noncomputable def coordGraph (c : TestCoord K) : Σ n, MultiLabeledGraph K n := + Sum.elim (fun S => ⟨1, MultiLabeledGraph.ofSimple (starTestGraph S)⟩) + (fun p => ⟨2, MultiLabeledGraph.ofSimple (edgeTestGraph p.1 p.2)⟩) c + +theorem coordGraph_eval {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (c : TestCoord K) (μ : Fin K → Fin T) : + multiLabeledEvalK K (coordGraph c).1 (coordGraph c).2 B W μ = testMoment B W c μ := by + cases c with + | inl S => + show multiLabeledEvalK K 1 (MultiLabeledGraph.ofSimple (starTestGraph S)) B W μ = _ + rw [← simpleEvalAt_eq_multi', simpleEvalAt_starTestGraph B hB W S μ] + rfl + | inr p => + show multiLabeledEvalK K 2 (MultiLabeledGraph.ofSimple (edgeTestGraph p.1 p.2)) B W μ = _ + rw [← simpleEvalAt_eq_multi', simpleEvalAt_edgeTestGraph B hB W p.1 p.2 μ] + rfl + +theorem coordGraph_simpleMult (c : TestCoord K) : (coordGraph c).2.SimpleMult := by + cases c with + | inl S => exact MultiLabeledGraph.ofSimple_simpleMult _ + | inr p => exact MultiLabeledGraph.ofSimple_simpleMult _ + +theorem coordGraph_noLabelPairs (c : TestCoord K) : (coordGraph c).2.NoLabelPairs := by + cases c with + | inl S => exact starTestGraph_noLabelPairs S + | inr p => exact edgeTestGraph_noLabelPairs p.1 p.2 + +/-- Product bookkeeping for replicated flatMaps (self-contained; avoids hunting for a +flatMap-product lemma). -/ +private theorem prod_map_flatMap_replicate {α β γ : Type*} [CommMonoid γ] (l : List α) + (k : α → ℕ) (g : α → β) (f : β → γ) : + ((l.flatMap fun a => List.replicate (k a) (g a)).map f).prod + = (l.map fun a => f (g a) ^ k a).prod := by + induction l with + | nil => rfl + | cons a l ih => + rw [List.flatMap_cons, List.map_append, List.prod_append, ih, List.map_cons, List.prod_cons, + List.map_replicate, List.prod_replicate] + +/-- The **exponent graph**: glue `k c` copies of each test coordinate's graph. -/ +noncomputable def expGraph (k : TestCoord K → ℕ) : Σ n, MultiLabeledGraph K n := + glueList ((Finset.univ : Finset (TestCoord K)).toList.flatMap + fun c => List.replicate (k c) (coordGraph c)) + +/-- Every component list element of `expGraph` is a `coordGraph`. -/ +private theorem expGraph_mem {k : TestCoord K → ℕ} {p : Σ n, MultiLabeledGraph K n} + (hp : p ∈ (Finset.univ : Finset (TestCoord K)).toList.flatMap + fun c => List.replicate (k c) (coordGraph c)) : ∃ c, p = coordGraph c := by + rw [List.mem_flatMap] at hp + obtain ⟨c, -, hmem⟩ := hp + exact ⟨c, List.eq_of_mem_replicate hmem⟩ + +theorem expGraph_simpleMult (k : TestCoord K → ℕ) : (expGraph k).2.SimpleMult := by + refine glueList_simpleMult _ (fun p hp => ?_) (fun p hp => ?_) <;> + obtain ⟨c, rfl⟩ := expGraph_mem hp + · exact coordGraph_simpleMult c + · exact coordGraph_noLabelPairs c + +/-- **Closed form of the exponent graph**: its evaluation is the product of test-moment +powers. -/ +theorem expGraph_eval {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (k : TestCoord K → ℕ) (μ : Fin K → Fin T) : + multiLabeledEvalK K (expGraph k).1 (expGraph k).2 B W μ + = ∏ c : TestCoord K, (testMoment B W c μ) ^ k c := by + rw [expGraph, multiLabeledEvalK_glueList B hB W, + prod_map_flatMap_replicate _ k coordGraph (fun p => multiLabeledEvalK K p.1 p.2 B W μ)] + rw [show ((Finset.univ : Finset (TestCoord K)).toList.map + fun c => multiLabeledEvalK K (coordGraph c).1 (coordGraph c).2 B W μ ^ k c) + = ((Finset.univ : Finset (TestCoord K)).toList.map + fun c => testMoment B W c μ ^ k c) from + List.map_congr_left fun c _ => by rw [coordGraph_eval B hB W c μ]] + exact Finset.prod_map_toList _ _ + +/-- The exponent graph, converted back to an honest simple graph (chunk 4B). -/ +noncomputable def expTestGraph (k : TestCoord K → ℕ) : + SimpleGraph (Fin ((expGraph k).1 + K)) := + (expGraph k).2.toSimple + +noncomputable instance (k : TestCoord K → ℕ) : DecidableRel (expTestGraph k).Adj := + Classical.decRel _ + +/-- **The moment-power realization**: `simpleEvalAt` of the exponent test graph is the +product of test-moment powers. This is the input eq. (10) consumes in chunk 4E. -/ +theorem simpleEvalAt_expTestGraph {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (k : TestCoord K → ℕ) (μ : Fin K → Fin T) : + simpleEvalAt B W (expTestGraph k) μ = ∏ c : TestCoord K, (testMoment B W c μ) ^ k c := by + have h := simpleEvalAt_toSimple B W (expGraph k).2 (expGraph_simpleMult k) μ + rw [expGraph_eval B hB W k μ] at h + exact h + +/-- The `TestEvalEq` interface is equivalent to matching of all test moments. -/ +theorem testEvalEq_iff_moments {T : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} : + TestEvalEq B W ξ ξ' ↔ ∀ c : TestCoord K, testMoment B W c ξ = testMoment B W c ξ' := by constructor + · intro h c + cases c with + | inl S => + have := h.star S + rwa [simpleEvalAt_starTestGraph B hB W S ξ, simpleEvalAt_starTestGraph B hB W S ξ'] at this + | inr p => + have := h.edge p.1 p.2 + rwa [simpleEvalAt_edgeTestGraph B hB W p.1 p.2 ξ, + simpleEvalAt_edgeTestGraph B hB W p.1 p.2 ξ'] at this · intro h - have hcard : (rangeFinset φ).card = T := by omega - apply Finset.eq_univ_of_card - rw [Fintype.card_fin] - exact hcard + refine ⟨fun S => ?_, fun Sₗ Sτ => ?_⟩ + · rw [simpleEvalAt_starTestGraph B hB W S ξ, simpleEvalAt_starTestGraph B hB W S ξ'] + exact h (Sum.inl S) + · rw [simpleEvalAt_edgeTestGraph B hB W Sₗ Sτ ξ, simpleEvalAt_edgeTestGraph B hB W Sₗ Sτ ξ'] + exact h (Sum.inr (Sₗ, Sτ)) + +/-! ## Chunk 4E: the power-moment identity for extension families + +Equation (10) instantiated at the exponent test graphs: simple-equivalence at level `K` +forces every weighted moment of the level-`(K+m)` test profile over the extension family of +`ξ` to match that of `ξ'`. This is the `hmom` input for the two-family Vandermonde in the +descent step (chunk 4F). -/ + +/-- **Power-moment identity** (eq. (10) at `G := expTestGraph k`). -/ +theorem extension_power_moments {T m : ℕ} (B : Fin T → Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} + (h : tupleEquivSimple B W ξ ξ') (k : TestCoord (K + m) → ℕ) : + ∑ ρ : Fin m → Fin T, (∏ j, W (ρ j)) + * ∏ c : TestCoord (K + m), (testMoment B W c (Fin.append ξ ρ)) ^ k c + = ∑ ρ : Fin m → Fin T, (∏ j, W (ρ j)) + * ∏ c : TestCoord (K + m), (testMoment B W c (Fin.append ξ' ρ)) ^ k c := by + have hid := extension_sum_identity B hB W h (expTestGraph k) + rw [sum_extensions_eq_sum_rho B W (expTestGraph k) ξ, + sum_extensions_eq_sum_rho B W (expTestGraph k) ξ'] at hid + simp only [simpleEvalAt_expTestGraph B hB W k] at hid + exact hid + +/-! ## Chunk 4F: matching a super-surjective extension of `ξ` inside the `ξ'`-family + +Two-family bounded Vandermonde over the extension families: the power-moment identity +(chunk 4E) matches all weighted test-moment powers, so the class-balance engine equates, at +each profile value, the two weighted masses. At the profile of `superExt ξ` the `ξ`-side mass +is positive (it contains `ρ = coverExtra T`, and `W > 0`), so the `ξ'`-side class is +nonempty: some extension of `ξ'` matches ALL test moments of `superExt ξ`. -/ + +/-- The test-moment profile as a `Fin`-indexed vector (transport along `Fintype.equivFin`), +for the graph-free Vandermonde engines. -/ +noncomputable def testProfile {T : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (μ : Fin K → Fin T) : Fin (Fintype.card (TestCoord K)) → ℝ := + fun c => testMoment B W ((Fintype.equivFin (TestCoord K)).symm c) μ + +theorem testProfile_eq_iff {T : ℕ} {B : Fin T → Fin T → ℝ} {W : Fin T → ℝ} + {μ ν : Fin K → Fin T} : + testProfile B W μ = testProfile B W ν + ↔ ∀ c : TestCoord K, testMoment B W c μ = testMoment B W c ν := by + constructor + · intro h c + have := congrFun h (Fintype.equivFin (TestCoord K) c) + simpa only [testProfile, Equiv.symm_apply_apply] using this · intro h - have : (rangeFinset φ).card = T := by - rw [h, Finset.card_univ, Fintype.card_fin] - omega - -/-- If `φ` is not surjective, some `a : Fin T` is missing from the -range. -/ -lemma exists_not_mem_rangeFinset {T k : ℕ} (φ : Fin k → Fin T) - (h : ¬ Function.Surjective φ) : - ∃ a, a ∉ rangeFinset φ := by + funext c + exact h _ + +/-- **Matching extension** (the 4F pivot). If `ξ ≈ ξ'` (equal simple evaluations), some +extension `Fin.append ξ' ρ'` of `ξ'` matches `superExt ξ` on every test moment. -/ +theorem exists_matching_extension {T : ℕ} (B : Fin T → Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) + {ξ ξ' : Fin K → Fin T} (h : tupleEquivSimple B W ξ ξ') : + ∃ ρ' : Fin (T * (2 * T ^ 2)) → Fin T, + ∀ c : TestCoord (K + T * (2 * T ^ 2)), + testMoment B W c (Fin.append ξ' ρ') = testMoment B W c (superExt ξ) := by classical - rw [surjective_iff_rangeFinset_eq_univ] at h - by_contra hcontra - push Not at hcontra - apply h - exact Finset.eq_univ_iff_forall.mpr hcontra + set e := Fintype.equivFin (TestCoord (K + T * (2 * T ^ 2))) with he + -- Profile-form conversion of the power products. + have hconv : ∀ (μ : Fin (K + T * (2 * T ^ 2)) → Fin T) + (k : Fin (Fintype.card (TestCoord (K + T * (2 * T ^ 2)))) → ℕ), + ∏ c : TestCoord (K + T * (2 * T ^ 2)), (testMoment B W c μ) ^ k (e c) + = ∏ c, (testProfile B W μ c) ^ k c := by + intro μ k + calc ∏ c : TestCoord (K + T * (2 * T ^ 2)), (testMoment B W c μ) ^ k (e c) + = ∏ c : TestCoord (K + T * (2 * T ^ 2)), (testProfile B W μ (e c)) ^ k (e c) := by + refine Finset.prod_congr rfl fun c _ => ?_ + congr 1 + show testMoment B W c μ = testMoment B W (e.symm (e c)) μ + rw [Equiv.symm_apply_apply] + _ = ∏ c, (testProfile B W μ c) ^ k c := + Equiv.prod_comp e (fun c => (testProfile B W μ c) ^ k c) + -- The moment feed for the class-balance engine (no exponent bound needed). + have hmom : ∀ k : Fin (Fintype.card (TestCoord (K + T * (2 * T ^ 2)))) → ℕ, + (∀ c, k c < 2 * Fintype.card (Fin (T * (2 * T ^ 2)) → Fin T)) → + ∑ ρ : Fin (T * (2 * T ^ 2)) → Fin T, (∏ j, W (ρ j)) + * ∏ c, (testProfile B W (Fin.append ξ ρ) c) ^ k c + = ∑ ρ : Fin (T * (2 * T ^ 2)) → Fin T, (∏ j, W (ρ j)) + * ∏ c, (testProfile B W (Fin.append ξ' ρ) c) ^ k c := by + intro k _ + have hpm := extension_power_moments B hB W h (fun c => k (e c)) + calc ∑ ρ : Fin (T * (2 * T ^ 2)) → Fin T, (∏ j, W (ρ j)) + * ∏ c, (testProfile B W (Fin.append ξ ρ) c) ^ k c + = ∑ ρ : Fin (T * (2 * T ^ 2)) → Fin T, (∏ j, W (ρ j)) + * ∏ c : TestCoord (K + T * (2 * T ^ 2)), + (testMoment B W c (Fin.append ξ ρ)) ^ k (e c) := by + refine Finset.sum_congr rfl fun ρ _ => ?_ + rw [hconv] + _ = ∑ ρ : Fin (T * (2 * T ^ 2)) → Fin T, (∏ j, W (ρ j)) + * ∏ c : TestCoord (K + T * (2 * T ^ 2)), + (testMoment B W c (Fin.append ξ' ρ)) ^ k (e c) := hpm + _ = ∑ ρ : Fin (T * (2 * T ^ 2)) → Fin T, (∏ j, W (ρ j)) + * ∏ c, (testProfile B W (Fin.append ξ' ρ) c) ^ k c := by + refine Finset.sum_congr rfl fun ρ _ => ?_ + rw [hconv] + -- Class balance at the profile of `superExt ξ`. + have hbal := aligned_moments_class_balance_of_bound + (fun ρ : Fin (T * (2 * T ^ 2)) → Fin T => testProfile B W (Fin.append ξ ρ)) + (fun ρ => testProfile B W (Fin.append ξ' ρ)) + (fun ρ => ∏ j, W (ρ j)) (fun ρ => ∏ j, W (ρ j)) + (Fintype.card (Fin (T * (2 * T ^ 2)) → Fin T)) + (fun _ => Finset.card_image_le.trans (by simp)) + (fun _ => Finset.card_image_le.trans (by simp)) + hmom (testProfile B W (superExt ξ)) + -- The ξ-side mass is positive: `coverExtra T` lies in the class, and all weights are > 0. + have hmem : coverExtra T ∈ univ.filter (fun ρ : Fin (T * (2 * T ^ 2)) → Fin T => + testProfile B W (Fin.append ξ ρ) = testProfile B W (superExt ξ)) := + Finset.mem_filter.mpr ⟨Finset.mem_univ _, rfl⟩ + have hpos : (0 : ℝ) < ∑ ρ ∈ univ.filter (fun ρ : Fin (T * (2 * T ^ 2)) → Fin T => + testProfile B W (Fin.append ξ ρ) = testProfile B W (superExt ξ)), ∏ j, W (ρ j) := + Finset.sum_pos (fun ρ _ => Finset.prod_pos fun j _ => hW _) ⟨coverExtra T, hmem⟩ + rw [hbal] at hpos + obtain ⟨ρ', hρ'mem⟩ := Finset.nonempty_of_sum_ne_zero (ne_of_gt hpos) + exact ⟨ρ', fun c => testProfile_eq_iff.mp (Finset.mem_filter.mp hρ'mem).2 c⟩ + +/-! ## Chunk 4G: the general descent theorem -/ + +/-- **The Cai–Govorov descent — the general simple-graph orbit theorem (#70).** If all +simple-graph evaluations at `ξ` and `ξ'` agree, then `ξ'` is in the weighted-automorphism +orbit of `ξ` — with NO surjectivity hypothesis on either tuple. Route: match an extension of +`ξ'` against the super-surjective `superExt ξ` on all test moments (chunk 4F), run the +moment-form super-case (chunk 4A) at level `K + T·2T²`, and restrict the resulting +automorphism to the first `K` labels. This is the statement of the sorry'd +`tupleEquivSimple_implies_orbit` (`Lovasz.lean` §3.10), proved downstream. -/ +theorem tupleEquivSimple_implies_orbit_general {T : ℕ} (B : Fin T → Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (hW : ∀ v, 0 < W v) + (htwin : ∀ i j, i ≠ j → B i ≠ B j) (ξ ξ' : Fin K → Fin T) + (h : tupleEquivSimple B W ξ ξ') : tupleOrbitRel B W ξ ξ' := by + obtain ⟨ρ', hρ'⟩ := exists_matching_extension B hB W hW h + have hTE : TestEvalEq B W (superExt ξ) (Fin.append ξ' ρ') := + (testEvalEq_iff_moments B hB W).mpr fun c => (hρ' c).symm + obtain ⟨σ, hσ_aut, hσ⟩ := testEvalEq_implies_orbit_super B hB W hW htwin (superExt ξ) + (Fin.append ξ' ρ') (superExt_superSurjective ξ) hTE + refine ⟨σ, hσ_aut, fun i => ?_⟩ + have hi := hσ (Fin.castAdd (T * (2 * T ^ 2)) i) + rw [Fin.append_left, superExt_extends ξ i] at hi + exact hi + + +end CaiGovorovStack + +/-! ### Multigraph descent corollaries (relocated 2026-07-02) + +The former §3.7 descent residues and their consumers, relocated below the Cai–Govorov +stack and PROVED via the orbit route: `tupleEquivSimple_implies_orbit_general` + +`multiLabeledEvalK_eq_of_orbit` close every case uniformly (the structural multiplicity +hypotheses and the square-moment inputs are no longer needed by the proofs, but the +statements are preserved — with `hW`/`htwin` added to the UU-nonisolated case, whose +unhypothesized form was never provable by this route). +-/ -/-- **Orbit ⟹ simple-equivalence** (forward direction of Lemma 2.5, -specialized to simple graphs). If `ξ ξ'` are `(B, W)`-orbit related, -they agree on every simple-graph evaluation. Used inside the strong -induction to normalize `ψ` by `σ⁻¹` before extending the base. +/-- **CANONICAL PAPER-ROOT** — unlabeled-excess descent (the final Lovász §3 +core). After polynomial decomposition handles all label-label multiplicities +(via `multigraphEval_LL_excess_descends_aux`), the remaining residue is +the case where some mult≥2 edge touches at least one unlabeled vertex. +Polynomial decomposition does NOT apply directly: the B-factor at such +an edge depends on σ (the unlabeled coloring), so it cannot be pulled +out of the σ-sum. -This is the simple-graph specialization of `tupleEquivMulti_of_orbit` -(via `tupleEquivSimple_of_tupleEquivMulti`). Direct proof here avoids -the multigraph detour. -/ -theorem tupleEquivSimple_of_tupleOrbitRel {T K : ℕ} - (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) {ξ ξ' : Fin K → Fin T} - (h : tupleOrbitRel B W ξ ξ') : - tupleEquivSimple B W ξ ξ' := by - -- Pass through tupleEquivMulti, then descend to simple via the - -- trivial direction. - obtain ⟨σ, ⟨hW, hB⟩, hconj⟩ := h - refine tupleEquivSimple_of_tupleEquivMulti B W ?_ - intro n M - exact multiLabeledEvalK_orbit_invariant B W M ⟨σ, hW, hB, hconj⟩ +**Hypotheses**: + - `B` symmetric. + - `h_simple`: the inlined `tupleEquivSimple` hypothesis at level K. + - `h_unlabeled_excess`: there exists an edge with multiplicity ≥ 2 + that touches at least one unlabeled vertex (val ≥ K). -/-- **Claim 4.1 — Restriction preserves `tupleEquivSimple`** -(Lovász TR-2004-82 §4, p. 6, "first paragraph"). +**Conclusion**: `multiLabeledEvalK K n M B W ξ = multiLabeledEvalK K n M B W ξ'`. -If `ξ ξ' : Fin (k+1) → Fin T` are simple-equivalent, then their -restrictions to the first `k` coordinates (via `Fin.castSucc`) are -also simple-equivalent. +**Status** (2026-05-19): this is the residual Lovász §3 content of #86, +the canonical paper-root for #62. Closing requires the connection-matrix +/ idempotent decomposition of the multigraph algebra `𝒜_K` (~300-500 LOC +of new spectral/rank infrastructure). -**Proof**: any simple graph `F'` on `Fin (n + k)` lifts to a simple -graph `F` on `Fin (n + (k + 1))` via the embedding `Fin.succAboveEmb p` -with `p = ⟨k, _⟩` (skip the pivot position `k`). The level-`(k+1)` -evaluation of `F` at `ξ` equals the level-`k` evaluation of `F'` at -`restrictTuple ξ`, because the embedding leaves the unlabeled vertices -untouched while reindexing the label slot. The hypothesis applied at -`F` then transfers to `F'`. +**Smallest non-trivial subcase** (next target): "one doubled edge involving +an unlabeled vertex" — even that requires the substantive Lovász §3 +algebra. If that subcase reduces, general multiplicities follow by +products (per Lovász §3.3). -This is the simple-graph analog of `tupleEquiv_restrict` (line 4461 of -`MatrixDetermination.lean`). -/ -theorem tupleEquivSimple_restrict {T k : ℕ} - (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) - {ξ ξ' : Fin (k + 1) → Fin T} - (h : tupleEquivSimple B W ξ ξ') : - tupleEquivSimple B W (restrictTuple ξ) (restrictTuple ξ') := by - classical - intro n F' hdec - -- Helper: edge-product term is independent of the Sym2 representative - -- thanks to `hB`. Stated for both target sizes. - have h_edge_rep : ∀ {m : ℕ} (ν : Fin m → Fin T) (a b : Fin m), - B (ν (Quot.out (s(a, b) : Sym2 (Fin m))).1) - (ν (Quot.out (s(a, b) : Sym2 (Fin m))).2) = B (ν a) (ν b) := by - intro m ν a b - have h_out_eq : s((Quot.out (s(a, b) : Sym2 (Fin m))).1, - (Quot.out (s(a, b) : Sym2 (Fin m))).2) = s(a, b) := - Quot.out_eq _ - rcases Sym2.eq_iff.mp h_out_eq with ⟨h1, h2⟩ | ⟨h1, h2⟩ - · rw [h1, h2] - · rw [h1, h2]; exact hB _ _ - -- Pivot at position k; shift = succAboveEmb p maps Fin (n+k) → Fin (n+(k+1)). - have hk : k < n + (k + 1) := by omega - let p : Fin (n + (k + 1)) := ⟨k, hk⟩ - let shift : Fin (n + k) ↪ Fin (n + (k + 1)) := Fin.succAboveEmb p - let F : SimpleGraph (Fin (n + (k + 1))) := SimpleGraph.map shift F' - haveI hF_dec : DecidableRel F.Adj := Classical.decRel _ - -- Core translation. The sum on the LHS of `tupleEquivSimple` at - -- `(restrictTuple ξ, F')` equals the sum on the LHS at `(ξ, F)`. - suffices trans : ∀ (θ : Fin (k + 1) → Fin T), - (∑ σ : Fin n → Fin T, - (let τ : Fin (n + (k + 1)) → Fin T := fun v => - if h : (v : ℕ) < k + 1 then θ ⟨v, h⟩ - else σ ⟨v - (k + 1), by have := v.isLt; omega⟩ - (∏ v : Fin n, W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) = - (∑ σ : Fin n → Fin T, - (let τ : Fin (n + k) → Fin T := fun v => - if h : (v : ℕ) < k then (restrictTuple θ) ⟨v, h⟩ - else σ ⟨v - k, by have := v.isLt; omega⟩ - (∏ v : Fin n, W (σ v)) * - ∏ e ∈ F'.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) by - -- Apply trans on both sides, then h at F. - rw [← trans ξ, ← trans ξ'] - exact h n F - intro θ - refine Finset.sum_congr rfl fun σ _ => ?_ - -- Both sides have the form (∏ W σ) * (edge prod). The W-prods agree - -- definitionally; reduce to edge-product equality. - simp only - refine congrArg (fun x => (∏ v : Fin n, W (σ v)) * x) ?_ - -- Edge product: Finset.prod_bij with shift.sym2Map. - symm - refine Finset.prod_bij (fun e _ => shift.sym2Map e) ?_ ?_ ?_ ?_ - · -- 1. Map lands in F.edgeFinset. - intro e he - change shift.sym2Map e ∈ (SimpleGraph.map shift F').edgeFinset - rw [SimpleGraph.mem_edgeFinset] at he ⊢ - induction e using Sym2.ind with - | _ a b => - simp only [Function.Embedding.sym2Map_apply, Sym2.map_mk] at * - rw [SimpleGraph.mem_edgeSet] at he ⊢ - rw [SimpleGraph.map_adj] - exact ⟨a, b, he, rfl, rfl⟩ - · -- 2. Injective. - intro e1 _ e2 _ hij - exact shift.sym2Map.injective hij - · -- 3. Surjective. - intro e he - change e ∈ (SimpleGraph.map shift F').edgeFinset at he - rw [SimpleGraph.mem_edgeFinset] at he - induction e using Sym2.ind with - | _ x y => - rw [SimpleGraph.mem_edgeSet] at he - rw [SimpleGraph.map_adj] at he - obtain ⟨a, b, hab, hax, hby⟩ := he - refine ⟨s(a, b), ?_, ?_⟩ - · rw [SimpleGraph.mem_edgeFinset, SimpleGraph.mem_edgeSet]; exact hab - · simp only [Function.Embedding.sym2Map_apply, Sym2.map_mk] - rw [hax, hby] - · -- 4. Term-by-term equality. - intro e _ - set ν' : Fin (n + k) → Fin T := fun v => - if h : (v : ℕ) < k then (restrictTuple θ) ⟨v, h⟩ - else σ ⟨(v : Fin (n + k)).val - k, by have := v.isLt; omega⟩ with hν'_def - set ν : Fin (n + (k + 1)) → Fin T := fun v => - if h : (v : ℕ) < k + 1 then θ ⟨v, h⟩ - else σ ⟨(v : Fin (n + (k + 1))).val - (k + 1), - by have := v.isLt; omega⟩ with hν_def - induction e using Sym2.ind with - | _ a b => - simp only [Function.Embedding.sym2Map_apply, Sym2.map_mk] - change B (ν' (Quot.out s(a, b)).1) (ν' (Quot.out s(a, b)).2) = - B (ν (Quot.out s(shift a, shift b)).1) - (ν (Quot.out s(shift a, shift b)).2) - rw [h_edge_rep ν' a b, h_edge_rep ν (shift a) (shift b)] - -- Reduces to ν ∘ shift = ν' pointwise. - have hτ : ∀ v : Fin (n + k), ν (shift v) = ν' v := by - intro v - by_cases hv : (v : ℕ) < k - · -- Below the pivot: shift v = v.castSucc, .val preserved. - have h_shift_val : (shift v : Fin (n + (k + 1))).val = v.val := by - show (p.succAboveEmb v : Fin (n + (k + 1))).val = v.val - simp only [Fin.coe_succAboveEmb] - rw [Fin.succAbove_of_castSucc_lt] - · rfl - · show v.castSucc < p - simp only [Fin.lt_def, Fin.val_castSucc] - exact hv - have h_lt : ((shift v : Fin (n + (k + 1))) : ℕ) < k + 1 := by - rw [h_shift_val]; omega - simp only [hν_def, hν'_def, dif_pos h_lt, dif_pos hv, restrictTuple] - congr 1 - apply Fin.ext - simp only [Fin.val_castSucc] - exact h_shift_val - · -- Above the pivot: shift v = v.succ, .val = v.val + 1. - have h_shift_val : (shift v : Fin (n + (k + 1))).val = v.val + 1 := by - show (p.succAboveEmb v : Fin (n + (k + 1))).val = v.val + 1 - simp only [Fin.coe_succAboveEmb] - rw [Fin.succAbove_of_le_castSucc] - · rfl - · show p ≤ v.castSucc - simp only [Fin.le_def, Fin.val_castSucc] - show k ≤ v.val - omega - have h_nlt : ¬ ((shift v : Fin (n + (k + 1))) : ℕ) < k + 1 := by - rw [h_shift_val]; omega - have h_nlt' : ¬ (v : ℕ) < k := hv - simp only [hν_def, hν'_def, dif_neg h_nlt, dif_neg h_nlt'] - congr 1 - apply Fin.ext - show (shift v : Fin (n + (k + 1))).val - (k + 1) = v.val - k - rw [h_shift_val]; omega - rw [hτ a, hτ b] +**Architecture note**: this is the general unlabeled-excess case. The +**final paper-root** is the smaller doubled-edge subcase +`multigraphEval_one_doubled_unlabeled_edge_descends` (see below), which +isolates the K=1 square moment as the genuine Lovász §3 residue. -/ +private theorem multigraphEval_unlabeled_excess_descends {T K n : ℕ} + (B : Fin T → Fin T → ℝ) (_hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) + (_hW : ∀ i, 0 < W i) (_htwin : ∀ i j, i ≠ j → B i ≠ B j) + (M : MultiLabeledGraph K n) + (_h_unlabeled_excess : + ∃ e : Sym2 (Fin (n + K)), ¬ isLLEdge e ∧ 2 ≤ M.mult e) + {ξ ξ' : Fin K → Fin T} + (_h_simple : ∀ (n' : ℕ) (F : SimpleGraph (Fin (n' + K))) [DecidableRel F.Adj], + ∑ σ : Fin n' → Fin T, + (let τ : Fin (n' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = + ∑ σ : Fin n' → Fin T, + (let τ : Fin (n' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ' ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) + (_h_sq_moment : ∀ (c : Fin K), + ∑ t : Fin T, W t * B (ξ c) t ^ 2 = ∑ t : Fin T, W t * B (ξ' c) t ^ 2) : + multiLabeledEvalK K n M B W ξ = multiLabeledEvalK K n M B W ξ' := by + obtain ⟨σ, hσ_aut, hconj⟩ := + tupleEquivSimple_implies_orbit_general B _hB W _hW _htwin ξ ξ' _h_simple + exact multiLabeledEvalK_eq_of_orbit B _hB W M ⟨σ, hσ_aut.1, hσ_aut.2, hconj⟩ + +/-- **Label-unlabeled non-isolated reduction**: same orientation as above +but with other edges touching `b`. Reduces to the isolated case via peeling +those other edges. BLOCKED BY: label_unlabeled_square_moment_descends + +non-LL peel infrastructure. -/ +private theorem multigraphEval_label_unlabeled_nonisolated_descends + {T K n : ℕ} (B : Fin T → Fin T → ℝ) (_hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (_hW : ∀ i, 0 < W i) + (_htwin : ∀ i j, i ≠ j → B i ≠ B j) + (M : MultiLabeledGraph K n) + (a b : Fin (n + K)) + (_ha : a.val < K) (_hb : K ≤ b.val) (_hab : a ≠ b) + (_h_doubled : M.mult s(a, b) = 2) + (_h_others_le_one : ∀ e, e ≠ s(a, b) → M.mult e ≤ 1) + (_h_b_not_iso : ¬ ∀ e, e ≠ s(a, b) → b ∈ e → M.mult e = 0) + {ξ ξ' : Fin K → Fin T} + (_h_simple : ∀ (n' : ℕ) (F : SimpleGraph (Fin (n' + K))) [DecidableRel F.Adj], + ∑ σ : Fin n' → Fin T, + (let τ : Fin (n' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = + ∑ σ : Fin n' → Fin T, + (let τ : Fin (n' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ' ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) + (_h_sq_moment : ∀ (c : Fin K), + ∑ t : Fin T, W t * B (ξ c) t ^ 2 = ∑ t : Fin T, W t * B (ξ' c) t ^ 2) : + multiLabeledEvalK K n M B W ξ = multiLabeledEvalK K n M B W ξ' := by + obtain ⟨σ, hσ_aut, hconj⟩ := + tupleEquivSimple_implies_orbit_general B _hB W _hW _htwin ξ ξ' _h_simple + exact multiLabeledEvalK_eq_of_orbit B _hB W M ⟨σ, hσ_aut.1, hσ_aut.2, hconj⟩ -/-! ### §3.9.1 — Restriction-weight coefficient (Claim 4.2 architecture) +/-- **Unlabeled-label non-isolated reduction**: symmetric to +label-unlabeled non-isolated via Sym2.eq_swap. -/ +private theorem multigraphEval_unlabeled_label_nonisolated_descends + {T K n : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ i, 0 < W i) + (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (M : MultiLabeledGraph K n) + (a b : Fin (n + K)) + (ha : K ≤ a.val) (hb : b.val < K) (hab : a ≠ b) + (h_doubled : M.mult s(a, b) = 2) + (h_others_le_one : ∀ e, e ≠ s(a, b) → M.mult e ≤ 1) + (h_a_not_iso : ¬ ∀ e, e ≠ s(a, b) → a ∈ e → M.mult e = 0) + {ξ ξ' : Fin K → Fin T} + (h_simple : ∀ (n' : ℕ) (F : SimpleGraph (Fin (n' + K))) [DecidableRel F.Adj], + ∑ σ : Fin n' → Fin T, + (let τ : Fin (n' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = + ∑ σ : Fin n' → Fin T, + (let τ : Fin (n' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ' ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) + (h_sq_moment : ∀ (c : Fin K), + ∑ t : Fin T, W t * B (ξ c) t ^ 2 = ∑ t : Fin T, W t * B (ξ' c) t ^ 2) : + multiLabeledEvalK K n M B W ξ = multiLabeledEvalK K n M B W ξ' := by + have h_swap : s(a, b) = (s(b, a) : Sym2 (Fin (n + K))) := Sym2.eq_swap + apply multigraphEval_label_unlabeled_nonisolated_descends B hB W hW htwin M b a hb ha hab.symm + · rw [← h_swap]; exact h_doubled + · intro e he + exact h_others_le_one e (by rw [h_swap]; exact he) + · intro h_b_iso + apply h_a_not_iso + intro e he hae + exact h_b_iso e (by rw [← h_swap]; exact he) hae + · exact h_simple + · exact h_sq_moment -The proof of Claim 4.2 (`tupleEquivSimple_extend`) below routes through -a `coeffRestrictSimple` "restriction weight" coefficient: - `coeffRestrictSimple B W μ ξ := ∑ t : Fin T, [tupleEquivSimple B W μ (snoc ξ t)] · W t` +/-- **UU non-isolated reduction**: doubled edge between two unlabeled vertices +with at least one OTHER edge touching `a` or `b`. -i.e., the total `W`-mass of extensions `t` of `ξ` that are -simple-equivalent (at level `k + 1`) to the given `(k + 1)`-tuple `μ`. +**Note**: simple "peel reduction" to UU isolated does NOT work cleanly because +the extra edge has at least one unlabeled endpoint (a or b), so the +B-factor depends on σ and cannot be pulled out of the σ-sum. -Three lemmas drive the assembly: +Honest proof structure: requires its own ~800 LOC parallel to UU isolated. +σ-sum factorization captures the (σ_a, σ_b)-coupled prefactor -* `coeffRestrictSimple_pos_at_restrict` — the coefficient is positive - at `ξ = restrictTuple μ` (witnessed by `t = μ (Fin.last k)`, which - makes the indicator `tupleEquivSimple μ μ` true by reflexivity). -* `coeffRestrictSimple_equiv` — class constancy: simple-equivalence - of `ξ` and `ξ'` transfers `coeffRestrictSimple B W μ ξ = - coeffRestrictSimple B W μ ξ'`. PROVED via `functional_span_zero` - + `product_trace_identity_simple` (the latter is a focused - sub-sorry capturing the Lovász §3 deep content). -* `exists_extension_of_coeffRestrictSimple_pos` — from positivity, some - `t` makes the indicator true, yielding the extension. + ∑_{s, t} W(s)·W(t)·B(s,t)² · (∏_{incident e} B(s/t, τ_e_other_endpoint)) -The class-constancy step is now proved structurally. The single -remaining architectural hurdle is the LIST-product trace identity -`product_trace_identity_simple` (Lovász §3 / DecLabeledGraph). -/ +times an F_rest_eval ξ for the remaining (non-touching) edges. -/-- **Restriction-weight coefficient** for a `(k+1)`-tuple `μ` -at a level-`k` base `ξ`. Sums `W t` over `t : Fin T` such that the -extended tuple `Fin.snoc ξ t` is simple-equivalent to `μ`. -/ -noncomputable def coeffRestrictSimple {T k : ℕ} - (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (μ : Fin (k + 1) → Fin T) (ξ : Fin k → Fin T) : ℝ := - ∑ t : Fin T, - haveI : Decidable (tupleEquivSimple B W μ (Fin.snoc ξ t)) := Classical.dec _ - if tupleEquivSimple B W μ (Fin.snoc ξ t) then W t else 0 +**Sub-case structure**: + - If no incident edge has a label endpoint, the prefactor is ξ-independent + (sum over σ_other interpretation) and the proof closes via h_simple. + - If some incident edge has a label endpoint, the prefactor involves ξ + via the label coordinate. Reduces to label_unlabeled_square_moment_descends + (the K=1 square moment generalization). -/-- `μ` is `Fin.snoc`-canonical at its own restriction: any tuple -equals `Fin.snoc` of its restriction with its last coordinate. -/ -private theorem snoc_restrict_eq {T k : ℕ} (μ : Fin (k + 1) → Fin T) : - Fin.snoc (restrictTuple μ) (μ (Fin.last k)) = μ := by - funext i - by_cases hi : (i : ℕ) < k - · rw [show i = (⟨i, hi⟩ : Fin k).castSucc from Fin.ext rfl, - Fin.snoc_castSucc] - rfl - · rw [show i = Fin.last k from Fin.ext (show i.val = k by omega), - Fin.snoc_last] +Dependency: substantial new work; may ultimately depend on +`label_unlabeled_square_moment_descends` for label-touching sub-cases. -/ +private theorem multigraphEval_unlabeled_unlabeled_nonisolated_descends + {T K n : ℕ} (B : Fin T → Fin T → ℝ) (_hB : ∀ i j, B i j = B j i) + (W : Fin T → ℝ) (hW : ∀ i, 0 < W i) + (htwin : ∀ i j, i ≠ j → B i ≠ B j) (M : MultiLabeledGraph K n) + (a b : Fin (n + K)) + (_ha : K ≤ a.val) (_hb : K ≤ b.val) (_hab : a ≠ b) + (_h_doubled : M.mult s(a, b) = 2) + (_h_others_le_one : ∀ e, e ≠ s(a, b) → M.mult e ≤ 1) + (_h_not_iso : ¬ ∀ e, e ≠ s(a, b) → (a ∈ e ∨ b ∈ e) → M.mult e = 0) + {ξ ξ' : Fin K → Fin T} + (_h_simple : ∀ (n' : ℕ) (F : SimpleGraph (Fin (n' + K))) [DecidableRel F.Adj], + ∑ σ : Fin n' → Fin T, + (let τ : Fin (n' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = + ∑ σ : Fin n' → Fin T, + (let τ : Fin (n' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ' ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) : + multiLabeledEvalK K n M B W ξ = multiLabeledEvalK K n M B W ξ' := by + -- BLOCKED BY: peel reduction to isolated UU case + -- (`multigraphEval_isolated_unlabeled_unlabeled_doubled_edge_descends` is proved). + -- Each peel removes one other edge touching `a` or `b`. Peel must handle + -- non-LL edges (since other edges have at least one unlabeled endpoint — + -- specifically `a` or `b`). Requires new non-LL peel infrastructure. + obtain ⟨σ, hσ_aut, hconj⟩ := + tupleEquivSimple_implies_orbit_general B _hB W hW htwin ξ ξ' _h_simple + exact multiLabeledEvalK_eq_of_orbit B _hB W M ⟨σ, hσ_aut.1, hσ_aut.2, hconj⟩ -/-- Reflexivity of `tupleEquivSimple`. -/ -private theorem tupleEquivSimple_refl {T K : ℕ} - (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) (ξ : Fin K → Fin T) : - tupleEquivSimple B W ξ ξ := - fun _ _ _ => rfl +/-- **FINAL PAPER-ROOT** — smallest unlabeled-excess subcase: one doubled +edge involving an unlabeled vertex, all other multiplicities ≤ 1. -/-- **Positivity of `coeffRestrictSimple` at its own restriction**. +**Algebraic analysis** (2026-05-19): given the above hypotheses, with +`e₀ = s(a, b)` the unique mult-2 edge having at least one endpoint +with `val ≥ K`, the σ-sum body of `multiLabeledEvalK M ξ` carries the +factor `B(τ_a, τ_b)²`. Three sub-sub-cases: + +1. **Unlabeled-unlabeled, isolated endpoints** (no other edges touch + `a` or `b`): + `multiLabeledEvalK M ξ = (∑_{s,t} W(s)W(t) B(s,t)²) · labeledEvalK F' ξ` + where the prefactor is **ξ-INDEPENDENT** and `F'` is the simple graph + on the remaining vertices. Both factors match at ξ vs ξ' (the + prefactor trivially, F' via `h_simple`). **Closable** via direct + σ-sum factorization. + +2. **Label-unlabeled, isolated unlabeled endpoint** (no other edges + touch the unlabeled vertex `j`): the σ_j-sum reduces to the K=1 + square moment `∑_t W(t) · B(ξ_a, t)²`. This is **NOT** a polynomial + in single-edge simple-graph evaluations (no simple graph evaluates + to `B(ξ_a, t)²`). Its ξ-invariance under `tupleEquivSimple` is + exactly the substantive Lovász §3 content (Lemma 2.5: every + auto-invariant function is in the simple-graph eval span; the + square moment is auto-invariant). + +3. **General doubled edge with other edges touching the endpoint(s)**: + the σ-sum involves mixed moments combining `B(?,t)²` with other + `B(t, ?)¹` factors. Strictly harder than case 2; reducible to + case 2 after handling the label-touching contributions, but the + reduction is itself non-trivial. + +**Conclusion**: the **smallest genuine paper-root** is the K=1 square +moment identity (case 2 — the simplest case requiring genuine Lovász §3 +content). Closing it requires the connection-matrix / idempotent +decomposition of the multigraph algebra `𝒜_K`. ~300-500 LOC of new +spectral/rank infrastructure. + +**Status** (2026-05-19): PROMOTED as the final paper-root per directive. +The unlabeled-unlabeled isolated case (1) is algebraically closable but +is not the bottleneck. The label-unlabeled isolated case (2) — the K=1 +square moment — IS the bottleneck. -/ +private theorem multigraphEval_one_doubled_unlabeled_edge_descends {T K n : ℕ} + (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) + (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (M : MultiLabeledGraph K n) + (e₀ : Sym2 (Fin (n + K))) + (he₀_unlabeled : ¬ isLLEdge e₀) + (he₀_doubled : M.mult e₀ = 2) + (h_others_le_one : ∀ e, e ≠ e₀ → M.mult e ≤ 1) + {ξ ξ' : Fin K → Fin T} + (h_simple : ∀ (n' : ℕ) (F : SimpleGraph (Fin (n' + K))) [DecidableRel F.Adj], + ∑ σ : Fin n' → Fin T, + (let τ : Fin (n' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = + ∑ σ : Fin n' → Fin T, + (let τ : Fin (n' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ' ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) + (h_sq_moment : ∀ (c : Fin K), + ∑ t : Fin T, W t * B (ξ c) t ^ 2 = ∑ t : Fin T, W t * B (ξ' c) t ^ 2) : + multiLabeledEvalK K n M B W ξ = multiLabeledEvalK K n M B W ξ' := by + classical + -- Case analysis on the orientation of `e₀`. + induction e₀ using Sym2.ind with + | h a b => + -- `M.mult e₀ = 2` ⟹ `a ≠ b` (no self-loop). + have hab_ne : a ≠ b := by + intro h_eq + have h_loop : M.mult s(a, b) = 0 := by rw [h_eq]; exact M.multNoLoop b + rw [he₀_doubled] at h_loop; omega + by_cases ha_lab : a.val < K + · by_cases hb_lab : b.val < K + · -- Both labels: contradicts `he₀_unlabeled`. + exact absurd (show a.val < K ∧ b.val < K from ⟨ha_lab, hb_lab⟩) he₀_unlabeled + · -- `a` label, `b` unlabeled. Label-unlabeled case. + push Not at hb_lab + by_cases h_b_iso : ∀ e, e ≠ s(a, b) → b ∈ e → M.mult e = 0 + · exact multigraphEval_label_unlabeled_isolated_descends + B hB W hW htwin M a b ha_lab hb_lab hab_ne he₀_doubled h_others_le_one + h_b_iso h_simple h_sq_moment + · exact multigraphEval_label_unlabeled_nonisolated_descends + B hB W hW htwin M a b ha_lab hb_lab hab_ne he₀_doubled h_others_le_one + h_b_iso h_simple h_sq_moment + · push Not at ha_lab + by_cases hb_lab : b.val < K + · -- `a` unlabeled, `b` label. + by_cases h_a_iso : ∀ e, e ≠ s(a, b) → a ∈ e → M.mult e = 0 + · exact multigraphEval_unlabeled_label_isolated_descends + B hB W hW htwin M a b ha_lab hb_lab hab_ne he₀_doubled h_others_le_one + h_a_iso h_simple h_sq_moment + · exact multigraphEval_unlabeled_label_nonisolated_descends + B hB W hW htwin M a b ha_lab hb_lab hab_ne he₀_doubled h_others_le_one + h_a_iso h_simple h_sq_moment + · -- Both unlabeled. + push Not at hb_lab + by_cases h_iso : ∀ e, e ≠ s(a, b) → (a ∈ e ∨ b ∈ e) → M.mult e = 0 + · -- **Isolated unlabeled-unlabeled doubled edge** — CLOSED via + -- `multigraphEval_isolated_unlabeled_unlabeled_doubled_edge_descends` (proved). + exact multigraphEval_isolated_unlabeled_unlabeled_doubled_edge_descends + B hB W M a b ha_lab hb_lab hab_ne he₀_doubled h_others_le_one h_iso h_simple + · -- **Non-isolated unlabeled-unlabeled** — dispatch to named reduction. + exact multigraphEval_unlabeled_unlabeled_nonisolated_descends + B hB W hW htwin M a b ha_lab hb_lab hab_ne he₀_doubled h_others_le_one h_iso h_simple -Under `0 < W`, the coefficient `coeffRestrictSimple B W μ -(restrictTuple μ)` is strictly positive: the term `t = μ (Fin.last k)` -contributes `W t > 0` (the indicator `tupleEquivSimple μ μ` holds by -reflexivity), and all other terms are nonneg. -/ -theorem coeffRestrictSimple_pos_at_restrict {T k : ℕ} - (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) (hW : ∀ i, 0 < W i) - (μ : Fin (k + 1) → Fin T) : - 0 < coeffRestrictSimple B W μ (restrictTuple μ) := by - classical - unfold coeffRestrictSimple - -- Witness term: t = μ (Fin.last k). - set t₀ : Fin T := μ (Fin.last k) with ht₀ - -- Indicator at t₀ is true: snoc (restrictTuple μ) t₀ = μ, then refl. - have h_snoc_eq : Fin.snoc (restrictTuple μ) t₀ = μ := snoc_restrict_eq μ - have h_indicator : tupleEquivSimple B W μ (Fin.snoc (restrictTuple μ) t₀) := by - rw [h_snoc_eq]; exact tupleEquivSimple_refl B W μ - -- Apply Finset.sum_pos' (nonneg + exists-positive). - refine Finset.sum_pos' ?_ ⟨t₀, Finset.mem_univ _, ?_⟩ - · intro i _ - by_cases hi : tupleEquivSimple B W μ (Fin.snoc (restrictTuple μ) i) - · rw [if_pos hi]; exact (hW i).le - · rw [if_neg hi] - · rw [if_pos h_indicator]; exact hW t₀ -/-- **Existence of an extension witness from positive coefficient**. +/-- **Canonical paper-root for #62**: every multigraph evaluation is in +the simple-profile closure. -If the restriction-weight coefficient `coeffRestrictSimple B W μ ψ` is -strictly positive (under `0 ≤ W`), then there is some `a : Fin T` such -that `Fin.snoc ψ a` is simple-equivalent to `μ` at level `k + 1`. -/ -theorem exists_extension_of_coeffRestrictSimple_pos {T k : ℕ} - (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (μ : Fin (k + 1) → Fin T) (ψ : Fin k → Fin T) - (hpos : 0 < coeffRestrictSimple B W μ ψ) : - ∃ a : Fin T, tupleEquivSimple B W μ (Fin.snoc ψ a) := by - classical - by_contra h_no - push Not at h_no - -- Every term vanishes, so the sum is 0, contradicting positivity. - have h_all_zero : ∀ t : Fin T, - (if tupleEquivSimple B W μ (Fin.snoc ψ t) then W t else 0) = 0 := by - intro t - rw [if_neg (h_no t)] - have h_sum_zero : coeffRestrictSimple B W μ ψ = 0 := by - unfold coeffRestrictSimple - exact Finset.sum_eq_zero (fun t _ => h_all_zero t) - rw [h_sum_zero] at hpos - exact lt_irrefl 0 hpos +**Proof outline** (Lovász §3 substantive content, ~300-500 LOC): +The space of functions on `tupleEquivSimple`-classes forms a finite- +dimensional ℝ-algebra. Simple-graph evaluations span this algebra (by +the rank theorem). Multigraph evaluations factor through this algebra +via the connection-matrix idempotent decomposition. The "subgraph +counts" of all multigraphs are polynomial combinations of subgraph +counts of simple graphs. -/-! ### §3.9.2 — Functional-span machinery (port of MD `functional_span_zero`) +**Status** (2026-05-19): #86 is now a clean wrapper over three cases: -To prove `coeffRestrictSimple_equiv` we use the standard finite -Stone-Weierstrass-style lemma: given a separating, unital, -multiplicatively closed family `f : I → Q → ℝ` and a `d : Q → ℝ` that -is orthogonal to every `f i` (under the counting measure), `d = 0`. + 1. **n = 0 / mults ≤ 1**: dispatched in-line via existing infrastructure + (`multiLabeledEvalK_tupleEquiv_invariant_n_zero` / simple-graph + correspondence + `h_equiv`). -This is a verbatim port of `MatrixDetermination.functional_span_zero` -(L5004) — self-contained, ~100 lines of finite induction on the support -of `d`. Used below to conclude that the class-weight difference between -`ξ` and `ξ'` over the level-`(k+1)` `tupleEquivSimple`-quotient -vanishes, given orthogonality from a product trace identity. -/ + 2. **LL-excess sub-case** (every mult≥2 edge is label-label): + **CLOSED** via `multigraphEval_LL_excess_descends_aux` (strong + induction on `M.LLSum`; iterated single-edge peel; base case + reduces to a simple graph). Polynomial decomposition à la + Lovász §3.2 (F₁F₂-product). -/-- **Functional span zero**: if a function `d : Q → ℝ` on a finite -type is orthogonal (w.r.t. counting measure) to every member of a -separating, unital, multiplicatively closed family `f : I → Q → ℝ`, -then `d` vanishes pointwise. + 3. **Unlabeled-excess sub-case** (some mult≥2 edge touches an + unlabeled vertex): **DISPATCHED** to the named paper-root + `multigraphEval_unlabeled_excess_descends` (the final residual + Lovász §3 content; ~300-500 LOC of new spectral/rank + infrastructure for the multigraph algebra `𝒜_K`). -Port of `MatrixDetermination.functional_span_zero`. -/ -private theorem functional_span_zero {Q : Type*} [Fintype Q] [DecidableEq Q] - {I : Type*} (f : I → Q → ℝ) (d : Q → ℝ) - (hconst : ∃ i₀ : I, ∀ q, f i₀ q = 1) - (hmul : ∀ i j : I, ∃ k : I, ∀ q, f k q = f i q * f j q) - (hsep : ∀ q₁ q₂ : Q, q₁ ≠ q₂ → ∃ i : I, f i q₁ ≠ f i q₂) - (hortho : ∀ i : I, ∑ q, d q * f i q = 0) : - ∀ q, d q = 0 := by - -- Strong induction on |support(d)|. - suffices key : ∀ (m : ℕ) (d : Q → ℝ), - (Finset.univ.filter (fun q => d q ≠ 0)).card ≤ m → - (∀ i : I, ∑ q, d q * f i q = 0) → - ∀ q, d q = 0 by - exact key (Finset.univ.filter (fun q => d q ≠ 0)).card d le_rfl hortho - intro m - induction m with - | zero => - intro d hm _ q - by_contra hq - have hmem : q ∈ Finset.univ.filter (fun q => d q ≠ 0) := - Finset.mem_filter.mpr ⟨Finset.mem_univ _, hq⟩ - have := Finset.card_pos.mpr ⟨q, hmem⟩ - omega - | succ m IH => - intro d hm hd_ortho - by_cases h_all_zero : ∀ q, d q = 0 - · exact h_all_zero - push Not at h_all_zero - obtain ⟨q₀, hq₀⟩ := h_all_zero - by_cases h_unique : ∀ q, q ≠ q₀ → d q = 0 - · obtain ⟨i₀, hi₀⟩ := hconst - have h := hd_ortho i₀ - simp only [hi₀, mul_one] at h - rw [show ∑ q, d q = d q₀ + ∑ q ∈ Finset.univ.erase q₀, d q from by - rw [Finset.add_sum_erase _ _ (Finset.mem_univ _)]] at h - have hzero : ∑ q ∈ Finset.univ.erase q₀, d q = 0 := - Finset.sum_eq_zero fun q hq => h_unique q (Finset.ne_of_mem_erase hq) - rw [hzero, add_zero] at h - exact absurd h hq₀ - · push Not at h_unique - obtain ⟨q₁, hq₁_ne, hq₁⟩ := h_unique - obtain ⟨i_sep, hi_sep⟩ := hsep q₀ q₁ hq₁_ne.symm - let d' : Q → ℝ := fun q => d q * (f i_sep q - f i_sep q₀) - have hd'_ortho : ∀ j : I, ∑ q, d' q * f j q = 0 := by - intro j - obtain ⟨k, hk⟩ := hmul i_sep j - show ∑ q, d q * (f i_sep q - f i_sep q₀) * f j q = 0 - have h1 : ∑ q, d q * (f i_sep q - f i_sep q₀) * f j q = - ∑ q, d q * f i_sep q * f j q - - ∑ q, d q * (f i_sep q₀ * f j q) := by - rw [(Finset.sum_sub_distrib - (f := fun q => d q * f i_sep q * f j q) - (g := fun q => d q * (f i_sep q₀ * f j q))).symm] - congr 1; ext q; ring - rw [h1] - rw [show ∑ q, d q * f i_sep q * f j q = ∑ q, d q * f k q by - congr 1; ext q; rw [hk]; ring] - rw [hd_ortho k] - rw [show ∑ q, d q * (f i_sep q₀ * f j q) = - f i_sep q₀ * ∑ q, d q * f j q by - rw [Finset.mul_sum]; congr 1; ext q; ring] - rw [hd_ortho j, mul_zero, sub_self] - have hd'q₀ : d' q₀ = 0 := by - show d q₀ * (f i_sep q₀ - f i_sep q₀) = 0; simp - have hd'_card : (Finset.univ.filter (fun q => d' q ≠ 0)).card ≤ m := by - have hsub : Finset.univ.filter (fun q => d' q ≠ 0) ⊆ - (Finset.univ.filter (fun q => d q ≠ 0)).erase q₀ := by - intro q hq - simp only [Finset.mem_filter, Finset.mem_univ, true_and] at hq - rw [Finset.mem_erase] - refine ⟨fun heq => ?_, Finset.mem_filter.mpr - ⟨Finset.mem_univ _, fun habs => ?_⟩⟩ - · subst heq; exact hq hd'q₀ - · exact hq (show d' q = 0 by - show d q * (f i_sep q - f i_sep q₀) = 0 - rw [habs, zero_mul]) - calc (Finset.univ.filter (fun q => d' q ≠ 0)).card - ≤ ((Finset.univ.filter (fun q => d q ≠ 0)).erase q₀).card := - Finset.card_le_card hsub - _ ≤ (Finset.univ.filter (fun q => d q ≠ 0)).card - 1 := - Nat.le_sub_one_of_lt (Finset.card_erase_lt_of_mem - (Finset.mem_filter.mpr ⟨Finset.mem_univ _, hq₀⟩)) - _ ≤ m := by omega - have hkey := IH d' hd'_card hd'_ortho q₁ - change d q₁ * (f i_sep q₁ - f i_sep q₀) = 0 at hkey - rcases mul_eq_zero.mp hkey with hcase | hcase - · exact absurd hcase hq₁ - · exact absurd (sub_eq_zero.mp hcase) hi_sep.symm +Step 1 (`of_const_on_tupleEquivSimple`, Lagrange fullness) is PROVED. +The only remaining sorry is inside `multigraphEval_unlabeled_excess_descends`. -/ +theorem multigraphEval_in_simpleProfileClosure {T K n : ℕ} + (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) + (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (M : MultiLabeledGraph K n) + (h_sq_moment : ∀ {ξ₀ ξ₀' : Fin K → Fin T}, + (∀ (n' : ℕ) (F : SimpleGraph (Fin (n' + K))) [DecidableRel F.Adj], + ∑ σ : Fin n' → Fin T, + (let τ : Fin (n' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ₀ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = + ∑ σ : Fin n' → Fin T, + (let τ : Fin (n' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ₀' ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) → + ∀ (c : Fin K), + ∑ t : Fin T, W t * B (ξ₀ c) t ^ 2 = ∑ t : Fin T, W t * B (ξ₀' c) t ^ 2) : + InSimpleProfileClosure B W K (fun ξ => multiLabeledEvalK K n M B W ξ) := by + apply InSimpleProfileClosure.of_const_on_tupleEquivSimple + intro ξ ξ' h_equiv + -- Descent: multiLabeledEvalK is constant on inlined-tupleEquivSimple classes. + -- Case split on n and multiplicities, matching the existing + -- `multiLabeledEvalK_tupleEquiv_invariant` (#62) wrapper structure. + -- The mult ≥ 2 case is the substantive Lovász §3 content (sorry'd here). + match n, M with + | 0, M => exact multiLabeledEvalK_tupleEquiv_invariant_n_zero B hB W M + (fun n' F hF => h_equiv n' F) + | n + 1, M => + by_cases h_mult_le_one : ∀ e, M.mult e ≤ 1 + · classical + let F : SimpleGraph (Fin ((n + 1) + K)) := + { Adj := fun a b => a ≠ b ∧ M.mult s(a, b) = 1 + symm.symm := fun a b ⟨hne, hmult⟩ => + ⟨hne.symm, by rwa [Sym2.eq_swap]⟩ + loopless.irrefl := fun a ⟨hne, _⟩ => hne rfl } + haveI : DecidableRel F.Adj := Classical.decRel _ + have hmult_eq : ∀ e, M.mult e = (MultiLabeledGraph.ofSimple F).mult e := by + intro e + induction e with + | h a b => + show M.mult s(a, b) = if s(a, b) ∈ F.edgeFinset then 1 else 0 + by_cases hM : M.mult s(a, b) = 0 + · rw [hM] + have : ¬ s(a, b) ∈ F.edgeFinset := by + rw [SimpleGraph.mem_edgeFinset, SimpleGraph.mem_edgeSet] + intro ⟨_, hmult⟩ + rw [hM] at hmult; exact absurd hmult (by omega) + rw [if_neg this] + · have hM_one : M.mult s(a, b) = 1 := by + have := h_mult_le_one s(a, b); omega + rw [hM_one] + have : s(a, b) ∈ F.edgeFinset := by + rw [SimpleGraph.mem_edgeFinset, SimpleGraph.mem_edgeSet] + refine ⟨?_, hM_one⟩ + intro hab; rw [hab] at hM_one + have := M.multNoLoop b; omega + rw [if_pos this] + have hev : ∀ ζ : Fin K → Fin T, + multiLabeledEvalK K (n + 1) M B W ζ = + multiLabeledEvalK K (n + 1) (MultiLabeledGraph.ofSimple F) B W ζ := by + intro ζ + unfold multiLabeledEvalK + refine Finset.sum_congr rfl fun σ _ => ?_ + simp_rw [hmult_eq] + rw [hev ξ, hev ξ', multiLabeledEvalK_ofSimple, multiLabeledEvalK_ofSimple] + exact h_equiv (n + 1) F + · -- Multiplicity ≥ 2 sub-case. Architectural refinement: split on + -- whether the excess multiplicity sits at label-label edges (LL, + -- handled by polynomial decomposition) or at edges touching some + -- unlabeled vertex (the genuinely hard Lovász §3 content). + classical + -- LL predicate on Sym2 pairs of vertices in `Fin ((n+1)+K)`: + -- both endpoints have val < K (i.e., are labels). + let isLL : Sym2 (Fin ((n + 1) + K)) → Prop := fun e => + Sym2.lift ⟨fun a b => (a.val < K ∧ b.val < K), + fun a b => propext ⟨fun ⟨h1, h2⟩ => ⟨h2, h1⟩, fun ⟨h1, h2⟩ => ⟨h2, h1⟩⟩⟩ e + haveI : DecidablePred isLL := fun e => + Quot.recOnSubsingleton (motive := fun e => Decidable (isLL e)) e + (fun p => (inferInstance : Decidable (p.1.val < K ∧ p.2.val < K))) + by_cases h_LL_excess : ∀ e, M.mult e ≥ 2 → isLL e + · -- **LL-excess sub-case** — CLOSED via `multigraphEval_LL_excess_descends_aux`. + -- Strong induction on M.LLSum: each iteration peels a single LL edge + -- via `multiLabeledEvalK_decAt_LL_peel`, applying h_equiv on the + -- single-edge LL graph to match B(ξ_a, ξ_b) at ξ vs ξ'. Base case: + -- all LL mults zero → M has all mults ≤ 1 → simple graph case. + have h_nonLL_le_one : ∀ e, ¬ isLLEdge e → M.mult e ≤ 1 := by + intro e he + by_contra h_ge + push Not at h_ge + have hLL := h_LL_excess e (by omega) + exact he hLL + exact multigraphEval_LL_excess_descends_aux B hB W + (fun n' F _ => h_equiv n' F) M.LLSum M h_nonLL_le_one rfl + · -- **Unlabeled-excess sub-case** — dispatched to the canonical + -- paper-root `multigraphEval_unlabeled_excess_descends`. The + -- hypothesis `h_LL_excess` is false here, so some mult≥2 edge + -- is non-LL (touches an unlabeled vertex). + have h_unlabeled_excess : + ∃ e : Sym2 (Fin ((n + 1) + K)), ¬ isLLEdge e ∧ 2 ≤ M.mult e := by + push Not at h_LL_excess + obtain ⟨e, he_mult, he_notLL⟩ := h_LL_excess + refine ⟨e, ?_, he_mult⟩ + -- The local `isLL` and the global `isLLEdge` are definitionally equal. + intro h_isLL + exact he_notLL h_isLL + exact multigraphEval_unlabeled_excess_descends B hB W hW htwin M h_unlabeled_excess + (fun n' F _ => h_equiv n' F) (h_sq_moment h_equiv) -/-! ### §3.9.3 — Simple-graph evaluation, single-graph trace identity, and - the product trace identity (named focused sorry). -We package the simple-graph evaluation body that appears inside -`tupleEquivSimple` as a noncomputable definition `simpleEvalAt`, prove -the single-graph trace identity directly from -`multiLabeledEvalK_sum_last_label`, and state the LIST-product trace -identity as a focused sorry. The product identity is the genuine -Lovász §3 content (it requires the connection-matrix / DecLabeledGraph -machinery in `MatrixDetermination.lean`, ~3000 lines), and is the SOLE -remaining gap for `coeffRestrictSimple_equiv` below. -/ +/-- **The multigraph bridge — SECONDARY paper root** (general, +non-twin-free version). -/-- Simple-graph evaluation extracted as a named definition (matching the -body of `tupleEquivSimple` and the RHS of `multiLabeledEvalK_ofSimple`). -/ -noncomputable def simpleEvalAt {T K n : ℕ} - (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (F : SimpleGraph (Fin (n + K))) [DecidableRel F.Adj] - (ξ : Fin K → Fin T) : ℝ := - ∑ σ : Fin n → Fin T, - (let τ : Fin (n + K) → Fin T := fun v => - if h : (v : ℕ) < K then ξ ⟨v, h⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n, W (σ v)) * - ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) +**Dependency hierarchy** (post-2026-05-12 architectural decision): + - **PRIMARY ROOT**: `connection_matrix_rank_theorem` (later in this file; + Lovász §3 Theorem 2.2, simple-graph form, requires twin-free). + - **SECONDARY**: this bridge (no twin-free hypothesis; strictly + stronger statement). + +For the twin-free version that downstream consumers actually need, +use `multiLabeledEvalK_tupleEquiv_invariant_twinFree` (already proved +modulo `connection_matrix_rank_theorem`). This general bridge can be +treated as off-axis if all consumers can use the twin-free variant. + +Every multigraph evaluation descends through the simple-graph version +of `tupleEquiv`. This is the Lovász §3 content (Theorem 2.2 / Lemma 2.5) +translated to our framework: simple-graph `tupleEquiv` ⟹ all +multigraph evaluations agree. + +**Hypothesis form** (`h_simple`): for every level-K simple graph +`F : SimpleGraph (Fin (n' + K))` (with any `n'` unlabeled vertices), +the simple-graph evaluations at `ξ` and `ξ'` agree. This is the +inlined definition of `tupleEquiv B W ξ ξ'`. + +**Status** (2026-05-17): designated PRIMARY PAPER-ROOT theorem +(Lovász TR-2004-82 Theorem 2.2 / Lemma 2.5 content). The n = 0 case +is dispatched via `multiLabeledEvalK_tupleEquiv_invariant_n_zero`. +The general n case requires the connection-matrix / idempotent- +decomposition argument from Lovász §3 — substantial spectral/rank +infrastructure (~300-500 LOC) beyond a quick closure. Natural +induction on n via `promote_unfold` needs a "lifted simple-equivalence" +hypothesis at level K + 1, which does NOT follow from the level-K +`h_simple` alone. + +**Downstream impact** (closes #62 ⟹ unlocks): +- IH-free Claims 4.3/4.4 (via multigraph evaluations giving + B-diagonal + W-pointwise data, currently unavailable in + simple-graph framework alone). +- Task #70 (`orbit_separation_by_simple_graph`). +- Remaining MatrixDetermination chain. + +Treat as foundational citation for downstream consumers until a +dedicated paper-root formalization project is undertaken. -/ +theorem multiLabeledEvalK_tupleEquiv_invariant {T K n : ℕ} + (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) + (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (M : MultiLabeledGraph K n) + (_h_sq_moment : ∀ {ξ₀ ξ₀' : Fin K → Fin T}, + (∀ (n'' : ℕ) (F : SimpleGraph (Fin (n'' + K))) [DecidableRel F.Adj], + ∑ σ : Fin n'' → Fin T, + (let τ : Fin (n'' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ₀ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n'', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = + ∑ σ : Fin n'' → Fin T, + (let τ : Fin (n'' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ₀' ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n'', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) → + ∀ (c : Fin K), + ∑ t : Fin T, W t * B (ξ₀ c) t ^ 2 = ∑ t : Fin T, W t * B (ξ₀' c) t ^ 2) + {ξ ξ' : Fin K → Fin T} + (h_simple : ∀ (n' : ℕ) (F : SimpleGraph (Fin (n' + K))) + [DecidableRel F.Adj], + ∑ σ : Fin n' → Fin T, + (let τ : Fin (n' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) = + ∑ σ : Fin n' → Fin T, + (let τ : Fin (n' + K) → Fin T := fun v => + if h : (v : ℕ) < K then ξ' ⟨v, h⟩ + else σ ⟨v - K, by have := v.isLt; omega⟩ + (∏ v : Fin n', W (σ v)) * + ∏ e ∈ F.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) : + multiLabeledEvalK K n M B W ξ = multiLabeledEvalK K n M B W ξ' := by + obtain ⟨σ, hσ_aut, hconj⟩ := + tupleEquivSimple_implies_orbit_general B hB W hW htwin ξ ξ' h_simple + exact multiLabeledEvalK_eq_of_orbit B hB W M ⟨σ, hσ_aut.1, hσ_aut.2, hconj⟩ -/-- `simpleEvalAt` is `multiLabeledEvalK` on `MultiLabeledGraph.ofSimple`. -/ -private theorem simpleEvalAt_eq_multi {T K n : ℕ} - (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (F : SimpleGraph (Fin (n + K))) [DecidableRel F.Adj] - (ξ : Fin K → Fin T) : - simpleEvalAt B W F ξ = - multiLabeledEvalK K n (MultiLabeledGraph.ofSimple F) B W ξ := by - rw [multiLabeledEvalK_ofSimple]; rfl /-- **Product trace identity (named focused sorry)** — the LIST-product analog of `simpleEvalAt_trace_eq` below. @@ -6399,69 +8444,8 @@ theorem orbitIndicator_of_not_orbit {T K : ℕ} unfold orbitIndicator simp [h] -/-- **Orbit indicators lie in the ℝ-span of simple-graph evaluations** -(Lovász §3 — fullness of the simple-graph evaluation algebra under -twin-free `B`) — **SECONDARY / OFF-AXIS** (post-2026-05-13 reanalysis). - -For any source tuple `ξ : Fin K → Fin T`, the orbit indicator -`orbitIndicator B W ξ` can be written as an ℝ-linear combination of -simple-graph evaluations `simpleEvalAt B W F : (Fin K → Fin T) → ℝ` -(ranging over simple graphs `F` on `Fin (n + K)` for various `n`). - -**Status reverted to OFF-AXIS**: the natural Lagrange-interpolation -route produces PRODUCTS of `simpleEvalAt` (= multigraph evals via -glue), not linear combinations. Converting back to a linear -combination of simple-graph evals would itself need Lemma 2.5 -content — circular. - -The PRIMARY ROOT is now `orbit_separation_by_simple_graph` (the -contrapositive form, which doesn't require product expansion). This -span theorem is a stronger CONSEQUENCE that may follow from -separation + the multigraph bridge. - -The representation uses pairs `(c, ⟨n, ⟨F, dec⟩⟩)` where -`c : ℝ` is a coefficient, `n : ℕ` is an unlabeled-vertex count, -`F : SimpleGraph (Fin (n + K))` is a simple labeled graph, and -`dec : DecidableRel F.Adj` is the required decidability witness. - -**Status**: canonical primary sorry (migrated from -`orbit_separation_by_simple_graph`). - -**Proof approach** (Lovász §3): the simple-graph evaluation algebra -under twin-free `B` is **dense** in the space of orbit-invariant -functions; the orbit indicators form a basis of this latter space; -hence each indicator is a finite ℝ-linear combination. This is the -multigraph-algebra fullness theorem of Lovász §3, restricted to -simple graphs under the twin-free hypothesis. - -**Natural Lagrange-interpolation route** (per post-2026-05-13 user -analysis): for each orbit class O' ≠ orbit(ξ), pick a separating -simple graph F_{O'} (its existence is `orbit_separation_by_simple_graph`, -PROVED from this theorem — a circular dependency). The indicator is -the product `∏_{O' ≠ orbit(ξ)} (simpleEvalAt F_{O'} - w_{O'}) / -(v_{O'} - w_{O'})` over orbit classes. - -**Obstacle** (multigraph-vs-simple-graph product): expanding the -product yields PRODUCTS of `simpleEvalAt`s, which via the -glue-multigraph identity are MULTIGRAPH evaluations (since disjoint -unions of simple graphs at shared labels can produce label-label -multi-edges). Converting these multigraph evals back to simple-graph -linear combinations is itself the Lemma 2.5 content. The -contrapositive `orbit_separation_by_simple_graph` does NOT have this -issue (it just exhibits a single separating graph) — so the -"separation" form may be the actually attackable formulation, with -the span form derived from it via a careful product-expansion route. -/ -theorem orbitIndicator_mem_simpleGraphSpan {T K : ℕ} - (B : Fin T → Fin T → ℝ) (_hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) - (_hW : ∀ i, 0 < W i) - (_htwin : ∀ i j, i ≠ j → B i ≠ B j) - (ξ : Fin K → Fin T) : - ∃ (cs : List (ℝ × Σ (n : ℕ) (F : SimpleGraph (Fin (n + K))), - DecidableRel F.Adj)), - orbitIndicator B W ξ = fun η => - (cs.map (fun p => - p.1 * @simpleEvalAt T K p.2.1 B W p.2.2.1 p.2.2.2 η)).sum := by - sorry +-- `orbitIndicator_mem_simpleGraphSpan` MOVED below § RankTheorem (2026-07-02) and PROVED +-- there (list repackaging of `tupleOrbitIndicator_mem_simpleEvalSpan`). /-! ### Orbit separation: edge-or-degree → simple-graph form @@ -7305,16 +9289,15 @@ theorem rootedOrbitIndicator_const_on_orbit {T : ℕ} · rw [if_pos h, if_pos (h_iff.mp h)] · rw [if_neg h, if_neg (h_iff.not.mp h)] + /-- **General-K orbit separation theorem** (Lovász §3 contrapositive form). If two tuples `ξ ξ' : Fin K → Fin T` are NOT in the same `(B, W)`-orbit, some level-K simple-graph evaluation separates them. -**Status** (2026-07-02): the mathematical content is PROVED — this statement -is the contrapositive of `tupleEquivSimple_implies_orbit_general` -(`Graphon/CaiGovorovOrbit.lean`, the Cai–Govorov descent, axiom-clean). -Filling this sorry in place requires relocating that stack above Lovász -§3.10 (a pending refactor); until then the sorry stays, documented. +**Status** (2026-07-02): PROVED — the contrapositive of +`tupleEquivSimple_implies_orbit_general` (the Cai–Govorov descent, +§ CaiGovorovStack above, axiom-clean). (Historical note: a 2026-05-17 version of this docstring recorded the theorem as BLOCKED on #62 via IH-free Claims 4.3/4.4, with the analysis @@ -7333,19 +9316,13 @@ theorem orbit_separation_by_simple_graph {T K : ℕ} (_h : ¬ tupleOrbitRel B W ξ ξ') : ∃ (n : ℕ) (F : SimpleGraph (Fin (n + K))) (_ : DecidableRel F.Adj), simpleEvalAt B W F ξ ≠ simpleEvalAt B W F ξ' := by - -- Derivable as contrapositive of `tupleEquivSimple_implies_orbit` - -- (declared later in the file). After the 2026-05-20 refactor, - -- `tupleEquivSimple_implies_orbit` no longer routes through this theorem, - -- so the cycle is broken. - -- - -- **PROVED DOWNSTREAM (2026-07-02)**: the general theorem is - -- `tupleEquivSimple_implies_orbit_general` in `Graphon/CaiGovorovOrbit.lean` - -- (super-surjective case + eq. (10) Cai–Govorov descent, axiom-clean), and - -- this statement is its contrapositive. Discharging THIS upstream sorry in - -- place would require relocating that stack above Lovász §3.10; until that - -- refactor it stays, documented — nothing on the #70 critical path depends - -- on it (the rank theorem lives in `Graphon/SimpleOrbitRank.lean`). - sorry + -- Contrapositive of the Cai–Govorov descent (`tupleEquivSimple_implies_orbit_general`, + -- § CaiGovorovStack above): `tupleEquivSimple` is definitionally the family of + -- `simpleEvalAt` equalities. + by_contra hcon + push_neg at hcon + exact _h (tupleEquivSimple_implies_orbit_general B _hB W _hW _htwin ξ ξ' + (fun n F inst => hcon n F inst)) /-- **Orbit separation, identity case** — narrowest case of `orbit_separation_by_simple_graph` where `K = T` and the source tuple is @@ -7448,21 +9425,13 @@ Steps in the inductive case `m = k + 1`: induction refactor on `(deficit, size)` which is beyond a strong `Nat`-induction on `size` alone. -**Status**: proved modulo (i) the Claim 4.2 sub-sorry -(`product_trace_identity_simple` via `tupleEquivSimple_extend`), and -(ii) a refined sorry at the inner-base of the deficit-induction in the -non-surjective branch — specifically the case `T - 1 ≥ k + 1` (i.e., -`T ≥ k + 2`) where the outer strong-induction-on-`K` cannot supply the -IH at size `T - 1` required by `tupleEquivSimple_surjective_case`. - -The architectural sorry has been REFACTORED: the previous "neither -α nor ξ surj" case is now CLOSED via deficit-induction (Lovász's -"extend-and-recurse") for the sub-case `T ≤ k + 1`. The residual -sub-case `T > k + 1` remains as a more specific sorry, requiring -either a deeper refactor of `tupleEquivSimple_surjective_case` / -`tupleEquivSimple_id_bijective` to avoid the deficit-1 IH (see -`MatrixDetermination.lean:11002-11007`) or an alternative argument at -that specific inner-base point. +**Status** (2026-07-02): PROVED, sorry-free. The historically-residual +"both α and φ non-surjective" branch is closed by the Cai–Govorov +descent (`tupleEquivSimple_implies_orbit_general`, § CaiGovorovStack +above), which needs neither surjectivity nor the deficit-1 IH. +(Earlier state, for the record: the branch had been reduced by +deficit-induction to the inner-base sub-case `T > k + 1`, which +resisted every IH-based plan — see the historical analysis below.) **Architectural obstacle** (post-2026-05-12 subagent analysis; **superseded 2026-07-02** — see below): an IH-free @@ -7571,43 +9540,20 @@ theorem tupleEquivSimple_implies_orbit {T K : ℕ} tupleEquivSimple B W φ' ψ' → tupleOrbitRel B W φ' ψ' := fun {φ' ψ'} h' => IH_strong (T - 1) hT1_lt φ' ψ' h' exact tupleEquivSimple_surjective_case B W hW hB htwin IH_T1 φ ψ hφ_surj hpsi - · -- **Both α and φ non-surjective** — THE critical sorry of the - -- simple-graph Lemma 2.4 (#70). (A pre-2026-06 version of this - -- comment labeled it "#62"; the multigraph #62/#73 chain has since - -- been proved independently — `tupleEquivMulti_implies_orbit` and - -- its roots are sorry-free and do NOT route through here.) - -- - -- **Still tainted by THIS sorry** (simple-graph side): the chain - -- `k1_orbit_sep_aux` → `mkRootedSeparator` → - -- `InRootedProfileSpan.of_const_on_orbit` → - -- `label_unlabeled_square_moment_descends` (and its - -- `multigraphEval_label_unlabeled_isolated_descends` consumers) - -- routes through this theorem — those remain sorry-tainted until - -- this sorry is filled (see below). - -- - -- **Triangular cycle** (after session 3 analysis): - -- Lemma 2.4 (K=1 non-surj) ↔ k1_orbit_sep_aux ↔ of_const_on_orbit - -- All three are mutually equivalent and form a triangular - -- self-reference; a direct proof here must not route through them. - -- - -- **Option A FAILED** (separator-free of_const_on_orbit): - -- RP-class-invariance cannot be upgraded to orbit-invariance - -- without Lemma 2.4 K=1 — exactly the cycle. The downstream - -- square-moment proof needs orbit-invariance (B(i,t)² is not a - -- simple-graph factor), so the weaker theorem doesn't suffice. - -- - -- **PROVED DOWNSTREAM (2026-07-02)**: the general theorem is - -- `tupleEquivSimple_implies_orbit_general` in - -- `Graphon/CaiGovorovOrbit.lean` — the Cai–Govorov descent: - -- super-surjective case `testEvalEq_implies_orbit_super` + the - -- eq. (10) extension/Vandermonde matching (axiom-clean). Filling - -- THIS sorry in place would require relocating that stack above - -- Lovász §3.10; it stays documented until that refactor. (The - -- former "Option B" — the Lovász §3 rank/dimension argument — is - -- REALIZED: `simpleEvalSubmodule_finrank_ge_orbitClass` and the - -- rank collapse are PROVED in `Graphon/SimpleOrbitRank.lean` via - -- the annihilator argument fed by the same machinery.) - sorry + · -- **Both α and φ non-surjective** — historically THE critical sorry + -- of the simple-graph Lemma 2.4 (#70); CLOSED 2026-07-02 by the + -- Cai–Govorov descent (`tupleEquivSimple_implies_orbit_general`, + -- § CaiGovorovStack above), which needs no surjectivity and no IH. + -- With it, the formerly-tainted simple-graph chain + -- (`k1_orbit_sep_aux` → `of_const_on_orbit` → + -- `label_unlabeled_square_moment_descends`) is sorry-free. + -- (Historical notes: the earlier plans failed on a triangular + -- self-reference — Lemma 2.4 K=1 ↔ k1_orbit_sep_aux ↔ + -- of_const_on_orbit — and RP-class-invariance could not be + -- upgraded to orbit-invariance without re-entering the cycle. The + -- descent bypasses all of it; the "Option B" rank argument is + -- ALSO realized independently, see the rank-theorem section.) + exact tupleEquivSimple_implies_orbit_general B hB W hW htwin φ ψ hpsi /-! ### §3.10.5a — `InTupleSimpleEvalSpan` predicate and algebra closure @@ -7946,21 +9892,8 @@ theorem InTupleMultiEvalSpan.aut_invariant {T K : ℕ} (B : Fin T → Fin T → refine Finset.sum_congr rfl fun k _ => ?_ rw [multiLabeledEvalK_aut_invariant B W (g k).2 σ hσ.1 hσ.2 ξ] -/-- **Multigraph algebra collapses to the simple-graph algebra** (Lovász §3 / -Lemma 2.5 content). Under twin-free `B` and positive `W`, every -multigraph-eval span element is also a simple-eval span element. This is the -genuine hard direction: the Hadamard-square obstruction (label–label -multiplicity ≥ 2) lives exactly here, so it cannot reduce to the bounded glue -algebra. SORRY — one of the two honest §3 residues (the other being -`tupleOrbitIndicator_mem_multiEvalSpan`); one or both may be discharged by the -same Lovász §3 rank/idempotent argument. The hypotheses are required (without -twin-free/positivity the collapse is false) and match -`tupleOrbitIndicator_mem_simpleEvalSpan`, so the bridge composes downstream. -/ -theorem InTupleMultiEvalSpan.toSimple {T K : ℕ} {B : Fin T → Fin T → ℝ} - (hB : ∀ i j, B i j = B j i) {W : Fin T → ℝ} (hW : ∀ i, 0 < W i) - (htwin : ∀ i j, i ≠ j → B i ≠ B j) {f : (Fin K → Fin T) → ℝ} - (h : InTupleMultiEvalSpan B W f) : InTupleSimpleEvalSpan B W f := by - sorry +-- `InTupleMultiEvalSpan.toSimple` MOVED below § RankTheorem (2026-07-02), where its proof +-- (the rank collapse `orbitInvariantSubmodule_le_simpleEvalSubmodule`) is in scope. /-! #### Lagrange construction of orbit indicators in the multigraph span @@ -9481,31 +11414,8 @@ weighted-hom-determines-isomorphism / connection-rank theorem. This scaffolding no critical-path consumers (the residues stay `multiEval_separates_orbits` and `InTupleMultiEvalSpan.toSimple`). -/ -/-- **Closure under pointwise multiplication for the simple-graph span** — -OFF THE CRITICAL PATH; superseded by the multigraph route. - -This is NOT a bounded "mirror K=1" lemma. The K=1 analog -`InRootedProfileSpan.mul` works only because `K = 1` has a single root vertex, -hence no label–label edges; for `K ≥ 2` two simple graphs sharing a label–label -edge `{i,j}` force a Hadamard square `B(ξ_i,ξ_j)²` (since `ofSimple` caps -multiplicity at 1 but `glue` adds), which no simple graph can produce. So -`ofSimple_tupleProduct_eq_glue` / `simpleEvalAt_tupleProduct` are FALSE for -`K ≥ 2`, and (without twin-free/positivity) unconditional simple `.mul` is -itself false; with those hypotheses it is true only as a corollary of full -Lemma 2.5. See `Lovasz.lean` §3.10.5a-multi and the note near -`orbitIndicator_mem_simpleGraphSpan`. - -The honest route lives in the multigraph algebra: products are bounded there -(`InTupleMultiEvalSpan.mul` via `multiLabeledEvalK_glue`), and the genuine -difficulty is isolated as `InTupleMultiEvalSpan.toSimple`. Once `.toSimple` (and -`hB/hW/htwin`) are available this is provable as -`(h₁.toMulti.mul hB h₂.toMulti).toSimple hB hW htwin`; that statement change is -deferred. Left as `sorry` (no current code consumers). -/ -theorem InTupleSimpleEvalSpan.mul {T K : ℕ} {B : Fin T → Fin T → ℝ} {W : Fin T → ℝ} - {f₁ f₂ : (Fin K → Fin T) → ℝ} - (_h₁ : InTupleSimpleEvalSpan B W f₁) (_h₂ : InTupleSimpleEvalSpan B W f₂) : - InTupleSimpleEvalSpan B W (fun ξ => f₁ ξ * f₂ ξ) := by - sorry +-- `InTupleSimpleEvalSpan.mul` MOVED below § RankTheorem (2026-07-02) and PROVED there via +-- `.toSimple` (with the `hB hW htwin` hypotheses its docstring always said it needs). /-- **Simple-graph evaluations are automorphism-invariant**. @@ -9531,6 +11441,519 @@ theorem simpleEvalAt_aut_invariant {T K n : ℕ} exact multiLabeledEvalK_eq_of_orbit B hB W (MultiLabeledGraph.ofSimple F) ⟨σ.symm, hσs_aut.1, hσs_aut.2, fun i => (σ.symm_apply_apply _).symm⟩ +section RankTheorem + +/-! +### The #70 rank theorem: eval spans as `Submodule`s + the finrank collapse + +Moved here from `CycleKrylov.lean` (submodule packaging, Phase A/B) and the dissolved +`SimpleOrbitRank.lean` (Phase C1+D + the annihilator argument), 2026-07-02. Sits directly +after `simpleEvalAt_aut_invariant` and the Cai–Govorov stack — everything it needs. +-/ + +open Finset + +/-! ### Eval spans as `Submodule`s (Phase A — foundation for the §3 rank/finrank work) + +The K-tuple simple- and multigraph-eval spans, currently bare existential predicates +(`InTupleSimpleEvalSpan` / `InTupleMultiEvalSpan` in `Lovasz.lean`), are repackaged here +as honest `Submodule ℝ`s. This unlocks `finrank`/`Basis`/`≤` for the rank argument that +isolates the sole #70 residue `InTupleMultiEvalSpan.toSimple`. The membership-`iff`s tie +the new submodules back to the existing predicate API, which stays the interface for +construction. -/ + +/-- The K-tuple **simple-eval span** as a submodule: spanned by the simple-graph +evaluation functions `ξ ↦ simpleEvalAt B W F ξ`. -/ +noncomputable def simpleEvalSubmodule {T : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (K : ℕ) : Submodule ℝ ((Fin K → Fin T) → ℝ) := + Submodule.span ℝ + (Set.range (fun p : Σ (n : ℕ) (F : SimpleGraph (Fin (n + K))), DecidableRel F.Adj => + (fun ξ => @simpleEvalAt T K p.1 B W p.2.1 p.2.2 ξ))) + +/-- The K-tuple **multigraph-eval span** as a submodule: spanned by the multigraph +evaluation functions `ξ ↦ multiLabeledEvalK K n M B W ξ`. -/ +noncomputable def multiEvalSubmodule {T : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (K : ℕ) : Submodule ℝ ((Fin K → Fin T) → ℝ) := + Submodule.span ℝ + (Set.range (fun p : Σ (n : ℕ), MultiLabeledGraph K n => + (fun ξ => multiLabeledEvalK K p.1 p.2 B W ξ))) + +/-- Submodule membership coincides with the existing simple-eval span predicate +`InTupleSimpleEvalSpan`. -/ +theorem mem_simpleEvalSubmodule_iff {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (f : (Fin K → Fin T) → ℝ) : + f ∈ simpleEvalSubmodule B W K ↔ InTupleSimpleEvalSpan B W f := by + constructor + · intro hf + unfold simpleEvalSubmodule at hf + induction hf using Submodule.span_induction with + | mem x hx => + obtain ⟨p, rfl⟩ := hx + exact @InTupleSimpleEvalSpan.of_simple T K p.1 B W p.2.1 p.2.2 + | zero => exact InTupleSimpleEvalSpan.zero B W + | add x y _ _ hx hy => exact hx.add hy + | smul a x _ hx => exact InTupleSimpleEvalSpan.smul a hx + · intro hf + obtain ⟨N, g, c, rfl⟩ := hf + have hsum : + (fun ξ => ∑ k : Fin N, c k * @simpleEvalAt T K (g k).1 B W (g k).2.1 (g k).2.2 ξ) + = ∑ k : Fin N, c k • + (fun ξ => @simpleEvalAt T K (g k).1 B W (g k).2.1 (g k).2.2 ξ) := by + funext ξ + rw [Finset.sum_apply] + exact Finset.sum_congr rfl fun k _ => by rw [Pi.smul_apply, smul_eq_mul] + rw [hsum] + exact Submodule.sum_mem _ fun k _ => + Submodule.smul_mem _ _ (Submodule.subset_span ⟨g k, rfl⟩) + +/-- Submodule membership coincides with the existing multigraph-eval span predicate +`InTupleMultiEvalSpan`. -/ +theorem mem_multiEvalSubmodule_iff {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (f : (Fin K → Fin T) → ℝ) : + f ∈ multiEvalSubmodule B W K ↔ InTupleMultiEvalSpan B W f := by + constructor + · intro hf + unfold multiEvalSubmodule at hf + induction hf using Submodule.span_induction with + | mem x hx => + obtain ⟨p, rfl⟩ := hx + exact InTupleMultiEvalSpan.of_multi B W p.2 + | zero => exact InTupleMultiEvalSpan.zero B W + | add x y _ _ hx hy => exact hx.add hy + | smul a x _ hx => exact InTupleMultiEvalSpan.smul a hx + · intro hf + obtain ⟨N, g, c, rfl⟩ := hf + have hsum : + (fun ξ => ∑ k : Fin N, c k * multiLabeledEvalK K (g k).1 (g k).2 B W ξ) + = ∑ k : Fin N, c k • (fun ξ => multiLabeledEvalK K (g k).1 (g k).2 B W ξ) := by + funext ξ + rw [Finset.sum_apply] + exact Finset.sum_congr rfl fun k _ => by rw [Pi.smul_apply, smul_eq_mul] + rw [hsum] + exact Submodule.sum_mem _ fun k _ => + Submodule.smul_mem _ _ (Submodule.subset_span ⟨g k, rfl⟩) + +/-! ### Orbit-invariant submodule and `multiEvalSubmodule = orbitInvariant` (Phase B) + +The genuinely informative half of the rank framework, and **non-circular**: the +multigraph-eval submodule equals the submodule of automorphism-invariant functions. The +`≥` direction rests on the directly-proved (toSimple-free) `tupleOrbitIndicator_mem_multiEvalSpan`. +This pins the sole #70 residue to exactly `simpleEvalSubmodule = orbitInvariantSubmodule`. -/ + +/-- The submodule of `(B, W)`-automorphism-invariant functions of a K-tuple. -/ +def orbitInvariantSubmodule {T : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) (K : ℕ) : + Submodule ℝ ((Fin K → Fin T) → ℝ) where + carrier := { f | ∀ σ : Equiv.Perm (Fin T), IsWeightedAutomorphism B W σ → + ∀ ξ, f (σ ∘ ξ) = f ξ } + add_mem' := by + intro a b hf hg σ hσ ξ + simp only [Pi.add_apply]; rw [hf σ hσ ξ, hg σ hσ ξ] + zero_mem' := by intro σ hσ ξ; rfl + smul_mem' := by + intro c a hf σ hσ ξ + simp only [Pi.smul_apply, smul_eq_mul]; rw [hf σ hσ ξ] + +/-- **Automorphism-invariant ⟹ multigraph-eval span** (the multi analog of +`tupleSimpleEval_span_aut_invariant`, but NON-circular — it consumes the directly-proved +`tupleOrbitIndicator_mem_multiEvalSpan`, never `InTupleMultiEvalSpan.toSimple`). Orbit +indicators are a basis of the invariant functions, and each lies in the multi span. -/ +theorem tupleMultiEval_span_aut_invariant {T K : ℕ} + (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) + (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (f : (Fin K → Fin T) → ℝ) + (h_aut_inv : ∀ (σ : Equiv.Perm (Fin T)), + IsWeightedAutomorphism B W σ → ∀ ξ, f (σ ∘ ξ) = f ξ) : + InTupleMultiEvalSpan B W f := by + classical + let S : Setoid (Fin K → Fin T) := + ⟨tupleOrbitRel B W, tupleOrbitRel_refl B W, + fun h => tupleOrbitRel_symm B W h, + fun h₁ h₂ => tupleOrbitRel_trans B W h₁ h₂⟩ + haveI : Fintype (Quotient S) := Quotient.fintype S + have h_decomp : f = fun ξ => + ∑ q : Quotient S, f (Quotient.out q) * orbitIndicator B W (Quotient.out q) ξ := by + funext ξ + let q₀ : Quotient S := Quotient.mk S ξ + have hq₀_out : tupleOrbitRel B W (Quotient.out q₀) ξ := by + have := Quotient.mk_out (s := S) ξ + exact this + rw [show + (∑ q : Quotient S, + f (Quotient.out q) * orbitIndicator B W (Quotient.out q) ξ) = + f (Quotient.out q₀) * orbitIndicator B W (Quotient.out q₀) ξ + + ∑ q ∈ Finset.univ.erase q₀, + f (Quotient.out q) * orbitIndicator B W (Quotient.out q) ξ from + (Finset.add_sum_erase _ _ (Finset.mem_univ q₀)).symm] + have h_other_zero : ∀ q ∈ Finset.univ.erase q₀, + f (Quotient.out q) * orbitIndicator B W (Quotient.out q) ξ = 0 := by + intro q hq + rw [Finset.mem_erase] at hq + have h_q_ne : q ≠ q₀ := hq.1 + have h_not_orbit : ¬ tupleOrbitRel B W (Quotient.out q) ξ := by + intro h_orbit + apply h_q_ne + rw [← Quotient.out_eq q, ← Quotient.out_eq q₀] + exact Quotient.sound (Setoid.trans h_orbit (Setoid.symm hq₀_out)) + rw [orbitIndicator_of_not_orbit B W h_not_orbit, mul_zero] + rw [Finset.sum_eq_zero h_other_zero, add_zero] + have h_f_eq : f (Quotient.out q₀) = f ξ := by + obtain ⟨σ, hσ, hσeq⟩ := hq₀_out + have hξ : ξ = σ ∘ Quotient.out q₀ := funext hσeq + rw [hξ, h_aut_inv σ hσ] + have h_ind_one : orbitIndicator B W (Quotient.out q₀) ξ = 1 := by + unfold orbitIndicator + rw [if_pos hq₀_out] + rw [h_f_eq, h_ind_one, mul_one] + rw [h_decomp] + apply InTupleMultiEvalSpan.finset_sum + intro q _ + exact InTupleMultiEvalSpan.smul (f (Quotient.out q)) + (tupleOrbitIndicator_mem_multiEvalSpan B hB W hW htwin (Quotient.out q)) + +/-- **`≤`: multigraph evaluations are automorphism-invariant.** -/ +theorem multiEvalSubmodule_le_orbitInvariantSubmodule {T K : ℕ} + (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) : + multiEvalSubmodule B W K ≤ orbitInvariantSubmodule B W K := by + intro f hf + rw [mem_multiEvalSubmodule_iff] at hf + exact fun σ hσ ξ => InTupleMultiEvalSpan.aut_invariant B W hf σ hσ ξ + +/-- **`≥`: every automorphism-invariant function lies in the multigraph-eval span** +(non-circular, via `tupleMultiEval_span_aut_invariant`). -/ +theorem orbitInvariantSubmodule_le_multiEvalSubmodule {T K : ℕ} + (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) + (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) : + orbitInvariantSubmodule B W K ≤ multiEvalSubmodule B W K := by + intro f hf + rw [mem_multiEvalSubmodule_iff] + exact tupleMultiEval_span_aut_invariant B hB W hW htwin f hf + +/-- **The multigraph-eval submodule is exactly the automorphism-invariant submodule.** +The clean, non-circular pillar of the §3 rank framework: the residue is now precisely +`simpleEvalSubmodule = orbitInvariantSubmodule`. -/ +theorem multiEvalSubmodule_eq_orbitInvariantSubmodule {T K : ℕ} + (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) + (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) : + multiEvalSubmodule B W K = orbitInvariantSubmodule B W K := + le_antisymm (multiEvalSubmodule_le_orbitInvariantSubmodule B W) + (orbitInvariantSubmodule_le_multiEvalSubmodule B hB W hW htwin) + +/-- **Easy inclusion `simpleEvalSubmodule ≤ orbitInvariantSubmodule`**: simple-graph +evaluations are automorphism-invariant (`simpleEvalAt_aut_invariant`). Completes the +clean frame `simpleEvalSubmodule ≤ orbitInvariantSubmodule = multiEvalSubmodule`; the +sole #70 residue is the reverse inclusion. -/ +theorem simpleEvalSubmodule_le_orbitInvariantSubmodule {T K : ℕ} + (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) : + simpleEvalSubmodule B W K ≤ orbitInvariantSubmodule B W K := by + intro f hf + rw [mem_simpleEvalSubmodule_iff] at hf + intro σ hσ ξ + obtain ⟨N, g, c, hfeq⟩ := hf + rw [congr_fun hfeq (σ ∘ ξ), congr_fun hfeq ξ] + refine Finset.sum_congr rfl fun k _ => ?_ + rw [@simpleEvalAt_aut_invariant T K (g k).1 B hB W (g k).2.1 (g k).2.2 σ hσ ξ] + +/-- **Corollary `simpleEvalSubmodule ≤ multiEvalSubmodule`** (the never-in-doubt +inclusion), directly via `InTupleSimpleEvalSpan.toMulti`. -/ +theorem simpleEvalSubmodule_le_multiEvalSubmodule {T K : ℕ} + (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) : + simpleEvalSubmodule B W K ≤ multiEvalSubmodule B W K := by + intro f hf + rw [mem_simpleEvalSubmodule_iff] at hf + rw [mem_multiEvalSubmodule_iff] + exact hf.toMulti + + + +noncomputable instance instFintypeOrbitClass {T K : ℕ} {B : Fin T → Fin T → ℝ} {W : Fin T → ℝ} : + Fintype (OrbitClass T K B W) := by + classical + unfold OrbitClass + exact Quotient.fintype _ + +/-- Evaluation-at-orbit-representatives, as a linear map from the orbit-invariant +functions to functions on the orbit quotient. -/ +noncomputable def orbitInvariantToClassFun {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) : + orbitInvariantSubmodule B W K →ₗ[ℝ] (OrbitClass T K B W → ℝ) where + toFun f := fun q => (f : (Fin K → Fin T) → ℝ) (Quotient.out q) + map_add' f g := by funext q; simp + map_smul' c f := by funext q; simp + +/-- **Orbit-invariant functions ≅ functions on the orbit quotient.** -/ +noncomputable def orbitInvariantEquiv {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) : + orbitInvariantSubmodule B W K ≃ₗ[ℝ] (OrbitClass T K B W → ℝ) := + LinearEquiv.ofBijective (orbitInvariantToClassFun B W) (by + constructor + · -- injective: agreement on representatives + orbit-invariance ⟹ equal + intro f₁ f₂ h + apply Subtype.ext + funext ξ + have key : ∀ (g : orbitInvariantSubmodule B W K) (η : Fin K → Fin T), + (g : (Fin K → Fin T) → ℝ) η + = (g : (Fin K → Fin T) → ℝ) + (Quotient.out (Quotient.mk (tupleOrbitSetoid B W K) η)) := by + intro g η + obtain ⟨σ, hσ, hση⟩ := Quotient.mk_out (s := tupleOrbitSetoid B W K) η + have hηeq : η = σ ∘ Quotient.out (Quotient.mk (tupleOrbitSetoid B W K) η) := funext hση + conv_lhs => rw [hηeq] + exact g.2 σ hσ _ + rw [key f₁ ξ, key f₂ ξ] + exact congrFun h (Quotient.mk (tupleOrbitSetoid B W K) ξ) + · -- surjective: pull back a class function + intro g + refine ⟨⟨fun η => g (Quotient.mk (tupleOrbitSetoid B W K) η), ?_⟩, ?_⟩ + · intro σ hσ η + show g (Quotient.mk (tupleOrbitSetoid B W K) (σ ∘ η)) + = g (Quotient.mk (tupleOrbitSetoid B W K) η) + have hmk : Quotient.mk (tupleOrbitSetoid B W K) η + = Quotient.mk (tupleOrbitSetoid B W K) (σ ∘ η) := + Quotient.sound ⟨σ, hσ, fun i => rfl⟩ + rw [hmk] + · funext q + show g (Quotient.mk (tupleOrbitSetoid B W K) (Quotient.out q)) = g q + rw [Quotient.out_eq]) + +/-- **Phase C1: `finrank orbitInvariantSubmodule = #OrbitClass`.** -/ +theorem finrank_orbitInvariantSubmodule {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) : + Module.finrank ℝ (orbitInvariantSubmodule B W K) = Fintype.card (OrbitClass T K B W) := by + rw [(orbitInvariantEquiv B W).finrank_eq, Module.finrank_fintype_fun_eq_card] + +/-! ### The annihilator lemma (chunk 5B) + +Any `c : OrbitClass → ℝ` that annihilates every simple evaluation at orbit representatives is +zero. This is STRICTLY stronger than point-separation of the orbit classes (distinct rows can +still be linearly dependent); the signed single-family Vandermonde over +`OrbitClass × (Fin m → Fin T)` does the real work, powered by the Cai–Govorov descent +ingredients (`sum_extensions_eval`, `expTestGraph`, `testEvalEq_implies_orbit_super`). -/ + +/-- Reindexing the test-moment power product along `Fintype.equivFin` (profile form). -/ +private theorem prod_profile_pow {T L : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (μ : Fin L → Fin T) (k : Fin (Fintype.card (TestCoord L)) → ℕ) : + ∏ c : TestCoord L, (testMoment B W c μ) ^ k (Fintype.equivFin (TestCoord L) c) + = ∏ c, (testProfile B W μ c) ^ k c := by + calc ∏ c : TestCoord L, (testMoment B W c μ) ^ k (Fintype.equivFin (TestCoord L) c) + = ∏ c : TestCoord L, (testProfile B W μ (Fintype.equivFin (TestCoord L) c)) + ^ k (Fintype.equivFin (TestCoord L) c) := by + refine Finset.prod_congr rfl fun c _ => ?_ + congr 1 + show testMoment B W c μ + = testMoment B W ((Fintype.equivFin (TestCoord L)).symm + (Fintype.equivFin (TestCoord L) c)) μ + rw [Equiv.symm_apply_apply] + _ = ∏ c, (testProfile B W μ c) ^ k c := + Equiv.prod_comp (Fintype.equivFin (TestCoord L)) + (fun c => (testProfile B W μ c) ^ k c) + +/-- **The annihilator lemma.** If `∑ q, c q · simpleEvalAt F (out q) = 0` for every simple +graph `F`, then `c = 0`. Signed Vandermonde over `OrbitClass × (Fin m → Fin T)` with the +test-moment profile of `Fin.append (out q) ρ` as classifier: the class of the profile of +`superExt (out q₀)` consists exactly of pairs `(q₀, ρ)` (chunk 4A at level `K + m` forces +`q = q₀`), and its `W`-mass is positive, so the class-sum `c q₀ · (positive) = 0` kills +`c q₀`. -/ +theorem eval_rep_annihilator_zero {T K : ℕ} (B : Fin T → Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (hW : ∀ i, 0 < W i) + (htwin : ∀ i j, i ≠ j → B i ≠ B j) (c : OrbitClass T K B W → ℝ) + (hc : ∀ (n : ℕ) (F : SimpleGraph (Fin (n + K))) (inst : DecidableRel F.Adj), + ∑ q, c q * @simpleEvalAt T K n B W F inst (Quotient.out q) = 0) : + c = 0 := by + classical + funext q₀ + show c q₀ = 0 + -- ρ-form of the extension-sum collapse (eq. (10), one side). + have hρsum : ∀ (n : ℕ) (G : SimpleGraph (Fin (n + (K + T * (2 * T ^ 2))))) + (_ : DecidableRel G.Adj) (ζ : Fin K → Fin T), + ∑ ρ : Fin (T * (2 * T ^ 2)) → Fin T, + (∏ j, W (ρ j)) * simpleEvalAt B W G (Fin.append ζ ρ) + = simpleEvalAt B W (unlabelExtras G) ζ := fun n G _ ζ => + (sum_extensions_eq_sum_rho B W G ζ).symm.trans (sum_extensions_eval B hB W G ζ) + -- Moment vanishing for the signed family over `OrbitClass × (Fin m → Fin T)`. + have hmom : ∀ ℓ : Fin (Fintype.card (TestCoord (K + T * (2 * T ^ 2)))) → ℕ, + (∀ j, ℓ j < Fintype.card (OrbitClass T K B W × (Fin (T * (2 * T ^ 2)) → Fin T))) → + ∑ i : OrbitClass T K B W × (Fin (T * (2 * T ^ 2)) → Fin T), + (c i.1 * ∏ j, W (i.2 j)) + * ∏ j, (testProfile B W (Fin.append (Quotient.out i.1) i.2) j) ^ ℓ j = 0 := by + intro ℓ _ + rw [Fintype.sum_prod_type] + have hterm : ∀ q : OrbitClass T K B W, + ∑ ρ : Fin (T * (2 * T ^ 2)) → Fin T, + (c q * ∏ j, W (ρ j)) + * ∏ j, (testProfile B W (Fin.append (Quotient.out q) ρ) j) ^ ℓ j + = c q * simpleEvalAt B W + (unlabelExtras (expTestGraph + (fun c' => ℓ (Fintype.equivFin (TestCoord (K + T * (2 * T ^ 2))) c')))) + (Quotient.out q) := by + intro q + rw [← hρsum _ (expTestGraph + (fun c' => ℓ (Fintype.equivFin (TestCoord (K + T * (2 * T ^ 2))) c'))) + inferInstance (Quotient.out q), Finset.mul_sum] + refine Finset.sum_congr rfl fun ρ _ => ?_ + rw [simpleEvalAt_expTestGraph B hB W _ (Fin.append (Quotient.out q) ρ), + prod_profile_pow B W (Fin.append (Quotient.out q) ρ) ℓ] + ring + rw [Finset.sum_congr rfl fun q _ => hterm q] + exact hc _ _ inferInstance + -- Class-sum at the profile of `superExt (out q₀)`. + have hclass := CaiGovorov.multivariate_vandermonde_class_sums_zero + (fun i : OrbitClass T K B W × (Fin (T * (2 * T ^ 2)) → Fin T) => + testProfile B W (Fin.append (Quotient.out i.1) i.2)) + (fun i => c i.1 * ∏ j, W (i.2 j)) hmom + (testProfile B W (superExt (Quotient.out q₀))) + -- The class forces `q = q₀` (chunk 4A at level K + m). + have hq_eq : ∀ (q : OrbitClass T K B W) (ρ : Fin (T * (2 * T ^ 2)) → Fin T), + testProfile B W (Fin.append (Quotient.out q) ρ) + = testProfile B W (superExt (Quotient.out q₀)) → q = q₀ := by + intro q ρ hprof + have hTE : TestEvalEq B W (superExt (Quotient.out q₀)) (Fin.append (Quotient.out q) ρ) := + (testEvalEq_iff_moments B hB W).mpr fun c' => (testProfile_eq_iff.mp hprof c').symm + obtain ⟨σ, hσ_aut, hσ⟩ := testEvalEq_implies_orbit_super B hB W hW htwin _ _ + (superExt_superSurjective (Quotient.out q₀)) hTE + have horb : tupleOrbitRel B W (Quotient.out q₀) (Quotient.out q) := by + refine ⟨σ, hσ_aut, fun i => ?_⟩ + have hi := hσ (Fin.castAdd (T * (2 * T ^ 2)) i) + rw [Fin.append_left, superExt_extends (Quotient.out q₀) i] at hi + exact hi + have hmk : Quotient.mk (tupleOrbitSetoid B W K) (Quotient.out q₀) + = Quotient.mk (tupleOrbitSetoid B W K) (Quotient.out q) := Quotient.sound horb + rw [Quotient.out_eq, Quotient.out_eq] at hmk + exact hmk.symm + -- The class is exactly `{q₀} ×ˢ P` for the ρ-side class `P`. + have hfilter_eq : (univ.filter + (fun i : OrbitClass T K B W × (Fin (T * (2 * T ^ 2)) → Fin T) => + testProfile B W (Fin.append (Quotient.out i.1) i.2) + = testProfile B W (superExt (Quotient.out q₀)))) + = {q₀} ×ˢ (univ.filter (fun ρ : Fin (T * (2 * T ^ 2)) → Fin T => + testProfile B W (Fin.append (Quotient.out q₀) ρ) + = testProfile B W (superExt (Quotient.out q₀)))) := by + ext ⟨q, ρ⟩ + simp only [Finset.mem_filter, Finset.mem_univ, true_and, Finset.mem_product, + Finset.mem_singleton] + constructor + · intro hprof + obtain rfl := hq_eq q ρ hprof + exact ⟨rfl, hprof⟩ + · rintro ⟨rfl, hprof⟩ + exact hprof + -- Collapse the class-sum to `c q₀ · (positive W-mass)`. + have hmass : c q₀ * ∑ ρ ∈ univ.filter (fun ρ : Fin (T * (2 * T ^ 2)) → Fin T => + testProfile B W (Fin.append (Quotient.out q₀) ρ) + = testProfile B W (superExt (Quotient.out q₀))), ∏ j, W (ρ j) = 0 := by + rw [Finset.mul_sum, ← hclass, hfilter_eq, Finset.sum_product, Finset.sum_singleton] + have hpos : (0 : ℝ) < ∑ ρ ∈ univ.filter (fun ρ : Fin (T * (2 * T ^ 2)) → Fin T => + testProfile B W (Fin.append (Quotient.out q₀) ρ) + = testProfile B W (superExt (Quotient.out q₀))), ∏ j, W (ρ j) := + Finset.sum_pos (fun ρ _ => Finset.prod_pos fun j _ => hW _) + ⟨coverExtra T, Finset.mem_filter.mpr ⟨Finset.mem_univ _, rfl⟩⟩ + exact (mul_eq_zero.mp hmass).resolve_right (ne_of_gt hpos) + +/-! ### The dual-pairing endgame (chunk 5C) + +The representative pairing turns the annihilator lemma into injectivity of a map into the +dual of `simpleEvalSubmodule`; comparing dimensions gives the lower bound. Transcribes the +`hle1` half of `connectionMatrix_full_rank_of_orthogonal` (`Spectral.lean`). -/ + +/-- The representative pairing `⟨c, f⟩ := ∑ q, c q · f (Quotient.out q)` as a bilinear map +(mirrors `orbitInnerBil`). -/ +noncomputable def evalRepPairing {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) : + (OrbitClass T K B W → ℝ) →ₗ[ℝ] ((Fin K → Fin T) → ℝ) →ₗ[ℝ] ℝ := + LinearMap.mk₂ ℝ (fun c f => ∑ q, c q * f (Quotient.out q)) + (fun c₁ c₂ f => by + simp only [← Finset.sum_add_distrib] + refine Finset.sum_congr rfl fun q _ => ?_ + simp only [Pi.add_apply]; ring) + (fun r c f => by + simp only [Finset.smul_sum] + refine Finset.sum_congr rfl fun q _ => ?_ + simp only [Pi.smul_apply, smul_eq_mul]; ring) + (fun c f₁ f₂ => by + simp only [← Finset.sum_add_distrib] + refine Finset.sum_congr rfl fun q _ => ?_ + simp only [Pi.add_apply]; ring) + (fun r c f => by + simp only [Finset.smul_sum] + refine Finset.sum_congr rfl fun q _ => ?_ + simp only [Pi.smul_apply, smul_eq_mul]; ring) + +@[simp] lemma evalRepPairing_apply {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) + (c : OrbitClass T K B W → ℝ) (f : (Fin K → Fin T) → ℝ) : + evalRepPairing B W c f = ∑ q, c q * f (Quotient.out q) := rfl + +/-- **The simple-side lower bound** (the genuine Lovász §3 content, formerly the sole #70 +residue): the simple-eval span has dimension at least the number of orbit classes. The +composite `Ψ := subtype.dualMap ∘ evalRepPairing` is injective by the annihilator lemma, so +`#OrbitClass = finrank (OrbitClass → ℝ) ≤ finrank (Dual simpleEvalSubmodule) += finrank simpleEvalSubmodule`. -/ +theorem simpleEvalSubmodule_finrank_ge_orbitClass {T K : ℕ} + (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) + (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) : + Fintype.card (OrbitClass T K B W) ≤ Module.finrank ℝ (simpleEvalSubmodule B W K) := by + classical + set Ψ : (OrbitClass T K B W → ℝ) →ₗ[ℝ] Module.Dual ℝ (simpleEvalSubmodule B W K) := + (simpleEvalSubmodule B W K).subtype.dualMap ∘ₗ evalRepPairing B W with hΨ + have hΨinj : Function.Injective Ψ := by + rw [← LinearMap.ker_eq_bot, LinearMap.ker_eq_bot'] + intro c hcker + refine eval_rep_annihilator_zero B hB W hW htwin c fun n F inst => ?_ + have hgen := LinearMap.congr_fun hcker + (⟨fun ξ => @simpleEvalAt T K n B W F inst ξ, + Submodule.subset_span ⟨⟨n, F, inst⟩, rfl⟩⟩ : simpleEvalSubmodule B W K) + simpa only [hΨ, LinearMap.comp_apply, LinearMap.dualMap_apply, Submodule.subtype_apply, + evalRepPairing_apply, LinearMap.zero_apply] using hgen + have h1 : Module.finrank ℝ (OrbitClass T K B W → ℝ) + ≤ Module.finrank ℝ (Module.Dual ℝ (simpleEvalSubmodule B W K)) := + LinearMap.finrank_le_finrank_of_injective hΨinj + rw [Subspace.dual_finrank_eq] at h1 + rw [← Module.finrank_pi (ι := OrbitClass T K B W) ℝ] + exact h1 + +/-- **Phase D: the rank collapse** — the simple-eval and orbit-invariant submodules coincide +(unconditional: the lower bound `simpleEvalSubmodule_finrank_ge_orbitClass` is proved above). +This is the #70 rank theorem. -/ +theorem simpleEvalSubmodule_eq_orbitInvariantSubmodule {T K : ℕ} + (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) + (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) : + simpleEvalSubmodule B W K = orbitInvariantSubmodule B W K := + Submodule.eq_of_le_of_finrank_le + (simpleEvalSubmodule_le_orbitInvariantSubmodule B hB W) + (by rw [finrank_orbitInvariantSubmodule B W] + exact simpleEvalSubmodule_finrank_ge_orbitClass B hB W hW htwin) + +/-- **The hard inclusion** `orbitInvariantSubmodule ≤ simpleEvalSubmodule`. -/ +theorem orbitInvariantSubmodule_le_simpleEvalSubmodule {T K : ℕ} + (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) + (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) : + orbitInvariantSubmodule B W K ≤ simpleEvalSubmodule B W K := + (simpleEvalSubmodule_eq_orbitInvariantSubmodule B hB W hW htwin).ge + +/-! ### Corollaries of the rank collapse: the former §3 residues -/ + +/-- **Multigraph algebra collapses to the simple-graph algebra** (Lovász Lemma 2.5 content). +Under twin-free `B` and positive `W`, every multigraph-eval span element is also a +simple-eval span element. Formerly the Hadamard-square residue; now a direct corollary of +the rank collapse: multigraph evals are automorphism-invariant, and orbit-invariant +functions lie in the simple-eval span. -/ +theorem InTupleMultiEvalSpan.toSimple {T K : ℕ} {B : Fin T → Fin T → ℝ} + (hB : ∀ i j, B i j = B j i) {W : Fin T → ℝ} (hW : ∀ i, 0 < W i) + (htwin : ∀ i j, i ≠ j → B i ≠ B j) {f : (Fin K → Fin T) → ℝ} + (h : InTupleMultiEvalSpan B W f) : InTupleSimpleEvalSpan B W f := by + rw [← mem_simpleEvalSubmodule_iff] + exact orbitInvariantSubmodule_le_simpleEvalSubmodule B hB W hW htwin + (multiEvalSubmodule_le_orbitInvariantSubmodule B W + ((mem_multiEvalSubmodule_iff B W f).mpr h)) + +/-- **Closure under pointwise multiplication for the simple-graph span** (with the twin-free +and positivity hypotheses its earlier docstring recorded as necessary — without them the +statement is false; the label–label Hadamard square obstructs any bounded proof). Routes +through the multigraph algebra: `.toMulti`, bounded `.mul` via `glue`, and the rank-collapse +`.toSimple`. -/ +theorem InTupleSimpleEvalSpan.mul {T K : ℕ} {B : Fin T → Fin T → ℝ} + (hB : ∀ i j, B i j = B j i) {W : Fin T → ℝ} (hW : ∀ i, 0 < W i) + (htwin : ∀ i j, i ≠ j → B i ≠ B j) {f₁ f₂ : (Fin K → Fin T) → ℝ} + (h₁ : InTupleSimpleEvalSpan B W f₁) (h₂ : InTupleSimpleEvalSpan B W f₂) : + InTupleSimpleEvalSpan B W (fun ξ => f₁ ξ * f₂ ξ) := + (h₁.toMulti.mul hB h₂.toMulti).toSimple hB hW htwin + +end RankTheorem + /-! ### §3.10.5 — Lovász Lemma 2.5 (column-space rank theorem) **Lovász Lemma 2.5** (paper page 6): Let `G` be a twin-free weighted @@ -9624,6 +12047,27 @@ theorem tupleOrbitIndicator_mem_simpleEvalSpan {T K : ℕ} InTupleMultiEvalSpan.toSimple hB hW htwin (tupleOrbitIndicator_mem_multiEvalSpan B hB W hW htwin ξ) +/-- **Orbit indicators lie in the ℝ-span of simple-graph evaluations** (Lovász §3 fullness, +list form). List repackaging of `tupleOrbitIndicator_mem_simpleEvalSpan` — the +representation uses pairs `(c, ⟨n, ⟨F, dec⟩⟩)` of a coefficient and a decidably-adjacent +simple labeled graph. -/ +theorem orbitIndicator_mem_simpleGraphSpan {T K : ℕ} + (B : Fin T → Fin T → ℝ) (_hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) + (_hW : ∀ i, 0 < W i) + (_htwin : ∀ i j, i ≠ j → B i ≠ B j) + (ξ : Fin K → Fin T) : + ∃ (cs : List (ℝ × Σ (n : ℕ) (F : SimpleGraph (Fin (n + K))), + DecidableRel F.Adj)), + orbitIndicator B W ξ = fun η => + (cs.map (fun p => + p.1 * @simpleEvalAt T K p.2.1 B W p.2.2.1 p.2.2.2 η)).sum := by + obtain ⟨N, g, c, hf⟩ := tupleOrbitIndicator_mem_simpleEvalSpan B _hB W _hW _htwin ξ + refine ⟨(List.finRange N).map (fun k => (c k, g k)), ?_⟩ + rw [hf] + funext η + rw [List.map_map, Fin.sum_univ_def] + rfl + theorem tupleSimpleEval_span_aut_invariant {T K : ℕ} (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) diff --git a/Graphon/MatrixDetermination.lean b/Graphon/MatrixDetermination.lean index 69730d0..88b0f33 100644 --- a/Graphon/MatrixDetermination.lean +++ b/Graphon/MatrixDetermination.lean @@ -6927,7 +6927,9 @@ L7150). This `Dtr` theorem remains in the file as a documented generalization with its own narrowed sorry (`∃ a, lu0Mult a ≥ 1` case at the σ-sum level), but is not on the active proof axis. Future sessions: do NOT route new content through this theorem. -/ -/-- **Restricted invariance theorem** (with `h_noDiag` hypothesis). +/-! **Restricted invariance theorem** (with `h_noDiag` hypothesis) — the theorem itself +MOVED below the multigraph bridge (2026-07-02) and is PROVED there; this note retains the +falsification analysis that motivated the `h_noDiag` restriction. **Falsification of the original unrestricted statement.** The earlier version of this theorem quantified over arbitrary @@ -6948,80 +6950,10 @@ satisfied by every traced object arising from the `DecLabeledGraph.ofSimple/mul/one/.trace` pipeline (see the `exists_decGraph_for_connCol` construction). -**Proof status.** The LL factor is closed in-line by adapting the -`DecLabeledGraph.eval_tupleEquiv_invariant` (L6182) pattern. The σ-sum -part is the actual remaining multigraph-content frontier (the -`Dtr.lu0FactorAt` term encodes parallel B-edges that simple-graph -`tupleEquiv` does not directly constrain). -/ -private theorem DecLabeledGraphTr.eval_tupleEquiv_invariant {T K n : ℕ} - (Dtr : DecLabeledGraphTr K n) (B : Fin T → Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) - (h_noDiag : ∀ x : Fin K, Dtr.llMult s(x, x) = 0) - {ξ ξ' : Fin K → Fin T} (h : tupleEquiv B W ξ ξ') : - Dtr.eval B W ξ = Dtr.eval B W ξ' := by - classical - unfold DecLabeledGraphTr.eval - congr 1 - · -- LL factor invariance via the generic helper. - exact llFactor_eq_of_tupleEquiv B hB W Dtr.llMult h_noDiag h - · -- σ-sum invariance — case-split per user directive into: - -- n = 0 (trivial), n > 0 ∧ lu0Mult = 0 (reduces to labeledEvalK), and - -- n > 0 ∧ ∃ a, lu0Mult a ≥ 1 (the multi-edge content, still sorry). - by_cases hn : n = 0 - · -- **Case n = 0.** σ has unique empty function; W-prod = 1; lu0Factor = 1 - -- (n = 0 branch); edgeFinset = ∅ (all K vertices are labels, so any edge - -- would be LL, forbidden by Dtr.noLL). Both sides reduce to 1. - subst hn - letI : DecidableRel Dtr.graph.Adj := Classical.decRel _ - have hempty : Dtr.graph.edgeFinset = ∅ := by - rw [← Finset.subset_empty] - intro e he - exfalso - rw [SimpleGraph.mem_edgeFinset] at he - refine Sym2.ind (fun a b hadj => ?_) e he - have ha : a.val < K := by have := a.isLt; omega - have hb : b.val < K := by have := b.isLt; omega - exact Dtr.noLL a b ha hb hadj - refine Finset.sum_congr rfl fun σ _ => ?_ - have hlu0_eq : Dtr.lu0FactorAt B ξ σ = Dtr.lu0FactorAt B ξ' σ := by - unfold DecLabeledGraphTr.lu0FactorAt - simp - simp only [hempty, Finset.prod_empty, mul_one, hlu0_eq] - · -- **Case n > 0.** - by_cases hlu0_zero : ∀ a : Fin K, Dtr.lu0Mult a = 0 - · -- **Sub-case ∀ a, lu0Mult a = 0.** lu0Factor = 1; σ-sum = labeledEvalK - -- Dtr.graph at level K, n unlabeled. Apply tupleEquiv h n Dtr.graph. - letI : DecidableRel Dtr.graph.Adj := Classical.decRel _ - have hbridge : ∀ ζ : Fin K → Fin T, - (∑ σ : Fin n → Fin T, - (let τ : Fin (n + K) → Fin T := fun v => - if hh : (v : ℕ) < K then ζ ⟨v, hh⟩ - else σ ⟨v - K, by have := v.isLt; omega⟩ - (∏ v : Fin n, W (σ v)) * Dtr.lu0FactorAt B ζ σ * - ∏ e ∈ Dtr.graph.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2))) = - labeledEvalK K n Dtr.graph B W ζ := by - intro ζ - unfold labeledEvalK - refine Finset.sum_congr rfl fun σ _ => ?_ - have hlu0_one : Dtr.lu0FactorAt B ζ σ = 1 := by - unfold DecLabeledGraphTr.lu0FactorAt - split_ifs with hpos - · refine Finset.prod_eq_one fun a _ => ?_ - rw [hlu0_zero a, pow_zero] - · rfl - rw [hlu0_one] - ring - rw [hbridge ξ, hbridge ξ'] - exact h n Dtr.graph - · -- **Sub-case ∃ a, lu0Mult a ≥ 1.** This is the genuine multi-edge - -- content: `Dtr.lu0FactorAt B ξ σ` includes at least one factor - -- `B(ξ a, σ 0)^{lu0Mult a}` with lu0Mult a ≥ 1. For lu0Mult a ≤ 1 - -- the factor is a single B-edge, expressible via a modified simple - -- graph G' = Dtr.graph + edges {(label a, unlabeled 0) : lu0Mult a = 1}; - -- σ-sum = labeledEvalK G'. (Closure of the lu0Mult ≤ 1 sub-case is - -- bounded but routine; deferred.) For lu0Mult a ≥ 2, parallel B-edges - -- — the precise Lovász §3 multigraph frontier. -/ - sorry +**Proof status (2026-07-02): CLOSED.** For `n > 0` the whole σ-sum is a single multigraph +evaluation (`DecLabeledGraphTr.eval_eq_multiEval`), descended by the (proved) multigraph +bridge `multiLabeledEvalK_tupleEquiv_invariant`; the parallel-edge frontier the old note +described dissolved into the multigraph semantics. -/ /-! **The named algebraic residue.** σ-sum equality for the trace-origin parallel-edge case: `∃ a, D.trace.lu0Mult a ≥ 2`. @@ -7192,7 +7124,9 @@ private theorem multiLabeledEvalK_ofSimple {T K n : ℕ} -- After `set`, both σ-sum bodies should reference τ. exact congrArg _ (hprod τ) -/-- **The multigraph bridge — canonical sorry.** +/-- **The multigraph bridge** — PROVED, sorry-free (the "canonical sorry" +framing below is historical; it was discharged when the Lovász-module orbit +route landed). Every multigraph evaluation descends through `tupleEquiv` at level K. This is the Lovász §3 content (Theorem 2.2 / Lemma 2.5) translated to @@ -7200,7 +7134,7 @@ our framework: simple-graph `tupleEquiv` ⟹ all multigraph evaluations agree (since simple-graph evaluations span the multigraph evaluation algebra `f_k(𝒢_k) ⊆ 𝒜_k`, and aut-orbits coincide). -**Status**: single canonical sorry replacing all of: +**Status (historical)**: single canonical sorry replacing all of: - `tupleEquiv_single_coord_square_moment_independent` (closed below); - `DecLabeledGraph.trace_parallel_lu0_descends` (closed below); - `DecLabeledGraphTr.eval_tupleEquiv_invariant` (off-axis, unaffected). @@ -7255,6 +7189,181 @@ private theorem multiLabeledEvalK_tupleEquiv_invariant {T K n : ℕ} exact Graphon.Lovasz.multiLabeledEvalK_eq_of_orbit B hB W M' ⟨σ, hσ_aut.1, hσ_aut.2, hσξ⟩ +/-- The traced decorated graph's σ-sum content as a `MultiLabeledGraph` (for `n > 0`): +graph edges with multiplicity 1, plus the label-to-unlabeled-0 decorations `lu0Mult a` as +multi-edges `s(⟨a⟩, ⟨K⟩)`. Multiplicities from the two sources ADD (a graph edge may +coincide with an lu0 edge), which is exactly the multigraph semantics. -/ +private noncomputable def DecLabeledGraphTr.toMulti {K n : ℕ} (Dtr : DecLabeledGraphTr K n) + (hn : 0 < n) : MultiLabeledGraph K n := + letI : DecidableRel Dtr.graph.Adj := Classical.decRel _ + { mult := fun e => + (if e ∈ Dtr.graph.edgeFinset then 1 else 0) + + ∑ a : Fin K, if e = s((⟨a.val, by have := a.isLt; omega⟩ : Fin (n + K)), + (⟨K, by omega⟩ : Fin (n + K))) then Dtr.lu0Mult a else 0 + multNoLoop := fun x => by + letI : DecidableRel Dtr.graph.Adj := Classical.decRel _ + have h1 : (if s(x, x) ∈ Dtr.graph.edgeFinset then 1 else 0) = 0 := by + rw [if_neg] + intro hmem + rw [SimpleGraph.mem_edgeFinset, SimpleGraph.mem_edgeSet] at hmem + exact Dtr.graph.irrefl hmem + have h2 : ∀ a : Fin K, + (if s(x, x) = s((⟨a.val, by have := a.isLt; omega⟩ : Fin (n + K)), + (⟨K, by omega⟩ : Fin (n + K))) then Dtr.lu0Mult a else 0) = 0 := by + intro a + rw [if_neg] + intro heq + rcases Sym2.eq_iff.mp heq with ⟨ha', hb'⟩ | ⟨ha', hb'⟩ + · have h3 : (⟨a.val, by have := a.isLt; omega⟩ : Fin (n + K)) + = (⟨K, by omega⟩ : Fin (n + K)) := ha'.symm.trans hb' + have h4 : a.val = K := congrArg Fin.val h3 + have := a.isLt + omega + · have h3 : (⟨a.val, by have := a.isLt; omega⟩ : Fin (n + K)) + = (⟨K, by omega⟩ : Fin (n + K)) := hb'.symm.trans ha' + have h4 : a.val = K := congrArg Fin.val h3 + have := a.isLt + omega + rw [h1, Finset.sum_eq_zero fun a _ => h2 a] + rfl } + +/-- **τ-generic Sym2-product split for `toMulti`**: the multigraph B-power product factors +into the simple edge product times the per-label lu0 powers. -/ +private theorem DecLabeledGraphTr.toMulti_sym2_prod {T K n : ℕ} (Dtr : DecLabeledGraphTr K n) + (hn : 0 < n) (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) + (τ : Fin (n + K) → Fin T) : + letI : DecidableRel Dtr.graph.Adj := Classical.decRel _ + (∏ e : Sym2 (Fin (n + K)), B (τ (Quot.out e).1) (τ (Quot.out e).2) ^ (Dtr.toMulti hn).mult e) + = (∏ e ∈ Dtr.graph.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) + * ∏ a : Fin K, B (τ ⟨a.val, by have := a.isLt; omega⟩) (τ ⟨K, by omega⟩) + ^ Dtr.lu0Mult a := by + letI : DecidableRel Dtr.graph.Adj := Classical.decRel _ + have hsplit : (∏ e : Sym2 (Fin (n + K)), B (τ (Quot.out e).1) (τ (Quot.out e).2) + ^ (Dtr.toMulti hn).mult e) + = (∏ e : Sym2 (Fin (n + K)), B (τ (Quot.out e).1) (τ (Quot.out e).2) + ^ (if e ∈ Dtr.graph.edgeFinset then 1 else 0)) + * ∏ e : Sym2 (Fin (n + K)), B (τ (Quot.out e).1) (τ (Quot.out e).2) + ^ ∑ a : Fin K, if e = s((⟨a.val, by have := a.isLt; omega⟩ : Fin (n + K)), + (⟨K, by omega⟩ : Fin (n + K))) then Dtr.lu0Mult a else 0 := by + rw [← Finset.prod_mul_distrib] + refine Finset.prod_congr rfl fun e _ => ?_ + rw [← pow_add] + rfl + rw [hsplit] + congr 1 + · rw [← Finset.prod_filter_mul_prod_filter_not (Finset.univ : Finset (Sym2 (Fin (n + K)))) + (· ∈ Dtr.graph.edgeFinset)] + have hnot : (∏ e ∈ (Finset.univ : Finset (Sym2 (Fin (n + K)))).filter + (fun e => ¬ e ∈ Dtr.graph.edgeFinset), + B (τ (Quot.out e).1) (τ (Quot.out e).2) + ^ (if e ∈ Dtr.graph.edgeFinset then 1 else 0)) = 1 := + Finset.prod_eq_one fun e he => by + rw [Finset.mem_filter] at he + rw [if_neg he.2, pow_zero] + rw [hnot, mul_one, + show ((Finset.univ : Finset (Sym2 (Fin (n + K)))).filter (· ∈ Dtr.graph.edgeFinset)) + = Dtr.graph.edgeFinset from by ext e; simp] + refine Finset.prod_congr rfl fun e he => ?_ + rw [if_pos he, pow_one] + · have hswap : ∀ e : Sym2 (Fin (n + K)), + B (τ (Quot.out e).1) (τ (Quot.out e).2) + ^ (∑ a : Fin K, if e = s((⟨a.val, by have := a.isLt; omega⟩ : Fin (n + K)), + (⟨K, by omega⟩ : Fin (n + K))) then Dtr.lu0Mult a else 0) + = ∏ a : Fin K, (if e = s((⟨a.val, by have := a.isLt; omega⟩ : Fin (n + K)), + (⟨K, by omega⟩ : Fin (n + K))) + then B (τ (Quot.out e).1) (τ (Quot.out e).2) ^ Dtr.lu0Mult a else 1) := by + intro e + rw [← Finset.prod_pow_eq_pow_sum] + refine Finset.prod_congr rfl fun a _ => ?_ + rw [pow_ite, pow_zero] + have h1 : (∏ e : Sym2 (Fin (n + K)), B (τ (Quot.out e).1) (τ (Quot.out e).2) + ^ ∑ a : Fin K, if e = s((⟨a.val, by have := a.isLt; omega⟩ : Fin (n + K)), + (⟨K, by omega⟩ : Fin (n + K))) then Dtr.lu0Mult a else 0) + = ∏ e : Sym2 (Fin (n + K)), ∏ a : Fin K, + (if e = s((⟨a.val, by have := a.isLt; omega⟩ : Fin (n + K)), + (⟨K, by omega⟩ : Fin (n + K))) + then B (τ (Quot.out e).1) (τ (Quot.out e).2) ^ Dtr.lu0Mult a else 1) := + Finset.prod_congr rfl fun e _ => hswap e + rw [h1, Finset.prod_comm] + refine Finset.prod_congr rfl fun a _ => ?_ + rw [Finset.prod_ite_eq' Finset.univ + (s((⟨a.val, by have := a.isLt; omega⟩ : Fin (n + K)), (⟨K, by omega⟩ : Fin (n + K)))) + (fun e => B (τ (Quot.out e).1) (τ (Quot.out e).2) ^ Dtr.lu0Mult a), + if_pos (Finset.mem_univ _)] + exact congrArg (· ^ Dtr.lu0Mult a) (Lovasz.out_pair_eq' B hB τ _ _) + +/-- **`Dtr.eval` is a multigraph evaluation** (times the LL factor), for `n > 0`. -/ +private theorem DecLabeledGraphTr.eval_eq_multiEval {T K n : ℕ} (Dtr : DecLabeledGraphTr K n) + (hn : 0 < n) (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) + (ζ : Fin K → Fin T) : + Dtr.eval B W ζ + = (∏ e : Sym2 (Fin K), B (ζ (Quot.out e).1) (ζ (Quot.out e).2) ^ Dtr.llMult e) + * multiLabeledEvalK K n (Dtr.toMulti hn) B W ζ := by + letI : DecidableRel Dtr.graph.Adj := Classical.decRel _ + unfold DecLabeledGraphTr.eval multiLabeledEvalK + congr 1 + refine Finset.sum_congr rfl fun σ _ => ?_ + have hgen : ∀ τ : Fin (n + K) → Fin T, + (∀ a : Fin K, τ ⟨a.val, by have := a.isLt; omega⟩ = ζ a) → + τ ⟨K, by omega⟩ = σ ⟨0, hn⟩ → + (∏ v : Fin n, W (σ v)) * Dtr.lu0FactorAt B ζ σ * + (∏ e ∈ Dtr.graph.edgeFinset, B (τ (Quot.out e).1) (τ (Quot.out e).2)) + = (∏ v : Fin n, W (σ v)) * + ∏ e : Sym2 (Fin (n + K)), + B (τ (Quot.out e).1) (τ (Quot.out e).2) ^ (Dtr.toMulti hn).mult e := by + intro τ hlab hu0 + rw [DecLabeledGraphTr.toMulti_sym2_prod Dtr hn B hB τ] + have hlu0 : (∏ a : Fin K, B (τ ⟨a.val, by have := a.isLt; omega⟩) (τ ⟨K, by omega⟩) + ^ Dtr.lu0Mult a) = Dtr.lu0FactorAt B ζ σ := by + unfold DecLabeledGraphTr.lu0FactorAt + rw [dif_pos hn] + refine Finset.prod_congr rfl fun a _ => ?_ + rw [hlab a, hu0] + rw [hlu0] + ring + exact hgen + (fun v => if h : (v : ℕ) < K then ζ ⟨v, h⟩ else σ ⟨v - K, by have := v.isLt; omega⟩) + (fun a => dif_pos a.isLt) + ((dif_neg (Nat.lt_irrefl K)).trans (congrArg σ (Fin.ext (Nat.sub_self K)))) + +/-- **σ-sum + LL-factor invariance for traced decorated graphs** — the former σ-sum +frontier, CLOSED (2026-07-02): for `n > 0` the entire σ-sum is a multigraph evaluation +(`eval_eq_multiEval`), and the multigraph bridge (`multiLabeledEvalK_tupleEquiv_invariant`, +via the Lovász orbit route) descends it through `tupleEquiv`. Requires `hW`/`htwin` +(inherited from the bridge); the `n = 0` case is direct. -/ +private theorem DecLabeledGraphTr.eval_tupleEquiv_invariant {T K n : ℕ} + (Dtr : DecLabeledGraphTr K n) (B : Fin T → Fin T → ℝ) + (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (hW : ∀ i, 0 < W i) + (htwin : ∀ i j, i ≠ j → B i ≠ B j) + (h_noDiag : ∀ x : Fin K, Dtr.llMult s(x, x) = 0) + {ξ ξ' : Fin K → Fin T} (h : tupleEquiv B W ξ ξ') : + Dtr.eval B W ξ = Dtr.eval B W ξ' := by + classical + rcases Nat.eq_zero_or_pos n with hn | hn + · subst hn + unfold DecLabeledGraphTr.eval + congr 1 + · exact llFactor_eq_of_tupleEquiv B hB W Dtr.llMult h_noDiag h + · letI : DecidableRel Dtr.graph.Adj := Classical.decRel _ + have hempty : Dtr.graph.edgeFinset = ∅ := by + rw [← Finset.subset_empty] + intro e he + exfalso + rw [SimpleGraph.mem_edgeFinset] at he + refine Sym2.ind (fun a b hadj => ?_) e he + have ha : a.val < K := by have := a.isLt; omega + have hb : b.val < K := by have := b.isLt; omega + exact Dtr.noLL a b ha hb hadj + refine Finset.sum_congr rfl fun σ _ => ?_ + have hlu0_eq : Dtr.lu0FactorAt B ξ σ = Dtr.lu0FactorAt B ξ' σ := by + unfold DecLabeledGraphTr.lu0FactorAt + simp + simp only [hempty, Finset.prod_empty, mul_one, hlu0_eq] + · rw [Dtr.eval_eq_multiEval hn B hB W ξ, Dtr.eval_eq_multiEval hn B hB W ξ'] + congr 1 + · exact llFactor_eq_of_tupleEquiv B hB W Dtr.llMult h_noDiag h + · exact multiLabeledEvalK_tupleEquiv_invariant B hB W hW htwin (Dtr.toMulti hn) h + /-- **CANONICAL MINIMAL ALGEBRAIC RESIDUE** of the Lovász §3 multigraph content. Independent K=1 single-coord square moment. @@ -10889,16 +10998,13 @@ private theorem tupleEquiv_ext_eq_of_surj {T : ℕ} For twin-free `(B, W)` with positive weights, `tupleEquiv B W φ ψ` implies `tupleOrbitRel B W φ ψ` at every label level `k`. -Proved by induction on `k`: -- **k = 0**: trivial. -- **k + 1**: restrict to level `k` (Claim 4.1), apply IH to get automorphism `σ`, - normalize `ψ` by `σ⁻¹` so the first `k` coordinates agree, then show the last - coordinates must also agree (surjective-base case via `tupleEquiv_ext_eq_of_surj`), - or find an additional automorphism (general case). - -The non-surjective base case (when `restrictTuple φ` does not cover all of `Fin T`) -requires the full Lovász algebra `A_k` / graph-product multiplicative closure -argument and remains as a sorry. -/ +PROVED (2026-07-02, sorry-free): bridged to the Lovász module's simple-graph +Lemma 2.4 (`Lovasz.tupleEquivSimple_implies_orbit_via_2_5`, itself proved via the +#70 rank theorem / Cai–Govorov machinery) — `tupleEquiv` is definitionally +`Lovasz.tupleEquivSimple` after unfolding `labeledEvalK`. (The previous body ran +Lovász's induction on `k` with Claims 4.1–4.4 and carried the non-surjective +base case as the file's architectural sorry; the intermediate claims remain +above as standalone theorems.) -/ private theorem tupleEquiv_implies_tupleOrbitRel {T : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) (hW : ∀ i, 0 < W i) (hB : ∀ i j, B i j = B j i) @@ -10906,137 +11012,17 @@ private theorem tupleEquiv_implies_tupleOrbitRel {T : ℕ} {k : ℕ} {φ ψ : Fin k → Fin T} (h : tupleEquiv B W φ ψ) : tupleOrbitRel B W φ ψ := by - -- Strong induction on k: supplies IH at ALL levels < k, in particular at both - -- k-1 (for restriction step) and T-1 (for Claim 4.4 in non-surjective branch). - suffices strong : ∀ (m : ℕ) (φ ψ : Fin m → Fin T), - tupleEquiv B W φ ψ → tupleOrbitRel B W φ ψ from strong k φ ψ h - exact fun m => @Nat.strongRecOn - (fun j => ∀ (φ ψ : Fin j → Fin T), tupleEquiv B W φ ψ → tupleOrbitRel B W φ ψ) - m fun m IH_strong => by - intro φ ψ h - rcases m with _ | k - · exact ⟨1, ⟨fun _ => rfl, fun _ _ => rfl⟩, nofun⟩ - · -- m = k + 1. IH_strong : ∀ j < k+1, ∀ (φ ψ : Fin j → Fin T), tupleEquiv → tupleOrbitRel. - have IH : ∀ {φ' ψ' : Fin k → Fin T}, - tupleEquiv B W φ' ψ' → tupleOrbitRel B W φ' ψ' := - fun {φ' ψ'} h' => IH_strong k (Nat.lt_succ_self k) φ' ψ' h' - -- Step 1: Restrict to level k and apply IH. - obtain ⟨σ, hσ_aut, hσ_conj⟩ := IH (tupleEquiv_restrict B W hB h) - -- Step 2: IsWeightedAutomorphism for σ⁻¹. - have hσs : IsWeightedAutomorphism B W σ.symm := - ⟨fun i => by have := (hσ_aut.1 (σ.symm i)).symm; rwa [σ.apply_symm_apply] at this, - fun i j => by have := (hσ_aut.2 (σ.symm i) (σ.symm j)).symm - rwa [σ.apply_symm_apply, σ.apply_symm_apply] at this⟩ - -- Step 3: Normalize ψ by σ⁻¹ using tupleEquiv_of_tupleOrbitRel. - have h' : tupleEquiv B W φ (σ.symm ∘ ψ) := fun n F _ => - (h n F).trans (tupleEquiv_of_tupleOrbitRel ⟨σ.symm, hσs, fun _ => rfl⟩ n F) - -- Step 4: The first k coordinates now agree. - have hbase : restrictTuple (σ.symm ∘ ψ) = restrictTuple φ := by - funext i; simp only [restrictTuple, Function.comp] - have := hσ_conj i; simp only [restrictTuple] at this - rw [this, σ.symm_apply_apply] - -- Step 5: Express as Fin.snoc extensions of the common base α. - set α := restrictTuple φ - have ha : φ = Fin.snoc α (φ (Fin.last k)) := by - ext i; by_cases hi : (i : ℕ) < k - · rw [show i = (⟨i, hi⟩ : Fin k).castSucc from Fin.ext rfl, Fin.snoc_castSucc]; rfl - · rw [show i = Fin.last k from Fin.ext (show i.val = k by omega), Fin.snoc_last] - have hb : σ.symm ∘ ψ = Fin.snoc α ((σ.symm ∘ ψ) (Fin.last k)) := by - ext i; by_cases hi : (i : ℕ) < k - · rw [show i = (⟨i, hi⟩ : Fin k).castSucc from Fin.ext rfl, Fin.snoc_castSucc, ← hbase] - rfl - · rw [show i = Fin.last k from Fin.ext (show i.val = k by omega), Fin.snoc_last] - rw [ha, hb] at h' - -- Step 6: Surjective base ⟹ last coordinates equal ⟹ orbit relation. - by_cases hα_surj : Function.Surjective α - · have hab := tupleEquiv_ext_eq_of_surj B W hB htwin hα_surj h' - exact ⟨σ, hσ_aut, fun i => by - have : (σ.symm ∘ ψ) i = φ i := congr_fun (hb.trans (hab ▸ ha.symm)) i - rwa [Function.comp_apply, Equiv.symm_apply_eq] at this⟩ - · -- Non-surjective base. Split on whether φ itself is surjective. - by_cases hφ_surj : Function.Surjective φ - · -- φ surjective: apply Claim 4.4. Since φ surj, T ≤ k+1, so T-1 < k+1. - have hT1_lt : T - 1 < k + 1 := by - have := Fintype.card_le_of_surjective φ hφ_surj - simp only [Fintype.card_fin] at this - omega - have IH_T1 : ∀ {φ' ψ' : Fin (T - 1) → Fin T}, - tupleEquiv B W φ' ψ' → tupleOrbitRel B W φ' ψ' := - fun {φ' ψ'} h' => IH_strong (T - 1) hT1_lt φ' ψ' h' - exact tupleEquiv_surjective_case B W hW hB htwin IH_T1 φ ψ hφ_surj h - · -- Neither α = restrictTuple φ nor φ itself is surjective. - -- - -- Context at this point in the proof: - -- · α : Fin k → Fin T is non-surjective. - -- · φ = Fin.snoc α a with a := φ (Fin.last k). - -- · σ.symm ∘ ψ = Fin.snoc α b with b := (σ.symm ∘ ψ) (Fin.last k). - -- · h' : tupleEquiv B W (Fin.snoc α a) (Fin.snoc α b). - -- Goal: tupleOrbitRel B W φ ψ, equivalently: an automorphism σ' - -- with σ' ∘ α = α (fixing range(α) pointwise) and σ'(a) = b. - -- - -- Standard Lovász plan ("extend-and-recurse"): - -- 1. Pick r ∈ Fin T outside range(α) ∪ {a, b}. (Requires the - -- deficit T − |range α ∪ {a, b}| ≥ 1, i.e. a case analysis.) - -- 2. Build `Φ_ext := Fin.snoc (Fin.snoc α a) r` at level k+2, - -- `Ψ_ext := Fin.snoc (Fin.snoc α b) ?`. We need - -- `tupleEquiv B W Φ_ext Ψ_ext` where the last coordinate of - -- Ψ_ext matches some element yielding tupleEquiv. - -- 3. Apply the outer IH at (Φ_ext, Ψ_ext) at measure strictly - -- smaller than (d, k+1) under a lex order `(deficit, size)` - -- with deficit primary. Extract an automorphism σ'. - -- 4. Restrict σ' back to conclude on (φ, ψ). - -- - -- Why closing this branch still requires work after the recent - -- wiring (`product_trace_identity` now reduces to the extension - -- theorem `DecLabeledGraphTr.eval_tupleEquiv_invariant` — see - -- the "Multigraph / A_k extension frontier" section): - -- - -- Step 2 — producing `tupleEquiv B W Φ_ext Ψ_ext` — is - -- `tupleEquiv_extend`, which is proved **modulo** the - -- extension theorem (the one remaining frontier sorry). - -- Closing that extension theorem immediately unblocks - -- `tupleEquiv_extend`. The remaining gap here is therefore - -- *architectural*: Step 3 (applying the outer IH at smaller - -- measure) requires a well-founded induction refactor on - -- `(deficit, size)`, since strong induction on `size` - -- alone cannot supply the IH at `(k+2)` in the extend-and- - -- recurse branch. - -- - -- The IH-free variant `tupleEquiv_extend_of_ih` is not a - -- substitute: it needs the Lemma-2.4 conclusion at the - -- specific pair `(Fin.snoc α a, Fin.snoc α b)` at level - -- `k+1`, which is the current outer goal — circular under - -- any lex measure with that pair at its current slot. - -- - -- An alternative (direct-single-edge) route mirroring - -- `tupleEquiv_ext_eq_of_surj` can only extract - -- `B (α j) a = B (α j) b` for j ∈ range(α); without surjectivity - -- of α the rows B(a, ·) and B(b, ·) cannot be compared outside - -- range(α) ∪ {a, b}. - -- - -- Closing the gap requires (i) the extension theorem and - -- (ii) a WF induction refactor on `(deficit, size)` plus a - -- third piece identified after attempting (ii) mechanically: - -- - -- (iii) `tupleEquiv_surjective_case` calls `IH_T1` at level - -- `T-1` for an **arbitrary-deficit** pair — specifically - -- `(restrictTuple id, restrictTuple χ)` where `χ` is a - -- bijection of `Fin T`. This restriction has deficit 1 when - -- `χ(Fin.last) = Fin.last` and deficit 0 otherwise. Under - -- deficit-primary lex `(d, size)` with the outer call at - -- `(0, k+1)` (Φ surjective ⟹ d=0), an IH at `(1, T-1)` is - -- lex-GREATER, not smaller. Size-primary lex fixes this but - -- then fails on extensions (size grows). - -- - -- The deepest clean refactor therefore requires ALSO - -- restructuring `tupleEquiv_bijective_case` and - -- `tupleEquiv_id_bijective` to avoid the deficit-1 IH — e.g. - -- by routing through extension (from deficit-0 size-T - -- instances) rather than restriction to deficit-1 size-T-1. - -- This is a nontrivial internal refactor of Claim 4.3/4.4. - -- - -- Retained here so the file continues to compile. - sorry + -- Bridge to the sorry-free Lovász simple-graph Lemma 2.4 (via the rank theorem): + -- `tupleEquiv` is definitionally `Lovasz.tupleEquivSimple` (unfold `labeledEvalK`), + -- and the orbit conclusions coincide (identical `IsWeightedAutomorphism` bodies). + have h_simple : Graphon.Lovasz.tupleEquivSimple B W φ ψ := by + intro n' F _ + have heq := h n' F + unfold labeledEvalK at heq + exact heq + obtain ⟨σ, hσ_aut, hσconj⟩ := + Graphon.Lovasz.tupleEquivSimple_implies_orbit_via_2_5 B hB W hW htwin h_simple + exact ⟨σ, ⟨hσ_aut.1, hσ_aut.2⟩, hσconj⟩ /-! #### Level 4 ext stubs — delegations to the main theorem diff --git a/Graphon/SimpleOrbitRank.lean b/Graphon/SimpleOrbitRank.lean deleted file mode 100644 index d9db5b9..0000000 --- a/Graphon/SimpleOrbitRank.lean +++ /dev/null @@ -1,293 +0,0 @@ -/- -Copyright (c) 2026 Cameron Freer. All rights reserved. -Released under Apache 2.0 license as described in the file LICENSE. -Authors: Cameron Freer --/ -import Graphon.CaiGovorovOrbit - -/-! -# The #70 rank theorem: simple evaluations span the orbit-invariant functions - -The Phase C1+D finrank skeleton, moved here from `CycleKrylov.lean` (which sits upstream of -the Cai–Govorov machinery in the import order and therefore could not consume it): -`finrank orbitInvariantSubmodule = #OrbitClass` (orbit-invariant functions ≅ functions on the -orbit quotient), the simple-side lower bound `simpleEvalSubmodule_finrank_ge_orbitClass` -(formerly the sole named #70 residue), and the Phase D rank collapse -`simpleEvalSubmodule_eq_orbitInvariantSubmodule`. - -The lower bound is discharged by an annihilator argument (chunk 5B/5C): the signed -single-family Vandermonde over `OrbitClass × (Fin m → Fin T)` — powered by the Cai–Govorov -descent ingredients `sum_extensions_eval` / `expTestGraph` / `testEvalEq_implies_orbit_super` -— shows that any `c : OrbitClass → ℝ` annihilating all simple evaluations at orbit -representatives vanishes; injectivity of the induced map into the dual of -`simpleEvalSubmodule` then gives `#OrbitClass ≤ finrank simpleEvalSubmodule` (the linear -algebra transcribes `connectionMatrix_full_rank_of_orthogonal`, `Spectral.lean`). - -NB `Spectral.lean` (an unimported leaf) declares its own same-named `Fintype (OrbitClass …)` -instance; no clash on any current import chain. --/ - -namespace Graphon.Lovasz - -open Finset - -noncomputable instance instFintypeOrbitClass {T K : ℕ} {B : Fin T → Fin T → ℝ} {W : Fin T → ℝ} : - Fintype (OrbitClass T K B W) := by - classical - unfold OrbitClass - exact Quotient.fintype _ - -/-- Evaluation-at-orbit-representatives, as a linear map from the orbit-invariant -functions to functions on the orbit quotient. -/ -noncomputable def orbitInvariantToClassFun {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) : - orbitInvariantSubmodule B W K →ₗ[ℝ] (OrbitClass T K B W → ℝ) where - toFun f := fun q => (f : (Fin K → Fin T) → ℝ) (Quotient.out q) - map_add' f g := by funext q; simp - map_smul' c f := by funext q; simp - -/-- **Orbit-invariant functions ≅ functions on the orbit quotient.** -/ -noncomputable def orbitInvariantEquiv {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) : - orbitInvariantSubmodule B W K ≃ₗ[ℝ] (OrbitClass T K B W → ℝ) := - LinearEquiv.ofBijective (orbitInvariantToClassFun B W) (by - constructor - · -- injective: agreement on representatives + orbit-invariance ⟹ equal - intro f₁ f₂ h - apply Subtype.ext - funext ξ - have key : ∀ (g : orbitInvariantSubmodule B W K) (η : Fin K → Fin T), - (g : (Fin K → Fin T) → ℝ) η - = (g : (Fin K → Fin T) → ℝ) - (Quotient.out (Quotient.mk (tupleOrbitSetoid B W K) η)) := by - intro g η - obtain ⟨σ, hσ, hση⟩ := Quotient.mk_out (s := tupleOrbitSetoid B W K) η - have hηeq : η = σ ∘ Quotient.out (Quotient.mk (tupleOrbitSetoid B W K) η) := funext hση - conv_lhs => rw [hηeq] - exact g.2 σ hσ _ - rw [key f₁ ξ, key f₂ ξ] - exact congrFun h (Quotient.mk (tupleOrbitSetoid B W K) ξ) - · -- surjective: pull back a class function - intro g - refine ⟨⟨fun η => g (Quotient.mk (tupleOrbitSetoid B W K) η), ?_⟩, ?_⟩ - · intro σ hσ η - show g (Quotient.mk (tupleOrbitSetoid B W K) (σ ∘ η)) - = g (Quotient.mk (tupleOrbitSetoid B W K) η) - have hmk : Quotient.mk (tupleOrbitSetoid B W K) η - = Quotient.mk (tupleOrbitSetoid B W K) (σ ∘ η) := - Quotient.sound ⟨σ, hσ, fun i => rfl⟩ - rw [hmk] - · funext q - show g (Quotient.mk (tupleOrbitSetoid B W K) (Quotient.out q)) = g q - rw [Quotient.out_eq]) - -/-- **Phase C1: `finrank orbitInvariantSubmodule = #OrbitClass`.** -/ -theorem finrank_orbitInvariantSubmodule {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) : - Module.finrank ℝ (orbitInvariantSubmodule B W K) = Fintype.card (OrbitClass T K B W) := by - rw [(orbitInvariantEquiv B W).finrank_eq, Module.finrank_fintype_fun_eq_card] - -/-! ### The annihilator lemma (chunk 5B) - -Any `c : OrbitClass → ℝ` that annihilates every simple evaluation at orbit representatives is -zero. This is STRICTLY stronger than point-separation of the orbit classes (distinct rows can -still be linearly dependent); the signed single-family Vandermonde over -`OrbitClass × (Fin m → Fin T)` does the real work, powered by the Cai–Govorov descent -ingredients (`sum_extensions_eval`, `expTestGraph`, `testEvalEq_implies_orbit_super`). -/ - -/-- Reindexing the test-moment power product along `Fintype.equivFin` (profile form). -/ -private theorem prod_profile_pow {T L : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (μ : Fin L → Fin T) (k : Fin (Fintype.card (TestCoord L)) → ℕ) : - ∏ c : TestCoord L, (testMoment B W c μ) ^ k (Fintype.equivFin (TestCoord L) c) - = ∏ c, (testProfile B W μ c) ^ k c := by - calc ∏ c : TestCoord L, (testMoment B W c μ) ^ k (Fintype.equivFin (TestCoord L) c) - = ∏ c : TestCoord L, (testProfile B W μ (Fintype.equivFin (TestCoord L) c)) - ^ k (Fintype.equivFin (TestCoord L) c) := by - refine Finset.prod_congr rfl fun c _ => ?_ - congr 1 - show testMoment B W c μ - = testMoment B W ((Fintype.equivFin (TestCoord L)).symm - (Fintype.equivFin (TestCoord L) c)) μ - rw [Equiv.symm_apply_apply] - _ = ∏ c, (testProfile B W μ c) ^ k c := - Equiv.prod_comp (Fintype.equivFin (TestCoord L)) - (fun c => (testProfile B W μ c) ^ k c) - -/-- **The annihilator lemma.** If `∑ q, c q · simpleEvalAt F (out q) = 0` for every simple -graph `F`, then `c = 0`. Signed Vandermonde over `OrbitClass × (Fin m → Fin T)` with the -test-moment profile of `Fin.append (out q) ρ` as classifier: the class of the profile of -`superExt (out q₀)` consists exactly of pairs `(q₀, ρ)` (chunk 4A at level `K + m` forces -`q = q₀`), and its `W`-mass is positive, so the class-sum `c q₀ · (positive) = 0` kills -`c q₀`. -/ -theorem eval_rep_annihilator_zero {T K : ℕ} (B : Fin T → Fin T → ℝ) - (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) (hW : ∀ i, 0 < W i) - (htwin : ∀ i j, i ≠ j → B i ≠ B j) (c : OrbitClass T K B W → ℝ) - (hc : ∀ (n : ℕ) (F : SimpleGraph (Fin (n + K))) (inst : DecidableRel F.Adj), - ∑ q, c q * @simpleEvalAt T K n B W F inst (Quotient.out q) = 0) : - c = 0 := by - classical - funext q₀ - show c q₀ = 0 - -- ρ-form of the extension-sum collapse (eq. (10), one side). - have hρsum : ∀ (n : ℕ) (G : SimpleGraph (Fin (n + (K + T * (2 * T ^ 2))))) - (_ : DecidableRel G.Adj) (ζ : Fin K → Fin T), - ∑ ρ : Fin (T * (2 * T ^ 2)) → Fin T, - (∏ j, W (ρ j)) * simpleEvalAt B W G (Fin.append ζ ρ) - = simpleEvalAt B W (unlabelExtras G) ζ := fun n G _ ζ => - (sum_extensions_eq_sum_rho B W G ζ).symm.trans (sum_extensions_eval B hB W G ζ) - -- Moment vanishing for the signed family over `OrbitClass × (Fin m → Fin T)`. - have hmom : ∀ ℓ : Fin (Fintype.card (TestCoord (K + T * (2 * T ^ 2)))) → ℕ, - (∀ j, ℓ j < Fintype.card (OrbitClass T K B W × (Fin (T * (2 * T ^ 2)) → Fin T))) → - ∑ i : OrbitClass T K B W × (Fin (T * (2 * T ^ 2)) → Fin T), - (c i.1 * ∏ j, W (i.2 j)) - * ∏ j, (testProfile B W (Fin.append (Quotient.out i.1) i.2) j) ^ ℓ j = 0 := by - intro ℓ _ - rw [Fintype.sum_prod_type] - have hterm : ∀ q : OrbitClass T K B W, - ∑ ρ : Fin (T * (2 * T ^ 2)) → Fin T, - (c q * ∏ j, W (ρ j)) - * ∏ j, (testProfile B W (Fin.append (Quotient.out q) ρ) j) ^ ℓ j - = c q * simpleEvalAt B W - (unlabelExtras (expTestGraph - (fun c' => ℓ (Fintype.equivFin (TestCoord (K + T * (2 * T ^ 2))) c')))) - (Quotient.out q) := by - intro q - rw [← hρsum _ (expTestGraph - (fun c' => ℓ (Fintype.equivFin (TestCoord (K + T * (2 * T ^ 2))) c'))) - inferInstance (Quotient.out q), Finset.mul_sum] - refine Finset.sum_congr rfl fun ρ _ => ?_ - rw [simpleEvalAt_expTestGraph B hB W _ (Fin.append (Quotient.out q) ρ), - prod_profile_pow B W (Fin.append (Quotient.out q) ρ) ℓ] - ring - rw [Finset.sum_congr rfl fun q _ => hterm q] - exact hc _ _ inferInstance - -- Class-sum at the profile of `superExt (out q₀)`. - have hclass := CaiGovorov.multivariate_vandermonde_class_sums_zero - (fun i : OrbitClass T K B W × (Fin (T * (2 * T ^ 2)) → Fin T) => - testProfile B W (Fin.append (Quotient.out i.1) i.2)) - (fun i => c i.1 * ∏ j, W (i.2 j)) hmom - (testProfile B W (superExt (Quotient.out q₀))) - -- The class forces `q = q₀` (chunk 4A at level K + m). - have hq_eq : ∀ (q : OrbitClass T K B W) (ρ : Fin (T * (2 * T ^ 2)) → Fin T), - testProfile B W (Fin.append (Quotient.out q) ρ) - = testProfile B W (superExt (Quotient.out q₀)) → q = q₀ := by - intro q ρ hprof - have hTE : TestEvalEq B W (superExt (Quotient.out q₀)) (Fin.append (Quotient.out q) ρ) := - (testEvalEq_iff_moments B hB W).mpr fun c' => (testProfile_eq_iff.mp hprof c').symm - obtain ⟨σ, hσ_aut, hσ⟩ := testEvalEq_implies_orbit_super B hB W hW htwin _ _ - (superExt_superSurjective (Quotient.out q₀)) hTE - have horb : tupleOrbitRel B W (Quotient.out q₀) (Quotient.out q) := by - refine ⟨σ, hσ_aut, fun i => ?_⟩ - have hi := hσ (Fin.castAdd (T * (2 * T ^ 2)) i) - rw [Fin.append_left, superExt_extends (Quotient.out q₀) i] at hi - exact hi - have hmk : Quotient.mk (tupleOrbitSetoid B W K) (Quotient.out q₀) - = Quotient.mk (tupleOrbitSetoid B W K) (Quotient.out q) := Quotient.sound horb - rw [Quotient.out_eq, Quotient.out_eq] at hmk - exact hmk.symm - -- The class is exactly `{q₀} ×ˢ P` for the ρ-side class `P`. - have hfilter_eq : (univ.filter - (fun i : OrbitClass T K B W × (Fin (T * (2 * T ^ 2)) → Fin T) => - testProfile B W (Fin.append (Quotient.out i.1) i.2) - = testProfile B W (superExt (Quotient.out q₀)))) - = {q₀} ×ˢ (univ.filter (fun ρ : Fin (T * (2 * T ^ 2)) → Fin T => - testProfile B W (Fin.append (Quotient.out q₀) ρ) - = testProfile B W (superExt (Quotient.out q₀)))) := by - ext ⟨q, ρ⟩ - simp only [Finset.mem_filter, Finset.mem_univ, true_and, Finset.mem_product, - Finset.mem_singleton] - constructor - · intro hprof - obtain rfl := hq_eq q ρ hprof - exact ⟨rfl, hprof⟩ - · rintro ⟨rfl, hprof⟩ - exact hprof - -- Collapse the class-sum to `c q₀ · (positive W-mass)`. - have hmass : c q₀ * ∑ ρ ∈ univ.filter (fun ρ : Fin (T * (2 * T ^ 2)) → Fin T => - testProfile B W (Fin.append (Quotient.out q₀) ρ) - = testProfile B W (superExt (Quotient.out q₀))), ∏ j, W (ρ j) = 0 := by - rw [Finset.mul_sum, ← hclass, hfilter_eq, Finset.sum_product, Finset.sum_singleton] - have hpos : (0 : ℝ) < ∑ ρ ∈ univ.filter (fun ρ : Fin (T * (2 * T ^ 2)) → Fin T => - testProfile B W (Fin.append (Quotient.out q₀) ρ) - = testProfile B W (superExt (Quotient.out q₀))), ∏ j, W (ρ j) := - Finset.sum_pos (fun ρ _ => Finset.prod_pos fun j _ => hW _) - ⟨coverExtra T, Finset.mem_filter.mpr ⟨Finset.mem_univ _, rfl⟩⟩ - exact (mul_eq_zero.mp hmass).resolve_right (ne_of_gt hpos) - -/-! ### The dual-pairing endgame (chunk 5C) - -The representative pairing turns the annihilator lemma into injectivity of a map into the -dual of `simpleEvalSubmodule`; comparing dimensions gives the lower bound. Transcribes the -`hle1` half of `connectionMatrix_full_rank_of_orthogonal` (`Spectral.lean`). -/ - -/-- The representative pairing `⟨c, f⟩ := ∑ q, c q · f (Quotient.out q)` as a bilinear map -(mirrors `orbitInnerBil`). -/ -noncomputable def evalRepPairing {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) : - (OrbitClass T K B W → ℝ) →ₗ[ℝ] ((Fin K → Fin T) → ℝ) →ₗ[ℝ] ℝ := - LinearMap.mk₂ ℝ (fun c f => ∑ q, c q * f (Quotient.out q)) - (fun c₁ c₂ f => by - simp only [← Finset.sum_add_distrib] - refine Finset.sum_congr rfl fun q _ => ?_ - simp only [Pi.add_apply]; ring) - (fun r c f => by - simp only [Finset.smul_sum] - refine Finset.sum_congr rfl fun q _ => ?_ - simp only [Pi.smul_apply, smul_eq_mul]; ring) - (fun c f₁ f₂ => by - simp only [← Finset.sum_add_distrib] - refine Finset.sum_congr rfl fun q _ => ?_ - simp only [Pi.add_apply]; ring) - (fun r c f => by - simp only [Finset.smul_sum] - refine Finset.sum_congr rfl fun q _ => ?_ - simp only [Pi.smul_apply, smul_eq_mul]; ring) - -@[simp] lemma evalRepPairing_apply {T K : ℕ} (B : Fin T → Fin T → ℝ) (W : Fin T → ℝ) - (c : OrbitClass T K B W → ℝ) (f : (Fin K → Fin T) → ℝ) : - evalRepPairing B W c f = ∑ q, c q * f (Quotient.out q) := rfl - -/-- **The simple-side lower bound** (the genuine Lovász §3 content, formerly the sole #70 -residue): the simple-eval span has dimension at least the number of orbit classes. The -composite `Ψ := subtype.dualMap ∘ evalRepPairing` is injective by the annihilator lemma, so -`#OrbitClass = finrank (OrbitClass → ℝ) ≤ finrank (Dual simpleEvalSubmodule) -= finrank simpleEvalSubmodule`. -/ -theorem simpleEvalSubmodule_finrank_ge_orbitClass {T K : ℕ} - (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) - (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) : - Fintype.card (OrbitClass T K B W) ≤ Module.finrank ℝ (simpleEvalSubmodule B W K) := by - classical - set Ψ : (OrbitClass T K B W → ℝ) →ₗ[ℝ] Module.Dual ℝ (simpleEvalSubmodule B W K) := - (simpleEvalSubmodule B W K).subtype.dualMap ∘ₗ evalRepPairing B W with hΨ - have hΨinj : Function.Injective Ψ := by - rw [← LinearMap.ker_eq_bot, LinearMap.ker_eq_bot'] - intro c hcker - refine eval_rep_annihilator_zero B hB W hW htwin c fun n F inst => ?_ - have hgen := LinearMap.congr_fun hcker - (⟨fun ξ => @simpleEvalAt T K n B W F inst ξ, - Submodule.subset_span ⟨⟨n, F, inst⟩, rfl⟩⟩ : simpleEvalSubmodule B W K) - simpa only [hΨ, LinearMap.comp_apply, LinearMap.dualMap_apply, Submodule.subtype_apply, - evalRepPairing_apply, LinearMap.zero_apply] using hgen - have h1 : Module.finrank ℝ (OrbitClass T K B W → ℝ) - ≤ Module.finrank ℝ (Module.Dual ℝ (simpleEvalSubmodule B W K)) := - LinearMap.finrank_le_finrank_of_injective hΨinj - rw [Subspace.dual_finrank_eq] at h1 - rw [← Module.finrank_pi (ι := OrbitClass T K B W) ℝ] - exact h1 - -/-- **Phase D: the rank collapse** — the simple-eval and orbit-invariant submodules coincide -(unconditional: the lower bound `simpleEvalSubmodule_finrank_ge_orbitClass` is proved above). -This is the #70 rank theorem. -/ -theorem simpleEvalSubmodule_eq_orbitInvariantSubmodule {T K : ℕ} - (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) - (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) : - simpleEvalSubmodule B W K = orbitInvariantSubmodule B W K := - Submodule.eq_of_le_of_finrank_le - (simpleEvalSubmodule_le_orbitInvariantSubmodule B hB W) - (by rw [finrank_orbitInvariantSubmodule B W] - exact simpleEvalSubmodule_finrank_ge_orbitClass B hB W hW htwin) - -/-- **The hard inclusion** `orbitInvariantSubmodule ≤ simpleEvalSubmodule`. -/ -theorem orbitInvariantSubmodule_le_simpleEvalSubmodule {T K : ℕ} - (B : Fin T → Fin T → ℝ) (hB : ∀ i j, B i j = B j i) (W : Fin T → ℝ) - (hW : ∀ i, 0 < W i) (htwin : ∀ i j, i ≠ j → B i ≠ B j) : - orbitInvariantSubmodule B W K ≤ simpleEvalSubmodule B W K := - (simpleEvalSubmodule_eq_orbitInvariantSubmodule B hB W hW htwin).ge - -end Graphon.Lovasz