The proof
Erdős problem 108
For every r ≥ 4 and k ≥ 2 is there some finite f(k,r) such that every graph of chromatic number ≥ f(k,r) contains a subgraph of girth ≥ r and chromatic number ≥ k?Source
Main.lean · 1846 lines · 84.5 kB
/-!
# A counterexample to Erdős problem 108
For every chromatic threshold, we construct an arc graph exceeding that threshold
whose four-cycle-free subgraphs are six-colorable. Taking girth five and chromatic
number seven therefore disproves the assertion in the target.
The base graph is obtained by finite counting in a multipartite random model.
Its parts have explicitly chosen sizes. All probability estimates, coloring
arguments, and the lift to arbitrary universes are proved below.
-/
open SimpleGraph
universe u
section ArcGraph
variable {V : Type u} [LinearOrder V]
/-- Edges directed from their smaller endpoint to their larger endpoint. -/
abbrev Arc (F : SimpleGraph V) := {e : V × V // e.1 < e.2 ∧ F.Adj e.1 e.2}
/-- The undirected graph on concatenating directed edges. -/
def arcGraph (F : SimpleGraph V) : SimpleGraph (Arc F) where
Adj a b := a.1.2 = b.1.1 ∨ b.1.2 = a.1.1
symm := ⟨fun _ _ => Or.symm⟩
loopless := ⟨fun a h => (ne_of_lt a.2.1) (h.elim Eq.symm Eq.symm)⟩
/-- The colors appearing on edges directed out of a vertex. -/
def outgoingColors {F : SimpleGraph V} {α : Type*}
(c : (arcGraph F).Coloring α) (v : V) : Set α :=
{i | ∃ a : Arc F, a.1.1 = v ∧ c a = i}
theorem outgoingColors_ne {F : SimpleGraph V} {α : Type*}
(c : (arcGraph F).Coloring α) (a : Arc F) :
outgoingColors c a.1.1 ≠ outgoingColors c a.1.2 := by
intro h
have hm : c a ∈ outgoingColors c a.1.1 := ⟨a, rfl, rfl⟩
rw [h] at hm
obtain ⟨b, hb, hbc⟩ := hm
exact c.valid (Or.inl hb.symm) hbc.symm
/-- A coloring of the arc graph gives a set-valued coloring of the base graph. -/
def baseColoring {F : SimpleGraph V} {α : Type*}
(c : (arcGraph F).Coloring α) : F.Coloring (Set α) :=
SimpleGraph.Coloring.mk (outgoingColors c) fun {x y} hxy => by
rcases lt_or_gt_of_ne hxy.ne with hlt | hgt
· exact outgoingColors_ne c ⟨(x, y), hlt, hxy⟩
· exact (outgoingColors_ne c ⟨(y, x), hgt, hxy.symm⟩).symm
/-- Lemma 2 of the attachment, stated without natural-valued chromatic numbers. -/
theorem base_colorable_of_arc_colorable {F : SimpleGraph V} {t : ℕ}
(h : (arcGraph F).Colorable t) : F.Colorable (2 ^ t) := by
obtain ⟨c⟩ := h
simpa using (baseColoring c).colorable
end ArcGraph
/-- Absence of a four-cycle, allowing arbitrary deletions of edges. -/
def FourCycleFree {V : Type*} (H : SimpleGraph V) : Prop :=
∀ a b x y, a ≠ b → x ≠ y →
H.Adj a x → H.Adj a y → H.Adj b x → H.Adj b y → False
theorem fourCycleFree_of_girth_ge_five {V : Type*} {H : SimpleGraph V}
(hg : 5 ≤ H.girth) : FourCycleFree H := by
intro a b x y hab hxy hax hay hbx hby
let w : H.Walk a a := .cons hax (.cons hbx.symm (.cons hby (.cons hay.symm .nil)))
have hw : w.IsCycle := {
edges_nodup := by simp [w, hab, hab.symm, hxy, hax.ne, hay.ne, hby.ne]
ne_nil := by simp [w]
support_nodup := by simp [w, hab.symm, hxy, hax.ne.symm, hay.ne.symm, hbx.ne.symm, hby.ne]
}
have hle := H.girth_le_length hw
have hlen : w.length = 4 := rfl
omega
/-- Distinct vertices with two neighbors in `T` require distinct neighbor pairs. -/
theorem card_le_choose_two_of_fourCycleFree {V : Type*} {H : SimpleGraph V}
(h4 : FourCycleFree H) (S T : Finset V)
(hS : ∀ a ∈ S, ∃ x ∈ T, ∃ y ∈ T, x ≠ y ∧ H.Adj a x ∧ H.Adj a y) :
S.card ≤ T.card.choose 2 := by
classical
have hpair : ∀ a : S, ∃ p : T.powersetCard 2,
∀ x ∈ p.1, H.Adj a.1 x := by
intro a
obtain ⟨x, hx, y, hy, hxy, hax, hay⟩ := hS a.1 a.2
refine ⟨⟨{x, y}, ?_⟩, ?_⟩
· refine Finset.mem_powersetCard.mpr ⟨?_, by simp [hxy]⟩
intro z hz
rcases Finset.mem_insert.mp hz with rfl | hz
· exact hx
· simpa only [Finset.mem_singleton.mp hz] using hy
· intro z hz
simp only [Finset.mem_insert, Finset.mem_singleton] at hz
rcases hz with rfl | rfl
· exact hax
· exact hay
choose p hp using hpair
have hinj : Function.Injective p := by
intro a b heq
apply Subtype.ext
by_contra hab
have hcard : (p a).1.card = 2 := (Finset.mem_powersetCard.mp (p a).2).2
obtain ⟨x, hx, y, hy, hxy⟩ := Finset.one_lt_card.mp (show 1 < (p a).1.card by omega)
have hx' : x ∈ (p b).1 := by simpa only [heq] using hx
have hy' : y ∈ (p b).1 := by simpa only [heq] using hy
exact h4 a b x y hab hxy (hp a x hx) (hp a y hy) (hp b x hx') (hp b y hy')
simpa using Fintype.card_le_of_injective p hinj
section Selection
variable {V : Type u} [LinearOrder V] {F : SimpleGraph V}
/-- An arc vertex with at least two distinct outgoing neighbors in `H`. -/
def Branching (H : SimpleGraph (Arc F)) (a : Arc F) : Prop :=
∃ b c : Arc F, b ≠ c ∧ H.Adj a b ∧ H.Adj a c ∧
a.1.2 = b.1.1 ∧ a.1.2 = c.1.1
/-- The base graph whose directed edges are the members of `S`. -/
def baseOfArcs (S : Set (Arc F)) : SimpleGraph V where
Adj x y := ∃ a ∈ S, (a.1.1 = x ∧ a.1.2 = y) ∨ (a.1.1 = y ∧ a.1.2 = x)
symm := ⟨fun _ _ ⟨a, ha, he⟩ => ⟨a, ha, he.symm⟩⟩
loopless := ⟨fun x ⟨a, _, he⟩ => by
rcases he with he | he <;> exact (ne_of_lt a.2.1) (he.1.trans he.2.symm)⟩
theorem baseOfArcs_le (S : Set (Arc F)) : baseOfArcs S ≤ F := by
intro x y ⟨a, _, he⟩
rcases he with ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩
· exact a.2.2
· exact a.2.2.symm
theorem branching_colorable {H : SimpleGraph (Arc F)} {a : ℕ}
(hH : H ≤ arcGraph F) (hc : (baseOfArcs {b | Branching H b}).Colorable a) :
(H.induce {b | Branching H b}).Colorable a := by
obtain ⟨c⟩ := hc
refine ⟨SimpleGraph.Coloring.mk (fun b => c b.1.1.1) ?_⟩
intro b d hbd
apply c.valid
rcases hH hbd with hbd | hdb
· exact ⟨b.1, b.2, Or.inl ⟨rfl, hbd⟩⟩
· exact ⟨d.1, d.2, Or.inr ⟨rfl, hdb⟩⟩
variable [Fintype V]
noncomputable def outgoingArcs (F : SimpleGraph V) (v : V) : Finset (Arc F) := by
classical
exact Finset.univ.filter fun a => a.1.1 = v
noncomputable def incomingBranches (H : SimpleGraph (Arc F)) (v : V) : Finset (Arc F) := by
classical
exact Finset.univ.filter fun a => a.1.2 = v ∧ Branching H a
theorem incomingBranches_card_le {H : SimpleGraph (Arc F)}
(h4 : FourCycleFree H) (v : V) :
(incomingBranches H v).card ≤ (outgoingArcs F v).card.choose 2 := by
classical
apply card_le_choose_two_of_fourCycleFree h4
intro a ha
obtain ⟨hav, b, c, hbc, hab, hac, hbt, hct⟩ :=
(Finset.mem_filter.mp ha).2
refine ⟨b, ?_, c, ?_, hbc, hab, hac⟩
· simp [outgoingArcs, ← hbt, hav]
· simp [outgoingArcs, ← hct, hav]
theorem selected_degree_le {H : SimpleGraph (Arc F)} (h4 : FourCycleFree H) (v : V) :
Nat.card ((baseOfArcs {a | Branching H a}).neighborSet v) ≤
(outgoingArcs F v).card + (outgoingArcs F v).card.choose 2 := by
classical
let J := baseOfArcs {a | Branching H a}
change Nat.card (J.neighborSet v) ≤ _
rw [Nat.card_eq_fintype_card, SimpleGraph.card_neighborSet_eq_degree]
have hsub : J.neighborFinset v ⊆
(outgoingArcs F v).image (fun a => a.1.2) ∪
(incomingBranches H v).image (fun a => a.1.1) := by
intro w hw
obtain ⟨a, ha, he⟩ := (J.mem_neighborFinset v w).mp hw
rcases he with ⟨hat, hah⟩ | ⟨hat, hah⟩
· apply Finset.mem_union_left
exact Finset.mem_image.mpr ⟨a, by simp [outgoingArcs, hat], hah⟩
· apply Finset.mem_union_right
exact Finset.mem_image.mpr ⟨a,
Finset.mem_filter.mpr ⟨Finset.mem_univ a, hah, ha⟩, hat⟩
calc
J.degree v = (J.neighborFinset v).card := rfl
_ ≤ ((outgoingArcs F v).image (fun a => a.1.2) ∪
(incomingBranches H v).image (fun a => a.1.1)).card := Finset.card_le_card hsub
_ ≤ ((outgoingArcs F v).image (fun a => a.1.2)).card +
((incomingBranches H v).image (fun a => a.1.1)).card := Finset.card_union_le _ _
_ ≤ (outgoingArcs F v).card + (incomingBranches H v).card :=
Nat.add_le_add (Finset.card_image_le) (Finset.card_image_le)
_ ≤ _ := Nat.add_le_add_left (incomingBranches_card_le h4 v) _
end Selection
/-- Greedy coloring, with a low-degree vertex available in every remaining set. -/
theorem colorable_of_low_degree {V : Type*} [Fintype V] [DecidableEq V]
(H : SimpleGraph V) [DecidableRel H.Adj] {k : ℕ} (hk : 0 < k)
(hdeg : ∀ S : Finset V, S.Nonempty → ∃ v ∈ S, (S.filter (H.Adj v)).card < k) :
H.Colorable k := by
classical
have hcolor : ∀ S : Finset V, ∃ c : V → Fin k,
∀ x ∈ S, ∀ y ∈ S, H.Adj x y → c x ≠ c y := by
intro S
induction S using Finset.strongInductionOn with
| _ S ih =>
by_cases hS : S.Nonempty
· obtain ⟨v, hv, hvc⟩ := hdeg S hS
obtain ⟨c, hc⟩ := ih (S.erase v) (Finset.erase_ssubset hv)
have hcard : ((S.filter (H.Adj v)).image c).card <
(Finset.univ : Finset (Fin k)).card := by
simpa using lt_of_le_of_lt Finset.card_image_le hvc
obtain ⟨j, _, hj⟩ := Finset.exists_mem_notMem_of_card_lt_card hcard
refine ⟨Function.update c v j, ?_⟩
intro x hx y hy hxy
by_cases hxv : x = v
· subst x
have hyv : y ≠ v := hxy.ne.symm
simp only [Function.update_self, Function.update_of_ne hyv]
intro heq
exact hj (Finset.mem_image.mpr ⟨y, Finset.mem_filter.mpr ⟨hy, hxy⟩, heq.symm⟩)
· by_cases hyv : y = v
· subst y
simp only [Function.update_self, Function.update_of_ne hxv]
intro heq
exact hj (Finset.mem_image.mpr ⟨x, Finset.mem_filter.mpr ⟨hx, hxy.symm⟩, heq⟩)
· simpa only [Function.update_of_ne hxv, Function.update_of_ne hyv] using
hc x (Finset.mem_erase.mpr ⟨hxv, hx⟩) y (Finset.mem_erase.mpr ⟨hyv, hy⟩) hxy
· refine ⟨fun _ => ⟨0, hk⟩, ?_⟩
intro x hx
exact (hS ⟨x, hx⟩).elim
obtain ⟨c, hc⟩ := hcolor Finset.univ
exact ⟨SimpleGraph.Coloring.mk c fun {x y} hxy =>
hc x (Finset.mem_univ x) y (Finset.mem_univ y) hxy⟩
theorem colorable_of_partition {V : Type*} {H : SimpleGraph V} (S : Set V) {a b : ℕ}
(hS : (H.induce S).Colorable a) (hR : (H.induce Sᶜ).Colorable b) :
H.Colorable (a + b) := by
classical
obtain ⟨cS⟩ := hS
obtain ⟨cR⟩ := hR
let c : V → Fin a ⊕ Fin b := fun v =>
if hv : v ∈ S then Sum.inl (cS ⟨v, hv⟩) else Sum.inr (cR ⟨v, hv⟩)
have hc : ∀ {x y}, H.Adj x y → c x ≠ c y := by
intro x y hxy
dsimp [c]
split_ifs with hx hy hy
· exact fun heq => cS.valid (v := ⟨x, hx⟩) (w := ⟨y, hy⟩) hxy (Sum.inl.inj heq)
· exact id
· exact id
· exact fun heq => cR.valid (v := ⟨x, hx⟩) (w := ⟨y, hy⟩) hxy (Sum.inr.inj heq)
simpa using (SimpleGraph.Coloring.mk c hc).colorable
section ArcColorBound
variable {V : Type u} [LinearOrder V] [Fintype V] {F : SimpleGraph V}
/-- The residual arc vertices can be greedily colored with two colors. -/
theorem nonbranching_colorable {H : SimpleGraph (Arc F)} (hH : H ≤ arcGraph F) :
(H.induce {a | ¬ Branching H a}).Colorable 2 := by
classical
apply colorable_of_low_degree _ (by decide)
intro S hS
obtain ⟨a, ha, hmin⟩ := S.exists_min_image (fun a => a.1.1.1) hS
refine ⟨a, ha, ?_⟩
have hforward : ∀ b ∈ S, H.Adj a.1 b.1 → a.1.1.2 = b.1.1.1 := by
intro b hb hab
rcases hH hab with hab | hba
· exact hab
· have hlt := b.1.2.1
rw [hba] at hlt
exact ((not_lt_of_ge (hmin b hb)) hlt).elim
have hcard : (S.filter (fun b => H.Adj a.1 b.1)).card ≤ 1 := by
apply Finset.card_le_one.mpr
intro b hb c hc
obtain ⟨hbS, hab⟩ := Finset.mem_filter.mp hb
obtain ⟨hcS, hac⟩ := Finset.mem_filter.mp hc
by_contra hbc
exact a.2 ⟨b.1, c.1, (fun heq => hbc (Subtype.ext heq)), hab, hac,
hforward b hbS hab, hforward c hcS hac⟩
exact Nat.lt_succ_of_le hcard
/-- Lemma 1 of the attachment, for arbitrary spanning edge selections. -/
theorem arc_colorable_bound {d a : ℕ}
(hout : ∀ v, (outgoingArcs F v).card ≤ d)
(hbase : ∀ J : SimpleGraph V, J ≤ F →
(∀ v, Nat.card (J.neighborSet v) ≤ d + d.choose 2) → J.Colorable a)
{H : SimpleGraph (Arc F)} (hH : H ≤ arcGraph F) (h4 : FourCycleFree H) :
H.Colorable (a + 2) := by
apply colorable_of_partition {b | Branching H b}
· apply branching_colorable hH
apply hbase _ (baseOfArcs_le _)
intro v
exact (selected_degree_le h4 v).trans
(Nat.add_le_add (hout v) (Nat.choose_le_choose 2 (hout v)))
· exact nonbranching_colorable hH
end ArcColorBound
theorem FourCycleFree.spanningCoe {V : Type*} {G : SimpleGraph V} {H : G.Subgraph}
(h : FourCycleFree H.coe) : FourCycleFree H.spanningCoe := by
intro a b x y hab hxy hax hay hbx hby
let a' : H.verts := ⟨a, H.edge_vert hax⟩
let b' : H.verts := ⟨b, H.edge_vert hbx⟩
let x' : H.verts := ⟨x, H.edge_vert (H.adj_symm hax)⟩
let y' : H.verts := ⟨y, H.edge_vert (H.adj_symm hay)⟩
exact h a' b' x' y' (fun heq => hab (congrArg Subtype.val heq))
(fun heq => hxy (congrArg Subtype.val heq)) hax hay hbx hby
/-- The arc lemma applies to ordinary subgraphs, including vertex and edge deletion. -/
theorem arc_subgraph_colorable_bound {V : Type u} [LinearOrder V] [Fintype V]
{F : SimpleGraph V} {d a : ℕ}
(hout : ∀ v, (outgoingArcs F v).card ≤ d)
(hbase : ∀ J : SimpleGraph V, J ≤ F →
(∀ v, Nat.card (J.neighborSet v) ≤ d + d.choose 2) → J.Colorable a)
(H : (arcGraph F).Subgraph) (h4 : FourCycleFree H.coe) :
H.coe.Colorable (a + 2) :=
(arc_colorable_bound hout hbase H.spanningCoe_le h4.spanningCoe).of_hom
H.coeEmbeddingSpanningCoe.toHom
section EdgeCounting
variable {V : Type*}
/-- Ordered incidences from `X` to `Y`, counted as a real number. -/
noncomputable def crossingCount (G : SimpleGraph V) (X Y : Finset V) : ℝ := by
classical
exact ∑ x ∈ X, ∑ y ∈ Y, if G.Adj x y then 1 else 0
/-- The number of edges with both endpoints in `X`. -/
noncomputable def internalCount (G : SimpleGraph V) (X : Finset V) : ℝ :=
crossingCount G X X / 2
theorem crossingCount_nonneg (G : SimpleGraph V) (X Y : Finset V) :
0 ≤ crossingCount G X Y := by
classical
unfold crossingCount
positivity
theorem crossingCount_comm (G : SimpleGraph V) (X Y : Finset V) :
crossingCount G X Y = crossingCount G Y X := by
classical
unfold crossingCount
rw [Finset.sum_comm]
apply Finset.sum_congr rfl
intro y hy
apply Finset.sum_congr rfl
intro x hx
rw [G.adj_comm]
theorem crossingCount_union_left [DecidableEq V] (G : SimpleGraph V) {X Y : Finset V}
(hd : Disjoint X Y) (Z : Finset V) :
crossingCount G (X ∪ Y) Z = crossingCount G X Z + crossingCount G Y Z := by
classical
exact Finset.sum_union hd
theorem crossingCount_union_right [DecidableEq V] (G : SimpleGraph V) (X : Finset V) {Y Z : Finset V}
(hd : Disjoint Y Z) :
crossingCount G X (Y ∪ Z) = crossingCount G X Y + crossingCount G X Z := by
rw [crossingCount_comm G X, crossingCount_union_left G hd,
crossingCount_comm G Y, crossingCount_comm G Z]
theorem crossingCount_graph_mono {F G : SimpleGraph V} (h : F ≤ G) (X Y : Finset V) :
crossingCount F X Y ≤ crossingCount G X Y := by
classical
apply Finset.sum_le_sum
intro x hx
apply Finset.sum_le_sum
intro y hy
by_cases hxy : F.Adj x y
· simp [hxy, h hxy]
· simp only [hxy, if_false]
positivity
theorem crossingCount_eq_sum_card (G : SimpleGraph V) (X Y : Finset V)
[DecidableRel G.Adj] :
crossingCount G X Y = ∑ x ∈ X, ((Y.filter (G.Adj x)).card : ℝ) := by
classical
simp only [crossingCount, Finset.card_filter, Nat.cast_sum, Nat.cast_ite,
Nat.cast_one, Nat.cast_zero]
apply Finset.sum_congr rfl
intro x hx
apply Finset.sum_congr rfl
intro y hy
split_ifs <;> rfl
theorem crossingCount_eq_card_product (G : SimpleGraph V) (X Y : Finset V)
[DecidableRel G.Adj] : crossingCount G X Y =
(((X ×ˢ Y).filter (fun e => G.Adj e.1 e.2)).card : ℝ) := by
classical
simp only [crossingCount, Finset.card_filter, Finset.sum_product, Nat.cast_sum,
Nat.cast_ite, Nat.cast_one, Nat.cast_zero]
apply Finset.sum_congr rfl
intro x hx
apply Finset.sum_congr rfl
intro y hy
split_ifs <;> rfl
theorem crossingCount_le_card_mul (G : SimpleGraph V) (X Y : Finset V)
[DecidableRel G.Adj] {k : ℕ}
(h : ∀ x ∈ X, (Y.filter (G.Adj x)).card ≤ k) :
crossingCount G X Y ≤ X.card * k := by
rw [crossingCount_eq_sum_card]
calc
_ ≤ ∑ _x ∈ X, (k : ℝ) := Finset.sum_le_sum fun x hx => by exact_mod_cast h x hx
_ = _ := by simp
theorem crossingCount_eq_zero (G : SimpleGraph V) (X Y : Finset V)
(h : ∀ x ∈ X, ∀ y ∈ Y, ¬ G.Adj x y) : crossingCount G X Y = 0 := by
classical
apply Finset.sum_eq_zero
intro x hx
apply Finset.sum_eq_zero
intro y hy
simp [h x hx y hy]
/-- Deleting all edges incident with `Z` costs at most its total incidence count. -/
theorem internalCount_cut [DecidableEq V] (G : SimpleGraph V) {X Y Z : Finset V}
(hXY : Disjoint X Y) (hXZ : Disjoint X Z) (hYZ : Disjoint Y Z)
(hY : crossingCount G Y Y = 0) :
internalCount G (X ∪ Y ∪ Z) ≤ internalCount G X + crossingCount G X Y +
crossingCount G Z (X ∪ Y ∪ Z) := by
have hXYZ : Disjoint (X ∪ Y) Z := Finset.disjoint_union_left.mpr ⟨hXZ, hYZ⟩
unfold internalCount
rw [crossingCount_union_left G hXYZ, crossingCount_union_left G hXY,
crossingCount_union_right G X hXYZ, crossingCount_union_right G X hXY,
crossingCount_union_right G Y hXYZ, crossingCount_union_right G Y hXY,
crossingCount_union_right G Z hXYZ, crossingCount_union_right G Z hXY,
crossingCount_comm G Y X, crossingCount_comm G Z X, crossingCount_comm G Z Y, hY]
nlinarith [crossingCount_nonneg G Z Z]
end EdgeCounting
/-- The numerical core of the deterministic cut in Lemma 3. -/
theorem cut_density_inequality {K s x y z e f : ℝ}
(hK : 4 ≤ K) (hs : 0 < s) (_hx : 0 ≤ x) (hy : 0 ≤ y) (hxy : x + y ≤ s)
(hz : z < 2 * s / (16 * K * (K + 1)))
(he : 2 * s ≤ e + f + K * z) (hfX : f ≤ x) (hfY : f ≤ K * y) :
(1 + 1 / (2 * (K + 1))) * x < e := by
have hK0 : 0 < K := by linarith
have hK1 : 0 < K + 1 := by linarith
have hden : 0 < 16 * K * (K + 1) := by positivity
have hcross : (K + 1) * f ≤ K * s := by nlinarith
have htail : (16 * K * (K + 1)) * z < 2 * s := by
nlinarith [(lt_div_iff₀ hden).mp hz]
have he' : (K + 1) * (2 * s) ≤ (K + 1) * (e + f + K * z) :=
mul_le_mul_of_nonneg_left he (le_of_lt hK1)
have hmain : 8 * (K + 1) * e > (8 * K + 15) * s := by nlinarith
have hxs : x ≤ s := by linarith
have htarget : (2 * (K + 1) + 1) * x < 2 * (K + 1) * e := by
nlinarith [mul_nonneg (show 0 ≤ 2 * (K + 1) + 1 by positivity) (sub_nonneg.mpr hxs)]
have hden2 : 0 < 2 * (K + 1) := by positivity
have heq : (1 + 1 / (2 * (K + 1))) * x =
((2 * (K + 1) + 1) * x) / (2 * (K + 1)) := by field_simp
rw [heq]
exact (div_lt_iff₀ hden2).mpr (by nlinarith)
section DeterministicObstruction
variable {V : Type*} [Fintype V] [DecidableEq V]
/-- The partitions and density estimates used by the deterministic cut argument. -/
def SparseCutProperty (F : SimpleGraph V) (K : ℕ) : Prop :=
∀ S : Finset V, S.Nonempty → ∃ X Y Z : Finset V,
S = X ∪ Y ∪ Z ∧ Disjoint X Y ∧ Disjoint X Z ∧ Disjoint Y Z ∧
crossingCount F Y Y = 0 ∧ crossingCount F X Y ≤ X.card ∧
(Z.card : ℝ) < 2 * S.card / (16 * K * (K + 1)) ∧
internalCount F X ≤ (1 + 1 / (2 * (K + 1))) * X.card
omit [DecidableEq V] in
theorem filter_neighbors_card_le (J : SimpleGraph V) [DecidableRel J.Adj]
(S : Finset V) (v : V) : (S.filter (J.Adj v)).card ≤ Nat.card (J.neighborSet v) := by
classical
rw [Nat.card_eq_fintype_card, SimpleGraph.card_neighborSet_eq_degree,
← SimpleGraph.card_neighborFinset_eq_degree]
apply Finset.card_le_card
intro w hw
exact (J.mem_neighborFinset v w).mpr (Finset.mem_filter.mp hw).2
/-- Every bounded-degree subgraph of a graph with the sparse cuts is 4-colorable. -/
theorem colorable_four_of_sparse_cuts {F J : SimpleGraph V} {K : ℕ}
(hK : 4 ≤ K) (hcuts : SparseCutProperty F K) (hJF : J ≤ F)
(hdeg : ∀ v, Nat.card (J.neighborSet v) ≤ K) : J.Colorable 4 := by
classical
apply colorable_of_low_degree _ (by decide)
intro S hS
by_contra! hmin
obtain ⟨X, Y, Z, hSXYZ, hXY, hXZ, hYZ, hFY, hFXY, hZ, hFX⟩ := hcuts S hS
have hJY : crossingCount J Y Y = 0 :=
le_antisymm ((crossingCount_graph_mono hJF Y Y).trans_eq hFY)
(crossingCount_nonneg J Y Y)
have hJS : 2 * (S.card : ℝ) ≤ internalCount J S := by
have hsum : (4 : ℝ) * S.card ≤ crossingCount J S S := by
rw [crossingCount_eq_sum_card]
calc
_ = ∑ _v ∈ S, (4 : ℝ) := by simp [mul_comm]
_ ≤ _ := Finset.sum_le_sum fun v hv => by exact_mod_cast hmin v hv
unfold internalCount
linarith
have hXYS : (X.card : ℝ) + Y.card ≤ S.card := by
norm_cast
rw [← Finset.card_union_of_disjoint hXY]
apply Finset.card_le_card
rw [hSXYZ]
exact Finset.subset_union_left
have hJXY : crossingCount J X Y ≤ X.card :=
(crossingCount_graph_mono hJF X Y).trans hFXY
have hJYX : crossingCount J X Y ≤ (K : ℝ) * Y.card := by
rw [crossingCount_comm J X Y, mul_comm]
apply crossingCount_le_card_mul
intro v hv
exact (filter_neighbors_card_le J X v).trans (hdeg v)
have hJZS : crossingCount J Z S ≤ (K : ℝ) * Z.card := by
rw [mul_comm]
apply crossingCount_le_card_mul
intro v hv
exact (filter_neighbors_card_le J S v).trans (hdeg v)
have hcut : internalCount J S ≤ internalCount J X + crossingCount J X Y +
crossingCount J Z S := by
rw [hSXYZ]
exact internalCount_cut J hXY hXZ hYZ hJY
have hbad := cut_density_inequality
(K := (K : ℝ)) (s := (S.card : ℝ)) (x := (X.card : ℝ)) (y := (Y.card : ℝ))
(z := (Z.card : ℝ)) (e := internalCount J X) (f := crossingCount J X Y)
(by exact_mod_cast hK) (by exact_mod_cast Finset.card_pos.mpr hS)
(by positivity) (by positivity) hXYS hZ (by linarith) hJXY hJYX
have hJX : internalCount J X ≤ internalCount F X :=
div_le_div_of_nonneg_right (crossingCount_graph_mono hJF X X) (by positivity)
linarith
/- Local sparsity in earlier parts yields the cuts used in Lemma 3. -/
omit [Fintype V] in
theorem sparse_cuts_of_parts {F : SimpleGraph V} {C K A : ℕ}
(part : V → Fin C) (n : Fin C → ℕ)
(hsame : ∀ v w, part v = part w → ¬ F.Adj v w)
(hone : ∀ v i, part v < i → ∀ w z, part w = i → part z = i →
F.Adj v w → F.Adj v z → w = z)
(hcut : ∀ S : Finset V, S.Nonempty → ∃ i : Fin C,
S.card ≤ A * n i ∧
((S.filter (fun v => i < part v)).card : ℝ) <
2 * S.card / (16 * K * (K + 1)))
(hsparse : ∀ (i : Fin C) (X : Finset V), (∀ v ∈ X, part v < i) →
X.card ≤ A * n i →
internalCount F X ≤ (1 + 1 / (2 * (K + 1))) * X.card) :
SparseCutProperty F K := by
classical
intro S hS
obtain ⟨i, hsize, htail⟩ := hcut S hS
let X := S.filter fun v => part v < i
let Y := S.filter fun v => part v = i
let Z := S.filter fun v => i < part v
have hpartition : S = X ∪ Y ∪ Z := by
ext v
simp only [X, Y, Z, Finset.mem_union, Finset.mem_filter]
have htri := lt_trichotomy (part v) i
tauto
have hXY : Disjoint X Y := by
apply Finset.disjoint_left.mpr
intro v hx hy
have hx' := (Finset.mem_filter.mp hx).2
have hy' := (Finset.mem_filter.mp hy).2
omega
have hXZ : Disjoint X Z := by
apply Finset.disjoint_left.mpr
intro v hx hz
have hx' := (Finset.mem_filter.mp hx).2
have hz' := (Finset.mem_filter.mp hz).2
omega
have hYZ : Disjoint Y Z := by
apply Finset.disjoint_left.mpr
intro v hy hz
have hy' := (Finset.mem_filter.mp hy).2
have hz' := (Finset.mem_filter.mp hz).2
omega
refine ⟨X, Y, Z, hpartition, hXY, hXZ, hYZ, ?_, ?_, htail, ?_⟩
· apply crossingCount_eq_zero
intro v hv w hw
exact hsame v w ((Finset.mem_filter.mp hv).2.trans (Finset.mem_filter.mp hw).2.symm)
· have hbound : crossingCount F X Y ≤ X.card * (1 : ℕ) := by
apply crossingCount_le_card_mul
intro v hv
apply Finset.card_le_one.mpr
intro w hw z hz
have hw' := Finset.mem_filter.mp hw
have hz' := Finset.mem_filter.mp hz
exact hone v i (Finset.mem_filter.mp hv).2 w z
(Finset.mem_filter.mp hw'.1).2 (Finset.mem_filter.mp hz'.1).2 hw'.2 hz'.2
simpa using hbound
· exact hsparse i X (fun v hv => (Finset.mem_filter.mp hv).2)
(le_trans (Finset.card_filter_le _ _) hsize)
end DeterministicObstruction
section FiniteProbability
variable {Ω : Type*} [Fintype Ω]
/-- Uniform probability on a finite sample space, expressed by counting. -/
noncomputable def finiteProb (A : Set Ω) : ℝ := (A.ncard : ℝ) / Fintype.card Ω
theorem finiteProb_nonneg (A : Set Ω) : 0 ≤ finiteProb A := by
unfold finiteProb
positivity
theorem finiteProb_mono {A B : Set Ω} (h : A ⊆ B) : finiteProb A ≤ finiteProb B := by
apply div_le_div_of_nonneg_right _ (by positivity)
exact_mod_cast Set.ncard_mono h
theorem finiteProb_empty : finiteProb (∅ : Set Ω) = 0 := by simp [finiteProb]
theorem finiteProb_univ [Nonempty Ω] : finiteProb (Set.univ : Set Ω) = 1 := by
simp [finiteProb, Fintype.card_ne_zero]
theorem finiteProb_union_le (A B : Set Ω) :
finiteProb (A ∪ B) ≤ finiteProb A + finiteProb B := by
unfold finiteProb
rw [← add_div]
apply div_le_div_of_nonneg_right _ (by positivity)
exact_mod_cast Set.ncard_union_le A B
theorem finiteProb_biUnion_le {ι : Type*} (s : Finset ι) (A : ι → Set Ω) :
finiteProb {ω | ∃ i ∈ s, ω ∈ A i} ≤ ∑ i ∈ s, finiteProb (A i) := by
classical
induction s using Finset.induction_on with
| empty => simp [finiteProb]
| @insert i s hi ih =>
have heq : {ω | ∃ j ∈ insert i s, ω ∈ A j} = A i ∪ {ω | ∃ j ∈ s, ω ∈ A j} := by
ext ω
simp
rw [heq, Finset.sum_insert hi]
exact (finiteProb_union_le _ _).trans (add_le_add le_rfl ih)
theorem exists_avoiding_of_finiteProb_lt_one [Nonempty Ω] (A B : Set Ω)
(h : finiteProb A + finiteProb B < 1) : ∃ ω, ω ∉ A ∧ ω ∉ B := by
by_contra! hbad
have heq : A ∪ B = Set.univ := by
ext ω
simp only [Set.mem_union, Set.mem_univ, iff_true]
by_cases ha : ω ∈ A
· exact Or.inl ha
· exact Or.inr (hbad ω ha)
have hu := finiteProb_union_le A B
rw [heq, finiteProb_univ] at hu
linarith
theorem finiteProb_box {ι : Type*} [Fintype ι] [DecidableEq ι] {α : ι → Type*}
[∀ i, Fintype (α i)] (A : ∀ i, Set (α i)) :
finiteProb {ω : ∀ i, α i | ∀ i, ω i ∈ A i} =
∏ i, ((A i).ncard : ℝ) / Fintype.card (α i) := by
classical
unfold finiteProb
have hcard : {ω : ∀ i, α i | ∀ i, ω i ∈ A i}.ncard = ∏ i, (A i).ncard := by
change Nat.card {ω : ∀ i, α i // ∀ i, ω i ∈ A i} = _
rw [Nat.card_congr (Equiv.subtypePiEquivPi (β := α) (p := fun i x => x ∈ A i)),
Nat.card_pi]
rfl
rw [hcard, Fintype.card_pi]
simp only [Nat.cast_prod, Finset.prod_div_distrib]
theorem finiteProb_agreement {ι : Type*} [Fintype ι] [DecidableEq ι] {α : ι → Type*}
[∀ i, Fintype (α i)] (ω₀ : ∀ i, α i) (s : Finset ι) :
finiteProb {ω : ∀ i, α i | ∀ i ∈ s, ω i = ω₀ i} =
∏ i ∈ s, (1 / (Fintype.card (α i) : ℝ)) := by
classical
let : ∀ i, Nonempty (α i) := fun i => ⟨ω₀ i⟩
let A : ∀ i, Set (α i) := fun i => if i ∈ s then {ω₀ i} else Set.univ
have heq : {ω : ∀ i, α i | ∀ i ∈ s, ω i = ω₀ i} =
{ω | ∀ i, ω i ∈ A i} := by
ext ω
simp [A]
rw [heq, finiteProb_box]
calc
_ = ∏ i, if i ∈ s then (1 / (Fintype.card (α i) : ℝ)) else 1 := by
apply Finset.prod_congr rfl
intro i hi
by_cases his : i ∈ s <;> simp [A, his, Fintype.card_ne_zero]
_ = _ := Fintype.prod_ite_mem s _
theorem finiteProb_agreement_le {ι : Type*} [Fintype ι] [DecidableEq ι] {α : ι → Type*}
[∀ i, Fintype (α i)] (ω₀ : ∀ i, α i) (s : Finset ι) {n : ℕ} (hn : 0 < n)
(hcard : ∀ i ∈ s, n ≤ Fintype.card (α i)) :
finiteProb {ω : ∀ i, α i | ∀ i ∈ s, ω i = ω₀ i} ≤ (1 / (n : ℝ)) ^ s.card := by
rw [finiteProb_agreement]
calc
_ ≤ ∏ _i ∈ s, (1 / (n : ℝ)) := by
apply Finset.prod_le_prod (fun _ _ => by positivity)
intro i hi
exact one_div_le_one_div_of_le (by exact_mod_cast hn) (by exact_mod_cast hcard i hi)
_ = _ := by simp
theorem finiteProb_card_ge_le {ε : Type*} [DecidableEq ε]
(P : Finset ε) (present : Ω → Finset ε) (hP : ∀ ω, present ω ⊆ P)
(m : ℕ) (B : ℝ)
(hB : ∀ E ∈ P.powersetCard m, finiteProb {ω | E ⊆ present ω} ≤ B) :
finiteProb {ω | m ≤ (present ω).card} ≤ (P.card.choose m : ℝ) * B := by
classical
have hsub : {ω | m ≤ (present ω).card} ⊆
{ω | ∃ E ∈ P.powersetCard m, E ⊆ present ω} := by
intro ω hω
obtain ⟨E, hE, hEm⟩ := Finset.exists_subset_card_eq hω
exact ⟨E, Finset.mem_powersetCard.mpr ⟨hE.trans (hP ω), hEm⟩, hE⟩
calc
_ ≤ finiteProb {ω | ∃ E ∈ P.powersetCard m, E ⊆ present ω} := finiteProb_mono hsub
_ ≤ ∑ E ∈ P.powersetCard m, finiteProb {ω | E ⊆ present ω} := finiteProb_biUnion_le _ _
_ ≤ ∑ _E ∈ P.powersetCard m, B := Finset.sum_le_sum hB
_ = _ := by simp
end FiniteProbability
section MultipartiteModel
variable {C : ℕ}
/-- Vertices in ordered parts of the specified sizes. -/
abbrev ModelVertex (n : Fin C → ℕ) := Lex (Σ i : Fin C, Fin (n i))
/-- Unused choices into earlier parts are retained to make a rectangular product. -/
abbrev ModelSample (n : Fin C → ℕ) := (k : ModelVertex n × Fin C) → Fin (n k.2)
/-- Each vertex chooses exactly one neighbor in each later part. -/
def modelGraph {n : Fin C → ℕ} (ω : ModelSample n) : SimpleGraph (ModelVertex n) where
Adj v w := (v.1 < w.1 ∧ ω (v, w.1) = w.2) ∨ (w.1 < v.1 ∧ ω (w, v.1) = v.2)
symm := ⟨fun _ _ => Or.symm⟩
loopless := ⟨fun v h => h.elim (fun h => (lt_irrefl v.1) h.1) (fun h => (lt_irrefl v.1) h.1)⟩
theorem modelGraph_same_part {n : Fin C → ℕ} (ω : ModelSample n)
(v w : ModelVertex n) (hvw : v.1 = w.1) : ¬ (modelGraph ω).Adj v w := by
rintro (h | h) <;> have hlt := h.1 <;> rw [hvw] at hlt <;> exact (lt_irrefl _) hlt
theorem modelGraph_forward {n : Fin C → ℕ} (ω : ModelSample n)
{v w : ModelVertex n} (hvw : v.1 < w.1) :
(modelGraph ω).Adj v w ↔ ω (v, w.1) = w.2 := by
constructor
· rintro (h | h)
· exact h.2
· exact (hvw.not_gt h.1).elim
· exact fun h => Or.inl ⟨hvw, h⟩
theorem modelGraph_one_neighbor {n : Fin C → ℕ} (ω : ModelSample n)
(v : ModelVertex n) (i : Fin C) (hvi : v.1 < i)
(w z : ModelVertex n) (hwi : w.1 = i) (hzi : z.1 = i)
(hvw : (modelGraph ω).Adj v w) (hvz : (modelGraph ω).Adj v z) : w = z := by
obtain ⟨j, w⟩ := w
obtain ⟨k, z⟩ := z
dsimp at hwi hzi
subst j
subst k
have hw := (modelGraph_forward ω hvi).mp hvw
have hz := (modelGraph_forward ω hvi).mp hvz
exact congrArg (fun x : Fin (n i) => (⟨i, x⟩ : ModelVertex n)) (hw.symm.trans hz)
theorem model_arc_forward {n : Fin C → ℕ} (ω : ModelSample n) (a : Arc (modelGraph ω)) :
a.1.1.1 < a.1.2.1 := by
rcases a.2.2 with h | h
· exact h.1
· rcases Sigma.Lex.lt_def.mp a.2.1 with hlt | ⟨heq, _⟩
· exact (hlt.not_gt h.1).elim
· have hlt := h.1
rw [heq] at hlt
exact (lt_irrefl _ hlt).elim
/-- The maximum outdegree depends only on the number of parts. -/
theorem model_outgoing_card_le {n : Fin C → ℕ} (ω : ModelSample n) (v : ModelVertex n) :
(outgoingArcs (modelGraph ω) v).card ≤ C - 1 := by
classical
let S := outgoingArcs (modelGraph ω) v
let f : Arc (modelGraph ω) → Fin C := fun a => a.1.2.1
have hinj : Set.InjOn f (S : Set (Arc (modelGraph ω))) := by
intro a ha b hb hab
have hat : a.1.1 = v := (Finset.mem_filter.mp ha).2
have hbt : b.1.1 = v := (Finset.mem_filter.mp hb).2
apply Subtype.ext
apply Prod.ext (hat.trans hbt.symm)
have hav : (modelGraph ω).Adj v a.1.2 := by simpa only [hat] using a.2.2
have hbv : (modelGraph ω).Adj v b.1.2 := by simpa only [hbt] using b.2.2
have hvi : v.1 < a.1.2.1 := by simpa only [hat] using model_arc_forward ω a
exact modelGraph_one_neighbor ω v a.1.2.1 hvi a.1.2 b.1.2 rfl hab.symm hav hbv
have hsub : S.image f ⊆ (Finset.univ : Finset (Fin C)).erase v.1 := by
intro j hj
obtain ⟨a, ha, rfl⟩ := Finset.mem_image.mp hj
have hat : a.1.1 = v := (Finset.mem_filter.mp ha).2
have hlt : v.1 < f a := by simpa only [f, hat] using model_arc_forward ω a
exact Finset.mem_erase.mpr ⟨hlt.ne.symm, Finset.mem_univ _⟩
calc
S.card = (S.image f).card := (Finset.card_image_of_injOn hinj).symm
_ ≤ ((Finset.univ : Finset (Fin C)).erase v.1).card := Finset.card_le_card hsub
_ = C - 1 := by simp
/-- The probability of a specified set of distinct forward edges. -/
theorem model_contains_probability_le {n : Fin C → ℕ}
(E : Finset (ModelVertex n × ModelVertex n))
(hE : ∀ e ∈ E, e.1.1 < e.2.1) {N : ℕ} (hN : 0 < N)
(hsize : ∀ e ∈ E, N ≤ n e.2.1) :
finiteProb {ω : ModelSample n | ∀ e ∈ E, (modelGraph ω).Adj e.1 e.2} ≤
(1 / (N : ℝ)) ^ E.card := by
classical
let A : Set (ModelSample n) := {ω | ∀ e ∈ E, (modelGraph ω).Adj e.1 e.2}
by_cases hA : A.Nonempty
· obtain ⟨ω₀, hω₀⟩ := hA
let key : ModelVertex n × ModelVertex n → ModelVertex n × Fin C :=
fun e => (e.1, e.2.1)
have hinj : Set.InjOn key (E : Set (ModelVertex n × ModelVertex n)) := by
intro a ha b hb hab
have hs : a.1 = b.1 := congrArg (fun k : ModelVertex n × Fin C => k.1) hab
have ht : a.2.1 = b.2.1 := congrArg (fun k : ModelVertex n × Fin C => k.2) hab
apply Prod.ext hs
apply modelGraph_one_neighbor ω₀ a.1 a.2.1 (hE a ha) a.2 b.2 rfl ht.symm
· exact hω₀ a ha
· simpa only [hs] using hω₀ b hb
have hsub : A ⊆ {ω : ModelSample n | ∀ k ∈ E.image key, ω k = ω₀ k} := by
intro ω hω k hk
obtain ⟨e, he, rfl⟩ := Finset.mem_image.mp hk
exact ((modelGraph_forward ω (hE e he)).mp (hω e he)).trans
((modelGraph_forward ω₀ (hE e he)).mp (hω₀ e he)).symm
have hsz : ∀ k ∈ E.image key, N ≤ Fintype.card (Fin (n k.2)) := by
intro k hk
obtain ⟨e, he, rfl⟩ := Finset.mem_image.mp hk
simpa using hsize e he
have hb := (finiteProb_mono hsub).trans (finiteProb_agreement_le ω₀ (E.image key) hN hsz)
simpa only [Finset.card_image_of_injOn hinj] using hb
· have heq : A = ∅ := Set.not_nonempty_iff_eq_empty.mp hA
change finiteProb A ≤ _
rw [heq, finiteProb_empty]
positivity
noncomputable def possibleEdges {n : Fin C → ℕ} (X : Finset (ModelVertex n)) :
Finset (ModelVertex n × ModelVertex n) := by
classical
exact (X ×ˢ X).filter fun e => e.1.1 < e.2.1
noncomputable def modelEdges {n : Fin C → ℕ} (ω : ModelSample n)
(X : Finset (ModelVertex n)) : Finset (ModelVertex n × ModelVertex n) := by
classical
exact (possibleEdges X).filter fun e => (modelGraph ω).Adj e.1 e.2
/-- Each internal edge has precisely one orientation from an earlier to a later part. -/
theorem internalCount_modelGraph {n : Fin C → ℕ} (ω : ModelSample n)
(X : Finset (ModelVertex n)) : internalCount (modelGraph ω) X = (modelEdges ω X).card := by
classical
let A := (X ×ˢ X).filter fun e => (modelGraph ω).Adj e.1 e.2
let B := A.filter fun e => ¬ e.1.1 < e.2.1
have hA : A.filter (fun e => e.1.1 < e.2.1) = modelEdges ω X := by
ext e
simp [A, modelEdges, possibleEdges, and_left_comm, and_comm]
have hB : (modelEdges ω X).card = B.card := by
apply Finset.card_bij (fun e _ => (e.2, e.1))
· intro e he
have he' : (e.1 ∈ X ∧ e.2 ∈ X) ∧ e.1.1 < e.2.1 ∧ (modelGraph ω).Adj e.1 e.2 := by
simpa [modelEdges, possibleEdges, and_assoc] using he
apply Finset.mem_filter.mpr
refine ⟨Finset.mem_filter.mpr ⟨Finset.mem_product.mpr ⟨he'.1.2, he'.1.1⟩,
he'.2.2.symm⟩, ?_⟩
exact he'.2.1.not_gt
· intro a ha b hb hab
exact Prod.ext (congrArg Prod.snd hab) (congrArg Prod.fst hab)
· intro e he
obtain ⟨heA, heback⟩ := Finset.mem_filter.mp he
obtain ⟨heX, heAdj⟩ := Finset.mem_filter.mp heA
have hedir : e.2.1 < e.1.1 := by
rcases heAdj with h | h
· exact (heback h.1).elim
· exact h.1
refine ⟨(e.2, e.1), ?_, rfl⟩
have hx := Finset.mem_product.mp heX
simp only [modelEdges, possibleEdges, Finset.mem_filter, Finset.mem_product]
exact ⟨⟨⟨hx.2, hx.1⟩, hedir⟩, heAdj.symm⟩
have hc : (modelEdges ω X).card + (modelEdges ω X).card = A.card := by
have h := Finset.card_filter_add_card_filter_not (s := A) (fun e => e.1.1 < e.2.1)
rw [hA] at h
change (modelEdges ω X).card + B.card = A.card at h
rw [← hB] at h
exact h
rw [internalCount, crossingCount_eq_card_product]
change (A.card : ℝ) / 2 = _
have hcR : ((modelEdges ω X).card : ℝ) + (modelEdges ω X).card = A.card := by exact_mod_cast hc
linarith
theorem model_many_edges_probability_le {n : Fin C → ℕ}
(X : Finset (ModelVertex n)) (m : ℕ) {N : ℕ} (hN : 0 < N)
(hsize : ∀ v ∈ X, N ≤ n v.1) :
finiteProb {ω : ModelSample n | m ≤ (modelEdges ω X).card} ≤
((X.card ^ 2).choose m : ℝ) * (1 / (N : ℝ)) ^ m := by
classical
have hbound := finiteProb_card_ge_le (possibleEdges X) (fun ω : ModelSample n => modelEdges ω X)
(fun _ => Finset.filter_subset _ _) m ((1 / (N : ℝ)) ^ m) (by
intro E hE
obtain ⟨hEP, hEm⟩ := Finset.mem_powersetCard.mp hE
have hsub : {ω : ModelSample n | E ⊆ modelEdges ω X} ⊆
{ω | ∀ e ∈ E, (modelGraph ω).Adj e.1 e.2} := by
intro ω hω e he
exact (Finset.mem_filter.mp (hω he)).2
have hdir : ∀ e ∈ E, e.1.1 < e.2.1 := fun e he => (Finset.mem_filter.mp (hEP he)).2
have hsz : ∀ e ∈ E, N ≤ n e.2.1 := by
intro e he
exact hsize e.2 (Finset.mem_product.mp (Finset.mem_filter.mp (hEP he)).1).2
exact (finiteProb_mono hsub).trans (by
simpa only [hEm] using model_contains_probability_le E hdir hN hsz))
apply hbound.trans
apply mul_le_mul_of_nonneg_right _ (by positivity)
exact_mod_cast Nat.choose_le_choose m (show (possibleEdges X).card ≤ X.card ^ 2 by
calc
_ ≤ (X ×ˢ X).card := Finset.card_filter_le _ _
_ = _ := by simp [pow_two])
noncomputable def modelFiber {n : Fin C → ℕ} (I : Finset (ModelVertex n)) (i : Fin C) :
Finset (Fin (n i)) := by
classical
exact Finset.univ.filter fun x => (⟨i, x⟩ : ModelVertex n) ∈ I
noncomputable def modelDensity {n : Fin C → ℕ} (I : Finset (ModelVertex n)) (i : Fin C) : ℝ :=
((modelFiber I i).card : ℝ) / n i
noncomputable def modelWeight {n : Fin C → ℕ} (I : Finset (ModelVertex n)) : ℝ :=
∑ i, modelDensity I i
theorem modelDensity_nonneg {n : Fin C → ℕ} (I : Finset (ModelVertex n)) (i : Fin C) :
0 ≤ modelDensity I i := by unfold modelDensity; positivity
theorem modelDensity_le_one {n : Fin C → ℕ} (I : Finset (ModelVertex n)) (i : Fin C)
(hn : 0 < n i) : modelDensity I i ≤ 1 := by
classical
apply (div_le_one₀ (by exact_mod_cast hn : (0 : ℝ) < n i)).mpr
exact_mod_cast (show (modelFiber I i).card ≤ n i from
(Finset.card_filter_le _ _).trans_eq (Fintype.card_fin (n i)))
noncomputable def modelColorClass {n : Fin C → ℕ} {k : ℕ}
(c : ModelVertex n → Fin k) (a : Fin k) : Finset (ModelVertex n) := by
classical
exact @Finset.filter _ (fun v => c v = a) (fun _ => Classical.propDecidable _) Finset.univ
theorem mem_modelColorClass {n : Fin C → ℕ} {k : ℕ}
(c : ModelVertex n → Fin k) (a : Fin k) (v : ModelVertex n) :
v ∈ modelColorClass c a ↔ c v = a := by
classical
exact (@Finset.mem_filter (ModelVertex n) (fun v => c v = a)
(fun _ => Classical.propDecidable _) Finset.univ v).trans
(and_iff_right (Finset.mem_univ _))
/-- The weights of all color classes sum to the number of parts. -/
theorem modelWeight_color_sum {n : Fin C → ℕ} {k : ℕ}
(hn : ∀ i, 0 < n i) (c : ModelVertex n → Fin k) :
(∑ a : Fin k, modelWeight (modelColorClass c a)) = C := by
classical
unfold modelWeight modelDensity
rw [Finset.sum_comm]
calc
_ = ∑ _i : Fin C, (1 : ℝ) := by
apply Finset.sum_congr rfl
intro i hi
have hcount : (∑ a : Fin k, (modelFiber (modelColorClass c a) i).card) = n i := by
have hfiber : ∀ a : Fin k, modelFiber (modelColorClass c a) i =
Finset.univ.filter (fun x : Fin (n i) => c (⟨i, x⟩ : ModelVertex n) = a) := by
intro a
ext x
simp only [modelFiber, Finset.mem_filter, Finset.mem_univ, true_and]
exact mem_modelColorClass c a (⟨i, x⟩ : ModelVertex n)
simp_rw [hfiber]
simpa using
(Finset.sum_card_fiberwise_eq_card_filter (Finset.univ : Finset (Fin (n i)))
(Finset.univ : Finset (Fin k)) (fun x => c (⟨i, x⟩ : ModelVertex n)))
rw [← Finset.sum_div]
have hcountR : (∑ a : Fin k, ((modelFiber (modelColorClass c a) i).card : ℝ)) =
n i := by exact_mod_cast hcount
rw [hcountR]
exact div_self (by exact_mod_cast Nat.ne_of_gt (hn i))
_ = _ := by simp
/-- Small independent-set weights force a large chromatic number. -/
theorem model_not_colorable_of_independent_weights {n : Fin C → ℕ} {k : ℕ}
(hn : ∀ i, 0 < n i) (hk : 0 < k) (ω : ModelSample n)
(hsmall : ∀ I : Finset (ModelVertex n),
(∀ v ∈ I, ∀ w ∈ I, ¬ (modelGraph ω).Adj v w) → modelWeight I < (C : ℝ) / k) :
¬ (modelGraph ω).Colorable k := by
classical
let : Nonempty (Fin k) := ⟨⟨0, hk⟩⟩
rintro ⟨c⟩
have hclasses : ∀ a : Fin k, modelWeight (modelColorClass c a) < (C : ℝ) / k := by
intro a
apply hsmall
intro v hv w hw hvw
exact c.valid hvw (((mem_modelColorClass c a v).mp hv).trans
((mem_modelColorClass c a w).mp hw).symm)
have hsum : (∑ a : Fin k, modelWeight (modelColorClass c a)) <
∑ _a : Fin k, (C : ℝ) / k :=
Finset.sum_lt_sum_of_nonempty Finset.univ_nonempty (fun a _ => hclasses a)
rw [modelWeight_color_sum hn c] at hsum
have heq : (∑ _a : Fin k, (C : ℝ) / k) = C := by
simp only [Finset.sum_const, Finset.card_univ, Fintype.card_fin, nsmul_eq_mul]
field_simp
linarith
/-- Counting a fiber as vertices or as coordinates gives the same cardinality. -/
theorem modelFiber_card {n : Fin C → ℕ} (I : Finset (ModelVertex n)) (i : Fin C) :
(modelFiber I i).card = (I.filter (fun v => v.1 = i)).card := by
classical
apply Finset.card_bij (fun x _ => (⟨i, x⟩ : ModelVertex n))
· intro x hx
exact Finset.mem_filter.mpr ⟨(Finset.mem_filter.mp hx).2, rfl⟩
· intro x hx y hy heq
cases heq
rfl
· intro v hv
obtain ⟨j, x⟩ := v
obtain ⟨hvI, hji⟩ := Finset.mem_filter.mp hv
dsimp at hji
subst j
exact ⟨x, Finset.mem_filter.mpr ⟨Finset.mem_univ _, hvI⟩, rfl⟩
noncomputable def modelLaterWeight {n : Fin C → ℕ}
(I : Finset (ModelVertex n)) (i : Fin C) : ℝ :=
∑ j : Fin C, if i < j then modelDensity I j else 0
theorem modelLaterWeight_nonneg {n : Fin C → ℕ}
(I : Finset (ModelVertex n)) (i : Fin C) : 0 ≤ modelLaterWeight I i := by
apply Finset.sum_nonneg
intro j hj
split_ifs <;> first | exact modelDensity_nonneg _ _ | rfl
/-- Choices from one fiber already give an exponential bound for independence. -/
theorem model_independent_probability_le {n : Fin C → ℕ} (hn : ∀ j, 0 < n j)
(I : Finset (ModelVertex n)) (i : Fin C) :
finiteProb {ω : ModelSample n | ∀ v ∈ I, ∀ w ∈ I, ¬ (modelGraph ω).Adj v w} ≤
Real.exp (-((modelFiber I i).card : ℝ) * modelLaterWeight I i) := by
classical
let S := I.filter (fun v => v.1 = i)
let A : ∀ k : ModelVertex n × Fin C, Set (Fin (n k.2)) := fun k =>
if k.1 ∈ S ∧ i < k.2 then (↑(modelFiber I k.2) : Set (Fin (n k.2)))ᶜ else Set.univ
let e : ModelVertex n × Fin C → ℝ := fun k =>
if k.1 ∈ S then if i < k.2 then -modelDensity I k.2 else 0 else 0
have hsub : {ω : ModelSample n | ∀ v ∈ I, ∀ w ∈ I, ¬ (modelGraph ω).Adj v w} ⊆
{ω | ∀ k, ω k ∈ A k} := by
intro ω hω k
by_cases hk : k.1 ∈ S ∧ i < k.2
· simp only [A, if_pos hk, Set.mem_compl_iff, Finset.mem_coe]
intro hx
have hsource := Finset.mem_filter.mp hk.1
have htarget : (⟨k.2, ω k⟩ : ModelVertex n) ∈ I := (Finset.mem_filter.mp hx).2
apply hω k.1 hsource.1 (⟨k.2, ω k⟩ : ModelVertex n) htarget
apply Or.inl
exact ⟨by simpa only [hsource.2] using hk.2, rfl⟩
· simp only [A, if_neg hk, Set.mem_univ]
have hfactor : ∀ k : ModelVertex n × Fin C,
((A k).ncard : ℝ) / Fintype.card (Fin (n k.2)) ≤ Real.exp (e k) := by
intro k
have hnR : (0 : ℝ) < n k.2 := by exact_mod_cast hn k.2
by_cases hs : k.1 ∈ S
· by_cases hj : i < k.2
· have hc : (modelFiber I k.2).card ≤ n k.2 :=
(Finset.card_filter_le _ _).trans_eq (Fintype.card_fin _)
have heq : ((A k).ncard : ℝ) / Fintype.card (Fin (n k.2)) =
1 - modelDensity I k.2 := by
simp only [A, if_pos (And.intro hs hj)]
rw [Set.ncard_compl (↑(modelFiber I k.2) : Set (Fin (n k.2)))]
simp only [Nat.card_eq_fintype_card,
Fintype.card_fin, Set.ncard_coe_finset, Nat.cast_sub hc, modelDensity]
field_simp
rw [heq]
have hb := Real.add_one_le_exp (-modelDensity I k.2)
simpa only [e, if_pos hs, if_pos hj, sub_eq_add_neg, add_comm] using hb
· simp [A, e, hs, hj, Set.ncard_univ, Nat.card_eq_fintype_card, hnR.ne']
· simp [A, e, hs, Set.ncard_univ, Nat.card_eq_fintype_card, hnR.ne']
have hexponent : (∑ k, e k) = -((modelFiber I i).card : ℝ) * modelLaterWeight I i := by
rw [Fintype.sum_prod_type]
calc
_ = ∑ v : ModelVertex n, if v ∈ S then -modelLaterWeight I i else 0 := by
apply Finset.sum_congr rfl
intro v hv
by_cases hs : v ∈ S
· simp only [e, if_pos hs, modelLaterWeight, ← Finset.sum_neg_distrib]
apply Finset.sum_congr rfl
intro j hj
split_ifs <;> simp
· simp only [e, if_neg hs, Finset.sum_const_zero]
_ = (S.card : ℝ) * (-modelLaterWeight I i) := by
rw [Fintype.sum_ite_mem]
simp
_ = _ := by rw [modelFiber_card]; ring
calc
_ ≤ finiteProb {ω : ModelSample n | ∀ k, ω k ∈ A k} := finiteProb_mono hsub
_ = ∏ k, ((A k).ncard : ℝ) / Fintype.card (Fin (n k.2)) := finiteProb_box A
_ ≤ ∏ k, Real.exp (e k) := Finset.prod_le_prod (fun _ _ => by positivity) (fun k _ => hfactor k)
_ = Real.exp (∑ k, e k) := (Real.exp_sum _ _).symm
_ = _ := by rw [hexponent]
end MultipartiteModel
/-- The first substantial coordinate leaves a substantial sum to its right. -/
theorem exists_heavy_coordinate {C : ℕ} (hC : 0 < C) (p : Fin C → ℝ) {θ : ℝ}
(hθ : 0 < θ) (hp : ∀ i, p i ≤ 1) (hsum : 2 * C * θ ≤ ∑ i, p i) :
∃ i : Fin C, θ ≤ p i ∧ (C : ℝ) * θ - 1 ≤ ∑ j : Fin C, if i < j then p j else 0 := by
classical
have hCR : (0 : ℝ) < C := by exact_mod_cast hC
have hex : ∃ i : Fin C, θ ≤ p i := by
by_contra! h
have hb : (∑ i, p i) ≤ ∑ _i : Fin C, θ :=
Finset.sum_le_sum (fun i _ => (h i).le)
simp only [Finset.sum_const, Finset.card_univ, Fintype.card_fin, nsmul_eq_mul] at hb
nlinarith [mul_pos hCR hθ]
let S := Finset.univ.filter (fun i : Fin C => θ ≤ p i)
have hS : S.Nonempty := by
obtain ⟨i, hi⟩ := hex
exact ⟨i, Finset.mem_filter.mpr ⟨Finset.mem_univ _, hi⟩⟩
let i := S.min' hS
have hi : θ ≤ p i := (Finset.mem_filter.mp (Finset.min'_mem S hS)).2
refine ⟨i, hi, ?_⟩
have hpoint : ∀ j : Fin C, p j ≤ θ + (if j = i then 1 else 0) +
(if i < j then p j else 0) := by
intro j
rcases lt_trichotomy j i with hj | rfl | hj
· have hjp : p j < θ := by
by_contra! hbad
have hji : i ≤ j := Finset.min'_le S j (Finset.mem_filter.mpr ⟨Finset.mem_univ _, hbad⟩)
exact (not_lt_of_ge hji) hj
simp only [if_neg hj.ne, if_neg hj.not_gt, add_zero]
exact hjp.le
· simp only [eq_self, if_true, lt_self_iff_false, if_false, add_zero]
linarith [hp i]
· simp only [if_neg hj.ne.symm, if_pos hj, add_zero]
linarith
have hb := Finset.sum_le_sum (fun j (_hj : j ∈ (Finset.univ : Finset (Fin C))) => hpoint j)
simp only [Finset.sum_add_distrib, Finset.sum_const, Finset.card_univ, Fintype.card_fin,
nsmul_eq_mul, Finset.sum_ite_eq', Finset.mem_univ, if_true] at hb
linarith
/-- A large independent-set weight has a fiber witnessing both required lower bounds. -/
theorem model_weight_heavy_part {q C : ℕ} (hq : 1 ≤ q) (hC : C = 64 * q ^ 2)
{n : Fin C → ℕ} (hn : ∀ j, 0 < n j) (I : Finset (ModelVertex n))
(hweight : (C : ℝ) / (2 * q) ≤ modelWeight I) :
∃ i : Fin C, 1 / (4 * (q : ℝ)) ≤ modelDensity I i ∧
15 * (q : ℝ) ≤ modelLaterWeight I i := by
have hqR : (0 : ℝ) < q := by exact_mod_cast (show 0 < q by omega)
have hCpos : 0 < C := by rw [hC]; positivity
have hsum : 2 * (C : ℝ) * (1 / (4 * q)) ≤ ∑ i, modelDensity I i := by
have heq : 2 * (C : ℝ) * (1 / (4 * q)) = (C : ℝ) / (2 * q) := by ring
rw [heq]
exact hweight
obtain ⟨i, hi, hright⟩ := exists_heavy_coordinate hCpos (modelDensity I)
(by positivity) (fun j => modelDensity_le_one I j (hn j)) hsum
refine ⟨i, hi, le_trans ?_ hright⟩
have hq1R : (1 : ℝ) ≤ q := by exact_mod_cast hq
have hCR : (C : ℝ) = 64 * (q : ℝ) ^ 2 := by exact_mod_cast hC
rw [hCR]
have heq : 64 * (q : ℝ) ^ 2 * (1 / (4 * q)) = 16 * q := by field_simp; ring
rw [heq]
linarith
noncomputable def modelSuffix {C : ℕ} (n : Fin C → ℕ) (i : Fin C) : Finset (ModelVertex n) := by
classical
exact Finset.univ.filter fun v => i ≤ v.1
noncomputable def modelRestrict {C : ℕ} {n : Fin C → ℕ}
(I : Finset (ModelVertex n)) (i : Fin C) : Finset (ModelVertex n) := by
classical
exact I.filter fun v => i ≤ v.1
theorem mem_modelRestrict {C : ℕ} {n : Fin C → ℕ}
(I : Finset (ModelVertex n)) (i : Fin C) (v : ModelVertex n) :
v ∈ modelRestrict I i ↔ v ∈ I ∧ i ≤ v.1 := by
classical
exact Finset.mem_filter
theorem modelFiber_restrict {C : ℕ} {n : Fin C → ℕ}
(I : Finset (ModelVertex n)) (i j : Fin C) (hij : i ≤ j) :
modelFiber (modelRestrict I i) j = modelFiber I j := by
classical
ext x
simp only [modelFiber, Finset.mem_filter, Finset.mem_univ, true_and]
exact (mem_modelRestrict I i (⟨j, x⟩ : ModelVertex n)).trans (and_iff_left hij)
theorem modelLaterWeight_restrict {C : ℕ} {n : Fin C → ℕ}
(I : Finset (ModelVertex n)) (i : Fin C) :
modelLaterWeight (modelRestrict I i) i = modelLaterWeight I i := by
unfold modelLaterWeight
apply Finset.sum_congr rfl
intro j hj
split_ifs with hij
· simp only [modelDensity, modelFiber_restrict I i j hij.le]
· rfl
/-- The exceptional independent sets can be searched for within a suffix. -/
def modelBadColor {C : ℕ} (n : Fin C → ℕ) (q : ℕ) : Set (ModelSample n) :=
{ω | ∃ i : Fin C, ∃ I : Finset (ModelVertex n), I ⊆ modelSuffix n i ∧
1 / (4 * (q : ℝ)) ≤ modelDensity I i ∧ 15 * (q : ℝ) ≤ modelLaterWeight I i ∧
∀ v ∈ I, ∀ w ∈ I, ¬ (modelGraph ω).Adj v w}
theorem model_small_weights_of_not_bad {q C : ℕ} (hq : 1 ≤ q) (hC : C = 64 * q ^ 2)
{n : Fin C → ℕ} (hn : ∀ j, 0 < n j) (ω : ModelSample n)
(hω : ω ∉ modelBadColor n q) (I : Finset (ModelVertex n))
(hI : ∀ v ∈ I, ∀ w ∈ I, ¬ (modelGraph ω).Adj v w) :
modelWeight I < (C : ℝ) / (2 * q) := by
classical
by_contra! hlarge
obtain ⟨i, hi, hright⟩ := model_weight_heavy_part hq hC hn I hlarge
apply hω
refine ⟨i, modelRestrict I i, ?_, ?_, ?_, ?_⟩
· intro v hv
exact Finset.mem_filter.mpr ⟨Finset.mem_univ _, ((mem_modelRestrict I i v).mp hv).2⟩
· simpa only [modelDensity, modelFiber_restrict I i i le_rfl] using hi
· simpa only [modelLaterWeight_restrict] using hright
· intro v hv w hw
exact hI v ((mem_modelRestrict I i v).mp hv).1 w ((mem_modelRestrict I i w).mp hw).1
theorem model_heavy_independent_probability_le {q C : ℕ} (hq : 0 < q)
{n : Fin C → ℕ} (hn : ∀ j, 0 < n j) (I : Finset (ModelVertex n)) (i : Fin C)
(hi : 1 / (4 * (q : ℝ)) ≤ modelDensity I i)
(hright : 15 * (q : ℝ) ≤ modelLaterWeight I i) :
finiteProb {ω : ModelSample n | ∀ v ∈ I, ∀ w ∈ I, ¬ (modelGraph ω).Adj v w} ≤
Real.exp (-3 * (n i : ℝ)) := by
have hqR : (0 : ℝ) < q := by exact_mod_cast hq
have hnR : (0 : ℝ) < n i := by exact_mod_cast hn i
have ht : (n i : ℝ) ≤ ((modelFiber I i).card : ℝ) * (4 * q) := by
have hb := (div_le_div_iff₀ (show (0 : ℝ) < 4 * q by positivity) hnR).mp hi
simpa only [one_mul] using hb
have hprod := mul_le_mul_of_nonneg_left hright
(show (0 : ℝ) ≤ (modelFiber I i).card by positivity)
apply (model_independent_probability_le hn I i).trans
apply Real.exp_le_exp.mpr
nlinarith
/-- A union bound over all suffix sets and all possible first heavy parts. -/
theorem model_badColor_probability_le {q C : ℕ} (hq : 0 < q) (hC : 0 < C)
{n : Fin C → ℕ} (hn : ∀ j, 0 < n j)
(hsuffix : ∀ i, (modelSuffix n i).card ≤ 2 * n i)
(hlarge : ∀ i, 8 * C ≤ n i) :
finiteProb (modelBadColor n q) ≤ (1 : ℝ) / 8 := by
classical
let A : Fin C → Finset (ModelVertex n) → Set (ModelSample n) := fun i I =>
{ω | 1 / (4 * (q : ℝ)) ≤ modelDensity I i ∧
15 * (q : ℝ) ≤ modelLaterWeight I i ∧
∀ v ∈ I, ∀ w ∈ I, ¬ (modelGraph ω).Adj v w}
have hfixed : ∀ i I, finiteProb (A i I) ≤ Real.exp (-3 * (n i : ℝ)) := by
intro i I
by_cases hi : 1 / (4 * (q : ℝ)) ≤ modelDensity I i
· by_cases hr : 15 * (q : ℝ) ≤ modelLaterWeight I i
· exact (finiteProb_mono (fun _ h => h.2.2)).trans
(model_heavy_independent_probability_le hq hn I i hi hr)
· have heq : A i I = ∅ := by ext ω; simp [A, hr]
rw [heq, finiteProb_empty]
exact Real.exp_nonneg _
· have heq : A i I = ∅ := by
ext ω
exact ⟨fun h => (hi h.1).elim, fun h => h.elim⟩
rw [heq, finiteProb_empty]
exact Real.exp_nonneg _
have hpart : ∀ i, finiteProb {ω | ∃ I ∈ (modelSuffix n i).powerset, ω ∈ A i I} ≤
1 / (8 * (C : ℝ)) := by
intro i
have hnR : (0 : ℝ) < n i := by exact_mod_cast hn i
have hCR : (0 : ℝ) < C := by exact_mod_cast hC
calc
_ ≤ ∑ I ∈ (modelSuffix n i).powerset, finiteProb (A i I) := finiteProb_biUnion_le _ _
_ ≤ ∑ _I ∈ (modelSuffix n i).powerset, Real.exp (-3 * (n i : ℝ)) :=
Finset.sum_le_sum (fun I _ => hfixed i I)
_ = (2 : ℝ) ^ (modelSuffix n i).card * Real.exp (-3 * (n i : ℝ)) := by simp
_ ≤ (2 : ℝ) ^ (2 * n i) * Real.exp (-3 * (n i : ℝ)) := by
gcongr
· norm_num
· exact hsuffix i
_ ≤ Real.exp (2 * (n i : ℝ)) * Real.exp (-3 * (n i : ℝ)) := by
apply mul_le_mul_of_nonneg_right _ (Real.exp_nonneg _)
calc
_ ≤ Real.exp 1 ^ (2 * n i) :=
pow_le_pow_left₀ (by norm_num) (by linarith [Real.add_one_le_exp (1 : ℝ)]) _
_ = _ := by rw [← Real.exp_nat_mul]; norm_cast; simp
_ = Real.exp (-(n i : ℝ)) := by rw [← Real.exp_add]; congr 1; ring
_ ≤ 1 / (8 * (C : ℝ)) := by
rw [Real.exp_neg, one_div]
apply (inv_le_inv₀ (Real.exp_pos _) (by positivity)).mpr
have hlargeR : 8 * (C : ℝ) ≤ n i := by exact_mod_cast hlarge i
linarith [Real.add_one_le_exp (n i : ℝ)]
have heq : modelBadColor n q =
{ω | ∃ i ∈ (Finset.univ : Finset (Fin C)),
∃ I ∈ (modelSuffix n i).powerset, ω ∈ A i I} := by
ext ω
simp only [modelBadColor, A, Set.mem_ofPred_eq, Finset.mem_univ, true_and, Finset.mem_powerset]
calc
_ = finiteProb {ω | ∃ i ∈ (Finset.univ : Finset (Fin C)),
∃ I ∈ (modelSuffix n i).powerset, ω ∈ A i I} := congrArg finiteProb heq
_ ≤ ∑ i : Fin C, finiteProb {ω | ∃ I ∈ (modelSuffix n i).powerset, ω ∈ A i I} :=
finiteProb_biUnion_le _ _
_ ≤ ∑ _i : Fin C, 1 / (8 * (C : ℝ)) := Finset.sum_le_sum (fun i _ => hpart i)
_ = 1 / 8 := by
simp only [Finset.sum_const, Finset.card_univ, Fintype.card_fin, nsmul_eq_mul]
field_simp
/-- A convenient binomial estimate avoiding logarithms in the probability bounds. -/
theorem choose_le_three_mul_div_pow (N k : ℕ) (hk : 0 < k) :
(N.choose k : ℝ) ≤ (3 * N / k) ^ k := by
have hkR : (0 : ℝ) < k := by exact_mod_cast hk
have hfact : (k : ℝ) ^ k / k.factorial ≤ (3 : ℝ) ^ k := by
calc
_ ≤ Real.exp k := Real.pow_div_factorial_le_exp (k : ℝ) (by positivity) k
_ = Real.exp 1 ^ k := by simp [Real.exp_nat_mul]
_ ≤ _ := pow_le_pow_left₀ (Real.exp_nonneg _) Real.exp_one_lt_three.le _
have hchoose := (Nat.choose_le_pow_div k N : (N.choose k : ℝ) ≤ (N : ℝ) ^ k / k.factorial)
have hm := mul_le_mul_of_nonneg_left hfact (show 0 ≤ (N : ℝ) ^ k by positivity)
have heq : (3 * (N : ℝ) / k) ^ k = (3 : ℝ) ^ k * (N : ℝ) ^ k / (k : ℝ) ^ k := by
rw [div_pow, mul_pow]
rw [heq]
apply (le_div_iff₀ (pow_pos hkR _)).mpr
have hc := mul_le_mul_of_nonneg_right hchoose (le_of_lt (pow_pos hkR k))
have he : (N : ℝ) ^ k / k.factorial * (k : ℝ) ^ k =
(N : ℝ) ^ k * ((k : ℝ) ^ k / k.factorial) := by ring
rw [he] at hc
exact hc.trans (by simpa only [mul_comm] using hm)
/-- Taking an integer power avoids fractional exponents in the sparse-set estimate. -/
theorem sparse_product_power_bound {a b δ : ℝ} {D x m : ℕ}
(ha : 0 ≤ a) (hb : 0 ≤ b) (hb1 : b ≤ 1) (hδ : 0 ≤ δ) (hD : 0 < D)
(hm : (D + 1) * x ≤ m * D) (hcoef : a ^ D * b ^ (D + 1) ≤ δ ^ D) :
a ^ x * b ^ m ≤ δ ^ x := by
apply le_of_pow_le_pow_left₀ (Nat.ne_of_gt hD) (pow_nonneg hδ x)
calc
(a ^ x * b ^ m) ^ D = (a ^ D) ^ x * b ^ (m * D) := by
simp only [mul_pow, ← pow_mul, Nat.mul_comm]
_ ≤ (a ^ D) ^ x * b ^ ((D + 1) * x) :=
mul_le_mul_of_nonneg_left (pow_le_pow_of_le_one hb hb1 hm) (by positivity)
_ = (a ^ D * b ^ (D + 1)) ^ x := by simp only [mul_pow, pow_mul]
_ ≤ (δ ^ D) ^ x := pow_le_pow_left₀ (by positivity) hcoef x
_ = (δ ^ x) ^ D := by simp only [← pow_mul, Nat.mul_comm]
theorem sparse_binomial_bound {N L x m D : ℕ} {δ : ℝ}
(hx : 0 < x) (hxm : x ≤ m) (hD : 0 < D) (hm : (D + 1) * x ≤ m * D)
(hL : 3 * x ≤ L) (hδ : 0 ≤ δ)
(hcoef : (3 : ℝ) ^ (2 * D + 1) * (N : ℝ) ^ D * x / (L : ℝ) ^ (D + 1) ≤ δ ^ D) :
(N.choose x : ℝ) * ((x ^ 2).choose m : ℝ) * (1 / (L : ℝ)) ^ m ≤ δ ^ x := by
have hxR : (0 : ℝ) < x := by exact_mod_cast hx
have hmR : (0 : ℝ) < m := by exact_mod_cast lt_of_lt_of_le hx hxm
have hLR : (0 : ℝ) < L := by exact_mod_cast (show 0 < L by omega)
have hxmR : (x : ℝ) ≤ m := by exact_mod_cast hxm
have hLR' : 3 * (x : ℝ) ≤ L := by exact_mod_cast hL
let a : ℝ := 3 * N / x
let b : ℝ := 3 * x / L
have hchoose₁ : (N.choose x : ℝ) ≤ a ^ x := choose_le_three_mul_div_pow N x hx
have hchoose₂ : ((x ^ 2).choose m : ℝ) ≤ (3 * (x : ℝ)) ^ m := by
apply (choose_le_three_mul_div_pow (x ^ 2) m (by omega)).trans
apply pow_le_pow_left₀ (by positivity)
apply (div_le_iff₀ hmR).mpr
push_cast
nlinarith
have hpow : a ^ D * b ^ (D + 1) ≤ δ ^ D := by
have heq : a ^ D * b ^ (D + 1) =
(3 : ℝ) ^ (2 * D + 1) * (N : ℝ) ^ D * x / (L : ℝ) ^ (D + 1) := by
dsimp [a, b]
rw [show 2 * D + 1 = D + (D + 1) by omega, pow_add]
simp only [div_pow, mul_pow, pow_succ]
field_simp
ring
rw [heq]
exact hcoef
calc
_ ≤ a ^ x * (3 * (x : ℝ)) ^ m * (1 / (L : ℝ)) ^ m := by gcongr
_ = a ^ x * b ^ m := by
rw [mul_assoc, ← mul_pow]
congr 1
dsimp [b]
congr 1
ring
_ ≤ _ := sparse_product_power_bound (by dsimp [a]; positivity) (by dsimp [b]; positivity)
((div_le_one₀ hLR).mpr hLR') hδ hD hm hpow
/-- A union bound over all vertex sets of one specified size. -/
theorem model_fixed_size_density_probability_le {C : ℕ} {n : Fin C → ℕ}
(P : Finset (ModelVertex n)) {x D L N : ℕ} {δ : ℝ}
(hx : 0 < x) (hD : 0 < D) (hL : 3 * x ≤ L) (hδ : 0 ≤ δ)
(hP : P.card ≤ N) (hsize : ∀ v ∈ P, L ≤ n v.1)
(hcoef : (3 : ℝ) ^ (2 * D + 1) * (N : ℝ) ^ D * x / (L : ℝ) ^ (D + 1) ≤ δ ^ D) :
finiteProb {ω : ModelSample n | ∃ X : Finset (ModelVertex n),
X ⊆ P ∧ X.card = x ∧ (D + 1) * x ≤ (modelEdges ω X).card * D} ≤ δ ^ x := by
classical
have hmex : ∃ m : ℕ, (D + 1) * x ≤ m * D :=
⟨(D + 1) * x, Nat.le_mul_of_pos_right _ hD⟩
let m := Nat.find hmex
have hm : (D + 1) * x ≤ m * D := Nat.find_spec hmex
have hxm : x ≤ m := by nlinarith
have hLpos : 0 < L := by omega
have hsub : {ω : ModelSample n | ∃ X : Finset (ModelVertex n),
X ⊆ P ∧ X.card = x ∧ (D + 1) * x ≤ (modelEdges ω X).card * D} ⊆
{ω | ∃ X ∈ P.powersetCard x, m ≤ (modelEdges ω X).card} := by
intro ω hω
obtain ⟨X, hXP, hXx, hX⟩ := hω
exact ⟨X, Finset.mem_powersetCard.mpr ⟨hXP, hXx⟩, Nat.find_min' hmex hX⟩
have hb : ∀ X ∈ P.powersetCard x,
finiteProb {ω : ModelSample n | m ≤ (modelEdges ω X).card} ≤
((x ^ 2).choose m : ℝ) * (1 / (L : ℝ)) ^ m := by
intro X hX
obtain ⟨hXP, hXx⟩ := Finset.mem_powersetCard.mp hX
simpa only [hXx] using model_many_edges_probability_le X m hLpos
(fun v hv => hsize v (hXP hv))
calc
_ ≤ finiteProb {ω : ModelSample n | ∃ X ∈ P.powersetCard x, m ≤ (modelEdges ω X).card} :=
finiteProb_mono hsub
_ ≤ ∑ X ∈ P.powersetCard x, finiteProb {ω : ModelSample n | m ≤ (modelEdges ω X).card} :=
finiteProb_biUnion_le _ _
_ ≤ ∑ _X ∈ P.powersetCard x, ((x ^ 2).choose m : ℝ) * (1 / (L : ℝ)) ^ m :=
Finset.sum_le_sum hb
_ = (P.card.choose x : ℝ) * ((x ^ 2).choose m : ℝ) * (1 / (L : ℝ)) ^ m := by
simp [mul_assoc]
_ ≤ (N.choose x : ℝ) * ((x ^ 2).choose m : ℝ) * (1 / (L : ℝ)) ^ m := by
gcongr
_ ≤ _ := sparse_binomial_bound hx hxm hD hm hL hδ hcoef
noncomputable def modelBefore {C : ℕ} (n : Fin C → ℕ) (i : Fin C) : Finset (ModelVertex n) := by
classical
exact Finset.univ.filter fun v => v.1 < i
def modelBadSparse {C : ℕ} (n : Fin C → ℕ) (A D : ℕ) : Set (ModelSample n) :=
{ω | ∃ i : Fin C, ∃ X : Finset (ModelVertex n), X ⊆ modelBefore n i ∧
X.Nonempty ∧ X.card ≤ A * n i ∧ (D + 1) * X.card ≤ (modelEdges ω X).card * D}
/-- Summing the dense-set estimate over sizes and parts. -/
theorem model_badSparse_probability_le {C A D : ℕ} (hC : 0 < C) (hD : 0 < D)
{n : Fin C → ℕ}
(hbounds : ∀ i : Fin C, 0 < i.val → ∀ x : ℕ, 0 < x → x ≤ A * n i →
∃ L N : ℕ, 3 * x ≤ L ∧ (modelBefore n i).card ≤ N ∧
(∀ v ∈ modelBefore n i, L ≤ n v.1) ∧
(3 : ℝ) ^ (2 * D + 1) * (N : ℝ) ^ D * x / (L : ℝ) ^ (D + 1) ≤
(1 / (16 * (C : ℝ))) ^ D) :
finiteProb (modelBadSparse n A D) ≤ (1 : ℝ) / 8 := by
classical
let δ : ℝ := 1 / (16 * (C : ℝ))
have hCR : (0 : ℝ) < C := by exact_mod_cast hC
have hδ : 0 ≤ δ := by dsimp [δ]; positivity
have hδhalf : δ ≤ 1 / 2 := by
dsimp [δ]
apply one_div_le_one_div_of_le (by norm_num)
have : (1 : ℝ) ≤ C := by exact_mod_cast hC
linarith
let E : Fin C → Set (ModelSample n) := fun i =>
{ω | ∃ X : Finset (ModelVertex n), X ⊆ modelBefore n i ∧
X.Nonempty ∧ X.card ≤ A * n i ∧ (D + 1) * X.card ≤ (modelEdges ω X).card * D}
have hpart : ∀ i, finiteProb (E i) ≤ 1 / (8 * (C : ℝ)) := by
intro i
by_cases hiz : i.val = 0
· have heq : E i = ∅ := by
ext ω
constructor
· rintro ⟨X, hX, hnonempty, _⟩
obtain ⟨v, hv⟩ := hnonempty
have hvi : v.1 < i := (Finset.mem_filter.mp (hX hv)).2
have : v.1.val < i.val := hvi
omega
· exact fun h => h.elim
rw [heq, finiteProb_empty]
positivity
· let B : ℕ → Set (ModelSample n) := fun k =>
{ω | ∃ X : Finset (ModelVertex n), X ⊆ modelBefore n i ∧ X.card = k + 1 ∧
(D + 1) * (k + 1) ≤ (modelEdges ω X).card * D}
have hsub : E i ⊆ {ω | ∃ k ∈ Finset.range (A * n i), ω ∈ B k} := by
rintro ω ⟨X, hX, hnonempty, hsize, hdense⟩
have hx : 0 < X.card := hnonempty.card_pos
refine ⟨X.card - 1, Finset.mem_range.mpr (by omega), X, hX, by omega, ?_⟩
simpa only [Nat.sub_add_cancel (show 1 ≤ X.card by omega)] using hdense
have hfixed : ∀ k ∈ Finset.range (A * n i), finiteProb (B k) ≤ δ ^ (k + 1) := by
intro k hk
have hk' : k + 1 ≤ A * n i := by have := Finset.mem_range.mp hk; omega
obtain ⟨L, N, hL, hP, hsize, hcoef⟩ := hbounds i (by omega) (k + 1) (by omega) hk'
exact model_fixed_size_density_probability_le (modelBefore n i) (by omega) hD hL hδ
hP hsize hcoef
calc
_ ≤ finiteProb {ω | ∃ k ∈ Finset.range (A * n i), ω ∈ B k} := finiteProb_mono hsub
_ ≤ ∑ k ∈ Finset.range (A * n i), finiteProb (B k) := finiteProb_biUnion_le _ _
_ ≤ ∑ k ∈ Finset.range (A * n i), δ ^ (k + 1) := Finset.sum_le_sum hfixed
_ ≤ ∑ k ∈ Finset.range (A * n i), δ * ((1 : ℝ) / 2) ^ k := by
apply Finset.sum_le_sum
intro k hk
rw [pow_succ']
exact mul_le_mul_of_nonneg_left (pow_le_pow_left₀ hδ hδhalf k) hδ
_ = δ * (∑ k ∈ Finset.range (A * n i), ((1 : ℝ) / 2) ^ k) :=
(Finset.mul_sum _ _ _).symm
_ ≤ δ * 2 := mul_le_mul_of_nonneg_left (sum_geometric_two_le _) hδ
_ = 1 / (8 * (C : ℝ)) := by dsimp [δ]; ring
have heq : modelBadSparse n A D = {ω | ∃ i ∈ (Finset.univ : Finset (Fin C)), ω ∈ E i} := by
ext ω
simp only [modelBadSparse, E, Set.mem_ofPred_eq, Finset.mem_univ, true_and]
calc
_ = finiteProb {ω | ∃ i ∈ (Finset.univ : Finset (Fin C)), ω ∈ E i} := congrArg finiteProb heq
_ ≤ ∑ i : Fin C, finiteProb (E i) := finiteProb_biUnion_le _ _
_ ≤ ∑ _i : Fin C, 1 / (8 * (C : ℝ)) := Finset.sum_le_sum (fun i _ => hpart i)
_ = 1 / 8 := by
simp only [Finset.sum_const, Finset.card_univ, Fintype.card_fin, nsmul_eq_mul]
field_simp
theorem model_sparse_of_not_bad {C A D : ℕ} (hD : 0 < D) {n : Fin C → ℕ}
(ω : ModelSample n) (hω : ω ∉ modelBadSparse n A D)
(i : Fin C) (X : Finset (ModelVertex n)) (hX : ∀ v ∈ X, v.1 < i)
(hsize : X.card ≤ A * n i) :
internalCount (modelGraph ω) X ≤ (1 + 1 / (D : ℝ)) * X.card := by
classical
by_cases hx : X.Nonempty
· have hbad : ¬ (D + 1) * X.card ≤ (modelEdges ω X).card * D := by
intro h
apply hω
exact ⟨i, X, fun v hv => Finset.mem_filter.mpr ⟨Finset.mem_univ _, hX v hv⟩,
hx, hsize, h⟩
have hlt : ((modelEdges ω X).card : ℝ) * D < ((D : ℝ) + 1) * X.card := by
exact_mod_cast lt_of_not_ge hbad
rw [internalCount_modelGraph]
have hDR : (0 : ℝ) < D := by exact_mod_cast hD
have heq : (1 + 1 / (D : ℝ)) * X.card = ((D + 1) * X.card) / (D : ℝ) := by
field_simp
rw [heq]
exact (le_div_iff₀ hDR).mpr hlt.le
· have heq : X = ∅ := Finset.not_nonempty_iff_eq_empty.mp hx
subst X
simp [internalCount, crossingCount]
theorem model_card {C : ℕ} (n : Fin C → ℕ) : Fintype.card (ModelVertex n) = ∑ i, n i := by
change Fintype.card (Σ i : Fin C, Fin (n i)) = _
simp only [Fintype.card_sigma, Fintype.card_fin]
theorem model_count_parts {C : ℕ} (n : Fin C → ℕ) (P : Fin C → Prop) [DecidablePred P] :
((Finset.univ : Finset (ModelVertex n)).filter (fun v => P v.1)).card =
∑ i : Fin C, if P i then n i else 0 := by
classical
rw [Finset.card_eq_sum_ones, Finset.sum_filter]
change (∑ v : Σ i : Fin C, Fin (n i), if P v.1 then (1 : ℕ) else 0) = _
rw [Fintype.sum_sigma]
apply Finset.sum_congr rfl
intro i hi
by_cases hp : P i <;> simp only [hp, if_true, if_false, Finset.sum_const,
Finset.card_univ, Fintype.card_fin, smul_eq_mul, mul_one, mul_zero]
theorem model_filter_card_le {C : ℕ} {n : Fin C → ℕ}
(S : Finset (ModelVertex n)) (P : Fin C → Prop) [DecidablePred P] :
(S.filter (fun v => P v.1)).card ≤ ∑ i : Fin C, if P i then n i else 0 := by
rw [← model_count_parts n P]
exact Finset.card_le_card (Finset.filter_subset_filter _ (Finset.subset_univ _))
theorem model_suffix_card_le {C : ℕ} (hC : 0 < C) {n : Fin C → ℕ}
(hsep : ∀ i j : Fin C, i < j → C * n j ≤ n i) (i : Fin C) :
(modelSuffix n i).card ≤ 2 * n i := by
classical
let t : ℕ := ∑ j : Fin C, if i < j then n j else 0
have hmul : C * t ≤ C * n i := by
dsimp [t]
rw [Finset.mul_sum]
calc
_ ≤ ∑ _j : Fin C, n i := by
apply Finset.sum_le_sum
intro j hj
by_cases hij : i < j
· simpa only [if_pos hij] using hsep i j hij
· simp only [if_neg hij, mul_zero, Nat.zero_le]
_ = _ := by simp
have ht : t ≤ n i := Nat.le_of_mul_le_mul_left hmul hC
have hcard : (modelSuffix n i).card = n i + t := by
rw [modelSuffix, model_count_parts]
calc
_ = ∑ j : Fin C, ((if j = i then n i else 0) + (if i < j then n j else 0)) := by
apply Finset.sum_congr rfl
intro j hj
rcases lt_trichotomy i j with hij | rfl | hij
· simp only [if_pos hij.le, if_neg hij.ne.symm, if_pos hij, zero_add]
· simp
· simp only [if_neg hij.not_ge, if_neg hij.ne, if_neg hij.not_gt, add_zero]
_ = _ := by simp only [Finset.sum_add_distrib, Finset.sum_ite_eq', Finset.mem_univ, if_true, t]
omega
/-- The last part large enough for a set provides the deterministic sparse cut. -/
theorem model_size_cut {C K A : ℕ} (hC : 0 < C) (hK : 4 ≤ K)
(hA : A = 16 * C * K * (K + 1)) {n : Fin C → ℕ}
(hmono : Antitone n) (S : Finset (ModelVertex n)) (hS : S.Nonempty) :
∃ i : Fin C, S.card ≤ A * n i ∧
((S.filter (fun v => i < v.1)).card : ℝ) <
2 * S.card / (16 * K * (K + 1)) := by
classical
let z : Fin C := ⟨0, hC⟩
have hCA : C ≤ A := by
rw [hA]
have hmul : 1 ≤ 16 * K * (K + 1) := by nlinarith
nlinarith
have htotal : Fintype.card (ModelVertex n) ≤ C * n z := by
rw [model_card]
calc
_ ≤ ∑ _i : Fin C, n z := Finset.sum_le_sum (fun j _ => hmono (by exact Nat.zero_le _))
_ = _ := by simp
have hz : S.card ≤ A * n z := (Finset.card_le_univ S).trans
(htotal.trans (Nat.mul_le_mul_right _ hCA))
let Q := Finset.univ.filter (fun i : Fin C => S.card ≤ A * n i)
have hQ : Q.Nonempty := ⟨z, Finset.mem_filter.mpr ⟨Finset.mem_univ _, hz⟩⟩
let i := Q.max' hQ
refine ⟨i, (Finset.mem_filter.mp (Finset.max'_mem Q hQ)).2, ?_⟩
have hKR : (0 : ℝ) < 16 * K * (K + 1) := by positivity
have hSR : (0 : ℝ) < S.card := by exact_mod_cast hS.card_pos
by_cases hnext : i.val + 1 < C
· let j : Fin C := ⟨i.val + 1, hnext⟩
have hij : i < j := by change i.val < i.val + 1; omega
have hjbig : A * n j < S.card := by
by_contra! hbad
have hji : j ≤ i := Finset.le_max' Q j (Finset.mem_filter.mpr ⟨Finset.mem_univ _, hbad⟩)
exact (not_lt_of_ge hji) hij
have htail : (S.filter (fun v => i < v.1)).card ≤ C * n j := by
apply (model_filter_card_le S (fun k => i < k)).trans
calc
_ ≤ ∑ _k : Fin C, n j := by
apply Finset.sum_le_sum
intro k hk
by_cases hik : i < k
· simp only [if_pos hik]
exact hmono (show j ≤ k by change i.val + 1 ≤ k.val; exact hik)
· simp only [if_neg hik, Nat.zero_le]
_ = _ := by simp
have htailR : ((S.filter (fun v => i < v.1)).card : ℝ) ≤ C * n j := by exact_mod_cast htail
have hjR : (16 * (C : ℝ) * K * (K + 1)) * n j < S.card := by
rw [hA] at hjbig
exact_mod_cast hjbig
apply (lt_div_iff₀ hKR).mpr
have hm := mul_le_mul_of_nonneg_right htailR hKR.le
nlinarith
· have hempty : S.filter (fun v => i < v.1) = ∅ := by
apply Finset.eq_empty_iff_forall_notMem.mpr
intro v hv
have hvi : i.val < v.1.val := (Finset.mem_filter.mp hv).2
have hvC := v.1.isLt
omega
rw [hempty, Finset.card_empty, Nat.cast_zero]
positivity
/-- Explicit, widely separated part sizes satisfying both probability estimates. -/
theorem model_sizes_exist {C A D : ℕ} (hC : 0 < C) (hD : 0 < D) :
∃ n : Fin C → ℕ,
(∀ i, 0 < n i) ∧ Antitone n ∧
(∀ i j : Fin C, i < j → C * n j ≤ n i) ∧ (∀ i, 8 * C ≤ n i) ∧
∀ i : Fin C, 0 < i.val → ∀ x : ℕ, 0 < x → x ≤ A * n i →
∃ L N : ℕ, 3 * x ≤ L ∧ (modelBefore n i).card ≤ N ∧
(∀ v ∈ modelBefore n i, L ≤ n v.1) ∧
(3 : ℝ) ^ (2 * D + 1) * (N : ℝ) ^ D * x / (L : ℝ) ^ (D + 1) ≤
(1 / (16 * (C : ℝ))) ^ D := by
classical
let R := (16 * C) ^ D * 3 ^ (2 * D + 1) * A + 3 * A + 8 * C + 2
let b := D + 2
let B := b ^ (C + 1)
let n : Fin C → ℕ := fun i => R ^ (B - b ^ (i.val + 1))
have hR : 2 ≤ R := by dsimp [R]; omega
have hRC : C ≤ R := by dsimp [R]; omega
have hRlarge : 8 * C ≤ R := by dsimp [R]; omega
have hRA : 3 * A ≤ R := by dsimp [R]; omega
have hRcoef : (16 * C) ^ D * 3 ^ (2 * D + 1) * A ≤ R := by dsimp [R]; omega
have hb : 1 < b := by dsimp [b]; omega
have hB : 0 < B := by dsimp [B]; positivity
have hpowlt : ∀ i : Fin C, b ^ (i.val + 1) < B := by
intro i
exact pow_lt_pow_right₀ hb (by have := i.isLt; omega)
have hnR : ∀ i, R ≤ n i := by
intro i
calc
R = R ^ 1 := by simp
_ ≤ _ := pow_le_pow_right₀ (by omega) (by have := hpowlt i; omega)
have hn : ∀ i, 0 < n i := fun i => lt_of_lt_of_le (by omega) (hnR i)
have hmono : Antitone n := by
intro i j hij
apply pow_le_pow_right₀ (by omega)
have hp : b ^ (i.val + 1) ≤ b ^ (j.val + 1) := pow_le_pow_right₀ hb.le (by exact Nat.add_le_add_right hij 1)
exact Nat.sub_le_sub_left hp B
have hgap : ∀ i j : Fin C, i < j → R * n j ≤ n i := by
intro i j hij
change R * R ^ (B - b ^ (j.val + 1)) ≤ R ^ (B - b ^ (i.val + 1))
rw [← pow_succ']
apply pow_le_pow_right₀ (by omega)
have hp : b ^ (i.val + 1) < b ^ (j.val + 1) :=
pow_lt_pow_right₀ hb (by exact Nat.add_lt_add_right hij 1)
have := hpowlt j
omega
have hsep : ∀ i j : Fin C, i < j → C * n j ≤ n i :=
fun i j hij => (Nat.mul_le_mul_right _ hRC).trans (hgap i j hij)
have htotal : Fintype.card (ModelVertex n) ≤ R ^ B := by
rw [model_card]
have hsmall : ∀ i : Fin C, n i ≤ R ^ (B - 1) := by
intro i
apply pow_le_pow_right₀ (by omega)
apply Nat.sub_le_sub_left
exact Nat.one_le_pow _ _ (by omega)
calc
_ ≤ ∑ _i : Fin C, R ^ (B - 1) := Finset.sum_le_sum (fun i _ => hsmall i)
_ = C * R ^ (B - 1) := by simp
_ ≤ R * R ^ (B - 1) := Nat.mul_le_mul_right _ hRC
_ = R ^ B := by rw [← pow_succ', Nat.sub_add_cancel hB]
refine ⟨n, hn, hmono, hsep, fun i => hRlarge.trans (hnR i), ?_⟩
intro i hi x hx hxi
let p : Fin C := ⟨i.val - 1, by have := i.isLt; omega⟩
let L := n p
let N := R ^ B
have hpi : p < i := by change i.val - 1 < i.val; omega
have hL : L = R ^ (B - b ^ i.val) := by
dsimp [L, n, p]
rw [Nat.sub_add_cancel hi]
have hLR : 0 < L := hn p
have hthree : 3 * x ≤ L := calc
3 * x ≤ 3 * (A * n i) := Nat.mul_le_mul_left _ hxi
_ = (3 * A) * n i := by ring
_ ≤ R * n i := Nat.mul_le_mul_right _ hRA
_ ≤ L := hgap p i hpi
have hP : (modelBefore n i).card ≤ N := (Finset.card_filter_le _ _).trans htotal
have hmin : ∀ v ∈ modelBefore n i, L ≤ n v.1 := by
intro v hv
apply hmono
have hvi : v.1.val < i.val := (Finset.mem_filter.mp hv).2
change v.1.val ≤ i.val - 1
omega
have hden : R * N ^ D * n i ≤ L ^ (D + 1) := by
rw [hL]
change R * (R ^ B) ^ D * R ^ (B - b ^ (i.val + 1)) ≤
(R ^ (B - b ^ i.val)) ^ (D + 1)
rw [← pow_mul, ← pow_succ', ← pow_add, ← pow_mul]
apply pow_le_pow_right₀ (by omega)
have ht : 1 ≤ b ^ i.val := Nat.one_le_pow _ _ (by omega)
have hbig : b ^ (i.val + 1) ≤ B := (hpowlt i).le
have hsmall : b ^ i.val ≤ B :=
(pow_le_pow_right₀ hb.le (by omega : i.val ≤ i.val + 1)).trans hbig
have he₁ := Nat.sub_add_cancel hsmall
have he₂ := Nat.sub_add_cancel hbig
rw [pow_succ] at he₂ ⊢
dsimp [b] at ht he₁ he₂ ⊢
nlinarith
have hnat : 3 ^ (2 * D + 1) * N ^ D * x * (16 * C) ^ D ≤ L ^ (D + 1) := calc
_ ≤ 3 ^ (2 * D + 1) * N ^ D * (A * n i) * (16 * C) ^ D :=
Nat.mul_le_mul_right _ (Nat.mul_le_mul_left _ hxi)
_ = ((16 * C) ^ D * 3 ^ (2 * D + 1) * A) * (N ^ D * n i) := by ring
_ ≤ R * (N ^ D * n i) := Nat.mul_le_mul_right _ hRcoef
_ ≤ L ^ (D + 1) := by simpa only [mul_assoc] using hden
refine ⟨L, N, hthree, hP, hmin, ?_⟩
rw [div_pow, one_pow]
apply (div_le_div_iff₀ (by exact_mod_cast pow_pos hLR (D + 1))
(by positivity : (0 : ℝ) < (16 * C) ^ D)).mpr
simpa only [one_mul] using (show (3 : ℝ) ^ (2 * D + 1) * (N : ℝ) ^ D * x *
(16 * (C : ℝ)) ^ D ≤ (L : ℝ) ^ (D + 1) by exact_mod_cast hnat)
/-- The probabilistic base graph: large chromatic number and sparse bounded-degree subgraphs. -/
theorem model_base_exists {q K : ℕ} (hq : 1 ≤ q) (hK : 4 ≤ K) :
∃ n : Fin (64 * q ^ 2) → ℕ, ∃ ω : ModelSample n,
¬ (modelGraph ω).Colorable (2 * q) ∧
∀ J : SimpleGraph (ModelVertex n), J ≤ modelGraph ω →
(∀ v, Nat.card (J.neighborSet v) ≤ K) → J.Colorable 4 := by
classical
let C := 64 * q ^ 2
let A := 16 * C * K * (K + 1)
let D := 2 * (K + 1)
have hqpos : 0 < q := by omega
have hC : 0 < C := by dsimp [C]; positivity
have hD : 0 < D := by dsimp [D]; positivity
obtain ⟨n, hn, hmono, hsep, hlarge, hbounds⟩ := model_sizes_exist (A := A) hC hD
let : Nonempty (ModelSample n) := ⟨fun k => ⟨0, hn k.2⟩⟩
have hcolor := model_badColor_probability_le hqpos hC hn (model_suffix_card_le hC hsep) hlarge
have hsparse := model_badSparse_probability_le hC hD hbounds
obtain ⟨ω, hωcolor, hωsparse⟩ := exists_avoiding_of_finiteProb_lt_one
(modelBadColor n q) (modelBadSparse n A D) (by linarith)
refine ⟨n, ω, ?_, ?_⟩
· apply model_not_colorable_of_independent_weights hn (by omega) ω
intro I hI
simpa only [C, Nat.cast_mul, Nat.cast_ofNat] using
model_small_weights_of_not_bad hq rfl hn ω hωcolor I hI
· have hcuts : SparseCutProperty (modelGraph ω) K := by
apply sparse_cuts_of_parts (A := A) (fun v : ModelVertex n => v.1) n
(modelGraph_same_part ω) (modelGraph_one_neighbor ω)
· exact model_size_cut hC hK rfl hmono
· intro i X hX hsize
simpa only [D, Nat.cast_mul, Nat.cast_add, Nat.cast_one, Nat.cast_ofNat] using
model_sparse_of_not_bad hD ω hωsparse i X hX hsize
intro J hJ hdeg
exact colorable_four_of_sparse_cuts hK hcuts hJ hdeg
/-- Arc graphs have arbitrarily large chromatic number while their four-cycle-free subgraphs
are six-colorable. -/
theorem arc_counterexample_family (M : ℕ) :
∃ (V : Type) (G : SimpleGraph V), Nonempty V ∧ M ≤ G.chromaticNumber ∧
∀ J : SimpleGraph V, J ≤ G → FourCycleFree J → J.Colorable 6 := by
classical
let q : ℕ := 2 ^ M + 2
let d := 64 * q ^ 2 - 1
let K := d + d.choose 2
have hq : 1 ≤ q := Nat.succ_le_succ (Nat.zero_le (2 ^ M + 1))
have hd : 4 ≤ d := by
have hbig : 64 ≤ 64 * q ^ 2 := by nlinarith
dsimp [d]
omega
have hK : 4 ≤ K := by dsimp [K]; omega
obtain ⟨n, ω, hnot, hbase⟩ := model_base_exists hq hK
let F := modelGraph ω
have hnotArc : ¬ (arcGraph F).Colorable M := by
intro hc
apply hnot
exact (base_colorable_of_arc_colorable hc).mono (by dsimp [q]; omega)
have hV : Nonempty (Arc F) := by
by_contra hempty
let : IsEmpty (Arc F) := not_nonempty_iff.mp hempty
exact hnotArc (SimpleGraph.Colorable.of_isEmpty M)
have hchi : (M : ℕ∞) ≤ (arcGraph F).chromaticNumber := by
apply le_of_lt
apply lt_of_not_ge
intro h
exact hnotArc (SimpleGraph.chromaticNumber_le_iff_colorable.mp h)
refine ⟨Arc F, arcGraph F, hV, hchi, ?_⟩
intro J hJ h4
exact arc_colorable_bound (d := d) (a := 4) (model_outgoing_card_le ω) hbase hJ h4
/-- The counterexample is available in every universe occurring in the conjecture. -/
theorem counterexample_family (M : ℕ) :
∃ (V : Type u) (G : SimpleGraph V), Nonempty V ∧ M ≤ G.chromaticNumber ∧
∀ H : G.Subgraph, 5 ≤ H.coe.girth → H.coe.Colorable 6 := by
classical
obtain ⟨V, G, hV, hchi, hcolor⟩ := arc_counterexample_family M
let W := ULift.{u} V
let G' : SimpleGraph W := G.comap ULift.down
let e : G' ≃g G := SimpleGraph.Iso.comap Equiv.ulift G
have hW : Nonempty W := hV.map ULift.up
refine ⟨W, G', hW, ?_, ?_⟩
· simpa only [SimpleGraph.chromaticNumber_congr e] using hchi
· intro H hg
have h4 : FourCycleFree H.spanningCoe := (fourCycleFree_of_girth_ge_five hg).spanningCoe
let J : SimpleGraph V := H.spanningCoe.comap ULift.up
have hJG : J ≤ G := by
intro a b hab
exact H.adj_sub hab
have hJ4 : FourCycleFree J := by
intro a b x y hab hxy hax hay hbx hby
exact h4 (ULift.up a) (ULift.up b) (ULift.up x) (ULift.up y)
(fun h => hab (congrArg ULift.down h)) (fun h => hxy (congrArg ULift.down h))
hax hay hbx hby
have hc : J.Colorable 6 := hcolor J hJG hJ4
let f : H.coe →g J := {
toFun := fun v => v.val.down
map_rel' := by
intro v w hvw
change H.Adj v.val w.val at hvw
change H.Adj (ULift.up v.val.down) (ULift.up w.val.down)
simpa only [ULift.up_down] using hvw
}
exact hc.of_hom f
/-- The final logical reduction at girth five and chromatic number seven. -/
theorem counterexample_of_family
(hfamily : ∀ M : ℕ, ∃ (V : Type u) (G : SimpleGraph V),
Nonempty V ∧ M ≤ G.chromaticNumber ∧
∀ H : G.Subgraph, 5 ≤ H.coe.girth → H.coe.Colorable 6) :
¬ (fcTypeOfName% "Erdos108.erdos_108") := by
intro h
obtain ⟨f, hf⟩ := h.mp trivial 5 (by decide) 7 (by decide)
obtain ⟨V, G, hV, hchi, hG⟩ := hfamily f
obtain ⟨H, hgirth, hseven⟩ := hf V G hV hchi
have hsix := (hG H hgirth).chromaticNumber_le
have hbad : (7 : ℕ∞) ≤ 6 := hseven.trans hsix
norm_num at hbad
theorem target : ¬ (fcTypeOfName% "Erdos108.erdos_108") := by
exact counterexample_of_family counterexample_family
Provenance
- Proof SHA-256
- sha256:a0b65a62937486813884b5bbc9fb36a2bb6da42850a898126eddaecd5aaa0fa2
- Solver
- JenW1N
- Attribution
- conjectures.io