l3lab/ntp-mathlib huggingface dataset:
/-- The leading coefficient of a product of polynomials is equal to
the product of the leading coefficients, provided that this product is nonzero.

See `Polynomial.leadingCoeff_multiset_prod` (without the `'`) for a version for integral domains,
where this condition is automatically satisfied.
-/
theorem leadingCoeff_multiset_prod' (h : (t.map leadingCoeff).prod ≠ 0) :
    t.prod.leadingCoeff = (t.map leadingCoeff).prod := by
  induction' t using Multiset.induction_on with a t ih; · simp
  simp only [Multiset.map_cons, Multiset.prod_cons] at h ⊢
  rw [Polynomial.leadingCoeff_mul']
  · rw [ih]
    simp only [ne_eq]
    apply right_ne_zero_of_mul h
  · rw [ih]
    

Proof state:
case cons
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
a : R[X]
t : Multiset R[X]
ih : prod (Multiset.map leadingCoeff t) ≠ 0 → leadingCoeff (prod t) = prod (Multiset.map leadingCoeff t)
h : leadingCoeff a * prod (Multiset.map leadingCoeff t) ≠ 0
⊢ leadingCoeff a * prod (Multiset.map leadingCoeff t) ≠ 0
case cons
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
a : R[X]
t : Multiset R[X]
ih : prod (Multiset.map leadingCoeff t) ≠ 0 → leadingCoeff (prod t) = prod (Multiset.map leadingCoeff t)
h : leadingCoeff a * prod (Multiset.map leadingCoeff t) ≠ 0
⊢ prod (Multiset.map leadingCoeff t) ≠ 0

Next tactic:
exact h
/-- The leading coefficient of a product of polynomials is equal to
the product of the leading coefficients, provided that this product is nonzero.

See `Polynomial.leadingCoeff_multiset_prod` (without the `'`) for a version for integral domains,
where this condition is automatically satisfied.
-/
theorem leadingCoeff_multiset_prod' (h : (t.map leadingCoeff).prod ≠ 0) :
    t.prod.leadingCoeff = (t.map leadingCoeff).prod := by
  induction' t using Multiset.induction_on with a t ih; · simp
  simp only [Multiset.map_cons, Multiset.prod_cons] at h ⊢
  rw [Polynomial.leadingCoeff_mul']
  · rw [ih]
    simp only [ne_eq]
    apply right_ne_zero_of_mul h
  · rw [ih]
    exact h
    

Proof state:
case cons
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
a : R[X]
t : Multiset R[X]
ih : prod (Multiset.map leadingCoeff t) ≠ 0 → leadingCoeff (prod t) = prod (Multiset.map leadingCoeff t)
h : leadingCoeff a * prod (Multiset.map leadingCoeff t) ≠ 0
⊢ prod (Multiset.map leadingCoeff t) ≠ 0

Next tactic:
simp only [ne_eq, not_false_eq_true]
/-- The leading coefficient of a product of polynomials is equal to
the product of the leading coefficients, provided that this product is nonzero.

See `Polynomial.leadingCoeff_multiset_prod` (without the `'`) for a version for integral domains,
where this condition is automatically satisfied.
-/
theorem leadingCoeff_multiset_prod' (h : (t.map leadingCoeff).prod ≠ 0) :
    t.prod.leadingCoeff = (t.map leadingCoeff).prod := by
  induction' t using Multiset.induction_on with a t ih; · simp
  simp only [Multiset.map_cons, Multiset.prod_cons] at h ⊢
  rw [Polynomial.leadingCoeff_mul']
  · rw [ih]
    simp only [ne_eq]
    apply right_ne_zero_of_mul h
  · rw [ih]
    exact h
    simp only [ne_eq, not_false_eq_true]
    

Proof state:
case cons
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
a : R[X]
t : Multiset R[X]
ih : prod (Multiset.map leadingCoeff t) ≠ 0 → leadingCoeff (prod t) = prod (Multiset.map leadingCoeff t)
h : leadingCoeff a * prod (Multiset.map leadingCoeff t) ≠ 0
⊢ ¬prod (Multiset.map leadingCoeff t) = 0

Next tactic:
apply right_ne_zero_of_mul h
/-- The leading coefficient of a product of polynomials is equal to
the product of the leading coefficients, provided that this product is nonzero.

See `Polynomial.leadingCoeff_prod` (without the `'`) for a version for integral domains,
where this condition is automatically satisfied.
-/
theorem leadingCoeff_prod' (h : (∏ i in s, (f i).leadingCoeff) ≠ 0) :
    (∏ i in s, f i).leadingCoeff = ∏ i in s, (f i).leadingCoeff := by
  

Proof state:
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∏ i in s, leadingCoeff (f i) ≠ 0
⊢ leadingCoeff (∏ i in s, f i) = ∏ i in s, leadingCoeff (f i)

Next tactic:
simpa using leadingCoeff_multiset_prod' (s.1.map f) (by simpa using h)
/-- The leading coefficient of a product of polynomials is equal to
the product of the leading coefficients, provided that this product is nonzero.

See `Polynomial.leadingCoeff_prod` (without the `'`) for a version for integral domains,
where this condition is automatically satisfied.
-/
theorem leadingCoeff_prod' (h : (∏ i in s, (f i).leadingCoeff) ≠ 0) :
    (∏ i in s, f i).leadingCoeff = ∏ i in s, (f i).leadingCoeff := by
  simpa using leadingCoeff_multiset_prod' (s.1.map f) (by 

Proof state:
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∏ i in s, leadingCoeff (f i) ≠ 0
⊢ prod (Multiset.map leadingCoeff (Multiset.map f s.val)) ≠ 0

Next tactic:
simpa using h
/-- The degree of a product of polynomials is equal to
the sum of the degrees, provided that the product of leading coefficients is nonzero.

See `Polynomial.natDegree_multiset_prod` (without the `'`) for a version for integral domains,
where this condition is automatically satisfied.
-/
theorem natDegree_multiset_prod' (h : (t.map fun f => leadingCoeff f).prod ≠ 0) :
    t.prod.natDegree = (t.map fun f => natDegree f).sum := by
  

Proof state:
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0
⊢ natDegree (prod t) = Multiset.sum (Multiset.map (fun f => natDegree f) t)

Next tactic:
revert h
/-- The degree of a product of polynomials is equal to
the sum of the degrees, provided that the product of leading coefficients is nonzero.

See `Polynomial.natDegree_multiset_prod` (without the `'`) for a version for integral domains,
where this condition is automatically satisfied.
-/
theorem natDegree_multiset_prod' (h : (t.map fun f => leadingCoeff f).prod ≠ 0) :
    t.prod.natDegree = (t.map fun f => natDegree f).sum := by
  revert h
  

Proof state:
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
⊢ prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0 →
    natDegree (prod t) = Multiset.sum (Multiset.map (fun f => natDegree f) t)

Next tactic:
refine' Multiset.induction_on t _ fun a t ih ht => _
/-- The degree of a product of polynomials is equal to
the sum of the degrees, provided that the product of leading coefficients is nonzero.

See `Polynomial.natDegree_multiset_prod` (without the `'`) for a version for integral domains,
where this condition is automatically satisfied.
-/
theorem natDegree_multiset_prod' (h : (t.map fun f => leadingCoeff f).prod ≠ 0) :
    t.prod.natDegree = (t.map fun f => natDegree f).sum := by
  revert h
  refine' Multiset.induction_on t _ fun a t ih ht => _; · 

Proof state:
case refine'_1
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
⊢ prod (Multiset.map (fun f => leadingCoeff f) 0) ≠ 0 →
    natDegree (prod 0) = Multiset.sum (Multiset.map (fun f => natDegree f) 0)

Next tactic:
simp
/-- The degree of a product of polynomials is equal to
the sum of the degrees, provided that the product of leading coefficients is nonzero.

See `Polynomial.natDegree_multiset_prod` (without the `'`) for a version for integral domains,
where this condition is automatically satisfied.
-/
theorem natDegree_multiset_prod' (h : (t.map fun f => leadingCoeff f).prod ≠ 0) :
    t.prod.natDegree = (t.map fun f => natDegree f).sum := by
  revert h
  refine' Multiset.induction_on t _ fun a t ih ht => _; · simp
  

Proof state:
case refine'_2
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
a : R[X]
t : Multiset R[X]
ih :
  prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0 →
    natDegree (prod t) = Multiset.sum (Multiset.map (fun f => natDegree f) t)
ht : prod (Multiset.map (fun f => leadingCoeff f) (a ::ₘ t)) ≠ 0
⊢ natDegree (prod (a ::ₘ t)) = Multiset.sum (Multiset.map (fun f => natDegree f) (a ::ₘ t))

Next tactic:
rw [Multiset.map_cons, Multiset.prod_cons] at ht ⊢
/-- The degree of a product of polynomials is equal to
the sum of the degrees, provided that the product of leading coefficients is nonzero.

See `Polynomial.natDegree_multiset_prod` (without the `'`) for a version for integral domains,
where this condition is automatically satisfied.
-/
theorem natDegree_multiset_prod' (h : (t.map fun f => leadingCoeff f).prod ≠ 0) :
    t.prod.natDegree = (t.map fun f => natDegree f).sum := by
  revert h
  refine' Multiset.induction_on t _ fun a t ih ht => _; · simp
  rw [Multiset.map_cons, Multiset.prod_cons] at ht ⊢
  

Proof state:
case refine'_2
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
a : R[X]
t : Multiset R[X]
ih :
  prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0 →
    natDegree (prod t) = Multiset.sum (Multiset.map (fun f => natDegree f) t)
ht : leadingCoeff a * prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0
⊢ natDegree (a * prod t) = Multiset.sum (natDegree a ::ₘ Multiset.map (fun f => natDegree f) t)

Next tactic:
rw [Multiset.sum_cons, Polynomial.natDegree_mul', ih]
/-- The degree of a product of polynomials is equal to
the sum of the degrees, provided that the product of leading coefficients is nonzero.

See `Polynomial.natDegree_multiset_prod` (without the `'`) for a version for integral domains,
where this condition is automatically satisfied.
-/
theorem natDegree_multiset_prod' (h : (t.map fun f => leadingCoeff f).prod ≠ 0) :
    t.prod.natDegree = (t.map fun f => natDegree f).sum := by
  revert h
  refine' Multiset.induction_on t _ fun a t ih ht => _; · simp
  rw [Multiset.map_cons, Multiset.prod_cons] at ht ⊢
  rw [Multiset.sum_cons, Polynomial.natDegree_mul', ih]
  · 

Proof state:
case refine'_2
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
a : R[X]
t : Multiset R[X]
ih :
  prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0 →
    natDegree (prod t) = Multiset.sum (Multiset.map (fun f => natDegree f) t)
ht : leadingCoeff a * prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0
⊢ prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0

Next tactic:
apply right_ne_zero_of_mul ht
/-- The degree of a product of polynomials is equal to
the sum of the degrees, provided that the product of leading coefficients is nonzero.

See `Polynomial.natDegree_multiset_prod` (without the `'`) for a version for integral domains,
where this condition is automatically satisfied.
-/
theorem natDegree_multiset_prod' (h : (t.map fun f => leadingCoeff f).prod ≠ 0) :
    t.prod.natDegree = (t.map fun f => natDegree f).sum := by
  revert h
  refine' Multiset.induction_on t _ fun a t ih ht => _; · simp
  rw [Multiset.map_cons, Multiset.prod_cons] at ht ⊢
  rw [Multiset.sum_cons, Polynomial.natDegree_mul', ih]
  · apply right_ne_zero_of_mul ht
  · 

Proof state:
case refine'_2
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
a : R[X]
t : Multiset R[X]
ih :
  prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0 →
    natDegree (prod t) = Multiset.sum (Multiset.map (fun f => natDegree f) t)
ht : leadingCoeff a * prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0
⊢ leadingCoeff a * leadingCoeff (prod t) ≠ 0

Next tactic:
rwa [Polynomial.leadingCoeff_multiset_prod']
/-- The degree of a product of polynomials is equal to
the sum of the degrees, provided that the product of leading coefficients is nonzero.

See `Polynomial.natDegree_multiset_prod` (without the `'`) for a version for integral domains,
where this condition is automatically satisfied.
-/
theorem natDegree_multiset_prod' (h : (t.map fun f => leadingCoeff f).prod ≠ 0) :
    t.prod.natDegree = (t.map fun f => natDegree f).sum := by
  revert h
  refine' Multiset.induction_on t _ fun a t ih ht => _; · simp
  rw [Multiset.map_cons, Multiset.prod_cons] at ht ⊢
  rw [Multiset.sum_cons, Polynomial.natDegree_mul', ih]
  · apply right_ne_zero_of_mul ht
  · rwa [Polynomial.leadingCoeff_multiset_prod']
    

Proof state:
case refine'_2.h
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
a : R[X]
t : Multiset R[X]
ih :
  prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0 →
    natDegree (prod t) = Multiset.sum (Multiset.map (fun f => natDegree f) t)
ht : leadingCoeff a * prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0
⊢ prod (Multiset.map leadingCoeff t) ≠ 0

Next tactic:
apply right_ne_zero_of_mul ht
/-- The degree of a product of polynomials is equal to
the sum of the degrees, provided that the product of leading coefficients is nonzero.

See `Polynomial.natDegree_prod` (without the `'`) for a version for integral domains,
where this condition is automatically satisfied.
-/
theorem natDegree_prod' (h : (∏ i in s, (f i).leadingCoeff) ≠ 0) :
    (∏ i in s, f i).natDegree = ∑ i in s, (f i).natDegree := by
  

Proof state:
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∏ i in s, leadingCoeff (f i) ≠ 0
⊢ natDegree (∏ i in s, f i) = ∑ i in s, natDegree (f i)

Next tactic:
simpa using natDegree_multiset_prod' (s.1.map f) (by simpa using h)
/-- The degree of a product of polynomials is equal to
the sum of the degrees, provided that the product of leading coefficients is nonzero.

See `Polynomial.natDegree_prod` (without the `'`) for a version for integral domains,
where this condition is automatically satisfied.
-/
theorem natDegree_prod' (h : (∏ i in s, (f i).leadingCoeff) ≠ 0) :
    (∏ i in s, f i).natDegree = ∑ i in s, (f i).natDegree := by
  simpa using natDegree_multiset_prod' (s.1.map f) (by 

Proof state:
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∏ i in s, leadingCoeff (f i) ≠ 0
⊢ prod (Multiset.map (fun f => leadingCoeff f) (Multiset.map f s.val)) ≠ 0

Next tactic:
simpa using h
theorem natDegree_multiset_prod_of_monic (h : ∀ f ∈ t, Monic f) :
    t.prod.natDegree = (t.map natDegree).sum := by
  

Proof state:
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ f ∈ t, Monic f
⊢ natDegree (prod t) = Multiset.sum (Multiset.map natDegree t)

Next tactic:
nontriviality R
theorem natDegree_multiset_prod_of_monic (h : ∀ f ∈ t, Monic f) :
    t.prod.natDegree = (t.map natDegree).sum := by
  nontriviality R
  

Proof state:
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ f ∈ t, Monic f
✝ : Nontrivial R
⊢ natDegree (prod t) = Multiset.sum (Multiset.map natDegree t)

Next tactic:
apply natDegree_multiset_prod'
theorem natDegree_multiset_prod_of_monic (h : ∀ f ∈ t, Monic f) :
    t.prod.natDegree = (t.map natDegree).sum := by
  nontriviality R
  apply natDegree_multiset_prod'
  

Proof state:
case h
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ f ∈ t, Monic f
✝ : Nontrivial R
⊢ prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0

Next tactic:
suffices (t.map fun f => leadingCoeff f).prod = 1 by
    rw [this]
    simp
theorem natDegree_multiset_prod_of_monic (h : ∀ f ∈ t, Monic f) :
    t.prod.natDegree = (t.map natDegree).sum := by
  nontriviality R
  apply natDegree_multiset_prod'
  suffices (t.map fun f => leadingCoeff f).prod = 1 by
    

Proof state:
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ f ∈ t, Monic f
✝ : Nontrivial R
this : prod (Multiset.map (fun f => leadingCoeff f) t) = 1
⊢ prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0

Next tactic:
rw [this]
theorem natDegree_multiset_prod_of_monic (h : ∀ f ∈ t, Monic f) :
    t.prod.natDegree = (t.map natDegree).sum := by
  nontriviality R
  apply natDegree_multiset_prod'
  suffices (t.map fun f => leadingCoeff f).prod = 1 by
    rw [this]
    

Proof state:
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ f ∈ t, Monic f
✝ : Nontrivial R
this : prod (Multiset.map (fun f => leadingCoeff f) t) = 1
⊢ 1 ≠ 0

Next tactic:
simp
theorem natDegree_multiset_prod_of_monic (h : ∀ f ∈ t, Monic f) :
    t.prod.natDegree = (t.map natDegree).sum := by
  nontriviality R
  apply natDegree_multiset_prod'
  suffices (t.map fun f => leadingCoeff f).prod = 1 by
    rw [this]
    simp
  

Proof state:
case h
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ f ∈ t, Monic f
✝ : Nontrivial R
⊢ prod (Multiset.map (fun f => leadingCoeff f) t) = 1

Next tactic:
convert prod_replicate (Multiset.card t) (1 : R)
theorem natDegree_multiset_prod_of_monic (h : ∀ f ∈ t, Monic f) :
    t.prod.natDegree = (t.map natDegree).sum := by
  nontriviality R
  apply natDegree_multiset_prod'
  suffices (t.map fun f => leadingCoeff f).prod = 1 by
    rw [this]
    simp
  convert prod_replicate (Multiset.card t) (1 : R)
  · 

Proof state:
case h.e'_2.h.e'_3
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ f ∈ t, Monic f
✝ : Nontrivial R
⊢ Multiset.map (fun f => leadingCoeff f) t = replicate (Multiset.card t) 1

Next tactic:
simp only [eq_replicate, Multiset.card_map, eq_self_iff_true, true_and_iff]
theorem natDegree_multiset_prod_of_monic (h : ∀ f ∈ t, Monic f) :
    t.prod.natDegree = (t.map natDegree).sum := by
  nontriviality R
  apply natDegree_multiset_prod'
  suffices (t.map fun f => leadingCoeff f).prod = 1 by
    rw [this]
    simp
  convert prod_replicate (Multiset.card t) (1 : R)
  · simp only [eq_replicate, Multiset.card_map, eq_self_iff_true, true_and_iff]
    

Proof state:
case h.e'_2.h.e'_3
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ f ∈ t, Monic f
✝ : Nontrivial R
⊢ ∀ b ∈ Multiset.map (fun f => leadingCoeff f) t, b = 1

Next tactic:
rintro i hi
theorem natDegree_multiset_prod_of_monic (h : ∀ f ∈ t, Monic f) :
    t.prod.natDegree = (t.map natDegree).sum := by
  nontriviality R
  apply natDegree_multiset_prod'
  suffices (t.map fun f => leadingCoeff f).prod = 1 by
    rw [this]
    simp
  convert prod_replicate (Multiset.card t) (1 : R)
  · simp only [eq_replicate, Multiset.card_map, eq_self_iff_true, true_and_iff]
    rintro i hi
    

Proof state:
case h.e'_2.h.e'_3
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ f ∈ t, Monic f
✝ : Nontrivial R
i : R
hi : i ∈ Multiset.map (fun f => leadingCoeff f) t
⊢ i = 1

Next tactic:
obtain ⟨i, hi, rfl⟩ := Multiset.mem_map.mp hi
theorem natDegree_multiset_prod_of_monic (h : ∀ f ∈ t, Monic f) :
    t.prod.natDegree = (t.map natDegree).sum := by
  nontriviality R
  apply natDegree_multiset_prod'
  suffices (t.map fun f => leadingCoeff f).prod = 1 by
    rw [this]
    simp
  convert prod_replicate (Multiset.card t) (1 : R)
  · simp only [eq_replicate, Multiset.card_map, eq_self_iff_true, true_and_iff]
    rintro i hi
    obtain ⟨i, hi, rfl⟩ := Multiset.mem_map.mp hi
    

Proof state:
case h.e'_2.h.e'_3.intro.intro
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ f ∈ t, Monic f
✝ : Nontrivial R
i : R[X]
hi✝ : i ∈ t
hi : leadingCoeff i ∈ Multiset.map (fun f => leadingCoeff f) t
⊢ leadingCoeff i = 1

Next tactic:
apply h
theorem natDegree_multiset_prod_of_monic (h : ∀ f ∈ t, Monic f) :
    t.prod.natDegree = (t.map natDegree).sum := by
  nontriviality R
  apply natDegree_multiset_prod'
  suffices (t.map fun f => leadingCoeff f).prod = 1 by
    rw [this]
    simp
  convert prod_replicate (Multiset.card t) (1 : R)
  · simp only [eq_replicate, Multiset.card_map, eq_self_iff_true, true_and_iff]
    rintro i hi
    obtain ⟨i, hi, rfl⟩ := Multiset.mem_map.mp hi
    apply h
    

Proof state:
case h.e'_2.h.e'_3.intro.intro.a
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ f ∈ t, Monic f
✝ : Nontrivial R
i : R[X]
hi✝ : i ∈ t
hi : leadingCoeff i ∈ Multiset.map (fun f => leadingCoeff f) t
⊢ i ∈ t

Next tactic:
assumption
theorem natDegree_multiset_prod_of_monic (h : ∀ f ∈ t, Monic f) :
    t.prod.natDegree = (t.map natDegree).sum := by
  nontriviality R
  apply natDegree_multiset_prod'
  suffices (t.map fun f => leadingCoeff f).prod = 1 by
    rw [this]
    simp
  convert prod_replicate (Multiset.card t) (1 : R)
  · simp only [eq_replicate, Multiset.card_map, eq_self_iff_true, true_and_iff]
    rintro i hi
    obtain ⟨i, hi, rfl⟩ := Multiset.mem_map.mp hi
    apply h
    assumption
  · 

Proof state:
case h.e'_3
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ f ∈ t, Monic f
✝ : Nontrivial R
⊢ 1 = 1 ^ Multiset.card t

Next tactic:
simp
theorem natDegree_prod_of_monic (h : ∀ i ∈ s, (f i).Monic) :
    (∏ i in s, f i).natDegree = ∑ i in s, (f i).natDegree := by
  

Proof state:
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ i ∈ s, Monic (f i)
⊢ natDegree (∏ i in s, f i) = ∑ i in s, natDegree (f i)

Next tactic:
simpa using natDegree_multiset_prod_of_monic (s.1.map f) (by simpa using h)
theorem natDegree_prod_of_monic (h : ∀ i ∈ s, (f i).Monic) :
    (∏ i in s, f i).natDegree = ∑ i in s, (f i).natDegree := by
  simpa using natDegree_multiset_prod_of_monic (s.1.map f) (by 

Proof state:
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ i ∈ s, Monic (f i)
⊢ ∀ f_1 ∈ Multiset.map f s.val, Monic f_1

Next tactic:
simpa using h
theorem coeff_multiset_prod_of_natDegree_le (n : ℕ) (hl : ∀ p ∈ t, natDegree p ≤ n) :
    coeff t.prod ((Multiset.card t) * n) = (t.map fun p => coeff p n).prod := by
  

Proof state:
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
n : ℕ
hl : ∀ p ∈ t, natDegree p ≤ n
⊢ coeff (prod t) (Multiset.card t * n) = prod (Multiset.map (fun p => coeff p n) t)

Next tactic:
induction t using Quotient.inductionOn
theorem coeff_multiset_prod_of_natDegree_le (n : ℕ) (hl : ∀ p ∈ t, natDegree p ≤ n) :
    coeff t.prod ((Multiset.card t) * n) = (t.map fun p => coeff p n).prod := by
  induction t using Quotient.inductionOn
  

Proof state:
case h
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
n : ℕ
a✝ : List R[X]
hl : ∀ p ∈ ⟦a✝⟧, natDegree p ≤ n
⊢ coeff (prod ⟦a✝⟧) (Multiset.card ⟦a✝⟧ * n) = prod (Multiset.map (fun p => coeff p n) ⟦a✝⟧)

Next tactic:
simpa using coeff_list_prod_of_natDegree_le _ _ hl
theorem coeff_prod_of_natDegree_le (f : ι → R[X]) (n : ℕ) (h : ∀ p ∈ s, natDegree (f p) ≤ n) :
    coeff (∏ i in s, f i) (s.card * n) = ∏ i in s, coeff (f i) n := by
  

Proof state:
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f✝ : ι → R[X]
t : Multiset R[X]
f : ι → R[X]
n : ℕ
h : ∀ p ∈ s, natDegree (f p) ≤ n
⊢ coeff (∏ i in s, f i) (Finset.card s * n) = ∏ i in s, coeff (f i) n

Next tactic:
cases' s with l hl
theorem coeff_prod_of_natDegree_le (f : ι → R[X]) (n : ℕ) (h : ∀ p ∈ s, natDegree (f p) ≤ n) :
    coeff (∏ i in s, f i) (s.card * n) = ∏ i in s, coeff (f i) n := by
  cases' s with l hl
  

Proof state:
case mk
R : Type u
ι : Type w
inst✝ : CommSemiring R
f✝ : ι → R[X]
t : Multiset R[X]
f : ι → R[X]
n : ℕ
l : Multiset ι
hl : Nodup l
h : ∀ p ∈ { val := l, nodup := hl }, natDegree (f p) ≤ n
⊢ coeff (∏ i in { val := l, nodup := hl }, f i) (Finset.card { val := l, nodup := hl } * n) =
    ∏ i in { val := l, nodup := hl }, coeff (f i) n

Next tactic:
convert coeff_multiset_prod_of_natDegree_le (l.map f) n ?_
theorem coeff_prod_of_natDegree_le (f : ι → R[X]) (n : ℕ) (h : ∀ p ∈ s, natDegree (f p) ≤ n) :
    coeff (∏ i in s, f i) (s.card * n) = ∏ i in s, coeff (f i) n := by
  cases' s with l hl
  convert coeff_multiset_prod_of_natDegree_le (l.map f) n ?_
  · 

Proof state:
case h.e'_2.h.e'_4.h.e'_5
R : Type u
ι : Type w
inst✝ : CommSemiring R
f✝ : ι → R[X]
t : Multiset R[X]
f : ι → R[X]
n : ℕ
l : Multiset ι
hl : Nodup l
h : ∀ p ∈ { val := l, nodup := hl }, natDegree (f p) ≤ n
⊢ Finset.card { val := l, nodup := hl } = Multiset.card (Multiset.map f l)

Next tactic:
simp