l3lab/ntp-mathlib huggingface dataset:
/-- This is used to prove the strictly stronger `ker_fg_of_surjective`. Use it instead. -/
theorem ker_fg_of_mvPolynomial {n : ℕ} (f : MvPolynomial (Fin n) R →ₐ[R] A)
    (hf : Function.Surjective f) (hfp : FinitePresentation R A) : f.toRingHom.ker.FG := by
  classical
    obtain ⟨m, f', hf', s, hs⟩ := hfp
    let RXn := MvPolynomial (Fin n) R
    let RXm := MvPolynomial (Fin m) R
    have := fun i : Fin n => hf' (f <| X i)
    choose g hg using this
    have := fun i : Fin m => hf (f' <| X i)
    choose h hh using this
    let aeval_h : RXm →ₐ[R] RXn := aeval h
    let g' : Fin n → RXn := fun i => X i - aeval_h (g i)
    refine' ⟨Finset.univ.image g' ∪ s.image aeval_h, _⟩
    simp only [Finset.coe_image, Finset.coe_union, Finset.coe_univ, Set.image_univ]
    have hh' : ∀ x, f (aeval_h x) = f' x := by
      intro x
      rw [← f.coe_toRingHom, map_aeval]
      simp_rw [AlgHom.coe_toRingHom, hh]
      rw [AlgHom.comp_algebraMap, ← aeval_eq_eval₂Hom,
        -- Porting note: added line below
        ← funext fun i => Function.comp_apply (f := ↑f') (g := MvPolynomial.X),
        ← aeval_unique]
    let s' := Set.range g' ∪ aeval_h '' s
    have leI : Ideal.span s' ≤ RingHom.ker f.toRingHom := by
      rw [Ideal.span_le]
      rintro _ (⟨i, rfl⟩ | ⟨x, hx, rfl⟩)
      · change f (g' i) = 0
        rw [map_sub, ← hg, hh', sub_self]
      · change f (aeval_h x) = 0
        rw [hh']
        change x ∈ RingHom.ker f'.toRingHom
        rw [← hs]
        exact Ideal.subset_span hx
    apply leI.antisymm
    intro x hx
    have : x ∈ aeval_h.range.toAddSubmonoid ⊔ (Ideal.span s').toAddSubmonoid := by
      have : x ∈ adjoin R (Set.range X : Set RXn) := by
        rw [adjoin_range_X]
        trivial
      refine adjoin_induction this ?_ ?_ ?_ ?_
      · rintro _ ⟨i, rfl⟩
        rw [← sub_add_cancel (X i) (aeval h (g i)), add_comm]
        apply AddSubmonoid.add_mem_sup
        · exact Set.mem_range_self _
        · apply Submodule.subset_span
          apply Set.mem_union_left
          exact Set.mem_range_self _
      · 

Proof state:
case refine_2
R : Type w₁
A : Type w₂
B : Type w₃
inst✝⁴ : CommRing R
inst✝³ : CommRing A
inst✝² : Algebra R A
inst✝¹ : CommRing B
inst✝ : Algebra R B
n : ℕ
f : MvPolynomial (Fin n) R →ₐ[R] A
hf : Surjective ⇑f
m : ℕ
f' : MvPolynomial (Fin m) R →ₐ[R] A
hf' : Surjective ⇑f'
s : Finset (MvPolynomial (Fin m) R)
hs : Ideal.span ↑s = RingHom.ker ↑f'
RXn : Type w₁ := MvPolynomial (Fin n) R
RXm : Type w₁ := MvPolynomial (Fin m) R
g : Fin n → MvPolynomial (Fin m) R
hg : ∀ (i : Fin n), f' (g i) = f (MvPolynomial.X i)
h : Fin m → MvPolynomial (Fin n) R
hh : ∀ (i : Fin m), f (h i) = f' (MvPolynomial.X i)
aeval_h : RXm →ₐ[R] RXn := MvPolynomial.aeval h
g' : Fin n → RXn := fun i => MvPolynomial.X i - aeval_h (g i)
hh' : ∀ (x : RXm), f (aeval_h x) = f' x
s' : Set RXn := Set.range g' ∪ ⇑aeval_h '' ↑s
leI : Ideal.span s' ≤ RingHom.ker ↑f
x : RXn
hx : x ∈ RingHom.ker ↑f
this : x ∈ adjoin R (Set.range MvPolynomial.X)
⊢ ∀ (r : R), (algebraMap R RXn) r ∈ Subalgebra.toAddSubmonoid (AlgHom.range aeval_h) ⊔ (Ideal.span s').toAddSubmonoid

Next tactic:
intro r
/-- This is used to prove the strictly stronger `ker_fg_of_surjective`. Use it instead. -/
theorem ker_fg_of_mvPolynomial {n : ℕ} (f : MvPolynomial (Fin n) R →ₐ[R] A)
    (hf : Function.Surjective f) (hfp : FinitePresentation R A) : f.toRingHom.ker.FG := by
  classical
    obtain ⟨m, f', hf', s, hs⟩ := hfp
    let RXn := MvPolynomial (Fin n) R
    let RXm := MvPolynomial (Fin m) R
    have := fun i : Fin n => hf' (f <| X i)
    choose g hg using this
    have := fun i : Fin m => hf (f' <| X i)
    choose h hh using this
    let aeval_h : RXm →ₐ[R] RXn := aeval h
    let g' : Fin n → RXn := fun i => X i - aeval_h (g i)
    refine' ⟨Finset.univ.image g' ∪ s.image aeval_h, _⟩
    simp only [Finset.coe_image, Finset.coe_union, Finset.coe_univ, Set.image_univ]
    have hh' : ∀ x, f (aeval_h x) = f' x := by
      intro x
      rw [← f.coe_toRingHom, map_aeval]
      simp_rw [AlgHom.coe_toRingHom, hh]
      rw [AlgHom.comp_algebraMap, ← aeval_eq_eval₂Hom,
        -- Porting note: added line below
        ← funext fun i => Function.comp_apply (f := ↑f') (g := MvPolynomial.X),
        ← aeval_unique]
    let s' := Set.range g' ∪ aeval_h '' s
    have leI : Ideal.span s' ≤ RingHom.ker f.toRingHom := by
      rw [Ideal.span_le]
      rintro _ (⟨i, rfl⟩ | ⟨x, hx, rfl⟩)
      · change f (g' i) = 0
        rw [map_sub, ← hg, hh', sub_self]
      · change f (aeval_h x) = 0
        rw [hh']
        change x ∈ RingHom.ker f'.toRingHom
        rw [← hs]
        exact Ideal.subset_span hx
    apply leI.antisymm
    intro x hx
    have : x ∈ aeval_h.range.toAddSubmonoid ⊔ (Ideal.span s').toAddSubmonoid := by
      have : x ∈ adjoin R (Set.range X : Set RXn) := by
        rw [adjoin_range_X]
        trivial
      refine adjoin_induction this ?_ ?_ ?_ ?_
      · rintro _ ⟨i, rfl⟩
        rw [← sub_add_cancel (X i) (aeval h (g i)), add_comm]
        apply AddSubmonoid.add_mem_sup
        · exact Set.mem_range_self _
        · apply Submodule.subset_span
          apply Set.mem_union_left
          exact Set.mem_range_self _
      · intro r
        

Proof state:
case refine_2
R : Type w₁
A : Type w₂
B : Type w₃
inst✝⁴ : CommRing R
inst✝³ : CommRing A
inst✝² : Algebra R A
inst✝¹ : CommRing B
inst✝ : Algebra R B
n : ℕ
f : MvPolynomial (Fin n) R →ₐ[R] A
hf : Surjective ⇑f
m : ℕ
f' : MvPolynomial (Fin m) R →ₐ[R] A
hf' : Surjective ⇑f'
s : Finset (MvPolynomial (Fin m) R)
hs : Ideal.span ↑s = RingHom.ker ↑f'
RXn : Type w₁ := MvPolynomial (Fin n) R
RXm : Type w₁ := MvPolynomial (Fin m) R
g : Fin n → MvPolynomial (Fin m) R
hg : ∀ (i : Fin n), f' (g i) = f (MvPolynomial.X i)
h : Fin m → MvPolynomial (Fin n) R
hh : ∀ (i : Fin m), f (h i) = f' (MvPolynomial.X i)
aeval_h : RXm →ₐ[R] RXn := MvPolynomial.aeval h
g' : Fin n → RXn := fun i => MvPolynomial.X i - aeval_h (g i)
hh' : ∀ (x : RXm), f (aeval_h x) = f' x
s' : Set RXn := Set.range g' ∪ ⇑aeval_h '' ↑s
leI : Ideal.span s' ≤ RingHom.ker ↑f
x : RXn
hx : x ∈ RingHom.ker ↑f
this : x ∈ adjoin R (Set.range MvPolynomial.X)
r : R
⊢ (algebraMap R RXn) r ∈ Subalgebra.toAddSubmonoid (AlgHom.range aeval_h) ⊔ (Ideal.span s').toAddSubmonoid

Next tactic:
apply AddSubmonoid.mem_sup_left
/-- This is used to prove the strictly stronger `ker_fg_of_surjective`. Use it instead. -/
theorem ker_fg_of_mvPolynomial {n : ℕ} (f : MvPolynomial (Fin n) R →ₐ[R] A)
    (hf : Function.Surjective f) (hfp : FinitePresentation R A) : f.toRingHom.ker.FG := by
  classical
    obtain ⟨m, f', hf', s, hs⟩ := hfp
    let RXn := MvPolynomial (Fin n) R
    let RXm := MvPolynomial (Fin m) R
    have := fun i : Fin n => hf' (f <| X i)
    choose g hg using this
    have := fun i : Fin m => hf (f' <| X i)
    choose h hh using this
    let aeval_h : RXm →ₐ[R] RXn := aeval h
    let g' : Fin n → RXn := fun i => X i - aeval_h (g i)
    refine' ⟨Finset.univ.image g' ∪ s.image aeval_h, _⟩
    simp only [Finset.coe_image, Finset.coe_union, Finset.coe_univ, Set.image_univ]
    have hh' : ∀ x, f (aeval_h x) = f' x := by
      intro x
      rw [← f.coe_toRingHom, map_aeval]
      simp_rw [AlgHom.coe_toRingHom, hh]
      rw [AlgHom.comp_algebraMap, ← aeval_eq_eval₂Hom,
        -- Porting note: added line below
        ← funext fun i => Function.comp_apply (f := ↑f') (g := MvPolynomial.X),
        ← aeval_unique]
    let s' := Set.range g' ∪ aeval_h '' s
    have leI : Ideal.span s' ≤ RingHom.ker f.toRingHom := by
      rw [Ideal.span_le]
      rintro _ (⟨i, rfl⟩ | ⟨x, hx, rfl⟩)
      · change f (g' i) = 0
        rw [map_sub, ← hg, hh', sub_self]
      · change f (aeval_h x) = 0
        rw [hh']
        change x ∈ RingHom.ker f'.toRingHom
        rw [← hs]
        exact Ideal.subset_span hx
    apply leI.antisymm
    intro x hx
    have : x ∈ aeval_h.range.toAddSubmonoid ⊔ (Ideal.span s').toAddSubmonoid := by
      have : x ∈ adjoin R (Set.range X : Set RXn) := by
        rw [adjoin_range_X]
        trivial
      refine adjoin_induction this ?_ ?_ ?_ ?_
      · rintro _ ⟨i, rfl⟩
        rw [← sub_add_cancel (X i) (aeval h (g i)), add_comm]
        apply AddSubmonoid.add_mem_sup
        · exact Set.mem_range_self _
        · apply Submodule.subset_span
          apply Set.mem_union_left
          exact Set.mem_range_self _
      · intro r
        apply AddSubmonoid.mem_sup_left
        

Proof state:
case refine_2.a
R : Type w₁
A : Type w₂
B : Type w₃
inst✝⁴ : CommRing R
inst✝³ : CommRing A
inst✝² : Algebra R A
inst✝¹ : CommRing B
inst✝ : Algebra R B
n : ℕ
f : MvPolynomial (Fin n) R →ₐ[R] A
hf : Surjective ⇑f
m : ℕ
f' : MvPolynomial (Fin m) R →ₐ[R] A
hf' : Surjective ⇑f'
s : Finset (MvPolynomial (Fin m) R)
hs : Ideal.span ↑s = RingHom.ker ↑f'
RXn : Type w₁ := MvPolynomial (Fin n) R
RXm : Type w₁ := MvPolynomial (Fin m) R
g : Fin n → MvPolynomial (Fin m) R
hg : ∀ (i : Fin n), f' (g i) = f (MvPolynomial.X i)
h : Fin m → MvPolynomial (Fin n) R
hh : ∀ (i : Fin m), f (h i) = f' (MvPolynomial.X i)
aeval_h : RXm →ₐ[R] RXn := MvPolynomial.aeval h
g' : Fin n → RXn := fun i => MvPolynomial.X i - aeval_h (g i)
hh' : ∀ (x : RXm), f (aeval_h x) = f' x
s' : Set RXn := Set.range g' ∪ ⇑aeval_h '' ↑s
leI : Ideal.span s' ≤ RingHom.ker ↑f
x : RXn
hx : x ∈ RingHom.ker ↑f
this : x ∈ adjoin R (Set.range MvPolynomial.X)
r : R
⊢ (algebraMap R RXn) r ∈ Subalgebra.toAddSubmonoid (AlgHom.range aeval_h)

Next tactic:
exact ⟨C r, aeval_C _ _⟩
/-- If `f : A →ₐ[R] B` is a surjection between finitely-presented `R`-algebras, then the kernel of
`f` is finitely generated. -/
theorem ker_fG_of_surjective (f : A →ₐ[R] B) (hf : Function.Surjective f)
    (hRA : FinitePresentation R A) (hRB : FinitePresentation R B) : f.toRingHom.ker.FG := by
  

Proof state:
R : Type w₁
A : Type w₂
B : Type w₃
inst✝⁴ : CommRing R
inst✝³ : CommRing A
inst✝² : Algebra R A
inst✝¹ : CommRing B
inst✝ : Algebra R B
f : A →ₐ[R] B
hf : Surjective ⇑f
hRA : FinitePresentation R A
hRB : FinitePresentation R B
⊢ Ideal.FG (RingHom.ker ↑f)

Next tactic:
obtain ⟨n, g, hg, _⟩ := hRA
/-- If `f : A →ₐ[R] B` is a surjection between finitely-presented `R`-algebras, then the kernel of
`f` is finitely generated. -/
theorem ker_fG_of_surjective (f : A →ₐ[R] B) (hf : Function.Surjective f)
    (hRA : FinitePresentation R A) (hRB : FinitePresentation R B) : f.toRingHom.ker.FG := by
  obtain ⟨n, g, hg, _⟩ := hRA
  

Proof state:
case intro.intro.intro
R : Type w₁
A : Type w₂
B : Type w₃
inst✝⁴ : CommRing R
inst✝³ : CommRing A
inst✝² : Algebra R A
inst✝¹ : CommRing B
inst✝ : Algebra R B
f : A →ₐ[R] B
hf : Surjective ⇑f
hRB : FinitePresentation R B
n : ℕ
g : MvPolynomial (Fin n) R →ₐ[R] A
hg : Surjective ⇑g
right✝ : Ideal.FG (RingHom.ker ↑g)
⊢ Ideal.FG (RingHom.ker ↑f)

Next tactic:
convert (ker_fg_of_mvPolynomial (f.comp g) (hf.comp hg) hRB).map g.toRingHom
/-- If `f : A →ₐ[R] B` is a surjection between finitely-presented `R`-algebras, then the kernel of
`f` is finitely generated. -/
theorem ker_fG_of_surjective (f : A →ₐ[R] B) (hf : Function.Surjective f)
    (hRA : FinitePresentation R A) (hRB : FinitePresentation R B) : f.toRingHom.ker.FG := by
  obtain ⟨n, g, hg, _⟩ := hRA
  convert (ker_fg_of_mvPolynomial (f.comp g) (hf.comp hg) hRB).map g.toRingHom
  

Proof state:
case h.e'_3
R : Type w₁
A : Type w₂
B : Type w₃
inst✝⁴ : CommRing R
inst✝³ : CommRing A
inst✝² : Algebra R A
inst✝¹ : CommRing B
inst✝ : Algebra R B
f : A →ₐ[R] B
hf : Surjective ⇑f
hRB : FinitePresentation R B
n : ℕ
g : MvPolynomial (Fin n) R →ₐ[R] A
hg : Surjective ⇑g
right✝ : Ideal.FG (RingHom.ker ↑g)
⊢ RingHom.ker ↑f = Ideal.map (↑g) (RingHom.ker ↑(AlgHom.comp f g))

Next tactic:
simp_rw [RingHom.ker_eq_comap_bot, AlgHom.toRingHom_eq_coe, AlgHom.comp_toRingHom]
/-- If `f : A →ₐ[R] B` is a surjection between finitely-presented `R`-algebras, then the kernel of
`f` is finitely generated. -/
theorem ker_fG_of_surjective (f : A →ₐ[R] B) (hf : Function.Surjective f)
    (hRA : FinitePresentation R A) (hRB : FinitePresentation R B) : f.toRingHom.ker.FG := by
  obtain ⟨n, g, hg, _⟩ := hRA
  convert (ker_fg_of_mvPolynomial (f.comp g) (hf.comp hg) hRB).map g.toRingHom
  simp_rw [RingHom.ker_eq_comap_bot, AlgHom.toRingHom_eq_coe, AlgHom.comp_toRingHom]
  

Proof state:
case h.e'_3
R : Type w₁
A : Type w₂
B : Type w₃
inst✝⁴ : CommRing R
inst✝³ : CommRing A
inst✝² : Algebra R A
inst✝¹ : CommRing B
inst✝ : Algebra R B
f : A →ₐ[R] B
hf : Surjective ⇑f
hRB : FinitePresentation R B
n : ℕ
g : MvPolynomial (Fin n) R →ₐ[R] A
hg : Surjective ⇑g
right✝ : Ideal.FG (RingHom.ker ↑g)
⊢ Ideal.comap ↑f ⊥ = Ideal.map (↑g) (Ideal.comap (RingHom.comp ↑f ↑g) ⊥)

Next tactic:
rw [← Ideal.comap_comap, Ideal.map_comap_of_surjective (g : MvPolynomial (Fin n) R →+* A) hg]
theorem of_surjective (f : A →+* B) (hf : Surjective f) (hker : f.ker.FG) :
    f.FinitePresentation := by
  

Proof state:
A : Type u_1
B : Type u_2
C : Type u_3
inst✝² : CommRing A
inst✝¹ : CommRing B
inst✝ : CommRing C
f : A →+* B
hf : Surjective ⇑f
hker : Ideal.FG (ker f)
⊢ FinitePresentation f

Next tactic:
rw [← f.comp_id]
theorem of_surjective (f : A →+* B) (hf : Surjective f) (hker : f.ker.FG) :
    f.FinitePresentation := by
  rw [← f.comp_id]
  

Proof state:
A : Type u_1
B : Type u_2
C : Type u_3
inst✝² : CommRing A
inst✝¹ : CommRing B
inst✝ : CommRing C
f : A →+* B
hf : Surjective ⇑f
hker : Ideal.FG (ker f)
⊢ FinitePresentation (comp f (RingHom.id A))

Next tactic:
exact (id A).comp_surjective hf hker
theorem comp {g : B →+* C} {f : A →+* B} (hg : g.FinitePresentation) (hf : f.FinitePresentation) :
    (g.comp f).FinitePresentation :=
  -- Porting note : specify `Algebra` instances to get `SMul`
  letI ins1 := RingHom.toAlgebra f
  letI ins2 := RingHom.toAlgebra g
  letI ins3 := RingHom.toAlgebra (g.comp f)
  letI ins4 : IsScalarTower A B C :=
    { smul_assoc := fun a b c => by 

Proof state:
A : Type u_1
B : Type u_2
C : Type u_3
inst✝² : CommRing A
inst✝¹ : CommRing B
inst✝ : CommRing C
g : B →+* C
f : A →+* B
hg : FinitePresentation g
hf : FinitePresentation f
ins1 : Algebra A B := toAlgebra f
ins2 : Algebra B C := toAlgebra g
ins3 : Algebra A C := toAlgebra (RingHom.comp g f)
a : A
b : B
c : C
⊢ (a • b) • c = a • b • c

Next tactic:
simp [Algebra.smul_def, mul_assoc]
theorem comp {g : B →+* C} {f : A →+* B} (hg : g.FinitePresentation) (hf : f.FinitePresentation) :
    (g.comp f).FinitePresentation :=
  -- Porting note : specify `Algebra` instances to get `SMul`
  letI ins1 := RingHom.toAlgebra f
  letI ins2 := RingHom.toAlgebra g
  letI ins3 := RingHom.toAlgebra (g.comp f)
  letI ins4 : IsScalarTower A B C :=
    { smul_assoc := fun a b c => by simp [Algebra.smul_def, mul_assoc]; 

Proof state:
A : Type u_1
B : Type u_2
C : Type u_3
inst✝² : CommRing A
inst✝¹ : CommRing B
inst✝ : CommRing C
g : B →+* C
f : A →+* B
hg : FinitePresentation g
hf : FinitePresentation f
ins1 : Algebra A B := toAlgebra f
ins2 : Algebra B C := toAlgebra g
ins3 : Algebra A C := toAlgebra (RingHom.comp g f)
a : A
b : B
c : C
⊢ (algebraMap B C) ((algebraMap A B) a) * ((algebraMap B C) b * c) = (algebraMap A C) a * ((algebraMap B C) b * c)

Next tactic:
rfl
theorem of_comp_finiteType (f : A →+* B) {g : B →+* C} (hg : (g.comp f).FinitePresentation)
    (hf : f.FiniteType) : g.FinitePresentation :=
  -- Porting note : need to specify some instances
  letI ins1 := RingHom.toAlgebra f
  letI ins2 := RingHom.toAlgebra g
  letI ins3 := RingHom.toAlgebra (g.comp f)
  letI ins4 : IsScalarTower A B C :=
    { smul_assoc := fun a b c => by 

Proof state:
A : Type u_1
B : Type u_2
C : Type u_3
inst✝² : CommRing A
inst✝¹ : CommRing B
inst✝ : CommRing C
f : A →+* B
g : B →+* C
hg : FinitePresentation (RingHom.comp g f)
hf : FiniteType f
ins1 : Algebra A B := toAlgebra f
ins2 : Algebra B C := toAlgebra g
ins3 : Algebra A C := toAlgebra (RingHom.comp g f)
a : A
b : B
c : C
⊢ (a • b) • c = a • b • c

Next tactic:
simp [Algebra.smul_def, mul_assoc]
theorem of_comp_finiteType (f : A →+* B) {g : B →+* C} (hg : (g.comp f).FinitePresentation)
    (hf : f.FiniteType) : g.FinitePresentation :=
  -- Porting note : need to specify some instances
  letI ins1 := RingHom.toAlgebra f
  letI ins2 := RingHom.toAlgebra g
  letI ins3 := RingHom.toAlgebra (g.comp f)
  letI ins4 : IsScalarTower A B C :=
    { smul_assoc := fun a b c => by simp [Algebra.smul_def, mul_assoc]; 

Proof state:
A : Type u_1
B : Type u_2
C : Type u_3
inst✝² : CommRing A
inst✝¹ : CommRing B
inst✝ : CommRing C
f : A →+* B
g : B →+* C
hg : FinitePresentation (RingHom.comp g f)
hf : FiniteType f
ins1 : Algebra A B := toAlgebra f
ins2 : Algebra B C := toAlgebra g
ins3 : Algebra A C := toAlgebra (RingHom.comp g f)
a : A
b : B
c : C
⊢ (algebraMap B C) ((algebraMap A B) a) * ((algebraMap B C) b * c) = (algebraMap A C) a * ((algebraMap B C) b * c)

Next tactic:
rfl
theorem of_surjective (f : A →ₐ[R] B) (hf : Surjective f) (hker : f.toRingHom.ker.FG) :
    f.FinitePresentation := by
  -- Porting note: added `convert`
  

Proof state:
R : Type u_1
A : Type u_2
B : Type u_3
C : Type u_4
inst✝⁶ : CommRing R
inst✝⁵ : CommRing A
inst✝⁴ : CommRing B
inst✝³ : CommRing C
inst✝² : Algebra R A
inst✝¹ : Algebra R B
inst✝ : Algebra R C
f : A →ₐ[R] B
hf : Surjective ⇑f
hker : Ideal.FG (RingHom.ker ↑f)
⊢ FinitePresentation f

Next tactic:
convert RingHom.FinitePresentation.of_surjective f hf hker
theorem count_apply (hs : MeasurableSet s) : count s = ∑' i : s, 1 := by
  

Proof state:
α : Type u_1
β : Type ?u.2044
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
hs : MeasurableSet s
⊢ ↑↑count s = ∑' (i : ↑s), 1

Next tactic:
simp only [count, sum_apply, hs, dirac_apply', ← tsum_subtype s (1 : α → ℝ≥0∞), Pi.one_apply]
theorem count_empty : count (∅ : Set α) = 0 := by 

Proof state:
α : Type u_1
β : Type ?u.2929
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
⊢ ↑↑count ∅ = 0

Next tactic:
rw [count_apply MeasurableSet.empty, tsum_empty]
@[simp]
theorem count_apply_finset' {s : Finset α} (s_mble : MeasurableSet (s : Set α)) :
    count (↑s : Set α) = s.card :=
  calc
    count (↑s : Set α) = ∑' i : (↑s : Set α), 1 := count_apply s_mble
    _ = ∑ i in s, 1 := (s.tsum_subtype 1)
    _ = s.card := by 

Proof state:
α : Type u_1
β : Type ?u.3652
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s✝ : Set α
s : Finset α
s_mble : MeasurableSet ↑s
⊢ ∑ i in s, 1 = ↑(Finset.card s)

Next tactic:
simp
theorem count_apply_finite' {s : Set α} (s_fin : s.Finite) (s_mble : MeasurableSet s) :
    count s = s_fin.toFinset.card := by
  

Proof state:
α : Type u_1
β : Type ?u.6890
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s✝ s : Set α
s_fin : Set.Finite s
s_mble : MeasurableSet s
⊢ ↑↑count s = ↑(Finset.card (Finite.toFinset s_fin))

Next tactic:
simp [←
    @count_apply_finset' _ _ s_fin.toFinset (by simpa only [Finite.coe_toFinset] using s_mble)]
theorem count_apply_finite' {s : Set α} (s_fin : s.Finite) (s_mble : MeasurableSet s) :
    count s = s_fin.toFinset.card := by
  simp [←
    @count_apply_finset' _ _ s_fin.toFinset (by 

Proof state:
α : Type u_1
β : Type ?u.6890
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s✝ s : Set α
s_fin : Set.Finite s
s_mble : MeasurableSet s
⊢ MeasurableSet ↑(Finite.toFinset s_fin)

Next tactic:
simpa only [Finite.coe_toFinset] using s_mble
theorem count_apply_finite [MeasurableSingletonClass α] (s : Set α) (hs : s.Finite) :
    count s = hs.toFinset.card := by 

Proof state:
α : Type u_1
β : Type ?u.7990
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s✝ : Set α
inst✝ : MeasurableSingletonClass α
s : Set α
hs : Set.Finite s
⊢ ↑↑count s = ↑(Finset.card (Finite.toFinset hs))

Next tactic:
rw [← count_apply_finset, Finite.coe_toFinset]
/-- `count` measure evaluates to infinity at infinite sets. -/
theorem count_apply_infinite (hs : s.Infinite) : count s = ∞ := by
  

Proof state:
α : Type u_1
β : Type ?u.8314
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
hs : Set.Infinite s
⊢ ↑↑count s = ⊤

Next tactic:
refine' top_unique (le_of_tendsto' ENNReal.tendsto_nat_nhds_top fun n => _)
/-- `count` measure evaluates to infinity at infinite sets. -/
theorem count_apply_infinite (hs : s.Infinite) : count s = ∞ := by
  refine' top_unique (le_of_tendsto' ENNReal.tendsto_nat_nhds_top fun n => _)
  

Proof state:
α : Type u_1
β : Type ?u.8314
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
hs : Set.Infinite s
n : ℕ
⊢ ↑n ≤ ↑↑count s

Next tactic:
rcases hs.exists_subset_card_eq n with ⟨t, ht, rfl⟩
/-- `count` measure evaluates to infinity at infinite sets. -/
theorem count_apply_infinite (hs : s.Infinite) : count s = ∞ := by
  refine' top_unique (le_of_tendsto' ENNReal.tendsto_nat_nhds_top fun n => _)
  rcases hs.exists_subset_card_eq n with ⟨t, ht, rfl⟩
  

Proof state:
case intro.intro
α : Type u_1
β : Type ?u.8314
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
hs : Set.Infinite s
t : Finset α
ht : ↑t ⊆ s
⊢ ↑(Finset.card t) ≤ ↑↑count s

Next tactic:
calc
    (t.card : ℝ≥0∞) = ∑ i in t, 1 := by simp
    _ = ∑' i : (t : Set α), 1 := (t.tsum_subtype 1).symm
    _ ≤ count (t : Set α) := le_count_apply
    _ ≤ count s := measure_mono ht
/-- `count` measure evaluates to infinity at infinite sets. -/
theorem count_apply_infinite (hs : s.Infinite) : count s = ∞ := by
  refine' top_unique (le_of_tendsto' ENNReal.tendsto_nat_nhds_top fun n => _)
  rcases hs.exists_subset_card_eq n with ⟨t, ht, rfl⟩
  calc
    (t.card : ℝ≥0∞) = ∑ i in t, 1 := by 

Proof state:
α : Type u_1
β : Type ?u.8314
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
hs : Set.Infinite s
t : Finset α
ht : ↑t ⊆ s
⊢ ↑(Finset.card t) = ∑ i in t, 1

Next tactic:
simp
@[simp]
theorem count_apply_eq_top' (s_mble : MeasurableSet s) : count s = ∞ ↔ s.Infinite := by
  

Proof state:
α : Type u_1
β : Type ?u.12095
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
s_mble : MeasurableSet s
⊢ ↑↑count s = ⊤ ↔ Set.Infinite s

Next tactic:
by_cases hs : s.Finite
@[simp]
theorem count_apply_eq_top' (s_mble : MeasurableSet s) : count s = ∞ ↔ s.Infinite := by
  by_cases hs : s.Finite
  · 

Proof state:
case pos
α : Type u_1
β : Type ?u.12095
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
s_mble : MeasurableSet s
hs : Set.Finite s
⊢ ↑↑count s = ⊤ ↔ Set.Infinite s

Next tactic:
simp [Set.Infinite, hs, count_apply_finite' hs s_mble]
@[simp]
theorem count_apply_eq_top' (s_mble : MeasurableSet s) : count s = ∞ ↔ s.Infinite := by
  by_cases hs : s.Finite
  · simp [Set.Infinite, hs, count_apply_finite' hs s_mble]
  · 

Proof state:
case neg
α : Type u_1
β : Type ?u.12095
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
s_mble : MeasurableSet s
hs : ¬Set.Finite s
⊢ ↑↑count s = ⊤ ↔ Set.Infinite s

Next tactic:
change s.Infinite at hs
@[simp]
theorem count_apply_eq_top' (s_mble : MeasurableSet s) : count s = ∞ ↔ s.Infinite := by
  by_cases hs : s.Finite
  · simp [Set.Infinite, hs, count_apply_finite' hs s_mble]
  · change s.Infinite at hs
    

Proof state:
case neg
α : Type u_1
β : Type ?u.12095
inst✝¹ : MeasurableSpace α
inst✝ : MeasurableSpace β
s : Set α
s_mble : MeasurableSet s
hs : Set.Infinite s
⊢ ↑↑count s = ⊤ ↔ Set.Infinite s

Next tactic:
simp [hs, count_apply_infinite]
@[simp]
theorem count_apply_eq_top [MeasurableSingletonClass α] : count s = ∞ ↔ s.Infinite := by
  

Proof state:
α : Type u_1
β : Type ?u.13331
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s : Set α
inst✝ : MeasurableSingletonClass α
⊢ ↑↑count s = ⊤ ↔ Set.Infinite s

Next tactic:
by_cases hs : s.Finite
@[simp]
theorem count_apply_eq_top [MeasurableSingletonClass α] : count s = ∞ ↔ s.Infinite := by
  by_cases hs : s.Finite
  · 

Proof state:
case pos
α : Type u_1
β : Type ?u.13331
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s : Set α
inst✝ : MeasurableSingletonClass α
hs : Set.Finite s
⊢ ↑↑count s = ⊤ ↔ Set.Infinite s

Next tactic:
exact count_apply_eq_top' hs.measurableSet
@[simp]
theorem count_apply_eq_top [MeasurableSingletonClass α] : count s = ∞ ↔ s.Infinite := by
  by_cases hs : s.Finite
  · exact count_apply_eq_top' hs.measurableSet
  · 

Proof state:
case neg
α : Type u_1
β : Type ?u.13331
inst✝² : MeasurableSpace α
inst✝¹ : MeasurableSpace β
s : Set α
inst✝ : MeasurableSingletonClass α
hs : ¬Set.Finite s
⊢ ↑↑count s = ⊤ ↔ Set.Infinite s

Next tactic:
change s.Infinite at hs