Skip to content

Commit 387b6ac

Browse files
committed
feat(Combinatorics/SimpleGraph/Copy): introduce Sub carrier subtype
Adds `abbrev Sub A B := {B' : B.Subgraph // Nonempty (A ≃g B'.coe)}`, the subtype of `SimpleGraph.Subgraph`s of `B` isomorphic to `A`. Redefines `copyCount G H` via `Fintype.card (H.Sub G)`, replacing the previous inline filter-set body, and rewrites the affected proofs (`copyCount_eq_zero`, `copyCount_pos`, `copyCount_le_labelledCopyCount`, `copyCount_bot`, `le_card_edgeFinset_killCopies`) to use `Sub` directly. The singleton-empty-subgraph reasoning previously inlined in `copyCount_bot`'s proof is factored into: * `private lemma subgraph_iso_emptyGraph` — extracts `G'.verts = univ ∧ G'.Adj = ⊥` from `(⊥ : SimpleGraph V) ≃g G'.coe`. * `instance uniqueSubEmptyGraph (G : SimpleGraph V) : Unique ((⊥V).Sub G)` — the resulting `Unique` instance, which makes `copyCount_bot` a one-liner via `Fintype.card_unique`. The names follow the `emptyGraph` / `completeGraph` convention introduced in #23838 and adopted in `AdjMatrix.lean`. Drops `copyCount_eq_card_image_copyToSubgraph` (the legacy bridge between the filter-set and Finset.image-of-Copy.toSubgraph forms) — unused after the type-form refactor.
1 parent 5961646 commit 387b6ac

1 file changed

Lines changed: 41 additions & 28 deletions

File tree

Mathlib/Combinatorics/SimpleGraph/Copy.lean

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Containment:
3535
same underlying vertex type.
3636
* `SimpleGraph.Free` is the predicate that `H` is `G`-free, that is, `H` does not contain a copy of
3737
`G`. This is the negation of `SimpleGraph.IsContained` implemented for convenience.
38+
* `SimpleGraph.Sub H G`: Type of `SimpleGraph.Subgraph`s of `G` isomorphic to `H`.
3839
* `SimpleGraph.killCopies G H`: Subgraph of `G` that does not contain `H`. Obtained by arbitrarily
3940
removing an edge from each copy of `H` in `G`.
4041
* `SimpleGraph.copyCount G H`: Number of copies of `H` in `G`, i.e. number of subgraphs of `G`
@@ -496,46 +497,60 @@ end LabelledCopyCount
496497
section CopyCount
497498
variable [Fintype V]
498499

500+
/-- `Sub A B` is the type of `SimpleGraph.Subgraph`s of `B` isomorphic to `A`. The corresponding
501+
count is `SimpleGraph.copyCount`. -/
502+
abbrev Sub (A : SimpleGraph α) (B : SimpleGraph β) : Type _ :=
503+
{B' : B.Subgraph // Nonempty (A ≃g B'.coe)}
504+
499505
/-- `G.copyCount H` is the number of unlabelled copies of `H` in `G`, i.e. the number of subgraphs
500506
of `G` isomorphic to `H`. See `SimpleGraph.labelledCopyCount` for the number of labelled copies. -/
501507
noncomputable def copyCount (G : SimpleGraph V) (H : SimpleGraph W) : ℕ := by
502-
classical exact #{G' : G.Subgraph | Nonempty (H ≃g G'.coe)}
503-
504-
lemma copyCount_eq_card_image_copyToSubgraph [Fintype {f : H →g G // Injective f}]
505-
[DecidableEq G.Subgraph] :
506-
copyCount G H = #((Finset.univ : Finset (H.Copy G)).image Copy.toSubgraph) := by
507-
rw [copyCount]
508-
congr
509-
refine Finset.coe_injective ?_
510-
simpa [-Copy.range_toSubgraph] using Copy.range_toSubgraph.symm
508+
classical exact Fintype.card (H.Sub G)
511509

512510
@[simp] lemma copyCount_eq_zero : G.copyCount H = 0 ↔ H.Free G := by
513-
simp [copyCount, Free, -nonempty_subtype, isContained_iff_exists_iso_subgraph,
514-
filter_eq_empty_iff]
511+
classical
512+
rw [copyCount, Fintype.card_eq_zero_iff, isEmpty_subtype]
513+
simp [Free, isContained_iff_exists_iso_subgraph]
515514

516515
@[simp] lemma copyCount_pos : 0 < G.copyCount H ↔ H ⊑ G := by
517-
simp [copyCount, -nonempty_subtype, isContained_iff_exists_iso_subgraph, card_pos,
518-
filter_nonempty_iff]
516+
simp [Nat.pos_iff_ne_zero, copyCount_eq_zero]
519517

520518
/-- There's at least as many labelled copies of `H` in `G` than unlabelled ones. -/
521519
lemma copyCount_le_labelledCopyCount [Fintype W] : G.copyCount H ≤ G.labelledCopyCount H := by
522-
classical rw [copyCount_eq_card_image_copyToSubgraph]; exact card_image_le
520+
classical
521+
rw [copyCount, labelledCopyCount]
522+
apply Fintype.card_le_of_surjective
523+
(fun c : Copy H G ↦ (⟨c.toSubgraph, ⟨c.isoToSubgraph⟩⟩ : H.Sub G))
524+
rintro ⟨G', hG'⟩
525+
obtain ⟨c, hc⟩ : ∃ c : Copy H G, c.toSubgraph = G' := by
526+
rwa [← Set.mem_range, Copy.range_toSubgraph]
527+
exact ⟨c, Subtype.ext hc⟩
523528

524-
@[simp] lemma copyCount_bot (G : SimpleGraph V) : copyCount G (⊥ : SimpleGraph V) = 1 := by
529+
set_option backward.privateInPublic true in
530+
set_option backward.privateInPublic.warn false in
531+
set_option linter.unusedFintypeInType false in
532+
set_option linter.unusedSectionVars false in
533+
private lemma subgraph_iso_emptyGraph [Fintype V] {G : SimpleGraph V} (G' : G.Subgraph)
534+
(e : (⊥ : SimpleGraph V) ≃g G'.coe) : G'.verts = Set.univ ∧ G'.Adj = ⊥ := by
525535
classical
526-
rw [copyCount]
527-
convert card_singleton (α := G.Subgraph)
528-
{ verts := .univ
529-
Adj := ⊥
530-
adj_sub := False.elim
531-
edge_vert := False.elim }
532-
simp only [eq_singleton_iff_unique_mem, mem_filter_univ, Nonempty.forall]
533-
refine ⟨⟨⟨(Equiv.Set.univ _).symm, by simp⟩⟩, fun H' e ↦
534-
Subgraph.ext ((set_fintype_card_eq_univ_iff _).1 <| Fintype.card_congr e.toEquiv.symm) ?_⟩
536+
refine ⟨(set_fintype_card_eq_univ_iff _).1 <| Fintype.card_congr e.toEquiv.symm, ?_⟩
535537
ext a b
536538
simp only [Prop.bot_eq_false, Pi.bot_apply, iff_false]
537539
exact fun hab ↦ e.symm.map_rel_iff.2 hab.coe
538540

541+
set_option backward.privateInPublic true in
542+
set_option backward.privateInPublic.warn false in
543+
instance uniqueSubEmptyGraph (G : SimpleGraph V) : Unique ((⊥ : SimpleGraph V).Sub G) where
544+
default := ⟨{ verts := .univ, Adj := ⊥, adj_sub := False.elim, edge_vert := False.elim },
545+
⟨(Equiv.Set.univ _).symm, by simp⟩⟩
546+
uniq := fun ⟨G', ⟨e⟩⟩ ↦ Subtype.ext <|
547+
Subgraph.ext (subgraph_iso_emptyGraph G' e).1 (subgraph_iso_emptyGraph G' e).2
548+
549+
@[simp] lemma copyCount_bot (G : SimpleGraph V) : copyCount G (⊥ : SimpleGraph V) = 1 := by
550+
classical
551+
rw [copyCount]
552+
exact Fintype.card_unique
553+
539554
@[simp] lemma copyCount_of_isEmpty [IsEmpty W] (G : SimpleGraph V) (H : SimpleGraph W) :
540555
G.copyCount H = 1 := by
541556
cases nonempty_fintype W
@@ -643,15 +658,13 @@ lemma le_card_edgeFinset_killCopies [Fintype V] :
643658
classical
644659
obtain rfl | hH := eq_or_ne H ⊥
645660
· simp [← card_edgeSet]
646-
let f (G' : {G' : G.Subgraph // Nonempty (H ≃g G'.coe)}) := (aux hH G'.2).some
661+
let f (G' : H.Sub G) := (aux hH G'.2).some
647662
calc
648-
_ = #G.edgeFinset - card {G' : G.Subgraph // Nonempty (H ≃g G'.coe)} := ?_
663+
_ = #G.edgeFinset - card (H.Sub G) := by rw [copyCount]
649664
_ ≤ #G.edgeFinset - #(univ.image f) := Nat.sub_le_sub_left card_image_le _
650665
_ = #G.edgeFinset - #(Set.range f).toFinset := by rw [Set.toFinset_range]
651666
_ ≤ #(G.edgeFinset \ (Set.range f).toFinset) := le_card_sdiff ..
652667
_ = #(G.killCopies H).edgeFinset := ?_
653-
· simp only [edgeFinset, Set.toFinset_card]
654-
rw [← Set.toFinset_card, ← edgeFinset, copyCount, ← card_subtype, subtype_univ, card_univ]
655668
congr 1
656669
ext e
657670
induction e using Sym2.inductionOn with | hf v w

0 commit comments

Comments
 (0)