[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.Category.ModuleCat.Sheaf).

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

```lean
lemma unitHomEquiv_symm_comp {M N : SheafOfModules.{u} R} (s : M.sections) (p : M ⟶ N) :
    M.unitHomEquiv.symm s ≫ p = N.unitHomEquiv.symm (sectionsMap p s)
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.hom_ext (L54-L56)
lemma hom_ext {X Y : SheafOfModules.{v} R} {f g : X ⟶ Y} (h : f.val = g.val) : f = g :=
Hom.ext h
```

-- snippet 2
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.id_val (L58-L59)
lemma id_val (X : SheafOfModules.{v} R) : Hom.val (𝟙 X) = 𝟙 X.val := rfl
```

-- snippet 3
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.comp_val (L61-L65)
lemma comp_val {X Y Z : SheafOfModules.{v} R} (f : X ⟶ Y) (g : Y ⟶ Z) :
    (f ≫ g).val = f.val ≫ g.val := rfl
variable (R)
/-- The forgetful functor `SheafOfModules.{v} R ⥤ PresheafOfModules R.val`. -/
```

-- snippet 4
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.forget (L67-L71)
def forget : SheafOfModules.{v} R ⥤ PresheafOfModules R.obj where
  obj F := F.val
map φ := φ.val

/-- The forget functor `SheafOfModules R ⥤ PresheafOfModules R.val` is fully faithful. -/
```

-- snippet 5
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.fullyFaithfulForget (L73-L75)
def fullyFaithfulForget : (forget.{v} R).FullyFaithful where
  preimage φ := ⟨φ⟩
```

-- snippet 6
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.evaluation (L84-L87)
def evaluation (X : Cᵒᵖ) : SheafOfModules.{v} R ⥤ ModuleCat.{v} (R.obj.obj X) :=
forget _ ⋙ PresheafOfModules.evaluation _ X

/-- The forget functor `SheafOfModules R ⥤ Sheaf J AddCommGrpCat`. -/
```

-- snippet 7
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.add_val (L120-L122)
lemma add_val {M N : SheafOfModules.{v} R} (f g : M ⟶ N) :
    (f + g).val = f.val + g.val := rfl
```

-- snippet 8
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.sections (L134-L136)
abbrev sections (M : SheafOfModules.{v} R) : Type _ := M.val.sections
/-- The map `M.sections → N.sections` induced by a morphism `M ⟶ N` of sheaves of modules. -/
```

-- snippet 9
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.sectionsMap (L137-L139)
abbrev sectionsMap {M N : SheafOfModules.{v} R} (f : M ⟶ N) (s : M.sections) : N.sections :=
PresheafOfModules.sectionsMap f.val s
```

-- snippet 10
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.sectionsMap_comp (L141-L143)
lemma sectionsMap_comp {M N P : SheafOfModules.{v} R} (f : M ⟶ N) (g : N ⟶ P) (s : M.sections) :
    sectionsMap (f ≫ g) s = sectionsMap g (sectionsMap f s) := rfl
```

-- snippet 11
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.sectionsMap_id (L145-L149)
lemma sectionsMap_id {M : SheafOfModules.{v} R} (s : M.sections) :
    sectionsMap (𝟙 M) s = s := rfl
variable (R) in
/-- The functor which sends a sheaf of modules to its type of sections. -/
```

-- snippet 12
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.sectionsFunctor (L151-L158)
def sectionsFunctor : SheafOfModules.{v} R ⥤ Type _ where
  obj := sections
map f := sectionsMap f

variable [J.HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})]

variable (R) in
/-- The obvious free sheaf of modules of rank `1`. -/
```

-- snippet 13
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.unitHomEquiv_apply_coe (L170-L172)
lemma unitHomEquiv_apply_coe (M : SheafOfModules R) (f : unit R ⟶ M) (X : Cᵒᵖ) :
    (M.unitHomEquiv f).val X = f.val.app X (1 : R.obj.obj X) := rfl
```

-- snippet 14
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.unitHomEquiv_comp_apply (L173-L176)
lemma unitHomEquiv_comp_apply {M N : SheafOfModules.{u} R}
    (f : unit R ⟶ M) (p : M ⟶ N) :
    N.unitHomEquiv (f ≫ p) = sectionsMap p (M.unitHomEquiv f) := rfl
```

-- snippet 15
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.IsLocallySurjective (L190-L194)
abbrev IsLocallySurjective : Prop :=
Presheaf.IsLocallySurjective J ((PresheafOfModules.toPresheaf R).map f)

/-- A morphism of presheaves of modules is locally injective
if the underlying morphism of presheaves of abelian groups is. -/
```

-- snippet 16
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.coe_of (L56-L61)
lemma coe_of (X : Type v) [Ring X] [Algebra R X] : (of R X : Type v) = X :=
rfl

variable {R} in
set_option backward.privateInPublic true in
/-- The type of morphisms in `AlgCat R`. -/
```

-- snippet 17
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.of (L53-L55)
abbrev of (X : Type v) [Ring X] [Algebra R X] : AlgCat.{v} R :=
⟨X⟩
```

-- snippet 18
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.ofHom_apply (L139-L141)
lemma ofHom_apply {R : Type u} [CommRing R] {X Y : Type v} [Ring X] [Algebra R X] [Ring Y]
    [Algebra R Y] (f : X →ₐ[R] Y) (x : X) : ofHom f x = f x := rfl
```

-- snippet 19
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.ofHom_hom (L127-L129)
lemma ofHom_hom {A B : AlgCat.{v} R} (f : A ⟶ B) :
    ofHom (Hom.hom f) = f := rfl
```

-- snippet 20
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.hom_id (L104-L106)
lemma hom_id {A : AlgCat.{v} R} : (𝟙 A : A ⟶ A).hom = AlgHom.id R A := rfl
/- Provided for rewriting. -/
```

-- snippet 21
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.id_apply (L107-L109)
lemma id_apply (A : AlgCat.{v} R) (a : A) :
    (𝟙 A : A ⟶ A) a = a := by simp
```

-- snippet 22
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.ofHom_comp (L134-L138)
lemma ofHom_comp {X Y Z : Type v} [Ring X] [Ring Y] [Ring Z] [Algebra R X] [Algebra R Y]
    [Algebra R Z] (f : X →ₐ[R] Y) (g : Y →ₐ[R] Z) :
    ofHom (g.comp f) = ofHom f ≫ ofHom g :=
rfl
```

-- snippet 23
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.ofHom (L88-L93)
abbrev ofHom {A B : Type v} [Ring A] [Ring B] [Algebra R A] [Algebra R B] (f : A →ₐ[R] B) :
    of R A ⟶ of R B :=
ConcreteCategory.ofHom (C := AlgCat R) f

variable {R} in
/-- Use the `ConcreteCategory.hom` projection for `@[simps]` lemmas. -/
```

-- snippet 24
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.hom_comp (L111-L114)
lemma hom_comp {A B C : AlgCat.{v} R} (f : A ⟶ B) (g : B ⟶ C) :
    (f ≫ g).hom = g.hom.comp f.hom := rfl
/- Provided for rewriting. -/
```

-- snippet 25
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.hom_ofHom (L123-L125)
lemma hom_ofHom {R : Type u} [CommRing R] {X Y : Type v} [Ring X] [Algebra R X] [Ring Y]
    [Algebra R Y] (f : X →ₐ[R] Y) : (ofHom f).hom = f := rfl
```

-- snippet 26
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.forget₂_module_obj (L174-L177)
lemma forget₂_module_obj (X : AlgCat.{v} R) :
    (forget₂ (AlgCat.{v} R) (ModuleCat.{v} R)).obj X = ModuleCat.of R X :=
rfl
```

-- snippet 27
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.comp_apply (L115-L117)
lemma comp_apply {A B C : AlgCat.{v} R} (f : A ⟶ B) (g : B ⟶ C) (a : A) :
    (f ≫ g) a = g (f a) := by simp
```

-- snippet 28
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.free (L185-L190)
def free : Type u ⥤ AlgCat.{u} R where
  obj S := of R (FreeAlgebra R S)
map f := ofHom <| FreeAlgebra.lift _ <| FreeAlgebra.ι _ ∘ f

set_option backward.isDefEq.respectTransparency false in
/-- The free/forget adjunction for `R`-algebras. -/
```

-- snippet 29
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.adj (L191-L198)
def adj : free.{u} R ⊣ forget (AlgCat.{u} R) :=
Adjunction.mkOfHomEquiv
    { homEquiv := fun _ _ =>
        { toFun := fun f ↦ (FreeAlgebra.lift _).symm f.hom
          invFun := fun f ↦ ofHom <| (FreeAlgebra.lift _) f
          left_inv := fun f ↦ by aesop
          right_inv := fun f ↦ by simp [forget_obj] } }
```

-- snippet 30
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.forget_map (L153-L156)
lemma forget_map {A B : AlgCat.{v} R} (f : A ⟶ B) :
    (forget (AlgCat.{v} R)).map f = (f : _ → _) :=
rfl
```

-- snippet 31
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.hom_ext (L119-L121)
lemma hom_ext {A B : AlgCat.{v} R} {f g : A ⟶ B} (hf : f.hom = g.hom) : f = g :=
Hom.ext hf
```

-- snippet 32
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.inv_hom_apply (L142-L144)
lemma inv_hom_apply {A B : AlgCat.{v} R} (e : A ≅ B) (x : A) : e.inv (e.hom x) = x := by
simp
```

-- snippet 33
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.forget_obj (L151-L152)
lemma forget_obj {A : AlgCat.{v} R} : (forget (AlgCat.{v} R)).obj A = A := rfl
```

-- snippet 34
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.Hom (L83-L87)
abbrev Hom.hom {A B : AlgCat.{v} R} (f : Hom A B) :=
ConcreteCategory.hom (C := AlgCat R) f

variable {R} in
/-- Typecheck an `AlgHom` as a morphism in `AlgCat`. -/
```

-- snippet 35
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.hom_inv_apply (L145-L147)
lemma hom_inv_apply {A B : AlgCat.{v} R} (e : A ≅ B) (x : B) : e.hom (e.inv x) = x := by
simp
```

-- snippet 36
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.hasForgetToModule (L168-L172)
instance hasForgetToModule : HasForget₂ (AlgCat.{v} R) (ModuleCat.{v} R) where
  forget₂ :=
{ obj := fun M => ModuleCat.of R M
      map := fun f => ModuleCat.ofHom f.hom.toLinearMap }
```

-- snippet 37
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.forget₂_module_map (L179-L183)
lemma forget₂_module_map {X Y : AlgCat.{v} R} (f : X ⟶ Y) :
    (forget₂ (AlgCat.{v} R) (ModuleCat.{v} R)).map f = ModuleCat.ofHom f.hom.toLinearMap :=
rfl

/-- The "free algebra" functor, sending a type `S` to the free algebra on `S`. -/
```

-- snippet 38
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.hasForgetToRing (L163-L167)
instance hasForgetToRing : HasForget₂ (AlgCat.{v} R) RingCat.{v} where
  forget₂ :=
{ obj := fun A => RingCat.of A
      map := fun f => RingCat.ofHom f.hom.toRingHom }
```

-- snippet 39
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.AlgEquiv (L208-L215)
def AlgEquiv.toAlgebraIso {g₁ : Ring X₁} {g₂ : Ring X₂} {m₁ : Algebra R X₁} {m₂ : Algebra R X₂}
    (e : X₁ ≃ₐ[R] X₂) : AlgCat.of R X₁ ≅ AlgCat.of R X₂ where
  hom := AlgCat.ofHom (e : X₁ →ₐ[R] X₂)
inv := AlgCat.ofHom (e.symm : X₂ →ₐ[R] X₁)

namespace CategoryTheory.Iso

/-- Build an `AlgEquiv` from an isomorphism in the category `AlgCat R`. -/
```

-- snippet 40
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.ofHom_id (L131-L132)
lemma ofHom_id {X : Type v} [Ring X] [Algebra R X] : ofHom (AlgHom.id R X) = 𝟙 (of R X) := rfl
```

<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.Category.ModuleCat.Sheaf).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Prove the following theorem. The retrieved context below may help.

```lean
lemma unitHomEquiv_symm_comp {M N : SheafOfModules.{u} R} (s : M.sections) (p : M ⟶ N) :
    M.unitHomEquiv.symm s ≫ p = N.unitHomEquiv.symm (sectionsMap p s)
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.hom_ext (L54-L56)
lemma hom_ext {X Y : SheafOfModules.{v} R} {f g : X ⟶ Y} (h : f.val = g.val) : f = g :=
Hom.ext h
```

-- snippet 2
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.id_val (L58-L59)
lemma id_val (X : SheafOfModules.{v} R) : Hom.val (𝟙 X) = 𝟙 X.val := rfl
```

-- snippet 3
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.comp_val (L61-L65)
lemma comp_val {X Y Z : SheafOfModules.{v} R} (f : X ⟶ Y) (g : Y ⟶ Z) :
    (f ≫ g).val = f.val ≫ g.val := rfl
variable (R)
/-- The forgetful functor `SheafOfModules.{v} R ⥤ PresheafOfModules R.val`. -/
```

-- snippet 4
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.forget (L67-L71)
def forget : SheafOfModules.{v} R ⥤ PresheafOfModules R.obj where
  obj F := F.val
map φ := φ.val

/-- The forget functor `SheafOfModules R ⥤ PresheafOfModules R.val` is fully faithful. -/
```

-- snippet 5
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.fullyFaithfulForget (L73-L75)
def fullyFaithfulForget : (forget.{v} R).FullyFaithful where
  preimage φ := ⟨φ⟩
```

-- snippet 6
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.evaluation (L84-L87)
def evaluation (X : Cᵒᵖ) : SheafOfModules.{v} R ⥤ ModuleCat.{v} (R.obj.obj X) :=
forget _ ⋙ PresheafOfModules.evaluation _ X

/-- The forget functor `SheafOfModules R ⥤ Sheaf J AddCommGrpCat`. -/
```

-- snippet 7
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.add_val (L120-L122)
lemma add_val {M N : SheafOfModules.{v} R} (f g : M ⟶ N) :
    (f + g).val = f.val + g.val := rfl
```

-- snippet 8
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.sections (L134-L136)
abbrev sections (M : SheafOfModules.{v} R) : Type _ := M.val.sections
/-- The map `M.sections → N.sections` induced by a morphism `M ⟶ N` of sheaves of modules. -/
```

-- snippet 9
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.sectionsMap (L137-L139)
abbrev sectionsMap {M N : SheafOfModules.{v} R} (f : M ⟶ N) (s : M.sections) : N.sections :=
PresheafOfModules.sectionsMap f.val s
```

-- snippet 10
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.sectionsMap_comp (L141-L143)
lemma sectionsMap_comp {M N P : SheafOfModules.{v} R} (f : M ⟶ N) (g : N ⟶ P) (s : M.sections) :
    sectionsMap (f ≫ g) s = sectionsMap g (sectionsMap f s) := rfl
```

-- snippet 11
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.sectionsMap_id (L145-L149)
lemma sectionsMap_id {M : SheafOfModules.{v} R} (s : M.sections) :
    sectionsMap (𝟙 M) s = s := rfl
variable (R) in
/-- The functor which sends a sheaf of modules to its type of sections. -/
```

-- snippet 12
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.sectionsFunctor (L151-L158)
def sectionsFunctor : SheafOfModules.{v} R ⥤ Type _ where
  obj := sections
map f := sectionsMap f

variable [J.HasSheafCompose (forget₂ RingCat.{u} AddCommGrpCat.{u})]

variable (R) in
/-- The obvious free sheaf of modules of rank `1`. -/
```

-- snippet 13
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.unitHomEquiv_apply_coe (L170-L172)
lemma unitHomEquiv_apply_coe (M : SheafOfModules R) (f : unit R ⟶ M) (X : Cᵒᵖ) :
    (M.unitHomEquiv f).val X = f.val.app X (1 : R.obj.obj X) := rfl
```

-- snippet 14
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.unitHomEquiv_comp_apply (L173-L176)
lemma unitHomEquiv_comp_apply {M N : SheafOfModules.{u} R}
    (f : unit R ⟶ M) (p : M ⟶ N) :
    N.unitHomEquiv (f ≫ p) = sectionsMap p (M.unitHomEquiv f) := rfl
```

-- snippet 15
```lean
-- Mathlib.Algebra.Category.ModuleCat.Sheaf.IsLocallySurjective (L190-L194)
abbrev IsLocallySurjective : Prop :=
Presheaf.IsLocallySurjective J ((PresheafOfModules.toPresheaf R).map f)

/-- A morphism of presheaves of modules is locally injective
if the underlying morphism of presheaves of abelian groups is. -/
```

-- snippet 16
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.coe_of (L56-L61)
lemma coe_of (X : Type v) [Ring X] [Algebra R X] : (of R X : Type v) = X :=
rfl

variable {R} in
set_option backward.privateInPublic true in
/-- The type of morphisms in `AlgCat R`. -/
```

-- snippet 17
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.of (L53-L55)
abbrev of (X : Type v) [Ring X] [Algebra R X] : AlgCat.{v} R :=
⟨X⟩
```

-- snippet 18
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.ofHom_apply (L139-L141)
lemma ofHom_apply {R : Type u} [CommRing R] {X Y : Type v} [Ring X] [Algebra R X] [Ring Y]
    [Algebra R Y] (f : X →ₐ[R] Y) (x : X) : ofHom f x = f x := rfl
```

-- snippet 19
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.ofHom_hom (L127-L129)
lemma ofHom_hom {A B : AlgCat.{v} R} (f : A ⟶ B) :
    ofHom (Hom.hom f) = f := rfl
```

-- snippet 20
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.hom_id (L104-L106)
lemma hom_id {A : AlgCat.{v} R} : (𝟙 A : A ⟶ A).hom = AlgHom.id R A := rfl
/- Provided for rewriting. -/
```

-- snippet 21
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.id_apply (L107-L109)
lemma id_apply (A : AlgCat.{v} R) (a : A) :
    (𝟙 A : A ⟶ A) a = a := by simp
```

-- snippet 22
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.ofHom_comp (L134-L138)
lemma ofHom_comp {X Y Z : Type v} [Ring X] [Ring Y] [Ring Z] [Algebra R X] [Algebra R Y]
    [Algebra R Z] (f : X →ₐ[R] Y) (g : Y →ₐ[R] Z) :
    ofHom (g.comp f) = ofHom f ≫ ofHom g :=
rfl
```

-- snippet 23
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.ofHom (L88-L93)
abbrev ofHom {A B : Type v} [Ring A] [Ring B] [Algebra R A] [Algebra R B] (f : A →ₐ[R] B) :
    of R A ⟶ of R B :=
ConcreteCategory.ofHom (C := AlgCat R) f

variable {R} in
/-- Use the `ConcreteCategory.hom` projection for `@[simps]` lemmas. -/
```

-- snippet 24
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.hom_comp (L111-L114)
lemma hom_comp {A B C : AlgCat.{v} R} (f : A ⟶ B) (g : B ⟶ C) :
    (f ≫ g).hom = g.hom.comp f.hom := rfl
/- Provided for rewriting. -/
```

-- snippet 25
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.hom_ofHom (L123-L125)
lemma hom_ofHom {R : Type u} [CommRing R] {X Y : Type v} [Ring X] [Algebra R X] [Ring Y]
    [Algebra R Y] (f : X →ₐ[R] Y) : (ofHom f).hom = f := rfl
```

-- snippet 26
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.forget₂_module_obj (L174-L177)
lemma forget₂_module_obj (X : AlgCat.{v} R) :
    (forget₂ (AlgCat.{v} R) (ModuleCat.{v} R)).obj X = ModuleCat.of R X :=
rfl
```

-- snippet 27
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.comp_apply (L115-L117)
lemma comp_apply {A B C : AlgCat.{v} R} (f : A ⟶ B) (g : B ⟶ C) (a : A) :
    (f ≫ g) a = g (f a) := by simp
```

-- snippet 28
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.free (L185-L190)
def free : Type u ⥤ AlgCat.{u} R where
  obj S := of R (FreeAlgebra R S)
map f := ofHom <| FreeAlgebra.lift _ <| FreeAlgebra.ι _ ∘ f

set_option backward.isDefEq.respectTransparency false in
/-- The free/forget adjunction for `R`-algebras. -/
```

-- snippet 29
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.adj (L191-L198)
def adj : free.{u} R ⊣ forget (AlgCat.{u} R) :=
Adjunction.mkOfHomEquiv
    { homEquiv := fun _ _ =>
        { toFun := fun f ↦ (FreeAlgebra.lift _).symm f.hom
          invFun := fun f ↦ ofHom <| (FreeAlgebra.lift _) f
          left_inv := fun f ↦ by aesop
          right_inv := fun f ↦ by simp [forget_obj] } }
```

-- snippet 30
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.forget_map (L153-L156)
lemma forget_map {A B : AlgCat.{v} R} (f : A ⟶ B) :
    (forget (AlgCat.{v} R)).map f = (f : _ → _) :=
rfl
```

-- snippet 31
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.hom_ext (L119-L121)
lemma hom_ext {A B : AlgCat.{v} R} {f g : A ⟶ B} (hf : f.hom = g.hom) : f = g :=
Hom.ext hf
```

-- snippet 32
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.inv_hom_apply (L142-L144)
lemma inv_hom_apply {A B : AlgCat.{v} R} (e : A ≅ B) (x : A) : e.inv (e.hom x) = x := by
simp
```

-- snippet 33
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.forget_obj (L151-L152)
lemma forget_obj {A : AlgCat.{v} R} : (forget (AlgCat.{v} R)).obj A = A := rfl
```

-- snippet 34
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.Hom (L83-L87)
abbrev Hom.hom {A B : AlgCat.{v} R} (f : Hom A B) :=
ConcreteCategory.hom (C := AlgCat R) f

variable {R} in
/-- Typecheck an `AlgHom` as a morphism in `AlgCat`. -/
```

-- snippet 35
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.hom_inv_apply (L145-L147)
lemma hom_inv_apply {A B : AlgCat.{v} R} (e : A ≅ B) (x : B) : e.hom (e.inv x) = x := by
simp
```

-- snippet 36
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.hasForgetToModule (L168-L172)
instance hasForgetToModule : HasForget₂ (AlgCat.{v} R) (ModuleCat.{v} R) where
  forget₂ :=
{ obj := fun M => ModuleCat.of R M
      map := fun f => ModuleCat.ofHom f.hom.toLinearMap }
```

-- snippet 37
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.forget₂_module_map (L179-L183)
lemma forget₂_module_map {X Y : AlgCat.{v} R} (f : X ⟶ Y) :
    (forget₂ (AlgCat.{v} R) (ModuleCat.{v} R)).map f = ModuleCat.ofHom f.hom.toLinearMap :=
rfl

/-- The "free algebra" functor, sending a type `S` to the free algebra on `S`. -/
```

-- snippet 38
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.hasForgetToRing (L163-L167)
instance hasForgetToRing : HasForget₂ (AlgCat.{v} R) RingCat.{v} where
  forget₂ :=
{ obj := fun A => RingCat.of A
      map := fun f => RingCat.ofHom f.hom.toRingHom }
```

-- snippet 39
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.AlgEquiv (L208-L215)
def AlgEquiv.toAlgebraIso {g₁ : Ring X₁} {g₂ : Ring X₂} {m₁ : Algebra R X₁} {m₂ : Algebra R X₂}
    (e : X₁ ≃ₐ[R] X₂) : AlgCat.of R X₁ ≅ AlgCat.of R X₂ where
  hom := AlgCat.ofHom (e : X₁ →ₐ[R] X₂)
inv := AlgCat.ofHom (e.symm : X₂ →ₐ[R] X₁)

namespace CategoryTheory.Iso

/-- Build an `AlgEquiv` from an isomorphism in the category `AlgCat R`. -/
```

-- snippet 40
```lean
-- Mathlib.Algebra.Category.AlgCat.Basic.ofHom_id (L131-L132)
lemma ofHom_id {X : Type v} [Ring X] [Algebra R X] : ofHom (AlgHom.id R X) = 𝟙 (of R X) := rfl
```
[/INST]


[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.GroupTheory.Torsion).

[User]
The following Lean code fails to compile. Fix it.

```lean
def IsTorsion
:= thisIsWrongLemmaNameXYZ
∀ g : G, IsOfFinOrder g

/-- A monoid is not a torsion monoid if it has an element of infinite order. -/
```

## Compiler diagnostic
```
[CompilationUnit(i_begin=0, i_end=41, messages=[Message(data='Unknown identifier `thisIsWrongLemmaNameXYZ`', pos=Position(line=2, column=3), pos_end=Position(line=2, column=26), severity=<Severity.ERROR: 3>, kind='lean.unknownIdentifier._namedError')], invocations=None, goal_state=None, goal_src_boundaries=None, new_constants=None), CompilationUnit(i_begin=41, i_end=147, messages=[Message(data="unexpected token '∀'; expected command", pos=Position(line=3, column=0), pos_end=Position(line=3, column=1), severity=<Severity.ERROR: 3>, kind=None), Message(data="unexpected end of input; expected 'lemma'", pos=Position(line=5, column=79), pos_end=None, severity=<Severity.ERROR: 3>, kind=None)], invocations=None, goal_state=None, goal_src_boundaries=None, new_constants=None)]
```

Return a corrected, compiling version of the code.

<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.GroupTheory.Torsion).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]The following Lean code fails to compile. Fix it.

```lean
def IsTorsion
:= thisIsWrongLemmaNameXYZ
∀ g : G, IsOfFinOrder g

/-- A monoid is not a torsion monoid if it has an element of infinite order. -/
```

## Compiler diagnostic
```
[CompilationUnit(i_begin=0, i_end=41, messages=[Message(data='Unknown identifier `thisIsWrongLemmaNameXYZ`', pos=Position(line=2, column=3), pos_end=Position(line=2, column=26), severity=<Severity.ERROR: 3>, kind='lean.unknownIdentifier._namedError')], invocations=None, goal_state=None, goal_src_boundaries=None, new_constants=None), CompilationUnit(i_begin=41, i_end=147, messages=[Message(data="unexpected token '∀'; expected command", pos=Position(line=3, column=0), pos_end=Position(line=3, column=1), severity=<Severity.ERROR: 3>, kind=None), Message(data="unexpected end of input; expected 'lemma'", pos=Position(line=5, column=79), pos_end=None, severity=<Severity.ERROR: 3>, kind=None)], invocations=None, goal_state=None, goal_src_boundaries=None, new_constants=None)]
```

Return a corrected, compiling version of the code.[/INST]


-- Mathlib.Algebra.Lie.Abelian.mem_maxTrivSubmodule (L172-L174)
theorem mem_maxTrivSubmodule (m : M) : m ∈ maxTrivSubmodule R L M ↔ ∀ x : L, ⁅x, m⁆ = 0 :=
Iff.rfl

-- Mathlib.Algebra.Lie.Basic.leibniz_lie (L117-L119)
lemma leibniz_lie [Add M] [IsLieTower L₁ L₂ M] (x : L₁) (y : L₂) (m : M) :
    ⁅x, ⁅y, m⁆⁆ = ⁅⁅x, y⁆, m⁆ + ⁅y, ⁅x, m⁆⁆ := IsLieTower.leibniz_lie x y m

-- Mathlib.Algebra.Lie.Basic.zero_lie (L168-L170)
theorem zero_lie : ⁅(0 : L), m⁆ = 0 :=
(AddMonoidHom.mk' (fun x : L => ⁅x, m⁆) fun x y => add_lie x y m).map_zero

-- Mathlib.Algebra.Lie.Basic.lie_smul (L157-L159)
theorem lie_smul : ⁅x, t • m⁆ = t • ⁅x, m⁆ :=
LieModule.lie_smul t x m

-- Mathlib.Algebra.Lie.AdjointAction.Derivation.ad_apply_lieDerivation (L60-L61)
lemma ad_apply_lieDerivation (x : L) (D : LieDerivation R L L) : ad R L (D x) = -⁅x, D⁆ := rfl

-- Mathlib.Algebra.Lie.Basic.add_lie (L145-L147)
theorem add_lie : ⁅x + y, m⁆ = ⁅x, m⁆ + ⁅y, m⁆ :=
LieRingModule.add_lie x y m

-- Mathlib.Algebra.Lie.Abelian.equiv (L386-L387)
def equiv : (TrivialLieModule R L M) ≃ₗ[R] M := LinearEquiv.refl R M

-- Mathlib.Algebra.Lie.Basic.lie_self (L172-L174)
theorem lie_self : ⁅x, x⁆ = 0 :=
LieRing.lie_self x

-- Mathlib.Algebra.Lie.Basic.smul_lie (L153-L155)
theorem smul_lie : ⁅t • x, m⁆ = t • ⁅x, m⁆ :=
LieModule.smul_lie t x m

-- Mathlib.Algebra.Lie.Abelian.IsLieAbelian (L57-L59)
abbrev IsLieAbelian (L : Type v) [Bracket L L] [Zero L] : Prop :=
LieModule.IsTrivial L L

-- Mathlib.Algebra.Lie.Abelian.isLieAbelian_iff_center_eq_top (L303-L305)
theorem isLieAbelian_iff_center_eq_top : IsLieAbelian L ↔ center R L = ⊤ :=
LieModule.isTrivial_iff_max_triv_eq_top R L L

-- Mathlib.Algebra.Lie.Basic.lie_zero (L164-L166)
theorem lie_zero : ⁅x, 0⁆ = (0 : M) :=
(AddMonoidHom.mk' _ (lie_add x)).map_zero

-- Mathlib.Algebra.Lie.Abelian.coe_maxTrivEquiv_apply (L230-L233)
theorem coe_maxTrivEquiv_apply (e : M ≃ₗ⁅R,L⁆ N) (m : maxTrivSubmodule R L M) :
    (maxTrivEquiv e m : N) = e ↑m :=
rfl

-- Mathlib.Algebra.Lie.Abelian.isFaithful_iff_ker_eq_bot (L155-L158)
lemma isFaithful_iff_ker_eq_bot : IsFaithful R L M ↔ LieModule.ker R L M = ⊥ := by
rw [isFaithful_iff', LieSubmodule.ext_iff]
  aesop

-- Mathlib.Algebra.Lie.Abelian.ad_ker_eq_self_module_ker (L291-L293)
theorem ad_ker_eq_self_module_ker : (ad R L).ker = LieModule.ker R L L :=
rfl

-- Mathlib.Algebra.Lie.Basic.lie_add (L149-L151)
theorem lie_add : ⁅x, m + n⁆ = ⁅x, m⁆ + ⁅x, n⁆ :=
LieRingModule.lie_add x m n

-- Mathlib.Algebra.Lie.BaseChange.instBaseLieAlgebra (L112-L113)
instance instBaseLieAlgebra : LieAlgebra R (A ⊗[R] L) where lie_smul := by simp [bracket_def]

-- Mathlib.Algebra.Lie.BaseChange.baseChange_bot (L225-L228)
lemma baseChange_bot : (⊥ : LieSubmodule R L M).baseChange A = ⊥ := by
simp only [baseChange, bot_toSubmodule, Submodule.baseChange_bot]
  rfl

-- Mathlib.Algebra.Lie.Basic.lieRingSelfModule (L175-L177)
instance lieRingSelfModule : LieRingModule L L :=
{ (inferInstance : LieRing L) with }

-- Mathlib.Algebra.Lie.Abelian.center (L284-L286)
abbrev center : LieIdeal R L :=
LieModule.maxTrivSubmodule R L L

def ofLieDerivation : (LieDerivation R L L) →ₗ⁅R⁆ (LieDerivation R (A ⊗[R] L) (A ⊗[R] L)) where
  toFun d

[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.Lie.Derivation.BaseChange).

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

```lean
def ofLieDerivation : (LieDerivation R L L) →ₗ⁅R⁆ (LieDerivation R (A ⊗[R] L) (A ⊗[R] L)) where
  toFun d
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Algebra.Lie.Derivation.BaseChange.ofDerivation (L37-L56)
def ofDerivation : Derivation R A A →ₗ⁅R⁆ LieDerivation R (A ⊗[R] L) (A ⊗[R] L) where
  toFun d :=
{ toFun := d.rTensor L
      map_add' := by simp
      map_smul' := by simp
      leibniz' x y := by
        simp only [LinearMap.coe_mk, AddHom.coe_mk]
        refine x.induction_on (by simp) (fun _ l ↦ ?_) (fun _ _ h1 h2 ↦ ?_)
        · refine y.induction_on (by simp) (fun _ l' ↦ ?_) (fun _ _ h1 h2 ↦ ?_)
          · simp [← lie_skew l' l, -lie_skew, add_tmul, tmul_neg]
          · simp [h1, h2, sub_add_sub_comm]
        · simp [h1, h2, sub_add_sub_comm] }
  map_add' _ _ := by ext; simp
  map_smul' _ _ := by ext; simp
  map_lie' {_ _} := by
    ext z
    refine z.induction_on (by simp) (by simp [sub_tmul]) (fun _ _ hx hy ↦ ?_)
    simp_all
    abel
```

-- snippet 2
```lean
-- Mathlib.Algebra.Lie.Derivation.BaseChange.ofDerivation_apply (L58-L64)
lemma ofDerivation_apply (d : Derivation R A A) (x : A ⊗[R] L) :
    ofDerivation L d x = d.toLinearMap.rTensor L x :=
rfl

variable (A) in
/-- A Lie derivation of an `R-`Lie algebra `L`, induces a Lie derivation of `A ⊗[R] L` for any
Algebra `A` over `R`. -/
```

-- snippet 3
```lean
-- Mathlib.Algebra.Lie.Derivation.BaseChange.ofLieDerivation_apply (L92-L96)
lemma ofLieDerivation_apply (d : LieDerivation R L L) (x : A ⊗[R] L) :
    ofLieDerivation A d x = d.toLinearMap.lTensor A x :=
rfl

end Lie.Derivation
```

-- snippet 4
```lean
-- Mathlib.Algebra.Lie.Abelian.mem_maxTrivSubmodule (L172-L174)
theorem mem_maxTrivSubmodule (m : M) : m ∈ maxTrivSubmodule R L M ↔ ∀ x : L, ⁅x, m⁆ = 0 :=
Iff.rfl
```

-- snippet 5
```lean
-- Mathlib.Algebra.Lie.Basic.leibniz_lie (L117-L119)
lemma leibniz_lie [Add M] [IsLieTower L₁ L₂ M] (x : L₁) (y : L₂) (m : M) :
    ⁅x, ⁅y, m⁆⁆ = ⁅⁅x, y⁆, m⁆ + ⁅y, ⁅x, m⁆⁆ := IsLieTower.leibniz_lie x y m
```

-- snippet 6
```lean
-- Mathlib.Algebra.Lie.Abelian.toLinearMap_maxTrivLinearMapEquivLieModuleHom_symm (L273-L283)
theorem toLinearMap_maxTrivLinearMapEquivLieModuleHom_symm (f : M →ₗ⁅R,L⁆ N) :
    (maxTrivLinearMapEquivLieModuleHom (M := M) (N := N) |>.symm f : M →ₗ[R] N) = (f : M →ₗ[R] N) :=
rfl

end LieModule

namespace LieAlgebra

/-- The center of a Lie algebra is the set of elements that commute with everything. It can
be viewed as the maximal trivial submodule of the Lie algebra as a Lie module over itself via the
adjoint representation. -/
```

-- snippet 7
```lean
-- Mathlib.Algebra.Lie.BaseChange.instLieRingModule (L118-L122)
instance instLieRingModule : LieRingModule (A ⊗[R] L) (A ⊗[R] M) where
  add_lie x y z := by simp only [bracket_def, LinearMap.add_apply, map_add]
lie_add x y z := by simp only [bracket_def, map_add]
  leibniz_lie := bracket_leibniz_lie R A L M
```

-- snippet 8
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Basic.LieAlgebra (L32-L37)
theorem LieAlgebra.commute_ad_of_commute {a b : A} (h : Commute a b) :
    Commute (LieAlgebra.ad R A a) (LieAlgebra.ad R A b) := by
rw [Commute, SemiconjBy, ← sub_eq_zero, ← Ring.lie_def,
    ← (LieAlgebra.ad R A).map_lie, Ring.lie_def, sub_eq_zero.mpr h, map_zero]

/-- The adjoint of a nilpotent element is nilpotent. -/
```

-- snippet 9
```lean
-- Mathlib.Algebra.Lie.Basic.LieAlgebra (L130-L134)
theorem LieAlgebra.toModule_injective (L : Type*) [LieRing L] :
    Function.Injective (@LieAlgebra.toModule _ _ _ _ : LieAlgebra ℚ L → Module ℚ L) := by
rintro ⟨h₁⟩ ⟨h₂⟩ heq
  congr
```

-- snippet 10
```lean
-- Mathlib.Algebra.Lie.BaseChange.instLieAlgebra (L114-L117)
instance instLieAlgebra : LieAlgebra A (A ⊗[R] L) where lie_smul _a _x _y := map_smul _ _ _
set_option backward.privateInPublic true in
set_option backward.privateInPublic.warn false in
```

-- snippet 11
```lean
-- Mathlib.Algebra.Lie.Basic.lie_swap_lie (L120-L129)
lemma lie_swap_lie [Bracket L₂ L₁] [AddCommGroup M] [IsLieTower L₁ L₂ M] [IsLieTower L₂ L₁ M]
    (x : L₁) (y : L₂) (m : M) : ⁅⁅x, y⁆, m⁆ = -⁅⁅y, x⁆, m⁆ := by
have h1 := leibniz_lie x y m
  have h2 := leibniz_lie y x m
  convert congr($h1.symm - $h2) using 1 <;> simp only [add_sub_cancel_right, sub_add_cancel_right]

end IsLieTower

section BasicProperties
```

-- snippet 12
```lean
-- Mathlib.Algebra.Lie.Basic.zero_lie (L168-L170)
theorem zero_lie : ⁅(0 : L), m⁆ = 0 :=
(AddMonoidHom.mk' (fun x : L => ⁅x, m⁆) fun x y => add_lie x y m).map_zero
```

-- snippet 13
```lean
-- Mathlib.Algebra.Lie.Abelian.TrivialLieModule (L375-L380)
def TrivialLieModule (R L M : Type*) := M
namespace TrivialLieModule

variable (R L M : Type*) [CommRing R] [LieRing L] [LieAlgebra R L] [AddCommGroup M] [Module R M]
```

-- snippet 14
```lean
-- Mathlib.Algebra.Lie.BaseChange.lie_baseChange (L234-L253)
lemma lie_baseChange {I : LieIdeal R L} {N : LieSubmodule R L M} :
    ⁅I, N⁆.baseChange A = ⁅I.baseChange A, N.baseChange A⁆ := by
set s : Set (A ⊗[R] M) := { m | ∃ x ∈ I, ∃ n ∈ N, 1 ⊗ₜ ⁅x, n⁆ = m}
  have : (TensorProduct.mk R A M 1) '' {m | ∃ x ∈ I, ∃ n ∈ N, ⁅x, n⁆ = m} = s := by ext; simp [s]
  rw [← toSubmodule_inj, coe_baseChange, lieIdeal_oper_eq_linear_span',
    Submodule.baseChange_span, this, lieIdeal_oper_eq_linear_span']
  refine le_antisymm (Submodule.span_mono ?_) (Submodule.span_le.mpr ?_)
  · rintro - ⟨x, hx, m, hm, rfl⟩
    exact ⟨1 ⊗ₜ x, tmul_mem_baseChange_of_mem 1 hx,
           1 ⊗ₜ m, tmul_mem_baseChange_of_mem 1 hm, by simp⟩
  · rintro - ⟨x, hx, m, hm, rfl⟩
    rw [mem_baseChange_iff] at hx hm
    refine Submodule.span_induction₂ (p := fun x m _ _ ↦ ⁅x, m⁆ ∈ Submodule.span A s)
      ?_ (by simp) (by simp) ?_ ?_ ?_ ?_ hx hm
    · rintro - - ⟨x, hx, rfl⟩ ⟨y, hy, rfl⟩; exact Submodule.subset_span ⟨x, hx, y, hy, by simp⟩
    all_goals { intros; simp [add_mem, Submodule.smul_mem, *] }

end LieSubmodule

end ExtendScalars
```

-- snippet 15
```lean
-- Mathlib.Algebra.Lie.Abelian.trivial_iff_le_maximal_trivial (L194-L198)
theorem trivial_iff_le_maximal_trivial (N : LieSubmodule R L M) :
    IsTrivial L N ↔ N ≤ maxTrivSubmodule R L M :=
⟨fun h m hm x => IsTrivial.casesOn h fun h => Subtype.ext_iff.mp (h x ⟨m, hm⟩), fun h =>
    { trivial := fun x m => Subtype.ext (h m.2 x) }⟩
```

-- snippet 16
```lean
-- Mathlib.Algebra.Lie.Basic.lie_smul (L157-L159)
theorem lie_smul : ⁅x, t • m⁆ = t • ⁅x, m⁆ :=
LieModule.lie_smul t x m
```

-- snippet 17
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.maxTrivSubmodule_eq_bot_of_center_eq_bot (L93-L104)
lemma maxTrivSubmodule_eq_bot_of_center_eq_bot (h : LieAlgebra.center R L = ⊥) :
    LieModule.maxTrivSubmodule R L (LieDerivation R L L) = ⊥ := by
refine (LieSubmodule.eq_bot_iff _).mpr fun D hD ↦ ext fun x ↦ ?_
  have : ad R L (D x) = 0 := by
    rw [LieModule.mem_maxTrivSubmodule] at hD
    simp [ad_apply_lieDerivation, hD]
  rw [← LieHom.mem_ker, ad_ker_eq_center, h, LieSubmodule.mem_bot] at this
  simp [this]

end AdjointAction

end LieDerivation
```

-- snippet 18
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.ad_apply_lieDerivation (L60-L61)
lemma ad_apply_lieDerivation (x : L) (D : LieDerivation R L L) : ad R L (D x) = -⁅x, D⁆ := rfl
```

-- snippet 19
```lean
-- Mathlib.Algebra.Lie.Basic.add_lie (L145-L147)
theorem add_lie : ⁅x + y, m⁆ = ⁅x, m⁆ + ⁅y, m⁆ :=
LieRingModule.add_lie x y m
```

-- snippet 20
```lean
-- Mathlib.Algebra.Lie.Abelian.equiv (L386-L387)
def equiv : (TrivialLieModule R L M) ≃ₗ[R] M := LinearEquiv.refl R M
```

-- snippet 21
```lean
-- Mathlib.Algebra.Lie.BaseChange.instLieModule (L123-L127)
instance instLieModule : LieModule A (A ⊗[R] L) (A ⊗[R] M) where
  smul_lie t x m := by simp only [bracket_def, map_smul, LinearMap.smul_apply]
lie_smul _ _ _ := map_smul _ _ _

/-- The Lie algebra homomorphism induced by an algebra map. -/
```

-- snippet 22
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.ad (L45-L57)
def ad : L →ₗ⁅R⁆ LieDerivation R L L :=
{ __ := - inner R L L
    map_lie' := by
      intro x y
      ext z
      simp only [AddHom.toFun_eq_coe, LinearMap.coe_toAddHom, LinearMap.neg_apply, coe_neg,
        Pi.neg_apply, inner_apply_apply, commutator_apply]
      rw [leibniz_lie, neg_lie, neg_lie, ← lie_skew x]
      abel }

variable {R L}

/-- The definitions `LieDerivation.ad` and `LieAlgebra.ad` agree. -/
```

-- snippet 23
```lean
-- Mathlib.Algebra.Lie.Abelian.Function (L64-L72)
theorem Function.Injective.isLieAbelian {R : Type u} {L₁ : Type v} {L₂ : Type w} [CommRing R]
    [LieRing L₁] [LieRing L₂] [LieAlgebra R L₁] [LieAlgebra R L₂] {f : L₁ →ₗ⁅R⁆ L₂}
    (h₁ : Function.Injective f) (_ : IsLieAbelian L₂) : IsLieAbelian L₁ :=
{ trivial := fun x y => h₁ <|
      calc
        f ⁅x, y⁆ = ⁅f x, f y⁆ := LieHom.map_lie f x y
        _ = 0 := trivial_lie_zero _ _ _ _
        _ = f 0 := (map_zero _).symm }
```

-- snippet 24
```lean
-- Mathlib.Algebra.Lie.Abelian.isTrivial_iff_max_triv_eq_top (L199-L207)
theorem isTrivial_iff_max_triv_eq_top : IsTrivial L M ↔ maxTrivSubmodule R L M = ⊤ := by
constructor
  · rintro ⟨h⟩; ext; simp only [mem_maxTrivSubmodule, h, forall_const, LieSubmodule.mem_top]
  · intro h; constructor; intro x m; revert x
    rw [← mem_maxTrivSubmodule R L M, h]; exact LieSubmodule.mem_top m

variable {R L M N}

/-- `maxTrivSubmodule` is functorial. -/
```

-- snippet 25
```lean
-- Mathlib.Algebra.Lie.Basic.lie_self (L172-L174)
theorem lie_self : ⁅x, x⁆ = 0 :=
LieRing.lie_self x
```

-- snippet 26
```lean
-- Mathlib.Algebra.Lie.Abelian.commute_toEnd_of_mem_center_left (L322-L325)
lemma commute_toEnd_of_mem_center_left :
    Commute (toEnd R L M x) (toEnd R L M y) := by
rw [Commute.symm_iff, commute_iff_lie_eq, ← LieHom.map_lie, hx y, map_zero]
```

-- snippet 27
```lean
-- Mathlib.Algebra.Lie.Abelian.le_max_triv_iff_bracket_eq_bot (L185-L193)
theorem le_max_triv_iff_bracket_eq_bot {N : LieSubmodule R L M} :
    N ≤ maxTrivSubmodule R L M ↔ ⁅(⊤ : LieIdeal R L), N⁆ = ⊥ := by
refine ⟨fun h => ?_, fun h m hm => ?_⟩
  · rw [← le_bot_iff, ← ideal_oper_maxTrivSubmodule_eq_bot R L M ⊤]
    exact LieSubmodule.mono_lie_right ⊤ h
  · rw [mem_maxTrivSubmodule]
    rw [LieSubmodule.lie_eq_bot_iff] at h
    exact fun x => h x (LieSubmodule.mem_top x) m hm
```

-- snippet 28
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.mem_ad_idealRange_iff (L89-L92)
lemma mem_ad_idealRange_iff {D : LieDerivation R L L} :
    D ∈ (ad R L).idealRange ↔ ∃ x : L, ad R L x = D :=
(ad R L).mem_idealRange_iff (ad_isIdealMorphism R L)
```

-- snippet 29
```lean
-- Mathlib.Algebra.Lie.BaseChange.map (L128-L139)
def map {R A B L L' : Type*} [CommRing R] [CommRing A] [Algebra R A] [CommRing B] [Algebra R B]
    [LieRing L] [LieAlgebra R L] [LieRing L'] [LieAlgebra R L'] (f : A →ₐ[R] B) (g : L →ₗ⁅R⁆ L') :
    A ⊗[R] L →ₗ⁅R⁆ B ⊗[R] L' :=
{ TensorProduct.map f.toLinearMap g with
    map_lie' {x y} := by
      simp only [bracket_def, AddHom.toFun_eq_coe, LinearMap.coe_toAddHom]
      refine x.induction_on (by simp) ?_ ?_
      · intro _ _
        refine y.induction_on (by simp) (fun _ _ ↦ by simp) (fun _ _ h1 h2 ↦ by simp [h1, h2])
      · intro _ _
        refine y.induction_on (by simp) (fun _ _ h ↦ by simp [h]) (by simp_all) }
```

-- snippet 30
```lean
-- Mathlib.Algebra.Lie.Abelian.coe_maxTrivLinearMapEquivLieModuleHom (L259-L261)
theorem coe_maxTrivLinearMapEquivLieModuleHom (f : maxTrivSubmodule R L (M →ₗ[R] N)) :
    (maxTrivLinearMapEquivLieModuleHom (M := M) (N := N) f : M → N) = f := by ext; rfl
```

-- snippet 31
```lean
-- Mathlib.Algebra.Lie.Abelian.abelian_of_le_center (L299-L302)
theorem abelian_of_le_center (I : LieIdeal R L) (h : I ≤ center R L) : IsLieAbelian I :=
haveI : LieModule.IsTrivial L I := (LieModule.trivial_iff_le_maximal_trivial R L L I).mpr h
  LieIdeal.isLieAbelian_of_trivial R L I
```

-- snippet 32
```lean
-- Mathlib.Algebra.Lie.Abelian.commute_toEnd_of_mem_center_right (L326-L341)
lemma commute_toEnd_of_mem_center_right :
    Commute (toEnd R L M y) (toEnd R L M x) :=
(LieModule.commute_toEnd_of_mem_center_left M hx y).symm

end LieModule

end Center

section IdealOperations

open LieSubmodule LieSubalgebra

variable {R : Type u} {L : Type v} {M : Type w}
variable [CommRing R] [LieRing L] [LieAlgebra R L] [AddCommGroup M] [Module R M]
variable [LieRingModule L M] (N N' : LieSubmodule R L M) (I J : LieIdeal R L)
```

-- snippet 33
```lean
-- Mathlib.Algebra.Lie.Abelian.self_module_ker_eq_center (L295-L298)
theorem self_module_ker_eq_center : LieModule.ker R L L = center R L := by
ext y
  simp only [LieModule.mem_maxTrivSubmodule, LieModule.mem_ker, ← lie_skew _ y, neg_eq_zero]
```

-- snippet 34
```lean
-- Mathlib.Algebra.Lie.Abelian.center_eq_bot (L310-L321)
theorem center_eq_bot [LieModule.IsFaithful R L L] :
    center R L = ⊥ :=
(isFaithful_self_iff R L).mp inferInstance

end LieAlgebra

namespace LieModule

variable {R L}
variable {x : L} (hx : x ∈ LieAlgebra.center R L) (y : L)
include hx
```

-- snippet 35
```lean
-- Mathlib.Algebra.Lie.BaseChange.instLieRing (L106-L111)
instance instLieRing : LieRing (A ⊗[R] L) where
  add_lie x y z := by simp only [bracket_def, LinearMap.add_apply, map_add]
lie_add x y z := by simp only [bracket_def, map_add]
  lie_self := bracket_lie_self R A L
  leibniz_lie := bracket_leibniz_lie R A L L
```

-- snippet 36
```lean
-- Mathlib.Algebra.Lie.BaseChange.lieAlgebra (L161-L174)
instance lieAlgebra [CommRing R] [Algebra R A] : LieAlgebra R (RestrictScalars R A L) where
  lie_smul t x y := (lie_smul (algebraMap R A t) (RestrictScalars.addEquiv R A L x)
(RestrictScalars.addEquiv R A L y) :)

end RestrictScalars

end LieAlgebra

section ExtendScalars

variable [CommRing R] [LieRing L] [LieAlgebra R L]
  [AddCommGroup M] [Module R M] [LieRingModule L M] [LieModule R L M]
  [CommRing A] [Algebra R A]
```

-- snippet 37
```lean
-- Mathlib.Algebra.Lie.BaseChange.mem_baseChange_iff (L219-L223)
lemma mem_baseChange_iff {m : A ⊗[R] M} :
    m ∈ N.baseChange A ↔
    m ∈ Submodule.span A ((N : Submodule R M).map (TensorProduct.mk R A M 1)) := by
rw [← Submodule.baseChange_eq_span]; rfl
```

-- snippet 38
```lean
-- Mathlib.Algebra.Lie.Basic.smul_lie (L153-L155)
theorem smul_lie : ⁅t • x, m⁆ = t • ⁅x, m⁆ :=
LieModule.smul_lie t x m
```

-- snippet 39
```lean
-- Mathlib.Algebra.Lie.Abelian.lie_abelian_iff_equiv_lie_abelian (L81-L85)
theorem lie_abelian_iff_equiv_lie_abelian {R : Type u} {L₁ : Type v} {L₂ : Type w} [CommRing R]
    [LieRing L₁] [LieRing L₂] [LieAlgebra R L₁] [LieAlgebra R L₂] (e : L₁ ≃ₗ⁅R⁆ L₂) :
    IsLieAbelian L₁ ↔ IsLieAbelian L₂ :=
⟨e.symm.injective.isLieAbelian, e.injective.isLieAbelian⟩
```

-- snippet 40
```lean
-- Mathlib.Algebra.Lie.Abelian.IsLieAbelian (L57-L59)
abbrev IsLieAbelian (L : Type v) [Bracket L L] [Zero L] : Prop :=
LieModule.IsTrivial L L
```

-- snippet 41
```lean
-- Mathlib.Algebra.Lie.BaseChange.map_apply_tmul (L141-L154)
lemma map_apply_tmul {R A B L L' : Type*} [CommRing R] [CommRing A] [Algebra R A] [CommRing B]
    [Algebra R B] [LieRing L] [LieAlgebra R L] [LieRing L'] [LieAlgebra R L'] {f : A →ₐ[R] B}
    {g : L →ₗ⁅R⁆ L'} (a : A) (x : L) :
    map f g (a ⊗ₜ x) = (f a) ⊗ₜ (g x) :=
rfl

end ExtendScalars

namespace RestrictScalars

open RestrictScalars

variable [h : LieRing L]
```

-- snippet 42
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Basic.LieSubalgebra (L45-L51)
theorem LieSubalgebra.isNilpotent_ad_of_isNilpotent_ad {L : Type*} [LieRing L] [LieAlgebra R L]
    (K : LieSubalgebra R L) {x : K} (h : IsNilpotent (LieAlgebra.ad R L ↑x)) :
    IsNilpotent (LieAlgebra.ad R K x) := by
obtain ⟨n, hn⟩ := h
  use n
  exact Module.End.submodule_pow_eq_zero_of_pow_eq_zero (K.ad_comp_incl_eq x) hn
```

-- snippet 43
```lean
-- Mathlib.Algebra.Lie.Abelian.lie_eq_self_of_isAtom_of_ne_bot (L359-L362)
lemma lie_eq_self_of_isAtom_of_ne_bot (hN : IsAtom N) (h : ⁅I, N⁆ ≠ ⊥) : ⁅I, N⁆ = N :=
(hN.le_iff_eq h).mp <| LieSubmodule.lie_le_right N I

-- TODO: introduce typeclass for perfect Lie algebras and use it here in the conclusion
```

-- snippet 44
```lean
-- Mathlib.Algebra.Lie.Abelian.commutative_ring_iff_abelian_lie_ring (L86-L92)
theorem commutative_ring_iff_abelian_lie_ring {A : Type v} [Ring A] :
    Std.Commutative (α := A) (· * ·) ↔ IsLieAbelian A := by
have h₁ : Std.Commutative (α := A) (· * ·) ↔ ∀ a b : A, a * b = b * a :=
    ⟨fun h => h.1, fun h => ⟨h⟩⟩
  have h₂ : IsLieAbelian A ↔ ∀ a b : A, ⁅a, b⁆ = 0 := ⟨fun h => h.1, fun h => ⟨h⟩⟩
  simp only [h₁, h₂, LieRing.of_associative_ring_bracket, sub_eq_zero]
```

-- snippet 45
```lean
-- Mathlib.Algebra.Lie.Abelian.isFaithful_self_iff (L306-L308)
theorem isFaithful_self_iff : LieModule.IsFaithful R L L ↔ center R L = ⊥ := by
rw [LieModule.isFaithful_iff_ker_eq_bot, self_module_ker_eq_center]
```

-- snippet 46
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.ad_ker_eq_center (L66-L71)
lemma ad_ker_eq_center : (ad R L).ker = LieAlgebra.center R L := by
ext x
  rw [← LieAlgebra.self_module_ker_eq_center, LieHom.mem_ker, LieModule.mem_ker]
  simp [DFunLike.ext_iff]

/-- If the center of a Lie algebra is trivial, then the adjoint action is injective. -/
```

-- snippet 47
```lean
-- Mathlib.Algebra.Lie.BaseChange.tmul_mem_baseChange_of_mem (L215-L218)
lemma tmul_mem_baseChange_of_mem (a : A) {m : M} (hm : m ∈ N) :
    a ⊗ₜ[R] m ∈ N.baseChange A :=
(N : Submodule R M).tmul_mem_baseChange_of_mem a hm
```

-- snippet 48
```lean
-- Mathlib.Algebra.Lie.Abelian.maxTrivSubmodule (L164-L170)
def maxTrivSubmodule : LieSubmodule R L M where
  carrier := { m | ∀ x : L, ⁅x, m⁆ = 0 }
zero_mem' x := lie_zero x
  add_mem' {x y} hx hy z := by rw [lie_add, hx, hy, add_zero]
  smul_mem' c x hx y := by rw [lie_smul, hx, smul_zero]
  lie_mem {x m} hm y := by rw [hm, lie_zero]
```

-- snippet 49
```lean
-- Mathlib.Algebra.Lie.Abelian.ideal_oper_maxTrivSubmodule_eq_bot (L178-L184)
theorem ideal_oper_maxTrivSubmodule_eq_bot (I : LieIdeal R L) :
    ⁅I, maxTrivSubmodule R L M⁆ = ⊥ := by
rw [← LieSubmodule.toSubmodule_inj, LieSubmodule.lieIdeal_oper_eq_linear_span,
    LieSubmodule.bot_toSubmodule, Submodule.span_eq_bot]
  rintro m ⟨⟨x, hx⟩, ⟨⟨m, hm⟩, rfl⟩⟩
  exact hm x
```

-- snippet 50
```lean
-- Mathlib.Algebra.Lie.BaseChange.bracket_tmul (L61-L105)
theorem bracket_tmul (s t : A) (x : L) (y : M) : ⁅s ⊗ₜ[R] x, t ⊗ₜ[R] y⁆ = (s * t) ⊗ₜ ⁅x, y⁆ := rfl
set_option backward.privateInPublic true in
private theorem bracket_lie_self (x : A ⊗[R] L) : ⁅x, x⁆ = 0 := by
  simp only [bracket_def]
  refine x.induction_on ?_ ?_ ?_
  · simp only [map_zero]
  · intro a l
    simp only [bracket'_tmul, TensorProduct.tmul_zero, lie_self]
  · intro z₁ z₂ h₁ h₂
    suffices bracket' R A L L z₁ z₂ + bracket' R A L L z₂ z₁ = 0 by
      rw [map_add, map_add, LinearMap.add_apply, LinearMap.add_apply, h₁, h₂,
        zero_add, add_zero, add_comm, this]
    refine z₁.induction_on ?_ ?_ ?_
    · simp only [map_zero, add_zero, LinearMap.zero_apply]
    · intro a₁ l₁; refine z₂.induction_on ?_ ?_ ?_
      · simp only [map_zero, add_zero, LinearMap.zero_apply]
      · intro a₂ l₂
        simp only [← lie_skew l₂ l₁, mul_comm a₁ a₂, TensorProduct.tmul_neg, bracket'_tmul,
          add_neg_cancel]
      · intro y₁ y₂ hy₁ hy₂
        simp only [hy₁, hy₂, add_add_add_comm, add_zero, LinearMap.add_apply, map_add]
    · intro y₁ y₂ hy₁ hy₂
      simp only [add_add_add_comm, hy₁, hy₂, add_zero, LinearMap.add_apply, map_add]

set_option backward.privateInPublic true in
private theorem bracket_leibniz_lie (x y : A ⊗[R] L) (z : A ⊗[R] M) :
    ⁅x, ⁅y, z⁆⁆ = ⁅⁅x, y⁆, z⁆ + ⁅y, ⁅x, z⁆⁆ := by
  simp only [bracket_def]
  refine x.induction_on ?_ ?_ ?_
  · simp only [map_zero, add_zero, LinearMap.zero_apply]
  · intro a₁ l₁
    refine y.induction_on ?_ ?_ ?_
    · simp only [map_zero, add_zero, LinearMap.zero_apply]
    · intro a₂ l₂
      refine z.induction_on ?_ ?_ ?_
      · simp only [map_zero, add_zero]
      · intro a₃ l₃; simp only [bracket'_tmul]
        rw [mul_left_comm a₂ a₁ a₃, mul_assoc, leibniz_lie, TensorProduct.tmul_add]
      · grind
    · grind [LinearMap.add_apply]
  · grind [LinearMap.add_apply]

set_option backward.privateInPublic true in
set_option backward.privateInPublic.warn false in
```

-- snippet 51
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.lie_der_ad_eq_ad_der (L77-L82)
lemma lie_der_ad_eq_ad_der (D : LieDerivation R L L) (x : L) : ⁅D, ad R L x⁆ = ad R L (D x) := by
rw [ad_apply_lieDerivation, ← lie_ad, lie_skew]

variable (R L) in
/-- The range of the adjoint action homomorphism from a Lie algebra `L` to the Lie algebra of its
derivations is an ideal of the latter. -/
```

-- snippet 52
```lean
-- Mathlib.Algebra.Lie.Abelian.isLieAbelian_iff_center_eq_top (L303-L305)
theorem isLieAbelian_iff_center_eq_top : IsLieAbelian L ↔ center R L = ⊤ :=
LieModule.isTrivial_iff_max_triv_eq_top R L L
```

-- snippet 53
```lean
-- Mathlib.Algebra.Lie.Basic.lie_zero (L164-L166)
theorem lie_zero : ⁅x, 0⁆ = (0 : M) :=
(AddMonoidHom.mk' _ (lie_add x)).map_zero
```

-- snippet 54
```lean
-- Mathlib.Algebra.Lie.Abelian.maxTrivEquiv_of_equiv_symm_eq_symm (L240-L245)
theorem maxTrivEquiv_of_equiv_symm_eq_symm (e : M ≃ₗ⁅R,L⁆ N) :
    (maxTrivEquiv e).symm = maxTrivEquiv e.symm :=
rfl

/-- A linear map between two Lie modules is a morphism of Lie modules iff the Lie algebra action
on it is trivial. -/
```

-- snippet 55
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.ad_isIdealMorphism (L83-L88)
lemma ad_isIdealMorphism : (ad R L).IsIdealMorphism := by
simp_rw [LieHom.isIdealMorphism_iff, lie_der_ad_eq_ad_der]
  tauto

/-- A derivation `D` belongs to the ideal range of the adjoint action iff it is of the form `ad x`
for some `x` in the Lie algebra `L`. -/
```

-- snippet 56
```lean
-- Mathlib.Algebra.Lie.Basic.lieAlgebraSelfModule (L184-L187)
instance lieAlgebraSelfModule : LieModule R L L where
  smul_lie t x m := by rw [← lie_skew, ← lie_skew x m, LieAlgebra.lie_smul, smul_neg]
lie_smul := by apply LieAlgebra.lie_smul
```

-- snippet 57
```lean
-- Mathlib.Algebra.Lie.Abelian.LieIdeal (L60-L63)
instance LieIdeal.isLieAbelian_of_trivial (R : Type u) (L : Type v) [CommRing R] [LieRing L]
    [LieAlgebra R L] (I : LieIdeal R L) [h : LieModule.IsTrivial L I] : IsLieAbelian I where
  trivial x y := by apply h.trivial
```

-- snippet 58
```lean
-- Mathlib.Algebra.Lie.Abelian.lie_eq_self_of_isAtom_of_nonabelian (L363-L373)
lemma lie_eq_self_of_isAtom_of_nonabelian {R L : Type*} [CommRing R] [LieRing L] [LieAlgebra R L]
    (I : LieIdeal R L) (hI : IsAtom I) (h : ¬IsLieAbelian I) :
    ⁅I, I⁆ = I :=
lie_eq_self_of_isAtom_of_ne_bot hI <| not_imp_not.mpr (lie_abelian_iff_lie_self_eq_bot I).mpr h

end IdealOperations

section TrivialLieModule

set_option linter.unusedVariables false in
/-- A type synonym for an `R`-module to have a trivial Lie module structure. -/
```

-- snippet 59
```lean
-- Mathlib.Algebra.Lie.Abelian.LieSubmodule (L343-L347)
theorem LieSubmodule.trivial_lie_oper_zero [LieModule.IsTrivial L M] : ⁅I, N⁆ = ⊥ := by
suffices ⁅I, N⁆ ≤ ⊥ from le_bot_iff.mp this
  rw [lieIdeal_oper_eq_span, LieSubmodule.lieSpan_le]
  rintro m ⟨x, n, h⟩; rw [trivial_lie_zero] at h; simp [← h]
```

-- snippet 60
```lean
-- Mathlib.Algebra.Lie.Abelian.coe_maxTrivEquiv_apply (L230-L233)
theorem coe_maxTrivEquiv_apply (e : M ≃ₗ⁅R,L⁆ N) (m : maxTrivSubmodule R L M) :
    (maxTrivEquiv e m : N) = e ↑m :=
rfl
```

-- snippet 61
```lean
-- Mathlib.Algebra.Lie.Abelian.maxTrivLinearMapEquivLieModuleHom (L246-L257)
def maxTrivLinearMapEquivLieModuleHom : maxTrivSubmodule R L (M →ₗ[R] N) ≃ₗ[R] M →ₗ⁅R,L⁆ N where
  toFun f :=
{ toLinearMap := f.val
      map_lie' := fun {x m} => by
        have hf : ⁅x, f.val⁆ m = 0 := by rw [f.property x, LinearMap.zero_apply]
        rw [LieHom.lie_apply, sub_eq_zero, ← LinearMap.toFun_eq_coe] at hf; exact hf.symm }
  map_add' f g := by ext; simp
  map_smul' F G := by ext; simp
  invFun F := ⟨F, fun x => by ext; simp⟩
  left_inv f := by simp
  right_inv F := by simp
```

-- snippet 62
```lean
-- Mathlib.Algebra.Lie.Abelian.coe_maxTrivHom_apply (L217-L221)
theorem coe_maxTrivHom_apply (f : M →ₗ⁅R,L⁆ N) (m : maxTrivSubmodule R L M) :
    (maxTrivHom f m : N) = f m :=
rfl

/-- The maximal trivial submodules of Lie-equivalent Lie modules are Lie-equivalent. -/
```

-- snippet 63
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.injective_ad_of_center_eq_bot (L72-L76)
lemma injective_ad_of_center_eq_bot (h : LieAlgebra.center R L = ⊥) :
    Function.Injective (ad R L) := by
rw [← LieHom.ker_eq_bot, ad_ker_eq_center, h]

/-- The commutator of a derivation `D` and a derivation of the form `ad x` is `ad (D x)`. -/
```

-- snippet 64
```lean
-- Mathlib.Algebra.Lie.Abelian.isFaithful_iff_ker_eq_bot (L155-L158)
lemma isFaithful_iff_ker_eq_bot : IsFaithful R L M ↔ LieModule.ker R L M = ⊥ := by
rw [isFaithful_iff', LieSubmodule.ext_iff]
  aesop
```

-- snippet 65
```lean
-- Mathlib.Algebra.Lie.BaseChange.coe_baseChange (L208-L214)
lemma coe_baseChange :
    (N.baseChange A : Submodule A (A ⊗[R] M)) = (N : Submodule R M).baseChange A :=
rfl

variable {N}

variable {R A L M} in
```

-- snippet 66
```lean
-- Mathlib.Algebra.Lie.Abelian.maxTrivHom (L208-L215)
def maxTrivHom (f : M →ₗ⁅R,L⁆ N) : maxTrivSubmodule R L M →ₗ⁅R,L⁆ maxTrivSubmodule R L N where
  toFun m := ⟨f m, fun x =>
(LieModuleHom.map_lie _ _ _).symm.trans <|
      (congr_arg f (m.property x)).trans (map_zero _)⟩
  map_add' m n := by ext; simp
  map_smul' t m := by ext; simp
  map_lie' {x m} := by simp
```

-- snippet 67
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.lie_ad (L62-L65)
lemma lie_ad (x : L) (D : LieDerivation R L L) : ⁅ad R L x, D⁆ = ⁅x, D⁆ := by ext; simp
variable (R L) in
/-- The kernel of the adjoint action on a Lie algebra is equal to its center. -/
```

-- snippet 68
```lean
-- Mathlib.Algebra.Lie.Abelian.ad_ker_eq_self_module_ker (L291-L293)
theorem ad_ker_eq_self_module_ker : (ad R L).ker = LieModule.ker R L L :=
rfl
```

-- snippet 69
```lean
-- Mathlib.Algebra.Lie.BaseChange.baseChange_top (L230-L233)
lemma baseChange_top : (⊤ : LieSubmodule R L M).baseChange A = ⊤ := by
simp only [baseChange, top_toSubmodule, Submodule.baseChange_top]
  rfl
```

-- snippet 70
```lean
-- Mathlib.Algebra.Lie.Basic.lie_add (L149-L151)
theorem lie_add : ⁅x, m + n⁆ = ⁅x, m⁆ + ⁅x, n⁆ :=
LieRingModule.lie_add x m n
```

-- snippet 71
```lean
-- Mathlib.Algebra.Lie.Abelian.toLinearMap_maxTrivLinearMapEquivLieModuleHom (L268-L271)
theorem toLinearMap_maxTrivLinearMapEquivLieModuleHom (f : maxTrivSubmodule R L (M →ₗ[R] N)) :
    (maxTrivLinearMapEquivLieModuleHom (M := M) (N := N) f : M →ₗ[R] N) = (f : M →ₗ[R] N) := by
ext; rfl
```

-- snippet 72
```lean
-- Mathlib.Algebra.Lie.Basic.lie_skew (L179-L183)
theorem lie_skew : -⁅y, x⁆ = ⁅x, y⁆ := by
have h : ⁅x + y, x⁆ + ⁅x + y, y⁆ = 0 := by rw [← lie_add]; apply lie_self
  simpa [neg_eq_iff_add_eq_zero] using h

/-- Every Lie algebra is a module over itself. -/
```

-- snippet 73
```lean
-- Mathlib.Algebra.Lie.BaseChange.baseChange (L191-L206)
def baseChange : LieSubmodule A (A ⊗[R] L) (A ⊗[R] M) :=
{ (N : Submodule R M).baseChange A with
    lie_mem := by
      intro x m hm
      rw [Submodule.mem_carrier, SetLike.mem_coe] at hm ⊢
      rw [Submodule.baseChange_eq_span] at hm
      obtain ⟨c, rfl⟩ := (Finsupp.mem_span_iff_linearCombination _ _ _).mp hm
      refine x.induction_on (by simp) (fun a y ↦ ?_) (fun y z hy hz ↦ ?_)
      · change toEnd A (A ⊗[R] L) (A ⊗[R] M) _ _ ∈ _
        simp_rw [Finsupp.linearCombination_apply, Finsupp.sum, map_sum, map_smul, toEnd_apply_apply]
        refine Submodule.sum_mem _ fun ⟨_, n, hn, h⟩ _ ↦ Submodule.smul_mem _ _ ?_
        rw [Subtype.coe_mk, ← h]
        exact Submodule.tmul_mem_baseChange_of_mem _ (N.lie_mem hn)
      · rw [add_lie]
        exact ((N : Submodule R M).baseChange A).add_mem hy hz }
```

-- snippet 74
```lean
-- Mathlib.Algebra.Lie.Abelian.trivial_lie_zero (L44-L47)
theorem trivial_lie_zero (L : Type v) (M : Type w) [Bracket L M] [Zero M] [LieModule.IsTrivial L M]
    (x : L) (m : M) : ⁅x, m⁆ = 0 :=
LieModule.IsTrivial.trivial x m
```

-- snippet 75
```lean
-- Mathlib.Algebra.Lie.BaseChange.instBaseLieAlgebra (L112-L113)
instance instBaseLieAlgebra : LieAlgebra R (A ⊗[R] L) where lie_smul := by simp [bracket_def]
```

-- snippet 76
```lean
-- Mathlib.Algebra.Lie.Abelian.coe_maxTrivLinearMapEquivLieModuleHom_symm (L263-L266)
theorem coe_maxTrivLinearMapEquivLieModuleHom_symm (f : M →ₗ⁅R,L⁆ N) :
    (maxTrivLinearMapEquivLieModuleHom (M := M) (N := N) |>.symm f : M → N) = f :=
rfl
```

-- snippet 77
```lean
-- Mathlib.Algebra.Lie.BaseChange.baseChange_bot (L225-L228)
lemma baseChange_bot : (⊥ : LieSubmodule R L M).baseChange A = ⊥ := by
simp only [baseChange, bot_toSubmodule, Submodule.baseChange_bot]
  rfl
```

-- snippet 78
```lean
-- Mathlib.Algebra.Lie.Basic.lieRingSelfModule (L175-L177)
instance lieRingSelfModule : LieRingModule L L :=
{ (inferInstance : LieRing L) with }
```

-- snippet 79
```lean
-- Mathlib.Algebra.Lie.Abelian.maxTrivEquiv_of_refl_eq_refl (L235-L238)
theorem maxTrivEquiv_of_refl_eq_refl :
    maxTrivEquiv (LieModuleEquiv.refl : M ≃ₗ⁅R,L⁆ M) = LieModuleEquiv.refl := by
ext; simp only [coe_maxTrivEquiv_apply, LieModuleEquiv.refl_apply]
```

-- snippet 80
```lean
-- Mathlib.Algebra.Lie.Abelian.maxTrivEquiv (L222-L228)
def maxTrivEquiv (e : M ≃ₗ⁅R,L⁆ N) : maxTrivSubmodule R L M ≃ₗ⁅R,L⁆ maxTrivSubmodule R L N :=
{ maxTrivHom (e : M →ₗ⁅R,L⁆ N) with
    toFun := maxTrivHom (e : M →ₗ⁅R,L⁆ N)
    invFun := maxTrivHom (e.symm : N →ₗ⁅R,L⁆ M)
    left_inv := fun m => by ext; simp
    right_inv := fun n => by ext; simp }
```

-- snippet 81
```lean
-- Mathlib.Algebra.Lie.BaseChange.LieModule (L176-L190)
lemma LieModule.toEnd_baseChange (x : L) :
    toEnd A (A ⊗[R] L) (A ⊗[R] M) (1 ⊗ₜ x) = (toEnd R L M x).baseChange A := by
ext; simp

namespace LieSubmodule

variable (N : LieSubmodule R L M)

open LieModule

variable {R L M} in
/-- If `A` is an `R`-algebra, any Lie submodule of a Lie module `M` with coefficients in `R` may be
pushed forward to a Lie submodule of `A ⊗ M` with coefficients in `A`.

This "base change" operation is also known as "extension of scalars". -/
```

-- snippet 82
```lean
-- Mathlib.Algebra.Lie.Abelian.LieModule (L48-L51)
instance LieModule.instIsTrivialOfSubsingleton {L M : Type*}
    [LieRing L] [AddCommGroup M] [LieRingModule L M] [Subsingleton L] : LieModule.IsTrivial L M :=
⟨fun x m ↦ by rw [Subsingleton.eq_zero x, zero_lie]⟩
```

-- snippet 83
```lean
-- Mathlib.Algebra.Lie.Abelian.center (L284-L286)
abbrev center : LieIdeal R L :=
LieModule.maxTrivSubmodule R L L
```

<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.Lie.Derivation.BaseChange).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Prove the following theorem. The retrieved context below may help.

```lean
def ofLieDerivation : (LieDerivation R L L) →ₗ⁅R⁆ (LieDerivation R (A ⊗[R] L) (A ⊗[R] L)) where
  toFun d
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Algebra.Lie.Derivation.BaseChange.ofDerivation (L37-L56)
def ofDerivation : Derivation R A A →ₗ⁅R⁆ LieDerivation R (A ⊗[R] L) (A ⊗[R] L) where
  toFun d :=
{ toFun := d.rTensor L
      map_add' := by simp
      map_smul' := by simp
      leibniz' x y := by
        simp only [LinearMap.coe_mk, AddHom.coe_mk]
        refine x.induction_on (by simp) (fun _ l ↦ ?_) (fun _ _ h1 h2 ↦ ?_)
        · refine y.induction_on (by simp) (fun _ l' ↦ ?_) (fun _ _ h1 h2 ↦ ?_)
          · simp [← lie_skew l' l, -lie_skew, add_tmul, tmul_neg]
          · simp [h1, h2, sub_add_sub_comm]
        · simp [h1, h2, sub_add_sub_comm] }
  map_add' _ _ := by ext; simp
  map_smul' _ _ := by ext; simp
  map_lie' {_ _} := by
    ext z
    refine z.induction_on (by simp) (by simp [sub_tmul]) (fun _ _ hx hy ↦ ?_)
    simp_all
    abel
```

-- snippet 2
```lean
-- Mathlib.Algebra.Lie.Derivation.BaseChange.ofDerivation_apply (L58-L64)
lemma ofDerivation_apply (d : Derivation R A A) (x : A ⊗[R] L) :
    ofDerivation L d x = d.toLinearMap.rTensor L x :=
rfl

variable (A) in
/-- A Lie derivation of an `R-`Lie algebra `L`, induces a Lie derivation of `A ⊗[R] L` for any
Algebra `A` over `R`. -/
```

-- snippet 3
```lean
-- Mathlib.Algebra.Lie.Derivation.BaseChange.ofLieDerivation_apply (L92-L96)
lemma ofLieDerivation_apply (d : LieDerivation R L L) (x : A ⊗[R] L) :
    ofLieDerivation A d x = d.toLinearMap.lTensor A x :=
rfl

end Lie.Derivation
```

-- snippet 4
```lean
-- Mathlib.Algebra.Lie.Abelian.mem_maxTrivSubmodule (L172-L174)
theorem mem_maxTrivSubmodule (m : M) : m ∈ maxTrivSubmodule R L M ↔ ∀ x : L, ⁅x, m⁆ = 0 :=
Iff.rfl
```

-- snippet 5
```lean
-- Mathlib.Algebra.Lie.Basic.leibniz_lie (L117-L119)
lemma leibniz_lie [Add M] [IsLieTower L₁ L₂ M] (x : L₁) (y : L₂) (m : M) :
    ⁅x, ⁅y, m⁆⁆ = ⁅⁅x, y⁆, m⁆ + ⁅y, ⁅x, m⁆⁆ := IsLieTower.leibniz_lie x y m
```

-- snippet 6
```lean
-- Mathlib.Algebra.Lie.Abelian.toLinearMap_maxTrivLinearMapEquivLieModuleHom_symm (L273-L283)
theorem toLinearMap_maxTrivLinearMapEquivLieModuleHom_symm (f : M →ₗ⁅R,L⁆ N) :
    (maxTrivLinearMapEquivLieModuleHom (M := M) (N := N) |>.symm f : M →ₗ[R] N) = (f : M →ₗ[R] N) :=
rfl

end LieModule

namespace LieAlgebra

/-- The center of a Lie algebra is the set of elements that commute with everything. It can
be viewed as the maximal trivial submodule of the Lie algebra as a Lie module over itself via the
adjoint representation. -/
```

-- snippet 7
```lean
-- Mathlib.Algebra.Lie.BaseChange.instLieRingModule (L118-L122)
instance instLieRingModule : LieRingModule (A ⊗[R] L) (A ⊗[R] M) where
  add_lie x y z := by simp only [bracket_def, LinearMap.add_apply, map_add]
lie_add x y z := by simp only [bracket_def, map_add]
  leibniz_lie := bracket_leibniz_lie R A L M
```

-- snippet 8
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Basic.LieAlgebra (L32-L37)
theorem LieAlgebra.commute_ad_of_commute {a b : A} (h : Commute a b) :
    Commute (LieAlgebra.ad R A a) (LieAlgebra.ad R A b) := by
rw [Commute, SemiconjBy, ← sub_eq_zero, ← Ring.lie_def,
    ← (LieAlgebra.ad R A).map_lie, Ring.lie_def, sub_eq_zero.mpr h, map_zero]

/-- The adjoint of a nilpotent element is nilpotent. -/
```

-- snippet 9
```lean
-- Mathlib.Algebra.Lie.Basic.LieAlgebra (L130-L134)
theorem LieAlgebra.toModule_injective (L : Type*) [LieRing L] :
    Function.Injective (@LieAlgebra.toModule _ _ _ _ : LieAlgebra ℚ L → Module ℚ L) := by
rintro ⟨h₁⟩ ⟨h₂⟩ heq
  congr
```

-- snippet 10
```lean
-- Mathlib.Algebra.Lie.BaseChange.instLieAlgebra (L114-L117)
instance instLieAlgebra : LieAlgebra A (A ⊗[R] L) where lie_smul _a _x _y := map_smul _ _ _
set_option backward.privateInPublic true in
set_option backward.privateInPublic.warn false in
```

-- snippet 11
```lean
-- Mathlib.Algebra.Lie.Basic.lie_swap_lie (L120-L129)
lemma lie_swap_lie [Bracket L₂ L₁] [AddCommGroup M] [IsLieTower L₁ L₂ M] [IsLieTower L₂ L₁ M]
    (x : L₁) (y : L₂) (m : M) : ⁅⁅x, y⁆, m⁆ = -⁅⁅y, x⁆, m⁆ := by
have h1 := leibniz_lie x y m
  have h2 := leibniz_lie y x m
  convert congr($h1.symm - $h2) using 1 <;> simp only [add_sub_cancel_right, sub_add_cancel_right]

end IsLieTower

section BasicProperties
```

-- snippet 12
```lean
-- Mathlib.Algebra.Lie.Basic.zero_lie (L168-L170)
theorem zero_lie : ⁅(0 : L), m⁆ = 0 :=
(AddMonoidHom.mk' (fun x : L => ⁅x, m⁆) fun x y => add_lie x y m).map_zero
```

-- snippet 13
```lean
-- Mathlib.Algebra.Lie.Abelian.TrivialLieModule (L375-L380)
def TrivialLieModule (R L M : Type*) := M
namespace TrivialLieModule

variable (R L M : Type*) [CommRing R] [LieRing L] [LieAlgebra R L] [AddCommGroup M] [Module R M]
```

-- snippet 14
```lean
-- Mathlib.Algebra.Lie.BaseChange.lie_baseChange (L234-L253)
lemma lie_baseChange {I : LieIdeal R L} {N : LieSubmodule R L M} :
    ⁅I, N⁆.baseChange A = ⁅I.baseChange A, N.baseChange A⁆ := by
set s : Set (A ⊗[R] M) := { m | ∃ x ∈ I, ∃ n ∈ N, 1 ⊗ₜ ⁅x, n⁆ = m}
  have : (TensorProduct.mk R A M 1) '' {m | ∃ x ∈ I, ∃ n ∈ N, ⁅x, n⁆ = m} = s := by ext; simp [s]
  rw [← toSubmodule_inj, coe_baseChange, lieIdeal_oper_eq_linear_span',
    Submodule.baseChange_span, this, lieIdeal_oper_eq_linear_span']
  refine le_antisymm (Submodule.span_mono ?_) (Submodule.span_le.mpr ?_)
  · rintro - ⟨x, hx, m, hm, rfl⟩
    exact ⟨1 ⊗ₜ x, tmul_mem_baseChange_of_mem 1 hx,
           1 ⊗ₜ m, tmul_mem_baseChange_of_mem 1 hm, by simp⟩
  · rintro - ⟨x, hx, m, hm, rfl⟩
    rw [mem_baseChange_iff] at hx hm
    refine Submodule.span_induction₂ (p := fun x m _ _ ↦ ⁅x, m⁆ ∈ Submodule.span A s)
      ?_ (by simp) (by simp) ?_ ?_ ?_ ?_ hx hm
    · rintro - - ⟨x, hx, rfl⟩ ⟨y, hy, rfl⟩; exact Submodule.subset_span ⟨x, hx, y, hy, by simp⟩
    all_goals { intros; simp [add_mem, Submodule.smul_mem, *] }

end LieSubmodule

end ExtendScalars
```

-- snippet 15
```lean
-- Mathlib.Algebra.Lie.Abelian.trivial_iff_le_maximal_trivial (L194-L198)
theorem trivial_iff_le_maximal_trivial (N : LieSubmodule R L M) :
    IsTrivial L N ↔ N ≤ maxTrivSubmodule R L M :=
⟨fun h m hm x => IsTrivial.casesOn h fun h => Subtype.ext_iff.mp (h x ⟨m, hm⟩), fun h =>
    { trivial := fun x m => Subtype.ext (h m.2 x) }⟩
```

-- snippet 16
```lean
-- Mathlib.Algebra.Lie.Basic.lie_smul (L157-L159)
theorem lie_smul : ⁅x, t • m⁆ = t • ⁅x, m⁆ :=
LieModule.lie_smul t x m
```

-- snippet 17
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.maxTrivSubmodule_eq_bot_of_center_eq_bot (L93-L104)
lemma maxTrivSubmodule_eq_bot_of_center_eq_bot (h : LieAlgebra.center R L = ⊥) :
    LieModule.maxTrivSubmodule R L (LieDerivation R L L) = ⊥ := by
refine (LieSubmodule.eq_bot_iff _).mpr fun D hD ↦ ext fun x ↦ ?_
  have : ad R L (D x) = 0 := by
    rw [LieModule.mem_maxTrivSubmodule] at hD
    simp [ad_apply_lieDerivation, hD]
  rw [← LieHom.mem_ker, ad_ker_eq_center, h, LieSubmodule.mem_bot] at this
  simp [this]

end AdjointAction

end LieDerivation
```

-- snippet 18
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.ad_apply_lieDerivation (L60-L61)
lemma ad_apply_lieDerivation (x : L) (D : LieDerivation R L L) : ad R L (D x) = -⁅x, D⁆ := rfl
```

-- snippet 19
```lean
-- Mathlib.Algebra.Lie.Basic.add_lie (L145-L147)
theorem add_lie : ⁅x + y, m⁆ = ⁅x, m⁆ + ⁅y, m⁆ :=
LieRingModule.add_lie x y m
```

-- snippet 20
```lean
-- Mathlib.Algebra.Lie.Abelian.equiv (L386-L387)
def equiv : (TrivialLieModule R L M) ≃ₗ[R] M := LinearEquiv.refl R M
```

-- snippet 21
```lean
-- Mathlib.Algebra.Lie.BaseChange.instLieModule (L123-L127)
instance instLieModule : LieModule A (A ⊗[R] L) (A ⊗[R] M) where
  smul_lie t x m := by simp only [bracket_def, map_smul, LinearMap.smul_apply]
lie_smul _ _ _ := map_smul _ _ _

/-- The Lie algebra homomorphism induced by an algebra map. -/
```

-- snippet 22
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.ad (L45-L57)
def ad : L →ₗ⁅R⁆ LieDerivation R L L :=
{ __ := - inner R L L
    map_lie' := by
      intro x y
      ext z
      simp only [AddHom.toFun_eq_coe, LinearMap.coe_toAddHom, LinearMap.neg_apply, coe_neg,
        Pi.neg_apply, inner_apply_apply, commutator_apply]
      rw [leibniz_lie, neg_lie, neg_lie, ← lie_skew x]
      abel }

variable {R L}

/-- The definitions `LieDerivation.ad` and `LieAlgebra.ad` agree. -/
```

-- snippet 23
```lean
-- Mathlib.Algebra.Lie.Abelian.Function (L64-L72)
theorem Function.Injective.isLieAbelian {R : Type u} {L₁ : Type v} {L₂ : Type w} [CommRing R]
    [LieRing L₁] [LieRing L₂] [LieAlgebra R L₁] [LieAlgebra R L₂] {f : L₁ →ₗ⁅R⁆ L₂}
    (h₁ : Function.Injective f) (_ : IsLieAbelian L₂) : IsLieAbelian L₁ :=
{ trivial := fun x y => h₁ <|
      calc
        f ⁅x, y⁆ = ⁅f x, f y⁆ := LieHom.map_lie f x y
        _ = 0 := trivial_lie_zero _ _ _ _
        _ = f 0 := (map_zero _).symm }
```

-- snippet 24
```lean
-- Mathlib.Algebra.Lie.Abelian.isTrivial_iff_max_triv_eq_top (L199-L207)
theorem isTrivial_iff_max_triv_eq_top : IsTrivial L M ↔ maxTrivSubmodule R L M = ⊤ := by
constructor
  · rintro ⟨h⟩; ext; simp only [mem_maxTrivSubmodule, h, forall_const, LieSubmodule.mem_top]
  · intro h; constructor; intro x m; revert x
    rw [← mem_maxTrivSubmodule R L M, h]; exact LieSubmodule.mem_top m

variable {R L M N}

/-- `maxTrivSubmodule` is functorial. -/
```

-- snippet 25
```lean
-- Mathlib.Algebra.Lie.Basic.lie_self (L172-L174)
theorem lie_self : ⁅x, x⁆ = 0 :=
LieRing.lie_self x
```

-- snippet 26
```lean
-- Mathlib.Algebra.Lie.Abelian.commute_toEnd_of_mem_center_left (L322-L325)
lemma commute_toEnd_of_mem_center_left :
    Commute (toEnd R L M x) (toEnd R L M y) := by
rw [Commute.symm_iff, commute_iff_lie_eq, ← LieHom.map_lie, hx y, map_zero]
```

-- snippet 27
```lean
-- Mathlib.Algebra.Lie.Abelian.le_max_triv_iff_bracket_eq_bot (L185-L193)
theorem le_max_triv_iff_bracket_eq_bot {N : LieSubmodule R L M} :
    N ≤ maxTrivSubmodule R L M ↔ ⁅(⊤ : LieIdeal R L), N⁆ = ⊥ := by
refine ⟨fun h => ?_, fun h m hm => ?_⟩
  · rw [← le_bot_iff, ← ideal_oper_maxTrivSubmodule_eq_bot R L M ⊤]
    exact LieSubmodule.mono_lie_right ⊤ h
  · rw [mem_maxTrivSubmodule]
    rw [LieSubmodule.lie_eq_bot_iff] at h
    exact fun x => h x (LieSubmodule.mem_top x) m hm
```

-- snippet 28
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.mem_ad_idealRange_iff (L89-L92)
lemma mem_ad_idealRange_iff {D : LieDerivation R L L} :
    D ∈ (ad R L).idealRange ↔ ∃ x : L, ad R L x = D :=
(ad R L).mem_idealRange_iff (ad_isIdealMorphism R L)
```

-- snippet 29
```lean
-- Mathlib.Algebra.Lie.BaseChange.map (L128-L139)
def map {R A B L L' : Type*} [CommRing R] [CommRing A] [Algebra R A] [CommRing B] [Algebra R B]
    [LieRing L] [LieAlgebra R L] [LieRing L'] [LieAlgebra R L'] (f : A →ₐ[R] B) (g : L →ₗ⁅R⁆ L') :
    A ⊗[R] L →ₗ⁅R⁆ B ⊗[R] L' :=
{ TensorProduct.map f.toLinearMap g with
    map_lie' {x y} := by
      simp only [bracket_def, AddHom.toFun_eq_coe, LinearMap.coe_toAddHom]
      refine x.induction_on (by simp) ?_ ?_
      · intro _ _
        refine y.induction_on (by simp) (fun _ _ ↦ by simp) (fun _ _ h1 h2 ↦ by simp [h1, h2])
      · intro _ _
        refine y.induction_on (by simp) (fun _ _ h ↦ by simp [h]) (by simp_all) }
```

-- snippet 30
```lean
-- Mathlib.Algebra.Lie.Abelian.coe_maxTrivLinearMapEquivLieModuleHom (L259-L261)
theorem coe_maxTrivLinearMapEquivLieModuleHom (f : maxTrivSubmodule R L (M →ₗ[R] N)) :
    (maxTrivLinearMapEquivLieModuleHom (M := M) (N := N) f : M → N) = f := by ext; rfl
```

-- snippet 31
```lean
-- Mathlib.Algebra.Lie.Abelian.abelian_of_le_center (L299-L302)
theorem abelian_of_le_center (I : LieIdeal R L) (h : I ≤ center R L) : IsLieAbelian I :=
haveI : LieModule.IsTrivial L I := (LieModule.trivial_iff_le_maximal_trivial R L L I).mpr h
  LieIdeal.isLieAbelian_of_trivial R L I
```

-- snippet 32
```lean
-- Mathlib.Algebra.Lie.Abelian.commute_toEnd_of_mem_center_right (L326-L341)
lemma commute_toEnd_of_mem_center_right :
    Commute (toEnd R L M y) (toEnd R L M x) :=
(LieModule.commute_toEnd_of_mem_center_left M hx y).symm

end LieModule

end Center

section IdealOperations

open LieSubmodule LieSubalgebra

variable {R : Type u} {L : Type v} {M : Type w}
variable [CommRing R] [LieRing L] [LieAlgebra R L] [AddCommGroup M] [Module R M]
variable [LieRingModule L M] (N N' : LieSubmodule R L M) (I J : LieIdeal R L)
```

-- snippet 33
```lean
-- Mathlib.Algebra.Lie.Abelian.self_module_ker_eq_center (L295-L298)
theorem self_module_ker_eq_center : LieModule.ker R L L = center R L := by
ext y
  simp only [LieModule.mem_maxTrivSubmodule, LieModule.mem_ker, ← lie_skew _ y, neg_eq_zero]
```

-- snippet 34
```lean
-- Mathlib.Algebra.Lie.Abelian.center_eq_bot (L310-L321)
theorem center_eq_bot [LieModule.IsFaithful R L L] :
    center R L = ⊥ :=
(isFaithful_self_iff R L).mp inferInstance

end LieAlgebra

namespace LieModule

variable {R L}
variable {x : L} (hx : x ∈ LieAlgebra.center R L) (y : L)
include hx
```

-- snippet 35
```lean
-- Mathlib.Algebra.Lie.BaseChange.instLieRing (L106-L111)
instance instLieRing : LieRing (A ⊗[R] L) where
  add_lie x y z := by simp only [bracket_def, LinearMap.add_apply, map_add]
lie_add x y z := by simp only [bracket_def, map_add]
  lie_self := bracket_lie_self R A L
  leibniz_lie := bracket_leibniz_lie R A L L
```

-- snippet 36
```lean
-- Mathlib.Algebra.Lie.BaseChange.lieAlgebra (L161-L174)
instance lieAlgebra [CommRing R] [Algebra R A] : LieAlgebra R (RestrictScalars R A L) where
  lie_smul t x y := (lie_smul (algebraMap R A t) (RestrictScalars.addEquiv R A L x)
(RestrictScalars.addEquiv R A L y) :)

end RestrictScalars

end LieAlgebra

section ExtendScalars

variable [CommRing R] [LieRing L] [LieAlgebra R L]
  [AddCommGroup M] [Module R M] [LieRingModule L M] [LieModule R L M]
  [CommRing A] [Algebra R A]
```

-- snippet 37
```lean
-- Mathlib.Algebra.Lie.BaseChange.mem_baseChange_iff (L219-L223)
lemma mem_baseChange_iff {m : A ⊗[R] M} :
    m ∈ N.baseChange A ↔
    m ∈ Submodule.span A ((N : Submodule R M).map (TensorProduct.mk R A M 1)) := by
rw [← Submodule.baseChange_eq_span]; rfl
```

-- snippet 38
```lean
-- Mathlib.Algebra.Lie.Basic.smul_lie (L153-L155)
theorem smul_lie : ⁅t • x, m⁆ = t • ⁅x, m⁆ :=
LieModule.smul_lie t x m
```

-- snippet 39
```lean
-- Mathlib.Algebra.Lie.Abelian.lie_abelian_iff_equiv_lie_abelian (L81-L85)
theorem lie_abelian_iff_equiv_lie_abelian {R : Type u} {L₁ : Type v} {L₂ : Type w} [CommRing R]
    [LieRing L₁] [LieRing L₂] [LieAlgebra R L₁] [LieAlgebra R L₂] (e : L₁ ≃ₗ⁅R⁆ L₂) :
    IsLieAbelian L₁ ↔ IsLieAbelian L₂ :=
⟨e.symm.injective.isLieAbelian, e.injective.isLieAbelian⟩
```

-- snippet 40
```lean
-- Mathlib.Algebra.Lie.Abelian.IsLieAbelian (L57-L59)
abbrev IsLieAbelian (L : Type v) [Bracket L L] [Zero L] : Prop :=
LieModule.IsTrivial L L
```

-- snippet 41
```lean
-- Mathlib.Algebra.Lie.BaseChange.map_apply_tmul (L141-L154)
lemma map_apply_tmul {R A B L L' : Type*} [CommRing R] [CommRing A] [Algebra R A] [CommRing B]
    [Algebra R B] [LieRing L] [LieAlgebra R L] [LieRing L'] [LieAlgebra R L'] {f : A →ₐ[R] B}
    {g : L →ₗ⁅R⁆ L'} (a : A) (x : L) :
    map f g (a ⊗ₜ x) = (f a) ⊗ₜ (g x) :=
rfl

end ExtendScalars

namespace RestrictScalars

open RestrictScalars

variable [h : LieRing L]
```

-- snippet 42
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Basic.LieSubalgebra (L45-L51)
theorem LieSubalgebra.isNilpotent_ad_of_isNilpotent_ad {L : Type*} [LieRing L] [LieAlgebra R L]
    (K : LieSubalgebra R L) {x : K} (h : IsNilpotent (LieAlgebra.ad R L ↑x)) :
    IsNilpotent (LieAlgebra.ad R K x) := by
obtain ⟨n, hn⟩ := h
  use n
  exact Module.End.submodule_pow_eq_zero_of_pow_eq_zero (K.ad_comp_incl_eq x) hn
```

-- snippet 43
```lean
-- Mathlib.Algebra.Lie.Abelian.lie_eq_self_of_isAtom_of_ne_bot (L359-L362)
lemma lie_eq_self_of_isAtom_of_ne_bot (hN : IsAtom N) (h : ⁅I, N⁆ ≠ ⊥) : ⁅I, N⁆ = N :=
(hN.le_iff_eq h).mp <| LieSubmodule.lie_le_right N I

-- TODO: introduce typeclass for perfect Lie algebras and use it here in the conclusion
```

-- snippet 44
```lean
-- Mathlib.Algebra.Lie.Abelian.commutative_ring_iff_abelian_lie_ring (L86-L92)
theorem commutative_ring_iff_abelian_lie_ring {A : Type v} [Ring A] :
    Std.Commutative (α := A) (· * ·) ↔ IsLieAbelian A := by
have h₁ : Std.Commutative (α := A) (· * ·) ↔ ∀ a b : A, a * b = b * a :=
    ⟨fun h => h.1, fun h => ⟨h⟩⟩
  have h₂ : IsLieAbelian A ↔ ∀ a b : A, ⁅a, b⁆ = 0 := ⟨fun h => h.1, fun h => ⟨h⟩⟩
  simp only [h₁, h₂, LieRing.of_associative_ring_bracket, sub_eq_zero]
```

-- snippet 45
```lean
-- Mathlib.Algebra.Lie.Abelian.isFaithful_self_iff (L306-L308)
theorem isFaithful_self_iff : LieModule.IsFaithful R L L ↔ center R L = ⊥ := by
rw [LieModule.isFaithful_iff_ker_eq_bot, self_module_ker_eq_center]
```

-- snippet 46
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.ad_ker_eq_center (L66-L71)
lemma ad_ker_eq_center : (ad R L).ker = LieAlgebra.center R L := by
ext x
  rw [← LieAlgebra.self_module_ker_eq_center, LieHom.mem_ker, LieModule.mem_ker]
  simp [DFunLike.ext_iff]

/-- If the center of a Lie algebra is trivial, then the adjoint action is injective. -/
```

-- snippet 47
```lean
-- Mathlib.Algebra.Lie.BaseChange.tmul_mem_baseChange_of_mem (L215-L218)
lemma tmul_mem_baseChange_of_mem (a : A) {m : M} (hm : m ∈ N) :
    a ⊗ₜ[R] m ∈ N.baseChange A :=
(N : Submodule R M).tmul_mem_baseChange_of_mem a hm
```

-- snippet 48
```lean
-- Mathlib.Algebra.Lie.Abelian.maxTrivSubmodule (L164-L170)
def maxTrivSubmodule : LieSubmodule R L M where
  carrier := { m | ∀ x : L, ⁅x, m⁆ = 0 }
zero_mem' x := lie_zero x
  add_mem' {x y} hx hy z := by rw [lie_add, hx, hy, add_zero]
  smul_mem' c x hx y := by rw [lie_smul, hx, smul_zero]
  lie_mem {x m} hm y := by rw [hm, lie_zero]
```

-- snippet 49
```lean
-- Mathlib.Algebra.Lie.Abelian.ideal_oper_maxTrivSubmodule_eq_bot (L178-L184)
theorem ideal_oper_maxTrivSubmodule_eq_bot (I : LieIdeal R L) :
    ⁅I, maxTrivSubmodule R L M⁆ = ⊥ := by
rw [← LieSubmodule.toSubmodule_inj, LieSubmodule.lieIdeal_oper_eq_linear_span,
    LieSubmodule.bot_toSubmodule, Submodule.span_eq_bot]
  rintro m ⟨⟨x, hx⟩, ⟨⟨m, hm⟩, rfl⟩⟩
  exact hm x
```

-- snippet 50
```lean
-- Mathlib.Algebra.Lie.BaseChange.bracket_tmul (L61-L105)
theorem bracket_tmul (s t : A) (x : L) (y : M) : ⁅s ⊗ₜ[R] x, t ⊗ₜ[R] y⁆ = (s * t) ⊗ₜ ⁅x, y⁆ := rfl
set_option backward.privateInPublic true in
private theorem bracket_lie_self (x : A ⊗[R] L) : ⁅x, x⁆ = 0 := by
  simp only [bracket_def]
  refine x.induction_on ?_ ?_ ?_
  · simp only [map_zero]
  · intro a l
    simp only [bracket'_tmul, TensorProduct.tmul_zero, lie_self]
  · intro z₁ z₂ h₁ h₂
    suffices bracket' R A L L z₁ z₂ + bracket' R A L L z₂ z₁ = 0 by
      rw [map_add, map_add, LinearMap.add_apply, LinearMap.add_apply, h₁, h₂,
        zero_add, add_zero, add_comm, this]
    refine z₁.induction_on ?_ ?_ ?_
    · simp only [map_zero, add_zero, LinearMap.zero_apply]
    · intro a₁ l₁; refine z₂.induction_on ?_ ?_ ?_
      · simp only [map_zero, add_zero, LinearMap.zero_apply]
      · intro a₂ l₂
        simp only [← lie_skew l₂ l₁, mul_comm a₁ a₂, TensorProduct.tmul_neg, bracket'_tmul,
          add_neg_cancel]
      · intro y₁ y₂ hy₁ hy₂
        simp only [hy₁, hy₂, add_add_add_comm, add_zero, LinearMap.add_apply, map_add]
    · intro y₁ y₂ hy₁ hy₂
      simp only [add_add_add_comm, hy₁, hy₂, add_zero, LinearMap.add_apply, map_add]

set_option backward.privateInPublic true in
private theorem bracket_leibniz_lie (x y : A ⊗[R] L) (z : A ⊗[R] M) :
    ⁅x, ⁅y, z⁆⁆ = ⁅⁅x, y⁆, z⁆ + ⁅y, ⁅x, z⁆⁆ := by
  simp only [bracket_def]
  refine x.induction_on ?_ ?_ ?_
  · simp only [map_zero, add_zero, LinearMap.zero_apply]
  · intro a₁ l₁
    refine y.induction_on ?_ ?_ ?_
    · simp only [map_zero, add_zero, LinearMap.zero_apply]
    · intro a₂ l₂
      refine z.induction_on ?_ ?_ ?_
      · simp only [map_zero, add_zero]
      · intro a₃ l₃; simp only [bracket'_tmul]
        rw [mul_left_comm a₂ a₁ a₃, mul_assoc, leibniz_lie, TensorProduct.tmul_add]
      · grind
    · grind [LinearMap.add_apply]
  · grind [LinearMap.add_apply]

set_option backward.privateInPublic true in
set_option backward.privateInPublic.warn false in
```

-- snippet 51
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.lie_der_ad_eq_ad_der (L77-L82)
lemma lie_der_ad_eq_ad_der (D : LieDerivation R L L) (x : L) : ⁅D, ad R L x⁆ = ad R L (D x) := by
rw [ad_apply_lieDerivation, ← lie_ad, lie_skew]

variable (R L) in
/-- The range of the adjoint action homomorphism from a Lie algebra `L` to the Lie algebra of its
derivations is an ideal of the latter. -/
```

-- snippet 52
```lean
-- Mathlib.Algebra.Lie.Abelian.isLieAbelian_iff_center_eq_top (L303-L305)
theorem isLieAbelian_iff_center_eq_top : IsLieAbelian L ↔ center R L = ⊤ :=
LieModule.isTrivial_iff_max_triv_eq_top R L L
```

-- snippet 53
```lean
-- Mathlib.Algebra.Lie.Basic.lie_zero (L164-L166)
theorem lie_zero : ⁅x, 0⁆ = (0 : M) :=
(AddMonoidHom.mk' _ (lie_add x)).map_zero
```

-- snippet 54
```lean
-- Mathlib.Algebra.Lie.Abelian.maxTrivEquiv_of_equiv_symm_eq_symm (L240-L245)
theorem maxTrivEquiv_of_equiv_symm_eq_symm (e : M ≃ₗ⁅R,L⁆ N) :
    (maxTrivEquiv e).symm = maxTrivEquiv e.symm :=
rfl

/-- A linear map between two Lie modules is a morphism of Lie modules iff the Lie algebra action
on it is trivial. -/
```

-- snippet 55
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.ad_isIdealMorphism (L83-L88)
lemma ad_isIdealMorphism : (ad R L).IsIdealMorphism := by
simp_rw [LieHom.isIdealMorphism_iff, lie_der_ad_eq_ad_der]
  tauto

/-- A derivation `D` belongs to the ideal range of the adjoint action iff it is of the form `ad x`
for some `x` in the Lie algebra `L`. -/
```

-- snippet 56
```lean
-- Mathlib.Algebra.Lie.Basic.lieAlgebraSelfModule (L184-L187)
instance lieAlgebraSelfModule : LieModule R L L where
  smul_lie t x m := by rw [← lie_skew, ← lie_skew x m, LieAlgebra.lie_smul, smul_neg]
lie_smul := by apply LieAlgebra.lie_smul
```

-- snippet 57
```lean
-- Mathlib.Algebra.Lie.Abelian.LieIdeal (L60-L63)
instance LieIdeal.isLieAbelian_of_trivial (R : Type u) (L : Type v) [CommRing R] [LieRing L]
    [LieAlgebra R L] (I : LieIdeal R L) [h : LieModule.IsTrivial L I] : IsLieAbelian I where
  trivial x y := by apply h.trivial
```

-- snippet 58
```lean
-- Mathlib.Algebra.Lie.Abelian.lie_eq_self_of_isAtom_of_nonabelian (L363-L373)
lemma lie_eq_self_of_isAtom_of_nonabelian {R L : Type*} [CommRing R] [LieRing L] [LieAlgebra R L]
    (I : LieIdeal R L) (hI : IsAtom I) (h : ¬IsLieAbelian I) :
    ⁅I, I⁆ = I :=
lie_eq_self_of_isAtom_of_ne_bot hI <| not_imp_not.mpr (lie_abelian_iff_lie_self_eq_bot I).mpr h

end IdealOperations

section TrivialLieModule

set_option linter.unusedVariables false in
/-- A type synonym for an `R`-module to have a trivial Lie module structure. -/
```

-- snippet 59
```lean
-- Mathlib.Algebra.Lie.Abelian.LieSubmodule (L343-L347)
theorem LieSubmodule.trivial_lie_oper_zero [LieModule.IsTrivial L M] : ⁅I, N⁆ = ⊥ := by
suffices ⁅I, N⁆ ≤ ⊥ from le_bot_iff.mp this
  rw [lieIdeal_oper_eq_span, LieSubmodule.lieSpan_le]
  rintro m ⟨x, n, h⟩; rw [trivial_lie_zero] at h; simp [← h]
```

-- snippet 60
```lean
-- Mathlib.Algebra.Lie.Abelian.coe_maxTrivEquiv_apply (L230-L233)
theorem coe_maxTrivEquiv_apply (e : M ≃ₗ⁅R,L⁆ N) (m : maxTrivSubmodule R L M) :
    (maxTrivEquiv e m : N) = e ↑m :=
rfl
```

-- snippet 61
```lean
-- Mathlib.Algebra.Lie.Abelian.maxTrivLinearMapEquivLieModuleHom (L246-L257)
def maxTrivLinearMapEquivLieModuleHom : maxTrivSubmodule R L (M →ₗ[R] N) ≃ₗ[R] M →ₗ⁅R,L⁆ N where
  toFun f :=
{ toLinearMap := f.val
      map_lie' := fun {x m} => by
        have hf : ⁅x, f.val⁆ m = 0 := by rw [f.property x, LinearMap.zero_apply]
        rw [LieHom.lie_apply, sub_eq_zero, ← LinearMap.toFun_eq_coe] at hf; exact hf.symm }
  map_add' f g := by ext; simp
  map_smul' F G := by ext; simp
  invFun F := ⟨F, fun x => by ext; simp⟩
  left_inv f := by simp
  right_inv F := by simp
```

-- snippet 62
```lean
-- Mathlib.Algebra.Lie.Abelian.coe_maxTrivHom_apply (L217-L221)
theorem coe_maxTrivHom_apply (f : M →ₗ⁅R,L⁆ N) (m : maxTrivSubmodule R L M) :
    (maxTrivHom f m : N) = f m :=
rfl

/-- The maximal trivial submodules of Lie-equivalent Lie modules are Lie-equivalent. -/
```

-- snippet 63
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.injective_ad_of_center_eq_bot (L72-L76)
lemma injective_ad_of_center_eq_bot (h : LieAlgebra.center R L = ⊥) :
    Function.Injective (ad R L) := by
rw [← LieHom.ker_eq_bot, ad_ker_eq_center, h]

/-- The commutator of a derivation `D` and a derivation of the form `ad x` is `ad (D x)`. -/
```

-- snippet 64
```lean
-- Mathlib.Algebra.Lie.Abelian.isFaithful_iff_ker_eq_bot (L155-L158)
lemma isFaithful_iff_ker_eq_bot : IsFaithful R L M ↔ LieModule.ker R L M = ⊥ := by
rw [isFaithful_iff', LieSubmodule.ext_iff]
  aesop
```

-- snippet 65
```lean
-- Mathlib.Algebra.Lie.BaseChange.coe_baseChange (L208-L214)
lemma coe_baseChange :
    (N.baseChange A : Submodule A (A ⊗[R] M)) = (N : Submodule R M).baseChange A :=
rfl

variable {N}

variable {R A L M} in
```

-- snippet 66
```lean
-- Mathlib.Algebra.Lie.Abelian.maxTrivHom (L208-L215)
def maxTrivHom (f : M →ₗ⁅R,L⁆ N) : maxTrivSubmodule R L M →ₗ⁅R,L⁆ maxTrivSubmodule R L N where
  toFun m := ⟨f m, fun x =>
(LieModuleHom.map_lie _ _ _).symm.trans <|
      (congr_arg f (m.property x)).trans (map_zero _)⟩
  map_add' m n := by ext; simp
  map_smul' t m := by ext; simp
  map_lie' {x m} := by simp
```

-- snippet 67
```lean
-- Mathlib.Algebra.Lie.AdjointAction.Derivation.lie_ad (L62-L65)
lemma lie_ad (x : L) (D : LieDerivation R L L) : ⁅ad R L x, D⁆ = ⁅x, D⁆ := by ext; simp
variable (R L) in
/-- The kernel of the adjoint action on a Lie algebra is equal to its center. -/
```

-- snippet 68
```lean
-- Mathlib.Algebra.Lie.Abelian.ad_ker_eq_self_module_ker (L291-L293)
theorem ad_ker_eq_self_module_ker : (ad R L).ker = LieModule.ker R L L :=
rfl
```

-- snippet 69
```lean
-- Mathlib.Algebra.Lie.BaseChange.baseChange_top (L230-L233)
lemma baseChange_top : (⊤ : LieSubmodule R L M).baseChange A = ⊤ := by
simp only [baseChange, top_toSubmodule, Submodule.baseChange_top]
  rfl
```

-- snippet 70
```lean
-- Mathlib.Algebra.Lie.Basic.lie_add (L149-L151)
theorem lie_add : ⁅x, m + n⁆ = ⁅x, m⁆ + ⁅x, n⁆ :=
LieRingModule.lie_add x m n
```

-- snippet 71
```lean
-- Mathlib.Algebra.Lie.Abelian.toLinearMap_maxTrivLinearMapEquivLieModuleHom (L268-L271)
theorem toLinearMap_maxTrivLinearMapEquivLieModuleHom (f : maxTrivSubmodule R L (M →ₗ[R] N)) :
    (maxTrivLinearMapEquivLieModuleHom (M := M) (N := N) f : M →ₗ[R] N) = (f : M →ₗ[R] N) := by
ext; rfl
```

-- snippet 72
```lean
-- Mathlib.Algebra.Lie.Basic.lie_skew (L179-L183)
theorem lie_skew : -⁅y, x⁆ = ⁅x, y⁆ := by
have h : ⁅x + y, x⁆ + ⁅x + y, y⁆ = 0 := by rw [← lie_add]; apply lie_self
  simpa [neg_eq_iff_add_eq_zero] using h

/-- Every Lie algebra is a module over itself. -/
```

-- snippet 73
```lean
-- Mathlib.Algebra.Lie.BaseChange.baseChange (L191-L206)
def baseChange : LieSubmodule A (A ⊗[R] L) (A ⊗[R] M) :=
{ (N : Submodule R M).baseChange A with
    lie_mem := by
      intro x m hm
      rw [Submodule.mem_carrier, SetLike.mem_coe] at hm ⊢
      rw [Submodule.baseChange_eq_span] at hm
      obtain ⟨c, rfl⟩ := (Finsupp.mem_span_iff_linearCombination _ _ _).mp hm
      refine x.induction_on (by simp) (fun a y ↦ ?_) (fun y z hy hz ↦ ?_)
      · change toEnd A (A ⊗[R] L) (A ⊗[R] M) _ _ ∈ _
        simp_rw [Finsupp.linearCombination_apply, Finsupp.sum, map_sum, map_smul, toEnd_apply_apply]
        refine Submodule.sum_mem _ fun ⟨_, n, hn, h⟩ _ ↦ Submodule.smul_mem _ _ ?_
        rw [Subtype.coe_mk, ← h]
        exact Submodule.tmul_mem_baseChange_of_mem _ (N.lie_mem hn)
      · rw [add_lie]
        exact ((N : Submodule R M).baseChange A).add_mem hy hz }
```

-- snippet 74
```lean
-- Mathlib.Algebra.Lie.Abelian.trivial_lie_zero (L44-L47)
theorem trivial_lie_zero (L : Type v) (M : Type w) [Bracket L M] [Zero M] [LieModule.IsTrivial L M]
    (x : L) (m : M) : ⁅x, m⁆ = 0 :=
LieModule.IsTrivial.trivial x m
```

-- snippet 75
```lean
-- Mathlib.Algebra.Lie.BaseChange.instBaseLieAlgebra (L112-L113)
instance instBaseLieAlgebra : LieAlgebra R (A ⊗[R] L) where lie_smul := by simp [bracket_def]
```

-- snippet 76
```lean
-- Mathlib.Algebra.Lie.Abelian.coe_maxTrivLinearMapEquivLieModuleHom_symm (L263-L266)
theorem coe_maxTrivLinearMapEquivLieModuleHom_symm (f : M →ₗ⁅R,L⁆ N) :
    (maxTrivLinearMapEquivLieModuleHom (M := M) (N := N) |>.symm f : M → N) = f :=
rfl
```

-- snippet 77
```lean
-- Mathlib.Algebra.Lie.BaseChange.baseChange_bot (L225-L228)
lemma baseChange_bot : (⊥ : LieSubmodule R L M).baseChange A = ⊥ := by
simp only [baseChange, bot_toSubmodule, Submodule.baseChange_bot]
  rfl
```

-- snippet 78
```lean
-- Mathlib.Algebra.Lie.Basic.lieRingSelfModule (L175-L177)
instance lieRingSelfModule : LieRingModule L L :=
{ (inferInstance : LieRing L) with }
```

-- snippet 79
```lean
-- Mathlib.Algebra.Lie.Abelian.maxTrivEquiv_of_refl_eq_refl (L235-L238)
theorem maxTrivEquiv_of_refl_eq_refl :
    maxTrivEquiv (LieModuleEquiv.refl : M ≃ₗ⁅R,L⁆ M) = LieModuleEquiv.refl := by
ext; simp only [coe_maxTrivEquiv_apply, LieModuleEquiv.refl_apply]
```

-- snippet 80
```lean
-- Mathlib.Algebra.Lie.Abelian.maxTrivEquiv (L222-L228)
def maxTrivEquiv (e : M ≃ₗ⁅R,L⁆ N) : maxTrivSubmodule R L M ≃ₗ⁅R,L⁆ maxTrivSubmodule R L N :=
{ maxTrivHom (e : M →ₗ⁅R,L⁆ N) with
    toFun := maxTrivHom (e : M →ₗ⁅R,L⁆ N)
    invFun := maxTrivHom (e.symm : N →ₗ⁅R,L⁆ M)
    left_inv := fun m => by ext; simp
    right_inv := fun n => by ext; simp }
```

-- snippet 81
```lean
-- Mathlib.Algebra.Lie.BaseChange.LieModule (L176-L190)
lemma LieModule.toEnd_baseChange (x : L) :
    toEnd A (A ⊗[R] L) (A ⊗[R] M) (1 ⊗ₜ x) = (toEnd R L M x).baseChange A := by
ext; simp

namespace LieSubmodule

variable (N : LieSubmodule R L M)

open LieModule

variable {R L M} in
/-- If `A` is an `R`-algebra, any Lie submodule of a Lie module `M` with coefficients in `R` may be
pushed forward to a Lie submodule of `A ⊗ M` with coefficients in `A`.

This "base change" operation is also known as "extension of scalars". -/
```

-- snippet 82
```lean
-- Mathlib.Algebra.Lie.Abelian.LieModule (L48-L51)
instance LieModule.instIsTrivialOfSubsingleton {L M : Type*}
    [LieRing L] [AddCommGroup M] [LieRingModule L M] [Subsingleton L] : LieModule.IsTrivial L M :=
⟨fun x m ↦ by rw [Subsingleton.eq_zero x, zero_lie]⟩
```

-- snippet 83
```lean
-- Mathlib.Algebra.Lie.Abelian.center (L284-L286)
abbrev center : LieIdeal R L :=
LieModule.maxTrivSubmodule R L L
```
[/INST]


[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.Probability.Independence.InfinitePi).

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

```lean
lemma iIndepFun_infinitePi {Ω : ι → Type*} {mΩ : ∀ i, MeasurableSpace (Ω i)}
    {P : (i : ι) → Measure (Ω i)} [∀ i, IsProbabilityMeasure (P i)] {X : (i : ι) → Ω i → 𝓧 i}
    (mX : ∀ i, Measurable (X i)) :
    iIndepFun (fun i ω ↦ X i (ω i)) (infinitePi P)
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Probability.Independence.InfinitePi.iIndepFun_iff_map_fun_eq_infinitePi_map₀ (L41-L71)
lemma iIndepFun_iff_map_fun_eq_infinitePi_map₀ (mX : AEMeasurable (fun ω i ↦ X i ω) P) :
    iIndepFun X P ↔ P.map (fun ω i ↦ X i ω) = infinitePi (fun i ↦ P.map (X i)) where
  mp h
```

-- snippet 2
```lean
-- Mathlib.Probability.Independence.InfinitePi.iIndepFun_iff_map_fun_eq_infinitePi_map₀' (L72-L76)
lemma iIndepFun_iff_map_fun_eq_infinitePi_map₀' [Countable ι] (mX : ∀ i, AEMeasurable (X i) P) :
    iIndepFun X P ↔ P.map (fun ω i ↦ X i ω) = infinitePi (fun i ↦ P.map (X i))
```

-- snippet 3
```lean
-- Mathlib.Probability.Independence.InfinitePi.iIndepFun_iff_map_fun_eq_infinitePi_map (L77-L82)
lemma iIndepFun_iff_map_fun_eq_infinitePi_map (mX : ∀ i, Measurable (X i)) :
    iIndepFun X P ↔ P.map (fun ω i ↦ X i ω) = infinitePi (fun i ↦ P.map (X i))
```

-- snippet 4
```lean
-- Mathlib.Probability.Independence.InfinitePi.iIndepFun_uncurry (L105-L124)
lemma iIndepFun_uncurry {X : (i : ι) → (j : κ i) → Ω → 𝓧 i j} (mX : ∀ i j, Measurable (X i j))
    (h1 : iIndepFun (fun i ω ↦ (X i · ω)) P) (h2 : ∀ i, iIndepFun (X i) P) :
    iIndepFun (fun (p : (i : ι) × (κ i)) ω ↦ X p.1 p.2 ω) P
```

-- snippet 5
```lean
-- Mathlib.Probability.Independence.InfinitePi.iIndepFun_uncurry_infinitePi (L125-L165)
lemma iIndepFun_uncurry_infinitePi {Ω : (i : ι) → κ i → Type*} {mΩ : ∀ i j, MeasurableSpace (Ω i j)}
    {X : (i : ι) → (j : κ i) → Ω i j → 𝓧 i j}
    (μ : (i : ι) → (j : κ i) → Measure (Ω i j)) [∀ i j, IsProbabilityMeasure (μ i j)]
    (mX : ∀ i j, Measurable (X i j)) :
    iIndepFun (fun (p : (i : ι) × κ i) (ω : Π i, Π j, Ω i j) ↦ X p.1 p.2 (ω p.1 p.2))
      (infinitePi (fun i ↦ infinitePi (μ i)))
```

-- snippet 6
```lean
-- Mathlib.Probability.Independence.InfinitePi.iIndepFun_uncurry' (L166-L172)
lemma iIndepFun_uncurry' {X : (i : ι) → (j : κ) → Ω → 𝓧 i j} (mX : ∀ i j, Measurable (X i j))
    (h1 : iIndepFun (fun i ω ↦ (X i · ω)) P) (h2 : ∀ i, iIndepFun (X i) P) :
    iIndepFun (fun (p : ι × κ) ω ↦ X p.1 p.2 ω) P
```

-- snippet 7
```lean
-- Mathlib.Probability.Independence.InfinitePi.iIndepFun_uncurry_infinitePi' (L173-L185)
lemma iIndepFun_uncurry_infinitePi' {Ω : ι → κ → Type*} {mΩ : ∀ i j, MeasurableSpace (Ω i j)}
    {X : (i : ι) → (j : κ) → Ω i j → 𝓧 i j}
    (μ : (i : ι) → (j : κ) → Measure (Ω i j)) [∀ i j, IsProbabilityMeasure (μ i j)]
    (mX : ∀ i j, Measurable (X i j)) :
    iIndepFun (fun (p : ι × κ) (ω : Π i, Π j, Ω i j) ↦ X p.1 p.2 (ω p.1 p.2))
      (infinitePi (fun i ↦ infinitePi (μ i)))
```

-- snippet 8
```lean
-- Mathlib.Probability.Independence.Basic.IndepSet (L129-L135)
def IndepSet {_mΩ : MeasurableSpace Ω} (s t : Set Ω) (μ : Measure Ω
```

-- snippet 9
```lean
-- Mathlib.Probability.Independence.Basic.iIndepSets (L96-L101)
def iIndepSets {_mΩ : MeasurableSpace Ω}
    (π : ι → Set (Set Ω)) (μ : Measure Ω
```

-- snippet 10
```lean
-- Mathlib.Probability.Independence.Basic.Indep (L118-L123)
def Indep (m₁ m₂ : MeasurableSpace Ω)
    {_mΩ : MeasurableSpace Ω} (μ : Measure Ω
```

-- snippet 11
```lean
-- Mathlib.Probability.Independence.Basic.iIndepSet (L124-L128)
def iIndepSet {_mΩ : MeasurableSpace Ω} (s : ι → Set Ω) (μ : Measure Ω
```

-- snippet 12
```lean
-- Mathlib.Probability.Independence.Basic.iIndep (L111-L117)
def iIndep (m : ι → MeasurableSpace Ω) {_mΩ : MeasurableSpace Ω} (μ : Measure Ω
```

-- snippet 13
```lean
-- Mathlib.Probability.Independence.Basic.IndepSets (L102-L107)
def IndepSets {_mΩ : MeasurableSpace Ω}
    (s1 s2 : Set (Set Ω)) (μ : Measure Ω
```

<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.Probability.Independence.InfinitePi).[/SYSTEM_PROMPT][MODEL_SETTINGS]{"reasoning_effort": "none"}[/MODEL_SETTINGS][INST]Prove the following theorem. The retrieved context below may help.

```lean
lemma iIndepFun_infinitePi {Ω : ι → Type*} {mΩ : ∀ i, MeasurableSpace (Ω i)}
    {P : (i : ι) → Measure (Ω i)} [∀ i, IsProbabilityMeasure (P i)] {X : (i : ι) → Ω i → 𝓧 i}
    (mX : ∀ i, Measurable (X i)) :
    iIndepFun (fun i ω ↦ X i (ω i)) (infinitePi P)
```

## Retrieved context
-- snippet 1
```lean
-- Mathlib.Probability.Independence.InfinitePi.iIndepFun_iff_map_fun_eq_infinitePi_map₀ (L41-L71)
lemma iIndepFun_iff_map_fun_eq_infinitePi_map₀ (mX : AEMeasurable (fun ω i ↦ X i ω) P) :
    iIndepFun X P ↔ P.map (fun ω i ↦ X i ω) = infinitePi (fun i ↦ P.map (X i)) where
  mp h
```

-- snippet 2
```lean
-- Mathlib.Probability.Independence.InfinitePi.iIndepFun_iff_map_fun_eq_infinitePi_map₀' (L72-L76)
lemma iIndepFun_iff_map_fun_eq_infinitePi_map₀' [Countable ι] (mX : ∀ i, AEMeasurable (X i) P) :
    iIndepFun X P ↔ P.map (fun ω i ↦ X i ω) = infinitePi (fun i ↦ P.map (X i))
```

-- snippet 3
```lean
-- Mathlib.Probability.Independence.InfinitePi.iIndepFun_iff_map_fun_eq_infinitePi_map (L77-L82)
lemma iIndepFun_iff_map_fun_eq_infinitePi_map (mX : ∀ i, Measurable (X i)) :
    iIndepFun X P ↔ P.map (fun ω i ↦ X i ω) = infinitePi (fun i ↦ P.map (X i))
```

-- snippet 4
```lean
-- Mathlib.Probability.Independence.InfinitePi.iIndepFun_uncurry (L105-L124)
lemma iIndepFun_uncurry {X : (i : ι) → (j : κ i) → Ω → 𝓧 i j} (mX : ∀ i j, Measurable (X i j))
    (h1 : iIndepFun (fun i ω ↦ (X i · ω)) P) (h2 : ∀ i, iIndepFun (X i) P) :
    iIndepFun (fun (p : (i : ι) × (κ i)) ω ↦ X p.1 p.2 ω) P
```

-- snippet 5
```lean
-- Mathlib.Probability.Independence.InfinitePi.iIndepFun_uncurry_infinitePi (L125-L165)
lemma iIndepFun_uncurry_infinitePi {Ω : (i : ι) → κ i → Type*} {mΩ : ∀ i j, MeasurableSpace (Ω i j)}
    {X : (i : ι) → (j : κ i) → Ω i j → 𝓧 i j}
    (μ : (i : ι) → (j : κ i) → Measure (Ω i j)) [∀ i j, IsProbabilityMeasure (μ i j)]
    (mX : ∀ i j, Measurable (X i j)) :
    iIndepFun (fun (p : (i : ι) × κ i) (ω : Π i, Π j, Ω i j) ↦ X p.1 p.2 (ω p.1 p.2))
      (infinitePi (fun i ↦ infinitePi (μ i)))
```

-- snippet 6
```lean
-- Mathlib.Probability.Independence.InfinitePi.iIndepFun_uncurry' (L166-L172)
lemma iIndepFun_uncurry' {X : (i : ι) → (j : κ) → Ω → 𝓧 i j} (mX : ∀ i j, Measurable (X i j))
    (h1 : iIndepFun (fun i ω ↦ (X i · ω)) P) (h2 : ∀ i, iIndepFun (X i) P) :
    iIndepFun (fun (p : ι × κ) ω ↦ X p.1 p.2 ω) P
```

-- snippet 7
```lean
-- Mathlib.Probability.Independence.InfinitePi.iIndepFun_uncurry_infinitePi' (L173-L185)
lemma iIndepFun_uncurry_infinitePi' {Ω : ι → κ → Type*} {mΩ : ∀ i j, MeasurableSpace (Ω i j)}
    {X : (i : ι) → (j : κ) → Ω i j → 𝓧 i j}
    (μ : (i : ι) → (j : κ) → Measure (Ω i j)) [∀ i j, IsProbabilityMeasure (μ i j)]
    (mX : ∀ i j, Measurable (X i j)) :
    iIndepFun (fun (p : ι × κ) (ω : Π i, Π j, Ω i j) ↦ X p.1 p.2 (ω p.1 p.2))
      (infinitePi (fun i ↦ infinitePi (μ i)))
```

-- snippet 8
```lean
-- Mathlib.Probability.Independence.Basic.IndepSet (L129-L135)
def IndepSet {_mΩ : MeasurableSpace Ω} (s t : Set Ω) (μ : Measure Ω
```

-- snippet 9
```lean
-- Mathlib.Probability.Independence.Basic.iIndepSets (L96-L101)
def iIndepSets {_mΩ : MeasurableSpace Ω}
    (π : ι → Set (Set Ω)) (μ : Measure Ω
```

-- snippet 10
```lean
-- Mathlib.Probability.Independence.Basic.Indep (L118-L123)
def Indep (m₁ m₂ : MeasurableSpace Ω)
    {_mΩ : MeasurableSpace Ω} (μ : Measure Ω
```

-- snippet 11
```lean
-- Mathlib.Probability.Independence.Basic.iIndepSet (L124-L128)
def iIndepSet {_mΩ : MeasurableSpace Ω} (s : ι → Set Ω) (μ : Measure Ω
```

-- snippet 12
```lean
-- Mathlib.Probability.Independence.Basic.iIndep (L111-L117)
def iIndep (m : ι → MeasurableSpace Ω) {_mΩ : MeasurableSpace Ω} (μ : Measure Ω
```

-- snippet 13
```lean
-- Mathlib.Probability.Independence.Basic.IndepSets (L102-L107)
def IndepSets {_mΩ : MeasurableSpace Ω}
    (s1 s2 : Set (Set Ω)) (μ : Measure Ω
```
[/INST]