l3lab/ntp-mathlib huggingface dataset:
theorem mem_iff_boolIndicator (x : α) : x ∈ s ↔ s.boolIndicator x = true := by
  unfold boolIndicator
  split_ifs with h <;> 

Proof state:
case pos
α : Type u_1
s : Set α
x : α
h : x ∈ s
⊢ x ∈ s ↔ true = true

Next tactic:
simp [h]
theorem mem_iff_boolIndicator (x : α) : x ∈ s ↔ s.boolIndicator x = true := by
  unfold boolIndicator
  split_ifs with h <;> 

Proof state:
case neg
α : Type u_1
s : Set α
x : α
h : x ∉ s
⊢ x ∈ s ↔ False

Next tactic:
simp [h]
theorem not_mem_iff_boolIndicator (x : α) : x ∉ s ↔ s.boolIndicator x = false := by
  

Proof state:
α : Type u_1
s : Set α
x : α
⊢ x ∉ s ↔ boolIndicator s x = false

Next tactic:
unfold boolIndicator
theorem not_mem_iff_boolIndicator (x : α) : x ∉ s ↔ s.boolIndicator x = false := by
  unfold boolIndicator
  

Proof state:
α : Type u_1
s : Set α
x : α
⊢ x ∉ s ↔ (if x ∈ s then true else false) = false

Next tactic:
split_ifs with h
theorem not_mem_iff_boolIndicator (x : α) : x ∉ s ↔ s.boolIndicator x = false := by
  unfold boolIndicator
  split_ifs with h <;> 

Proof state:
case pos
α : Type u_1
s : Set α
x : α
h : x ∈ s
⊢ x ∉ s ↔ False

Next tactic:
simp [h]
theorem not_mem_iff_boolIndicator (x : α) : x ∉ s ↔ s.boolIndicator x = false := by
  unfold boolIndicator
  split_ifs with h <;> 

Proof state:
case neg
α : Type u_1
s : Set α
x : α
h : x ∉ s
⊢ x ∉ s ↔ false = false

Next tactic:
simp [h]
theorem preimage_boolIndicator_eq_union (t : Set Bool) :
    s.boolIndicator ⁻¹' t = (if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅ := by
  

Proof state:
α : Type u_1
s : Set α
t : Set Bool
⊢ boolIndicator s ⁻¹' t = (if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅

Next tactic:
ext x
theorem preimage_boolIndicator_eq_union (t : Set Bool) :
    s.boolIndicator ⁻¹' t = (if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅ := by
  ext x
  

Proof state:
case h
α : Type u_1
s : Set α
t : Set Bool
x : α
⊢ x ∈ boolIndicator s ⁻¹' t ↔ x ∈ (if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅

Next tactic:
simp only [boolIndicator, mem_preimage]
theorem preimage_boolIndicator_eq_union (t : Set Bool) :
    s.boolIndicator ⁻¹' t = (if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅ := by
  ext x
  simp only [boolIndicator, mem_preimage]
  

Proof state:
case h
α : Type u_1
s : Set α
t : Set Bool
x : α
⊢ (if x ∈ s then true else false) ∈ t ↔ x ∈ (if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅

Next tactic:
split_ifs
theorem preimage_boolIndicator_eq_union (t : Set Bool) :
    s.boolIndicator ⁻¹' t = (if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅ := by
  ext x
  simp only [boolIndicator, mem_preimage]
  split_ifs <;> 

Proof state:
case pos
α : Type u_1
s : Set α
t : Set Bool
x : α
h✝² : x ∈ s
h✝¹ : true ∈ t
h✝ : false ∈ t
⊢ true ∈ t ↔ x ∈ s ∪ sᶜ

Next tactic:
simp [*]
theorem preimage_boolIndicator_eq_union (t : Set Bool) :
    s.boolIndicator ⁻¹' t = (if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅ := by
  ext x
  simp only [boolIndicator, mem_preimage]
  split_ifs <;> 

Proof state:
case neg
α : Type u_1
s : Set α
t : Set Bool
x : α
h✝² : x ∈ s
h✝¹ : true ∈ t
h✝ : false ∉ t
⊢ true ∈ t ↔ x ∈ s ∪ ∅

Next tactic:
simp [*]
theorem preimage_boolIndicator_eq_union (t : Set Bool) :
    s.boolIndicator ⁻¹' t = (if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅ := by
  ext x
  simp only [boolIndicator, mem_preimage]
  split_ifs <;> 

Proof state:
case pos
α : Type u_1
s : Set α
t : Set Bool
x : α
h✝² : x ∈ s
h✝¹ : true ∉ t
h✝ : false ∈ t
⊢ true ∈ t ↔ x ∈ ∅ ∪ sᶜ

Next tactic:
simp [*]
theorem preimage_boolIndicator_eq_union (t : Set Bool) :
    s.boolIndicator ⁻¹' t = (if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅ := by
  ext x
  simp only [boolIndicator, mem_preimage]
  split_ifs <;> 

Proof state:
case neg
α : Type u_1
s : Set α
t : Set Bool
x : α
h✝² : x ∈ s
h✝¹ : true ∉ t
h✝ : false ∉ t
⊢ true ∈ t ↔ x ∈ ∅ ∪ ∅

Next tactic:
simp [*]
theorem preimage_boolIndicator_eq_union (t : Set Bool) :
    s.boolIndicator ⁻¹' t = (if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅ := by
  ext x
  simp only [boolIndicator, mem_preimage]
  split_ifs <;> 

Proof state:
case pos
α : Type u_1
s : Set α
t : Set Bool
x : α
h✝² : x ∉ s
h✝¹ : true ∈ t
h✝ : false ∈ t
⊢ false ∈ t ↔ x ∈ s ∪ sᶜ

Next tactic:
simp [*]
theorem preimage_boolIndicator_eq_union (t : Set Bool) :
    s.boolIndicator ⁻¹' t = (if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅ := by
  ext x
  simp only [boolIndicator, mem_preimage]
  split_ifs <;> 

Proof state:
case neg
α : Type u_1
s : Set α
t : Set Bool
x : α
h✝² : x ∉ s
h✝¹ : true ∈ t
h✝ : false ∉ t
⊢ false ∈ t ↔ x ∈ s ∪ ∅

Next tactic:
simp [*]
theorem preimage_boolIndicator_eq_union (t : Set Bool) :
    s.boolIndicator ⁻¹' t = (if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅ := by
  ext x
  simp only [boolIndicator, mem_preimage]
  split_ifs <;> 

Proof state:
case pos
α : Type u_1
s : Set α
t : Set Bool
x : α
h✝² : x ∉ s
h✝¹ : true ∉ t
h✝ : false ∈ t
⊢ false ∈ t ↔ x ∈ ∅ ∪ sᶜ

Next tactic:
simp [*]
theorem preimage_boolIndicator_eq_union (t : Set Bool) :
    s.boolIndicator ⁻¹' t = (if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅ := by
  ext x
  simp only [boolIndicator, mem_preimage]
  split_ifs <;> 

Proof state:
case neg
α : Type u_1
s : Set α
t : Set Bool
x : α
h✝² : x ∉ s
h✝¹ : true ∉ t
h✝ : false ∉ t
⊢ false ∈ t ↔ x ∈ ∅ ∪ ∅

Next tactic:
simp [*]
theorem preimage_boolIndicator (t : Set Bool) :
    s.boolIndicator ⁻¹' t = univ ∨
      s.boolIndicator ⁻¹' t = s ∨ s.boolIndicator ⁻¹' t = sᶜ ∨ s.boolIndicator ⁻¹' t = ∅ := by
  

Proof state:
α : Type u_1
s : Set α
t : Set Bool
⊢ boolIndicator s ⁻¹' t = univ ∨ boolIndicator s ⁻¹' t = s ∨ boolIndicator s ⁻¹' t = sᶜ ∨ boolIndicator s ⁻¹' t = ∅

Next tactic:
simp only [preimage_boolIndicator_eq_union]
theorem preimage_boolIndicator (t : Set Bool) :
    s.boolIndicator ⁻¹' t = univ ∨
      s.boolIndicator ⁻¹' t = s ∨ s.boolIndicator ⁻¹' t = sᶜ ∨ s.boolIndicator ⁻¹' t = ∅ := by
  simp only [preimage_boolIndicator_eq_union]
  

Proof state:
α : Type u_1
s : Set α
t : Set Bool
⊢ ((if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅) = univ ∨
    ((if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅) = s ∨
      ((if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅) = sᶜ ∨
        ((if true ∈ t then s else ∅) ∪ if false ∈ t then sᶜ else ∅) = ∅

Next tactic:
split_ifs
theorem preimage_boolIndicator (t : Set Bool) :
    s.boolIndicator ⁻¹' t = univ ∨
      s.boolIndicator ⁻¹' t = s ∨ s.boolIndicator ⁻¹' t = sᶜ ∨ s.boolIndicator ⁻¹' t = ∅ := by
  simp only [preimage_boolIndicator_eq_union]
  split_ifs <;> 

Proof state:
case pos
α : Type u_1
s : Set α
t : Set Bool
h✝¹ : true ∈ t
h✝ : false ∈ t
⊢ s ∪ sᶜ = univ ∨ s ∪ sᶜ = s ∨ s ∪ sᶜ = sᶜ ∨ s ∪ sᶜ = ∅

Next tactic:
simp [s.union_compl_self]
theorem preimage_boolIndicator (t : Set Bool) :
    s.boolIndicator ⁻¹' t = univ ∨
      s.boolIndicator ⁻¹' t = s ∨ s.boolIndicator ⁻¹' t = sᶜ ∨ s.boolIndicator ⁻¹' t = ∅ := by
  simp only [preimage_boolIndicator_eq_union]
  split_ifs <;> 

Proof state:
case neg
α : Type u_1
s : Set α
t : Set Bool
h✝¹ : true ∈ t
h✝ : false ∉ t
⊢ s ∪ ∅ = univ ∨ s ∪ ∅ = s ∨ s ∪ ∅ = sᶜ ∨ s ∪ ∅ = ∅

Next tactic:
simp [s.union_compl_self]
theorem preimage_boolIndicator (t : Set Bool) :
    s.boolIndicator ⁻¹' t = univ ∨
      s.boolIndicator ⁻¹' t = s ∨ s.boolIndicator ⁻¹' t = sᶜ ∨ s.boolIndicator ⁻¹' t = ∅ := by
  simp only [preimage_boolIndicator_eq_union]
  split_ifs <;> 

Proof state:
case pos
α : Type u_1
s : Set α
t : Set Bool
h✝¹ : true ∉ t
h✝ : false ∈ t
⊢ ∅ ∪ sᶜ = univ ∨ ∅ ∪ sᶜ = s ∨ ∅ ∪ sᶜ = sᶜ ∨ ∅ ∪ sᶜ = ∅

Next tactic:
simp [s.union_compl_self]
theorem preimage_boolIndicator (t : Set Bool) :
    s.boolIndicator ⁻¹' t = univ ∨
      s.boolIndicator ⁻¹' t = s ∨ s.boolIndicator ⁻¹' t = sᶜ ∨ s.boolIndicator ⁻¹' t = ∅ := by
  simp only [preimage_boolIndicator_eq_union]
  split_ifs <;> 

Proof state:
case neg
α : Type u_1
s : Set α
t : Set Bool
h✝¹ : true ∉ t
h✝ : false ∉ t
⊢ ∅ ∪ ∅ = univ ∨ ∅ ∪ ∅ = s ∨ ∅ ∪ ∅ = sᶜ ∨ ∅ ∪ ∅ = ∅

Next tactic:
simp [s.union_compl_self]
@[simp]
theorem integralNormalization_zero : integralNormalization (0 : R[X]) = 0 := by
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
⊢ integralNormalization 0 = 0

Next tactic:
simp [integralNormalization]
theorem integralNormalization_coeff {f : R[X]} {i : ℕ} :
    (integralNormalization f).coeff i =
      if f.degree = i then 1 else coeff f i * f.leadingCoeff ^ (f.natDegree - 1 - i) := by
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
f : R[X]
i : ℕ
⊢ coeff (integralNormalization f) i = if degree f = ↑i then 1 else coeff f i * leadingCoeff f ^ (natDegree f - 1 - i)

Next tactic:
have : f.coeff i = 0 → f.degree ≠ i := fun hc hd => coeff_ne_zero_of_eq_degree hd hc
theorem integralNormalization_coeff {f : R[X]} {i : ℕ} :
    (integralNormalization f).coeff i =
      if f.degree = i then 1 else coeff f i * f.leadingCoeff ^ (f.natDegree - 1 - i) := by
  have : f.coeff i = 0 → f.degree ≠ i := fun hc hd => coeff_ne_zero_of_eq_degree hd hc
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
f : R[X]
i : ℕ
this : coeff f i = 0 → degree f ≠ ↑i
⊢ coeff (integralNormalization f) i = if degree f = ↑i then 1 else coeff f i * leadingCoeff f ^ (natDegree f - 1 - i)

Next tactic:
simp (config := { contextual := true }) [integralNormalization, coeff_monomial, this,
    mem_support_iff]
theorem integralNormalization_support {f : R[X]} :
    (integralNormalization f).support ⊆ f.support := by
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
f : R[X]
⊢ support (integralNormalization f) ⊆ support f

Next tactic:
intro
theorem integralNormalization_support {f : R[X]} :
    (integralNormalization f).support ⊆ f.support := by
  intro
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
f : R[X]
a✝ : ℕ
⊢ a✝ ∈ support (integralNormalization f) → a✝ ∈ support f

Next tactic:
simp (config := { contextual := true }) [integralNormalization, coeff_monomial, mem_support_iff]
theorem integralNormalization_coeff_degree {f : R[X]} {i : ℕ} (hi : f.degree = i) :
    (integralNormalization f).coeff i = 1 := by 

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
f : R[X]
i : ℕ
hi : degree f = ↑i
⊢ coeff (integralNormalization f) i = 1

Next tactic:
rw [integralNormalization_coeff, if_pos hi]
theorem integralNormalization_coeff_ne_degree {f : R[X]} {i : ℕ} (hi : f.degree ≠ i) :
    coeff (integralNormalization f) i = coeff f i * f.leadingCoeff ^ (f.natDegree - 1 - i) := by
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
f : R[X]
i : ℕ
hi : degree f ≠ ↑i
⊢ coeff (integralNormalization f) i = coeff f i * leadingCoeff f ^ (natDegree f - 1 - i)

Next tactic:
rw [integralNormalization_coeff, if_neg hi]
@[simp]
theorem support_integralNormalization {f : R[X]} :
    (integralNormalization f).support = f.support := by
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝¹ : Ring R
inst✝ : IsDomain R
f : R[X]
⊢ support (integralNormalization f) = support f

Next tactic:
by_cases hf : f = 0
@[simp]
theorem support_integralNormalization {f : R[X]} :
    (integralNormalization f).support = f.support := by
  by_cases hf : f = 0; · 

Proof state:
case pos
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝¹ : Ring R
inst✝ : IsDomain R
f : R[X]
hf : f = 0
⊢ support (integralNormalization f) = support f

Next tactic:
simp [hf]
@[simp]
theorem support_integralNormalization {f : R[X]} :
    (integralNormalization f).support = f.support := by
  by_cases hf : f = 0; · simp [hf]
  

Proof state:
case neg
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝¹ : Ring R
inst✝ : IsDomain R
f : R[X]
hf : ¬f = 0
⊢ support (integralNormalization f) = support f

Next tactic:
ext i
@[simp]
theorem support_integralNormalization {f : R[X]} :
    (integralNormalization f).support = f.support := by
  by_cases hf : f = 0; · simp [hf]
  ext i
  

Proof state:
case neg.a
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝¹ : Ring R
inst✝ : IsDomain R
f : R[X]
hf : ¬f = 0
i : ℕ
⊢ i ∈ support (integralNormalization f) ↔ i ∈ support f

Next tactic:
refine' ⟨fun h => integralNormalization_support h, _⟩
@[simp]
theorem support_integralNormalization {f : R[X]} :
    (integralNormalization f).support = f.support := by
  by_cases hf : f = 0; · simp [hf]
  ext i
  refine' ⟨fun h => integralNormalization_support h, _⟩
  

Proof state:
case neg.a
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝¹ : Ring R
inst✝ : IsDomain R
f : R[X]
hf : ¬f = 0
i : ℕ
⊢ i ∈ support f → i ∈ support (integralNormalization f)

Next tactic:
simp only [integralNormalization_coeff, mem_support_iff]
@[simp]
theorem support_integralNormalization {f : R[X]} :
    (integralNormalization f).support = f.support := by
  by_cases hf : f = 0; · simp [hf]
  ext i
  refine' ⟨fun h => integralNormalization_support h, _⟩
  simp only [integralNormalization_coeff, mem_support_iff]
  

Proof state:
case neg.a
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝¹ : Ring R
inst✝ : IsDomain R
f : R[X]
hf : ¬f = 0
i : ℕ
⊢ coeff f i ≠ 0 → (if degree f = ↑i then 1 else coeff f i * leadingCoeff f ^ (natDegree f - 1 - i)) ≠ 0

Next tactic:
intro hfi
@[simp]
theorem support_integralNormalization {f : R[X]} :
    (integralNormalization f).support = f.support := by
  by_cases hf : f = 0; · simp [hf]
  ext i
  refine' ⟨fun h => integralNormalization_support h, _⟩
  simp only [integralNormalization_coeff, mem_support_iff]
  intro hfi
  

Proof state:
case neg.a
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝¹ : Ring R
inst✝ : IsDomain R
f : R[X]
hf : ¬f = 0
i : ℕ
hfi : coeff f i ≠ 0
⊢ (if degree f = ↑i then 1 else coeff f i * leadingCoeff f ^ (natDegree f - 1 - i)) ≠ 0

Next tactic:
split_ifs with hi
@[simp]
theorem support_integralNormalization {f : R[X]} :
    (integralNormalization f).support = f.support := by
  by_cases hf : f = 0; · simp [hf]
  ext i
  refine' ⟨fun h => integralNormalization_support h, _⟩
  simp only [integralNormalization_coeff, mem_support_iff]
  intro hfi
  split_ifs with hi <;> 

Proof state:
case pos
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝¹ : Ring R
inst✝ : IsDomain R
f : R[X]
hf : ¬f = 0
i : ℕ
hfi : coeff f i ≠ 0
hi : degree f = ↑i
⊢ 1 ≠ 0

Next tactic:
simp [hf, hfi, hi]
@[simp]
theorem support_integralNormalization {f : R[X]} :
    (integralNormalization f).support = f.support := by
  by_cases hf : f = 0; · simp [hf]
  ext i
  refine' ⟨fun h => integralNormalization_support h, _⟩
  simp only [integralNormalization_coeff, mem_support_iff]
  intro hfi
  split_ifs with hi <;> 

Proof state:
case neg
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝¹ : Ring R
inst✝ : IsDomain R
f : R[X]
hf : ¬f = 0
i : ℕ
hfi : coeff f i ≠ 0
hi : ¬degree f = ↑i
⊢ coeff f i * leadingCoeff f ^ (natDegree f - 1 - i) ≠ 0

Next tactic:
simp [hf, hfi, hi]
theorem integralNormalization_eval₂_eq_zero {p : R[X]} (f : R →+* S) {z : S} (hz : eval₂ f z p = 0)
    (inj : ∀ x : R, f x = 0 → x = 0) :
    eval₂ f (z * f p.leadingCoeff) (integralNormalization p) = 0 :=
  calc
    eval₂ f (z * f p.leadingCoeff) (integralNormalization p) =
        p.support.attach.sum fun i =>
          f (coeff (integralNormalization p) i.1 * p.leadingCoeff ^ i.1) * z ^ i.1 := by
      

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CommSemiring S
p : R[X]
f : R →+* S
z : S
hz : eval₂ f z p = 0
inj : ∀ (x : R), f x = 0 → x = 0
⊢ eval₂ f (z * f (leadingCoeff p)) (integralNormalization p) =
    ∑ i in Finset.attach (support p), f (coeff (integralNormalization p) ↑i * leadingCoeff p ^ ↑i) * z ^ ↑i

Next tactic:
rw [eval₂_eq_sum, sum_def, support_integralNormalization]
theorem integralNormalization_eval₂_eq_zero {p : R[X]} (f : R →+* S) {z : S} (hz : eval₂ f z p = 0)
    (inj : ∀ x : R, f x = 0 → x = 0) :
    eval₂ f (z * f p.leadingCoeff) (integralNormalization p) = 0 :=
  calc
    eval₂ f (z * f p.leadingCoeff) (integralNormalization p) =
        p.support.attach.sum fun i =>
          f (coeff (integralNormalization p) i.1 * p.leadingCoeff ^ i.1) * z ^ i.1 := by
      rw [eval₂_eq_sum, sum_def, support_integralNormalization]
      

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CommSemiring S
p : R[X]
f : R →+* S
z : S
hz : eval₂ f z p = 0
inj : ∀ (x : R), f x = 0 → x = 0
⊢ ∑ n in support p, f (coeff (integralNormalization p) n) * (z * f (leadingCoeff p)) ^ n =
    ∑ i in Finset.attach (support p), f (coeff (integralNormalization p) ↑i * leadingCoeff p ^ ↑i) * z ^ ↑i

Next tactic:
simp only [mul_comm z, mul_pow, mul_assoc, RingHom.map_pow, RingHom.map_mul]
theorem integralNormalization_eval₂_eq_zero {p : R[X]} (f : R →+* S) {z : S} (hz : eval₂ f z p = 0)
    (inj : ∀ x : R, f x = 0 → x = 0) :
    eval₂ f (z * f p.leadingCoeff) (integralNormalization p) = 0 :=
  calc
    eval₂ f (z * f p.leadingCoeff) (integralNormalization p) =
        p.support.attach.sum fun i =>
          f (coeff (integralNormalization p) i.1 * p.leadingCoeff ^ i.1) * z ^ i.1 := by
      rw [eval₂_eq_sum, sum_def, support_integralNormalization]
      simp only [mul_comm z, mul_pow, mul_assoc, RingHom.map_pow, RingHom.map_mul]
      

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CommSemiring S
p : R[X]
f : R →+* S
z : S
hz : eval₂ f z p = 0
inj : ∀ (x : R), f x = 0 → x = 0
⊢ ∑ x in support p, f (coeff (integralNormalization p) x) * (f (leadingCoeff p) ^ x * z ^ x) =
    ∑ x in Finset.attach (support p), f (coeff (integralNormalization p) ↑x) * (f (leadingCoeff p) ^ ↑x * z ^ ↑x)

Next tactic:
exact Finset.sum_attach.symm
theorem integralNormalization_eval₂_eq_zero {p : R[X]} (f : R →+* S) {z : S} (hz : eval₂ f z p = 0)
    (inj : ∀ x : R, f x = 0 → x = 0) :
    eval₂ f (z * f p.leadingCoeff) (integralNormalization p) = 0 :=
  calc
    eval₂ f (z * f p.leadingCoeff) (integralNormalization p) =
        p.support.attach.sum fun i =>
          f (coeff (integralNormalization p) i.1 * p.leadingCoeff ^ i.1) * z ^ i.1 := by
      rw [eval₂_eq_sum, sum_def, support_integralNormalization]
      simp only [mul_comm z, mul_pow, mul_assoc, RingHom.map_pow, RingHom.map_mul]
      exact Finset.sum_attach.symm
    _ =
        p.support.attach.sum fun i =>
          f (coeff p i.1 * p.leadingCoeff ^ (natDegree p - 1)) * z ^ i.1 := by
      

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CommSemiring S
p : R[X]
f : R →+* S
z : S
hz : eval₂ f z p = 0
inj : ∀ (x : R), f x = 0 → x = 0
⊢ ∑ i in Finset.attach (support p), f (coeff (integralNormalization p) ↑i * leadingCoeff p ^ ↑i) * z ^ ↑i =
    ∑ i in Finset.attach (support p), f (coeff p ↑i * leadingCoeff p ^ (natDegree p - 1)) * z ^ ↑i

Next tactic:
by_cases hp : p = 0
theorem integralNormalization_eval₂_eq_zero {p : R[X]} (f : R →+* S) {z : S} (hz : eval₂ f z p = 0)
    (inj : ∀ x : R, f x = 0 → x = 0) :
    eval₂ f (z * f p.leadingCoeff) (integralNormalization p) = 0 :=
  calc
    eval₂ f (z * f p.leadingCoeff) (integralNormalization p) =
        p.support.attach.sum fun i =>
          f (coeff (integralNormalization p) i.1 * p.leadingCoeff ^ i.1) * z ^ i.1 := by
      rw [eval₂_eq_sum, sum_def, support_integralNormalization]
      simp only [mul_comm z, mul_pow, mul_assoc, RingHom.map_pow, RingHom.map_mul]
      exact Finset.sum_attach.symm
    _ =
        p.support.attach.sum fun i =>
          f (coeff p i.1 * p.leadingCoeff ^ (natDegree p - 1)) * z ^ i.1 := by
      by_cases hp : p = 0; · 

Proof state:
case pos
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CommSemiring S
p : R[X]
f : R →+* S
z : S
hz : eval₂ f z p = 0
inj : ∀ (x : R), f x = 0 → x = 0
hp : p = 0
⊢ ∑ i in Finset.attach (support p), f (coeff (integralNormalization p) ↑i * leadingCoeff p ^ ↑i) * z ^ ↑i =
    ∑ i in Finset.attach (support p), f (coeff p ↑i * leadingCoeff p ^ (natDegree p - 1)) * z ^ ↑i

Next tactic:
simp [hp]
theorem integralNormalization_eval₂_eq_zero {p : R[X]} (f : R →+* S) {z : S} (hz : eval₂ f z p = 0)
    (inj : ∀ x : R, f x = 0 → x = 0) :
    eval₂ f (z * f p.leadingCoeff) (integralNormalization p) = 0 :=
  calc
    eval₂ f (z * f p.leadingCoeff) (integralNormalization p) =
        p.support.attach.sum fun i =>
          f (coeff (integralNormalization p) i.1 * p.leadingCoeff ^ i.1) * z ^ i.1 := by
      rw [eval₂_eq_sum, sum_def, support_integralNormalization]
      simp only [mul_comm z, mul_pow, mul_assoc, RingHom.map_pow, RingHom.map_mul]
      exact Finset.sum_attach.symm
    _ =
        p.support.attach.sum fun i =>
          f (coeff p i.1 * p.leadingCoeff ^ (natDegree p - 1)) * z ^ i.1 := by
      by_cases hp : p = 0; · simp [hp]
      

Proof state:
case neg
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CommSemiring S
p : R[X]
f : R →+* S
z : S
hz : eval₂ f z p = 0
inj : ∀ (x : R), f x = 0 → x = 0
hp : ¬p = 0
⊢ ∑ i in Finset.attach (support p), f (coeff (integralNormalization p) ↑i * leadingCoeff p ^ ↑i) * z ^ ↑i =
    ∑ i in Finset.attach (support p), f (coeff p ↑i * leadingCoeff p ^ (natDegree p - 1)) * z ^ ↑i

Next tactic:
have one_le_deg : 1 ≤ natDegree p :=
        Nat.succ_le_of_lt (natDegree_pos_of_eval₂_root hp f hz inj)
theorem integralNormalization_eval₂_eq_zero {p : R[X]} (f : R →+* S) {z : S} (hz : eval₂ f z p = 0)
    (inj : ∀ x : R, f x = 0 → x = 0) :
    eval₂ f (z * f p.leadingCoeff) (integralNormalization p) = 0 :=
  calc
    eval₂ f (z * f p.leadingCoeff) (integralNormalization p) =
        p.support.attach.sum fun i =>
          f (coeff (integralNormalization p) i.1 * p.leadingCoeff ^ i.1) * z ^ i.1 := by
      rw [eval₂_eq_sum, sum_def, support_integralNormalization]
      simp only [mul_comm z, mul_pow, mul_assoc, RingHom.map_pow, RingHom.map_mul]
      exact Finset.sum_attach.symm
    _ =
        p.support.attach.sum fun i =>
          f (coeff p i.1 * p.leadingCoeff ^ (natDegree p - 1)) * z ^ i.1 := by
      by_cases hp : p = 0; · simp [hp]
      have one_le_deg : 1 ≤ natDegree p :=
        Nat.succ_le_of_lt (natDegree_pos_of_eval₂_root hp f hz inj)
      

Proof state:
case neg
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CommSemiring S
p : R[X]
f : R →+* S
z : S
hz : eval₂ f z p = 0
inj : ∀ (x : R), f x = 0 → x = 0
hp : ¬p = 0
one_le_deg : 1 ≤ natDegree p
⊢ ∑ i in Finset.attach (support p), f (coeff (integralNormalization p) ↑i * leadingCoeff p ^ ↑i) * z ^ ↑i =
    ∑ i in Finset.attach (support p), f (coeff p ↑i * leadingCoeff p ^ (natDegree p - 1)) * z ^ ↑i

Next tactic:
congr with i
theorem integralNormalization_eval₂_eq_zero {p : R[X]} (f : R →+* S) {z : S} (hz : eval₂ f z p = 0)
    (inj : ∀ x : R, f x = 0 → x = 0) :
    eval₂ f (z * f p.leadingCoeff) (integralNormalization p) = 0 :=
  calc
    eval₂ f (z * f p.leadingCoeff) (integralNormalization p) =
        p.support.attach.sum fun i =>
          f (coeff (integralNormalization p) i.1 * p.leadingCoeff ^ i.1) * z ^ i.1 := by
      rw [eval₂_eq_sum, sum_def, support_integralNormalization]
      simp only [mul_comm z, mul_pow, mul_assoc, RingHom.map_pow, RingHom.map_mul]
      exact Finset.sum_attach.symm
    _ =
        p.support.attach.sum fun i =>
          f (coeff p i.1 * p.leadingCoeff ^ (natDegree p - 1)) * z ^ i.1 := by
      by_cases hp : p = 0; · simp [hp]
      have one_le_deg : 1 ≤ natDegree p :=
        Nat.succ_le_of_lt (natDegree_pos_of_eval₂_root hp f hz inj)
      congr with i
      

Proof state:
case neg.e_f.h
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : CommSemiring S
p : R[X]
f : R →+* S
z : S
hz : eval₂ f z p = 0
inj : ∀ (x : R), f x = 0 → x = 0
hp : ¬p = 0
one_le_deg : 1 ≤ natDegree p
i : { x // x ∈ support p }
⊢ f (coeff (integralNormalization p) ↑i * leadingCoeff p ^ ↑i) * z ^ ↑i =
    f (coeff p ↑i * leadingCoeff p ^ (natDegree p - 1)) * z ^ ↑i

Next tactic:
congr 2