l3lab/ntp-mathlib huggingface dataset:
/-- Reinterpret `Additive G ≃+ H` as `G ≃* Multiplicative H`. -/
@[simps]
def AddEquiv.toMultiplicative' [MulOneClass G] [AddZeroClass H] :
    Additive G ≃+ H ≃ (G ≃* Multiplicative H) where
  toFun f :=
  { toFun := AddMonoidHom.toMultiplicative' f.toAddMonoidHom
    invFun := AddMonoidHom.toMultiplicative'' f.symm.toAddMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_mul' := f.map_add }
  invFun f :=
  { toFun := AddMonoidHom.toMultiplicative'.symm f.toMonoidHom
    invFun := AddMonoidHom.toMultiplicative''.symm f.symm.toMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_add' := f.map_mul }
  left_inv x := by ext; rfl
  right_inv x := by ext; 

Proof state:
case h
G : Type u_1
H : Type u_2
inst✝¹ : MulOneClass G
inst✝ : AddZeroClass H
x : G ≃* Multiplicative H
x✝ : G
⊢ ((fun f =>
          {
            toEquiv :=
              { toFun := ⇑(AddMonoidHom.toMultiplicative' (toAddMonoidHom f)),
                invFun := ⇑(AddMonoidHom.toMultiplicative'' (toAddMonoidHom (symm f))),
                left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
            map_mul' := (_ : ∀ (x y : Additive G), f (x + y) = f x + f y) })
        ((fun f =>
            {
              toEquiv :=
                { toFun := ⇑(AddMonoidHom.toMultiplicative'.symm (MulEquiv.toMonoidHom f)),
                  invFun := ⇑(AddMonoidHom.toMultiplicative''.symm (MulEquiv.toMonoidHom (MulEquiv.symm f))),
                  left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                  right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
              map_add' := (_ : ∀ (x y : G), f (x * y) = f x * f y) })
          x))
      x✝ =
    x x✝

Next tactic:
rfl
/-- Reinterpret `G ≃+ Additive H` as `Multiplicative G ≃* H`. -/
@[simps]
def AddEquiv.toMultiplicative'' [AddZeroClass G] [MulOneClass H] :
    G ≃+ Additive H ≃ (Multiplicative G ≃* H) where
  toFun f :=
  { toFun := AddMonoidHom.toMultiplicative'' f.toAddMonoidHom
    invFun := AddMonoidHom.toMultiplicative' f.symm.toAddMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_mul' := f.map_add }
  invFun f :=
  { toFun := AddMonoidHom.toMultiplicative''.symm f.toMonoidHom
    invFun := AddMonoidHom.toMultiplicative'.symm f.symm.toMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_add' := f.map_mul }
  left_inv x := by 

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : AddZeroClass G
inst✝ : MulOneClass H
x : G ≃+ Additive H
⊢ (fun f =>
        {
          toEquiv :=
            { toFun := ⇑(AddMonoidHom.toMultiplicative''.symm (MulEquiv.toMonoidHom f)),
              invFun := ⇑(AddMonoidHom.toMultiplicative'.symm (MulEquiv.toMonoidHom (MulEquiv.symm f))),
              left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
              right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
          map_add' := (_ : ∀ (x y : Multiplicative G), f (x * y) = f x * f y) })
      ((fun f =>
          {
            toEquiv :=
              { toFun := ⇑(AddMonoidHom.toMultiplicative'' (toAddMonoidHom f)),
                invFun := ⇑(AddMonoidHom.toMultiplicative' (toAddMonoidHom (symm f))),
                left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
            map_mul' := (_ : ∀ (x y : G), f (x + y) = f x + f y) })
        x) =
    x

Next tactic:
ext
/-- Reinterpret `G ≃+ Additive H` as `Multiplicative G ≃* H`. -/
@[simps]
def AddEquiv.toMultiplicative'' [AddZeroClass G] [MulOneClass H] :
    G ≃+ Additive H ≃ (Multiplicative G ≃* H) where
  toFun f :=
  { toFun := AddMonoidHom.toMultiplicative'' f.toAddMonoidHom
    invFun := AddMonoidHom.toMultiplicative' f.symm.toAddMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_mul' := f.map_add }
  invFun f :=
  { toFun := AddMonoidHom.toMultiplicative''.symm f.toMonoidHom
    invFun := AddMonoidHom.toMultiplicative'.symm f.symm.toMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_add' := f.map_mul }
  left_inv x := by ext; 

Proof state:
case h
G : Type u_1
H : Type u_2
inst✝¹ : AddZeroClass G
inst✝ : MulOneClass H
x : G ≃+ Additive H
x✝ : G
⊢ ((fun f =>
          {
            toEquiv :=
              { toFun := ⇑(AddMonoidHom.toMultiplicative''.symm (MulEquiv.toMonoidHom f)),
                invFun := ⇑(AddMonoidHom.toMultiplicative'.symm (MulEquiv.toMonoidHom (MulEquiv.symm f))),
                left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
            map_add' := (_ : ∀ (x y : Multiplicative G), f (x * y) = f x * f y) })
        ((fun f =>
            {
              toEquiv :=
                { toFun := ⇑(AddMonoidHom.toMultiplicative'' (toAddMonoidHom f)),
                  invFun := ⇑(AddMonoidHom.toMultiplicative' (toAddMonoidHom (symm f))),
                  left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                  right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
              map_mul' := (_ : ∀ (x y : G), f (x + y) = f x + f y) })
          x))
      x✝ =
    x x✝

Next tactic:
rfl
/-- Reinterpret `G ≃+ Additive H` as `Multiplicative G ≃* H`. -/
@[simps]
def AddEquiv.toMultiplicative'' [AddZeroClass G] [MulOneClass H] :
    G ≃+ Additive H ≃ (Multiplicative G ≃* H) where
  toFun f :=
  { toFun := AddMonoidHom.toMultiplicative'' f.toAddMonoidHom
    invFun := AddMonoidHom.toMultiplicative' f.symm.toAddMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_mul' := f.map_add }
  invFun f :=
  { toFun := AddMonoidHom.toMultiplicative''.symm f.toMonoidHom
    invFun := AddMonoidHom.toMultiplicative'.symm f.symm.toMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_add' := f.map_mul }
  left_inv x := by ext; rfl
  right_inv x := by 

Proof state:
G : Type u_1
H : Type u_2
inst✝¹ : AddZeroClass G
inst✝ : MulOneClass H
x : Multiplicative G ≃* H
⊢ (fun f =>
        {
          toEquiv :=
            { toFun := ⇑(AddMonoidHom.toMultiplicative'' (toAddMonoidHom f)),
              invFun := ⇑(AddMonoidHom.toMultiplicative' (toAddMonoidHom (symm f))),
              left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
              right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
          map_mul' := (_ : ∀ (x y : G), f (x + y) = f x + f y) })
      ((fun f =>
          {
            toEquiv :=
              { toFun := ⇑(AddMonoidHom.toMultiplicative''.symm (MulEquiv.toMonoidHom f)),
                invFun := ⇑(AddMonoidHom.toMultiplicative'.symm (MulEquiv.toMonoidHom (MulEquiv.symm f))),
                left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
            map_add' := (_ : ∀ (x y : Multiplicative G), f (x * y) = f x * f y) })
        x) =
    x

Next tactic:
ext
/-- Reinterpret `G ≃+ Additive H` as `Multiplicative G ≃* H`. -/
@[simps]
def AddEquiv.toMultiplicative'' [AddZeroClass G] [MulOneClass H] :
    G ≃+ Additive H ≃ (Multiplicative G ≃* H) where
  toFun f :=
  { toFun := AddMonoidHom.toMultiplicative'' f.toAddMonoidHom
    invFun := AddMonoidHom.toMultiplicative' f.symm.toAddMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_mul' := f.map_add }
  invFun f :=
  { toFun := AddMonoidHom.toMultiplicative''.symm f.toMonoidHom
    invFun := AddMonoidHom.toMultiplicative'.symm f.symm.toMonoidHom
    left_inv := f.left_inv
    right_inv := f.right_inv
    map_add' := f.map_mul }
  left_inv x := by ext; rfl
  right_inv x := by ext; 

Proof state:
case h
G : Type u_1
H : Type u_2
inst✝¹ : AddZeroClass G
inst✝ : MulOneClass H
x : Multiplicative G ≃* H
x✝ : Multiplicative G
⊢ ((fun f =>
          {
            toEquiv :=
              { toFun := ⇑(AddMonoidHom.toMultiplicative'' (toAddMonoidHom f)),
                invFun := ⇑(AddMonoidHom.toMultiplicative' (toAddMonoidHom (symm f))),
                left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
            map_mul' := (_ : ∀ (x y : G), f (x + y) = f x + f y) })
        ((fun f =>
            {
              toEquiv :=
                { toFun := ⇑(AddMonoidHom.toMultiplicative''.symm (MulEquiv.toMonoidHom f)),
                  invFun := ⇑(AddMonoidHom.toMultiplicative'.symm (MulEquiv.toMonoidHom (MulEquiv.symm f))),
                  left_inv := (_ : Function.LeftInverse f.invFun f.toFun),
                  right_inv := (_ : Function.RightInverse f.invFun f.toFun) },
              map_add' := (_ : ∀ (x y : Multiplicative G), f (x * y) = f x * f y) })
          x))
      x✝ =
    x x✝

Next tactic:
rfl
theorem KaehlerDifferential.one_smul_sub_smul_one_mem_ideal (a : S) :
    (1 : S) ⊗ₜ[R] a - a ⊗ₜ[R] (1 : S) ∈ KaehlerDifferential.ideal R S := by 

Proof state:
R : Type u
S : Type v
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : Algebra R S
a : S
⊢ 1 ⊗ₜ[R] a - a ⊗ₜ[R] 1 ∈ ideal R S

Next tactic:
simp [RingHom.mem_ker]
theorem Derivation.tensorProductTo_mul (D : Derivation R S M) (x y : S ⊗[R] S) :
    D.tensorProductTo (x * y) =
      TensorProduct.lmul' (S := S) R x • D.tensorProductTo y +
        TensorProduct.lmul' (S := S) R y • D.tensorProductTo x := by
  

Proof state:
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
M : Type u_1
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : Module S M
inst✝ : IsScalarTower R S M
D : Derivation R S M
x y : S ⊗[R] S
⊢ (tensorProductTo D) (x * y) =
    (TensorProduct.lmul' R) x • (tensorProductTo D) y + (TensorProduct.lmul' R) y • (tensorProductTo D) x

Next tactic:
refine TensorProduct.induction_on x ?_ ?_ ?_
theorem Derivation.tensorProductTo_mul (D : Derivation R S M) (x y : S ⊗[R] S) :
    D.tensorProductTo (x * y) =
      TensorProduct.lmul' (S := S) R x • D.tensorProductTo y +
        TensorProduct.lmul' (S := S) R y • D.tensorProductTo x := by
  refine TensorProduct.induction_on x ?_ ?_ ?_
  · 

Proof state:
case refine_1
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
M : Type u_1
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : Module S M
inst✝ : IsScalarTower R S M
D : Derivation R S M
x y : S ⊗[R] S
⊢ (tensorProductTo D) (0 * y) =
    (TensorProduct.lmul' R) 0 • (tensorProductTo D) y + (TensorProduct.lmul' R) y • (tensorProductTo D) 0

Next tactic:
rw [zero_mul, map_zero, map_zero, zero_smul, smul_zero, add_zero]
theorem Derivation.tensorProductTo_mul (D : Derivation R S M) (x y : S ⊗[R] S) :
    D.tensorProductTo (x * y) =
      TensorProduct.lmul' (S := S) R x • D.tensorProductTo y +
        TensorProduct.lmul' (S := S) R y • D.tensorProductTo x := by
  refine TensorProduct.induction_on x ?_ ?_ ?_
  · rw [zero_mul, map_zero, map_zero, zero_smul, smul_zero, add_zero]
  

Proof state:
case refine_2
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
M : Type u_1
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : Module S M
inst✝ : IsScalarTower R S M
D : Derivation R S M
x y : S ⊗[R] S
⊢ ∀ (x y_1 : S),
    (tensorProductTo D) (x ⊗ₜ[R] y_1 * y) =
      (TensorProduct.lmul' R) (x ⊗ₜ[R] y_1) • (tensorProductTo D) y +
        (TensorProduct.lmul' R) y • (tensorProductTo D) (x ⊗ₜ[R] y_1)
case refine_3
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
M : Type u_1
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : Module S M
inst✝ : IsScalarTower R S M
D : Derivation R S M
x y : S ⊗[R] S
⊢ ∀ (x y_1 : S ⊗[R] S),
    (tensorProductTo D) (x * y) =
        (TensorProduct.lmul' R) x • (tensorProductTo D) y + (TensorProduct.lmul' R) y • (tensorProductTo D) x →
      (tensorProductTo D) (y_1 * y) =
          (TensorProduct.lmul' R) y_1 • (tensorProductTo D) y + (TensorProduct.lmul' R) y • (tensorProductTo D) y_1 →
        (tensorProductTo D) ((x + y_1) * y) =
          (TensorProduct.lmul' R) (x + y_1) • (tensorProductTo D) y +
            (TensorProduct.lmul' R) y • (tensorProductTo D) (x + y_1)

Next tactic:
swap
theorem Derivation.tensorProductTo_mul (D : Derivation R S M) (x y : S ⊗[R] S) :
    D.tensorProductTo (x * y) =
      TensorProduct.lmul' (S := S) R x • D.tensorProductTo y +
        TensorProduct.lmul' (S := S) R y • D.tensorProductTo x := by
  refine TensorProduct.induction_on x ?_ ?_ ?_
  · rw [zero_mul, map_zero, map_zero, zero_smul, smul_zero, add_zero]
  swap
  · 

Proof state:
case refine_3
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
M : Type u_1
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : Module S M
inst✝ : IsScalarTower R S M
D : Derivation R S M
x y : S ⊗[R] S
⊢ ∀ (x y_1 : S ⊗[R] S),
    (tensorProductTo D) (x * y) =
        (TensorProduct.lmul' R) x • (tensorProductTo D) y + (TensorProduct.lmul' R) y • (tensorProductTo D) x →
      (tensorProductTo D) (y_1 * y) =
          (TensorProduct.lmul' R) y_1 • (tensorProductTo D) y + (TensorProduct.lmul' R) y • (tensorProductTo D) y_1 →
        (tensorProductTo D) ((x + y_1) * y) =
          (TensorProduct.lmul' R) (x + y_1) • (tensorProductTo D) y +
            (TensorProduct.lmul' R) y • (tensorProductTo D) (x + y_1)

Next tactic:
intro x₁ y₁ h₁ h₂
theorem Derivation.tensorProductTo_mul (D : Derivation R S M) (x y : S ⊗[R] S) :
    D.tensorProductTo (x * y) =
      TensorProduct.lmul' (S := S) R x • D.tensorProductTo y +
        TensorProduct.lmul' (S := S) R y • D.tensorProductTo x := by
  refine TensorProduct.induction_on x ?_ ?_ ?_
  · rw [zero_mul, map_zero, map_zero, zero_smul, smul_zero, add_zero]
  swap
  · intro x₁ y₁ h₁ h₂
    

Proof state:
case refine_3
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
M : Type u_1
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : Module S M
inst✝ : IsScalarTower R S M
D : Derivation R S M
x y x₁ y₁ : S ⊗[R] S
h₁ :
  (tensorProductTo D) (x₁ * y) =
    (TensorProduct.lmul' R) x₁ • (tensorProductTo D) y + (TensorProduct.lmul' R) y • (tensorProductTo D) x₁
h₂ :
  (tensorProductTo D) (y₁ * y) =
    (TensorProduct.lmul' R) y₁ • (tensorProductTo D) y + (TensorProduct.lmul' R) y • (tensorProductTo D) y₁
⊢ (tensorProductTo D) ((x₁ + y₁) * y) =
    (TensorProduct.lmul' R) (x₁ + y₁) • (tensorProductTo D) y +
      (TensorProduct.lmul' R) y • (tensorProductTo D) (x₁ + y₁)

Next tactic:
rw [add_mul, map_add, map_add, map_add, add_smul, smul_add, h₁, h₂, add_add_add_comm]
theorem Derivation.tensorProductTo_mul (D : Derivation R S M) (x y : S ⊗[R] S) :
    D.tensorProductTo (x * y) =
      TensorProduct.lmul' (S := S) R x • D.tensorProductTo y +
        TensorProduct.lmul' (S := S) R y • D.tensorProductTo x := by
  refine TensorProduct.induction_on x ?_ ?_ ?_
  · rw [zero_mul, map_zero, map_zero, zero_smul, smul_zero, add_zero]
  swap
  · intro x₁ y₁ h₁ h₂
    rw [add_mul, map_add, map_add, map_add, add_smul, smul_add, h₁, h₂, add_add_add_comm]
  

Proof state:
case refine_2
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
M : Type u_1
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : Module S M
inst✝ : IsScalarTower R S M
D : Derivation R S M
x y : S ⊗[R] S
⊢ ∀ (x y_1 : S),
    (tensorProductTo D) (x ⊗ₜ[R] y_1 * y) =
      (TensorProduct.lmul' R) (x ⊗ₜ[R] y_1) • (tensorProductTo D) y +
        (TensorProduct.lmul' R) y • (tensorProductTo D) (x ⊗ₜ[R] y_1)

Next tactic:
intro x₁ x₂
theorem Derivation.tensorProductTo_mul (D : Derivation R S M) (x y : S ⊗[R] S) :
    D.tensorProductTo (x * y) =
      TensorProduct.lmul' (S := S) R x • D.tensorProductTo y +
        TensorProduct.lmul' (S := S) R y • D.tensorProductTo x := by
  refine TensorProduct.induction_on x ?_ ?_ ?_
  · rw [zero_mul, map_zero, map_zero, zero_smul, smul_zero, add_zero]
  swap
  · intro x₁ y₁ h₁ h₂
    rw [add_mul, map_add, map_add, map_add, add_smul, smul_add, h₁, h₂, add_add_add_comm]
  intro x₁ x₂
  

Proof state:
case refine_2
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
M : Type u_1
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : Module S M
inst✝ : IsScalarTower R S M
D : Derivation R S M
x y : S ⊗[R] S
x₁ x₂ : S
⊢ (tensorProductTo D) (x₁ ⊗ₜ[R] x₂ * y) =
    (TensorProduct.lmul' R) (x₁ ⊗ₜ[R] x₂) • (tensorProductTo D) y +
      (TensorProduct.lmul' R) y • (tensorProductTo D) (x₁ ⊗ₜ[R] x₂)

Next tactic:
refine TensorProduct.induction_on y ?_ ?_ ?_
theorem Derivation.tensorProductTo_mul (D : Derivation R S M) (x y : S ⊗[R] S) :
    D.tensorProductTo (x * y) =
      TensorProduct.lmul' (S := S) R x • D.tensorProductTo y +
        TensorProduct.lmul' (S := S) R y • D.tensorProductTo x := by
  refine TensorProduct.induction_on x ?_ ?_ ?_
  · rw [zero_mul, map_zero, map_zero, zero_smul, smul_zero, add_zero]
  swap
  · intro x₁ y₁ h₁ h₂
    rw [add_mul, map_add, map_add, map_add, add_smul, smul_add, h₁, h₂, add_add_add_comm]
  intro x₁ x₂
  refine TensorProduct.induction_on y ?_ ?_ ?_
  · 

Proof state:
case refine_2.refine_1
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
M : Type u_1
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : Module S M
inst✝ : IsScalarTower R S M
D : Derivation R S M
x y : S ⊗[R] S
x₁ x₂ : S
⊢ (tensorProductTo D) (x₁ ⊗ₜ[R] x₂ * 0) =
    (TensorProduct.lmul' R) (x₁ ⊗ₜ[R] x₂) • (tensorProductTo D) 0 +
      (TensorProduct.lmul' R) 0 • (tensorProductTo D) (x₁ ⊗ₜ[R] x₂)

Next tactic:
rw [mul_zero, map_zero, map_zero, zero_smul, smul_zero, add_zero]
theorem Derivation.tensorProductTo_mul (D : Derivation R S M) (x y : S ⊗[R] S) :
    D.tensorProductTo (x * y) =
      TensorProduct.lmul' (S := S) R x • D.tensorProductTo y +
        TensorProduct.lmul' (S := S) R y • D.tensorProductTo x := by
  refine TensorProduct.induction_on x ?_ ?_ ?_
  · rw [zero_mul, map_zero, map_zero, zero_smul, smul_zero, add_zero]
  swap
  · intro x₁ y₁ h₁ h₂
    rw [add_mul, map_add, map_add, map_add, add_smul, smul_add, h₁, h₂, add_add_add_comm]
  intro x₁ x₂
  refine TensorProduct.induction_on y ?_ ?_ ?_
  · rw [mul_zero, map_zero, map_zero, zero_smul, smul_zero, add_zero]
  

Proof state:
case refine_2.refine_2
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
M : Type u_1
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : Module S M
inst✝ : IsScalarTower R S M
D : Derivation R S M
x y : S ⊗[R] S
x₁ x₂ : S
⊢ ∀ (x y : S),
    (tensorProductTo D) (x₁ ⊗ₜ[R] x₂ * x ⊗ₜ[R] y) =
      (TensorProduct.lmul' R) (x₁ ⊗ₜ[R] x₂) • (tensorProductTo D) (x ⊗ₜ[R] y) +
        (TensorProduct.lmul' R) (x ⊗ₜ[R] y) • (tensorProductTo D) (x₁ ⊗ₜ[R] x₂)
case refine_2.refine_3
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
M : Type u_1
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : Module S M
inst✝ : IsScalarTower R S M
D : Derivation R S M
x y : S ⊗[R] S
x₁ x₂ : S
⊢ ∀ (x y : S ⊗[R] S),
    (tensorProductTo D) (x₁ ⊗ₜ[R] x₂ * x) =
        (TensorProduct.lmul' R) (x₁ ⊗ₜ[R] x₂) • (tensorProductTo D) x +
          (TensorProduct.lmul' R) x • (tensorProductTo D) (x₁ ⊗ₜ[R] x₂) →
      (tensorProductTo D) (x₁ ⊗ₜ[R] x₂ * y) =
          (TensorProduct.lmul' R) (x₁ ⊗ₜ[R] x₂) • (tensorProductTo D) y +
            (TensorProduct.lmul' R) y • (tensorProductTo D) (x₁ ⊗ₜ[R] x₂) →
        (tensorProductTo D) (x₁ ⊗ₜ[R] x₂ * (x + y)) =
          (TensorProduct.lmul' R) (x₁ ⊗ₜ[R] x₂) • (tensorProductTo D) (x + y) +
            (TensorProduct.lmul' R) (x + y) • (tensorProductTo D) (x₁ ⊗ₜ[R] x₂)

Next tactic:
swap
theorem Derivation.tensorProductTo_mul (D : Derivation R S M) (x y : S ⊗[R] S) :
    D.tensorProductTo (x * y) =
      TensorProduct.lmul' (S := S) R x • D.tensorProductTo y +
        TensorProduct.lmul' (S := S) R y • D.tensorProductTo x := by
  refine TensorProduct.induction_on x ?_ ?_ ?_
  · rw [zero_mul, map_zero, map_zero, zero_smul, smul_zero, add_zero]
  swap
  · intro x₁ y₁ h₁ h₂
    rw [add_mul, map_add, map_add, map_add, add_smul, smul_add, h₁, h₂, add_add_add_comm]
  intro x₁ x₂
  refine TensorProduct.induction_on y ?_ ?_ ?_
  · rw [mul_zero, map_zero, map_zero, zero_smul, smul_zero, add_zero]
  swap
  · 

Proof state:
case refine_2.refine_3
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
M : Type u_1
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : Module S M
inst✝ : IsScalarTower R S M
D : Derivation R S M
x y : S ⊗[R] S
x₁ x₂ : S
⊢ ∀ (x y : S ⊗[R] S),
    (tensorProductTo D) (x₁ ⊗ₜ[R] x₂ * x) =
        (TensorProduct.lmul' R) (x₁ ⊗ₜ[R] x₂) • (tensorProductTo D) x +
          (TensorProduct.lmul' R) x • (tensorProductTo D) (x₁ ⊗ₜ[R] x₂) →
      (tensorProductTo D) (x₁ ⊗ₜ[R] x₂ * y) =
          (TensorProduct.lmul' R) (x₁ ⊗ₜ[R] x₂) • (tensorProductTo D) y +
            (TensorProduct.lmul' R) y • (tensorProductTo D) (x₁ ⊗ₜ[R] x₂) →
        (tensorProductTo D) (x₁ ⊗ₜ[R] x₂ * (x + y)) =
          (TensorProduct.lmul' R) (x₁ ⊗ₜ[R] x₂) • (tensorProductTo D) (x + y) +
            (TensorProduct.lmul' R) (x + y) • (tensorProductTo D) (x₁ ⊗ₜ[R] x₂)

Next tactic:
intro x₁ y₁ h₁ h₂
theorem Derivation.tensorProductTo_mul (D : Derivation R S M) (x y : S ⊗[R] S) :
    D.tensorProductTo (x * y) =
      TensorProduct.lmul' (S := S) R x • D.tensorProductTo y +
        TensorProduct.lmul' (S := S) R y • D.tensorProductTo x := by
  refine TensorProduct.induction_on x ?_ ?_ ?_
  · rw [zero_mul, map_zero, map_zero, zero_smul, smul_zero, add_zero]
  swap
  · intro x₁ y₁ h₁ h₂
    rw [add_mul, map_add, map_add, map_add, add_smul, smul_add, h₁, h₂, add_add_add_comm]
  intro x₁ x₂
  refine TensorProduct.induction_on y ?_ ?_ ?_
  · rw [mul_zero, map_zero, map_zero, zero_smul, smul_zero, add_zero]
  swap
  · intro x₁ y₁ h₁ h₂
    

Proof state:
case refine_2.refine_3
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
M : Type u_1
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : Module S M
inst✝ : IsScalarTower R S M
D : Derivation R S M
x y : S ⊗[R] S
x₁✝ x₂ : S
x₁ y₁ : S ⊗[R] S
h₁ :
  (tensorProductTo D) (x₁✝ ⊗ₜ[R] x₂ * x₁) =
    (TensorProduct.lmul' R) (x₁✝ ⊗ₜ[R] x₂) • (tensorProductTo D) x₁ +
      (TensorProduct.lmul' R) x₁ • (tensorProductTo D) (x₁✝ ⊗ₜ[R] x₂)
h₂ :
  (tensorProductTo D) (x₁✝ ⊗ₜ[R] x₂ * y₁) =
    (TensorProduct.lmul' R) (x₁✝ ⊗ₜ[R] x₂) • (tensorProductTo D) y₁ +
      (TensorProduct.lmul' R) y₁ • (tensorProductTo D) (x₁✝ ⊗ₜ[R] x₂)
⊢ (tensorProductTo D) (x₁✝ ⊗ₜ[R] x₂ * (x₁ + y₁)) =
    (TensorProduct.lmul' R) (x₁✝ ⊗ₜ[R] x₂) • (tensorProductTo D) (x₁ + y₁) +
      (TensorProduct.lmul' R) (x₁ + y₁) • (tensorProductTo D) (x₁✝ ⊗ₜ[R] x₂)

Next tactic:
rw [mul_add, map_add, map_add, map_add, add_smul, smul_add, h₁, h₂, add_add_add_comm]
theorem Derivation.tensorProductTo_mul (D : Derivation R S M) (x y : S ⊗[R] S) :
    D.tensorProductTo (x * y) =
      TensorProduct.lmul' (S := S) R x • D.tensorProductTo y +
        TensorProduct.lmul' (S := S) R y • D.tensorProductTo x := by
  refine TensorProduct.induction_on x ?_ ?_ ?_
  · rw [zero_mul, map_zero, map_zero, zero_smul, smul_zero, add_zero]
  swap
  · intro x₁ y₁ h₁ h₂
    rw [add_mul, map_add, map_add, map_add, add_smul, smul_add, h₁, h₂, add_add_add_comm]
  intro x₁ x₂
  refine TensorProduct.induction_on y ?_ ?_ ?_
  · rw [mul_zero, map_zero, map_zero, zero_smul, smul_zero, add_zero]
  swap
  · intro x₁ y₁ h₁ h₂
    rw [mul_add, map_add, map_add, map_add, add_smul, smul_add, h₁, h₂, add_add_add_comm]
  

Proof state:
case refine_2.refine_2
R : Type u
S : Type v
inst✝⁶ : CommRing R
inst✝⁵ : CommRing S
inst✝⁴ : Algebra R S
M : Type u_1
inst✝³ : AddCommGroup M
inst✝² : Module R M
inst✝¹ : Module S M
inst✝ : IsScalarTower R S M
D : Derivation R S M
x y : S ⊗[R] S
x₁ x₂ : S
⊢ ∀ (x y : S),
    (tensorProductTo D) (x₁ ⊗ₜ[R] x₂ * x ⊗ₜ[R] y) =
      (TensorProduct.lmul' R) (x₁ ⊗ₜ[R] x₂) • (tensorProductTo D) (x ⊗ₜ[R] y) +
        (TensorProduct.lmul' R) (x ⊗ₜ[R] y) • (tensorProductTo D) (x₁ ⊗ₜ[R] x₂)

Next tactic:
intro x y