group_theory.nielsen_schreier
⟷
Mathlib.GroupTheory.FreeGroup.NielsenSchreier
The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(no changes)
(last sync)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -6,7 +6,7 @@ Authors: David Wärn
import CategoryTheory.Action
import Combinatorics.Quiver.Arborescence
import Combinatorics.Quiver.ConnectedComponent
-import GroupTheory.IsFreeGroup
+import GroupTheory.FreeGroup.IsFreeGroup
#align_import group_theory.nielsen_schreier from "leanprover-community/mathlib"@"2ed2c6310e6f1c5562bdf6bfbda55ebbf6891abe"
@@ -202,7 +202,7 @@ def loopOfHom {a b : G} (p : a ⟶ b) : End (root' T) :=
#align is_free_groupoid.spanning_tree.loop_of_hom IsFreeGroupoid.SpanningTree.loopOfHom
-/
-/- ./././Mathport/Syntax/Translate/Basic.lean:641:2: warning: expanding binder collection (e «expr ∈ » wide_subquiver_symmetrify[quiver.wide_subquiver_symmetrify] T a b) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:642:2: warning: expanding binder collection (e «expr ∈ » wide_subquiver_symmetrify[quiver.wide_subquiver_symmetrify] T a b) -/
#print IsFreeGroupoid.SpanningTree.loopOfHom_eq_id /-
/-- Turning an edge in the spanning tree into a loop gives the indentity loop. -/
theorem loopOfHom_eq_id {a b : Generators G} (e) (_ : e ∈ wideSubquiverSymmetrify T a b) :
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -309,7 +309,7 @@ theorem path_nonempty_of_hom {G} [Groupoid.{u, u} G] [IsFreeGroupoid G] {a b : G
/-- Given a connected free groupoid, its generating quiver is rooted-connected. -/
instance generators_connected (G) [Groupoid.{u, u} G] [IsConnected G] [IsFreeGroupoid G] (r : G) :
RootedConnected (symgen r) :=
- ⟨fun b => path_nonempty_of_hom (CategoryTheory.nonempty_hom_of_connected_groupoid r b)⟩
+ ⟨fun b => path_nonempty_of_hom (CategoryTheory.nonempty_hom_of_preconnected_groupoid r b)⟩
#align is_free_groupoid.generators_connected IsFreeGroupoid.generators_connected
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/3365b20c2ffa7c35e47e5209b89ba9abdddf3ffe
@@ -239,7 +239,7 @@ def functorOfMonoidHom {X} [Monoid X] (f : End (root' T) →* X) : G ⥤ Categor
group at the root is freely generated by loops coming from generating arrows
in the complement of the tree. -/
def endIsFree : IsFreeGroup (End (root' T)) :=
- IsFreeGroup.ofUniqueLift ((wideSubquiverEquivSetTotal <| wideSubquiverSymmetrify T)ᶜ : Set _)
+ IsFreeGroup.of_unique_lift ((wideSubquiverEquivSetTotal <| wideSubquiverSymmetrify T)ᶜ : Set _)
(fun e => loopOfHom T (of e.val.Hom))
(by
intro X _ f
@@ -328,7 +328,7 @@ end IsFreeGroupoid
/-- The Nielsen-Schreier theorem: a subgroup of a free group is free. -/
instance subgroupIsFreeOfIsFree {G : Type u} [Group G] [IsFreeGroup G] (H : Subgroup G) :
IsFreeGroup H :=
- IsFreeGroup.ofMulEquiv (endMulEquivSubgroup H)
+ IsFreeGroup.of_mulEquiv (endMulEquivSubgroup H)
#align subgroup_is_free_of_is_free subgroupIsFreeOfIsFree
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,10 +3,10 @@ Copyright (c) 2021 David Wärn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Wärn
-/
-import Mathbin.CategoryTheory.Action
-import Mathbin.Combinatorics.Quiver.Arborescence
-import Mathbin.Combinatorics.Quiver.ConnectedComponent
-import Mathbin.GroupTheory.IsFreeGroup
+import CategoryTheory.Action
+import Combinatorics.Quiver.Arborescence
+import Combinatorics.Quiver.ConnectedComponent
+import GroupTheory.IsFreeGroup
#align_import group_theory.nielsen_schreier from "leanprover-community/mathlib"@"2ed2c6310e6f1c5562bdf6bfbda55ebbf6891abe"
@@ -202,7 +202,7 @@ def loopOfHom {a b : G} (p : a ⟶ b) : End (root' T) :=
#align is_free_groupoid.spanning_tree.loop_of_hom IsFreeGroupoid.SpanningTree.loopOfHom
-/
-/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (e «expr ∈ » wide_subquiver_symmetrify[quiver.wide_subquiver_symmetrify] T a b) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:641:2: warning: expanding binder collection (e «expr ∈ » wide_subquiver_symmetrify[quiver.wide_subquiver_symmetrify] T a b) -/
#print IsFreeGroupoid.SpanningTree.loopOfHom_eq_id /-
/-- Turning an edge in the spanning tree into a loop gives the indentity loop. -/
theorem loopOfHom_eq_id {a b : Generators G} (e) (_ : e ∈ wideSubquiverSymmetrify T a b) :
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,17 +2,14 @@
Copyright (c) 2021 David Wärn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Wärn
-
-! This file was ported from Lean 3 source module group_theory.nielsen_schreier
-! leanprover-community/mathlib commit 2ed2c6310e6f1c5562bdf6bfbda55ebbf6891abe
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.CategoryTheory.Action
import Mathbin.Combinatorics.Quiver.Arborescence
import Mathbin.Combinatorics.Quiver.ConnectedComponent
import Mathbin.GroupTheory.IsFreeGroup
+#align_import group_theory.nielsen_schreier from "leanprover-community/mathlib"@"2ed2c6310e6f1c5562bdf6bfbda55ebbf6891abe"
+
/-!
# The Nielsen-Schreier theorem
@@ -205,7 +202,7 @@ def loopOfHom {a b : G} (p : a ⟶ b) : End (root' T) :=
#align is_free_groupoid.spanning_tree.loop_of_hom IsFreeGroupoid.SpanningTree.loopOfHom
-/
-/- ./././Mathport/Syntax/Translate/Basic.lean:638:2: warning: expanding binder collection (e «expr ∈ » wide_subquiver_symmetrify[quiver.wide_subquiver_symmetrify] T a b) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (e «expr ∈ » wide_subquiver_symmetrify[quiver.wide_subquiver_symmetrify] T a b) -/
#print IsFreeGroupoid.SpanningTree.loopOfHom_eq_id /-
/-- Turning an edge in the spanning tree into a loop gives the indentity loop. -/
theorem loopOfHom_eq_id {a b : Generators G} (e) (_ : e ∈ wideSubquiverSymmetrify T a b) :
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -97,6 +97,7 @@ namespace IsFreeGroupoid
attribute [instance] quiver_generators
+#print IsFreeGroupoid.ext_functor /-
/-- Two functors from a free groupoid to a group are equal when they agree on the generating
quiver. -/
@[ext]
@@ -106,6 +107,7 @@ theorem ext_functor {G} [Groupoid.{v} G] [IsFreeGroupoid G] {X : Type v} [Group
let ⟨_, _, u⟩ := @unique_lift G _ _ X _ fun (a b : Generators G) (e : a ⟶ b) => g.map (of e)
trans (u _ h) (u _ fun _ _ _ => rfl).symm
#align is_free_groupoid.ext_functor IsFreeGroupoid.ext_functor
+-/
#print IsFreeGroupoid.actionGroupoidIsFree /-
/-- An action groupoid over a free group is free. More generally, one could show that the groupoid
@@ -325,9 +327,11 @@ instance endIsFreeOfConnectedFree {G} [Groupoid G] [IsConnected G] [IsFreeGroupo
end IsFreeGroupoid
+#print subgroupIsFreeOfIsFree /-
/-- The Nielsen-Schreier theorem: a subgroup of a free group is free. -/
instance subgroupIsFreeOfIsFree {G : Type u} [Group G] [IsFreeGroup G] (H : Subgroup G) :
IsFreeGroup H :=
IsFreeGroup.ofMulEquiv (endMulEquivSubgroup H)
#align subgroup_is_free_of_is_free subgroupIsFreeOfIsFree
+-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/31c24aa72e7b3e5ed97a8412470e904f82b81004
@@ -203,7 +203,7 @@ def loopOfHom {a b : G} (p : a ⟶ b) : End (root' T) :=
#align is_free_groupoid.spanning_tree.loop_of_hom IsFreeGroupoid.SpanningTree.loopOfHom
-/
-/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (e «expr ∈ » wide_subquiver_symmetrify[quiver.wide_subquiver_symmetrify] T a b) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:638:2: warning: expanding binder collection (e «expr ∈ » wide_subquiver_symmetrify[quiver.wide_subquiver_symmetrify] T a b) -/
#print IsFreeGroupoid.SpanningTree.loopOfHom_eq_id /-
/-- Turning an edge in the spanning tree into a loop gives the indentity loop. -/
theorem loopOfHom_eq_id {a b : Generators G} (e) (_ : e ∈ wideSubquiverSymmetrify T a b) :
mathlib commit https://github.com/leanprover-community/mathlib/commit/5f25c089cb34db4db112556f23c50d12da81b297
@@ -62,7 +62,7 @@ open scoped Classical
universe v u
-/- ./././Mathport/Syntax/Translate/Command.lean:229:11: unsupported: unusual advanced open style -/
+/- ./././Mathport/Syntax/Translate/Command.lean:230:11: unsupported: unusual advanced open style -/
open CategoryTheory CategoryTheory.ActionCategory CategoryTheory.SingleObj Quiver
#print IsFreeGroupoid.Generators /-
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -144,7 +144,7 @@ instance actionGroupoidIsFree {G A : Type u} [Group G] [IsFreeGroup G] [MulActio
· convert hE _ _ _; rfl
· rfl
apply functor.hext
- · intro ; apply Unit.ext
+ · intro; apply Unit.ext
· refine' action_category.cases _; intros
simp only [← this, uncurry_map, curry_apply_left, coe_back, hom_of_pair.val]
#align is_free_groupoid.action_groupoid_is_free IsFreeGroupoid.actionGroupoidIsFree
@@ -298,7 +298,7 @@ theorem path_nonempty_of_hom {G} [Groupoid.{u, u} G] [IsFreeGroupoid G] {a b : G
let f : G → X := fun g => FreeGroup.of (weakly_connected_component.mk g)
let F : G ⥤ CategoryTheory.SingleObj X := single_obj.difference_functor f
change F.map p = ((CategoryTheory.Functor.const G).obj ()).map p
- congr ; ext
+ congr; ext
rw [functor.const_obj_map, id_as_one, difference_functor_map, mul_inv_eq_one]
apply congr_arg FreeGroup.of
apply (weakly_connected_component.eq _ _).mpr
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -58,7 +58,7 @@ free group, free groupoid, Nielsen-Schreier
noncomputable section
-open Classical
+open scoped Classical
universe v u
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -97,12 +97,6 @@ namespace IsFreeGroupoid
attribute [instance] quiver_generators
-/- warning: is_free_groupoid.ext_functor -> IsFreeGroupoid.ext_functor is a dubious translation:
-lean 3 declaration is
- forall {G : Type.{u2}} [_inst_1 : CategoryTheory.Groupoid.{u1, u2} G] [_inst_2 : IsFreeGroupoid.{u1, u2} G _inst_1] {X : Type.{u1}} [_inst_3 : Group.{u1} X] (f : CategoryTheory.Functor.{u1, u1, u2, 0} G (CategoryTheory.Groupoid.toCategory.{u1, u2} G _inst_1) (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.SingleObj.category.{u1} X (DivInvMonoid.toMonoid.{u1} X (Group.toDivInvMonoid.{u1} X _inst_3)))) (g : CategoryTheory.Functor.{u1, u1, u2, 0} G (CategoryTheory.Groupoid.toCategory.{u1, u2} G _inst_1) (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.SingleObj.category.{u1} X (DivInvMonoid.toMonoid.{u1} X (Group.toDivInvMonoid.{u1} X _inst_3)))), (forall (a : IsFreeGroupoid.Generators.{u2, u1} G _inst_1) (b : IsFreeGroupoid.Generators.{u2, u1} G _inst_1) (e : Quiver.Hom.{succ u1, u2} (IsFreeGroupoid.Generators.{u2, u1} G _inst_1) (IsFreeGroupoid.quiverGenerators.{u1, u2} G _inst_1 _inst_2) a b), Eq.{succ u1} (Quiver.Hom.{succ u1, 0} (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.CategoryStruct.toQuiver.{u1, 0} (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.Category.toCategoryStruct.{u1, 0} (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.SingleObj.category.{u1} X (DivInvMonoid.toMonoid.{u1} X (Group.toDivInvMonoid.{u1} X _inst_3))))) (CategoryTheory.Functor.obj.{u1, u1, u2, 0} G (CategoryTheory.Groupoid.toCategory.{u1, u2} G _inst_1) (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.SingleObj.category.{u1} X (DivInvMonoid.toMonoid.{u1} X (Group.toDivInvMonoid.{u1} X _inst_3))) f ((fun (this : G) => this) a)) (CategoryTheory.Functor.obj.{u1, u1, u2, 0} G (CategoryTheory.Groupoid.toCategory.{u1, u2} G _inst_1) (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.SingleObj.category.{u1} X (DivInvMonoid.toMonoid.{u1} X (Group.toDivInvMonoid.{u1} X _inst_3))) f b)) (CategoryTheory.Functor.map.{u1, u1, u2, 0} G (CategoryTheory.Groupoid.toCategory.{u1, u2} G _inst_1) (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.SingleObj.category.{u1} X (DivInvMonoid.toMonoid.{u1} X (Group.toDivInvMonoid.{u1} X _inst_3))) f ((fun (this : G) => this) a) b (IsFreeGroupoid.of.{u1, u2} G _inst_1 _inst_2 a b e)) (CategoryTheory.Functor.map.{u1, u1, u2, 0} G (CategoryTheory.Groupoid.toCategory.{u1, u2} G _inst_1) (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.SingleObj.category.{u1} X (DivInvMonoid.toMonoid.{u1} X (Group.toDivInvMonoid.{u1} X _inst_3))) g ((fun (this : G) => this) a) b (IsFreeGroupoid.of.{u1, u2} G _inst_1 _inst_2 a b e))) -> (Eq.{succ (max u1 u2)} (CategoryTheory.Functor.{u1, u1, u2, 0} G (CategoryTheory.Groupoid.toCategory.{u1, u2} G _inst_1) (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.SingleObj.category.{u1} X (DivInvMonoid.toMonoid.{u1} X (Group.toDivInvMonoid.{u1} X _inst_3)))) f g)
-but is expected to have type
- forall {G : Type.{u1}} [_inst_1 : CategoryTheory.Groupoid.{u2, u1} G] [_inst_2 : IsFreeGroupoid.{u2, u1} G _inst_1] {X : Type.{u2}} [_inst_3 : Group.{u2} X] (f : CategoryTheory.Functor.{u2, u2, u1, 0} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3)))) (g : CategoryTheory.Functor.{u2, u2, u1, 0} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3)))), (forall (a : IsFreeGroupoid.Generators.{u1, u2} G _inst_1) (b : IsFreeGroupoid.Generators.{u1, u2} G _inst_1) (e : Quiver.Hom.{succ u2, u1} (IsFreeGroupoid.Generators.{u1, u2} G _inst_1) (IsFreeGroupoid.quiverGenerators.{u2, u1} G _inst_1 _inst_2) a b), Eq.{succ u2} (Quiver.Hom.{succ u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.CategoryStruct.toQuiver.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.Category.toCategoryStruct.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))))) (Prefunctor.obj.{succ u2, succ u2, u1, 0} G (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} G (CategoryTheory.Category.toCategoryStruct.{u2, u1} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1))) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.CategoryStruct.toQuiver.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.Category.toCategoryStruct.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))))) (CategoryTheory.Functor.toPrefunctor.{u2, u2, u1, 0} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))) f) ([mdata let_fun:1 (fun (this : G) => this) a])) (Prefunctor.obj.{succ u2, succ u2, u1, 0} G (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} G (CategoryTheory.Category.toCategoryStruct.{u2, u1} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1))) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.CategoryStruct.toQuiver.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.Category.toCategoryStruct.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))))) (CategoryTheory.Functor.toPrefunctor.{u2, u2, u1, 0} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))) f) b)) (Prefunctor.map.{succ u2, succ u2, u1, 0} G (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} G (CategoryTheory.Category.toCategoryStruct.{u2, u1} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1))) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.CategoryStruct.toQuiver.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.Category.toCategoryStruct.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))))) (CategoryTheory.Functor.toPrefunctor.{u2, u2, u1, 0} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))) f) ([mdata let_fun:1 (fun (this : G) => this) a]) b (IsFreeGroupoid.of.{u2, u1} G _inst_1 _inst_2 a b e)) (Prefunctor.map.{succ u2, succ u2, u1, 0} G (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} G (CategoryTheory.Category.toCategoryStruct.{u2, u1} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1))) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.CategoryStruct.toQuiver.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.Category.toCategoryStruct.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))))) (CategoryTheory.Functor.toPrefunctor.{u2, u2, u1, 0} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))) g) ([mdata let_fun:1 (fun (this : G) => this) a]) b (IsFreeGroupoid.of.{u2, u1} G _inst_1 _inst_2 a b e))) -> (Eq.{max (succ u2) (succ u1)} (CategoryTheory.Functor.{u2, u2, u1, 0} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3)))) f g)
-Case conversion may be inaccurate. Consider using '#align is_free_groupoid.ext_functor IsFreeGroupoid.ext_functorₓ'. -/
/-- Two functors from a free groupoid to a group are equal when they agree on the generating
quiver. -/
@[ext]
@@ -331,12 +325,6 @@ instance endIsFreeOfConnectedFree {G} [Groupoid G] [IsConnected G] [IsFreeGroupo
end IsFreeGroupoid
-/- warning: subgroup_is_free_of_is_free -> subgroupIsFreeOfIsFree is a dubious translation:
-lean 3 declaration is
- forall {G : Type.{u1}} [_inst_1 : Group.{u1} G] [_inst_2 : IsFreeGroup.{u1} G _inst_1] (H : Subgroup.{u1} G _inst_1), IsFreeGroup.{u1} (coeSort.{succ u1, succ (succ u1)} (Subgroup.{u1} G _inst_1) Type.{u1} (SetLike.hasCoeToSort.{u1, u1} (Subgroup.{u1} G _inst_1) G (Subgroup.setLike.{u1} G _inst_1)) H) (Subgroup.toGroup.{u1} G _inst_1 H)
-but is expected to have type
- forall {G : Type.{u1}} [_inst_1 : Group.{u1} G] [_inst_2 : IsFreeGroup.{u1} G _inst_1] (H : Subgroup.{u1} G _inst_1), IsFreeGroup.{u1} (Subtype.{succ u1} G (fun (x : G) => Membership.mem.{u1, u1} G (Subgroup.{u1} G _inst_1) (SetLike.instMembership.{u1, u1} (Subgroup.{u1} G _inst_1) G (Subgroup.instSetLikeSubgroup.{u1} G _inst_1)) x H)) (Subgroup.toGroup.{u1} G _inst_1 H)
-Case conversion may be inaccurate. Consider using '#align subgroup_is_free_of_is_free subgroupIsFreeOfIsFreeₓ'. -/
/-- The Nielsen-Schreier theorem: a subgroup of a free group is free. -/
instance subgroupIsFreeOfIsFree {G : Type u} [Group G] [IsFreeGroup G] (H : Subgroup G) :
IsFreeGroup H :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -147,14 +147,11 @@ instance actionGroupoidIsFree {G A : Type u} [Group G] [IsFreeGroup G] [MulActio
apply uF'
intro e
ext
- · convert hE _ _ _
- rfl
+ · convert hE _ _ _; rfl
· rfl
apply functor.hext
- · intro
- apply Unit.ext
- · refine' action_category.cases _
- intros
+ · intro ; apply Unit.ext
+ · refine' action_category.cases _; intros
simp only [← this, uncurry_map, curry_apply_left, coe_back, hom_of_pair.val]
#align is_free_groupoid.action_groupoid_is_free IsFreeGroupoid.actionGroupoidIsFree
-/
@@ -220,8 +217,7 @@ theorem loopOfHom_eq_id {a b : Generators G} (e) (_ : e ∈ wideSubquiverSymmetr
by
rw [loop_of_hom, ← category.assoc, is_iso.comp_inv_eq, category.id_comp]
cases H
- · rw [tree_hom_eq T (path.cons default ⟨Sum.inl e, H⟩), hom_of_path]
- rfl
+ · rw [tree_hom_eq T (path.cons default ⟨Sum.inl e, H⟩), hom_of_path]; rfl
· rw [tree_hom_eq T (path.cons default ⟨Sum.inr e, H⟩), hom_of_path]
simp only [is_iso.inv_hom_id, category.comp_id, category.assoc, tree_hom]
#align is_free_groupoid.spanning_tree.loop_of_hom_eq_id IsFreeGroupoid.SpanningTree.loopOfHom_eq_id
@@ -267,15 +263,12 @@ def endIsFree : IsFreeGroup (End (root' T)) :=
suffices ∀ {a} (p : Path (root' T) a), F'.map (hom_of_path T p) = 1 by
simp only [this, tree_hom, comp_as_mul, inv_as_inv, loop_of_hom, inv_one, mul_one,
one_mul, functor.map_inv, functor.map_comp]
- intro a p
- induction' p with b c p e ih
+ intro a p; induction' p with b c p e ih
· rw [hom_of_path, F'.map_id, id_as_one]
rw [hom_of_path, F'.map_comp, comp_as_mul, ih, mul_one]
rcases e with ⟨e | e, eT⟩
- · rw [hF']
- exact dif_pos (Or.inl eT)
- · rw [F'.map_inv, inv_as_inv, inv_eq_one, hF']
- exact dif_pos (Or.inr eT)
+ · rw [hF']; exact dif_pos (Or.inl eT)
+ · rw [F'.map_inv, inv_as_inv, inv_eq_one, hF']; exact dif_pos (Or.inr eT)
· intro E hE
ext
suffices (functor_of_monoid_hom T E).map x = F'.map x by
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -171,7 +171,6 @@ variable {G : Type u} [Groupoid.{u} G] [IsFreeGroupoid G]
/-- The root of `T`, except its type is `G` instead of the type synonym `T`. -/
private def root' : G :=
show T from root T
-#align is_free_groupoid.spanning_tree.root' is_free_groupoid.spanning_tree.root'
#print IsFreeGroupoid.SpanningTree.homOfPath /-
-- this has to be marked noncomputable, see issue #451.
@@ -298,7 +297,6 @@ end SpanningTree
private def symgen {G : Type u} [Groupoid.{v} G] [IsFreeGroupoid G] :
G → Symmetrify (Generators G) :=
id
-#align is_free_groupoid.symgen is_free_groupoid.symgen
#print IsFreeGroupoid.path_nonempty_of_hom /-
/-- If there exists a morphism `a → b` in a free groupoid, then there also exists a zigzag
mathlib commit https://github.com/leanprover-community/mathlib/commit/c89fe2d59ae06402c3f55f978016d1ada444f57e
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Wärn
! This file was ported from Lean 3 source module group_theory.nielsen_schreier
-! leanprover-community/mathlib commit 1bda4fc53de6ade5ab9da36f2192e24e2084a2ce
+! leanprover-community/mathlib commit 2ed2c6310e6f1c5562bdf6bfbda55ebbf6891abe
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -16,6 +16,9 @@ import Mathbin.GroupTheory.IsFreeGroup
/-!
# The Nielsen-Schreier theorem
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
This file proves that a subgroup of a free group is itself free.
## Main result
mathlib commit https://github.com/leanprover-community/mathlib/commit/7ad820c4997738e2f542f8a20f32911f52020e26
@@ -62,6 +62,7 @@ universe v u
/- ./././Mathport/Syntax/Translate/Command.lean:229:11: unsupported: unusual advanced open style -/
open CategoryTheory CategoryTheory.ActionCategory CategoryTheory.SingleObj Quiver
+#print IsFreeGroupoid.Generators /-
/-- `is_free_groupoid.generators G` is a type synonym for `G`. We think of this as
the vertices of the generating quiver of `G` when `G` is free. We can't use `G` directly,
since `G` already has a quiver instance from being a groupoid. -/
@@ -69,7 +70,9 @@ since `G` already has a quiver instance from being a groupoid. -/
def IsFreeGroupoid.Generators (G) [Groupoid G] :=
G
#align is_free_groupoid.generators IsFreeGroupoid.Generators
+-/
+#print IsFreeGroupoid /-
/-- A groupoid `G` is free when we have the following data:
- a quiver on `is_free_groupoid.generators G` (a type synonym for `G`)
- a function `of` taking a generating arrow to a morphism in `G`
@@ -85,11 +88,18 @@ class IsFreeGroupoid (G) [Groupoid.{v} G] where
∀ {X : Type v} [Group X] (f : Labelling (IsFreeGroupoid.Generators G) X),
∃! F : G ⥤ CategoryTheory.SingleObj X, ∀ (a b) (g : a ⟶ b), F.map (of g) = f g
#align is_free_groupoid IsFreeGroupoid
+-/
namespace IsFreeGroupoid
attribute [instance] quiver_generators
+/- warning: is_free_groupoid.ext_functor -> IsFreeGroupoid.ext_functor is a dubious translation:
+lean 3 declaration is
+ forall {G : Type.{u2}} [_inst_1 : CategoryTheory.Groupoid.{u1, u2} G] [_inst_2 : IsFreeGroupoid.{u1, u2} G _inst_1] {X : Type.{u1}} [_inst_3 : Group.{u1} X] (f : CategoryTheory.Functor.{u1, u1, u2, 0} G (CategoryTheory.Groupoid.toCategory.{u1, u2} G _inst_1) (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.SingleObj.category.{u1} X (DivInvMonoid.toMonoid.{u1} X (Group.toDivInvMonoid.{u1} X _inst_3)))) (g : CategoryTheory.Functor.{u1, u1, u2, 0} G (CategoryTheory.Groupoid.toCategory.{u1, u2} G _inst_1) (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.SingleObj.category.{u1} X (DivInvMonoid.toMonoid.{u1} X (Group.toDivInvMonoid.{u1} X _inst_3)))), (forall (a : IsFreeGroupoid.Generators.{u2, u1} G _inst_1) (b : IsFreeGroupoid.Generators.{u2, u1} G _inst_1) (e : Quiver.Hom.{succ u1, u2} (IsFreeGroupoid.Generators.{u2, u1} G _inst_1) (IsFreeGroupoid.quiverGenerators.{u1, u2} G _inst_1 _inst_2) a b), Eq.{succ u1} (Quiver.Hom.{succ u1, 0} (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.CategoryStruct.toQuiver.{u1, 0} (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.Category.toCategoryStruct.{u1, 0} (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.SingleObj.category.{u1} X (DivInvMonoid.toMonoid.{u1} X (Group.toDivInvMonoid.{u1} X _inst_3))))) (CategoryTheory.Functor.obj.{u1, u1, u2, 0} G (CategoryTheory.Groupoid.toCategory.{u1, u2} G _inst_1) (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.SingleObj.category.{u1} X (DivInvMonoid.toMonoid.{u1} X (Group.toDivInvMonoid.{u1} X _inst_3))) f ((fun (this : G) => this) a)) (CategoryTheory.Functor.obj.{u1, u1, u2, 0} G (CategoryTheory.Groupoid.toCategory.{u1, u2} G _inst_1) (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.SingleObj.category.{u1} X (DivInvMonoid.toMonoid.{u1} X (Group.toDivInvMonoid.{u1} X _inst_3))) f b)) (CategoryTheory.Functor.map.{u1, u1, u2, 0} G (CategoryTheory.Groupoid.toCategory.{u1, u2} G _inst_1) (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.SingleObj.category.{u1} X (DivInvMonoid.toMonoid.{u1} X (Group.toDivInvMonoid.{u1} X _inst_3))) f ((fun (this : G) => this) a) b (IsFreeGroupoid.of.{u1, u2} G _inst_1 _inst_2 a b e)) (CategoryTheory.Functor.map.{u1, u1, u2, 0} G (CategoryTheory.Groupoid.toCategory.{u1, u2} G _inst_1) (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.SingleObj.category.{u1} X (DivInvMonoid.toMonoid.{u1} X (Group.toDivInvMonoid.{u1} X _inst_3))) g ((fun (this : G) => this) a) b (IsFreeGroupoid.of.{u1, u2} G _inst_1 _inst_2 a b e))) -> (Eq.{succ (max u1 u2)} (CategoryTheory.Functor.{u1, u1, u2, 0} G (CategoryTheory.Groupoid.toCategory.{u1, u2} G _inst_1) (CategoryTheory.SingleObj.{u1} X) (CategoryTheory.SingleObj.category.{u1} X (DivInvMonoid.toMonoid.{u1} X (Group.toDivInvMonoid.{u1} X _inst_3)))) f g)
+but is expected to have type
+ forall {G : Type.{u1}} [_inst_1 : CategoryTheory.Groupoid.{u2, u1} G] [_inst_2 : IsFreeGroupoid.{u2, u1} G _inst_1] {X : Type.{u2}} [_inst_3 : Group.{u2} X] (f : CategoryTheory.Functor.{u2, u2, u1, 0} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3)))) (g : CategoryTheory.Functor.{u2, u2, u1, 0} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3)))), (forall (a : IsFreeGroupoid.Generators.{u1, u2} G _inst_1) (b : IsFreeGroupoid.Generators.{u1, u2} G _inst_1) (e : Quiver.Hom.{succ u2, u1} (IsFreeGroupoid.Generators.{u1, u2} G _inst_1) (IsFreeGroupoid.quiverGenerators.{u2, u1} G _inst_1 _inst_2) a b), Eq.{succ u2} (Quiver.Hom.{succ u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.CategoryStruct.toQuiver.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.Category.toCategoryStruct.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))))) (Prefunctor.obj.{succ u2, succ u2, u1, 0} G (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} G (CategoryTheory.Category.toCategoryStruct.{u2, u1} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1))) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.CategoryStruct.toQuiver.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.Category.toCategoryStruct.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))))) (CategoryTheory.Functor.toPrefunctor.{u2, u2, u1, 0} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))) f) ([mdata let_fun:1 (fun (this : G) => this) a])) (Prefunctor.obj.{succ u2, succ u2, u1, 0} G (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} G (CategoryTheory.Category.toCategoryStruct.{u2, u1} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1))) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.CategoryStruct.toQuiver.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.Category.toCategoryStruct.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))))) (CategoryTheory.Functor.toPrefunctor.{u2, u2, u1, 0} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))) f) b)) (Prefunctor.map.{succ u2, succ u2, u1, 0} G (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} G (CategoryTheory.Category.toCategoryStruct.{u2, u1} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1))) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.CategoryStruct.toQuiver.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.Category.toCategoryStruct.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))))) (CategoryTheory.Functor.toPrefunctor.{u2, u2, u1, 0} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))) f) ([mdata let_fun:1 (fun (this : G) => this) a]) b (IsFreeGroupoid.of.{u2, u1} G _inst_1 _inst_2 a b e)) (Prefunctor.map.{succ u2, succ u2, u1, 0} G (CategoryTheory.CategoryStruct.toQuiver.{u2, u1} G (CategoryTheory.Category.toCategoryStruct.{u2, u1} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1))) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.CategoryStruct.toQuiver.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.Category.toCategoryStruct.{u2, 0} (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))))) (CategoryTheory.Functor.toPrefunctor.{u2, u2, u1, 0} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3))) g) ([mdata let_fun:1 (fun (this : G) => this) a]) b (IsFreeGroupoid.of.{u2, u1} G _inst_1 _inst_2 a b e))) -> (Eq.{max (succ u2) (succ u1)} (CategoryTheory.Functor.{u2, u2, u1, 0} G (CategoryTheory.Groupoid.toCategory.{u2, u1} G _inst_1) (CategoryTheory.SingleObj.{u2} X) (CategoryTheory.SingleObj.category.{u2} X (DivInvMonoid.toMonoid.{u2} X (Group.toDivInvMonoid.{u2} X _inst_3)))) f g)
+Case conversion may be inaccurate. Consider using '#align is_free_groupoid.ext_functor IsFreeGroupoid.ext_functorₓ'. -/
/-- Two functors from a free groupoid to a group are equal when they agree on the generating
quiver. -/
@[ext]
@@ -100,6 +110,7 @@ theorem ext_functor {G} [Groupoid.{v} G] [IsFreeGroupoid G] {X : Type v} [Group
trans (u _ h) (u _ fun _ _ _ => rfl).symm
#align is_free_groupoid.ext_functor IsFreeGroupoid.ext_functor
+#print IsFreeGroupoid.actionGroupoidIsFree /-
/-- An action groupoid over a free group is free. More generally, one could show that the groupoid
of elements over a free groupoid is free, but this version is easier to prove and suffices for our
purposes.
@@ -143,6 +154,7 @@ instance actionGroupoidIsFree {G A : Type u} [Group G] [IsFreeGroup G] [MulActio
intros
simp only [← this, uncurry_map, curry_apply_left, coe_back, hom_of_pair.val]
#align is_free_groupoid.action_groupoid_is_free IsFreeGroupoid.actionGroupoidIsFree
+-/
namespace SpanningTree
@@ -158,6 +170,7 @@ private def root' : G :=
show T from root T
#align is_free_groupoid.spanning_tree.root' is_free_groupoid.spanning_tree.root'
+#print IsFreeGroupoid.SpanningTree.homOfPath /-
-- this has to be marked noncomputable, see issue #451.
-- It might be nicer to define this in terms of `compose_path`
/-- A path in the tree gives a hom, by composition. -/
@@ -165,30 +178,40 @@ noncomputable def homOfPath : ∀ {a : G}, Path (root T) a → (root' T ⟶ a)
| _, path.nil => 𝟙 _
| a, path.cons p f => hom_of_path p ≫ Sum.recOn f.val (fun e => of e) fun e => inv (of e)
#align is_free_groupoid.spanning_tree.hom_of_path IsFreeGroupoid.SpanningTree.homOfPath
+-/
+#print IsFreeGroupoid.SpanningTree.treeHom /-
/-- For every vertex `a`, there is a canonical hom from the root, given by the path in the tree. -/
def treeHom (a : G) : root' T ⟶ a :=
homOfPath T default
#align is_free_groupoid.spanning_tree.tree_hom IsFreeGroupoid.SpanningTree.treeHom
+-/
+#print IsFreeGroupoid.SpanningTree.treeHom_eq /-
/-- Any path to `a` gives `tree_hom T a`, since paths in the tree are unique. -/
theorem treeHom_eq {a : G} (p : Path (root T) a) : treeHom T a = homOfPath T p := by
rw [tree_hom, Unique.default_eq]
#align is_free_groupoid.spanning_tree.tree_hom_eq IsFreeGroupoid.SpanningTree.treeHom_eq
+-/
+#print IsFreeGroupoid.SpanningTree.treeHom_root /-
@[simp]
theorem treeHom_root : treeHom T (root' T) = 𝟙 _ :=
-- this should just be `tree_hom_eq T path.nil`, but Lean treats `hom_of_path` with suspicion.
trans
(treeHom_eq T Path.nil) rfl
#align is_free_groupoid.spanning_tree.tree_hom_root IsFreeGroupoid.SpanningTree.treeHom_root
+-/
+#print IsFreeGroupoid.SpanningTree.loopOfHom /-
/-- Any hom in `G` can be made into a loop, by conjugating with `tree_hom`s. -/
def loopOfHom {a b : G} (p : a ⟶ b) : End (root' T) :=
treeHom T a ≫ p ≫ inv (treeHom T b)
#align is_free_groupoid.spanning_tree.loop_of_hom IsFreeGroupoid.SpanningTree.loopOfHom
+-/
/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (e «expr ∈ » wide_subquiver_symmetrify[quiver.wide_subquiver_symmetrify] T a b) -/
+#print IsFreeGroupoid.SpanningTree.loopOfHom_eq_id /-
/-- Turning an edge in the spanning tree into a loop gives the indentity loop. -/
theorem loopOfHom_eq_id {a b : Generators G} (e) (_ : e ∈ wideSubquiverSymmetrify T a b) :
loopOfHom T (of e) = 𝟙 (root' T) :=
@@ -200,7 +223,9 @@ theorem loopOfHom_eq_id {a b : Generators G} (e) (_ : e ∈ wideSubquiverSymmetr
· rw [tree_hom_eq T (path.cons default ⟨Sum.inr e, H⟩), hom_of_path]
simp only [is_iso.inv_hom_id, category.comp_id, category.assoc, tree_hom]
#align is_free_groupoid.spanning_tree.loop_of_hom_eq_id IsFreeGroupoid.SpanningTree.loopOfHom_eq_id
+-/
+#print IsFreeGroupoid.SpanningTree.functorOfMonoidHom /-
/-- Since a hom gives a loop, any homomorphism from the vertex group at the root
extends to a functor on the whole groupoid. -/
@[simps]
@@ -216,7 +241,9 @@ def functorOfMonoidHom {X} [Monoid X] (f : End (root' T) →* X) : G ⥤ Categor
rw [comp_as_mul, ← f.map_mul]
simp only [is_iso.inv_hom_id_assoc, loop_of_hom, End.mul_def, category.assoc]
#align is_free_groupoid.spanning_tree.functor_of_monoid_hom IsFreeGroupoid.SpanningTree.functorOfMonoidHom
+-/
+#print IsFreeGroupoid.SpanningTree.endIsFree /-
/-- Given a free groupoid and an arborescence of its generating quiver, the vertex
group at the root is freely generated by loops coming from generating arrows
in the complement of the tree. -/
@@ -260,6 +287,7 @@ def endIsFree : IsFreeGroup (End (root' T)) :=
· rw [loop_of_hom_eq_id T e h, ← End.one_def, E.map_one]
· exact hE ⟨⟨a, b, e⟩, h⟩)
#align is_free_groupoid.spanning_tree.End_is_free IsFreeGroupoid.SpanningTree.endIsFree
+-/
end SpanningTree
@@ -269,6 +297,7 @@ private def symgen {G : Type u} [Groupoid.{v} G] [IsFreeGroupoid G] :
id
#align is_free_groupoid.symgen is_free_groupoid.symgen
+#print IsFreeGroupoid.path_nonempty_of_hom /-
/-- If there exists a morphism `a → b` in a free groupoid, then there also exists a zigzag
from `a` to `b` in the generating quiver. -/
theorem path_nonempty_of_hom {G} [Groupoid.{u, u} G] [IsFreeGroupoid G] {a b : G} :
@@ -287,22 +316,33 @@ theorem path_nonempty_of_hom {G} [Groupoid.{u, u} G] [IsFreeGroupoid G] {a b : G
apply (weakly_connected_component.eq _ _).mpr
exact ⟨hom.to_path (Sum.inr e)⟩
#align is_free_groupoid.path_nonempty_of_hom IsFreeGroupoid.path_nonempty_of_hom
+-/
+#print IsFreeGroupoid.generators_connected /-
/-- Given a connected free groupoid, its generating quiver is rooted-connected. -/
instance generators_connected (G) [Groupoid.{u, u} G] [IsConnected G] [IsFreeGroupoid G] (r : G) :
RootedConnected (symgen r) :=
⟨fun b => path_nonempty_of_hom (CategoryTheory.nonempty_hom_of_connected_groupoid r b)⟩
#align is_free_groupoid.generators_connected IsFreeGroupoid.generators_connected
+-/
+#print IsFreeGroupoid.endIsFreeOfConnectedFree /-
/-- A vertex group in a free connected groupoid is free. With some work one could drop the
connectedness assumption, by looking at connected components. -/
instance endIsFreeOfConnectedFree {G} [Groupoid G] [IsConnected G] [IsFreeGroupoid G] (r : G) :
IsFreeGroup (End r) :=
SpanningTree.endIsFree <| geodesicSubtree (symgen r)
#align is_free_groupoid.End_is_free_of_connected_free IsFreeGroupoid.endIsFreeOfConnectedFree
+-/
end IsFreeGroupoid
+/- warning: subgroup_is_free_of_is_free -> subgroupIsFreeOfIsFree is a dubious translation:
+lean 3 declaration is
+ forall {G : Type.{u1}} [_inst_1 : Group.{u1} G] [_inst_2 : IsFreeGroup.{u1} G _inst_1] (H : Subgroup.{u1} G _inst_1), IsFreeGroup.{u1} (coeSort.{succ u1, succ (succ u1)} (Subgroup.{u1} G _inst_1) Type.{u1} (SetLike.hasCoeToSort.{u1, u1} (Subgroup.{u1} G _inst_1) G (Subgroup.setLike.{u1} G _inst_1)) H) (Subgroup.toGroup.{u1} G _inst_1 H)
+but is expected to have type
+ forall {G : Type.{u1}} [_inst_1 : Group.{u1} G] [_inst_2 : IsFreeGroup.{u1} G _inst_1] (H : Subgroup.{u1} G _inst_1), IsFreeGroup.{u1} (Subtype.{succ u1} G (fun (x : G) => Membership.mem.{u1, u1} G (Subgroup.{u1} G _inst_1) (SetLike.instMembership.{u1, u1} (Subgroup.{u1} G _inst_1) G (Subgroup.instSetLikeSubgroup.{u1} G _inst_1)) x H)) (Subgroup.toGroup.{u1} G _inst_1 H)
+Case conversion may be inaccurate. Consider using '#align subgroup_is_free_of_is_free subgroupIsFreeOfIsFreeₓ'. -/
/-- The Nielsen-Schreier theorem: a subgroup of a free group is free. -/
instance subgroupIsFreeOfIsFree {G : Type u} [Group G] [IsFreeGroup G] (H : Subgroup G) :
IsFreeGroup H :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/09079525fd01b3dda35e96adaa08d2f943e1648c
@@ -59,7 +59,7 @@ open Classical
universe v u
-/- ./././Mathport/Syntax/Translate/Command.lean:224:11: unsupported: unusual advanced open style -/
+/- ./././Mathport/Syntax/Translate/Command.lean:229:11: unsupported: unusual advanced open style -/
open CategoryTheory CategoryTheory.ActionCategory CategoryTheory.SingleObj Quiver
/-- `is_free_groupoid.generators G` is a type synonym for `G`. We think of this as
mathlib commit https://github.com/leanprover-community/mathlib/commit/57e09a1296bfb4330ddf6624f1028ba186117d82
@@ -235,7 +235,7 @@ def endIsFree : IsFreeGroup (End (root' T)) :=
rw [functor.map_End_apply, this, hF']
exact dif_neg h
intros
- suffices ∀ {a} (p : path (root' T) a), F'.map (hom_of_path T p) = 1 by
+ suffices ∀ {a} (p : Path (root' T) a), F'.map (hom_of_path T p) = 1 by
simp only [this, tree_hom, comp_as_mul, inv_as_inv, loop_of_hom, inv_one, mul_one,
one_mul, functor.map_inv, functor.map_comp]
intro a p
mathlib commit https://github.com/leanprover-community/mathlib/commit/4c586d291f189eecb9d00581aeb3dd998ac34442
@@ -188,7 +188,7 @@ def loopOfHom {a b : G} (p : a ⟶ b) : End (root' T) :=
treeHom T a ≫ p ≫ inv (treeHom T b)
#align is_free_groupoid.spanning_tree.loop_of_hom IsFreeGroupoid.SpanningTree.loopOfHom
-/- ./././Mathport/Syntax/Translate/Basic.lean:628:2: warning: expanding binder collection (e «expr ∈ » wide_subquiver_symmetrify[quiver.wide_subquiver_symmetrify] T a b) -/
+/- ./././Mathport/Syntax/Translate/Basic.lean:635:2: warning: expanding binder collection (e «expr ∈ » wide_subquiver_symmetrify[quiver.wide_subquiver_symmetrify] T a b) -/
/-- Turning an edge in the spanning tree into a loop gives the indentity loop. -/
theorem loopOfHom_eq_id {a b : Generators G} (e) (_ : e ∈ wideSubquiverSymmetrify T a b) :
loopOfHom T (of e) = 𝟙 (root' T) :=
mathlib commit https://github.com/leanprover-community/mathlib/commit/3ade05ac9447ae31a22d2ea5423435e054131240
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Wärn
! This file was ported from Lean 3 source module group_theory.nielsen_schreier
-! leanprover-community/mathlib commit 56adee5b5eef9e734d82272918300fca4f3e7cef
+! leanprover-community/mathlib commit 1bda4fc53de6ade5ab9da36f2192e24e2084a2ce
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -100,7 +100,7 @@ theorem ext_functor {G} [Groupoid.{v} G] [IsFreeGroupoid G] {X : Type v} [Group
trans (u _ h) (u _ fun _ _ _ => rfl).symm
#align is_free_groupoid.ext_functor IsFreeGroupoid.ext_functor
-/-- An action groupoid over a free froup is free. More generally, one could show that the groupoid
+/-- An action groupoid over a free group is free. More generally, one could show that the groupoid
of elements over a free groupoid is free, but this version is easier to prove and suffices for our
purposes.
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
@@ -63,7 +63,7 @@ open CategoryTheory CategoryTheory.ActionCategory CategoryTheory.SingleObj Quive
/-- `IsFreeGroupoid.Generators G` is a type synonym for `G`. We think of this as
the vertices of the generating quiver of `G` when `G` is free. We can't use `G` directly,
since `G` already has a quiver instance from being a groupoid. -/
--- Porting note: @[nolint has_nonempty_instance]
+-- Porting note(#5171): @[nolint has_nonempty_instance]
@[nolint unusedArguments]
def IsFreeGroupoid.Generators (G) [Groupoid G] :=
G
open Classical
(#11199)
We remove all but one open Classical
s, instead preferring to use open scoped Classical
. The only real side-effect this led to is moving a couple declarations to use Exists.choose
instead of Classical.choose
.
The first few commits are explicitly labelled regex replaces for ease of review.
@@ -52,7 +52,7 @@ free group, free groupoid, Nielsen-Schreier
noncomputable section
-open Classical
+open scoped Classical
universe v u
@@ -291,7 +291,7 @@ theorem path_nonempty_of_hom {G} [Groupoid.{u, u} G] [IsFreeGroupoid G] {a b : G
/-- Given a connected free groupoid, its generating quiver is rooted-connected. -/
instance generators_connected (G) [Groupoid.{u, u} G] [IsConnected G] [IsFreeGroupoid G] (r : G) :
RootedConnected (symgen r) :=
- ⟨fun b => path_nonempty_of_hom (CategoryTheory.nonempty_hom_of_connected_groupoid r b)⟩
+ ⟨fun b => path_nonempty_of_hom (CategoryTheory.nonempty_hom_of_preconnected_groupoid r b)⟩
#align is_free_groupoid.generators_connected IsFreeGroupoid.generators_connected
/-- A vertex group in a free connected groupoid is free. With some work one could drop the
FunLike
to DFunLike
(#9785)
This prepares for the introduction of a non-dependent synonym of FunLike, which helps a lot with keeping #8386 readable.
This is entirely search-and-replace in 680197f combined with manual fixes in 4145626, e900597 and b8428f8. The commands that generated this change:
sed -i 's/\bFunLike\b/DFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\btoFunLike\b/toDFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/import Mathlib.Data.DFunLike/import Mathlib.Data.FunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\bHom_FunLike\b/Hom_DFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\binstFunLike\b/instDFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\bfunLike\b/instDFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\btoo many metavariables to apply `fun_like.has_coe_to_fun`/too many metavariables to apply `DFunLike.hasCoeToFun`/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
Co-authored-by: Anne Baanen <Vierkantor@users.noreply.github.com>
@@ -120,7 +120,7 @@ instance actionGroupoidIsFree {G A : Type u} [Group G] [IsFreeGroup G] [MulActio
refine' ⟨uncurry F' _, _, _⟩
· suffices SemidirectProduct.rightHom.comp F' = MonoidHom.id _ by
-- Porting note: `MonoidHom.ext_iff` has been deprecated.
- exact FunLike.ext_iff.mp this
+ exact DFunLike.ext_iff.mp this
apply IsFreeGroup.ext_hom (fun x ↦ ?_)
rw [MonoidHom.comp_apply, hF']
rfl
IsFreeGroup
to a Prop
(#7698)
Currently, the class IsFreeGroup
contains data (namely, a specific set of generators). This is bad, as there are many sets of generators in a free group, and changing sets of generators happens all the time in geometric group theory. We switch to a design in which
FreeGroupBasis
, following the definition and API of bases of vector spaces. Most existing API around IsFreeGroup
is transferred to lemmas taking a free group basis as a variable.IsFreeGroup
is Prop-valued, and requires only the existence of a free group basis.@@ -121,7 +121,7 @@ instance actionGroupoidIsFree {G A : Type u} [Group G] [IsFreeGroup G] [MulActio
· suffices SemidirectProduct.rightHom.comp F' = MonoidHom.id _ by
-- Porting note: `MonoidHom.ext_iff` has been deprecated.
exact FunLike.ext_iff.mp this
- ext
+ apply IsFreeGroup.ext_hom (fun x ↦ ?_)
rw [MonoidHom.comp_apply, hF']
rfl
· rintro ⟨⟨⟩, a : A⟩ ⟨⟨⟩, b⟩ ⟨e, h : IsFreeGroup.of e • a = b⟩
@@ -222,7 +222,7 @@ def functorOfMonoidHom {X} [Monoid X] (f : End (root' T) →* X) : G ⥤ Categor
/-- Given a free groupoid and an arborescence of its generating quiver, the vertex
group at the root is freely generated by loops coming from generating arrows
in the complement of the tree. -/
-def endIsFree : IsFreeGroup (End (root' T)) :=
+lemma endIsFree : IsFreeGroup (End (root' T)) :=
IsFreeGroup.ofUniqueLift ((wideSubquiverEquivSetTotal <| wideSubquiverSymmetrify T)ᶜ : Set _)
(fun e => loopOfHom T (of e.val.hom))
(by
@@ -6,7 +6,7 @@ Authors: David Wärn
import Mathlib.CategoryTheory.Action
import Mathlib.Combinatorics.Quiver.Arborescence
import Mathlib.Combinatorics.Quiver.ConnectedComponent
-import Mathlib.GroupTheory.IsFreeGroup
+import Mathlib.GroupTheory.FreeGroup.IsFreeGroup
#align_import group_theory.nielsen_schreier from "leanprover-community/mathlib"@"1bda4fc53de6ade5ab9da36f2192e24e2084a2ce"
@@ -2,17 +2,14 @@
Copyright (c) 2021 David Wärn. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: David Wärn
-
-! This file was ported from Lean 3 source module group_theory.nielsen_schreier
-! leanprover-community/mathlib commit 1bda4fc53de6ade5ab9da36f2192e24e2084a2ce
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.CategoryTheory.Action
import Mathlib.Combinatorics.Quiver.Arborescence
import Mathlib.Combinatorics.Quiver.ConnectedComponent
import Mathlib.GroupTheory.IsFreeGroup
+#align_import group_theory.nielsen_schreier from "leanprover-community/mathlib"@"1bda4fc53de6ade5ab9da36f2192e24e2084a2ce"
+
/-!
# The Nielsen-Schreier theorem
This is the second half of the changes originally in #5699, removing all occurrences of ;
after a space and implementing a linter rule to enforce it.
In most cases this 2-character substring has a space after it, so the following command was run first:
find . -type f -name "*.lean" -exec sed -i -E 's/ ; /; /g' {} \;
The remaining cases were few enough in number that they were done manually.
@@ -284,7 +284,7 @@ theorem path_nonempty_of_hom {G} [Groupoid.{u, u} G] [IsFreeGroupoid G] {a b : G
let f : G → X := fun g => FreeGroup.of (WeaklyConnectedComponent.mk g)
let F : G ⥤ CategoryTheory.SingleObj.{u} (X : Type u) := SingleObj.differenceFunctor f
change (F.map p) = ((@CategoryTheory.Functor.const G _ _ (SingleObj.category X)).obj ()).map p
- congr ; ext
+ congr; ext
rw [Functor.const_obj_map, id_as_one, differenceFunctor_map, @mul_inv_eq_one _ _ (f _)]
apply congr_arg FreeGroup.of
apply (WeaklyConnectedComponent.eq _ _).mpr
@@ -194,7 +194,7 @@ def loopOfHom {a b : G} (p : a ⟶ b) : End (root' T) :=
treeHom T a ≫ p ≫ inv (treeHom T b)
#align is_free_groupoid.spanning_tree.loop_of_hom IsFreeGroupoid.SpanningTree.loopOfHom
-/-- Turning an edge in the spanning tree into a loop gives the indentity loop. -/
+/-- Turning an edge in the spanning tree into a loop gives the identity loop. -/
theorem loopOfHom_eq_id {a b : Generators G} (e) (H : e ∈ wideSubquiverSymmetrify T a b) :
loopOfHom T (of e) = 𝟙 (root' T) := by
rw [loopOfHom, ← Category.assoc, IsIso.comp_inv_eq, Category.id_comp]
The unported dependencies are