l3lab/ntp-mathlib huggingface dataset:
instance EquivFunctorFinset : EquivFunctor Finset where
  map e s := s.map e.toEmbedding
  map_refl' α := by ext; simp
  map_trans' k h := by
    ext _ a; simp; constructor <;> intro h'
    · let ⟨a, ha₁, ha₂⟩ := h'
      rw [← ha₂]; simp; apply ha₁
    · 

Proof state:
case h.a.mpr
α✝ β✝ γ✝ : Type ?u.6305
k : α✝ ≃ β✝
h : β✝ ≃ γ✝
x✝ : Finset α✝
a : γ✝
h' : k.symm (h.symm a) ∈ x✝
⊢ ∃ a_1 ∈ x✝, h (k a_1) = a

Next tactic:
exists (Equiv.symm k) ((Equiv.symm h) a)
instance EquivFunctorFinset : EquivFunctor Finset where
  map e s := s.map e.toEmbedding
  map_refl' α := by ext; simp
  map_trans' k h := by
    ext _ a; simp; constructor <;> intro h'
    · let ⟨a, ha₁, ha₂⟩ := h'
      rw [← ha₂]; simp; apply ha₁
    · exists (Equiv.symm k) ((Equiv.symm h) a)
      

Proof state:
case h.a.mpr
α✝ β✝ γ✝ : Type ?u.6305
k : α✝ ≃ β✝
h : β✝ ≃ γ✝
x✝ : Finset α✝
a : γ✝
h' : k.symm (h.symm a) ∈ x✝
⊢ k.symm (h.symm a) ∈ x✝ ∧ h (k (k.symm (h.symm a))) = a

Next tactic:
simp [h']
instance EquivFunctorFintype : EquivFunctor Fintype where
  map e s := Fintype.ofBijective e e.bijective
  map_refl' α := by 

Proof state:
α : Type ?u.9290
⊢ (fun {α β} e s => Fintype.ofBijective ⇑e (_ : Function.Bijective ⇑e)) (Equiv.refl α) = id

Next tactic:
ext
instance EquivFunctorFintype : EquivFunctor Fintype where
  map e s := Fintype.ofBijective e e.bijective
  map_refl' α := by ext; 

Proof state:
case h
α : Type ?u.9290
x✝ : Fintype α
⊢ (fun {α β} e s => Fintype.ofBijective ⇑e (_ : Function.Bijective ⇑e)) (Equiv.refl α) x✝ = id x✝

Next tactic:
simp [eq_iff_true_of_subsingleton]
instance EquivFunctorFintype : EquivFunctor Fintype where
  map e s := Fintype.ofBijective e e.bijective
  map_refl' α := by ext; simp [eq_iff_true_of_subsingleton]
  map_trans' := by 

Proof state:
⊢ ∀ {α β γ : Type ?u.9290} (k : α ≃ β) (h : β ≃ γ),
    (fun {α β} e s => Fintype.ofBijective ⇑e (_ : Function.Bijective ⇑e)) (k.trans h) =
      (fun {α β} e s => Fintype.ofBijective ⇑e (_ : Function.Bijective ⇑e)) h ∘
        (fun {α β} e s => Fintype.ofBijective ⇑e (_ : Function.Bijective ⇑e)) k

Next tactic:
simp [eq_iff_true_of_subsingleton]
@[simp]
theorem coeff_divX : (divX p).coeff n = p.coeff (n + 1) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ coeff (divX p) n = coeff p (n + 1)

Next tactic:
rw [add_comm]
@[simp]
theorem coeff_divX : (divX p).coeff n = p.coeff (n + 1) := by
  rw [add_comm]; 

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ coeff (divX p) n = coeff p (1 + n)

Next tactic:
cases p
@[simp]
theorem coeff_divX : (divX p).coeff n = p.coeff (n + 1) := by
  rw [add_comm]; cases p; 

Proof state:
case ofFinsupp
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
q : R[X]
toFinsupp✝ : AddMonoidAlgebra R ℕ
⊢ coeff (divX { toFinsupp := toFinsupp✝ }) n = coeff { toFinsupp := toFinsupp✝ } (1 + n)

Next tactic:
rfl
theorem divX_mul_X_add (p : R[X]) : divX p * X + C (p.coeff 0) = p :=
  ext <| by 

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
⊢ ∀ (n : ℕ), coeff (divX p * X + C (coeff p 0)) n = coeff p n

Next tactic:
rintro ⟨_ | _⟩
theorem divX_mul_X_add (p : R[X]) : divX p * X + C (p.coeff 0) = p :=
  ext <| by rintro ⟨_ | _⟩ <;> 

Proof state:
case zero
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
⊢ coeff (divX p * X + C (coeff p 0)) Nat.zero = coeff p Nat.zero

Next tactic:
simp [coeff_C, Nat.succ_ne_zero, coeff_mul_X]
theorem divX_mul_X_add (p : R[X]) : divX p * X + C (p.coeff 0) = p :=
  ext <| by rintro ⟨_ | _⟩ <;> 

Proof state:
case succ
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
n✝ : ℕ
⊢ coeff (divX p * X + C (coeff p 0)) (Nat.succ n✝) = coeff p (Nat.succ n✝)

Next tactic:
simp [coeff_C, Nat.succ_ne_zero, coeff_mul_X]
@[simp]
theorem X_mul_divX_add (p : R[X]) : X * divX p + C (p.coeff 0) = p :=
  ext <| by 

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
⊢ ∀ (n : ℕ), coeff (X * divX p + C (coeff p 0)) n = coeff p n

Next tactic:
rintro ⟨_ | _⟩
@[simp]
theorem X_mul_divX_add (p : R[X]) : X * divX p + C (p.coeff 0) = p :=
  ext <| by rintro ⟨_ | _⟩ <;> 

Proof state:
case zero
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
⊢ coeff (X * divX p + C (coeff p 0)) Nat.zero = coeff p Nat.zero

Next tactic:
simp [coeff_C, Nat.succ_ne_zero, coeff_mul_X]
@[simp]
theorem X_mul_divX_add (p : R[X]) : X * divX p + C (p.coeff 0) = p :=
  ext <| by rintro ⟨_ | _⟩ <;> 

Proof state:
case succ
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
n✝ : ℕ
⊢ coeff (X * divX p + C (coeff p 0)) (Nat.succ n✝) = coeff p (Nat.succ n✝)

Next tactic:
simp [coeff_C, Nat.succ_ne_zero, coeff_mul_X]
@[simp]
theorem divX_C (a : R) : divX (C a) = 0 :=
  ext fun n => by 

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a✝ b : R
n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
a : R
n : ℕ
⊢ coeff (divX (C a)) n = coeff 0 n

Next tactic:
simp [coeff_divX, coeff_C, Finsupp.single_eq_of_ne _]
theorem divX_eq_zero_iff : divX p = 0 ↔ p = C (p.coeff 0) :=
  ⟨fun h => by 

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
h : divX p = 0
⊢ p = C (coeff p 0)

Next tactic:
simpa [eq_comm, h] using divX_mul_X_add p
theorem divX_eq_zero_iff : divX p = 0 ↔ p = C (p.coeff 0) :=
  ⟨fun h => by simpa [eq_comm, h] using divX_mul_X_add p, fun h => by 

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
h : p = C (coeff p 0)
⊢ divX p = 0

Next tactic:
rw [h, divX_C]
theorem divX_add : divX (p + q) = divX p + divX q :=
  ext <| by 

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ ∀ (n : ℕ), coeff (divX (p + q)) n = coeff (divX p + divX q) n

Next tactic:
simp
@[simp]
theorem divX_one : divX (1 : R[X]) = 0 := by
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ divX 1 = 0

Next tactic:
ext
@[simp]
theorem divX_one : divX (1 : R[X]) = 0 := by
  ext
  

Proof state:
case a
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
n✝ : ℕ
⊢ coeff (divX 1) n✝ = coeff 0 n✝

Next tactic:
simpa only [coeff_divX, coeff_zero] using coeff_one
@[simp]
theorem divX_C_mul : divX (C a * p) = C a * divX p := by
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ divX (C a * p) = C a * divX p

Next tactic:
ext
@[simp]
theorem divX_C_mul : divX (C a * p) = C a * divX p := by
  ext
  

Proof state:
case a
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
n✝ : ℕ
⊢ coeff (divX (C a * p)) n✝ = coeff (C a * divX p) n✝

Next tactic:
simp
theorem divX_X_pow : divX (X ^ n : R[X]) = if (n = 0) then 0 else X ^ (n - 1) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ divX (X ^ n) = if n = 0 then 0 else X ^ (n - 1)

Next tactic:
cases n
theorem divX_X_pow : divX (X ^ n : R[X]) = if (n = 0) then 0 else X ^ (n - 1) := by
  cases n
  · 

Proof state:
case zero
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
inst✝ : Semiring R
p q : R[X]
⊢ divX (X ^ Nat.zero) = if Nat.zero = 0 then 0 else X ^ (Nat.zero - 1)

Next tactic:
simp
theorem divX_X_pow : divX (X ^ n : R[X]) = if (n = 0) then 0 else X ^ (n - 1) := by
  cases n
  · simp
  · 

Proof state:
case succ
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
inst✝ : Semiring R
p q : R[X]
n✝ : ℕ
⊢ divX (X ^ Nat.succ n✝) = if Nat.succ n✝ = 0 then 0 else X ^ (Nat.succ n✝ - 1)

Next tactic:
ext n
theorem divX_X_pow : divX (X ^ n : R[X]) = if (n = 0) then 0 else X ^ (n - 1) := by
  cases n
  · simp
  · ext n
    

Proof state:
case succ.a
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
inst✝ : Semiring R
p q : R[X]
n✝ n : ℕ
⊢ coeff (divX (X ^ Nat.succ n✝)) n = coeff (if Nat.succ n✝ = 0 then 0 else X ^ (Nat.succ n✝ - 1)) n

Next tactic:
simp [coeff_X_pow]
theorem natDegree_divX_eq_natDegree_tsub_one : p.divX.natDegree = p.natDegree - 1 := by
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ natDegree (divX p) = natDegree p - 1

Next tactic:
apply map_natDegree_eq_sub (φ := divX_hom)
theorem natDegree_divX_eq_natDegree_tsub_one : p.divX.natDegree = p.natDegree - 1 := by
  apply map_natDegree_eq_sub (φ := divX_hom)
  · 

Proof state:
case φ_k
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ ∀ (f : R[X]), natDegree f < 1 → divX_hom f = 0

Next tactic:
intro f
theorem natDegree_divX_eq_natDegree_tsub_one : p.divX.natDegree = p.natDegree - 1 := by
  apply map_natDegree_eq_sub (φ := divX_hom)
  · intro f
    

Proof state:
case φ_k
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q f : R[X]
⊢ natDegree f < 1 → divX_hom f = 0

Next tactic:
simpa [divX_hom, divX_eq_zero_iff] using eq_C_of_natDegree_eq_zero
theorem natDegree_divX_eq_natDegree_tsub_one : p.divX.natDegree = p.natDegree - 1 := by
  apply map_natDegree_eq_sub (φ := divX_hom)
  · intro f
    simpa [divX_hom, divX_eq_zero_iff] using eq_C_of_natDegree_eq_zero
  · 

Proof state:
case φ_mon
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ ∀ (n : ℕ) (c : R), c ≠ 0 → natDegree (divX_hom ((monomial n) c)) = n - 1

Next tactic:
intros n c c0
theorem natDegree_divX_eq_natDegree_tsub_one : p.divX.natDegree = p.natDegree - 1 := by
  apply map_natDegree_eq_sub (φ := divX_hom)
  · intro f
    simpa [divX_hom, divX_eq_zero_iff] using eq_C_of_natDegree_eq_zero
  · intros n c c0
    

Proof state:
case φ_mon
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
c : R
c0 : c ≠ 0
⊢ natDegree (divX_hom ((monomial n) c)) = n - 1

Next tactic:
rw [← C_mul_X_pow_eq_monomial, divX_hom_toFun, divX_C_mul, divX_X_pow]
theorem natDegree_divX_eq_natDegree_tsub_one : p.divX.natDegree = p.natDegree - 1 := by
  apply map_natDegree_eq_sub (φ := divX_hom)
  · intro f
    simpa [divX_hom, divX_eq_zero_iff] using eq_C_of_natDegree_eq_zero
  · intros n c c0
    rw [← C_mul_X_pow_eq_monomial, divX_hom_toFun, divX_C_mul, divX_X_pow]
    

Proof state:
case φ_mon
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
c : R
c0 : c ≠ 0
⊢ natDegree (C c * if n = 0 then 0 else X ^ (n - 1)) = n - 1

Next tactic:
split_ifs with n0
theorem natDegree_divX_eq_natDegree_tsub_one : p.divX.natDegree = p.natDegree - 1 := by
  apply map_natDegree_eq_sub (φ := divX_hom)
  · intro f
    simpa [divX_hom, divX_eq_zero_iff] using eq_C_of_natDegree_eq_zero
  · intros n c c0
    rw [← C_mul_X_pow_eq_monomial, divX_hom_toFun, divX_C_mul, divX_X_pow]
    split_ifs with n0
    · 

Proof state:
case pos
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
c : R
c0 : c ≠ 0
n0 : n = 0
⊢ natDegree (C c * 0) = n - 1

Next tactic:
simp [n0]
theorem natDegree_divX_eq_natDegree_tsub_one : p.divX.natDegree = p.natDegree - 1 := by
  apply map_natDegree_eq_sub (φ := divX_hom)
  · intro f
    simpa [divX_hom, divX_eq_zero_iff] using eq_C_of_natDegree_eq_zero
  · intros n c c0
    rw [← C_mul_X_pow_eq_monomial, divX_hom_toFun, divX_C_mul, divX_X_pow]
    split_ifs with n0
    · simp [n0]
    · 

Proof state:
case neg
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
c : R
c0 : c ≠ 0
n0 : ¬n = 0
⊢ natDegree (C c * X ^ (n - 1)) = n - 1

Next tactic:
exact natDegree_C_mul_X_pow (n - 1) c c0
theorem divX_C_mul_X_pow : divX (C a * X ^ n) = if n = 0 then 0 else C a * X ^ (n - 1) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ divX (C a * X ^ n) = if n = 0 then 0 else C a * X ^ (n - 1)

Next tactic:
simp only [divX_C_mul, divX_X_pow, mul_ite, mul_zero]
theorem degree_divX_lt (hp0 : p ≠ 0) : (divX p).degree < p.degree := by
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
hp0 : p ≠ 0
⊢ degree (divX p) < degree p

Next tactic:
haveI := Nontrivial.of_polynomial_ne hp0
theorem degree_divX_lt (hp0 : p ≠ 0) : (divX p).degree < p.degree := by
  haveI := Nontrivial.of_polynomial_ne hp0
  

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
hp0 : p ≠ 0
this : Nontrivial R
⊢ degree (divX p) < degree p

Next tactic:
calc
    degree (divX p) < (divX p * X + C (p.coeff 0)).degree :=
      if h : degree p ≤ 0 then by
        have h' : C (p.coeff 0) ≠ 0 := by rwa [← eq_C_of_degree_le_zero h]
        rw [eq_C_of_degree_le_zero h, divX_C, degree_zero, zero_mul, zero_add]
        exact lt_of_le_of_ne bot_le (Ne.symm (mt degree_eq_bot.1 <| by simpa using h'))
      else by
        have hXp0 : divX p ≠ 0 := by
          simpa [divX_eq_zero_iff, -not_le, degree_le_zero_iff] using h
        have : leadingCoeff (divX p) * leadingCoeff X ≠ 0 := by simpa
        have : degree (C (p.coeff 0)) < degree (divX p * X) :=
          calc
            degree (C (p.coeff 0)) ≤ 0 := degree_C_le
            _ < 1 := by decide
            _ = degree (X : R[X]) := degree_X.symm
            _ ≤ degree (divX p * X) := by
              rw [← zero_add (degree X), degree_mul' this]
              exact add_le_add
                (by rw [zero_le_degree_iff, Ne.def, divX_eq_zero_iff]
                    exact fun h0 => h (h0.symm ▸ degree_C_le))
                    le_rfl
        rw [degree_add_eq_left_of_degree_lt this]; exact degree_lt_degree_mul_X hXp0
    _ = degree p := congr_arg _ (divX_mul_X_add _)
theorem degree_divX_lt (hp0 : p ≠ 0) : (divX p).degree < p.degree := by
  haveI := Nontrivial.of_polynomial_ne hp0
  calc
    degree (divX p) < (divX p * X + C (p.coeff 0)).degree :=
      if h : degree p ≤ 0 then by
        

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
hp0 : p ≠ 0
this : Nontrivial R
h : degree p ≤ 0
⊢ degree (divX p) < degree (divX p * X + C (coeff p 0))

Next tactic:
have h' : C (p.coeff 0) ≠ 0 := by rwa [← eq_C_of_degree_le_zero h]
theorem degree_divX_lt (hp0 : p ≠ 0) : (divX p).degree < p.degree := by
  haveI := Nontrivial.of_polynomial_ne hp0
  calc
    degree (divX p) < (divX p * X + C (p.coeff 0)).degree :=
      if h : degree p ≤ 0 then by
        have h' : C (p.coeff 0) ≠ 0 := by 

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
hp0 : p ≠ 0
this : Nontrivial R
h : degree p ≤ 0
⊢ C (coeff p 0) ≠ 0

Next tactic:
rwa [← eq_C_of_degree_le_zero h]
theorem degree_divX_lt (hp0 : p ≠ 0) : (divX p).degree < p.degree := by
  haveI := Nontrivial.of_polynomial_ne hp0
  calc
    degree (divX p) < (divX p * X + C (p.coeff 0)).degree :=
      if h : degree p ≤ 0 then by
        have h' : C (p.coeff 0) ≠ 0 := by rwa [← eq_C_of_degree_le_zero h]
        

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
hp0 : p ≠ 0
this : Nontrivial R
h : degree p ≤ 0
h' : C (coeff p 0) ≠ 0
⊢ degree (divX p) < degree (divX p * X + C (coeff p 0))

Next tactic:
rw [eq_C_of_degree_le_zero h, divX_C, degree_zero, zero_mul, zero_add]
theorem degree_divX_lt (hp0 : p ≠ 0) : (divX p).degree < p.degree := by
  haveI := Nontrivial.of_polynomial_ne hp0
  calc
    degree (divX p) < (divX p * X + C (p.coeff 0)).degree :=
      if h : degree p ≤ 0 then by
        have h' : C (p.coeff 0) ≠ 0 := by rwa [← eq_C_of_degree_le_zero h]
        rw [eq_C_of_degree_le_zero h, divX_C, degree_zero, zero_mul, zero_add]
        

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
hp0 : p ≠ 0
this : Nontrivial R
h : degree p ≤ 0
h' : C (coeff p 0) ≠ 0
⊢ ⊥ < degree (C (coeff (C (coeff p 0)) 0))

Next tactic:
exact lt_of_le_of_ne bot_le (Ne.symm (mt degree_eq_bot.1 <| by simpa using h'))
theorem degree_divX_lt (hp0 : p ≠ 0) : (divX p).degree < p.degree := by
  haveI := Nontrivial.of_polynomial_ne hp0
  calc
    degree (divX p) < (divX p * X + C (p.coeff 0)).degree :=
      if h : degree p ≤ 0 then by
        have h' : C (p.coeff 0) ≠ 0 := by rwa [← eq_C_of_degree_le_zero h]
        rw [eq_C_of_degree_le_zero h, divX_C, degree_zero, zero_mul, zero_add]
        exact lt_of_le_of_ne bot_le (Ne.symm (mt degree_eq_bot.1 <| by 

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
hp0 : p ≠ 0
this : Nontrivial R
h : degree p ≤ 0
h' : C (coeff p 0) ≠ 0
⊢ ¬C (coeff (C (coeff p 0)) 0) = 0

Next tactic:
simpa using h'
theorem degree_divX_lt (hp0 : p ≠ 0) : (divX p).degree < p.degree := by
  haveI := Nontrivial.of_polynomial_ne hp0
  calc
    degree (divX p) < (divX p * X + C (p.coeff 0)).degree :=
      if h : degree p ≤ 0 then by
        have h' : C (p.coeff 0) ≠ 0 := by rwa [← eq_C_of_degree_le_zero h]
        rw [eq_C_of_degree_le_zero h, divX_C, degree_zero, zero_mul, zero_add]
        exact lt_of_le_of_ne bot_le (Ne.symm (mt degree_eq_bot.1 <| by simpa using h'))
      else by
        

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
hp0 : p ≠ 0
this : Nontrivial R
h : ¬degree p ≤ 0
⊢ degree (divX p) < degree (divX p * X + C (coeff p 0))

Next tactic:
have hXp0 : divX p ≠ 0 := by
          simpa [divX_eq_zero_iff, -not_le, degree_le_zero_iff] using h
theorem degree_divX_lt (hp0 : p ≠ 0) : (divX p).degree < p.degree := by
  haveI := Nontrivial.of_polynomial_ne hp0
  calc
    degree (divX p) < (divX p * X + C (p.coeff 0)).degree :=
      if h : degree p ≤ 0 then by
        have h' : C (p.coeff 0) ≠ 0 := by rwa [← eq_C_of_degree_le_zero h]
        rw [eq_C_of_degree_le_zero h, divX_C, degree_zero, zero_mul, zero_add]
        exact lt_of_le_of_ne bot_le (Ne.symm (mt degree_eq_bot.1 <| by simpa using h'))
      else by
        have hXp0 : divX p ≠ 0 := by
          

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
hp0 : p ≠ 0
this : Nontrivial R
h : ¬degree p ≤ 0
⊢ divX p ≠ 0

Next tactic:
simpa [divX_eq_zero_iff, -not_le, degree_le_zero_iff] using h
theorem degree_divX_lt (hp0 : p ≠ 0) : (divX p).degree < p.degree := by
  haveI := Nontrivial.of_polynomial_ne hp0
  calc
    degree (divX p) < (divX p * X + C (p.coeff 0)).degree :=
      if h : degree p ≤ 0 then by
        have h' : C (p.coeff 0) ≠ 0 := by rwa [← eq_C_of_degree_le_zero h]
        rw [eq_C_of_degree_le_zero h, divX_C, degree_zero, zero_mul, zero_add]
        exact lt_of_le_of_ne bot_le (Ne.symm (mt degree_eq_bot.1 <| by simpa using h'))
      else by
        have hXp0 : divX p ≠ 0 := by
          simpa [divX_eq_zero_iff, -not_le, degree_le_zero_iff] using h
        

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
hp0 : p ≠ 0
this : Nontrivial R
h : ¬degree p ≤ 0
hXp0 : divX p ≠ 0
⊢ degree (divX p) < degree (divX p * X + C (coeff p 0))

Next tactic:
have : leadingCoeff (divX p) * leadingCoeff X ≠ 0 := by simpa
theorem degree_divX_lt (hp0 : p ≠ 0) : (divX p).degree < p.degree := by
  haveI := Nontrivial.of_polynomial_ne hp0
  calc
    degree (divX p) < (divX p * X + C (p.coeff 0)).degree :=
      if h : degree p ≤ 0 then by
        have h' : C (p.coeff 0) ≠ 0 := by rwa [← eq_C_of_degree_le_zero h]
        rw [eq_C_of_degree_le_zero h, divX_C, degree_zero, zero_mul, zero_add]
        exact lt_of_le_of_ne bot_le (Ne.symm (mt degree_eq_bot.1 <| by simpa using h'))
      else by
        have hXp0 : divX p ≠ 0 := by
          simpa [divX_eq_zero_iff, -not_le, degree_le_zero_iff] using h
        have : leadingCoeff (divX p) * leadingCoeff X ≠ 0 := by 

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
hp0 : p ≠ 0
this : Nontrivial R
h : ¬degree p ≤ 0
hXp0 : divX p ≠ 0
⊢ leadingCoeff (divX p) * leadingCoeff X ≠ 0

Next tactic:
simpa
theorem degree_divX_lt (hp0 : p ≠ 0) : (divX p).degree < p.degree := by
  haveI := Nontrivial.of_polynomial_ne hp0
  calc
    degree (divX p) < (divX p * X + C (p.coeff 0)).degree :=
      if h : degree p ≤ 0 then by
        have h' : C (p.coeff 0) ≠ 0 := by rwa [← eq_C_of_degree_le_zero h]
        rw [eq_C_of_degree_le_zero h, divX_C, degree_zero, zero_mul, zero_add]
        exact lt_of_le_of_ne bot_le (Ne.symm (mt degree_eq_bot.1 <| by simpa using h'))
      else by
        have hXp0 : divX p ≠ 0 := by
          simpa [divX_eq_zero_iff, -not_le, degree_le_zero_iff] using h
        have : leadingCoeff (divX p) * leadingCoeff X ≠ 0 := by simpa
        

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
hp0 : p ≠ 0
this✝ : Nontrivial R
h : ¬degree p ≤ 0
hXp0 : divX p ≠ 0
this : leadingCoeff (divX p) * leadingCoeff X ≠ 0
⊢ degree (divX p) < degree (divX p * X + C (coeff p 0))

Next tactic:
have : degree (C (p.coeff 0)) < degree (divX p * X) :=
          calc
            degree (C (p.coeff 0)) ≤ 0 := degree_C_le
            _ < 1 := by decide
            _ = degree (X : R[X]) := degree_X.symm
            _ ≤ degree (divX p * X) := by
              rw [← zero_add (degree X), degree_mul' this]
              exact add_le_add
                (by rw [zero_le_degree_iff, Ne.def, divX_eq_zero_iff]
                    exact fun h0 => h (h0.symm ▸ degree_C_le))
                    le_rfl
theorem degree_divX_lt (hp0 : p ≠ 0) : (divX p).degree < p.degree := by
  haveI := Nontrivial.of_polynomial_ne hp0
  calc
    degree (divX p) < (divX p * X + C (p.coeff 0)).degree :=
      if h : degree p ≤ 0 then by
        have h' : C (p.coeff 0) ≠ 0 := by rwa [← eq_C_of_degree_le_zero h]
        rw [eq_C_of_degree_le_zero h, divX_C, degree_zero, zero_mul, zero_add]
        exact lt_of_le_of_ne bot_le (Ne.symm (mt degree_eq_bot.1 <| by simpa using h'))
      else by
        have hXp0 : divX p ≠ 0 := by
          simpa [divX_eq_zero_iff, -not_le, degree_le_zero_iff] using h
        have : leadingCoeff (divX p) * leadingCoeff X ≠ 0 := by simpa
        have : degree (C (p.coeff 0)) < degree (divX p * X) :=
          calc
            degree (C (p.coeff 0)) ≤ 0 := degree_C_le
            _ < 1 := by 

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
hp0 : p ≠ 0
this✝ : Nontrivial R
h : ¬degree p ≤ 0
hXp0 : divX p ≠ 0
this : leadingCoeff (divX p) * leadingCoeff X ≠ 0
⊢ 0 < 1

Next tactic:
decide
theorem degree_divX_lt (hp0 : p ≠ 0) : (divX p).degree < p.degree := by
  haveI := Nontrivial.of_polynomial_ne hp0
  calc
    degree (divX p) < (divX p * X + C (p.coeff 0)).degree :=
      if h : degree p ≤ 0 then by
        have h' : C (p.coeff 0) ≠ 0 := by rwa [← eq_C_of_degree_le_zero h]
        rw [eq_C_of_degree_le_zero h, divX_C, degree_zero, zero_mul, zero_add]
        exact lt_of_le_of_ne bot_le (Ne.symm (mt degree_eq_bot.1 <| by simpa using h'))
      else by
        have hXp0 : divX p ≠ 0 := by
          simpa [divX_eq_zero_iff, -not_le, degree_le_zero_iff] using h
        have : leadingCoeff (divX p) * leadingCoeff X ≠ 0 := by simpa
        have : degree (C (p.coeff 0)) < degree (divX p * X) :=
          calc
            degree (C (p.coeff 0)) ≤ 0 := degree_C_le
            _ < 1 := by decide
            _ = degree (X : R[X]) := degree_X.symm
            _ ≤ degree (divX p * X) := by
              

Proof state:
R : Type u
S : Type v
T : Type w
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
hp0 : p ≠ 0
this✝ : Nontrivial R
h : ¬degree p ≤ 0
hXp0 : divX p ≠ 0
this : leadingCoeff (divX p) * leadingCoeff X ≠ 0
⊢ degree X ≤ degree (divX p * X)

Next tactic:
rw [← zero_add (degree X), degree_mul' this]