CubicPathwidth.T4.Cor5S
Source file CubicPathwidth/T4/Cor5S.lean of the Lean project (how it is built).
import CubicPathwidth.T4.Defs
import CubicPathwidth.Relabelling
import Mathlib.Combinatorics.SimpleGraph.DegreeSum
noncomputable section
namespace CubicPathwidth
namespace T4
open SectionDecomposition
theorem hasPathwidth_mono {n : ℕ} {G : SimpleGraph (Fin n)} {a b : ℝ}
(h : HasPathwidthAtMost G a) (hab : a ≤ b) : HasPathwidthAtMost G b := by
obtain ⟨D, hD⟩ := h
exact ⟨D, fun i => (hD i).trans (by linarith)⟩
/-- Adding isolated vertices one at a time. -/
theorem add_isolated {n : ℕ} (G : SimpleGraph (Fin n)) [DecidableRel G.Adj] {w : ℝ} (hw : 0 ≤ w) :
∀ (S : Finset (Fin n)) (U : Finset (Fin n)),
(∀ v ∈ S, v ∉ U ∧ G.degree v = 0) →
∀ P : SectionDecomposition G U, P.toBagPath.WidthAtMost w →
∃ Q : SectionDecomposition G (S ∪ U), Q.toBagPath.WidthAtMost w := by
intro S
induction S using Finset.induction_on with
| empty =>
intro U _ P hP
rw [Finset.empty_union]
exact ⟨P, hP⟩
| insert a S ha ih =>
intro U hS P hP
have haU : a ∉ U := (hS a (Finset.mem_insert_self _ _)).1
have hdeg : G.degree a = 0 := (hS a (Finset.mem_insert_self _ _)).2
have hno : ∀ u, ¬ G.Adj a u := by
intro u hu
have := (G.degree_pos_iff_exists_adj a).mpr ⟨u, hu⟩
omega
let R := P.restoreVertex a haU {a} (Finset.mem_singleton_self a)
(by intro u hu; simp at hu; subst hu; exact Finset.mem_insert_self _ _)
(by intro u hu hau; rw [Finset.mem_singleton] at hu; exact absurd (hu ▸ hau) haU)
(fun u _ h => absurd h (hno u))
have hR : R.toBagPath.WidthAtMost w := by
have := restoreVertex_width P a haU {a} (Finset.mem_singleton_self a)
(by intro u hu; simp at hu; subst hu; exact Finset.mem_insert_self _ _)
(by intro u hu hau; rw [Finset.mem_singleton] at hu; exact absurd (hu ▸ hau) haU)
(fun u _ h => absurd h (hno u)) hP
exact fun i hi => (this i hi).trans (by simp [hw])
obtain ⟨Q, hQ⟩ := ih (insert a U) (by
intro v hv
have := hS v (Finset.mem_insert_of_mem hv)
refine ⟨?_, this.2⟩
intro hv'
rcases Finset.mem_insert.mp hv' with rfl | h
· exact ha hv
· exact this.1 h) R hR
have heq : S ∪ insert a U = insert a S ∪ U := by
ext x; simp
have key : ∃ Q : SectionDecomposition G (S ∪ insert a U), Q.toBagPath.WidthAtMost w :=
⟨Q, hQ⟩
rw [heq] at key
exact key
/-- Per-degree bound `a_d ≤ (7/96) d`. -/
theorem coeff_le (d : ℕ) : thm4Coeff d ≤ 7 / 96 * (d : ℝ) := by
by_cases h2 : d ≤ 2
· simp only [thm4Coeff, if_pos h2]; positivity
by_cases h13 : d ≤ 13
· interval_cases d <;> norm_num [thm4Coeff]
· push_neg at h13
have hd : (14 : ℝ) ≤ d := by exact_mod_cast h13
have h1 : thm4Coeff d ≤ 1 := by
have : ¬ d ≤ 2 := h2
have h6 : ¬ d ≤ 6 := by omega
have h10 : ¬ d ≤ 10 := by omega
simp only [thm4Coeff, if_neg this, if_neg h6, if_neg h10]
have : 0 ≤ 4 / ((d : ℝ) + 1) := by positivity
linarith
linarith
theorem pw_extend {n : ℕ} (G : SimpleGraph (Fin n)) [DecidableRel G.Adj] {w : ℝ} (hw : 0 ≤ w) :
HasPathwidthAtMost (inducedOnFin G (Finset.univ.filter (fun v => 0 < G.degree v)))
w → HasPathwidthAtMost G w := by
intro ⟨D, hD⟩
generalize hU : Finset.univ.filter (fun v => 0 < G.degree v) = U at D hD
have hP := lift_width G U D hD
obtain ⟨Q, hQ⟩ := add_isolated G hw (Finset.univ.filter (fun v => ¬ 0 < G.degree v)) U
(by
intro v hv
simp only [Finset.mem_filter, Finset.mem_univ, true_and] at hv
refine ⟨?_, by omega⟩
rw [← hU]; simp [hv]) (lift G U D) hP
have hall : (Finset.univ.filter (fun v => ¬ 0 < G.degree v)) ∪ U = Finset.univ := by
ext x; subst hU; simp; omega
have key : ∃ Q : SectionDecomposition G ((Finset.univ.filter (fun v => ¬ 0 < G.degree v)) ∪ U),
Q.toBagPath.WidthAtMost w := ⟨Q, hQ⟩
rw [hall] at key
obtain ⟨Q, hQ⟩ := key
exact ⟨Q.toFull, Q.toFull_width hQ⟩
theorem deg_induced_le {n : ℕ} (G : SimpleGraph (Fin n)) [DecidableRel G.Adj]
[DecidableRel (inducedOnFin G (Finset.univ.filter (fun v => 0 < G.degree v))).Adj]
(U : Finset (Fin n)) [DecidableRel (inducedOnFin G U).Adj] (i : Fin U.card) :
(inducedOnFin G U).degree i ≤ G.degree (enumerate U i) := by
have hsub : ((inducedOnFin G U).neighborFinset i).image (enumerate U) ⊆
G.neighborFinset (enumerate U i) := by
intro u hu
obtain ⟨w, hw, rfl⟩ := Finset.mem_image.mp hu
apply (G.mem_neighborFinset _ _).mpr
exact ((inducedOnFin G U).mem_neighborFinset i w).mp hw
calc (inducedOnFin G U).degree i = ((inducedOnFin G U).neighborFinset i).card := rfl
_ = (((inducedOnFin G U).neighborFinset i).image (enumerate U)).card :=
(Finset.card_image_of_injective _ (enumerate U).injective).symm
_ ≤ (G.neighborFinset (enumerate U i)).card := Finset.card_le_card hsub
theorem cor5_s : Cor5Claim := by
classical
intro h4 ε hε
obtain ⟨N, hN⟩ := h4 (ε / 2) (by positivity)
refine ⟨⌈(N : ℝ) / ε⌉₊, ?_⟩
intro n G hM
set m := edgeCount G with hm
have hmR : ((⌈(N : ℝ) / ε⌉₊ : ℕ) : ℝ) ≤ (m : ℝ) := by exact_mod_cast hM
have hNm : (N : ℝ) ≤ ε * m := by
have h1 : (N : ℝ) / ε ≤ m := (Nat.le_ceil _).trans hmR
rw [div_le_iff₀ hε] at h1; linarith
have hm0 : (0 : ℝ) ≤ m := Nat.cast_nonneg _
have hdeg : ∑ v, G.degree v = 2 * m := by
rw [hm]; unfold edgeCount; exact SimpleGraph.sum_degrees_eq_twice_card_edges G
set U := Finset.univ.filter (fun v => 0 < G.degree v) with hU
have hcardU : (U.card : ℝ) ≤ 2 * m := by
have : U.card ≤ ∑ v, G.degree v := by
calc U.card = ∑ v ∈ U, 1 := by simp
_ ≤ ∑ v ∈ U, G.degree v := Finset.sum_le_sum (fun v hv => by
have : 0 < G.degree v := by simpa [hU] using hv
omega)
_ ≤ ∑ v, G.degree v := Finset.sum_le_sum_of_subset (Finset.subset_univ _)
rw [hdeg] at this
exact_mod_cast this
have hw : (0 : ℝ) ≤ (7 / 48 + ε) * m := by positivity
apply pw_extend G hw
by_cases hbig : N ≤ U.card
· apply hasPathwidth_mono (hN U.card hbig (inducedOnFin G U))
have hsum : ∑ i : Fin U.card, (inducedOnFin G U).degree i ≤ 2 * m := by
have : ∑ i : Fin U.card, (inducedOnFin G U).degree i ≤ ∑ v, G.degree v := by
calc ∑ i : Fin U.card, (inducedOnFin G U).degree i
≤ ∑ i : Fin U.card, G.degree (enumerate U i) :=
Finset.sum_le_sum (fun i _ => deg_induced_le G U i)
_ = ∑ v ∈ Finset.univ.map (enumerate U), G.degree v := by
rw [Finset.sum_map]
_ ≤ ∑ v, G.degree v := Finset.sum_le_sum_of_subset (Finset.subset_univ _)
omega
have hsumR : (∑ i : Fin U.card, ((inducedOnFin G U).degree i : ℝ)) ≤ 2 * m := by
exact_mod_cast hsum
have hdw : degreeWeight (inducedOnFin G U) thm4Coeff ≤ 7 / 48 * m := by
unfold degreeWeight
calc _ ≤ ∑ i : Fin U.card, 7 / 96 * (((inducedOnFin G U).degree i : ℕ) : ℝ) :=
Finset.sum_le_sum (fun i _ => coeff_le _)
_ = 7 / 96 * ∑ i : Fin U.card, (((inducedOnFin G U).degree i : ℕ) : ℝ) := by
rw [← Finset.mul_sum]
_ ≤ 7 / 96 * (2 * m) := by gcongr
_ = 7 / 48 * m := by ring
nlinarith
· push_neg at hbig
apply hasPathwidth_mono (trivial_pathwidth_bound (inducedOnFin G U))
have : (U.card : ℝ) ≤ N := by exact_mod_cast hbig.le
nlinarith
end T4
end CubicPathwidth
#print axioms CubicPathwidth.T4.cor5_s
Back to top