Skip to content

Commit d9da9e5

Browse files
feat(Combinatorics/SimpleGraph/Inversion): Möbius inversion between copy counts and induced copy counts
Adds the bijection `Copy.equivSigmaEmbedding`, the labelled forward count identity `copyCount_eq_sum_embeddingCount`, and its Möbius inverse `embeddingCount_eq_sum_signed_copyCount` over ℤ. The Möbius direction reduces via the order-equivalence `iccEquivPowersetEdgeFinsetSdiff` between `Icc G K` and the powerset of the edge difference to `Finset.sum_powerset_neg_one_pow_card`. Supporting `Copy.inducedShape` (the pullback `H.comap f.toEmbedding`) and the per-fiber bijection `Copy.fiberInducedShapeEquiv` are kept inline in this file rather than split out, since neither has a standalone consumer outside this Möbius decomposition. Co-authored-by: Malte Jackisch <45597826+MaltyBlanket@users.noreply.github.com>
1 parent fa6e3bb commit d9da9e5

2 files changed

Lines changed: 324 additions & 0 deletions

File tree

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3620,6 +3620,7 @@ public import Mathlib.Combinatorics.SimpleGraph.Hasse
36203620
public import Mathlib.Combinatorics.SimpleGraph.IncMatrix
36213621
public import Mathlib.Combinatorics.SimpleGraph.InducedCopy
36223622
public import Mathlib.Combinatorics.SimpleGraph.Init
3623+
public import Mathlib.Combinatorics.SimpleGraph.Inversion
36233624
public import Mathlib.Combinatorics.SimpleGraph.LapMatrix
36243625
public import Mathlib.Combinatorics.SimpleGraph.LineGraph
36253626
public import Mathlib.Combinatorics.SimpleGraph.Maps
Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
/-
2+
Copyright (c) 2026 Christoph Spiegel. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Christoph Spiegel
5+
-/
6+
module
7+
8+
public import Mathlib.Algebra.BigOperators.Field
9+
public import Mathlib.Combinatorics.SimpleGraph.Automorphism
10+
public import Mathlib.Combinatorics.SimpleGraph.Finite
11+
public import Mathlib.Data.Nat.Choose.Sum
12+
public import Mathlib.Data.Rat.Cast.Defs
13+
14+
/-!
15+
# Möbius inversion between copy counts and induced copy counts
16+
17+
For a guest graph `G : SimpleGraph V` and a host graph `H : SimpleGraph W` with finite
18+
vertex types, this file establishes the standard summation identity expressing the copy
19+
count `H.copyCount G` as a sum over supergraphs of `G` (on the same vertex type `V`) of
20+
induced copy counts `H.embeddingCount G'`, together with its Möbius inverse expressing
21+
`H.embeddingCount G` as a signed sum of `H.copyCount G'`.
22+
23+
Following the convention from `Mathlib/Combinatorics/SimpleGraph/Copy.lean` and
24+
`Mathlib/Combinatorics/SimpleGraph/InducedCopy.lean`, counting operations are host-first
25+
(`H.copyCount G`, `H.embeddingCount G`); types are guest-first (`Copy G H`, `Embedding G H`).
26+
27+
## Main declarations
28+
29+
* `SimpleGraph.Copy.inducedShape` — for `f : Copy G H`, the supergraph of `G` on `V`
30+
recording the induced adjacency on the image, transported back via `f.toEmbedding`.
31+
* `SimpleGraph.Copy.fiberInducedShapeEquiv` — the per-fiber bijection between copies with a
32+
prescribed induced shape and graph embeddings of that shape.
33+
* `SimpleGraph.Copy.equivSigmaEmbedding` — the load-bearing bijection
34+
`Copy G H ≃ Σ G' ∈ Icc G ⊤, Embedding G'.val H`.
35+
* `SimpleGraph.iccEquivPowersetEdgeFinsetSdiff` — for `G ≤ K`, the equivalence
36+
`Finset.Icc G K ≃ (K.edgeFinset \ G.edgeFinset).powerset` used to reduce the inner
37+
alternating sum to `Finset.sum_powerset_neg_one_pow_card`.
38+
39+
## Main results
40+
41+
* `SimpleGraph.copyCount_eq_sum_embeddingCount` — forward identity:
42+
`H.copyCount G = ∑ G' ∈ Icc G ⊤, H.embeddingCount G'`.
43+
* `SimpleGraph.embeddingCount_eq_sum_signed_copyCount` — Möbius inverse over `ℤ`:
44+
`(H.embeddingCount G : ℤ) = ∑ G' ∈ Icc G ⊤,
45+
(-1) ^ #(G'.edgeFinset \ G.edgeFinset) * (H.copyCount G' : ℤ)`.
46+
47+
## Implementation notes
48+
49+
The forward bijection `Copy.equivSigmaEmbedding` is the only "real" content; the Möbius
50+
direction reduces to it via the classical alternating-sum identity
51+
`Finset.sum_powerset_neg_one_pow_card`, reindexed through the order-isomorphism
52+
`G' ∈ Icc G ⊤ ↔ S ⊆ E(⊤) \ E(G)`.
53+
54+
The Möbius identity is stated in `ℤ` (rather than `ℕ`) because the signs are essential.
55+
56+
The `LocallyFiniteOrder (SimpleGraph V)` instance consumed by `Finset.Icc G ⊤` comes from
57+
`SimpleGraph.Finite.instLocallyFiniteOrder`, which requires `[DecidableLE (SimpleGraph V)]`.
58+
The declarations below routinely invoke `Classical.decRel _` since the bijection is already
59+
noncomputable.
60+
-/
61+
62+
public section
63+
64+
open Finset Function
65+
66+
namespace SimpleGraph
67+
68+
variable {V W : Type*}
69+
70+
/-! ### Induced shape of a copy
71+
72+
The pullback `H.comap f.toEmbedding` records the induced adjacency on the image of a copy
73+
`f : Copy G H`, transported back to `V`. It is always a supergraph of `G`, and pinning it
74+
down to a specific supergraph `G'` promotes the copy to an embedding `G' ↪g H`. -/
75+
76+
namespace Copy
77+
78+
variable {G G' : SimpleGraph V} {H : SimpleGraph W}
79+
80+
/-- The pullback of the host graph along the underlying injection of a copy. -/
81+
def inducedShape (f : Copy G H) : SimpleGraph V :=
82+
H.comap f.toEmbedding
83+
84+
@[simp] lemma inducedShape_adj (f : Copy G H) {a b : V} :
85+
f.inducedShape.Adj a b ↔ H.Adj (f a) (f b) := Iff.rfl
86+
87+
lemma le_inducedShape (f : Copy G H) : G ≤ f.inducedShape :=
88+
fun _ _ => f.toHom.map_adj
89+
90+
/-- A copy with induced shape `G'` promotes to a graph embedding `G' ↪g H`. -/
91+
@[expose] def toEmbeddingOfInducedShapeEq (f : Copy G H) (h : f.inducedShape = G') :
92+
G' ↪g H where
93+
toFun := f
94+
inj' := f.injective
95+
map_rel_iff' {a b} := by
96+
change H.Adj (f a) (f b) ↔ G'.Adj a b
97+
rw [← h, inducedShape_adj]
98+
99+
@[simp] lemma toEmbeddingOfInducedShapeEq_apply (f : Copy G H) (h : f.inducedShape = G')
100+
(v : V) : f.toEmbeddingOfInducedShapeEq h v = f v := rfl
101+
102+
/-- The fiber of `inducedShape` over a supergraph `G' ≥ G` is canonically `Embedding G' H`. -/
103+
def fiberInducedShapeEquiv (hGG' : G ≤ G') :
104+
{f : Copy G H // f.inducedShape = G'} ≃ Embedding G' H where
105+
toFun f := f.val.toEmbeddingOfInducedShapeEq f.prop
106+
invFun e := ⟨e.toCopy.comp (Copy.ofLE G G' hGG'), by ext a b; simp [inducedShape]⟩
107+
left_inv f := by apply Subtype.ext; ext v; simp
108+
right_inv e := by apply DFunLike.ext; intro v; simp
109+
110+
end Copy
111+
112+
@[simp] lemma Embedding.inducedShape_toCopy {G : SimpleGraph V} {H : SimpleGraph W}
113+
(e : Embedding G H) : e.toCopy.inducedShape = G := by
114+
ext a b; rw [Copy.inducedShape_adj]; exact e.map_rel_iff
115+
116+
/-! ### Forward bijection and count identity -/
117+
118+
section Forward
119+
120+
variable {G : SimpleGraph V} {H : SimpleGraph W}
121+
122+
/-- The load-bearing equivalence: a copy of `G` in `H` is the same data as a choice of
123+
supergraph `G' ∈ Icc G ⊤` (the induced shape) together with a graph embedding
124+
`G' ↪g H`. This expresses every copy uniquely as an induced copy of some shape `G'`
125+
between `G` and the complete graph.
126+
127+
The proof goes via the canonical fiber decomposition `Equiv.sigmaFiberEquiv` for the map
128+
`Copy.inducedShape`. The index `K : SimpleGraph V` is restricted to `Icc G ⊤`, which is
129+
exactly the set of shapes with nonempty fiber. The per-fiber bijection is
130+
`Copy.fiberInducedShapeEquiv`. -/
131+
noncomputable def Copy.equivSigmaEmbedding (G : SimpleGraph V) (H : SimpleGraph W)
132+
[Fintype V] [DecidableEq V] [DecidableLE (SimpleGraph V)] :
133+
Copy G H ≃ Σ G' : ↥(Finset.Icc G ⊤), Embedding G'.val H :=
134+
(Equiv.sigmaFiberEquiv (Copy.inducedShape : Copy G H → SimpleGraph V)).symm.trans <|
135+
{ toFun := fun ⟨K, f⟩ =>
136+
let hGK : G ≤ K := f.prop ▸ f.val.le_inducedShape
137+
⟨⟨K, Finset.mem_Icc.mpr ⟨hGK, le_top⟩⟩,
138+
Copy.fiberInducedShapeEquiv hGK f⟩
139+
invFun := fun ⟨⟨K, hK⟩, e⟩ =>
140+
⟨K, (Copy.fiberInducedShapeEquiv (Finset.mem_Icc.mp hK).1).symm e⟩
141+
left_inv := by
142+
rintro ⟨K, f⟩
143+
simp
144+
right_inv := by
145+
rintro ⟨⟨K, hK⟩, e⟩
146+
simp only [Equiv.apply_symm_apply] }
147+
148+
/-- Forward identity: every copy of `G` in `H` is an induced copy of some unique
149+
supergraph `G' ∈ Icc G ⊤` of `G`. -/
150+
theorem copyCount_eq_sum_embeddingCount [Fintype V] [DecidableEq V]
151+
[DecidableLE (SimpleGraph V)] [Finite W] (G : SimpleGraph V) (H : SimpleGraph W) :
152+
H.copyCount G = ∑ G' ∈ Finset.Icc G ⊤, H.embeddingCount G' := by
153+
rw [copyCount_eq_nat_card, Nat.card_congr (Copy.equivSigmaEmbedding G H), Nat.card_sigma,
154+
← Finset.sum_attach (Finset.Icc G ⊤) (fun G' => H.embeddingCount G')]
155+
refine Finset.sum_congr rfl fun G' _ => ?_
156+
exact (embeddingCount_eq_nat_card _ _).symm
157+
158+
end Forward
159+
160+
/-! ### Möbius (signed-sum) inverse
161+
162+
The Möbius inverse to the forward identity, expressing `H.embeddingCount G` as a signed
163+
sum of `H.copyCount G'` over supergraphs `G' ∈ Icc G ⊤`. The proof reduces, via the
164+
order-isomorphism `iccEquivPowersetEdgeFinsetSdiff` below, to the alternating-sum
165+
identity `Finset.sum_powerset_neg_one_pow_card`.
166+
-/
167+
168+
section Mobius
169+
170+
open Classical in
171+
/-- Order-isomorphism between the closed interval `Finset.Icc G K` of graphs and the
172+
powerset of the edge difference `K.edgeFinset \ G.edgeFinset`, valid when `G ≤ K`.
173+
174+
The forward map sends a graph `G'` with `G ≤ G' ≤ K` to its "extra edges over `G`",
175+
namely `G'.edgeFinset \ G.edgeFinset`. The inverse sends a subset `S` of "missing edges
176+
of `G` inside `K`" to the graph whose edge set is `G.edgeFinset ∪ S`, constructed via
177+
`fromEdgeSet`. -/
178+
noncomputable def iccEquivPowersetEdgeFinsetSdiff [Fintype V] [DecidableEq V]
179+
[DecidableLE (SimpleGraph V)] {G K : SimpleGraph V} (hGK : G ≤ K) :
180+
↥(Finset.Icc G K) ≃ ↥(K.edgeFinset \ G.edgeFinset).powerset where
181+
toFun G' :=
182+
⟨G'.val.edgeFinset \ G.edgeFinset, by
183+
simp only [Finset.mem_powerset]
184+
exact Finset.sdiff_subset_sdiff (edgeFinset_mono (Finset.mem_Icc.mp G'.prop).2)
185+
Finset.Subset.rfl⟩
186+
invFun S :=
187+
⟨fromEdgeSet ((G.edgeFinset : Set (Sym2 V)) ∪ S.val), by
188+
have hSK : S.val ⊆ K.edgeFinset \ G.edgeFinset := Finset.mem_powerset.mp S.prop
189+
refine Finset.mem_Icc.mpr ⟨fun a b hab => ?_, ?_⟩
190+
· exact (fromEdgeSet_adj _).mpr ⟨.inl (mem_coe.mpr <| mem_edgeFinset.mpr hab), hab.ne⟩
191+
· rw [fromEdgeSet_le]
192+
rintro e ⟨heGS | heGS, _⟩
193+
· exact edgeSet_subset_edgeSet.mpr hGK (mem_edgeFinset.mp heGS)
194+
· exact mem_edgeFinset.mp (Finset.mem_sdiff.mp (hSK heGS)).1
195+
left_inv := by
196+
rintro ⟨G', hG'⟩
197+
have hGG' : G ≤ G' := (Finset.mem_Icc.mp hG').1
198+
apply Subtype.ext
199+
ext a b
200+
simp only [fromEdgeSet_adj, Set.mem_union, mem_coe, mem_edgeFinset, Finset.coe_sdiff,
201+
Set.mem_diff]
202+
refine ⟨fun ⟨h, _⟩ => h.elim (hGG' ·) (·.1), fun h => ⟨?_, h.ne⟩⟩
203+
by_cases hG : G.Adj a b
204+
· exact .inl hG
205+
· exact .inr ⟨h, hG⟩
206+
right_inv := by
207+
rintro ⟨S, hS⟩
208+
have hSK : S ⊆ K.edgeFinset \ G.edgeFinset := Finset.mem_powerset.mp hS
209+
apply Subtype.ext
210+
ext e
211+
simp only [Finset.mem_sdiff, mem_edgeFinset, edgeSet_fromEdgeSet, Set.mem_diff,
212+
Set.mem_union, mem_coe]
213+
refine ⟨?_, fun heS => ?_⟩
214+
· rintro ⟨⟨h | h, _⟩, heG⟩
215+
· exact absurd h heG
216+
· exact h
217+
· have heKsd := Finset.mem_sdiff.mp (hSK heS)
218+
refine ⟨⟨.inr heS, fun hd =>
219+
K.not_isDiag_of_mem_edgeSet (mem_edgeFinset.mp heKsd.1) hd⟩, ?_⟩
220+
exact fun heG => heKsd.2 (mem_edgeFinset.mpr heG)
221+
222+
open Classical in
223+
/-- The combinatorial kernel of Möbius inversion at the graph level: the alternating sum of
224+
`(-1) ^ #(K' \ G)` over `K'` in a closed interval `[G, L]` collapses to `1` when `L = G` and
225+
`0` otherwise. Reindexes via `iccEquivPowersetEdgeFinsetSdiff` to
226+
`Finset.sum_powerset_neg_one_pow_card`. -/
227+
private theorem sum_Icc_neg_one_pow_card_edgeFinset_sdiff_eq_ite
228+
[Fintype V] [DecidableEq V] [DecidableLE (SimpleGraph V)]
229+
{G L : SimpleGraph V} (hGL : G ≤ L) :
230+
∑ K' ∈ Finset.Icc G L, (-1 : ℤ) ^ #(K'.edgeFinset \ G.edgeFinset)
231+
= if L = G then 1 else 0 := by
232+
have key : ∑ K' ∈ Finset.Icc G L, (-1 : ℤ) ^ #(K'.edgeFinset \ G.edgeFinset)
233+
= ∑ S ∈ (L.edgeFinset \ G.edgeFinset).powerset, (-1 : ℤ) ^ #S := by
234+
rw [← Finset.sum_attach (Finset.Icc G L)
235+
(fun K' => (-1 : ℤ) ^ #(K'.edgeFinset \ G.edgeFinset)),
236+
← Finset.sum_attach (L.edgeFinset \ G.edgeFinset).powerset
237+
(fun S => (-1 : ℤ) ^ #S)]
238+
exact Finset.sum_equiv (iccEquivPowersetEdgeFinsetSdiff hGL)
239+
(fun _ => by simp) (fun _ _ => rfl)
240+
rw [key, Finset.sum_powerset_neg_one_pow_card]
241+
obtain rfl | hLG := eq_or_ne L G
242+
· simp
243+
· rw [if_neg, if_neg hLG]
244+
intro hempty
245+
apply hLG
246+
have hsub : L ≤ G := by
247+
simpa [Finset.sdiff_eq_empty_iff_subset, edgeFinset_subset_edgeFinset] using hempty
248+
exact le_antisymm hsub hGL
249+
250+
open Classical in
251+
/-- The Möbius (signed-sum) inverse to `copyCount_eq_sum_embeddingCount`: the induced
252+
copy count is recovered as an alternating sum of copy counts indexed by supergraphs
253+
`G' ∈ Icc G ⊤`, with sign `(-1) ^ #(G'.edgeFinset \ G.edgeFinset)`. -/
254+
theorem embeddingCount_eq_sum_signed_copyCount [Fintype V] [DecidableEq V]
255+
[DecidableLE (SimpleGraph V)] [Finite W] (G : SimpleGraph V) (H : SimpleGraph W) :
256+
(H.embeddingCount G : ℤ) =
257+
∑ G' ∈ Finset.Icc G ⊤,
258+
(-1 : ℤ) ^ #(G'.edgeFinset \ G.edgeFinset) * (H.copyCount G' : ℤ) := by
259+
symm
260+
calc ∑ G' ∈ Finset.Icc G ⊤,
261+
(-1 : ℤ) ^ #(G'.edgeFinset \ G.edgeFinset) * (H.copyCount G' : ℤ)
262+
-- Substitute the forward identity into each summand.
263+
= ∑ G' ∈ Finset.Icc G ⊤, ∑ L ∈ Finset.Icc G' ⊤,
264+
(-1 : ℤ) ^ #(G'.edgeFinset \ G.edgeFinset) * (H.embeddingCount L : ℤ) := by
265+
simp_rw [copyCount_eq_sum_embeddingCount, Nat.cast_sum, Finset.mul_sum]
266+
-- Swap the order of summation over the triangle `G ≤ G' ≤ L ≤ ⊤`.
267+
_ = ∑ L ∈ Finset.Icc G ⊤, ∑ G' ∈ Finset.Icc G L,
268+
(-1 : ℤ) ^ #(G'.edgeFinset \ G.edgeFinset) * (H.embeddingCount L : ℤ) := by
269+
rw [Finset.sum_comm' (s := Finset.Icc G (⊤ : SimpleGraph V))
270+
(t := fun G' => Finset.Icc G' ⊤)
271+
(s' := fun L => Finset.Icc G L) (t' := Finset.Icc G (⊤ : SimpleGraph V))
272+
(h := fun G' L => by
273+
simp only [Finset.mem_Icc]
274+
exact ⟨fun ⟨⟨hGG', _⟩, hG'L, _⟩ => ⟨⟨hGG', hG'L⟩, hGG'.trans hG'L, le_top⟩,
275+
fun ⟨⟨hGG', hG'L⟩, _⟩ => ⟨⟨hGG', le_top⟩, hG'L, le_top⟩⟩)]
276+
-- Factor `H.embeddingCount L` out of the inner sum.
277+
_ = ∑ L ∈ Finset.Icc G ⊤, (H.embeddingCount L : ℤ) *
278+
∑ G' ∈ Finset.Icc G L, (-1 : ℤ) ^ #(G'.edgeFinset \ G.edgeFinset) := by
279+
simp_rw [mul_comm ((-1 : ℤ) ^ _) ((H.embeddingCount _ : ℤ)), ← Finset.mul_sum]
280+
-- Inner sum collapses to `δ_{L = G}` by the kernel lemma.
281+
_ = ∑ L ∈ Finset.Icc G ⊤, (H.embeddingCount L : ℤ) * (if L = G then 1 else 0) := by
282+
refine Finset.sum_congr rfl fun L hL => ?_
283+
rw [sum_Icc_neg_one_pow_card_edgeFinset_sdiff_eq_ite (Finset.mem_Icc.mp hL).1]
284+
-- Only the `L = G` term survives.
285+
_ = (H.embeddingCount G : ℤ) := by
286+
simp_rw [mul_ite, mul_one, mul_zero]
287+
rw [Finset.sum_ite_eq' (Finset.Icc G ⊤) G fun L => (H.embeddingCount L : ℤ),
288+
if_pos (Finset.mem_Icc.mpr ⟨le_refl _, le_top⟩)]
289+
290+
end Mobius
291+
292+
/-! ### Unlabelled variants
293+
294+
Substituting the orbit-stabiliser bridges from `Automorphism.lean`
295+
(`copyCount = unlabeledCopyCount * autCount` and the embedding analogue) into the labelled
296+
identities yields `autCount`-weighted forms on the unlabelled counts. -/
297+
298+
section Unlabelled
299+
300+
variable {G : SimpleGraph V} {H : SimpleGraph W}
301+
302+
theorem unlabeledCopyCount_mul_autCount_eq_sum [Fintype V] [DecidableEq V]
303+
[DecidableLE (SimpleGraph V)] [Finite W] (G : SimpleGraph V) (H : SimpleGraph W) :
304+
H.unlabeledCopyCount G * G.autCount =
305+
∑ G' ∈ Finset.Icc G ⊤, H.unlabeledEmbeddingCount G' * G'.autCount := by
306+
rw [← copyCount_eq_unlabeledCopyCount_mul_autCount, copyCount_eq_sum_embeddingCount]
307+
exact Finset.sum_congr rfl fun _ _ => embeddingCount_eq_unlabeledEmbeddingCount_mul_autCount
308+
309+
open Classical in
310+
theorem unlabeledEmbeddingCount_mul_autCount_eq_sum_signed [Fintype V] [DecidableEq V]
311+
[DecidableLE (SimpleGraph V)] [Finite W] (G : SimpleGraph V) (H : SimpleGraph W) :
312+
(H.unlabeledEmbeddingCount G * G.autCount : ℤ) =
313+
∑ G' ∈ Finset.Icc G ⊤,
314+
(-1 : ℤ) ^ #(G'.edgeFinset \ G.edgeFinset) *
315+
(H.unlabeledCopyCount G' * G'.autCount : ℤ) := by
316+
rw [← Nat.cast_mul, ← embeddingCount_eq_unlabeledEmbeddingCount_mul_autCount,
317+
embeddingCount_eq_sum_signed_copyCount]
318+
refine Finset.sum_congr rfl fun _ _ => ?_
319+
rw [copyCount_eq_unlabeledCopyCount_mul_autCount, Nat.cast_mul]
320+
321+
end Unlabelled
322+
323+
end SimpleGraph

0 commit comments

Comments
 (0)