l3lab/ntp-mathlib huggingface dataset:
theorem coeff_mirror (n : ℕ) :
    p.mirror.coeff n = p.coeff (revAt (p.natDegree + p.natTrailingDegree) n) := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
⊢ coeff (mirror p) n = coeff p ((revAt (natDegree p + natTrailingDegree p)) n)

Next tactic:
by_cases h2 : p.natDegree < n
theorem coeff_mirror (n : ℕ) :
    p.mirror.coeff n = p.coeff (revAt (p.natDegree + p.natTrailingDegree) n) := by
  by_cases h2 : p.natDegree < n
  · 

Proof state:
case pos
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
h2 : natDegree p < n
⊢ coeff (mirror p) n = coeff p ((revAt (natDegree p + natTrailingDegree p)) n)

Next tactic:
rw [coeff_eq_zero_of_natDegree_lt (by rwa [mirror_natDegree])]
theorem coeff_mirror (n : ℕ) :
    p.mirror.coeff n = p.coeff (revAt (p.natDegree + p.natTrailingDegree) n) := by
  by_cases h2 : p.natDegree < n
  · rw [coeff_eq_zero_of_natDegree_lt (by 

Proof state:
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
h2 : natDegree p < n
⊢ natDegree (mirror p) < n

Next tactic:
rwa [mirror_natDegree]
theorem coeff_mirror (n : ℕ) :
    p.mirror.coeff n = p.coeff (revAt (p.natDegree + p.natTrailingDegree) n) := by
  by_cases h2 : p.natDegree < n
  · rw [coeff_eq_zero_of_natDegree_lt (by rwa [mirror_natDegree])]
    

Proof state:
case pos
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
h2 : natDegree p < n
⊢ 0 = coeff p ((revAt (natDegree p + natTrailingDegree p)) n)

Next tactic:
by_cases h1 : n ≤ p.natDegree + p.natTrailingDegree
theorem coeff_mirror (n : ℕ) :
    p.mirror.coeff n = p.coeff (revAt (p.natDegree + p.natTrailingDegree) n) := by
  by_cases h2 : p.natDegree < n
  · rw [coeff_eq_zero_of_natDegree_lt (by rwa [mirror_natDegree])]
    by_cases h1 : n ≤ p.natDegree + p.natTrailingDegree
    · 

Proof state:
case pos
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
h2 : natDegree p < n
h1 : n ≤ natDegree p + natTrailingDegree p
⊢ 0 = coeff p ((revAt (natDegree p + natTrailingDegree p)) n)

Next tactic:
rw [revAt_le h1, coeff_eq_zero_of_lt_natTrailingDegree]
theorem coeff_mirror (n : ℕ) :
    p.mirror.coeff n = p.coeff (revAt (p.natDegree + p.natTrailingDegree) n) := by
  by_cases h2 : p.natDegree < n
  · rw [coeff_eq_zero_of_natDegree_lt (by rwa [mirror_natDegree])]
    by_cases h1 : n ≤ p.natDegree + p.natTrailingDegree
    · rw [revAt_le h1, coeff_eq_zero_of_lt_natTrailingDegree]
      

Proof state:
case pos
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
h2 : natDegree p < n
h1 : n ≤ natDegree p + natTrailingDegree p
⊢ natDegree p + natTrailingDegree p - n < natTrailingDegree p

Next tactic:
exact (tsub_lt_iff_left h1).mpr (Nat.add_lt_add_right h2 _)
theorem coeff_mirror (n : ℕ) :
    p.mirror.coeff n = p.coeff (revAt (p.natDegree + p.natTrailingDegree) n) := by
  by_cases h2 : p.natDegree < n
  · rw [coeff_eq_zero_of_natDegree_lt (by rwa [mirror_natDegree])]
    by_cases h1 : n ≤ p.natDegree + p.natTrailingDegree
    · rw [revAt_le h1, coeff_eq_zero_of_lt_natTrailingDegree]
      exact (tsub_lt_iff_left h1).mpr (Nat.add_lt_add_right h2 _)
    · 

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
h2 : natDegree p < n
h1 : ¬n ≤ natDegree p + natTrailingDegree p
⊢ 0 = coeff p ((revAt (natDegree p + natTrailingDegree p)) n)

Next tactic:
rw [← revAtFun_eq, revAtFun, if_neg h1, coeff_eq_zero_of_natDegree_lt h2]
theorem coeff_mirror (n : ℕ) :
    p.mirror.coeff n = p.coeff (revAt (p.natDegree + p.natTrailingDegree) n) := by
  by_cases h2 : p.natDegree < n
  · rw [coeff_eq_zero_of_natDegree_lt (by rwa [mirror_natDegree])]
    by_cases h1 : n ≤ p.natDegree + p.natTrailingDegree
    · rw [revAt_le h1, coeff_eq_zero_of_lt_natTrailingDegree]
      exact (tsub_lt_iff_left h1).mpr (Nat.add_lt_add_right h2 _)
    · rw [← revAtFun_eq, revAtFun, if_neg h1, coeff_eq_zero_of_natDegree_lt h2]
  

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
h2 : ¬natDegree p < n
⊢ coeff (mirror p) n = coeff p ((revAt (natDegree p + natTrailingDegree p)) n)

Next tactic:
rw [not_lt] at h2
theorem coeff_mirror (n : ℕ) :
    p.mirror.coeff n = p.coeff (revAt (p.natDegree + p.natTrailingDegree) n) := by
  by_cases h2 : p.natDegree < n
  · rw [coeff_eq_zero_of_natDegree_lt (by rwa [mirror_natDegree])]
    by_cases h1 : n ≤ p.natDegree + p.natTrailingDegree
    · rw [revAt_le h1, coeff_eq_zero_of_lt_natTrailingDegree]
      exact (tsub_lt_iff_left h1).mpr (Nat.add_lt_add_right h2 _)
    · rw [← revAtFun_eq, revAtFun, if_neg h1, coeff_eq_zero_of_natDegree_lt h2]
  rw [not_lt] at h2
  

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
h2 : n ≤ natDegree p
⊢ coeff (mirror p) n = coeff p ((revAt (natDegree p + natTrailingDegree p)) n)

Next tactic:
rw [revAt_le (h2.trans (Nat.le_add_right _ _))]
theorem coeff_mirror (n : ℕ) :
    p.mirror.coeff n = p.coeff (revAt (p.natDegree + p.natTrailingDegree) n) := by
  by_cases h2 : p.natDegree < n
  · rw [coeff_eq_zero_of_natDegree_lt (by rwa [mirror_natDegree])]
    by_cases h1 : n ≤ p.natDegree + p.natTrailingDegree
    · rw [revAt_le h1, coeff_eq_zero_of_lt_natTrailingDegree]
      exact (tsub_lt_iff_left h1).mpr (Nat.add_lt_add_right h2 _)
    · rw [← revAtFun_eq, revAtFun, if_neg h1, coeff_eq_zero_of_natDegree_lt h2]
  rw [not_lt] at h2
  rw [revAt_le (h2.trans (Nat.le_add_right _ _))]
  

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
h2 : n ≤ natDegree p
⊢ coeff (mirror p) n = coeff p (natDegree p + natTrailingDegree p - n)

Next tactic:
by_cases h3 : p.natTrailingDegree ≤ n
theorem coeff_mirror (n : ℕ) :
    p.mirror.coeff n = p.coeff (revAt (p.natDegree + p.natTrailingDegree) n) := by
  by_cases h2 : p.natDegree < n
  · rw [coeff_eq_zero_of_natDegree_lt (by rwa [mirror_natDegree])]
    by_cases h1 : n ≤ p.natDegree + p.natTrailingDegree
    · rw [revAt_le h1, coeff_eq_zero_of_lt_natTrailingDegree]
      exact (tsub_lt_iff_left h1).mpr (Nat.add_lt_add_right h2 _)
    · rw [← revAtFun_eq, revAtFun, if_neg h1, coeff_eq_zero_of_natDegree_lt h2]
  rw [not_lt] at h2
  rw [revAt_le (h2.trans (Nat.le_add_right _ _))]
  by_cases h3 : p.natTrailingDegree ≤ n
  · 

Proof state:
case pos
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
h2 : n ≤ natDegree p
h3 : natTrailingDegree p ≤ n
⊢ coeff (mirror p) n = coeff p (natDegree p + natTrailingDegree p - n)

Next tactic:
rw [← tsub_add_eq_add_tsub h2, ← tsub_tsub_assoc h2 h3, mirror, coeff_mul_X_pow', if_pos h3,
      coeff_reverse, revAt_le (tsub_le_self.trans h2)]
theorem coeff_mirror (n : ℕ) :
    p.mirror.coeff n = p.coeff (revAt (p.natDegree + p.natTrailingDegree) n) := by
  by_cases h2 : p.natDegree < n
  · rw [coeff_eq_zero_of_natDegree_lt (by rwa [mirror_natDegree])]
    by_cases h1 : n ≤ p.natDegree + p.natTrailingDegree
    · rw [revAt_le h1, coeff_eq_zero_of_lt_natTrailingDegree]
      exact (tsub_lt_iff_left h1).mpr (Nat.add_lt_add_right h2 _)
    · rw [← revAtFun_eq, revAtFun, if_neg h1, coeff_eq_zero_of_natDegree_lt h2]
  rw [not_lt] at h2
  rw [revAt_le (h2.trans (Nat.le_add_right _ _))]
  by_cases h3 : p.natTrailingDegree ≤ n
  · rw [← tsub_add_eq_add_tsub h2, ← tsub_tsub_assoc h2 h3, mirror, coeff_mul_X_pow', if_pos h3,
      coeff_reverse, revAt_le (tsub_le_self.trans h2)]
  

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
h2 : n ≤ natDegree p
h3 : ¬natTrailingDegree p ≤ n
⊢ coeff (mirror p) n = coeff p (natDegree p + natTrailingDegree p - n)

Next tactic:
rw [not_le] at h3
theorem coeff_mirror (n : ℕ) :
    p.mirror.coeff n = p.coeff (revAt (p.natDegree + p.natTrailingDegree) n) := by
  by_cases h2 : p.natDegree < n
  · rw [coeff_eq_zero_of_natDegree_lt (by rwa [mirror_natDegree])]
    by_cases h1 : n ≤ p.natDegree + p.natTrailingDegree
    · rw [revAt_le h1, coeff_eq_zero_of_lt_natTrailingDegree]
      exact (tsub_lt_iff_left h1).mpr (Nat.add_lt_add_right h2 _)
    · rw [← revAtFun_eq, revAtFun, if_neg h1, coeff_eq_zero_of_natDegree_lt h2]
  rw [not_lt] at h2
  rw [revAt_le (h2.trans (Nat.le_add_right _ _))]
  by_cases h3 : p.natTrailingDegree ≤ n
  · rw [← tsub_add_eq_add_tsub h2, ← tsub_tsub_assoc h2 h3, mirror, coeff_mul_X_pow', if_pos h3,
      coeff_reverse, revAt_le (tsub_le_self.trans h2)]
  rw [not_le] at h3
  

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
h2 : n ≤ natDegree p
h3 : n < natTrailingDegree p
⊢ coeff (mirror p) n = coeff p (natDegree p + natTrailingDegree p - n)

Next tactic:
rw [coeff_eq_zero_of_natDegree_lt (lt_tsub_iff_right.mpr (Nat.add_lt_add_left h3 _))]
theorem coeff_mirror (n : ℕ) :
    p.mirror.coeff n = p.coeff (revAt (p.natDegree + p.natTrailingDegree) n) := by
  by_cases h2 : p.natDegree < n
  · rw [coeff_eq_zero_of_natDegree_lt (by rwa [mirror_natDegree])]
    by_cases h1 : n ≤ p.natDegree + p.natTrailingDegree
    · rw [revAt_le h1, coeff_eq_zero_of_lt_natTrailingDegree]
      exact (tsub_lt_iff_left h1).mpr (Nat.add_lt_add_right h2 _)
    · rw [← revAtFun_eq, revAtFun, if_neg h1, coeff_eq_zero_of_natDegree_lt h2]
  rw [not_lt] at h2
  rw [revAt_le (h2.trans (Nat.le_add_right _ _))]
  by_cases h3 : p.natTrailingDegree ≤ n
  · rw [← tsub_add_eq_add_tsub h2, ← tsub_tsub_assoc h2 h3, mirror, coeff_mul_X_pow', if_pos h3,
      coeff_reverse, revAt_le (tsub_le_self.trans h2)]
  rw [not_le] at h3
  rw [coeff_eq_zero_of_natDegree_lt (lt_tsub_iff_right.mpr (Nat.add_lt_add_left h3 _))]
  

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
h2 : n ≤ natDegree p
h3 : n < natTrailingDegree p
⊢ coeff (mirror p) n = 0

Next tactic:
exact coeff_eq_zero_of_lt_natTrailingDegree (by rwa [mirror_natTrailingDegree])
theorem coeff_mirror (n : ℕ) :
    p.mirror.coeff n = p.coeff (revAt (p.natDegree + p.natTrailingDegree) n) := by
  by_cases h2 : p.natDegree < n
  · rw [coeff_eq_zero_of_natDegree_lt (by rwa [mirror_natDegree])]
    by_cases h1 : n ≤ p.natDegree + p.natTrailingDegree
    · rw [revAt_le h1, coeff_eq_zero_of_lt_natTrailingDegree]
      exact (tsub_lt_iff_left h1).mpr (Nat.add_lt_add_right h2 _)
    · rw [← revAtFun_eq, revAtFun, if_neg h1, coeff_eq_zero_of_natDegree_lt h2]
  rw [not_lt] at h2
  rw [revAt_le (h2.trans (Nat.le_add_right _ _))]
  by_cases h3 : p.natTrailingDegree ≤ n
  · rw [← tsub_add_eq_add_tsub h2, ← tsub_tsub_assoc h2 h3, mirror, coeff_mul_X_pow', if_pos h3,
      coeff_reverse, revAt_le (tsub_le_self.trans h2)]
  rw [not_le] at h3
  rw [coeff_eq_zero_of_natDegree_lt (lt_tsub_iff_right.mpr (Nat.add_lt_add_left h3 _))]
  exact coeff_eq_zero_of_lt_natTrailingDegree (by 

Proof state:
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
h2 : n ≤ natDegree p
h3 : n < natTrailingDegree p
⊢ n < natTrailingDegree (mirror p)

Next tactic:
rwa [mirror_natTrailingDegree]
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
p q : R[X]
⊢ eval 1 (mirror p) = eval 1 p

Next tactic:
simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
  

Proof state:
R : Type u_1
inst✝ : Semiring R
p q : R[X]
⊢ (Finset.sum (Finset.range (natDegree p + 1)) fun x => coeff (mirror p) x) =
    Finset.sum (Finset.range (natDegree p + 1)) fun x => coeff p x

Next tactic:
refine' Finset.sum_bij_ne_zero _ _ _ _ _
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
  refine' Finset.sum_bij_ne_zero _ _ _ _ _
  · 

Proof state:
case refine'_1
R : Type u_1
inst✝ : Semiring R
p q : R[X]
⊢ (a : ℕ) → a ∈ Finset.range (natDegree p + 1) → coeff (mirror p) a ≠ 0 → ℕ

Next tactic:
exact fun n _ _ => revAt (p.natDegree + p.natTrailingDegree) n
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
  refine' Finset.sum_bij_ne_zero _ _ _ _ _
  · exact fun n _ _ => revAt (p.natDegree + p.natTrailingDegree) n
  · 

Proof state:
case refine'_2
R : Type u_1
inst✝ : Semiring R
p q : R[X]
⊢ ∀ a ∈ Finset.range (natDegree p + 1),
    coeff (mirror p) a ≠ 0 → (revAt (natDegree p + natTrailingDegree p)) a ∈ Finset.range (natDegree p + 1)

Next tactic:
intro n hn hp
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
  refine' Finset.sum_bij_ne_zero _ _ _ _ _
  · exact fun n _ _ => revAt (p.natDegree + p.natTrailingDegree) n
  · intro n hn hp
    

Proof state:
case refine'_2
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
hn : n ∈ Finset.range (natDegree p + 1)
hp : coeff (mirror p) n ≠ 0
⊢ (revAt (natDegree p + natTrailingDegree p)) n ∈ Finset.range (natDegree p + 1)

Next tactic:
rw [Finset.mem_range_succ_iff] at *
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
  refine' Finset.sum_bij_ne_zero _ _ _ _ _
  · exact fun n _ _ => revAt (p.natDegree + p.natTrailingDegree) n
  · intro n hn hp
    rw [Finset.mem_range_succ_iff] at *
    

Proof state:
case refine'_2
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
hn : n ≤ natDegree p
hp : coeff (mirror p) n ≠ 0
⊢ (revAt (natDegree p + natTrailingDegree p)) n ≤ natDegree p

Next tactic:
rw [revAt_le (hn.trans (Nat.le_add_right _ _))]
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
  refine' Finset.sum_bij_ne_zero _ _ _ _ _
  · exact fun n _ _ => revAt (p.natDegree + p.natTrailingDegree) n
  · intro n hn hp
    rw [Finset.mem_range_succ_iff] at *
    rw [revAt_le (hn.trans (Nat.le_add_right _ _))]
    

Proof state:
case refine'_2
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
hn : n ≤ natDegree p
hp : coeff (mirror p) n ≠ 0
⊢ natDegree p + natTrailingDegree p - n ≤ natDegree p

Next tactic:
rw [tsub_le_iff_tsub_le, add_comm, add_tsub_cancel_right, ← mirror_natTrailingDegree]
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
  refine' Finset.sum_bij_ne_zero _ _ _ _ _
  · exact fun n _ _ => revAt (p.natDegree + p.natTrailingDegree) n
  · intro n hn hp
    rw [Finset.mem_range_succ_iff] at *
    rw [revAt_le (hn.trans (Nat.le_add_right _ _))]
    rw [tsub_le_iff_tsub_le, add_comm, add_tsub_cancel_right, ← mirror_natTrailingDegree]
    

Proof state:
case refine'_2
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
hn : n ≤ natDegree p
hp : coeff (mirror p) n ≠ 0
⊢ natTrailingDegree (mirror p) ≤ n

Next tactic:
exact natTrailingDegree_le_of_ne_zero hp
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
  refine' Finset.sum_bij_ne_zero _ _ _ _ _
  · exact fun n _ _ => revAt (p.natDegree + p.natTrailingDegree) n
  · intro n hn hp
    rw [Finset.mem_range_succ_iff] at *
    rw [revAt_le (hn.trans (Nat.le_add_right _ _))]
    rw [tsub_le_iff_tsub_le, add_comm, add_tsub_cancel_right, ← mirror_natTrailingDegree]
    exact natTrailingDegree_le_of_ne_zero hp
  · 

Proof state:
case refine'_3
R : Type u_1
inst✝ : Semiring R
p q : R[X]
⊢ ∀ (a₁ a₂ : ℕ),
    a₁ ∈ Finset.range (natDegree p + 1) →
      coeff (mirror p) a₁ ≠ 0 →
        a₂ ∈ Finset.range (natDegree p + 1) →
          coeff (mirror p) a₂ ≠ 0 →
            (revAt (natDegree p + natTrailingDegree p)) a₁ = (revAt (natDegree p + natTrailingDegree p)) a₂ → a₁ = a₂

Next tactic:
exact fun n₁ n₂ _ _ _ _ h => by rw [← @revAt_invol _ n₁, h, revAt_invol]
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
  refine' Finset.sum_bij_ne_zero _ _ _ _ _
  · exact fun n _ _ => revAt (p.natDegree + p.natTrailingDegree) n
  · intro n hn hp
    rw [Finset.mem_range_succ_iff] at *
    rw [revAt_le (hn.trans (Nat.le_add_right _ _))]
    rw [tsub_le_iff_tsub_le, add_comm, add_tsub_cancel_right, ← mirror_natTrailingDegree]
    exact natTrailingDegree_le_of_ne_zero hp
  · exact fun n₁ n₂ _ _ _ _ h => by 

Proof state:
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n₁ n₂ : ℕ
x✝³ : n₁ ∈ Finset.range (natDegree p + 1)
x✝² : coeff (mirror p) n₁ ≠ 0
x✝¹ : n₂ ∈ Finset.range (natDegree p + 1)
x✝ : coeff (mirror p) n₂ ≠ 0
h : (revAt (natDegree p + natTrailingDegree p)) n₁ = (revAt (natDegree p + natTrailingDegree p)) n₂
⊢ n₁ = n₂

Next tactic:
rw [← @revAt_invol _ n₁, h, revAt_invol]
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
  refine' Finset.sum_bij_ne_zero _ _ _ _ _
  · exact fun n _ _ => revAt (p.natDegree + p.natTrailingDegree) n
  · intro n hn hp
    rw [Finset.mem_range_succ_iff] at *
    rw [revAt_le (hn.trans (Nat.le_add_right _ _))]
    rw [tsub_le_iff_tsub_le, add_comm, add_tsub_cancel_right, ← mirror_natTrailingDegree]
    exact natTrailingDegree_le_of_ne_zero hp
  · exact fun n₁ n₂ _ _ _ _ h => by rw [← @revAt_invol _ n₁, h, revAt_invol]
  · 

Proof state:
case refine'_4
R : Type u_1
inst✝ : Semiring R
p q : R[X]
⊢ ∀ b ∈ Finset.range (natDegree p + 1),
    coeff p b ≠ 0 →
      ∃ a,
        ∃ (_ : a ∈ Finset.range (natDegree p + 1)) (_ : coeff (mirror p) a ≠ 0),
          b = (revAt (natDegree p + natTrailingDegree p)) a

Next tactic:
intro n hn hp
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
  refine' Finset.sum_bij_ne_zero _ _ _ _ _
  · exact fun n _ _ => revAt (p.natDegree + p.natTrailingDegree) n
  · intro n hn hp
    rw [Finset.mem_range_succ_iff] at *
    rw [revAt_le (hn.trans (Nat.le_add_right _ _))]
    rw [tsub_le_iff_tsub_le, add_comm, add_tsub_cancel_right, ← mirror_natTrailingDegree]
    exact natTrailingDegree_le_of_ne_zero hp
  · exact fun n₁ n₂ _ _ _ _ h => by rw [← @revAt_invol _ n₁, h, revAt_invol]
  · intro n hn hp
    

Proof state:
case refine'_4
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
hn : n ∈ Finset.range (natDegree p + 1)
hp : coeff p n ≠ 0
⊢ ∃ a,
    ∃ (_ : a ∈ Finset.range (natDegree p + 1)) (_ : coeff (mirror p) a ≠ 0),
      n = (revAt (natDegree p + natTrailingDegree p)) a

Next tactic:
use revAt (p.natDegree + p.natTrailingDegree) n
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
  refine' Finset.sum_bij_ne_zero _ _ _ _ _
  · exact fun n _ _ => revAt (p.natDegree + p.natTrailingDegree) n
  · intro n hn hp
    rw [Finset.mem_range_succ_iff] at *
    rw [revAt_le (hn.trans (Nat.le_add_right _ _))]
    rw [tsub_le_iff_tsub_le, add_comm, add_tsub_cancel_right, ← mirror_natTrailingDegree]
    exact natTrailingDegree_le_of_ne_zero hp
  · exact fun n₁ n₂ _ _ _ _ h => by rw [← @revAt_invol _ n₁, h, revAt_invol]
  · intro n hn hp
    use revAt (p.natDegree + p.natTrailingDegree) n
    

Proof state:
case h
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
hn : n ∈ Finset.range (natDegree p + 1)
hp : coeff p n ≠ 0
⊢ ∃ (_ : (revAt (natDegree p + natTrailingDegree p)) n ∈ Finset.range (natDegree p + 1)) (_ :
    coeff (mirror p) ((revAt (natDegree p + natTrailingDegree p)) n) ≠ 0),
    n = (revAt (natDegree p + natTrailingDegree p)) ((revAt (natDegree p + natTrailingDegree p)) n)

Next tactic:
refine' ⟨_, _, revAt_invol.symm⟩
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
  refine' Finset.sum_bij_ne_zero _ _ _ _ _
  · exact fun n _ _ => revAt (p.natDegree + p.natTrailingDegree) n
  · intro n hn hp
    rw [Finset.mem_range_succ_iff] at *
    rw [revAt_le (hn.trans (Nat.le_add_right _ _))]
    rw [tsub_le_iff_tsub_le, add_comm, add_tsub_cancel_right, ← mirror_natTrailingDegree]
    exact natTrailingDegree_le_of_ne_zero hp
  · exact fun n₁ n₂ _ _ _ _ h => by rw [← @revAt_invol _ n₁, h, revAt_invol]
  · intro n hn hp
    use revAt (p.natDegree + p.natTrailingDegree) n
    refine' ⟨_, _, revAt_invol.symm⟩
    · 

Proof state:
case h.refine'_1
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
hn : n ∈ Finset.range (natDegree p + 1)
hp : coeff p n ≠ 0
⊢ (revAt (natDegree p + natTrailingDegree p)) n ∈ Finset.range (natDegree p + 1)

Next tactic:
rw [Finset.mem_range_succ_iff] at *
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
  refine' Finset.sum_bij_ne_zero _ _ _ _ _
  · exact fun n _ _ => revAt (p.natDegree + p.natTrailingDegree) n
  · intro n hn hp
    rw [Finset.mem_range_succ_iff] at *
    rw [revAt_le (hn.trans (Nat.le_add_right _ _))]
    rw [tsub_le_iff_tsub_le, add_comm, add_tsub_cancel_right, ← mirror_natTrailingDegree]
    exact natTrailingDegree_le_of_ne_zero hp
  · exact fun n₁ n₂ _ _ _ _ h => by rw [← @revAt_invol _ n₁, h, revAt_invol]
  · intro n hn hp
    use revAt (p.natDegree + p.natTrailingDegree) n
    refine' ⟨_, _, revAt_invol.symm⟩
    · rw [Finset.mem_range_succ_iff] at *
      

Proof state:
case h.refine'_1
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
hn : n ≤ natDegree p
hp : coeff p n ≠ 0
⊢ (revAt (natDegree p + natTrailingDegree p)) n ≤ natDegree p

Next tactic:
rw [revAt_le (hn.trans (Nat.le_add_right _ _))]
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
  refine' Finset.sum_bij_ne_zero _ _ _ _ _
  · exact fun n _ _ => revAt (p.natDegree + p.natTrailingDegree) n
  · intro n hn hp
    rw [Finset.mem_range_succ_iff] at *
    rw [revAt_le (hn.trans (Nat.le_add_right _ _))]
    rw [tsub_le_iff_tsub_le, add_comm, add_tsub_cancel_right, ← mirror_natTrailingDegree]
    exact natTrailingDegree_le_of_ne_zero hp
  · exact fun n₁ n₂ _ _ _ _ h => by rw [← @revAt_invol _ n₁, h, revAt_invol]
  · intro n hn hp
    use revAt (p.natDegree + p.natTrailingDegree) n
    refine' ⟨_, _, revAt_invol.symm⟩
    · rw [Finset.mem_range_succ_iff] at *
      rw [revAt_le (hn.trans (Nat.le_add_right _ _))]
      

Proof state:
case h.refine'_1
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
hn : n ≤ natDegree p
hp : coeff p n ≠ 0
⊢ natDegree p + natTrailingDegree p - n ≤ natDegree p

Next tactic:
rw [tsub_le_iff_tsub_le, add_comm, add_tsub_cancel_right]
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
  refine' Finset.sum_bij_ne_zero _ _ _ _ _
  · exact fun n _ _ => revAt (p.natDegree + p.natTrailingDegree) n
  · intro n hn hp
    rw [Finset.mem_range_succ_iff] at *
    rw [revAt_le (hn.trans (Nat.le_add_right _ _))]
    rw [tsub_le_iff_tsub_le, add_comm, add_tsub_cancel_right, ← mirror_natTrailingDegree]
    exact natTrailingDegree_le_of_ne_zero hp
  · exact fun n₁ n₂ _ _ _ _ h => by rw [← @revAt_invol _ n₁, h, revAt_invol]
  · intro n hn hp
    use revAt (p.natDegree + p.natTrailingDegree) n
    refine' ⟨_, _, revAt_invol.symm⟩
    · rw [Finset.mem_range_succ_iff] at *
      rw [revAt_le (hn.trans (Nat.le_add_right _ _))]
      rw [tsub_le_iff_tsub_le, add_comm, add_tsub_cancel_right]
      

Proof state:
case h.refine'_1
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
hn : n ≤ natDegree p
hp : coeff p n ≠ 0
⊢ natTrailingDegree p ≤ n

Next tactic:
exact natTrailingDegree_le_of_ne_zero hp
theorem mirror_eval_one : p.mirror.eval 1 = p.eval 1 := by
  simp_rw [eval_eq_sum_range, one_pow, mul_one, mirror_natDegree]
  refine' Finset.sum_bij_ne_zero _ _ _ _ _
  · exact fun n _ _ => revAt (p.natDegree + p.natTrailingDegree) n
  · intro n hn hp
    rw [Finset.mem_range_succ_iff] at *
    rw [revAt_le (hn.trans (Nat.le_add_right _ _))]
    rw [tsub_le_iff_tsub_le, add_comm, add_tsub_cancel_right, ← mirror_natTrailingDegree]
    exact natTrailingDegree_le_of_ne_zero hp
  · exact fun n₁ n₂ _ _ _ _ h => by rw [← @revAt_invol _ n₁, h, revAt_invol]
  · intro n hn hp
    use revAt (p.natDegree + p.natTrailingDegree) n
    refine' ⟨_, _, revAt_invol.symm⟩
    · rw [Finset.mem_range_succ_iff] at *
      rw [revAt_le (hn.trans (Nat.le_add_right _ _))]
      rw [tsub_le_iff_tsub_le, add_comm, add_tsub_cancel_right]
      exact natTrailingDegree_le_of_ne_zero hp
    · 

Proof state:
case h.refine'_2
R : Type u_1
inst✝ : Semiring R
p q : R[X]
n : ℕ
hn : n ∈ Finset.range (natDegree p + 1)
hp : coeff p n ≠ 0
⊢ coeff (mirror p) ((revAt (natDegree p + natTrailingDegree p)) n) ≠ 0

Next tactic:
change p.mirror.coeff _ ≠ 0