Skip to content

Commit c1d469e

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 3ae9341 commit c1d469e

2 files changed

Lines changed: 324 additions & 0 deletions

File tree

Mathlib.lean

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3584,6 +3584,7 @@ public import Mathlib.Combinatorics.SetFamily.Shadow
35843584
public import Mathlib.Combinatorics.SetFamily.Shatter
35853585
public import Mathlib.Combinatorics.SimpleGraph.Acyclic
35863586
public import Mathlib.Combinatorics.SimpleGraph.AdjMatrix
3587+
public import Mathlib.Combinatorics.SimpleGraph.Automorphism
35873588
public import Mathlib.Combinatorics.SimpleGraph.Basic
35883589
public import Mathlib.Combinatorics.SimpleGraph.Bipartite
35893590
public import Mathlib.Combinatorics.SimpleGraph.Cayley
@@ -3619,6 +3620,7 @@ public import Mathlib.Combinatorics.SimpleGraph.Hasse
36193620
public import Mathlib.Combinatorics.SimpleGraph.IncMatrix
36203621
public import Mathlib.Combinatorics.SimpleGraph.InducedCopy
36213622
public import Mathlib.Combinatorics.SimpleGraph.Init
3623+
public import Mathlib.Combinatorics.SimpleGraph.Inversion
36223624
public import Mathlib.Combinatorics.SimpleGraph.LapMatrix
36233625
public import Mathlib.Combinatorics.SimpleGraph.LineGraph
36243626
public import Mathlib.Combinatorics.SimpleGraph.Maps
Lines changed: 322 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
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.Combinatorics.SimpleGraph.Finite
9+
public import Mathlib.Combinatorics.SimpleGraph.InducedCopy
10+
public import Mathlib.Data.Nat.Choose.Sum
11+
12+
/-!
13+
# Möbius inversion between copy counts and induced copy counts
14+
15+
For a guest graph `G : SimpleGraph V` and a host graph `H : SimpleGraph W` with finite
16+
vertex types, this file establishes the standard summation identity expressing the copy
17+
count `H.copyCount G` as a sum over supergraphs of `G` (on the same vertex type `V`) of
18+
induced copy counts `H.embeddingCount G'`, together with its Möbius inverse expressing
19+
`H.embeddingCount G` as a signed sum of `H.copyCount G'`.
20+
21+
Following the convention from `Mathlib/Combinatorics/SimpleGraph/Copy.lean` and
22+
`Mathlib/Combinatorics/SimpleGraph/InducedCopy.lean`, counting operations are host-first
23+
(`H.copyCount G`, `H.embeddingCount G`); types are guest-first (`Copy G H`, `Embedding G H`).
24+
25+
## Main declarations
26+
27+
* `SimpleGraph.Copy.inducedShape` — for `f : Copy G H`, the supergraph of `G` on `V`
28+
recording the induced adjacency on the image, transported back via `f.toEmbedding`.
29+
* `SimpleGraph.Copy.fiberInducedShapeEquiv` — the per-fiber bijection between copies with a
30+
prescribed induced shape and graph embeddings of that shape.
31+
* `SimpleGraph.Copy.equivSigmaEmbedding` — the load-bearing bijection
32+
`Copy G H ≃ Σ G' ∈ Icc G ⊤, Embedding G'.val H`.
33+
* `SimpleGraph.iccEquivPowersetEdgeFinsetSdiff` — for `G ≤ K`, the equivalence
34+
`Finset.Icc G K ≃ (K.edgeFinset \ G.edgeFinset).powerset` used to reduce the inner
35+
alternating sum to `Finset.sum_powerset_neg_one_pow_card`.
36+
37+
## Main results
38+
39+
* `SimpleGraph.copyCount_eq_sum_embeddingCount` — forward identity:
40+
`H.copyCount G = ∑ G' ∈ Icc G ⊤, H.embeddingCount G'`.
41+
* `SimpleGraph.embeddingCount_eq_sum_signed_copyCount` — Möbius inverse over `ℤ`:
42+
`(H.embeddingCount G : ℤ) = (-1) ^ Nat.card G.edgeSet *
43+
∑ G' ∈ Icc G ⊤, (-1) ^ Nat.card G'.edgeSet * (H.copyCount G' : ℤ)`.
44+
45+
## Implementation notes
46+
47+
The forward bijection `Copy.equivSigmaEmbedding` is the only "real" content; the Möbius
48+
direction reduces to it via the classical alternating-sum identity
49+
`Finset.sum_powerset_neg_one_pow_card`, reindexed through the order-isomorphism
50+
`G' ∈ Icc G ⊤ ↔ S ⊆ E(⊤) \ E(G)`.
51+
52+
The Möbius identity is stated in `ℤ` (rather than `ℕ`) because the signs are essential.
53+
The user-facing form uses `Nat.card G.edgeSet` rather than `#(G'.edgeFinset \ G.edgeFinset)`
54+
in the sign exponent: equivalent under `G ≤ G'` by parity, but `Nat.card` has no per-graph
55+
`Fintype` hypothesis, keeping the theorem signature free of `Classical`.
56+
57+
The `LocallyFiniteOrder (SimpleGraph V)` instance consumed by `Finset.Icc G ⊤` comes from
58+
`SimpleGraph.Finite.instLocallyFiniteOrder`, which requires `[DecidableLE (SimpleGraph V)]`.
59+
-/
60+
61+
public section
62+
63+
open Finset Function
64+
65+
namespace SimpleGraph
66+
67+
variable {V W : Type*}
68+
69+
/-! ### Induced shape of a copy
70+
71+
The pullback `H.comap f.toEmbedding` records the induced adjacency on the image of a copy
72+
`f : Copy G H`, transported back to `V`. It is always a supergraph of `G`, and pinning it
73+
down to a specific supergraph `G'` promotes the copy to an embedding `G' ↪g H`. -/
74+
75+
namespace Copy
76+
77+
variable {G G' : SimpleGraph V} {H : SimpleGraph W}
78+
79+
/-- The pullback of the host graph along the underlying injection of a copy. -/
80+
def inducedShape (f : Copy G H) : SimpleGraph V :=
81+
H.comap f.toEmbedding
82+
83+
@[simp] lemma inducedShape_adj (f : Copy G H) {a b : V} :
84+
f.inducedShape.Adj a b ↔ H.Adj (f a) (f b) := Iff.rfl
85+
86+
lemma le_inducedShape (f : Copy G H) : G ≤ f.inducedShape :=
87+
fun _ _ => f.toHom.map_adj
88+
89+
/-- A copy with induced shape `G'` promotes to a graph embedding `G' ↪g H`. -/
90+
@[expose] def toEmbeddingOfInducedShapeEq (f : Copy G H) (h : f.inducedShape = G') :
91+
G' ↪g H where
92+
toFun := f
93+
inj' := f.injective
94+
map_rel_iff' {a b} := by
95+
change H.Adj (f a) (f b) ↔ G'.Adj a b
96+
rw [← h, inducedShape_adj]
97+
98+
@[simp] lemma toEmbeddingOfInducedShapeEq_apply (f : Copy G H) (h : f.inducedShape = G')
99+
(v : V) : f.toEmbeddingOfInducedShapeEq h v = f v := rfl
100+
101+
/-- The fiber of `inducedShape` over a supergraph `G' ≥ G` is canonically `Embedding G' H`. -/
102+
def fiberInducedShapeEquiv (hGG' : G ≤ G') :
103+
{f : Copy G H // f.inducedShape = G'} ≃ Embedding G' H where
104+
toFun f := f.val.toEmbeddingOfInducedShapeEq f.prop
105+
invFun e := ⟨e.toCopy.comp (Copy.ofLE G G' hGG'), by ext a b; simp [inducedShape]⟩
106+
left_inv f := by apply Subtype.ext; ext v; simp
107+
right_inv e := by apply DFunLike.ext; intro v; simp
108+
109+
end Copy
110+
111+
@[simp] lemma Embedding.inducedShape_toCopy {G : SimpleGraph V} {H : SimpleGraph W}
112+
(e : Embedding G H) : e.toCopy.inducedShape = G := by
113+
ext a b; rw [Copy.inducedShape_adj]; exact e.map_rel_iff
114+
115+
/-! ### Forward bijection and count identity -/
116+
117+
section Forward
118+
119+
variable {G : SimpleGraph V} {H : SimpleGraph W}
120+
121+
/-- The load-bearing equivalence: a copy of `G` in `H` is the same data as a choice of
122+
supergraph `G' ∈ Icc G ⊤` (the induced shape) together with a graph embedding
123+
`G' ↪g H`. This expresses every copy uniquely as an induced copy of some shape `G'`
124+
between `G` and the complete graph.
125+
126+
The proof goes via the canonical fiber decomposition `Equiv.sigmaFiberEquiv` for the map
127+
`Copy.inducedShape`. The index `K : SimpleGraph V` is restricted to `Icc G ⊤`, which is
128+
exactly the set of shapes with nonempty fiber. The per-fiber bijection is
129+
`Copy.fiberInducedShapeEquiv`. -/
130+
noncomputable def Copy.equivSigmaEmbedding (G : SimpleGraph V) (H : SimpleGraph W)
131+
[Fintype V] [DecidableEq V] [DecidableLE (SimpleGraph V)] :
132+
Copy G H ≃ Σ G' : ↥(Finset.Icc G ⊤), Embedding G'.val H :=
133+
(Equiv.sigmaFiberEquiv (Copy.inducedShape : Copy G H → SimpleGraph V)).symm.trans <|
134+
{ toFun := fun ⟨K, f⟩ =>
135+
let hGK : G ≤ K := f.prop ▸ f.val.le_inducedShape
136+
⟨⟨K, Finset.mem_Icc.mpr ⟨hGK, le_top⟩⟩,
137+
Copy.fiberInducedShapeEquiv hGK f⟩
138+
invFun := fun ⟨⟨K, hK⟩, e⟩ =>
139+
⟨K, (Copy.fiberInducedShapeEquiv (Finset.mem_Icc.mp hK).1).symm e⟩
140+
left_inv := by
141+
rintro ⟨K, f⟩
142+
simp
143+
right_inv := by
144+
rintro ⟨⟨K, hK⟩, e⟩
145+
simp only [Equiv.apply_symm_apply] }
146+
147+
/-- Forward identity: every copy of `G` in `H` is an induced copy of some unique
148+
supergraph `G' ∈ Icc G ⊤` of `G`. -/
149+
theorem copyCount_eq_sum_embeddingCount [Fintype V] [DecidableEq V]
150+
[DecidableLE (SimpleGraph V)] [Finite W] (G : SimpleGraph V) (H : SimpleGraph W) :
151+
H.copyCount G = ∑ G' ∈ Finset.Icc G ⊤, H.embeddingCount G' := by
152+
rw [copyCount_eq_nat_card, Nat.card_congr (Copy.equivSigmaEmbedding G H), Nat.card_sigma,
153+
← Finset.sum_attach (Finset.Icc G ⊤) (fun G' => H.embeddingCount G')]
154+
refine Finset.sum_congr rfl fun G' _ => ?_
155+
exact (embeddingCount_eq_nat_card _ _).symm
156+
157+
end Forward
158+
159+
/-! ### Möbius (signed-sum) inverse
160+
161+
The Möbius inverse to the forward identity, expressing `H.embeddingCount G` as a signed
162+
sum of `H.copyCount G'` over supergraphs `G' ∈ Icc G ⊤`. The proof reduces, via the
163+
order-isomorphism `iccEquivPowersetEdgeFinsetSdiff` below, to the alternating-sum
164+
identity `Finset.sum_powerset_neg_one_pow_card`.
165+
-/
166+
167+
section Mobius
168+
169+
attribute [local instance 0] Classical.decRel
170+
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+
/-- The combinatorial kernel of Möbius inversion at the graph level: the alternating sum of
223+
`(-1) ^ #(K' \ G)` over `K'` in a closed interval `[G, L]` collapses to `1` when `L = G` and
224+
`0` otherwise. Reindexes via `iccEquivPowersetEdgeFinsetSdiff` to
225+
`Finset.sum_powerset_neg_one_pow_card`. -/
226+
private theorem sum_Icc_neg_one_pow_card_edgeFinset_sdiff_eq_ite
227+
[Fintype V] [DecidableEq V] [DecidableLE (SimpleGraph V)]
228+
{G L : SimpleGraph V} (hGL : G ≤ L) :
229+
∑ K' ∈ Finset.Icc G L, (-1 : ℤ) ^ #(K'.edgeFinset \ G.edgeFinset)
230+
= if L = G then 1 else 0 := by
231+
have key : ∑ K' ∈ Finset.Icc G L, (-1 : ℤ) ^ #(K'.edgeFinset \ G.edgeFinset)
232+
= ∑ S ∈ (L.edgeFinset \ G.edgeFinset).powerset, (-1 : ℤ) ^ #S := by
233+
rw [← Finset.sum_attach (Finset.Icc G L)
234+
(fun K' => (-1 : ℤ) ^ #(K'.edgeFinset \ G.edgeFinset)),
235+
← Finset.sum_attach (L.edgeFinset \ G.edgeFinset).powerset
236+
(fun S => (-1 : ℤ) ^ #S)]
237+
exact Finset.sum_equiv (iccEquivPowersetEdgeFinsetSdiff hGL)
238+
(fun _ => by simp) (fun _ _ => rfl)
239+
rw [key, Finset.sum_powerset_neg_one_pow_card]
240+
obtain rfl | hLG := eq_or_ne L G
241+
· simp
242+
· rw [if_neg, if_neg hLG]
243+
intro hempty
244+
apply hLG
245+
have hsub : L ≤ G := by
246+
simpa [Finset.sdiff_eq_empty_iff_subset, edgeFinset_subset_edgeFinset] using hempty
247+
exact le_antisymm hsub hGL
248+
249+
/-- Auxiliary form of the Möbius inverse with sign `(-1) ^ #(G'.edgeFinset \ G.edgeFinset)`.
250+
The user-facing version `embeddingCount_eq_sum_signed_copyCount` factors the sign through
251+
`Nat.card G.edgeSet * Nat.card G'.edgeSet`, eliminating per-graph `Fintype` hypotheses from
252+
the signature. -/
253+
private theorem embeddingCount_eq_sum_signed_copyCount_aux [Fintype V] [DecidableEq V]
254+
[DecidableLE (SimpleGraph V)] [Finite W] (G : SimpleGraph V) (H : SimpleGraph W) :
255+
(H.embeddingCount G : ℤ) =
256+
∑ G' ∈ Finset.Icc G ⊤,
257+
(-1 : ℤ) ^ #(G'.edgeFinset \ G.edgeFinset) * (H.copyCount G' : ℤ) := by
258+
symm
259+
calc ∑ G' ∈ Finset.Icc G ⊤,
260+
(-1 : ℤ) ^ #(G'.edgeFinset \ G.edgeFinset) * (H.copyCount G' : ℤ)
261+
-- Substitute the forward identity into each summand.
262+
= ∑ G' ∈ Finset.Icc G ⊤, ∑ L ∈ Finset.Icc G' ⊤,
263+
(-1 : ℤ) ^ #(G'.edgeFinset \ G.edgeFinset) * (H.embeddingCount L : ℤ) := by
264+
simp_rw [copyCount_eq_sum_embeddingCount, Nat.cast_sum, Finset.mul_sum]
265+
-- Swap the order of summation over the triangle `G ≤ G' ≤ L ≤ ⊤`.
266+
_ = ∑ L ∈ Finset.Icc G ⊤, ∑ G' ∈ Finset.Icc G L,
267+
(-1 : ℤ) ^ #(G'.edgeFinset \ G.edgeFinset) * (H.embeddingCount L : ℤ) := by
268+
rw [Finset.sum_comm' (s := Finset.Icc G (⊤ : SimpleGraph V))
269+
(t := fun G' => Finset.Icc G' ⊤)
270+
(s' := fun L => Finset.Icc G L) (t' := Finset.Icc G (⊤ : SimpleGraph V))
271+
(h := fun G' L => by
272+
simp only [Finset.mem_Icc]
273+
exact ⟨fun ⟨⟨hGG', _⟩, hG'L, _⟩ => ⟨⟨hGG', hG'L⟩, hGG'.trans hG'L, le_top⟩,
274+
fun ⟨⟨hGG', hG'L⟩, _⟩ => ⟨⟨hGG', le_top⟩, hG'L, le_top⟩⟩)]
275+
-- Factor `H.embeddingCount L` out of the inner sum.
276+
_ = ∑ L ∈ Finset.Icc G ⊤, (H.embeddingCount L : ℤ) *
277+
∑ G' ∈ Finset.Icc G L, (-1 : ℤ) ^ #(G'.edgeFinset \ G.edgeFinset) := by
278+
simp_rw [mul_comm ((-1 : ℤ) ^ _) ((H.embeddingCount _ : ℤ)), ← Finset.mul_sum]
279+
-- Inner sum collapses to `δ_{L = G}` by the kernel lemma.
280+
_ = ∑ L ∈ Finset.Icc G ⊤, (H.embeddingCount L : ℤ) * (if L = G then 1 else 0) := by
281+
refine Finset.sum_congr rfl fun L hL => ?_
282+
rw [sum_Icc_neg_one_pow_card_edgeFinset_sdiff_eq_ite (Finset.mem_Icc.mp hL).1]
283+
-- Only the `L = G` term survives.
284+
_ = (H.embeddingCount G : ℤ) := by
285+
simp_rw [mul_ite, mul_one, mul_zero]
286+
rw [Finset.sum_ite_eq' (Finset.Icc G ⊤) G fun L => (H.embeddingCount L : ℤ),
287+
if_pos (Finset.mem_Icc.mpr ⟨le_refl _, le_top⟩)]
288+
289+
/-- Sign factorization: under `G ≤ G'`, the parity of `#(G'.edgeFinset \ G.edgeFinset)`
290+
equals the sum of the parities of `Nat.card G.edgeSet` and `Nat.card G'.edgeSet`. -/
291+
private lemma neg_one_pow_card_edgeFinset_sdiff [Fintype V] [DecidableEq V]
292+
{G G' : SimpleGraph V} (hGG' : G ≤ G') :
293+
(-1 : ℤ) ^ #(G'.edgeFinset \ G.edgeFinset)
294+
= (-1 : ℤ) ^ Nat.card G.edgeSet * (-1 : ℤ) ^ Nat.card G'.edgeSet := by
295+
rw [show Nat.card G.edgeSet = #G.edgeFinset from
296+
Nat.card_eq_fintype_card.trans G.card_edgeSet,
297+
show Nat.card G'.edgeSet = #G'.edgeFinset from
298+
Nat.card_eq_fintype_card.trans G'.card_edgeSet,
299+
show #G'.edgeFinset = #G.edgeFinset + #(G'.edgeFinset \ G.edgeFinset) by
300+
have := Finset.card_sdiff_add_card_eq_card (edgeFinset_mono hGG'); omega,
301+
pow_add, ← mul_assoc, ← pow_add,
302+
show (-1 : ℤ) ^ (#G.edgeFinset + #G.edgeFinset) = 1 from Even.neg_one_pow ⟨_, rfl⟩,
303+
one_mul]
304+
305+
/-- The Möbius (signed-sum) inverse to `copyCount_eq_sum_embeddingCount`. The induced copy
306+
count is expressed as a signed sum of copy counts over supergraphs `G' ∈ Icc G ⊤`, with the
307+
sign factored as `(-1) ^ Nat.card G.edgeSet * (-1) ^ Nat.card G'.edgeSet` — equivalently
308+
`(-1) ^ #(G'.edgeFinset \ G.edgeFinset)`, but stated via `Nat.card` so no per-graph
309+
`Fintype` hypothesis on the edge sets appears in the signature. -/
310+
theorem embeddingCount_eq_sum_signed_copyCount [Fintype V] [DecidableEq V]
311+
[DecidableLE (SimpleGraph V)] [Finite W] (G : SimpleGraph V) (H : SimpleGraph W) :
312+
(H.embeddingCount G : ℤ) =
313+
(-1 : ℤ) ^ Nat.card G.edgeSet *
314+
∑ G' ∈ Finset.Icc G ⊤,
315+
(-1 : ℤ) ^ Nat.card G'.edgeSet * (H.copyCount G' : ℤ) := by
316+
rw [embeddingCount_eq_sum_signed_copyCount_aux, Finset.mul_sum]
317+
refine Finset.sum_congr rfl fun G' hG' => ?_
318+
rw [neg_one_pow_card_edgeFinset_sdiff (Finset.mem_Icc.mp hG').1, mul_assoc]
319+
320+
end Mobius
321+
322+
end SimpleGraph

0 commit comments

Comments
 (0)