File: Mathlib/Algebra/Algebra/RestrictScalars.lean

full_name: RestrictScalars
code: /-- If we put an `R`-algebra structure on a semiring `S`, we get a natural equivalence from the
category of `S`-modules to the category of representations of the algebra `S` (over `R`). The type
synonym `RestrictScalars` is essentially this equivalence.

Warning: use this type synonym judiciously! Consider an example where we want to construct an
`R`-linear map from `M` to `S`, given:
```lean
variable (R S M : Type*)
variable [CommSemiring R] [Semiring S] [Algebra R S] [AddCommMonoid M] [Module S M]
```
With the assumptions above we can't directly state our map as we have no `Module R M` structure, but
`RestrictScalars` permits it to be written as:
```lean
-- an `R`-module structure on `M` is provided by `RestrictScalars` which is compatible
example : RestrictScalars R S M →ₗ[R] S := sorry
```
However, it is usually better just to add this extra structure as an argument:
```lean
-- an `R`-module structure on `M` and proof of its compatibility is provided by the user
example [Module R M] [IsScalarTower R S M] : M →ₗ[R] S := sorry
```
The advantage of the second approach is that it defers the duty of providing the missing typeclasses
`[Module R M] [IsScalarTower R S M]`. If some concrete `M` naturally carries these (as is often
the case) then we have avoided `RestrictScalars` entirely. If not, we can pass
`RestrictScalars R S M` later on instead of `M`.

Note that this means we almost always want to state definitions and lemmas in the language of
`IsScalarTower` rather than `RestrictScalars`.

An example of when one might want to use `RestrictScalars` would be if one has a vector space
over a field of characteristic zero and wishes to make use of the `ℚ`-algebra structure. -/
@[nolint unusedArguments]
def RestrictScalars (_R _S M : Type*) : Type _ 
goal: Type u_7

full_name: instInhabitedRestrictScalars
code: instance [I : Inhabited M] : Inhabited (RestrictScalars R S M) 
goal: Inhabited (RestrictScalars R S M)

full_name: instAddCommMonoidRestrictScalars
code: instance [I : AddCommMonoid M] : AddCommMonoid (RestrictScalars R S M) 
goal: AddCommMonoid (RestrictScalars R S M)

full_name: instAddCommGroupRestrictScalars
code: instance [I : AddCommGroup M] : AddCommGroup (RestrictScalars R S M) 
goal: AddCommGroup (RestrictScalars R S M)

full_name: RestrictScalars.moduleOrig
code: /-- We temporarily install an action of the original ring on `RestrictScalars R S M`. -/
def RestrictScalars.moduleOrig [I : Module S M] : Module S (RestrictScalars R S M) 
goal: Module S (RestrictScalars R S M)

full_name: RestrictScalars.module
code: /-- When `M` is a module over a ring `S`, and `S` is an algebra over `R`, then `M` inherits a
module structure over `R`.

The preferred way of setting this up is `[Module R M] [Module S M] [IsScalarTower R S M]`.
-/
instance RestrictScalars.module [Module S M] : Module R (RestrictScalars R S M) 
goal: Module R (RestrictScalars R S M)

full_name: RestrictScalars.isScalarTower
code: /-- This instance is only relevant when `RestrictScalars.moduleOrig` is available as an instance.
-/
instance RestrictScalars.isScalarTower [Module S M] : IsScalarTower R S (RestrictScalars R S M) 
goal: IsScalarTower R S (RestrictScalars R S M)

full_name: RestrictScalars.opModule
code: /-- When `M` is a right-module over a ring `S`, and `S` is an algebra over `R`, then `M` inherits a
right-module structure over `R`.
The preferred way of setting this up is
`[Module Rᵐᵒᵖ M] [Module Sᵐᵒᵖ M] [IsScalarTower Rᵐᵒᵖ Sᵐᵒᵖ M]`.
-/
instance RestrictScalars.opModule [Module Sᵐᵒᵖ M] : Module Rᵐᵒᵖ (RestrictScalars R S M) 
goal: Module Rᵐᵒᵖ (RestrictScalars R S M)

full_name: RestrictScalars.isCentralScalar
code: instance RestrictScalars.isCentralScalar [Module S M] [Module Sᵐᵒᵖ M] [IsCentralScalar S M] :
    IsCentralScalar R (RestrictScalars R S M) 
goal: IsCentralScalar R (RestrictScalars R S M)

full_name: RestrictScalars.lsmul
code: /-- The `R`-algebra homomorphism from the original coefficient algebra `S` to endomorphisms
of `RestrictScalars R S M`.
-/
def RestrictScalars.lsmul [Module S M] : S →ₐ[R] Module.End R (RestrictScalars R S M) 
goal: S →ₐ[R] Module.End R (RestrictScalars R S M)

full_name: RestrictScalars.addEquiv
code: /-- `RestrictScalars.addEquiv` is the additive equivalence with the original module. -/
def RestrictScalars.addEquiv : RestrictScalars R S M ≃+ M 
goal: RestrictScalars R S M ≃+ M

full_name: RestrictScalars.smul_def
code: theorem RestrictScalars.smul_def (c : R) (x : RestrictScalars R S M) :
    c • x = (RestrictScalars.addEquiv R S M).symm
      (algebraMap R S c • RestrictScalars.addEquiv R S M x) 
goal: c • x = (RestrictScalars.addEquiv R S M).symm ((algebraMap R S) c • (RestrictScalars.addEquiv R S M) x)

full_name: RestrictScalars.addEquiv_map_smul
code: @[simp]
theorem RestrictScalars.addEquiv_map_smul (c : R) (x : RestrictScalars R S M) :
    RestrictScalars.addEquiv R S M (c • x) = algebraMap R S c • RestrictScalars.addEquiv R S M x 
goal: (RestrictScalars.addEquiv R S M) (c • x) = (algebraMap R S) c • (RestrictScalars.addEquiv R S M) x

full_name: RestrictScalars.addEquiv_symm_map_algebraMap_smul
code: theorem RestrictScalars.addEquiv_symm_map_algebraMap_smul (r : R) (x : M) :
    (RestrictScalars.addEquiv R S M).symm (algebraMap R S r • x) =
      r • (RestrictScalars.addEquiv R S M).symm x 
goal: (RestrictScalars.addEquiv R S M).symm ((algebraMap R S) r • x) = r • (RestrictScalars.addEquiv R S M).symm x

full_name: RestrictScalars.addEquiv_symm_map_smul_smul
code: theorem RestrictScalars.addEquiv_symm_map_smul_smul (r : R) (s : S) (x : M) :
    (RestrictScalars.addEquiv R S M).symm ((r • s) • x) =
      r • (RestrictScalars.addEquiv R S M).symm (s • x) 
goal: (RestrictScalars.addEquiv R S M).symm ((r • s) • x) = r • (RestrictScalars.addEquiv R S M).symm (s • x)

full_name: RestrictScalars.lsmul_apply_apply
code: theorem RestrictScalars.lsmul_apply_apply (s : S) (x : RestrictScalars R S M) :
    RestrictScalars.lsmul R S M s x =
      (RestrictScalars.addEquiv R S M).symm (s • RestrictScalars.addEquiv R S M x) 
goal: ((RestrictScalars.lsmul R S M) s) x = (RestrictScalars.addEquiv R S M).symm (s • (RestrictScalars.addEquiv R S M) x)

full_name: instSemiringRestrictScalars
code: instance [I : Semiring A] : Semiring (RestrictScalars R S A) 
goal: Semiring (RestrictScalars R S A)

full_name: instRingRestrictScalars
code: instance [I : Ring A] : Ring (RestrictScalars R S A) 
goal: Ring (RestrictScalars R S A)

full_name: instCommSemiringRestrictScalars
code: instance [I : CommSemiring A] : CommSemiring (RestrictScalars R S A) 
goal: CommSemiring (RestrictScalars R S A)

full_name: instCommRingRestrictScalars
code: instance [I : CommRing A] : CommRing (RestrictScalars R S A) 
goal: CommRing (RestrictScalars R S A)

full_name: RestrictScalars.ringEquiv
code: /-- Tautological ring isomorphism `RestrictScalars R S A ≃+* A`. -/
def RestrictScalars.ringEquiv : RestrictScalars R S A ≃+* A 
goal: RestrictScalars R S A ≃+* A

full_name: RestrictScalars.ringEquiv_map_smul
code: @[simp]
theorem RestrictScalars.ringEquiv_map_smul (r : R) (x : RestrictScalars R S A) :
    RestrictScalars.ringEquiv R S A (r • x) =
      algebraMap R S r • RestrictScalars.ringEquiv R S A x 
goal: (RestrictScalars.ringEquiv R S A) (r • x) = (algebraMap R S) r • (RestrictScalars.ringEquiv R S A) x

full_name: RestrictScalars.algebra
code: /-- `R ⟶ S` induces `S-Alg ⥤ R-Alg` -/
instance RestrictScalars.algebra : Algebra R (RestrictScalars R S A) 
goal: Algebra R (RestrictScalars R S A)

full_name: RestrictScalars.ringEquiv_algebraMap
code: @[simp]
theorem RestrictScalars.ringEquiv_algebraMap (r : R) :
    RestrictScalars.ringEquiv R S A (algebraMap R (RestrictScalars R S A) r) =
      algebraMap S A (algebraMap R S r) 
goal: (RestrictScalars.ringEquiv R S A) ((algebraMap R (RestrictScalars R S A)) r) = (algebraMap S A) ((algebraMap R S) r)