l3lab/ntp-mathlib huggingface dataset:
theorem monic_map_iff [Semiring S] [Nontrivial S] {f : R →+* S} {p : R[X]} :
    (p.map f).Monic ↔ p.Monic := by
  

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝² : DivisionRing R
p✝ q : R[X]
inst✝¹ : Semiring S
inst✝ : Nontrivial S
f : R →+* S
p : R[X]
⊢ Monic (map f p) ↔ Monic p

Next tactic:
rw [Monic, leadingCoeff_map, ← f.map_one, Function.Injective.eq_iff f.injective, Monic]
theorem isUnit_iff_degree_eq_zero : IsUnit p ↔ degree p = 0 :=
  ⟨degree_eq_zero_of_isUnit, fun h =>
    have : degree p ≤ 0 := by 

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 0
⊢ degree p ≤ 0

Next tactic:
simp [*, le_refl]
theorem isUnit_iff_degree_eq_zero : IsUnit p ↔ degree p = 0 :=
  ⟨degree_eq_zero_of_isUnit, fun h =>
    have : degree p ≤ 0 := by simp [*, le_refl]
    have hc : coeff p 0 ≠ 0 := fun hc => by
      

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 0
this : degree p ≤ 0
hc : coeff p 0 = 0
⊢ False

Next tactic:
rw [eq_C_of_degree_le_zero this, hc] at h
theorem isUnit_iff_degree_eq_zero : IsUnit p ↔ degree p = 0 :=
  ⟨degree_eq_zero_of_isUnit, fun h =>
    have : degree p ≤ 0 := by simp [*, le_refl]
    have hc : coeff p 0 ≠ 0 := fun hc => by
      rw [eq_C_of_degree_le_zero this, hc] at h; 

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree (C 0) = 0
this : degree p ≤ 0
hc : coeff p 0 = 0
⊢ False

Next tactic:
simp only [map_zero] at h
theorem isUnit_iff_degree_eq_zero : IsUnit p ↔ degree p = 0 :=
  ⟨degree_eq_zero_of_isUnit, fun h =>
    have : degree p ≤ 0 := by simp [*, le_refl]
    have hc : coeff p 0 ≠ 0 := fun hc => by
      rw [eq_C_of_degree_le_zero this, hc] at h; simp only [map_zero] at h; 

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
this : degree p ≤ 0
hc : coeff p 0 = 0
h : degree 0 = 0
⊢ False

Next tactic:
contradiction
theorem isUnit_iff_degree_eq_zero : IsUnit p ↔ degree p = 0 :=
  ⟨degree_eq_zero_of_isUnit, fun h =>
    have : degree p ≤ 0 := by simp [*, le_refl]
    have hc : coeff p 0 ≠ 0 := fun hc => by
      rw [eq_C_of_degree_le_zero this, hc] at h; simp only [map_zero] at h; contradiction
    isUnit_iff_dvd_one.2
      ⟨C (coeff p 0)⁻¹, by
        

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 0
this : degree p ≤ 0
hc : coeff p 0 ≠ 0
⊢ 1 = p * C (coeff p 0)⁻¹

Next tactic:
conv in p => rw [eq_C_of_degree_le_zero this]
theorem isUnit_iff_degree_eq_zero : IsUnit p ↔ degree p = 0 :=
  ⟨degree_eq_zero_of_isUnit, fun h =>
    have : degree p ≤ 0 := by simp [*, le_refl]
    have hc : coeff p 0 ≠ 0 := fun hc => by
      rw [eq_C_of_degree_le_zero this, hc] at h; simp only [map_zero] at h; contradiction
    isUnit_iff_dvd_one.2
      ⟨C (coeff p 0)⁻¹, by
        conv in p => 

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 0
this : degree p ≤ 0
hc : coeff p 0 ≠ 0
| p

Next tactic:
rw [eq_C_of_degree_le_zero this]
theorem isUnit_iff_degree_eq_zero : IsUnit p ↔ degree p = 0 :=
  ⟨degree_eq_zero_of_isUnit, fun h =>
    have : degree p ≤ 0 := by simp [*, le_refl]
    have hc : coeff p 0 ≠ 0 := fun hc => by
      rw [eq_C_of_degree_le_zero this, hc] at h; simp only [map_zero] at h; contradiction
    isUnit_iff_dvd_one.2
      ⟨C (coeff p 0)⁻¹, by
        conv in p => rw [eq_C_of_degree_le_zero this]
        

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
h : degree p = 0
this : degree p ≤ 0
hc : coeff p 0 ≠ 0
⊢ 1 = C (coeff p 0) * C (coeff p 0)⁻¹

Next tactic:
rw [← C_mul, _root_.mul_inv_cancel hc, C_1]
private theorem quotient_mul_add_remainder_eq_aux (p q : R[X]) : q * div p q + mod p q = p := by
  

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
⊢ q * div p q + mod p q = p

Next tactic:
by_cases h : q = 0
private theorem quotient_mul_add_remainder_eq_aux (p q : R[X]) : q * div p q + mod p q = p := by
  by_cases h : q = 0
  · 

Proof state:
case pos
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
h : q = 0
⊢ q * div p q + mod p q = p

Next tactic:
simp only [h, zero_mul, mod, modByMonic_zero, zero_add]
private theorem quotient_mul_add_remainder_eq_aux (p q : R[X]) : q * div p q + mod p q = p := by
  by_cases h : q = 0
  · simp only [h, zero_mul, mod, modByMonic_zero, zero_add]
  · 

Proof state:
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
h : ¬q = 0
⊢ q * div p q + mod p q = p

Next tactic:
conv =>
      rhs
      rw [← modByMonic_add_div p (monic_mul_leadingCoeff_inv h)]
private theorem quotient_mul_add_remainder_eq_aux (p q : R[X]) : q * div p q + mod p q = p := by
  by_cases h : q = 0
  · simp only [h, zero_mul, mod, modByMonic_zero, zero_add]
  · conv =>
      

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
h : ¬q = 0
| q * div p q + mod p q = p

Next tactic:
rhs
      rw [← modByMonic_add_div p (monic_mul_leadingCoeff_inv h)]
private theorem quotient_mul_add_remainder_eq_aux (p q : R[X]) : q * div p q + mod p q = p := by
  by_cases h : q = 0
  · simp only [h, zero_mul, mod, modByMonic_zero, zero_add]
  · conv =>
      

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
h : ¬q = 0
| q * div p q + mod p q = p

Next tactic:
rhs
private theorem quotient_mul_add_remainder_eq_aux (p q : R[X]) : q * div p q + mod p q = p := by
  by_cases h : q = 0
  · simp only [h, zero_mul, mod, modByMonic_zero, zero_add]
  · conv =>
      rhs
      

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
h : ¬q = 0
| p

Next tactic:
rw [← modByMonic_add_div p (monic_mul_leadingCoeff_inv h)]
private theorem quotient_mul_add_remainder_eq_aux (p q : R[X]) : q * div p q + mod p q = p := by
  by_cases h : q = 0
  · simp only [h, zero_mul, mod, modByMonic_zero, zero_add]
  · conv =>
      rhs
      rw [← modByMonic_add_div p (monic_mul_leadingCoeff_inv h)]
    

Proof state:
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
h : ¬q = 0
⊢ q * div p q + mod p q = p %ₘ (q * C (leadingCoeff q)⁻¹) + q * C (leadingCoeff q)⁻¹ * (p /ₘ (q * C (leadingCoeff q)⁻¹))

Next tactic:
rw [div, mod, add_comm, mul_assoc]
private theorem remainder_lt_aux (p : R[X]) (hq : q ≠ 0) : degree (mod p q) < degree q := by
  

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q p : R[X]
hq : q ≠ 0
⊢ degree (mod p q) < degree q

Next tactic:
rw [← degree_mul_leadingCoeff_inv q hq]
private theorem remainder_lt_aux (p : R[X]) (hq : q ≠ 0) : degree (mod p q) < degree q := by
  rw [← degree_mul_leadingCoeff_inv q hq]
  

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q p : R[X]
hq : q ≠ 0
⊢ degree (mod p q) < degree (q * C (leadingCoeff q)⁻¹)

Next tactic:
exact degree_modByMonic_lt p (monic_mul_leadingCoeff_inv hq)
theorem modByMonic_eq_mod (p : R[X]) (hq : Monic q) : p %ₘ q = p % q :=
  show p %ₘ q = p %ₘ (q * C (leadingCoeff q)⁻¹) by 

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q p : R[X]
hq : Monic q
⊢ p %ₘ q = p %ₘ (q * C (leadingCoeff q)⁻¹)

Next tactic:
simp only [Monic.def.1 hq, inv_one, mul_one, C_1]
theorem divByMonic_eq_div (p : R[X]) (hq : Monic q) : p /ₘ q = p / q :=
  show p /ₘ q = C (leadingCoeff q)⁻¹ * (p /ₘ (q * C (leadingCoeff q)⁻¹)) by
    

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q p : R[X]
hq : Monic q
⊢ p /ₘ q = C (leadingCoeff q)⁻¹ * (p /ₘ (q * C (leadingCoeff q)⁻¹))

Next tactic:
simp only [Monic.def.1 hq, inv_one, C_1, one_mul, mul_one]
instance : EuclideanDomain R[X] :=
  { Polynomial.commRing,
    Polynomial.nontrivial with
    quotient := (· / ·)
    quotient_zero := by 

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
src✝¹ : CommRing R[X] := commRing
src✝ : Nontrivial R[X] := nontrivial
⊢ ∀ (a : R[X]), (fun x x_1 => x / x_1) a 0 = 0

Next tactic:
simp [div_def]
theorem mod_eq_self_iff (hq0 : q ≠ 0) : p % q = p ↔ degree p < degree q :=
  ⟨fun h => h ▸ EuclideanDomain.mod_lt _ hq0, fun h => by
    

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
⊢ p % q = p

Next tactic:
classical
    have : ¬degree (q * C (leadingCoeff q)⁻¹) ≤ degree p :=
      not_le_of_gt <| by rwa [degree_mul_leadingCoeff_inv q hq0]
    rw [mod_def, modByMonic, dif_pos (monic_mul_leadingCoeff_inv hq0)]
    unfold divModByMonicAux
    dsimp
    simp only [this, false_and_iff, if_false]
theorem mod_eq_self_iff (hq0 : q ≠ 0) : p % q = p ↔ degree p < degree q :=
  ⟨fun h => h ▸ EuclideanDomain.mod_lt _ hq0, fun h => by
    classical
    

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
⊢ p % q = p

Next tactic:
have : ¬degree (q * C (leadingCoeff q)⁻¹) ≤ degree p :=
      not_le_of_gt <| by rwa [degree_mul_leadingCoeff_inv q hq0]
theorem mod_eq_self_iff (hq0 : q ≠ 0) : p % q = p ↔ degree p < degree q :=
  ⟨fun h => h ▸ EuclideanDomain.mod_lt _ hq0, fun h => by
    classical
    have : ¬degree (q * C (leadingCoeff q)⁻¹) ≤ degree p :=
      not_le_of_gt <| by 

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
⊢ degree (q * C (leadingCoeff q)⁻¹) > degree p

Next tactic:
rwa [degree_mul_leadingCoeff_inv q hq0]
theorem mod_eq_self_iff (hq0 : q ≠ 0) : p % q = p ↔ degree p < degree q :=
  ⟨fun h => h ▸ EuclideanDomain.mod_lt _ hq0, fun h => by
    classical
    have : ¬degree (q * C (leadingCoeff q)⁻¹) ≤ degree p :=
      not_le_of_gt <| by rwa [degree_mul_leadingCoeff_inv q hq0]
    

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
this : ¬degree (q * C (leadingCoeff q)⁻¹) ≤ degree p
⊢ p % q = p

Next tactic:
rw [mod_def, modByMonic, dif_pos (monic_mul_leadingCoeff_inv hq0)]
theorem mod_eq_self_iff (hq0 : q ≠ 0) : p % q = p ↔ degree p < degree q :=
  ⟨fun h => h ▸ EuclideanDomain.mod_lt _ hq0, fun h => by
    classical
    have : ¬degree (q * C (leadingCoeff q)⁻¹) ≤ degree p :=
      not_le_of_gt <| by rwa [degree_mul_leadingCoeff_inv q hq0]
    rw [mod_def, modByMonic, dif_pos (monic_mul_leadingCoeff_inv hq0)]
    

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
this : ¬degree (q * C (leadingCoeff q)⁻¹) ≤ degree p
⊢ (divModByMonicAux p (_ : Monic (q * C (leadingCoeff q)⁻¹))).2 = p

Next tactic:
unfold divModByMonicAux
theorem mod_eq_self_iff (hq0 : q ≠ 0) : p % q = p ↔ degree p < degree q :=
  ⟨fun h => h ▸ EuclideanDomain.mod_lt _ hq0, fun h => by
    classical
    have : ¬degree (q * C (leadingCoeff q)⁻¹) ≤ degree p :=
      not_le_of_gt <| by rwa [degree_mul_leadingCoeff_inv q hq0]
    rw [mod_def, modByMonic, dif_pos (monic_mul_leadingCoeff_inv hq0)]
    unfold divModByMonicAux
    

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
this : ¬degree (q * C (leadingCoeff q)⁻¹) ≤ degree p
⊢ (if h : degree (q * C (leadingCoeff q)⁻¹) ≤ degree p ∧ p ≠ 0 then
        let z := C (leadingCoeff p) * X ^ (natDegree p - natDegree (q * C (leadingCoeff q)⁻¹));
        let_fun _wf :=
          (_ :
            degree
                (p -
                  q * C (leadingCoeff q)⁻¹ *
                    (C (leadingCoeff p) * X ^ (natDegree p - natDegree (q * C (leadingCoeff q)⁻¹)))) <
              degree p);
        let dm := divModByMonicAux (p - q * C (leadingCoeff q)⁻¹ * z) (_ : Monic (q * C (leadingCoeff q)⁻¹));
        (z + dm.1, dm.2)
      else (0, p)).2 =
    p

Next tactic:
dsimp
theorem mod_eq_self_iff (hq0 : q ≠ 0) : p % q = p ↔ degree p < degree q :=
  ⟨fun h => h ▸ EuclideanDomain.mod_lt _ hq0, fun h => by
    classical
    have : ¬degree (q * C (leadingCoeff q)⁻¹) ≤ degree p :=
      not_le_of_gt <| by rwa [degree_mul_leadingCoeff_inv q hq0]
    rw [mod_def, modByMonic, dif_pos (monic_mul_leadingCoeff_inv hq0)]
    unfold divModByMonicAux
    dsimp
    

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
this : ¬degree (q * C (leadingCoeff q)⁻¹) ≤ degree p
⊢ (if degree (q * C (leadingCoeff q)⁻¹) ≤ degree p ∧ ¬p = 0 then
        (C (leadingCoeff p) * X ^ (natDegree p - natDegree (q * C (leadingCoeff q)⁻¹)) +
            (divModByMonicAux
                (p -
                  q * C (leadingCoeff q)⁻¹ *
                    (C (leadingCoeff p) * X ^ (natDegree p - natDegree (q * C (leadingCoeff q)⁻¹))))
                (_ : Monic (q * C (leadingCoeff q)⁻¹))).1,
          (divModByMonicAux
              (p -
                q * C (leadingCoeff q)⁻¹ *
                  (C (leadingCoeff p) * X ^ (natDegree p - natDegree (q * C (leadingCoeff q)⁻¹))))
              (_ : Monic (q * C (leadingCoeff q)⁻¹))).2)
      else (0, p)).2 =
    p

Next tactic:
simp only [this, false_and_iff, if_false]
theorem div_eq_zero_iff (hq0 : q ≠ 0) : p / q = 0 ↔ degree p < degree q :=
  ⟨fun h => by
    

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : p / q = 0
⊢ degree p < degree q

Next tactic:
have := EuclideanDomain.div_add_mod p q
theorem div_eq_zero_iff (hq0 : q ≠ 0) : p / q = 0 ↔ degree p < degree q :=
  ⟨fun h => by
    have := EuclideanDomain.div_add_mod p q;
      

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : p / q = 0
this : q * (p / q) + p % q = p
⊢ degree p < degree q

Next tactic:
rwa [h, mul_zero, zero_add, mod_eq_self_iff hq0] at this
theorem div_eq_zero_iff (hq0 : q ≠ 0) : p / q = 0 ↔ degree p < degree q :=
  ⟨fun h => by
    have := EuclideanDomain.div_add_mod p q;
      rwa [h, mul_zero, zero_add, mod_eq_self_iff hq0] at this,
    fun h => by
    

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
⊢ p / q = 0

Next tactic:
have hlt : degree p < degree (q * C (leadingCoeff q)⁻¹) := by
      rwa [degree_mul_leadingCoeff_inv q hq0]
theorem div_eq_zero_iff (hq0 : q ≠ 0) : p / q = 0 ↔ degree p < degree q :=
  ⟨fun h => by
    have := EuclideanDomain.div_add_mod p q;
      rwa [h, mul_zero, zero_add, mod_eq_self_iff hq0] at this,
    fun h => by
    have hlt : degree p < degree (q * C (leadingCoeff q)⁻¹) := by
      

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
⊢ degree p < degree (q * C (leadingCoeff q)⁻¹)

Next tactic:
rwa [degree_mul_leadingCoeff_inv q hq0]
theorem div_eq_zero_iff (hq0 : q ≠ 0) : p / q = 0 ↔ degree p < degree q :=
  ⟨fun h => by
    have := EuclideanDomain.div_add_mod p q;
      rwa [h, mul_zero, zero_add, mod_eq_self_iff hq0] at this,
    fun h => by
    have hlt : degree p < degree (q * C (leadingCoeff q)⁻¹) := by
      rwa [degree_mul_leadingCoeff_inv q hq0]
    

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
hlt : degree p < degree (q * C (leadingCoeff q)⁻¹)
⊢ p / q = 0

Next tactic:
have hm : Monic (q * C (leadingCoeff q)⁻¹) := monic_mul_leadingCoeff_inv hq0
theorem div_eq_zero_iff (hq0 : q ≠ 0) : p / q = 0 ↔ degree p < degree q :=
  ⟨fun h => by
    have := EuclideanDomain.div_add_mod p q;
      rwa [h, mul_zero, zero_add, mod_eq_self_iff hq0] at this,
    fun h => by
    have hlt : degree p < degree (q * C (leadingCoeff q)⁻¹) := by
      rwa [degree_mul_leadingCoeff_inv q hq0]
    have hm : Monic (q * C (leadingCoeff q)⁻¹) := monic_mul_leadingCoeff_inv hq0
    

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
h : degree p < degree q
hlt : degree p < degree (q * C (leadingCoeff q)⁻¹)
hm : Monic (q * C (leadingCoeff q)⁻¹)
⊢ p / q = 0

Next tactic:
rw [div_def, (divByMonic_eq_zero_iff hm).2 hlt, mul_zero]
theorem degree_add_div (hq0 : q ≠ 0) (hpq : degree q ≤ degree p) :
    degree q + degree (p / q) = degree p := by
  

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
hpq : degree q ≤ degree p
⊢ degree q + degree (p / q) = degree p

Next tactic:
have : degree (p % q) < degree (q * (p / q)) :=
    calc
      degree (p % q) < degree q := EuclideanDomain.mod_lt _ hq0
      _ ≤ _ := degree_le_mul_left _ (mt (div_eq_zero_iff hq0).1 (not_lt_of_ge hpq))
theorem degree_add_div (hq0 : q ≠ 0) (hpq : degree q ≤ degree p) :
    degree q + degree (p / q) = degree p := by
  have : degree (p % q) < degree (q * (p / q)) :=
    calc
      degree (p % q) < degree q := EuclideanDomain.mod_lt _ hq0
      _ ≤ _ := degree_le_mul_left _ (mt (div_eq_zero_iff hq0).1 (not_lt_of_ge hpq))

  

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
hpq : degree q ≤ degree p
this : degree (p % q) < degree (q * (p / q))
⊢ degree q + degree (p / q) = degree p

Next tactic:
conv_rhs =>
    rw [← EuclideanDomain.div_add_mod p q, degree_add_eq_left_of_degree_lt this, degree_mul]
theorem degree_add_div (hq0 : q ≠ 0) (hpq : degree q ≤ degree p) :
    degree q + degree (p / q) = degree p := by
  have : degree (p % q) < degree (q * (p / q)) :=
    calc
      degree (p % q) < degree q := EuclideanDomain.mod_lt _ hq0
      _ ≤ _ := degree_le_mul_left _ (mt (div_eq_zero_iff hq0).1 (not_lt_of_ge hpq))

  conv_rhs =>
    

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hq0 : q ≠ 0
hpq : degree q ≤ degree p
this : degree (p % q) < degree (q * (p / q))
| degree p

Next tactic:
rw [← EuclideanDomain.div_add_mod p q, degree_add_eq_left_of_degree_lt this, degree_mul]
theorem degree_div_le (p q : R[X]) : degree (p / q) ≤ degree p := by
  

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
⊢ degree (p / q) ≤ degree p

Next tactic:
by_cases hq : q = 0
theorem degree_div_le (p q : R[X]) : degree (p / q) ≤ degree p := by
  by_cases hq : q = 0
  · 

Proof state:
case pos
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
hq : q = 0
⊢ degree (p / q) ≤ degree p

Next tactic:
simp [hq]
theorem degree_div_le (p q : R[X]) : degree (p / q) ≤ degree p := by
  by_cases hq : q = 0
  · simp [hq]
  · 

Proof state:
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
hq : ¬q = 0
⊢ degree (p / q) ≤ degree p

Next tactic:
rw [div_def, mul_comm, degree_mul_leadingCoeff_inv _ hq]
theorem degree_div_le (p q : R[X]) : degree (p / q) ≤ degree p := by
  by_cases hq : q = 0
  · simp [hq]
  · rw [div_def, mul_comm, degree_mul_leadingCoeff_inv _ hq]; 

Proof state:
case neg
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p✝ q✝ p q : R[X]
hq : ¬q = 0
⊢ degree (p /ₘ (q * C (leadingCoeff q)⁻¹)) ≤ degree p

Next tactic:
exact degree_divByMonic_le _ _
theorem degree_div_lt (hp : p ≠ 0) (hq : 0 < degree q) : degree (p / q) < degree p := by
  

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hp : p ≠ 0
hq : 0 < degree q
⊢ degree (p / q) < degree p

Next tactic:
have hq0 : q ≠ 0 := fun hq0 => by simp [hq0] at hq
theorem degree_div_lt (hp : p ≠ 0) (hq : 0 < degree q) : degree (p / q) < degree p := by
  have hq0 : q ≠ 0 := fun hq0 => by 

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hp : p ≠ 0
hq : 0 < degree q
hq0 : q = 0
⊢ False

Next tactic:
simp [hq0] at hq
theorem degree_div_lt (hp : p ≠ 0) (hq : 0 < degree q) : degree (p / q) < degree p := by
  have hq0 : q ≠ 0 := fun hq0 => by simp [hq0] at hq
  

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hp : p ≠ 0
hq : 0 < degree q
hq0 : q ≠ 0
⊢ degree (p / q) < degree p

Next tactic:
rw [div_def, mul_comm, degree_mul_leadingCoeff_inv _ hq0]
theorem degree_div_lt (hp : p ≠ 0) (hq : 0 < degree q) : degree (p / q) < degree p := by
  have hq0 : q ≠ 0 := fun hq0 => by simp [hq0] at hq
  rw [div_def, mul_comm, degree_mul_leadingCoeff_inv _ hq0];
    

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hp : p ≠ 0
hq : 0 < degree q
hq0 : q ≠ 0
⊢ degree (p /ₘ (q * C (leadingCoeff q)⁻¹)) < degree p

Next tactic:
exact
      degree_divByMonic_lt _ (monic_mul_leadingCoeff_inv hq0) hp
        (by rw [degree_mul_leadingCoeff_inv _ hq0]; exact hq)
theorem degree_div_lt (hp : p ≠ 0) (hq : 0 < degree q) : degree (p / q) < degree p := by
  have hq0 : q ≠ 0 := fun hq0 => by simp [hq0] at hq
  rw [div_def, mul_comm, degree_mul_leadingCoeff_inv _ hq0];
    exact
      degree_divByMonic_lt _ (monic_mul_leadingCoeff_inv hq0) hp
        (by 

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hp : p ≠ 0
hq : 0 < degree q
hq0 : q ≠ 0
⊢ 0 < degree (q * C (leadingCoeff q)⁻¹)

Next tactic:
rw [degree_mul_leadingCoeff_inv _ hq0]
theorem degree_div_lt (hp : p ≠ 0) (hq : 0 < degree q) : degree (p / q) < degree p := by
  have hq0 : q ≠ 0 := fun hq0 => by simp [hq0] at hq
  rw [div_def, mul_comm, degree_mul_leadingCoeff_inv _ hq0];
    exact
      degree_divByMonic_lt _ (monic_mul_leadingCoeff_inv hq0) hp
        (by rw [degree_mul_leadingCoeff_inv _ hq0]; 

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Field R
p q : R[X]
hp : p ≠ 0
hq : 0 < degree q
hq0 : q ≠ 0
⊢ 0 < degree q

Next tactic:
exact hq
theorem isUnit_map [Field k] (f : R →+* k) : IsUnit (p.map f) ↔ IsUnit p := by
  

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
⊢ IsUnit (map f p) ↔ IsUnit p

Next tactic:
simp_rw [isUnit_iff_degree_eq_zero, degree_map]
theorem map_div [Field k] (f : R →+* k) : (p / q).map f = p.map f / q.map f := by
  

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
⊢ map f (p / q) = map f p / map f q

Next tactic:
if hq0 : q = 0 then simp [hq0]
  else
    rw [div_def, div_def, Polynomial.map_mul, map_divByMonic f (monic_mul_leadingCoeff_inv hq0),
      Polynomial.map_mul, map_C, leadingCoeff_map, map_inv₀]
theorem map_div [Field k] (f : R →+* k) : (p / q).map f = p.map f / q.map f := by
  if hq0 : q = 0 then 

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
hq0 : q = 0
⊢ map f (p / q) = map f p / map f q

Next tactic:
simp [hq0]
theorem map_div [Field k] (f : R →+* k) : (p / q).map f = p.map f / q.map f := by
  if hq0 : q = 0 then simp [hq0]
  else
    

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
hq0 : ¬q = 0
⊢ map f (p / q) = map f p / map f q

Next tactic:
rw [div_def, div_def, Polynomial.map_mul, map_divByMonic f (monic_mul_leadingCoeff_inv hq0),
      Polynomial.map_mul, map_C, leadingCoeff_map, map_inv₀]
theorem map_mod [Field k] (f : R →+* k) : (p % q).map f = p.map f % q.map f := by
  

Proof state:
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
⊢ map f (p % q) = map f p % map f q

Next tactic:
by_cases hq0 : q = 0
theorem map_mod [Field k] (f : R →+* k) : (p % q).map f = p.map f % q.map f := by
  by_cases hq0 : q = 0
  · 

Proof state:
case pos
R : Type u
S : Type v
k : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Field R
p q : R[X]
inst✝ : Field k
f : R →+* k
hq0 : q = 0
⊢ map f (p % q) = map f p % map f q

Next tactic:
simp [hq0]