l3lab/ntp-mathlib huggingface dataset:
/-- Pushforward a `Module` structure along a surjective additive monoid homomorphism. -/
protected def Function.Surjective.module [AddCommMonoid M₂] [SMul R M₂] (f : M →+ M₂)
    (hf : Surjective f) (smul : ∀ (c : R) (x), f (c • x) = c • f x) : Module R M₂ :=
  { toDistribMulAction := hf.distribMulAction f smul
    add_smul := fun c₁ c₂ x => by
      rcases hf x with ⟨x, rfl⟩
      simp only [add_smul, ← smul, ← f.map_add]
    zero_smul := fun x => by
      rcases hf x with ⟨x, rfl⟩
      

Proof state:
case intro
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝⁴ : Semiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
r s : R
x✝ y : M
inst✝¹ : AddCommMonoid M₂
inst✝ : SMul R M₂
f : M →+ M₂
hf : Surjective ⇑f
smul : ∀ (c : R) (x : M), f (c • x) = c • f x
x : M
⊢ 0 • f x = 0

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

See also `Function.Surjective.mulActionLeft` and `Function.Surjective.distribMulActionLeft`.
-/
@[reducible]
def Function.Surjective.moduleLeft {R S M : Type*} [Semiring R] [AddCommMonoid M] [Module R M]
    [Semiring S] [SMul S M] (f : R →+* S) (hf : Function.Surjective f)
    (hsmul : ∀ (c) (x : M), f c • x = c • x) : Module S M :=
  { hf.distribMulActionLeft f.toMonoidHom hsmul with
    zero_smul := fun x => by rw [← f.map_zero, hsmul, zero_smul]
    add_smul := hf.forall₂.mpr fun a b x => by 

Proof state:
α : Type u_1
R✝ : Type u_2
k : Type u_3
S✝ : Type u_4
M✝ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝⁷ : Semiring R✝
inst✝⁶ : AddCommMonoid M✝
inst✝⁵ : Module R✝ M✝
r s : R✝
x✝ y : M✝
R : Type u_9
S : Type u_10
M : Type u_11
inst✝⁴ : Semiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
inst✝¹ : Semiring S
inst✝ : SMul S M
f : R →+* S
hf : Surjective ⇑f
hsmul : ∀ (c : R) (x : M), f c • x = c • x
src✝ : DistribMulAction S M := distribMulActionLeft (↑f) hf hsmul
a b : R
x : M
⊢ (f a + f b) • x = f a • x + f b • x

Next tactic:
simp only [← f.map_add, hsmul, add_smul]
/-- Push forward the action of `R` on `M` along a compatible surjective map `f : R →+* S`.

See also `Function.Surjective.mulActionLeft` and `Function.Surjective.distribMulActionLeft`.
-/
@[reducible]
def Function.Surjective.moduleLeft {R S M : Type*} [Semiring R] [AddCommMonoid M] [Module R M]
    [Semiring S] [SMul S M] (f : R →+* S) (hf : Function.Surjective f)
    (hsmul : ∀ (c) (x : M), f c • x = c • x) : Module S M :=
  { hf.distribMulActionLeft f.toMonoidHom hsmul with
    zero_smul := fun x => by 

Proof state:
α : Type u_1
R✝ : Type u_2
k : Type u_3
S✝ : Type u_4
M✝ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝⁷ : Semiring R✝
inst✝⁶ : AddCommMonoid M✝
inst✝⁵ : Module R✝ M✝
r s : R✝
x✝ y : M✝
R : Type u_9
S : Type u_10
M : Type u_11
inst✝⁴ : Semiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
inst✝¹ : Semiring S
inst✝ : SMul S M
f : R →+* S
hf : Surjective ⇑f
hsmul : ∀ (c : R) (x : M), f c • x = c • x
src✝ : DistribMulAction S M := distribMulActionLeft (↑f) hf hsmul
x : M
⊢ 0 • x = 0

Next tactic:
rw [← f.map_zero, hsmul, zero_smul]
/-- Compose a `Module` with a `RingHom`, with action `f s • m`.

See note [reducible non-instances]. -/
@[reducible]
def Module.compHom [Semiring S] (f : S →+* R) : Module S M :=
  { MulActionWithZero.compHom M f.toMonoidWithZeroHom, DistribMulAction.compHom M (f : S →* R) with
    -- Porting note: the `show f (r + s) • x = f r • x + f s • x` wasn't needed in mathlib3.
    -- Somehow, now that `SMul` is heterogeneous, it can't unfold earlier fields of a definition for
    -- use in later fields.  See
    -- https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/Heterogeneous.20scalar.20multiplication
    add_smul := fun r s x => show f (r + s) • x = f r • x + f s • x by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝³ : Semiring R
inst✝² : AddCommMonoid M
inst✝¹ : Module R M
r✝ s✝ : R
x✝ y : M
inst✝ : Semiring S
f : S →+* R
src✝¹ : MulActionWithZero S M := MulActionWithZero.compHom M (RingHom.toMonoidWithZeroHom f)
src✝ : DistribMulAction S M := DistribMulAction.compHom M ↑f
r s : S
x : M
⊢ f (r + s) • x = f r • x + f s • x

Next tactic:
simp [add_smul]
/-- `(•)` as an `AddMonoidHom`.

This is a stronger version of `DistribMulAction.toAddMonoidEnd` -/
@[simps! apply_apply]
def Module.toAddMonoidEnd : R →+* AddMonoid.End M :=
  { DistribMulAction.toAddMonoidEnd R M with
    -- Porting note: the two `show`s weren't needed in mathlib3.
    -- Somehow, now that `SMul` is heterogeneous, it can't unfold earlier fields of a definition for
    -- use in later fields.  See
    -- https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/Heterogeneous.20scalar.20multiplication
    map_zero' := AddMonoidHom.ext fun r => show (0:R) • r = 0 by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r✝ s : R
x y : M
src✝ : R →* AddMonoid.End M := DistribMulAction.toAddMonoidEnd R M
r : M
⊢ 0 • r = 0

Next tactic:
simp
/-- `(•)` as an `AddMonoidHom`.

This is a stronger version of `DistribMulAction.toAddMonoidEnd` -/
@[simps! apply_apply]
def Module.toAddMonoidEnd : R →+* AddMonoid.End M :=
  { DistribMulAction.toAddMonoidEnd R M with
    -- Porting note: the two `show`s weren't needed in mathlib3.
    -- Somehow, now that `SMul` is heterogeneous, it can't unfold earlier fields of a definition for
    -- use in later fields.  See
    -- https://leanprover.zulipchat.com/#narrow/stream/287929-mathlib4/topic/Heterogeneous.20scalar.20multiplication
    map_zero' := AddMonoidHom.ext fun r => show (0:R) • r = 0 by simp
    map_add' := fun x y =>
      AddMonoidHom.ext fun r => show (x + y) • r = x • r + y • r by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r✝ s : R
x✝ y✝ : M
src✝ : R →* AddMonoid.End M := DistribMulAction.toAddMonoidEnd R M
x y : R
r : M
⊢ (x + y) • r = x • r + y • r

Next tactic:
simp [add_smul]
theorem Module.eq_zero_of_zero_eq_one (zero_eq_one : (0 : R) = 1) : x = 0 := by
  

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
r s : R
x y : M
zero_eq_one : 0 = 1
⊢ x = 0

Next tactic:
rw [← one_smul R x, ← zero_eq_one, zero_smul]
@[simp]
theorem smul_add_one_sub_smul {R : Type*} [Ring R] [Module R M] {r : R} {m : M} :
    r • m + (1 - r) • m = m := by 

Proof state:
α : Type u_1
R✝ : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝⁴ : Semiring R✝
inst✝³ : AddCommMonoid M
inst✝² : Module R✝ M
r✝ s : R✝
x y : M
R : Type u_9
inst✝¹ : Ring R
inst✝ : Module R M
r : R
m : M
⊢ r • m + (1 - r) • m = m

Next tactic:
rw [← add_smul, add_sub_cancel'_right, one_smul]
theorem Convex.combo_eq_smul_sub_add [Module R M] {x y : M} {a b : R} (h : a + b = 1) :
    a • x + b • y = b • (y - x) + x :=
  calc
    a • x + b • y = b • y - b • x + (a • x + b • x) := by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Semiring R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
x y : M
a b : R
h : a + b = 1
⊢ a • x + b • y = b • y - b • x + (a • x + b • x)

Next tactic:
abel
theorem Convex.combo_eq_smul_sub_add [Module R M] {x y : M} {a b : R} (h : a + b = 1) :
    a • x + b • y = b • (y - x) + x :=
  calc
    a • x + b • y = b • y - b • x + (a • x + b • x) := by abel
    _ = b • (y - x) + x := by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Semiring R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
x y : M
a b : R
h : a + b = 1
⊢ b • y - b • x + (a • x + b • x) = b • (y - x) + x

Next tactic:
rw [smul_sub, Convex.combo_self h]
/-- A variant of `Module.ext` that's convenient for term-mode. -/
theorem Module.ext' {R : Type*} [Semiring R] {M : Type*} [AddCommMonoid M] (P Q : Module R M)
    (w : ∀ (r : R) (m : M), (haveI := P; r • m) = (haveI := Q; r • m)) :
    P = Q := by
  

Proof state:
α : Type u_1
R✝ : Type u_2
k : Type u_3
S : Type u_4
M✝ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
R : Type u_9
inst✝¹ : Semiring R
M : Type u_10
inst✝ : AddCommMonoid M
P Q : Module R M
w : ∀ (r : R) (m : M), r • m = r • m
⊢ P = Q

Next tactic:
ext
/-- A variant of `Module.ext` that's convenient for term-mode. -/
theorem Module.ext' {R : Type*} [Semiring R] {M : Type*} [AddCommMonoid M] (P Q : Module R M)
    (w : ∀ (r : R) (m : M), (haveI := P; r • m) = (haveI := Q; r • m)) :
    P = Q := by
  ext
  

Proof state:
case smul.h.h
α : Type u_1
R✝ : Type u_2
k : Type u_3
S : Type u_4
M✝ : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
R : Type u_9
inst✝¹ : Semiring R
M : Type u_10
inst✝ : AddCommMonoid M
P Q : Module R M
w : ∀ (r : R) (m : M), r • m = r • m
x✝¹ : R
x✝ : M
⊢ SMul.smul x✝¹ x✝ = SMul.smul x✝¹ x✝

Next tactic:
exact w _ _
@[simp]
theorem neg_smul : -r • x = -(r • x) :=
  eq_neg_of_add_eq_zero_left <| by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Ring R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
r s : R
x y : M
⊢ -r • x + r • x = 0

Next tactic:
rw [← add_smul, add_left_neg, zero_smul]
theorem neg_smul_neg : -r • -x = r • x := by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Ring R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
r s : R
x y : M
⊢ -r • -x = r • x

Next tactic:
rw [neg_smul, smul_neg, neg_neg]
@[simp]
theorem Units.neg_smul (u : Rˣ) (x : M) : -u • x = -(u • x) := by
  

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Ring R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
r s : R
x✝ y : M
u : Rˣ
x : M
⊢ -u • x = -(u • x)

Next tactic:
rw [Units.smul_def, Units.val_neg, _root_.neg_smul, Units.smul_def]
theorem neg_one_smul (x : M) : (-1 : R) • x = -x := by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Ring R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
r s : R
x✝ y x : M
⊢ -1 • x = -x

Next tactic:
simp
theorem sub_smul (r s : R) (y : M) : (r - s) • y = r • y - s • y := by
  

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Ring R
inst✝¹ : AddCommGroup M
inst✝ : Module R M
r✝ s✝ : R
x y✝ : M
r s : R
y : M
⊢ (r - s) • y = r • y - s • y

Next tactic:
simp [add_smul, sub_eq_add_neg]
/-- An `AddCommMonoid` that is a `Module` over a `Ring` carries a natural `AddCommGroup`
structure.
See note [reducible non-instances]. -/
@[reducible]
def Module.addCommMonoidToAddCommGroup [Ring R] [AddCommMonoid M] [Module R M] : AddCommGroup M :=
  { (inferInstance : AddCommMonoid M) with
    neg := fun a => (-1 : R) • a
    add_left_neg := fun a =>
      show (-1 : R) • a + a = 0 by
        nth_rw 2 [← one_smul R a]
        rw [← add_smul, add_left_neg, zero_smul]
    zsmul := fun z a => (z : R) • a
    zsmul_zero' := fun a => by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Ring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
src✝ : AddCommMonoid M := inferInstance
a : M
⊢ (fun z a => ↑z • a) 0 a = 0

Next tactic:
simpa only [Int.cast_zero] using zero_smul R a
/-- An `AddCommMonoid` that is a `Module` over a `Ring` carries a natural `AddCommGroup`
structure.
See note [reducible non-instances]. -/
@[reducible]
def Module.addCommMonoidToAddCommGroup [Ring R] [AddCommMonoid M] [Module R M] : AddCommGroup M :=
  { (inferInstance : AddCommMonoid M) with
    neg := fun a => (-1 : R) • a
    add_left_neg := fun a =>
      show (-1 : R) • a + a = 0 by
        nth_rw 2 [← one_smul R a]
        rw [← add_smul, add_left_neg, zero_smul]
    zsmul := fun z a => (z : R) • a
    zsmul_zero' := fun a => by simpa only [Int.cast_zero] using zero_smul R a
    zsmul_succ' := fun z a => by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Ring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
src✝ : AddCommMonoid M := inferInstance
z : ℕ
a : M
⊢ (fun z a => ↑z • a) (Int.ofNat (Nat.succ z)) a = a + (fun z a => ↑z • a) (Int.ofNat z) a

Next tactic:
simp [add_comm, add_smul]
/-- An `AddCommMonoid` that is a `Module` over a `Ring` carries a natural `AddCommGroup`
structure.
See note [reducible non-instances]. -/
@[reducible]
def Module.addCommMonoidToAddCommGroup [Ring R] [AddCommMonoid M] [Module R M] : AddCommGroup M :=
  { (inferInstance : AddCommMonoid M) with
    neg := fun a => (-1 : R) • a
    add_left_neg := fun a =>
      show (-1 : R) • a + a = 0 by
        nth_rw 2 [← one_smul R a]
        rw [← add_smul, add_left_neg, zero_smul]
    zsmul := fun z a => (z : R) • a
    zsmul_zero' := fun a => by simpa only [Int.cast_zero] using zero_smul R a
    zsmul_succ' := fun z a => by simp [add_comm, add_smul]
    zsmul_neg' := fun z a => by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Ring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
src✝ : AddCommMonoid M := inferInstance
z : ℕ
a : M
⊢ (fun z a => ↑z • a) (Int.negSucc z) a = -(fun z a => ↑z • a) (↑(Nat.succ z)) a

Next tactic:
simp [← smul_assoc, neg_one_smul]
/-- An `AddCommMonoid` that is a `Module` over a `Ring` carries a natural `AddCommGroup`
structure.
See note [reducible non-instances]. -/
@[reducible]
def Module.addCommMonoidToAddCommGroup [Ring R] [AddCommMonoid M] [Module R M] : AddCommGroup M :=
  { (inferInstance : AddCommMonoid M) with
    neg := fun a => (-1 : R) • a
    add_left_neg := fun a =>
      show (-1 : R) • a + a = 0 by
        

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Ring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
src✝ : AddCommMonoid M := inferInstance
a : M
⊢ -1 • a + a = 0

Next tactic:
nth_rw 2 [← one_smul R a]
/-- An `AddCommMonoid` that is a `Module` over a `Ring` carries a natural `AddCommGroup`
structure.
See note [reducible non-instances]. -/
@[reducible]
def Module.addCommMonoidToAddCommGroup [Ring R] [AddCommMonoid M] [Module R M] : AddCommGroup M :=
  { (inferInstance : AddCommMonoid M) with
    neg := fun a => (-1 : R) • a
    add_left_neg := fun a =>
      show (-1 : R) • a + a = 0 by
        nth_rw 2 [← one_smul R a]
        

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Ring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
src✝ : AddCommMonoid M := inferInstance
a : M
⊢ -1 • a + 1 • a = 0

Next tactic:
rw [← add_smul, add_left_neg, zero_smul]
/-- `nsmul` is equal to any other module structure via a cast. -/
theorem nsmul_eq_smul_cast (n : ℕ) (b : M) : n • b = (n : R) • b := by
  

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n : ℕ
b : M
⊢ n • b = ↑n • b

Next tactic:
induction' n with n ih
/-- `nsmul` is equal to any other module structure via a cast. -/
theorem nsmul_eq_smul_cast (n : ℕ) (b : M) : n • b = (n : R) • b := by
  induction' n with n ih
  · 

Proof state:
case zero
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
b : M
⊢ Nat.zero • b = ↑Nat.zero • b

Next tactic:
rw [Nat.zero_eq, Nat.cast_zero, zero_smul, zero_smul]
/-- `nsmul` is equal to any other module structure via a cast. -/
theorem nsmul_eq_smul_cast (n : ℕ) (b : M) : n • b = (n : R) • b := by
  induction' n with n ih
  · rw [Nat.zero_eq, Nat.cast_zero, zero_smul, zero_smul]
  · 

Proof state:
case succ
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
b : M
n : ℕ
ih : n • b = ↑n • b
⊢ Nat.succ n • b = ↑(Nat.succ n) • b

Next tactic:
rw [Nat.succ_eq_add_one, Nat.cast_succ, add_smul, add_smul, one_smul, ih, one_smul]
/-- Convert back any exotic `ℕ`-smul to the canonical instance. This should not be needed since in
mathlib all `AddCommMonoid`s should normally have exactly one `ℕ`-module structure by design.
-/
theorem nat_smul_eq_nsmul (h : Module ℕ M) (n : ℕ) (x : M) :
    @SMul.smul ℕ M h.toSMul n x = n • x := by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
h : Module ℕ M
n : ℕ
x : M
⊢ SMul.smul n x = n • x

Next tactic:
rw [nsmul_eq_smul_cast ℕ n x, Nat.cast_id]
/-- Convert back any exotic `ℕ`-smul to the canonical instance. This should not be needed since in
mathlib all `AddCommMonoid`s should normally have exactly one `ℕ`-module structure by design.
-/
theorem nat_smul_eq_nsmul (h : Module ℕ M) (n : ℕ) (x : M) :
    @SMul.smul ℕ M h.toSMul n x = n • x := by rw [nsmul_eq_smul_cast ℕ n x, Nat.cast_id]; 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
h : Module ℕ M
n : ℕ
x : M
⊢ SMul.smul n x = n • x

Next tactic:
rfl
/-- All `ℕ`-module structures are equal. Not an instance since in mathlib all `AddCommMonoid`
should normally have exactly one `ℕ`-module structure by design. -/
def AddCommMonoid.natModule.unique : Unique (Module ℕ M) where
  default := by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
⊢ Module ℕ M

Next tactic:
infer_instance
/-- All `ℕ`-module structures are equal. Not an instance since in mathlib all `AddCommMonoid`
should normally have exactly one `ℕ`-module structure by design. -/
def AddCommMonoid.natModule.unique : Unique (Module ℕ M) where
  default := by infer_instance
  uniq P := (Module.ext' P _) fun n => by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
P : Module ℕ M
n : ℕ
⊢ ∀ (m : M), n • m = n • m

Next tactic:
convert nat_smul_eq_nsmul P n
instance AddCommMonoid.nat_isScalarTower : IsScalarTower ℕ R M where
  smul_assoc n x y :=
    Nat.recOn n (by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n : ℕ
x : R
y : M
⊢ (Nat.zero • x) • y = Nat.zero • x • y

Next tactic:
simp only [Nat.zero_eq, zero_smul]
instance AddCommMonoid.nat_isScalarTower : IsScalarTower ℕ R M where
  smul_assoc n x y :=
    Nat.recOn n (by simp only [Nat.zero_eq, zero_smul])
    fun n ih => by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝² : Semiring R
inst✝¹ : AddCommMonoid M
inst✝ : Module R M
n✝ : ℕ
x : R
y : M
n : ℕ
ih : (n • x) • y = n • x • y
⊢ (Nat.succ n • x) • y = Nat.succ n • x • y

Next tactic:
simp only [Nat.succ_eq_add_one, add_smul, one_smul, ih]
/-- `zsmul` is equal to any other module structure via a cast. -/
theorem zsmul_eq_smul_cast (n : ℤ) (b : M) : n • b = (n : R) • b :=
  have : (smulAddHom ℤ M).flip b = ((smulAddHom R M).flip b).comp (Int.castAddHom R) := by
    

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝⁴ : Semiring S
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module S M
inst✝ : Module R M
n : ℤ
b : M
⊢ (AddMonoidHom.flip (smulAddHom ℤ M)) b = AddMonoidHom.comp ((AddMonoidHom.flip (smulAddHom R M)) b) (Int.castAddHom R)

Next tactic:
apply AddMonoidHom.ext_int
/-- `zsmul` is equal to any other module structure via a cast. -/
theorem zsmul_eq_smul_cast (n : ℤ) (b : M) : n • b = (n : R) • b :=
  have : (smulAddHom ℤ M).flip b = ((smulAddHom R M).flip b).comp (Int.castAddHom R) := by
    apply AddMonoidHom.ext_int
    

Proof state:
case h1
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝⁴ : Semiring S
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module S M
inst✝ : Module R M
n : ℤ
b : M
⊢ ((AddMonoidHom.flip (smulAddHom ℤ M)) b) 1 =
    (AddMonoidHom.comp ((AddMonoidHom.flip (smulAddHom R M)) b) (Int.castAddHom R)) 1

Next tactic:
simp
/-- Convert back any exotic `ℤ`-smul to the canonical instance. This should not be needed since in
mathlib all `AddCommGroup`s should normally have exactly one `ℤ`-module structure by design. -/
theorem int_smul_eq_zsmul (h : Module ℤ M) (n : ℤ) (x : M) :
    @SMul.smul ℤ M h.toSMul n x = n • x := by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝⁴ : Semiring S
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module S M
inst✝ : Module R M
h : Module ℤ M
n : ℤ
x : M
⊢ SMul.smul n x = n • x

Next tactic:
rw [zsmul_eq_smul_cast ℤ n x, Int.cast_id]
/-- Convert back any exotic `ℤ`-smul to the canonical instance. This should not be needed since in
mathlib all `AddCommGroup`s should normally have exactly one `ℤ`-module structure by design. -/
theorem int_smul_eq_zsmul (h : Module ℤ M) (n : ℤ) (x : M) :
    @SMul.smul ℤ M h.toSMul n x = n • x := by rw [zsmul_eq_smul_cast ℤ n x, Int.cast_id]; 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝⁴ : Semiring S
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module S M
inst✝ : Module R M
h : Module ℤ M
n : ℤ
x : M
⊢ SMul.smul n x = n • x

Next tactic:
rfl
/-- All `ℤ`-module structures are equal. Not an instance since in mathlib all `AddCommGroup`
should normally have exactly one `ℤ`-module structure by design. -/
def AddCommGroup.intModule.unique : Unique (Module ℤ M) where
  default := by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝⁴ : Semiring S
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module S M
inst✝ : Module R M
⊢ Module ℤ M

Next tactic:
infer_instance
/-- All `ℤ`-module structures are equal. Not an instance since in mathlib all `AddCommGroup`
should normally have exactly one `ℤ`-module structure by design. -/
def AddCommGroup.intModule.unique : Unique (Module ℤ M) where
  default := by infer_instance
  uniq P := (Module.ext' P _) fun n => by 

Proof state:
α : Type u_1
R : Type u_2
k : Type u_3
S : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝⁴ : Semiring S
inst✝³ : Ring R
inst✝² : AddCommGroup M
inst✝¹ : Module S M
inst✝ : Module R M
P : Module ℤ M
n : ℤ
⊢ ∀ (m : M), n • m = n • m

Next tactic:
convert int_smul_eq_zsmul P n
theorem map_int_cast_smul [AddCommGroup M] [AddCommGroup M₂] {F : Type*} [AddMonoidHomClass F M M₂]
    (f : F) (R S : Type*) [Ring R] [Ring S] [Module R M] [Module S M₂] (x : ℤ) (a : M) :
    f ((x : R) • a) = (x : S) • f a := by 

Proof state:
α : Type u_1
R✝ : Type u_2
k : Type u_3
S✝ : Type u_4
M : Type u_5
M₂ : Type u_6
M₃ : Type u_7
ι : Type u_8
inst✝⁶ : AddCommGroup M
inst✝⁵ : AddCommGroup M₂
F : Type u_9
inst✝⁴ : AddMonoidHomClass F M M₂
f : F
R : Type u_10
S : Type u_11
inst✝³ : Ring R
inst✝² : Ring S
inst✝¹ : Module R M
inst✝ : Module S M₂
x : ℤ
a : M
⊢ f (↑x • a) = ↑x • f a

Next tactic:
simp only [← zsmul_eq_smul_cast, map_zsmul]