l3lab/ntp-mathlib huggingface dataset:
/-- In a well-founded lattice, any element is the supremum of finitely many sup-irreducible
elements. This is the order-theoretic analogue of prime factorisation. -/
theorem exists_supIrred_decomposition (a : α) :
    ∃ s : Finset α, s.sup id = a ∧ ∀ ⦃b⦄, b ∈ s → SupIrred b := by
  classical
  apply WellFoundedLT.induction a _
  clear a
  rintro a ih
  by_cases ha : SupIrred a
  · exact ⟨{a}, by simp [ha]⟩
  

Proof state:
case neg
ι : Type u_1
α : Type u_2
inst✝² : SemilatticeSup α
a✝ b c : α
inst✝¹ : OrderBot α
s : Finset ι
f : ι → α
inst✝ : WellFoundedLT α
a : α
ih : ∀ y < a, ∃ s, sup s id = y ∧ ∀ ⦃b : α⦄, b ∈ s → SupIrred b
ha : ¬SupIrred a
⊢ ∃ s, sup s id = a ∧ ∀ ⦃b : α⦄, b ∈ s → SupIrred b

Next tactic:
rw [not_supIrred] at ha
/-- In a well-founded lattice, any element is the supremum of finitely many sup-irreducible
elements. This is the order-theoretic analogue of prime factorisation. -/
theorem exists_supIrred_decomposition (a : α) :
    ∃ s : Finset α, s.sup id = a ∧ ∀ ⦃b⦄, b ∈ s → SupIrred b := by
  classical
  apply WellFoundedLT.induction a _
  clear a
  rintro a ih
  by_cases ha : SupIrred a
  · exact ⟨{a}, by simp [ha]⟩
  rw [not_supIrred] at ha
  

Proof state:
case neg
ι : Type u_1
α : Type u_2
inst✝² : SemilatticeSup α
a✝ b c : α
inst✝¹ : OrderBot α
s : Finset ι
f : ι → α
inst✝ : WellFoundedLT α
a : α
ih : ∀ y < a, ∃ s, sup s id = y ∧ ∀ ⦃b : α⦄, b ∈ s → SupIrred b
ha : IsMin a ∨ ∃ b c, b ⊔ c = a ∧ b < a ∧ c < a
⊢ ∃ s, sup s id = a ∧ ∀ ⦃b : α⦄, b ∈ s → SupIrred b

Next tactic:
obtain ha | ⟨b, c, rfl, hb, hc⟩ := ha
/-- In a well-founded lattice, any element is the supremum of finitely many sup-irreducible
elements. This is the order-theoretic analogue of prime factorisation. -/
theorem exists_supIrred_decomposition (a : α) :
    ∃ s : Finset α, s.sup id = a ∧ ∀ ⦃b⦄, b ∈ s → SupIrred b := by
  classical
  apply WellFoundedLT.induction a _
  clear a
  rintro a ih
  by_cases ha : SupIrred a
  · exact ⟨{a}, by simp [ha]⟩
  rw [not_supIrred] at ha
  obtain ha | ⟨b, c, rfl, hb, hc⟩ := ha
  · 

Proof state:
case neg.inl
ι : Type u_1
α : Type u_2
inst✝² : SemilatticeSup α
a✝ b c : α
inst✝¹ : OrderBot α
s : Finset ι
f : ι → α
inst✝ : WellFoundedLT α
a : α
ih : ∀ y < a, ∃ s, sup s id = y ∧ ∀ ⦃b : α⦄, b ∈ s → SupIrred b
ha : IsMin a
⊢ ∃ s, sup s id = a ∧ ∀ ⦃b : α⦄, b ∈ s → SupIrred b

Next tactic:
exact ⟨∅, by simp [ha.eq_bot]⟩
/-- In a well-founded lattice, any element is the supremum of finitely many sup-irreducible
elements. This is the order-theoretic analogue of prime factorisation. -/
theorem exists_supIrred_decomposition (a : α) :
    ∃ s : Finset α, s.sup id = a ∧ ∀ ⦃b⦄, b ∈ s → SupIrred b := by
  classical
  apply WellFoundedLT.induction a _
  clear a
  rintro a ih
  by_cases ha : SupIrred a
  · exact ⟨{a}, by simp [ha]⟩
  rw [not_supIrred] at ha
  obtain ha | ⟨b, c, rfl, hb, hc⟩ := ha
  · exact ⟨∅, by 

Proof state:
ι : Type u_1
α : Type u_2
inst✝² : SemilatticeSup α
a✝ b c : α
inst✝¹ : OrderBot α
s : Finset ι
f : ι → α
inst✝ : WellFoundedLT α
a : α
ih : ∀ y < a, ∃ s, sup s id = y ∧ ∀ ⦃b : α⦄, b ∈ s → SupIrred b
ha : IsMin a
⊢ sup ∅ id = a ∧ ∀ ⦃b : α⦄, b ∈ ∅ → SupIrred b

Next tactic:
simp [ha.eq_bot]
/-- In a well-founded lattice, any element is the supremum of finitely many sup-irreducible
elements. This is the order-theoretic analogue of prime factorisation. -/
theorem exists_supIrred_decomposition (a : α) :
    ∃ s : Finset α, s.sup id = a ∧ ∀ ⦃b⦄, b ∈ s → SupIrred b := by
  classical
  apply WellFoundedLT.induction a _
  clear a
  rintro a ih
  by_cases ha : SupIrred a
  · exact ⟨{a}, by simp [ha]⟩
  rw [not_supIrred] at ha
  obtain ha | ⟨b, c, rfl, hb, hc⟩ := ha
  · exact ⟨∅, by simp [ha.eq_bot]⟩
  

Proof state:
case neg.inr.intro.intro.intro.intro
ι : Type u_1
α : Type u_2
inst✝² : SemilatticeSup α
a b✝ c✝ : α
inst✝¹ : OrderBot α
s : Finset ι
f : ι → α
inst✝ : WellFoundedLT α
b c : α
ih : ∀ y < b ⊔ c, ∃ s, sup s id = y ∧ ∀ ⦃b : α⦄, b ∈ s → SupIrred b
hb : b < b ⊔ c
hc : c < b ⊔ c
⊢ ∃ s, sup s id = b ⊔ c ∧ ∀ ⦃b : α⦄, b ∈ s → SupIrred b

Next tactic:
obtain ⟨s, rfl, hs⟩ := ih _ hb
/-- In a well-founded lattice, any element is the supremum of finitely many sup-irreducible
elements. This is the order-theoretic analogue of prime factorisation. -/
theorem exists_supIrred_decomposition (a : α) :
    ∃ s : Finset α, s.sup id = a ∧ ∀ ⦃b⦄, b ∈ s → SupIrred b := by
  classical
  apply WellFoundedLT.induction a _
  clear a
  rintro a ih
  by_cases ha : SupIrred a
  · exact ⟨{a}, by simp [ha]⟩
  rw [not_supIrred] at ha
  obtain ha | ⟨b, c, rfl, hb, hc⟩ := ha
  · exact ⟨∅, by simp [ha.eq_bot]⟩
  obtain ⟨s, rfl, hs⟩ := ih _ hb
  

Proof state:
case neg.inr.intro.intro.intro.intro.intro.intro
ι : Type u_1
α : Type u_2
inst✝² : SemilatticeSup α
a b c✝ : α
inst✝¹ : OrderBot α
s✝ : Finset ι
f : ι → α
inst✝ : WellFoundedLT α
c : α
s : Finset α
hs : ∀ ⦃b : α⦄, b ∈ s → SupIrred b
ih : ∀ y < sup s id ⊔ c, ∃ s, sup s id = y ∧ ∀ ⦃b : α⦄, b ∈ s → SupIrred b
hb : sup s id < sup s id ⊔ c
hc : c < sup s id ⊔ c
⊢ ∃ s_1, sup s_1 id = sup s id ⊔ c ∧ ∀ ⦃b : α⦄, b ∈ s_1 → SupIrred b

Next tactic:
obtain ⟨t, rfl, ht⟩ := ih _ hc
/-- In a well-founded lattice, any element is the supremum of finitely many sup-irreducible
elements. This is the order-theoretic analogue of prime factorisation. -/
theorem exists_supIrred_decomposition (a : α) :
    ∃ s : Finset α, s.sup id = a ∧ ∀ ⦃b⦄, b ∈ s → SupIrred b := by
  classical
  apply WellFoundedLT.induction a _
  clear a
  rintro a ih
  by_cases ha : SupIrred a
  · exact ⟨{a}, by simp [ha]⟩
  rw [not_supIrred] at ha
  obtain ha | ⟨b, c, rfl, hb, hc⟩ := ha
  · exact ⟨∅, by simp [ha.eq_bot]⟩
  obtain ⟨s, rfl, hs⟩ := ih _ hb
  obtain ⟨t, rfl, ht⟩ := ih _ hc
  

Proof state:
case neg.inr.intro.intro.intro.intro.intro.intro.intro.intro
ι : Type u_1
α : Type u_2
inst✝² : SemilatticeSup α
a b c : α
inst✝¹ : OrderBot α
s✝ : Finset ι
f : ι → α
inst✝ : WellFoundedLT α
s : Finset α
hs : ∀ ⦃b : α⦄, b ∈ s → SupIrred b
t : Finset α
ht : ∀ ⦃b : α⦄, b ∈ t → SupIrred b
ih : ∀ y < sup s id ⊔ sup t id, ∃ s, sup s id = y ∧ ∀ ⦃b : α⦄, b ∈ s → SupIrred b
hb : sup s id < sup s id ⊔ sup t id
hc : sup t id < sup s id ⊔ sup t id
⊢ ∃ s_1, sup s_1 id = sup s id ⊔ sup t id ∧ ∀ ⦃b : α⦄, b ∈ s_1 → SupIrred b

Next tactic:
exact ⟨s ∪ t, sup_union, forall_mem_union.2 ⟨hs, ht⟩⟩
protected theorem InfPrime.infIrred : InfPrime a → InfIrred a :=
  And.imp_right fun h b c ha => by 

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : SemilatticeInf α
a b✝ c✝ : α
h : ∀ ⦃b c : α⦄, b ⊓ c ≤ a → b ≤ a ∨ c ≤ a
b c : α
ha : b ⊓ c = a
⊢ b = a ∨ c = a

Next tactic:
simpa [← ha] using h ha.le
theorem InfIrred.ne_top (ha : InfIrred a) : a ≠ ⊤ := by 

Proof state:
ι : Type u_1
α : Type u_2
inst✝¹ : SemilatticeInf α
a b c : α
inst✝ : OrderTop α
s : Finset ι
f : ι → α
ha : InfIrred a
⊢ a ≠ ⊤

Next tactic:
rintro rfl
theorem InfIrred.ne_top (ha : InfIrred a) : a ≠ ⊤ := by rintro rfl; 

Proof state:
ι : Type u_1
α : Type u_2
inst✝¹ : SemilatticeInf α
b c : α
inst✝ : OrderTop α
s : Finset ι
f : ι → α
ha : InfIrred ⊤
⊢ False

Next tactic:
exact not_infIrred_top ha
theorem InfPrime.ne_top (ha : InfPrime a) : a ≠ ⊤ := by 

Proof state:
ι : Type u_1
α : Type u_2
inst✝¹ : SemilatticeInf α
a b c : α
inst✝ : OrderTop α
s : Finset ι
f : ι → α
ha : InfPrime a
⊢ a ≠ ⊤

Next tactic:
rintro rfl
theorem InfPrime.ne_top (ha : InfPrime a) : a ≠ ⊤ := by rintro rfl; 

Proof state:
ι : Type u_1
α : Type u_2
inst✝¹ : SemilatticeInf α
b c : α
inst✝ : OrderTop α
s : Finset ι
f : ι → α
ha : InfPrime ⊤
⊢ False

Next tactic:
exact not_infPrime_top ha
@[simp]
theorem supPrime_iff_supIrred : SupPrime a ↔ SupIrred a :=
  ⟨SupPrime.supIrred,
    And.imp_right fun h b c => by 

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : DistribLattice α
a b✝ c✝ : α
h : ∀ ⦃b c : α⦄, b ⊔ c = a → b = a ∨ c = a
b c : α
⊢ a ≤ b ⊔ c → a ≤ b ∨ a ≤ c

Next tactic:
simp_rw [← inf_eq_left, inf_sup_left]
@[simp]
theorem supPrime_iff_supIrred : SupPrime a ↔ SupIrred a :=
  ⟨SupPrime.supIrred,
    And.imp_right fun h b c => by simp_rw [← inf_eq_left, inf_sup_left]; 

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : DistribLattice α
a b✝ c✝ : α
h : ∀ ⦃b c : α⦄, b ⊔ c = a → b = a ∨ c = a
b c : α
⊢ a ⊓ b ⊔ a ⊓ c = a → a ⊓ b = a ∨ a ⊓ c = a

Next tactic:
exact @h _ _
@[simp]
theorem infPrime_iff_infIrred : InfPrime a ↔ InfIrred a :=
  ⟨InfPrime.infIrred,
    And.imp_right fun h b c => by 

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : DistribLattice α
a b✝ c✝ : α
h : ∀ ⦃b c : α⦄, b ⊓ c = a → b = a ∨ c = a
b c : α
⊢ b ⊓ c ≤ a → b ≤ a ∨ c ≤ a

Next tactic:
simp_rw [← sup_eq_left, sup_inf_left]
@[simp]
theorem infPrime_iff_infIrred : InfPrime a ↔ InfIrred a :=
  ⟨InfPrime.infIrred,
    And.imp_right fun h b c => by simp_rw [← sup_eq_left, sup_inf_left]; 

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : DistribLattice α
a b✝ c✝ : α
h : ∀ ⦃b c : α⦄, b ⊓ c = a → b = a ∨ c = a
b c : α
⊢ (a ⊔ b) ⊓ (a ⊔ c) = a → a ⊔ b = a ∨ a ⊔ c = a

Next tactic:
exact @h _ _
theorem supPrime_iff_not_isMin : SupPrime a ↔ ¬IsMin a :=
  and_iff_left <| by 

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : LinearOrder α
a : α
⊢ ∀ ⦃b c : α⦄, a ≤ b ⊔ c → a ≤ b ∨ a ≤ c

Next tactic:
simp
theorem infPrime_iff_not_isMax : InfPrime a ↔ ¬IsMax a :=
  and_iff_left <| by 

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : LinearOrder α
a : α
⊢ ∀ ⦃b c : α⦄, b ⊓ c ≤ a → b ≤ a ∨ c ≤ a

Next tactic:
simp
@[simp]
theorem supIrred_iff_not_isMin : SupIrred a ↔ ¬IsMin a :=
  and_iff_left fun _ _ => by 

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : LinearOrder α
a x✝¹ x✝ : α
⊢ x✝¹ ⊔ x✝ = a → x✝¹ = a ∨ x✝ = a

Next tactic:
simpa only [sup_eq_max, max_eq_iff] using Or.imp And.left And.left
@[simp]
theorem infIrred_iff_not_isMax : InfIrred a ↔ ¬IsMax a :=
  and_iff_left fun _ _ => by 

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : LinearOrder α
a x✝¹ x✝ : α
⊢ x✝¹ ⊓ x✝ = a → x✝¹ = a ∨ x✝ = a

Next tactic:
simpa only [inf_eq_min, min_eq_iff] using Or.imp And.left And.left
theorem modByMonic_eq_of_dvd_sub (hq : q.Monic) {p₁ p₂ : R[X]} (h : q ∣ p₁ - p₂) :
    p₁ %ₘ q = p₂ %ₘ q := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
p q : R[X]
inst✝ : Semiring S
hq : Monic q
p₁ p₂ : R[X]
h : q ∣ p₁ - p₂
⊢ p₁ %ₘ q = p₂ %ₘ q

Next tactic:
nontriviality R
theorem modByMonic_eq_of_dvd_sub (hq : q.Monic) {p₁ p₂ : R[X]} (h : q ∣ p₁ - p₂) :
    p₁ %ₘ q = p₂ %ₘ q := by
  nontriviality R
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
p q : R[X]
inst✝ : Semiring S
hq : Monic q
p₁ p₂ : R[X]
h : q ∣ p₁ - p₂
✝ : Nontrivial R
⊢ p₁ %ₘ q = p₂ %ₘ q

Next tactic:
obtain ⟨f, sub_eq⟩ := h
theorem modByMonic_eq_of_dvd_sub (hq : q.Monic) {p₁ p₂ : R[X]} (h : q ∣ p₁ - p₂) :
    p₁ %ₘ q = p₂ %ₘ q := by
  nontriviality R
  obtain ⟨f, sub_eq⟩ := h
  

Proof state:
case intro
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
p q : R[X]
inst✝ : Semiring S
hq : Monic q
p₁ p₂ : R[X]
✝ : Nontrivial R
f : R[X]
sub_eq : p₁ - p₂ = q * f
⊢ p₁ %ₘ q = p₂ %ₘ q

Next tactic:
refine' (div_modByMonic_unique (p₂ /ₘ q + f) _ hq ⟨_, degree_modByMonic_lt _ hq⟩).2
theorem modByMonic_eq_of_dvd_sub (hq : q.Monic) {p₁ p₂ : R[X]} (h : q ∣ p₁ - p₂) :
    p₁ %ₘ q = p₂ %ₘ q := by
  nontriviality R
  obtain ⟨f, sub_eq⟩ := h
  refine' (div_modByMonic_unique (p₂ /ₘ q + f) _ hq ⟨_, degree_modByMonic_lt _ hq⟩).2
  

Proof state:
case intro
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
p q : R[X]
inst✝ : Semiring S
hq : Monic q
p₁ p₂ : R[X]
✝ : Nontrivial R
f : R[X]
sub_eq : p₁ - p₂ = q * f
⊢ p₂ %ₘ q + q * (p₂ /ₘ q + f) = p₁

Next tactic:
rw [sub_eq_iff_eq_add.mp sub_eq, mul_add, ← add_assoc, modByMonic_add_div _ hq, add_comm]
theorem add_modByMonic (p₁ p₂ : R[X]) : (p₁ + p₂) %ₘ q = p₁ %ₘ q + p₂ %ₘ q := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
p q : R[X]
inst✝ : Semiring S
p₁ p₂ : R[X]
⊢ (p₁ + p₂) %ₘ q = p₁ %ₘ q + p₂ %ₘ q

Next tactic:
by_cases hq : q.Monic
theorem add_modByMonic (p₁ p₂ : R[X]) : (p₁ + p₂) %ₘ q = p₁ %ₘ q + p₂ %ₘ q := by
  by_cases hq : q.Monic
  · 

Proof state:
case pos
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
p q : R[X]
inst✝ : Semiring S
p₁ p₂ : R[X]
hq : Monic q
⊢ (p₁ + p₂) %ₘ q = p₁ %ₘ q + p₂ %ₘ q

Next tactic:
cases' subsingleton_or_nontrivial R with hR hR
theorem add_modByMonic (p₁ p₂ : R[X]) : (p₁ + p₂) %ₘ q = p₁ %ₘ q + p₂ %ₘ q := by
  by_cases hq : q.Monic
  · cases' subsingleton_or_nontrivial R with hR hR
    · 

Proof state:
case pos.inl
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
p q : R[X]
inst✝ : Semiring S
p₁ p₂ : R[X]
hq : Monic q
hR : Subsingleton R
⊢ (p₁ + p₂) %ₘ q = p₁ %ₘ q + p₂ %ₘ q

Next tactic:
simp only [eq_iff_true_of_subsingleton]
theorem add_modByMonic (p₁ p₂ : R[X]) : (p₁ + p₂) %ₘ q = p₁ %ₘ q + p₂ %ₘ q := by
  by_cases hq : q.Monic
  · cases' subsingleton_or_nontrivial R with hR hR
    · simp only [eq_iff_true_of_subsingleton]
    · 

Proof state:
case pos.inr
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
p q : R[X]
inst✝ : Semiring S
p₁ p₂ : R[X]
hq : Monic q
hR : Nontrivial R
⊢ (p₁ + p₂) %ₘ q = p₁ %ₘ q + p₂ %ₘ q

Next tactic:
exact
      (div_modByMonic_unique (p₁ /ₘ q + p₂ /ₘ q) _ hq
          ⟨by
            rw [mul_add, add_left_comm, add_assoc, modByMonic_add_div _ hq, ← add_assoc,
              add_comm (q * _), modByMonic_add_div _ hq],
            (degree_add_le _ _).trans_lt
              (max_lt (degree_modByMonic_lt _ hq) (degree_modByMonic_lt _ hq))⟩).2
theorem add_modByMonic (p₁ p₂ : R[X]) : (p₁ + p₂) %ₘ q = p₁ %ₘ q + p₂ %ₘ q := by
  by_cases hq : q.Monic
  · cases' subsingleton_or_nontrivial R with hR hR
    · simp only [eq_iff_true_of_subsingleton]
    · exact
      (div_modByMonic_unique (p₁ /ₘ q + p₂ /ₘ q) _ hq
          ⟨by
            

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
p q : R[X]
inst✝ : Semiring S
p₁ p₂ : R[X]
hq : Monic q
hR : Nontrivial R
⊢ p₁ %ₘ q + p₂ %ₘ q + q * (p₁ /ₘ q + p₂ /ₘ q) = p₁ + p₂

Next tactic:
rw [mul_add, add_left_comm, add_assoc, modByMonic_add_div _ hq, ← add_assoc,
              add_comm (q * _), modByMonic_add_div _ hq]
theorem add_modByMonic (p₁ p₂ : R[X]) : (p₁ + p₂) %ₘ q = p₁ %ₘ q + p₂ %ₘ q := by
  by_cases hq : q.Monic
  · cases' subsingleton_or_nontrivial R with hR hR
    · simp only [eq_iff_true_of_subsingleton]
    · exact
      (div_modByMonic_unique (p₁ /ₘ q + p₂ /ₘ q) _ hq
          ⟨by
            rw [mul_add, add_left_comm, add_assoc, modByMonic_add_div _ hq, ← add_assoc,
              add_comm (q * _), modByMonic_add_div _ hq],
            (degree_add_le _ _).trans_lt
              (max_lt (degree_modByMonic_lt _ hq) (degree_modByMonic_lt _ hq))⟩).2
  · 

Proof state:
case neg
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
p q : R[X]
inst✝ : Semiring S
p₁ p₂ : R[X]
hq : ¬Monic q
⊢ (p₁ + p₂) %ₘ q = p₁ %ₘ q + p₂ %ₘ q

Next tactic:
simp_rw [modByMonic_eq_of_not_monic _ hq]
theorem smul_modByMonic (c : R) (p : R[X]) : c • p %ₘ q = c • (p %ₘ q) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
p✝ q : R[X]
inst✝ : Semiring S
c : R
p : R[X]
⊢ c • p %ₘ q = c • (p %ₘ q)

Next tactic:
by_cases hq : q.Monic
theorem smul_modByMonic (c : R) (p : R[X]) : c • p %ₘ q = c • (p %ₘ q) := by
  by_cases hq : q.Monic
  · 

Proof state:
case pos
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
p✝ q : R[X]
inst✝ : Semiring S
c : R
p : R[X]
hq : Monic q
⊢ c • p %ₘ q = c • (p %ₘ q)

Next tactic:
cases' subsingleton_or_nontrivial R with hR hR
theorem smul_modByMonic (c : R) (p : R[X]) : c • p %ₘ q = c • (p %ₘ q) := by
  by_cases hq : q.Monic
  · cases' subsingleton_or_nontrivial R with hR hR
    · 

Proof state:
case pos.inl
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
p✝ q : R[X]
inst✝ : Semiring S
c : R
p : R[X]
hq : Monic q
hR : Subsingleton R
⊢ c • p %ₘ q = c • (p %ₘ q)

Next tactic:
simp only [eq_iff_true_of_subsingleton]
theorem smul_modByMonic (c : R) (p : R[X]) : c • p %ₘ q = c • (p %ₘ q) := by
  by_cases hq : q.Monic
  · cases' subsingleton_or_nontrivial R with hR hR
    · simp only [eq_iff_true_of_subsingleton]
    · 

Proof state:
case pos.inr
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
p✝ q : R[X]
inst✝ : Semiring S
c : R
p : R[X]
hq : Monic q
hR : Nontrivial R
⊢ c • p %ₘ q = c • (p %ₘ q)

Next tactic:
exact
      (div_modByMonic_unique (c • (p /ₘ q)) (c • (p %ₘ q)) hq
          ⟨by rw [mul_smul_comm, ← smul_add, modByMonic_add_div p hq],
            (degree_smul_le _ _).trans_lt (degree_modByMonic_lt _ hq)⟩).2
theorem smul_modByMonic (c : R) (p : R[X]) : c • p %ₘ q = c • (p %ₘ q) := by
  by_cases hq : q.Monic
  · cases' subsingleton_or_nontrivial R with hR hR
    · simp only [eq_iff_true_of_subsingleton]
    · exact
      (div_modByMonic_unique (c • (p /ₘ q)) (c • (p %ₘ q)) hq
          ⟨by 

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
p✝ q : R[X]
inst✝ : Semiring S
c : R
p : R[X]
hq : Monic q
hR : Nontrivial R
⊢ c • (p %ₘ q) + q * c • (p /ₘ q) = c • p

Next tactic:
rw [mul_smul_comm, ← smul_add, modByMonic_add_div p hq]
theorem smul_modByMonic (c : R) (p : R[X]) : c • p %ₘ q = c • (p %ₘ q) := by
  by_cases hq : q.Monic
  · cases' subsingleton_or_nontrivial R with hR hR
    · simp only [eq_iff_true_of_subsingleton]
    · exact
      (div_modByMonic_unique (c • (p /ₘ q)) (c • (p %ₘ q)) hq
          ⟨by rw [mul_smul_comm, ← smul_add, modByMonic_add_div p hq],
            (degree_smul_le _ _).trans_lt (degree_modByMonic_lt _ hq)⟩).2
  · 

Proof state:
case neg
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : CommRing R
p✝ q : R[X]
inst✝ : Semiring S
c : R
p : R[X]
hq : ¬Monic q
⊢ c • p %ₘ q = c • (p %ₘ q)

Next tactic:
simp_rw [modByMonic_eq_of_not_monic _ hq]
theorem aeval_modByMonic_eq_self_of_root [Algebra R S] {p q : R[X]} (hq : q.Monic) {x : S}
    (hx : aeval x q = 0) : aeval x (p %ₘ q) = aeval x p := by
    --`eval₂_modByMonic_eq_self_of_root` doesn't work here as it needs commutativity
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝² : CommRing R
p✝ q✝ : R[X]
inst✝¹ : Ring S
inst✝ : Algebra R S
p q : R[X]
hq : Monic q
x : S
hx : (aeval x) q = 0
⊢ (aeval x) (p %ₘ q) = (aeval x) p

Next tactic:
rw [modByMonic_eq_sub_mul_div p hq, _root_.map_sub, _root_.map_mul, hx, zero_mul,
    sub_zero]
instance : NoZeroDivisors R[X] where
  eq_zero_or_eq_zero_of_mul_eq_zero h := by
    

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : Semiring R
inst✝ : NoZeroDivisors R
p q a✝ b✝ : R[X]
h : a✝ * b✝ = 0
⊢ a✝ = 0 ∨ b✝ = 0

Next tactic:
rw [← leadingCoeff_eq_zero, ← leadingCoeff_eq_zero]
instance : NoZeroDivisors R[X] where
  eq_zero_or_eq_zero_of_mul_eq_zero h := by
    rw [← leadingCoeff_eq_zero, ← leadingCoeff_eq_zero]
    

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : Semiring R
inst✝ : NoZeroDivisors R
p q a✝ b✝ : R[X]
h : a✝ * b✝ = 0
⊢ leadingCoeff a✝ = 0 ∨ leadingCoeff b✝ = 0

Next tactic:
refine' eq_zero_or_eq_zero_of_mul_eq_zero _
instance : NoZeroDivisors R[X] where
  eq_zero_or_eq_zero_of_mul_eq_zero h := by
    rw [← leadingCoeff_eq_zero, ← leadingCoeff_eq_zero]
    refine' eq_zero_or_eq_zero_of_mul_eq_zero _
    

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : Semiring R
inst✝ : NoZeroDivisors R
p q a✝ b✝ : R[X]
h : a✝ * b✝ = 0
⊢ leadingCoeff a✝ * leadingCoeff b✝ = 0

Next tactic:
rw [← leadingCoeff_zero, ← leadingCoeff_mul, h]
theorem natDegree_mul (hp : p ≠ 0) (hq : q ≠ 0) : (p*q).natDegree = p.natDegree + q.natDegree := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : Semiring R
inst✝ : NoZeroDivisors R
p q : R[X]
hp : p ≠ 0
hq : q ≠ 0
⊢ natDegree (p * q) = natDegree p + natDegree q

Next tactic:
rw [← Nat.cast_inj (R := WithBot ℕ), ← degree_eq_natDegree (mul_ne_zero hp hq),
    Nat.cast_add, ← degree_eq_natDegree hp, ← degree_eq_natDegree hq, degree_mul]
theorem trailingDegree_mul : (p * q).trailingDegree = p.trailingDegree + q.trailingDegree := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : Semiring R
inst✝ : NoZeroDivisors R
p q : R[X]
⊢ trailingDegree (p * q) = trailingDegree p + trailingDegree q

Next tactic:
by_cases hp : p = 0
theorem trailingDegree_mul : (p * q).trailingDegree = p.trailingDegree + q.trailingDegree := by
  by_cases hp : p = 0
  · 

Proof state:
case pos
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : Semiring R
inst✝ : NoZeroDivisors R
p q : R[X]
hp : p = 0
⊢ trailingDegree (p * q) = trailingDegree p + trailingDegree q

Next tactic:
rw [hp, zero_mul, trailingDegree_zero, top_add]
theorem trailingDegree_mul : (p * q).trailingDegree = p.trailingDegree + q.trailingDegree := by
  by_cases hp : p = 0
  · rw [hp, zero_mul, trailingDegree_zero, top_add]
  

Proof state:
case neg
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : Semiring R
inst✝ : NoZeroDivisors R
p q : R[X]
hp : ¬p = 0
⊢ trailingDegree (p * q) = trailingDegree p + trailingDegree q

Next tactic:
by_cases hq : q = 0
theorem trailingDegree_mul : (p * q).trailingDegree = p.trailingDegree + q.trailingDegree := by
  by_cases hp : p = 0
  · rw [hp, zero_mul, trailingDegree_zero, top_add]
  by_cases hq : q = 0
  · 

Proof state:
case pos
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : Semiring R
inst✝ : NoZeroDivisors R
p q : R[X]
hp : ¬p = 0
hq : q = 0
⊢ trailingDegree (p * q) = trailingDegree p + trailingDegree q

Next tactic:
rw [hq, mul_zero, trailingDegree_zero, add_top]
theorem trailingDegree_mul : (p * q).trailingDegree = p.trailingDegree + q.trailingDegree := by
  by_cases hp : p = 0
  · rw [hp, zero_mul, trailingDegree_zero, top_add]
  by_cases hq : q = 0
  · rw [hq, mul_zero, trailingDegree_zero, add_top]
  · 

Proof state:
case neg
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : Semiring R
inst✝ : NoZeroDivisors R
p q : R[X]
hp : ¬p = 0
hq : ¬q = 0
⊢ trailingDegree (p * q) = trailingDegree p + trailingDegree q

Next tactic:
rw [trailingDegree_eq_natTrailingDegree hp, trailingDegree_eq_natTrailingDegree hq,
    trailingDegree_eq_natTrailingDegree (mul_ne_zero hp hq), natTrailingDegree_mul hp hq]
theorem trailingDegree_mul : (p * q).trailingDegree = p.trailingDegree + q.trailingDegree := by
  by_cases hp : p = 0
  · rw [hp, zero_mul, trailingDegree_zero, top_add]
  by_cases hq : q = 0
  · rw [hq, mul_zero, trailingDegree_zero, add_top]
  · rw [trailingDegree_eq_natTrailingDegree hp, trailingDegree_eq_natTrailingDegree hq,
    trailingDegree_eq_natTrailingDegree (mul_ne_zero hp hq), natTrailingDegree_mul hp hq]
    

Proof state:
case neg
R : Type u
S : Type v
T : Type w
a b : R
n : ℕ
inst✝¹ : Semiring R
inst✝ : NoZeroDivisors R
p q : R[X]
hp : ¬p = 0
hq : ¬q = 0
⊢ ↑(natTrailingDegree p + natTrailingDegree q) = ↑(natTrailingDegree p) + ↑(natTrailingDegree q)

Next tactic:
apply WithTop.coe_add
@[simp]
theorem natDegree_pow (p : R[X]) (n : ℕ) : natDegree (p ^ n) = n * natDegree p := by
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n✝ : ℕ
inst✝¹ : Semiring R
inst✝ : NoZeroDivisors R
p✝ q p : R[X]
n : ℕ
⊢ natDegree (p ^ n) = n * natDegree p

Next tactic:
classical
  exact if hp0 : p = 0 then
    if hn0 : n = 0 then by simp [hp0, hn0]
    else by rw [hp0, zero_pow (Nat.pos_of_ne_zero hn0)]; simp
  else
    natDegree_pow'
      (by rw [← leadingCoeff_pow, Ne.def, leadingCoeff_eq_zero]; exact pow_ne_zero _ hp0)
@[simp]
theorem natDegree_pow (p : R[X]) (n : ℕ) : natDegree (p ^ n) = n * natDegree p := by
  classical
  

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n✝ : ℕ
inst✝¹ : Semiring R
inst✝ : NoZeroDivisors R
p✝ q p : R[X]
n : ℕ
⊢ natDegree (p ^ n) = n * natDegree p

Next tactic:
exact if hp0 : p = 0 then
    if hn0 : n = 0 then by simp [hp0, hn0]
    else by rw [hp0, zero_pow (Nat.pos_of_ne_zero hn0)]; simp
  else
    natDegree_pow'
      (by rw [← leadingCoeff_pow, Ne.def, leadingCoeff_eq_zero]; exact pow_ne_zero _ hp0)
@[simp]
theorem natDegree_pow (p : R[X]) (n : ℕ) : natDegree (p ^ n) = n * natDegree p := by
  classical
  exact if hp0 : p = 0 then
    if hn0 : n = 0 then by 

Proof state:
R : Type u
S : Type v
T : Type w
a b : R
n✝ : ℕ
inst✝¹ : Semiring R
inst✝ : NoZeroDivisors R
p✝ q p : R[X]
n : ℕ
hp0 : p = 0
hn0 : n = 0
⊢ natDegree (p ^ n) = n * natDegree p

Next tactic:
simp [hp0, hn0]