@@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
44Authors: Jeremy Tan
55-/
66import Mathlib.Combinatorics.SimpleGraph.Clique
7+ import Mathlib.Combinatorics.SimpleGraph.DegreeSum
78import Mathlib.Order.Partition.Equipartition
89
910/-!
@@ -255,8 +256,7 @@ theorem card_parts [DecidableEq V] : #h.finpartition.parts = min (Fintype.card V
255256 have cf : G.CliqueFree r := by
256257 simp_rw [← cliqueFinset_eq_empty_iff, cliqueFinset, filter_eq_empty_iff, mem_univ,
257258 forall_true_left, isNClique_iff, and_comm, not_and, isClique_iff, Set.Pairwise]
258- #adaptation_note /-- 2025-07-19 added `-congrConsts` -/
259- intro z zc; push_neg; simp_rw -congrConsts [h.not_adj_iff_part_eq]
259+ intro z zc; push_neg; simp_rw [h.not_adj_iff_part_eq]
260260 exact exists_ne_map_eq_of_card_lt_of_maps_to (zc.symm ▸ l.2 ) fun a _ ↦
261261 fp.part_mem.2 (mem_univ a)
262262 use G ⊔ edge x y, inferInstance, cf.sup_edge x y
@@ -310,4 +310,110 @@ theorem isTuranMaximal_iff_nonempty_iso_turanGraph (hr : 0 < r) :
310310 G.IsTuranMaximal r ↔ Nonempty (G ≃g turanGraph (Fintype.card V) r) :=
311311 ⟨fun h ↦ h.nonempty_iso_turanGraph, fun h ↦ isTuranMaximal_of_iso h.some hr⟩
312312
313+ /-! ### Number of edges in the Turán graph -/
314+
315+ private lemma sum_ne_add_mod_eq_sub_one {c : ℕ} :
316+ ∑ w ∈ range r, (if c % r ≠ (n + w) % r then 1 else 0 ) = r - 1 := by
317+ rcases r.eq_zero_or_pos with rfl | hr; · simp
318+ suffices #{i ∈ range r | c % r = (n + i) % r} = 1 by
319+ rw [← card_filter, ← this]; apply Nat.eq_sub_of_add_eq'
320+ rw [filter_card_add_filter_neg_card_eq_card, card_range]
321+ apply le_antisymm
322+ · change #{i ∈ range r | _ ≡ _ [MOD r]} ≤ 1
323+ rw [card_le_one_iff]; intro w x mw mx
324+ simp only [mem_filter, mem_range] at mw mx
325+ have := mw.2 .symm.trans mx.2
326+ rw [Nat.ModEq.add_iff_left rfl] at this
327+ change w % r = x % r at this
328+ rwa [Nat.mod_eq_of_lt mw.1 , Nat.mod_eq_of_lt mx.1 ] at this
329+ · rw [one_le_card]; use ((r - 1 ) * n + c) % r
330+ simp only [mem_filter, mem_range]; refine ⟨Nat.mod_lt _ hr, ?_⟩
331+ rw [Nat.add_mod_mod, ← add_assoc, ← one_add_mul, show 1 + (r - 1 ) = r by omega,
332+ Nat.mul_add_mod_self_left]
333+
334+ lemma card_edgeFinset_turanGraph_add :
335+ #(turanGraph (n + r) r).edgeFinset =
336+ #(turanGraph n r).edgeFinset + n * (r - 1 ) + r.choose 2 := by
337+ rw [← mul_right_inj' two_ne_zero]
338+ simp_rw [mul_add, ← sum_degrees_eq_twice_card_edges,
339+ degree, neighborFinset_eq_filter, turanGraph, card_filter]
340+ conv_lhs =>
341+ enter [2 , v]
342+ rw [Fin.sum_univ_eq_sum_range fun w ↦ if v % r ≠ w % r then 1 else 0 , sum_range_add]
343+ rw [sum_add_distrib,
344+ Fin.sum_univ_eq_sum_range fun v ↦ ∑ w ∈ range n, if v % r ≠ w % r then 1 else 0 ,
345+ Fin.sum_univ_eq_sum_range fun v ↦ ∑ w ∈ range r, if v % r ≠ (n + w) % r then 1 else 0 ,
346+ sum_range_add, sum_range_add, add_assoc, add_assoc]
347+ congr 1 ; · simp [← Fin.sum_univ_eq_sum_range]
348+ rw [← add_assoc, sum_comm]; simp_rw [ne_comm, ← two_mul]; congr
349+ · conv_rhs => rw [← card_range n, ← smul_eq_mul, ← sum_const]
350+ congr!; exact sum_ne_add_mod_eq_sub_one
351+ · rw [mul_comm 2 , Nat.choose_two_right, Nat.div_two_mul_two_of_even (Nat.even_mul_pred_self r)]
352+ conv_rhs => enter [1 ]; rw [← card_range r]
353+ rw [← smul_eq_mul, ← sum_const]
354+ congr!; exact sum_ne_add_mod_eq_sub_one
355+
356+ /-- The exact formula for the number of edges in `turanGraph n r`. -/
357+ theorem card_edgeFinset_turanGraph {n r : ℕ} :
358+ #(turanGraph n r).edgeFinset =
359+ (n ^ 2 - (n % r) ^ 2 ) * (r - 1 ) / (2 * r) + (n % r).choose 2 := by
360+ rcases r.eq_zero_or_pos with rfl | hr
361+ · rw [Nat.mod_zero, tsub_self, zero_mul, Nat.zero_div, zero_add]
362+ have := card_edgeFinset_top_eq_card_choose_two (V := Fin n)
363+ rw [Fintype.card_fin] at this; convert this; exact turanGraph_zero
364+ · have ring₁ (n) : (n ^ 2 - (n % r) ^ 2 ) * (r - 1 ) / (2 * r) =
365+ n % r * (n / r) * (r - 1 ) + r * (r - 1 ) * (n / r) ^ 2 / 2 := by
366+ nth_rw 1 [← Nat.mod_add_div n r, Nat.sq_sub_sq, add_tsub_cancel_left,
367+ show (n % r + r * (n / r) + n % r) * (r * (n / r)) * (r - 1 ) =
368+ (2 * ((n % r) * (n / r) * (r - 1 )) + r * (r - 1 ) * (n / r) ^ 2 ) * r by grind]
369+ rw [Nat.mul_div_mul_right _ _ hr, Nat.mul_add_div zero_lt_two]
370+ rcases lt_or_ge n r with h | h
371+ · rw [Nat.mod_eq_of_lt h, tsub_self, zero_mul, Nat.zero_div, zero_add]
372+ have := card_edgeFinset_top_eq_card_choose_two (V := Fin n)
373+ rw [Fintype.card_fin] at this; convert this
374+ rw [turanGraph_eq_top]; exact .inr h.le
375+ · let n' := n - r
376+ have n'r : n = n' + r := by omega
377+ rw [n'r, card_edgeFinset_turanGraph_add, card_edgeFinset_turanGraph, ring₁, ring₁,
378+ add_rotate, ← add_assoc, Nat.add_mod_right, Nat.add_div_right _ hr]
379+ congr 1
380+ have rd : 2 ∣ r * (r - 1 ) := (Nat.even_mul_pred_self _).two_dvd
381+ rw [← Nat.div_mul_right_comm rd, ← Nat.div_mul_right_comm rd, ← Nat.choose_two_right]
382+ have ring₂ : n' % r * (n' / r + 1 ) * (r - 1 ) + r.choose 2 * (n' / r + 1 ) ^ 2 =
383+ n' % r * (n' / r + 1 ) * (r - 1 ) + r.choose 2 +
384+ r.choose 2 * 2 * (n' / r) + r.choose 2 * (n' / r) ^ 2 := by grind
385+ rw [ring₂, ← add_assoc]; congr 1
386+ rw [← add_rotate, ← add_rotate _ _ (r.choose 2 )]; congr 1
387+ rw [Nat.choose_two_right, Nat.div_mul_cancel rd, mul_add_one, add_mul, ← add_assoc,
388+ ← add_rotate, add_comm _ (_ *_)]; congr 1
389+ rw [← mul_rotate, ← add_mul, add_comm, mul_comm _ r, Nat.div_add_mod n' r]
390+
391+ /-- A looser (but simpler than `card_edgeFinset_turanGraph`) bound on the number of edges in
392+ `turanGraph n r`. -/
393+ theorem mul_card_edgeFinset_turanGraph_le :
394+ 2 * r * #(turanGraph n r).edgeFinset ≤ (r - 1 ) * n ^ 2 := by
395+ rw [card_edgeFinset_turanGraph, mul_add]
396+ apply (Nat.add_le_add_right (Nat.mul_div_le ..) _).trans
397+ rw [tsub_mul, ← Nat.sub_add_comm]; swap
398+ · exact mul_le_mul_right' (pow_le_pow_left' (Nat.mod_le ..) _) _
399+ rw [Nat.sub_le_iff_le_add, mul_comm, Nat.add_le_add_iff_left, Nat.choose_two_right,
400+ ← Nat.mul_div_assoc _ (Nat.even_mul_pred_self _).two_dvd, mul_assoc,
401+ mul_div_cancel_left₀ _ two_ne_zero, ← mul_assoc, ← mul_rotate, sq, ← mul_rotate (r - 1 )]
402+ refine mul_le_mul_right' ?_ _
403+ rcases r.eq_zero_or_pos with rfl | hr; · omega
404+ rw [Nat.sub_one_mul, Nat.sub_one_mul, mul_comm]
405+ exact Nat.sub_le_sub_left (Nat.mod_lt _ hr).le _
406+
407+ theorem CliqueFree.card_edgeFinset_le (cf : G.CliqueFree (r + 1 )) :
408+ let n := Fintype.card V;
409+ #G.edgeFinset ≤ (n ^ 2 - (n % r) ^ 2 ) * (r - 1 ) / (2 * r) + (n % r).choose 2 := by
410+ rcases r.eq_zero_or_pos with rfl | hr
411+ · rw [cliqueFree_one, ← Fintype.card_eq_zero_iff] at cf
412+ simp_rw [zero_tsub, mul_zero, Nat.mod_zero, Nat.div_zero, zero_add]
413+ exact card_edgeFinset_le_card_choose_two
414+ · obtain ⟨H, _, maxH⟩ := exists_isTuranMaximal (V := V) hr
415+ convert maxH.2 _ cf
416+ rw [((isTuranMaximal_iff_nonempty_iso_turanGraph hr).mp maxH).some.card_edgeFinset_eq,
417+ card_edgeFinset_turanGraph]
418+
313419end SimpleGraph
0 commit comments