CubicPathwidth.T2.Charging
Source file CubicPathwidth/T2/Charging.lean of the Lean project (how it is built).
import CubicPathwidth.T2.DefsB
/-!
# Charging along edges joining degrees 3 and 4 (Theorem 2(b),(c) plan, claim B3)
Proves `ChargingClaim`: under the per-type charging inequalities, the total charge
is at most `a₃ n₃ + a₄ n₄`. The transfer terms cancel by the double count of
edges joining a degree-3 vertex and a degree-4 vertex.
-/
noncomputable section
open scoped Classical
namespace CubicPathwidth
namespace T2
open Finset
/-- The number of neighbors of degree `d`, as a sum of adjacency indicators. -/
lemma nbrCount_cast_eq {n : ℕ} (G : SimpleGraph (Fin n)) (v : Fin n) (d : ℕ) :
(nbrCount G v d : ℝ) =
∑ u, if G.Adj v u ∧ G.degree u = d then (1 : ℝ) else 0 := by
classical
unfold nbrCount
rw [Finset.card_filter, Nat.cast_sum, SimpleGraph.neighborFinset_eq_filter,
Finset.sum_filter]
push_cast
refine Finset.sum_congr rfl fun u _ => ?_
by_cases h1 : G.Adj v u <;> by_cases h2 : G.degree u = d <;> simp [h1, h2]
/-- Double count: the edges joining a degree-3 and a degree-4 vertex are counted
the same way from both ends. -/
lemma edge_double_count {n : ℕ} (G : SimpleGraph (Fin n)) :
∑ v, (if G.degree v = 3 then (nbrCount G v 4 : ℝ) else 0) =
∑ u, (if G.degree u = 4 then (nbrCount G u 3 : ℝ) else 0) := by
classical
have hL : ∀ v : Fin n,
(if G.degree v = 3 then (nbrCount G v 4 : ℝ) else 0) =
∑ u, if G.degree v = 3 ∧ G.Adj v u ∧ G.degree u = 4 then (1 : ℝ) else 0 := by
intro v
rw [nbrCount_cast_eq]
split_ifs with h
· simp [h]
· simp [h]
have hR : ∀ u : Fin n,
(if G.degree u = 4 then (nbrCount G u 3 : ℝ) else 0) =
∑ v, if G.degree v = 3 ∧ G.Adj v u ∧ G.degree u = 4 then (1 : ℝ) else 0 := by
intro u
rw [nbrCount_cast_eq]
split_ifs with h
· refine Finset.sum_congr rfl fun v _ => ?_
simp only [h, and_true]
by_cases h1 : G.Adj v u
· have h1' := h1.symm
by_cases h2 : G.degree v = 3 <;> simp [h1, h1', h2]
· have h1' : ¬G.Adj u v := fun h' => h1 h'.symm
by_cases h2 : G.degree v = 3 <;> simp [h1, h1', h2]
· simp [h]
simp_rw [hL, hR]
exact Finset.sum_comm
/-- Each vertex of degree 3 or 4 is counted once: the number of vertices of degree
exactly `d` weighted by a constant. -/
lemma sum_ite_degree_const {n : ℕ} (G : SimpleGraph (Fin n)) (d : ℕ) (a : ℝ) :
∑ v, (if G.degree v = d then a else 0) = a * (degreeCount G d : ℝ) := by
unfold degreeCount
rw [Finset.sum_ite, Finset.sum_const_zero, add_zero, Finset.sum_const, nsmul_eq_mul]
ring
theorem charging : ChargingClaim := by
classical
unfold ChargingClaim
intro n G hmin hmax C a₃ a₄ t h3 h4
unfold MinDegreeAtLeast at hmin
unfold MaxDegreeAtMost at hmax
have hdeg : ∀ v : Fin n, G.degree v = 3 ∨ G.degree v = 4 := by
intro v
have h1 := hmin v
have h2 := hmax v
omega
have hpt : ∀ v : Fin n,
C v ≤ (if G.degree v = 3 then a₃ else 0) + (if G.degree v = 4 then a₄ else 0) +
t * ((if G.degree v = 3 then (nbrCount G v 4 : ℝ) else 0) -
(if G.degree v = 4 then (nbrCount G v 3 : ℝ) else 0)) := by
intro v
rcases hdeg v with h | h
· have := h3 v h
simp [h]
linarith
· have := h4 v h
simp [h]
linarith
calc ∑ v, C v
≤ ∑ v, ((if G.degree v = 3 then a₃ else 0) + (if G.degree v = 4 then a₄ else 0) +
t * ((if G.degree v = 3 then (nbrCount G v 4 : ℝ) else 0) -
(if G.degree v = 4 then (nbrCount G v 3 : ℝ) else 0))) :=
Finset.sum_le_sum fun v _ => hpt v
_ = (∑ v, (if G.degree v = 3 then a₃ else 0)) + (∑ v, (if G.degree v = 4 then a₄ else 0))
+ t * ((∑ v, (if G.degree v = 3 then (nbrCount G v 4 : ℝ) else 0)) -
(∑ v, (if G.degree v = 4 then (nbrCount G v 3 : ℝ) else 0))) := by
rw [Finset.sum_add_distrib, Finset.sum_add_distrib, ← Finset.mul_sum,
Finset.sum_sub_distrib]
_ = a₃ * (degreeCount G 3 : ℝ) + a₄ * (degreeCount G 4 : ℝ) := by
rw [sum_ite_degree_const, sum_ite_degree_const, edge_double_count, sub_self, mul_zero,
add_zero]
end T2
end CubicPathwidth
#print axioms CubicPathwidth.T2.charging
Back to top