[System] You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Algebra.Module.SpanRank).

[User]
Prove the following theorem. The retrieved context below may help.

```lean
lemma Module.Basis.mk_eq_spanRank [RankCondition R] {ι : Type*} (v : Basis ι R M) :
    #(Set.range v) = (⊤ : Submodule R M).spanRank
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Algebra.Module.SpanRank.spanRank_toENat_eq_iInf_encard (L72-L87)
lemma spanRank_toENat_eq_iInf_encard (p : Submodule R M) : p.spanRank.toENat =
    (⨅ (s : Set M) (_ : span R s = p), s.encard) := by
rw [spanRank]
  apply le_antisymm
  · refine le_iInf₂ (fun s hs ↦ ?_)
    rw [Set.encard, ENat.card]
    exact toENat.monotone' (ciInf_le' _ (⟨s, hs⟩ : {s : Set M // span R s = p}))
  · have := congrFun toENat_comp_ofENat.{u}.symm (⨅ (s : Set M) (_ : span R s = p), s.encard)
    rw [id_eq] at this; rw [this]
    refine toENat.monotone' (le_ciInf fun s ↦ ?_)
    have : ofENat.{u} (⨅ (s' : Set M), ⨅ (_ : span R s' = p), s'.encard) ≤ ofENat s.1.encard :=
      ofENatHom.monotone' (le_trans (ciInf_le' _ s.1) (ciInf_le' _ s.2))
    apply le_trans this
    rw [Set.encard, ENat.card]
    exact Cardinal.ofENat_toENat_le _
```

-- snippet 2
```lean
-- Mathlib.Algebra.Module.SpanRank.spanRank_toENat_eq_iInf_finset_card (L88-L102)
lemma spanRank_toENat_eq_iInf_finset_card (p : Submodule R M) :
    p.spanRank.toENat = ⨅ (s : {s : Finset M // span R s = p}), (s.1.card : ℕ∞) := by
rw [spanRank_toENat_eq_iInf_encard]
  rcases eq_or_ne (⨅ (s : Set M) (_ : span R s = p), s.encard) ⊤ with (h1 | h2)
  · rw [h1, eq_comm]; simp_rw [iInf_eq_top] at h1 ⊢
    exact fun s ↦ False.elim (Set.encard_ne_top_iff.mpr s.1.finite_toSet (h1 s.1 s.2))
  · simp_rw [← Set.encard_coe_eq_coe_finsetCard]
    apply le_antisymm
    · exact le_iInf fun s ↦ iInf₂_le (s.1 : Set M) s.2
    · refine le_iInf fun s ↦ le_iInf fun h ↦ ?_
      by_cases hs : s.Finite
      · exact iInf_le_of_le ⟨hs.toFinset, by simpa⟩ (by simp)
      · rw [Set.Infinite.encard_eq hs]
        exact OrderTop.le_top _
```

-- snippet 3
```lean
-- Mathlib.Algebra.Module.SpanRank.spanFinrank_eq_iInf (L103-L107)
lemma spanFinrank_eq_iInf (p : Submodule R M) :
    p.spanFinrank = ⨅ (s : {s : Finset M // span R s = p}), s.1.card := by
simp [spanFinrank, Cardinal.toNat, spanRank_toENat_eq_iInf_finset_card, ENat.iInf_toNat]

/-- A submodule's `spanRank` is finite if and only if it is finitely generated. -/
```

-- snippet 4
```lean
-- Mathlib.Algebra.Module.SpanRank.spanRank_finite_iff_fg (L109-L119)
lemma spanRank_finite_iff_fg {p : Submodule R M} : p.spanRank < aleph0 ↔ p.FG := by
rw [spanRank, Submodule.fg_def]
  constructor
  · rintro h
    obtain ⟨s, hs⟩ : ⨅ (s : {s : Set M // span R s = p}), #s ∈
      Set.range (fun (s : {s : Set M // span R s = p}) ↦ #s) := csInf_mem ⟨#p, ⟨⟨p, by simp⟩, rfl⟩⟩
    refine ⟨s.1, ?_, s.2⟩
    simpa [← hs] using h
  · rintro ⟨s, hs₁, hs₂⟩
    exact (ciInf_le' _ ⟨s, hs₂⟩).trans_lt (by simpa)
```

-- snippet 5
```lean
-- Mathlib.Algebra.Module.SpanRank.spanFinrank_of_not_fg (L120-L127)
lemma spanFinrank_of_not_fg {p : Submodule R M} (hp : ¬p.FG) : p.spanFinrank = 0 := by
refine toNat_eq_zero.2 ?_
  right
  by_contra! h
  exact hp (spanRank_finite_iff_fg.1 h)

/-- A submodule is finitely generated if and only if its `spanRank` is equal to its `spanFinrank`.
-/
```

-- snippet 6
```lean
-- Mathlib.Algebra.Module.SpanRank.fg_iff_spanRank_eq_spanFinrank (L128-L131)
lemma fg_iff_spanRank_eq_spanFinrank {p : Submodule R M} : p.spanRank = p.spanFinrank ↔ p.FG := by
rw [spanFinrank, ← spanRank_finite_iff_fg, eq_comm]
  exact cast_toNat_eq_iff_lt_aleph0
```

-- snippet 7
```lean
-- Mathlib.Algebra.Module.SpanRank.FG (L132-L134)
lemma FG.spanRank_eq_spanFinrank {p : Submodule R M} (fg : p.FG) : p.spanRank = p.spanFinrank :=
fg_iff_spanRank_eq_spanFinrank.mpr fg
```

-- snippet 8
```lean
-- Mathlib.Algebra.Module.SpanRank.FG (L135-L138)
lemma FG.spanRank_le_iff {p : Submodule R M} (hp : p.FG) (n : ℕ) :
    p.spanRank ≤ n ↔ p.spanFinrank ≤ n :=
(Cardinal.toNat_le_iff_of_lt_aleph0 n (by simpa)).symm
```

-- snippet 9
```lean
-- Mathlib.Algebra.Module.SpanRank.FG (L139-L142)
lemma FG.spanRank_eq_iff {p : Submodule R M} (hp : p.FG) (n : ℕ) :
    p.spanRank = n ↔ p.spanFinrank = n :=
(Cardinal.toNat_eq_iff_of_lt_aleph0 n (by simpa)).symm
```

-- snippet 10
```lean
-- Mathlib.Algebra.Module.SpanRank.spanRank_span_le_card (L143-L147)
lemma spanRank_span_le_card (s : Set M) : (Submodule.span R s).spanRank ≤ #s := by
rw [spanRank]
  let s' : {s1 : Set M // span R s1 = span R s} := ⟨s, rfl⟩
  exact ciInf_le' _ s'
```

-- snippet 11
```lean
-- Mathlib.Algebra.Module.SpanRank.spanRank_span_range_of_linearIndependent (L148-L160)
lemma spanRank_span_range_of_linearIndependent [RankCondition R] {ι : Type u} {v : ι → M}
    (hv : v.Injective) (hs : LinearIndependent R v) :
    (span R (.range v)).spanRank = #ι := by
refine le_antisymm (le_trans (spanRank_span_le_card _) mk_range_le) (le_ciInf fun x ↦ ?_)
  have : #x.1 = #((Subtype.val : span R (.range v) → _) ⁻¹' x.1) :=
    (mk_preimage_of_injective_of_subset_range _ _ Subtype.val_injective (by simp [← x.2])).symm
  rw [this]
  refine le_trans ?_ ((Module.Basis.span hs).le_span (R := R) (J := Subtype.val ⁻¹' x.1) ?_)
  · rw [mk_range_eq]
    exact .of_comp (f := Subtype.val) (by convert hv; ext; simp [Module.Basis.span_apply])
  · apply map_injective_of_injective (f := (span R _).subtype) (injective_subtype _)
    simp [map_span, Set.image_preimage_eq_inter_range, Set.inter_eq_self_of_subset_left, ← x.2]
```

-- snippet 12
```lean
-- Mathlib.Algebra.Module.SpanRank.spanRank_span_of_linearIndepOn (L161-L164)
lemma spanRank_span_of_linearIndepOn [RankCondition R] (s : Set M) (hs : LinearIndepOn R id s) :
    (span R s).spanRank = #s := by
simp [← spanRank_span_range_of_linearIndependent Subtype.val_injective hs]
```

-- snippet 13
```lean
-- Mathlib.Algebra.Module.SpanRank.spanFinrank_span_le_encard (L165-L168)
lemma spanFinrank_span_le_encard (s : Set M) : (span R s).spanFinrank ≤ s.encard := by
rw [spanFinrank, Set.encard, ENat.card]
  exact le_trans (by simp) (toENat.monotone' (spanRank_span_le_card (R := R) s))
```

-- snippet 14
```lean
-- Mathlib.Algebra.Module.SpanRank.spanFinrank_span_le_ncard_of_finite (L169-L174)
lemma spanFinrank_span_le_ncard_of_finite {s : Set M} (hs : s.Finite) :
    (span R s).spanFinrank ≤ s.ncard := by
rw [← Nat.cast_le (α := ℕ∞)]
  exact le_trans (spanFinrank_span_le_encard _) hs.cast_ncard_eq.ge

/-- Constructs a generating set with cardinality equal to the `spanRank` of the submodule -/
```

-- snippet 15
```lean
-- Mathlib.Algebra.Module.SpanRank.exists_span_set_card_eq_spanRank (L175-L183)
theorem exists_span_set_card_eq_spanRank (p : Submodule R M) :
    ∃ s : Set M, #s = p.spanRank ∧ span R s = p := by
rw [spanRank]
  obtain ⟨s, hs⟩ : ⨅ (s : {s : Set M // span R s = p}), #s ∈
    Set.range (fun (s : {s : Set M // span R s = p}) ↦ #s) := csInf_mem ⟨#p, ⟨⟨p, by simp⟩, rfl⟩⟩
  exact ⟨s.1, ⟨hs, s.2⟩⟩

/-- Constructs a generating set with cardinality equal to the `spanFinrank` of the submodule when
  the submodule is finitely generated. -/
```

-- snippet 16
```lean
-- Mathlib.Algebra.Module.SpanRank.FG (L184-L191)
theorem FG.exists_span_set_encard_eq_spanFinrank {p : Submodule R M} (h : p.FG) :
    ∃ s : Set M, s.encard = p.spanFinrank ∧ span R s = p := by
obtain ⟨s, ⟨hs₁, hs₂⟩⟩ := exists_span_set_card_eq_spanRank p
  refine ⟨s, ⟨?_, hs₂⟩⟩
  have := fg_iff_spanRank_eq_spanFinrank.mpr h
  rw [Set.encard, ENat.card, spanFinrank, hs₁, this]
  simp
```

-- snippet 17
```lean
-- Mathlib.Algebra.Module.SpanRank.lift_spanRank_le_iff_exists_span_set_card_le (L192-L201)
lemma lift_spanRank_le_iff_exists_span_set_card_le (p : Submodule R M) {a : Cardinal.{max u v}} :
    Cardinal.lift.{v} p.spanRank ≤ a ↔ ∃ s : Set M, Cardinal.lift.{v} #s ≤ a ∧ span R s = p := by
constructor
  · intro h
    obtain ⟨s, ⟨hs₁, hs₂⟩⟩ := exists_span_set_card_eq_spanRank p
    exact ⟨s, ⟨hs₁ ▸ h, hs₂⟩⟩
  · exact fun ⟨s, ⟨h₁, h₂⟩⟩ ↦ h₂.symm ▸ (Cardinal.lift_le.mpr (spanRank_span_le_card s)).trans h₁

/-- For a finitely generated submodule, its spanRank is less than or equal to a cardinal `a`
  if and only if there is a generating subset with cardinality less than or equal to `a`. -/
```

-- snippet 18
```lean
-- Mathlib.Algebra.Module.SpanRank.FG (L202-L205)
lemma FG.spanRank_le_iff_exists_span_set_card_le (p : Submodule R M) {a : Cardinal} :
    p.spanRank ≤ a ↔ ∃ s : Set M, #s ≤ a ∧ span R s = p := by
convert lift_spanRank_le_iff_exists_span_set_card_le p (a := a) <;> simp
```

-- snippet 19
```lean
-- Mathlib.Algebra.Module.SpanRank.spanRank_eq_zero_iff_eq_bot (L207-L216)
lemma spanRank_eq_zero_iff_eq_bot {I : Submodule R M} : I.spanRank = 0 ↔ I = ⊥ := by
constructor
  · intro h
    obtain ⟨s, ⟨hs₁, hs₂⟩⟩ :=
      (FG.spanRank_le_iff_exists_span_set_card_le I (a := 0)).mp (by rw [h])
    simp only [nonpos_iff_eq_zero, mk_eq_zero_iff, Set.isEmpty_coe_sort] at hs₁
    simp_all
  · rintro rfl; rw [spanRank]
    exact Cardinal.iInf_eq_zero_iff.mpr (Or.inr ⟨⟨∅, by simp⟩, by simp⟩)
```

-- snippet 20
```lean
-- Mathlib.Algebra.Module.SpanRank.spanRank_bot (L218-L219)
lemma spanRank_bot : (⊥ : Ideal R).spanRank = 0 := Submodule.spanRank_eq_zero_iff_eq_bot.mpr rfl
```

-- snippet 21
```lean
-- Mathlib.Algebra.Module.SpanRank.spanFinrank_bot (L221-L226)
lemma spanFinrank_bot : (⊥ : Submodule R M).spanFinrank = 0 := by simp [spanFinrank]
/-- Generating elements for the submodule of minimum cardinality. -/
noncomputable def generators (p : Submodule R M) : Set M :=
  Classical.choose (exists_span_set_card_eq_spanRank p)
```

-- snippet 22
```lean
-- Mathlib.Algebra.Module.SpanRank.generators_card (L227-L229)
lemma generators_card (p : Submodule R M) : #(generators p) = spanRank p :=
(Classical.choose_spec (exists_span_set_card_eq_spanRank p)).1
```

-- snippet 23
```lean
-- Mathlib.Algebra.Module.SpanRank.FG (L230-L235)
lemma FG.generators_ncard {p : Submodule R M} (h : p.FG) :
    (generators p).ncard = spanFinrank p := by
rw [← Nat.cast_inj (R := Cardinal), ← fg_iff_spanRank_eq_spanFinrank.mpr h, Set.ncard, Set.encard,
     ENat.card, generators_card, toNat_toENat, ← spanFinrank]
  exact (fg_iff_spanRank_eq_spanFinrank.mpr h).symm
```

-- snippet 24
```lean
-- Mathlib.Algebra.Module.SpanRank.FG (L236-L241)
lemma FG.finite_generators {p : Submodule R M} (hp : p.FG) :
    p.generators.Finite := by
rw [← Cardinal.lt_aleph0_iff_set_finite, Submodule.generators_card]
  exact spanRank_finite_iff_fg.mpr hp

/-- The span of the generators equals the submodule. -/
```

-- snippet 25
```lean
-- Mathlib.Algebra.Module.SpanRank.span_generators (L242-L245)
lemma span_generators (p : Submodule R M) : span R (generators p) = p :=
(Classical.choose_spec (exists_span_set_card_eq_spanRank p)).2

/-- The elements of the generators are in the submodule. -/
```

-- snippet 26
```lean
-- Mathlib.Algebra.Module.Basic.invOf_two_smul_add_invOf_two_smul (L36-L40)
theorem invOf_two_smul_add_invOf_two_smul (R) [Semiring R] [AddCommMonoid M] [Module R M]
    [Invertible (2 : R)] (x : M) :
    (⅟2 : R) • x + (⅟2 : R) • x = x :=
Convex.combo_self invOf_two_add_invOf_two _
```

-- snippet 27
```lean
-- Mathlib.Algebra.Module.Basic.indicator_smul_apply (L122-L127)
lemma indicator_smul_apply (s : Set α) (r : α → R) (f : α → M) (a : α) :
    indicator s (fun a ↦ r a • f a) a = r a • indicator s f a := by
dsimp only [indicator]
  split_ifs
  exacts [rfl, (smul_zero (r a)).symm]
```

-- snippet 28
```lean
-- Mathlib.Algebra.Module.BigOperators.sum_single_smul (L66-L71)
lemma sum_single_smul
    {R : Type*} [Semiring R] [Module R α] (f : ι → α) (r : R) (i₀ : ι) :
    ∑ i, (Pi.single (M := fun _ ↦ R) i₀ r i) • f i = r • f i₀ := by
rw [Finset.sum_eq_single i₀, Pi.single_eq_same] <;> aesop

end Fintype
```

-- snippet 29
```lean
-- Mathlib.Algebra.Module.Defs.neg_smul_neg (L142-L145)
theorem neg_smul_neg : -r • -x = r • x := by rw [neg_smul, smul_neg, neg_neg]
variable (R)
```

-- snippet 30
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.coe_toLinearMap_one (L99-L100)
lemma coe_toLinearMap_one : (↑(1 : M ≃ₗ[R] M) : M →ₗ[R] M) = LinearMap.id := rfl
```

-- snippet 31
```lean
-- Mathlib.Algebra.Module.CharacterModule.CharacterModule (L46-L49)
def CharacterModule : Type uA := A →+ AddCircle (1 : ℚ)
namespace CharacterModule
```

-- snippet 32
```lean
-- Mathlib.Algebra.Module.Basic.indicator_smul_left (L151-L154)
lemma indicator_smul_left (s : Set α) (r : α → R) (f : α → M) :
    indicator s (fun a ↦ r a • f a) = fun a ↦ indicator s r a • f a :=
funext <| indicator_smul_apply_left _ _ _
```

-- snippet 33
```lean
-- Mathlib.Algebra.Module.Basic.inv_intCast_smul_eq (L75-L80)
theorem inv_intCast_smul_eq {E : Type*} (R S : Type*) [AddCommGroup E] [DivisionRing R]
    [DivisionRing S] [Module R E] [Module S E] (n : ℤ) (x : E) : (n⁻¹ : R) • x = (n⁻¹ : S) • x :=
map_inv_intCast_smul (AddMonoidHom.id E) R S n x

/-- If `E` is a vector space over a division semiring `R` and has a monoid action by `α`, then that
action commutes by scalar multiplication of inverses of natural numbers in `R`. -/
```

-- snippet 34
```lean
-- Mathlib.Algebra.Module.Card.mk_le_of_module (L28-L35)
theorem mk_le_of_module (R : Type u) (E : Type v)
    [AddCommGroup E] [Ring R] [IsDomain R] [Module R E] [Nontrivial E] [Module.IsTorsionFree R E] :
    Cardinal.lift.{v} (#R) ≤ Cardinal.lift.{u} (#E) := by
obtain ⟨x, hx⟩ : ∃ (x : E), x ≠ 0 := exists_ne 0
  have : Injective (fun k ↦ k • x) := smul_left_injective R hx
  exact lift_mk_le_lift_mk_of_injective this

end Cardinal
```

-- snippet 35
```lean
-- Mathlib.Algebra.Module.Defs.two_smul (L81-L104)
theorem two_smul : (2 : R) • x = x + x := by rw [← one_add_one_eq_two, add_smul, one_smul]
/-- Pullback a `Module` structure along an injective additive monoid homomorphism.
See note [reducible non-instances]. -/
protected abbrev Function.Injective.module [AddCommMonoid M₂] [SMul R M₂] (f : M₂ →+ M)
    (hf : Injective f) (smul : ∀ (c : R) (x), f (c • x) = c • f x) : Module R M₂ :=
  { hf.distribMulAction f smul with
    add_smul := fun c₁ c₂ x => hf <| by simp only [smul, f.map_add, add_smul]
    zero_smul := fun x => hf <| by simp only [smul, zero_smul, f.map_zero] }

/-- Pushforward a `Module` structure along a surjective additive monoid homomorphism.
See note [reducible non-instances]. -/
protected abbrev Function.Surjective.module [AddCommMonoid M₂] [SMul R M₂] (f : M →+ M₂)
    (hf : Surjective f) (smul : ∀ (c : R) (x), f (c • x) = c • f x) : Module R M₂ :=
  { toDistribMulAction := hf.distribMulAction f smul
    add_smul := fun c₁ c₂ x => by
      rcases hf x with ⟨x, rfl⟩
      simp only [add_smul, ← smul, ← f.map_add]
    zero_smul := fun x => by
      rcases hf x with ⟨x, rfl⟩
      rw [← f.map_zero, ← smul, zero_smul] }

variable {R}
```

-- snippet 36
```lean
-- Mathlib.Algebra.Module.Basic.indicator_const_smul_apply (L132-L135)
lemma indicator_const_smul_apply (s : Set α) (r : R) (f : α → M) (a : α) :
    indicator s (r • f ·) a = r • indicator s f a :=
indicator_smul_apply s (fun _ ↦ r) f a
```

-- snippet 37
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.coe_toLinearMap_mul (L102-L105)
lemma coe_toLinearMap_mul {e₁ e₂ : M ≃ₗ[R] M} :
    (↑(e₁ * e₂) : M →ₗ[R] M) = (e₁ : M →ₗ[R] M) * (e₂ : M →ₗ[R] M) :=
rfl
```

-- snippet 38
```lean
-- Mathlib.Algebra.Module.CharacterModule.dual_surjective_of_injective (L103-L109)
lemma dual_surjective_of_injective (f : A →ₗ[R] B) (hf : Function.Injective f) :
    Function.Surjective (dual f) :=
(Module.Baer.of_divisible _).extension_property_addMonoidHom _ hf

/--
Two isomorphic modules have isomorphic character modules.
-/
```

-- snippet 39
```lean
-- Mathlib.Algebra.Module.BigOperators.Finset (L38-L40)
theorem Finset.sum_smul {f : ι → R} {s : Finset ι} {x : M} :
    (∑ i ∈ s, f i) • x = ∑ i ∈ s, f i • x := map_sum ((smulAddHom R M).flip x) f s
```

-- snippet 40
```lean
-- Mathlib.Algebra.Module.End.IsAddUnit (L62-L67)
lemma IsAddUnit.smul_left [DistribSMul S M] (hx : IsAddUnit x) (s : S) :
    IsAddUnit (s • x) :=
hx.map (DistribSMul.toAddMonoidHom M s)

variable {r} (x)
```

-- snippet 41
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.restrictScalars_injective (L55-L58)
theorem restrictScalars_injective :
    Function.Injective (restrictScalars R : (M ≃ₗ[S] M₂) → M ≃ₗ[R] M₂) := fun _ _ h ↦
ext (LinearEquiv.congr_fun h :)
```

-- snippet 42
```lean
-- Mathlib.Algebra.Module.Basic.Units (L31-L34)
theorem Units.neg_smul [Ring R] [AddCommGroup M] [Module R M] (u : Rˣ) (x : M) :
    -u • x = -(u • x) := by
rw [Units.smul_def, Units.val_neg, _root_.neg_smul, Units.smul_def]
```

-- snippet 43
```lean
-- Mathlib.Algebra.Module.Congruence.Defs.addConGen' (L64-L81)
def addConGen' (r : M → M → Prop) (hr : ∀ (s : S) {m m'}, r m m' → r (s • m) (s • m')) :
    ModuleCon S M where
  toAddCon := addConGen r
smul s _ _ h := ((addConGen r).comap (DistribSMul.toAddMonoidHom M s) <| by simp).addConGen_le
    (fun _ _ h ↦ .of _ _ (hr s h)) h

/-- The `AddCon` generated by a `SMulCon` is a `ModuleCon`. -/
protected abbrev addConGen (c : SMulCon S M) : ModuleCon S M := addConGen' c.r c.smul

end addConGen

end SMulCon

namespace ModuleCon

/-- The quotient by a congruence relation preserving addition and scalar multiplication. -/
protected def Quotient [Add M] [SMul S M] (c : ModuleCon S M) : Type _ := Quotient c.toSetoid
```

-- snippet 44
```lean
-- Mathlib.Algebra.Module.Bimodule.smul_mem (L91-L94)
theorem smul_mem (p : Submodule (A ⊗[R] B) M) (a : A) {m : M} (hm : m ∈ p) : a • m ∈ p := by
suffices a • m = a ⊗ₜ[R] (1 : B) • m by exact this.symm ▸ p.smul_mem _ hm
  simp [TensorProduct.Algebra.smul_def]
```

-- snippet 45
```lean
-- Mathlib.Algebra.Module.End.smulAddHom_apply (L57-L61)
theorem smulAddHom_apply : smulAddHom R M r x = r • x :=
rfl

variable {x}
```

-- snippet 46
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.coe_pow (L106-L107)
theorem coe_pow (e : M ≃ₗ[R] M) (n : ℕ) : ⇑(e ^ n) = e^[n] := hom_coe_pow _ rfl (fun _ _ ↦ rfl) _ _
```

-- snippet 47
```lean
-- Mathlib.Algebra.Module.Basic.support_smul_subset_right (L101-L104)
lemma support_smul_subset_right [Zero M] [SMulZeroClass R M] (f : α → R) (g : α → M) :
    support (f • g) ⊆ support g :=
fun x hbf hf ↦ hbf <| by rw [Pi.smul_apply', hf, smul_zero]
```

-- snippet 48
```lean
-- Mathlib.Algebra.Module.CharacterModule.dual_injective_of_surjective (L95-L102)
lemma dual_injective_of_surjective (f : A →ₗ[R] B) (hf : Function.Surjective f) :
    Function.Injective (dual f) := by
intro φ ψ eq
  ext x
  obtain ⟨y, rfl⟩ := hf x
  change (dual f) φ _ = (dual f) ψ _
  rw [eq]
```

-- snippet 49
```lean
-- Mathlib.Algebra.Module.CharacterModule.exists_character_apply_ne_zero_of_ne_zero (L215-L219)
lemma exists_character_apply_ne_zero_of_ne_zero {a : A} (ne_zero : a ≠ 0) :
    ∃ (c : CharacterModule A), c a ≠ 0 :=
have ⟨c, hc⟩ := dual_surjective_of_injective _ (Submodule.injective_subtype _) (ofSpanSingleton a)
  ⟨c, fun h ↦ ne_zero <| eq_zero_of_ofSpanSingleton_apply_self a <| by rwa [← hc]⟩
```

-- snippet 50
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.restrictScalars (L48-L54)
def restrictScalars (f : M ≃ₗ[S] M₂) : M ≃ₗ[R] M₂ :=
{ f.toLinearMap.restrictScalars R with
    toFun := f
    invFun := f.symm
    left_inv := f.left_inv
    right_inv := f.right_inv }
```

-- snippet 51
```lean
-- Mathlib.Algebra.Module.Bimodule.toSubmodule (L109-L114)
def toSubmodule (p : Submodule (A ⊗[R] B) M) : Submodule A M :=
{ p with
    carrier := p
    smul_mem' := smul_mem p }

/-- Forgetting the `A` action, a `Submodule` over `A ⊗[R] B` is just a `Submodule` over `B`. -/
```

-- snippet 52
```lean
-- Mathlib.Algebra.Module.End.smulAddHom (L51-L55)
def smulAddHom : R →+ M →+ M :=
(Module.toAddMonoidEnd R M).toAddMonoidHom

variable {R M}
```

-- snippet 53
```lean
-- Mathlib.Algebra.Module.End.AddMonoid (L32-L41)
theorem AddMonoid.End.natCast_def (n : ℕ) :
    (↑n : AddMonoid.End M) = DistribMulAction.toAddMonoidEnd ℕ M n :=
rfl

variable (R M)

set_option backward.isDefEq.respectTransparency false in
/-- `(•)` as an `AddMonoidHom`.

This is a stronger version of `DistribMulAction.toAddMonoidEnd` -/
```

-- snippet 54
```lean
-- Mathlib.Algebra.Module.Bimodule.mk (L82-L90)
def mk (p : AddSubmonoid M) (hA : ∀ (a : A) {m : M}, m ∈ p → a • m ∈ p)
    (hB : ∀ (b : B) {m : M}, m ∈ p → b • m ∈ p) : Submodule (A ⊗[R] B) M :=
{ p with
    carrier := p
    smul_mem' := fun ab m =>
      TensorProduct.induction_on ab (fun _ => by simp only [zero_smul, SetLike.mem_coe, zero_mem])
        (fun a b hm => by simpa only [TensorProduct.Algebra.smul_def] using hA a (hB b hm))
        fun z w hz hw hm => by simpa only [add_smul] using p.add_mem (hz hm) (hw hm) }
```

-- snippet 55
```lean
-- Mathlib.Algebra.Module.BigOperators.Fintype (L45-L51)
lemma Fintype.sum_smul_sum [Fintype α] [Fintype β] (f : α → R) (g : β → M) :
    (∑ i, f i) • ∑ j, g j = ∑ i, ∑ j, f i • g j := Finset.sum_smul_sum _ _
end AddCommMonoid

open Finset
```

-- snippet 56
```lean
-- Mathlib.Algebra.Module.CharacterModule.eq_zero_of_character_apply (L220-L224)
lemma eq_zero_of_character_apply {a : A} (h : ∀ c : CharacterModule A, c a = 0) : a = 0 := by
contrapose! h; exact exists_character_apply_ne_zero_of_ne_zero h

variable [Module R A] [Module R A'] [Module R B] {R A' B}
```

-- snippet 57
```lean
-- Mathlib.Algebra.Module.Basic.indicator_smul (L128-L131)
lemma indicator_smul (s : Set α) (r : α → R) (f : α → M) :
    indicator s (fun a ↦ r a • f a) = fun a ↦ r a • indicator s f a :=
funext <| indicator_smul_apply s r f
```

-- snippet 58
```lean
-- Mathlib.Algebra.Module.Basic.smul_indicator_one_apply (L168-L173)
lemma smul_indicator_one_apply (s : Set α) (r : R) (a : α) :
    r • s.indicator (1 : α → R) a = s.indicator (fun _ ↦ r) a := by
simp_rw [← indicator_const_smul_apply, Pi.one_apply, smul_eq_mul, mul_one]

end MulZeroOneClass
end Set
```

-- snippet 59
```lean
-- Mathlib.Algebra.Module.Bimodule.toSubmodule' (L116-L129)
def toSubmodule' (p : Submodule (A ⊗[R] B) M) : Submodule B M :=
{ p with
    carrier := p
    smul_mem' := smul_mem' p }

end Algebra

section Ring

variable (R S M : Type*) [Ring R] [Ring S]
variable [AddCommGroup M] [Module R M] [Module S M] [SMulCommClass R S M]

/-- A `Submodule` over `R ⊗[ℕ] S` is naturally also a `Submodule` over the canonically-isomorphic
ring `R ⊗[ℤ] S`. -/
```

-- snippet 60
```lean
-- Mathlib.Algebra.Module.Defs.Convex (L76-L80)
theorem Convex.combo_self {a b : R} (h : a + b = 1) (x : M) : a • x + b • x = x := by
rw [← add_smul, h, one_smul]

variable (R)
```

-- snippet 61
```lean
-- Mathlib.Algebra.Module.Bimodule.smul_mem' (L95-L100)
theorem smul_mem' (p : Submodule (A ⊗[R] B) M) (b : B) {m : M} (hm : m ∈ p) : b • m ∈ p := by
suffices b • m = (1 : A) ⊗ₜ[R] b • m by exact this.symm ▸ p.smul_mem _ hm
  simp [TensorProduct.Algebra.smul_def]

/-- If `A` and `B` are also `Algebra`s over yet another set of scalars `S` then we may "base change"
from `R` to `S`. -/
```

-- snippet 62
```lean
-- Mathlib.Algebra.Module.Basic.inv_intCast_smul_comm (L88-L94)
theorem inv_intCast_smul_comm {α E : Type*} (R : Type*) [AddCommGroup E] [DivisionRing R]
    [Module R E] [DistribSMul α E] (n : ℤ) (s : α) (x : E) :
    (n⁻¹ : R) • s • x = s • (n⁻¹ : R) • x :=
(map_inv_intCast_smul (DistribSMul.toAddMonoidHom E s) R R n x).symm

namespace Function
```

-- snippet 63
```lean
-- Mathlib.Algebra.Module.Basic.indicator_smul_const (L158-L167)
lemma indicator_smul_const (s : Set α) (r : α → R) (m : M) :
    indicator s (r · • m) = (indicator s r · • m) :=
funext <| indicator_smul_const_apply _ _ _

end SMulWithZero

section MulZeroOneClass

variable [MulZeroOneClass R]
```

-- snippet 64
```lean
-- Mathlib.Algebra.Module.CharacterModule.dual_injective_iff_surjective (L246-L249)
lemma dual_injective_iff_surjective {f : A →ₗ[R] A'} :
    Function.Injective (dual f) ↔ Function.Surjective f :=
⟨fun h ↦ surjective_of_dual_injective f h, fun h ↦ dual_injective_of_surjective f h⟩
```

-- snippet 65
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.coe_one (L94-L95)
lemma coe_one : ↑(1 : M ≃ₗ[R] M) = id := rfl
```

-- snippet 66
```lean
-- Mathlib.Algebra.Module.CharacterModule.dual_zero (L86-L89)
lemma dual_zero : dual (0 : A →ₗ[R] B) = 0 := by
ext f
  exact map_zero f
```

-- snippet 67
```lean
-- Mathlib.Algebra.Module.Basic.indicator_smul_apply_left (L145-L150)
lemma indicator_smul_apply_left (s : Set α) (r : α → R) (f : α → M) (a : α) :
    indicator s (fun a ↦ r a • f a) a = indicator s r a • f a := by
dsimp only [indicator]
  split_ifs
  exacts [rfl, (zero_smul _ (f a)).symm]
```

-- snippet 68
```lean
-- Mathlib.Algebra.Module.BigOperators.sum_piFinset_apply (L58-L64)
lemma sum_piFinset_apply (f : κ → α) (s : Finset κ) (i : ι) :
    ∑ g ∈ piFinset fun _ : ι ↦ s, f (g i) = #s ^ (card ι - 1) • ∑ b ∈ s, f b := by
classical
  rw [Finset.sum_comp]
  simp only [eval_image_piFinset_const, card_filter_piFinset_const s, ite_smul, zero_smul, smul_sum,
    Finset.sum_ite_mem, inter_self]
```

-- snippet 69
```lean
-- Mathlib.Algebra.Module.Defs.add_smul (L73-L75)
theorem add_smul : (r + s) • x = r • x + s • x :=
Module.add_smul r s x
```

-- snippet 70
```lean
-- Mathlib.Algebra.Module.Congruence.Defs.ModuleCon (L148-L160)
def ModuleCon.ker [Monoid R] [Monoid S] [AddMonoid M] [AddMonoid N] [DistribMulAction R M]
    [DistribMulAction S N] {φ : R →* S} (f : M →ₑ+[φ] N) : ModuleCon R M where
  __ := SMulCon.ker f.toMulActionHom
__ := AddCon.ker f

/-- The first isomorphism theorem for semimodules in the case of a surjective homomorphism. -/
noncomputable def ModuleCon.quotientKerEquivOfSurjective [Semiring S] [AddCommMonoid M]
    [AddCommMonoid N] [Module S M] [Module S N] (f : M →ₗ[S] N) (hf : Function.Surjective f) :
    (ker f.toDistribMulActionHom).Quotient ≃ₗ[S] N where
  __ := AddCon.quotientKerEquivOfSurjective f.toAddMonoidHom hf
  map_smul' s := by rintro ⟨⟩; apply map_smul f

end ker
```

-- snippet 71
```lean
-- Mathlib.Algebra.Module.Basic.indicator_const_smul (L136-L144)
lemma indicator_const_smul (s : Set α) (r : R) (f : α → M) :
    indicator s (r • f ·) = (r • indicator s f ·) :=
funext <| indicator_const_smul_apply s r f

end SMulZeroClass

section SMulWithZero
variable [Zero R] [Zero M] [SMulWithZero R M]
```

-- snippet 72
```lean
-- Mathlib.Algebra.Module.DedekindDomain.isInternal_prime_power_torsion (L64-L75)
theorem isInternal_prime_power_torsion [Module.Finite R M]
    (hM : Module.IsTorsion R M) :
    DirectSum.IsInternal fun p : (factors (⊤ : Submodule R M).annihilator).toFinset =>
      torsionBySet R M (p ^ (factors (⊤ : Submodule R M).annihilator).count ↑p : Ideal R) := by
have hM' := Module.isTorsionBySet_annihilator_top R M
  have hI := Submodule.annihilator_top_inter_nonZeroDivisors hM
  refine isInternal_prime_power_torsion_of_is_torsion_by_ideal ?_ hM'
  rw [Submodule.ne_bot_iff]
  obtain ⟨x, H, hx⟩ := hI; exact ⟨x, H, nonZeroDivisors.ne_zero hx⟩

/-- A finitely generated torsion module over a Dedekind domain is an internal direct sum of its
`p i ^ e i`-torsion submodules for some prime ideals `p i` and numbers `e i`. -/
```

-- snippet 73
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.automorphismGroup (L81-L89)
instance automorphismGroup : Group (M ≃ₗ[R] M) where
  mul f g := g.trans f
one := LinearEquiv.refl R M
  inv f := f.symm
  mul_assoc _ _ _ := rfl
  mul_one _ := ext fun _ ↦ rfl
  one_mul _ := ext fun _ ↦ rfl
  inv_mul_cancel f := ext <| f.left_inv
```

-- snippet 74
```lean
-- Mathlib.Algebra.Module.Basic.indicator_smul_const_apply (L155-L157)
lemma indicator_smul_const_apply (s : Set α) (r : α → R) (m : M) (a : α) :
    indicator s (r · • m) a = indicator s r a • m := indicator_smul_apply_left _ _ _ _
```

-- snippet 75
```lean
-- Mathlib.Algebra.Module.CharacterModule.dual_rTensor_conj_homEquiv (L147-L171)
theorem dual_rTensor_conj_homEquiv (f : A →ₗ[R] A') :
    homEquiv.symm.toLinearMap ∘ₗ dual (f.rTensor B) ∘ₗ homEquiv.toLinearMap = f.lcomp R _ := rfl
end module

/--
`ℤ⋆`, the character module of `ℤ` in the unit rational circle.
-/
protected abbrev int : Type := CharacterModule ℤ

/-- Given `n : ℕ`, the map `m ↦ m / n`. -/
protected abbrev int.divByNat (n : ℕ) : CharacterModule.int :=
  LinearMap.toSpanSingleton ℤ _ (QuotientAddGroup.mk (n : ℚ)⁻¹) |>.toAddMonoidHom

protected lemma int.divByNat_self (n : ℕ) :
    int.divByNat n n = 0 := by
  obtain rfl | h0 := eq_or_ne n 0
  · apply map_zero
  exact (AddCircle.coe_eq_zero_iff _).mpr
    ⟨1, by simp [mul_inv_cancel₀ (Nat.cast_ne_zero (R := ℚ).mpr h0)]⟩

variable {A}

/-- The `ℤ`-submodule spanned by a single element `a` is isomorphic to the quotient of `ℤ`
by the ideal generated by the order of `a`. -/
```

-- snippet 76
```lean
-- Mathlib.Algebra.Module.BigOperators.Multiset (L29-L31)
theorem Multiset.sum_smul {l : Multiset R} {x : M} : l.sum • x = (l.map fun r ↦ r • x).sum :=
((smulAddHom R M).flip x).map_multiset_sum l
```

-- snippet 77
```lean
-- Mathlib.Algebra.Module.Basic.map_inv_intCast_smul (L58-L67)
theorem map_inv_intCast_smul [AddCommGroup M] [AddCommGroup M₂] {F : Type*} [FunLike F M M₂]
    [AddMonoidHomClass F M M₂] (f : F) (R S : Type*) [DivisionRing R] [DivisionRing S] [Module R M]
    [Module S M₂] (z : ℤ) (x : M) : f ((z⁻¹ : R) • x) = (z⁻¹ : S) • f x := by
obtain ⟨n, rfl | rfl⟩ := z.eq_nat_or_neg
  · rw [Int.cast_natCast, Int.cast_natCast, map_inv_natCast_smul _ R S]
  · simp_rw [Int.cast_neg, Int.cast_natCast, inv_neg, neg_smul, map_neg,
      map_inv_natCast_smul _ R S]

/-- If `E` is a vector space over two division semirings `R` and `S`, then scalar multiplications
agree on inverses of natural numbers in `R` and `S`. -/
```

-- snippet 78
```lean
-- Mathlib.Algebra.Module.Defs.smul_add_one_sub_smul (L109-L117)
theorem smul_add_one_sub_smul {R : Type*} [Ring R] [Module R M] {r : R} {m : M} :
    r • m + (1 - r) • m = m := by rw [← add_smul, add_sub_cancel, one_smul]
end AddCommMonoid

section AddCommGroup

variable [Semiring R] [AddCommGroup M]
```

-- snippet 79
```lean
-- Mathlib.Algebra.Module.CharacterModule.surjective_of_dual_injective (L236-L245)
lemma surjective_of_dual_injective (f : A →ₗ[R] A') (hf : Function.Injective (dual f)) :
    Function.Surjective f := by
rw [← LinearMap.range_eq_top, ← Submodule.unique_quotient_iff_eq_top]
  refine ⟨Unique.mk inferInstance fun a ↦ eq_zero_of_character_apply fun c ↦ ?_⟩
  obtain ⟨b, rfl⟩ := QuotientAddGroup.mk'_surjective _ a
  suffices eq : dual (Submodule.mkQ _) c = 0 from congr($eq b)
  refine hf ?_
  rw [← LinearMap.comp_apply, ← dual_comp, LinearMap.range_mkQ_comp, dual_zero,
    LinearMap.zero_apply, dual_apply, AddMonoidHom.zero_comp]
```

-- snippet 80
```lean
-- Mathlib.Algebra.Module.CharacterModule.congr (L110-L119)
def congr (e : A ≃ₗ[R] B) : CharacterModule A ≃ₗ[R] CharacterModule B :=
.ofLinear (dual e.symm) (dual e)
    (by ext c _; exact congr(c $(e.right_inv _)))
    (by ext c _; exact congr(c $(e.left_inv _)))

open TensorProduct

/--
Any linear map `L : A → B⋆` induces a character in `(A ⊗ B)⋆` by `a ⊗ b ↦ L a b`.
-/
```

-- snippet 81
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.one_eq_refl (L90-L90)
lemma one_eq_refl : (1 : M ≃ₗ[R] M) = refl R M := rfl
```

-- snippet 82
```lean
-- Mathlib.Algebra.Module.DedekindDomain.exists_isInternal_prime_power_torsion (L76-L83)
theorem exists_isInternal_prime_power_torsion [Module.Finite R M] (hM : Module.IsTorsion R M) :
    ∃ (P : Finset <| Ideal R) (_ : DecidableEq P) (_ : ∀ p ∈ P, Prime p) (e : P → ℕ),
      DirectSum.IsInternal fun p : P => torsionBySet R M (p ^ e p : Ideal R) := by
classical
  exact ⟨_, _, fun p hp => prime_of_factor p (Multiset.mem_toFinset.mp hp), _,
    isInternal_prime_power_torsion hM⟩

end Submodule
```

-- snippet 83
```lean
-- Mathlib.Algebra.Module.Defs.sub_smul (L150-L166)
theorem sub_smul (r s : R) (y : M) : (r - s) • y = r • y - s • y := by
simp [add_smul, sub_eq_add_neg]

end Module

/-- A module over a `Subsingleton` semiring is a `Subsingleton`. We cannot register this
as an instance because Lean has no way to guess `R`. -/
protected theorem Module.subsingleton (R M : Type*) [MonoidWithZero R] [Subsingleton R] [Zero M]
    [MulActionWithZero R M] : Subsingleton M :=
  MulActionWithZero.subsingleton R M

/-- A semiring is `Nontrivial` provided that there exists a nontrivial module over this semiring. -/
protected theorem Module.nontrivial (R M : Type*) [MonoidWithZero R] [Nontrivial M] [Zero M]
    [MulActionWithZero R M] : Nontrivial R :=
  MulActionWithZero.nontrivial R M

-- see Note [lower instance priority]
```

-- snippet 84
```lean
-- Mathlib.Algebra.Module.CharacterModule.dual_bijective_iff_bijective (L250-L255)
lemma dual_bijective_iff_bijective {f : A →ₗ[R] A'} :
    Function.Bijective (dual f) ↔ Function.Bijective f :=
⟨fun h ↦ ⟨dual_surjective_iff_injective.mp h.2, dual_injective_iff_surjective.mp h.1⟩,
  fun h ↦ ⟨dual_injective_iff_surjective.mpr h.2, dual_surjective_iff_injective.mpr h.1⟩⟩

end CharacterModule
```

-- snippet 85
```lean
-- Mathlib.Algebra.Module.Bimodule.baseChange (L102-L107)
def baseChange (S : Type*) [CommSemiring S] [Module S M] [Algebra S A] [Algebra S B]
    [IsScalarTower S A M] [IsScalarTower S B M] (p : Submodule (A ⊗[R] B) M) :
    Submodule (A ⊗[S] B) M :=
mk p.toAddSubmonoid (smul_mem p) (smul_mem' p)

/-- Forgetting the `B` action, a `Submodule` over `A ⊗[R] B` is just a `Submodule` over `A`. -/
```

-- snippet 86
```lean
-- Mathlib.Algebra.Module.Basic.support_const_smul_subset (L113-L121)
lemma support_const_smul_subset [Zero M] [SMulZeroClass R M] (a : R) (f : α → M) :
    support (a • f) ⊆ support f := support_smul_subset_right (fun _ ↦ a) f
end Function

namespace Set
section SMulZeroClass
variable [Zero M] [SMulZeroClass R M]
```

-- snippet 87
```lean
-- Mathlib.Algebra.Module.Bimodule.toSubbimoduleInt (L131-L135)
def toSubbimoduleInt (p : Submodule (R ⊗[ℕ] S) M) : Submodule (R ⊗[ℤ] S) M :=
baseChange ℤ p

/-- A `Submodule` over `R ⊗[ℤ] S` is naturally also a `Submodule` over the canonically-isomorphic
ring `R ⊗[ℕ] S`. -/
```

-- snippet 88
```lean
-- Mathlib.Algebra.Module.BigOperators.List (L26-L28)
theorem List.sum_smul {l : List R} {x : M} : l.sum • x = (l.map fun r ↦ r • x).sum :=
map_list_sum ((smulAddHom R M).flip x) l
```

-- snippet 89
```lean
-- Mathlib.Algebra.Module.DedekindDomain.isInternal_prime_power_torsion_of_is_torsion_by_ideal (L37-L63)
theorem isInternal_prime_power_torsion_of_is_torsion_by_ideal
    {I : Ideal R} (hI : I ≠ ⊥) (hM : Module.IsTorsionBySet R M I) :
    DirectSum.IsInternal fun p : (factors I).toFinset =>
      torsionBySet R M (p ^ (factors I).count ↑p : Ideal R) := by
let P := factors I
  have prime_of_mem := fun p (hp : p ∈ P.toFinset) =>
    prime_of_factor p (Multiset.mem_toFinset.mp hp)
  apply torsionBySet_isInternal (p := fun p => p ^ P.count p) _
  · convert hM
    rw [← Finset.inf_eq_iInf, IsDedekindDomain.inf_pow_eq_prod_of_prime,
      ← Finset.prod_multiset_count, ← associated_iff_eq]
    · exact factors_prod hI
    · exact prime_of_mem
    · exact fun _ _ _ _ ij => ij
  · intro p hp q hq pq; dsimp
    rw [irreducible_pow_sup]
    · suffices (normalizedFactors _).count p = 0 by rw [this, zero_min, pow_zero, Ideal.one_eq_top]
      rw [Multiset.count_eq_zero,
        normalizedFactors_of_irreducible_pow (prime_of_mem q hq).irreducible,
        Multiset.mem_replicate]
      exact fun H => pq <| H.2.trans <| normalize_eq q
    · rw [← Ideal.zero_eq_bot]; apply pow_ne_zero; exact (prime_of_mem q hq).ne_zero
    · exact (prime_of_mem p hp).irreducible

/-- A finitely generated torsion module over a Dedekind domain is an internal direct sum of its
`p i ^ e i`-torsion submodules where `p i` are factors of `(⊤ : Submodule R M).annihilator` and
`e i` are their multiplicities. -/
```

-- snippet 90
```lean
-- Mathlib.Algebra.Module.Defs.neg_one_smul (L146-L149)
theorem neg_one_smul (x : M) : (-1 : R) • x = -x := by simp
variable {R}
```

-- snippet 91
```lean
-- Mathlib.Algebra.Module.Congruence.Defs.SMulCon (L143-L147)
def SMulCon.ker [SMul R M] [SMul S N] {φ : R → S} (f : M →ₑ[φ] N) : SMulCon R M where
  __ := Setoid.ker f
smul r _ _ h := by rw [Setoid.ker_def] at h ⊢; simp_rw [map_smulₛₗ, h]

/-- The kernel of a `DistribMulActionHom` as a congruence relation. -/
```

-- snippet 92
```lean
-- Mathlib.Algebra.Module.Basic.support_const_smul_of_ne_zero (L105-L108)
lemma support_const_smul_of_ne_zero [Semiring R] [IsDomain R] [AddCommMonoid M] [Module R M]
    [Module.IsTorsionFree R M] (c : R) (g : α → M) (hc : c ≠ 0) : support (c • g) = support g :=
ext fun _ ↦ smul_ne_zero_iff_right hc
```

-- snippet 93
```lean
-- Mathlib.Algebra.Module.CharacterModule.eq_zero_of_ofSpanSingleton_apply_self (L201-L214)
lemma eq_zero_of_ofSpanSingleton_apply_self (a : A)
    (h : ofSpanSingleton a ⟨a, Submodule.mem_span_singleton_self a⟩ = 0) : a = 0 := by
erw [ofSpanSingleton, LinearMap.toAddMonoidHom_coe, LinearMap.comp_apply,
     intSpanEquivQuotAddOrderOf_apply_self, Submodule.liftQSpanSingleton_apply,
    AddMonoidHom.coe_toIntLinearMap, int.divByNat, LinearMap.toSpanSingleton_apply_one,
    AddCircle.coe_eq_zero_iff] at h
  rcases h with ⟨n, hn⟩
  apply_fun Rat.den at hn
  rw [zsmul_one, Rat.den_intCast, Rat.inv_natCast_den_of_pos] at hn
  · split_ifs at hn
    · cases hn
    · rwa [eq_comm, AddMonoid.addOrderOf_eq_one_iff] at hn
  · grind
```

-- snippet 94
```lean
-- Mathlib.Algebra.Module.Bimodule.toSubbimoduleNat (L137-L142)
def toSubbimoduleNat (p : Submodule (R ⊗[ℤ] S) M) : Submodule (R ⊗[ℕ] S) M :=
baseChange ℕ p

end Ring

end Subbimodule
```

-- snippet 95
```lean
-- Mathlib.Algebra.Module.CharacterModule.intSpanEquivQuotAddOrderOf_apply_self (L181-L200)
lemma intSpanEquivQuotAddOrderOf_apply_self (a : A) :
    intSpanEquivQuotAddOrderOf a ⟨a, Submodule.mem_span_singleton_self a⟩ =
    Submodule.Quotient.mk 1 :=
(LinearEquiv.eq_symm_apply _).mp <| Subtype.ext (one_zsmul _).symm

/--
For an abelian group `A` and an element `a ∈ A`, there is a character `c : ℤ ∙ a → ℚ ⧸ ℤ` given by
`m • a ↦ m / n` where `n` is the smallest positive integer such that `n • a = 0` and when such `n`
does not exist, `c` is defined by `m • a ↦ m / 2`.
-/
noncomputable def ofSpanSingleton (a : A) : CharacterModule (ℤ ∙ a) :=
  let l : ℤ ⧸ Ideal.span {(addOrderOf a : ℤ)} →ₗ[ℤ] AddCircle (1 : ℚ) :=
    Submodule.liftQSpanSingleton _
      (CharacterModule.int.divByNat <|
        if addOrderOf a = 0 then 2 else addOrderOf a).toIntLinearMap <| by
        split_ifs with h
        · rw [h, Nat.cast_zero, map_zero]
        · apply CharacterModule.int.divByNat_self
  l ∘ₗ intSpanEquivQuotAddOrderOf a |>.toAddMonoidHom
```

-- snippet 96
```lean
-- Mathlib.Algebra.Module.Basic.support_smul (L109-L112)
lemma support_smul [Semiring R] [IsDomain R] [AddCommMonoid M] [Module R M]
    [Module.IsTorsionFree R M] (f : α → R) (g : α → M) : support (f • g) = support f ∩ support g :=
ext fun _ => smul_ne_zero_iff
```

-- snippet 97
```lean
-- Mathlib.Algebra.Module.CharacterModule.dual_comp (L90-L94)
lemma dual_comp {C : Type*} [AddCommGroup C] [Module R C] (f : A →ₗ[R] B) (g : B →ₗ[R] C) :
    dual (g.comp f) = (dual f).comp (dual g) := by
ext
  rfl
```

-- snippet 98
```lean
-- Mathlib.Algebra.Module.Defs.neg_smul (L139-L141)
theorem neg_smul : -r • x = -(r • x) :=
eq_neg_of_add_eq_zero_left <| by rw [← add_smul, neg_add_cancel, zero_smul]
```

-- snippet 99
```lean
-- Mathlib.Algebra.Module.Basic.inv_natCast_smul_comm (L81-L87)
theorem inv_natCast_smul_comm {α E : Type*} (R : Type*) [AddCommMonoid E] [DivisionSemiring R]
    [Module R E] [DistribSMul α E] (n : ℕ) (s : α) (x : E) :
    (n⁻¹ : R) • s • x = s • (n⁻¹ : R) • x :=
(map_inv_natCast_smul (DistribSMul.toAddMonoidHom E s) R R n x).symm

/-- If `E` is a vector space over a division ring `R` and has a monoid action by `α`, then that
action commutes by scalar multiplication of inverses of integers in `R` -/
```

-- snippet 100
```lean
-- Mathlib.Algebra.Module.Basic.support_smul_subset_left (L95-L100)
lemma support_smul_subset_left [Zero R] [Zero M] [SMulWithZero R M] (f : α → R) (g : α → M) :
    support (f • g) ⊆ support f := fun x hfg hf ↦
hfg <| by rw [Pi.smul_apply', hf, zero_smul]

-- Changed (2024-01-21): this lemma was generalised;
-- the old version is now called `support_const_smul_subset`.
```

-- snippet 101
```lean
-- Mathlib.Algebra.Module.Basic.map_inv_natCast_smul (L41-L57)
theorem map_inv_natCast_smul [AddCommMonoid M] [AddCommMonoid M₂] {F : Type*} [FunLike F M M₂]
    [AddMonoidHomClass F M M₂] (f : F) (R S : Type*)
    [DivisionSemiring R] [DivisionSemiring S] [Module R M]
    [Module S M₂] (n : ℕ) (x : M) : f ((n⁻¹ : R) • x) = (n⁻¹ : S) • f x := by
by_cases hR : (n : R) = 0 <;> by_cases hS : (n : S) = 0
  · simp [hR, hS, map_zero f]
  · suffices ∀ y, f y = 0 by rw [this, this, smul_zero]
    clear x
    intro x
    rw [← inv_smul_smul₀ hS (f x), ← map_natCast_smul f R S]
    simp [hR, map_zero f]
  · suffices ∀ y, f y = 0 by simp [this]
    clear x
    intro x
    rw [← smul_inv_smul₀ hR x, map_natCast_smul f R S, hS, zero_smul]
  · rw [← inv_smul_smul₀ hS (f _), ← map_natCast_smul f R S, smul_inv_smul₀ hR]
```

-- snippet 102
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.mul_eq_trans (L91-L92)
lemma mul_eq_trans (f g : M ≃ₗ[R] M) : f * g = g.trans f := rfl
```

-- snippet 103
```lean
-- Mathlib.Algebra.Module.Basic.inv_natCast_smul_eq (L68-L74)
theorem inv_natCast_smul_eq {E : Type*} (R S : Type*) [AddCommMonoid E] [DivisionSemiring R]
    [DivisionSemiring S] [Module R E] [Module S E] (n : ℕ) (x : E) :
    (n⁻¹ : R) • x = (n⁻¹ : S) • x :=
map_inv_natCast_smul (AddMonoidHom.id E) R S n x

/-- If `E` is a vector space over two division rings `R` and `S`, then scalar multiplications
agree on inverses of integer numbers in `R` and `S`. -/
```

-- snippet 104
```lean
-- Mathlib.Algebra.Module.CharacterModule.dual_surjective_iff_injective (L225-L230)
lemma dual_surjective_iff_injective {f : A →ₗ[R] A'} :
    Function.Surjective (dual f) ↔ Function.Injective f :=
⟨fun h ↦ (injective_iff_map_eq_zero _).2 fun a h0 ↦ eq_zero_of_character_apply fun c ↦ by
    obtain ⟨c, rfl⟩ := h c; exact congr(c $h0).trans c.map_zero,
  dual_surjective_of_injective f⟩
```

-- snippet 105
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.restrictScalars_inj (L60-L65)
theorem restrictScalars_inj (f g : M ≃ₗ[S] M₂) :
    f.restrictScalars R = g.restrictScalars R ↔ f = g :=
(restrictScalars_injective R).eq_iff

end RestrictScalars
```

<s>[SYSTEM_PROMPT]You are Leanstral, a Lean 4 proof assistant. Complete the task below using the provided Lean source context. The target mathlib commit is 5e932f97dd25535344f80f9dd8da3aab83df0fe6 (module Mathlib.Algebra.Module.SpanRank).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Prove the following theorem. The retrieved context below may help.

```lean
lemma Module.Basis.mk_eq_spanRank [RankCondition R] {ι : Type*} (v : Basis ι R M) :
    #(Set.range v) = (⊤ : Submodule R M).spanRank
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Algebra.Module.SpanRank.spanRank_toENat_eq_iInf_encard (L72-L87)
lemma spanRank_toENat_eq_iInf_encard (p : Submodule R M) : p.spanRank.toENat =
    (⨅ (s : Set M) (_ : span R s = p), s.encard) := by
rw [spanRank]
  apply le_antisymm
  · refine le_iInf₂ (fun s hs ↦ ?_)
    rw [Set.encard, ENat.card]
    exact toENat.monotone' (ciInf_le' _ (⟨s, hs⟩ : {s : Set M // span R s = p}))
  · have := congrFun toENat_comp_ofENat.{u}.symm (⨅ (s : Set M) (_ : span R s = p), s.encard)
    rw [id_eq] at this; rw [this]
    refine toENat.monotone' (le_ciInf fun s ↦ ?_)
    have : ofENat.{u} (⨅ (s' : Set M), ⨅ (_ : span R s' = p), s'.encard) ≤ ofENat s.1.encard :=
      ofENatHom.monotone' (le_trans (ciInf_le' _ s.1) (ciInf_le' _ s.2))
    apply le_trans this
    rw [Set.encard, ENat.card]
    exact Cardinal.ofENat_toENat_le _
```

-- snippet 2
```lean
-- Mathlib.Algebra.Module.SpanRank.spanRank_toENat_eq_iInf_finset_card (L88-L102)
lemma spanRank_toENat_eq_iInf_finset_card (p : Submodule R M) :
    p.spanRank.toENat = ⨅ (s : {s : Finset M // span R s = p}), (s.1.card : ℕ∞) := by
rw [spanRank_toENat_eq_iInf_encard]
  rcases eq_or_ne (⨅ (s : Set M) (_ : span R s = p), s.encard) ⊤ with (h1 | h2)
  · rw [h1, eq_comm]; simp_rw [iInf_eq_top] at h1 ⊢
    exact fun s ↦ False.elim (Set.encard_ne_top_iff.mpr s.1.finite_toSet (h1 s.1 s.2))
  · simp_rw [← Set.encard_coe_eq_coe_finsetCard]
    apply le_antisymm
    · exact le_iInf fun s ↦ iInf₂_le (s.1 : Set M) s.2
    · refine le_iInf fun s ↦ le_iInf fun h ↦ ?_
      by_cases hs : s.Finite
      · exact iInf_le_of_le ⟨hs.toFinset, by simpa⟩ (by simp)
      · rw [Set.Infinite.encard_eq hs]
        exact OrderTop.le_top _
```

-- snippet 3
```lean
-- Mathlib.Algebra.Module.SpanRank.spanFinrank_eq_iInf (L103-L107)
lemma spanFinrank_eq_iInf (p : Submodule R M) :
    p.spanFinrank = ⨅ (s : {s : Finset M // span R s = p}), s.1.card := by
simp [spanFinrank, Cardinal.toNat, spanRank_toENat_eq_iInf_finset_card, ENat.iInf_toNat]

/-- A submodule's `spanRank` is finite if and only if it is finitely generated. -/
```

-- snippet 4
```lean
-- Mathlib.Algebra.Module.SpanRank.spanRank_finite_iff_fg (L109-L119)
lemma spanRank_finite_iff_fg {p : Submodule R M} : p.spanRank < aleph0 ↔ p.FG := by
rw [spanRank, Submodule.fg_def]
  constructor
  · rintro h
    obtain ⟨s, hs⟩ : ⨅ (s : {s : Set M // span R s = p}), #s ∈
      Set.range (fun (s : {s : Set M // span R s = p}) ↦ #s) := csInf_mem ⟨#p, ⟨⟨p, by simp⟩, rfl⟩⟩
    refine ⟨s.1, ?_, s.2⟩
    simpa [← hs] using h
  · rintro ⟨s, hs₁, hs₂⟩
    exact (ciInf_le' _ ⟨s, hs₂⟩).trans_lt (by simpa)
```

-- snippet 5
```lean
-- Mathlib.Algebra.Module.SpanRank.spanFinrank_of_not_fg (L120-L127)
lemma spanFinrank_of_not_fg {p : Submodule R M} (hp : ¬p.FG) : p.spanFinrank = 0 := by
refine toNat_eq_zero.2 ?_
  right
  by_contra! h
  exact hp (spanRank_finite_iff_fg.1 h)

/-- A submodule is finitely generated if and only if its `spanRank` is equal to its `spanFinrank`.
-/
```

-- snippet 6
```lean
-- Mathlib.Algebra.Module.SpanRank.fg_iff_spanRank_eq_spanFinrank (L128-L131)
lemma fg_iff_spanRank_eq_spanFinrank {p : Submodule R M} : p.spanRank = p.spanFinrank ↔ p.FG := by
rw [spanFinrank, ← spanRank_finite_iff_fg, eq_comm]
  exact cast_toNat_eq_iff_lt_aleph0
```

-- snippet 7
```lean
-- Mathlib.Algebra.Module.SpanRank.FG (L132-L134)
lemma FG.spanRank_eq_spanFinrank {p : Submodule R M} (fg : p.FG) : p.spanRank = p.spanFinrank :=
fg_iff_spanRank_eq_spanFinrank.mpr fg
```

-- snippet 8
```lean
-- Mathlib.Algebra.Module.SpanRank.FG (L135-L138)
lemma FG.spanRank_le_iff {p : Submodule R M} (hp : p.FG) (n : ℕ) :
    p.spanRank ≤ n ↔ p.spanFinrank ≤ n :=
(Cardinal.toNat_le_iff_of_lt_aleph0 n (by simpa)).symm
```

-- snippet 9
```lean
-- Mathlib.Algebra.Module.SpanRank.FG (L139-L142)
lemma FG.spanRank_eq_iff {p : Submodule R M} (hp : p.FG) (n : ℕ) :
    p.spanRank = n ↔ p.spanFinrank = n :=
(Cardinal.toNat_eq_iff_of_lt_aleph0 n (by simpa)).symm
```

-- snippet 10
```lean
-- Mathlib.Algebra.Module.SpanRank.spanRank_span_le_card (L143-L147)
lemma spanRank_span_le_card (s : Set M) : (Submodule.span R s).spanRank ≤ #s := by
rw [spanRank]
  let s' : {s1 : Set M // span R s1 = span R s} := ⟨s, rfl⟩
  exact ciInf_le' _ s'
```

-- snippet 11
```lean
-- Mathlib.Algebra.Module.SpanRank.spanRank_span_range_of_linearIndependent (L148-L160)
lemma spanRank_span_range_of_linearIndependent [RankCondition R] {ι : Type u} {v : ι → M}
    (hv : v.Injective) (hs : LinearIndependent R v) :
    (span R (.range v)).spanRank = #ι := by
refine le_antisymm (le_trans (spanRank_span_le_card _) mk_range_le) (le_ciInf fun x ↦ ?_)
  have : #x.1 = #((Subtype.val : span R (.range v) → _) ⁻¹' x.1) :=
    (mk_preimage_of_injective_of_subset_range _ _ Subtype.val_injective (by simp [← x.2])).symm
  rw [this]
  refine le_trans ?_ ((Module.Basis.span hs).le_span (R := R) (J := Subtype.val ⁻¹' x.1) ?_)
  · rw [mk_range_eq]
    exact .of_comp (f := Subtype.val) (by convert hv; ext; simp [Module.Basis.span_apply])
  · apply map_injective_of_injective (f := (span R _).subtype) (injective_subtype _)
    simp [map_span, Set.image_preimage_eq_inter_range, Set.inter_eq_self_of_subset_left, ← x.2]
```

-- snippet 12
```lean
-- Mathlib.Algebra.Module.SpanRank.spanRank_span_of_linearIndepOn (L161-L164)
lemma spanRank_span_of_linearIndepOn [RankCondition R] (s : Set M) (hs : LinearIndepOn R id s) :
    (span R s).spanRank = #s := by
simp [← spanRank_span_range_of_linearIndependent Subtype.val_injective hs]
```

-- snippet 13
```lean
-- Mathlib.Algebra.Module.SpanRank.spanFinrank_span_le_encard (L165-L168)
lemma spanFinrank_span_le_encard (s : Set M) : (span R s).spanFinrank ≤ s.encard := by
rw [spanFinrank, Set.encard, ENat.card]
  exact le_trans (by simp) (toENat.monotone' (spanRank_span_le_card (R := R) s))
```

-- snippet 14
```lean
-- Mathlib.Algebra.Module.SpanRank.spanFinrank_span_le_ncard_of_finite (L169-L174)
lemma spanFinrank_span_le_ncard_of_finite {s : Set M} (hs : s.Finite) :
    (span R s).spanFinrank ≤ s.ncard := by
rw [← Nat.cast_le (α := ℕ∞)]
  exact le_trans (spanFinrank_span_le_encard _) hs.cast_ncard_eq.ge

/-- Constructs a generating set with cardinality equal to the `spanRank` of the submodule -/
```

-- snippet 15
```lean
-- Mathlib.Algebra.Module.SpanRank.exists_span_set_card_eq_spanRank (L175-L183)
theorem exists_span_set_card_eq_spanRank (p : Submodule R M) :
    ∃ s : Set M, #s = p.spanRank ∧ span R s = p := by
rw [spanRank]
  obtain ⟨s, hs⟩ : ⨅ (s : {s : Set M // span R s = p}), #s ∈
    Set.range (fun (s : {s : Set M // span R s = p}) ↦ #s) := csInf_mem ⟨#p, ⟨⟨p, by simp⟩, rfl⟩⟩
  exact ⟨s.1, ⟨hs, s.2⟩⟩

/-- Constructs a generating set with cardinality equal to the `spanFinrank` of the submodule when
  the submodule is finitely generated. -/
```

-- snippet 16
```lean
-- Mathlib.Algebra.Module.SpanRank.FG (L184-L191)
theorem FG.exists_span_set_encard_eq_spanFinrank {p : Submodule R M} (h : p.FG) :
    ∃ s : Set M, s.encard = p.spanFinrank ∧ span R s = p := by
obtain ⟨s, ⟨hs₁, hs₂⟩⟩ := exists_span_set_card_eq_spanRank p
  refine ⟨s, ⟨?_, hs₂⟩⟩
  have := fg_iff_spanRank_eq_spanFinrank.mpr h
  rw [Set.encard, ENat.card, spanFinrank, hs₁, this]
  simp
```

-- snippet 17
```lean
-- Mathlib.Algebra.Module.SpanRank.lift_spanRank_le_iff_exists_span_set_card_le (L192-L201)
lemma lift_spanRank_le_iff_exists_span_set_card_le (p : Submodule R M) {a : Cardinal.{max u v}} :
    Cardinal.lift.{v} p.spanRank ≤ a ↔ ∃ s : Set M, Cardinal.lift.{v} #s ≤ a ∧ span R s = p := by
constructor
  · intro h
    obtain ⟨s, ⟨hs₁, hs₂⟩⟩ := exists_span_set_card_eq_spanRank p
    exact ⟨s, ⟨hs₁ ▸ h, hs₂⟩⟩
  · exact fun ⟨s, ⟨h₁, h₂⟩⟩ ↦ h₂.symm ▸ (Cardinal.lift_le.mpr (spanRank_span_le_card s)).trans h₁

/-- For a finitely generated submodule, its spanRank is less than or equal to a cardinal `a`
  if and only if there is a generating subset with cardinality less than or equal to `a`. -/
```

-- snippet 18
```lean
-- Mathlib.Algebra.Module.SpanRank.FG (L202-L205)
lemma FG.spanRank_le_iff_exists_span_set_card_le (p : Submodule R M) {a : Cardinal} :
    p.spanRank ≤ a ↔ ∃ s : Set M, #s ≤ a ∧ span R s = p := by
convert lift_spanRank_le_iff_exists_span_set_card_le p (a := a) <;> simp
```

-- snippet 19
```lean
-- Mathlib.Algebra.Module.SpanRank.spanRank_eq_zero_iff_eq_bot (L207-L216)
lemma spanRank_eq_zero_iff_eq_bot {I : Submodule R M} : I.spanRank = 0 ↔ I = ⊥ := by
constructor
  · intro h
    obtain ⟨s, ⟨hs₁, hs₂⟩⟩ :=
      (FG.spanRank_le_iff_exists_span_set_card_le I (a := 0)).mp (by rw [h])
    simp only [nonpos_iff_eq_zero, mk_eq_zero_iff, Set.isEmpty_coe_sort] at hs₁
    simp_all
  · rintro rfl; rw [spanRank]
    exact Cardinal.iInf_eq_zero_iff.mpr (Or.inr ⟨⟨∅, by simp⟩, by simp⟩)
```

-- snippet 20
```lean
-- Mathlib.Algebra.Module.SpanRank.spanRank_bot (L218-L219)
lemma spanRank_bot : (⊥ : Ideal R).spanRank = 0 := Submodule.spanRank_eq_zero_iff_eq_bot.mpr rfl
```

-- snippet 21
```lean
-- Mathlib.Algebra.Module.SpanRank.spanFinrank_bot (L221-L226)
lemma spanFinrank_bot : (⊥ : Submodule R M).spanFinrank = 0 := by simp [spanFinrank]
/-- Generating elements for the submodule of minimum cardinality. -/
noncomputable def generators (p : Submodule R M) : Set M :=
  Classical.choose (exists_span_set_card_eq_spanRank p)
```

-- snippet 22
```lean
-- Mathlib.Algebra.Module.SpanRank.generators_card (L227-L229)
lemma generators_card (p : Submodule R M) : #(generators p) = spanRank p :=
(Classical.choose_spec (exists_span_set_card_eq_spanRank p)).1
```

-- snippet 23
```lean
-- Mathlib.Algebra.Module.SpanRank.FG (L230-L235)
lemma FG.generators_ncard {p : Submodule R M} (h : p.FG) :
    (generators p).ncard = spanFinrank p := by
rw [← Nat.cast_inj (R := Cardinal), ← fg_iff_spanRank_eq_spanFinrank.mpr h, Set.ncard, Set.encard,
     ENat.card, generators_card, toNat_toENat, ← spanFinrank]
  exact (fg_iff_spanRank_eq_spanFinrank.mpr h).symm
```

-- snippet 24
```lean
-- Mathlib.Algebra.Module.SpanRank.FG (L236-L241)
lemma FG.finite_generators {p : Submodule R M} (hp : p.FG) :
    p.generators.Finite := by
rw [← Cardinal.lt_aleph0_iff_set_finite, Submodule.generators_card]
  exact spanRank_finite_iff_fg.mpr hp

/-- The span of the generators equals the submodule. -/
```

-- snippet 25
```lean
-- Mathlib.Algebra.Module.SpanRank.span_generators (L242-L245)
lemma span_generators (p : Submodule R M) : span R (generators p) = p :=
(Classical.choose_spec (exists_span_set_card_eq_spanRank p)).2

/-- The elements of the generators are in the submodule. -/
```

-- snippet 26
```lean
-- Mathlib.Algebra.Module.Basic.invOf_two_smul_add_invOf_two_smul (L36-L40)
theorem invOf_two_smul_add_invOf_two_smul (R) [Semiring R] [AddCommMonoid M] [Module R M]
    [Invertible (2 : R)] (x : M) :
    (⅟2 : R) • x + (⅟2 : R) • x = x :=
Convex.combo_self invOf_two_add_invOf_two _
```

-- snippet 27
```lean
-- Mathlib.Algebra.Module.Basic.indicator_smul_apply (L122-L127)
lemma indicator_smul_apply (s : Set α) (r : α → R) (f : α → M) (a : α) :
    indicator s (fun a ↦ r a • f a) a = r a • indicator s f a := by
dsimp only [indicator]
  split_ifs
  exacts [rfl, (smul_zero (r a)).symm]
```

-- snippet 28
```lean
-- Mathlib.Algebra.Module.BigOperators.sum_single_smul (L66-L71)
lemma sum_single_smul
    {R : Type*} [Semiring R] [Module R α] (f : ι → α) (r : R) (i₀ : ι) :
    ∑ i, (Pi.single (M := fun _ ↦ R) i₀ r i) • f i = r • f i₀ := by
rw [Finset.sum_eq_single i₀, Pi.single_eq_same] <;> aesop

end Fintype
```

-- snippet 29
```lean
-- Mathlib.Algebra.Module.Defs.neg_smul_neg (L142-L145)
theorem neg_smul_neg : -r • -x = r • x := by rw [neg_smul, smul_neg, neg_neg]
variable (R)
```

-- snippet 30
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.coe_toLinearMap_one (L99-L100)
lemma coe_toLinearMap_one : (↑(1 : M ≃ₗ[R] M) : M →ₗ[R] M) = LinearMap.id := rfl
```

-- snippet 31
```lean
-- Mathlib.Algebra.Module.CharacterModule.CharacterModule (L46-L49)
def CharacterModule : Type uA := A →+ AddCircle (1 : ℚ)
namespace CharacterModule
```

-- snippet 32
```lean
-- Mathlib.Algebra.Module.Basic.indicator_smul_left (L151-L154)
lemma indicator_smul_left (s : Set α) (r : α → R) (f : α → M) :
    indicator s (fun a ↦ r a • f a) = fun a ↦ indicator s r a • f a :=
funext <| indicator_smul_apply_left _ _ _
```

-- snippet 33
```lean
-- Mathlib.Algebra.Module.Basic.inv_intCast_smul_eq (L75-L80)
theorem inv_intCast_smul_eq {E : Type*} (R S : Type*) [AddCommGroup E] [DivisionRing R]
    [DivisionRing S] [Module R E] [Module S E] (n : ℤ) (x : E) : (n⁻¹ : R) • x = (n⁻¹ : S) • x :=
map_inv_intCast_smul (AddMonoidHom.id E) R S n x

/-- If `E` is a vector space over a division semiring `R` and has a monoid action by `α`, then that
action commutes by scalar multiplication of inverses of natural numbers in `R`. -/
```

-- snippet 34
```lean
-- Mathlib.Algebra.Module.Card.mk_le_of_module (L28-L35)
theorem mk_le_of_module (R : Type u) (E : Type v)
    [AddCommGroup E] [Ring R] [IsDomain R] [Module R E] [Nontrivial E] [Module.IsTorsionFree R E] :
    Cardinal.lift.{v} (#R) ≤ Cardinal.lift.{u} (#E) := by
obtain ⟨x, hx⟩ : ∃ (x : E), x ≠ 0 := exists_ne 0
  have : Injective (fun k ↦ k • x) := smul_left_injective R hx
  exact lift_mk_le_lift_mk_of_injective this

end Cardinal
```

-- snippet 35
```lean
-- Mathlib.Algebra.Module.Defs.two_smul (L81-L104)
theorem two_smul : (2 : R) • x = x + x := by rw [← one_add_one_eq_two, add_smul, one_smul]
/-- Pullback a `Module` structure along an injective additive monoid homomorphism.
See note [reducible non-instances]. -/
protected abbrev Function.Injective.module [AddCommMonoid M₂] [SMul R M₂] (f : M₂ →+ M)
    (hf : Injective f) (smul : ∀ (c : R) (x), f (c • x) = c • f x) : Module R M₂ :=
  { hf.distribMulAction f smul with
    add_smul := fun c₁ c₂ x => hf <| by simp only [smul, f.map_add, add_smul]
    zero_smul := fun x => hf <| by simp only [smul, zero_smul, f.map_zero] }

/-- Pushforward a `Module` structure along a surjective additive monoid homomorphism.
See note [reducible non-instances]. -/
protected abbrev Function.Surjective.module [AddCommMonoid M₂] [SMul R M₂] (f : M →+ M₂)
    (hf : Surjective f) (smul : ∀ (c : R) (x), f (c • x) = c • f x) : Module R M₂ :=
  { toDistribMulAction := hf.distribMulAction f smul
    add_smul := fun c₁ c₂ x => by
      rcases hf x with ⟨x, rfl⟩
      simp only [add_smul, ← smul, ← f.map_add]
    zero_smul := fun x => by
      rcases hf x with ⟨x, rfl⟩
      rw [← f.map_zero, ← smul, zero_smul] }

variable {R}
```

-- snippet 36
```lean
-- Mathlib.Algebra.Module.Basic.indicator_const_smul_apply (L132-L135)
lemma indicator_const_smul_apply (s : Set α) (r : R) (f : α → M) (a : α) :
    indicator s (r • f ·) a = r • indicator s f a :=
indicator_smul_apply s (fun _ ↦ r) f a
```

-- snippet 37
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.coe_toLinearMap_mul (L102-L105)
lemma coe_toLinearMap_mul {e₁ e₂ : M ≃ₗ[R] M} :
    (↑(e₁ * e₂) : M →ₗ[R] M) = (e₁ : M →ₗ[R] M) * (e₂ : M →ₗ[R] M) :=
rfl
```

-- snippet 38
```lean
-- Mathlib.Algebra.Module.CharacterModule.dual_surjective_of_injective (L103-L109)
lemma dual_surjective_of_injective (f : A →ₗ[R] B) (hf : Function.Injective f) :
    Function.Surjective (dual f) :=
(Module.Baer.of_divisible _).extension_property_addMonoidHom _ hf

/--
Two isomorphic modules have isomorphic character modules.
-/
```

-- snippet 39
```lean
-- Mathlib.Algebra.Module.BigOperators.Finset (L38-L40)
theorem Finset.sum_smul {f : ι → R} {s : Finset ι} {x : M} :
    (∑ i ∈ s, f i) • x = ∑ i ∈ s, f i • x := map_sum ((smulAddHom R M).flip x) f s
```

-- snippet 40
```lean
-- Mathlib.Algebra.Module.End.IsAddUnit (L62-L67)
lemma IsAddUnit.smul_left [DistribSMul S M] (hx : IsAddUnit x) (s : S) :
    IsAddUnit (s • x) :=
hx.map (DistribSMul.toAddMonoidHom M s)

variable {r} (x)
```

-- snippet 41
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.restrictScalars_injective (L55-L58)
theorem restrictScalars_injective :
    Function.Injective (restrictScalars R : (M ≃ₗ[S] M₂) → M ≃ₗ[R] M₂) := fun _ _ h ↦
ext (LinearEquiv.congr_fun h :)
```

-- snippet 42
```lean
-- Mathlib.Algebra.Module.Basic.Units (L31-L34)
theorem Units.neg_smul [Ring R] [AddCommGroup M] [Module R M] (u : Rˣ) (x : M) :
    -u • x = -(u • x) := by
rw [Units.smul_def, Units.val_neg, _root_.neg_smul, Units.smul_def]
```

-- snippet 43
```lean
-- Mathlib.Algebra.Module.Congruence.Defs.addConGen' (L64-L81)
def addConGen' (r : M → M → Prop) (hr : ∀ (s : S) {m m'}, r m m' → r (s • m) (s • m')) :
    ModuleCon S M where
  toAddCon := addConGen r
smul s _ _ h := ((addConGen r).comap (DistribSMul.toAddMonoidHom M s) <| by simp).addConGen_le
    (fun _ _ h ↦ .of _ _ (hr s h)) h

/-- The `AddCon` generated by a `SMulCon` is a `ModuleCon`. -/
protected abbrev addConGen (c : SMulCon S M) : ModuleCon S M := addConGen' c.r c.smul

end addConGen

end SMulCon

namespace ModuleCon

/-- The quotient by a congruence relation preserving addition and scalar multiplication. -/
protected def Quotient [Add M] [SMul S M] (c : ModuleCon S M) : Type _ := Quotient c.toSetoid
```

-- snippet 44
```lean
-- Mathlib.Algebra.Module.Bimodule.smul_mem (L91-L94)
theorem smul_mem (p : Submodule (A ⊗[R] B) M) (a : A) {m : M} (hm : m ∈ p) : a • m ∈ p := by
suffices a • m = a ⊗ₜ[R] (1 : B) • m by exact this.symm ▸ p.smul_mem _ hm
  simp [TensorProduct.Algebra.smul_def]
```

-- snippet 45
```lean
-- Mathlib.Algebra.Module.End.smulAddHom_apply (L57-L61)
theorem smulAddHom_apply : smulAddHom R M r x = r • x :=
rfl

variable {x}
```

-- snippet 46
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.coe_pow (L106-L107)
theorem coe_pow (e : M ≃ₗ[R] M) (n : ℕ) : ⇑(e ^ n) = e^[n] := hom_coe_pow _ rfl (fun _ _ ↦ rfl) _ _
```

-- snippet 47
```lean
-- Mathlib.Algebra.Module.Basic.support_smul_subset_right (L101-L104)
lemma support_smul_subset_right [Zero M] [SMulZeroClass R M] (f : α → R) (g : α → M) :
    support (f • g) ⊆ support g :=
fun x hbf hf ↦ hbf <| by rw [Pi.smul_apply', hf, smul_zero]
```

-- snippet 48
```lean
-- Mathlib.Algebra.Module.CharacterModule.dual_injective_of_surjective (L95-L102)
lemma dual_injective_of_surjective (f : A →ₗ[R] B) (hf : Function.Surjective f) :
    Function.Injective (dual f) := by
intro φ ψ eq
  ext x
  obtain ⟨y, rfl⟩ := hf x
  change (dual f) φ _ = (dual f) ψ _
  rw [eq]
```

-- snippet 49
```lean
-- Mathlib.Algebra.Module.CharacterModule.exists_character_apply_ne_zero_of_ne_zero (L215-L219)
lemma exists_character_apply_ne_zero_of_ne_zero {a : A} (ne_zero : a ≠ 0) :
    ∃ (c : CharacterModule A), c a ≠ 0 :=
have ⟨c, hc⟩ := dual_surjective_of_injective _ (Submodule.injective_subtype _) (ofSpanSingleton a)
  ⟨c, fun h ↦ ne_zero <| eq_zero_of_ofSpanSingleton_apply_self a <| by rwa [← hc]⟩
```

-- snippet 50
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.restrictScalars (L48-L54)
def restrictScalars (f : M ≃ₗ[S] M₂) : M ≃ₗ[R] M₂ :=
{ f.toLinearMap.restrictScalars R with
    toFun := f
    invFun := f.symm
    left_inv := f.left_inv
    right_inv := f.right_inv }
```

-- snippet 51
```lean
-- Mathlib.Algebra.Module.Bimodule.toSubmodule (L109-L114)
def toSubmodule (p : Submodule (A ⊗[R] B) M) : Submodule A M :=
{ p with
    carrier := p
    smul_mem' := smul_mem p }

/-- Forgetting the `A` action, a `Submodule` over `A ⊗[R] B` is just a `Submodule` over `B`. -/
```

-- snippet 52
```lean
-- Mathlib.Algebra.Module.End.smulAddHom (L51-L55)
def smulAddHom : R →+ M →+ M :=
(Module.toAddMonoidEnd R M).toAddMonoidHom

variable {R M}
```

-- snippet 53
```lean
-- Mathlib.Algebra.Module.End.AddMonoid (L32-L41)
theorem AddMonoid.End.natCast_def (n : ℕ) :
    (↑n : AddMonoid.End M) = DistribMulAction.toAddMonoidEnd ℕ M n :=
rfl

variable (R M)

set_option backward.isDefEq.respectTransparency false in
/-- `(•)` as an `AddMonoidHom`.

This is a stronger version of `DistribMulAction.toAddMonoidEnd` -/
```

-- snippet 54
```lean
-- Mathlib.Algebra.Module.Bimodule.mk (L82-L90)
def mk (p : AddSubmonoid M) (hA : ∀ (a : A) {m : M}, m ∈ p → a • m ∈ p)
    (hB : ∀ (b : B) {m : M}, m ∈ p → b • m ∈ p) : Submodule (A ⊗[R] B) M :=
{ p with
    carrier := p
    smul_mem' := fun ab m =>
      TensorProduct.induction_on ab (fun _ => by simp only [zero_smul, SetLike.mem_coe, zero_mem])
        (fun a b hm => by simpa only [TensorProduct.Algebra.smul_def] using hA a (hB b hm))
        fun z w hz hw hm => by simpa only [add_smul] using p.add_mem (hz hm) (hw hm) }
```

-- snippet 55
```lean
-- Mathlib.Algebra.Module.BigOperators.Fintype (L45-L51)
lemma Fintype.sum_smul_sum [Fintype α] [Fintype β] (f : α → R) (g : β → M) :
    (∑ i, f i) • ∑ j, g j = ∑ i, ∑ j, f i • g j := Finset.sum_smul_sum _ _
end AddCommMonoid

open Finset
```

-- snippet 56
```lean
-- Mathlib.Algebra.Module.CharacterModule.eq_zero_of_character_apply (L220-L224)
lemma eq_zero_of_character_apply {a : A} (h : ∀ c : CharacterModule A, c a = 0) : a = 0 := by
contrapose! h; exact exists_character_apply_ne_zero_of_ne_zero h

variable [Module R A] [Module R A'] [Module R B] {R A' B}
```

-- snippet 57
```lean
-- Mathlib.Algebra.Module.Basic.indicator_smul (L128-L131)
lemma indicator_smul (s : Set α) (r : α → R) (f : α → M) :
    indicator s (fun a ↦ r a • f a) = fun a ↦ r a • indicator s f a :=
funext <| indicator_smul_apply s r f
```

-- snippet 58
```lean
-- Mathlib.Algebra.Module.Basic.smul_indicator_one_apply (L168-L173)
lemma smul_indicator_one_apply (s : Set α) (r : R) (a : α) :
    r • s.indicator (1 : α → R) a = s.indicator (fun _ ↦ r) a := by
simp_rw [← indicator_const_smul_apply, Pi.one_apply, smul_eq_mul, mul_one]

end MulZeroOneClass
end Set
```

-- snippet 59
```lean
-- Mathlib.Algebra.Module.Bimodule.toSubmodule' (L116-L129)
def toSubmodule' (p : Submodule (A ⊗[R] B) M) : Submodule B M :=
{ p with
    carrier := p
    smul_mem' := smul_mem' p }

end Algebra

section Ring

variable (R S M : Type*) [Ring R] [Ring S]
variable [AddCommGroup M] [Module R M] [Module S M] [SMulCommClass R S M]

/-- A `Submodule` over `R ⊗[ℕ] S` is naturally also a `Submodule` over the canonically-isomorphic
ring `R ⊗[ℤ] S`. -/
```

-- snippet 60
```lean
-- Mathlib.Algebra.Module.Defs.Convex (L76-L80)
theorem Convex.combo_self {a b : R} (h : a + b = 1) (x : M) : a • x + b • x = x := by
rw [← add_smul, h, one_smul]

variable (R)
```

-- snippet 61
```lean
-- Mathlib.Algebra.Module.Bimodule.smul_mem' (L95-L100)
theorem smul_mem' (p : Submodule (A ⊗[R] B) M) (b : B) {m : M} (hm : m ∈ p) : b • m ∈ p := by
suffices b • m = (1 : A) ⊗ₜ[R] b • m by exact this.symm ▸ p.smul_mem _ hm
  simp [TensorProduct.Algebra.smul_def]

/-- If `A` and `B` are also `Algebra`s over yet another set of scalars `S` then we may "base change"
from `R` to `S`. -/
```

-- snippet 62
```lean
-- Mathlib.Algebra.Module.Basic.inv_intCast_smul_comm (L88-L94)
theorem inv_intCast_smul_comm {α E : Type*} (R : Type*) [AddCommGroup E] [DivisionRing R]
    [Module R E] [DistribSMul α E] (n : ℤ) (s : α) (x : E) :
    (n⁻¹ : R) • s • x = s • (n⁻¹ : R) • x :=
(map_inv_intCast_smul (DistribSMul.toAddMonoidHom E s) R R n x).symm

namespace Function
```

-- snippet 63
```lean
-- Mathlib.Algebra.Module.Basic.indicator_smul_const (L158-L167)
lemma indicator_smul_const (s : Set α) (r : α → R) (m : M) :
    indicator s (r · • m) = (indicator s r · • m) :=
funext <| indicator_smul_const_apply _ _ _

end SMulWithZero

section MulZeroOneClass

variable [MulZeroOneClass R]
```

-- snippet 64
```lean
-- Mathlib.Algebra.Module.CharacterModule.dual_injective_iff_surjective (L246-L249)
lemma dual_injective_iff_surjective {f : A →ₗ[R] A'} :
    Function.Injective (dual f) ↔ Function.Surjective f :=
⟨fun h ↦ surjective_of_dual_injective f h, fun h ↦ dual_injective_of_surjective f h⟩
```

-- snippet 65
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.coe_one (L94-L95)
lemma coe_one : ↑(1 : M ≃ₗ[R] M) = id := rfl
```

-- snippet 66
```lean
-- Mathlib.Algebra.Module.CharacterModule.dual_zero (L86-L89)
lemma dual_zero : dual (0 : A →ₗ[R] B) = 0 := by
ext f
  exact map_zero f
```

-- snippet 67
```lean
-- Mathlib.Algebra.Module.Basic.indicator_smul_apply_left (L145-L150)
lemma indicator_smul_apply_left (s : Set α) (r : α → R) (f : α → M) (a : α) :
    indicator s (fun a ↦ r a • f a) a = indicator s r a • f a := by
dsimp only [indicator]
  split_ifs
  exacts [rfl, (zero_smul _ (f a)).symm]
```

-- snippet 68
```lean
-- Mathlib.Algebra.Module.BigOperators.sum_piFinset_apply (L58-L64)
lemma sum_piFinset_apply (f : κ → α) (s : Finset κ) (i : ι) :
    ∑ g ∈ piFinset fun _ : ι ↦ s, f (g i) = #s ^ (card ι - 1) • ∑ b ∈ s, f b := by
classical
  rw [Finset.sum_comp]
  simp only [eval_image_piFinset_const, card_filter_piFinset_const s, ite_smul, zero_smul, smul_sum,
    Finset.sum_ite_mem, inter_self]
```

-- snippet 69
```lean
-- Mathlib.Algebra.Module.Defs.add_smul (L73-L75)
theorem add_smul : (r + s) • x = r • x + s • x :=
Module.add_smul r s x
```

-- snippet 70
```lean
-- Mathlib.Algebra.Module.Congruence.Defs.ModuleCon (L148-L160)
def ModuleCon.ker [Monoid R] [Monoid S] [AddMonoid M] [AddMonoid N] [DistribMulAction R M]
    [DistribMulAction S N] {φ : R →* S} (f : M →ₑ+[φ] N) : ModuleCon R M where
  __ := SMulCon.ker f.toMulActionHom
__ := AddCon.ker f

/-- The first isomorphism theorem for semimodules in the case of a surjective homomorphism. -/
noncomputable def ModuleCon.quotientKerEquivOfSurjective [Semiring S] [AddCommMonoid M]
    [AddCommMonoid N] [Module S M] [Module S N] (f : M →ₗ[S] N) (hf : Function.Surjective f) :
    (ker f.toDistribMulActionHom).Quotient ≃ₗ[S] N where
  __ := AddCon.quotientKerEquivOfSurjective f.toAddMonoidHom hf
  map_smul' s := by rintro ⟨⟩; apply map_smul f

end ker
```

-- snippet 71
```lean
-- Mathlib.Algebra.Module.Basic.indicator_const_smul (L136-L144)
lemma indicator_const_smul (s : Set α) (r : R) (f : α → M) :
    indicator s (r • f ·) = (r • indicator s f ·) :=
funext <| indicator_const_smul_apply s r f

end SMulZeroClass

section SMulWithZero
variable [Zero R] [Zero M] [SMulWithZero R M]
```

-- snippet 72
```lean
-- Mathlib.Algebra.Module.DedekindDomain.isInternal_prime_power_torsion (L64-L75)
theorem isInternal_prime_power_torsion [Module.Finite R M]
    (hM : Module.IsTorsion R M) :
    DirectSum.IsInternal fun p : (factors (⊤ : Submodule R M).annihilator).toFinset =>
      torsionBySet R M (p ^ (factors (⊤ : Submodule R M).annihilator).count ↑p : Ideal R) := by
have hM' := Module.isTorsionBySet_annihilator_top R M
  have hI := Submodule.annihilator_top_inter_nonZeroDivisors hM
  refine isInternal_prime_power_torsion_of_is_torsion_by_ideal ?_ hM'
  rw [Submodule.ne_bot_iff]
  obtain ⟨x, H, hx⟩ := hI; exact ⟨x, H, nonZeroDivisors.ne_zero hx⟩

/-- A finitely generated torsion module over a Dedekind domain is an internal direct sum of its
`p i ^ e i`-torsion submodules for some prime ideals `p i` and numbers `e i`. -/
```

-- snippet 73
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.automorphismGroup (L81-L89)
instance automorphismGroup : Group (M ≃ₗ[R] M) where
  mul f g := g.trans f
one := LinearEquiv.refl R M
  inv f := f.symm
  mul_assoc _ _ _ := rfl
  mul_one _ := ext fun _ ↦ rfl
  one_mul _ := ext fun _ ↦ rfl
  inv_mul_cancel f := ext <| f.left_inv
```

-- snippet 74
```lean
-- Mathlib.Algebra.Module.Basic.indicator_smul_const_apply (L155-L157)
lemma indicator_smul_const_apply (s : Set α) (r : α → R) (m : M) (a : α) :
    indicator s (r · • m) a = indicator s r a • m := indicator_smul_apply_left _ _ _ _
```

-- snippet 75
```lean
-- Mathlib.Algebra.Module.CharacterModule.dual_rTensor_conj_homEquiv (L147-L171)
theorem dual_rTensor_conj_homEquiv (f : A →ₗ[R] A') :
    homEquiv.symm.toLinearMap ∘ₗ dual (f.rTensor B) ∘ₗ homEquiv.toLinearMap = f.lcomp R _ := rfl
end module

/--
`ℤ⋆`, the character module of `ℤ` in the unit rational circle.
-/
protected abbrev int : Type := CharacterModule ℤ

/-- Given `n : ℕ`, the map `m ↦ m / n`. -/
protected abbrev int.divByNat (n : ℕ) : CharacterModule.int :=
  LinearMap.toSpanSingleton ℤ _ (QuotientAddGroup.mk (n : ℚ)⁻¹) |>.toAddMonoidHom

protected lemma int.divByNat_self (n : ℕ) :
    int.divByNat n n = 0 := by
  obtain rfl | h0 := eq_or_ne n 0
  · apply map_zero
  exact (AddCircle.coe_eq_zero_iff _).mpr
    ⟨1, by simp [mul_inv_cancel₀ (Nat.cast_ne_zero (R := ℚ).mpr h0)]⟩

variable {A}

/-- The `ℤ`-submodule spanned by a single element `a` is isomorphic to the quotient of `ℤ`
by the ideal generated by the order of `a`. -/
```

-- snippet 76
```lean
-- Mathlib.Algebra.Module.BigOperators.Multiset (L29-L31)
theorem Multiset.sum_smul {l : Multiset R} {x : M} : l.sum • x = (l.map fun r ↦ r • x).sum :=
((smulAddHom R M).flip x).map_multiset_sum l
```

-- snippet 77
```lean
-- Mathlib.Algebra.Module.Basic.map_inv_intCast_smul (L58-L67)
theorem map_inv_intCast_smul [AddCommGroup M] [AddCommGroup M₂] {F : Type*} [FunLike F M M₂]
    [AddMonoidHomClass F M M₂] (f : F) (R S : Type*) [DivisionRing R] [DivisionRing S] [Module R M]
    [Module S M₂] (z : ℤ) (x : M) : f ((z⁻¹ : R) • x) = (z⁻¹ : S) • f x := by
obtain ⟨n, rfl | rfl⟩ := z.eq_nat_or_neg
  · rw [Int.cast_natCast, Int.cast_natCast, map_inv_natCast_smul _ R S]
  · simp_rw [Int.cast_neg, Int.cast_natCast, inv_neg, neg_smul, map_neg,
      map_inv_natCast_smul _ R S]

/-- If `E` is a vector space over two division semirings `R` and `S`, then scalar multiplications
agree on inverses of natural numbers in `R` and `S`. -/
```

-- snippet 78
```lean
-- Mathlib.Algebra.Module.Defs.smul_add_one_sub_smul (L109-L117)
theorem smul_add_one_sub_smul {R : Type*} [Ring R] [Module R M] {r : R} {m : M} :
    r • m + (1 - r) • m = m := by rw [← add_smul, add_sub_cancel, one_smul]
end AddCommMonoid

section AddCommGroup

variable [Semiring R] [AddCommGroup M]
```

-- snippet 79
```lean
-- Mathlib.Algebra.Module.CharacterModule.surjective_of_dual_injective (L236-L245)
lemma surjective_of_dual_injective (f : A →ₗ[R] A') (hf : Function.Injective (dual f)) :
    Function.Surjective f := by
rw [← LinearMap.range_eq_top, ← Submodule.unique_quotient_iff_eq_top]
  refine ⟨Unique.mk inferInstance fun a ↦ eq_zero_of_character_apply fun c ↦ ?_⟩
  obtain ⟨b, rfl⟩ := QuotientAddGroup.mk'_surjective _ a
  suffices eq : dual (Submodule.mkQ _) c = 0 from congr($eq b)
  refine hf ?_
  rw [← LinearMap.comp_apply, ← dual_comp, LinearMap.range_mkQ_comp, dual_zero,
    LinearMap.zero_apply, dual_apply, AddMonoidHom.zero_comp]
```

-- snippet 80
```lean
-- Mathlib.Algebra.Module.CharacterModule.congr (L110-L119)
def congr (e : A ≃ₗ[R] B) : CharacterModule A ≃ₗ[R] CharacterModule B :=
.ofLinear (dual e.symm) (dual e)
    (by ext c _; exact congr(c $(e.right_inv _)))
    (by ext c _; exact congr(c $(e.left_inv _)))

open TensorProduct

/--
Any linear map `L : A → B⋆` induces a character in `(A ⊗ B)⋆` by `a ⊗ b ↦ L a b`.
-/
```

-- snippet 81
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.one_eq_refl (L90-L90)
lemma one_eq_refl : (1 : M ≃ₗ[R] M) = refl R M := rfl
```

-- snippet 82
```lean
-- Mathlib.Algebra.Module.DedekindDomain.exists_isInternal_prime_power_torsion (L76-L83)
theorem exists_isInternal_prime_power_torsion [Module.Finite R M] (hM : Module.IsTorsion R M) :
    ∃ (P : Finset <| Ideal R) (_ : DecidableEq P) (_ : ∀ p ∈ P, Prime p) (e : P → ℕ),
      DirectSum.IsInternal fun p : P => torsionBySet R M (p ^ e p : Ideal R) := by
classical
  exact ⟨_, _, fun p hp => prime_of_factor p (Multiset.mem_toFinset.mp hp), _,
    isInternal_prime_power_torsion hM⟩

end Submodule
```

-- snippet 83
```lean
-- Mathlib.Algebra.Module.Defs.sub_smul (L150-L166)
theorem sub_smul (r s : R) (y : M) : (r - s) • y = r • y - s • y := by
simp [add_smul, sub_eq_add_neg]

end Module

/-- A module over a `Subsingleton` semiring is a `Subsingleton`. We cannot register this
as an instance because Lean has no way to guess `R`. -/
protected theorem Module.subsingleton (R M : Type*) [MonoidWithZero R] [Subsingleton R] [Zero M]
    [MulActionWithZero R M] : Subsingleton M :=
  MulActionWithZero.subsingleton R M

/-- A semiring is `Nontrivial` provided that there exists a nontrivial module over this semiring. -/
protected theorem Module.nontrivial (R M : Type*) [MonoidWithZero R] [Nontrivial M] [Zero M]
    [MulActionWithZero R M] : Nontrivial R :=
  MulActionWithZero.nontrivial R M

-- see Note [lower instance priority]
```

-- snippet 84
```lean
-- Mathlib.Algebra.Module.CharacterModule.dual_bijective_iff_bijective (L250-L255)
lemma dual_bijective_iff_bijective {f : A →ₗ[R] A'} :
    Function.Bijective (dual f) ↔ Function.Bijective f :=
⟨fun h ↦ ⟨dual_surjective_iff_injective.mp h.2, dual_injective_iff_surjective.mp h.1⟩,
  fun h ↦ ⟨dual_injective_iff_surjective.mpr h.2, dual_surjective_iff_injective.mpr h.1⟩⟩

end CharacterModule
```

-- snippet 85
```lean
-- Mathlib.Algebra.Module.Bimodule.baseChange (L102-L107)
def baseChange (S : Type*) [CommSemiring S] [Module S M] [Algebra S A] [Algebra S B]
    [IsScalarTower S A M] [IsScalarTower S B M] (p : Submodule (A ⊗[R] B) M) :
    Submodule (A ⊗[S] B) M :=
mk p.toAddSubmonoid (smul_mem p) (smul_mem' p)

/-- Forgetting the `B` action, a `Submodule` over `A ⊗[R] B` is just a `Submodule` over `A`. -/
```

-- snippet 86
```lean
-- Mathlib.Algebra.Module.Basic.support_const_smul_subset (L113-L121)
lemma support_const_smul_subset [Zero M] [SMulZeroClass R M] (a : R) (f : α → M) :
    support (a • f) ⊆ support f := support_smul_subset_right (fun _ ↦ a) f
end Function

namespace Set
section SMulZeroClass
variable [Zero M] [SMulZeroClass R M]
```

-- snippet 87
```lean
-- Mathlib.Algebra.Module.Bimodule.toSubbimoduleInt (L131-L135)
def toSubbimoduleInt (p : Submodule (R ⊗[ℕ] S) M) : Submodule (R ⊗[ℤ] S) M :=
baseChange ℤ p

/-- A `Submodule` over `R ⊗[ℤ] S` is naturally also a `Submodule` over the canonically-isomorphic
ring `R ⊗[ℕ] S`. -/
```

-- snippet 88
```lean
-- Mathlib.Algebra.Module.BigOperators.List (L26-L28)
theorem List.sum_smul {l : List R} {x : M} : l.sum • x = (l.map fun r ↦ r • x).sum :=
map_list_sum ((smulAddHom R M).flip x) l
```

-- snippet 89
```lean
-- Mathlib.Algebra.Module.DedekindDomain.isInternal_prime_power_torsion_of_is_torsion_by_ideal (L37-L63)
theorem isInternal_prime_power_torsion_of_is_torsion_by_ideal
    {I : Ideal R} (hI : I ≠ ⊥) (hM : Module.IsTorsionBySet R M I) :
    DirectSum.IsInternal fun p : (factors I).toFinset =>
      torsionBySet R M (p ^ (factors I).count ↑p : Ideal R) := by
let P := factors I
  have prime_of_mem := fun p (hp : p ∈ P.toFinset) =>
    prime_of_factor p (Multiset.mem_toFinset.mp hp)
  apply torsionBySet_isInternal (p := fun p => p ^ P.count p) _
  · convert hM
    rw [← Finset.inf_eq_iInf, IsDedekindDomain.inf_pow_eq_prod_of_prime,
      ← Finset.prod_multiset_count, ← associated_iff_eq]
    · exact factors_prod hI
    · exact prime_of_mem
    · exact fun _ _ _ _ ij => ij
  · intro p hp q hq pq; dsimp
    rw [irreducible_pow_sup]
    · suffices (normalizedFactors _).count p = 0 by rw [this, zero_min, pow_zero, Ideal.one_eq_top]
      rw [Multiset.count_eq_zero,
        normalizedFactors_of_irreducible_pow (prime_of_mem q hq).irreducible,
        Multiset.mem_replicate]
      exact fun H => pq <| H.2.trans <| normalize_eq q
    · rw [← Ideal.zero_eq_bot]; apply pow_ne_zero; exact (prime_of_mem q hq).ne_zero
    · exact (prime_of_mem p hp).irreducible

/-- A finitely generated torsion module over a Dedekind domain is an internal direct sum of its
`p i ^ e i`-torsion submodules where `p i` are factors of `(⊤ : Submodule R M).annihilator` and
`e i` are their multiplicities. -/
```

-- snippet 90
```lean
-- Mathlib.Algebra.Module.Defs.neg_one_smul (L146-L149)
theorem neg_one_smul (x : M) : (-1 : R) • x = -x := by simp
variable {R}
```

-- snippet 91
```lean
-- Mathlib.Algebra.Module.Congruence.Defs.SMulCon (L143-L147)
def SMulCon.ker [SMul R M] [SMul S N] {φ : R → S} (f : M →ₑ[φ] N) : SMulCon R M where
  __ := Setoid.ker f
smul r _ _ h := by rw [Setoid.ker_def] at h ⊢; simp_rw [map_smulₛₗ, h]

/-- The kernel of a `DistribMulActionHom` as a congruence relation. -/
```

-- snippet 92
```lean
-- Mathlib.Algebra.Module.Basic.support_const_smul_of_ne_zero (L105-L108)
lemma support_const_smul_of_ne_zero [Semiring R] [IsDomain R] [AddCommMonoid M] [Module R M]
    [Module.IsTorsionFree R M] (c : R) (g : α → M) (hc : c ≠ 0) : support (c • g) = support g :=
ext fun _ ↦ smul_ne_zero_iff_right hc
```

-- snippet 93
```lean
-- Mathlib.Algebra.Module.CharacterModule.eq_zero_of_ofSpanSingleton_apply_self (L201-L214)
lemma eq_zero_of_ofSpanSingleton_apply_self (a : A)
    (h : ofSpanSingleton a ⟨a, Submodule.mem_span_singleton_self a⟩ = 0) : a = 0 := by
erw [ofSpanSingleton, LinearMap.toAddMonoidHom_coe, LinearMap.comp_apply,
     intSpanEquivQuotAddOrderOf_apply_self, Submodule.liftQSpanSingleton_apply,
    AddMonoidHom.coe_toIntLinearMap, int.divByNat, LinearMap.toSpanSingleton_apply_one,
    AddCircle.coe_eq_zero_iff] at h
  rcases h with ⟨n, hn⟩
  apply_fun Rat.den at hn
  rw [zsmul_one, Rat.den_intCast, Rat.inv_natCast_den_of_pos] at hn
  · split_ifs at hn
    · cases hn
    · rwa [eq_comm, AddMonoid.addOrderOf_eq_one_iff] at hn
  · grind
```

-- snippet 94
```lean
-- Mathlib.Algebra.Module.Bimodule.toSubbimoduleNat (L137-L142)
def toSubbimoduleNat (p : Submodule (R ⊗[ℤ] S) M) : Submodule (R ⊗[ℕ] S) M :=
baseChange ℕ p

end Ring

end Subbimodule
```

-- snippet 95
```lean
-- Mathlib.Algebra.Module.CharacterModule.intSpanEquivQuotAddOrderOf_apply_self (L181-L200)
lemma intSpanEquivQuotAddOrderOf_apply_self (a : A) :
    intSpanEquivQuotAddOrderOf a ⟨a, Submodule.mem_span_singleton_self a⟩ =
    Submodule.Quotient.mk 1 :=
(LinearEquiv.eq_symm_apply _).mp <| Subtype.ext (one_zsmul _).symm

/--
For an abelian group `A` and an element `a ∈ A`, there is a character `c : ℤ ∙ a → ℚ ⧸ ℤ` given by
`m • a ↦ m / n` where `n` is the smallest positive integer such that `n • a = 0` and when such `n`
does not exist, `c` is defined by `m • a ↦ m / 2`.
-/
noncomputable def ofSpanSingleton (a : A) : CharacterModule (ℤ ∙ a) :=
  let l : ℤ ⧸ Ideal.span {(addOrderOf a : ℤ)} →ₗ[ℤ] AddCircle (1 : ℚ) :=
    Submodule.liftQSpanSingleton _
      (CharacterModule.int.divByNat <|
        if addOrderOf a = 0 then 2 else addOrderOf a).toIntLinearMap <| by
        split_ifs with h
        · rw [h, Nat.cast_zero, map_zero]
        · apply CharacterModule.int.divByNat_self
  l ∘ₗ intSpanEquivQuotAddOrderOf a |>.toAddMonoidHom
```

-- snippet 96
```lean
-- Mathlib.Algebra.Module.Basic.support_smul (L109-L112)
lemma support_smul [Semiring R] [IsDomain R] [AddCommMonoid M] [Module R M]
    [Module.IsTorsionFree R M] (f : α → R) (g : α → M) : support (f • g) = support f ∩ support g :=
ext fun _ => smul_ne_zero_iff
```

-- snippet 97
```lean
-- Mathlib.Algebra.Module.CharacterModule.dual_comp (L90-L94)
lemma dual_comp {C : Type*} [AddCommGroup C] [Module R C] (f : A →ₗ[R] B) (g : B →ₗ[R] C) :
    dual (g.comp f) = (dual f).comp (dual g) := by
ext
  rfl
```

-- snippet 98
```lean
-- Mathlib.Algebra.Module.Defs.neg_smul (L139-L141)
theorem neg_smul : -r • x = -(r • x) :=
eq_neg_of_add_eq_zero_left <| by rw [← add_smul, neg_add_cancel, zero_smul]
```

-- snippet 99
```lean
-- Mathlib.Algebra.Module.Basic.inv_natCast_smul_comm (L81-L87)
theorem inv_natCast_smul_comm {α E : Type*} (R : Type*) [AddCommMonoid E] [DivisionSemiring R]
    [Module R E] [DistribSMul α E] (n : ℕ) (s : α) (x : E) :
    (n⁻¹ : R) • s • x = s • (n⁻¹ : R) • x :=
(map_inv_natCast_smul (DistribSMul.toAddMonoidHom E s) R R n x).symm

/-- If `E` is a vector space over a division ring `R` and has a monoid action by `α`, then that
action commutes by scalar multiplication of inverses of integers in `R` -/
```

-- snippet 100
```lean
-- Mathlib.Algebra.Module.Basic.support_smul_subset_left (L95-L100)
lemma support_smul_subset_left [Zero R] [Zero M] [SMulWithZero R M] (f : α → R) (g : α → M) :
    support (f • g) ⊆ support f := fun x hfg hf ↦
hfg <| by rw [Pi.smul_apply', hf, zero_smul]

-- Changed (2024-01-21): this lemma was generalised;
-- the old version is now called `support_const_smul_subset`.
```

-- snippet 101
```lean
-- Mathlib.Algebra.Module.Basic.map_inv_natCast_smul (L41-L57)
theorem map_inv_natCast_smul [AddCommMonoid M] [AddCommMonoid M₂] {F : Type*} [FunLike F M M₂]
    [AddMonoidHomClass F M M₂] (f : F) (R S : Type*)
    [DivisionSemiring R] [DivisionSemiring S] [Module R M]
    [Module S M₂] (n : ℕ) (x : M) : f ((n⁻¹ : R) • x) = (n⁻¹ : S) • f x := by
by_cases hR : (n : R) = 0 <;> by_cases hS : (n : S) = 0
  · simp [hR, hS, map_zero f]
  · suffices ∀ y, f y = 0 by rw [this, this, smul_zero]
    clear x
    intro x
    rw [← inv_smul_smul₀ hS (f x), ← map_natCast_smul f R S]
    simp [hR, map_zero f]
  · suffices ∀ y, f y = 0 by simp [this]
    clear x
    intro x
    rw [← smul_inv_smul₀ hR x, map_natCast_smul f R S, hS, zero_smul]
  · rw [← inv_smul_smul₀ hS (f _), ← map_natCast_smul f R S, smul_inv_smul₀ hR]
```

-- snippet 102
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.mul_eq_trans (L91-L92)
lemma mul_eq_trans (f g : M ≃ₗ[R] M) : f * g = g.trans f := rfl
```

-- snippet 103
```lean
-- Mathlib.Algebra.Module.Basic.inv_natCast_smul_eq (L68-L74)
theorem inv_natCast_smul_eq {E : Type*} (R S : Type*) [AddCommMonoid E] [DivisionSemiring R]
    [DivisionSemiring S] [Module R E] [Module S E] (n : ℕ) (x : E) :
    (n⁻¹ : R) • x = (n⁻¹ : S) • x :=
map_inv_natCast_smul (AddMonoidHom.id E) R S n x

/-- If `E` is a vector space over two division rings `R` and `S`, then scalar multiplications
agree on inverses of integer numbers in `R` and `S`. -/
```

-- snippet 104
```lean
-- Mathlib.Algebra.Module.CharacterModule.dual_surjective_iff_injective (L225-L230)
lemma dual_surjective_iff_injective {f : A →ₗ[R] A'} :
    Function.Surjective (dual f) ↔ Function.Injective f :=
⟨fun h ↦ (injective_iff_map_eq_zero _).2 fun a h0 ↦ eq_zero_of_character_apply fun c ↦ by
    obtain ⟨c, rfl⟩ := h c; exact congr(c $h0).trans c.map_zero,
  dual_surjective_of_injective f⟩
```

-- snippet 105
```lean
-- Mathlib.Algebra.Module.Equiv.Basic.restrictScalars_inj (L60-L65)
theorem restrictScalars_inj (f g : M ≃ₗ[S] M₂) :
    f.restrictScalars R = g.restrictScalars R ↔ f = g :=
(restrictScalars_injective R).eq_iff

end RestrictScalars
```
[/INST]