R : Type u
A : Type v
inst✝² : CommSemiring R
inst✝¹ : Semiring A
inst✝ : Algebra R A
x : A
r : R
⊢ (fun r => r • 1) r = x ↔ (algebraMap R A) r = x

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by


ι : Sort uι
R : Type u
inst✝² : CommSemiring R
A : Type v
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Set A
M N P Q : Submodule R A
m n : A
⊢ 1 ≤ 1.toAddSubmonoid

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by


case intro
ι : Sort uι
R : Type u
inst✝² : CommSemiring R
A : Type v
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Set A
M N P Q : Submodule R A
m n✝ : A
n : ℕ
⊢ (Nat.castAddMonoidHom A) n ∈ 1.toAddSubmonoid

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩

exact ⟨n, map_natCast (algebraMap R A) n⟩


ι : Sort uι
R : Type u
inst✝² : CommSemiring R
A : Type v
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Set A
M N P Q : Submodule R A
m n : A
⊢ 1 = span R {1}

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by


case h
ι : Sort uι
R : Type u
inst✝² : CommSemiring R
A : Type v
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Set A
M N P Q : Submodule R A
m n : A
⊢ ∀ (x : A), x ∈ 1 ↔ x ∈ span R {1}

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by
  apply Submodule.ext


case h
ι : Sort uι
R : Type u
inst✝² : CommSemiring R
A : Type v
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Set A
M N P Q : Submodule R A
m n a : A
⊢ a ∈ 1 ↔ a ∈ span R {1}

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by
  apply Submodule.ext
  intro a

simp only [mem_one, mem_span_singleton, Algebra.smul_def, mul_one]


ι : Sort uι
R : Type u
inst✝² : CommSemiring R
A : Type v
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Set A
M N P Q : Submodule R A
m n : A
⊢ 1 ≤ P ↔ 1 ∈ P

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by
  apply Submodule.ext
  intro a
  simp only [mem_one, mem_span_singleton, Algebra.smul_def, mul_one]
#align submodule.one_eq_span Submodule.one_eq_span

theorem one_eq_span_one_set : (1 : Submodule R A) = span R 1 :=
  one_eq_span
#align submodule.one_eq_span_one_set Submodule.one_eq_span_one_set

theorem one_le : (1 : Submodule R A) ≤ P ↔ (1 : A) ∈ P := by
  -- porting note: simpa no longer closes refl goals, so added `SetLike.mem_coe`

simp only [one_eq_span, span_le, Set.singleton_subset_iff, SetLike.mem_coe]


ι : Sort uι
R : Type u
inst✝⁴ : CommSemiring R
A : Type v
inst✝³ : Semiring A
inst✝² : Algebra R A
S T : Set A
M N P Q : Submodule R A
m n : A
A' : Type u_1
inst✝¹ : Semiring A'
inst✝ : Algebra R A'
f : A →ₐ[R] A'
⊢ map (AlgHom.toLinearMap f) 1 = 1

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by
  apply Submodule.ext
  intro a
  simp only [mem_one, mem_span_singleton, Algebra.smul_def, mul_one]
#align submodule.one_eq_span Submodule.one_eq_span

theorem one_eq_span_one_set : (1 : Submodule R A) = span R 1 :=
  one_eq_span
#align submodule.one_eq_span_one_set Submodule.one_eq_span_one_set

theorem one_le : (1 : Submodule R A) ≤ P ↔ (1 : A) ∈ P := by
  -- porting note: simpa no longer closes refl goals, so added `SetLike.mem_coe`
  simp only [one_eq_span, span_le, Set.singleton_subset_iff, SetLike.mem_coe]
#align submodule.one_le Submodule.one_le

protected theorem map_one {A'} [Semiring A'] [Algebra R A'] (f : A →ₐ[R] A') :
    map f.toLinearMap (1 : Submodule R A) = 1 := by


case h
ι : Sort uι
R : Type u
inst✝⁴ : CommSemiring R
A : Type v
inst✝³ : Semiring A
inst✝² : Algebra R A
S T : Set A
M N P Q : Submodule R A
m n : A
A' : Type u_1
inst✝¹ : Semiring A'
inst✝ : Algebra R A'
f : A →ₐ[R] A'
x✝ : A'
⊢ x✝ ∈ map (AlgHom.toLinearMap f) 1 ↔ x✝ ∈ 1

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by
  apply Submodule.ext
  intro a
  simp only [mem_one, mem_span_singleton, Algebra.smul_def, mul_one]
#align submodule.one_eq_span Submodule.one_eq_span

theorem one_eq_span_one_set : (1 : Submodule R A) = span R 1 :=
  one_eq_span
#align submodule.one_eq_span_one_set Submodule.one_eq_span_one_set

theorem one_le : (1 : Submodule R A) ≤ P ↔ (1 : A) ∈ P := by
  -- porting note: simpa no longer closes refl goals, so added `SetLike.mem_coe`
  simp only [one_eq_span, span_le, Set.singleton_subset_iff, SetLike.mem_coe]
#align submodule.one_le Submodule.one_le

protected theorem map_one {A'} [Semiring A'] [Algebra R A'] (f : A →ₐ[R] A') :
    map f.toLinearMap (1 : Submodule R A) = 1 := by
  ext


ι : Sort uι
R : Type u
inst✝² : CommSemiring R
A : Type v
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Set A
M N P Q : Submodule R A
m n : A
⊢ map (↑(opLinearEquiv R)) 1 = 1

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by
  apply Submodule.ext
  intro a
  simp only [mem_one, mem_span_singleton, Algebra.smul_def, mul_one]
#align submodule.one_eq_span Submodule.one_eq_span

theorem one_eq_span_one_set : (1 : Submodule R A) = span R 1 :=
  one_eq_span
#align submodule.one_eq_span_one_set Submodule.one_eq_span_one_set

theorem one_le : (1 : Submodule R A) ≤ P ↔ (1 : A) ∈ P := by
  -- porting note: simpa no longer closes refl goals, so added `SetLike.mem_coe`
  simp only [one_eq_span, span_le, Set.singleton_subset_iff, SetLike.mem_coe]
#align submodule.one_le Submodule.one_le

protected theorem map_one {A'} [Semiring A'] [Algebra R A'] (f : A →ₐ[R] A') :
    map f.toLinearMap (1 : Submodule R A) = 1 := by
  ext
  simp
#align submodule.map_one Submodule.map_one

@[simp]
theorem map_op_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R A) = 1 := by


case h
ι : Sort uι
R : Type u
inst✝² : CommSemiring R
A : Type v
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Set A
M N P Q : Submodule R A
m n : A
x : Aᵐᵒᵖ
⊢ x ∈ map (↑(opLinearEquiv R)) 1 ↔ x ∈ 1

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by
  apply Submodule.ext
  intro a
  simp only [mem_one, mem_span_singleton, Algebra.smul_def, mul_one]
#align submodule.one_eq_span Submodule.one_eq_span

theorem one_eq_span_one_set : (1 : Submodule R A) = span R 1 :=
  one_eq_span
#align submodule.one_eq_span_one_set Submodule.one_eq_span_one_set

theorem one_le : (1 : Submodule R A) ≤ P ↔ (1 : A) ∈ P := by
  -- porting note: simpa no longer closes refl goals, so added `SetLike.mem_coe`
  simp only [one_eq_span, span_le, Set.singleton_subset_iff, SetLike.mem_coe]
#align submodule.one_le Submodule.one_le

protected theorem map_one {A'} [Semiring A'] [Algebra R A'] (f : A →ₐ[R] A') :
    map f.toLinearMap (1 : Submodule R A) = 1 := by
  ext
  simp
#align submodule.map_one Submodule.map_one

@[simp]
theorem map_op_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R A) = 1 := by
  ext x


case h.h
ι : Sort uι
R : Type u
inst✝² : CommSemiring R
A : Type v
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Set A
M N P Q : Submodule R A
m n X✝ : A
⊢ op X✝ ∈ map (↑(opLinearEquiv R)) 1 ↔ op X✝ ∈ 1

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by
  apply Submodule.ext
  intro a
  simp only [mem_one, mem_span_singleton, Algebra.smul_def, mul_one]
#align submodule.one_eq_span Submodule.one_eq_span

theorem one_eq_span_one_set : (1 : Submodule R A) = span R 1 :=
  one_eq_span
#align submodule.one_eq_span_one_set Submodule.one_eq_span_one_set

theorem one_le : (1 : Submodule R A) ≤ P ↔ (1 : A) ∈ P := by
  -- porting note: simpa no longer closes refl goals, so added `SetLike.mem_coe`
  simp only [one_eq_span, span_le, Set.singleton_subset_iff, SetLike.mem_coe]
#align submodule.one_le Submodule.one_le

protected theorem map_one {A'} [Semiring A'] [Algebra R A'] (f : A →ₐ[R] A') :
    map f.toLinearMap (1 : Submodule R A) = 1 := by
  ext
  simp
#align submodule.map_one Submodule.map_one

@[simp]
theorem map_op_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R A) = 1 := by
  ext x
  induction x using MulOpposite.rec'


ι : Sort uι
R : Type u
inst✝² : CommSemiring R
A : Type v
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Set A
M N P Q : Submodule R A
m n : A
⊢ comap (↑(opLinearEquiv R)) 1 = 1

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by
  apply Submodule.ext
  intro a
  simp only [mem_one, mem_span_singleton, Algebra.smul_def, mul_one]
#align submodule.one_eq_span Submodule.one_eq_span

theorem one_eq_span_one_set : (1 : Submodule R A) = span R 1 :=
  one_eq_span
#align submodule.one_eq_span_one_set Submodule.one_eq_span_one_set

theorem one_le : (1 : Submodule R A) ≤ P ↔ (1 : A) ∈ P := by
  -- porting note: simpa no longer closes refl goals, so added `SetLike.mem_coe`
  simp only [one_eq_span, span_le, Set.singleton_subset_iff, SetLike.mem_coe]
#align submodule.one_le Submodule.one_le

protected theorem map_one {A'} [Semiring A'] [Algebra R A'] (f : A →ₐ[R] A') :
    map f.toLinearMap (1 : Submodule R A) = 1 := by
  ext
  simp
#align submodule.map_one Submodule.map_one

@[simp]
theorem map_op_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R A) = 1 := by
  ext x
  induction x using MulOpposite.rec'
  simp
#align submodule.map_op_one Submodule.map_op_one

@[simp]
theorem comap_op_one :
    comap (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R Aᵐᵒᵖ) = 1 := by


case h
ι : Sort uι
R : Type u
inst✝² : CommSemiring R
A : Type v
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Set A
M N P Q : Submodule R A
m n x✝ : A
⊢ x✝ ∈ comap (↑(opLinearEquiv R)) 1 ↔ x✝ ∈ 1

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by
  apply Submodule.ext
  intro a
  simp only [mem_one, mem_span_singleton, Algebra.smul_def, mul_one]
#align submodule.one_eq_span Submodule.one_eq_span

theorem one_eq_span_one_set : (1 : Submodule R A) = span R 1 :=
  one_eq_span
#align submodule.one_eq_span_one_set Submodule.one_eq_span_one_set

theorem one_le : (1 : Submodule R A) ≤ P ↔ (1 : A) ∈ P := by
  -- porting note: simpa no longer closes refl goals, so added `SetLike.mem_coe`
  simp only [one_eq_span, span_le, Set.singleton_subset_iff, SetLike.mem_coe]
#align submodule.one_le Submodule.one_le

protected theorem map_one {A'} [Semiring A'] [Algebra R A'] (f : A →ₐ[R] A') :
    map f.toLinearMap (1 : Submodule R A) = 1 := by
  ext
  simp
#align submodule.map_one Submodule.map_one

@[simp]
theorem map_op_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R A) = 1 := by
  ext x
  induction x using MulOpposite.rec'
  simp
#align submodule.map_op_one Submodule.map_op_one

@[simp]
theorem comap_op_one :
    comap (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R Aᵐᵒᵖ) = 1 := by
  ext


ι : Sort uι
R : Type u
inst✝² : CommSemiring R
A : Type v
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Set A
M N P Q : Submodule R A
m n : A
⊢ map (↑(LinearEquiv.symm (opLinearEquiv R))) 1 = 1

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by
  apply Submodule.ext
  intro a
  simp only [mem_one, mem_span_singleton, Algebra.smul_def, mul_one]
#align submodule.one_eq_span Submodule.one_eq_span

theorem one_eq_span_one_set : (1 : Submodule R A) = span R 1 :=
  one_eq_span
#align submodule.one_eq_span_one_set Submodule.one_eq_span_one_set

theorem one_le : (1 : Submodule R A) ≤ P ↔ (1 : A) ∈ P := by
  -- porting note: simpa no longer closes refl goals, so added `SetLike.mem_coe`
  simp only [one_eq_span, span_le, Set.singleton_subset_iff, SetLike.mem_coe]
#align submodule.one_le Submodule.one_le

protected theorem map_one {A'} [Semiring A'] [Algebra R A'] (f : A →ₐ[R] A') :
    map f.toLinearMap (1 : Submodule R A) = 1 := by
  ext
  simp
#align submodule.map_one Submodule.map_one

@[simp]
theorem map_op_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R A) = 1 := by
  ext x
  induction x using MulOpposite.rec'
  simp
#align submodule.map_op_one Submodule.map_op_one

@[simp]
theorem comap_op_one :
    comap (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R Aᵐᵒᵖ) = 1 := by
  ext
  simp
#align submodule.comap_op_one Submodule.comap_op_one

@[simp]
theorem map_unop_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ).symm : Aᵐᵒᵖ →ₗ[R] A) (1 : Submodule R Aᵐᵒᵖ) = 1 := by


/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by
  apply Submodule.ext
  intro a
  simp only [mem_one, mem_span_singleton, Algebra.smul_def, mul_one]
#align submodule.one_eq_span Submodule.one_eq_span

theorem one_eq_span_one_set : (1 : Submodule R A) = span R 1 :=
  one_eq_span
#align submodule.one_eq_span_one_set Submodule.one_eq_span_one_set

theorem one_le : (1 : Submodule R A) ≤ P ↔ (1 : A) ∈ P := by
  -- porting note: simpa no longer closes refl goals, so added `SetLike.mem_coe`
  simp only [one_eq_span, span_le, Set.singleton_subset_iff, SetLike.mem_coe]
#align submodule.one_le Submodule.one_le

protected theorem map_one {A'} [Semiring A'] [Algebra R A'] (f : A →ₐ[R] A') :
    map f.toLinearMap (1 : Submodule R A) = 1 := by
  ext
  simp
#align submodule.map_one Submodule.map_one

@[simp]
theorem map_op_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R A) = 1 := by
  ext x
  induction x using MulOpposite.rec'
  simp
#align submodule.map_op_one Submodule.map_op_one

@[simp]
theorem comap_op_one :
    comap (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R Aᵐᵒᵖ) = 1 := by
  ext
  simp
#align submodule.comap_op_one Submodule.comap_op_one

@[simp]
theorem map_unop_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ).symm : Aᵐᵒᵖ →ₗ[R] A) (1 : Submodule R Aᵐᵒᵖ) = 1 := by
  rw [← comap_equiv_eq_map_symm]


ι : Sort uι
R : Type u
inst✝² : CommSemiring R
A : Type v
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Set A
M N P Q : Submodule R A
m n : A
⊢ comap (↑(LinearEquiv.symm (opLinearEquiv R))) 1 = 1

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by
  apply Submodule.ext
  intro a
  simp only [mem_one, mem_span_singleton, Algebra.smul_def, mul_one]
#align submodule.one_eq_span Submodule.one_eq_span

theorem one_eq_span_one_set : (1 : Submodule R A) = span R 1 :=
  one_eq_span
#align submodule.one_eq_span_one_set Submodule.one_eq_span_one_set

theorem one_le : (1 : Submodule R A) ≤ P ↔ (1 : A) ∈ P := by
  -- porting note: simpa no longer closes refl goals, so added `SetLike.mem_coe`
  simp only [one_eq_span, span_le, Set.singleton_subset_iff, SetLike.mem_coe]
#align submodule.one_le Submodule.one_le

protected theorem map_one {A'} [Semiring A'] [Algebra R A'] (f : A →ₐ[R] A') :
    map f.toLinearMap (1 : Submodule R A) = 1 := by
  ext
  simp
#align submodule.map_one Submodule.map_one

@[simp]
theorem map_op_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R A) = 1 := by
  ext x
  induction x using MulOpposite.rec'
  simp
#align submodule.map_op_one Submodule.map_op_one

@[simp]
theorem comap_op_one :
    comap (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R Aᵐᵒᵖ) = 1 := by
  ext
  simp
#align submodule.comap_op_one Submodule.comap_op_one

@[simp]
theorem map_unop_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ).symm : Aᵐᵒᵖ →ₗ[R] A) (1 : Submodule R Aᵐᵒᵖ) = 1 := by
  rw [← comap_equiv_eq_map_symm]
  rw [comap_op_one]
#align submodule.map_unop_one Submodule.map_unop_one

@[simp]
theorem comap_unop_one :
    comap (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ).symm : Aᵐᵒᵖ →ₗ[R] A) (1 : Submodule R A) = 1 := by


/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by
  apply Submodule.ext
  intro a
  simp only [mem_one, mem_span_singleton, Algebra.smul_def, mul_one]
#align submodule.one_eq_span Submodule.one_eq_span

theorem one_eq_span_one_set : (1 : Submodule R A) = span R 1 :=
  one_eq_span
#align submodule.one_eq_span_one_set Submodule.one_eq_span_one_set

theorem one_le : (1 : Submodule R A) ≤ P ↔ (1 : A) ∈ P := by
  -- porting note: simpa no longer closes refl goals, so added `SetLike.mem_coe`
  simp only [one_eq_span, span_le, Set.singleton_subset_iff, SetLike.mem_coe]
#align submodule.one_le Submodule.one_le

protected theorem map_one {A'} [Semiring A'] [Algebra R A'] (f : A →ₐ[R] A') :
    map f.toLinearMap (1 : Submodule R A) = 1 := by
  ext
  simp
#align submodule.map_one Submodule.map_one

@[simp]
theorem map_op_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R A) = 1 := by
  ext x
  induction x using MulOpposite.rec'
  simp
#align submodule.map_op_one Submodule.map_op_one

@[simp]
theorem comap_op_one :
    comap (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R Aᵐᵒᵖ) = 1 := by
  ext
  simp
#align submodule.comap_op_one Submodule.comap_op_one

@[simp]
theorem map_unop_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ).symm : Aᵐᵒᵖ →ₗ[R] A) (1 : Submodule R Aᵐᵒᵖ) = 1 := by
  rw [← comap_equiv_eq_map_symm]
  rw [comap_op_one]
#align submodule.map_unop_one Submodule.map_unop_one

@[simp]
theorem comap_unop_one :
    comap (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ).symm : Aᵐᵒᵖ →ₗ[R] A) (1 : Submodule R A) = 1 := by
  rw [← map_equiv_eq_comap_symm]


ι : Sort uι
R : Type u
inst✝² : CommSemiring R
A : Type v
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Set A
M✝ N✝ P Q : Submodule R A
m n : A
M N : Submodule R A
⊢ (M * N).toAddSubmonoid = M.toAddSubmonoid * N.toAddSubmonoid

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by
  apply Submodule.ext
  intro a
  simp only [mem_one, mem_span_singleton, Algebra.smul_def, mul_one]
#align submodule.one_eq_span Submodule.one_eq_span

theorem one_eq_span_one_set : (1 : Submodule R A) = span R 1 :=
  one_eq_span
#align submodule.one_eq_span_one_set Submodule.one_eq_span_one_set

theorem one_le : (1 : Submodule R A) ≤ P ↔ (1 : A) ∈ P := by
  -- porting note: simpa no longer closes refl goals, so added `SetLike.mem_coe`
  simp only [one_eq_span, span_le, Set.singleton_subset_iff, SetLike.mem_coe]
#align submodule.one_le Submodule.one_le

protected theorem map_one {A'} [Semiring A'] [Algebra R A'] (f : A →ₐ[R] A') :
    map f.toLinearMap (1 : Submodule R A) = 1 := by
  ext
  simp
#align submodule.map_one Submodule.map_one

@[simp]
theorem map_op_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R A) = 1 := by
  ext x
  induction x using MulOpposite.rec'
  simp
#align submodule.map_op_one Submodule.map_op_one

@[simp]
theorem comap_op_one :
    comap (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R Aᵐᵒᵖ) = 1 := by
  ext
  simp
#align submodule.comap_op_one Submodule.comap_op_one

@[simp]
theorem map_unop_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ).symm : Aᵐᵒᵖ →ₗ[R] A) (1 : Submodule R Aᵐᵒᵖ) = 1 := by
  rw [← comap_equiv_eq_map_symm]
  rw [comap_op_one]
#align submodule.map_unop_one Submodule.map_unop_one

@[simp]
theorem comap_unop_one :
    comap (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ).symm : Aᵐᵒᵖ →ₗ[R] A) (1 : Submodule R A) = 1 := by
  rw [← map_equiv_eq_comap_symm]
  rw [map_op_one]
#align submodule.comap_unop_one Submodule.comap_unop_one

/-- Multiplication of sub-R-modules of an R-algebra A. The submodule `M * N` is the
smallest R-submodule of `A` containing the elements `m * n` for `m ∈ M` and `n ∈ N`. -/
instance mul : Mul (Submodule R A) :=
  ⟨Submodule.map₂ <| LinearMap.mul R A⟩
#align submodule.has_mul Submodule.mul

theorem mul_mem_mul (hm : m ∈ M) (hn : n ∈ N) : m * n ∈ M * N :=
  apply_mem_map₂ _ hm hn
#align submodule.mul_mem_mul Submodule.mul_mem_mul

theorem mul_le : M * N ≤ P ↔ ∀ m ∈ M, ∀ n ∈ N, m * n ∈ P :=
  map₂_le
#align submodule.mul_le Submodule.mul_le

theorem mul_toAddSubmonoid (M N : Submodule R A) :
    (M * N).toAddSubmonoid = M.toAddSubmonoid * N.toAddSubmonoid := by


ι : Sort uι
R : Type u
inst✝² : CommSemiring R
A : Type v
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Set A
M✝ N✝ P Q : Submodule R A
m n : A
M N : Submodule R A
⊢ (map₂ (LinearMap.mul R A) M N).toAddSubmonoid = ⨆ s, AddSubmonoid.map (AddMonoidHom.mulLeft ↑s) N.toAddSubmonoid

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by
  apply Submodule.ext
  intro a
  simp only [mem_one, mem_span_singleton, Algebra.smul_def, mul_one]
#align submodule.one_eq_span Submodule.one_eq_span

theorem one_eq_span_one_set : (1 : Submodule R A) = span R 1 :=
  one_eq_span
#align submodule.one_eq_span_one_set Submodule.one_eq_span_one_set

theorem one_le : (1 : Submodule R A) ≤ P ↔ (1 : A) ∈ P := by
  -- porting note: simpa no longer closes refl goals, so added `SetLike.mem_coe`
  simp only [one_eq_span, span_le, Set.singleton_subset_iff, SetLike.mem_coe]
#align submodule.one_le Submodule.one_le

protected theorem map_one {A'} [Semiring A'] [Algebra R A'] (f : A →ₐ[R] A') :
    map f.toLinearMap (1 : Submodule R A) = 1 := by
  ext
  simp
#align submodule.map_one Submodule.map_one

@[simp]
theorem map_op_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R A) = 1 := by
  ext x
  induction x using MulOpposite.rec'
  simp
#align submodule.map_op_one Submodule.map_op_one

@[simp]
theorem comap_op_one :
    comap (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R Aᵐᵒᵖ) = 1 := by
  ext
  simp
#align submodule.comap_op_one Submodule.comap_op_one

@[simp]
theorem map_unop_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ).symm : Aᵐᵒᵖ →ₗ[R] A) (1 : Submodule R Aᵐᵒᵖ) = 1 := by
  rw [← comap_equiv_eq_map_symm]
  rw [comap_op_one]
#align submodule.map_unop_one Submodule.map_unop_one

@[simp]
theorem comap_unop_one :
    comap (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ).symm : Aᵐᵒᵖ →ₗ[R] A) (1 : Submodule R A) = 1 := by
  rw [← map_equiv_eq_comap_symm]
  rw [map_op_one]
#align submodule.comap_unop_one Submodule.comap_unop_one

/-- Multiplication of sub-R-modules of an R-algebra A. The submodule `M * N` is the
smallest R-submodule of `A` containing the elements `m * n` for `m ∈ M` and `n ∈ N`. -/
instance mul : Mul (Submodule R A) :=
  ⟨Submodule.map₂ <| LinearMap.mul R A⟩
#align submodule.has_mul Submodule.mul

theorem mul_mem_mul (hm : m ∈ M) (hn : n ∈ N) : m * n ∈ M * N :=
  apply_mem_map₂ _ hm hn
#align submodule.mul_mem_mul Submodule.mul_mem_mul

theorem mul_le : M * N ≤ P ↔ ∀ m ∈ M, ∀ n ∈ N, m * n ∈ P :=
  map₂_le
#align submodule.mul_le Submodule.mul_le

theorem mul_toAddSubmonoid (M N : Submodule R A) :
    (M * N).toAddSubmonoid = M.toAddSubmonoid * N.toAddSubmonoid := by
  dsimp [HMul.hMul, Mul.mul]  --porting note: added `hMul`


ι : Sort uι
R : Type u
inst✝² : CommSemiring R
A : Type v
inst✝¹ : Semiring A
inst✝ : Algebra R A
S T : Set A
M✝ N✝ P Q : Submodule R A
m n : A
M N : Submodule R A
⊢ (⨆ s, map ((LinearMap.mul R A) ↑s) N).toAddSubmonoid =
    ⨆ s, AddSubmonoid.map (AddMonoidHom.mulLeft ↑s) N.toAddSubmonoid

/-
Copyright (c) 2019 Kenny Lau. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Kenny Lau
-/
import Mathlib.Algebra.Algebra.Bilinear
import Mathlib.Algebra.Algebra.Equiv
import Mathlib.Algebra.Algebra.Opposite
import Mathlib.Algebra.Module.Submodule.Pointwise
import Mathlib.Algebra.Module.Submodule.Bilinear
import Mathlib.Algebra.Module.Opposites
import Mathlib.Algebra.Order.Kleene
import Mathlib.Data.Finset.Pointwise
import Mathlib.Data.Set.Semiring
import Mathlib.Data.Set.Pointwise.BigOperators
import Mathlib.GroupTheory.GroupAction.SubMulAction.Pointwise
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors

#align_import algebra.algebra.operations from "leanprover-community/mathlib"@"27b54c47c3137250a521aa64e9f1db90be5f6a26"

/-!
# Multiplication and division of submodules of an algebra.

An interface for multiplication and division of sub-R-modules of an R-algebra A is developed.

## Main definitions

Let `R` be a commutative ring (or semiring) and let `A` be an `R`-algebra.

* `1 : Submodule R A`       : the R-submodule R of the R-algebra A
* `Mul (Submodule R A)` : multiplication of two sub-R-modules M and N of A is defined to be
                              the smallest submodule containing all the products `m * n`.
* `Div (Submodule R A)` : `I / J` is defined to be the submodule consisting of all `a : A` such
                              that `a • J ⊆ I`

It is proved that `Submodule R A` is a semiring, and also an algebra over `Set A`.

Additionally, in the `pointwise` locale we promote `Submodule.pointwiseDistribMulAction` to a
`MulSemiringAction` as `Submodule.pointwiseMulSemiringAction`.

## Tags

multiplication of submodules, division of submodules, submodule semiring
-/

universe uι u v

open Algebra Set MulOpposite

open BigOperators

open Pointwise

namespace SubMulAction

variable {R : Type u} {A : Type v} [CommSemiring R] [Semiring A] [Algebra R A]

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : SubMulAction R A) :=
  ⟨r, (algebraMap_eq_smul_one r).symm⟩
#align sub_mul_action.algebra_map_mem SubMulAction.algebraMap_mem

theorem mem_one' {x : A} : x ∈ (1 : SubMulAction R A) ↔ ∃ y, algebraMap R A y = x :=
  exists_congr fun r => by rw [algebraMap_eq_smul_one]
#align sub_mul_action.mem_one' SubMulAction.mem_one'

end SubMulAction

namespace Submodule

variable {ι : Sort uι}

variable {R : Type u} [CommSemiring R]

section Ring

variable {A : Type v} [Semiring A] [Algebra R A]

variable (S T : Set A) {M N P Q : Submodule R A} {m n : A}

/-- `1 : Submodule R A` is the submodule R of A. -/
instance one : One (Submodule R A) :=
  -- porting note: `f.range` notation doesn't work
  ⟨LinearMap.range (Algebra.linearMap R A)⟩
#align submodule.has_one Submodule.one

theorem one_eq_range : (1 : Submodule R A) = LinearMap.range (Algebra.linearMap R A) :=
  rfl
#align submodule.one_eq_range Submodule.one_eq_range

theorem le_one_toAddSubmonoid : 1 ≤ (1 : Submodule R A).toAddSubmonoid := by
  rintro x ⟨n, rfl⟩
  exact ⟨n, map_natCast (algebraMap R A) n⟩
#align submodule.le_one_to_add_submonoid Submodule.le_one_toAddSubmonoid

theorem algebraMap_mem (r : R) : algebraMap R A r ∈ (1 : Submodule R A) :=
  LinearMap.mem_range_self _ _
#align submodule.algebra_map_mem Submodule.algebraMap_mem

@[simp]
theorem mem_one {x : A} : x ∈ (1 : Submodule R A) ↔ ∃ y, algebraMap R A y = x :=
  Iff.rfl
#align submodule.mem_one Submodule.mem_one

@[simp]
theorem toSubMulAction_one : (1 : Submodule R A).toSubMulAction = 1 :=
  SetLike.ext fun _ => mem_one.trans SubMulAction.mem_one'.symm
#align submodule.to_sub_mul_action_one Submodule.toSubMulAction_one

theorem one_eq_span : (1 : Submodule R A) = R ∙ 1 := by
  apply Submodule.ext
  intro a
  simp only [mem_one, mem_span_singleton, Algebra.smul_def, mul_one]
#align submodule.one_eq_span Submodule.one_eq_span

theorem one_eq_span_one_set : (1 : Submodule R A) = span R 1 :=
  one_eq_span
#align submodule.one_eq_span_one_set Submodule.one_eq_span_one_set

theorem one_le : (1 : Submodule R A) ≤ P ↔ (1 : A) ∈ P := by
  -- porting note: simpa no longer closes refl goals, so added `SetLike.mem_coe`
  simp only [one_eq_span, span_le, Set.singleton_subset_iff, SetLike.mem_coe]
#align submodule.one_le Submodule.one_le

protected theorem map_one {A'} [Semiring A'] [Algebra R A'] (f : A →ₐ[R] A') :
    map f.toLinearMap (1 : Submodule R A) = 1 := by
  ext
  simp
#align submodule.map_one Submodule.map_one

@[simp]
theorem map_op_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R A) = 1 := by
  ext x
  induction x using MulOpposite.rec'
  simp
#align submodule.map_op_one Submodule.map_op_one

@[simp]
theorem comap_op_one :
    comap (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ) : A →ₗ[R] Aᵐᵒᵖ) (1 : Submodule R Aᵐᵒᵖ) = 1 := by
  ext
  simp
#align submodule.comap_op_one Submodule.comap_op_one

@[simp]
theorem map_unop_one :
    map (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ).symm : Aᵐᵒᵖ →ₗ[R] A) (1 : Submodule R Aᵐᵒᵖ) = 1 := by
  rw [← comap_equiv_eq_map_symm]
  rw [comap_op_one]
#align submodule.map_unop_one Submodule.map_unop_one

@[simp]
theorem comap_unop_one :
    comap (↑(opLinearEquiv R : A ≃ₗ[R] Aᵐᵒᵖ).symm : Aᵐᵒᵖ →ₗ[R] A) (1 : Submodule R A) = 1 := by
  rw [← map_equiv_eq_comap_symm]
  rw [map_op_one]
#align submodule.comap_unop_one Submodule.comap_unop_one

/-- Multiplication of sub-R-modules of an R-algebra A. The submodule `M * N` is the
smallest R-submodule of `A` containing the elements `m * n` for `m ∈ M` and `n ∈ N`. -/
instance mul : Mul (Submodule R A) :=
  ⟨Submodule.map₂ <| LinearMap.mul R A⟩
#align submodule.has_mul Submodule.mul

theorem mul_mem_mul (hm : m ∈ M) (hn : n ∈ N) : m * n ∈ M * N :=
  apply_mem_map₂ _ hm hn
#align submodule.mul_mem_mul Submodule.mul_mem_mul

theorem mul_le : M * N ≤ P ↔ ∀ m ∈ M, ∀ n ∈ N, m * n ∈ P :=
  map₂_le
#align submodule.mul_le Submodule.mul_le

theorem mul_toAddSubmonoid (M N : Submodule R A) :
    (M * N).toAddSubmonoid = M.toAddSubmonoid * N.toAddSubmonoid := by
  dsimp [HMul.hMul, Mul.mul]  --porting note: added `hMul`
  rw [map₂]