File: Mathlib/LinearAlgebra/TensorProduct/Basic.lean

full_name: TensorProduct.Eqv.of_zero_right
code: /-- The relation on `FreeAddMonoid (M × N)` that generates a congruence whose quotient is
the tensor product. -/
inductive Eqv : FreeAddMonoid (M × N) → FreeAddMonoid (M × N) → Prop
  | of_zero_left : ∀ n : N, Eqv (.of (0, n)) 0
  | of_zero_right : ∀ m : M, Eqv (.of (m, 0)) 0
  | of_add_left : ∀ (m₁ m₂ : M) (n : N), Eqv (.of (m₁, n) + .of (m₂, n)) (.of (m₁ + m₂, n))
  | of_add_right : ∀ (m : M) (n₁ n₂ : N), Eqv (.of (m, n₁) + .of (m, n₂)) (.of (m, n₁ + n₂))
  | of_smul : ∀ (r : R) (m : M) (n : N), Eqv (.of (r • m, n)) (.of (m, r • n))
  | add_comm : ∀ x y, Eqv (x + y) (y + x)
goal: TensorProduct.Eqv R M N (FreeAddMonoid.of (m, 0)) 0

full_name: TensorProduct.Eqv
code: /-- The relation on `FreeAddMonoid (M × N)` that generates a congruence whose quotient is
the tensor product. -/
inductive Eqv : FreeAddMonoid (M × N) → FreeAddMonoid (M × N) → Prop
  | of_zero_left : ∀ n : N, Eqv (.of (0, n)) 0
  | of_zero_right : ∀ m : M, Eqv (.of (m, 0)) 0
  | of_add_left : ∀ (m₁ m₂ : M) (n : N), Eqv (.of (m₁, n) + .of (m₂, n)) (.of (m₁ + m₂, n))
  | of_add_right : ∀ (m : M) (n₁ n₂ : N), Eqv (.of (m, n₁) + .of (m, n₂)) (.of (m, n₁ + n₂))
  | of_smul : ∀ (r : R) (m : M) (n : N), Eqv (.of (r • m, n)) (.of (m, r • n))
  | add_comm : ∀ x y, Eqv (x + y) (y + x)
goal: FreeAddMonoid (M × N) → FreeAddMonoid (M × N) → Prop

full_name: TensorProduct.Eqv.of_smul
code: /-- The relation on `FreeAddMonoid (M × N)` that generates a congruence whose quotient is
the tensor product. -/
inductive Eqv : FreeAddMonoid (M × N) → FreeAddMonoid (M × N) → Prop
  | of_zero_left : ∀ n : N, Eqv (.of (0, n)) 0
  | of_zero_right : ∀ m : M, Eqv (.of (m, 0)) 0
  | of_add_left : ∀ (m₁ m₂ : M) (n : N), Eqv (.of (m₁, n) + .of (m₂, n)) (.of (m₁ + m₂, n))
  | of_add_right : ∀ (m : M) (n₁ n₂ : N), Eqv (.of (m, n₁) + .of (m, n₂)) (.of (m, n₁ + n₂))
  | of_smul : ∀ (r : R) (m : M) (n : N), Eqv (.of (r • m, n)) (.of (m, r • n))
  | add_comm : ∀ x y, Eqv (x + y) (y + x)
goal: TensorProduct.Eqv R M N (FreeAddMonoid.of (r • m, n)) (FreeAddMonoid.of (m, r • n))

full_name: TensorProduct.Eqv.of_add_left
code: /-- The relation on `FreeAddMonoid (M × N)` that generates a congruence whose quotient is
the tensor product. -/
inductive Eqv : FreeAddMonoid (M × N) → FreeAddMonoid (M × N) → Prop
  | of_zero_left : ∀ n : N, Eqv (.of (0, n)) 0
  | of_zero_right : ∀ m : M, Eqv (.of (m, 0)) 0
  | of_add_left : ∀ (m₁ m₂ : M) (n : N), Eqv (.of (m₁, n) + .of (m₂, n)) (.of (m₁ + m₂, n))
  | of_add_right : ∀ (m : M) (n₁ n₂ : N), Eqv (.of (m, n₁) + .of (m, n₂)) (.of (m, n₁ + n₂))
  | of_smul : ∀ (r : R) (m : M) (n : N), Eqv (.of (r • m, n)) (.of (m, r • n))
  | add_comm : ∀ x y, Eqv (x + y) (y + x)
goal: TensorProduct.Eqv R M N (FreeAddMonoid.of (m₁, n) + FreeAddMonoid.of (m₂, n)) (FreeAddMonoid.of (m₁ + m₂, n))

full_name: TensorProduct.Eqv.of_add_right
code: /-- The relation on `FreeAddMonoid (M × N)` that generates a congruence whose quotient is
the tensor product. -/
inductive Eqv : FreeAddMonoid (M × N) → FreeAddMonoid (M × N) → Prop
  | of_zero_left : ∀ n : N, Eqv (.of (0, n)) 0
  | of_zero_right : ∀ m : M, Eqv (.of (m, 0)) 0
  | of_add_left : ∀ (m₁ m₂ : M) (n : N), Eqv (.of (m₁, n) + .of (m₂, n)) (.of (m₁ + m₂, n))
  | of_add_right : ∀ (m : M) (n₁ n₂ : N), Eqv (.of (m, n₁) + .of (m, n₂)) (.of (m, n₁ + n₂))
  | of_smul : ∀ (r : R) (m : M) (n : N), Eqv (.of (r • m, n)) (.of (m, r • n))
  | add_comm : ∀ x y, Eqv (x + y) (y + x)
goal: TensorProduct.Eqv R M N (FreeAddMonoid.of (m, n₁) + FreeAddMonoid.of (m, n₂)) (FreeAddMonoid.of (m, n₁ + n₂))

full_name: TensorProduct.Eqv.of_zero_left
code: /-- The relation on `FreeAddMonoid (M × N)` that generates a congruence whose quotient is
the tensor product. -/
inductive Eqv : FreeAddMonoid (M × N) → FreeAddMonoid (M × N) → Prop
  | of_zero_left : ∀ n : N, Eqv (.of (0, n)) 0
  | of_zero_right : ∀ m : M, Eqv (.of (m, 0)) 0
  | of_add_left : ∀ (m₁ m₂ : M) (n : N), Eqv (.of (m₁, n) + .of (m₂, n)) (.of (m₁ + m₂, n))
  | of_add_right : ∀ (m : M) (n₁ n₂ : N), Eqv (.of (m, n₁) + .of (m, n₂)) (.of (m, n₁ + n₂))
  | of_smul : ∀ (r : R) (m : M) (n : N), Eqv (.of (r • m, n)) (.of (m, r • n))
  | add_comm : ∀ x y, Eqv (x + y) (y + x)
goal: TensorProduct.Eqv R M N (FreeAddMonoid.of (0, n)) 0

full_name: TensorProduct.Eqv.add_comm
code: /-- The relation on `FreeAddMonoid (M × N)` that generates a congruence whose quotient is
the tensor product. -/
inductive Eqv : FreeAddMonoid (M × N) → FreeAddMonoid (M × N) → Prop
  | of_zero_left : ∀ n : N, Eqv (.of (0, n)) 0
  | of_zero_right : ∀ m : M, Eqv (.of (m, 0)) 0
  | of_add_left : ∀ (m₁ m₂ : M) (n : N), Eqv (.of (m₁, n) + .of (m₂, n)) (.of (m₁ + m₂, n))
  | of_add_right : ∀ (m : M) (n₁ n₂ : N), Eqv (.of (m, n₁) + .of (m, n₂)) (.of (m, n₁ + n₂))
  | of_smul : ∀ (r : R) (m : M) (n : N), Eqv (.of (r • m, n)) (.of (m, r • n))
  | add_comm : ∀ x y, Eqv (x + y) (y + x)
goal: TensorProduct.Eqv R M N (x + y) (y + x)

full_name: TensorProduct
code: /-- The tensor product of two modules `M` and `N` over the same commutative semiring `R`.
The localized notations are `M ⊗ N` and `M ⊗[R] N`, accessed by `open scoped TensorProduct`. -/
def TensorProduct : Type _ 
goal: Type (max u_4 u_5)

full_name: TensorProduct.«_aux_Mathlib_LinearAlgebra_TensorProduct_Basic___macroRules_TensorProduct_term_⊗__1»
code: @[inherit_doc TensorProduct] scoped[TensorProduct] infixl:100 " ⊗ " => TensorProduct _
goal: Lean.Macro

full_name: TensorProduct.«_aux_Mathlib_LinearAlgebra_TensorProduct_Basic___macroRules_TensorProduct_term_⊗[_]__1»
code: @[inherit_doc] scoped[TensorProduct] notation:100 M " ⊗[" R "] " N:100 => TensorProduct R M N
goal: Lean.Macro

full_name: TensorProduct._aux_Mathlib_LinearAlgebra_TensorProduct_Basic___unexpand_TensorProduct_1
code: @[inherit_doc] scoped[TensorProduct] notation:100 M " ⊗[" R "] " N:100 => TensorProduct R M N
goal: Lean.PrettyPrinter.Unexpander

full_name: TensorProduct.add
code: protected instance add : Add (M ⊗[R] N) 
goal: Add (TensorProduct R M N)

full_name: TensorProduct.addZeroClass
code: instance addZeroClass : AddZeroClass (M ⊗[R] N) 
goal: AddZeroClass (TensorProduct R M N)

full_name: TensorProduct.addSemigroup
code: instance addSemigroup : AddSemigroup (M ⊗[R] N) 
goal: AddSemigroup (TensorProduct R M N)

full_name: TensorProduct.addCommSemigroup
code: instance addCommSemigroup : AddCommSemigroup (M ⊗[R] N) 
goal: AddCommSemigroup (TensorProduct R M N)

full_name: TensorProduct.instInhabited
code: instance : Inhabited (M ⊗[R] N) 
goal: Inhabited (TensorProduct R M N)

full_name: TensorProduct.tmul
code: /-- The canonical function `M → N → M ⊗ N`. The localized notations are `m ⊗ₜ n` and `m ⊗ₜ[R] n`,
accessed by `open scoped TensorProduct`. -/
def tmul (m : M) (n : N) : M ⊗[R] N 
goal: TensorProduct R M N

full_name: TensorProduct.«_aux_Mathlib_LinearAlgebra_TensorProduct_Basic___macroRules_TensorProduct_term_⊗ₜ__1»
code: /-- The canonical function `M → N → M ⊗ N`. -/
infixl:100 " ⊗ₜ " => tmul _
goal: Lean.Macro

full_name: TensorProduct._aux_Mathlib_LinearAlgebra_TensorProduct_Basic___unexpand_TensorProduct_tmul_1
code: /-- The canonical function `M → N → M ⊗ N`. -/
notation:100 x " ⊗ₜ[" R "] " y:100 => tmul R x y
goal: Lean.PrettyPrinter.Unexpander

full_name: TensorProduct.«_aux_Mathlib_LinearAlgebra_TensorProduct_Basic___macroRules_TensorProduct_term_⊗ₜ[_]__1»
code: /-- The canonical function `M → N → M ⊗ N`. -/
notation:100 x " ⊗ₜ[" R "] " y:100 => tmul R x y
goal: Lean.Macro

full_name: TensorProduct.induction_on
code: @[elab_as_elim, induction_eliminator]
protected theorem induction_on {motive : M ⊗[R] N → Prop} (z : M ⊗[R] N)
    (zero : motive 0)
    (tmul : ∀ x y, motive <| x ⊗ₜ[R] y)
    (add : ∀ x y, motive x → motive y → motive (x + y)) : motive z 
goal: motive z

full_name: TensorProduct.liftAddHom
code: /-- Lift an `R`-balanced map to the tensor product.

A map `f : M →+ N →+ P` additive in both components is `R`-balanced, or middle linear with respect
to `R`, if scalar multiplication in either argument is equivalent, `f (r • m) n = f m (r • n)`.

Note that strictly the first action should be a right-action by `R`, but for now `R` is commutative
so it doesn't matter. -/
-- TODO: use this to implement `lift` and `SMul.aux`. For now we do not do this as it causes
-- performance issues elsewhere.
def liftAddHom (f : M →+ N →+ P)
    (hf : ∀ (r : R) (m : M) (n : N), f (r • m) n = f m (r • n)) :
    M ⊗[R] N →+ P 
goal: TensorProduct R M N →+ P

full_name: TensorProduct.liftAddHom_tmul
code: @[simp]
theorem liftAddHom_tmul (f : M →+ N →+ P)
    (hf : ∀ (r : R) (m : M) (n : N), f (r • m) n = f m (r • n)) (m : M) (n : N) :
    liftAddHom f hf (m ⊗ₜ n) = f m n 
goal: (TensorProduct.liftAddHom f hf) (m ⊗ₜ[R] n) = (f m) n

full_name: TensorProduct.zero_tmul
code: @[simp]
theorem zero_tmul (n : N) : (0 : M) ⊗ₜ[R] n = 0 
goal: 0 ⊗ₜ[R] n = 0

full_name: TensorProduct.add_tmul
code: theorem add_tmul (m₁ m₂ : M) (n : N) : (m₁ + m₂) ⊗ₜ n = m₁ ⊗ₜ n + m₂ ⊗ₜ[R] n 
goal: (m₁ + m₂) ⊗ₜ[R] n = m₁ ⊗ₜ[R] n + m₂ ⊗ₜ[R] n

full_name: TensorProduct.tmul_zero
code: @[simp]
theorem tmul_zero (m : M) : m ⊗ₜ[R] (0 : N) = 0 
goal: m ⊗ₜ[R] 0 = 0

full_name: TensorProduct.tmul_add
code: theorem tmul_add (m : M) (n₁ n₂ : N) : m ⊗ₜ (n₁ + n₂) = m ⊗ₜ n₁ + m ⊗ₜ[R] n₂ 
goal: m ⊗ₜ[R] (n₁ + n₂) = m ⊗ₜ[R] n₁ + m ⊗ₜ[R] n₂

full_name: TensorProduct.uniqueLeft
code: instance uniqueLeft [Subsingleton M] : Unique (M ⊗[R] N) 
goal: Unique (TensorProduct R M N)

full_name: TensorProduct.uniqueRight
code: instance uniqueRight [Subsingleton N] : Unique (M ⊗[R] N) 
goal: Unique (TensorProduct R M N)

full_name: TensorProduct.CompatibleSMul
code: /-- A typeclass for `SMul` structures which can be moved across a tensor product.

This typeclass is generated automatically from an `IsScalarTower` instance, but exists so that
we can also add an instance for `AddCommGroup.intModule`, allowing `z •` to be moved even if
`R` does not support negation.

Note that `Module R' (M ⊗[R] N)` is available even without this typeclass on `R'`; it's only
needed if `TensorProduct.smul_tmul`, `TensorProduct.smul_tmul'`, or `TensorProduct.tmul_smul` is
used.
-/
class CompatibleSMul [DistribMulAction R' N] : Prop where
  smul_tmul : ∀ (r : R') (m : M) (n : N), (r • m) ⊗ₜ n = m ⊗ₜ[R] (r • n)
goal: Prop

full_name: TensorProduct.CompatibleSMul.smul_tmul
code: /-- A typeclass for `SMul` structures which can be moved across a tensor product.

This typeclass is generated automatically from an `IsScalarTower` instance, but exists so that
we can also add an instance for `AddCommGroup.intModule`, allowing `z •` to be moved even if
`R` does not support negation.

Note that `Module R' (M ⊗[R] N)` is available even without this typeclass on `R'`; it's only
needed if `TensorProduct.smul_tmul`, `TensorProduct.smul_tmul'`, or `TensorProduct.tmul_smul` is
used.
-/
class CompatibleSMul [DistribMulAction R' N] : Prop where
  smul_tmul : ∀ (r : R') (m : M) (n : N), (r • m) ⊗ₜ n = m ⊗ₜ[R] (r • n)
goal: (r • m) ⊗ₜ[R] n = m ⊗ₜ[R] (r • n)

full_name: TensorProduct.CompatibleSMul.isScalarTower
code: /-- Note that this provides the default `CompatibleSMul R R M N` instance through
`IsScalarTower.left`. -/
instance (priority := 100) CompatibleSMul.isScalarTower [SMul R' R] [IsScalarTower R' R M]
    [DistribMulAction R' N] [IsScalarTower R' R N] : CompatibleSMul R R' M N 
goal: TensorProduct.CompatibleSMul R R' M N

full_name: TensorProduct.smul_tmul
code: /-- `smul` can be moved from one side of the product to the other . -/
theorem smul_tmul [DistribMulAction R' N] [CompatibleSMul R R' M N] (r : R') (m : M) (n : N) :
    (r • m) ⊗ₜ n = m ⊗ₜ[R] (r • n) 
goal: (r • m) ⊗ₜ[R] n = m ⊗ₜ[R] (r • n)

full_name: _private.Mathlib.LinearAlgebra.TensorProduct.Basic.0.TensorProduct.addMonoidWithWrongNSMul
code: private def addMonoidWithWrongNSMul : AddMonoid (M ⊗[R] N) 
goal: AddMonoid (TensorProduct R M N)

full_name: TensorProduct.SMul.aux
code: /-- Auxiliary function to defining scalar multiplication on tensor product. -/
def SMul.aux {R' : Type*} [SMul R' M] (r : R') : FreeAddMonoid (M × N) →+ M ⊗[R] N 
goal: FreeAddMonoid (M × N) →+ TensorProduct R M N

full_name: TensorProduct.SMul.aux_of
code: theorem SMul.aux_of {R' : Type*} [SMul R' M] (r : R') (m : M) (n : N) :
    SMul.aux r (.of (m, n)) = (r • m) ⊗ₜ[R] n 
goal: (TensorProduct.SMul.aux r) (FreeAddMonoid.of (m, n)) = (r • m) ⊗ₜ[R] n

full_name: TensorProduct.leftHasSMul
code: /-- Given two modules over a commutative semiring `R`, if one of the factors carries a
(distributive) action of a second type of scalars `R'`, which commutes with the action of `R`, then
the tensor product (over `R`) carries an action of `R'`.

This instance defines this `R'` action in the case that it is the left module which has the `R'`
action. Two natural ways in which this situation arises are:
 * Extension of scalars
 * A tensor product of a group representation with a module not carrying an action

Note that in the special case that `R = R'`, since `R` is commutative, we just get the usual scalar
action on a tensor product of two modules. This special case is important enough that, for
performance reasons, we define it explicitly below. -/
instance leftHasSMul : SMul R' (M ⊗[R] N) 
goal: SMul R' (TensorProduct R M N)

full_name: TensorProduct.instSMul
code: instance : SMul R (M ⊗[R] N) 
goal: SMul R (TensorProduct R M N)

full_name: TensorProduct.smul_zero
code: protected theorem smul_zero (r : R') : r • (0 : M ⊗[R] N) = 0 
goal: r • 0 = 0

full_name: TensorProduct.smul_add
code: protected theorem smul_add (r : R') (x y : M ⊗[R] N) : r • (x + y) = r • x + r • y 
goal: r • (x + y) = r • x + r • y

full_name: TensorProduct.zero_smul
code: protected theorem zero_smul (x : M ⊗[R] N) : (0 : R'') • x = 0 
goal: 0 • x = 0

full_name: TensorProduct.one_smul
code: protected theorem one_smul (x : M ⊗[R] N) : (1 : R') • x = x 
goal: 1 • x = x

full_name: TensorProduct.add_smul
code: protected theorem add_smul (r s : R'') (x : M ⊗[R] N) : (r + s) • x = r • x + s • x 
goal: (r + s) • x = r • x + s • x

full_name: TensorProduct.addMonoid
code: instance addMonoid : AddMonoid (M ⊗[R] N) 
goal: AddMonoid (TensorProduct R M N)

full_name: TensorProduct.addCommMonoid
code: instance addCommMonoid : AddCommMonoid (M ⊗[R] N) 
goal: AddCommMonoid (TensorProduct R M N)

full_name: TensorProduct.leftDistribMulAction
code: instance leftDistribMulAction : DistribMulAction R' (M ⊗[R] N) 
goal: DistribMulAction R' (TensorProduct R M N)

full_name: TensorProduct.instDistribMulAction
code: instance : DistribMulAction R (M ⊗[R] N) 
goal: DistribMulAction R (TensorProduct R M N)

full_name: TensorProduct.smul_tmul'
code: theorem smul_tmul' (r : R') (m : M) (n : N) : r • m ⊗ₜ[R] n = (r • m) ⊗ₜ n 
goal: r • m ⊗ₜ[R] n = (r • m) ⊗ₜ[R] n

full_name: TensorProduct.tmul_smul
code: @[simp]
theorem tmul_smul [DistribMulAction R' N] [CompatibleSMul R R' M N] (r : R') (x : M) (y : N) :
    x ⊗ₜ (r • y) = r • x ⊗ₜ[R] y 
goal: x ⊗ₜ[R] (r • y) = r • x ⊗ₜ[R] y

full_name: TensorProduct.smul_tmul_smul
code: theorem smul_tmul_smul (r s : R) (m : M) (n : N) : (r • m) ⊗ₜ[R] (s • n) = (r * s) • m ⊗ₜ[R] n 
goal: (r • m) ⊗ₜ[R] (s • n) = (r * s) • m ⊗ₜ[R] n

full_name: TensorProduct.leftModule
code: instance leftModule : Module R'' (M ⊗[R] N) 
goal: Module R'' (TensorProduct R M N)

full_name: TensorProduct.instModule
code: instance : Module R (M ⊗[R] N) 
goal: Module R (TensorProduct R M N)

full_name: TensorProduct.instIsCentralScalar
code: instance [Module R''ᵐᵒᵖ M] [IsCentralScalar R'' M] : IsCentralScalar R'' (M ⊗[R] N) 
goal: IsCentralScalar R'' (TensorProduct R M N)

full_name: TensorProduct.smulCommClass_left
code: /-- `SMulCommClass R' R'₂ M` implies `SMulCommClass R' R'₂ (M ⊗[R] N)` -/
instance smulCommClass_left [SMulCommClass R' R'₂ M] : SMulCommClass R' R'₂ (M ⊗[R] N) 
goal: SMulCommClass R' R'₂ (TensorProduct R M N)

full_name: TensorProduct.isScalarTower_left
code: /-- `IsScalarTower R'₂ R' M` implies `IsScalarTower R'₂ R' (M ⊗[R] N)` -/
instance isScalarTower_left [IsScalarTower R'₂ R' M] : IsScalarTower R'₂ R' (M ⊗[R] N) 
goal: IsScalarTower R'₂ R' (TensorProduct R M N)

full_name: TensorProduct.isScalarTower_right
code: /-- `IsScalarTower R'₂ R' N` implies `IsScalarTower R'₂ R' (M ⊗[R] N)` -/
instance isScalarTower_right [IsScalarTower R'₂ R' N] : IsScalarTower R'₂ R' (M ⊗[R] N) 
goal: IsScalarTower R'₂ R' (TensorProduct R M N)

full_name: TensorProduct.isScalarTower
code: /-- A short-cut instance for the common case, where the requirements for the `compatible_smul`
instances are sufficient. -/
instance isScalarTower [SMul R' R] [IsScalarTower R' R M] : IsScalarTower R' R (M ⊗[R] N) 
goal: IsScalarTower R' R (TensorProduct R M N)

full_name: TensorProduct.mk
code: /-- The canonical bilinear map `M → N → M ⊗[R] N`. -/
def mk : M →ₗ[R] N →ₗ[R] M ⊗[R] N 
goal: M →ₗ[R] N →ₗ[R] TensorProduct R M N

full_name: TensorProduct.mk_apply
code: @[simp]
theorem mk_apply (m : M) (n : N) : mk R M N m n = m ⊗ₜ n 
goal: ((TensorProduct.mk R M N) m) n = m ⊗ₜ[R] n

full_name: TensorProduct.ite_tmul
code: theorem ite_tmul (x₁ : M) (x₂ : N) (P : Prop) [Decidable P] :
    (if P then x₁ else 0) ⊗ₜ[R] x₂ = if P then x₁ ⊗ₜ x₂ else 0 
goal: (if P then x₁ else 0) ⊗ₜ[R] x₂ = if P then x₁ ⊗ₜ[R] x₂ else 0

full_name: TensorProduct.tmul_ite
code: theorem tmul_ite (x₁ : M) (x₂ : N) (P : Prop) [Decidable P] :
    (x₁ ⊗ₜ[R] if P then x₂ else 0) = if P then x₁ ⊗ₜ x₂ else 0 
goal: (x₁ ⊗ₜ[R] if P then x₂ else 0) = if P then x₁ ⊗ₜ[R] x₂ else 0

full_name: TensorProduct.sum_tmul
code: theorem sum_tmul {α : Type*} (s : Finset α) (m : α → M) (n : N) :
    (∑ a ∈ s, m a) ⊗ₜ[R] n = ∑ a ∈ s, m a ⊗ₜ[R] n 
goal: (∑ a ∈ s, m a) ⊗ₜ[R] n = ∑ a ∈ s, m a ⊗ₜ[R] n

full_name: TensorProduct.tmul_sum
code: theorem tmul_sum (m : M) {α : Type*} (s : Finset α) (n : α → N) :
    (m ⊗ₜ[R] ∑ a ∈ s, n a) = ∑ a ∈ s, m ⊗ₜ[R] n a 
goal: m ⊗ₜ[R] ∑ a ∈ s, n a = ∑ a ∈ s, m ⊗ₜ[R] n a

full_name: TensorProduct.span_tmul_eq_top
code: /-- The simple (aka pure) elements span the tensor product. -/
theorem span_tmul_eq_top : Submodule.span R { t : M ⊗[R] N | ∃ m n, m ⊗ₜ n = t } = ⊤ 
goal: Submodule.span R {t | ∃ m n, m ⊗ₜ[R] n = t} = ⊤

full_name: TensorProduct.map₂_mk_top_top_eq_top
code: @[simp]
theorem map₂_mk_top_top_eq_top : Submodule.map₂ (mk R M N) ⊤ ⊤ = ⊤ 
goal: Submodule.map₂ (TensorProduct.mk R M N) ⊤ ⊤ = ⊤

full_name: TensorProduct.exists_eq_tmul_of_forall
code: theorem exists_eq_tmul_of_forall (x : TensorProduct R M N)
    (h : ∀ (m₁ m₂ : M) (n₁ n₂ : N), ∃ m n, m₁ ⊗ₜ n₁ + m₂ ⊗ₜ n₂ = m ⊗ₜ[R] n) :
    ∃ m n, x = m ⊗ₜ n 
goal: ∃ m n, x = m ⊗ₜ[R] n

full_name: TensorProduct.liftAux
code: /-- Auxiliary function to constructing a linear map `M ⊗ N → P` given a bilinear map `M → N → P`
with the property that its composition with the canonical bilinear map `M → N → M ⊗ N` is
the given bilinear map `M → N → P`. -/
def liftAux : M ⊗[R] N →+ P 
goal: TensorProduct R M N →+ P

full_name: TensorProduct.liftAux_tmul
code: theorem liftAux_tmul (m n) : liftAux f (m ⊗ₜ n) = f m n 
goal: (TensorProduct.liftAux f) (m ⊗ₜ[R] n) = (f m) n

full_name: TensorProduct.liftAux.smul
code: @[simp]
theorem liftAux.smul (r : R) (x) : liftAux f (r • x) = r • liftAux f x 
goal: (TensorProduct.liftAux f) (r • x) = r • (TensorProduct.liftAux f) x

full_name: TensorProduct.lift
code: /-- Constructing a linear map `M ⊗ N → P` given a bilinear map `M → N → P` with the property that
its composition with the canonical bilinear map `M → N → M ⊗ N` is
the given bilinear map `M → N → P`. -/
def lift : M ⊗[R] N →ₗ[R] P 
goal: TensorProduct R M N →ₗ[R] P

full_name: TensorProduct.lift.tmul
code: @[simp]
theorem lift.tmul (x y) : lift f (x ⊗ₜ y) = f x y 
goal: (TensorProduct.lift f) (x ⊗ₜ[R] y) = (f x) y

full_name: TensorProduct.lift.tmul'
code: @[simp]
theorem lift.tmul' (x y) : (lift f).1 (x ⊗ₜ y) = f x y 
goal: (TensorProduct.lift f).toAddHom (x ⊗ₜ[R] y) = (f x) y

full_name: TensorProduct.ext'
code: theorem ext' {g h : M ⊗[R] N →ₗ[R] P} (H : ∀ x y, g (x ⊗ₜ y) = h (x ⊗ₜ y)) : g = h 
goal: g = h

full_name: TensorProduct.lift.unique
code: theorem lift.unique {g : M ⊗[R] N →ₗ[R] P} (H : ∀ x y, g (x ⊗ₜ y) = f x y) : g = lift f 
goal: g = TensorProduct.lift f

full_name: TensorProduct.lift_mk
code: theorem lift_mk : lift (mk R M N) = LinearMap.id 
goal: TensorProduct.lift (TensorProduct.mk R M N) = LinearMap.id

full_name: TensorProduct.lift_compr₂
code: theorem lift_compr₂ (g : P →ₗ[R] Q) : lift (f.compr₂ g) = g.comp (lift f) 
goal: TensorProduct.lift (f.compr₂ g) = g ∘ₗ TensorProduct.lift f

full_name: TensorProduct.lift_mk_compr₂
code: theorem lift_mk_compr₂ (f : M ⊗ N →ₗ[R] P) : lift ((mk R M N).compr₂ f) = f 
goal: TensorProduct.lift ((TensorProduct.mk R M N).compr₂ f) = f

full_name: TensorProduct.ext
code: /-- This used to be an `@[ext]` lemma, but it fails very slowly when the `ext` tactic tries to apply
it in some cases, notably when one wants to show equality of two linear maps. The `@[ext]`
attribute is now added locally where it is needed. Using this as the `@[ext]` lemma instead of
`TensorProduct.ext'` allows `ext` to apply lemmas specific to `M →ₗ _` and `N →ₗ _`.

See note [partially-applied ext lemmas]. -/
theorem ext {g h : M ⊗ N →ₗ[R] P} (H : (mk R M N).compr₂ g = (mk R M N).compr₂ h) : g = h 
goal: g = h

full_name: TensorProduct.uncurry
code: /-- Linearly constructing a linear map `M ⊗ N → P` given a bilinear map `M → N → P`
with the property that its composition with the canonical bilinear map `M → N → M ⊗ N` is
the given bilinear map `M → N → P`. -/
def uncurry : (M →ₗ[R] N →ₗ[R] P) →ₗ[R] M ⊗[R] N →ₗ[R] P 
goal: (M →ₗ[R] N →ₗ[R] P) →ₗ[R] TensorProduct R M N →ₗ[R] P

full_name: TensorProduct.uncurry_apply
code: @[simp]
theorem uncurry_apply (f : M →ₗ[R] N →ₗ[R] P) (m : M) (n : N) :
    uncurry R M N P f (m ⊗ₜ n) = f m n 
goal: ((TensorProduct.uncurry R M N P) f) (m ⊗ₜ[R] n) = (f m) n

full_name: TensorProduct.lift.equiv
code: /-- A linear equivalence constructing a linear map `M ⊗ N → P` given a bilinear map `M → N → P`
with the property that its composition with the canonical bilinear map `M → N → M ⊗ N` is
the given bilinear map `M → N → P`. -/
def lift.equiv : (M →ₗ[R] N →ₗ[R] P) ≃ₗ[R] M ⊗[R] N →ₗ[R] P 
goal: (M →ₗ[R] N →ₗ[R] P) ≃ₗ[R] TensorProduct R M N →ₗ[R] P

full_name: TensorProduct.lift.equiv_apply
code: @[simp]
theorem lift.equiv_apply (f : M →ₗ[R] N →ₗ[R] P) (m : M) (n : N) :
    lift.equiv R M N P f (m ⊗ₜ n) = f m n 
goal: ((TensorProduct.lift.equiv R M N P) f) (m ⊗ₜ[R] n) = (f m) n

full_name: TensorProduct.lift.equiv_symm_apply
code: @[simp]
theorem lift.equiv_symm_apply (f : M ⊗[R] N →ₗ[R] P) (m : M) (n : N) :
    (lift.equiv R M N P).symm f m n = f (m ⊗ₜ n) 
goal: (((TensorProduct.lift.equiv R M N P).symm f) m) n = f (m ⊗ₜ[R] n)

full_name: TensorProduct.lcurry
code: /-- Given a linear map `M ⊗ N → P`, compose it with the canonical bilinear map `M → N → M ⊗ N` to
form a bilinear map `M → N → P`. -/
def lcurry : (M ⊗[R] N →ₗ[R] P) →ₗ[R] M →ₗ[R] N →ₗ[R] P 
goal: (TensorProduct R M N →ₗ[R] P) →ₗ[R] M →ₗ[R] N →ₗ[R] P

full_name: TensorProduct.lcurry_apply
code: @[simp]
theorem lcurry_apply (f : M ⊗[R] N →ₗ[R] P) (m : M) (n : N) : lcurry R M N P f m n = f (m ⊗ₜ n) 
goal: (((TensorProduct.lcurry R M N P) f) m) n = f (m ⊗ₜ[R] n)

full_name: TensorProduct.curry
code: /-- Given a linear map `M ⊗ N → P`, compose it with the canonical bilinear map `M → N → M ⊗ N` to
form a bilinear map `M → N → P`. -/
def curry (f : M ⊗[R] N →ₗ[R] P) : M →ₗ[R] N →ₗ[R] P 
goal: M →ₗ[R] N →ₗ[R] P

full_name: TensorProduct.curry_apply
code: @[simp]
theorem curry_apply (f : M ⊗ N →ₗ[R] P) (m : M) (n : N) : curry f m n = f (m ⊗ₜ n) 
goal: ((TensorProduct.curry f) m) n = f (m ⊗ₜ[R] n)

full_name: TensorProduct.curry_injective
code: theorem curry_injective : Function.Injective (curry : (M ⊗[R] N →ₗ[R] P) → M →ₗ[R] N →ₗ[R] P) 
goal: Function.Injective TensorProduct.curry

full_name: TensorProduct.ext_threefold
code: theorem ext_threefold {g h : (M ⊗[R] N) ⊗[R] P →ₗ[R] Q}
    (H : ∀ x y z, g (x ⊗ₜ y ⊗ₜ z) = h (x ⊗ₜ y ⊗ₜ z)) : g = h 
goal: g = h

full_name: TensorProduct.ext_fourfold
code: theorem ext_fourfold {g h : ((M ⊗[R] N) ⊗[R] P) ⊗[R] Q →ₗ[R] S}
    (H : ∀ w x y z, g (w ⊗ₜ x ⊗ₜ y ⊗ₜ z) = h (w ⊗ₜ x ⊗ₜ y ⊗ₜ z)) : g = h 
goal: g = h

full_name: TensorProduct.ext_fourfold'
code: /-- Two linear maps (M ⊗ N) ⊗ (P ⊗ Q) → S which agree on all elements of the
form (m ⊗ₜ n) ⊗ₜ (p ⊗ₜ q) are equal. -/
theorem ext_fourfold' {φ ψ : (M ⊗[R] N) ⊗[R] P ⊗[R] Q →ₗ[R] S}
    (H : ∀ w x y z, φ (w ⊗ₜ x ⊗ₜ (y ⊗ₜ z)) = ψ (w ⊗ₜ x ⊗ₜ (y ⊗ₜ z))) : φ = ψ 
goal: φ = ψ

full_name: TensorProduct.lid
code: /-- The base ring is a left identity for the tensor product of modules, up to linear equivalence.
-/
protected def lid : R ⊗[R] M ≃ₗ[R] M 
goal: TensorProduct R R M ≃ₗ[R] M

full_name: TensorProduct.lid_tmul
code: @[simp]
theorem lid_tmul (m : M) (r : R) : (TensorProduct.lid R M : R ⊗ M → M) (r ⊗ₜ m) = r • m 
goal: (TensorProduct.lid R M) (r ⊗ₜ[R] m) = r • m

full_name: TensorProduct.lid_symm_apply
code: @[simp]
theorem lid_symm_apply (m : M) : (TensorProduct.lid R M).symm m = 1 ⊗ₜ m 
goal: (TensorProduct.lid R M).symm m = 1 ⊗ₜ[R] m

full_name: TensorProduct.comm
code: /-- The tensor product of modules is commutative, up to linear equivalence.
-/
protected def comm : M ⊗[R] N ≃ₗ[R] N ⊗[R] M 
goal: TensorProduct R M N ≃ₗ[R] TensorProduct R N M

full_name: TensorProduct.comm_tmul
code: @[simp]
theorem comm_tmul (m : M) (n : N) : (TensorProduct.comm R M N) (m ⊗ₜ n) = n ⊗ₜ m 
goal: (TensorProduct.comm R M N) (m ⊗ₜ[R] n) = n ⊗ₜ[R] m

full_name: TensorProduct.comm_symm_tmul
code: @[simp]
theorem comm_symm_tmul (m : M) (n : N) : (TensorProduct.comm R M N).symm (n ⊗ₜ m) = m ⊗ₜ n 
goal: (TensorProduct.comm R M N).symm (n ⊗ₜ[R] m) = m ⊗ₜ[R] n

full_name: TensorProduct.lift_comp_comm_eq
code: lemma lift_comp_comm_eq  (f : M →ₗ[R] N →ₗ[R] P) :
    lift f ∘ₗ TensorProduct.comm R N M = lift f.flip 
goal: TensorProduct.lift f ∘ₗ ↑(TensorProduct.comm R N M) = TensorProduct.lift f.flip

full_name: TensorProduct.rid
code: /-- The base ring is a right identity for the tensor product of modules, up to linear equivalence.
-/
protected def rid : M ⊗[R] R ≃ₗ[R] M 
goal: TensorProduct R M R ≃ₗ[R] M

full_name: TensorProduct.rid_tmul
code: @[simp]
theorem rid_tmul (m : M) (r : R) : (TensorProduct.rid R M) (m ⊗ₜ r) = r • m 
goal: (TensorProduct.rid R M) (m ⊗ₜ[R] r) = r • m

full_name: TensorProduct.rid_symm_apply
code: @[simp]
theorem rid_symm_apply (m : M) : (TensorProduct.rid R M).symm m = m ⊗ₜ 1 
goal: (TensorProduct.rid R M).symm m = m ⊗ₜ[R] 1

full_name: TensorProduct.lid_eq_rid
code: theorem lid_eq_rid : TensorProduct.lid R R = TensorProduct.rid R R 
goal: TensorProduct.lid R R = TensorProduct.rid R R

full_name: TensorProduct.assoc
code: /-- The associator for tensor product of R-modules, as a linear equivalence. -/
protected def assoc : (M ⊗[R] N) ⊗[R] P ≃ₗ[R] M ⊗[R] N ⊗[R] P 
goal: TensorProduct R (TensorProduct R M N) P ≃ₗ[R] TensorProduct R M (TensorProduct R N P)

full_name: TensorProduct.assoc_tmul
code: @[simp]
theorem assoc_tmul (m : M) (n : N) (p : P) :
    (TensorProduct.assoc R M N P) (m ⊗ₜ n ⊗ₜ p) = m ⊗ₜ (n ⊗ₜ p) 
goal: (TensorProduct.assoc R M N P) ((m ⊗ₜ[R] n) ⊗ₜ[R] p) = m ⊗ₜ[R] n ⊗ₜ[R] p

full_name: TensorProduct.assoc_symm_tmul
code: @[simp]
theorem assoc_symm_tmul (m : M) (n : N) (p : P) :
    (TensorProduct.assoc R M N P).symm (m ⊗ₜ (n ⊗ₜ p)) = m ⊗ₜ n ⊗ₜ p 
goal: (TensorProduct.assoc R M N P).symm (m ⊗ₜ[R] n ⊗ₜ[R] p) = (m ⊗ₜ[R] n) ⊗ₜ[R] p

full_name: TensorProduct.map
code: /-- The tensor product of a pair of linear maps between modules. -/
def map (f : M →ₗ[R] P) (g : N →ₗ[R] Q) : M ⊗[R] N →ₗ[R] P ⊗[R] Q 
goal: TensorProduct R M N →ₗ[R] TensorProduct R P Q

full_name: TensorProduct.map_tmul
code: @[simp]
theorem map_tmul (f : M →ₗ[R] P) (g : N →ₗ[R] Q) (m : M) (n : N) : map f g (m ⊗ₜ n) = f m ⊗ₜ g n 
goal: (TensorProduct.map f g) (m ⊗ₜ[R] n) = f m ⊗ₜ[R] g n

full_name: TensorProduct.map_comp_comm_eq
code: /-- Given linear maps `f : M → P`, `g : N → Q`, if we identify `M ⊗ N` with `N ⊗ M` and `P ⊗ Q`
with `Q ⊗ P`, then this lemma states that `f ⊗ g = g ⊗ f`. -/
lemma map_comp_comm_eq (f : M →ₗ[R] P) (g : N →ₗ[R] Q) :
    map f g ∘ₗ TensorProduct.comm R N M = TensorProduct.comm R Q P ∘ₗ map g f 
goal: TensorProduct.map f g ∘ₗ ↑(TensorProduct.comm R N M) = ↑(TensorProduct.comm R Q P) ∘ₗ TensorProduct.map g f

full_name: TensorProduct.map_comm
code: lemma map_comm (f : M →ₗ[R] P) (g : N →ₗ[R] Q) (x : N ⊗[R] M) :
    map f g (TensorProduct.comm R N M x) = TensorProduct.comm R Q P (map g f x) 
goal: (TensorProduct.map f g) ((TensorProduct.comm R N M) x) = (TensorProduct.comm R Q P) ((TensorProduct.map g f) x)

full_name: TensorProduct.map_map_comp_assoc_eq
code: /-- Given linear maps `f : M → Q`, `g : N → S`, and `h : P → T`, if we identify `(M ⊗ N) ⊗ P`
with `M ⊗ (N ⊗ P)` and `(Q ⊗ S) ⊗ T` with `Q ⊗ (S ⊗ T)`, then this lemma states that
`f ⊗ (g ⊗ h) = (f ⊗ g) ⊗ h`. -/
lemma map_map_comp_assoc_eq (f : M →ₗ[R] Q) (g : N →ₗ[R] S) (h : P →ₗ[R] T) :
    map f (map g h) ∘ₗ TensorProduct.assoc R M N P =
      TensorProduct.assoc R Q S T ∘ₗ map (map f g) h 
goal: TensorProduct.map f (TensorProduct.map g h) ∘ₗ ↑(TensorProduct.assoc R M N P) =
  ↑(TensorProduct.assoc R Q S T) ∘ₗ TensorProduct.map (TensorProduct.map f g) h

full_name: TensorProduct.map_map_assoc
code: lemma map_map_assoc (f : M →ₗ[R] Q) (g : N →ₗ[R] S) (h : P →ₗ[R] T) (x : (M ⊗[R] N) ⊗[R] P) :
    map f (map g h) (TensorProduct.assoc R M N P x) =
      TensorProduct.assoc R Q S T (map (map f g) h x) 
goal: (TensorProduct.map f (TensorProduct.map g h)) ((TensorProduct.assoc R M N P) x) =
  (TensorProduct.assoc R Q S T) ((TensorProduct.map (TensorProduct.map f g) h) x)

full_name: TensorProduct.map_map_comp_assoc_symm_eq
code: /-- Given linear maps `f : M → Q`, `g : N → S`, and `h : P → T`, if we identify `M ⊗ (N ⊗ P)`
with `(M ⊗ N) ⊗ P` and `Q ⊗ (S ⊗ T)` with `(Q ⊗ S) ⊗ T`, then this lemma states that
`(f ⊗ g) ⊗ h = f ⊗ (g ⊗ h)`. -/
lemma map_map_comp_assoc_symm_eq (f : M →ₗ[R] Q) (g : N →ₗ[R] S) (h : P →ₗ[R] T) :
    map (map f g) h ∘ₗ (TensorProduct.assoc R M N P).symm =
      (TensorProduct.assoc R Q S T).symm ∘ₗ map f (map g h) 
goal: TensorProduct.map (TensorProduct.map f g) h ∘ₗ ↑(TensorProduct.assoc R M N P).symm =
  ↑(TensorProduct.assoc R Q S T).symm ∘ₗ TensorProduct.map f (TensorProduct.map g h)

full_name: TensorProduct.map_map_assoc_symm
code: lemma map_map_assoc_symm (f : M →ₗ[R] Q) (g : N →ₗ[R] S) (h : P →ₗ[R] T) (x : M ⊗[R] (N ⊗[R] P)) :
    map (map f g) h ((TensorProduct.assoc R M N P).symm x) =
      (TensorProduct.assoc R Q S T).symm (map f (map g h) x) 
goal: (TensorProduct.map (TensorProduct.map f g) h) ((TensorProduct.assoc R M N P).symm x) =
  (TensorProduct.assoc R Q S T).symm ((TensorProduct.map f (TensorProduct.map g h)) x)

full_name: TensorProduct.map_range_eq_span_tmul
code: theorem map_range_eq_span_tmul (f : M →ₗ[R] P) (g : N →ₗ[R] Q) :
    range (map f g) = Submodule.span R { t | ∃ m n, f m ⊗ₜ g n = t } 
goal: LinearMap.range (TensorProduct.map f g) = Submodule.span R {t | ∃ m n, f m ⊗ₜ[R] g n = t}

full_name: TensorProduct.mapIncl
code: /-- Given submodules `p ⊆ P` and `q ⊆ Q`, this is the natural map: `p ⊗ q → P ⊗ Q`. -/
@[simp]
def mapIncl (p : Submodule R P) (q : Submodule R Q) : p ⊗[R] q →ₗ[R] P ⊗[R] Q 
goal: TensorProduct R ↥p ↥q →ₗ[R] TensorProduct R P Q

full_name: TensorProduct.range_mapIncl
code: lemma range_mapIncl (p : Submodule R P) (q : Submodule R Q) :
    LinearMap.range (mapIncl p q) = Submodule.span R (Set.image2 (· ⊗ₜ ·) p q) 
goal: LinearMap.range (TensorProduct.mapIncl p q) = Submodule.span R (Set.image2 (fun x x_1 => x ⊗ₜ[R] x_1) ↑p ↑q)

full_name: TensorProduct.map₂_eq_range_lift_comp_mapIncl
code: theorem map₂_eq_range_lift_comp_mapIncl (f : P →ₗ[R] Q →ₗ[R] M)
    (p : Submodule R P) (q : Submodule R Q) :
    Submodule.map₂ f p q = LinearMap.range (lift f ∘ₗ mapIncl p q) 
goal: Submodule.map₂ f p q = LinearMap.range (TensorProduct.lift f ∘ₗ TensorProduct.mapIncl p q)

full_name: TensorProduct.map_comp
code: theorem map_comp (f₂ : P →ₗ[R] P') (f₁ : M →ₗ[R] P) (g₂ : Q →ₗ[R] Q') (g₁ : N →ₗ[R] Q) :
    map (f₂.comp f₁) (g₂.comp g₁) = (map f₂ g₂).comp (map f₁ g₁) 
goal: TensorProduct.map (f₂ ∘ₗ f₁) (g₂ ∘ₗ g₁) = TensorProduct.map f₂ g₂ ∘ₗ TensorProduct.map f₁ g₁

full_name: TensorProduct.range_mapIncl_mono
code: lemma range_mapIncl_mono {p p' : Submodule R P} {q q' : Submodule R Q} (hp : p ≤ p') (hq : q ≤ q') :
    LinearMap.range (mapIncl p q) ≤ LinearMap.range (mapIncl p' q') 
goal: LinearMap.range (TensorProduct.mapIncl p q) ≤ LinearMap.range (TensorProduct.mapIncl p' q')

full_name: TensorProduct.lift_comp_map
code: theorem lift_comp_map (i : P →ₗ[R] Q →ₗ[R] Q') (f : M →ₗ[R] P) (g : N →ₗ[R] Q) :
    (lift i).comp (map f g) = lift ((i.comp f).compl₂ g) 
goal: TensorProduct.lift i ∘ₗ TensorProduct.map f g = TensorProduct.lift ((i ∘ₗ f).compl₂ g)

full_name: TensorProduct.map_id
code: @[simp]
theorem map_id : map (id : M →ₗ[R] M) (id : N →ₗ[R] N) = .id 
goal: TensorProduct.map LinearMap.id LinearMap.id = LinearMap.id

full_name: TensorProduct.map_one
code: @[simp]
theorem map_one : map (1 : M →ₗ[R] M) (1 : N →ₗ[R] N) = 1 
goal: TensorProduct.map 1 1 = 1

full_name: TensorProduct.map_mul
code: theorem map_mul (f₁ f₂ : M →ₗ[R] M) (g₁ g₂ : N →ₗ[R] N) :
    map (f₁ * f₂) (g₁ * g₂) = map f₁ g₁ * map f₂ g₂ 
goal: TensorProduct.map (f₁ * f₂) (g₁ * g₂) = TensorProduct.map f₁ g₁ * TensorProduct.map f₂ g₂

full_name: TensorProduct.map_pow
code: @[simp]
protected theorem map_pow (f : M →ₗ[R] M) (g : N →ₗ[R] N) (n : ℕ) :
    map f g ^ n = map (f ^ n) (g ^ n) 
goal: TensorProduct.map f g ^ n = TensorProduct.map (f ^ n) (g ^ n)

full_name: TensorProduct.map_add_left
code: theorem map_add_left (f₁ f₂ : M →ₗ[R] P) (g : N →ₗ[R] Q) :
    map (f₁ + f₂) g = map f₁ g + map f₂ g 
goal: TensorProduct.map (f₁ + f₂) g = TensorProduct.map f₁ g + TensorProduct.map f₂ g

full_name: TensorProduct.map_add_right
code: theorem map_add_right (f : M →ₗ[R] P) (g₁ g₂ : N →ₗ[R] Q) :
    map f (g₁ + g₂) = map f g₁ + map f g₂ 
goal: TensorProduct.map f (g₁ + g₂) = TensorProduct.map f g₁ + TensorProduct.map f g₂

full_name: TensorProduct.map_smul_left
code: theorem map_smul_left (r : R) (f : M →ₗ[R] P) (g : N →ₗ[R] Q) : map (r • f) g = r • map f g 
goal: TensorProduct.map (r • f) g = r • TensorProduct.map f g

full_name: TensorProduct.map_smul_right
code: theorem map_smul_right (r : R) (f : M →ₗ[R] P) (g : N →ₗ[R] Q) : map f (r • g) = r • map f g 
goal: TensorProduct.map f (r • g) = r • TensorProduct.map f g

full_name: TensorProduct.mapBilinear
code: /-- The tensor product of a pair of linear maps between modules, bilinear in both maps. -/
def mapBilinear : (M →ₗ[R] P) →ₗ[R] (N →ₗ[R] Q) →ₗ[R] M ⊗[R] N →ₗ[R] P ⊗[R] Q 
goal: (M →ₗ[R] P) →ₗ[R] (N →ₗ[R] Q) →ₗ[R] TensorProduct R M N →ₗ[R] TensorProduct R P Q

full_name: TensorProduct.lTensorHomToHomLTensor
code: /-- The canonical linear map from `P ⊗[R] (M →ₗ[R] Q)` to `(M →ₗ[R] P ⊗[R] Q)` -/
def lTensorHomToHomLTensor : P ⊗[R] (M →ₗ[R] Q) →ₗ[R] M →ₗ[R] P ⊗[R] Q 
goal: TensorProduct R P (M →ₗ[R] Q) →ₗ[R] M →ₗ[R] TensorProduct R P Q

full_name: TensorProduct.rTensorHomToHomRTensor
code: /-- The canonical linear map from `(M →ₗ[R] P) ⊗[R] Q` to `(M →ₗ[R] P ⊗[R] Q)` -/
def rTensorHomToHomRTensor : (M →ₗ[R] P) ⊗[R] Q →ₗ[R] M →ₗ[R] P ⊗[R] Q 
goal: TensorProduct R (M →ₗ[R] P) Q →ₗ[R] M →ₗ[R] TensorProduct R P Q

full_name: TensorProduct.homTensorHomMap
code: /-- The linear map from `(M →ₗ P) ⊗ (N →ₗ Q)` to `(M ⊗ N →ₗ P ⊗ Q)` sending `f ⊗ₜ g` to
the `TensorProduct.map f g`, the tensor product of the two maps. -/
def homTensorHomMap : (M →ₗ[R] P) ⊗[R] (N →ₗ[R] Q) →ₗ[R] M ⊗[R] N →ₗ[R] P ⊗[R] Q 
goal: TensorProduct R (M →ₗ[R] P) (N →ₗ[R] Q) →ₗ[R] TensorProduct R M N →ₗ[R] TensorProduct R P Q

full_name: TensorProduct.map₂
code: /--
This is a binary version of `TensorProduct.map`: Given a bilinear map `f : M ⟶ P ⟶ Q` and a
bilinear map `g : N ⟶ S ⟶ T`, if we think `f` and `g` as linear maps with two inputs, then
`map₂ f g` is a bilinear map taking two inputs `M ⊗ N → P ⊗ S → Q ⊗ S` defined by
`map₂ f g (m ⊗ n) (p ⊗ s) = f m p ⊗ g n s`.

Mathematically, `TensorProduct.map₂` is defined as the composition
`M ⊗ N -map→ Hom(P, Q) ⊗ Hom(S, T) -homTensorHomMap→ Hom(P ⊗ S, Q ⊗ T)`.
-/
def map₂ (f : M →ₗ[R] P →ₗ[R] Q) (g : N →ₗ[R] S →ₗ[R] T) :
    M ⊗[R] N →ₗ[R] P ⊗[R] S →ₗ[R] Q ⊗[R] T 
goal: TensorProduct R M N →ₗ[R] TensorProduct R P S →ₗ[R] TensorProduct R Q T

full_name: TensorProduct.mapBilinear_apply
code: @[simp]
theorem mapBilinear_apply (f : M →ₗ[R] P) (g : N →ₗ[R] Q) : mapBilinear R M N P Q f g = map f g 
goal: ((TensorProduct.mapBilinear R M N P Q) f) g = TensorProduct.map f g

full_name: TensorProduct.lTensorHomToHomLTensor_apply
code: @[simp]
theorem lTensorHomToHomLTensor_apply (p : P) (f : M →ₗ[R] Q) (m : M) :
    lTensorHomToHomLTensor R M P Q (p ⊗ₜ f) m = p ⊗ₜ f m 
goal: ((TensorProduct.lTensorHomToHomLTensor R M P Q) (p ⊗ₜ[R] f)) m = p ⊗ₜ[R] f m

full_name: TensorProduct.rTensorHomToHomRTensor_apply
code: @[simp]
theorem rTensorHomToHomRTensor_apply (f : M →ₗ[R] P) (q : Q) (m : M) :
    rTensorHomToHomRTensor R M P Q (f ⊗ₜ q) m = f m ⊗ₜ q 
goal: ((TensorProduct.rTensorHomToHomRTensor R M P Q) (f ⊗ₜ[R] q)) m = f m ⊗ₜ[R] q

full_name: TensorProduct.homTensorHomMap_apply
code: @[simp]
theorem homTensorHomMap_apply (f : M →ₗ[R] P) (g : N →ₗ[R] Q) :
    homTensorHomMap R M N P Q (f ⊗ₜ g) = map f g 
goal: (TensorProduct.homTensorHomMap R M N P Q) (f ⊗ₜ[R] g) = TensorProduct.map f g

full_name: TensorProduct.map₂_apply_tmul
code: @[simp]
theorem map₂_apply_tmul (f : M →ₗ[R] P →ₗ[R] Q) (g : N →ₗ[R] S →ₗ[R] T) (m : M) (n : N) :
    map₂ f g (m ⊗ₜ n) = map (f m) (g n) 
goal: (TensorProduct.map₂ f g) (m ⊗ₜ[R] n) = TensorProduct.map (f m) (g n)

full_name: TensorProduct.map_zero_left
code: @[simp]
theorem map_zero_left (g : N →ₗ[R] Q) : map (0 : M →ₗ[R] P) g = 0 
goal: TensorProduct.map 0 g = 0

full_name: TensorProduct.map_zero_right
code: @[simp]
theorem map_zero_right (f : M →ₗ[R] P) : map f (0 : N →ₗ[R] Q) = 0 
goal: TensorProduct.map f 0 = 0

full_name: TensorProduct.congr
code: /-- If `M` and `P` are linearly equivalent and `N` and `Q` are linearly equivalent
then `M ⊗ N` and `P ⊗ Q` are linearly equivalent. -/
def congr (f : M ≃ₗ[R] P) (g : N ≃ₗ[R] Q) : M ⊗[R] N ≃ₗ[R] P ⊗[R] Q 
goal: TensorProduct R M N ≃ₗ[R] TensorProduct R P Q

full_name: TensorProduct.congr_tmul
code: @[simp]
theorem congr_tmul (f : M ≃ₗ[R] P) (g : N ≃ₗ[R] Q) (m : M) (n : N) :
    congr f g (m ⊗ₜ n) = f m ⊗ₜ g n 
goal: (TensorProduct.congr f g) (m ⊗ₜ[R] n) = f m ⊗ₜ[R] g n

full_name: TensorProduct.congr_symm_tmul
code: @[simp]
theorem congr_symm_tmul (f : M ≃ₗ[R] P) (g : N ≃ₗ[R] Q) (p : P) (q : Q) :
    (congr f g).symm (p ⊗ₜ q) = f.symm p ⊗ₜ g.symm q 
goal: (TensorProduct.congr f g).symm (p ⊗ₜ[R] q) = f.symm p ⊗ₜ[R] g.symm q

full_name: TensorProduct.congr_symm
code: theorem congr_symm (f : M ≃ₗ[R] P) (g : N ≃ₗ[R] Q) : (congr f g).symm = congr f.symm g.symm 
goal: (TensorProduct.congr f g).symm = TensorProduct.congr f.symm g.symm

full_name: TensorProduct.congr_refl_refl
code: @[simp] theorem congr_refl_refl : congr (.refl R M) (.refl R N) = .refl R _ 
goal: TensorProduct.congr (LinearEquiv.refl R M) (LinearEquiv.refl R N) = LinearEquiv.refl R (TensorProduct R M N)

full_name: TensorProduct.congr_trans
code: theorem congr_trans (f : M ≃ₗ[R] P) (g : N ≃ₗ[R] Q) (f' : P ≃ₗ[R] S) (g' : Q ≃ₗ[R] T) :
    congr (f ≪≫ₗ f') (g ≪≫ₗ g') = congr f g ≪≫ₗ congr f' g' 
goal: TensorProduct.congr (f ≪≫ₗ f') (g ≪≫ₗ g') = TensorProduct.congr f g ≪≫ₗ TensorProduct.congr f' g'

full_name: TensorProduct.congr_mul
code: theorem congr_mul (f : M ≃ₗ[R] M) (g : N ≃ₗ[R] N) (f' : M ≃ₗ[R] M) (g' : N ≃ₗ[R] N) :
    congr (f * f') (g * g') = congr f g * congr f' g' 
goal: TensorProduct.congr (f * f') (g * g') = TensorProduct.congr f g * TensorProduct.congr f' g'

full_name: TensorProduct.congr_pow
code: @[simp] theorem congr_pow (f : M ≃ₗ[R] M) (g : N ≃ₗ[R] N) (n : ℕ) :
    congr f g ^ n = congr (f ^ n) (g ^ n) 
goal: TensorProduct.congr f g ^ n = TensorProduct.congr (f ^ n) (g ^ n)

full_name: TensorProduct.congr_zpow
code: @[simp] theorem congr_zpow (f : M ≃ₗ[R] M) (g : N ≃ₗ[R] N) (n : ℤ) :
    congr f g ^ n = congr (f ^ n) (g ^ n) 
goal: TensorProduct.congr f g ^ n = TensorProduct.congr (f ^ n) (g ^ n)

full_name: TensorProduct.leftComm
code: /-- A tensor product analogue of `mul_left_comm`. -/
def leftComm : M ⊗[R] N ⊗[R] P ≃ₗ[R] N ⊗[R] M ⊗[R] P 
goal: TensorProduct R M (TensorProduct R N P) ≃ₗ[R] TensorProduct R N (TensorProduct R M P)

full_name: TensorProduct.leftComm_tmul
code: @[simp]
theorem leftComm_tmul (m : M) (n : N) (p : P) : leftComm R M N P (m ⊗ₜ (n ⊗ₜ p)) = n ⊗ₜ (m ⊗ₜ p) 
goal: (TensorProduct.leftComm R M N P) (m ⊗ₜ[R] n ⊗ₜ[R] p) = n ⊗ₜ[R] m ⊗ₜ[R] p

full_name: TensorProduct.leftComm_symm_tmul
code: @[simp]
theorem leftComm_symm_tmul (m : M) (n : N) (p : P) :
    (leftComm R M N P).symm (n ⊗ₜ (m ⊗ₜ p)) = m ⊗ₜ (n ⊗ₜ p) 
goal: (TensorProduct.leftComm R M N P).symm (n ⊗ₜ[R] m ⊗ₜ[R] p) = m ⊗ₜ[R] n ⊗ₜ[R] p

full_name: TensorProduct.tensorTensorTensorComm
code: /-- This special case is worth defining explicitly since it is useful for defining multiplication
on tensor products of modules carrying multiplications (e.g., associative rings, Lie rings, ...).

E.g., suppose `M = P` and `N = Q` and that `M` and `N` carry bilinear multiplications:
`M ⊗ M → M` and `N ⊗ N → N`. Using `map`, we can define `(M ⊗ M) ⊗ (N ⊗ N) → M ⊗ N` which, when
combined with this definition, yields a bilinear multiplication on `M ⊗ N`:
`(M ⊗ N) ⊗ (M ⊗ N) → M ⊗ N`. In particular we could use this to define the multiplication in
the `TensorProduct.semiring` instance (currently defined "by hand" using `TensorProduct.mul`).

See also `mul_mul_mul_comm`. -/
def tensorTensorTensorComm : (M ⊗[R] N) ⊗[R] P ⊗[R] Q ≃ₗ[R] (M ⊗[R] P) ⊗[R] N ⊗[R] Q 
goal: TensorProduct R (TensorProduct R M N) (TensorProduct R P Q) ≃ₗ[R]
  TensorProduct R (TensorProduct R M P) (TensorProduct R N Q)

full_name: TensorProduct.tensorTensorTensorComm_tmul
code: @[simp]
theorem tensorTensorTensorComm_tmul (m : M) (n : N) (p : P) (q : Q) :
    tensorTensorTensorComm R M N P Q (m ⊗ₜ n ⊗ₜ (p ⊗ₜ q)) = m ⊗ₜ p ⊗ₜ (n ⊗ₜ q) 
goal: (TensorProduct.tensorTensorTensorComm R M N P Q) ((m ⊗ₜ[R] n) ⊗ₜ[R] p ⊗ₜ[R] q) = (m ⊗ₜ[R] p) ⊗ₜ[R] n ⊗ₜ[R] q

full_name: TensorProduct.tensorTensorTensorComm_symm
code: @[simp]
theorem tensorTensorTensorComm_symm :
    (tensorTensorTensorComm R M N P Q).symm = tensorTensorTensorComm R M P N Q 
goal: (TensorProduct.tensorTensorTensorComm R M N P Q).symm = TensorProduct.tensorTensorTensorComm R M P N Q

full_name: TensorProduct.tensorTensorTensorAssoc
code: /-- This special case is useful for describing the interplay between `dualTensorHomEquiv` and
composition of linear maps.

E.g., composition of linear maps gives a map `(M → N) ⊗ (N → P) → (M → P)`, and applying
`dual_tensor_hom_equiv.symm` to the three hom-modules gives a map
`(M.dual ⊗ N) ⊗ (N.dual ⊗ P) → (M.dual ⊗ P)`, which agrees with the application of `contractRight`
on `N ⊗ N.dual` after the suitable rebracketting.
-/
def tensorTensorTensorAssoc : (M ⊗[R] N) ⊗[R] P ⊗[R] Q ≃ₗ[R] (M ⊗[R] N ⊗[R] P) ⊗[R] Q 
goal: TensorProduct R (TensorProduct R M N) (TensorProduct R P Q) ≃ₗ[R]
  TensorProduct R (TensorProduct R M (TensorProduct R N P)) Q

full_name: TensorProduct.tensorTensorTensorAssoc_tmul
code: @[simp]
theorem tensorTensorTensorAssoc_tmul (m : M) (n : N) (p : P) (q : Q) :
    tensorTensorTensorAssoc R M N P Q (m ⊗ₜ n ⊗ₜ (p ⊗ₜ q)) = m ⊗ₜ (n ⊗ₜ p) ⊗ₜ q 
goal: (TensorProduct.tensorTensorTensorAssoc R M N P Q) ((m ⊗ₜ[R] n) ⊗ₜ[R] p ⊗ₜ[R] q) = (m ⊗ₜ[R] n ⊗ₜ[R] p) ⊗ₜ[R] q

full_name: TensorProduct.tensorTensorTensorAssoc_symm_tmul
code: @[simp]
theorem tensorTensorTensorAssoc_symm_tmul (m : M) (n : N) (p : P) (q : Q) :
    (tensorTensorTensorAssoc R M N P Q).symm (m ⊗ₜ (n ⊗ₜ p) ⊗ₜ q) = m ⊗ₜ n ⊗ₜ (p ⊗ₜ q) 
goal: (TensorProduct.tensorTensorTensorAssoc R M N P Q).symm ((m ⊗ₜ[R] n ⊗ₜ[R] p) ⊗ₜ[R] q) = (m ⊗ₜ[R] n) ⊗ₜ[R] p ⊗ₜ[R] q

full_name: LinearMap.lTensor
code: /-- `LinearMap.lTensor M f : M ⊗ N →ₗ M ⊗ P` is the natural linear map
induced by `f : N →ₗ P`. -/
def lTensor (f : N →ₗ[R] P) : M ⊗[R] N →ₗ[R] M ⊗[R] P 
goal: TensorProduct R M N →ₗ[R] TensorProduct R M P

full_name: LinearMap.rTensor
code: /-- `LinearMap.rTensor M f : N₁ ⊗ M →ₗ N₂ ⊗ M` is the natural linear map
induced by `f : N₁ →ₗ N₂`. -/
def rTensor (f : N →ₗ[R] P) : N ⊗[R] M →ₗ[R] P ⊗[R] M 
goal: TensorProduct R N M →ₗ[R] TensorProduct R P M

full_name: LinearMap.lTensor_tmul
code: @[simp]
theorem lTensor_tmul (m : M) (n : N) : f.lTensor M (m ⊗ₜ n) = m ⊗ₜ f n 
goal: (LinearMap.lTensor M f) (m ⊗ₜ[R] n) = m ⊗ₜ[R] f n

full_name: LinearMap.rTensor_tmul
code: @[simp]
theorem rTensor_tmul (m : M) (n : N) : f.rTensor M (n ⊗ₜ m) = f n ⊗ₜ m 
goal: (LinearMap.rTensor M f) (n ⊗ₜ[R] m) = f n ⊗ₜ[R] m

full_name: LinearMap.lTensor_comp_mk
code: @[simp]
theorem lTensor_comp_mk (m : M) :
    f.lTensor M ∘ₗ TensorProduct.mk R M N m = TensorProduct.mk R M P m ∘ₗ f 
goal: LinearMap.lTensor M f ∘ₗ (TensorProduct.mk R M N) m = (TensorProduct.mk R M P) m ∘ₗ f

full_name: LinearMap.rTensor_comp_flip_mk
code: @[simp]
theorem rTensor_comp_flip_mk (m : M) :
    f.rTensor M ∘ₗ (TensorProduct.mk R N M).flip m = (TensorProduct.mk R P M).flip m ∘ₗ f 
goal: LinearMap.rTensor M f ∘ₗ (TensorProduct.mk R N M).flip m = (TensorProduct.mk R P M).flip m ∘ₗ f

full_name: LinearMap.comm_comp_rTensor_comp_comm_eq
code: lemma comm_comp_rTensor_comp_comm_eq (g : N →ₗ[R] P) :
    TensorProduct.comm R P Q ∘ₗ rTensor Q g ∘ₗ TensorProduct.comm R Q N =
      lTensor Q g 
goal: ↑(TensorProduct.comm R P Q) ∘ₗ LinearMap.rTensor Q g ∘ₗ ↑(TensorProduct.comm R Q N) = LinearMap.lTensor Q g

full_name: LinearMap.comm_comp_lTensor_comp_comm_eq
code: lemma comm_comp_lTensor_comp_comm_eq (g : N →ₗ[R] P) :
    TensorProduct.comm R Q P ∘ₗ lTensor Q g ∘ₗ TensorProduct.comm R N Q =
      rTensor Q g 
goal: ↑(TensorProduct.comm R Q P) ∘ₗ LinearMap.lTensor Q g ∘ₗ ↑(TensorProduct.comm R N Q) = LinearMap.rTensor Q g

full_name: LinearMap.lTensor_inj_iff_rTensor_inj
code: /-- Given a linear map `f : N → P`, `f ⊗ M` is injective if and only if `M ⊗ f` is injective. -/
theorem lTensor_inj_iff_rTensor_inj :
    Function.Injective (lTensor M f) ↔ Function.Injective (rTensor M f) 
goal: Function.Injective ⇑(LinearMap.lTensor M f) ↔ Function.Injective ⇑(LinearMap.rTensor M f)

full_name: LinearMap.lTensor_surj_iff_rTensor_surj
code: /-- Given a linear map `f : N → P`, `f ⊗ M` is surjective if and only if `M ⊗ f` is surjective. -/
theorem lTensor_surj_iff_rTensor_surj :
    Function.Surjective (lTensor M f) ↔ Function.Surjective (rTensor M f) 
goal: Function.Surjective ⇑(LinearMap.lTensor M f) ↔ Function.Surjective ⇑(LinearMap.rTensor M f)

full_name: LinearMap.lTensor_bij_iff_rTensor_bij
code: /-- Given a linear map `f : N → P`, `f ⊗ M` is bijective if and only if `M ⊗ f` is bijective. -/
theorem lTensor_bij_iff_rTensor_bij :
    Function.Bijective (lTensor M f) ↔ Function.Bijective (rTensor M f) 
goal: Function.Bijective ⇑(LinearMap.lTensor M f) ↔ Function.Bijective ⇑(LinearMap.rTensor M f)

full_name: LinearMap.lTensorHom
code: /-- `lTensorHom M` is the natural linear map that sends a linear map `f : N →ₗ P` to `M ⊗ f`. -/
def lTensorHom : (N →ₗ[R] P) →ₗ[R] M ⊗[R] N →ₗ[R] M ⊗[R] P 
goal: (N →ₗ[R] P) →ₗ[R] TensorProduct R M N →ₗ[R] TensorProduct R M P

full_name: LinearMap.rTensorHom
code: /-- `rTensorHom M` is the natural linear map that sends a linear map `f : N →ₗ P` to `f ⊗ M`. -/
def rTensorHom : (N →ₗ[R] P) →ₗ[R] N ⊗[R] M →ₗ[R] P ⊗[R] M 
goal: (N →ₗ[R] P) →ₗ[R] TensorProduct R N M →ₗ[R] TensorProduct R P M

full_name: LinearMap.coe_lTensorHom
code: @[simp]
theorem coe_lTensorHom : (lTensorHom M : (N →ₗ[R] P) → M ⊗[R] N →ₗ[R] M ⊗[R] P) = lTensor M 
goal: ⇑(LinearMap.lTensorHom M) = LinearMap.lTensor M

full_name: LinearMap.coe_rTensorHom
code: @[simp]
theorem coe_rTensorHom : (rTensorHom M : (N →ₗ[R] P) → N ⊗[R] M →ₗ[R] P ⊗[R] M) = rTensor M 
goal: ⇑(LinearMap.rTensorHom M) = LinearMap.rTensor M

full_name: LinearMap.lTensor_add
code: @[simp]
theorem lTensor_add (f g : N →ₗ[R] P) : (f + g).lTensor M = f.lTensor M + g.lTensor M 
goal: LinearMap.lTensor M (f + g) = LinearMap.lTensor M f + LinearMap.lTensor M g

full_name: LinearMap.rTensor_add
code: @[simp]
theorem rTensor_add (f g : N →ₗ[R] P) : (f + g).rTensor M = f.rTensor M + g.rTensor M 
goal: LinearMap.rTensor M (f + g) = LinearMap.rTensor M f + LinearMap.rTensor M g

full_name: LinearMap.lTensor_zero
code: @[simp]
theorem lTensor_zero : lTensor M (0 : N →ₗ[R] P) = 0 
goal: LinearMap.lTensor M 0 = 0

full_name: LinearMap.rTensor_zero
code: @[simp]
theorem rTensor_zero : rTensor M (0 : N →ₗ[R] P) = 0 
goal: LinearMap.rTensor M 0 = 0

full_name: LinearMap.lTensor_smul
code: @[simp]
theorem lTensor_smul (r : R) (f : N →ₗ[R] P) : (r • f).lTensor M = r • f.lTensor M 
goal: LinearMap.lTensor M (r • f) = r • LinearMap.lTensor M f

full_name: LinearMap.rTensor_smul
code: @[simp]
theorem rTensor_smul (r : R) (f : N →ₗ[R] P) : (r • f).rTensor M = r • f.rTensor M 
goal: LinearMap.rTensor M (r • f) = r • LinearMap.rTensor M f

full_name: LinearMap.lTensor_comp
code: theorem lTensor_comp : (g.comp f).lTensor M = (g.lTensor M).comp (f.lTensor M) 
goal: LinearMap.lTensor M (g ∘ₗ f) = LinearMap.lTensor M g ∘ₗ LinearMap.lTensor M f

full_name: LinearMap.lTensor_comp_apply
code: theorem lTensor_comp_apply (x : M ⊗[R] N) :
    (g.comp f).lTensor M x = (g.lTensor M) ((f.lTensor M) x) 
goal: (LinearMap.lTensor M (g ∘ₗ f)) x = (LinearMap.lTensor M g) ((LinearMap.lTensor M f) x)

full_name: LinearMap.rTensor_comp
code: theorem rTensor_comp : (g.comp f).rTensor M = (g.rTensor M).comp (f.rTensor M) 
goal: LinearMap.rTensor M (g ∘ₗ f) = LinearMap.rTensor M g ∘ₗ LinearMap.rTensor M f

full_name: LinearMap.rTensor_comp_apply
code: theorem rTensor_comp_apply (x : N ⊗[R] M) :
    (g.comp f).rTensor M x = (g.rTensor M) ((f.rTensor M) x) 
goal: (LinearMap.rTensor M (g ∘ₗ f)) x = (LinearMap.rTensor M g) ((LinearMap.rTensor M f) x)

full_name: LinearMap.lTensor_mul
code: theorem lTensor_mul (f g : Module.End R N) : (f * g).lTensor M = f.lTensor M * g.lTensor M 
goal: LinearMap.lTensor M (f * g) = LinearMap.lTensor M f * LinearMap.lTensor M g

full_name: LinearMap.rTensor_mul
code: theorem rTensor_mul (f g : Module.End R N) : (f * g).rTensor M = f.rTensor M * g.rTensor M 
goal: LinearMap.rTensor M (f * g) = LinearMap.rTensor M f * LinearMap.rTensor M g

full_name: LinearMap.lTensor_id
code: @[simp]
theorem lTensor_id : (id : N →ₗ[R] N).lTensor M = id 
goal: LinearMap.lTensor M LinearMap.id = LinearMap.id

full_name: LinearMap.lTensor_id_apply
code: theorem lTensor_id_apply (x : M ⊗[R] N) : (LinearMap.id : N →ₗ[R] N).lTensor M x = x 
goal: (LinearMap.lTensor M LinearMap.id) x = x

full_name: LinearMap.rTensor_id
code: @[simp]
theorem rTensor_id : (id : N →ₗ[R] N).rTensor M = id 
goal: LinearMap.rTensor M LinearMap.id = LinearMap.id

full_name: LinearMap.rTensor_id_apply
code: theorem rTensor_id_apply (x : N ⊗[R] M) : (LinearMap.id : N →ₗ[R] N).rTensor M x = x 
goal: (LinearMap.rTensor M LinearMap.id) x = x

full_name: LinearMap.lTensor_smul_action
code: @[simp]
theorem lTensor_smul_action (r : R) :
    (DistribMulAction.toLinearMap R N r).lTensor M =
      DistribMulAction.toLinearMap R (M ⊗[R] N) r 
goal: LinearMap.lTensor M (DistribMulAction.toLinearMap R N r) = DistribMulAction.toLinearMap R (TensorProduct R M N) r

full_name: LinearMap.rTensor_smul_action
code: @[simp]
theorem rTensor_smul_action (r : R) :
    (DistribMulAction.toLinearMap R N r).rTensor M =
      DistribMulAction.toLinearMap R (N ⊗[R] M) r 
goal: LinearMap.rTensor M (DistribMulAction.toLinearMap R N r) = DistribMulAction.toLinearMap R (TensorProduct R N M) r

full_name: LinearMap.lid_comp_rTensor
code: theorem lid_comp_rTensor (f : N →ₗ[R] R) :
    (TensorProduct.lid R M).comp (rTensor M f) = lift ((lsmul R M).comp f) 
goal: ↑(TensorProduct.lid R M) ∘ₗ LinearMap.rTensor M f = TensorProduct.lift (LinearMap.lsmul R M ∘ₗ f)

full_name: LinearMap.lTensor_comp_rTensor
code: @[simp]
theorem lTensor_comp_rTensor (f : M →ₗ[R] P) (g : N →ₗ[R] Q) :
    (g.lTensor P).comp (f.rTensor N) = map f g 
goal: LinearMap.lTensor P g ∘ₗ LinearMap.rTensor N f = TensorProduct.map f g

full_name: LinearMap.rTensor_comp_lTensor
code: @[simp]
theorem rTensor_comp_lTensor (f : M →ₗ[R] P) (g : N →ₗ[R] Q) :
    (f.rTensor Q).comp (g.lTensor M) = map f g 
goal: LinearMap.rTensor Q f ∘ₗ LinearMap.lTensor M g = TensorProduct.map f g

full_name: LinearMap.map_comp_rTensor
code: @[simp]
theorem map_comp_rTensor (f : M →ₗ[R] P) (g : N →ₗ[R] Q) (f' : S →ₗ[R] M) :
    (map f g).comp (f'.rTensor _) = map (f.comp f') g 
goal: TensorProduct.map f g ∘ₗ LinearMap.rTensor N f' = TensorProduct.map (f ∘ₗ f') g

full_name: LinearMap.map_comp_lTensor
code: @[simp]
theorem map_comp_lTensor (f : M →ₗ[R] P) (g : N →ₗ[R] Q) (g' : S →ₗ[R] N) :
    (map f g).comp (g'.lTensor _) = map f (g.comp g') 
goal: TensorProduct.map f g ∘ₗ LinearMap.lTensor M g' = TensorProduct.map f (g ∘ₗ g')

full_name: LinearMap.rTensor_comp_map
code: @[simp]
theorem rTensor_comp_map (f' : P →ₗ[R] S) (f : M →ₗ[R] P) (g : N →ₗ[R] Q) :
    (f'.rTensor _).comp (map f g) = map (f'.comp f) g 
goal: LinearMap.rTensor Q f' ∘ₗ TensorProduct.map f g = TensorProduct.map (f' ∘ₗ f) g

full_name: LinearMap.lTensor_comp_map
code: @[simp]
theorem lTensor_comp_map (g' : Q →ₗ[R] S) (f : M →ₗ[R] P) (g : N →ₗ[R] Q) :
    (g'.lTensor _).comp (map f g) = map f (g'.comp g) 
goal: LinearMap.lTensor P g' ∘ₗ TensorProduct.map f g = TensorProduct.map f (g' ∘ₗ g)

full_name: LinearMap.rTensor_pow
code: @[simp]
theorem rTensor_pow (f : M →ₗ[R] M) (n : ℕ) : f.rTensor N ^ n = (f ^ n).rTensor N 
goal: LinearMap.rTensor N f ^ n = LinearMap.rTensor N (f ^ n)

full_name: LinearMap.lTensor_pow
code: @[simp]
theorem lTensor_pow (f : N →ₗ[R] N) (n : ℕ) : f.lTensor M ^ n = (f ^ n).lTensor M 
goal: LinearMap.lTensor M f ^ n = LinearMap.lTensor M (f ^ n)

full_name: LinearEquiv.lTensor
code: /-- `LinearEquiv.lTensor M f : M ⊗ N ≃ₗ M ⊗ P` is the natural linear equivalence
induced by `f : N ≃ₗ P`. -/
def lTensor (f : N ≃ₗ[R] P) : M ⊗[R] N ≃ₗ[R] M ⊗[R] P 
goal: TensorProduct R M N ≃ₗ[R] TensorProduct R M P

full_name: LinearEquiv.rTensor
code: /-- `LinearEquiv.rTensor M f : N₁ ⊗ M ≃ₗ N₂ ⊗ M` is the natural linear equivalence
induced by `f : N₁ ≃ₗ N₂`. -/
def rTensor (f : N ≃ₗ[R] P) : N ⊗[R] M ≃ₗ[R] P ⊗[R] M 
goal: TensorProduct R N M ≃ₗ[R] TensorProduct R P M

full_name: LinearEquiv.coe_lTensor
code: @[simp] theorem coe_lTensor : lTensor M f = (f : N →ₗ[R] P).lTensor M 
goal: ↑(LinearEquiv.lTensor M f) = LinearMap.lTensor M ↑f

full_name: LinearEquiv.coe_lTensor_symm
code: @[simp] theorem coe_lTensor_symm : (lTensor M f).symm = (f.symm : P →ₗ[R] N).lTensor M 
goal: ↑(LinearEquiv.lTensor M f).symm = LinearMap.lTensor M ↑f.symm

full_name: LinearEquiv.coe_rTensor
code: @[simp] theorem coe_rTensor : rTensor M f = (f : N →ₗ[R] P).rTensor M 
goal: ↑(LinearEquiv.rTensor M f) = LinearMap.rTensor M ↑f

full_name: LinearEquiv.coe_rTensor_symm
code: @[simp] theorem coe_rTensor_symm : (rTensor M f).symm = (f.symm : P →ₗ[R] N).rTensor M 
goal: ↑(LinearEquiv.rTensor M f).symm = LinearMap.rTensor M ↑f.symm

full_name: LinearEquiv.lTensor_tmul
code: @[simp] theorem lTensor_tmul : f.lTensor M (m ⊗ₜ n) = m ⊗ₜ f n 
goal: (LinearEquiv.lTensor M f) (m ⊗ₜ[R] n) = m ⊗ₜ[R] f n

full_name: LinearEquiv.lTensor_symm_tmul
code: @[simp] theorem lTensor_symm_tmul : (f.lTensor M).symm (m ⊗ₜ p) = m ⊗ₜ f.symm p 
goal: (LinearEquiv.lTensor M f).symm (m ⊗ₜ[R] p) = m ⊗ₜ[R] f.symm p

full_name: LinearEquiv.rTensor_tmul
code: @[simp] theorem rTensor_tmul : f.rTensor M (n ⊗ₜ m) = f n ⊗ₜ m 
goal: (LinearEquiv.rTensor M f) (n ⊗ₜ[R] m) = f n ⊗ₜ[R] m

full_name: LinearEquiv.rTensor_symm_tmul
code: @[simp] theorem rTensor_symm_tmul : (f.rTensor M).symm (p ⊗ₜ m) = f.symm p ⊗ₜ m 
goal: (LinearEquiv.rTensor M f).symm (p ⊗ₜ[R] m) = f.symm p ⊗ₜ[R] m

full_name: LinearEquiv.comm_trans_rTensor_trans_comm_eq
code: lemma comm_trans_rTensor_trans_comm_eq (g : N ≃ₗ[R] P) :
    TensorProduct.comm R Q N ≪≫ₗ rTensor Q g ≪≫ₗ TensorProduct.comm R P Q = lTensor Q g 
goal: TensorProduct.comm R Q N ≪≫ₗ LinearEquiv.rTensor Q g ≪≫ₗ TensorProduct.comm R P Q = LinearEquiv.lTensor Q g

full_name: LinearEquiv.comm_trans_lTensor_trans_comm_eq
code: lemma comm_trans_lTensor_trans_comm_eq (g : N ≃ₗ[R] P) :
    TensorProduct.comm R N Q ≪≫ₗ lTensor Q g ≪≫ₗ TensorProduct.comm R Q P = rTensor Q g 
goal: TensorProduct.comm R N Q ≪≫ₗ LinearEquiv.lTensor Q g ≪≫ₗ TensorProduct.comm R Q P = LinearEquiv.rTensor Q g

full_name: LinearEquiv.lTensor_trans
code: theorem lTensor_trans : (f ≪≫ₗ g).lTensor M = f.lTensor M ≪≫ₗ g.lTensor M 
goal: LinearEquiv.lTensor M (f ≪≫ₗ g) = LinearEquiv.lTensor M f ≪≫ₗ LinearEquiv.lTensor M g

full_name: LinearEquiv.lTensor_trans_apply
code: theorem lTensor_trans_apply : (f ≪≫ₗ g).lTensor M x = g.lTensor M (f.lTensor M x) 
goal: (LinearEquiv.lTensor M (f ≪≫ₗ g)) x = (LinearEquiv.lTensor M g) ((LinearEquiv.lTensor M f) x)

full_name: LinearEquiv.rTensor_trans
code: theorem rTensor_trans : (f ≪≫ₗ g).rTensor M = f.rTensor M ≪≫ₗ g.rTensor M 
goal: LinearEquiv.rTensor M (f ≪≫ₗ g) = LinearEquiv.rTensor M f ≪≫ₗ LinearEquiv.rTensor M g

full_name: LinearEquiv.rTensor_trans_apply
code: theorem rTensor_trans_apply : (f ≪≫ₗ g).rTensor M y = g.rTensor M (f.rTensor M y) 
goal: (LinearEquiv.rTensor M (f ≪≫ₗ g)) y = (LinearEquiv.rTensor M g) ((LinearEquiv.rTensor M f) y)

full_name: LinearEquiv.lTensor_mul
code: theorem lTensor_mul (f g : N ≃ₗ[R] N) : (f * g).lTensor M = f.lTensor M * g.lTensor M 
goal: LinearEquiv.lTensor M (f * g) = LinearEquiv.lTensor M f * LinearEquiv.lTensor M g

full_name: LinearEquiv.rTensor_mul
code: theorem rTensor_mul (f g : N ≃ₗ[R] N) : (f * g).rTensor M = f.rTensor M * g.rTensor M 
goal: LinearEquiv.rTensor M (f * g) = LinearEquiv.rTensor M f * LinearEquiv.rTensor M g

full_name: LinearEquiv.lTensor_refl
code: @[simp] theorem lTensor_refl : (refl R N).lTensor M = refl R _ 
goal: LinearEquiv.lTensor M (LinearEquiv.refl R N) = LinearEquiv.refl R (TensorProduct R M N)

full_name: LinearEquiv.lTensor_refl_apply
code: theorem lTensor_refl_apply : (refl R N).lTensor M x = x 
goal: (LinearEquiv.lTensor M (LinearEquiv.refl R N)) x = x

full_name: LinearEquiv.rTensor_refl
code: @[simp] theorem rTensor_refl : (refl R N).rTensor M = refl R _ 
goal: LinearEquiv.rTensor M (LinearEquiv.refl R N) = LinearEquiv.refl R (TensorProduct R N M)

full_name: LinearEquiv.rTensor_refl_apply
code: theorem rTensor_refl_apply : (refl R N).rTensor M y = y 
goal: (LinearEquiv.rTensor M (LinearEquiv.refl R N)) y = y

full_name: LinearEquiv.rTensor_trans_lTensor
code: @[simp] theorem rTensor_trans_lTensor (f : M ≃ₗ[R] P) (g : N ≃ₗ[R] Q) :
    f.rTensor N ≪≫ₗ g.lTensor P = TensorProduct.congr f g 
goal: LinearEquiv.rTensor N f ≪≫ₗ LinearEquiv.lTensor P g = TensorProduct.congr f g

full_name: LinearEquiv.lTensor_trans_rTensor
code: @[simp] theorem lTensor_trans_rTensor (f : M ≃ₗ[R] P) (g : N ≃ₗ[R] Q) :
    g.lTensor M ≪≫ₗ f.rTensor Q = TensorProduct.congr f g 
goal: LinearEquiv.lTensor M g ≪≫ₗ LinearEquiv.rTensor Q f = TensorProduct.congr f g

full_name: LinearEquiv.rTensor_trans_congr
code: @[simp] theorem rTensor_trans_congr (f : M ≃ₗ[R] P) (g : N ≃ₗ[R] Q) (f' : S ≃ₗ[R] M) :
    f'.rTensor _ ≪≫ₗ TensorProduct.congr f g = TensorProduct.congr (f' ≪≫ₗ f) g 
goal: LinearEquiv.rTensor N f' ≪≫ₗ TensorProduct.congr f g = TensorProduct.congr (f' ≪≫ₗ f) g

full_name: LinearEquiv.lTensor_trans_congr
code: @[simp] theorem lTensor_trans_congr (f : M ≃ₗ[R] P) (g : N ≃ₗ[R] Q) (g' : S ≃ₗ[R] N) :
    g'.lTensor _ ≪≫ₗ TensorProduct.congr f g = TensorProduct.congr f (g' ≪≫ₗ g) 
goal: LinearEquiv.lTensor M g' ≪≫ₗ TensorProduct.congr f g = TensorProduct.congr f (g' ≪≫ₗ g)

full_name: LinearEquiv.congr_trans_rTensor
code: @[simp] theorem congr_trans_rTensor (f' : P ≃ₗ[R] S) (f : M ≃ₗ[R] P) (g : N ≃ₗ[R] Q) :
    TensorProduct.congr f g ≪≫ₗ f'.rTensor _ = TensorProduct.congr (f ≪≫ₗ f') g 
goal: TensorProduct.congr f g ≪≫ₗ LinearEquiv.rTensor Q f' = TensorProduct.congr (f ≪≫ₗ f') g

full_name: LinearEquiv.congr_trans_lTensor
code: @[simp] theorem congr_trans_lTensor (g' : Q ≃ₗ[R] S) (f : M ≃ₗ[R] P) (g : N ≃ₗ[R] Q) :
    TensorProduct.congr f g ≪≫ₗ g'.lTensor _ = TensorProduct.congr f (g ≪≫ₗ g') 
goal: TensorProduct.congr f g ≪≫ₗ LinearEquiv.lTensor P g' = TensorProduct.congr f (g ≪≫ₗ g')

full_name: LinearEquiv.rTensor_pow
code: @[simp] theorem rTensor_pow (f : M ≃ₗ[R] M) (n : ℕ) : f.rTensor N ^ n = (f ^ n).rTensor N 
goal: LinearEquiv.rTensor N f ^ n = LinearEquiv.rTensor N (f ^ n)

full_name: LinearEquiv.rTensor_zpow
code: @[simp] theorem rTensor_zpow (f : M ≃ₗ[R] M) (n : ℤ) : f.rTensor N ^ n = (f ^ n).rTensor N 
goal: LinearEquiv.rTensor N f ^ n = LinearEquiv.rTensor N (f ^ n)

full_name: LinearEquiv.lTensor_pow
code: @[simp] theorem lTensor_pow (f : N ≃ₗ[R] N) (n : ℕ) : f.lTensor M ^ n = (f ^ n).lTensor M 
goal: LinearEquiv.lTensor M f ^ n = LinearEquiv.lTensor M (f ^ n)

full_name: LinearEquiv.lTensor_zpow
code: @[simp] theorem lTensor_zpow (f : N ≃ₗ[R] N) (n : ℤ) : f.lTensor M ^ n = (f ^ n).lTensor M 
goal: LinearEquiv.lTensor M f ^ n = LinearEquiv.lTensor M (f ^ n)

full_name: TensorProduct.Neg.aux
code: /-- Auxiliary function to defining negation multiplication on tensor product. -/
def Neg.aux : M ⊗[R] N →ₗ[R] M ⊗[R] N 
goal: TensorProduct R M N →ₗ[R] TensorProduct R M N

full_name: TensorProduct.neg
code: instance neg : Neg (M ⊗[R] N) 
goal: Neg (TensorProduct R M N)

full_name: TensorProduct.add_left_neg
code: protected theorem add_left_neg (x : M ⊗[R] N) : -x + x = 0 
goal: -x + x = 0

full_name: TensorProduct.addCommGroup
code: instance addCommGroup : AddCommGroup (M ⊗[R] N) 
goal: AddCommGroup (TensorProduct R M N)

full_name: TensorProduct.neg_tmul
code: theorem neg_tmul (m : M) (n : N) : (-m) ⊗ₜ n = -m ⊗ₜ[R] n 
goal: (-m) ⊗ₜ[R] n = -m ⊗ₜ[R] n

full_name: TensorProduct.tmul_neg
code: theorem tmul_neg (m : M) (n : N) : m ⊗ₜ (-n) = -m ⊗ₜ[R] n 
goal: m ⊗ₜ[R] (-n) = -m ⊗ₜ[R] n

full_name: TensorProduct.tmul_sub
code: theorem tmul_sub (m : M) (n₁ n₂ : N) : m ⊗ₜ (n₁ - n₂) = m ⊗ₜ[R] n₁ - m ⊗ₜ[R] n₂ 
goal: m ⊗ₜ[R] (n₁ - n₂) = m ⊗ₜ[R] n₁ - m ⊗ₜ[R] n₂

full_name: TensorProduct.sub_tmul
code: theorem sub_tmul (m₁ m₂ : M) (n : N) : (m₁ - m₂) ⊗ₜ n = m₁ ⊗ₜ[R] n - m₂ ⊗ₜ[R] n 
goal: (m₁ - m₂) ⊗ₜ[R] n = m₁ ⊗ₜ[R] n - m₂ ⊗ₜ[R] n

full_name: TensorProduct.CompatibleSMul.int
code: /-- While the tensor product will automatically inherit a ℤ-module structure from
`AddCommGroup.intModule`, that structure won't be compatible with lemmas like `tmul_smul` unless
we use a `ℤ-Module` instance provided by `TensorProduct.left_module`.

When `R` is a `Ring` we get the required `TensorProduct.compatible_smul` instance through
`IsScalarTower`, but when it is only a `Semiring` we need to build it from scratch.
The instance diamond in `compatible_smul` doesn't matter because it's in `Prop`.
-/
instance CompatibleSMul.int : CompatibleSMul R ℤ M N 
goal: TensorProduct.CompatibleSMul R ℤ M N

full_name: TensorProduct.CompatibleSMul.unit
code: instance CompatibleSMul.unit {S} [Monoid S] [DistribMulAction S M] [DistribMulAction S N]
    [CompatibleSMul R S M N] : CompatibleSMul R Sˣ M N 
goal: TensorProduct.CompatibleSMul R Sˣ M N

full_name: LinearMap.lTensor_sub
code: @[simp]
theorem lTensor_sub (f g : N →ₗ[R] P) : (f - g).lTensor M = f.lTensor M - g.lTensor M 
goal: LinearMap.lTensor M (f - g) = LinearMap.lTensor M f - LinearMap.lTensor M g

full_name: LinearMap.rTensor_sub
code: @[simp]
theorem rTensor_sub (f g : N →ₗ[R] P) : (f - g).rTensor M = f.rTensor M - g.rTensor M 
goal: LinearMap.rTensor M (f - g) = LinearMap.rTensor M f - LinearMap.rTensor M g

full_name: LinearMap.lTensor_neg
code: @[simp]
theorem lTensor_neg (f : N →ₗ[R] P) : (-f).lTensor M = -f.lTensor M 
goal: LinearMap.lTensor M (-f) = -LinearMap.lTensor M f

full_name: LinearMap.rTensor_neg
code: @[simp]
theorem rTensor_neg (f : N →ₗ[R] P) : (-f).rTensor M = -f.rTensor M 
goal: LinearMap.rTensor M (-f) = -LinearMap.rTensor M f