l3lab/ntp-mathlib huggingface dataset:
/-- Suppose the sequence `stirlingSeq` (defined above) has the limit `a ≠ 0`.
Then the Wallis sequence `W n` has limit `a^2 / 2`.
-/
theorem second_wallis_limit (a : ℝ) (hane : a ≠ 0) (ha : Tendsto stirlingSeq atTop (𝓝 a)) :
    Tendsto Wallis.W atTop (𝓝 (a ^ 2 / 2)) := by
  refine' Tendsto.congr' (eventually_atTop.mpr ⟨1, fun n hn =>
    stirlingSeq_pow_four_div_stirlingSeq_pow_two_eq n (one_le_iff_ne_zero.mp hn)⟩) _
  have h : a ^ 2 / ↑2 = a ^ 4 / a ^ 2 * (1 / 2) := by
    rw [mul_one_div, ← mul_one_div (a ^ 4) (a ^ 2), one_div, ← pow_sub_of_lt a]
    norm_num
  rw [h]
  

Proof state:
a : ℝ
hane : a ≠ 0
ha : Tendsto stirlingSeq atTop (𝓝 a)
h : a ^ 2 / 2 = a ^ 4 / a ^ 2 * (1 / 2)
⊢ Tendsto (fun n => stirlingSeq n ^ 4 / stirlingSeq (2 * n) ^ 2 * (↑n / (2 * ↑n + 1))) atTop
    (𝓝 (a ^ 4 / a ^ 2 * (1 / 2)))

Next tactic:
exact ((ha.pow 4).div ((ha.comp (tendsto_id.const_mul_atTop' two_pos)).pow 2)
    (pow_ne_zero 2 hane)).mul tendsto_self_div_two_mul_self_add_one
/-- **Stirling's Formula** -/
theorem tendsto_stirlingSeq_sqrt_pi : Tendsto (fun n : ℕ => stirlingSeq n) atTop (𝓝 (sqrt π)) := by
  

Proof state:
⊢ Tendsto (fun n => stirlingSeq n) atTop (𝓝 (Real.sqrt π))

Next tactic:
obtain ⟨a, hapos, halimit⟩ := stirlingSeq_has_pos_limit_a
/-- **Stirling's Formula** -/
theorem tendsto_stirlingSeq_sqrt_pi : Tendsto (fun n : ℕ => stirlingSeq n) atTop (𝓝 (sqrt π)) := by
  obtain ⟨a, hapos, halimit⟩ := stirlingSeq_has_pos_limit_a
  

Proof state:
case intro.intro
a : ℝ
hapos : 0 < a
halimit : Tendsto stirlingSeq atTop (𝓝 a)
⊢ Tendsto (fun n => stirlingSeq n) atTop (𝓝 (Real.sqrt π))

Next tactic:
have hπ : π / 2 = a ^ 2 / 2 :=
    tendsto_nhds_unique Wallis.tendsto_W_nhds_pi_div_two (second_wallis_limit a hapos.ne' halimit)
/-- **Stirling's Formula** -/
theorem tendsto_stirlingSeq_sqrt_pi : Tendsto (fun n : ℕ => stirlingSeq n) atTop (𝓝 (sqrt π)) := by
  obtain ⟨a, hapos, halimit⟩ := stirlingSeq_has_pos_limit_a
  have hπ : π / 2 = a ^ 2 / 2 :=
    tendsto_nhds_unique Wallis.tendsto_W_nhds_pi_div_two (second_wallis_limit a hapos.ne' halimit)
  

Proof state:
case intro.intro
a : ℝ
hapos : 0 < a
halimit : Tendsto stirlingSeq atTop (𝓝 a)
hπ : π / 2 = a ^ 2 / 2
⊢ Tendsto (fun n => stirlingSeq n) atTop (𝓝 (Real.sqrt π))

Next tactic:
rwa [(div_left_inj' (two_ne_zero' ℝ)).mp hπ, sqrt_sq hapos.le]
/-- Create an element of `ι →₀ α` from a finset `s` and a function `f` defined on this finset. -/
def indicator (s : Finset ι) (f : ∀ i ∈ s, α) : ι →₀ α
    where
  toFun i :=
    haveI := Classical.decEq ι
    if H : i ∈ s then f i H else 0
  support :=
    haveI := Classical.decEq α
    (s.attach.filter fun i : s => f i.1 i.2 ≠ 0).map (Embedding.subtype _)
  mem_support_toFun i := by
    

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : Zero α
s✝ : Finset ι
f✝ : (i : ι) → i ∈ s✝ → α
i✝ : ι
s : Finset ι
f : (i : ι) → i ∈ s → α
i : ι
⊢ i ∈ map (Embedding.subtype fun x => x ∈ s) (filter (fun i => f ↑i (_ : ↑i ∈ s) ≠ 0) (attach s)) ↔
    (fun i => if H : i ∈ s then f i H else 0) i ≠ 0

Next tactic:
classical simp
/-- Create an element of `ι →₀ α` from a finset `s` and a function `f` defined on this finset. -/
def indicator (s : Finset ι) (f : ∀ i ∈ s, α) : ι →₀ α
    where
  toFun i :=
    haveI := Classical.decEq ι
    if H : i ∈ s then f i H else 0
  support :=
    haveI := Classical.decEq α
    (s.attach.filter fun i : s => f i.1 i.2 ≠ 0).map (Embedding.subtype _)
  mem_support_toFun i := by
    classical 

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : Zero α
s✝ : Finset ι
f✝ : (i : ι) → i ∈ s✝ → α
i✝ : ι
s : Finset ι
f : (i : ι) → i ∈ s → α
i : ι
⊢ i ∈ map (Embedding.subtype fun x => x ∈ s) (filter (fun i => f ↑i (_ : ↑i ∈ s) ≠ 0) (attach s)) ↔
    (fun i => if H : i ∈ s then f i H else 0) i ≠ 0

Next tactic:
simp
@[simp]
theorem indicator_apply [DecidableEq ι] : indicator s f i = if hi : i ∈ s then f i hi else 0 := by
  

Proof state:
ι : Type u_1
α : Type u_2
inst✝¹ : Zero α
s : Finset ι
f : (i : ι) → i ∈ s → α
i : ι
inst✝ : DecidableEq ι
⊢ (indicator s f) i = if hi : i ∈ s then f i hi else 0

Next tactic:
simp only [indicator, ne_eq, coe_mk]
@[simp]
theorem indicator_apply [DecidableEq ι] : indicator s f i = if hi : i ∈ s then f i hi else 0 := by
  simp only [indicator, ne_eq, coe_mk]
  

Proof state:
ι : Type u_1
α : Type u_2
inst✝¹ : Zero α
s : Finset ι
f : (i : ι) → i ∈ s → α
i : ι
inst✝ : DecidableEq ι
⊢ (if H : i ∈ s then f i H else 0) = if hi : i ∈ s then f i hi else 0

Next tactic:
congr
theorem indicator_injective : Injective fun f : ∀ i ∈ s, α => indicator s f := by
  

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : Zero α
s : Finset ι
f : (i : ι) → i ∈ s → α
i : ι
⊢ Injective fun f => indicator s f

Next tactic:
intro a b h
theorem indicator_injective : Injective fun f : ∀ i ∈ s, α => indicator s f := by
  intro a b h
  

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : Zero α
s : Finset ι
f : (i : ι) → i ∈ s → α
i : ι
a b : (i : ι) → i ∈ s → α
h : (fun f => indicator s f) a = (fun f => indicator s f) b
⊢ a = b

Next tactic:
ext i hi
theorem indicator_injective : Injective fun f : ∀ i ∈ s, α => indicator s f := by
  intro a b h
  ext i hi
  

Proof state:
case h.h
ι : Type u_1
α : Type u_2
inst✝ : Zero α
s : Finset ι
f : (i : ι) → i ∈ s → α
i✝ : ι
a b : (i : ι) → i ∈ s → α
h : (fun f => indicator s f) a = (fun f => indicator s f) b
i : ι
hi : i ∈ s
⊢ a i hi = b i hi

Next tactic:
rw [← indicator_of_mem hi a, ← indicator_of_mem hi b]
theorem indicator_injective : Injective fun f : ∀ i ∈ s, α => indicator s f := by
  intro a b h
  ext i hi
  rw [← indicator_of_mem hi a, ← indicator_of_mem hi b]
  

Proof state:
case h.h
ι : Type u_1
α : Type u_2
inst✝ : Zero α
s : Finset ι
f : (i : ι) → i ∈ s → α
i✝ : ι
a b : (i : ι) → i ∈ s → α
h : (fun f => indicator s f) a = (fun f => indicator s f) b
i : ι
hi : i ∈ s
⊢ (indicator s a) i = (indicator s b) i

Next tactic:
exact FunLike.congr_fun h i
theorem support_indicator_subset : ((indicator s f).support : Set ι) ⊆ s := by
  

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : Zero α
s : Finset ι
f : (i : ι) → i ∈ s → α
i : ι
⊢ ↑(indicator s f).support ⊆ ↑s

Next tactic:
intro i hi
theorem support_indicator_subset : ((indicator s f).support : Set ι) ⊆ s := by
  intro i hi
  

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : Zero α
s : Finset ι
f : (i : ι) → i ∈ s → α
i✝ i : ι
hi : i ∈ ↑(indicator s f).support
⊢ i ∈ ↑s

Next tactic:
rw [mem_coe, mem_support_iff] at hi
theorem support_indicator_subset : ((indicator s f).support : Set ι) ⊆ s := by
  intro i hi
  rw [mem_coe, mem_support_iff] at hi
  

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : Zero α
s : Finset ι
f : (i : ι) → i ∈ s → α
i✝ i : ι
hi : (indicator s f) i ≠ 0
⊢ i ∈ ↑s

Next tactic:
by_contra h
theorem support_indicator_subset : ((indicator s f).support : Set ι) ⊆ s := by
  intro i hi
  rw [mem_coe, mem_support_iff] at hi
  by_contra h
  

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : Zero α
s : Finset ι
f : (i : ι) → i ∈ s → α
i✝ i : ι
hi : (indicator s f) i ≠ 0
h : i ∉ ↑s
⊢ False

Next tactic:
exact hi (indicator_of_not_mem h _)
lemma single_eq_indicator (b : α) : single i b = indicator {i} (fun _ _ => b) := by
  

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : Zero α
s : Finset ι
f : (i : ι) → i ∈ s → α
i : ι
b : α
⊢ single i b = indicator {i} fun x x => b

Next tactic:
classical
  ext j
  simp [single_apply, indicator_apply, @eq_comm _ j]
lemma single_eq_indicator (b : α) : single i b = indicator {i} (fun _ _ => b) := by
  classical
  

Proof state:
ι : Type u_1
α : Type u_2
inst✝ : Zero α
s : Finset ι
f : (i : ι) → i ∈ s → α
i : ι
b : α
⊢ single i b = indicator {i} fun x x => b

Next tactic:
ext j
lemma single_eq_indicator (b : α) : single i b = indicator {i} (fun _ _ => b) := by
  classical
  ext j
  

Proof state:
case h
ι : Type u_1
α : Type u_2
inst✝ : Zero α
s : Finset ι
f : (i : ι) → i ∈ s → α
i : ι
b : α
j : ι
⊢ (single i b) j = (indicator {i} fun x x => b) j

Next tactic:
simp [single_apply, indicator_apply, @eq_comm _ j]
@[to_additive]
theorem saturated_iff_zpow {H : Subgroup G} :
    Saturated H ↔ ∀ (n : ℤ) (g : G), g ^ n ∈ H → n = 0 ∨ g ∈ H := by
  

Proof state:
G : Type u_1
inst✝ : Group G
H : Subgroup G
⊢ Saturated H ↔ ∀ (n : ℤ) (g : G), g ^ n ∈ H → n = 0 ∨ g ∈ H

Next tactic:
constructor
@[to_additive]
theorem saturated_iff_zpow {H : Subgroup G} :
    Saturated H ↔ ∀ (n : ℤ) (g : G), g ^ n ∈ H → n = 0 ∨ g ∈ H := by
  constructor
  · 

Proof state:
case mp
G : Type u_1
inst✝ : Group G
H : Subgroup G
⊢ Saturated H → ∀ (n : ℤ) (g : G), g ^ n ∈ H → n = 0 ∨ g ∈ H

Next tactic:
intros hH n g hgn
@[to_additive]
theorem saturated_iff_zpow {H : Subgroup G} :
    Saturated H ↔ ∀ (n : ℤ) (g : G), g ^ n ∈ H → n = 0 ∨ g ∈ H := by
  constructor
  · intros hH n g hgn
    

Proof state:
case mp
G : Type u_1
inst✝ : Group G
H : Subgroup G
hH : Saturated H
n : ℤ
g : G
hgn : g ^ n ∈ H
⊢ n = 0 ∨ g ∈ H

Next tactic:
induction' n with n n
@[to_additive]
theorem saturated_iff_zpow {H : Subgroup G} :
    Saturated H ↔ ∀ (n : ℤ) (g : G), g ^ n ∈ H → n = 0 ∨ g ∈ H := by
  constructor
  · intros hH n g hgn
    induction' n with n n
    · 

Proof state:
case mp.ofNat
G : Type u_1
inst✝ : Group G
H : Subgroup G
hH : Saturated H
g : G
n : ℕ
hgn : g ^ Int.ofNat n ∈ H
⊢ Int.ofNat n = 0 ∨ g ∈ H

Next tactic:
simp only [Int.coe_nat_eq_zero, Int.ofNat_eq_coe, zpow_ofNat] at hgn ⊢
@[to_additive]
theorem saturated_iff_zpow {H : Subgroup G} :
    Saturated H ↔ ∀ (n : ℤ) (g : G), g ^ n ∈ H → n = 0 ∨ g ∈ H := by
  constructor
  · intros hH n g hgn
    induction' n with n n
    · simp only [Int.coe_nat_eq_zero, Int.ofNat_eq_coe, zpow_ofNat] at hgn ⊢
      

Proof state:
case mp.ofNat
G : Type u_1
inst✝ : Group G
H : Subgroup G
hH : Saturated H
g : G
n : ℕ
hgn : g ^ n ∈ H
⊢ n = 0 ∨ g ∈ H

Next tactic:
exact hH hgn
@[to_additive]
theorem saturated_iff_zpow {H : Subgroup G} :
    Saturated H ↔ ∀ (n : ℤ) (g : G), g ^ n ∈ H → n = 0 ∨ g ∈ H := by
  constructor
  · intros hH n g hgn
    induction' n with n n
    · simp only [Int.coe_nat_eq_zero, Int.ofNat_eq_coe, zpow_ofNat] at hgn ⊢
      exact hH hgn
    · 

Proof state:
case mp.negSucc
G : Type u_1
inst✝ : Group G
H : Subgroup G
hH : Saturated H
g : G
n : ℕ
hgn : g ^ Int.negSucc n ∈ H
⊢ Int.negSucc n = 0 ∨ g ∈ H

Next tactic:
suffices g ^ (n + 1) ∈ H by
        refine' (hH this).imp _ id
        simp only [IsEmpty.forall_iff, Nat.succ_ne_zero]
@[to_additive]
theorem saturated_iff_zpow {H : Subgroup G} :
    Saturated H ↔ ∀ (n : ℤ) (g : G), g ^ n ∈ H → n = 0 ∨ g ∈ H := by
  constructor
  · intros hH n g hgn
    induction' n with n n
    · simp only [Int.coe_nat_eq_zero, Int.ofNat_eq_coe, zpow_ofNat] at hgn ⊢
      exact hH hgn
    · suffices g ^ (n + 1) ∈ H by
        

Proof state:
G : Type u_1
inst✝ : Group G
H : Subgroup G
hH : Saturated H
g : G
n : ℕ
hgn : g ^ Int.negSucc n ∈ H
this : g ^ (n + 1) ∈ H
⊢ Int.negSucc n = 0 ∨ g ∈ H

Next tactic:
refine' (hH this).imp _ id
@[to_additive]
theorem saturated_iff_zpow {H : Subgroup G} :
    Saturated H ↔ ∀ (n : ℤ) (g : G), g ^ n ∈ H → n = 0 ∨ g ∈ H := by
  constructor
  · intros hH n g hgn
    induction' n with n n
    · simp only [Int.coe_nat_eq_zero, Int.ofNat_eq_coe, zpow_ofNat] at hgn ⊢
      exact hH hgn
    · suffices g ^ (n + 1) ∈ H by
        refine' (hH this).imp _ id
        

Proof state:
G : Type u_1
inst✝ : Group G
H : Subgroup G
hH : Saturated H
g : G
n : ℕ
hgn : g ^ Int.negSucc n ∈ H
this : g ^ (n + 1) ∈ H
⊢ n + 1 = 0 → Int.negSucc n = 0

Next tactic:
simp only [IsEmpty.forall_iff, Nat.succ_ne_zero]
@[to_additive]
theorem saturated_iff_zpow {H : Subgroup G} :
    Saturated H ↔ ∀ (n : ℤ) (g : G), g ^ n ∈ H → n = 0 ∨ g ∈ H := by
  constructor
  · intros hH n g hgn
    induction' n with n n
    · simp only [Int.coe_nat_eq_zero, Int.ofNat_eq_coe, zpow_ofNat] at hgn ⊢
      exact hH hgn
    · suffices g ^ (n + 1) ∈ H by
        refine' (hH this).imp _ id
        simp only [IsEmpty.forall_iff, Nat.succ_ne_zero]
      

Proof state:
case mp.negSucc
G : Type u_1
inst✝ : Group G
H : Subgroup G
hH : Saturated H
g : G
n : ℕ
hgn : g ^ Int.negSucc n ∈ H
⊢ g ^ (n + 1) ∈ H

Next tactic:
simpa only [inv_mem_iff, zpow_negSucc] using hgn
@[to_additive]
theorem saturated_iff_zpow {H : Subgroup G} :
    Saturated H ↔ ∀ (n : ℤ) (g : G), g ^ n ∈ H → n = 0 ∨ g ∈ H := by
  constructor
  · intros hH n g hgn
    induction' n with n n
    · simp only [Int.coe_nat_eq_zero, Int.ofNat_eq_coe, zpow_ofNat] at hgn ⊢
      exact hH hgn
    · suffices g ^ (n + 1) ∈ H by
        refine' (hH this).imp _ id
        simp only [IsEmpty.forall_iff, Nat.succ_ne_zero]
      simpa only [inv_mem_iff, zpow_negSucc] using hgn
  · 

Proof state:
case mpr
G : Type u_1
inst✝ : Group G
H : Subgroup G
⊢ (∀ (n : ℤ) (g : G), g ^ n ∈ H → n = 0 ∨ g ∈ H) → Saturated H

Next tactic:
intro h n g hgn
@[to_additive]
theorem saturated_iff_zpow {H : Subgroup G} :
    Saturated H ↔ ∀ (n : ℤ) (g : G), g ^ n ∈ H → n = 0 ∨ g ∈ H := by
  constructor
  · intros hH n g hgn
    induction' n with n n
    · simp only [Int.coe_nat_eq_zero, Int.ofNat_eq_coe, zpow_ofNat] at hgn ⊢
      exact hH hgn
    · suffices g ^ (n + 1) ∈ H by
        refine' (hH this).imp _ id
        simp only [IsEmpty.forall_iff, Nat.succ_ne_zero]
      simpa only [inv_mem_iff, zpow_negSucc] using hgn
  · intro h n g hgn
    

Proof state:
case mpr
G : Type u_1
inst✝ : Group G
H : Subgroup G
h : ∀ (n : ℤ) (g : G), g ^ n ∈ H → n = 0 ∨ g ∈ H
n : ℕ
g : G
hgn : g ^ n ∈ H
⊢ n = 0 ∨ g ∈ H

Next tactic:
specialize h n g
@[to_additive]
theorem saturated_iff_zpow {H : Subgroup G} :
    Saturated H ↔ ∀ (n : ℤ) (g : G), g ^ n ∈ H → n = 0 ∨ g ∈ H := by
  constructor
  · intros hH n g hgn
    induction' n with n n
    · simp only [Int.coe_nat_eq_zero, Int.ofNat_eq_coe, zpow_ofNat] at hgn ⊢
      exact hH hgn
    · suffices g ^ (n + 1) ∈ H by
        refine' (hH this).imp _ id
        simp only [IsEmpty.forall_iff, Nat.succ_ne_zero]
      simpa only [inv_mem_iff, zpow_negSucc] using hgn
  · intro h n g hgn
    specialize h n g
    

Proof state:
case mpr
G : Type u_1
inst✝ : Group G
H : Subgroup G
n : ℕ
g : G
hgn : g ^ n ∈ H
h : g ^ ↑n ∈ H → ↑n = 0 ∨ g ∈ H
⊢ n = 0 ∨ g ∈ H

Next tactic:
simp only [Int.coe_nat_eq_zero, zpow_ofNat] at h
@[to_additive]
theorem saturated_iff_zpow {H : Subgroup G} :
    Saturated H ↔ ∀ (n : ℤ) (g : G), g ^ n ∈ H → n = 0 ∨ g ∈ H := by
  constructor
  · intros hH n g hgn
    induction' n with n n
    · simp only [Int.coe_nat_eq_zero, Int.ofNat_eq_coe, zpow_ofNat] at hgn ⊢
      exact hH hgn
    · suffices g ^ (n + 1) ∈ H by
        refine' (hH this).imp _ id
        simp only [IsEmpty.forall_iff, Nat.succ_ne_zero]
      simpa only [inv_mem_iff, zpow_negSucc] using hgn
  · intro h n g hgn
    specialize h n g
    simp only [Int.coe_nat_eq_zero, zpow_ofNat] at h
    

Proof state:
case mpr
G : Type u_1
inst✝ : Group G
H : Subgroup G
n : ℕ
g : G
hgn : g ^ n ∈ H
h : g ^ n ∈ H → n = 0 ∨ g ∈ H
⊢ n = 0 ∨ g ∈ H

Next tactic:
apply h hgn
theorem ker_saturated {A₁ A₂ : Type*} [AddCommGroup A₁] [AddCommGroup A₂] [NoZeroSMulDivisors ℕ A₂]
    (f : A₁ →+ A₂) : f.ker.Saturated := by
  

Proof state:
A₁ : Type u_1
A₂ : Type u_2
inst✝² : AddCommGroup A₁
inst✝¹ : AddCommGroup A₂
inst✝ : NoZeroSMulDivisors ℕ A₂
f : A₁ →+ A₂
⊢ Saturated (AddMonoidHom.ker f)

Next tactic:
intro n g hg
theorem ker_saturated {A₁ A₂ : Type*} [AddCommGroup A₁] [AddCommGroup A₂] [NoZeroSMulDivisors ℕ A₂]
    (f : A₁ →+ A₂) : f.ker.Saturated := by
  intro n g hg
  

Proof state:
A₁ : Type u_1
A₂ : Type u_2
inst✝² : AddCommGroup A₁
inst✝¹ : AddCommGroup A₂
inst✝ : NoZeroSMulDivisors ℕ A₂
f : A₁ →+ A₂
n : ℕ
g : A₁
hg : n • g ∈ AddMonoidHom.ker f
⊢ n = 0 ∨ g ∈ AddMonoidHom.ker f

Next tactic:
simpa only [f.mem_ker, nsmul_eq_smul, f.map_nsmul, smul_eq_zero] using hg
instance [Finite V] : IsEmpty G.end where
  false := by
    

Proof state:
V : Type
G : SimpleGraph V
inst✝ : Finite V
⊢ ↑(SimpleGraph.end G) → False

Next tactic:
rintro ⟨s, _⟩
instance [Finite V] : IsEmpty G.end where
  false := by
    rintro ⟨s, _⟩
    

Proof state:
case mk
V : Type
G : SimpleGraph V
inst✝ : Finite V
s : (j : (Finset V)ᵒᵖ) → (componentComplFunctor G).obj j
property✝ : s ∈ SimpleGraph.end G
⊢ False

Next tactic:
cases nonempty_fintype V
instance [Finite V] : IsEmpty G.end where
  false := by
    rintro ⟨s, _⟩
    cases nonempty_fintype V
    

Proof state:
case mk.intro
V : Type
G : SimpleGraph V
inst✝ : Finite V
s : (j : (Finset V)ᵒᵖ) → (componentComplFunctor G).obj j
property✝ : s ∈ SimpleGraph.end G
val✝ : Fintype V
⊢ False

Next tactic:
obtain ⟨v, h⟩ := (s <| Opposite.op Finset.univ).nonempty
instance [Finite V] : IsEmpty G.end where
  false := by
    rintro ⟨s, _⟩
    cases nonempty_fintype V
    obtain ⟨v, h⟩ := (s <| Opposite.op Finset.univ).nonempty
    

Proof state:
case mk.intro.intro
V : Type
G : SimpleGraph V
inst✝ : Finite V
s : (j : (Finset V)ᵒᵖ) → (componentComplFunctor G).obj j
property✝ : s ∈ SimpleGraph.end G
val✝ : Fintype V
v : V
h : v ∈ ↑(s (Opposite.op Finset.univ))
⊢ False

Next tactic:
exact Set.disjoint_iff.mp (s _).disjoint_right
        ⟨by simp only [Opposite.unop_op, Finset.coe_univ, Set.mem_univ], h⟩
instance [Finite V] : IsEmpty G.end where
  false := by
    rintro ⟨s, _⟩
    cases nonempty_fintype V
    obtain ⟨v, h⟩ := (s <| Opposite.op Finset.univ).nonempty
    exact Set.disjoint_iff.mp (s _).disjoint_right
        ⟨by 

Proof state:
V : Type
G : SimpleGraph V
inst✝ : Finite V
s : (j : (Finset V)ᵒᵖ) → (componentComplFunctor G).obj j
property✝ : s ∈ SimpleGraph.end G
val✝ : Fintype V
v : V
h : v ∈ ↑(s (Opposite.op Finset.univ))
⊢ v ∈ ↑(Opposite.op Finset.univ).unop

Next tactic:
simp only [Opposite.unop_op, Finset.coe_univ, Set.mem_univ]
/-- The `componentCompl`s chosen by an end are all infinite. -/
lemma end_componentCompl_infinite (e : G.end) (K : (Finset V)ᵒᵖ) :
    ((e : (j : (Finset V)ᵒᵖ) → G.componentComplFunctor.obj j) K).supp.Infinite := by
  

Proof state:
V : Type
G : SimpleGraph V
e : ↑(SimpleGraph.end G)
K : (Finset V)ᵒᵖ
⊢ Set.Infinite (ComponentCompl.supp (↑e K))

Next tactic:
refine (e.val K).infinite_iff_in_all_ranges.mpr (fun L h => ?_)
/-- The `componentCompl`s chosen by an end are all infinite. -/
lemma end_componentCompl_infinite (e : G.end) (K : (Finset V)ᵒᵖ) :
    ((e : (j : (Finset V)ᵒᵖ) → G.componentComplFunctor.obj j) K).supp.Infinite := by
  refine (e.val K).infinite_iff_in_all_ranges.mpr (fun L h => ?_)
  

Proof state:
V : Type
G : SimpleGraph V
e : ↑(SimpleGraph.end G)
K : (Finset V)ᵒᵖ
L : Finset V
h : K.unop ⊆ L
⊢ ∃ D, ComponentCompl.hom h D = ↑e K

Next tactic:
change Opposite.unop K ⊆ Opposite.unop (Opposite.op L) at h
/-- The `componentCompl`s chosen by an end are all infinite. -/
lemma end_componentCompl_infinite (e : G.end) (K : (Finset V)ᵒᵖ) :
    ((e : (j : (Finset V)ᵒᵖ) → G.componentComplFunctor.obj j) K).supp.Infinite := by
  refine (e.val K).infinite_iff_in_all_ranges.mpr (fun L h => ?_)
  change Opposite.unop K ⊆ Opposite.unop (Opposite.op L) at h
  

Proof state:
V : Type
G : SimpleGraph V
e : ↑(SimpleGraph.end G)
K : (Finset V)ᵒᵖ
L : Finset V
h : K.unop ⊆ (Opposite.op L).unop
⊢ ∃ D, ComponentCompl.hom h D = ↑e K

Next tactic:
exact ⟨e.val (Opposite.op L), (e.prop (CategoryTheory.opHomOfLE h))⟩
/-- A locally finite preconnected infinite graph has at least one end. -/
lemma nonempty_ends_of_infinite [LocallyFinite G] [Fact G.Preconnected] [Infinite V] :
    G.end.Nonempty := by
  

Proof state:
V : Type
G : SimpleGraph V
inst✝² : LocallyFinite G
inst✝¹ : Fact (Preconnected G)
inst✝ : Infinite V
⊢ Set.Nonempty (SimpleGraph.end G)

Next tactic:
classical
  apply nonempty_sections_of_finite_inverse_system G.componentComplFunctor
/-- A locally finite preconnected infinite graph has at least one end. -/
lemma nonempty_ends_of_infinite [LocallyFinite G] [Fact G.Preconnected] [Infinite V] :
    G.end.Nonempty := by
  classical
  

Proof state:
V : Type
G : SimpleGraph V
inst✝² : LocallyFinite G
inst✝¹ : Fact (Preconnected G)
inst✝ : Infinite V
⊢ Set.Nonempty (SimpleGraph.end G)

Next tactic:
apply nonempty_sections_of_finite_inverse_system G.componentComplFunctor
/-- *Dirichlet's approximation theorem:*
For any real number `ξ` and positive natural `n`, there are integers `j` and `k`,
with `0 < k ≤ n` and `|k*ξ - j| ≤ 1/(n+1)`.

See also `Real.exists_nat_abs_mul_sub_round_le`. -/
theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
    ∃ j k : ℤ, 0 < k ∧ k ≤ n ∧ |↑k * ξ - j| ≤ 1 / (n + 1) := by
  

Proof state:
ξ : ℝ
n : ℕ
n_pos : 0 < n
⊢ ∃ j k, 0 < k ∧ k ≤ ↑n ∧ |↑k * ξ - ↑j| ≤ 1 / (↑n + 1)

Next tactic:
let f : ℤ → ℤ := fun m => ⌊fract (ξ * m) * (n + 1)⌋
/-- *Dirichlet's approximation theorem:*
For any real number `ξ` and positive natural `n`, there are integers `j` and `k`,
with `0 < k ≤ n` and `|k*ξ - j| ≤ 1/(n+1)`.

See also `Real.exists_nat_abs_mul_sub_round_le`. -/
theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
    ∃ j k : ℤ, 0 < k ∧ k ≤ n ∧ |↑k * ξ - j| ≤ 1 / (n + 1) := by
  let f : ℤ → ℤ := fun m => ⌊fract (ξ * m) * (n + 1)⌋
  

Proof state:
ξ : ℝ
n : ℕ
n_pos : 0 < n
f : ℤ → ℤ := fun m => ⌊fract (ξ * ↑m) * (↑n + 1)⌋
⊢ ∃ j k, 0 < k ∧ k ≤ ↑n ∧ |↑k * ξ - ↑j| ≤ 1 / (↑n + 1)

Next tactic:
have hn : 0 < (n : ℝ) + 1 := mod_cast Nat.succ_pos _
/-- *Dirichlet's approximation theorem:*
For any real number `ξ` and positive natural `n`, there are integers `j` and `k`,
with `0 < k ≤ n` and `|k*ξ - j| ≤ 1/(n+1)`.

See also `Real.exists_nat_abs_mul_sub_round_le`. -/
theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
    ∃ j k : ℤ, 0 < k ∧ k ≤ n ∧ |↑k * ξ - j| ≤ 1 / (n + 1) := by
  let f : ℤ → ℤ := fun m => ⌊fract (ξ * m) * (n + 1)⌋
  have hn : 0 < (n : ℝ) + 1 := mod_cast Nat.succ_pos _
  

Proof state:
ξ : ℝ
n : ℕ
n_pos : 0 < n
f : ℤ → ℤ := fun m => ⌊fract (ξ * ↑m) * (↑n + 1)⌋
hn : 0 < ↑n + 1
⊢ ∃ j k, 0 < k ∧ k ≤ ↑n ∧ |↑k * ξ - ↑j| ≤ 1 / (↑n + 1)

Next tactic:
have hfu := fun m : ℤ => mul_lt_of_lt_one_left hn <| fract_lt_one (ξ * ↑m)
/-- *Dirichlet's approximation theorem:*
For any real number `ξ` and positive natural `n`, there are integers `j` and `k`,
with `0 < k ≤ n` and `|k*ξ - j| ≤ 1/(n+1)`.

See also `Real.exists_nat_abs_mul_sub_round_le`. -/
theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
    ∃ j k : ℤ, 0 < k ∧ k ≤ n ∧ |↑k * ξ - j| ≤ 1 / (n + 1) := by
  let f : ℤ → ℤ := fun m => ⌊fract (ξ * m) * (n + 1)⌋
  have hn : 0 < (n : ℝ) + 1 := mod_cast Nat.succ_pos _
  have hfu := fun m : ℤ => mul_lt_of_lt_one_left hn <| fract_lt_one (ξ * ↑m)
  

Proof state:
ξ : ℝ
n : ℕ
n_pos : 0 < n
f : ℤ → ℤ := fun m => ⌊fract (ξ * ↑m) * (↑n + 1)⌋
hn : 0 < ↑n + 1
hfu : ∀ (m : ℤ), fract (ξ * ↑m) * (↑n + 1) < ↑n + 1
⊢ ∃ j k, 0 < k ∧ k ≤ ↑n ∧ |↑k * ξ - ↑j| ≤ 1 / (↑n + 1)

Next tactic:
conv in |_| ≤ _ => rw [mul_comm, le_div_iff hn, ← abs_of_pos hn, ← abs_mul]
/-- *Dirichlet's approximation theorem:*
For any real number `ξ` and positive natural `n`, there are integers `j` and `k`,
with `0 < k ≤ n` and `|k*ξ - j| ≤ 1/(n+1)`.

See also `Real.exists_nat_abs_mul_sub_round_le`. -/
theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
    ∃ j k : ℤ, 0 < k ∧ k ≤ n ∧ |↑k * ξ - j| ≤ 1 / (n + 1) := by
  let f : ℤ → ℤ := fun m => ⌊fract (ξ * m) * (n + 1)⌋
  have hn : 0 < (n : ℝ) + 1 := mod_cast Nat.succ_pos _
  have hfu := fun m : ℤ => mul_lt_of_lt_one_left hn <| fract_lt_one (ξ * ↑m)
  conv in |_| ≤ _ => 

Proof state:
ξ : ℝ
n : ℕ
n_pos : 0 < n
f : ℤ → ℤ := fun m => ⌊fract (ξ * ↑m) * (↑n + 1)⌋
hn : 0 < ↑n + 1
hfu : ∀ (m : ℤ), fract (ξ * ↑m) * (↑n + 1) < ↑n + 1
j k : ℤ
| |↑k * ξ - ↑j| ≤ 1 / (↑n + 1)

Next tactic:
rw [mul_comm, le_div_iff hn, ← abs_of_pos hn, ← abs_mul]
/-- *Dirichlet's approximation theorem:*
For any real number `ξ` and positive natural `n`, there are integers `j` and `k`,
with `0 < k ≤ n` and `|k*ξ - j| ≤ 1/(n+1)`.

See also `Real.exists_nat_abs_mul_sub_round_le`. -/
theorem exists_int_int_abs_mul_sub_le (ξ : ℝ) {n : ℕ} (n_pos : 0 < n) :
    ∃ j k : ℤ, 0 < k ∧ k ≤ n ∧ |↑k * ξ - j| ≤ 1 / (n + 1) := by
  let f : ℤ → ℤ := fun m => ⌊fract (ξ * m) * (n + 1)⌋
  have hn : 0 < (n : ℝ) + 1 := mod_cast Nat.succ_pos _
  have hfu := fun m : ℤ => mul_lt_of_lt_one_left hn <| fract_lt_one (ξ * ↑m)
  conv in |_| ≤ _ => rw [mul_comm, le_div_iff hn, ← abs_of_pos hn, ← abs_mul]
  

Proof state:
ξ : ℝ
n : ℕ
n_pos : 0 < n
f : ℤ → ℤ := fun m => ⌊fract (ξ * ↑m) * (↑n + 1)⌋
hn : 0 < ↑n + 1
hfu : ∀ (m : ℤ), fract (ξ * ↑m) * (↑n + 1) < ↑n + 1
⊢ ∃ j k, 0 < k ∧ k ≤ ↑n ∧ |(ξ * ↑k - ↑j) * (↑n + 1)| ≤ 1

Next tactic:
let D := Icc (0 : ℤ) n