algebra.module.pid
⟷
Mathlib.Algebra.Module.PID
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)
(last sync)
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -4,9 +4,9 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Pierre-Alexandre Bazin
-/
import Algebra.Module.DedekindDomain
-import LinearAlgebra.FreeModule.Pid
+import LinearAlgebra.FreeModule.PID
import Algebra.Module.Projective
-import Algebra.Category.Module.Biproducts
+import Algebra.Category.ModuleCat.Biproducts
#align_import algebra.module.pid from "leanprover-community/mathlib"@"1a51edf13debfcbe223fa06b1cb353b9ed9751cc"
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -121,7 +121,7 @@ theorem Ideal.torsionOf_eq_span_pow_pOrder (x : M) : torsionOf R M x = span {p ^
(fun n : ℕ => p ^ n • x = 0) = fun n : ℕ =>
(Associates.mk <| generator <| torsion_of R M x) ∣ Associates.mk p ^ n :=
by ext n; rw [← Associates.mk_pow, Associates.mk_dvd_mk, ← mem_iff_generator_dvd]; rfl
- have := (is_torsion'_powers_iff p).mp hM x; rw [prop] at this
+ have := (is_torsion'_powers_iff p).mp hM x; rw [prop] at this
classical convert
Associates.eq_pow_find_of_dvd_irreducible_pow ((Associates.irreducible_mk p).mpr hp)
this.some_spec
@@ -143,10 +143,10 @@ theorem p_pow_smul_lift {x y : M} {k : ℕ} (hM' : Module.IsTorsionBy R M (p ^ p
convert f.symm.map_zero; ext
rw [coe_smul_of_tower, coe_mk, coe_zero, smul_smul, ← pow_add, Nat.sub_add_cancel hk, @hM' x]
· exact mem_nonZeroDivisors_of_ne_zero (pow_ne_zero _ hp.ne_zero)
- rw [Submodule.mem_span_singleton] at this ; obtain ⟨a, ha⟩ := this; use a
- rw [f.eq_symm_apply, ← Ideal.Quotient.mk_eq_mk, ← quotient.mk_smul] at ha
+ rw [Submodule.mem_span_singleton] at this; obtain ⟨a, ha⟩ := this; use a
+ rw [f.eq_symm_apply, ← Ideal.Quotient.mk_eq_mk, ← quotient.mk_smul] at ha
dsimp only [smul_eq_mul, f, LinearEquiv.trans_apply, Submodule.quotEquivOfEq_mk,
- quot_torsion_of_equiv_span_singleton_apply_mk] at ha
+ quot_torsion_of_equiv_span_singleton_apply_mk] at ha
rw [smul_smul, mul_comm]; exact congr_arg coe ha.symm
· symm; convert Ideal.torsionOf_eq_span_pow_pOrder hp hM y
rw [← pow_add, Nat.sub_add_cancel hk]
@@ -189,7 +189,7 @@ theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoi
obtain ⟨d, s, hs⟩ := @Module.Finite.exists_fin _ _ _ _ _ h'; use d; clear h'
induction' d with d IH generalizing N
· use fun i => finZeroElim i
- rw [Set.range_eq_empty, Submodule.span_empty] at hs
+ rw [Set.range_eq_empty, Submodule.span_empty] at hs
haveI : Unique N := ⟨⟨0⟩, fun x => by rw [← mem_bot _, hs]; trivial⟩
exact ⟨0⟩
· have : ∀ x : N, Decidable (x = 0)
@@ -241,10 +241,10 @@ theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoi
(mk_surjective _).forall.mpr fun x =>
⟨(@hN x).some, by rw [← quotient.mk_smul, (@hN x).choose_spec, quotient.mk_zero]⟩
· have hs' := congr_arg (Submodule.map <| mkq <| R ∙ s j) hs
- rw [Submodule.map_span, Submodule.map_top, range_mkq] at hs' ; simp only [mkq_apply] at hs'
+ rw [Submodule.map_span, Submodule.map_top, range_mkq] at hs'; simp only [mkq_apply] at hs'
simp only [s']; rw [Set.range_comp (_ ∘ s), Fin.range_succAbove]
rw [← Set.range_comp, ← Set.insert_image_compl_eq_range _ j, Function.comp_apply,
- (quotient.mk_eq_zero _).mpr (Submodule.mem_span_singleton_self _), span_insert_zero] at hs'
+ (quotient.mk_eq_zero _).mpr (Submodule.mem_span_singleton_self _), span_insert_zero] at hs'
exact hs'
#align module.torsion_by_prime_power_decomposition Module.torsion_by_prime_power_decomposition
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -122,7 +122,9 @@ theorem Ideal.torsionOf_eq_span_pow_pOrder (x : M) : torsionOf R M x = span {p ^
(Associates.mk <| generator <| torsion_of R M x) ∣ Associates.mk p ^ n :=
by ext n; rw [← Associates.mk_pow, Associates.mk_dvd_mk, ← mem_iff_generator_dvd]; rfl
have := (is_torsion'_powers_iff p).mp hM x; rw [prop] at this
- classical
+ classical convert
+ Associates.eq_pow_find_of_dvd_irreducible_pow ((Associates.irreducible_mk p).mpr hp)
+ this.some_spec
#align ideal.torsion_of_eq_span_pow_p_order Ideal.torsionOf_eq_span_pow_pOrder
-/
@@ -192,6 +194,58 @@ theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoi
exact ⟨0⟩
· have : ∀ x : N, Decidable (x = 0)
classical
+ infer_instance
+ obtain ⟨j, hj⟩ := exists_is_torsion_by hN d.succ d.succ_ne_zero s hs
+ let s' : Fin d → N ⧸ R ∙ s j := Submodule.Quotient.mk ∘ s ∘ j.succ_above
+ obtain ⟨k, ⟨f⟩⟩ := IH _ s' _ <;> clear IH
+ · have :
+ ∀ i : Fin d,
+ ∃ x : N, p ^ k i • x = 0 ∧ f (Submodule.Quotient.mk x) = DirectSum.lof R _ _ i 1 :=
+ by
+ intro i
+ let fi := f.symm.to_linear_map.comp (DirectSum.lof _ _ _ i)
+ obtain ⟨x, h0, h1⟩ := exists_smul_eq_zero_and_mk_eq hp hN hj fi; refine' ⟨x, h0, _⟩; rw [h1]
+ simp only [LinearMap.coe_comp, f.symm.coe_to_linear_map, f.apply_symm_apply]
+ refine'
+ ⟨_,
+ ⟨(((@lequivProdOfRightSplitExact _ _ _ _ _ _ _ _ _ _ _ _
+ ((f.trans ULift.moduleEquiv.{u, u, v}.symm).toLinearMap.comp <| mkq _)
+ ((DirectSum.toModule _ _ _ fun i =>
+ (liftQSpanSingleton.{u, u} (p ^ k i)
+ (LinearMap.toSpanSingleton _ _ _) (this i).choose_spec.left :
+ R ⧸ _ →ₗ[R] _)).comp
+ ulift.module_equiv.to_linear_map)
+ (R ∙ s j).injective_subtype _ _).symm.trans <|
+ ((quot_torsion_of_equiv_span_singleton _ _ _).symm.trans <|
+ quot_equiv_of_eq _ _ <|
+ Ideal.torsionOf_eq_span_pow_pOrder hp hN _).Prod <|
+ ULift.moduleEquiv).trans <|
+ (@DirectSum.lequivProdDirectSum R _ _ _
+ (fun i => R ⧸ R ∙ p ^ @Option.rec _ (fun _ => ℕ) (p_order hN <| s j) k i) _
+ _).symm).trans <|
+ DirectSum.lequivCongrLeft R (finSuccEquiv d).symm⟩⟩
+ · rw [range_subtype, LinearEquiv.toLinearMap_eq_coe, LinearEquiv.ker_comp, ker_mkq]
+ · rw [LinearEquiv.toLinearMap_eq_coe, ← f.comp_coe, LinearMap.comp_assoc,
+ LinearMap.comp_assoc, ← LinearEquiv.toLinearMap_eq_coe,
+ LinearEquiv.toLinearMap_symm_comp_eq, LinearMap.comp_id, ← LinearMap.comp_assoc, ←
+ LinearMap.comp_assoc]
+ suffices (f.to_linear_map.comp (R ∙ s j).mkQ).comp _ = LinearMap.id by
+ rw [← f.to_linear_map_eq_coe, this, LinearMap.id_comp]
+ ext i : 3
+ simp only [LinearMap.coe_comp, Function.comp_apply, mkq_apply]
+ rw [LinearEquiv.coe_toLinearMap, LinearMap.id_apply, DirectSum.toModule_lof,
+ liftq_span_singleton_apply, LinearMap.toSpanSingleton_one, Ideal.Quotient.mk_eq_mk,
+ map_one, (this i).choose_spec.right]
+ ·
+ exact
+ (mk_surjective _).forall.mpr fun x =>
+ ⟨(@hN x).some, by rw [← quotient.mk_smul, (@hN x).choose_spec, quotient.mk_zero]⟩
+ · have hs' := congr_arg (Submodule.map <| mkq <| R ∙ s j) hs
+ rw [Submodule.map_span, Submodule.map_top, range_mkq] at hs' ; simp only [mkq_apply] at hs'
+ simp only [s']; rw [Set.range_comp (_ ∘ s), Fin.range_succAbove]
+ rw [← Set.range_comp, ← Set.insert_image_compl_eq_range _ j, Function.comp_apply,
+ (quotient.mk_eq_zero _).mpr (Submodule.mem_span_singleton_self _), span_insert_zero] at hs'
+ exact hs'
#align module.torsion_by_prime_power_decomposition Module.torsion_by_prime_power_decomposition
-/
@@ -217,6 +271,15 @@ theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTor
torsion_by_prime_power_decomposition (hp i)
((is_torsion'_powers_iff <| p i).mpr fun x => ⟨e i, smul_torsion_by _ _⟩)
classical
+ refine'
+ ⟨Σ i, Fin (this i).some, inferInstance, fun ⟨i, j⟩ => p i, fun ⟨i, j⟩ => hp i, fun ⟨i, j⟩ =>
+ (this i).choose_spec.some j,
+ ⟨(LinearEquiv.ofBijective (DirectSum.coeLinearMap _) h).symm.trans <|
+ (DFinsupp.mapRange.linearEquiv fun i => (this i).choose_spec.choose_spec.some).trans <|
+ (DirectSum.sigmaLcurryEquiv R).symm.trans
+ (DFinsupp.mapRange.linearEquiv fun i => quot_equiv_of_eq _ _ _)⟩⟩
+ cases' i with i j
+ simp only
#align module.equiv_direct_sum_of_is_torsion Module.equiv_directSum_of_isTorsion
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/65a1391a0106c9204fe45bc73a039f056558cb83
@@ -122,9 +122,7 @@ theorem Ideal.torsionOf_eq_span_pow_pOrder (x : M) : torsionOf R M x = span {p ^
(Associates.mk <| generator <| torsion_of R M x) ∣ Associates.mk p ^ n :=
by ext n; rw [← Associates.mk_pow, Associates.mk_dvd_mk, ← mem_iff_generator_dvd]; rfl
have := (is_torsion'_powers_iff p).mp hM x; rw [prop] at this
- classical convert
- Associates.eq_pow_find_of_dvd_irreducible_pow ((Associates.irreducible_mk p).mpr hp)
- this.some_spec
+ classical
#align ideal.torsion_of_eq_span_pow_p_order Ideal.torsionOf_eq_span_pow_pOrder
-/
@@ -194,58 +192,6 @@ theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoi
exact ⟨0⟩
· have : ∀ x : N, Decidable (x = 0)
classical
- infer_instance
- obtain ⟨j, hj⟩ := exists_is_torsion_by hN d.succ d.succ_ne_zero s hs
- let s' : Fin d → N ⧸ R ∙ s j := Submodule.Quotient.mk ∘ s ∘ j.succ_above
- obtain ⟨k, ⟨f⟩⟩ := IH _ s' _ <;> clear IH
- · have :
- ∀ i : Fin d,
- ∃ x : N, p ^ k i • x = 0 ∧ f (Submodule.Quotient.mk x) = DirectSum.lof R _ _ i 1 :=
- by
- intro i
- let fi := f.symm.to_linear_map.comp (DirectSum.lof _ _ _ i)
- obtain ⟨x, h0, h1⟩ := exists_smul_eq_zero_and_mk_eq hp hN hj fi; refine' ⟨x, h0, _⟩; rw [h1]
- simp only [LinearMap.coe_comp, f.symm.coe_to_linear_map, f.apply_symm_apply]
- refine'
- ⟨_,
- ⟨(((@lequivProdOfRightSplitExact _ _ _ _ _ _ _ _ _ _ _ _
- ((f.trans ULift.moduleEquiv.{u, u, v}.symm).toLinearMap.comp <| mkq _)
- ((DirectSum.toModule _ _ _ fun i =>
- (liftQSpanSingleton.{u, u} (p ^ k i)
- (LinearMap.toSpanSingleton _ _ _) (this i).choose_spec.left :
- R ⧸ _ →ₗ[R] _)).comp
- ulift.module_equiv.to_linear_map)
- (R ∙ s j).injective_subtype _ _).symm.trans <|
- ((quot_torsion_of_equiv_span_singleton _ _ _).symm.trans <|
- quot_equiv_of_eq _ _ <|
- Ideal.torsionOf_eq_span_pow_pOrder hp hN _).Prod <|
- ULift.moduleEquiv).trans <|
- (@DirectSum.lequivProdDirectSum R _ _ _
- (fun i => R ⧸ R ∙ p ^ @Option.rec _ (fun _ => ℕ) (p_order hN <| s j) k i) _
- _).symm).trans <|
- DirectSum.lequivCongrLeft R (finSuccEquiv d).symm⟩⟩
- · rw [range_subtype, LinearEquiv.toLinearMap_eq_coe, LinearEquiv.ker_comp, ker_mkq]
- · rw [LinearEquiv.toLinearMap_eq_coe, ← f.comp_coe, LinearMap.comp_assoc,
- LinearMap.comp_assoc, ← LinearEquiv.toLinearMap_eq_coe,
- LinearEquiv.toLinearMap_symm_comp_eq, LinearMap.comp_id, ← LinearMap.comp_assoc, ←
- LinearMap.comp_assoc]
- suffices (f.to_linear_map.comp (R ∙ s j).mkQ).comp _ = LinearMap.id by
- rw [← f.to_linear_map_eq_coe, this, LinearMap.id_comp]
- ext i : 3
- simp only [LinearMap.coe_comp, Function.comp_apply, mkq_apply]
- rw [LinearEquiv.coe_toLinearMap, LinearMap.id_apply, DirectSum.toModule_lof,
- liftq_span_singleton_apply, LinearMap.toSpanSingleton_one, Ideal.Quotient.mk_eq_mk,
- map_one, (this i).choose_spec.right]
- ·
- exact
- (mk_surjective _).forall.mpr fun x =>
- ⟨(@hN x).some, by rw [← quotient.mk_smul, (@hN x).choose_spec, quotient.mk_zero]⟩
- · have hs' := congr_arg (Submodule.map <| mkq <| R ∙ s j) hs
- rw [Submodule.map_span, Submodule.map_top, range_mkq] at hs' ; simp only [mkq_apply] at hs'
- simp only [s']; rw [Set.range_comp (_ ∘ s), Fin.range_succAbove]
- rw [← Set.range_comp, ← Set.insert_image_compl_eq_range _ j, Function.comp_apply,
- (quotient.mk_eq_zero _).mpr (Submodule.mem_span_singleton_self _), span_insert_zero] at hs'
- exact hs'
#align module.torsion_by_prime_power_decomposition Module.torsion_by_prime_power_decomposition
-/
@@ -271,15 +217,6 @@ theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTor
torsion_by_prime_power_decomposition (hp i)
((is_torsion'_powers_iff <| p i).mpr fun x => ⟨e i, smul_torsion_by _ _⟩)
classical
- refine'
- ⟨Σ i, Fin (this i).some, inferInstance, fun ⟨i, j⟩ => p i, fun ⟨i, j⟩ => hp i, fun ⟨i, j⟩ =>
- (this i).choose_spec.some j,
- ⟨(LinearEquiv.ofBijective (DirectSum.coeLinearMap _) h).symm.trans <|
- (DFinsupp.mapRange.linearEquiv fun i => (this i).choose_spec.choose_spec.some).trans <|
- (DirectSum.sigmaLcurryEquiv R).symm.trans
- (DFinsupp.mapRange.linearEquiv fun i => quot_equiv_of_eq _ _ _)⟩⟩
- cases' i with i j
- simp only
#align module.equiv_direct_sum_of_is_torsion Module.equiv_directSum_of_isTorsion
-/
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce64cd319bb6b3e82f31c2d38e79080d377be451
@@ -3,10 +3,10 @@ Copyright (c) 2022 Pierre-Alexandre Bazin. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Pierre-Alexandre Bazin
-/
-import Mathbin.Algebra.Module.DedekindDomain
-import Mathbin.LinearAlgebra.FreeModule.Pid
-import Mathbin.Algebra.Module.Projective
-import Mathbin.Algebra.Category.Module.Biproducts
+import Algebra.Module.DedekindDomain
+import LinearAlgebra.FreeModule.Pid
+import Algebra.Module.Projective
+import Algebra.Category.Module.Biproducts
#align_import algebra.module.pid from "leanprover-community/mathlib"@"1a51edf13debfcbe223fa06b1cb353b9ed9751cc"
mathlib commit https://github.com/leanprover-community/mathlib/commit/32a7e535287f9c73f2e4d2aef306a39190f0b504
@@ -265,7 +265,7 @@ theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTor
∃ (d : ℕ) (k : Fin d → ℕ),
Nonempty <| torsion_by R N (p i ^ e i) ≃ₗ[R] ⨁ j, R ⧸ R ∙ p i ^ k j :=
by
- haveI := isNoetherian_of_fg_of_noetherian' (module.finite_def.mp h')
+ haveI := isNoetherian_of_isNoetherianRing_of_finite (module.finite_def.mp h')
haveI := fun i => isNoetherian_submodule' (torsion_by R N <| p i ^ e i)
exact fun i =>
torsion_by_prime_power_decomposition (hp i)
@@ -291,7 +291,7 @@ theorem equiv_free_prod_directSum [h' : Module.Finite R N] :
∃ (n : ℕ) (ι : Type u) (_ : Fintype ι) (p : ι → R) (h : ∀ i, Irreducible <| p i) (e : ι → ℕ),
Nonempty <| N ≃ₗ[R] (Fin n →₀ R) × ⨁ i : ι, R ⧸ R ∙ p i ^ e i :=
by
- haveI := isNoetherian_of_fg_of_noetherian' (module.finite_def.mp h')
+ haveI := isNoetherian_of_isNoetherianRing_of_finite (module.finite_def.mp h')
haveI := isNoetherian_submodule' (torsion R N)
haveI := Module.Finite.of_surjective _ (torsion R N).mkQ_surjective
obtain ⟨I, fI, p, hp, e, ⟨h⟩⟩ := equiv_direct_sum_of_is_torsion (@torsion_is_torsion R N _ _ _)
mathlib commit https://github.com/leanprover-community/mathlib/commit/8ea5598db6caeddde6cb734aa179cc2408dbd345
@@ -2,17 +2,14 @@
Copyright (c) 2022 Pierre-Alexandre Bazin. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Pierre-Alexandre Bazin
-
-! This file was ported from Lean 3 source module algebra.module.pid
-! leanprover-community/mathlib commit 1a51edf13debfcbe223fa06b1cb353b9ed9751cc
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathbin.Algebra.Module.DedekindDomain
import Mathbin.LinearAlgebra.FreeModule.Pid
import Mathbin.Algebra.Module.Projective
import Mathbin.Algebra.Category.Module.Biproducts
+#align_import algebra.module.pid from "leanprover-community/mathlib"@"1a51edf13debfcbe223fa06b1cb353b9ed9751cc"
+
/-!
# Structure of finitely generated modules over a PID
mathlib commit https://github.com/leanprover-community/mathlib/commit/4e24c4bfcff371c71f7ba22050308aa17815626c
@@ -278,9 +278,9 @@ theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTor
⟨Σ i, Fin (this i).some, inferInstance, fun ⟨i, j⟩ => p i, fun ⟨i, j⟩ => hp i, fun ⟨i, j⟩ =>
(this i).choose_spec.some j,
⟨(LinearEquiv.ofBijective (DirectSum.coeLinearMap _) h).symm.trans <|
- (Dfinsupp.mapRange.linearEquiv fun i => (this i).choose_spec.choose_spec.some).trans <|
+ (DFinsupp.mapRange.linearEquiv fun i => (this i).choose_spec.choose_spec.some).trans <|
(DirectSum.sigmaLcurryEquiv R).symm.trans
- (Dfinsupp.mapRange.linearEquiv fun i => quot_equiv_of_eq _ _ _)⟩⟩
+ (DFinsupp.mapRange.linearEquiv fun i => quot_equiv_of_eq _ _ _)⟩⟩
cases' i with i j
simp only
#align module.equiv_direct_sum_of_is_torsion Module.equiv_directSum_of_isTorsion
mathlib commit https://github.com/leanprover-community/mathlib/commit/1a51edf13debfcbe223fa06b1cb353b9ed9751cc
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Pierre-Alexandre Bazin
! This file was ported from Lean 3 source module algebra.module.pid
-! leanprover-community/mathlib commit cdc34484a07418af43daf8198beaf5c00324bca8
+! leanprover-community/mathlib commit 1a51edf13debfcbe223fa06b1cb353b9ed9751cc
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -16,6 +16,9 @@ import Mathbin.Algebra.Category.Module.Biproducts
/-!
# Structure of finitely generated modules over a PID
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
## Main statements
* `module.equiv_direct_sum_of_is_torsion` : A finitely generated torsion module over a PID is
mathlib commit https://github.com/leanprover-community/mathlib/commit/5dc6092d09e5e489106865241986f7f2ad28d4c8
@@ -68,6 +68,7 @@ open Submodule
open UniqueFactorizationMonoid
+#print Submodule.isInternal_prime_power_torsion_of_pid /-
/-- A finitely generated torsion module over a PID is an internal direct sum of its
`p i ^ e i`-torsion submodules for some primes `p i` and numbers `e i`.-/
theorem Submodule.isInternal_prime_power_torsion_of_pid [Module.Finite R M]
@@ -81,7 +82,9 @@ theorem Submodule.isInternal_prime_power_torsion_of_pid [Module.Finite R M]
rw [← torsion_by_span_singleton_eq, Ideal.submodule_span_eq, ← Ideal.span_singleton_pow,
Ideal.span_singleton_generator]
#align submodule.is_internal_prime_power_torsion_of_pid Submodule.isInternal_prime_power_torsion_of_pid
+-/
+#print Submodule.exists_isInternal_prime_power_torsion_of_pid /-
/-- A finitely generated torsion module over a PID is an internal direct sum of its
`p i ^ e i`-torsion submodules for some primes `p i` and numbers `e i`.-/
theorem Submodule.exists_isInternal_prime_power_torsion_of_pid [Module.Finite R M]
@@ -96,6 +99,7 @@ theorem Submodule.exists_isInternal_prime_power_torsion_of_pid [Module.Finite R
haveI := Ideal.isPrime_of_prime hP
exact (is_principal.prime_generator_of_is_prime p hP.ne_zero).Irreducible
#align submodule.exists_is_internal_prime_power_torsion_of_pid Submodule.exists_isInternal_prime_power_torsion_of_pid
+-/
namespace Module
@@ -107,6 +111,7 @@ variable [dec : ∀ x : M, Decidable (x = 0)]
open Ideal Submodule.IsPrincipal
+#print Ideal.torsionOf_eq_span_pow_pOrder /-
theorem Ideal.torsionOf_eq_span_pow_pOrder (x : M) : torsionOf R M x = span {p ^ pOrder hM x} :=
by
dsimp only [p_order]
@@ -121,7 +126,9 @@ theorem Ideal.torsionOf_eq_span_pow_pOrder (x : M) : torsionOf R M x = span {p ^
Associates.eq_pow_find_of_dvd_irreducible_pow ((Associates.irreducible_mk p).mpr hp)
this.some_spec
#align ideal.torsion_of_eq_span_pow_p_order Ideal.torsionOf_eq_span_pow_pOrder
+-/
+#print Module.p_pow_smul_lift /-
theorem p_pow_smul_lift {x y : M} {k : ℕ} (hM' : Module.IsTorsionBy R M (p ^ pOrder hM y))
(h : p ^ k • x ∈ R ∙ y) : ∃ a : R, p ^ k • x = p ^ k • a • y :=
by
@@ -147,9 +154,11 @@ theorem p_pow_smul_lift {x y : M} {k : ℕ} (hM' : Module.IsTorsionBy R M (p ^ p
rw [zero_smul, smul_zero, ← Nat.sub_add_cancel (le_of_not_le hk), pow_add, mul_smul, hM',
smul_zero]
#align module.p_pow_smul_lift Module.p_pow_smul_lift
+-/
open Submodule.Quotient
+#print Module.exists_smul_eq_zero_and_mk_eq /-
theorem exists_smul_eq_zero_and_mk_eq {z : M} (hz : Module.IsTorsionBy R M (p ^ pOrder hM z))
{k : ℕ} (f : (R ⧸ R ∙ p ^ k) →ₗ[R] M ⧸ R ∙ z) :
∃ x : M, p ^ k • x = 0 ∧ Submodule.Quotient.mk x = f 1 :=
@@ -166,9 +175,11 @@ theorem exists_smul_eq_zero_and_mk_eq {z : M} (hz : Module.IsTorsionBy R M (p ^
rw [mk_sub, mk_smul, (quotient.mk_eq_zero _).mpr <| Submodule.mem_span_singleton_self _,
smul_zero, sub_zero, f1.some_spec]
#align module.exists_smul_eq_zero_and_mk_eq Module.exists_smul_eq_zero_and_mk_eq
+-/
open Finset Multiset
+#print Module.torsion_by_prime_power_decomposition /-
/-- A finitely generated `p ^ ∞`-torsion module over a PID is isomorphic to a direct sum of some
`R ⧸ R ∙ (p ^ e i)` for some `e i`.-/
theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoid.powers p))
@@ -236,9 +247,11 @@ theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoi
(quotient.mk_eq_zero _).mpr (Submodule.mem_span_singleton_self _), span_insert_zero] at hs'
exact hs'
#align module.torsion_by_prime_power_decomposition Module.torsion_by_prime_power_decomposition
+-/
end PTorsion
+#print Module.equiv_directSum_of_isTorsion /-
/-- A finitely generated torsion module over a PID is isomorphic to a direct sum of some
`R ⧸ R ∙ (p i ^ e i)` where the `p i ^ e i` are prime powers.-/
theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTorsion R N) :
@@ -268,7 +281,9 @@ theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTor
cases' i with i j
simp only
#align module.equiv_direct_sum_of_is_torsion Module.equiv_directSum_of_isTorsion
+-/
+#print Module.equiv_free_prod_directSum /-
/-- **Structure theorem of finitely generated modules over a PID** : A finitely generated
module over a PID is isomorphic to the product of a free module and a direct sum of some
`R ⧸ R ∙ (p i ^ e i)` where the `p i ^ e i` are prime powers.-/
@@ -289,6 +304,7 @@ theorem equiv_free_prod_directSum [h' : Module.Finite R N] :
(h.prod g).trans <| LinearEquiv.prodComm R _ _⟩⟩
rw [range_subtype, ker_mkq]
#align module.equiv_free_prod_direct_sum Module.equiv_free_prod_directSum
+-/
end Module
mathlib commit https://github.com/leanprover-community/mathlib/commit/9fb8964792b4237dac6200193a0d533f1b3f7423
@@ -107,10 +107,6 @@ variable [dec : ∀ x : M, Decidable (x = 0)]
open Ideal Submodule.IsPrincipal
-include dec
-
-include hp hM
-
theorem Ideal.torsionOf_eq_span_pow_pOrder (x : M) : torsionOf R M x = span {p ^ pOrder hM x} :=
by
dsimp only [p_order]
@@ -173,8 +169,6 @@ theorem exists_smul_eq_zero_and_mk_eq {z : M} (hz : Module.IsTorsionBy R M (p ^
open Finset Multiset
-omit dec hM
-
/-- A finitely generated `p ^ ∞`-torsion module over a PID is isomorphic to a direct sum of some
`R ⧸ R ∙ (p ^ e i)` for some `e i`.-/
theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoid.powers p))
mathlib commit https://github.com/leanprover-community/mathlib/commit/5f25c089cb34db4db112556f23c50d12da81b297
@@ -121,8 +121,9 @@ theorem Ideal.torsionOf_eq_span_pow_pOrder (x : M) : torsionOf R M x = span {p ^
(Associates.mk <| generator <| torsion_of R M x) ∣ Associates.mk p ^ n :=
by ext n; rw [← Associates.mk_pow, Associates.mk_dvd_mk, ← mem_iff_generator_dvd]; rfl
have := (is_torsion'_powers_iff p).mp hM x; rw [prop] at this
- classical convert Associates.eq_pow_find_of_dvd_irreducible_pow
- ((Associates.irreducible_mk p).mpr hp) this.some_spec
+ classical convert
+ Associates.eq_pow_find_of_dvd_irreducible_pow ((Associates.irreducible_mk p).mpr hp)
+ this.some_spec
#align ideal.torsion_of_eq_span_pow_p_order Ideal.torsionOf_eq_span_pow_pOrder
theorem p_pow_smul_lift {x y : M} {k : ℕ} (hM' : Module.IsTorsionBy R M (p ^ pOrder hM y))
@@ -188,61 +189,58 @@ theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoi
exact ⟨0⟩
· have : ∀ x : N, Decidable (x = 0)
classical
- infer_instance
- obtain ⟨j, hj⟩ := exists_is_torsion_by hN d.succ d.succ_ne_zero s hs
- let s' : Fin d → N ⧸ R ∙ s j := Submodule.Quotient.mk ∘ s ∘ j.succ_above
- obtain ⟨k, ⟨f⟩⟩ := IH _ s' _ <;> clear IH
- · have :
- ∀ i : Fin d,
- ∃ x : N, p ^ k i • x = 0 ∧ f (Submodule.Quotient.mk x) = DirectSum.lof R _ _ i 1 :=
- by
- intro i
- let fi := f.symm.to_linear_map.comp (DirectSum.lof _ _ _ i)
- obtain ⟨x, h0, h1⟩ := exists_smul_eq_zero_and_mk_eq hp hN hj fi; refine' ⟨x, h0, _⟩;
- rw [h1]
- simp only [LinearMap.coe_comp, f.symm.coe_to_linear_map, f.apply_symm_apply]
- refine'
- ⟨_,
- ⟨(((@lequivProdOfRightSplitExact _ _ _ _ _ _ _ _ _ _ _ _
- ((f.trans ULift.moduleEquiv.{u, u, v}.symm).toLinearMap.comp <| mkq _)
- ((DirectSum.toModule _ _ _ fun i =>
- (liftQSpanSingleton.{u, u} (p ^ k i)
- (LinearMap.toSpanSingleton _ _ _)
- (this i).choose_spec.left :
- R ⧸ _ →ₗ[R] _)).comp
- ulift.module_equiv.to_linear_map)
- (R ∙ s j).injective_subtype _ _).symm.trans <|
- ((quot_torsion_of_equiv_span_singleton _ _ _).symm.trans <|
- quot_equiv_of_eq _ _ <|
- Ideal.torsionOf_eq_span_pow_pOrder hp hN _).Prod <|
- ULift.moduleEquiv).trans <|
- (@DirectSum.lequivProdDirectSum R _ _ _
- (fun i => R ⧸ R ∙ p ^ @Option.rec _ (fun _ => ℕ) (p_order hN <| s j) k i) _
- _).symm).trans <|
- DirectSum.lequivCongrLeft R (finSuccEquiv d).symm⟩⟩
- · rw [range_subtype, LinearEquiv.toLinearMap_eq_coe, LinearEquiv.ker_comp, ker_mkq]
- · rw [LinearEquiv.toLinearMap_eq_coe, ← f.comp_coe, LinearMap.comp_assoc,
- LinearMap.comp_assoc, ← LinearEquiv.toLinearMap_eq_coe,
- LinearEquiv.toLinearMap_symm_comp_eq, LinearMap.comp_id, ← LinearMap.comp_assoc, ←
- LinearMap.comp_assoc]
- suffices (f.to_linear_map.comp (R ∙ s j).mkQ).comp _ = LinearMap.id by
- rw [← f.to_linear_map_eq_coe, this, LinearMap.id_comp]
- ext i : 3
- simp only [LinearMap.coe_comp, Function.comp_apply, mkq_apply]
- rw [LinearEquiv.coe_toLinearMap, LinearMap.id_apply, DirectSum.toModule_lof,
- liftq_span_singleton_apply, LinearMap.toSpanSingleton_one, Ideal.Quotient.mk_eq_mk,
- map_one, (this i).choose_spec.right]
- ·
- exact
- (mk_surjective _).forall.mpr fun x =>
- ⟨(@hN x).some, by rw [← quotient.mk_smul, (@hN x).choose_spec, quotient.mk_zero]⟩
- · have hs' := congr_arg (Submodule.map <| mkq <| R ∙ s j) hs
- rw [Submodule.map_span, Submodule.map_top, range_mkq] at hs' ; simp only [mkq_apply] at hs'
- simp only [s']; rw [Set.range_comp (_ ∘ s), Fin.range_succAbove]
- rw [← Set.range_comp, ← Set.insert_image_compl_eq_range _ j, Function.comp_apply,
- (quotient.mk_eq_zero _).mpr (Submodule.mem_span_singleton_self _), span_insert_zero] at
- hs'
- exact hs'
+ infer_instance
+ obtain ⟨j, hj⟩ := exists_is_torsion_by hN d.succ d.succ_ne_zero s hs
+ let s' : Fin d → N ⧸ R ∙ s j := Submodule.Quotient.mk ∘ s ∘ j.succ_above
+ obtain ⟨k, ⟨f⟩⟩ := IH _ s' _ <;> clear IH
+ · have :
+ ∀ i : Fin d,
+ ∃ x : N, p ^ k i • x = 0 ∧ f (Submodule.Quotient.mk x) = DirectSum.lof R _ _ i 1 :=
+ by
+ intro i
+ let fi := f.symm.to_linear_map.comp (DirectSum.lof _ _ _ i)
+ obtain ⟨x, h0, h1⟩ := exists_smul_eq_zero_and_mk_eq hp hN hj fi; refine' ⟨x, h0, _⟩; rw [h1]
+ simp only [LinearMap.coe_comp, f.symm.coe_to_linear_map, f.apply_symm_apply]
+ refine'
+ ⟨_,
+ ⟨(((@lequivProdOfRightSplitExact _ _ _ _ _ _ _ _ _ _ _ _
+ ((f.trans ULift.moduleEquiv.{u, u, v}.symm).toLinearMap.comp <| mkq _)
+ ((DirectSum.toModule _ _ _ fun i =>
+ (liftQSpanSingleton.{u, u} (p ^ k i)
+ (LinearMap.toSpanSingleton _ _ _) (this i).choose_spec.left :
+ R ⧸ _ →ₗ[R] _)).comp
+ ulift.module_equiv.to_linear_map)
+ (R ∙ s j).injective_subtype _ _).symm.trans <|
+ ((quot_torsion_of_equiv_span_singleton _ _ _).symm.trans <|
+ quot_equiv_of_eq _ _ <|
+ Ideal.torsionOf_eq_span_pow_pOrder hp hN _).Prod <|
+ ULift.moduleEquiv).trans <|
+ (@DirectSum.lequivProdDirectSum R _ _ _
+ (fun i => R ⧸ R ∙ p ^ @Option.rec _ (fun _ => ℕ) (p_order hN <| s j) k i) _
+ _).symm).trans <|
+ DirectSum.lequivCongrLeft R (finSuccEquiv d).symm⟩⟩
+ · rw [range_subtype, LinearEquiv.toLinearMap_eq_coe, LinearEquiv.ker_comp, ker_mkq]
+ · rw [LinearEquiv.toLinearMap_eq_coe, ← f.comp_coe, LinearMap.comp_assoc,
+ LinearMap.comp_assoc, ← LinearEquiv.toLinearMap_eq_coe,
+ LinearEquiv.toLinearMap_symm_comp_eq, LinearMap.comp_id, ← LinearMap.comp_assoc, ←
+ LinearMap.comp_assoc]
+ suffices (f.to_linear_map.comp (R ∙ s j).mkQ).comp _ = LinearMap.id by
+ rw [← f.to_linear_map_eq_coe, this, LinearMap.id_comp]
+ ext i : 3
+ simp only [LinearMap.coe_comp, Function.comp_apply, mkq_apply]
+ rw [LinearEquiv.coe_toLinearMap, LinearMap.id_apply, DirectSum.toModule_lof,
+ liftq_span_singleton_apply, LinearMap.toSpanSingleton_one, Ideal.Quotient.mk_eq_mk,
+ map_one, (this i).choose_spec.right]
+ ·
+ exact
+ (mk_surjective _).forall.mpr fun x =>
+ ⟨(@hN x).some, by rw [← quotient.mk_smul, (@hN x).choose_spec, quotient.mk_zero]⟩
+ · have hs' := congr_arg (Submodule.map <| mkq <| R ∙ s j) hs
+ rw [Submodule.map_span, Submodule.map_top, range_mkq] at hs' ; simp only [mkq_apply] at hs'
+ simp only [s']; rw [Set.range_comp (_ ∘ s), Fin.range_succAbove]
+ rw [← Set.range_comp, ← Set.insert_image_compl_eq_range _ j, Function.comp_apply,
+ (quotient.mk_eq_zero _).mpr (Submodule.mem_span_singleton_self _), span_insert_zero] at hs'
+ exact hs'
#align module.torsion_by_prime_power_decomposition Module.torsion_by_prime_power_decomposition
end PTorsion
@@ -266,15 +264,15 @@ theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTor
torsion_by_prime_power_decomposition (hp i)
((is_torsion'_powers_iff <| p i).mpr fun x => ⟨e i, smul_torsion_by _ _⟩)
classical
- refine'
- ⟨Σ i, Fin (this i).some, inferInstance, fun ⟨i, j⟩ => p i, fun ⟨i, j⟩ => hp i, fun ⟨i, j⟩ =>
- (this i).choose_spec.some j,
- ⟨(LinearEquiv.ofBijective (DirectSum.coeLinearMap _) h).symm.trans <|
- (Dfinsupp.mapRange.linearEquiv fun i => (this i).choose_spec.choose_spec.some).trans <|
- (DirectSum.sigmaLcurryEquiv R).symm.trans
- (Dfinsupp.mapRange.linearEquiv fun i => quot_equiv_of_eq _ _ _)⟩⟩
- cases' i with i j
- simp only
+ refine'
+ ⟨Σ i, Fin (this i).some, inferInstance, fun ⟨i, j⟩ => p i, fun ⟨i, j⟩ => hp i, fun ⟨i, j⟩ =>
+ (this i).choose_spec.some j,
+ ⟨(LinearEquiv.ofBijective (DirectSum.coeLinearMap _) h).symm.trans <|
+ (Dfinsupp.mapRange.linearEquiv fun i => (this i).choose_spec.choose_spec.some).trans <|
+ (DirectSum.sigmaLcurryEquiv R).symm.trans
+ (Dfinsupp.mapRange.linearEquiv fun i => quot_equiv_of_eq _ _ _)⟩⟩
+ cases' i with i j
+ simp only
#align module.equiv_direct_sum_of_is_torsion Module.equiv_directSum_of_isTorsion
/-- **Structure theorem of finitely generated modules over a PID** : A finitely generated
mathlib commit https://github.com/leanprover-community/mathlib/commit/cca40788df1b8755d5baf17ab2f27dacc2e17acb
@@ -86,8 +86,8 @@ theorem Submodule.isInternal_prime_power_torsion_of_pid [Module.Finite R M]
`p i ^ e i`-torsion submodules for some primes `p i` and numbers `e i`.-/
theorem Submodule.exists_isInternal_prime_power_torsion_of_pid [Module.Finite R M]
(hM : Module.IsTorsion R M) :
- ∃ (ι : Type u)(_ : Fintype ι)(_ : DecidableEq ι)(p : ι → R)(h : ∀ i, Irreducible <| p i)(e :
- ι → ℕ), DirectSum.IsInternal fun i => torsion_by R M <| p i ^ e i :=
+ ∃ (ι : Type u) (_ : Fintype ι) (_ : DecidableEq ι) (p : ι → R) (h : ∀ i, Irreducible <| p i) (e
+ : ι → ℕ), DirectSum.IsInternal fun i => torsion_by R M <| p i ^ e i :=
by
refine' ⟨_, _, _, _, _, _, Submodule.isInternal_prime_power_torsion_of_pid hM⟩
exact Finset.fintypeCoeSort _
@@ -120,7 +120,7 @@ theorem Ideal.torsionOf_eq_span_pow_pOrder (x : M) : torsionOf R M x = span {p ^
(fun n : ℕ => p ^ n • x = 0) = fun n : ℕ =>
(Associates.mk <| generator <| torsion_of R M x) ∣ Associates.mk p ^ n :=
by ext n; rw [← Associates.mk_pow, Associates.mk_dvd_mk, ← mem_iff_generator_dvd]; rfl
- have := (is_torsion'_powers_iff p).mp hM x; rw [prop] at this
+ have := (is_torsion'_powers_iff p).mp hM x; rw [prop] at this
classical convert Associates.eq_pow_find_of_dvd_irreducible_pow
((Associates.irreducible_mk p).mpr hp) this.some_spec
#align ideal.torsion_of_eq_span_pow_p_order Ideal.torsionOf_eq_span_pow_pOrder
@@ -139,10 +139,10 @@ theorem p_pow_smul_lift {x y : M} {k : ℕ} (hM' : Module.IsTorsionBy R M (p ^ p
convert f.symm.map_zero; ext
rw [coe_smul_of_tower, coe_mk, coe_zero, smul_smul, ← pow_add, Nat.sub_add_cancel hk, @hM' x]
· exact mem_nonZeroDivisors_of_ne_zero (pow_ne_zero _ hp.ne_zero)
- rw [Submodule.mem_span_singleton] at this; obtain ⟨a, ha⟩ := this; use a
- rw [f.eq_symm_apply, ← Ideal.Quotient.mk_eq_mk, ← quotient.mk_smul] at ha
+ rw [Submodule.mem_span_singleton] at this ; obtain ⟨a, ha⟩ := this; use a
+ rw [f.eq_symm_apply, ← Ideal.Quotient.mk_eq_mk, ← quotient.mk_smul] at ha
dsimp only [smul_eq_mul, f, LinearEquiv.trans_apply, Submodule.quotEquivOfEq_mk,
- quot_torsion_of_equiv_span_singleton_apply_mk] at ha
+ quot_torsion_of_equiv_span_singleton_apply_mk] at ha
rw [smul_smul, mul_comm]; exact congr_arg coe ha.symm
· symm; convert Ideal.torsionOf_eq_span_pow_pOrder hp hM y
rw [← pow_add, Nat.sub_add_cancel hk]
@@ -178,12 +178,12 @@ omit dec hM
`R ⧸ R ∙ (p ^ e i)` for some `e i`.-/
theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoid.powers p))
[h' : Module.Finite R N] :
- ∃ (d : ℕ)(k : Fin d → ℕ), Nonempty <| N ≃ₗ[R] ⨁ i : Fin d, R ⧸ R ∙ p ^ (k i : ℕ) :=
+ ∃ (d : ℕ) (k : Fin d → ℕ), Nonempty <| N ≃ₗ[R] ⨁ i : Fin d, R ⧸ R ∙ p ^ (k i : ℕ) :=
by
obtain ⟨d, s, hs⟩ := @Module.Finite.exists_fin _ _ _ _ _ h'; use d; clear h'
induction' d with d IH generalizing N
· use fun i => finZeroElim i
- rw [Set.range_eq_empty, Submodule.span_empty] at hs
+ rw [Set.range_eq_empty, Submodule.span_empty] at hs
haveI : Unique N := ⟨⟨0⟩, fun x => by rw [← mem_bot _, hs]; trivial⟩
exact ⟨0⟩
· have : ∀ x : N, Decidable (x = 0)
@@ -237,11 +237,11 @@ theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoi
(mk_surjective _).forall.mpr fun x =>
⟨(@hN x).some, by rw [← quotient.mk_smul, (@hN x).choose_spec, quotient.mk_zero]⟩
· have hs' := congr_arg (Submodule.map <| mkq <| R ∙ s j) hs
- rw [Submodule.map_span, Submodule.map_top, range_mkq] at hs'; simp only [mkq_apply] at hs'
+ rw [Submodule.map_span, Submodule.map_top, range_mkq] at hs' ; simp only [mkq_apply] at hs'
simp only [s']; rw [Set.range_comp (_ ∘ s), Fin.range_succAbove]
rw [← Set.range_comp, ← Set.insert_image_compl_eq_range _ j, Function.comp_apply,
(quotient.mk_eq_zero _).mpr (Submodule.mem_span_singleton_self _), span_insert_zero] at
- hs'
+ hs'
exact hs'
#align module.torsion_by_prime_power_decomposition Module.torsion_by_prime_power_decomposition
@@ -250,14 +250,14 @@ end PTorsion
/-- A finitely generated torsion module over a PID is isomorphic to a direct sum of some
`R ⧸ R ∙ (p i ^ e i)` where the `p i ^ e i` are prime powers.-/
theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTorsion R N) :
- ∃ (ι : Type u)(_ : Fintype ι)(p : ι → R)(h : ∀ i, Irreducible <| p i)(e : ι → ℕ),
+ ∃ (ι : Type u) (_ : Fintype ι) (p : ι → R) (h : ∀ i, Irreducible <| p i) (e : ι → ℕ),
Nonempty <| N ≃ₗ[R] ⨁ i : ι, R ⧸ R ∙ p i ^ e i :=
by
obtain ⟨I, fI, _, p, hp, e, h⟩ := Submodule.exists_isInternal_prime_power_torsion_of_pid hN
haveI := fI
have :
∀ i,
- ∃ (d : ℕ)(k : Fin d → ℕ),
+ ∃ (d : ℕ) (k : Fin d → ℕ),
Nonempty <| torsion_by R N (p i ^ e i) ≃ₗ[R] ⨁ j, R ⧸ R ∙ p i ^ k j :=
by
haveI := isNoetherian_of_fg_of_noetherian' (module.finite_def.mp h')
@@ -267,7 +267,7 @@ theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTor
((is_torsion'_powers_iff <| p i).mpr fun x => ⟨e i, smul_torsion_by _ _⟩)
classical
refine'
- ⟨Σi, Fin (this i).some, inferInstance, fun ⟨i, j⟩ => p i, fun ⟨i, j⟩ => hp i, fun ⟨i, j⟩ =>
+ ⟨Σ i, Fin (this i).some, inferInstance, fun ⟨i, j⟩ => p i, fun ⟨i, j⟩ => hp i, fun ⟨i, j⟩ =>
(this i).choose_spec.some j,
⟨(LinearEquiv.ofBijective (DirectSum.coeLinearMap _) h).symm.trans <|
(Dfinsupp.mapRange.linearEquiv fun i => (this i).choose_spec.choose_spec.some).trans <|
@@ -281,7 +281,7 @@ theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTor
module over a PID is isomorphic to the product of a free module and a direct sum of some
`R ⧸ R ∙ (p i ^ e i)` where the `p i ^ e i` are prime powers.-/
theorem equiv_free_prod_directSum [h' : Module.Finite R N] :
- ∃ (n : ℕ)(ι : Type u)(_ : Fintype ι)(p : ι → R)(h : ∀ i, Irreducible <| p i)(e : ι → ℕ),
+ ∃ (n : ℕ) (ι : Type u) (_ : Fintype ι) (p : ι → R) (h : ∀ i, Irreducible <| p i) (e : ι → ℕ),
Nonempty <| N ≃ₗ[R] (Fin n →₀ R) × ⨁ i : ι, R ⧸ R ∙ p i ^ e i :=
by
haveI := isNoetherian_of_fg_of_noetherian' (module.finite_def.mp h')
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -54,7 +54,7 @@ Finitely generated module, principal ideal domain, classification, structure the
universe u v
-open BigOperators Classical
+open scoped BigOperators Classical
variable {R : Type u} [CommRing R] [IsDomain R] [IsPrincipalIdealRing R]
@@ -62,7 +62,7 @@ variable {M : Type v} [AddCommGroup M] [Module R M]
variable {N : Type max u v} [AddCommGroup N] [Module R N]
-open DirectSum
+open scoped DirectSum
open Submodule
mathlib commit https://github.com/leanprover-community/mathlib/commit/917c3c072e487b3cccdbfeff17e75b40e45f66cb
@@ -119,12 +119,8 @@ theorem Ideal.torsionOf_eq_span_pow_pOrder (x : M) : torsionOf R M x = span {p ^
have prop :
(fun n : ℕ => p ^ n • x = 0) = fun n : ℕ =>
(Associates.mk <| generator <| torsion_of R M x) ∣ Associates.mk p ^ n :=
- by
- ext n
- rw [← Associates.mk_pow, Associates.mk_dvd_mk, ← mem_iff_generator_dvd]
- rfl
- have := (is_torsion'_powers_iff p).mp hM x
- rw [prop] at this
+ by ext n; rw [← Associates.mk_pow, Associates.mk_dvd_mk, ← mem_iff_generator_dvd]; rfl
+ have := (is_torsion'_powers_iff p).mp hM x; rw [prop] at this
classical convert Associates.eq_pow_find_of_dvd_irreducible_pow
((Associates.irreducible_mk p).mpr hp) this.some_spec
#align ideal.torsion_of_eq_span_pow_p_order Ideal.torsionOf_eq_span_pow_pOrder
@@ -140,22 +136,17 @@ theorem p_pow_smul_lift {x y : M} {k : ℕ} (hM' : Module.IsTorsionBy R M (p ^ p
f.symm ⟨p ^ k • x, h⟩ ∈ R ∙ Ideal.Quotient.mk (R ∙ p ^ (p_order hM y - k) * p ^ k) (p ^ k) :=
by
rw [← quotient.torsion_by_eq_span_singleton, mem_torsion_by_iff, ← f.symm.map_smul]
- convert f.symm.map_zero
- ext
+ convert f.symm.map_zero; ext
rw [coe_smul_of_tower, coe_mk, coe_zero, smul_smul, ← pow_add, Nat.sub_add_cancel hk, @hM' x]
· exact mem_nonZeroDivisors_of_ne_zero (pow_ne_zero _ hp.ne_zero)
- rw [Submodule.mem_span_singleton] at this
- obtain ⟨a, ha⟩ := this
- use a
+ rw [Submodule.mem_span_singleton] at this; obtain ⟨a, ha⟩ := this; use a
rw [f.eq_symm_apply, ← Ideal.Quotient.mk_eq_mk, ← quotient.mk_smul] at ha
dsimp only [smul_eq_mul, f, LinearEquiv.trans_apply, Submodule.quotEquivOfEq_mk,
quot_torsion_of_equiv_span_singleton_apply_mk] at ha
- rw [smul_smul, mul_comm]
- exact congr_arg coe ha.symm
- · symm
- convert Ideal.torsionOf_eq_span_pow_pOrder hp hM y
+ rw [smul_smul, mul_comm]; exact congr_arg coe ha.symm
+ · symm; convert Ideal.torsionOf_eq_span_pow_pOrder hp hM y
rw [← pow_add, Nat.sub_add_cancel hk]
- · use 0
+ · use 0;
rw [zero_smul, smul_zero, ← Nat.sub_add_cancel (le_of_not_le hk), pow_add, mul_smul, hM',
smul_zero]
#align module.p_pow_smul_lift Module.p_pow_smul_lift
@@ -170,8 +161,7 @@ theorem exists_smul_eq_zero_and_mk_eq {z : M} (hz : Module.IsTorsionBy R M (p ^
have : p ^ k • f1.some ∈ R ∙ z :=
by
rw [← quotient.mk_eq_zero, mk_smul, f1.some_spec, ← f.map_smul]
- convert f.map_zero
- change _ • Submodule.Quotient.mk _ = _
+ convert f.map_zero; change _ • Submodule.Quotient.mk _ = _
rw [← mk_smul, quotient.mk_eq_zero, Algebra.id.smul_eq_mul, mul_one]
exact Submodule.mem_span_singleton_self _
obtain ⟨a, ha⟩ := p_pow_smul_lift hp hM hz this
@@ -194,10 +184,7 @@ theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoi
induction' d with d IH generalizing N
· use fun i => finZeroElim i
rw [Set.range_eq_empty, Submodule.span_empty] at hs
- haveI : Unique N :=
- ⟨⟨0⟩, fun x => by
- rw [← mem_bot _, hs]
- trivial⟩
+ haveI : Unique N := ⟨⟨0⟩, fun x => by rw [← mem_bot _, hs]; trivial⟩
exact ⟨0⟩
· have : ∀ x : N, Decidable (x = 0)
classical
@@ -211,8 +198,7 @@ theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoi
by
intro i
let fi := f.symm.to_linear_map.comp (DirectSum.lof _ _ _ i)
- obtain ⟨x, h0, h1⟩ := exists_smul_eq_zero_and_mk_eq hp hN hj fi
- refine' ⟨x, h0, _⟩
+ obtain ⟨x, h0, h1⟩ := exists_smul_eq_zero_and_mk_eq hp hN hj fi; refine' ⟨x, h0, _⟩;
rw [h1]
simp only [LinearMap.coe_comp, f.symm.coe_to_linear_map, f.apply_symm_apply]
refine'
@@ -251,10 +237,8 @@ theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoi
(mk_surjective _).forall.mpr fun x =>
⟨(@hN x).some, by rw [← quotient.mk_smul, (@hN x).choose_spec, quotient.mk_zero]⟩
· have hs' := congr_arg (Submodule.map <| mkq <| R ∙ s j) hs
- rw [Submodule.map_span, Submodule.map_top, range_mkq] at hs'
- simp only [mkq_apply] at hs'
- simp only [s']
- rw [Set.range_comp (_ ∘ s), Fin.range_succAbove]
+ rw [Submodule.map_span, Submodule.map_top, range_mkq] at hs'; simp only [mkq_apply] at hs'
+ simp only [s']; rw [Set.range_comp (_ ∘ s), Fin.range_succAbove]
rw [← Set.range_comp, ← Set.insert_image_compl_eq_range _ j, Function.comp_apply,
(quotient.mk_eq_zero _).mpr (Submodule.mem_span_singleton_self _), span_insert_zero] at
hs'
mathlib commit https://github.com/leanprover-community/mathlib/commit/246f6f7989ff86bd07e1b014846f11304f33cf9e
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Pierre-Alexandre Bazin
! This file was ported from Lean 3 source module algebra.module.pid
-! leanprover-community/mathlib commit f62c15c01a5409b31b97a82d79a12980be4eff35
+! leanprover-community/mathlib commit cdc34484a07418af43daf8198beaf5c00324bca8
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -54,7 +54,7 @@ Finitely generated module, principal ideal domain, classification, structure the
universe u v
-open BigOperators
+open BigOperators Classical
variable {R : Type u} [CommRing R] [IsDomain R] [IsPrincipalIdealRing R]
@@ -66,23 +66,36 @@ open DirectSum
open Submodule
+open UniqueFactorizationMonoid
+
/-- A finitely generated torsion module over a PID is an internal direct sum of its
`p i ^ e i`-torsion submodules for some primes `p i` and numbers `e i`.-/
theorem Submodule.isInternal_prime_power_torsion_of_pid [Module.Finite R M]
+ (hM : Module.IsTorsion R M) :
+ DirectSum.IsInternal fun p : (factors (⊤ : Submodule R M).annihilator).toFinset =>
+ torsionBy R M
+ (IsPrincipal.generator (p : Ideal R) ^ (factors (⊤ : Submodule R M).annihilator).count p) :=
+ by
+ convert is_internal_prime_power_torsion hM
+ ext p : 1
+ rw [← torsion_by_span_singleton_eq, Ideal.submodule_span_eq, ← Ideal.span_singleton_pow,
+ Ideal.span_singleton_generator]
+#align submodule.is_internal_prime_power_torsion_of_pid Submodule.isInternal_prime_power_torsion_of_pid
+
+/-- A finitely generated torsion module over a PID is an internal direct sum of its
+`p i ^ e i`-torsion submodules for some primes `p i` and numbers `e i`.-/
+theorem Submodule.exists_isInternal_prime_power_torsion_of_pid [Module.Finite R M]
(hM : Module.IsTorsion R M) :
∃ (ι : Type u)(_ : Fintype ι)(_ : DecidableEq ι)(p : ι → R)(h : ∀ i, Irreducible <| p i)(e :
ι → ℕ), DirectSum.IsInternal fun i => torsion_by R M <| p i ^ e i :=
by
- obtain ⟨P, dec, hP, e, this⟩ := is_internal_prime_power_torsion hM
- refine' ⟨P, inferInstance, dec, fun p => is_principal.generator (p : Ideal R), _, e, _⟩
+ refine' ⟨_, _, _, _, _, _, Submodule.isInternal_prime_power_torsion_of_pid hM⟩
+ exact Finset.fintypeCoeSort _
· rintro ⟨p, hp⟩
- haveI := Ideal.isPrime_of_prime (hP p hp)
- exact (is_principal.prime_generator_of_is_prime p (hP p hp).NeZero).Irreducible
- · convert this
- ext p : 1
- rw [← torsion_by_span_singleton_eq, Ideal.submodule_span_eq, ← Ideal.span_singleton_pow,
- Ideal.span_singleton_generator]
-#align submodule.is_internal_prime_power_torsion_of_pid Submodule.isInternal_prime_power_torsion_of_pid
+ have hP := prime_of_factor p (multiset.mem_to_finset.mp hp)
+ haveI := Ideal.isPrime_of_prime hP
+ exact (is_principal.prime_generator_of_is_prime p hP.ne_zero).Irreducible
+#align submodule.exists_is_internal_prime_power_torsion_of_pid Submodule.exists_isInternal_prime_power_torsion_of_pid
namespace Module
@@ -256,7 +269,7 @@ theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTor
∃ (ι : Type u)(_ : Fintype ι)(p : ι → R)(h : ∀ i, Irreducible <| p i)(e : ι → ℕ),
Nonempty <| N ≃ₗ[R] ⨁ i : ι, R ⧸ R ∙ p i ^ e i :=
by
- obtain ⟨I, fI, _, p, hp, e, h⟩ := Submodule.isInternal_prime_power_torsion_of_pid hN
+ obtain ⟨I, fI, _, p, hp, e, h⟩ := Submodule.exists_isInternal_prime_power_torsion_of_pid hN
haveI := fI
have :
∀ i,
mathlib commit https://github.com/leanprover-community/mathlib/commit/e05ead7993520a432bec94ac504842d90707ad63
@@ -292,7 +292,7 @@ theorem equiv_free_prod_directSum [h' : Module.Finite R N] :
haveI := Module.Finite.of_surjective _ (torsion R N).mkQ_surjective
obtain ⟨I, fI, p, hp, e, ⟨h⟩⟩ := equiv_direct_sum_of_is_torsion (@torsion_is_torsion R N _ _ _)
obtain ⟨n, ⟨g⟩⟩ := @Module.basisOfFiniteTypeTorsionFree' R _ _ _ (N ⧸ torsion R N) _ _ _ _
- haveI : Module.Projective R (N ⧸ torsion R N) := Module.projectiveOfBasis ⟨g⟩
+ haveI : Module.Projective R (N ⧸ torsion R N) := Module.Projective.of_basis ⟨g⟩
obtain ⟨f, hf⟩ := Module.projective_lifting_property _ LinearMap.id (torsion R N).mkQ_surjective
refine'
⟨n, I, fI, p, hp, e,
mathlib commit https://github.com/leanprover-community/mathlib/commit/ce7e9d53d4bbc38065db3b595cd5bd73c323bc1d
@@ -112,9 +112,8 @@ theorem Ideal.torsionOf_eq_span_pow_pOrder (x : M) : torsionOf R M x = span {p ^
rfl
have := (is_torsion'_powers_iff p).mp hM x
rw [prop] at this
- classical convert
- Associates.eq_pow_find_of_dvd_irreducible_pow ((Associates.irreducible_mk p).mpr hp)
- this.some_spec
+ classical convert Associates.eq_pow_find_of_dvd_irreducible_pow
+ ((Associates.irreducible_mk p).mpr hp) this.some_spec
#align ideal.torsion_of_eq_span_pow_p_order Ideal.torsionOf_eq_span_pow_pOrder
theorem p_pow_smul_lift {x y : M} {k : ℕ} (hM' : Module.IsTorsionBy R M (p ^ pOrder hM y))
mathlib commit https://github.com/leanprover-community/mathlib/commit/62e8311c791f02c47451bf14aa2501048e7c2f33
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
Authors: Pierre-Alexandre Bazin
! This file was ported from Lean 3 source module algebra.module.pid
-! leanprover-community/mathlib commit 6623e6af705e97002a9054c1c05a980180276fc1
+! leanprover-community/mathlib commit f62c15c01a5409b31b97a82d79a12980be4eff35
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
@@ -292,7 +292,7 @@ theorem equiv_free_prod_directSum [h' : Module.Finite R N] :
haveI := isNoetherian_submodule' (torsion R N)
haveI := Module.Finite.of_surjective _ (torsion R N).mkQ_surjective
obtain ⟨I, fI, p, hp, e, ⟨h⟩⟩ := equiv_direct_sum_of_is_torsion (@torsion_is_torsion R N _ _ _)
- obtain ⟨n, ⟨g⟩⟩ := @Module.freeOfFiniteTypeTorsionFree' R _ _ _ (N ⧸ torsion R N) _ _ _ _
+ obtain ⟨n, ⟨g⟩⟩ := @Module.basisOfFiniteTypeTorsionFree' R _ _ _ (N ⧸ torsion R N) _ _ _ _
haveI : Module.Projective R (N ⧸ torsion R N) := Module.projectiveOfBasis ⟨g⟩
obtain ⟨f, hf⟩ := Module.projective_lifting_property _ LinearMap.id (torsion R N).mkQ_surjective
refine'
mathlib commit https://github.com/leanprover-community/mathlib/commit/bd9851ca476957ea4549eb19b40e7b5ade9428cc
simp
tags or simp
lemmasassociated_one_iff_isUnit
, associated_zero_iff_eq_zero
,
Associates.mk_eq_one
, Associates.mk_dvd_mk
,
Associates.mk_isRelPrime_iff
, Associates.mk_zero
,
Associates.quot_out_zero
, Associates.le_zero
,
Associates.prime_mk
, Associates.irreducible_mk
,
Associates.mk_dvdNotUnit_mk_iff
, Associates.factors_le
,
Associates.prod_factors
gcongr
tagsAssociates.factors_mono
, Associates.prod_mono
Associates.prime_mk
, Associates.irreducible_mk
,
Associates.one_or_eq_of_le_of_prime
[Nontrivial _]
here and there,
mostly in cases when a lemma has _ ≠ _
assumptionAssociates.FactorSetMem
WithTop
APIUse WithTop.some
and ⊤
instead of Option.some
and none
in UniqueFactorizationDomain
.
Associates.isPrimal_iff
→ Associates.isPrimal_mk
;Associates.mk_le_mk_iff_dvd_iff
→ Associates.mk_le_mk_iff_dvd
;Associates.factors_0
→ Associates.factors_zero
;Associates.factors_eq_none_iff_zero
→
Associates.factors_eq_top_iff_zero
@@ -119,10 +119,8 @@ theorem _root_.Ideal.torsionOf_eq_span_pow_pOrder (x : M) :
(Associates.mk <| generator <| torsionOf R M x) ∣ Associates.mk p ^ n :=
by ext n; rw [← Associates.mk_pow, Associates.mk_dvd_mk, ← mem_iff_generator_dvd]; rfl
have := (isTorsion'_powers_iff p).mp hM x; rw [prop] at this
- classical
- convert
- Associates.eq_pow_find_of_dvd_irreducible_pow ((Associates.irreducible_mk p).mpr hp)
- this.choose_spec
+ convert Associates.eq_pow_find_of_dvd_irreducible_pow (Associates.irreducible_mk.mpr hp)
+ this.choose_spec
#align ideal.torsion_of_eq_span_pow_p_order Ideal.torsionOf_eq_span_pow_pOrder
theorem p_pow_smul_lift {x y : M} {k : ℕ} (hM' : Module.IsTorsionBy R M (p ^ pOrder hM y))
Purely automatic replacement. If this is in any way controversial; I'm happy to just close this PR.
@@ -73,7 +73,7 @@ theorem Submodule.isSemisimple_torsionBy_of_irreducible {a : R} (h : Irreducible
exact Module.Submodule.complementedLattice
/-- A finitely generated torsion module over a PID is an internal direct sum of its
-`p i ^ e i`-torsion submodules for some primes `p i` and numbers `e i`.-/
+`p i ^ e i`-torsion submodules for some primes `p i` and numbers `e i`. -/
theorem Submodule.isInternal_prime_power_torsion_of_pid [Module.Finite R M]
(hM : Module.IsTorsion R M) :
DirectSum.IsInternal fun p : (factors (⊤ : Submodule R M).annihilator).toFinset =>
@@ -87,7 +87,7 @@ theorem Submodule.isInternal_prime_power_torsion_of_pid [Module.Finite R M]
#align submodule.is_internal_prime_power_torsion_of_pid Submodule.isInternal_prime_power_torsion_of_pid
/-- A finitely generated torsion module over a PID is an internal direct sum of its
-`p i ^ e i`-torsion submodules for some primes `p i` and numbers `e i`.-/
+`p i ^ e i`-torsion submodules for some primes `p i` and numbers `e i`. -/
theorem Submodule.exists_isInternal_prime_power_torsion_of_pid [Module.Finite R M]
(hM : Module.IsTorsion R M) :
∃ (ι : Type u) (_ : Fintype ι) (_ : DecidableEq ι) (p : ι → R) (_ : ∀ i, Irreducible <| p i)
@@ -171,7 +171,7 @@ theorem exists_smul_eq_zero_and_mk_eq {z : M} (hz : Module.IsTorsionBy R M (p ^
open Finset Multiset
/-- A finitely generated `p ^ ∞`-torsion module over a PID is isomorphic to a direct sum of some
- `R ⧸ R ∙ (p ^ e i)` for some `e i`.-/
+ `R ⧸ R ∙ (p ^ e i)` for some `e i`. -/
theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoid.powers p))
[h' : Module.Finite R N] :
∃ (d : ℕ) (k : Fin d → ℕ), Nonempty <| N ≃ₗ[R] ⨁ i : Fin d, R ⧸ R ∙ p ^ (k i : ℕ) := by
@@ -238,7 +238,7 @@ theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoi
end PTorsion
/-- A finitely generated torsion module over a PID is isomorphic to a direct sum of some
- `R ⧸ R ∙ (p i ^ e i)` where the `p i ^ e i` are prime powers.-/
+ `R ⧸ R ∙ (p i ^ e i)` where the `p i ^ e i` are prime powers. -/
theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTorsion R N) :
∃ (ι : Type u) (_ : Fintype ι) (p : ι → R) (_ : ∀ i, Irreducible <| p i) (e : ι → ℕ),
Nonempty <| N ≃ₗ[R] ⨁ i : ι, R ⧸ R ∙ p i ^ e i := by
@@ -266,7 +266,7 @@ theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTor
/-- **Structure theorem of finitely generated modules over a PID** : A finitely generated
module over a PID is isomorphic to the product of a free module and a direct sum of some
- `R ⧸ R ∙ (p i ^ e i)` where the `p i ^ e i` are prime powers.-/
+ `R ⧸ R ∙ (p i ^ e i)` where the `p i ^ e i` are prime powers. -/
theorem equiv_free_prod_directSum [h' : Module.Finite R N] :
∃ (n : ℕ) (ι : Type u) (_ : Fintype ι) (p : ι → R) (_ : ∀ i, Irreducible <| p i) (e : ι → ℕ),
Nonempty <| N ≃ₗ[R] (Fin n →₀ R) × ⨁ i : ι, R ⧸ R ∙ p i ^ e i := by
Empty lines were removed by executing the following Python script twice
import os
import re
# Loop through each file in the repository
for dir_path, dirs, files in os.walk('.'):
for filename in files:
if filename.endswith('.lean'):
file_path = os.path.join(dir_path, filename)
# Open the file and read its contents
with open(file_path, 'r') as file:
content = file.read()
# Use a regular expression to replace sequences of "variable" lines separated by empty lines
# with sequences without empty lines
modified_content = re.sub(r'(variable.*\n)\n(variable(?! .* in))', r'\1\2', content)
# Write the modified content back to the file
with open(file_path, 'w') as file:
file.write(modified_content)
@@ -55,9 +55,7 @@ universe u v
open scoped BigOperators Classical
variable {R : Type u} [CommRing R] [IsDomain R] [IsPrincipalIdealRing R]
-
variable {M : Type v} [AddCommGroup M] [Module R M]
-
variable {N : Type max u v} [AddCommGroup N] [Module R N]
open scoped DirectSum
@@ -107,7 +105,6 @@ namespace Module
section PTorsion
variable {p : R} (hp : Irreducible p) (hM : Module.IsTorsion' M (Submonoid.powers p))
-
variable [dec : ∀ x : M, Decidable (x = 0)]
open Ideal Submodule.IsPrincipal
@@ -201,7 +201,7 @@ theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoi
intro i
let fi := f.symm.toLinearMap.comp (DirectSum.lof _ _ _ i)
obtain ⟨x, h0, h1⟩ := exists_smul_eq_zero_and_mk_eq hp hN hj fi; refine' ⟨x, h0, _⟩; rw [h1]
- simp only [LinearMap.coe_comp, f.symm.coe_toLinearMap, f.apply_symm_apply,
+ simp only [fi, LinearMap.coe_comp, f.symm.coe_toLinearMap, f.apply_symm_apply,
Function.comp_apply]
refine ⟨?_, ⟨?_⟩⟩
· exact fun a => (fun i => (Option.rec (pOrder hN (s j)) k i : ℕ)) (finSuccEquiv d a)
@@ -232,7 +232,7 @@ theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoi
⟨(@hN x).choose, by rw [← Quotient.mk_smul, (@hN x).choose_spec, Quotient.mk_zero]⟩
· have hs' := congr_arg (Submodule.map <| mkQ <| R ∙ s j) hs
rw [Submodule.map_span, Submodule.map_top, range_mkQ] at hs'; simp only [mkQ_apply] at hs'
- simp only; rw [← Function.comp.assoc, Set.range_comp (_ ∘ s), Fin.range_succAbove]
+ simp only [s']; rw [← Function.comp.assoc, Set.range_comp (_ ∘ s), Fin.range_succAbove]
rw [← Set.range_comp, ← Set.insert_image_compl_eq_range _ j, Function.comp_apply,
(Quotient.mk_eq_zero _).mpr (Submodule.mem_span_singleton_self _), span_insert_zero] at hs'
exact hs'
The FunLike hierarchy is very big and gets scanned through each time we need a coercion (via the CoeFun
instance). It looks like unbundled inheritance suits Lean 4 better here. The only class that still extends FunLike
is EquivLike
, since that has a custom coe_injective'
field that is easier to implement. All other classes should take FunLike
or EquivLike
as a parameter.
Previously, morphism classes would be Type
-valued and extend FunLike
:
/-- `MyHomClass F A B` states that `F` is a type of `MyClass.op`-preserving morphisms.
You should extend this class when you extend `MyHom`. -/
class MyHomClass (F : Type*) (A B : outParam <| Type*) [MyClass A] [MyClass B]
extends FunLike F A B :=
(map_op : ∀ (f : F) (x y : A), f (MyClass.op x y) = MyClass.op (f x) (f y))
After this PR, they should be Prop
-valued and take FunLike
as a parameter:
/-- `MyHomClass F A B` states that `F` is a type of `MyClass.op`-preserving morphisms.
You should extend this class when you extend `MyHom`. -/
class MyHomClass (F : Type*) (A B : outParam <| Type*) [MyClass A] [MyClass B]
[FunLike F A B] : Prop :=
(map_op : ∀ (f : F) (x y : A), f (MyClass.op x y) = MyClass.op (f x) (f y))
(Note that A B
stay marked as outParam
even though they are not purely required to be so due to the FunLike
parameter already filling them in. This is required to see through type synonyms, which is important in the category theory library. Also, I think keeping them as outParam
is slightly faster.)
Similarly, MyEquivClass
should take EquivLike
as a parameter.
As a result, every mention of [MyHomClass F A B]
should become [FunLike F A B] [MyHomClass F A B]
.
While overall this gives some great speedups, there are some cases that are noticeably slower. In particular, a failing application of a lemma such as map_mul
is more expensive. This is due to suboptimal processing of arguments. For example:
variable [FunLike F M N] [Mul M] [Mul N] (f : F) (x : M) (y : M)
theorem map_mul [MulHomClass F M N] : f (x * y) = f x * f y
example [AddHomClass F A B] : f (x * y) = f x * f y := map_mul f _ _
Before this PR, applying map_mul f
gives the goals [Mul ?M] [Mul ?N] [MulHomClass F ?M ?N]
. Since M
and N
are out_param
s, [MulHomClass F ?M ?N]
is synthesized first, supplies values for ?M
and ?N
and then the Mul M
and Mul N
instances can be found.
After this PR, the goals become [FunLike F ?M ?N] [Mul ?M] [Mul ?N] [MulHomClass F ?M ?N]
. Now [FunLike F ?M ?N]
is synthesized first, supplies values for ?M
and ?N
and then the Mul M
and Mul N
instances can be found, before trying MulHomClass F M N
which fails. Since the Mul
hierarchy is very big, this can be slow to fail, especially when there is no such Mul
instance.
A long-term but harder to achieve solution would be to specify the order in which instance goals get solved. For example, we'd like to change the arguments to map_mul
to look like [FunLike F M N] [Mul M] [Mul N] [highPriority <| MulHomClass F M N]
because MulHomClass
fails or succeeds much faster than the others.
As a consequence, the simpNF
linter is much slower since by design it tries and fails to apply many map_
lemmas. The same issue occurs a few times in existing calls to simp [map_mul]
, where map_mul
is tried "too soon" and fails. Thanks to the speedup of leanprover/lean4#2478 the impact is very limited, only in files that already were close to the timeout.
simp
not firing sometimesThis affects map_smulₛₗ
and related definitions. For simp
lemmas Lean apparently uses a slightly different mechanism to find instances, so that rw
can find every argument to map_smulₛₗ
successfully but simp
can't: leanprover/lean4#3701.
Especially in the category theory library, we might sometimes have a type A
which is also accessible as a synonym (Bundled A hA).1
. Instance synthesis doesn't always work if we have f : A →* B
but x * y : (Bundled A hA).1
or vice versa. This seems to be mostly fixed by keeping A B
as outParam
s in MulHomClass F A B
. (Presumably because Lean will do a definitional check A =?= (Bundled A hA).1
instead of using the syntax in the discrimination tree.)
The timeouts can be worked around for now by specifying which map_mul
we mean, either as map_mul f
for some explicit f
, or as e.g. MonoidHomClass.map_mul
.
map_smulₛₗ
not firing as simp
lemma can be worked around by going back to the pre-FunLike situation and making LinearMap.map_smulₛₗ
a simp
lemma instead of the generic map_smulₛₗ
. Writing simp [map_smulₛₗ _]
also works.
Co-authored-by: Matthew Ballard <matt@mrb.email> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Scott Morrison <scott@tqft.net> Co-authored-by: Anne Baanen <Vierkantor@users.noreply.github.com>
@@ -227,7 +227,7 @@ theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoi
simp only [LinearMap.coe_comp, Function.comp_apply, mkQ_apply]
rw [LinearEquiv.coe_toLinearMap, LinearMap.id_apply, DirectSum.toModule_lof,
liftQSpanSingleton_apply, LinearMap.toSpanSingleton_one, Ideal.Quotient.mk_eq_mk,
- map_one, (this i).choose_spec.right]
+ map_one (Ideal.Quotient.mk _), (this i).choose_spec.right]
· exact (mk_surjective _).forall.mpr fun x =>
⟨(@hN x).choose, by rw [← Quotient.mk_smul, (@hN x).choose_spec, Quotient.mk_zero]⟩
· have hs' := congr_arg (Submodule.map <| mkQ <| R ∙ s j) hs
With multiple changes, it is a good time to check if existing set_option maxHeartbeats
and set_option synthInstance.maxHeartbeats
remain necessary. This brings the number of files with such down from 23 to 9. Most are straight deletions though I did change one proof.
@@ -173,7 +173,6 @@ theorem exists_smul_eq_zero_and_mk_eq {z : M} (hz : Module.IsTorsionBy R M (p ^
open Finset Multiset
-set_option maxHeartbeats 400000 in
/-- A finitely generated `p ^ ∞`-torsion module over a PID is isomorphic to a direct sum of some
`R ⧸ R ∙ (p ^ e i)` for some `e i`.-/
theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoid.powers p))
(provided the coefficients are a principal ideal ring)
@@ -7,6 +7,7 @@ import Mathlib.Algebra.Module.DedekindDomain
import Mathlib.LinearAlgebra.FreeModule.PID
import Mathlib.Algebra.Module.Projective
import Mathlib.Algebra.Category.ModuleCat.Biproducts
+import Mathlib.RingTheory.SimpleModule
#align_import algebra.module.pid from "leanprover-community/mathlib"@"cdc34484a07418af43daf8198beaf5c00324bca8"
@@ -65,6 +66,14 @@ open Submodule
open UniqueFactorizationMonoid
+theorem Submodule.isSemisimple_torsionBy_of_irreducible {a : R} (h : Irreducible a) :
+ IsSemisimpleModule R (torsionBy R M a) := by
+ rw [IsSemisimpleModule, ← (submodule_torsionBy_orderIso a).complementedLattice_iff]
+ set I : Ideal R := R ∙ a
+ have _i2 : I.IsMaximal := PrincipalIdealRing.isMaximal_of_irreducible h
+ let _i3 : Field (R ⧸ I) := Ideal.Quotient.field I
+ exact Module.Submodule.complementedLattice
+
/-- A finitely generated torsion module over a PID is an internal direct sum of its
`p i ^ e i`-torsion submodules for some primes `p i` and numbers `e i`.-/
theorem Submodule.isInternal_prime_power_torsion_of_pid [Module.Finite R M]
Make isNoetherian_of_isNoetherianRing_of_finite an instance
: this was impossible in Lean 3 because of a loop.
@@ -243,7 +243,6 @@ theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTor
∀ i,
∃ (d : ℕ) (k : Fin d → ℕ),
Nonempty <| torsionBy R N (p i ^ e i) ≃ₗ[R] ⨁ j, R ⧸ R ∙ p i ^ k j := by
- have := isNoetherian_of_isNoetherianRing_of_finite R N
haveI := fun i => isNoetherian_submodule' (torsionBy R N <| p i ^ e i)
exact fun i =>
torsion_by_prime_power_decomposition.{u, v} (hp i)
@@ -266,7 +265,6 @@ theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTor
theorem equiv_free_prod_directSum [h' : Module.Finite R N] :
∃ (n : ℕ) (ι : Type u) (_ : Fintype ι) (p : ι → R) (_ : ∀ i, Irreducible <| p i) (e : ι → ℕ),
Nonempty <| N ≃ₗ[R] (Fin n →₀ R) × ⨁ i : ι, R ⧸ R ∙ p i ^ e i := by
- have := isNoetherian_of_isNoetherianRing_of_finite R N
haveI := isNoetherian_submodule' (torsion R N)
haveI := Module.Finite.of_surjective _ (torsion R N).mkQ_surjective
obtain ⟨I, fI, p, hp, e, ⟨h⟩⟩ :=
[@foo](https://github.com/foo) _ _ _ _ _ ...
by named arguments (#8702)
Using Lean4's named arguments, we manage to remove a few hard-to-read explicit function calls [@foo](https://github.com/foo) _ _ _ _ _ ...
which used to be necessary in Lean3.
Occasionally, this results in slightly longer code. The benefit of named arguments is readability, as well as to reduce the brittleness of the code when the argument order is changed.
Co-authored-by: Michael Rothgang <rothgami@math.hu-berlin.de>
@@ -197,9 +197,9 @@ theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoi
Function.comp_apply]
refine ⟨?_, ⟨?_⟩⟩
· exact fun a => (fun i => (Option.rec (pOrder hN (s j)) k i : ℕ)) (finSuccEquiv d a)
- · refine (((@lequivProdOfRightSplitExact _ _ _ _ _ _ _ _ _ _ _ _
- ((f.trans ULift.moduleEquiv.{u, u, v}.symm).toLinearMap.comp <| mkQ _)
- ((DirectSum.toModule _ _ _ fun i => (liftQSpanSingleton (p ^ k i)
+ · refine (((lequivProdOfRightSplitExact
+ (g := (f.trans ULift.moduleEquiv.{u, u, v}.symm).toLinearMap.comp <| mkQ _)
+ (f := (DirectSum.toModule _ _ _ fun i => (liftQSpanSingleton (p ^ k i)
(LinearMap.toSpanSingleton _ _ _) (this i).choose_spec.left : R ⧸ _ →ₗ[R] _)).comp
ULift.moduleEquiv.toLinearMap) (R ∙ s j).injective_subtype ?_ ?_).symm.trans
(((quotTorsionOfEquivSpanSingleton R N (s j)).symm.trans
Due to recent changes in core we can reduce or remove many set_option maxHeartbeats
statements.
I have tried to be careful to not leave anything too close to the line, so don't be surprised if some of these can still be reduced further.
This reduces us from 96 maxHeartbeats
statements to 44
. (There are 10 false positives in meta or testing code.)
Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
@@ -164,7 +164,7 @@ theorem exists_smul_eq_zero_and_mk_eq {z : M} (hz : Module.IsTorsionBy R M (p ^
open Finset Multiset
-set_option maxHeartbeats 800000 in
+set_option maxHeartbeats 400000 in
/-- A finitely generated `p ^ ∞`-torsion module over a PID is isomorphic to a direct sum of some
`R ⧸ R ∙ (p ^ e i)` for some `e i`.-/
theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoid.powers p))
@@ -243,7 +243,7 @@ theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTor
∀ i,
∃ (d : ℕ) (k : Fin d → ℕ),
Nonempty <| torsionBy R N (p i ^ e i) ≃ₗ[R] ⨁ j, R ⧸ R ∙ p i ^ k j := by
- haveI := isNoetherian_of_fg_of_noetherian' (Module.finite_def.mp h')
+ have := isNoetherian_of_isNoetherianRing_of_finite R N
haveI := fun i => isNoetherian_submodule' (torsionBy R N <| p i ^ e i)
exact fun i =>
torsion_by_prime_power_decomposition.{u, v} (hp i)
@@ -266,7 +266,7 @@ theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTor
theorem equiv_free_prod_directSum [h' : Module.Finite R N] :
∃ (n : ℕ) (ι : Type u) (_ : Fintype ι) (p : ι → R) (_ : ∀ i, Irreducible <| p i) (e : ι → ℕ),
Nonempty <| N ≃ₗ[R] (Fin n →₀ R) × ⨁ i : ι, R ⧸ R ∙ p i ^ e i := by
- haveI := isNoetherian_of_fg_of_noetherian' (Module.finite_def.mp h')
+ have := isNoetherian_of_isNoetherianRing_of_finite R N
haveI := isNoetherian_submodule' (torsion R N)
haveI := Module.Finite.of_surjective _ (torsion R N).mkQ_surjective
obtain ⟨I, fI, p, hp, e, ⟨h⟩⟩ :=
Type _
and Sort _
(#6499)
We remove all possible occurences of Type _
and Sort _
in favor of Type*
and Sort*
.
This has nice performance benefits.
@@ -199,7 +199,7 @@ theorem torsion_by_prime_power_decomposition (hN : Module.IsTorsion' N (Submonoi
· exact fun a => (fun i => (Option.rec (pOrder hN (s j)) k i : ℕ)) (finSuccEquiv d a)
· refine (((@lequivProdOfRightSplitExact _ _ _ _ _ _ _ _ _ _ _ _
((f.trans ULift.moduleEquiv.{u, u, v}.symm).toLinearMap.comp <| mkQ _)
- ((DirectSum.toModule _ _ _ fun i => (liftQSpanSingleton.{u, u} (p ^ k i)
+ ((DirectSum.toModule _ _ _ fun i => (liftQSpanSingleton (p ^ k i)
(LinearMap.toSpanSingleton _ _ _) (this i).choose_spec.left : R ⧸ _ →ₗ[R] _)).comp
ULift.moduleEquiv.toLinearMap) (R ∙ s j).injective_subtype ?_ ?_).symm.trans
(((quotTorsionOfEquivSpanSingleton R N (s j)).symm.trans
@@ -25,7 +25,7 @@ import Mathlib.Algebra.Category.ModuleCat.Biproducts
* `R` is a PID and `M` is a (finitely generated for main statements) `R`-module, with additional
torsion hypotheses in the intermediate lemmas.
-* `N` is a `R`-module lying over a higher type universe than `R`. This assumption is needed on the
+* `N` is an `R`-module lying over a higher type universe than `R`. This assumption is needed on the
final statement for technical reasons.
* `p` is an irreducible element of `R` or a tuple of these.
@@ -2,17 +2,14 @@
Copyright (c) 2022 Pierre-Alexandre Bazin. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Pierre-Alexandre Bazin
-
-! This file was ported from Lean 3 source module algebra.module.pid
-! leanprover-community/mathlib commit cdc34484a07418af43daf8198beaf5c00324bca8
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
-/
import Mathlib.Algebra.Module.DedekindDomain
import Mathlib.LinearAlgebra.FreeModule.PID
import Mathlib.Algebra.Module.Projective
import Mathlib.Algebra.Category.ModuleCat.Biproducts
+#align_import algebra.module.pid from "leanprover-community/mathlib"@"cdc34484a07418af43daf8198beaf5c00324bca8"
+
/-!
# Structure of finitely generated modules over a PID
@@ -256,9 +256,9 @@ theorem equiv_directSum_of_isTorsion [h' : Module.Finite R N] (hN : Module.IsTor
⟨Σ i, Fin (this i).choose, inferInstance, fun ⟨i, _⟩ => p i, fun ⟨i, _⟩ => hp i, fun ⟨i, j⟩ =>
(this i).choose_spec.choose j,
⟨(LinearEquiv.ofBijective (DirectSum.coeLinearMap _) h).symm.trans <|
- (Dfinsupp.mapRange.linearEquiv fun i => (this i).choose_spec.choose_spec.some).trans <|
+ (DFinsupp.mapRange.linearEquiv fun i => (this i).choose_spec.choose_spec.some).trans <|
(DirectSum.sigmaLcurryEquiv R).symm.trans
- (Dfinsupp.mapRange.linearEquiv fun i => quotEquivOfEq _ _ _)⟩⟩
+ (DFinsupp.mapRange.linearEquiv fun i => quotEquivOfEq _ _ _)⟩⟩
cases' i with i j
simp only
#align module.equiv_direct_sum_of_is_torsion Module.equiv_directSum_of_isTorsion
The unported dependencies are
algebra.homology.short_exact.preadditive
init.core
linear_algebra.free_module.finite.rank
algebra.order.monoid.cancel.defs
algebra.abs
algebra.group_power.lemmas
algebra.homology.short_exact.abelian
init.data.list.basic
linear_algebra.free_module.rank
init.data.list.default
algebra.order.monoid.cancel.basic
topology.subset_properties
init.logic