-
Notifications
You must be signed in to change notification settings - Fork 1.5k
feat(Combinatorics/SimpleGraph/Acyclic): a graph is a tree iff it's acyclic and has exactly n - 1 edges
#34910
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
c6ec473
4980ed5
cf038ba
68b3331
c29bf8b
7437183
9e8cadc
353130b
294e917
e1df04b
c996f86
88e2969
7c870cf
1b2c614
26389a6
73086cf
87bad13
ad81eb8
0f9476f
eee507f
32ebd1a
0ea71f5
856c74a
be182cb
54e21b2
c277057
d19d07d
f02f013
b57791d
fa03e4b
3461c62
7443c51
9bc5dd6
4c2f32c
9e3daec
bc79940
058fa64
66da04f
5c98360
2ebd30d
16a5dad
e952ebd
fbff91b
ea26511
43c05db
87fd089
f60f58a
fc3fa5a
7eabf4a
50081fe
8846957
f2906dc
8379122
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| /- | ||
| Copyright (c) 2022 Kyle Miller. All rights reserved. | ||
| Released under Apache 2.0 license as described in the file LICENSE. | ||
| Authors: Kyle Miller | ||
| Authors: Kyle Miller, Snir Broshi | ||
| -/ | ||
| module | ||
|
|
||
|
|
@@ -343,6 +343,12 @@ lemma IsTree.card_edgeFinset [Fintype V] [Fintype G.edgeSet] (hG : G.IsTree) : | |
| refine (hG.existsUnique_path _ _).unique ((hf _).takeUntil _) ?_ | ||
| simp [h.ne] | ||
|
|
||
| theorem IsTree.ncard_edgeSet_add_one [Finite V] (hG : G.IsTree) : | ||
| G.edgeSet.ncard + 1 = Nat.card V := by | ||
| have := Fintype.ofFinite V | ||
| have := Fintype.ofFinite G.edgeSet | ||
| simpa [edgeFinset] using hG.card_edgeFinset | ||
|
|
||
| /-- A minimally connected graph is a tree. -/ | ||
| lemma isTree_of_minimal_connected (h : Minimal Connected G) : IsTree G := by | ||
| rw [isTree_iff, and_iff_right h.prop, isAcyclic_iff_forall_adj_isBridge] | ||
|
|
@@ -466,6 +472,23 @@ lemma Connected.exists_isTree_le (h : G.Connected) : ∃ T ≤ G, IsTree T := by | |
| obtain ⟨F, hF⟩ := G.exists_isAcyclic_reachable_eq_le_of_le_of_isAcyclic bot_le isAcyclic_bot | ||
| grind [IsTree, Connected, preconnected_iff_reachable_eq_top] | ||
|
|
||
| theorem connected_iff_card_connectedComponent_eq_one : | ||
| G.Connected ↔ Nat.card G.ConnectedComponent = 1 := by | ||
| have : G.ConnectedComponent = Quotient G.reachableSetoid := rfl | ||
| simp_rw [connected_iff, preconnected_iff_reachable_eq_top, Nat.card_eq_one_iff_unique, this, | ||
| nonempty_quotient_iff, Quotient.subsingleton_iff, reachableSetoid, Setoid.mk_eq_top] | ||
|
|
||
| variable (G) in | ||
| theorem sum_connectedComponent_ncard_supp [Finite V] [Fintype G.ConnectedComponent] : | ||
| ∑ c : G.ConnectedComponent, c.supp.ncard = Nat.card V := by | ||
| rw [Nat.card_congr G.verticesEquivSigmaConnectedComponent, Nat.card_sigma] | ||
| rfl | ||
|
|
||
| variable (G) in | ||
| theorem sum_connectedComponent_ncard_edgeSet [Finite V] [Fintype G.ConnectedComponent] : | ||
| ∑ c : G.ConnectedComponent, c.toSimpleGraph.edgeSet.ncard = G.edgeSet.ncard := by | ||
| simpa [Nat.card_sigma] using Nat.card_congr G.edgeSetEquivSigmaConnectedComponent.symm | ||
|
|
||
| /-- Every connected graph on `n` vertices has at least `n-1` edges. -/ | ||
| lemma Connected.card_vert_le_card_edgeSet_add_one (h : G.Connected) : | ||
| Nat.card V ≤ Nat.card G.edgeSet + 1 := by | ||
|
|
@@ -481,15 +504,41 @@ lemma isTree_iff_connected_and_card [Finite V] : | |
| G.IsTree ↔ G.Connected ∧ Nat.card G.edgeSet + 1 = Nat.card V := by | ||
| have := Fintype.ofFinite V | ||
| classical | ||
| refine ⟨fun h ↦ ⟨h.connected, by simpa [edgeFinset] using h.card_edgeFinset⟩, | ||
| fun ⟨h₁, h₂⟩ ↦ ⟨h₁, ?_⟩⟩ | ||
| refine ⟨fun h ↦ ⟨h.connected, h.ncard_edgeSet_add_one⟩, fun ⟨h₁, h₂⟩ ↦ ⟨h₁, ?_⟩⟩ | ||
| simp_rw [isAcyclic_iff_forall_adj_isBridge] | ||
| refine fun x y h ↦ by_contra fun hbr ↦ | ||
| (h₁.connected_delete_edge_of_not_isBridge hbr).card_vert_le_card_edgeSet_add_one.not_gt ?_ | ||
| rw [Nat.card_eq_fintype_card, ← edgeFinset_card, ← h₂, Nat.card_eq_fintype_card, | ||
| ← edgeFinset_card, add_lt_add_iff_right] | ||
| exact Finset.card_lt_card <| by simpa [deleteEdges, edgeFinset] | ||
|
|
||
| /-- An acyclic graph on `n` vertices with `c` connected components has exactly `n - c` edges. -/ | ||
| theorem IsAcyclic.ncard_edgeSet_add_card_connectedComponent [Finite V] (h : G.IsAcyclic) : | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the naming is fine, but sometimes while naming we are using the plural
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only uses of the plural seem to be what you mentioned and
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point, fixed in #41648. |
||
| G.edgeSet.ncard + Nat.card G.ConnectedComponent = Nat.card V := by | ||
| have := Fintype.ofFinite G.ConnectedComponent | ||
| rw [← sum_connectedComponent_ncard_edgeSet, ← G.sum_connectedComponent_ncard_supp, | ||
| ← Fintype.card_eq_nat_card, Fintype.card_eq_sum_ones, ← Finset.sum_add_distrib] | ||
| simp_rw [h.isTree_connectedComponent _ |>.ncard_edgeSet_add_one] | ||
| rfl | ||
|
|
||
| /-- An acyclic graph on `n` vertices has at most `n - 1` edges. -/ | ||
| theorem IsAcyclic.ncard_edgeSet_add_one_le_card [Finite V] [Nonempty V] (h : G.IsAcyclic) : | ||
| G.edgeSet.ncard + 1 ≤ Nat.card V := by | ||
| grind [h.ncard_edgeSet_add_card_connectedComponent, Nat.card_pos] | ||
|
|
||
| /-- A graph on `n` vertices with at least `n` edges has a cycle. -/ | ||
| theorem exists_isCycle_of_card_le [Finite V] [Nonempty V] | ||
| (h : Nat.card V ≤ G.edgeSet.ncard) : ∃ (v : V) (c : G.Walk v v), c.IsCycle := by | ||
| suffices ¬G.IsAcyclic by grind [IsAcyclic] | ||
| apply mt IsAcyclic.ncard_edgeSet_add_one_le_card | ||
| lia | ||
|
|
||
| /-- A graph on `n` vertices is a tree iff it is acyclic and has exactly `n - 1` edges. -/ | ||
| theorem isTree_iff_isAcyclic_and_ncard_edgeSet_add_one_eq_card [Finite V] : | ||
| G.IsTree ↔ G.IsAcyclic ∧ G.edgeSet.ncard + 1 = Nat.card V := by | ||
| refine ⟨fun h ↦ ⟨h.isAcyclic, h.ncard_edgeSet_add_one⟩, fun ⟨h, _⟩ ↦ ⟨?_, h⟩⟩ | ||
| grind [connected_iff_card_connectedComponent_eq_one, h.ncard_edgeSet_add_card_connectedComponent] | ||
|
|
||
| /-- The minimum degree of all vertices in a nontrivial tree is one. -/ | ||
| lemma IsTree.minDegree_eq_one_of_nontrivial (h : G.IsTree) [Fintype V] [Nontrivial V] | ||
| [DecidableRel G.Adj] : G.minDegree = 1 := by | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to move this to
Connectivity/Connected.lean?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not without import changes as it doesn't import
Nat.card. It is imported inConnectivity/Subgraph.leanandConnectivity/EdgeConnectivity.lean, but they also seem weird.#40624 will fix the import issues, but no one commented on it yet.