Modules over a ring #
In this file we define
module R M
: an additive commutative monoidM
is amodule
over asemiring R
if forr : R
andx : M
their "scalar multiplicationr • x : M
is defined, and the operation•
satisfies some natural associativity and distributivity axioms similar to those on a ring.
Implementation notes #
In typical mathematical usage, our definition of module
corresponds to "semimodule", and the
word "module" is reserved for module R M
where R
is a ring
and M
an add_comm_group
.
If R
is a field
and M
an add_comm_group
, M
would be called an R
-vector space.
Since those assumptions can be made by changing the typeclasses applied to R
and M
,
without changing the axioms in module
, mathlib calls everything a module
.
In older versions of mathlib, we had separate semimodule
and vector_space
abbreviations.
This caused inference issues in some cases, while not providing any real advantages, so we decided
to use a canonical module
typeclass throughout.
Tags #
semimodule, module, vector space
- to_distrib_mul_action : distrib_mul_action R M
- add_smul : ∀ (r s : R) (x : M), (r + s) • x = r • x + s • x
- zero_smul : ∀ (x : M), 0 • x = 0
A module is a generalization of vector spaces to a scalar semiring.
It consists of a scalar semiring R
and an additive monoid of "vectors" M
,
connected by a "scalar multiplication" operation r • x : M
(where r : R
and x : M
) with some natural associativity and
distributivity axioms similar to those on a ring.
Instances
- algebra.to_module
- semiring.to_module
- semiring.to_opposite_module
- add_comm_monoid.nat_module
- add_comm_group.int_module
- real.module
- pi.module
- pi.module'
- add_monoid_hom.module
- prod.module
- subsemiring.module
- subring.module
- linear_map.module
- linear_map.apply_module
- submodule.module'
- submodule.module
- submodule.restrict_scalars.orig_module
- punit.module
- dfinsupp.module
- finsupp.module
- nnreal.module
- ennreal.module
A module over a semiring automatically inherits a mul_action_with_zero
structure.
Equations
- module.to_mul_action_with_zero = {to_mul_action := {to_has_scalar := mul_action.to_has_scalar infer_instance, one_smul := _, mul_smul := _}, smul_zero := _, zero_smul := _}
Equations
- add_comm_monoid.nat_module = {to_distrib_mul_action := {to_mul_action := {to_has_scalar := add_monoid.has_scalar_nat (add_comm_monoid.to_add_monoid M), one_smul := _, mul_smul := _}, smul_add := _, smul_zero := _}, add_smul := _, zero_smul := _}
Pullback a module
structure along an injective additive monoid homomorphism.
See note [reducible non-instances].
Equations
- function.injective.module R f hf smul = {to_distrib_mul_action := {to_mul_action := {to_has_scalar := {smul := has_scalar.smul _inst_5}, one_smul := _, mul_smul := _}, smul_add := _, smul_zero := _}, add_smul := _, zero_smul := _}
Pushforward a module
structure along a surjective additive monoid homomorphism.
Equations
- function.surjective.module R f hf smul = {to_distrib_mul_action := {to_mul_action := {to_has_scalar := {smul := has_scalar.smul _inst_5}, one_smul := _, mul_smul := _}, smul_add := _, smul_zero := _}, add_smul := _, zero_smul := _}
Push forward the action of R
on M
along a compatible surjective map f : R →+* S
.
See also function.surjective.mul_action_left
and function.surjective.distrib_mul_action_left
.
Equations
- function.surjective.module_left f hf hsmul = {to_distrib_mul_action := {to_mul_action := {to_has_scalar := {smul := has_scalar.smul _inst_8}, one_smul := _, mul_smul := _}, smul_add := _, smul_zero := _}, add_smul := _, zero_smul := _}
Compose a module
with a ring_hom
, with action f s • m
.
See note [reducible non-instances].
Equations
- module.comp_hom M f = {to_distrib_mul_action := {to_mul_action := {to_has_scalar := {smul := has_scalar.comp.smul ⇑f}, one_smul := _, mul_smul := _}, smul_add := _, smul_zero := _}, add_smul := _, zero_smul := _}
(•)
as an add_monoid_hom
.
This is a stronger version of distrib_mul_action.to_add_monoid_End
Equations
- module.to_add_monoid_End R M = {to_fun := (distrib_mul_action.to_add_monoid_End R M).to_fun, map_one' := _, map_mul' := _, map_zero' := _, map_add' := _}
A convenience alias for module.to_add_monoid_End
as an add_monoid_hom
, usually to allow the
use of add_monoid_hom.flip
.
Equations
An add_comm_monoid
that is a module
over a ring
carries a natural add_comm_group
structure.
See note [reducible non-instances].
Equations
- module.add_comm_monoid_to_add_comm_group R = {add := add_comm_monoid.add infer_instance, add_assoc := _, zero := add_comm_monoid.zero infer_instance, zero_add := _, add_zero := _, nsmul := add_comm_monoid.nsmul infer_instance, nsmul_zero' := _, nsmul_succ' := _, neg := λ (a : M), (-1) • a, sub := add_group.sub._default add_comm_monoid.add module.add_comm_monoid_to_add_comm_group._proof_6 add_comm_monoid.zero module.add_comm_monoid_to_add_comm_group._proof_7 module.add_comm_monoid_to_add_comm_group._proof_8 add_comm_monoid.nsmul module.add_comm_monoid_to_add_comm_group._proof_9 module.add_comm_monoid_to_add_comm_group._proof_10 (λ (a : M), (-1) • a), sub_eq_add_neg := _, zsmul := add_group.zsmul._default add_comm_monoid.add module.add_comm_monoid_to_add_comm_group._proof_12 add_comm_monoid.zero module.add_comm_monoid_to_add_comm_group._proof_13 module.add_comm_monoid_to_add_comm_group._proof_14 add_comm_monoid.nsmul module.add_comm_monoid_to_add_comm_group._proof_15 module.add_comm_monoid_to_add_comm_group._proof_16 (λ (a : M), (-1) • a), zsmul_zero' := _, zsmul_succ' := _, zsmul_neg' := _, add_left_neg := _, add_comm := _}
Equations
- add_comm_group.int_module M = {to_distrib_mul_action := {to_mul_action := {to_has_scalar := sub_neg_monoid.has_scalar_int (add_group.to_sub_neg_monoid M), one_smul := _, mul_smul := _}, smul_add := _, smul_zero := _}, add_smul := _, zero_smul := _}
- to_has_scalar : has_scalar R M
- smul_add : ∀ (r : R) (x y : M), r • (x + y) = r • x + r • y
- add_smul : ∀ (r s : R) (x : M), (r + s) • x = r • x + s • x
- mul_smul : ∀ (r s : R) (x : M), (r * s) • x = r • s • x
- one_smul : ∀ (x : M), 1 • x = x
A structure containing most informations as in a module, except the fields zero_smul
and smul_zero
. As these fields can be deduced from the other ones when M
is an add_comm_group
,
this provides a way to construct a module structure by checking less properties, in
module.of_core
.
Define module
without proving zero_smul
and smul_zero
by using an auxiliary
structure module.core
, when the underlying space is an add_comm_group
.
Equations
- module.of_core H = let _inst : has_scalar R M := H.to_has_scalar in {to_distrib_mul_action := {to_mul_action := {to_has_scalar := H.to_has_scalar, one_smul := _, mul_smul := _}, smul_add := _, smul_zero := _}, add_smul := _, zero_smul := _}
To prove two module structures on a fixed add_comm_monoid
agree,
it suffices to check the scalar multiplications agree.
A module over a subsingleton
semiring is a subsingleton
. We cannot register this
as an instance because Lean has no way to guess R
.
Equations
- semiring.to_module = {to_distrib_mul_action := {to_mul_action := monoid.to_mul_action R (monoid_with_zero.to_monoid R), smul_add := _, smul_zero := _}, add_smul := _, zero_smul := _}
A ring homomorphism f : R →+* M
defines a module structure by r • x = f r * x
.
Equations
- f.to_module = module.comp_hom S f
The tautological action by R →+* R
on R
.
This generalizes function.End.apply_mul_action
.
Equations
- ring_hom.apply_distrib_mul_action = {to_mul_action := {to_has_scalar := {smul := λ (_x : R →+* R) (_y : R), ⇑_x _y}, one_smul := _, mul_smul := _}, smul_add := _, smul_zero := _}
ring_hom.apply_distrib_mul_action
is faithful.
nsmul
is equal to any other module structure via a cast.
Convert back any exotic ℕ
-smul to the canonical instance. This should not be needed since in
mathlib all add_comm_monoid
s should normally have exactly one ℕ
-module structure by design.
All ℕ
-module structures are equal. Not an instance since in mathlib all add_comm_monoid
should normally have exactly one ℕ
-module structure by design.
Equations
- add_comm_monoid.nat_module.unique = {to_inhabited := {default := add_comm_monoid.nat_module _inst_2}, uniq := _}
zsmul
is equal to any other module structure via a cast.
Convert back any exotic ℤ
-smul to the canonical instance. This should not be needed since in
mathlib all add_comm_group
s should normally have exactly one ℤ
-module structure by design.
All ℤ
-module structures are equal. Not an instance since in mathlib all add_comm_group
should normally have exactly one ℤ
-module structure by design.
Equations
- add_comm_group.int_module.unique = {to_inhabited := {default := add_comm_group.int_module M _inst_3}, uniq := _}
There can be at most one module ℚ E
structure on an additive commutative group. This is not
an instance because simp
becomes very slow if we have many subsingleton
instances,
see [gh-6025].
If E
is a vector space over two division rings R
and S
, then scalar multiplications
agree on inverses of integer numbers in R
and S
.
If E
is a vector space over two division rings R
and S
, then scalar multiplications
agree on inverses of natural numbers in R
and S
.
If E
is a vector space over two division rings R
and S
, then scalar multiplications
agree on rational numbers in R
and S
.
no_zero_smul_divisors
#
This section defines the no_zero_smul_divisors
class, and includes some tests
for the vanishing of elements (especially in modules over division rings).
no_zero_smul_divisors R M
states that a scalar multiple is 0
only if either argument is 0
.
This a version of saying that M
is torsion free, without assuming R
is zero-divisor free.
The main application of no_zero_smul_divisors R M
, when M
is a module,
is the result smul_eq_zero
: a scalar multiple is 0
iff either argument is 0
.
It is a generalization of the no_zero_divisors
class to heterogeneous multiplication.
Pullback a no_zero_smul_divisors
instance along an injective function.