l3lab/ntp-mathlib huggingface dataset:
theorem coe_eq : ((↑) : FreeRing α → FreeCommRing α) =
    @Functor.map FreeAbelianGroup _ _ _ fun l : List α => (l : Multiset α) := by
  funext x
  erw [castFreeCommRing, toFreeCommRing, FreeRing.lift, Equiv.coe_trans, Function.comp,
    FreeAbelianGroup.liftMonoid_coe (FreeMonoid.lift FreeCommRing.of)]
  dsimp [Functor.map]
  rw [← AddMonoidHom.coe_coe]
  apply FreeAbelianGroup.lift.unique; intro L
  erw [FreeAbelianGroup.lift.of, Function.comp]
  exact
    FreeMonoid.recOn L rfl fun hd tl ih => by
      rw [(FreeMonoid.lift _).map_mul, FreeMonoid.lift_eval_of, ih]
      

Proof state:
α : Type u
x : FreeRing α
L : FreeMonoid α
hd : α
tl : FreeMonoid α
ih : (FreeMonoid.lift FreeCommRing.of) tl = (fun x => FreeAbelianGroup.of ↑x) tl
⊢ FreeCommRing.of hd * (fun x => FreeAbelianGroup.of ↑x) tl = (fun x => FreeAbelianGroup.of ↑x) (FreeMonoid.of hd * tl)

Next tactic:
conv_lhs => reduce
theorem coe_eq : ((↑) : FreeRing α → FreeCommRing α) =
    @Functor.map FreeAbelianGroup _ _ _ fun l : List α => (l : Multiset α) := by
  funext x
  erw [castFreeCommRing, toFreeCommRing, FreeRing.lift, Equiv.coe_trans, Function.comp,
    FreeAbelianGroup.liftMonoid_coe (FreeMonoid.lift FreeCommRing.of)]
  dsimp [Functor.map]
  rw [← AddMonoidHom.coe_coe]
  apply FreeAbelianGroup.lift.unique; intro L
  erw [FreeAbelianGroup.lift.of, Function.comp]
  exact
    FreeMonoid.recOn L rfl fun hd tl ih => by
      rw [(FreeMonoid.lift _).map_mul, FreeMonoid.lift_eval_of, ih]
      conv_lhs => 

Proof state:
α : Type u
x : FreeRing α
L : FreeMonoid α
hd : α
tl : FreeMonoid α
ih : (FreeMonoid.lift FreeCommRing.of) tl = (fun x => FreeAbelianGroup.of ↑x) tl
| FreeCommRing.of hd * (fun x => FreeAbelianGroup.of ↑x) tl

Next tactic:
reduce
/-- If α has size at most 1 then the natural map from the free ring on `α` to the
    free commutative ring on `α` is an isomorphism of rings. -/
def subsingletonEquivFreeCommRing [Subsingleton α] : FreeRing α ≃+* FreeCommRing α :=
  RingEquiv.ofBijective (coeRingHom _) (by
    

Proof state:
α : Type u
inst✝ : Subsingleton α
⊢ Bijective ⇑(coeRingHom α)

Next tactic:
have : (coeRingHom _ : FreeRing α → FreeCommRing α) =
        Functor.mapEquiv FreeAbelianGroup (Multiset.subsingletonEquiv α) :=
      coe_eq α
/-- If α has size at most 1 then the natural map from the free ring on `α` to the
    free commutative ring on `α` is an isomorphism of rings. -/
def subsingletonEquivFreeCommRing [Subsingleton α] : FreeRing α ≃+* FreeCommRing α :=
  RingEquiv.ofBijective (coeRingHom _) (by
    have : (coeRingHom _ : FreeRing α → FreeCommRing α) =
        Functor.mapEquiv FreeAbelianGroup (Multiset.subsingletonEquiv α) :=
      coe_eq α
    

Proof state:
α : Type u
inst✝ : Subsingleton α
this : ⇑(coeRingHom α) = ⇑(Functor.mapEquiv FreeAbelianGroup (Multiset.subsingletonEquiv α))
⊢ Bijective ⇑(coeRingHom α)

Next tactic:
rw [this]
/-- If α has size at most 1 then the natural map from the free ring on `α` to the
    free commutative ring on `α` is an isomorphism of rings. -/
def subsingletonEquivFreeCommRing [Subsingleton α] : FreeRing α ≃+* FreeCommRing α :=
  RingEquiv.ofBijective (coeRingHom _) (by
    have : (coeRingHom _ : FreeRing α → FreeCommRing α) =
        Functor.mapEquiv FreeAbelianGroup (Multiset.subsingletonEquiv α) :=
      coe_eq α
    rw [this]
    

Proof state:
α : Type u
inst✝ : Subsingleton α
this : ⇑(coeRingHom α) = ⇑(Functor.mapEquiv FreeAbelianGroup (Multiset.subsingletonEquiv α))
⊢ Bijective ⇑(Functor.mapEquiv FreeAbelianGroup (Multiset.subsingletonEquiv α))

Next tactic:
apply Equiv.bijective
instance instCommRing [Subsingleton α] : CommRing (FreeRing α) :=
  { inferInstanceAs (Ring (FreeRing α)) with
    mul_comm := fun x y => by
      

Proof state:
α : Type u
inst✝ : Subsingleton α
src✝ : Ring (FreeRing α) := inferInstanceAs (Ring (FreeRing α))
x y : FreeRing α
⊢ x * y = y * x

Next tactic:
rw [← (subsingletonEquivFreeCommRing α).symm_apply_apply (y * x),
        (subsingletonEquivFreeCommRing α).map_mul, mul_comm,
        ← (subsingletonEquivFreeCommRing α).map_mul,
        (subsingletonEquivFreeCommRing α).symm_apply_apply]
/-- The free commutative ring on `α` is isomorphic to the polynomial ring over ℤ with
    variables in `α` -/
def freeCommRingEquivMvPolynomialInt : FreeCommRing α ≃+* MvPolynomial α ℤ :=
  RingEquiv.ofHomInv (FreeCommRing.lift <| (fun a => MvPolynomial.X a : α → MvPolynomial α ℤ))
    (MvPolynomial.eval₂Hom (Int.castRingHom (FreeCommRing α)) FreeCommRing.of)
    (by 

Proof state:
α : Type u
⊢ RingHom.comp ↑(MvPolynomial.eval₂Hom (Int.castRingHom (FreeCommRing α)) FreeCommRing.of)
      ↑(FreeCommRing.lift fun a => MvPolynomial.X a) =
    RingHom.id (FreeCommRing α)

Next tactic:
ext
/-- The free commutative ring on `α` is isomorphic to the polynomial ring over ℤ with
    variables in `α` -/
def freeCommRingEquivMvPolynomialInt : FreeCommRing α ≃+* MvPolynomial α ℤ :=
  RingEquiv.ofHomInv (FreeCommRing.lift <| (fun a => MvPolynomial.X a : α → MvPolynomial α ℤ))
    (MvPolynomial.eval₂Hom (Int.castRingHom (FreeCommRing α)) FreeCommRing.of)
    (by ext; 

Proof state:
case h
α : Type u
x✝ : α
⊢ (RingHom.comp ↑(MvPolynomial.eval₂Hom (Int.castRingHom (FreeCommRing α)) FreeCommRing.of)
        ↑(FreeCommRing.lift fun a => MvPolynomial.X a))
      (FreeCommRing.of x✝) =
    (RingHom.id (FreeCommRing α)) (FreeCommRing.of x✝)

Next tactic:
simp
/-- The free commutative ring on `α` is isomorphic to the polynomial ring over ℤ with
    variables in `α` -/
def freeCommRingEquivMvPolynomialInt : FreeCommRing α ≃+* MvPolynomial α ℤ :=
  RingEquiv.ofHomInv (FreeCommRing.lift <| (fun a => MvPolynomial.X a : α → MvPolynomial α ℤ))
    (MvPolynomial.eval₂Hom (Int.castRingHom (FreeCommRing α)) FreeCommRing.of)
    (by ext; simp) (by 

Proof state:
α : Type u
⊢ RingHom.comp ↑(FreeCommRing.lift fun a => MvPolynomial.X a)
      ↑(MvPolynomial.eval₂Hom (Int.castRingHom (FreeCommRing α)) FreeCommRing.of) =
    RingHom.id (MvPolynomial α ℤ)

Next tactic:
ext
/-- The free commutative ring on `α` is isomorphic to the polynomial ring over ℤ with
    variables in `α` -/
def freeCommRingEquivMvPolynomialInt : FreeCommRing α ≃+* MvPolynomial α ℤ :=
  RingEquiv.ofHomInv (FreeCommRing.lift <| (fun a => MvPolynomial.X a : α → MvPolynomial α ℤ))
    (MvPolynomial.eval₂Hom (Int.castRingHom (FreeCommRing α)) FreeCommRing.of)
    (by ext; simp) (by ext <;> 

Proof state:
case hC.a.a
α : Type u
x✝ : ℤ
m✝ : α →₀ ℕ
⊢ MvPolynomial.coeff m✝
      ((RingHom.comp
          (RingHom.comp ↑(FreeCommRing.lift fun a => MvPolynomial.X a)
            ↑(MvPolynomial.eval₂Hom (Int.castRingHom (FreeCommRing α)) FreeCommRing.of))
          MvPolynomial.C)
        x✝) =
    MvPolynomial.coeff m✝ ((RingHom.comp (RingHom.id (MvPolynomial α ℤ)) MvPolynomial.C) x✝)

Next tactic:
simp
/-- The free commutative ring on `α` is isomorphic to the polynomial ring over ℤ with
    variables in `α` -/
def freeCommRingEquivMvPolynomialInt : FreeCommRing α ≃+* MvPolynomial α ℤ :=
  RingEquiv.ofHomInv (FreeCommRing.lift <| (fun a => MvPolynomial.X a : α → MvPolynomial α ℤ))
    (MvPolynomial.eval₂Hom (Int.castRingHom (FreeCommRing α)) FreeCommRing.of)
    (by ext; simp) (by ext <;> 

Proof state:
case hX.a
α : Type u
i✝ : α
m✝ : α →₀ ℕ
⊢ MvPolynomial.coeff m✝
      ((RingHom.comp ↑(FreeCommRing.lift fun a => MvPolynomial.X a)
          ↑(MvPolynomial.eval₂Hom (Int.castRingHom (FreeCommRing α)) FreeCommRing.of))
        (MvPolynomial.X i✝)) =
    MvPolynomial.coeff m✝ ((RingHom.id (MvPolynomial α ℤ)) (MvPolynomial.X i✝))

Next tactic:
simp
theorem rank_eq [CommRing R] [Nontrivial R] :
    Module.rank R (FreeAlgebra R X) = Cardinal.lift.{u} (Cardinal.mk (List X)) := by
  

Proof state:
R : Type u
X : Type v
inst✝¹ : CommRing R
inst✝ : Nontrivial R
⊢ Module.rank R (FreeAlgebra R X) = Cardinal.lift.{u, v} (Cardinal.mk (List X))

Next tactic:
rw [← (Basis.mk_eq_rank'.{_,_,_,u} (basisFreeMonoid R X)).trans (Cardinal.lift_id _),
    Cardinal.lift_umax'.{v,u}, FreeMonoid]
theorem mem_of_integral {x : R} (hx : IsIntegral O x) : x ∈ v.integer :=
  let ⟨p, hpm, hpx⟩ := hx
  le_of_not_lt fun hvx : 1 < v x => by
    

Proof state:
R : Type u
Γ₀ : Type v
inst✝³ : CommRing R
inst✝² : LinearOrderedCommGroupWithZero Γ₀
v : Valuation R Γ₀
O : Type w
inst✝¹ : CommRing O
inst✝ : Algebra O R
hv : Integers v O
x : R
hx : IsIntegral O x
p : O[X]
hpm : Monic p
hpx : eval₂ (algebraMap O R) x p = 0
hvx : 1 < v x
⊢ False

Next tactic:
rw [hpm.as_sum, eval₂_add, eval₂_pow, eval₂_X, eval₂_finset_sum, add_eq_zero_iff_eq_neg] at hpx
theorem mem_of_integral {x : R} (hx : IsIntegral O x) : x ∈ v.integer :=
  let ⟨p, hpm, hpx⟩ := hx
  le_of_not_lt fun hvx : 1 < v x => by
    rw [hpm.as_sum, eval₂_add, eval₂_pow, eval₂_X, eval₂_finset_sum, add_eq_zero_iff_eq_neg] at hpx
    

Proof state:
R : Type u
Γ₀ : Type v
inst✝³ : CommRing R
inst✝² : LinearOrderedCommGroupWithZero Γ₀
v : Valuation R Γ₀
O : Type w
inst✝¹ : CommRing O
inst✝ : Algebra O R
hv : Integers v O
x : R
hx : IsIntegral O x
p : O[X]
hpm : Monic p
hpx : x ^ natDegree p = -∑ i in Finset.range (natDegree p), eval₂ (algebraMap O R) x (C (coeff p i) * X ^ i)
hvx : 1 < v x
⊢ False

Next tactic:
replace hpx := congr_arg v hpx
theorem mem_of_integral {x : R} (hx : IsIntegral O x) : x ∈ v.integer :=
  let ⟨p, hpm, hpx⟩ := hx
  le_of_not_lt fun hvx : 1 < v x => by
    rw [hpm.as_sum, eval₂_add, eval₂_pow, eval₂_X, eval₂_finset_sum, add_eq_zero_iff_eq_neg] at hpx
    replace hpx := congr_arg v hpx; 

Proof state:
R : Type u
Γ₀ : Type v
inst✝³ : CommRing R
inst✝² : LinearOrderedCommGroupWithZero Γ₀
v : Valuation R Γ₀
O : Type w
inst✝¹ : CommRing O
inst✝ : Algebra O R
hv : Integers v O
x : R
hx : IsIntegral O x
p : O[X]
hpm : Monic p
hvx : 1 < v x
hpx : v (x ^ natDegree p) = v (-∑ i in Finset.range (natDegree p), eval₂ (algebraMap O R) x (C (coeff p i) * X ^ i))
⊢ False

Next tactic:
refine' ne_of_gt _ hpx
theorem mem_of_integral {x : R} (hx : IsIntegral O x) : x ∈ v.integer :=
  let ⟨p, hpm, hpx⟩ := hx
  le_of_not_lt fun hvx : 1 < v x => by
    rw [hpm.as_sum, eval₂_add, eval₂_pow, eval₂_X, eval₂_finset_sum, add_eq_zero_iff_eq_neg] at hpx
    replace hpx := congr_arg v hpx; refine' ne_of_gt _ hpx
    

Proof state:
R : Type u
Γ₀ : Type v
inst✝³ : CommRing R
inst✝² : LinearOrderedCommGroupWithZero Γ₀
v : Valuation R Γ₀
O : Type w
inst✝¹ : CommRing O
inst✝ : Algebra O R
hv : Integers v O
x : R
hx : IsIntegral O x
p : O[X]
hpm : Monic p
hvx : 1 < v x
hpx : v (x ^ natDegree p) = v (-∑ i in Finset.range (natDegree p), eval₂ (algebraMap O R) x (C (coeff p i) * X ^ i))
⊢ v (-∑ i in Finset.range (natDegree p), eval₂ (algebraMap O R) x (C (coeff p i) * X ^ i)) < v (x ^ natDegree p)

Next tactic:
rw [v.map_neg, v.map_pow]
theorem mem_of_integral {x : R} (hx : IsIntegral O x) : x ∈ v.integer :=
  let ⟨p, hpm, hpx⟩ := hx
  le_of_not_lt fun hvx : 1 < v x => by
    rw [hpm.as_sum, eval₂_add, eval₂_pow, eval₂_X, eval₂_finset_sum, add_eq_zero_iff_eq_neg] at hpx
    replace hpx := congr_arg v hpx; refine' ne_of_gt _ hpx
    rw [v.map_neg, v.map_pow]
    

Proof state:
R : Type u
Γ₀ : Type v
inst✝³ : CommRing R
inst✝² : LinearOrderedCommGroupWithZero Γ₀
v : Valuation R Γ₀
O : Type w
inst✝¹ : CommRing O
inst✝ : Algebra O R
hv : Integers v O
x : R
hx : IsIntegral O x
p : O[X]
hpm : Monic p
hvx : 1 < v x
hpx : v (x ^ natDegree p) = v (-∑ i in Finset.range (natDegree p), eval₂ (algebraMap O R) x (C (coeff p i) * X ^ i))
⊢ v (∑ i in Finset.range (natDegree p), eval₂ (algebraMap O R) x (C (coeff p i) * X ^ i)) < v x ^ natDegree p

Next tactic:
refine' v.map_sum_lt' (zero_lt_one.trans_le (one_le_pow_of_one_le' hvx.le _)) fun i hi => _
theorem mem_of_integral {x : R} (hx : IsIntegral O x) : x ∈ v.integer :=
  let ⟨p, hpm, hpx⟩ := hx
  le_of_not_lt fun hvx : 1 < v x => by
    rw [hpm.as_sum, eval₂_add, eval₂_pow, eval₂_X, eval₂_finset_sum, add_eq_zero_iff_eq_neg] at hpx
    replace hpx := congr_arg v hpx; refine' ne_of_gt _ hpx
    rw [v.map_neg, v.map_pow]
    refine' v.map_sum_lt' (zero_lt_one.trans_le (one_le_pow_of_one_le' hvx.le _)) fun i hi => _
    

Proof state:
R : Type u
Γ₀ : Type v
inst✝³ : CommRing R
inst✝² : LinearOrderedCommGroupWithZero Γ₀
v : Valuation R Γ₀
O : Type w
inst✝¹ : CommRing O
inst✝ : Algebra O R
hv : Integers v O
x : R
hx : IsIntegral O x
p : O[X]
hpm : Monic p
hvx : 1 < v x
hpx : v (x ^ natDegree p) = v (-∑ i in Finset.range (natDegree p), eval₂ (algebraMap O R) x (C (coeff p i) * X ^ i))
i : ℕ
hi : i ∈ Finset.range (natDegree p)
⊢ v (eval₂ (algebraMap O R) x (C (coeff p i) * X ^ i)) < v x ^ natDegree p

Next tactic:
rw [eval₂_mul, eval₂_pow, eval₂_C, eval₂_X, v.map_mul, v.map_pow, ←
      one_mul (v x ^ p.natDegree)]
theorem mem_of_integral {x : R} (hx : IsIntegral O x) : x ∈ v.integer :=
  let ⟨p, hpm, hpx⟩ := hx
  le_of_not_lt fun hvx : 1 < v x => by
    rw [hpm.as_sum, eval₂_add, eval₂_pow, eval₂_X, eval₂_finset_sum, add_eq_zero_iff_eq_neg] at hpx
    replace hpx := congr_arg v hpx; refine' ne_of_gt _ hpx
    rw [v.map_neg, v.map_pow]
    refine' v.map_sum_lt' (zero_lt_one.trans_le (one_le_pow_of_one_le' hvx.le _)) fun i hi => _
    rw [eval₂_mul, eval₂_pow, eval₂_C, eval₂_X, v.map_mul, v.map_pow, ←
      one_mul (v x ^ p.natDegree)]
    

Proof state:
R : Type u
Γ₀ : Type v
inst✝³ : CommRing R
inst✝² : LinearOrderedCommGroupWithZero Γ₀
v : Valuation R Γ₀
O : Type w
inst✝¹ : CommRing O
inst✝ : Algebra O R
hv : Integers v O
x : R
hx : IsIntegral O x
p : O[X]
hpm : Monic p
hvx : 1 < v x
hpx : v (x ^ natDegree p) = v (-∑ i in Finset.range (natDegree p), eval₂ (algebraMap O R) x (C (coeff p i) * X ^ i))
i : ℕ
hi : i ∈ Finset.range (natDegree p)
⊢ v ((algebraMap O R) (coeff p i)) * v x ^ i < 1 * v x ^ natDegree p

Next tactic:
cases' (hv.2 <| p.coeff i).lt_or_eq with hvpi hvpi
theorem mem_of_integral {x : R} (hx : IsIntegral O x) : x ∈ v.integer :=
  let ⟨p, hpm, hpx⟩ := hx
  le_of_not_lt fun hvx : 1 < v x => by
    rw [hpm.as_sum, eval₂_add, eval₂_pow, eval₂_X, eval₂_finset_sum, add_eq_zero_iff_eq_neg] at hpx
    replace hpx := congr_arg v hpx; refine' ne_of_gt _ hpx
    rw [v.map_neg, v.map_pow]
    refine' v.map_sum_lt' (zero_lt_one.trans_le (one_le_pow_of_one_le' hvx.le _)) fun i hi => _
    rw [eval₂_mul, eval₂_pow, eval₂_C, eval₂_X, v.map_mul, v.map_pow, ←
      one_mul (v x ^ p.natDegree)]
    cases' (hv.2 <| p.coeff i).lt_or_eq with hvpi hvpi
    · 

Proof state:
case inl
R : Type u
Γ₀ : Type v
inst✝³ : CommRing R
inst✝² : LinearOrderedCommGroupWithZero Γ₀
v : Valuation R Γ₀
O : Type w
inst✝¹ : CommRing O
inst✝ : Algebra O R
hv : Integers v O
x : R
hx : IsIntegral O x
p : O[X]
hpm : Monic p
hvx : 1 < v x
hpx : v (x ^ natDegree p) = v (-∑ i in Finset.range (natDegree p), eval₂ (algebraMap O R) x (C (coeff p i) * X ^ i))
i : ℕ
hi : i ∈ Finset.range (natDegree p)
hvpi : v ((algebraMap O R) (coeff p i)) < 1
⊢ v ((algebraMap O R) (coeff p i)) * v x ^ i < 1 * v x ^ natDegree p

Next tactic:
exact mul_lt_mul₀ hvpi (pow_lt_pow_right₀ hvx <| Finset.mem_range.1 hi)
theorem mem_of_integral {x : R} (hx : IsIntegral O x) : x ∈ v.integer :=
  let ⟨p, hpm, hpx⟩ := hx
  le_of_not_lt fun hvx : 1 < v x => by
    rw [hpm.as_sum, eval₂_add, eval₂_pow, eval₂_X, eval₂_finset_sum, add_eq_zero_iff_eq_neg] at hpx
    replace hpx := congr_arg v hpx; refine' ne_of_gt _ hpx
    rw [v.map_neg, v.map_pow]
    refine' v.map_sum_lt' (zero_lt_one.trans_le (one_le_pow_of_one_le' hvx.le _)) fun i hi => _
    rw [eval₂_mul, eval₂_pow, eval₂_C, eval₂_X, v.map_mul, v.map_pow, ←
      one_mul (v x ^ p.natDegree)]
    cases' (hv.2 <| p.coeff i).lt_or_eq with hvpi hvpi
    · exact mul_lt_mul₀ hvpi (pow_lt_pow_right₀ hvx <| Finset.mem_range.1 hi)
    · 

Proof state:
case inr
R : Type u
Γ₀ : Type v
inst✝³ : CommRing R
inst✝² : LinearOrderedCommGroupWithZero Γ₀
v : Valuation R Γ₀
O : Type w
inst✝¹ : CommRing O
inst✝ : Algebra O R
hv : Integers v O
x : R
hx : IsIntegral O x
p : O[X]
hpm : Monic p
hvx : 1 < v x
hpx : v (x ^ natDegree p) = v (-∑ i in Finset.range (natDegree p), eval₂ (algebraMap O R) x (C (coeff p i) * X ^ i))
i : ℕ
hi : i ∈ Finset.range (natDegree p)
hvpi : v ((algebraMap O R) (coeff p i)) = 1
⊢ v ((algebraMap O R) (coeff p i)) * v x ^ i < 1 * v x ^ natDegree p

Next tactic:
erw [hvpi]
theorem mem_of_integral {x : R} (hx : IsIntegral O x) : x ∈ v.integer :=
  let ⟨p, hpm, hpx⟩ := hx
  le_of_not_lt fun hvx : 1 < v x => by
    rw [hpm.as_sum, eval₂_add, eval₂_pow, eval₂_X, eval₂_finset_sum, add_eq_zero_iff_eq_neg] at hpx
    replace hpx := congr_arg v hpx; refine' ne_of_gt _ hpx
    rw [v.map_neg, v.map_pow]
    refine' v.map_sum_lt' (zero_lt_one.trans_le (one_le_pow_of_one_le' hvx.le _)) fun i hi => _
    rw [eval₂_mul, eval₂_pow, eval₂_C, eval₂_X, v.map_mul, v.map_pow, ←
      one_mul (v x ^ p.natDegree)]
    cases' (hv.2 <| p.coeff i).lt_or_eq with hvpi hvpi
    · exact mul_lt_mul₀ hvpi (pow_lt_pow_right₀ hvx <| Finset.mem_range.1 hi)
    · erw [hvpi]; 

Proof state:
case inr
R : Type u
Γ₀ : Type v
inst✝³ : CommRing R
inst✝² : LinearOrderedCommGroupWithZero Γ₀
v : Valuation R Γ₀
O : Type w
inst✝¹ : CommRing O
inst✝ : Algebra O R
hv : Integers v O
x : R
hx : IsIntegral O x
p : O[X]
hpm : Monic p
hvx : 1 < v x
hpx : v (x ^ natDegree p) = v (-∑ i in Finset.range (natDegree p), eval₂ (algebraMap O R) x (C (coeff p i) * X ^ i))
i : ℕ
hi : i ∈ Finset.range (natDegree p)
hvpi : v ((algebraMap O R) (coeff p i)) = 1
⊢ 1 * v x ^ i < 1 * v x ^ natDegree p

Next tactic:
rw [one_mul, one_mul]
theorem mem_of_integral {x : R} (hx : IsIntegral O x) : x ∈ v.integer :=
  let ⟨p, hpm, hpx⟩ := hx
  le_of_not_lt fun hvx : 1 < v x => by
    rw [hpm.as_sum, eval₂_add, eval₂_pow, eval₂_X, eval₂_finset_sum, add_eq_zero_iff_eq_neg] at hpx
    replace hpx := congr_arg v hpx; refine' ne_of_gt _ hpx
    rw [v.map_neg, v.map_pow]
    refine' v.map_sum_lt' (zero_lt_one.trans_le (one_le_pow_of_one_le' hvx.le _)) fun i hi => _
    rw [eval₂_mul, eval₂_pow, eval₂_C, eval₂_X, v.map_mul, v.map_pow, ←
      one_mul (v x ^ p.natDegree)]
    cases' (hv.2 <| p.coeff i).lt_or_eq with hvpi hvpi
    · exact mul_lt_mul₀ hvpi (pow_lt_pow_right₀ hvx <| Finset.mem_range.1 hi)
    · erw [hvpi]; rw [one_mul, one_mul]; 

Proof state:
case inr
R : Type u
Γ₀ : Type v
inst✝³ : CommRing R
inst✝² : LinearOrderedCommGroupWithZero Γ₀
v : Valuation R Γ₀
O : Type w
inst✝¹ : CommRing O
inst✝ : Algebra O R
hv : Integers v O
x : R
hx : IsIntegral O x
p : O[X]
hpm : Monic p
hvx : 1 < v x
hpx : v (x ^ natDegree p) = v (-∑ i in Finset.range (natDegree p), eval₂ (algebraMap O R) x (C (coeff p i) * X ^ i))
i : ℕ
hi : i ∈ Finset.range (natDegree p)
hvpi : v ((algebraMap O R) (coeff p i)) = 1
⊢ v x ^ i < v x ^ natDegree p

Next tactic:
exact pow_lt_pow_right₀ hvx (Finset.mem_range.1 hi)
/-- A prime `p` is a unit in a commutative ring `R` of nonzero characteristic iff it does not divide
the characteristic. -/
theorem isUnit_iff_not_dvd_char_of_ringChar_ne_zero (R : Type*) [CommRing R] (p : ℕ) [Fact p.Prime]
    (hR : ringChar R ≠ 0) : IsUnit (p : R) ↔ ¬p ∣ ringChar R := by
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
p : ℕ
inst✝ : Fact (Nat.Prime p)
hR : ringChar R ≠ 0
⊢ IsUnit ↑p ↔ ¬p ∣ ringChar R

Next tactic:
have hch := CharP.cast_eq_zero R (ringChar R)
/-- A prime `p` is a unit in a commutative ring `R` of nonzero characteristic iff it does not divide
the characteristic. -/
theorem isUnit_iff_not_dvd_char_of_ringChar_ne_zero (R : Type*) [CommRing R] (p : ℕ) [Fact p.Prime]
    (hR : ringChar R ≠ 0) : IsUnit (p : R) ↔ ¬p ∣ ringChar R := by
  have hch := CharP.cast_eq_zero R (ringChar R)
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
p : ℕ
inst✝ : Fact (Nat.Prime p)
hR : ringChar R ≠ 0
hch : ↑(ringChar R) = 0
⊢ IsUnit ↑p ↔ ¬p ∣ ringChar R

Next tactic:
have hp : p.Prime := Fact.out
/-- A prime `p` is a unit in a commutative ring `R` of nonzero characteristic iff it does not divide
the characteristic. -/
theorem isUnit_iff_not_dvd_char_of_ringChar_ne_zero (R : Type*) [CommRing R] (p : ℕ) [Fact p.Prime]
    (hR : ringChar R ≠ 0) : IsUnit (p : R) ↔ ¬p ∣ ringChar R := by
  have hch := CharP.cast_eq_zero R (ringChar R)
  have hp : p.Prime := Fact.out
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
p : ℕ
inst✝ : Fact (Nat.Prime p)
hR : ringChar R ≠ 0
hch : ↑(ringChar R) = 0
hp : Nat.Prime p
⊢ IsUnit ↑p ↔ ¬p ∣ ringChar R

Next tactic:
constructor
/-- A prime `p` is a unit in a commutative ring `R` of nonzero characteristic iff it does not divide
the characteristic. -/
theorem isUnit_iff_not_dvd_char_of_ringChar_ne_zero (R : Type*) [CommRing R] (p : ℕ) [Fact p.Prime]
    (hR : ringChar R ≠ 0) : IsUnit (p : R) ↔ ¬p ∣ ringChar R := by
  have hch := CharP.cast_eq_zero R (ringChar R)
  have hp : p.Prime := Fact.out
  constructor
  · 

Proof state:
case mp
R : Type u_1
inst✝¹ : CommRing R
p : ℕ
inst✝ : Fact (Nat.Prime p)
hR : ringChar R ≠ 0
hch : ↑(ringChar R) = 0
hp : Nat.Prime p
⊢ IsUnit ↑p → ¬p ∣ ringChar R

Next tactic:
rintro h₁ ⟨q, hq⟩
/-- A prime `p` is a unit in a commutative ring `R` of nonzero characteristic iff it does not divide
the characteristic. -/
theorem isUnit_iff_not_dvd_char_of_ringChar_ne_zero (R : Type*) [CommRing R] (p : ℕ) [Fact p.Prime]
    (hR : ringChar R ≠ 0) : IsUnit (p : R) ↔ ¬p ∣ ringChar R := by
  have hch := CharP.cast_eq_zero R (ringChar R)
  have hp : p.Prime := Fact.out
  constructor
  · rintro h₁ ⟨q, hq⟩
    

Proof state:
case mp.intro
R : Type u_1
inst✝¹ : CommRing R
p : ℕ
inst✝ : Fact (Nat.Prime p)
hR : ringChar R ≠ 0
hch : ↑(ringChar R) = 0
hp : Nat.Prime p
h₁ : IsUnit ↑p
q : ℕ
hq : ringChar R = p * q
⊢ False

Next tactic:
rcases IsUnit.exists_left_inv h₁ with ⟨a, ha⟩
/-- A prime `p` is a unit in a commutative ring `R` of nonzero characteristic iff it does not divide
the characteristic. -/
theorem isUnit_iff_not_dvd_char_of_ringChar_ne_zero (R : Type*) [CommRing R] (p : ℕ) [Fact p.Prime]
    (hR : ringChar R ≠ 0) : IsUnit (p : R) ↔ ¬p ∣ ringChar R := by
  have hch := CharP.cast_eq_zero R (ringChar R)
  have hp : p.Prime := Fact.out
  constructor
  · rintro h₁ ⟨q, hq⟩
    rcases IsUnit.exists_left_inv h₁ with ⟨a, ha⟩
    

Proof state:
case mp.intro.intro
R : Type u_1
inst✝¹ : CommRing R
p : ℕ
inst✝ : Fact (Nat.Prime p)
hR : ringChar R ≠ 0
hch : ↑(ringChar R) = 0
hp : Nat.Prime p
h₁ : IsUnit ↑p
q : ℕ
hq : ringChar R = p * q
a : R
ha : a * ↑p = 1
⊢ False

Next tactic:
have h₃ : ¬ringChar R ∣ q := by
      rintro ⟨r, hr⟩
      rw [hr, ← mul_assoc, mul_comm p, mul_assoc] at hq
      nth_rw 1 [← mul_one (ringChar R)] at hq
      exact Nat.Prime.not_dvd_one hp ⟨r, mul_left_cancel₀ hR hq⟩
/-- A prime `p` is a unit in a commutative ring `R` of nonzero characteristic iff it does not divide
the characteristic. -/
theorem isUnit_iff_not_dvd_char_of_ringChar_ne_zero (R : Type*) [CommRing R] (p : ℕ) [Fact p.Prime]
    (hR : ringChar R ≠ 0) : IsUnit (p : R) ↔ ¬p ∣ ringChar R := by
  have hch := CharP.cast_eq_zero R (ringChar R)
  have hp : p.Prime := Fact.out
  constructor
  · rintro h₁ ⟨q, hq⟩
    rcases IsUnit.exists_left_inv h₁ with ⟨a, ha⟩
    have h₃ : ¬ringChar R ∣ q := by
      

Proof state:
R : Type u_1
inst✝¹ : CommRing R
p : ℕ
inst✝ : Fact (Nat.Prime p)
hR : ringChar R ≠ 0
hch : ↑(ringChar R) = 0
hp : Nat.Prime p
h₁ : IsUnit ↑p
q : ℕ
hq : ringChar R = p * q
a : R
ha : a * ↑p = 1
⊢ ¬ringChar R ∣ q

Next tactic:
rintro ⟨r, hr⟩
/-- A prime `p` is a unit in a commutative ring `R` of nonzero characteristic iff it does not divide
the characteristic. -/
theorem isUnit_iff_not_dvd_char_of_ringChar_ne_zero (R : Type*) [CommRing R] (p : ℕ) [Fact p.Prime]
    (hR : ringChar R ≠ 0) : IsUnit (p : R) ↔ ¬p ∣ ringChar R := by
  have hch := CharP.cast_eq_zero R (ringChar R)
  have hp : p.Prime := Fact.out
  constructor
  · rintro h₁ ⟨q, hq⟩
    rcases IsUnit.exists_left_inv h₁ with ⟨a, ha⟩
    have h₃ : ¬ringChar R ∣ q := by
      rintro ⟨r, hr⟩
      

Proof state:
case intro
R : Type u_1
inst✝¹ : CommRing R
p : ℕ
inst✝ : Fact (Nat.Prime p)
hR : ringChar R ≠ 0
hch : ↑(ringChar R) = 0
hp : Nat.Prime p
h₁ : IsUnit ↑p
q : ℕ
hq : ringChar R = p * q
a : R
ha : a * ↑p = 1
r : ℕ
hr : q = ringChar R * r
⊢ False

Next tactic:
rw [hr, ← mul_assoc, mul_comm p, mul_assoc] at hq