l3lab/ntp-mathlib huggingface dataset:
instance uniqueLeft [Subsingleton M] : Unique (M ⊗[R] N) where
  default := 0
  uniq z := z.induction_on rfl (fun x y ↦ by rw [Subsingleton.elim x 0, zero_tmul]; rfl) <| by
    

Proof state:
R : Type u_1
inst✝¹⁷ : CommSemiring R
R' : Type u_2
inst✝¹⁶ : Monoid R'
R'' : Type u_3
inst✝¹⁵ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁴ : AddCommMonoid M
inst✝¹³ : AddCommMonoid N
inst✝¹² : AddCommMonoid P
inst✝¹¹ : AddCommMonoid Q
inst✝¹⁰ : AddCommMonoid S
inst✝⁹ : AddCommMonoid T
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Module R S
inst✝³ : Module R T
inst✝² : DistribMulAction R' M
inst✝¹ : Module R'' M
inst✝ : Subsingleton M
z : M ⊗[R] N
⊢ ∀ (x y : M ⊗[R] N), x = default → y = default → x + y = default

Next tactic:
rintro _ _ rfl rfl
instance uniqueLeft [Subsingleton M] : Unique (M ⊗[R] N) where
  default := 0
  uniq z := z.induction_on rfl (fun x y ↦ by rw [Subsingleton.elim x 0, zero_tmul]; rfl) <| by
    rintro _ _ rfl rfl; 

Proof state:
R : Type u_1
inst✝¹⁷ : CommSemiring R
R' : Type u_2
inst✝¹⁶ : Monoid R'
R'' : Type u_3
inst✝¹⁵ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁴ : AddCommMonoid M
inst✝¹³ : AddCommMonoid N
inst✝¹² : AddCommMonoid P
inst✝¹¹ : AddCommMonoid Q
inst✝¹⁰ : AddCommMonoid S
inst✝⁹ : AddCommMonoid T
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Module R S
inst✝³ : Module R T
inst✝² : DistribMulAction R' M
inst✝¹ : Module R'' M
inst✝ : Subsingleton M
z : M ⊗[R] N
⊢ default + default = default

Next tactic:
apply add_zero
instance uniqueRight [Subsingleton N] : Unique (M ⊗[R] N) where
  default := 0
  uniq z := z.induction_on rfl (fun x y ↦ by 

Proof state:
R : Type u_1
inst✝¹⁷ : CommSemiring R
R' : Type u_2
inst✝¹⁶ : Monoid R'
R'' : Type u_3
inst✝¹⁵ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁴ : AddCommMonoid M
inst✝¹³ : AddCommMonoid N
inst✝¹² : AddCommMonoid P
inst✝¹¹ : AddCommMonoid Q
inst✝¹⁰ : AddCommMonoid S
inst✝⁹ : AddCommMonoid T
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Module R S
inst✝³ : Module R T
inst✝² : DistribMulAction R' M
inst✝¹ : Module R'' M
inst✝ : Subsingleton N
z : M ⊗[R] N
x : M
y : N
⊢ x ⊗ₜ[R] y = default

Next tactic:
rw [Subsingleton.elim y 0, tmul_zero]
instance uniqueRight [Subsingleton N] : Unique (M ⊗[R] N) where
  default := 0
  uniq z := z.induction_on rfl (fun x y ↦ by rw [Subsingleton.elim y 0, tmul_zero]; 

Proof state:
R : Type u_1
inst✝¹⁷ : CommSemiring R
R' : Type u_2
inst✝¹⁶ : Monoid R'
R'' : Type u_3
inst✝¹⁵ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁴ : AddCommMonoid M
inst✝¹³ : AddCommMonoid N
inst✝¹² : AddCommMonoid P
inst✝¹¹ : AddCommMonoid Q
inst✝¹⁰ : AddCommMonoid S
inst✝⁹ : AddCommMonoid T
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Module R S
inst✝³ : Module R T
inst✝² : DistribMulAction R' M
inst✝¹ : Module R'' M
inst✝ : Subsingleton N
z : M ⊗[R] N
x : M
y : N
⊢ 0 = default

Next tactic:
rfl
instance uniqueRight [Subsingleton N] : Unique (M ⊗[R] N) where
  default := 0
  uniq z := z.induction_on rfl (fun x y ↦ by rw [Subsingleton.elim y 0, tmul_zero]; rfl) <| by
    

Proof state:
R : Type u_1
inst✝¹⁷ : CommSemiring R
R' : Type u_2
inst✝¹⁶ : Monoid R'
R'' : Type u_3
inst✝¹⁵ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁴ : AddCommMonoid M
inst✝¹³ : AddCommMonoid N
inst✝¹² : AddCommMonoid P
inst✝¹¹ : AddCommMonoid Q
inst✝¹⁰ : AddCommMonoid S
inst✝⁹ : AddCommMonoid T
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Module R S
inst✝³ : Module R T
inst✝² : DistribMulAction R' M
inst✝¹ : Module R'' M
inst✝ : Subsingleton N
z : M ⊗[R] N
⊢ ∀ (x y : M ⊗[R] N), x = default → y = default → x + y = default

Next tactic:
rintro _ _ rfl rfl
instance uniqueRight [Subsingleton N] : Unique (M ⊗[R] N) where
  default := 0
  uniq z := z.induction_on rfl (fun x y ↦ by rw [Subsingleton.elim y 0, tmul_zero]; rfl) <| by
    rintro _ _ rfl rfl; 

Proof state:
R : Type u_1
inst✝¹⁷ : CommSemiring R
R' : Type u_2
inst✝¹⁶ : Monoid R'
R'' : Type u_3
inst✝¹⁵ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁴ : AddCommMonoid M
inst✝¹³ : AddCommMonoid N
inst✝¹² : AddCommMonoid P
inst✝¹¹ : AddCommMonoid Q
inst✝¹⁰ : AddCommMonoid S
inst✝⁹ : AddCommMonoid T
inst✝⁸ : Module R M
inst✝⁷ : Module R N
inst✝⁶ : Module R P
inst✝⁵ : Module R Q
inst✝⁴ : Module R S
inst✝³ : Module R T
inst✝² : DistribMulAction R' M
inst✝¹ : Module R'' M
inst✝ : Subsingleton N
z : M ⊗[R] N
⊢ default + default = default

Next tactic:
apply add_zero
/-- Note that this provides the default `compatible_smul 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 :=
  ⟨fun r m n => by
    

Proof state:
R : Type u_1
inst✝²⁰ : CommSemiring R
R' : Type u_2
inst✝¹⁹ : Monoid R'
R'' : Type u_3
inst✝¹⁸ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁷ : AddCommMonoid M
inst✝¹⁶ : AddCommMonoid N
inst✝¹⁵ : AddCommMonoid P
inst✝¹⁴ : AddCommMonoid Q
inst✝¹³ : AddCommMonoid S
inst✝¹² : AddCommMonoid T
inst✝¹¹ : Module R M
inst✝¹⁰ : Module R N
inst✝⁹ : Module R P
inst✝⁸ : Module R Q
inst✝⁷ : Module R S
inst✝⁶ : Module R T
inst✝⁵ : DistribMulAction R' M
inst✝⁴ : Module R'' M
inst✝³ : SMul R' R
inst✝² : IsScalarTower R' R M
inst✝¹ : DistribMulAction R' N
inst✝ : IsScalarTower R' R N
r : R'
m : M
n : N
⊢ (r • m) ⊗ₜ[R] n = m ⊗ₜ[R] (r • n)

Next tactic:
conv_lhs => rw [← one_smul R m]
/-- Note that this provides the default `compatible_smul 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 :=
  ⟨fun r m n => by
    conv_lhs => 

Proof state:
R : Type u_1
inst✝²⁰ : CommSemiring R
R' : Type u_2
inst✝¹⁹ : Monoid R'
R'' : Type u_3
inst✝¹⁸ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁷ : AddCommMonoid M
inst✝¹⁶ : AddCommMonoid N
inst✝¹⁵ : AddCommMonoid P
inst✝¹⁴ : AddCommMonoid Q
inst✝¹³ : AddCommMonoid S
inst✝¹² : AddCommMonoid T
inst✝¹¹ : Module R M
inst✝¹⁰ : Module R N
inst✝⁹ : Module R P
inst✝⁸ : Module R Q
inst✝⁷ : Module R S
inst✝⁶ : Module R T
inst✝⁵ : DistribMulAction R' M
inst✝⁴ : Module R'' M
inst✝³ : SMul R' R
inst✝² : IsScalarTower R' R M
inst✝¹ : DistribMulAction R' N
inst✝ : IsScalarTower R' R N
r : R'
m : M
n : N
| (r • m) ⊗ₜ[R] n

Next tactic:
rw [← one_smul R m]
/-- Note that this provides the default `compatible_smul 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 :=
  ⟨fun r m n => by
    conv_lhs => rw [← one_smul R m]
    

Proof state:
R : Type u_1
inst✝²⁰ : CommSemiring R
R' : Type u_2
inst✝¹⁹ : Monoid R'
R'' : Type u_3
inst✝¹⁸ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁷ : AddCommMonoid M
inst✝¹⁶ : AddCommMonoid N
inst✝¹⁵ : AddCommMonoid P
inst✝¹⁴ : AddCommMonoid Q
inst✝¹³ : AddCommMonoid S
inst✝¹² : AddCommMonoid T
inst✝¹¹ : Module R M
inst✝¹⁰ : Module R N
inst✝⁹ : Module R P
inst✝⁸ : Module R Q
inst✝⁷ : Module R S
inst✝⁶ : Module R T
inst✝⁵ : DistribMulAction R' M
inst✝⁴ : Module R'' M
inst✝³ : SMul R' R
inst✝² : IsScalarTower R' R M
inst✝¹ : DistribMulAction R' N
inst✝ : IsScalarTower R' R N
r : R'
m : M
n : N
⊢ (r • 1 • m) ⊗ₜ[R] n = m ⊗ₜ[R] (r • n)

Next tactic:
conv_rhs => rw [← one_smul R n]
/-- Note that this provides the default `compatible_smul 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 :=
  ⟨fun r m n => by
    conv_lhs => rw [← one_smul R m]
    conv_rhs => 

Proof state:
R : Type u_1
inst✝²⁰ : CommSemiring R
R' : Type u_2
inst✝¹⁹ : Monoid R'
R'' : Type u_3
inst✝¹⁸ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁷ : AddCommMonoid M
inst✝¹⁶ : AddCommMonoid N
inst✝¹⁵ : AddCommMonoid P
inst✝¹⁴ : AddCommMonoid Q
inst✝¹³ : AddCommMonoid S
inst✝¹² : AddCommMonoid T
inst✝¹¹ : Module R M
inst✝¹⁰ : Module R N
inst✝⁹ : Module R P
inst✝⁸ : Module R Q
inst✝⁷ : Module R S
inst✝⁶ : Module R T
inst✝⁵ : DistribMulAction R' M
inst✝⁴ : Module R'' M
inst✝³ : SMul R' R
inst✝² : IsScalarTower R' R M
inst✝¹ : DistribMulAction R' N
inst✝ : IsScalarTower R' R N
r : R'
m : M
n : N
| m ⊗ₜ[R] (r • n)

Next tactic:
rw [← one_smul R n]
/-- Note that this provides the default `compatible_smul 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 :=
  ⟨fun r m n => by
    conv_lhs => rw [← one_smul R m]
    conv_rhs => rw [← one_smul R n]
    

Proof state:
R : Type u_1
inst✝²⁰ : CommSemiring R
R' : Type u_2
inst✝¹⁹ : Monoid R'
R'' : Type u_3
inst✝¹⁸ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁷ : AddCommMonoid M
inst✝¹⁶ : AddCommMonoid N
inst✝¹⁵ : AddCommMonoid P
inst✝¹⁴ : AddCommMonoid Q
inst✝¹³ : AddCommMonoid S
inst✝¹² : AddCommMonoid T
inst✝¹¹ : Module R M
inst✝¹⁰ : Module R N
inst✝⁹ : Module R P
inst✝⁸ : Module R Q
inst✝⁷ : Module R S
inst✝⁶ : Module R T
inst✝⁵ : DistribMulAction R' M
inst✝⁴ : Module R'' M
inst✝³ : SMul R' R
inst✝² : IsScalarTower R' R M
inst✝¹ : DistribMulAction R' N
inst✝ : IsScalarTower R' R N
r : R'
m : M
n : N
⊢ (r • 1 • m) ⊗ₜ[R] n = m ⊗ₜ[R] (r • 1 • n)

Next tactic:
rw [← smul_assoc, ← smul_assoc]
/-- Note that this provides the default `compatible_smul 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 :=
  ⟨fun r m n => by
    conv_lhs => rw [← one_smul R m]
    conv_rhs => rw [← one_smul R n]
    rw [← smul_assoc, ← smul_assoc]
    

Proof state:
R : Type u_1
inst✝²⁰ : CommSemiring R
R' : Type u_2
inst✝¹⁹ : Monoid R'
R'' : Type u_3
inst✝¹⁸ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁷ : AddCommMonoid M
inst✝¹⁶ : AddCommMonoid N
inst✝¹⁵ : AddCommMonoid P
inst✝¹⁴ : AddCommMonoid Q
inst✝¹³ : AddCommMonoid S
inst✝¹² : AddCommMonoid T
inst✝¹¹ : Module R M
inst✝¹⁰ : Module R N
inst✝⁹ : Module R P
inst✝⁸ : Module R Q
inst✝⁷ : Module R S
inst✝⁶ : Module R T
inst✝⁵ : DistribMulAction R' M
inst✝⁴ : Module R'' M
inst✝³ : SMul R' R
inst✝² : IsScalarTower R' R M
inst✝¹ : DistribMulAction R' N
inst✝ : IsScalarTower R' R N
r : R'
m : M
n : N
⊢ ((r • 1) • m) ⊗ₜ[R] n = m ⊗ₜ[R] ((r • 1) • n)

Next tactic:
exact Quotient.sound' <| AddConGen.Rel.of _ _ <| Eqv.of_smul _ _ _
/-- 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) :=
  ⟨fun r =>
    (addConGen (TensorProduct.Eqv R M N)).lift (SMul.aux r : _ →+ M ⊗[R] N) <|
      AddCon.addConGen_le fun x y hxy =>
        match x, y, hxy with
        | _, _, .of_zero_left n =>
          (AddCon.ker_rel _).2 <| by 

Proof state:
R : Type u_1
inst✝¹⁸ : CommSemiring R
R' : Type u_2
inst✝¹⁷ : Monoid R'
R'' : Type u_3
inst✝¹⁶ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁵ : AddCommMonoid M
inst✝¹⁴ : AddCommMonoid N
inst✝¹³ : AddCommMonoid P
inst✝¹² : AddCommMonoid Q
inst✝¹¹ : AddCommMonoid S
inst✝¹⁰ : AddCommMonoid T
inst✝⁹ : Module R M
inst✝⁸ : Module R N
inst✝⁷ : Module R P
inst✝⁶ : Module R Q
inst✝⁵ : Module R S
inst✝⁴ : Module R T
inst✝³ : DistribMulAction R' M
inst✝² : Module R'' M
inst✝¹ : SMulCommClass R R' M
inst✝ : SMulCommClass R R'' M
r : R'
x y : FreeAddMonoid (M × N)
hxy : Eqv R M N x y
n : N
⊢ (SMul.aux r) (FreeAddMonoid.of (0, n)) = (SMul.aux r) 0

Next tactic:
simp_rw [map_zero, SMul.aux_of, smul_zero, zero_tmul]
/-- 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) :=
  ⟨fun r =>
    (addConGen (TensorProduct.Eqv R M N)).lift (SMul.aux r : _ →+ M ⊗[R] N) <|
      AddCon.addConGen_le fun x y hxy =>
        match x, y, hxy with
        | _, _, .of_zero_left n =>
          (AddCon.ker_rel _).2 <| by simp_rw [map_zero, SMul.aux_of, smul_zero, zero_tmul]
        | _, _, .of_zero_right m =>
          (AddCon.ker_rel _).2 <| by 

Proof state:
R : Type u_1
inst✝¹⁸ : CommSemiring R
R' : Type u_2
inst✝¹⁷ : Monoid R'
R'' : Type u_3
inst✝¹⁶ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁵ : AddCommMonoid M
inst✝¹⁴ : AddCommMonoid N
inst✝¹³ : AddCommMonoid P
inst✝¹² : AddCommMonoid Q
inst✝¹¹ : AddCommMonoid S
inst✝¹⁰ : AddCommMonoid T
inst✝⁹ : Module R M
inst✝⁸ : Module R N
inst✝⁷ : Module R P
inst✝⁶ : Module R Q
inst✝⁵ : Module R S
inst✝⁴ : Module R T
inst✝³ : DistribMulAction R' M
inst✝² : Module R'' M
inst✝¹ : SMulCommClass R R' M
inst✝ : SMulCommClass R R'' M
r : R'
x y : FreeAddMonoid (M × N)
hxy : Eqv R M N x y
m : M
⊢ (SMul.aux r) (FreeAddMonoid.of (m, 0)) = (SMul.aux r) 0

Next tactic:
simp_rw [map_zero, SMul.aux_of, tmul_zero]
/-- 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) :=
  ⟨fun r =>
    (addConGen (TensorProduct.Eqv R M N)).lift (SMul.aux r : _ →+ M ⊗[R] N) <|
      AddCon.addConGen_le fun x y hxy =>
        match x, y, hxy with
        | _, _, .of_zero_left n =>
          (AddCon.ker_rel _).2 <| by simp_rw [map_zero, SMul.aux_of, smul_zero, zero_tmul]
        | _, _, .of_zero_right m =>
          (AddCon.ker_rel _).2 <| by simp_rw [map_zero, SMul.aux_of, tmul_zero]
        | _, _, .of_add_left m₁ m₂ n =>
          (AddCon.ker_rel _).2 <| by 

Proof state:
R : Type u_1
inst✝¹⁸ : CommSemiring R
R' : Type u_2
inst✝¹⁷ : Monoid R'
R'' : Type u_3
inst✝¹⁶ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁵ : AddCommMonoid M
inst✝¹⁴ : AddCommMonoid N
inst✝¹³ : AddCommMonoid P
inst✝¹² : AddCommMonoid Q
inst✝¹¹ : AddCommMonoid S
inst✝¹⁰ : AddCommMonoid T
inst✝⁹ : Module R M
inst✝⁸ : Module R N
inst✝⁷ : Module R P
inst✝⁶ : Module R Q
inst✝⁵ : Module R S
inst✝⁴ : Module R T
inst✝³ : DistribMulAction R' M
inst✝² : Module R'' M
inst✝¹ : SMulCommClass R R' M
inst✝ : SMulCommClass R R'' M
r : R'
x y : FreeAddMonoid (M × N)
hxy : Eqv R M N x y
m₁ m₂ : M
n : N
⊢ (SMul.aux r) (FreeAddMonoid.of (m₁, n) + FreeAddMonoid.of (m₂, n)) = (SMul.aux r) (FreeAddMonoid.of (m₁ + m₂, n))

Next tactic:
simp_rw [map_add, SMul.aux_of, smul_add, add_tmul]
/-- 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) :=
  ⟨fun r =>
    (addConGen (TensorProduct.Eqv R M N)).lift (SMul.aux r : _ →+ M ⊗[R] N) <|
      AddCon.addConGen_le fun x y hxy =>
        match x, y, hxy with
        | _, _, .of_zero_left n =>
          (AddCon.ker_rel _).2 <| by simp_rw [map_zero, SMul.aux_of, smul_zero, zero_tmul]
        | _, _, .of_zero_right m =>
          (AddCon.ker_rel _).2 <| by simp_rw [map_zero, SMul.aux_of, tmul_zero]
        | _, _, .of_add_left m₁ m₂ n =>
          (AddCon.ker_rel _).2 <| by simp_rw [map_add, SMul.aux_of, smul_add, add_tmul]
        | _, _, .of_add_right m n₁ n₂ =>
          (AddCon.ker_rel _).2 <| by 

Proof state:
R : Type u_1
inst✝¹⁸ : CommSemiring R
R' : Type u_2
inst✝¹⁷ : Monoid R'
R'' : Type u_3
inst✝¹⁶ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁵ : AddCommMonoid M
inst✝¹⁴ : AddCommMonoid N
inst✝¹³ : AddCommMonoid P
inst✝¹² : AddCommMonoid Q
inst✝¹¹ : AddCommMonoid S
inst✝¹⁰ : AddCommMonoid T
inst✝⁹ : Module R M
inst✝⁸ : Module R N
inst✝⁷ : Module R P
inst✝⁶ : Module R Q
inst✝⁵ : Module R S
inst✝⁴ : Module R T
inst✝³ : DistribMulAction R' M
inst✝² : Module R'' M
inst✝¹ : SMulCommClass R R' M
inst✝ : SMulCommClass R R'' M
r : R'
x y : FreeAddMonoid (M × N)
hxy : Eqv R M N x y
m : M
n₁ n₂ : N
⊢ (SMul.aux r) (FreeAddMonoid.of (m, n₁) + FreeAddMonoid.of (m, n₂)) = (SMul.aux r) (FreeAddMonoid.of (m, n₁ + n₂))

Next tactic:
simp_rw [map_add, SMul.aux_of, tmul_add]
/-- 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) :=
  ⟨fun r =>
    (addConGen (TensorProduct.Eqv R M N)).lift (SMul.aux r : _ →+ M ⊗[R] N) <|
      AddCon.addConGen_le fun x y hxy =>
        match x, y, hxy with
        | _, _, .of_zero_left n =>
          (AddCon.ker_rel _).2 <| by simp_rw [map_zero, SMul.aux_of, smul_zero, zero_tmul]
        | _, _, .of_zero_right m =>
          (AddCon.ker_rel _).2 <| by simp_rw [map_zero, SMul.aux_of, tmul_zero]
        | _, _, .of_add_left m₁ m₂ n =>
          (AddCon.ker_rel _).2 <| by simp_rw [map_add, SMul.aux_of, smul_add, add_tmul]
        | _, _, .of_add_right m n₁ n₂ =>
          (AddCon.ker_rel _).2 <| by simp_rw [map_add, SMul.aux_of, tmul_add]
        | _, _, .of_smul s m n =>
          (AddCon.ker_rel _).2 <| by 

Proof state:
R : Type u_1
inst✝¹⁸ : CommSemiring R
R' : Type u_2
inst✝¹⁷ : Monoid R'
R'' : Type u_3
inst✝¹⁶ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁵ : AddCommMonoid M
inst✝¹⁴ : AddCommMonoid N
inst✝¹³ : AddCommMonoid P
inst✝¹² : AddCommMonoid Q
inst✝¹¹ : AddCommMonoid S
inst✝¹⁰ : AddCommMonoid T
inst✝⁹ : Module R M
inst✝⁸ : Module R N
inst✝⁷ : Module R P
inst✝⁶ : Module R Q
inst✝⁵ : Module R S
inst✝⁴ : Module R T
inst✝³ : DistribMulAction R' M
inst✝² : Module R'' M
inst✝¹ : SMulCommClass R R' M
inst✝ : SMulCommClass R R'' M
r : R'
x y : FreeAddMonoid (M × N)
hxy : Eqv R M N x y
s : R
m : M
n : N
⊢ (SMul.aux r) (FreeAddMonoid.of (s • m, n)) = (SMul.aux r) (FreeAddMonoid.of (m, s • n))

Next tactic:
rw [SMul.aux_of, SMul.aux_of, ← smul_comm, smul_tmul]
/-- 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) :=
  ⟨fun r =>
    (addConGen (TensorProduct.Eqv R M N)).lift (SMul.aux r : _ →+ M ⊗[R] N) <|
      AddCon.addConGen_le fun x y hxy =>
        match x, y, hxy with
        | _, _, .of_zero_left n =>
          (AddCon.ker_rel _).2 <| by simp_rw [map_zero, SMul.aux_of, smul_zero, zero_tmul]
        | _, _, .of_zero_right m =>
          (AddCon.ker_rel _).2 <| by simp_rw [map_zero, SMul.aux_of, tmul_zero]
        | _, _, .of_add_left m₁ m₂ n =>
          (AddCon.ker_rel _).2 <| by simp_rw [map_add, SMul.aux_of, smul_add, add_tmul]
        | _, _, .of_add_right m n₁ n₂ =>
          (AddCon.ker_rel _).2 <| by simp_rw [map_add, SMul.aux_of, tmul_add]
        | _, _, .of_smul s m n =>
          (AddCon.ker_rel _).2 <| by rw [SMul.aux_of, SMul.aux_of, ← smul_comm, smul_tmul]
        | _, _, .add_comm x y =>
          (AddCon.ker_rel _).2 <| by 

Proof state:
R : Type u_1
inst✝¹⁸ : CommSemiring R
R' : Type u_2
inst✝¹⁷ : Monoid R'
R'' : Type u_3
inst✝¹⁶ : Semiring R''
M : Type u_4
N : Type u_5
P : Type u_6
Q : Type u_7
S : Type u_8
T : Type u_9
inst✝¹⁵ : AddCommMonoid M
inst✝¹⁴ : AddCommMonoid N
inst✝¹³ : AddCommMonoid P
inst✝¹² : AddCommMonoid Q
inst✝¹¹ : AddCommMonoid S
inst✝¹⁰ : AddCommMonoid T
inst✝⁹ : Module R M
inst✝⁸ : Module R N
inst✝⁷ : Module R P
inst✝⁶ : Module R Q
inst✝⁵ : Module R S
inst✝⁴ : Module R T
inst✝³ : DistribMulAction R' M
inst✝² : Module R'' M
inst✝¹ : SMulCommClass R R' M
inst✝ : SMulCommClass R R'' M
r : R'
x✝ y✝ : FreeAddMonoid (M × N)
hxy : Eqv R M N x✝ y✝
x y : FreeAddMonoid (M × N)
⊢ (SMul.aux r) (x + y) = (SMul.aux r) (y + x)

Next tactic:
simp_rw [map_add, add_comm]