l3lab/ntp-mathlib huggingface dataset:
instance monoid [Monoid R] [AddMonoid M] [DistribMulAction R M] [DistribMulAction Rᵐᵒᵖ M]
    [SMulCommClass R Rᵐᵒᵖ M] : Monoid (tsze R M) :=
  { TrivSqZeroExt.mulOneClass with
    mul_assoc := fun x y z =>
      ext (mul_assoc x.1 y.1 z.1) <|
        show
          (x.1 * y.1) • z.2 + op z.1 • (x.1 • y.2 + op y.1 • x.2) =
            x.1 • (y.1 • z.2 + op z.1 • y.2) + (op z.1 * op y.1) • x.2
          by 

Proof state:
R : Type u
M : Type v
inst✝⁴ : Monoid R
inst✝³ : AddMonoid M
inst✝² : DistribMulAction R M
inst✝¹ : DistribMulAction Rᵐᵒᵖ M
inst✝ : SMulCommClass R Rᵐᵒᵖ M
src✝ : MulOneClass (tsze R M) := mulOneClass
x y z : tsze R M
⊢ (x.1 * y.1) • z.2 + op z.1 • (x.1 • y.2 + op y.1 • x.2) = x.1 • (y.1 • z.2 + op z.1 • y.2) + (op z.1 * op y.1) • x.2

Next tactic:
simp_rw [smul_add, ← mul_smul, add_assoc, smul_comm]
instance monoid [Monoid R] [AddMonoid M] [DistribMulAction R M] [DistribMulAction Rᵐᵒᵖ M]
    [SMulCommClass R Rᵐᵒᵖ M] : Monoid (tsze R M) :=
  { TrivSqZeroExt.mulOneClass with
    mul_assoc := fun x y z =>
      ext (mul_assoc x.1 y.1 z.1) <|
        show
          (x.1 * y.1) • z.2 + op z.1 • (x.1 • y.2 + op y.1 • x.2) =
            x.1 • (y.1 • z.2 + op z.1 • y.2) + (op z.1 * op y.1) • x.2
          by simp_rw [smul_add, ← mul_smul, add_assoc, smul_comm]
    npow := fun n x => x ^ n
    npow_zero := fun x => ext (pow_zero x.fst) (by 

Proof state:
R : Type u
M : Type v
inst✝⁴ : Monoid R
inst✝³ : AddMonoid M
inst✝² : DistribMulAction R M
inst✝¹ : DistribMulAction Rᵐᵒᵖ M
inst✝ : SMulCommClass R Rᵐᵒᵖ M
src✝ : MulOneClass (tsze R M) := mulOneClass
x : tsze R M
⊢ snd ((fun n x => x ^ n) 0 x) = snd 1

Next tactic:
simp [snd_pow_eq_sum]
instance monoid [Monoid R] [AddMonoid M] [DistribMulAction R M] [DistribMulAction Rᵐᵒᵖ M]
    [SMulCommClass R Rᵐᵒᵖ M] : Monoid (tsze R M) :=
  { TrivSqZeroExt.mulOneClass with
    mul_assoc := fun x y z =>
      ext (mul_assoc x.1 y.1 z.1) <|
        show
          (x.1 * y.1) • z.2 + op z.1 • (x.1 • y.2 + op y.1 • x.2) =
            x.1 • (y.1 • z.2 + op z.1 • y.2) + (op z.1 * op y.1) • x.2
          by simp_rw [smul_add, ← mul_smul, add_assoc, smul_comm]
    npow := fun n x => x ^ n
    npow_zero := fun x => ext (pow_zero x.fst) (by simp [snd_pow_eq_sum])
    npow_succ := fun n x =>
      ext (pow_succ _ _)
        (by
          

Proof state:
R : Type u
M : Type v
inst✝⁴ : Monoid R
inst✝³ : AddMonoid M
inst✝² : DistribMulAction R M
inst✝¹ : DistribMulAction Rᵐᵒᵖ M
inst✝ : SMulCommClass R Rᵐᵒᵖ M
src✝ : MulOneClass (tsze R M) := mulOneClass
n : ℕ
x : tsze R M
⊢ snd ((fun n x => x ^ n) (n + 1) x) = snd (x * (fun n x => x ^ n) n x)

Next tactic:
simp_rw [snd_mul, snd_pow_eq_sum, Nat.pred_succ]
instance monoid [Monoid R] [AddMonoid M] [DistribMulAction R M] [DistribMulAction Rᵐᵒᵖ M]
    [SMulCommClass R Rᵐᵒᵖ M] : Monoid (tsze R M) :=
  { TrivSqZeroExt.mulOneClass with
    mul_assoc := fun x y z =>
      ext (mul_assoc x.1 y.1 z.1) <|
        show
          (x.1 * y.1) • z.2 + op z.1 • (x.1 • y.2 + op y.1 • x.2) =
            x.1 • (y.1 • z.2 + op z.1 • y.2) + (op z.1 * op y.1) • x.2
          by simp_rw [smul_add, ← mul_smul, add_assoc, smul_comm]
    npow := fun n x => x ^ n
    npow_zero := fun x => ext (pow_zero x.fst) (by simp [snd_pow_eq_sum])
    npow_succ := fun n x =>
      ext (pow_succ _ _)
        (by
          simp_rw [snd_mul, snd_pow_eq_sum, Nat.pred_succ]
          

Proof state:
R : Type u
M : Type v
inst✝⁴ : Monoid R
inst✝³ : AddMonoid M
inst✝² : DistribMulAction R M
inst✝¹ : DistribMulAction Rᵐᵒᵖ M
inst✝ : SMulCommClass R Rᵐᵒᵖ M
src✝ : MulOneClass (tsze R M) := mulOneClass
n : ℕ
x : tsze R M
⊢ List.sum (List.map (fun i => fst x ^ (n - i) • op (fst x ^ i) • snd x) (List.range (n + 1))) =
    fst x • List.sum (List.map (fun i => fst x ^ (Nat.pred n - i) • op (fst x ^ i) • snd x) (List.range n)) +
      op (fst (x ^ n)) • snd x

Next tactic:
cases n
instance monoid [Monoid R] [AddMonoid M] [DistribMulAction R M] [DistribMulAction Rᵐᵒᵖ M]
    [SMulCommClass R Rᵐᵒᵖ M] : Monoid (tsze R M) :=
  { TrivSqZeroExt.mulOneClass with
    mul_assoc := fun x y z =>
      ext (mul_assoc x.1 y.1 z.1) <|
        show
          (x.1 * y.1) • z.2 + op z.1 • (x.1 • y.2 + op y.1 • x.2) =
            x.1 • (y.1 • z.2 + op z.1 • y.2) + (op z.1 * op y.1) • x.2
          by simp_rw [smul_add, ← mul_smul, add_assoc, smul_comm]
    npow := fun n x => x ^ n
    npow_zero := fun x => ext (pow_zero x.fst) (by simp [snd_pow_eq_sum])
    npow_succ := fun n x =>
      ext (pow_succ _ _)
        (by
          simp_rw [snd_mul, snd_pow_eq_sum, Nat.pred_succ]
          cases n
          · 

Proof state:
case zero
R : Type u
M : Type v
inst✝⁴ : Monoid R
inst✝³ : AddMonoid M
inst✝² : DistribMulAction R M
inst✝¹ : DistribMulAction Rᵐᵒᵖ M
inst✝ : SMulCommClass R Rᵐᵒᵖ M
src✝ : MulOneClass (tsze R M) := mulOneClass
x : tsze R M
⊢ List.sum (List.map (fun i => fst x ^ (Nat.zero - i) • op (fst x ^ i) • snd x) (List.range (Nat.zero + 1))) =
    fst x •
        List.sum (List.map (fun i => fst x ^ (Nat.pred Nat.zero - i) • op (fst x ^ i) • snd x) (List.range Nat.zero)) +
      op (fst (x ^ Nat.zero)) • snd x

Next tactic:
simp [List.range_succ]
instance monoid [Monoid R] [AddMonoid M] [DistribMulAction R M] [DistribMulAction Rᵐᵒᵖ M]
    [SMulCommClass R Rᵐᵒᵖ M] : Monoid (tsze R M) :=
  { TrivSqZeroExt.mulOneClass with
    mul_assoc := fun x y z =>
      ext (mul_assoc x.1 y.1 z.1) <|
        show
          (x.1 * y.1) • z.2 + op z.1 • (x.1 • y.2 + op y.1 • x.2) =
            x.1 • (y.1 • z.2 + op z.1 • y.2) + (op z.1 * op y.1) • x.2
          by simp_rw [smul_add, ← mul_smul, add_assoc, smul_comm]
    npow := fun n x => x ^ n
    npow_zero := fun x => ext (pow_zero x.fst) (by simp [snd_pow_eq_sum])
    npow_succ := fun n x =>
      ext (pow_succ _ _)
        (by
          simp_rw [snd_mul, snd_pow_eq_sum, Nat.pred_succ]
          cases n
          · simp [List.range_succ]
          

Proof state:
case succ
R : Type u
M : Type v
inst✝⁴ : Monoid R
inst✝³ : AddMonoid M
inst✝² : DistribMulAction R M
inst✝¹ : DistribMulAction Rᵐᵒᵖ M
inst✝ : SMulCommClass R Rᵐᵒᵖ M
src✝ : MulOneClass (tsze R M) := mulOneClass
x : tsze R M
n✝ : ℕ
⊢ List.sum (List.map (fun i => fst x ^ (Nat.succ n✝ - i) • op (fst x ^ i) • snd x) (List.range (Nat.succ n✝ + 1))) =
    fst x •
        List.sum
          (List.map (fun i => fst x ^ (Nat.pred (Nat.succ n✝) - i) • op (fst x ^ i) • snd x)
            (List.range (Nat.succ n✝))) +
      op (fst (x ^ Nat.succ n✝)) • snd x

Next tactic:
simp_rw [Nat.pred_succ]
instance monoid [Monoid R] [AddMonoid M] [DistribMulAction R M] [DistribMulAction Rᵐᵒᵖ M]
    [SMulCommClass R Rᵐᵒᵖ M] : Monoid (tsze R M) :=
  { TrivSqZeroExt.mulOneClass with
    mul_assoc := fun x y z =>
      ext (mul_assoc x.1 y.1 z.1) <|
        show
          (x.1 * y.1) • z.2 + op z.1 • (x.1 • y.2 + op y.1 • x.2) =
            x.1 • (y.1 • z.2 + op z.1 • y.2) + (op z.1 * op y.1) • x.2
          by simp_rw [smul_add, ← mul_smul, add_assoc, smul_comm]
    npow := fun n x => x ^ n
    npow_zero := fun x => ext (pow_zero x.fst) (by simp [snd_pow_eq_sum])
    npow_succ := fun n x =>
      ext (pow_succ _ _)
        (by
          simp_rw [snd_mul, snd_pow_eq_sum, Nat.pred_succ]
          cases n
          · simp [List.range_succ]
          simp_rw [Nat.pred_succ]
          

Proof state:
case succ
R : Type u
M : Type v
inst✝⁴ : Monoid R
inst✝³ : AddMonoid M
inst✝² : DistribMulAction R M
inst✝¹ : DistribMulAction Rᵐᵒᵖ M
inst✝ : SMulCommClass R Rᵐᵒᵖ M
src✝ : MulOneClass (tsze R M) := mulOneClass
x : tsze R M
n✝ : ℕ
⊢ List.sum (List.map (fun i => fst x ^ (Nat.succ n✝ - i) • op (fst x ^ i) • snd x) (List.range (Nat.succ n✝ + 1))) =
    fst x • List.sum (List.map (fun i => fst x ^ (n✝ - i) • op (fst x ^ i) • snd x) (List.range (Nat.succ n✝))) +
      op (fst (x ^ Nat.succ n✝)) • snd x

Next tactic:
rw [List.range_succ, List.map_append, List.sum_append, List.map_singleton,
            List.sum_singleton, Nat.sub_self, pow_zero, one_smul, List.smul_sum, List.map_map,
            fst_pow]
instance monoid [Monoid R] [AddMonoid M] [DistribMulAction R M] [DistribMulAction Rᵐᵒᵖ M]
    [SMulCommClass R Rᵐᵒᵖ M] : Monoid (tsze R M) :=
  { TrivSqZeroExt.mulOneClass with
    mul_assoc := fun x y z =>
      ext (mul_assoc x.1 y.1 z.1) <|
        show
          (x.1 * y.1) • z.2 + op z.1 • (x.1 • y.2 + op y.1 • x.2) =
            x.1 • (y.1 • z.2 + op z.1 • y.2) + (op z.1 * op y.1) • x.2
          by simp_rw [smul_add, ← mul_smul, add_assoc, smul_comm]
    npow := fun n x => x ^ n
    npow_zero := fun x => ext (pow_zero x.fst) (by simp [snd_pow_eq_sum])
    npow_succ := fun n x =>
      ext (pow_succ _ _)
        (by
          simp_rw [snd_mul, snd_pow_eq_sum, Nat.pred_succ]
          cases n
          · simp [List.range_succ]
          simp_rw [Nat.pred_succ]
          rw [List.range_succ, List.map_append, List.sum_append, List.map_singleton,
            List.sum_singleton, Nat.sub_self, pow_zero, one_smul, List.smul_sum, List.map_map,
            fst_pow]  --porting note: `Function.comp` no longer works in `rw` so move to `simp_rw`
          

Proof state:
case succ
R : Type u
M : Type v
inst✝⁴ : Monoid R
inst✝³ : AddMonoid M
inst✝² : DistribMulAction R M
inst✝¹ : DistribMulAction Rᵐᵒᵖ M
inst✝ : SMulCommClass R Rᵐᵒᵖ M
src✝ : MulOneClass (tsze R M) := mulOneClass
x : tsze R M
n✝ : ℕ
⊢ List.sum (List.map (fun i => fst x ^ (Nat.succ n✝ - i) • op (fst x ^ i) • snd x) (List.range (n✝ + 1))) +
      op (fst x ^ (n✝ + 1)) • snd x =
    List.sum
        (List.map ((fun x_1 => fst x • x_1) ∘ fun i => fst x ^ (n✝ - i) • op (fst x ^ i) • snd x)
          (List.range (Nat.succ n✝))) +
      op (fst x ^ Nat.succ n✝) • snd x

Next tactic:
simp_rw [Function.comp, smul_smul, ← pow_succ, Nat.succ_eq_add_one]
instance monoid [Monoid R] [AddMonoid M] [DistribMulAction R M] [DistribMulAction Rᵐᵒᵖ M]
    [SMulCommClass R Rᵐᵒᵖ M] : Monoid (tsze R M) :=
  { TrivSqZeroExt.mulOneClass with
    mul_assoc := fun x y z =>
      ext (mul_assoc x.1 y.1 z.1) <|
        show
          (x.1 * y.1) • z.2 + op z.1 • (x.1 • y.2 + op y.1 • x.2) =
            x.1 • (y.1 • z.2 + op z.1 • y.2) + (op z.1 * op y.1) • x.2
          by simp_rw [smul_add, ← mul_smul, add_assoc, smul_comm]
    npow := fun n x => x ^ n
    npow_zero := fun x => ext (pow_zero x.fst) (by simp [snd_pow_eq_sum])
    npow_succ := fun n x =>
      ext (pow_succ _ _)
        (by
          simp_rw [snd_mul, snd_pow_eq_sum, Nat.pred_succ]
          cases n
          · simp [List.range_succ]
          simp_rw [Nat.pred_succ]
          rw [List.range_succ, List.map_append, List.sum_append, List.map_singleton,
            List.sum_singleton, Nat.sub_self, pow_zero, one_smul, List.smul_sum, List.map_map,
            fst_pow]  --porting note: `Function.comp` no longer works in `rw` so move to `simp_rw`
          simp_rw [Function.comp, smul_smul, ← pow_succ, Nat.succ_eq_add_one]
          

Proof state:
case succ
R : Type u
M : Type v
inst✝⁴ : Monoid R
inst✝³ : AddMonoid M
inst✝² : DistribMulAction R M
inst✝¹ : DistribMulAction Rᵐᵒᵖ M
inst✝ : SMulCommClass R Rᵐᵒᵖ M
src✝ : MulOneClass (tsze R M) := mulOneClass
x : tsze R M
n✝ : ℕ
⊢ List.sum (List.map (fun i => fst x ^ (n✝ + 1 - i) • op (fst x ^ i) • snd x) (List.range (n✝ + 1))) +
      op (fst x ^ (n✝ + 1)) • snd x =
    List.sum (List.map (fun x_1 => fst x ^ (n✝ - x_1 + 1) • op (fst x ^ x_1) • snd x) (List.range (n✝ + 1))) +
      op (fst x ^ (n✝ + 1)) • snd x

Next tactic:
congr 2
instance monoid [Monoid R] [AddMonoid M] [DistribMulAction R M] [DistribMulAction Rᵐᵒᵖ M]
    [SMulCommClass R Rᵐᵒᵖ M] : Monoid (tsze R M) :=
  { TrivSqZeroExt.mulOneClass with
    mul_assoc := fun x y z =>
      ext (mul_assoc x.1 y.1 z.1) <|
        show
          (x.1 * y.1) • z.2 + op z.1 • (x.1 • y.2 + op y.1 • x.2) =
            x.1 • (y.1 • z.2 + op z.1 • y.2) + (op z.1 * op y.1) • x.2
          by simp_rw [smul_add, ← mul_smul, add_assoc, smul_comm]
    npow := fun n x => x ^ n
    npow_zero := fun x => ext (pow_zero x.fst) (by simp [snd_pow_eq_sum])
    npow_succ := fun n x =>
      ext (pow_succ _ _)
        (by
          simp_rw [snd_mul, snd_pow_eq_sum, Nat.pred_succ]
          cases n
          · simp [List.range_succ]
          simp_rw [Nat.pred_succ]
          rw [List.range_succ, List.map_append, List.sum_append, List.map_singleton,
            List.sum_singleton, Nat.sub_self, pow_zero, one_smul, List.smul_sum, List.map_map,
            fst_pow]  --porting note: `Function.comp` no longer works in `rw` so move to `simp_rw`
          simp_rw [Function.comp, smul_smul, ← pow_succ, Nat.succ_eq_add_one]
          congr 2
          

Proof state:
case succ.e_a.e_a
R : Type u
M : Type v
inst✝⁴ : Monoid R
inst✝³ : AddMonoid M
inst✝² : DistribMulAction R M
inst✝¹ : DistribMulAction Rᵐᵒᵖ M
inst✝ : SMulCommClass R Rᵐᵒᵖ M
src✝ : MulOneClass (tsze R M) := mulOneClass
x : tsze R M
n✝ : ℕ
⊢ List.map (fun i => fst x ^ (n✝ + 1 - i) • op (fst x ^ i) • snd x) (List.range (n✝ + 1)) =
    List.map (fun x_1 => fst x ^ (n✝ - x_1 + 1) • op (fst x ^ x_1) • snd x) (List.range (n✝ + 1))

Next tactic:
refine' List.map_congr fun i hi => _
instance monoid [Monoid R] [AddMonoid M] [DistribMulAction R M] [DistribMulAction Rᵐᵒᵖ M]
    [SMulCommClass R Rᵐᵒᵖ M] : Monoid (tsze R M) :=
  { TrivSqZeroExt.mulOneClass with
    mul_assoc := fun x y z =>
      ext (mul_assoc x.1 y.1 z.1) <|
        show
          (x.1 * y.1) • z.2 + op z.1 • (x.1 • y.2 + op y.1 • x.2) =
            x.1 • (y.1 • z.2 + op z.1 • y.2) + (op z.1 * op y.1) • x.2
          by simp_rw [smul_add, ← mul_smul, add_assoc, smul_comm]
    npow := fun n x => x ^ n
    npow_zero := fun x => ext (pow_zero x.fst) (by simp [snd_pow_eq_sum])
    npow_succ := fun n x =>
      ext (pow_succ _ _)
        (by
          simp_rw [snd_mul, snd_pow_eq_sum, Nat.pred_succ]
          cases n
          · simp [List.range_succ]
          simp_rw [Nat.pred_succ]
          rw [List.range_succ, List.map_append, List.sum_append, List.map_singleton,
            List.sum_singleton, Nat.sub_self, pow_zero, one_smul, List.smul_sum, List.map_map,
            fst_pow]  --porting note: `Function.comp` no longer works in `rw` so move to `simp_rw`
          simp_rw [Function.comp, smul_smul, ← pow_succ, Nat.succ_eq_add_one]
          congr 2
          refine' List.map_congr fun i hi => _
          

Proof state:
case succ.e_a.e_a
R : Type u
M : Type v
inst✝⁴ : Monoid R
inst✝³ : AddMonoid M
inst✝² : DistribMulAction R M
inst✝¹ : DistribMulAction Rᵐᵒᵖ M
inst✝ : SMulCommClass R Rᵐᵒᵖ M
src✝ : MulOneClass (tsze R M) := mulOneClass
x : tsze R M
n✝ i : ℕ
hi : i ∈ List.range (n✝ + 1)
⊢ fst x ^ (n✝ + 1 - i) • op (fst x ^ i) • snd x = fst x ^ (n✝ - i + 1) • op (fst x ^ i) • snd x

Next tactic:
rw [List.mem_range, Nat.lt_succ_iff] at hi
instance monoid [Monoid R] [AddMonoid M] [DistribMulAction R M] [DistribMulAction Rᵐᵒᵖ M]
    [SMulCommClass R Rᵐᵒᵖ M] : Monoid (tsze R M) :=
  { TrivSqZeroExt.mulOneClass with
    mul_assoc := fun x y z =>
      ext (mul_assoc x.1 y.1 z.1) <|
        show
          (x.1 * y.1) • z.2 + op z.1 • (x.1 • y.2 + op y.1 • x.2) =
            x.1 • (y.1 • z.2 + op z.1 • y.2) + (op z.1 * op y.1) • x.2
          by simp_rw [smul_add, ← mul_smul, add_assoc, smul_comm]
    npow := fun n x => x ^ n
    npow_zero := fun x => ext (pow_zero x.fst) (by simp [snd_pow_eq_sum])
    npow_succ := fun n x =>
      ext (pow_succ _ _)
        (by
          simp_rw [snd_mul, snd_pow_eq_sum, Nat.pred_succ]
          cases n
          · simp [List.range_succ]
          simp_rw [Nat.pred_succ]
          rw [List.range_succ, List.map_append, List.sum_append, List.map_singleton,
            List.sum_singleton, Nat.sub_self, pow_zero, one_smul, List.smul_sum, List.map_map,
            fst_pow]  --porting note: `Function.comp` no longer works in `rw` so move to `simp_rw`
          simp_rw [Function.comp, smul_smul, ← pow_succ, Nat.succ_eq_add_one]
          congr 2
          refine' List.map_congr fun i hi => _
          rw [List.mem_range, Nat.lt_succ_iff] at hi
          

Proof state:
case succ.e_a.e_a
R : Type u
M : Type v
inst✝⁴ : Monoid R
inst✝³ : AddMonoid M
inst✝² : DistribMulAction R M
inst✝¹ : DistribMulAction Rᵐᵒᵖ M
inst✝ : SMulCommClass R Rᵐᵒᵖ M
src✝ : MulOneClass (tsze R M) := mulOneClass
x : tsze R M
n✝ i : ℕ
hi : i ≤ n✝
⊢ fst x ^ (n✝ + 1 - i) • op (fst x ^ i) • snd x = fst x ^ (n✝ - i + 1) • op (fst x ^ i) • snd x

Next tactic:
rw [Nat.sub_add_comm hi]
/-- The second element of a product $\prod_{i=0}^n (r_i + m_i)$ is a sum of terms of the form
$r_0\cdots r_{i-1}m_ir_{i+1}\cdots r_n$. -/
theorem snd_list_prod [Semiring R] [AddCommMonoid M] [Module R M] [Module Rᵐᵒᵖ M]
    [SMulCommClass R Rᵐᵒᵖ M] (l : List (tsze R M)) :
    l.prod.snd =
      (l.enum.map fun x : ℕ × tsze R M =>
          ((l.map fst).take x.1).prod • op ((l.map fst).drop x.1.succ).prod • x.snd.snd).sum := by
  

Proof state:
R : Type u
M : Type v
inst✝⁴ : Semiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
inst✝¹ : Module Rᵐᵒᵖ M
inst✝ : SMulCommClass R Rᵐᵒᵖ M
l : List (tsze R M)
⊢ snd (List.prod l) =
    List.sum
      (List.map
        (fun x =>
          List.prod (List.take x.1 (List.map fst l)) •
            op (List.prod (List.drop (Nat.succ x.1) (List.map fst l))) • snd x.2)
        (List.enum l))

Next tactic:
induction' l with x xs ih
/-- The second element of a product $\prod_{i=0}^n (r_i + m_i)$ is a sum of terms of the form
$r_0\cdots r_{i-1}m_ir_{i+1}\cdots r_n$. -/
theorem snd_list_prod [Semiring R] [AddCommMonoid M] [Module R M] [Module Rᵐᵒᵖ M]
    [SMulCommClass R Rᵐᵒᵖ M] (l : List (tsze R M)) :
    l.prod.snd =
      (l.enum.map fun x : ℕ × tsze R M =>
          ((l.map fst).take x.1).prod • op ((l.map fst).drop x.1.succ).prod • x.snd.snd).sum := by
  induction' l with x xs ih
  · 

Proof state:
case nil
R : Type u
M : Type v
inst✝⁴ : Semiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
inst✝¹ : Module Rᵐᵒᵖ M
inst✝ : SMulCommClass R Rᵐᵒᵖ M
⊢ snd (List.prod []) =
    List.sum
      (List.map
        (fun x =>
          List.prod (List.take x.1 (List.map fst [])) •
            op (List.prod (List.drop (Nat.succ x.1) (List.map fst []))) • snd x.2)
        (List.enum []))

Next tactic:
simp
/-- The second element of a product $\prod_{i=0}^n (r_i + m_i)$ is a sum of terms of the form
$r_0\cdots r_{i-1}m_ir_{i+1}\cdots r_n$. -/
theorem snd_list_prod [Semiring R] [AddCommMonoid M] [Module R M] [Module Rᵐᵒᵖ M]
    [SMulCommClass R Rᵐᵒᵖ M] (l : List (tsze R M)) :
    l.prod.snd =
      (l.enum.map fun x : ℕ × tsze R M =>
          ((l.map fst).take x.1).prod • op ((l.map fst).drop x.1.succ).prod • x.snd.snd).sum := by
  induction' l with x xs ih
  · simp
  · 

Proof state:
case cons
R : Type u
M : Type v
inst✝⁴ : Semiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
inst✝¹ : Module Rᵐᵒᵖ M
inst✝ : SMulCommClass R Rᵐᵒᵖ M
x : tsze R M
xs : List (tsze R M)
ih :
  snd (List.prod xs) =
    List.sum
      (List.map
        (fun x =>
          List.prod (List.take x.1 (List.map fst xs)) •
            op (List.prod (List.drop (Nat.succ x.1) (List.map fst xs))) • snd x.2)
        (List.enum xs))
⊢ snd (List.prod (x :: xs)) =
    List.sum
      (List.map
        (fun x_1 =>
          List.prod (List.take x_1.1 (List.map fst (x :: xs))) •
            op (List.prod (List.drop (Nat.succ x_1.1) (List.map fst (x :: xs)))) • snd x_1.2)
        (List.enum (x :: xs)))

Next tactic:
rw [List.enum_cons, ← List.map_fst_add_enum_eq_enumFrom]
/-- The second element of a product $\prod_{i=0}^n (r_i + m_i)$ is a sum of terms of the form
$r_0\cdots r_{i-1}m_ir_{i+1}\cdots r_n$. -/
theorem snd_list_prod [Semiring R] [AddCommMonoid M] [Module R M] [Module Rᵐᵒᵖ M]
    [SMulCommClass R Rᵐᵒᵖ M] (l : List (tsze R M)) :
    l.prod.snd =
      (l.enum.map fun x : ℕ × tsze R M =>
          ((l.map fst).take x.1).prod • op ((l.map fst).drop x.1.succ).prod • x.snd.snd).sum := by
  induction' l with x xs ih
  · simp
  · rw [List.enum_cons, ← List.map_fst_add_enum_eq_enumFrom]
    

Proof state:
case cons
R : Type u
M : Type v
inst✝⁴ : Semiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
inst✝¹ : Module Rᵐᵒᵖ M
inst✝ : SMulCommClass R Rᵐᵒᵖ M
x : tsze R M
xs : List (tsze R M)
ih :
  snd (List.prod xs) =
    List.sum
      (List.map
        (fun x =>
          List.prod (List.take x.1 (List.map fst xs)) •
            op (List.prod (List.drop (Nat.succ x.1) (List.map fst xs))) • snd x.2)
        (List.enum xs))
⊢ snd (List.prod (x :: xs)) =
    List.sum
      (List.map
        (fun x_1 =>
          List.prod (List.take x_1.1 (List.map fst (x :: xs))) •
            op (List.prod (List.drop (Nat.succ x_1.1) (List.map fst (x :: xs)))) • snd x_1.2)
        ((0, x) :: List.map (Prod.map (fun x => x + 1) id) (List.enum xs)))

Next tactic:
simp_rw [List.map_cons, List.map_map, Function.comp, Prod.map_snd, Prod.map_fst, id,
      List.take_zero, List.take_cons, List.prod_nil, List.prod_cons, snd_mul, one_smul, List.drop,
      mul_smul, List.sum_cons, fst_list_prod, ih, List.smul_sum, List.map_map]
/-- The second element of a product $\prod_{i=0}^n (r_i + m_i)$ is a sum of terms of the form
$r_0\cdots r_{i-1}m_ir_{i+1}\cdots r_n$. -/
theorem snd_list_prod [Semiring R] [AddCommMonoid M] [Module R M] [Module Rᵐᵒᵖ M]
    [SMulCommClass R Rᵐᵒᵖ M] (l : List (tsze R M)) :
    l.prod.snd =
      (l.enum.map fun x : ℕ × tsze R M =>
          ((l.map fst).take x.1).prod • op ((l.map fst).drop x.1.succ).prod • x.snd.snd).sum := by
  induction' l with x xs ih
  · simp
  · rw [List.enum_cons, ← List.map_fst_add_enum_eq_enumFrom]
    simp_rw [List.map_cons, List.map_map, Function.comp, Prod.map_snd, Prod.map_fst, id,
      List.take_zero, List.take_cons, List.prod_nil, List.prod_cons, snd_mul, one_smul, List.drop,
      mul_smul, List.sum_cons, fst_list_prod, ih, List.smul_sum, List.map_map]
    

Proof state:
case cons
R : Type u
M : Type v
inst✝⁴ : Semiring R
inst✝³ : AddCommMonoid M
inst✝² : Module R M
inst✝¹ : Module Rᵐᵒᵖ M
inst✝ : SMulCommClass R Rᵐᵒᵖ M
x : tsze R M
xs : List (tsze R M)
ih :
  snd (List.prod xs) =
    List.sum
      (List.map
        (fun x =>
          List.prod (List.take x.1 (List.map fst xs)) •
            op (List.prod (List.drop (Nat.succ x.1) (List.map fst xs))) • snd x.2)
        (List.enum xs))
⊢ List.sum
        (List.map
          ((fun x_1 => fst x • x_1) ∘ fun x =>
            List.prod (List.take x.1 (List.map fst xs)) •
              op (List.prod (List.drop (Nat.succ x.1) (List.map fst xs))) • snd x.2)
          (List.enum xs)) +
      op (List.prod (List.map fst xs)) • snd x =
    op (List.prod (List.map fst xs)) • snd x +
      List.sum
        (List.map
          (fun x_1 =>
            fst x •
              List.prod (List.take x_1.1 (List.map fst xs)) •
                op (List.prod (List.drop (x_1.1 + 1) (List.map fst xs))) • snd x_1.2)
          (List.enum xs))

Next tactic:
exact add_comm _ _
instance commMonoid [CommMonoid R] [AddCommMonoid M] [DistribMulAction R M]
    [DistribMulAction Rᵐᵒᵖ M] [IsCentralScalar R M] : CommMonoid (tsze R M) :=
  { TrivSqZeroExt.monoid with
    mul_comm := fun x₁ x₂ =>
      ext (mul_comm x₁.1 x₂.1) <|
        show x₁.1 • x₂.2 + op x₂.1 • x₁.2 = x₂.1 • x₁.2 + op x₁.1 • x₂.2 by
          

Proof state:
R : Type u
M : Type v
inst✝⁴ : CommMonoid R
inst✝³ : AddCommMonoid M
inst✝² : DistribMulAction R M
inst✝¹ : DistribMulAction Rᵐᵒᵖ M
inst✝ : IsCentralScalar R M
src✝ : Monoid (tsze R M) := monoid
x₁ x₂ : tsze R M
⊢ x₁.1 • x₂.2 + op x₂.1 • x₁.2 = x₂.1 • x₁.2 + op x₁.1 • x₂.2

Next tactic:
rw [op_smul_eq_smul, op_smul_eq_smul, add_comm]