-- Mathlib/LinearAlgebra/Dimension/Torsion/Basic.lean
theorem rank_quotient_eq_of_le_torsion {R M : Type*} [CommRing R] [AddCommGroup M] [Module R M]
    {M' : Submodule R M} (hN : M' ≤ torsion R M) : Module.rank R (M ⧸ M') = Module.rank R M :=
  (rank_quotient_le M').antisymm <| by
    nontriviality R
    rw [Module.rank]
    have := nonempty_linearIndependent_set R M
    refine ciSup_le fun ⟨s, hs⟩ ↦ LinearIndependent.cardinal_le_rank (v := (M'.mkQ ·)) ?_
    rw [LinearIndepOn, linearIndependent_iff'] at hs
    simp_rw [linearIndependent_iff', ← map_smul, ← map_sum, mkQ_apply, Quotient.mk_eq_zero]
    intro t g hg i hi
    obtain ⟨r, hg⟩ := hN hg
    simp_rw [Finset.smul_sum, Submonoid.smul_def, smul_smul] at hg
    exact r.prop _ (mul_comm (g i) r ▸ hs t _ hg i hi)

Proof state:
case intro
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
M' : Submodule R M
hN : M' ≤ torsion R M
a✝ : Nontrivial R
this : Nonempty { s // LinearIndepOn R id s }
x✝ : { s // LinearIndepOn R id s }
s : Set M
hs✝ : LinearIndepOn R id s
hs : ∀ (s_1 : Finset ↑s) (g : ↑s → R), ∑ i ∈ s_1, g i • id ↑i = 0 → ∀ i ∈ s_1, g i = 0
t : Finset ↑s
g : ↑s → R
hg✝ : ∑ x ∈ t, g x • ↑x ∈ M'
i : ↑s
hi : i ∈ t
r : ↥(nonZeroDivisors R)
hg : ∑ x ∈ t, (↑r * g x) • ↑x = 0
⊢ g i = 0

Tactic:
exact r.prop _ (mul_comm (g i) r ▸ hs t _ hg i hi)

Result:
no goals

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
M' : Submodule R M
hN : M' ≤ torsion R M
a✝ : Nontrivial R
this : Nonempty { s // LinearIndepOn R id s }
x✝ : { s // LinearIndepOn R id s }
s : Set M
hs✝ : LinearIndepOn R id s
hs : ∀ (s_1 : Finset ↑s) (g : ↑s → R), ∑ i ∈ s_1, g i • id ↑i = 0 → ∀ i ∈ s_1, g i = 0
⊢ LinearIndependent R fun (x : ↑↑⟨s, hs✝⟩) => M'.mkQ ↑x

Tactic:
simp_rw [linearIndependent_iff', ← map_smul, ← map_sum, mkQ_apply, Quotient.mk_eq_zero]

Result:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
M' : Submodule R M
hN : M' ≤ torsion R M
a✝ : Nontrivial R
this : Nonempty { s // LinearIndepOn R id s }
x✝ : { s // LinearIndepOn R id s }
s : Set M
hs✝ : LinearIndepOn R id s
hs : ∀ (s_1 : Finset ↑s) (g : ↑s → R), ∑ i ∈ s_1, g i • id ↑i = 0 → ∀ i ∈ s_1, g i = 0
⊢ ∀ (s_1 : Finset ↑s) (g : ↑s → R), ∑ x ∈ s_1, g x • ↑x ∈ M' → ∀ i ∈ s_1, g i = 0

Proof state:
case intro
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
M' : Submodule R M
hN : M' ≤ torsion R M
a✝ : Nontrivial R
this : Nonempty { s // LinearIndepOn R id s }
x✝ : { s // LinearIndepOn R id s }
s : Set M
hs✝ : LinearIndepOn R id s
hs : ∀ (s_1 : Finset ↑s) (g : ↑s → R), ∑ i ∈ s_1, g i • id ↑i = 0 → ∀ i ∈ s_1, g i = 0
t : Finset ↑s
g : ↑s → R
hg✝ : ∑ x ∈ t, g x • ↑x ∈ M'
i : ↑s
hi : i ∈ t
r : ↥(nonZeroDivisors R)
hg : r • ∑ x ∈ t, g x • ↑x = 0
⊢ g i = 0

Tactic:
simp_rw [Finset.smul_sum, Submonoid.smul_def, smul_smul] at hg

Result:
case intro
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
M' : Submodule R M
hN : M' ≤ torsion R M
a✝ : Nontrivial R
this : Nonempty { s // LinearIndepOn R id s }
x✝ : { s // LinearIndepOn R id s }
s : Set M
hs✝ : LinearIndepOn R id s
hs : ∀ (s_1 : Finset ↑s) (g : ↑s → R), ∑ i ∈ s_1, g i • id ↑i = 0 → ∀ i ∈ s_1, g i = 0
t : Finset ↑s
g : ↑s → R
hg✝ : ∑ x ∈ t, g x • ↑x ∈ M'
i : ↑s
hi : i ∈ t
r : ↥(nonZeroDivisors R)
hg : ∑ x ∈ t, (↑r * g x) • ↑x = 0
⊢ g i = 0

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
M' : Submodule R M
hN : M' ≤ torsion R M
a✝ : Nontrivial R
this : Nonempty { s // LinearIndepOn R id s }
x✝ : { s // LinearIndepOn R id s }
s : Set M
hs✝ : LinearIndepOn R id s
hs : ∀ (s_1 : Finset ↑s) (g : ↑s → R), ∑ i ∈ s_1, g i • id ↑i = 0 → ∀ i ∈ s_1, g i = 0
⊢ ∀ (s_1 : Finset ↑s) (g : ↑s → R), ∑ x ∈ s_1, g x • ↑x ∈ M' → ∀ i ∈ s_1, g i = 0

Tactic:
intro t g hg i hi

Result:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
M' : Submodule R M
hN : M' ≤ torsion R M
a✝ : Nontrivial R
this : Nonempty { s // LinearIndepOn R id s }
x✝ : { s // LinearIndepOn R id s }
s : Set M
hs✝ : LinearIndepOn R id s
hs : ∀ (s_1 : Finset ↑s) (g : ↑s → R), ∑ i ∈ s_1, g i • id ↑i = 0 → ∀ i ∈ s_1, g i = 0
t : Finset ↑s
g : ↑s → R
hg : ∑ x ∈ t, g x • ↑x ∈ M'
i : ↑s
hi : i ∈ t
⊢ g i = 0

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
M' : Submodule R M
hN : M' ≤ torsion R M
a✝ : Nontrivial R
this : Nonempty { s // LinearIndepOn R id s }
x✝ : { s // LinearIndepOn R id s }
s : Set M
hs✝ : LinearIndepOn R id s
hs : ∀ (s_1 : Finset ↑s) (g : ↑s → R), ∑ i ∈ s_1, g i • id ↑i = 0 → ∀ i ∈ s_1, g i = 0
t : Finset ↑s
g : ↑s → R
hg : ∑ x ∈ t, g x • ↑x ∈ M'
i : ↑s
hi : i ∈ t
⊢ g i = 0

Tactic:
obtain ⟨r, hg⟩ := hN hg

Result:
case intro
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
M' : Submodule R M
hN : M' ≤ torsion R M
a✝ : Nontrivial R
this : Nonempty { s // LinearIndepOn R id s }
x✝ : { s // LinearIndepOn R id s }
s : Set M
hs✝ : LinearIndepOn R id s
hs : ∀ (s_1 : Finset ↑s) (g : ↑s → R), ∑ i ∈ s_1, g i • id ↑i = 0 → ∀ i ∈ s_1, g i = 0
t : Finset ↑s
g : ↑s → R
hg✝ : ∑ x ∈ t, g x • ↑x ∈ M'
i : ↑s
hi : i ∈ t
r : ↥(nonZeroDivisors R)
hg : r • ∑ x ∈ t, g x • ↑x = 0
⊢ g i = 0

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
M' : Submodule R M
hN : M' ≤ torsion R M
a✝ : Nontrivial R
⊢ ⨆ ι, Cardinal.mk ↑↑ι ≤ Module.rank R (M ⧸ M')

Tactic:
have := nonempty_linearIndependent_set R M

Result:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
M' : Submodule R M
hN : M' ≤ torsion R M
a✝ : Nontrivial R
this : Nonempty { s // LinearIndepOn R id s }
⊢ ⨆ ι, Cardinal.mk ↑↑ι ≤ Module.rank R (M ⧸ M')

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
M' : Submodule R M
hN : M' ≤ torsion R M
a✝ : Nontrivial R
⊢ Module.rank R M ≤ Module.rank R (M ⧸ M')

Tactic:
rw [Module.rank]

Result:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
M' : Submodule R M
hN : M' ≤ torsion R M
a✝ : Nontrivial R
⊢ ⨆ ι, Cardinal.mk ↑↑ι ≤ Module.rank R (M ⧸ M')

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
M' : Submodule R M
hN : M' ≤ torsion R M
⊢ Module.rank R M ≤ Module.rank R (M ⧸ M')

Tactic:
nontriviality R

Result:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
M' : Submodule R M
hN : M' ≤ torsion R M
a✝ : Nontrivial R
⊢ Module.rank R M ≤ Module.rank R (M ⧸ M')

Proof state:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
M' : Submodule R M
hN : M' ≤ torsion R M
a✝ : Nontrivial R
this : Nonempty { s // LinearIndepOn R id s }
x✝ : { s // LinearIndepOn R id s }
s : Set M
hs : LinearIndepOn R id s
⊢ LinearIndependent R fun (x : ↑↑⟨s, hs⟩) => M'.mkQ ↑x

Tactic:
rw [LinearIndepOn, linearIndependent_iff'] at hs

Result:
R : Type u_1
M : Type u_2
inst✝² : CommRing R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
M' : Submodule R M
hN : M' ≤ torsion R M
a✝ : Nontrivial R
this : Nonempty { s // LinearIndepOn R id s }
x✝ : { s // LinearIndepOn R id s }
s : Set M
hs✝ : LinearIndepOn R id s
hs : ∀ (s_1 : Finset ↑s) (g : ↑s → R), ∑ i ∈ s_1, g i • id ↑i = 0 → ∀ i ∈ s_1, g i = 0
⊢ LinearIndependent R fun (x : ↑↑⟨s, hs✝⟩) => M'.mkQ ↑x