l3lab/ntp-mathlib huggingface dataset:
theorem coe_isIntegral_iff {R : Type*} [CommRing R] [Algebra R K] [Algebra R L]
    [IsScalarTower R K L] {x : S} : IsIntegral R (x : L) ↔ IsIntegral R x := by
  refine' ⟨fun h => _, fun h => _⟩
  · obtain ⟨P, hPmo, hProot⟩ := h
    

Proof state:
case refine'_1.intro.intro
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁸ : Field K
inst✝⁷ : Field L
inst✝⁶ : Field L'
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra K L'
S : IntermediateField K L
R : Type u_4
inst✝³ : CommRing R
inst✝² : Algebra R K
inst✝¹ : Algebra R L
inst✝ : IsScalarTower R K L
x : ↥S
P : R[X]
hPmo : Monic P
hProot : eval₂ (algebraMap R L) (↑x) P = 0
⊢ IsIntegral R x

Next tactic:
refine' ⟨P, hPmo, (injective_iff_map_eq_zero _).1 (algebraMap (↥S) L).injective _ _⟩
theorem coe_isIntegral_iff {R : Type*} [CommRing R] [Algebra R K] [Algebra R L]
    [IsScalarTower R K L] {x : S} : IsIntegral R (x : L) ↔ IsIntegral R x := by
  refine' ⟨fun h => _, fun h => _⟩
  · obtain ⟨P, hPmo, hProot⟩ := h
    refine' ⟨P, hPmo, (injective_iff_map_eq_zero _).1 (algebraMap (↥S) L).injective _ _⟩
    

Proof state:
case refine'_1.intro.intro
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁸ : Field K
inst✝⁷ : Field L
inst✝⁶ : Field L'
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra K L'
S : IntermediateField K L
R : Type u_4
inst✝³ : CommRing R
inst✝² : Algebra R K
inst✝¹ : Algebra R L
inst✝ : IsScalarTower R K L
x : ↥S
P : R[X]
hPmo : Monic P
hProot : eval₂ (algebraMap R L) (↑x) P = 0
⊢ (algebraMap (↥S) L) (eval₂ (algebraMap R ↥S) x P) = 0

Next tactic:
letI : IsScalarTower R S L := IsScalarTower.of_algebraMap_eq (congr_fun rfl)
theorem coe_isIntegral_iff {R : Type*} [CommRing R] [Algebra R K] [Algebra R L]
    [IsScalarTower R K L] {x : S} : IsIntegral R (x : L) ↔ IsIntegral R x := by
  refine' ⟨fun h => _, fun h => _⟩
  · obtain ⟨P, hPmo, hProot⟩ := h
    refine' ⟨P, hPmo, (injective_iff_map_eq_zero _).1 (algebraMap (↥S) L).injective _ _⟩
    letI : IsScalarTower R S L := IsScalarTower.of_algebraMap_eq (congr_fun rfl)
    

Proof state:
case refine'_1.intro.intro
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁸ : Field K
inst✝⁷ : Field L
inst✝⁶ : Field L'
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra K L'
S : IntermediateField K L
R : Type u_4
inst✝³ : CommRing R
inst✝² : Algebra R K
inst✝¹ : Algebra R L
inst✝ : IsScalarTower R K L
x : ↥S
P : R[X]
hPmo : Monic P
hProot : eval₂ (algebraMap R L) (↑x) P = 0
this : IsScalarTower R (↥S) L := IsScalarTower.of_algebraMap_eq (congr_fun rfl)
⊢ (algebraMap (↥S) L) (eval₂ (algebraMap R ↥S) x P) = 0

Next tactic:
rw [eval₂_eq_eval_map, ← eval₂_at_apply, eval₂_eq_eval_map, Polynomial.map_map, ←
      IsScalarTower.algebraMap_eq, ← eval₂_eq_eval_map]
theorem coe_isIntegral_iff {R : Type*} [CommRing R] [Algebra R K] [Algebra R L]
    [IsScalarTower R K L] {x : S} : IsIntegral R (x : L) ↔ IsIntegral R x := by
  refine' ⟨fun h => _, fun h => _⟩
  · obtain ⟨P, hPmo, hProot⟩ := h
    refine' ⟨P, hPmo, (injective_iff_map_eq_zero _).1 (algebraMap (↥S) L).injective _ _⟩
    letI : IsScalarTower R S L := IsScalarTower.of_algebraMap_eq (congr_fun rfl)
    rw [eval₂_eq_eval_map, ← eval₂_at_apply, eval₂_eq_eval_map, Polynomial.map_map, ←
      IsScalarTower.algebraMap_eq, ← eval₂_eq_eval_map]
    

Proof state:
case refine'_1.intro.intro
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁸ : Field K
inst✝⁷ : Field L
inst✝⁶ : Field L'
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra K L'
S : IntermediateField K L
R : Type u_4
inst✝³ : CommRing R
inst✝² : Algebra R K
inst✝¹ : Algebra R L
inst✝ : IsScalarTower R K L
x : ↥S
P : R[X]
hPmo : Monic P
hProot : eval₂ (algebraMap R L) (↑x) P = 0
this : IsScalarTower R (↥S) L := IsScalarTower.of_algebraMap_eq (congr_fun rfl)
⊢ eval₂ (algebraMap R L) ((algebraMap (↥S) L) x) P = 0

Next tactic:
exact hProot
theorem coe_isIntegral_iff {R : Type*} [CommRing R] [Algebra R K] [Algebra R L]
    [IsScalarTower R K L] {x : S} : IsIntegral R (x : L) ↔ IsIntegral R x := by
  refine' ⟨fun h => _, fun h => _⟩
  · obtain ⟨P, hPmo, hProot⟩ := h
    refine' ⟨P, hPmo, (injective_iff_map_eq_zero _).1 (algebraMap (↥S) L).injective _ _⟩
    letI : IsScalarTower R S L := IsScalarTower.of_algebraMap_eq (congr_fun rfl)
    rw [eval₂_eq_eval_map, ← eval₂_at_apply, eval₂_eq_eval_map, Polynomial.map_map, ←
      IsScalarTower.algebraMap_eq, ← eval₂_eq_eval_map]
    exact hProot
  · 

Proof state:
case refine'_2
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁸ : Field K
inst✝⁷ : Field L
inst✝⁶ : Field L'
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra K L'
S : IntermediateField K L
R : Type u_4
inst✝³ : CommRing R
inst✝² : Algebra R K
inst✝¹ : Algebra R L
inst✝ : IsScalarTower R K L
x : ↥S
h : IsIntegral R x
⊢ IsIntegral R ↑x

Next tactic:
obtain ⟨P, hPmo, hProot⟩ := h
theorem coe_isIntegral_iff {R : Type*} [CommRing R] [Algebra R K] [Algebra R L]
    [IsScalarTower R K L] {x : S} : IsIntegral R (x : L) ↔ IsIntegral R x := by
  refine' ⟨fun h => _, fun h => _⟩
  · obtain ⟨P, hPmo, hProot⟩ := h
    refine' ⟨P, hPmo, (injective_iff_map_eq_zero _).1 (algebraMap (↥S) L).injective _ _⟩
    letI : IsScalarTower R S L := IsScalarTower.of_algebraMap_eq (congr_fun rfl)
    rw [eval₂_eq_eval_map, ← eval₂_at_apply, eval₂_eq_eval_map, Polynomial.map_map, ←
      IsScalarTower.algebraMap_eq, ← eval₂_eq_eval_map]
    exact hProot
  · obtain ⟨P, hPmo, hProot⟩ := h
    

Proof state:
case refine'_2.intro.intro
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁸ : Field K
inst✝⁷ : Field L
inst✝⁶ : Field L'
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra K L'
S : IntermediateField K L
R : Type u_4
inst✝³ : CommRing R
inst✝² : Algebra R K
inst✝¹ : Algebra R L
inst✝ : IsScalarTower R K L
x : ↥S
P : R[X]
hPmo : Monic P
hProot : eval₂ (algebraMap R ↥S) x P = 0
⊢ IsIntegral R ↑x

Next tactic:
refine' ⟨P, hPmo, _⟩
theorem coe_isIntegral_iff {R : Type*} [CommRing R] [Algebra R K] [Algebra R L]
    [IsScalarTower R K L] {x : S} : IsIntegral R (x : L) ↔ IsIntegral R x := by
  refine' ⟨fun h => _, fun h => _⟩
  · obtain ⟨P, hPmo, hProot⟩ := h
    refine' ⟨P, hPmo, (injective_iff_map_eq_zero _).1 (algebraMap (↥S) L).injective _ _⟩
    letI : IsScalarTower R S L := IsScalarTower.of_algebraMap_eq (congr_fun rfl)
    rw [eval₂_eq_eval_map, ← eval₂_at_apply, eval₂_eq_eval_map, Polynomial.map_map, ←
      IsScalarTower.algebraMap_eq, ← eval₂_eq_eval_map]
    exact hProot
  · obtain ⟨P, hPmo, hProot⟩ := h
    refine' ⟨P, hPmo, _⟩
    

Proof state:
case refine'_2.intro.intro
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁸ : Field K
inst✝⁷ : Field L
inst✝⁶ : Field L'
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra K L'
S : IntermediateField K L
R : Type u_4
inst✝³ : CommRing R
inst✝² : Algebra R K
inst✝¹ : Algebra R L
inst✝ : IsScalarTower R K L
x : ↥S
P : R[X]
hPmo : Monic P
hProot : eval₂ (algebraMap R ↥S) x P = 0
⊢ eval₂ (algebraMap R L) (↑x) P = 0

Next tactic:
rw [← aeval_def, aeval_coe, aeval_def, hProot, ZeroMemClass.coe_zero]
theorem toSubalgebra_injective :
    Function.Injective (IntermediateField.toSubalgebra : IntermediateField K L → _) := by
  

Proof state:
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field L'
inst✝¹ : Algebra K L
inst✝ : Algebra K L'
S : IntermediateField K L
⊢ Function.Injective toSubalgebra

Next tactic:
intro S S' h
theorem toSubalgebra_injective :
    Function.Injective (IntermediateField.toSubalgebra : IntermediateField K L → _) := by
  intro S S' h
  

Proof state:
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field L'
inst✝¹ : Algebra K L
inst✝ : Algebra K L'
S✝ S S' : IntermediateField K L
h : S.toSubalgebra = S'.toSubalgebra
⊢ S = S'

Next tactic:
ext
theorem toSubalgebra_injective :
    Function.Injective (IntermediateField.toSubalgebra : IntermediateField K L → _) := by
  intro S S' h
  ext
  

Proof state:
case h
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field L'
inst✝¹ : Algebra K L
inst✝ : Algebra K L'
S✝ S S' : IntermediateField K L
h : S.toSubalgebra = S'.toSubalgebra
x✝ : L
⊢ x✝ ∈ S ↔ x✝ ∈ S'

Next tactic:
rw [← mem_toSubalgebra, ← mem_toSubalgebra, h]
theorem fieldRange_le : (algebraMap K L).fieldRange ≤ S.toSubfield := fun x hx =>
  S.toSubalgebra.range_subset (by 

Proof state:
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field L'
inst✝¹ : Algebra K L
inst✝ : Algebra K L'
S : IntermediateField K L
x : L
hx : x ∈ RingHom.fieldRange (algebraMap K L)
⊢ x ∈ Set.range ⇑(algebraMap K L)

Next tactic:
rwa [Set.mem_range, ← RingHom.mem_fieldRange]
theorem restrictScalars_injective :
    Function.Injective (restrictScalars K : IntermediateField L' L → IntermediateField K L) :=
  fun U V H => ext fun x => by 

Proof state:
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁶ : Field K
inst✝⁵ : Field L
inst✝⁴ : Field L'
inst✝³ : Algebra K L
inst✝² : Algebra K L'
S : IntermediateField K L
inst✝¹ : Algebra L' L
inst✝ : IsScalarTower K L' L
U V : IntermediateField L' L
H : restrictScalars K U = restrictScalars K V
x : L
⊢ x ∈ U ↔ x ∈ V

Next tactic:
rw [← mem_restrictScalars K, H, mem_restrictScalars]
/-- This was formerly an instance called `lift2_alg`, but an instance above already provides it. -/
example {F : IntermediateField K L} {E : IntermediateField F L} : Algebra K E := by 

Proof state:
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field L'
inst✝¹ : Algebra K L
inst✝ : Algebra K L'
S F : IntermediateField K L
E : IntermediateField (↥F) L
⊢ Algebra K ↥E

Next tactic:
infer_instance
/-- `IntermediateField.extendScalars` is an order isomorphism from
`{ E : IntermediateField K L // F ≤ E }` to `IntermediateField F L`. Its inverse is
`IntermediateField.restrictScalars`. -/
def extendScalars.orderIso : { E : IntermediateField K L // F ≤ E } ≃o IntermediateField F L where
  toFun E := extendScalars E.2
  invFun E := ⟨E.restrictScalars K, fun x hx ↦ E.algebraMap_mem ⟨x, hx⟩⟩
  left_inv E := rfl
  right_inv E := rfl
  map_rel_iff' {E E'} := by
    simp only [Equiv.coe_fn_mk]
    

Proof state:
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field L'
inst✝¹ : Algebra K L
inst✝ : Algebra K L'
S F E✝ E'✝ : IntermediateField K L
h : F ≤ E✝
h' : F ≤ E'✝
x : L
E E' : { E // F ≤ E }
⊢ extendScalars (_ : F ≤ ↑E) ≤ extendScalars (_ : F ≤ ↑E') ↔ E ≤ E'

Next tactic:
exact extendScalars_le_extendScalars_iff _ _
@[simp]
theorem toSubalgebra_eq_iff : F.toSubalgebra = E.toSubalgebra ↔ F = E := by
  

Proof state:
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field L'
inst✝¹ : Algebra K L
inst✝ : Algebra K L'
S F E : IntermediateField K L
⊢ F.toSubalgebra = E.toSubalgebra ↔ F = E

Next tactic:
rw [SetLike.ext_iff, SetLike.ext'_iff, Set.ext_iff]
@[simp]
theorem toSubalgebra_eq_iff : F.toSubalgebra = E.toSubalgebra ↔ F = E := by
  rw [SetLike.ext_iff, SetLike.ext'_iff, Set.ext_iff]
  

Proof state:
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field L'
inst✝¹ : Algebra K L
inst✝ : Algebra K L'
S F E : IntermediateField K L
⊢ (∀ (x : L), x ∈ F.toSubalgebra ↔ x ∈ E.toSubalgebra) ↔ ∀ (x : L), x ∈ ↑F ↔ x ∈ ↑E

Next tactic:
rfl
private theorem eq_of_le_of_finrank_le'' [FiniteDimensional K L] (h_le : F ≤ E)
    (h_finrank : finrank F L ≤ finrank E L) : F = E := by
  

Proof state:
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁵ : Field K
inst✝⁴ : Field L
inst✝³ : Field L'
inst✝² : Algebra K L
inst✝¹ : Algebra K L'
S F E : IntermediateField K L
inst✝ : FiniteDimensional K L
h_le : F ≤ E
h_finrank : finrank (↥F) L ≤ finrank (↥E) L
⊢ F = E

Next tactic:
apply eq_of_le_of_finrank_le h_le
private theorem eq_of_le_of_finrank_le'' [FiniteDimensional K L] (h_le : F ≤ E)
    (h_finrank : finrank F L ≤ finrank E L) : F = E := by
  apply eq_of_le_of_finrank_le h_le
  

Proof state:
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁵ : Field K
inst✝⁴ : Field L
inst✝³ : Field L'
inst✝² : Algebra K L
inst✝¹ : Algebra K L'
S F E : IntermediateField K L
inst✝ : FiniteDimensional K L
h_le : F ≤ E
h_finrank : finrank (↥F) L ≤ finrank (↥E) L
⊢ finrank K ↥E ≤ finrank K ↥F

Next tactic:
have h1 := finrank_mul_finrank K F L
private theorem eq_of_le_of_finrank_le'' [FiniteDimensional K L] (h_le : F ≤ E)
    (h_finrank : finrank F L ≤ finrank E L) : F = E := by
  apply eq_of_le_of_finrank_le h_le
  have h1 := finrank_mul_finrank K F L
  

Proof state:
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁵ : Field K
inst✝⁴ : Field L
inst✝³ : Field L'
inst✝² : Algebra K L
inst✝¹ : Algebra K L'
S F E : IntermediateField K L
inst✝ : FiniteDimensional K L
h_le : F ≤ E
h_finrank : finrank (↥F) L ≤ finrank (↥E) L
h1 : finrank K ↥F * finrank (↥F) L = finrank K L
⊢ finrank K ↥E ≤ finrank K ↥F

Next tactic:
have h2 := finrank_mul_finrank K E L
private theorem eq_of_le_of_finrank_le'' [FiniteDimensional K L] (h_le : F ≤ E)
    (h_finrank : finrank F L ≤ finrank E L) : F = E := by
  apply eq_of_le_of_finrank_le h_le
  have h1 := finrank_mul_finrank K F L
  have h2 := finrank_mul_finrank K E L
  

Proof state:
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁵ : Field K
inst✝⁴ : Field L
inst✝³ : Field L'
inst✝² : Algebra K L
inst✝¹ : Algebra K L'
S F E : IntermediateField K L
inst✝ : FiniteDimensional K L
h_le : F ≤ E
h_finrank : finrank (↥F) L ≤ finrank (↥E) L
h1 : finrank K ↥F * finrank (↥F) L = finrank K L
h2 : finrank K ↥E * finrank (↥E) L = finrank K L
⊢ finrank K ↥E ≤ finrank K ↥F

Next tactic:
have h3 : 0 < finrank E L := finrank_pos
private theorem eq_of_le_of_finrank_le'' [FiniteDimensional K L] (h_le : F ≤ E)
    (h_finrank : finrank F L ≤ finrank E L) : F = E := by
  apply eq_of_le_of_finrank_le h_le
  have h1 := finrank_mul_finrank K F L
  have h2 := finrank_mul_finrank K E L
  have h3 : 0 < finrank E L := finrank_pos
  

Proof state:
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁵ : Field K
inst✝⁴ : Field L
inst✝³ : Field L'
inst✝² : Algebra K L
inst✝¹ : Algebra K L'
S F E : IntermediateField K L
inst✝ : FiniteDimensional K L
h_le : F ≤ E
h_finrank : finrank (↥F) L ≤ finrank (↥E) L
h1 : finrank K ↥F * finrank (↥F) L = finrank K L
h2 : finrank K ↥E * finrank (↥E) L = finrank K L
h3 : 0 < finrank (↥E) L
⊢ finrank K ↥E ≤ finrank K ↥F

Next tactic:
nlinarith
/-- If `F ≤ E` are two intermediate fields of `L / K` such that `[L : F] ≤ [L : E]` are finite,
then `F = E`. -/
theorem eq_of_le_of_finrank_le' [FiniteDimensional F L] (h_le : F ≤ E)
    (h_finrank : finrank F L ≤ finrank E L) : F = E := by
  

Proof state:
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁵ : Field K
inst✝⁴ : Field L
inst✝³ : Field L'
inst✝² : Algebra K L
inst✝¹ : Algebra K L'
S F E : IntermediateField K L
inst✝ : FiniteDimensional (↥F) L
h_le : F ≤ E
h_finrank : finrank (↥F) L ≤ finrank (↥E) L
⊢ F = E

Next tactic:
refine le_antisymm h_le (fun l hl ↦ ?_)
/-- If `F ≤ E` are two intermediate fields of `L / K` such that `[L : F] ≤ [L : E]` are finite,
then `F = E`. -/
theorem eq_of_le_of_finrank_le' [FiniteDimensional F L] (h_le : F ≤ E)
    (h_finrank : finrank F L ≤ finrank E L) : F = E := by
  refine le_antisymm h_le (fun l hl ↦ ?_)
  

Proof state:
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁵ : Field K
inst✝⁴ : Field L
inst✝³ : Field L'
inst✝² : Algebra K L
inst✝¹ : Algebra K L'
S F E : IntermediateField K L
inst✝ : FiniteDimensional (↥F) L
h_le : F ≤ E
h_finrank : finrank (↥F) L ≤ finrank (↥E) L
l : L
hl : l ∈ E
⊢ l ∈ F

Next tactic:
rwa [← mem_extendScalars (le_refl F), eq_of_le_of_finrank_le''
    ((extendScalars_le_extendScalars_iff (le_refl F) h_le).2 h_le) h_finrank, mem_extendScalars]
theorem isIntegral_iff {x : S} : IsIntegral K x ↔ IsIntegral K (x : L) := by
  

Proof state:
K : Type u_1
L : Type u_2
L' : Type u_3
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field L'
inst✝¹ : Algebra K L
inst✝ : Algebra K L'
S : IntermediateField K L
x : ↥S
⊢ IsIntegral K x ↔ IsIntegral K ↑x

Next tactic:
rw [← isAlgebraic_iff_isIntegral, isAlgebraic_iff, isAlgebraic_iff_isIntegral]
/-- The multiplicity of `m` in `n` is the number of positive natural numbers `i` such that `m ^ i`
divides `n`. This set is expressed by filtering `Ico 1 b` where `b` is any bound greater than
`log m n`. -/
theorem multiplicity_eq_card_pow_dvd {m n b : ℕ} (hm : m ≠ 1) (hn : 0 < n) (hb : log m n < b) :
    multiplicity m n = ↑((Finset.Ico 1 b).filter fun i => m ^ i ∣ n).card :=
  calc
    multiplicity m n = ↑(Ico 1 <| (multiplicity m n).get (finite_nat_iff.2 ⟨hm, hn⟩) + 1).card := by
      

Proof state:
m n b : ℕ
hm : m ≠ 1
hn : 0 < n
hb : log m n < b
⊢ multiplicity m n = ↑(card (Ico 1 (Part.get (multiplicity m n) (_ : multiplicity.Finite m n) + 1)))

Next tactic:
simp
/-- The multiplicity of `m` in `n` is the number of positive natural numbers `i` such that `m ^ i`
divides `n`. This set is expressed by filtering `Ico 1 b` where `b` is any bound greater than
`log m n`. -/
theorem multiplicity_eq_card_pow_dvd {m n b : ℕ} (hm : m ≠ 1) (hn : 0 < n) (hb : log m n < b) :
    multiplicity m n = ↑((Finset.Ico 1 b).filter fun i => m ^ i ∣ n).card :=
  calc
    multiplicity m n = ↑(Ico 1 <| (multiplicity m n).get (finite_nat_iff.2 ⟨hm, hn⟩) + 1).card := by
      simp
    _ = ↑((Finset.Ico 1 b).filter fun i => m ^ i ∣ n).card :=
      congr_arg _ <|
        congr_arg card <|
          Finset.ext fun i => by
            

Proof state:
m n b : ℕ
hm : m ≠ 1
hn : 0 < n
hb : log m n < b
i : ℕ
⊢ i ∈ Ico 1 (Part.get (multiplicity m n) (_ : multiplicity.Finite m n) + 1) ↔ i ∈ filter (fun i => m ^ i ∣ n) (Ico 1 b)

Next tactic:
rw [mem_filter, mem_Ico, mem_Ico, lt_succ_iff, ← @PartENat.coe_le_coe i,
              PartENat.natCast_get, ← pow_dvd_iff_le_multiplicity, and_right_comm]
/-- The multiplicity of `m` in `n` is the number of positive natural numbers `i` such that `m ^ i`
divides `n`. This set is expressed by filtering `Ico 1 b` where `b` is any bound greater than
`log m n`. -/
theorem multiplicity_eq_card_pow_dvd {m n b : ℕ} (hm : m ≠ 1) (hn : 0 < n) (hb : log m n < b) :
    multiplicity m n = ↑((Finset.Ico 1 b).filter fun i => m ^ i ∣ n).card :=
  calc
    multiplicity m n = ↑(Ico 1 <| (multiplicity m n).get (finite_nat_iff.2 ⟨hm, hn⟩) + 1).card := by
      simp
    _ = ↑((Finset.Ico 1 b).filter fun i => m ^ i ∣ n).card :=
      congr_arg _ <|
        congr_arg card <|
          Finset.ext fun i => by
            rw [mem_filter, mem_Ico, mem_Ico, lt_succ_iff, ← @PartENat.coe_le_coe i,
              PartENat.natCast_get, ← pow_dvd_iff_le_multiplicity, and_right_comm]
            

Proof state:
m n b : ℕ
hm : m ≠ 1
hn : 0 < n
hb : log m n < b
i : ℕ
⊢ 1 ≤ i ∧ m ^ i ∣ n ↔ (1 ≤ i ∧ m ^ i ∣ n) ∧ i < b

Next tactic:
refine' (and_iff_left_of_imp fun h => lt_of_le_of_lt _ hb).symm
/-- The multiplicity of `m` in `n` is the number of positive natural numbers `i` such that `m ^ i`
divides `n`. This set is expressed by filtering `Ico 1 b` where `b` is any bound greater than
`log m n`. -/
theorem multiplicity_eq_card_pow_dvd {m n b : ℕ} (hm : m ≠ 1) (hn : 0 < n) (hb : log m n < b) :
    multiplicity m n = ↑((Finset.Ico 1 b).filter fun i => m ^ i ∣ n).card :=
  calc
    multiplicity m n = ↑(Ico 1 <| (multiplicity m n).get (finite_nat_iff.2 ⟨hm, hn⟩) + 1).card := by
      simp
    _ = ↑((Finset.Ico 1 b).filter fun i => m ^ i ∣ n).card :=
      congr_arg _ <|
        congr_arg card <|
          Finset.ext fun i => by
            rw [mem_filter, mem_Ico, mem_Ico, lt_succ_iff, ← @PartENat.coe_le_coe i,
              PartENat.natCast_get, ← pow_dvd_iff_le_multiplicity, and_right_comm]
            refine' (and_iff_left_of_imp fun h => lt_of_le_of_lt _ hb).symm
            

Proof state:
m n b : ℕ
hm : m ≠ 1
hn : 0 < n
hb : log m n < b
i : ℕ
h : 1 ≤ i ∧ m ^ i ∣ n
⊢ i ≤ log m n

Next tactic:
cases' m with m
/-- The multiplicity of `m` in `n` is the number of positive natural numbers `i` such that `m ^ i`
divides `n`. This set is expressed by filtering `Ico 1 b` where `b` is any bound greater than
`log m n`. -/
theorem multiplicity_eq_card_pow_dvd {m n b : ℕ} (hm : m ≠ 1) (hn : 0 < n) (hb : log m n < b) :
    multiplicity m n = ↑((Finset.Ico 1 b).filter fun i => m ^ i ∣ n).card :=
  calc
    multiplicity m n = ↑(Ico 1 <| (multiplicity m n).get (finite_nat_iff.2 ⟨hm, hn⟩) + 1).card := by
      simp
    _ = ↑((Finset.Ico 1 b).filter fun i => m ^ i ∣ n).card :=
      congr_arg _ <|
        congr_arg card <|
          Finset.ext fun i => by
            rw [mem_filter, mem_Ico, mem_Ico, lt_succ_iff, ← @PartENat.coe_le_coe i,
              PartENat.natCast_get, ← pow_dvd_iff_le_multiplicity, and_right_comm]
            refine' (and_iff_left_of_imp fun h => lt_of_le_of_lt _ hb).symm
            cases' m with m
            · 

Proof state:
case zero
n b : ℕ
hn : 0 < n
i : ℕ
hm : zero ≠ 1
hb : log zero n < b
h : 1 ≤ i ∧ zero ^ i ∣ n
⊢ i ≤ log zero n

Next tactic:
rw [zero_eq, zero_pow, zero_dvd_iff] at h
/-- The multiplicity of `m` in `n` is the number of positive natural numbers `i` such that `m ^ i`
divides `n`. This set is expressed by filtering `Ico 1 b` where `b` is any bound greater than
`log m n`. -/
theorem multiplicity_eq_card_pow_dvd {m n b : ℕ} (hm : m ≠ 1) (hn : 0 < n) (hb : log m n < b) :
    multiplicity m n = ↑((Finset.Ico 1 b).filter fun i => m ^ i ∣ n).card :=
  calc
    multiplicity m n = ↑(Ico 1 <| (multiplicity m n).get (finite_nat_iff.2 ⟨hm, hn⟩) + 1).card := by
      simp
    _ = ↑((Finset.Ico 1 b).filter fun i => m ^ i ∣ n).card :=
      congr_arg _ <|
        congr_arg card <|
          Finset.ext fun i => by
            rw [mem_filter, mem_Ico, mem_Ico, lt_succ_iff, ← @PartENat.coe_le_coe i,
              PartENat.natCast_get, ← pow_dvd_iff_le_multiplicity, and_right_comm]
            refine' (and_iff_left_of_imp fun h => lt_of_le_of_lt _ hb).symm
            cases' m with m
            · rw [zero_eq, zero_pow, zero_dvd_iff] at h
              

Proof state:
case zero
n b : ℕ
hn : 0 < n
i : ℕ
hm : zero ≠ 1
hb : log zero n < b
h : 1 ≤ i ∧ n = 0
⊢ i ≤ log zero n
case zero n b : ℕ hn : 0 < n i : ℕ hm : zero ≠ 1 hb : log zero n < b h : 1 ≤ i ∧ 0 ^ i ∣ n ⊢ 0 < i

Next tactic:
exacts [(hn.ne' h.2).elim, h.1]
/-- The multiplicity of `m` in `n` is the number of positive natural numbers `i` such that `m ^ i`
divides `n`. This set is expressed by filtering `Ico 1 b` where `b` is any bound greater than
`log m n`. -/
theorem multiplicity_eq_card_pow_dvd {m n b : ℕ} (hm : m ≠ 1) (hn : 0 < n) (hb : log m n < b) :
    multiplicity m n = ↑((Finset.Ico 1 b).filter fun i => m ^ i ∣ n).card :=
  calc
    multiplicity m n = ↑(Ico 1 <| (multiplicity m n).get (finite_nat_iff.2 ⟨hm, hn⟩) + 1).card := by
      simp
    _ = ↑((Finset.Ico 1 b).filter fun i => m ^ i ∣ n).card :=
      congr_arg _ <|
        congr_arg card <|
          Finset.ext fun i => by
            rw [mem_filter, mem_Ico, mem_Ico, lt_succ_iff, ← @PartENat.coe_le_coe i,
              PartENat.natCast_get, ← pow_dvd_iff_le_multiplicity, and_right_comm]
            refine' (and_iff_left_of_imp fun h => lt_of_le_of_lt _ hb).symm
            cases' m with m
            · rw [zero_eq, zero_pow, zero_dvd_iff] at h
              exacts [(hn.ne' h.2).elim, h.1]
            

Proof state:
case succ
n b : ℕ
hn : 0 < n
i m : ℕ
hm : succ m ≠ 1
hb : log (succ m) n < b
h : 1 ≤ i ∧ succ m ^ i ∣ n
⊢ i ≤ log (succ m) n

Next tactic:
exact le_log_of_pow_le (one_lt_iff_ne_zero_and_ne_one.2 ⟨m.succ_ne_zero, hm⟩)
                (le_of_dvd hn h.2)
/-- **Legendre's Theorem**

The multiplicity of a prime in `n!` is the sum of the quotients `n / p ^ i`. This sum is expressed
over the finset `Ico 1 b` where `b` is any bound greater than `log p n`. -/
theorem multiplicity_factorial {p : ℕ} (hp : p.Prime) :
    ∀ {n b : ℕ}, log p n < b → multiplicity p n ! = (∑ i in Ico 1 b, n / p ^ i : ℕ)
  | 0, b, _ => by 

Proof state:
p : ℕ
hp : Prime p
b : ℕ
x✝ : log p 0 < b
⊢ multiplicity p 0! = ↑(∑ i in Ico 1 b, 0 / p ^ i)

Next tactic:
simp [Ico, hp.multiplicity_one]