MaxLeafFormal.LobsterGraph
Source file MaxLeafFormal/LobsterGraph.lean of the Lean project (how it is built).
Statements of the paper formalised here: Lemma 7.3, Proposition 7.9.
import MaxLeafFormal.Lobster
import MaxLeafFormal.CDS
import MaxLeafFormal.MLS
import MaxLeafFormal.RateAssembly
/-!
# Uniform lobsters: the graph side of `prop:rst-caterpillar`(c)
The proof of `prop:rst-caterpillar`(c): the identity `W_{S*}(y) = fᵀ M_y^{L-1} u_y` and the step
from the matrix inequalities of `MaxLeafFormal.Lobster` to the moments `μ_t(S*)`.
-/
namespace MaxLeafFormal.LobsterGraph
open Finset Matrix MaxLeafFormal.CDS MaxLeafFormal.MLS MaxLeafFormal.RateAssembly
/-! ### General results -/
section General
variable {V : Type*} [Fintype V] [DecidableEq V]
/-- `lem:rst-E`, equality clause:
if `F = G[S]` and every vertex outside `S` has exactly one neighbour in `S` (its owner),
then `|Tm(J_X)| = Π_{F,ν}(X)` for every `X ⊆ S`. -/
theorem tree_reduction_eq (G : SimpleGraph V) [DecidableRel G.Adj] (S : Finset V)
(F : SimpleGraph S) (hFG : F = G.induce (S : Set V))
(o : {v // v ∉ S} → S) (ho : ∀ v, G.Adj v.1 (o v).1)
(huniq : ∀ (v : {v // v ∉ S}) (w : S), G.Adj v.1 w.1 → w = o v) :
let ν : S → ℕ := fun u => (univ.filter (fun v => o v = u)).card
∀ X : Finset S,
termCount G (X.map (Function.Embedding.subtype _)) = treePotential F ν X := by
classical
intro ν X
have hadjF : ∀ a b : S, F.Adj a b ↔ G.Adj a.1 b.1 := by
subst hFG; intro a b; exact Iff.rfl
set Xv := X.map (Function.Embedding.subtype _) with hXv
set N := closedNbhd G Xv
have memXv : ∀ v : S, v.1 ∈ Xv ↔ v ∈ X := fun v => by simp [hXv]
have memXv' : ∀ w : V, w ∈ Xv → ∃ h : w ∈ S, (⟨w, h⟩ : S) ∈ X := by
intro w hw
rw [hXv, mem_map] at hw
obtain ⟨v, hv, rfl⟩ := hw
exact ⟨v.2, hv⟩
-- (1) outside vertices not dominated by `X` are exactly those whose owner is outside `X`
set B := univ.filter (fun w : {v // v ∉ S} => w.1 ∉ N)
have hB : (univ.filter (fun w : V => w ∉ S ∧ w ∉ N)) = B.map (Function.Embedding.subtype _) := by
ext w; simp [B, and_comm]
have hBeq : B = univ.filter (fun w => o w ∉ X) := by
ext w
simp only [B, mem_filter, mem_univ, true_and]
constructor
· intro hw hoX
apply hw
rw [mem_closedNbhd]
exact Or.inr ⟨(o w).1, (memXv _).2 hoX, (ho w).symm⟩
· intro hoX hw
rw [mem_closedNbhd] at hw
rcases hw with hw | ⟨x, hx, hxw⟩
· obtain ⟨h, _⟩ := memXv' _ hw
exact w.2 h
· obtain ⟨h, hx'⟩ := memXv' _ hx
have hxo := huniq w ⟨x, h⟩ hxw.symm
rw [hxo] at hx'
exact hoX hx'
have hsumν : ∑ v ∈ univ \ X, ν v = (univ.filter (fun w => o w ∉ X)).card := by
rw [card_eq_sum_card_fiberwise (f := o) (t := univ \ X)
(fun w hw => by simpa using hw)]
refine sum_congr rfl fun v hv => ?_
simp only [ν]
congr 1
ext w
simp only [mem_filter, mem_univ, true_and]
constructor
· intro h; exact ⟨h ▸ (mem_sdiff.1 hv).2, h⟩
· exact fun h => h.2
have h1 : (univ.filter (fun w : V => w ∉ S ∧ w ∉ N)).card = ∑ v ∈ univ \ X, ν v := by
rw [hB, card_map, hBeq, hsumν]
-- (2) solution vertices not dominated by `X` are exactly those not dominated within `F`
set C := univ.filter (fun v : S => v.1 ∉ N)
have hC : (univ.filter (fun w : V => w ∈ S ∧ w ∉ N)) = C.map (Function.Embedding.subtype _) := by
ext w; simp [C, and_comm]
have h2 : (univ.filter (fun w : V => w ∈ S ∧ w ∉ N)).card
= (univ.filter (fun v => v ∉ X ∧ ∀ u, F.Adj v u → u ∉ X)).card := by
rw [hC, card_map]
congr 1
ext v
simp only [C, mem_filter, mem_univ, true_and]
constructor
· intro hv
refine ⟨fun hvX => hv ((mem_closedNbhd G Xv v.1).2 (Or.inl ((memXv v).2 hvX))), ?_⟩
intro u hvu huX
apply hv
rw [mem_closedNbhd]
exact Or.inr ⟨u.1, (memXv u).2 huX, ((hadjF v u).1 hvu).symm⟩
· rintro ⟨hvX, hnb⟩ hv
rw [mem_closedNbhd] at hv
rcases hv with hv | ⟨x, hx, hxv⟩
· exact hvX ((memXv v).1 hv)
· obtain ⟨h, hx'⟩ := memXv' _ hx
exact hnb ⟨x, h⟩ ((hadjF v ⟨x, h⟩).2 hxv.symm) hx'
-- (3) components: `F[X] ≅ G[X]`
have h3 : CDS.comp G Xv = Nat.card (F.induce (X : Set S)).ConnectedComponent := by
unfold CDS.comp
let e : F.induce (X : Set S) ≃g G.induce (Xv : Set V) :=
{ toFun := fun x => ⟨x.1.1, (memXv x.1).2 x.2⟩
invFun := fun y => ⟨⟨y.1, (memXv' y.1 y.2).1⟩, (memXv' y.1 y.2).2⟩
left_inv := fun _ => rfl
right_inv := fun _ => rfl
map_rel_iff' := fun {a b} => (hadjF a.1 b.1).symm }
exact (Nat.card_congr (SimpleGraph.Iso.connectedComponentEquiv e)).symm
-- assemble
have hsplit : Fintype.card V - N.card = (univ.filter (fun w : V => w ∉ S ∧ w ∉ N)).card
+ (univ.filter (fun w : V => w ∈ S ∧ w ∉ N)).card := by
rw [← card_univ_sdiff, ← card_filter_add_card_filter_not (s := univ \ N) (fun w => w ∈ S),
add_comm]
congr 2 <;> ext w <;> simp [and_comm]
unfold termCount treePotential
rw [hsplit]
omega
/-- One term of `W_S`: `μ_t(S) y^t ≤ W_S(y)` for `y ≥ 0` (proof of `lem:fw-gf`). -/
theorem mu_mul_pow_le_W (g : Finset V → ℕ → ℝ) (S : Finset V) (k t : ℕ) (y : ℝ) (hy : 0 ≤ y) :
mu g S k t * y ^ t ≤ W g S k y := by
unfold MLS.mu MLS.W
rw [sum_mul]
calc ∑ X ∈ S.powersetCard t, (2:ℝ) ^ (-(g X (k - t))) * y ^ t
= ∑ X ∈ S.powersetCard t, y ^ X.card * (2:ℝ) ^ (-(g X (k - X.card))) := by
refine sum_congr rfl fun X hX => ?_
rw [(mem_powersetCard.1 hX).2, mul_comm]
_ ≤ ∑ X ∈ S.powerset, y ^ X.card * (2:ℝ) ^ (-(g X (k - X.card))) := by
apply sum_le_sum_of_subset_of_nonneg
· intro X hX
exact mem_powerset.2 (mem_powersetCard.1 hX).1
· intro X _ _
exact mul_nonneg (pow_nonneg hy _) (Real.rpow_nonneg (by norm_num) _)
/-- A graph with a parent map `p` towards `r` that strictly lowers a rank, and whose edges are
exactly the parent edges, is a tree. -/
theorem isTree_of_parent (G : SimpleGraph V) (r : V) (p : V → V) (h : V → ℕ)
(hadj : ∀ v w, G.Adj v w ↔ (v ≠ r ∧ p v = w) ∨ (w ≠ r ∧ p w = v))
(hh : ∀ v, v ≠ r → h (p v) < h v) : G.IsTree := by
have hreach : ∀ n, ∀ v, h v = n → G.Reachable v r := by
intro n
induction n using Nat.strong_induction_on with
| _ n ih =>
intro v hv
by_cases hvr : v = r
· subst hvr; exact SimpleGraph.Reachable.refl _
· have hA : G.Adj v (p v) := (hadj v (p v)).2 (Or.inl ⟨hvr, rfl⟩)
exact hA.reachable.trans (ih (h (p v)) (by rw [← hv]; exact hh v hvr) (p v) rfl)
have hconn : G.Connected := by
have : Nonempty V := ⟨r⟩
exact SimpleGraph.Connected.mk fun u v => (hreach _ u rfl).trans (hreach _ v rfl).symm
rw [SimpleGraph.isTree_iff_connected_and_card]
refine ⟨hconn, ?_⟩
have hcard : Nat.card {v : V // v ≠ r} = Nat.card G.edgeSet := by
apply Nat.card_eq_of_bijective (fun v : {v : V // v ≠ r} =>
(⟨s(v.1, p v.1), (hadj v.1 (p v.1)).2 (Or.inl ⟨v.2, rfl⟩)⟩ : G.edgeSet))
constructor
· rintro ⟨a, ha⟩ ⟨b, hb⟩ hab
have hab' : s(a, p a) = s(b, p b) := congrArg Subtype.val hab
rcases Sym2.eq_iff.1 hab' with ⟨h1, _⟩ | ⟨h1, h2⟩
· exact Subtype.ext h1
· exfalso
have e1 := hh a ha
have e2 := hh b hb
rw [h2] at e1
rw [← h1] at e2
omega
· rintro ⟨e, he⟩
induction e using Sym2.ind with
| h a b =>
have he' := he
rw [SimpleGraph.mem_edgeSet, hadj] at he'
rcases he' with ⟨ha, hab⟩ | ⟨hb, hba⟩
· exact ⟨⟨a, ha⟩, Subtype.ext (by simp only [hab])⟩
· refine ⟨⟨b, hb⟩, Subtype.ext ?_⟩
show s(b, p b) = s(a, b)
rw [hba]
exact Sym2.eq_swap
rw [← hcard, Nat.card_eq_fintype_card, Nat.card_eq_fintype_card, Fintype.card_subtype,
filter_ne', card_erase_of_mem (mem_univ _), card_univ]
have : 0 < Fintype.card V := Fintype.card_pos_iff.2 ⟨r⟩
omega
/-- Under the hypotheses of `isTree_of_parent`, the rooting parent `CDS.par` is `p`. -/
theorem par_eq_of_parent {G : SimpleGraph V} (hG : G.IsTree) (r : V) (p : V → V) (h : V → ℕ)
(hadj : ∀ v w, G.Adj v w ↔ (v ≠ r ∧ p v = w) ∨ (w ≠ r ∧ p w = v))
(hh : ∀ v, v ≠ r → h (p v) < h v) : ∀ v, v ≠ r → CDS.par hG r v = p v := by
have key : ∀ n, ∀ v, h v = n → v ≠ r → CDS.par hG r v = p v := by
intro n
induction n using Nat.strong_induction_on with
| _ n ih =>
intro v hn hv
have hA : G.Adj v (p v) := (hadj v (p v)).2 (Or.inl ⟨hv, rfl⟩)
rcases (CDS.adj_iff_par hG r).1 hA with ⟨_, h1⟩ | ⟨h1, h2⟩
· exact h1
· exfalso
have h3 := ih (h (p v)) (by rw [← hn]; exact hh v hv) (p v) rfl h1
rw [h3] at h2
have e1 := hh (p v) h1
rw [h2] at e1
have e2 := hh v hv
omega
exact fun v hv => key _ v rfl hv
end General
/-- `C(n,t) y^t ≥ (1+y)^n / (n+1)` at `y = t/(n-t)`, for `t < n` (proof of `lem:fw-gf`,
as used in the proof of `prop:rst-caterpillar`). -/
theorem pow_le_choose_mul (n t : ℕ) (ht : t < n) :
(1 + (t : ℝ) / ((n : ℝ) - t)) ^ n
≤ ((n : ℝ) + 1) * (n.choose t : ℝ) * ((t : ℝ) / ((n : ℝ) - t)) ^ t := by
have htn : (t : ℝ) < n := by exact_mod_cast ht
have hnt : (0 : ℝ) < (n : ℝ) - t := by linarith
have hn0 : (0 : ℝ) ≤ n := Nat.cast_nonneg n
generalize hy : (t : ℝ) / ((n : ℝ) - t) = y
have hy0 : 0 ≤ y := hy ▸ div_nonneg (Nat.cast_nonneg _) hnt.le
have hyb : y * ((n : ℝ) - t) = t := by rw [← hy]; exact div_mul_cancel₀ _ hnt.ne'
-- the ratio of consecutive terms
have hrat : ∀ s, s < n → (n.choose (s + 1) : ℝ) * y ^ (s + 1) * (((s : ℝ) + 1) * ((n : ℝ) - t))
= (n.choose s : ℝ) * y ^ s * (((n : ℝ) - s) * t) := by
intro s hs
have h' : (n.choose (s + 1) : ℝ) * ((s : ℝ) + 1) = (n.choose s : ℝ) * ((n : ℝ) - s) := by
have h2 : ((n.choose (s + 1) * (s + 1) : ℕ) : ℝ) = ((n.choose s * (n - s) : ℕ) : ℝ) := by
rw [Nat.choose_succ_right_eq]
push_cast [Nat.cast_sub hs.le] at h2
exact h2
calc (n.choose (s + 1) : ℝ) * y ^ (s + 1) * (((s : ℝ) + 1) * ((n : ℝ) - t))
= ((n.choose (s + 1) : ℝ) * ((s : ℝ) + 1)) * y ^ s * (y * ((n : ℝ) - t)) := by ring
_ = (n.choose s : ℝ) * y ^ s * (((n : ℝ) - s) * t) := by rw [h', hyb]; ring
have hup : ∀ s, s < t → (n.choose s : ℝ) * y ^ s ≤ (n.choose (s + 1) : ℝ) * y ^ (s + 1) := by
intro s hs
have hs' : (s : ℝ) + 1 ≤ t := by exact_mod_cast hs
have hpos : (0 : ℝ) < ((s : ℝ) + 1) * ((n : ℝ) - t) := mul_pos (by positivity) hnt
have hst : ((s : ℝ) + 1) * ((n : ℝ) - t) ≤ ((n : ℝ) - s) * t := by
nlinarith [mul_nonneg hn0 (by linarith : (0 : ℝ) ≤ t - s - 1)]
have hf0 : 0 ≤ (n.choose s : ℝ) * y ^ s := mul_nonneg (Nat.cast_nonneg _) (pow_nonneg hy0 _)
refine le_of_mul_le_mul_right ?_ hpos
rw [hrat s (by omega)]
exact mul_le_mul_of_nonneg_left hst hf0
have hdown : ∀ s, t ≤ s → s < n →
(n.choose (s + 1) : ℝ) * y ^ (s + 1) ≤ (n.choose s : ℝ) * y ^ s := by
intro s hs hsn
have hs1 : (t : ℝ) ≤ s := by exact_mod_cast hs
have hpos : (0 : ℝ) < ((s : ℝ) + 1) * ((n : ℝ) - t) := mul_pos (by positivity) hnt
have hst : ((n : ℝ) - s) * t ≤ ((s : ℝ) + 1) * ((n : ℝ) - t) := by
nlinarith [mul_nonneg hn0 (by linarith : (0 : ℝ) ≤ s - t)]
have hf0 : 0 ≤ (n.choose s : ℝ) * y ^ s := mul_nonneg (Nat.cast_nonneg _) (pow_nonneg hy0 _)
refine le_of_mul_le_mul_right ?_ hpos
rw [hrat s hsn]
exact mul_le_mul_of_nonneg_left hst hf0
have hle_up : ∀ d s, s + d = t → (n.choose s : ℝ) * y ^ s ≤ (n.choose t : ℝ) * y ^ t := by
intro d
induction d with
| zero => intro s hs; rw [Nat.add_zero] at hs; subst hs; exact le_rfl
| succ d ih => intro s hs; exact (hup s (by omega)).trans (ih (s + 1) (by omega))
have hle_down : ∀ d, t + d ≤ n →
(n.choose (t + d) : ℝ) * y ^ (t + d) ≤ (n.choose t : ℝ) * y ^ t := by
intro d
induction d with
| zero => intro _; simp only [Nat.add_zero, le_refl]
| succ d ih =>
intro hd
exact (hdown (t + d) (by omega) (by omega)).trans (ih (by omega))
have hbound : ∀ s, s ≤ n → (n.choose s : ℝ) * y ^ s ≤ (n.choose t : ℝ) * y ^ t := by
intro s hs
rcases Nat.lt_or_ge s t with h | h
· exact hle_up (t - s) s (by omega)
· have := hle_down (s - t) (by omega)
rwa [show t + (s - t) = s by omega] at this
have hsum : (1 + y) ^ n = ∑ s ∈ range (n + 1), (n.choose s : ℝ) * y ^ s := by
rw [add_comm (1 : ℝ) y, add_pow]
refine sum_congr rfl fun s _ => ?_
rw [one_pow, mul_one, mul_comm]
rw [hsum]
calc ∑ s ∈ range (n + 1), (n.choose s : ℝ) * y ^ s
≤ ∑ _s ∈ range (n + 1), (n.choose t : ℝ) * y ^ t :=
sum_le_sum fun s hs => hbound s (Nat.lt_succ_iff.1 (mem_range.1 hs))
_ = ((n : ℝ) + 1) * (n.choose t : ℝ) * y ^ t := by
rw [sum_const, card_range, nsmul_eq_mul]; push_cast; ring
/-! ### The uniform (2,2)-lobster -/
/-- Edges inside one block: spine vertex 0, legs 1 and 2, claws 3, 4 (of leg 1), 5, 6 (of leg 2). -/
def lobEdge (a b : Fin 7) : Prop :=
(a = 0 ∧ (b = 1 ∨ b = 2)) ∨ (a = 1 ∧ (b = 3 ∨ b = 4)) ∨ (a = 2 ∧ (b = 5 ∨ b = 6))
instance instDecidableRelLobEdge : DecidableRel lobEdge := fun a b => by
unfold lobEdge; infer_instance
/-- Block edges, and the spine edges `x_i x_{i+1}` of `Λ_L`. -/
def lobRel (L : ℕ) (p q : Fin L × Fin 7) : Prop :=
(p.1 = q.1 ∧ lobEdge p.2 q.2) ∨ (p.2 = 0 ∧ q.2 = 0 ∧ p.1.val + 1 = q.1.val)
instance instDecidableRelLobRel (L : ℕ) : DecidableRel (lobRel L) := fun p q => by
unfold lobRel; infer_instance
/-- `Λ_L`. -/
def Lam (L : ℕ) : SimpleGraph (Fin L × Fin 7) := SimpleGraph.fromRel (lobRel L)
instance instDecidableRelLamAdj (L : ℕ) : DecidableRel (Lam L).Adj := fun p q =>
decidable_of_iff (p ≠ q ∧ (lobRel L p q ∨ lobRel L q p)) (SimpleGraph.fromRel_adj _ p q).symm
/-- `S*`: the spine vertices and the legs. -/
def Sstar (L : ℕ) : Finset (Fin L × Fin 7) := univ ×ˢ ({0, 1, 2} : Finset (Fin 7))
/-- `F = Λ_L[S*]`, the caterpillar. -/
def lobF (L : ℕ) : SimpleGraph (Sstar L) := (Lam L).induce (Sstar L : Set (Fin L × Fin 7))
/-- `ν`: 2 at the legs, 0 on the spine. -/
def lobNu (L : ℕ) (v : Sstar L) : ℕ := if v.1.2 = 0 then 0 else 2
/-- `n = 7L`. -/
theorem card_Lam (L : ℕ) : Fintype.card (Fin L × Fin 7) = 7 * L := by
rw [Fintype.card_prod, Fintype.card_fin, Fintype.card_fin, mul_comm]
/-- `|S*| = 3L`. -/
theorem card_Sstar (L : ℕ) : (Sstar L).card = 3 * L := by
have h3 : ({0, 1, 2} : Finset (Fin 7)).card = 3 := by decide
unfold Sstar
rw [card_product, card_univ, Fintype.card_fin, h3, mul_comm]
/-! #### Helpers: coordinates -/
theorem mem_Sstar {L : ℕ} (p : Fin L × Fin 7) : p ∈ Sstar L ↔ p.2.val ≤ 2 := by
have h : ∀ a : Fin 7, (a = 0 ∨ a = 1 ∨ a = 2 ↔ a.val ≤ 2) := by decide
simp only [Sstar, mem_product, mem_univ, true_and, mem_insert, mem_singleton]
exact h p.2
theorem sstar_eq_iff {L : ℕ} (v w : Sstar L) :
v = w ↔ v.1.1.val = w.1.1.val ∧ v.1.2.val = w.1.2.val := by
rw [Subtype.ext_iff, Prod.ext_iff, Fin.ext_iff, Fin.ext_iff]
theorem out_eq_iff {L : ℕ} (v w : {v // v ∉ Sstar L}) :
v = w ↔ v.1.1.val = w.1.1.val ∧ v.1.2.val = w.1.2.val := by
rw [Subtype.ext_iff, Prod.ext_iff, Fin.ext_iff, Fin.ext_iff]
/-- The vertex `(i, a)` of `S*` (block `i`, role `a ≤ 2`). -/
def lobV (L i a : ℕ) (hi : i < L) (ha : a ≤ 2) : Sstar L :=
⟨(⟨i, hi⟩, ⟨a, by omega⟩), (mem_Sstar _).2 ha⟩
@[simp] theorem lobV_blk (L i a : ℕ) (hi : i < L) (ha : a ≤ 2) : (lobV L i a hi ha).1.1.val = i :=
rfl
@[simp] theorem lobV_role (L i a : ℕ) (hi : i < L) (ha : a ≤ 2) :
(lobV L i a hi ha).1.2.val = a := rfl
/-- The claw `(i, c)` (block `i`, role `3 ≤ c ≤ 6`), outside `S*`. -/
def lobO (L i c : ℕ) (hi : i < L) (hc : 3 ≤ c) (hc' : c < 7) : {v // v ∉ Sstar L} :=
⟨(⟨i, hi⟩, ⟨c, hc'⟩), fun h => absurd ((mem_Sstar _).1 h) (by show ¬ c ≤ 2; omega)⟩
@[simp] theorem lobO_blk (L i c : ℕ) (hi : i < L) (hc : 3 ≤ c) (hc' : c < 7) :
(lobO L i c hi hc hc').1.1.val = i := rfl
@[simp] theorem lobO_role (L i c : ℕ) (hi : i < L) (hc : 3 ≤ c) (hc' : c < 7) :
(lobO L i c hi hc hc').1.2.val = c := rfl
theorem lobNu_eq (L : ℕ) (v : Sstar L) : lobNu L v = if v.1.2.val = 0 then 0 else 2 := by
unfold lobNu
by_cases h : v.1.2.val = 0 <;> simp [h, Fin.ext_iff]
/-- Adjacency in `Λ_L`, in coordinates. -/
theorem lam_adj_iff (L : ℕ) (p q : Fin L × Fin 7) : (Lam L).Adj p q ↔
(p.1.val = q.1.val ∧
((p.2.val = 0 ∧ (q.2.val = 1 ∨ q.2.val = 2)) ∨ (p.2.val = 1 ∧ (q.2.val = 3 ∨ q.2.val = 4)) ∨
(p.2.val = 2 ∧ (q.2.val = 5 ∨ q.2.val = 6)) ∨ (q.2.val = 0 ∧ (p.2.val = 1 ∨ p.2.val = 2)) ∨
(q.2.val = 1 ∧ (p.2.val = 3 ∨ p.2.val = 4)) ∨ (q.2.val = 2 ∧ (p.2.val = 5 ∨ p.2.val = 6)))) ∨
(p.2.val = 0 ∧ q.2.val = 0 ∧ (p.1.val + 1 = q.1.val ∨ q.1.val + 1 = p.1.val)) := by
have hE : ∀ a b : Fin 7, lobEdge a b ↔ ((a.val = 0 ∧ (b.val = 1 ∨ b.val = 2)) ∨
(a.val = 1 ∧ (b.val = 3 ∨ b.val = 4)) ∨ (a.val = 2 ∧ (b.val = 5 ∨ b.val = 6))) := by
unfold lobEdge; decide
have h0 : ∀ a : Fin 7, a = 0 ↔ a.val = 0 := by decide
show (SimpleGraph.fromRel (lobRel L)).Adj p q ↔ _
rw [SimpleGraph.fromRel_adj]
simp only [lobRel, hE, h0, ne_eq, Prod.ext_iff, Fin.ext_iff]
omega
theorem lobF_adj (L : ℕ) (v w : Sstar L) : (lobF L).Adj v w ↔ (Lam L).Adj v.1 w.1 := Iff.rfl
/-- Adjacency in `F = Λ_L[S*]`, in coordinates. -/
theorem lobF_adj_val (L : ℕ) (v w : Sstar L) : (lobF L).Adj v w ↔
(v.1.1.val = w.1.1.val ∧ ((v.1.2.val = 0 ∧ w.1.2.val ≠ 0) ∨ (w.1.2.val = 0 ∧ v.1.2.val ≠ 0))) ∨
(v.1.2.val = 0 ∧ w.1.2.val = 0 ∧ (v.1.1.val + 1 = w.1.1.val ∨ w.1.1.val + 1 = v.1.1.val)) := by
have hv := (mem_Sstar v.1).1 v.2
have hw := (mem_Sstar w.1).1 w.2
rw [lobF_adj, lam_adj_iff]
omega
/-! #### Helpers: the rooting of `F` at `x_L = (L-1, 0)` -/
/-- The root `x_L`. -/
def lobRoot (L : ℕ) (hL : 1 ≤ L) : Sstar L := lobV L (L - 1) 0 (by omega) (Nat.zero_le _)
/-- The parent towards the root: the next spine vertex, or the spine vertex of a leg. -/
def lobP (L : ℕ) (v : Sstar L) : Sstar L :=
if h : v.1.2.val = 0 ∧ v.1.1.val + 1 < L then lobV L (v.1.1.val + 1) 0 h.2 (Nat.zero_le _)
else lobV L v.1.1.val 0 v.1.1.isLt (Nat.zero_le _)
theorem lobP_role (L : ℕ) (v : Sstar L) : (lobP L v).1.2.val = 0 := by
unfold lobP; split_ifs <;> rfl
theorem lobP_blk (L : ℕ) (v : Sstar L) :
(v.1.2.val = 0 ∧ v.1.1.val + 1 < L ∧ (lobP L v).1.1.val = v.1.1.val + 1) ∨
(¬ (v.1.2.val = 0 ∧ v.1.1.val + 1 < L) ∧ (lobP L v).1.1.val = v.1.1.val) := by
unfold lobP
split_ifs with h
· exact Or.inl ⟨h.1, h.2, rfl⟩
· exact Or.inr ⟨h, rfl⟩
/-- A rank that `lobP` lowers. -/
def lobRank (L : ℕ) (v : Sstar L) : ℕ := 2 * (L - v.1.1.val) + (if v.1.2.val = 0 then 0 else 1)
theorem lobRank_lt (L : ℕ) (hL : 1 ≤ L) (v : Sstar L) (hv : v ≠ lobRoot L hL) :
lobRank L (lobP L v) < lobRank L v := by
rw [ne_eq, sstar_eq_iff] at hv
simp only [lobRoot, lobV_blk, lobV_role] at hv
have h1 := lobP_blk L v
have h2 := lobP_role L v
have h3 := v.1.1.isLt
unfold lobRank
split_ifs <;> omega
theorem lobF_adj_iff (L : ℕ) (hL : 1 ≤ L) (v w : Sstar L) :
(lobF L).Adj v w ↔ (v ≠ lobRoot L hL ∧ lobP L v = w) ∨ (w ≠ lobRoot L hL ∧ lobP L w = v) := by
have hv := (mem_Sstar v.1).1 v.2
have hw := (mem_Sstar w.1).1 w.2
have hv' := v.1.1.isLt
have hw' := w.1.1.isLt
have pv := lobP_blk L v
have pw := lobP_blk L w
have rv := lobP_role L v
have rw' := lobP_role L w
rw [lobF_adj_val]
simp only [ne_eq, sstar_eq_iff, lobRoot, lobV_blk, lobV_role]
omega
/-- `G[S*]` is a tree. -/
theorem lobF_isTree (L : ℕ) (hL : 1 ≤ L) : (lobF L).IsTree :=
isTree_of_parent (lobF L) (lobRoot L hL) (lobP L) (lobRank L) (lobF_adj_iff L hL)
(lobRank_lt L hL)
theorem lob_par (L : ℕ) (hL : 1 ≤ L) (v : Sstar L) (hv : v ≠ lobRoot L hL) :
CDS.par (lobF_isTree L hL) (lobRoot L hL) v = lobP L v :=
par_eq_of_parent (lobF_isTree L hL) (lobRoot L hL) (lobP L) (lobRank L) (lobF_adj_iff L hL)
(lobRank_lt L hL) v hv
/-! #### Helpers: the owner map (each claw is owned by its leg) -/
/-- The owner of a claw: its leg. -/
def lobOwner (L : ℕ) (v : {v // v ∉ Sstar L}) : Sstar L :=
lobV L v.1.1.val (if v.1.2.val ≤ 4 then 1 else 2) v.1.1.isLt (by split_ifs <;> omega)
theorem lobOwner_blk (L : ℕ) (v : {v // v ∉ Sstar L}) : (lobOwner L v).1.1.val = v.1.1.val := rfl
theorem lobOwner_role (L : ℕ) (v : {v // v ∉ Sstar L}) :
(lobOwner L v).1.2.val = if v.1.2.val ≤ 4 then 1 else 2 := rfl
theorem lobOwner_adj (L : ℕ) (v : {v // v ∉ Sstar L}) : (Lam L).Adj v.1 (lobOwner L v).1 := by
have h1 : ¬ v.1.2.val ≤ 2 := fun h => v.2 ((mem_Sstar v.1).2 h)
have h2 := v.1.2.isLt
rw [lam_adj_iff, lobOwner_blk, lobOwner_role]
split_ifs <;> omega
theorem lobOwner_uniq (L : ℕ) (v : {v // v ∉ Sstar L}) (w : Sstar L)
(h : (Lam L).Adj v.1 w.1) : w = lobOwner L v := by
have h1 : ¬ v.1.2.val ≤ 2 := fun h => v.2 ((mem_Sstar v.1).2 h)
have h2 := v.1.2.isLt
have h3 := (mem_Sstar w.1).1 w.2
rw [lam_adj_iff] at h
rw [sstar_eq_iff, lobOwner_blk, lobOwner_role]
split_ifs <;> omega
theorem lobOwner_card (L : ℕ) (u : Sstar L) :
(univ.filter (fun v : {v // v ∉ Sstar L} => lobOwner L v = u)).card = lobNu L u := by
have hu := (mem_Sstar u.1).1 u.2
have hb := u.1.1.isLt
rw [lobNu_eq]
split_ifs with h0
· rw [card_eq_zero, filter_eq_empty_iff]
intro v _ hv
rw [sstar_eq_iff, lobOwner_blk, lobOwner_role] at hv
split_ifs at hv <;> omega
· rw [card_eq_two]
refine ⟨lobO L u.1.1.val (2 * u.1.2.val + 1) hb (by omega) (by omega),
lobO L u.1.1.val (2 * u.1.2.val + 2) hb (by omega) (by omega), ?_, ?_⟩
· rw [Ne, out_eq_iff, lobO_blk, lobO_blk, lobO_role, lobO_role]
omega
· ext v
have hv1 : ¬ v.1.2.val ≤ 2 := fun h => v.2 ((mem_Sstar v.1).2 h)
have hv2 := v.1.2.isLt
simp only [mem_filter, mem_univ, true_and, mem_insert, mem_singleton, out_eq_iff,
sstar_eq_iff, lobOwner_blk, lobOwner_role, lobO_blk, lobO_role]
split_ifs <;> omega
/-- `lem:rst-E` holds with equality on `Λ_L`, with `ν = 2` at the legs and `0` on the spine
Also true at `L = 0` (both sides `0`). -/
theorem lob_termCount_eq (L : ℕ) (X : Finset (Sstar L)) :
termCount (Lam L) (X.map (Function.Embedding.subtype _))
= treePotential (lobF L) (lobNu L) X := by
rw [tree_reduction_eq (Lam L) (Sstar L) (lobF L) rfl (lobOwner L) (lobOwner_adj L)
(lobOwner_uniq L) X]
congr 1
funext u
exact lobOwner_card L u
/-- `W_{S*} = W_{F,ν}`. Also true at `L = 0` (both sides `1`). -/
theorem lobW_eq_treeW (L : ℕ) (y : ℝ) :
W (gT (Lam L)) (Sstar L) (3 * L) y = treeW (lobF L) (lobNu L) y := by
rw [RateAssembly.W_gT]
unfold treeW
symm
refine sum_nbij' (fun X => X.map (Function.Embedding.subtype _))
(fun Y => Y.subtype (fun x => x ∈ Sstar L)) ?_ ?_ ?_ ?_ ?_
· intro X _
rw [mem_powerset]
intro x hx
rw [mem_map] at hx
obtain ⟨v, -, rfl⟩ := hx
exact v.2
· intro Y _
exact mem_powerset.2 (subset_univ _)
· intro X _
ext x; simp
· intro Y hY
rw [mem_powerset] at hY
exact subtype_map_of_mem hY
· intro X _
rw [card_map, lob_termCount_eq]
/-! #### Helpers: the messages along the spine -/
/-- The vertices of `S*` in blocks `≤ i`. -/
def lobBlk (L i : ℕ) : Finset (Sstar L) := univ.filter (fun v => v.1.1.val ≤ i)
/-- The vertices of `S*` in block `i`. -/
def lobBlkA (L i : ℕ) : Finset (Sstar L) := univ.filter (fun v => v.1.1.val = i)
theorem lobBlk_zero (L : ℕ) : lobBlk L 0 = lobBlkA L 0 := by
ext v; simp [lobBlk, lobBlkA]
theorem lobBlk_succ (L i : ℕ) : lobBlk L (i + 1) = lobBlkA L (i + 1) ∪ lobBlk L i := by
ext v; simp only [lobBlk, lobBlkA, mem_filter, mem_univ, true_and, mem_union]; omega
theorem lobBlk_last (L : ℕ) : lobBlk L (L - 1) = univ := by
ext v
have := v.1.1.isLt
simp only [lobBlk, mem_filter, mem_univ, true_and, iff_true]
omega
theorem lob_par_role (L : ℕ) (hL : 1 ≤ L) (u : Sstar L) (hu : u ≠ lobRoot L hL) :
(CDS.par (lobF_isTree L hL) (lobRoot L hL) u).1.2.val = 0 := by
rw [lob_par L hL u hu]; exact lobP_role L u
/-- The message of one block, `ψ = Init(0) ∘ Init(2) ∘ Init(2) = u_y`. -/
theorem lob_triple_A (L : ℕ) (hL : 1 ≤ L) [DecidableRel (lobF L).Adj] (y : ℝ) (i : ℕ)
(hi : i < L) :
Antinorm3.triple (lobF_isTree L hL) (lobRoot L hL) (lobNu L) y (lobBlkA L i)
(lobV L i 0 hi (Nat.zero_le _)) = Lobster.toT (Lobster.u y) := by
have hA : lobBlkA L i = ({lobV L i 0 hi (Nat.zero_le _)} ∪ {lobV L i 1 hi (by norm_num)})
∪ {lobV L i 2 hi le_rfl} := by
ext v
have := (mem_Sstar v.1).1 v.2
simp only [lobBlkA, mem_filter, mem_univ, true_and, mem_union, mem_singleton, sstar_eq_iff,
lobV_blk, lobV_role]
omega
have hr1 : lobV L i 1 hi (by norm_num) ≠ lobRoot L hL := by
simp only [lobRoot, ne_eq, sstar_eq_iff, lobV_blk, lobV_role]; omega
have hr2 : lobV L i 2 hi le_rfl ≠ lobRoot L hL := by
simp only [lobRoot, ne_eq, sstar_eq_iff, lobV_blk, lobV_role]; omega
have hp1 : CDS.par (lobF_isTree L hL) (lobRoot L hL) (lobV L i 1 hi (by norm_num))
= lobV L i 0 hi (Nat.zero_le _) := by
rw [lob_par L hL _ hr1, sstar_eq_iff]
have h1 := lobP_blk L (lobV L i 1 hi (by norm_num))
have h2 := lobP_role L (lobV L i 1 hi (by norm_num))
simp only [lobV_blk, lobV_role] at h1 h2 ⊢; omega
have hp2 : CDS.par (lobF_isTree L hL) (lobRoot L hL) (lobV L i 2 hi le_rfl)
= lobV L i 0 hi (Nat.zero_le _) := by
rw [lob_par L hL _ hr2, sstar_eq_iff]
have h1 := lobP_blk L (lobV L i 2 hi le_rfl)
have h2 := lobP_role L (lobV L i 2 hi le_rfl)
simp only [lobV_blk, lobV_role] at h1 h2 ⊢; omega
-- first split: `A = {x, ℓ₁}`, `B = {ℓ₂}`
have d1 : Disjoint ({lobV L i 0 hi (Nat.zero_le _)} ∪ {lobV L i 1 hi (by norm_num)})
({lobV L i 2 hi le_rfl} : Finset (Sstar L)) := by
refine disjoint_left.2 fun a ha hb => ?_
simp only [mem_union, mem_singleton, sstar_eq_iff, lobV_blk, lobV_role] at ha hb; omega
have e1 : ∀ a ∈ ({lobV L i 0 hi (Nat.zero_le _)} ∪ {lobV L i 1 hi (by norm_num)} :
Finset (Sstar L)), ∀ b ∈ ({lobV L i 2 hi le_rfl} : Finset (Sstar L)),
(lobF L).Adj a b → a = lobV L i 0 hi (Nat.zero_le _) ∧ b = lobV L i 2 hi le_rfl := by
intro a ha b hb hab
rw [lobF_adj_val] at hab
simp only [mem_union, mem_singleton, sstar_eq_iff, lobV_blk, lobV_role] at ha hb ⊢; omega
have b1 : ∀ u ∈ ({lobV L i 2 hi le_rfl} : Finset (Sstar L)), u ≠ lobV L i 2 hi le_rfl →
u ≠ lobRoot L hL ∧ CDS.par (lobF_isTree L hL) (lobRoot L hL) u ∈
({lobV L i 2 hi le_rfl} : Finset (Sstar L)) :=
fun u hu hne => absurd (mem_singleton.1 hu) hne
have a1 : ∀ u ∈ ({lobV L i 0 hi (Nat.zero_le _)} ∪ {lobV L i 1 hi (by norm_num)} :
Finset (Sstar L)), u ≠ lobRoot L hL → CDS.par (lobF_isTree L hL) (lobRoot L hL) u ∉
({lobV L i 2 hi le_rfl} : Finset (Sstar L)) := by
intro u _ hu
have := lob_par_role L hL u hu
rw [mem_singleton, sstar_eq_iff, lobV_blk, lobV_role]
omega
-- second split: `A = {x}`, `B = {ℓ₁}`
have d2 : Disjoint ({lobV L i 0 hi (Nat.zero_le _)} : Finset (Sstar L))
{lobV L i 1 hi (by norm_num)} := by
rw [disjoint_singleton, ne_eq, sstar_eq_iff, lobV_blk, lobV_role, lobV_blk, lobV_role]
omega
have e2 : ∀ a ∈ ({lobV L i 0 hi (Nat.zero_le _)} : Finset (Sstar L)),
∀ b ∈ ({lobV L i 1 hi (by norm_num)} : Finset (Sstar L)),
(lobF L).Adj a b → a = lobV L i 0 hi (Nat.zero_le _) ∧ b = lobV L i 1 hi (by norm_num) :=
fun a ha b hb _ => ⟨mem_singleton.1 ha, mem_singleton.1 hb⟩
have b2 : ∀ u ∈ ({lobV L i 1 hi (by norm_num)} : Finset (Sstar L)),
u ≠ lobV L i 1 hi (by norm_num) →
u ≠ lobRoot L hL ∧ CDS.par (lobF_isTree L hL) (lobRoot L hL) u ∈
({lobV L i 1 hi (by norm_num)} : Finset (Sstar L)) :=
fun u hu hne => absurd (mem_singleton.1 hu) hne
have a2 : ∀ u ∈ ({lobV L i 0 hi (Nat.zero_le _)} : Finset (Sstar L)), u ≠ lobRoot L hL →
CDS.par (lobF_isTree L hL) (lobRoot L hL) u ∉
({lobV L i 1 hi (by norm_num)} : Finset (Sstar L)) := by
intro u _ hu
have := lob_par_role L hL u hu
rw [mem_singleton, sstar_eq_iff, lobV_blk, lobV_role]
omega
rw [hA, Antinorm3.triple_split (lobF_isTree L hL) (lobRoot L hL) (lobNu L) y d1
(mem_union_left _ (mem_singleton_self _)) (mem_singleton_self _) hr2 hp2 e1 b1 a1,
Antinorm3.triple_split (lobF_isTree L hL) (lobRoot L hL) (lobNu L) y d2
(mem_singleton_self _) (mem_singleton_self _) hr1 hp1 e2 b2 a2,
Antinorm3.triple_single, Antinorm3.triple_single, Antinorm3.triple_single, Lobster.u_eq,
lobNu_eq, lobNu_eq, lobNu_eq, lobV_role, lobV_role, lobV_role]
rfl
/-- The message of the blocks `≤ i` at `x_i` is `M_y^i u_y`. -/
theorem lob_triple_blk (L : ℕ) (hL : 1 ≤ L) [DecidableRel (lobF L).Adj] (y : ℝ) (i : ℕ)
(hi : i < L) :
Antinorm3.triple (lobF_isTree L hL) (lobRoot L hL) (lobNu L) y (lobBlk L i)
(lobV L i 0 hi (Nat.zero_le _)) = Lobster.toT (Lobster.M y ^ i *ᵥ Lobster.u y) := by
induction i with
| zero =>
rw [lobBlk_zero, pow_zero, Matrix.one_mulVec]
exact lob_triple_A L hL y 0 hi
| succ i ih =>
have hi' : i < L := by omega
have hwr : lobV L i 0 hi' (Nat.zero_le _) ≠ lobRoot L hL := by
simp only [lobRoot, ne_eq, sstar_eq_iff, lobV_blk, lobV_role]; omega
have hpw : CDS.par (lobF_isTree L hL) (lobRoot L hL) (lobV L i 0 hi' (Nat.zero_le _))
= lobV L (i + 1) 0 hi (Nat.zero_le _) := by
rw [lob_par L hL _ hwr, sstar_eq_iff]
have h1 := lobP_blk L (lobV L i 0 hi' (Nat.zero_le _))
have h2 := lobP_role L (lobV L i 0 hi' (Nat.zero_le _))
simp only [lobV_blk, lobV_role, true_and] at h1 h2 ⊢; omega
have hAB : Disjoint (lobBlkA L (i + 1)) (lobBlk L i) := by
refine disjoint_left.2 fun a ha hb => ?_
simp only [lobBlkA, lobBlk, mem_filter, mem_univ, true_and] at ha hb
omega
have hv : lobV L (i + 1) 0 hi (Nat.zero_le _) ∈ lobBlkA L (i + 1) := by
simp only [lobBlkA, mem_filter, mem_univ, true_and, lobV_blk]
have hw : lobV L i 0 hi' (Nat.zero_le _) ∈ lobBlk L i := by
simp only [lobBlk, mem_filter, mem_univ, true_and, lobV_blk, le_refl]
have hedge : ∀ a ∈ lobBlkA L (i + 1), ∀ b ∈ lobBlk L i, (lobF L).Adj a b →
a = lobV L (i + 1) 0 hi (Nat.zero_le _) ∧ b = lobV L i 0 hi' (Nat.zero_le _) := by
intro a ha b hb hab
rw [lobF_adj_val] at hab
simp only [lobBlkA, lobBlk, mem_filter, mem_univ, true_and] at ha hb
simp only [sstar_eq_iff, lobV_blk, lobV_role]
omega
have hB : ∀ u ∈ lobBlk L i, u ≠ lobV L i 0 hi' (Nat.zero_le _) →
u ≠ lobRoot L hL ∧ CDS.par (lobF_isTree L hL) (lobRoot L hL) u ∈ lobBlk L i := by
intro u hu hne
simp only [lobBlk, mem_filter, mem_univ, true_and] at hu ⊢
have hur : u ≠ lobRoot L hL := by
simp only [lobRoot, ne_eq, sstar_eq_iff, lobV_blk, lobV_role]; omega
refine ⟨hur, ?_⟩
rw [lob_par L hL u hur]
have := lobP_blk L u
rw [ne_eq, sstar_eq_iff, lobV_blk, lobV_role] at hne
omega
have hA : ∀ u ∈ lobBlkA L (i + 1), u ≠ lobRoot L hL →
CDS.par (lobF_isTree L hL) (lobRoot L hL) u ∉ lobBlk L i := by
intro u hu hur
rw [lob_par L hL u hur]
simp only [lobBlkA, lobBlk, mem_filter, mem_univ, true_and] at hu ⊢
have := lobP_blk L u
omega
rw [lobBlk_succ, Antinorm3.triple_split (lobF_isTree L hL) (lobRoot L hL) (lobNu L) y hAB hv
hw hwr hpw hedge hB hA, lob_triple_A L hL y (i + 1) hi, ih hi', ← Lobster.M_mulVec,
Matrix.mulVec_mulVec, ← pow_succ']
/-- `W_{F,ν}(y) = fin(M_y^{L-1} u_y)` (`lem:rst-treerec` on `G[S*]`). -/
theorem lob_treeW_eq (L : ℕ) (hL : 1 ≤ L) (y : ℝ) :
treeW (lobF L) (lobNu L) y = Lobster.f ⬝ᵥ (Lobster.M y ^ (L - 1) *ᵥ Lobster.u y) := by
classical
have key := lob_triple_blk L hL y (L - 1) (by omega)
rw [lobBlk_last] at key
have key' : Antinorm3.triple (lobF_isTree L hL) (lobRoot L hL) (lobNu L) y univ (lobRoot L hL)
= Lobster.toT (Lobster.M y ^ (L - 1) *ᵥ Lobster.u y) := key
rw [Antinorm3.treeW_eq_fin (lobF_isTree L hL) (lobRoot L hL) (lobNu L) y, key', Lobster.f_dot]
rfl
/-- **The identity** `W_{S*}(y) = fᵀ M_y^{L-1} u_y`. -/
theorem lobW_eq_matrix (L : ℕ) (hL : 1 ≤ L) (y : ℝ) :
W (gT (Lam L)) (Sstar L) (3 * L) y = Lobster.f ⬝ᵥ (Lobster.M y ^ (L - 1) *ᵥ Lobster.u y) := by
rw [lobW_eq_treeW, lob_treeW_eq L hL y]
/-- `prop:rst-caterpillar`(c), first bound: `μ_t(S*)/C(n,t) ≤ (n+1) 1.71927^{-n}` for `0 ≤ t ≤ n`. -/
theorem lob_moments_upper (L : ℕ) (hL : 1 ≤ L) (t : ℕ) (ht : t ≤ 7 * L) :
mu (gT (Lam L)) (Sstar L) (3 * L) t / ((7 * L).choose t : ℝ)
≤ (((7 * L : ℕ) : ℝ) + 1) / (171927 / 100000 : ℝ) ^ (7 * L) := by
have hB : (0 : ℝ) < (171927 / 100000 : ℝ) ^ (7 * L) := by positivity
have hC : (0 : ℝ) < ((7 * L).choose t : ℝ) := by exact_mod_cast Nat.choose_pos ht
by_cases h3' : 3 * L < t
· have h3 := h3'
have h0 : mu (gT (Lam L)) (Sstar L) (3 * L) t = 0 := by
unfold MLS.mu
refine sum_eq_zero fun X hX => ?_
exfalso
have h1 := card_le_card (mem_powersetCard.1 hX).1
rw [(mem_powersetCard.1 hX).2, card_Sstar] at h1
omega
rw [h0, zero_div]
positivity
· have h3 : t ≤ 3 * L := not_lt.1 h3'
have htn : t < 7 * L := by omega
have hnt : (0 : ℝ) < ((7 * L : ℕ) : ℝ) - t := by
have : (t : ℝ) < ((7 * L : ℕ) : ℝ) := by exact_mod_cast htn
linarith
set y : ℝ := (t : ℝ) / (((7 * L : ℕ) : ℝ) - t) with hy
have hy0 : 0 ≤ y := div_nonneg (Nat.cast_nonneg _) hnt.le
have hy34 : y ≤ 3 / 4 := by
rw [hy, div_le_iff₀ hnt]
have h1 : (t : ℝ) ≤ 3 * L := by exact_mod_cast h3
push_cast
linarith
have hyt : 0 < y ^ t := by
rcases Nat.eq_zero_or_pos t with h | h
· rw [h, pow_zero]; exact one_pos
· exact pow_pos (div_pos (by exact_mod_cast h) hnt) _
have h1 : mu (gT (Lam L)) (Sstar L) (3 * L) t * y ^ t
≤ Lobster.f ⬝ᵥ (Lobster.M y ^ (L - 1) *ᵥ Lobster.u y) := by
rw [← lobW_eq_matrix L hL y]
exact mu_mul_pow_le_W _ _ _ _ _ hy0
have h2 := Lobster.lobster_lower L hL y ⟨hy0, hy34⟩
have h3' : (1 + y) ^ (7 * L) ≤ (((7 * L : ℕ) : ℝ) + 1) * ((7 * L).choose t : ℝ) * y ^ t :=
pow_le_choose_mul (7 * L) t htn
have key : mu (gT (Lam L)) (Sstar L) (3 * L) t * y ^ t * (171927 / 100000 : ℝ) ^ (7 * L)
≤ (((7 * L : ℕ) : ℝ) + 1) * ((7 * L).choose t : ℝ) * y ^ t := by
have := (le_div_iff₀ hB).1 (h1.trans h2)
linarith
rw [div_le_div_iff₀ hC hB]
have key2 : (mu (gT (Lam L)) (Sstar L) (3 * L) t * (171927 / 100000 : ℝ) ^ (7 * L)) * y ^ t
≤ ((((7 * L : ℕ) : ℝ) + 1) * ((7 * L).choose t : ℝ)) * y ^ t := by
calc (mu (gT (Lam L)) (Sstar L) (3 * L) t * (171927 / 100000 : ℝ) ^ (7 * L)) * y ^ t
= mu (gT (Lam L)) (Sstar L) (3 * L) t * y ^ t * (171927 / 100000 : ℝ) ^ (7 * L) := by
ring
_ ≤ _ := key
exact le_of_mul_le_mul_right key2 hyt
/-- `prop:rst-caterpillar`(c), converse: `min_t C(n,t)/μ_t(S*) ≤ C · 1.71928^n`, without division. -/
theorem lob_moments_lower :
∃ C : ℝ, 0 < C ∧ ∀ L : ℕ, 1 ≤ L → ∃ t ≤ 3 * L,
((7 * L).choose t : ℝ)
≤ C * (171928 / 100000 : ℝ) ^ (7 * L) * mu (gT (Lam L)) (Sstar L) (3 * L) t := by
obtain ⟨C, hC, hup⟩ := Lobster.lobster_upper
refine ⟨C, hC, fun L hL => ?_⟩
by_contra hcon
simp only [not_exists, not_and, not_le] at hcon
have h1 := hup L hL
rw [← lobW_eq_matrix L hL, MLS.W_eq_sum_mu _ _ _ (card_Sstar L)] at h1
have h2 : C * (171928 / 100000 : ℝ) ^ (7 * L) * ∑ t ∈ range (3 * L + 1),
(3453 / 10000 : ℝ) ^ t * mu (gT (Lam L)) (Sstar L) (3 * L) t
< ∑ t ∈ range (3 * L + 1), (3453 / 10000 : ℝ) ^ t * ((7 * L).choose t : ℝ) := by
rw [mul_sum]
apply sum_lt_sum_of_nonempty ⟨0, by simp⟩
intro t ht
have hyt : (0 : ℝ) < (3453 / 10000 : ℝ) ^ t := by positivity
have := hcon t (Nat.lt_succ_iff.1 (mem_range.1 ht))
calc C * (171928 / 100000 : ℝ) ^ (7 * L)
* ((3453 / 10000 : ℝ) ^ t * mu (gT (Lam L)) (Sstar L) (3 * L) t)
= (3453 / 10000 : ℝ) ^ t
* (C * (171928 / 100000 : ℝ) ^ (7 * L) * mu (gT (Lam L)) (Sstar L) (3 * L) t) := by
ring
_ < (3453 / 10000 : ℝ) ^ t * ((7 * L).choose t : ℝ) := mul_lt_mul_of_pos_left this hyt
have h3 : ∑ t ∈ range (3 * L + 1), (3453 / 10000 : ℝ) ^ t * ((7 * L).choose t : ℝ)
≤ (1 + 3453 / 10000 : ℝ) ^ (7 * L) := by
rw [add_comm (1 : ℝ), add_pow]
calc ∑ t ∈ range (3 * L + 1), (3453 / 10000 : ℝ) ^ t * ((7 * L).choose t : ℝ)
≤ ∑ t ∈ range (7 * L + 1), (3453 / 10000 : ℝ) ^ t * ((7 * L).choose t : ℝ) := by
apply sum_le_sum_of_subset_of_nonneg
· intro t ht
simp only [mem_range] at ht ⊢
omega
· intro t _ _
positivity
_ = _ := by
refine sum_congr rfl fun t _ => ?_
rw [one_pow, mul_one]
linarith
/-- `prop:rst-caterpillar`(c), the two bounds together. -/
theorem rst_caterpillar_c :
(∀ L : ℕ, 1 ≤ L → ∀ t ≤ 7 * L,
mu (gT (Lam L)) (Sstar L) (3 * L) t / ((7 * L).choose t : ℝ)
≤ (((7 * L : ℕ) : ℝ) + 1) / (171927 / 100000 : ℝ) ^ (7 * L)) ∧
∃ C : ℝ, 0 < C ∧ ∀ L : ℕ, 1 ≤ L → ∃ t ≤ 3 * L,
((7 * L).choose t : ℝ)
≤ C * (171928 / 100000 : ℝ) ^ (7 * L) * mu (gT (Lam L)) (Sstar L) (3 * L) t :=
⟨fun L hL t ht => lob_moments_upper L hL t ht, lob_moments_lower⟩
/-! ### Optional: graphs that agree with `Λ_L` at `S*` -/
section Agree
variable {V : Type*} [Fintype V] [DecidableEq V]
/-- Two graphs with the same edges at every vertex of `S` have the same `|Tm(J_X)|` for `X ⊆ S`. -/
theorem termCount_congr (G H : SimpleGraph V) [DecidableRel G.Adj] [DecidableRel H.Adj]
(S : Finset V) (hGH : ∀ u ∈ S, ∀ v, G.Adj u v ↔ H.Adj u v) (X : Finset V) (hX : X ⊆ S) :
termCount G X = termCount H X := by
have hN : closedNbhd G X = closedNbhd H X := by
ext v
rw [mem_closedNbhd, mem_closedNbhd]
constructor
· rintro (h | ⟨x, hx, hxv⟩)
· exact Or.inl h
· exact Or.inr ⟨x, hx, (hGH x (hX hx) v).1 hxv⟩
· rintro (h | ⟨x, hx, hxv⟩)
· exact Or.inl h
· exact Or.inr ⟨x, hx, (hGH x (hX hx) v).2 hxv⟩
have hI : G.induce (X : Set V) = H.induce (X : Set V) := by
ext a b
exact hGH a.1 (hX (mem_coe.1 a.2)) b.1
unfold termCount CDS.comp
rw [hN, hI]
end Agree
/-- `prop:rst-caterpillar`(c) for every graph that agrees with `Λ_L` on all edges at `S*`
(added edges join two claws), as the paragraph after the proposition says. -/
theorem rst_caterpillar_c_of_agree :
(∀ L : ℕ, 1 ≤ L → ∀ (G : SimpleGraph (Fin L × Fin 7)) [DecidableRel G.Adj],
(∀ u ∈ Sstar L, ∀ v, G.Adj u v ↔ (Lam L).Adj u v) →
∀ t ≤ 7 * L,
mu (gT G) (Sstar L) (3 * L) t / ((7 * L).choose t : ℝ)
≤ (((7 * L : ℕ) : ℝ) + 1) / (171927 / 100000 : ℝ) ^ (7 * L)) ∧
∃ C : ℝ, 0 < C ∧ ∀ L : ℕ, 1 ≤ L → ∀ (G : SimpleGraph (Fin L × Fin 7)) [DecidableRel G.Adj],
(∀ u ∈ Sstar L, ∀ v, G.Adj u v ↔ (Lam L).Adj u v) →
∃ t ≤ 3 * L,
((7 * L).choose t : ℝ)
≤ C * (171928 / 100000 : ℝ) ^ (7 * L) * mu (gT G) (Sstar L) (3 * L) t := by
have hmu : ∀ (L : ℕ) (G : SimpleGraph (Fin L × Fin 7)) [DecidableRel G.Adj],
(∀ u ∈ Sstar L, ∀ v, G.Adj u v ↔ (Lam L).Adj u v) →
∀ t, mu (gT G) (Sstar L) (3 * L) t = mu (gT (Lam L)) (Sstar L) (3 * L) t := by
intro L G _ hG t
unfold MLS.mu RateAssembly.gT
refine sum_congr rfl fun X hX => ?_
rw [termCount_congr G (Lam L) (Sstar L) hG X (mem_powersetCard.1 hX).1]
obtain ⟨C, hC, hlow⟩ := lob_moments_lower
refine ⟨fun L hL G _ hG t ht => ?_, C, hC, fun L hL G _ hG => ?_⟩
· rw [hmu L G hG t]
exact lob_moments_upper L hL t ht
· obtain ⟨t, ht, h⟩ := hlow L hL
exact ⟨t, ht, by rw [hmu L G hG t]; exact h⟩
end MaxLeafFormal.LobsterGraph
Back to top