|
| 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