Skip to content

Commit 5ef6397

Browse files
feat(Combinatorics/SimpleGraph): define the Zarankiewicz function (leanprover-community#34633)
Defines the Zarankiewicz function $z(m, n; s, t)$ in terms of bipartite graphs.
1 parent a687aeb commit 5ef6397

3 files changed

Lines changed: 164 additions & 0 deletions

File tree

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3660,6 +3660,7 @@ public import Mathlib.Combinatorics.SimpleGraph.Extremal.Basic
36603660
public import Mathlib.Combinatorics.SimpleGraph.Extremal.ErdosStoneSimonovits
36613661
public import Mathlib.Combinatorics.SimpleGraph.Extremal.Turan
36623662
public import Mathlib.Combinatorics.SimpleGraph.Extremal.TuranDensity
3663+
public import Mathlib.Combinatorics.SimpleGraph.Extremal.Zarankiewicz
36633664
public import Mathlib.Combinatorics.SimpleGraph.Finite
36643665
public import Mathlib.Combinatorics.SimpleGraph.Finsubgraph
36653666
public import Mathlib.Combinatorics.SimpleGraph.FiveWheelLike
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/-
2+
Copyright (c) 2026 Mitchell Horner. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Mitchell Horner
5+
-/
6+
module
7+
8+
public import Mathlib.Algebra.Order.Floor.Semiring
9+
public import Mathlib.Combinatorics.SimpleGraph.Bipartite
10+
public import Mathlib.Combinatorics.SimpleGraph.Extremal.Basic
11+
public import Mathlib.Combinatorics.SimpleGraph.Maps
12+
13+
import Mathlib.Algebra.Order.Archimedean.Real.Basic
14+
import Mathlib.Logic.Equiv.Fin.Basic
15+
import Mathlib.Tactic.Rify
16+
17+
/-!
18+
# The Zarankiewicz function
19+
20+
This file defines the **Zarankiewicz function** in terms of bipartite graphs.
21+
-/
22+
23+
public section
24+
25+
open Finset Fintype
26+
27+
namespace SimpleGraph
28+
29+
/-- The **Zarankiewicz function** of natural numbers `m`, `n`, `s`, and `t` is the maximum
30+
number of edges in a `completeBipartiteGraph (Fin s) (Fin t)`-free bipartite graph with parts of
31+
size `m` and `n`.
32+
33+
This is the *extremal graph theory* version of the **Zarankiewicz function**. -/
34+
noncomputable def zarankiewicz (m n s t : ℕ) : ℕ :=
35+
open Classical in
36+
sup { G : SimpleGraph (Fin m ⊕ Fin n) | G ≤ completeBipartiteGraph (Fin m) (Fin n)
37+
∧ (completeBipartiteGraph (Fin s) (Fin t)).Free G} (#·.edgeFinset)
38+
39+
variable {m n s t : ℕ} {V W α β : Type*} [Fintype V] [Fintype W] [Fintype α] [Fintype β]
40+
41+
open Classical in
42+
theorem zarankiewicz_of_fintypeCard_eq
43+
(hm : card V = m) (hn : card W = n) (hs : card α = s) (ht : card β = t) :
44+
zarankiewicz m n s t =
45+
sup { G : SimpleGraph (V ⊕ W) | G ≤ completeBipartiteGraph V W
46+
∧ (completeBipartiteGraph α β).Free G} (#·.edgeFinset) := by
47+
let e₁ := completeBipartiteGraphCongr
48+
(Fintype.equivFinOfCardEq hm) (Fintype.equivFinOfCardEq hn)
49+
let K := completeBipartiteGraph (Fin s) (Fin t)
50+
let e₂ := completeBipartiteGraphCongr
51+
(Fintype.equivFinOfCardEq hs) (Fintype.equivFinOfCardEq ht)
52+
rw [zarankiewicz, le_antisymm_iff]
53+
and_intros
54+
on_goal 1 =>
55+
let e₁ := e₁.symm
56+
let K := completeBipartiteGraph α β
57+
let e₂ := e₂.symm
58+
all_goals
59+
simp_rw [Finset.sup_le_iff, mem_filter, mem_univ, true_and]
60+
intro G ⟨h_le, h_free⟩
61+
simp_rw [Iso.card_edgeFinset_eq (.map e₁.toEquiv G)]
62+
have h' : G.map e₁.toEquiv.toEmbedding ∈ univ.filter fun G ↦
63+
G ≤ completeBipartiteGraph _ _ ∧ K.Free G := by
64+
rw [mem_filter_univ, map_le_iff_le_comap]
65+
refine ⟨fun _ _ hadj ↦ ?_, ?_⟩
66+
· replace h_le := h_le hadj
67+
rw [← Embedding.map_adj_iff e₁.toEmbedding, ← comap_adj] at h_le
68+
exact h_le
69+
· rw [Function.Embedding.coeFn_mk, ← free_congr e₂ (.map e₁.toEquiv G)]
70+
exact h_free
71+
have h_le_sup := @le_sup _ _ _ _ _ (#·.edgeFinset) (G.map e₁.toEquiv.toEmbedding) h'
72+
simp_rw [← card_coe, mem_edgeFinset] at h_le_sup ⊢
73+
exact h_le_sup
74+
75+
/-- `zarankiewicz m n s t` is at most `x` if and only if every
76+
`completeBipartiteGraph α β`-free bipartite graph `G` has at most `x` edges. -/
77+
theorem zarankiewicz_le_iff
78+
(hm : card V = m) (hn : card W = n) (hs : card α = s) (ht : card β = t) (x : ℕ) :
79+
zarankiewicz m n s t ≤ x ↔
80+
∀ ⦃G : SimpleGraph (V ⊕ W)⦄ [DecidableRel G.Adj], G ≤ completeBipartiteGraph V W →
81+
(completeBipartiteGraph α β).Free G → #G.edgeFinset ≤ x := by
82+
simp_rw [zarankiewicz_of_fintypeCard_eq hm hn hs ht,
83+
Finset.sup_le_iff, mem_filter, mem_univ, true_and]
84+
exact ⟨fun h _ _ h_le h_free ↦ (h _ ⟨h_le, h_free⟩).trans_eq' <| by convert rfl,
85+
fun h _ ⟨h_le, h_free⟩ ↦ by convert h h_le h_free⟩
86+
87+
/-- `zarankiewicz m n s t` is greater than `x` if and only if there
88+
exists a `completeBipartiteGraph α β`-free bipartite graph `G` with more than `x` edges. -/
89+
theorem lt_zarankiewicz_iff
90+
(hm : card V = m) (hn : card W = n) (hs : card α = s) (ht : card β = t) (x : ℕ) :
91+
x < zarankiewicz m n s t ↔
92+
∃ G : SimpleGraph (V ⊕ W), ∃ _ : DecidableRel G.Adj, G ≤ completeBipartiteGraph V W ∧
93+
(completeBipartiteGraph α β).Free G ∧ x < #G.edgeFinset := by
94+
simp_rw [zarankiewicz_of_fintypeCard_eq hm hn hs ht,
95+
Finset.lt_sup_iff, mem_filter, mem_univ, true_and]
96+
exact ⟨fun ⟨_, ⟨h_le, h_free⟩, h_lt⟩ ↦ ⟨_, _, h_le, h_free, by convert h_lt⟩,
97+
fun ⟨_, _, ⟨h_le, h_free, h_lt⟩⟩ ↦ ⟨_, ⟨h_le, h_free⟩, h_lt.trans_eq <| by convert rfl⟩⟩
98+
99+
variable {R : Type*} [Semiring R] [LinearOrder R] [FloorSemiring R]
100+
101+
@[inherit_doc zarankiewicz_le_iff]
102+
theorem zarankiewicz_le_iff_of_nonneg
103+
(hm : card V = m) (hn : card W = n) (hs : card α = s) (ht : card β = t) {x : R} (h : 0 ≤ x) :
104+
zarankiewicz m n s t ≤ x ↔
105+
∀ ⦃G : SimpleGraph (V ⊕ W)⦄ [DecidableRel G.Adj], G ≤ completeBipartiteGraph V W →
106+
(completeBipartiteGraph α β).Free G → #G.edgeFinset ≤ x := by
107+
simp_rw [← Nat.le_floor_iff h]
108+
exact zarankiewicz_le_iff hm hn hs ht ⌊x⌋₊
109+
110+
@[inherit_doc lt_zarankiewicz_iff]
111+
theorem lt_zarankiewicz_iff_of_nonneg
112+
(hm : card V = m) (hn : card W = n) (hs : card α = s) (ht : card β = t) {x : R} (h : 0 ≤ x) :
113+
x < zarankiewicz m n s t ↔
114+
∃ G : SimpleGraph (V ⊕ W), ∃ _ : DecidableRel G.Adj, G ≤ completeBipartiteGraph V W ∧
115+
(completeBipartiteGraph α β).Free G ∧ x < #G.edgeFinset := by
116+
simp_rw [← Nat.floor_lt h]
117+
exact lt_zarankiewicz_iff hm hn hs ht ⌊x⌋₊
118+
119+
open Classical in
120+
/-- The Zarankiewicz function is at most the corresponding extremal number. -/
121+
theorem zarankiewicz_le_extremalNumber (hs : card α = s) (ht : card β = t) :
122+
zarankiewicz m n s t ≤ extremalNumber (m + n) (completeBipartiteGraph α β) := by
123+
conv =>
124+
enter [2, 1]
125+
rw [← Fintype.card_fin (m + n)]
126+
simp_rw [zarankiewicz, Finset.sup_le_iff, mem_filter, mem_univ, true_and]
127+
intro B ⟨_, h⟩
128+
rw [(Iso.map finSumFinEquiv B).card_edgeFinset_eq]
129+
refine card_edgeFinset_le_extremalNumber <|
130+
(h.congr_left ?_).congr_right (Iso.map finSumFinEquiv B).symm
131+
exact completeBipartiteGraphCongr
132+
(Fintype.equivFinOfCardEq hs) (Fintype.equivFinOfCardEq ht)
133+
134+
/-- The symmetric Zarankiewicz function is at least twice a corresponding extremal number. -/
135+
theorem two_mul_extremalNumber_le_zarankiewicz_symm
136+
[Nonempty α] [Nonempty β] (hs : card α = s) (ht : card β = t) :
137+
2 * extremalNumber n (completeBipartiteGraph α β) ≤ zarankiewicz n n s t := by
138+
conv =>
139+
enter [1, 2, 1]
140+
rw [← Fintype.card_fin n]
141+
rify
142+
rw [← le_div_iff₀' (by positivity), extremalNumber_le_iff_of_nonneg _ (by positivity)]
143+
intro G _ h
144+
rw [le_div_iff₀' (by positivity), ← Nat.cast_two, ← Nat.cast_mul, Nat.cast_le]
145+
apply Finset.le_sup_of_le (b := G.bipartiteDoubleCover)
146+
· simp_rw [mem_filter, mem_univ, true_and]
147+
refine ⟨bipartiteDoubleCover_le, ?_⟩
148+
contrapose! h
149+
refine completeBipartiteGraph_isContained_bipartiteDoubleCover.mp <|
150+
h.trans' ⟨Iso.toCopy ?_⟩
151+
exact completeBipartiteGraphCongr
152+
(Fintype.equivFinOfCardEq hs) (Fintype.equivFinOfCardEq ht)
153+
· convert card_edgeFinset_bipartiteDoubleCover.symm.le
154+
155+
end SimpleGraph

Mathlib/Combinatorics/SimpleGraph/Maps.lean

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,14 @@ def induceUnivIso (G : SimpleGraph V) : G.induce Set.univ ≃g G where
799799
map_rel_iff' := by simp only [Equiv.Set.univ, Equiv.coe_fn_mk, comap_adj, Embedding.coe_subtype,
800800
implies_true]
801801

802+
/-- The isomorphism between `completeBipartiteGraph V₁ W₁` and
803+
`completeBipartiteGraph V₂ W₂` where `V₁ ≃ V₂` and `W₁ ≃ W₂`. -/
804+
@[simps!]
805+
def completeBipartiteGraphCongr {V₁ V₂ W₁ W₂ : Type*} (hV : V₁ ≃ V₂) (hW : W₁ ≃ W₂) :
806+
completeBipartiteGraph V₁ W₁ ≃g completeBipartiteGraph V₂ W₂ where
807+
__ := hV.sumCongr hW
808+
map_rel_iff' := by simp
809+
802810
section Finite
803811

804812
variable [Fintype V] {n : ℕ}

0 commit comments

Comments
 (0)