MaxLeafFormal.CDS
Source file MaxLeafFormal/CDS.lean of the Lean project (how it is built).
Statements of the paper formalised here: Lemma 5.1, Lemma 5.9, Lemma 5.10, Lemma 5.11, Lemma 7.3.
import Mathlib
import MaxLeafFormal.Antinorm3
/-!
# The MaxLeaf–CDS graph bridge
-/
namespace MaxLeafFormal.CDS
open Finset SimpleGraph
variable {V : Type*} [Fintype V] [DecidableEq V]
def closedNbhd (G : SimpleGraph V) [DecidableRel G.Adj] (X : Finset V) : Finset V :=
X ∪ X.biUnion (fun x => G.neighborFinset x)
def IsCDS (G : SimpleGraph V) (S : Finset V) : Prop :=
(G.induce (S : Set V)).Connected ∧ ∀ v, v ∈ S ∨ ∃ u ∈ S, G.Adj v u
noncomputable def γc (G : SimpleGraph V) : ℕ := sInf {s | ∃ S, IsCDS G S ∧ S.card = s}
noncomputable def numLeaves (F : SimpleGraph V) : ℕ :=
(univ.filter (fun v => Nat.card (F.neighborSet v) = 1)).card
noncomputable def termCount (G : SimpleGraph V) [DecidableRel G.Adj] (X : Finset V) : ℕ :=
Fintype.card V - (closedNbhd G X).card + comp G X
/-! ### General lemmas -/
theorem mem_closedNbhd (G : SimpleGraph V) [DecidableRel G.Adj] (X : Finset V) (v : V) :
v ∈ closedNbhd G X ↔ v ∈ X ∨ ∃ x ∈ X, G.Adj x v := by
simp [closedNbhd, mem_neighborFinset]
theorem closedNbhd_mono {F G : SimpleGraph V} [DecidableRel F.Adj] [DecidableRel G.Adj]
(hFG : F ≤ G) (X : Finset V) : closedNbhd F X ⊆ closedNbhd G X := by
intro v hv
rw [mem_closedNbhd] at hv ⊢
rcases hv with h | ⟨x, hx, h⟩
· exact Or.inl h
· exact Or.inr ⟨x, hx, hFG h⟩
/-- A surjective graph homomorphism does not increase the number of components. -/
theorem card_cc_le_of_surjective {α β : Type*} [Finite α] {H : SimpleGraph α} {K : SimpleGraph β}
(f : H →g K) (hf : Function.Surjective f) :
Nat.card K.ConnectedComponent ≤ Nat.card H.ConnectedComponent := by
apply Nat.card_le_card_of_surjective (ConnectedComponent.map f)
intro c
induction c using ConnectedComponent.ind with
| h b =>
obtain ⟨a, rfl⟩ := hf b
exact ⟨H.connectedComponentMk a, rfl⟩
/-- Spanning subgraphs have at least as many induced components. -/
theorem comp_le_comp_of_le {F G : SimpleGraph V} (hFG : F ≤ G) (X : Finset V) :
comp G X ≤ comp F X := by
unfold comp
exact card_cc_le_of_surjective
⟨id, fun h => hFG h⟩ Function.surjective_id
/-- In a connected graph, a nonempty set closed under adjacency is everything. -/
theorem eq_univ_of_closed {H : SimpleGraph V} (hH : H.Connected) (A : Set V) (a : V)
(ha : a ∈ A) (hA : ∀ u ∈ A, ∀ w, H.Adj u w → w ∈ A) (v : V) : v ∈ A := by
obtain ⟨p⟩ := hH a v
induction p with
| nil => exact ha
| cons h _ ih => exact ih (hA _ ha _ h)
/-! ### Rooted trees: a parent function -/
/-! ### 2. `lem:cds-tree` (inequality) -/
theorem tree_inequality (F : SimpleGraph V) [DecidableRel F.Adj] (hF : F.IsTree)
(X : Finset V) (hX : X.Nonempty) :
1 + ∑ x ∈ X, ((F.degree x : ℤ) - 1) ≤ ((closedNbhd F X).card : ℤ) - comp F X := by
obtain ⟨r, hr⟩ := hX
set A := univ.filter (fun w => w ≠ r ∧ par hF r w ∈ X)
set Ain := X.filter (fun w => w ≠ r ∧ par hF r w ∈ X)
set T := X.filter (fun t => ¬ (t ≠ r ∧ par hF r t ∈ X))
-- the degree sum counts the children of `X`
have hdeg : ∑ x ∈ X, ((F.degree x : ℤ) - 1) = (A.card : ℤ) - 1 := by
have h1 : ∑ x ∈ X, (F.degree x : ℤ)
= ∑ x ∈ X, ((univ.filter (fun w => w ≠ r ∧ par hF r w = x)).card : ℤ)
+ ∑ x ∈ X, ((if x = r then 0 else 1 : ℕ) : ℤ) := by
rw [← sum_add_distrib]
exact sum_congr rfl fun x _ => by rw [degree_eq_children hF r x]; push_cast; rfl
have h2 : (A.card : ℤ) = ∑ x ∈ X, ((univ.filter (fun w => w ≠ r ∧ par hF r w = x)).card : ℤ) := by
rw [card_eq_sum_card_fiberwise (f := par hF r) (t := X)
(fun w hw => (mem_filter.1 hw).2.2)]
push_cast
refine sum_congr rfl fun x hx => ?_
congr 2
ext w
simp only [A, mem_filter, mem_univ, true_and]
constructor
· rintro ⟨⟨h, -⟩, h'⟩; exact ⟨h, h'⟩
· rintro ⟨h, h'⟩; exact ⟨⟨h, h' ▸ hx⟩, h'⟩
have h3 : ∑ x ∈ X, ((if x = r then 0 else 1 : ℕ) : ℤ) = (X.card : ℤ) - 1 := by
rw [← sum_erase_add _ _ hr, if_pos rfl, sum_congr rfl (fun x hx => by
rw [if_neg (ne_of_mem_erase hx)])]
have := card_pos.2 ⟨r, hr⟩
simp [card_erase_of_mem hr]
omega
rw [sum_sub_distrib, h1, h2, h3, sum_const, nsmul_eq_mul, mul_one]
ring
-- children of `X` inside and outside `X`
have hA : A.card = Ain.card + (A.filter (fun w => w ∉ X)).card := by
rw [← card_filter_add_card_filter_not (fun w => w ∈ X)]
congr 2
ext w; simp [A, Ain, and_comm]
have hout : (A.filter (fun w => w ∉ X)).card ≤ (closedNbhd F X).card - X.card := by
have hsub : A.filter (fun w => w ∉ X) ⊆ closedNbhd F X \ X := by
intro w hw
simp only [A, mem_filter, mem_univ, true_and] at hw
rw [mem_sdiff, mem_closedNbhd]
exact ⟨Or.inr ⟨_, hw.1.2, (par_spec hF r hw.1.1).1.symm⟩, hw.2⟩
have := card_le_card hsub
rwa [card_sdiff_of_subset (fun x hx => (mem_closedNbhd F X x).2 (Or.inl hx))] at this
have hXN : X.card ≤ (closedNbhd F X).card :=
card_le_card (fun x hx => (mem_closedNbhd F X x).2 (Or.inl hx))
have hT : Ain.card + T.card = X.card := card_filter_add_card_filter_not _
have hc : comp F X ≤ T.card := comp_le_tops hF r X
rw [hdeg]
omega
/-! ### Spanning trees from connected dominating sets -/
theorem leaf_iff {F : SimpleGraph V} {v : V} :
Nat.card (F.neighborSet v) = 1 ↔ ∃ u, F.neighborSet v = {u} := by
rw [Nat.card_coe_set_eq, Set.ncard_eq_one]
theorem spanningTree_of_CDS (G : SimpleGraph V) [DecidableRel G.Adj] (hG : G.Connected)
(S : Finset V) (hS : IsCDS G S) :
∃ F : SimpleGraph V, F ≤ G ∧ F.IsTree ∧
(∀ v ∉ S, Nat.card (F.neighborSet v) = 1) ∧ Fintype.card V - S.card ≤ numLeaves F := by
classical
obtain ⟨hconn, hdom⟩ := hS
have hown : ∀ v, v ∉ S → ∃ u ∈ S, G.Adj v u := fun v hv => (hdom v).resolve_left hv
let own : V → V := fun v => if hv : v ∈ S then v else Classical.choose (hown v hv)
have own_spec : ∀ v (hv : v ∉ S), own v ∈ S ∧ G.Adj v (own v) := fun v hv => by
simp only [own, dif_neg hv]; exact Classical.choose_spec (hown v hv)
-- `G[S]` together with one edge from each outside vertex to its owner
let R : V → V → Prop := fun u v => G.Adj u v ∧
((u ∈ S ∧ v ∈ S) ∨ (u ∉ S ∧ v = own u) ∨ (v ∉ S ∧ u = own v))
let G' : SimpleGraph V :=
{ Adj := R
symm := ⟨fun u v h => ⟨h.1.symm, by tauto⟩⟩
loopless := ⟨fun u h => G.loopless.irrefl u h.1⟩ }
have hG' : ∀ u v, G'.Adj u v ↔ R u v := fun _ _ => Iff.rfl
have hG'G : G' ≤ G := fun u v h => ((hG' u v).1 h).1
obtain ⟨⟨s0, hs0⟩⟩ := hconn.nonempty
have hφ : ∀ a b : (S : Set V), (G.induce (S : Set V)).Adj a b → G'.Adj a.1 b.1 :=
fun a b h => (hG' _ _).2 ⟨by simpa using h, Or.inl ⟨a.2, b.2⟩⟩
let φ : G.induce (S : Set V) →g G' := ⟨Subtype.val, fun {a b} h => hφ a b h⟩
have hreachS : ∀ u ∈ S, G'.Reachable u s0 := fun u hu =>
(hconn.preconnected ⟨u, hu⟩ ⟨s0, hs0⟩).map φ
have hreach : ∀ u, G'.Reachable u s0 := by
intro u
by_cases hu : u ∈ S
· exact hreachS u hu
· exact (Adj.reachable ((hG' _ _).2 ⟨(own_spec u hu).2, Or.inr (Or.inl ⟨hu, rfl⟩)⟩)).trans
(hreachS _ (own_spec u hu).1)
have hG'conn : G'.Connected :=
(connected_iff _).2 ⟨fun u v => (hreach u).trans (hreach v).symm, ⟨s0⟩⟩
obtain ⟨T, hTG', hT⟩ := hG'conn.exists_isTree_le
have hleaf : ∀ v ∉ S, Nat.card (T.neighborSet v) = 1 := by
intro v hv
have hsub : T.neighborSet v ⊆ {own v} := by
intro w hw
rcases ((hG' _ _).1 (hTG' hw)).2 with h | h | h
· exact absurd h.1 hv
· exact h.2
· exact absurd ((own_spec w h.1).1) (h.2 ▸ hv)
have hne : own v ∈ T.neighborSet v := by
obtain ⟨p⟩ := hT.connected v (own v)
have hnil : ¬ p.Nil := fun h => hv (h.eq ▸ (own_spec v hv).1)
have h := p.adj_snd hnil
have hw : p.snd = own v := hsub h
rw [← hw]; exact h
rw [leaf_iff]
exact ⟨own v, Set.Subset.antisymm hsub (Set.singleton_subset_iff.2 hne)⟩
refine ⟨T, hTG'.trans hG'G, hT, hleaf, ?_⟩
unfold numLeaves
calc Fintype.card V - S.card = (univ \ S).card := by rw [card_univ_sdiff]
_ ≤ _ := card_le_card fun v hv => mem_filter.2 ⟨mem_univ _, hleaf v (mem_sdiff.1 hv).2⟩
/-- In a spanning tree with at least 3 vertices, the non-leaves form a connected dominating
set. -/
theorem nonleaves_isCDS (G : SimpleGraph V) (hn : 3 ≤ Fintype.card V)
(F : SimpleGraph V) (hFG : F ≤ G) (hF : F.IsTree) :
IsCDS G (univ.filter (fun v => ¬ Nat.card (F.neighborSet v) = 1)) := by
set S := univ.filter (fun v => ¬ Nat.card (F.neighborSet v) = 1) with hSdef
have memS : ∀ v, v ∈ S ↔ ¬ Nat.card (F.neighborSet v) = 1 := by simp [hSdef]
-- the neighbour of a leaf is not a leaf
have hnb : ∀ v u, F.neighborSet v = {u} → u ∈ S := by
intro v u hv
rw [memS, leaf_iff]
rintro ⟨w, hu⟩
have hvu : F.Adj v u := by
have : u ∈ F.neighborSet v := by rw [hv]; rfl
exact this
have hw : w = v := by
have : v ∈ F.neighborSet u := hvu.symm
rw [hu] at this; exact this.symm
subst hw
have hall : ∀ x, x ∈ ({w, u} : Set V) := eq_univ_of_closed hF.connected {w, u} w
(Set.mem_insert _ _) (by
rintro a (rfl | rfl) b hab
· have : b ∈ F.neighborSet a := hab
rw [hv] at this; exact Or.inr this
· have : b ∈ F.neighborSet a := hab
rw [hu] at this; exact Or.inl this)
have : (univ : Finset V) ⊆ {w, u} := fun x _ => by
have := hall x
simp only [Set.mem_insert_iff, Set.mem_singleton_iff] at this
simp [this]
have := card_le_card this
rw [card_univ] at this
have := card_le_two (a := w) (b := u)
omega
have hdom : ∀ v, v ∈ S ∨ ∃ u ∈ S, G.Adj v u := by
intro v
by_cases hv : v ∈ S
· exact Or.inl hv
· rw [memS, not_not, leaf_iff] at hv
obtain ⟨u, hu⟩ := hv
have hvu : F.Adj v u := by
have : u ∈ F.neighborSet v := by rw [hu]; rfl
exact this
exact Or.inr ⟨u, hnb v u hu, hFG hvu⟩
refine ⟨?_, hdom⟩
-- connectivity: walks in `F` between non-leaves can be shortcut past leaves
have hwalk : ∀ m, ∀ a b (p : F.Walk a b) (ha : a ∈ S) (hb : b ∈ S), p.length = m →
(G.induce (S : Set V)).Reachable ⟨a, ha⟩ ⟨b, hb⟩ := by
intro m
induction m using Nat.strong_induction_on with
| _ m ih =>
intro a b p ha hb hm
cases p with
| nil => exact Reachable.refl _
| @cons _ c _ h q =>
by_cases hc : c ∈ S
· have hadj : (G.induce (S : Set V)).Adj ⟨a, ha⟩ ⟨c, hc⟩ := by simpa using hFG h
exact hadj.reachable.trans (ih q.length (by simp at hm; omega) c b q hc hb rfl)
· rw [memS, not_not, leaf_iff] at hc
obtain ⟨u, hu⟩ := hc
have hca : u = a := by
have : a ∈ F.neighborSet c := h.symm
rw [hu] at this; exact this.symm
cases q with
| nil =>
exact absurd (hnb _ _ hu) (by
rw [hca, memS, not_not]
rw [memS] at hb
exact absurd (by rw [leaf_iff]; exact ⟨u, hu⟩) hb)
| @cons _ d _ h' q' =>
have hd : d = a := by
have : d ∈ F.neighborSet c := h'
rw [hu] at this; rw [← hca]; exact this
subst hd
exact ih q'.length (by simp at hm; omega) _ b q' ha hb rfl
rw [connected_iff]
refine ⟨fun x y => ?_, ?_⟩
· obtain ⟨p⟩ := hF.connected x.1 y.1
exact hwalk _ x.1 y.1 p x.2 y.2 rfl
· obtain ⟨v⟩ : Nonempty V := ⟨(Fintype.card_pos_iff.1 (by omega)).some⟩
rcases hdom v with h | ⟨u, hu, -⟩
· exact ⟨⟨v, h⟩⟩
· exact ⟨⟨u, hu⟩⟩
theorem numLeaves_add_card (F : SimpleGraph V) :
numLeaves F + (univ.filter (fun v => ¬ Nat.card (F.neighborSet v) = 1)).card
= Fintype.card V := by
unfold numLeaves
rw [card_filter_add_card_filter_not, card_univ]
/-! ### 1. `lem:cds-maxleaf` -/
theorem numLeaves_le (G : SimpleGraph V) (hn : 3 ≤ Fintype.card V)
(F : SimpleGraph V) (hFG : F ≤ G) (hF : F.IsTree) :
numLeaves F ≤ Fintype.card V - γc G := by
have hS := nonleaves_isCDS G hn F hFG hF
have hγ : γc G ≤ (univ.filter (fun v => ¬ Nat.card (F.neighborSet v) = 1)).card :=
Nat.sInf_le ⟨_, hS, rfl⟩
have := numLeaves_add_card F
omega
theorem maxLeaf_eq (G : SimpleGraph V) [DecidableRel G.Adj] (hG : G.Connected)
(hn : 3 ≤ Fintype.card V) :
IsGreatest {ℓ | ∃ F : SimpleGraph V, F ≤ G ∧ F.IsTree ∧ numLeaves F = ℓ}
(Fintype.card V - γc G) := by
refine ⟨?_, ?_⟩
· obtain ⟨T0, hT0G, hT0⟩ := hG.exists_isTree_le
have hne : {s | ∃ S, IsCDS G S ∧ S.card = s}.Nonempty :=
⟨_, _, nonleaves_isCDS G hn T0 hT0G hT0, rfl⟩
obtain ⟨S, hS, hSc⟩ := Nat.sInf_mem hne
obtain ⟨F, hFG, hF, -, hle⟩ := spanningTree_of_CDS G hG S hS
refine ⟨F, hFG, hF, le_antisymm (numLeaves_le G hn F hFG hF) ?_⟩
change Fintype.card V - sInf _ ≤ _
rwa [← hSc]
· rintro ℓ ⟨F, hFG, hF, rfl⟩
exact numLeaves_le G hn F hFG hF
/-- With at most two vertices, two vertices that differ from `v` are equal. -/
theorem eq_of_ne_of_card_le_two (hn : Fintype.card V ≤ 2) {v x y : V} (hx : x ≠ v) (hy : y ≠ v) :
x = y := by
by_contra hxy
have h3 : ({v, x, y} : Finset V).card = 3 :=
Finset.card_eq_three.mpr ⟨v, x, y, hx.symm, hy.symm, hxy, rfl⟩
have := Finset.card_le_univ ({v, x, y} : Finset V)
omega
/-- In a connected graph, a vertex with another vertex in the graph has a neighbour. -/
theorem exists_adj_of_connected {F : SimpleGraph V} (hF : F.Connected) {v w : V} (hvw : v ≠ w) :
∃ x, F.Adj v x := by
obtain ⟨p⟩ := hF.preconnected v w
cases p with
| nil => exact absurd rfl hvw
| cons h _ => exact ⟨_, h⟩
/-- `lem:cds-maxleaf`, the case `n ≤ 2`: the only spanning tree of `G` is `G` itself, with no leaf
if `n = 1` and two leaves if `n = 2`. -/
theorem maxLeaf_small (G : SimpleGraph V) (hG : G.Connected) (hn : Fintype.card V ≤ 2) :
G.IsTree ∧ (∀ F : SimpleGraph V, F ≤ G → F.IsTree → F = G) ∧
(Fintype.card V = 1 → numLeaves G = 0) ∧ (Fintype.card V = 2 → numLeaves G = 2) := by
have key : ∀ F : SimpleGraph V, F ≤ G → F.IsTree → F = G := by
intro F hFG hF
ext u v
constructor
· intro h
exact hFG h
· intro h
obtain ⟨x, hx⟩ := exists_adj_of_connected hF.connected (G.ne_of_adj h)
have hxv : x = v :=
eq_of_ne_of_card_le_two hn (F.ne_of_adj hx).symm (G.ne_of_adj h).symm
rw [← hxv]
exact hx
obtain ⟨T, hTG, hT⟩ := hG.exists_isTree_le
have hGt : G.IsTree := by
rw [← key T hTG hT]
exact hT
refine ⟨hGt, key, ?_, ?_⟩
· intro h1
unfold numLeaves
rw [Finset.card_eq_zero, Finset.filter_eq_empty_iff]
intro v _ hv
obtain ⟨u, hu⟩ := leaf_iff.mp hv
have hmem : u ∈ G.neighborSet v := by
rw [hu]
exact Set.mem_singleton u
have hadj : G.Adj v u := (G.mem_neighborSet v u).mp hmem
exact G.ne_of_adj hadj (Fintype.card_le_one_iff.mp (by omega) v u)
· intro h2
unfold numLeaves
rw [Finset.filter_true_of_mem, Finset.card_univ, h2]
intro v _
obtain ⟨w, hw⟩ := Fintype.exists_ne_of_one_lt_card (by omega : 1 < Fintype.card V) v
obtain ⟨x, hx⟩ := exists_adj_of_connected hGt.connected hw.symm
refine leaf_iff.mpr ⟨x, ?_⟩
ext y
simp only [SimpleGraph.mem_neighborSet, Set.mem_singleton_iff]
constructor
· intro hy
exact eq_of_ne_of_card_le_two hn (G.ne_of_adj hy).symm (G.ne_of_adj hx).symm
· rintro rfl
exact hx
/-! ### 3. `lem:cds-pointwise` -/
theorem pointwise (G : SimpleGraph V) [DecidableRel G.Adj] (hn : 2 ≤ Fintype.card V)
(S : Finset V) (hS : IsCDS G S)
(F : SimpleGraph V) [DecidableRel F.Adj] (hFG : F ≤ G) (hF : F.IsTree)
(hleaf : ∀ v ∉ S, F.degree v = 1) :
∑ u ∈ S, ((F.degree u : ℤ) - 1) = Fintype.card V - 2 ∧
∀ X ⊆ S, X.Nonempty →
1 + ∑ x ∈ X, ((F.degree x : ℤ) - 1) ≤ ((closedNbhd G X).card : ℤ) - comp G X := by
refine ⟨?_, fun X _ hX => ?_⟩
· have h1 : ∑ v, (F.degree v : ℤ) = 2 * ((Fintype.card V : ℤ) - 1) := by
have := sum_degrees_eq_twice_card_edges F
have h2 := hF.card_edgeFinset
have : ∑ v, (F.degree v : ℤ) = 2 * (F.edgeFinset.card : ℤ) := by exact_mod_cast this
rw [this]
have : (F.edgeFinset.card : ℤ) + 1 = Fintype.card V := by exact_mod_cast h2
linarith
have h2 : ∑ v ∈ Sᶜ, (F.degree v : ℤ) = (Fintype.card V : ℤ) - S.card := by
rw [sum_congr rfl fun v hv => by rw [hleaf v (mem_compl.1 hv)]]
simp only [Nat.cast_one, sum_const, nsmul_eq_mul, mul_one]
rw [card_compl, Nat.cast_sub (card_le_univ S)]
have h3 := sum_add_sum_compl S (fun v => (F.degree v : ℤ))
rw [sum_sub_distrib, sum_const, nsmul_eq_mul, mul_one]
linarith
· have h1 := tree_inequality F hF X hX
have h2 : (closedNbhd F X).card ≤ (closedNbhd G X).card := card_le_card (closedNbhd_mono hFG X)
have h3 := comp_le_comp_of_le hFG X
have : ((closedNbhd F X).card : ℤ) - comp F X ≤ ((closedNbhd G X).card : ℤ) - comp G X := by
push_cast; omega
linarith
/-! ### 4. `lem:cds-C` -/
theorem choose_pred_mul (s t : ℕ) (ht1 : 1 ≤ t) (hts : t ≤ s) :
((s - 1).choose (t - 1) : ℝ) * s = (s.choose t : ℝ) * t := by
obtain ⟨s', rfl⟩ : ∃ s', s = s' + 1 := ⟨s - 1, by omega⟩
obtain ⟨t', rfl⟩ : ∃ t', t = t' + 1 := ⟨t - 1, by omega⟩
have := Nat.add_one_mul_choose_eq s' t'
simp only [Nat.add_sub_cancel]
rw [mul_comm]
exact_mod_cast this
theorem mean_terminals (G : SimpleGraph V) [DecidableRel G.Adj] (hG : G.Connected)
(hn : 2 ≤ Fintype.card V) (S : Finset V) (hS : IsCDS G S) (t : ℕ)
(ht1 : 1 ≤ t) (hts : t ≤ S.card) :
1 + (t : ℝ) * (Fintype.card V - 2) / S.card
≤ (∑ X ∈ S.powersetCard t, (((closedNbhd G X).card : ℝ) - comp G X))
/ S.card.choose t
∧ (∑ X ∈ S.powersetCard t, (termCount G X : ℝ)) / S.card.choose t
≤ Fintype.card V - 1 - (t : ℝ) * (Fintype.card V - 2) / S.card := by
classical
obtain ⟨F, hFG, hF, hleafF, -⟩ := spanningTree_of_CDS G hG S hS
have hleaf : ∀ v ∉ S, F.degree v = 1 := fun v hv => by
rw [← card_neighborSet_eq_degree, ← Nat.card_eq_fintype_card]; exact hleafF v hv
obtain ⟨-, hpt⟩ := pointwise G hn S hS F hFG hF hleaf
have hw := (pointwise G hn S hS F hFG hF hleaf).1
set s := S.card with hs
set P := S.powersetCard t
set w : V → ℝ := fun x => (F.degree x : ℝ) - 1
have hs0 : (0:ℝ) < s := by exact_mod_cast (show 0 < s by omega)
have hN : (0:ℝ) < s.choose t := by exact_mod_cast Nat.choose_pos hts
-- pointwise bound, summed
have hX : ∀ X ∈ P, 1 + ∑ x ∈ X, w x ≤ ((closedNbhd G X).card : ℝ) - comp G X := by
intro X hX
rw [mem_powersetCard] at hX
have hne : X.Nonempty := card_pos.1 (by omega)
have := hpt X hX.1 hne
have : ((1 + ∑ x ∈ X, ((F.degree x : ℤ) - 1) : ℤ) : ℝ)
≤ ((((closedNbhd G X).card : ℤ) - comp G X : ℤ) : ℝ) := by exact_mod_cast this
push_cast at this
exact this
-- double counting
have hcount : ∀ u ∈ S, (P.filter (fun X => u ∈ X)).card = (s - 1).choose (t - 1) := by
intro u hu
have := card_filter_powersetCard_subset {u} S t (singleton_subset_iff.2 hu)
(by simp; omega)
simp only [singleton_subset_iff, card_singleton] at this
exact this
have hdouble : ∑ X ∈ P, ∑ x ∈ X, w x = (s - 1).choose (t - 1) * ∑ u ∈ S, w u := by
have : ∀ X ∈ P, ∑ x ∈ X, w x = ∑ u ∈ S, if u ∈ X then w u else 0 := by
intro X hX
rw [← sum_filter, filter_mem_eq_inter, inter_eq_right.2 (mem_powersetCard.1 hX).1]
rw [sum_congr rfl this, sum_comm, mul_sum]
refine sum_congr rfl fun u hu => ?_
rw [← sum_filter, sum_const, nsmul_eq_mul, hcount u hu, mul_comm]
have hwS : ∑ u ∈ S, w u = (Fintype.card V : ℝ) - 2 := by
have : ((∑ u ∈ S, ((F.degree u : ℤ) - 1) : ℤ) : ℝ) = (((Fintype.card V : ℤ) - 2 : ℤ) : ℝ) := by
rw [hw]
push_cast at this
exact this
have hchoose : ((s - 1).choose (t - 1) : ℝ) * s = (s.choose t : ℝ) * t :=
choose_pred_mul s t ht1 hts
have hlow : (s.choose t : ℝ) + (s - 1).choose (t - 1) * ((Fintype.card V : ℝ) - 2)
≤ ∑ X ∈ P, (((closedNbhd G X).card : ℝ) - comp G X) := by
calc (s.choose t : ℝ) + (s - 1).choose (t - 1) * ((Fintype.card V : ℝ) - 2)
= ∑ X ∈ P, (1 + ∑ x ∈ X, w x) := by
rw [sum_add_distrib, hdouble, hwS, sum_const, card_powersetCard, nsmul_eq_mul, mul_one]
_ ≤ _ := sum_le_sum hX
have hfirst : 1 + (t : ℝ) * (Fintype.card V - 2) / s
≤ (∑ X ∈ P, (((closedNbhd G X).card : ℝ) - comp G X)) / s.choose t := by
rw [le_div_iff₀ hN]
calc (1 + (t : ℝ) * (Fintype.card V - 2) / s) * s.choose t
= (s.choose t : ℝ) + (s - 1).choose (t - 1) * ((Fintype.card V : ℝ) - 2) := by
field_simp
linear_combination (-((Fintype.card V : ℝ) - 2)) * hchoose
_ ≤ _ := hlow
refine ⟨hfirst, ?_⟩
have hterm : ∀ X ∈ P, (termCount G X : ℝ)
= Fintype.card V - (((closedNbhd G X).card : ℝ) - comp G X) := by
intro X _
unfold termCount
rw [Nat.cast_add, Nat.cast_sub (card_le_univ _)]
ring
rw [sum_congr rfl hterm, sum_sub_distrib, sum_const, card_powersetCard, nsmul_eq_mul,
sub_div, mul_div_cancel_left₀ _ hN.ne']
linarith
/-! ### 5. `lem:rst-E` -/
theorem tree_reduction (G : SimpleGraph V) [DecidableRel G.Adj] (hG : G.Connected)
(S : Finset V) (hS : IsCDS G S)
(F : SimpleGraph S) (hFG : F ≤ G.induce (S : Set V)) (hF : F.IsTree)
(o : {v // v ∉ S} → S) (ho : ∀ v, G.Adj v.1 (o v).1) :
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) ∧
∀ y : ℝ, 0 ≤ y →
treeW F ν y ≤ ∑ X ∈ S.powerset, y ^ X.card * (1/2 : ℝ) ^ termCount G X := by
classical
intro ν
have hpot : ∀ X : Finset S, termCount G (X.map (Function.Embedding.subtype _))
≤ treePotential F ν X := by
intro X
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]
-- (1) outside vertices not dominated by `X` have their owner 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 hBsub : B ⊆ univ.filter (fun w => o w ∉ X) := by
intro w hw
simp only [B, mem_filter, mem_univ, true_and] at hw ⊢
intro hoX
apply hw
rw [mem_closedNbhd]
exact Or.inr ⟨(o w).1, (memXv _).2 hoX, (ho w).symm⟩
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, hsumν]; exact card_le_card hBsub
-- (2) solution vertices not dominated by `X` are 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]
apply card_le_card
intro v hv
simp only [C, mem_filter, mem_univ, true_and] at 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]
have : (G.induce (S : Set V)).Adj v u := hFG hvu
exact Or.inr ⟨u.1, (memXv u).2 huX, (by simpa using this : G.Adj v.1 u.1).symm⟩
-- (3) components
have h3 : comp G Xv ≤ Nat.card (F.induce (X : Set S)).ConnectedComponent := by
unfold comp
let f : F.induce (X : Set S) →g G.induce (Xv : Set V) :=
⟨fun x => ⟨x.1.1, (memXv x.1).2 x.2⟩, fun {a b} h => by
have : (G.induce (S : Set V)).Adj a.1 b.1 := hFG h
simpa using this⟩
apply card_cc_le_of_surjective f
intro x
have hx : x.1 ∈ X.map (Function.Embedding.subtype _) := x.2
obtain ⟨v, hvX, hv⟩ := mem_map.1 hx
exact ⟨⟨v, hvX⟩, Subtype.ext hv⟩
-- 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
refine ⟨hpot, fun y hy => ?_⟩
unfold treeW
have hle : ∀ X ∈ (univ : Finset S).powerset, y ^ X.card * (1/2 : ℝ) ^ treePotential F ν X
≤ y ^ X.card * (1/2 : ℝ) ^ termCount G (X.map (Function.Embedding.subtype _)) := by
intro X _
exact mul_le_mul_of_nonneg_left (pow_le_pow_of_le_one (by norm_num) (by norm_num) (hpot X))
(pow_nonneg hy _)
refine (sum_le_sum hle).trans (le_of_eq ?_)
refine sum_nbij' (fun X => X.map (Function.Embedding.subtype _))
(fun Y => Y.subtype (fun x => x ∈ S)) ?_ ?_ ?_ ?_ ?_
· 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]
/-! ### 6. Joint corollary with the RS-θ antinorm certificates -/
/-- The common step: a tree bound on every tree turns into a bound on `W_S(y)` for every
connected dominating set `S`. -/
theorem moment_bound_of_tree_bound.{u} (y c e₁ e₂ : ℝ) (hy : 0 ≤ y)
(htree : ∀ (U : Type u) [Fintype U] [DecidableEq U] (T : SimpleGraph U) [DecidableRel T.Adj],
T.IsTree → ∀ ν : U → ℕ, c * e₁ ^ Fintype.card U * e₂ ^ (∑ u, ν u) ≤ treeW T ν y)
{V : Type u} [Fintype V] [DecidableEq V]
(G : SimpleGraph V) [DecidableRel G.Adj] (hG : G.Connected) (S : Finset V) (hS : IsCDS G S) :
c * e₁ ^ S.card * e₂ ^ (Fintype.card V - S.card)
≤ ∑ X ∈ S.powerset, y ^ X.card * (1/2 : ℝ) ^ termCount G X := by
classical
obtain ⟨F, hFG, hF⟩ := hS.1.exists_isTree_le
have hown : ∀ v : {v // v ∉ S}, ∃ u : S, G.Adj v.1 u.1 := by
intro v
rcases hS.2 v.1 with h | ⟨u, hu, huv⟩
· exact absurd h v.2
· exact ⟨⟨u, hu⟩, huv⟩
choose o ho using hown
have hred := (tree_reduction G hG S hS F hFG hF o ho).2 y hy
have hb := htree S F hF (fun u => (univ.filter (fun v => o v = u)).card)
have hcard : Fintype.card S = S.card := Fintype.card_coe S
have hsum : ∑ u : S, (univ.filter (fun v : {v // v ∉ S} => o v = u)).card
= Fintype.card V - S.card := by
rw [← card_eq_sum_card_fiberwise (fun v _ => mem_univ (o v)), card_univ,
Fintype.card_subtype_compl, Fintype.card_coe]
rw [hcard, hsum] at hb
exact hb.trans hred
/-- The joint corollary for certificate 0. -/
theorem rstheta_moment_bound_0
(G : SimpleGraph V) [DecidableRel G.Adj] (hG : G.Connected)
(S : Finset V) (hS : IsCDS G S) :
(6212/10000 : ℝ) * (747593601/960952792 : ℝ) ^ S.card
* (512099210/652701491 : ℝ) ^ (Fintype.card V - S.card)
≤ ∑ X ∈ S.powerset, (69/200 : ℝ) ^ X.card * (1/2 : ℝ) ^ termCount G X :=
moment_bound_of_tree_bound _ _ _ _ (by norm_num)
(fun _ _ _ T _ hT ν => rstheta_tree_bound_0 T hT ν) G hG S hS
/-- The joint corollary for certificate 1. -/
theorem rstheta_moment_bound_1
(G : SimpleGraph V) [DecidableRel G.Adj] (hG : G.Connected)
(S : Finset V) (hS : IsCDS G S) :
(6293/10000 : ℝ) * (248231700/312721579 : ℝ) ^ S.card
* (568097827/739289481 : ℝ) ^ (Fintype.card V - S.card)
≤ ∑ X ∈ S.powerset, (17/50 : ℝ) ^ X.card * (1/2 : ℝ) ^ termCount G X :=
moment_bound_of_tree_bound _ _ _ _ (by norm_num)
(fun _ _ _ T _ hT ν => rstheta_tree_bound_1 T hT ν) G hG S hS
end MaxLeafFormal.CDS
Back to top