l3lab/ntp-mathlib huggingface dataset:
theorem coeff_list_prod_of_natDegree_le (l : List S[X]) (n : ℕ) (hl : ∀ p ∈ l, natDegree p ≤ n) :
    coeff (List.prod l) (l.length * n) = (l.map fun p => coeff p n).prod := by
  induction' l with hd tl IH
  · simp
  · have hl' : ∀ p ∈ tl, natDegree p ≤ n := fun p hp => hl p (List.mem_cons_of_mem _ hp)
    simp only [List.prod_cons, List.map, List.length]
    rw [add_mul, one_mul, add_comm, ← IH hl', mul_comm tl.length]
    have h : natDegree tl.prod ≤ n * tl.length := by
      refine' (natDegree_list_prod_le _).trans _
      

Proof state:
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
n : ℕ
hd : S[X]
tl : List S[X]
IH :
  (∀ p ∈ tl, natDegree p ≤ n) → coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ p ∈ hd :: tl, natDegree p ≤ n
hl' : ∀ p ∈ tl, natDegree p ≤ n
⊢ List.sum (List.map natDegree tl) ≤ n * List.length tl

Next tactic:
rw [← tl.length_map natDegree, mul_comm]
theorem coeff_list_prod_of_natDegree_le (l : List S[X]) (n : ℕ) (hl : ∀ p ∈ l, natDegree p ≤ n) :
    coeff (List.prod l) (l.length * n) = (l.map fun p => coeff p n).prod := by
  induction' l with hd tl IH
  · simp
  · have hl' : ∀ p ∈ tl, natDegree p ≤ n := fun p hp => hl p (List.mem_cons_of_mem _ hp)
    simp only [List.prod_cons, List.map, List.length]
    rw [add_mul, one_mul, add_comm, ← IH hl', mul_comm tl.length]
    have h : natDegree tl.prod ≤ n * tl.length := by
      refine' (natDegree_list_prod_le _).trans _
      rw [← tl.length_map natDegree, mul_comm]
      

Proof state:
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
n : ℕ
hd : S[X]
tl : List S[X]
IH :
  (∀ p ∈ tl, natDegree p ≤ n) → coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ p ∈ hd :: tl, natDegree p ≤ n
hl' : ∀ p ∈ tl, natDegree p ≤ n
⊢ List.sum (List.map natDegree tl) ≤ List.length (List.map natDegree tl) * n

Next tactic:
refine' List.sum_le_card_nsmul _ _ _
theorem coeff_list_prod_of_natDegree_le (l : List S[X]) (n : ℕ) (hl : ∀ p ∈ l, natDegree p ≤ n) :
    coeff (List.prod l) (l.length * n) = (l.map fun p => coeff p n).prod := by
  induction' l with hd tl IH
  · simp
  · have hl' : ∀ p ∈ tl, natDegree p ≤ n := fun p hp => hl p (List.mem_cons_of_mem _ hp)
    simp only [List.prod_cons, List.map, List.length]
    rw [add_mul, one_mul, add_comm, ← IH hl', mul_comm tl.length]
    have h : natDegree tl.prod ≤ n * tl.length := by
      refine' (natDegree_list_prod_le _).trans _
      rw [← tl.length_map natDegree, mul_comm]
      refine' List.sum_le_card_nsmul _ _ _
      

Proof state:
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
n : ℕ
hd : S[X]
tl : List S[X]
IH :
  (∀ p ∈ tl, natDegree p ≤ n) → coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ p ∈ hd :: tl, natDegree p ≤ n
hl' : ∀ p ∈ tl, natDegree p ≤ n
⊢ ∀ x ∈ List.map natDegree tl, x ≤ n

Next tactic:
simpa using hl'
theorem coeff_list_prod_of_natDegree_le (l : List S[X]) (n : ℕ) (hl : ∀ p ∈ l, natDegree p ≤ n) :
    coeff (List.prod l) (l.length * n) = (l.map fun p => coeff p n).prod := by
  induction' l with hd tl IH
  · simp
  · have hl' : ∀ p ∈ tl, natDegree p ≤ n := fun p hp => hl p (List.mem_cons_of_mem _ hp)
    simp only [List.prod_cons, List.map, List.length]
    rw [add_mul, one_mul, add_comm, ← IH hl', mul_comm tl.length]
    have h : natDegree tl.prod ≤ n * tl.length := by
      refine' (natDegree_list_prod_le _).trans _
      rw [← tl.length_map natDegree, mul_comm]
      refine' List.sum_le_card_nsmul _ _ _
      simpa using hl'
    

Proof state:
case cons
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
n : ℕ
hd : S[X]
tl : List S[X]
IH :
  (∀ p ∈ tl, natDegree p ≤ n) → coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ p ∈ hd :: tl, natDegree p ≤ n
hl' : ∀ p ∈ tl, natDegree p ≤ n
h : natDegree (List.prod tl) ≤ n * List.length tl
⊢ coeff (hd * List.prod tl) (n + n * List.length tl) = coeff hd n * coeff (List.prod tl) (n * List.length tl)

Next tactic:
have hdn : natDegree hd ≤ n := hl _ (List.mem_cons_self _ _)
theorem coeff_list_prod_of_natDegree_le (l : List S[X]) (n : ℕ) (hl : ∀ p ∈ l, natDegree p ≤ n) :
    coeff (List.prod l) (l.length * n) = (l.map fun p => coeff p n).prod := by
  induction' l with hd tl IH
  · simp
  · have hl' : ∀ p ∈ tl, natDegree p ≤ n := fun p hp => hl p (List.mem_cons_of_mem _ hp)
    simp only [List.prod_cons, List.map, List.length]
    rw [add_mul, one_mul, add_comm, ← IH hl', mul_comm tl.length]
    have h : natDegree tl.prod ≤ n * tl.length := by
      refine' (natDegree_list_prod_le _).trans _
      rw [← tl.length_map natDegree, mul_comm]
      refine' List.sum_le_card_nsmul _ _ _
      simpa using hl'
    have hdn : natDegree hd ≤ n := hl _ (List.mem_cons_self _ _)
    

Proof state:
case cons
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
n : ℕ
hd : S[X]
tl : List S[X]
IH :
  (∀ p ∈ tl, natDegree p ≤ n) → coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ p ∈ hd :: tl, natDegree p ≤ n
hl' : ∀ p ∈ tl, natDegree p ≤ n
h : natDegree (List.prod tl) ≤ n * List.length tl
hdn : natDegree hd ≤ n
⊢ coeff (hd * List.prod tl) (n + n * List.length tl) = coeff hd n * coeff (List.prod tl) (n * List.length tl)

Next tactic:
rcases hdn.eq_or_lt with (rfl | hdn')
theorem coeff_list_prod_of_natDegree_le (l : List S[X]) (n : ℕ) (hl : ∀ p ∈ l, natDegree p ≤ n) :
    coeff (List.prod l) (l.length * n) = (l.map fun p => coeff p n).prod := by
  induction' l with hd tl IH
  · simp
  · have hl' : ∀ p ∈ tl, natDegree p ≤ n := fun p hp => hl p (List.mem_cons_of_mem _ hp)
    simp only [List.prod_cons, List.map, List.length]
    rw [add_mul, one_mul, add_comm, ← IH hl', mul_comm tl.length]
    have h : natDegree tl.prod ≤ n * tl.length := by
      refine' (natDegree_list_prod_le _).trans _
      rw [← tl.length_map natDegree, mul_comm]
      refine' List.sum_le_card_nsmul _ _ _
      simpa using hl'
    have hdn : natDegree hd ≤ n := hl _ (List.mem_cons_self _ _)
    rcases hdn.eq_or_lt with (rfl | hdn')
    · 

Proof state:
case cons.inl
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
hd : S[X]
tl : List S[X]
IH :
  (∀ p ∈ tl, natDegree p ≤ natDegree hd) →
    coeff (List.prod tl) (List.length tl * natDegree hd) = List.prod (List.map (fun p => coeff p (natDegree hd)) tl)
hl : ∀ p ∈ hd :: tl, natDegree p ≤ natDegree hd
hl' : ∀ p ∈ tl, natDegree p ≤ natDegree hd
h : natDegree (List.prod tl) ≤ natDegree hd * List.length tl
hdn : natDegree hd ≤ natDegree hd
⊢ coeff (hd * List.prod tl) (natDegree hd + natDegree hd * List.length tl) =
    coeff hd (natDegree hd) * coeff (List.prod tl) (natDegree hd * List.length tl)

Next tactic:
rcases h.eq_or_lt with h' | h'
theorem coeff_list_prod_of_natDegree_le (l : List S[X]) (n : ℕ) (hl : ∀ p ∈ l, natDegree p ≤ n) :
    coeff (List.prod l) (l.length * n) = (l.map fun p => coeff p n).prod := by
  induction' l with hd tl IH
  · simp
  · have hl' : ∀ p ∈ tl, natDegree p ≤ n := fun p hp => hl p (List.mem_cons_of_mem _ hp)
    simp only [List.prod_cons, List.map, List.length]
    rw [add_mul, one_mul, add_comm, ← IH hl', mul_comm tl.length]
    have h : natDegree tl.prod ≤ n * tl.length := by
      refine' (natDegree_list_prod_le _).trans _
      rw [← tl.length_map natDegree, mul_comm]
      refine' List.sum_le_card_nsmul _ _ _
      simpa using hl'
    have hdn : natDegree hd ≤ n := hl _ (List.mem_cons_self _ _)
    rcases hdn.eq_or_lt with (rfl | hdn')
    · rcases h.eq_or_lt with h' | h'
      · 

Proof state:
case cons.inl.inl
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
hd : S[X]
tl : List S[X]
IH :
  (∀ p ∈ tl, natDegree p ≤ natDegree hd) →
    coeff (List.prod tl) (List.length tl * natDegree hd) = List.prod (List.map (fun p => coeff p (natDegree hd)) tl)
hl : ∀ p ∈ hd :: tl, natDegree p ≤ natDegree hd
hl' : ∀ p ∈ tl, natDegree p ≤ natDegree hd
h : natDegree (List.prod tl) ≤ natDegree hd * List.length tl
hdn : natDegree hd ≤ natDegree hd
h' : natDegree (List.prod tl) = natDegree hd * List.length tl
⊢ coeff (hd * List.prod tl) (natDegree hd + natDegree hd * List.length tl) =
    coeff hd (natDegree hd) * coeff (List.prod tl) (natDegree hd * List.length tl)

Next tactic:
rw [← h', coeff_mul_degree_add_degree, leadingCoeff, leadingCoeff]
theorem coeff_list_prod_of_natDegree_le (l : List S[X]) (n : ℕ) (hl : ∀ p ∈ l, natDegree p ≤ n) :
    coeff (List.prod l) (l.length * n) = (l.map fun p => coeff p n).prod := by
  induction' l with hd tl IH
  · simp
  · have hl' : ∀ p ∈ tl, natDegree p ≤ n := fun p hp => hl p (List.mem_cons_of_mem _ hp)
    simp only [List.prod_cons, List.map, List.length]
    rw [add_mul, one_mul, add_comm, ← IH hl', mul_comm tl.length]
    have h : natDegree tl.prod ≤ n * tl.length := by
      refine' (natDegree_list_prod_le _).trans _
      rw [← tl.length_map natDegree, mul_comm]
      refine' List.sum_le_card_nsmul _ _ _
      simpa using hl'
    have hdn : natDegree hd ≤ n := hl _ (List.mem_cons_self _ _)
    rcases hdn.eq_or_lt with (rfl | hdn')
    · rcases h.eq_or_lt with h' | h'
      · rw [← h', coeff_mul_degree_add_degree, leadingCoeff, leadingCoeff]
      · 

Proof state:
case cons.inl.inr
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
hd : S[X]
tl : List S[X]
IH :
  (∀ p ∈ tl, natDegree p ≤ natDegree hd) →
    coeff (List.prod tl) (List.length tl * natDegree hd) = List.prod (List.map (fun p => coeff p (natDegree hd)) tl)
hl : ∀ p ∈ hd :: tl, natDegree p ≤ natDegree hd
hl' : ∀ p ∈ tl, natDegree p ≤ natDegree hd
h : natDegree (List.prod tl) ≤ natDegree hd * List.length tl
hdn : natDegree hd ≤ natDegree hd
h' : natDegree (List.prod tl) < natDegree hd * List.length tl
⊢ coeff (hd * List.prod tl) (natDegree hd + natDegree hd * List.length tl) =
    coeff hd (natDegree hd) * coeff (List.prod tl) (natDegree hd * List.length tl)

Next tactic:
rw [coeff_eq_zero_of_natDegree_lt, coeff_eq_zero_of_natDegree_lt h', mul_zero]
theorem coeff_list_prod_of_natDegree_le (l : List S[X]) (n : ℕ) (hl : ∀ p ∈ l, natDegree p ≤ n) :
    coeff (List.prod l) (l.length * n) = (l.map fun p => coeff p n).prod := by
  induction' l with hd tl IH
  · simp
  · have hl' : ∀ p ∈ tl, natDegree p ≤ n := fun p hp => hl p (List.mem_cons_of_mem _ hp)
    simp only [List.prod_cons, List.map, List.length]
    rw [add_mul, one_mul, add_comm, ← IH hl', mul_comm tl.length]
    have h : natDegree tl.prod ≤ n * tl.length := by
      refine' (natDegree_list_prod_le _).trans _
      rw [← tl.length_map natDegree, mul_comm]
      refine' List.sum_le_card_nsmul _ _ _
      simpa using hl'
    have hdn : natDegree hd ≤ n := hl _ (List.mem_cons_self _ _)
    rcases hdn.eq_or_lt with (rfl | hdn')
    · rcases h.eq_or_lt with h' | h'
      · rw [← h', coeff_mul_degree_add_degree, leadingCoeff, leadingCoeff]
      · rw [coeff_eq_zero_of_natDegree_lt, coeff_eq_zero_of_natDegree_lt h', mul_zero]
        

Proof state:
case cons.inl.inr
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
hd : S[X]
tl : List S[X]
IH :
  (∀ p ∈ tl, natDegree p ≤ natDegree hd) →
    coeff (List.prod tl) (List.length tl * natDegree hd) = List.prod (List.map (fun p => coeff p (natDegree hd)) tl)
hl : ∀ p ∈ hd :: tl, natDegree p ≤ natDegree hd
hl' : ∀ p ∈ tl, natDegree p ≤ natDegree hd
h : natDegree (List.prod tl) ≤ natDegree hd * List.length tl
hdn : natDegree hd ≤ natDegree hd
h' : natDegree (List.prod tl) < natDegree hd * List.length tl
⊢ natDegree (hd * List.prod tl) < natDegree hd + natDegree hd * List.length tl

Next tactic:
exact natDegree_mul_le.trans_lt (add_lt_add_left h' _)
theorem coeff_list_prod_of_natDegree_le (l : List S[X]) (n : ℕ) (hl : ∀ p ∈ l, natDegree p ≤ n) :
    coeff (List.prod l) (l.length * n) = (l.map fun p => coeff p n).prod := by
  induction' l with hd tl IH
  · simp
  · have hl' : ∀ p ∈ tl, natDegree p ≤ n := fun p hp => hl p (List.mem_cons_of_mem _ hp)
    simp only [List.prod_cons, List.map, List.length]
    rw [add_mul, one_mul, add_comm, ← IH hl', mul_comm tl.length]
    have h : natDegree tl.prod ≤ n * tl.length := by
      refine' (natDegree_list_prod_le _).trans _
      rw [← tl.length_map natDegree, mul_comm]
      refine' List.sum_le_card_nsmul _ _ _
      simpa using hl'
    have hdn : natDegree hd ≤ n := hl _ (List.mem_cons_self _ _)
    rcases hdn.eq_or_lt with (rfl | hdn')
    · rcases h.eq_or_lt with h' | h'
      · rw [← h', coeff_mul_degree_add_degree, leadingCoeff, leadingCoeff]
      · rw [coeff_eq_zero_of_natDegree_lt, coeff_eq_zero_of_natDegree_lt h', mul_zero]
        exact natDegree_mul_le.trans_lt (add_lt_add_left h' _)
    · 

Proof state:
case cons.inr
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
n : ℕ
hd : S[X]
tl : List S[X]
IH :
  (∀ p ∈ tl, natDegree p ≤ n) → coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ p ∈ hd :: tl, natDegree p ≤ n
hl' : ∀ p ∈ tl, natDegree p ≤ n
h : natDegree (List.prod tl) ≤ n * List.length tl
hdn : natDegree hd ≤ n
hdn' : natDegree hd < n
⊢ coeff (hd * List.prod tl) (n + n * List.length tl) = coeff hd n * coeff (List.prod tl) (n * List.length tl)

Next tactic:
rw [coeff_eq_zero_of_natDegree_lt hdn', coeff_eq_zero_of_natDegree_lt, zero_mul]
theorem coeff_list_prod_of_natDegree_le (l : List S[X]) (n : ℕ) (hl : ∀ p ∈ l, natDegree p ≤ n) :
    coeff (List.prod l) (l.length * n) = (l.map fun p => coeff p n).prod := by
  induction' l with hd tl IH
  · simp
  · have hl' : ∀ p ∈ tl, natDegree p ≤ n := fun p hp => hl p (List.mem_cons_of_mem _ hp)
    simp only [List.prod_cons, List.map, List.length]
    rw [add_mul, one_mul, add_comm, ← IH hl', mul_comm tl.length]
    have h : natDegree tl.prod ≤ n * tl.length := by
      refine' (natDegree_list_prod_le _).trans _
      rw [← tl.length_map natDegree, mul_comm]
      refine' List.sum_le_card_nsmul _ _ _
      simpa using hl'
    have hdn : natDegree hd ≤ n := hl _ (List.mem_cons_self _ _)
    rcases hdn.eq_or_lt with (rfl | hdn')
    · rcases h.eq_or_lt with h' | h'
      · rw [← h', coeff_mul_degree_add_degree, leadingCoeff, leadingCoeff]
      · rw [coeff_eq_zero_of_natDegree_lt, coeff_eq_zero_of_natDegree_lt h', mul_zero]
        exact natDegree_mul_le.trans_lt (add_lt_add_left h' _)
    · rw [coeff_eq_zero_of_natDegree_lt hdn', coeff_eq_zero_of_natDegree_lt, zero_mul]
      

Proof state:
case cons.inr
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
n : ℕ
hd : S[X]
tl : List S[X]
IH :
  (∀ p ∈ tl, natDegree p ≤ n) → coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ p ∈ hd :: tl, natDegree p ≤ n
hl' : ∀ p ∈ tl, natDegree p ≤ n
h : natDegree (List.prod tl) ≤ n * List.length tl
hdn : natDegree hd ≤ n
hdn' : natDegree hd < n
⊢ natDegree (hd * List.prod tl) < n + n * List.length tl

Next tactic:
exact natDegree_mul_le.trans_lt (add_lt_add_of_lt_of_le hdn' h)
theorem natDegree_multiset_prod_le : t.prod.natDegree ≤ (t.map natDegree).sum :=
  Quotient.inductionOn t (by 

Proof state:
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
⊢ ∀ (a : List R[X]), natDegree (prod ⟦a⟧) ≤ Multiset.sum (Multiset.map natDegree ⟦a⟧)

Next tactic:
simpa using natDegree_list_prod_le
theorem natDegree_prod_le : (∏ 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]
⊢ natDegree (∏ i in s, f i) ≤ ∑ i in s, natDegree (f i)

Next tactic:
simpa using natDegree_multiset_prod_le (s.1.map f)
/-- The degree of a product of polynomials is at most the sum of the degrees,
where the degree of the zero polynomial is ⊥.
-/
theorem degree_multiset_prod_le : t.prod.degree ≤ (t.map Polynomial.degree).sum :=
  Quotient.inductionOn t (by 

Proof state:
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
⊢ ∀ (a : List R[X]), degree (prod ⟦a⟧) ≤ Multiset.sum (Multiset.map degree ⟦a⟧)

Next tactic:
simpa using degree_list_prod_le
theorem degree_prod_le : (∏ i in s, f i).degree ≤ ∑ i in s, (f i).degree := by
  

Proof state:
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
⊢ degree (∏ i in s, f i) ≤ ∑ i in s, degree (f i)

Next tactic:
simpa only [Multiset.map_map] using degree_multiset_prod_le (s.1.map f)
/-- 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
  

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

Next tactic:
induction' t using Multiset.induction_on with a t ih
/-- 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; · 

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

Next tactic:
simp
/-- 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
  

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 : prod (Multiset.map leadingCoeff (a ::ₘ t)) ≠ 0
⊢ leadingCoeff (prod (a ::ₘ t)) = prod (Multiset.map leadingCoeff (a ::ₘ t))

Next tactic:
simp only [Multiset.map_cons, Multiset.prod_cons] at 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 ⊢
  

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 t) = leadingCoeff a * prod (Multiset.map leadingCoeff t)

Next tactic:
rw [Polynomial.leadingCoeff_mul']
/-- 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']
  · 

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 * leadingCoeff (prod t) = leadingCoeff a * prod (Multiset.map leadingCoeff t)

Next tactic:
rw [ih]
/-- 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]
    

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]
/-- 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]
    

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_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
  · 

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 * leadingCoeff (prod t) ≠ 0

Next tactic:
rw [ih]