Skip to content

Commit ac4cb3d

Browse files
committed
WIP: clean-slate restructure of Möbius file — no Classical anywhere
Drops `attribute [local instance 0] Classical.decRel` and all `open Classical in` blocks. Restructures helpers to use `Set.Finite.toFinset` (noncomputable, but no per-graph `Fintype` synthesis required) instead of `edgeFinset`. The kernel is split into two pieces (degenerate `Icc G G` case and strict `G < L` case) to avoid `if-then-else` in the signature, which would require `DecidableEq (SimpleGraph V)`. Four `sorry`s remain: * `natCard_edgeSet_eq_add_card_sdiff` — bridge between `Nat.card K.edgeSet` and `Nat.card G.edgeSet + #(edgeSetSdiffFinset G K)`. * `iccEquivPowersetEdgeFinsetSdiff` — `left_inv` / `right_inv`. * `sum_Icc_neg_one_pow_natCard_edgeSet_of_lt` — alternating-sum collapse via `Finset.sum_powerset_neg_one_pow_card`. * `embeddingCount_eq_sum_signed_copyCount` — main proof. This commit lands the signature shape (all `Classical`-free) and lets the proofs follow in subsequent commits.
1 parent c1d469e commit ac4cb3d

1 file changed

Lines changed: 77 additions & 138 deletions

File tree

Mathlib/Combinatorics/SimpleGraph/Inversion.lean

Lines changed: 77 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -166,156 +166,95 @@ identity `Finset.sum_powerset_neg_one_pow_card`.
166166

167167
section Mobius
168168

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
169+
variable [Fintype V] [DecidableEq V] [DecidableLE (SimpleGraph V)]
170+
171+
/-! ### Finset of extra edges
172+
173+
Helper construction giving the Finset of edges in `K` but not in `G`, without requiring a
174+
per-graph `Fintype` instance on the edge sets. Uses `Set.Finite.toFinset` (noncomputable). -/
175+
176+
/-- The set difference of edge sets on a finite vertex type is finite. -/
177+
lemma edgeSet_sdiff_finite (G K : SimpleGraph V) : (K.edgeSet \ G.edgeSet).Finite :=
178+
Set.finite_univ.subset (Set.subset_univ _)
179+
180+
/-- The Finset of edges in `K` but not in `G`. Constructed via `Set.Finite.toFinset`,
181+
so noncomputable, but requires no per-graph `Fintype` synthesis. -/
182+
noncomputable def edgeSetSdiffFinset (G K : SimpleGraph V) : Finset (Sym2 V) :=
183+
(edgeSet_sdiff_finite G K).toFinset
184+
185+
@[simp] lemma mem_edgeSetSdiffFinset {G K : SimpleGraph V} {e : Sym2 V} :
186+
e ∈ edgeSetSdiffFinset G K ↔ e ∈ K.edgeSet ∧ e ∉ G.edgeSet :=
187+
Set.Finite.mem_toFinset _
188+
189+
/-- Under `G ≤ K`, `Nat.card K.edgeSet = Nat.card G.edgeSet + #(edgeSetSdiffFinset G K)`. -/
190+
lemma natCard_edgeSet_eq_add_card_sdiff {G K : SimpleGraph V} (hGK : G ≤ K) :
191+
Nat.card K.edgeSet = Nat.card G.edgeSet + #(edgeSetSdiffFinset G K) := by
192+
sorry
193+
194+
/-! ### Bijection between Icc and powerset of extra edges -/
195+
196+
/-- Equivalence between the closed interval `Finset.Icc G K` of graphs and the powerset of
197+
the Finset of edges in `K` not in `G`, when `G ≤ K`.
198+
199+
Forward: `G' ∈ [G, K]` maps to the Finset `edgeSetSdiffFinset G G'.val` (its extra edges
200+
over `G`, automatically a subset of `edgeSetSdiffFinset G K` since `G' ≤ K`).
201+
202+
Inverse: a subset `S ⊆ edgeSetSdiffFinset G K` maps to `fromEdgeSet (G.edgeSet ∪ ↑S)`. -/
203+
noncomputable def iccEquivPowersetEdgeFinsetSdiff
204+
{G K : SimpleGraph V} (hGK : G ≤ K) :
205+
↥(Finset.Icc G K) ≃ ↥(edgeSetSdiffFinset G K).powerset where
181206
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⟩
207+
⟨edgeSetSdiffFinset G G'.val, by
208+
rw [Finset.mem_powerset]
209+
intro e he
210+
rw [mem_edgeSetSdiffFinset] at he ⊢
211+
exact ⟨edgeSet_subset_edgeSet.mpr (Finset.mem_Icc.mp G'.prop).2 he.1, he.2⟩⟩
186212
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
213+
⟨fromEdgeSet (G.edgeSet ∪ ↑S.val), by
214+
have hSK : ∀ e ∈ S.val, e ∈ K.edgeSet ∧ e ∉ G.edgeSet := fun e he => by
215+
have := Finset.mem_powerset.mp S.prop he
216+
rwa [mem_edgeSetSdiffFinset] at this
189217
refine Finset.mem_Icc.mpr ⟨fun a b hab => ?_, ?_⟩
190-
· exact (fromEdgeSet_adj _).mpr ⟨.inl (mem_coe.mpr <| mem_edgeFinset.mpr hab), hab.ne⟩
218+
· exact (fromEdgeSet_adj _).mpr ⟨.inl hab, hab.ne⟩
191219
· rw [fromEdgeSet_le]
192220
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]
221+
· exact edgeSet_subset_edgeSet.mpr hGK heGS
222+
· exact (hSK e (Finset.mem_coe.mp heGS)).1
223+
left_inv := by sorry
224+
right_inv := by sorry
225+
226+
/-! ### Combinatorial kernel
227+
228+
Split into two pieces, avoiding `if-then-else` (which would require `DecidableEq` on
229+
`SimpleGraph V`). Consumers case-split on `G = L vs G < L` via `eq_or_lt_of_le`. -/
230+
231+
/-- Degenerate case: the alternating sum over a singleton interval. -/
232+
lemma sum_Icc_self_neg_one_pow_natCard_edgeSet (G : SimpleGraph V) :
233+
∑ K' ∈ Finset.Icc G G, (-1 : ℤ) ^ Nat.card K'.edgeSet
234+
= (-1 : ℤ) ^ Nat.card G.edgeSet := by
235+
rw [Finset.Icc_self, Finset.sum_singleton]
236+
237+
/-- Strictly-larger case: the alternating sum over `Icc G L` with `G < L` is zero. -/
238+
lemma sum_Icc_neg_one_pow_natCard_edgeSet_of_lt
239+
{G L : SimpleGraph V} (hGL : G < L) :
240+
∑ K' ∈ Finset.Icc G L, (-1 : ℤ) ^ Nat.card K'.edgeSet = 0 := by
241+
sorry
242+
243+
/-! ### Main Möbius identity -/
304244

305245
/-- The Möbius (signed-sum) inverse to `copyCount_eq_sum_embeddingCount`. The induced copy
306246
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) :
247+
sign factored as `(-1)^Nat.card G.edgeSet * (-1)^Nat.card G'.edgeSet`.
248+
249+
The `Nat.card` form keeps the signature free of per-graph `Fintype` synthesis on edge sets
250+
(and hence free of `Classical`). -/
251+
theorem embeddingCount_eq_sum_signed_copyCount [Finite W]
252+
(G : SimpleGraph V) (H : SimpleGraph W) :
312253
(H.embeddingCount G : ℤ) =
313254
(-1 : ℤ) ^ Nat.card G.edgeSet *
314255
∑ G' ∈ Finset.Icc G ⊤,
315256
(-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]
257+
sorry
319258

320259
end Mobius
321260

0 commit comments

Comments
 (0)