l3lab/ntp-mathlib huggingface dataset:
@[to_additive (attr := simp)]
theorem mul_smul_one {M N} [MulOneClass N] [SMul M N] [SMulCommClass M N N] (x : M) (y : N) :
    y * x • (1 : N) = x • y := by 

Proof state:
M✝ : Type u_1
N✝ : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
M : Type u_10
N : Type u_11
inst✝² : MulOneClass N
inst✝¹ : SMul M N
inst✝ : SMulCommClass M N N
x : M
y : N
⊢ y * x • 1 = x • y

Next tactic:
rw [← smul_eq_mul, ← smul_comm, smul_eq_mul, mul_one]
@[to_additive]
theorem IsScalarTower.of_smul_one_mul {M N} [Monoid N] [SMul M N]
    (h : ∀ (x : M) (y : N), x • (1 : N) * y = x • y) : IsScalarTower M N N :=
  ⟨fun x y z => by 

Proof state:
M✝ : Type u_1
N✝ : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
M : Type u_10
N : Type u_11
inst✝¹ : Monoid N
inst✝ : SMul M N
h : ∀ (x : M) (y : N), x • 1 * y = x • y
x : M
y z : N
⊢ (x • y) • z = x • y • z

Next tactic:
rw [← h, smul_eq_mul, mul_assoc, h, smul_eq_mul]
@[to_additive]
theorem SMulCommClass.of_mul_smul_one {M N} [Monoid N] [SMul M N]
    (H : ∀ (x : M) (y : N), y * x • (1 : N) = x • y) : SMulCommClass M N N :=
  ⟨fun x y z => by 

Proof state:
M✝ : Type u_1
N✝ : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
M : Type u_10
N : Type u_11
inst✝¹ : Monoid N
inst✝ : SMul M N
H : ∀ (x : M) (y : N), y * x • 1 = x • y
x : M
y z : N
⊢ x • y • z = y • x • z

Next tactic:
rw [← H x z, smul_eq_mul, ← H, smul_eq_mul, mul_assoc]
/-- If the multiplicative action of `M` on `N` is compatible with multiplication on `N`, then
`fun x => x • 1` is a monoid homomorphism from `M` to `N`. -/
@[to_additive (attr := simps)
    "If the additive action of `M` on `N` is compatible with addition on `N`, then
    `fun x => x +ᵥ 0` is an additive monoid homomorphism from `M` to `N`."]
def MonoidHom.smulOneHom {M N} [Monoid M] [MulOneClass N] [MulAction M N] [IsScalarTower M N N] :
    M →* N where
  toFun x := x • (1 : N)
  map_one' := one_smul _ _
  map_mul' x y := by 

Proof state:
M✝ : Type u_1
N✝ : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
M : Type ?u.30720
N : Type ?u.30723
inst✝³ : Monoid M
inst✝² : MulOneClass N
inst✝¹ : MulAction M N
inst✝ : IsScalarTower M N N
x y : M
⊢ OneHom.toFun { toFun := fun x => x • 1, map_one' := (_ : 1 • 1 = 1) } (x * y) =
    OneHom.toFun { toFun := fun x => x • 1, map_one' := (_ : 1 • 1 = 1) } x *
      OneHom.toFun { toFun := fun x => x • 1, map_one' := (_ : 1 • 1 = 1) } y

Next tactic:
rw [smul_one_mul, smul_smul]
@[simp]
lemma smul_ite_zero (p : Prop) [Decidable p] (a : M) (b : A) :
    (a • if p then b else 0) = if p then a • b else 0 := by 

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝² : Zero A
inst✝¹ : SMulZeroClass M A
p : Prop
inst✝ : Decidable p
a : M
b : A
⊢ (a • if p then b else 0) = if p then a • b else 0

Next tactic:
rw [smul_ite, smul_zero]
/-- Pullback a zero-preserving scalar multiplication along an injective zero-preserving map.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Injective.smulZeroClass [Zero B] [SMul M B] (f : ZeroHom B A)
    (hf : Injective f) (smul : ∀ (c : M) (x), f (c • x) = c • f x) :
    SMulZeroClass M B where
  smul := (· • ·)
  smul_zero c := hf <| by 

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝³ : Zero A
inst✝² : SMulZeroClass M A
inst✝¹ : Zero B
inst✝ : SMul M B
f : ZeroHom B A
hf : Injective ⇑f
smul : ∀ (c : M) (x : B), f (c • x) = c • f x
c : M
⊢ f (c • 0) = f 0

Next tactic:
simp only [smul, map_zero, smul_zero]
/-- Pushforward a zero-preserving scalar multiplication along a zero-preserving map.
See note [reducible non-instances]. -/
@[reducible]
protected def ZeroHom.smulZeroClass [Zero B] [SMul M B] (f : ZeroHom A B)
    (smul : ∀ (c : M) (x), f (c • x) = c • f x) :
    SMulZeroClass M B where
  -- Porting note: `simp` no longer works here.
  smul_zero c := by 

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝³ : Zero A
inst✝² : SMulZeroClass M A
inst✝¹ : Zero B
inst✝ : SMul M B
f : ZeroHom A B
smul : ∀ (c : M) (x : A), f (c • x) = c • f x
c : M
⊢ c • 0 = 0

Next tactic:
rw [← map_zero f, ← smul, smul_zero]
/-- Push forward the multiplication of `R` on `M` along a compatible surjective map `f : R → S`.

See also `Function.Surjective.distribMulActionLeft`.
-/
@[reducible]
def Function.Surjective.smulZeroClassLeft {R S M : Type*} [Zero M] [SMulZeroClass R M]
    [SMul S M] (f : R → S) (hf : Function.Surjective f)
    (hsmul : ∀ (c) (x : M), f c • x = c • x) :
    SMulZeroClass S M where
  smul := (· • ·)
  smul_zero := hf.forall.mpr fun c => by 

Proof state:
M✝ : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝⁴ : Zero A
inst✝³ : SMulZeroClass M✝ A
R : Type u_10
S : Type u_11
M : Type u_12
inst✝² : Zero M
inst✝¹ : SMulZeroClass R M
inst✝ : SMul S M
f : R → S
hf : Surjective f
hsmul : ∀ (c : R) (x : M), f c • x = c • x
c : R
⊢ f c • 0 = 0

Next tactic:
rw [hsmul, smul_zero]
instance AddMonoidHom.smulZeroClass [AddZeroClass B] : SMulZeroClass M (B →+ A) where
  smul r f :=
    { toFun := (fun a => r • (f a))
      map_zero' := by 

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝² : AddZeroClass A
inst✝¹ : DistribSMul M A
inst✝ : AddZeroClass B
r : M
f : B →+ A
⊢ (fun a => r • f a) 0 = 0

Next tactic:
simp only [map_zero, smul_zero]
instance AddMonoidHom.smulZeroClass [AddZeroClass B] : SMulZeroClass M (B →+ A) where
  smul r f :=
    { toFun := (fun a => r • (f a))
      map_zero' := by simp only [map_zero, smul_zero]
      map_add' := fun x y => by 

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝² : AddZeroClass A
inst✝¹ : DistribSMul M A
inst✝ : AddZeroClass B
r : M
f : B →+ A
x y : B
⊢ ZeroHom.toFun { toFun := fun a => r • f a, map_zero' := (_ : r • f 0 = 0) } (x + y) =
    ZeroHom.toFun { toFun := fun a => r • f a, map_zero' := (_ : r • f 0 = 0) } x +
      ZeroHom.toFun { toFun := fun a => r • f a, map_zero' := (_ : r • f 0 = 0) } y

Next tactic:
simp only [map_add, smul_add]
/-- Pullback a distributive scalar multiplication along an injective additive monoid
homomorphism.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Injective.distribSMul [AddZeroClass B] [SMul M B] (f : B →+ A)
    (hf : Injective f) (smul : ∀ (c : M) (x), f (c • x) = c • f x) : DistribSMul M B :=
  { hf.smulZeroClass f.toZeroHom smul with
    smul_add := fun c x y => hf <| by 

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝³ : AddZeroClass A
inst✝² : DistribSMul M A
inst✝¹ : AddZeroClass B
inst✝ : SMul M B
f : B →+ A
hf : Injective ⇑f
smul : ∀ (c : M) (x : B), f (c • x) = c • f x
src✝ : SMulZeroClass M B := Injective.smulZeroClass (↑f) hf smul
c : M
x y : B
⊢ f (c • (x + y)) = f (c • x + c • y)

Next tactic:
simp only [smul, map_add, smul_add]
/-- Pushforward a distributive scalar multiplication along a surjective additive monoid
homomorphism.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Surjective.distribSMul [AddZeroClass B] [SMul M B] (f : A →+ B)
    (hf : Surjective f) (smul : ∀ (c : M) (x), f (c • x) = c • f x) : DistribSMul M B :=
  { f.toZeroHom.smulZeroClass smul with
    smul_add := fun c x y => by
      

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝³ : AddZeroClass A
inst✝² : DistribSMul M A
inst✝¹ : AddZeroClass B
inst✝ : SMul M B
f : A →+ B
hf : Surjective ⇑f
smul : ∀ (c : M) (x : A), f (c • x) = c • f x
src✝ : SMulZeroClass M B := ZeroHom.smulZeroClass (↑f) smul
c : M
x y : B
⊢ c • (x + y) = c • x + c • y

Next tactic:
rcases hf x with ⟨x, rfl⟩
/-- Pushforward a distributive scalar multiplication along a surjective additive monoid
homomorphism.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Surjective.distribSMul [AddZeroClass B] [SMul M B] (f : A →+ B)
    (hf : Surjective f) (smul : ∀ (c : M) (x), f (c • x) = c • f x) : DistribSMul M B :=
  { f.toZeroHom.smulZeroClass smul with
    smul_add := fun c x y => by
      rcases hf x with ⟨x, rfl⟩
      

Proof state:
case intro
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝³ : AddZeroClass A
inst✝² : DistribSMul M A
inst✝¹ : AddZeroClass B
inst✝ : SMul M B
f : A →+ B
hf : Surjective ⇑f
smul : ∀ (c : M) (x : A), f (c • x) = c • f x
src✝ : SMulZeroClass M B := ZeroHom.smulZeroClass (↑f) smul
c : M
y : B
x : A
⊢ c • (f x + y) = c • f x + c • y

Next tactic:
rcases hf y with ⟨y, rfl⟩
/-- Pushforward a distributive scalar multiplication along a surjective additive monoid
homomorphism.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Surjective.distribSMul [AddZeroClass B] [SMul M B] (f : A →+ B)
    (hf : Surjective f) (smul : ∀ (c : M) (x), f (c • x) = c • f x) : DistribSMul M B :=
  { f.toZeroHom.smulZeroClass smul with
    smul_add := fun c x y => by
      rcases hf x with ⟨x, rfl⟩
      rcases hf y with ⟨y, rfl⟩
      

Proof state:
case intro.intro
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝³ : AddZeroClass A
inst✝² : DistribSMul M A
inst✝¹ : AddZeroClass B
inst✝ : SMul M B
f : A →+ B
hf : Surjective ⇑f
smul : ∀ (c : M) (x : A), f (c • x) = c • f x
src✝ : SMulZeroClass M B := ZeroHom.smulZeroClass (↑f) smul
c : M
x y : A
⊢ c • (f x + f y) = c • f x + c • f y

Next tactic:
simp only [smul_add, ← smul, ← map_add]
/-- Push forward the multiplication of `R` on `M` along a compatible surjective map `f : R → S`.

See also `Function.Surjective.distribMulActionLeft`.
-/
@[reducible]
def Function.Surjective.distribSMulLeft {R S M : Type*} [AddZeroClass M] [DistribSMul R M]
    [SMul S M] (f : R → S) (hf : Function.Surjective f)
    (hsmul : ∀ (c) (x : M), f c • x = c • x) : DistribSMul S M :=
  { hf.smulZeroClassLeft f hsmul with
    smul_add := hf.forall.mpr fun c x y => by 

Proof state:
M✝ : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝⁴ : AddZeroClass A
inst✝³ : DistribSMul M✝ A
R : Type u_10
S : Type u_11
M : Type u_12
inst✝² : AddZeroClass M
inst✝¹ : DistribSMul R M
inst✝ : SMul S M
f : R → S
hf : Surjective f
hsmul : ∀ (c : R) (x : M), f c • x = c • x
src✝ : SMulZeroClass S M := smulZeroClassLeft f hf hsmul
c : R
x y : M
⊢ f c • (x + y) = f c • x + f c • y

Next tactic:
simp only [hsmul, smul_add]
@[simp]
theorem smul_neg (r : M) (x : A) : r • -x = -(r • x) :=
  eq_neg_of_add_eq_zero_left <| by 

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝² : Monoid M
inst✝¹ : AddGroup A
inst✝ : DistribMulAction M A
r : M
x : A
⊢ r • -x + r • x = 0

Next tactic:
rw [← smul_add, neg_add_self, smul_zero]
theorem smul_sub (r : M) (x y : A) : r • (x - y) = r • x - r • y := by
  

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝² : Monoid M
inst✝¹ : AddGroup A
inst✝ : DistribMulAction M A
r : M
x y : A
⊢ r • (x - y) = r • x - r • y

Next tactic:
rw [sub_eq_add_neg, sub_eq_add_neg, smul_add, smul_neg]
/-- Pullback a multiplicative distributive multiplicative action along an injective monoid
homomorphism.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Injective.mulDistribMulAction [Monoid B] [SMul M B] (f : B →* A)
    (hf : Injective f) (smul : ∀ (c : M) (x), f (c • x) = c • f x) : MulDistribMulAction M B :=
  { hf.mulAction f smul with
    smul_mul := fun c x y => hf <| by 

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝⁴ : Monoid M
inst✝³ : Monoid A
inst✝² : MulDistribMulAction M A
inst✝¹ : Monoid B
inst✝ : SMul M B
f : B →* A
hf : Injective ⇑f
smul : ∀ (c : M) (x : B), f (c • x) = c • f x
src✝ : MulAction M B := Injective.mulAction (⇑f) hf smul
c : M
x y : B
⊢ f (c • (x * y)) = f (c • x * c • y)

Next tactic:
simp only [smul, f.map_mul, smul_mul']
/-- Pullback a multiplicative distributive multiplicative action along an injective monoid
homomorphism.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Injective.mulDistribMulAction [Monoid B] [SMul M B] (f : B →* A)
    (hf : Injective f) (smul : ∀ (c : M) (x), f (c • x) = c • f x) : MulDistribMulAction M B :=
  { hf.mulAction f smul with
    smul_mul := fun c x y => hf <| by simp only [smul, f.map_mul, smul_mul'],
    smul_one := fun c => hf <| by 

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝⁴ : Monoid M
inst✝³ : Monoid A
inst✝² : MulDistribMulAction M A
inst✝¹ : Monoid B
inst✝ : SMul M B
f : B →* A
hf : Injective ⇑f
smul : ∀ (c : M) (x : B), f (c • x) = c • f x
src✝ : MulAction M B := Injective.mulAction (⇑f) hf smul
c : M
⊢ f (c • 1) = f 1

Next tactic:
simp only [smul, f.map_one, smul_one]
/-- Pushforward a multiplicative distributive multiplicative action along a surjective monoid
homomorphism.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Surjective.mulDistribMulAction [Monoid B] [SMul M B] (f : A →* B)
    (hf : Surjective f) (smul : ∀ (c : M) (x), f (c • x) = c • f x) : MulDistribMulAction M B :=
  { hf.mulAction f smul with
    smul_mul := fun c x y => by
      

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝⁴ : Monoid M
inst✝³ : Monoid A
inst✝² : MulDistribMulAction M A
inst✝¹ : Monoid B
inst✝ : SMul M B
f : A →* B
hf : Surjective ⇑f
smul : ∀ (c : M) (x : A), f (c • x) = c • f x
src✝ : MulAction M B := Surjective.mulAction (⇑f) hf smul
c : M
x y : B
⊢ c • (x * y) = c • x * c • y

Next tactic:
rcases hf x with ⟨x, rfl⟩
/-- Pushforward a multiplicative distributive multiplicative action along a surjective monoid
homomorphism.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Surjective.mulDistribMulAction [Monoid B] [SMul M B] (f : A →* B)
    (hf : Surjective f) (smul : ∀ (c : M) (x), f (c • x) = c • f x) : MulDistribMulAction M B :=
  { hf.mulAction f smul with
    smul_mul := fun c x y => by
      rcases hf x with ⟨x, rfl⟩
      

Proof state:
case intro
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝⁴ : Monoid M
inst✝³ : Monoid A
inst✝² : MulDistribMulAction M A
inst✝¹ : Monoid B
inst✝ : SMul M B
f : A →* B
hf : Surjective ⇑f
smul : ∀ (c : M) (x : A), f (c • x) = c • f x
src✝ : MulAction M B := Surjective.mulAction (⇑f) hf smul
c : M
y : B
x : A
⊢ c • (f x * y) = c • f x * c • y

Next tactic:
rcases hf y with ⟨y, rfl⟩
/-- Pushforward a multiplicative distributive multiplicative action along a surjective monoid
homomorphism.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Surjective.mulDistribMulAction [Monoid B] [SMul M B] (f : A →* B)
    (hf : Surjective f) (smul : ∀ (c : M) (x), f (c • x) = c • f x) : MulDistribMulAction M B :=
  { hf.mulAction f smul with
    smul_mul := fun c x y => by
      rcases hf x with ⟨x, rfl⟩
      rcases hf y with ⟨y, rfl⟩
      

Proof state:
case intro.intro
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝⁴ : Monoid M
inst✝³ : Monoid A
inst✝² : MulDistribMulAction M A
inst✝¹ : Monoid B
inst✝ : SMul M B
f : A →* B
hf : Surjective ⇑f
smul : ∀ (c : M) (x : A), f (c • x) = c • f x
src✝ : MulAction M B := Surjective.mulAction (⇑f) hf smul
c : M
x y : A
⊢ c • (f x * f y) = c • f x * c • f y

Next tactic:
simp only [smul_mul', ← smul, ← f.map_mul]
/-- Pushforward a multiplicative distributive multiplicative action along a surjective monoid
homomorphism.
See note [reducible non-instances]. -/
@[reducible]
protected def Function.Surjective.mulDistribMulAction [Monoid B] [SMul M B] (f : A →* B)
    (hf : Surjective f) (smul : ∀ (c : M) (x), f (c • x) = c • f x) : MulDistribMulAction M B :=
  { hf.mulAction f smul with
    smul_mul := fun c x y => by
      rcases hf x with ⟨x, rfl⟩
      rcases hf y with ⟨y, rfl⟩
      simp only [smul_mul', ← smul, ← f.map_mul],
    smul_one := fun c => by 

Proof state:
M : Type u_1
N : Type u_2
G : Type u_3
A : Type u_4
B : Type u_5
α : Type u_6
β : Type u_7
γ : Type u_8
δ : Type u_9
inst✝⁴ : Monoid M
inst✝³ : Monoid A
inst✝² : MulDistribMulAction M A
inst✝¹ : Monoid B
inst✝ : SMul M B
f : A →* B
hf : Surjective ⇑f
smul : ∀ (c : M) (x : A), f (c • x) = c • f x
src✝ : MulAction M B := Surjective.mulAction (⇑f) hf smul
c : M
⊢ c • 1 = 1

Next tactic:
rw [← f.map_one, ← smul, smul_one]
theorem Multiset.sum_smul_sum {s : Multiset R} {t : Multiset M} :
    s.sum • t.sum = ((s ×ˢ t).map fun p : R × M ↦ p.fst • p.snd).sum := by
  

Proof state:
α : Type u_1
β : Type u_2
R : Type u_3
M : Type u_4
ι : Type u_5
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r s✝ : R
x y : M
s : Multiset R
t : Multiset M
⊢ sum s • sum t = sum (map (fun p => p.1 • p.2) (s ×ˢ t))

Next tactic:
induction' s using Multiset.induction with a s ih
theorem Multiset.sum_smul_sum {s : Multiset R} {t : Multiset M} :
    s.sum • t.sum = ((s ×ˢ t).map fun p : R × M ↦ p.fst • p.snd).sum := by
  induction' s using Multiset.induction with a s ih
  · 

Proof state:
case empty
α : Type u_1
β : Type u_2
R : Type u_3
M : Type u_4
ι : Type u_5
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r s : R
x y : M
t : Multiset M
⊢ sum 0 • sum t = sum (map (fun p => p.1 • p.2) (0 ×ˢ t))

Next tactic:
simp
theorem Multiset.sum_smul_sum {s : Multiset R} {t : Multiset M} :
    s.sum • t.sum = ((s ×ˢ t).map fun p : R × M ↦ p.fst • p.snd).sum := by
  induction' s using Multiset.induction with a s ih
  · simp
  · 

Proof state:
case cons
α : Type u_1
β : Type u_2
R : Type u_3
M : Type u_4
ι : Type u_5
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r s✝ : R
x y : M
t : Multiset M
a : R
s : Multiset R
ih : sum s • sum t = sum (map (fun p => p.1 • p.2) (s ×ˢ t))
⊢ sum (a ::ₘ s) • sum t = sum (map (fun p => p.1 • p.2) ((a ::ₘ s) ×ˢ t))

Next tactic:
simp [add_smul, ih, ← Multiset.smul_sum]
theorem Finset.sum_smul_sum {f : α → R} {g : β → M} {s : Finset α} {t : Finset β} :
    ((∑ i in s, f i) • ∑ i in t, g i) = ∑ p in s ×ˢ t, f p.fst • g p.snd := by
  

Proof state:
α : Type u_1
β : Type u_2
R : Type u_3
M : Type u_4
ι : Type u_5
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r s✝ : R
x y : M
f : α → R
g : β → M
s : Finset α
t : Finset β
⊢ (∑ i in s, f i) • ∑ i in t, g i = ∑ p in s ×ˢ t, f p.1 • g p.2

Next tactic:
rw [Finset.sum_product, Finset.sum_smul, Finset.sum_congr rfl]
theorem Finset.sum_smul_sum {f : α → R} {g : β → M} {s : Finset α} {t : Finset β} :
    ((∑ i in s, f i) • ∑ i in t, g i) = ∑ p in s ×ˢ t, f p.fst • g p.snd := by
  rw [Finset.sum_product, Finset.sum_smul, Finset.sum_congr rfl]
  

Proof state:
α : Type u_1
β : Type u_2
R : Type u_3
M : Type u_4
ι : Type u_5
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r s✝ : R
x y : M
f : α → R
g : β → M
s : Finset α
t : Finset β
⊢ ∀ x ∈ s, f x • ∑ i in t, g i = ∑ y in t, f (x, y).1 • g (x, y).2

Next tactic:
intros
theorem Finset.sum_smul_sum {f : α → R} {g : β → M} {s : Finset α} {t : Finset β} :
    ((∑ i in s, f i) • ∑ i in t, g i) = ∑ p in s ×ˢ t, f p.fst • g p.snd := by
  rw [Finset.sum_product, Finset.sum_smul, Finset.sum_congr rfl]
  intros
  

Proof state:
α : Type u_1
β : Type u_2
R : Type u_3
M : Type u_4
ι : Type u_5
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r s✝ : R
x y : M
f : α → R
g : β → M
s : Finset α
t : Finset β
x✝ : α
a✝ : x✝ ∈ s
⊢ f x✝ • ∑ i in t, g i = ∑ y in t, f (x✝, y).1 • g (x✝, y).2

Next tactic:
rw [Finset.smul_sum]
theorem Finset.cast_card [CommSemiring R] (s : Finset α) : (s.card : R) = ∑ a in s, 1 := by
  

Proof state:
α : Type u_1
β : Type u_2
R : Type u_3
M : Type u_4
ι : Type u_5
inst✝ : CommSemiring R
s : Finset α
⊢ ↑(card s) = ∑ a in s, 1

Next tactic:
rw [Finset.sum_const, Nat.smul_one_eq_coe]
theorem AffineTargetMorphismProperty.toProperty_apply (P : AffineTargetMorphismProperty)
    {X Y : Scheme} (f : X ⟶ Y) [i : IsAffine Y] : P.toProperty f ↔ P f := by
  

Proof state:
P : AffineTargetMorphismProperty
X Y : Scheme
f : X ⟶ Y
i : IsAffine Y
⊢ toProperty P f ↔ P f

Next tactic:
delta AffineTargetMorphismProperty.toProperty
theorem AffineTargetMorphismProperty.toProperty_apply (P : AffineTargetMorphismProperty)
    {X Y : Scheme} (f : X ⟶ Y) [i : IsAffine Y] : P.toProperty f ↔ P f := by
  delta AffineTargetMorphismProperty.toProperty; 

Proof state:
P : AffineTargetMorphismProperty
X Y : Scheme
f : X ⟶ Y
i : IsAffine Y
⊢ (∃ (h : IsAffine Y), P f) ↔ P f

Next tactic:
simp [*]
theorem affine_cancel_left_isIso {P : AffineTargetMorphismProperty} (hP : P.toProperty.RespectsIso)
    {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [IsIso f] [IsAffine Z] : P (f ≫ g) ↔ P g := by
  

Proof state:
P : AffineTargetMorphismProperty
hP : MorphismProperty.RespectsIso (AffineTargetMorphismProperty.toProperty P)
X Y Z : Scheme
f : X ⟶ Y
g : Y ⟶ Z
inst✝¹ : IsIso f
inst✝ : IsAffine Z
⊢ P (f ≫ g) ↔ P g

Next tactic:
rw [← P.toProperty_apply, ← P.toProperty_apply, hP.cancel_left_isIso]
theorem affine_cancel_right_isIso {P : AffineTargetMorphismProperty} (hP : P.toProperty.RespectsIso)
    {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [IsIso g] [IsAffine Z] [IsAffine Y] :
    P (f ≫ g) ↔ P f := by 

Proof state:
P : AffineTargetMorphismProperty
hP : MorphismProperty.RespectsIso (AffineTargetMorphismProperty.toProperty P)
X Y Z : Scheme
f : X ⟶ Y
g : Y ⟶ Z
inst✝² : IsIso g
inst✝¹ : IsAffine Z
inst✝ : IsAffine Y
⊢ P (f ≫ g) ↔ P f

Next tactic:
rw [← P.toProperty_apply, ← P.toProperty_apply, hP.cancel_right_isIso]
theorem AffineTargetMorphismProperty.respectsIso_mk {P : AffineTargetMorphismProperty}
    (h₁ : ∀ {X Y Z} (e : X ≅ Y) (f : Y ⟶ Z) [IsAffine Z], P f → P (e.hom ≫ f))
    (h₂ : ∀ {X Y Z} (e : Y ≅ Z) (f : X ⟶ Y) [h : IsAffine Y],
      P f → @P _ _ (f ≫ e.hom) (isAffineOfIso e.inv)) :
    P.toProperty.RespectsIso := by
  

Proof state:
P : AffineTargetMorphismProperty
h₁ : ∀ {X Y Z : Scheme} (e : X ≅ Y) (f : Y ⟶ Z) [inst : IsAffine Z], P f → P (e.hom ≫ f)
h₂ : ∀ {X Y Z : Scheme} (e : Y ≅ Z) (f : X ⟶ Y) [h : IsAffine Y], P f → P (f ≫ e.hom)
⊢ MorphismProperty.RespectsIso (toProperty P)

Next tactic:
constructor
theorem AffineTargetMorphismProperty.respectsIso_mk {P : AffineTargetMorphismProperty}
    (h₁ : ∀ {X Y Z} (e : X ≅ Y) (f : Y ⟶ Z) [IsAffine Z], P f → P (e.hom ≫ f))
    (h₂ : ∀ {X Y Z} (e : Y ≅ Z) (f : X ⟶ Y) [h : IsAffine Y],
      P f → @P _ _ (f ≫ e.hom) (isAffineOfIso e.inv)) :
    P.toProperty.RespectsIso := by
  constructor
  · 

Proof state:
case left
P : AffineTargetMorphismProperty
h₁ : ∀ {X Y Z : Scheme} (e : X ≅ Y) (f : Y ⟶ Z) [inst : IsAffine Z], P f → P (e.hom ≫ f)
h₂ : ∀ {X Y Z : Scheme} (e : Y ≅ Z) (f : X ⟶ Y) [h : IsAffine Y], P f → P (f ≫ e.hom)
⊢ ∀ {X Y Z : Scheme} (e : X ≅ Y) (f : Y ⟶ Z), toProperty P f → toProperty P (e.hom ≫ f)

Next tactic:
rintro X Y Z e f ⟨a, h⟩