l3lab/ntp-mathlib huggingface dataset:
/-- One implication of the portmanteau theorem:
Weak convergence of probability measures implies that if the boundary of a Borel set
carries no probability mass under the limit measure, then the limit of the measures of the set
equals the measure of the set under the limit probability measure.

A version with coercions to ordinary `ℝ≥0∞`-valued measures is
`MeasureTheory.ProbabilityMeasure.tendsto_measure_of_null_frontier_of_tendsto'`.
-/
theorem ProbabilityMeasure.tendsto_measure_of_null_frontier_of_tendsto {Ω ι : Type*} {L : Filter ι}
    [MeasurableSpace Ω] [PseudoEMetricSpace Ω] [OpensMeasurableSpace Ω] [HasOuterApproxClosed Ω]
    {μ : ProbabilityMeasure Ω} {μs : ι → ProbabilityMeasure Ω} (μs_lim : Tendsto μs L (𝓝 μ))
    {E : Set Ω} (E_nullbdry : μ (frontier E) = 0) : Tendsto (fun i => μs i E) L (𝓝 (μ E)) := by
  have E_nullbdry' : (μ : Measure Ω) (frontier E) = 0 := by
    rw [← ProbabilityMeasure.ennreal_coeFn_eq_coeFn_toMeasure, E_nullbdry, ENNReal.coe_zero]
  

Proof state:
Ω : Type u_1
ι : Type u_2
L : Filter ι
inst✝³ : MeasurableSpace Ω
inst✝² : PseudoEMetricSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
inst✝ : HasOuterApproxClosed Ω
μ : ProbabilityMeasure Ω
μs : ι → ProbabilityMeasure Ω
μs_lim : Tendsto μs L (𝓝 μ)
E : Set Ω
E_nullbdry : (fun s => ENNReal.toNNReal (↑↑↑μ s)) (frontier E) = 0
E_nullbdry' : ↑↑↑μ (frontier E) = 0
⊢ Tendsto (fun i => (fun s => ENNReal.toNNReal (↑↑↑(μs i) s)) E) L (𝓝 ((fun s => ENNReal.toNNReal (↑↑↑μ s)) E))

Next tactic:
have key := ProbabilityMeasure.tendsto_measure_of_null_frontier_of_tendsto' μs_lim E_nullbdry'
/-- One implication of the portmanteau theorem:
Weak convergence of probability measures implies that if the boundary of a Borel set
carries no probability mass under the limit measure, then the limit of the measures of the set
equals the measure of the set under the limit probability measure.

A version with coercions to ordinary `ℝ≥0∞`-valued measures is
`MeasureTheory.ProbabilityMeasure.tendsto_measure_of_null_frontier_of_tendsto'`.
-/
theorem ProbabilityMeasure.tendsto_measure_of_null_frontier_of_tendsto {Ω ι : Type*} {L : Filter ι}
    [MeasurableSpace Ω] [PseudoEMetricSpace Ω] [OpensMeasurableSpace Ω] [HasOuterApproxClosed Ω]
    {μ : ProbabilityMeasure Ω} {μs : ι → ProbabilityMeasure Ω} (μs_lim : Tendsto μs L (𝓝 μ))
    {E : Set Ω} (E_nullbdry : μ (frontier E) = 0) : Tendsto (fun i => μs i E) L (𝓝 (μ E)) := by
  have E_nullbdry' : (μ : Measure Ω) (frontier E) = 0 := by
    rw [← ProbabilityMeasure.ennreal_coeFn_eq_coeFn_toMeasure, E_nullbdry, ENNReal.coe_zero]
  have key := ProbabilityMeasure.tendsto_measure_of_null_frontier_of_tendsto' μs_lim E_nullbdry'
  

Proof state:
Ω : Type u_1
ι : Type u_2
L : Filter ι
inst✝³ : MeasurableSpace Ω
inst✝² : PseudoEMetricSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
inst✝ : HasOuterApproxClosed Ω
μ : ProbabilityMeasure Ω
μs : ι → ProbabilityMeasure Ω
μs_lim : Tendsto μs L (𝓝 μ)
E : Set Ω
E_nullbdry : (fun s => ENNReal.toNNReal (↑↑↑μ s)) (frontier E) = 0
E_nullbdry' : ↑↑↑μ (frontier E) = 0
key : Tendsto (fun i => ↑↑↑(μs i) E) L (𝓝 (↑↑↑μ E))
⊢ Tendsto (fun i => (fun s => ENNReal.toNNReal (↑↑↑(μs i) s)) E) L (𝓝 ((fun s => ENNReal.toNNReal (↑↑↑μ s)) E))

Next tactic:
exact (ENNReal.tendsto_toNNReal (measure_ne_top (↑μ) E)).comp key
theorem exists_null_frontier_thickening (μ : Measure Ω) [SigmaFinite μ] (s : Set Ω) {a b : ℝ}
    (hab : a < b) : ∃ r ∈ Ioo a b, μ (frontier (Metric.thickening r s)) = 0 := by
  

Proof state:
Ω : Type u_1
inst✝³ : PseudoEMetricSpace Ω
inst✝² : MeasurableSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : SigmaFinite μ
s : Set Ω
a b : ℝ
hab : a < b
⊢ ∃ r ∈ Ioo a b, ↑↑μ (frontier (Metric.thickening r s)) = 0

Next tactic:
have mbles : ∀ r : ℝ, MeasurableSet (frontier (Metric.thickening r s)) :=
    fun r => isClosed_frontier.measurableSet
theorem exists_null_frontier_thickening (μ : Measure Ω) [SigmaFinite μ] (s : Set Ω) {a b : ℝ}
    (hab : a < b) : ∃ r ∈ Ioo a b, μ (frontier (Metric.thickening r s)) = 0 := by
  have mbles : ∀ r : ℝ, MeasurableSet (frontier (Metric.thickening r s)) :=
    fun r => isClosed_frontier.measurableSet
  

Proof state:
Ω : Type u_1
inst✝³ : PseudoEMetricSpace Ω
inst✝² : MeasurableSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : SigmaFinite μ
s : Set Ω
a b : ℝ
hab : a < b
mbles : ∀ (r : ℝ), MeasurableSet (frontier (Metric.thickening r s))
⊢ ∃ r ∈ Ioo a b, ↑↑μ (frontier (Metric.thickening r s)) = 0

Next tactic:
have disjs := Metric.frontier_thickening_disjoint s
theorem exists_null_frontier_thickening (μ : Measure Ω) [SigmaFinite μ] (s : Set Ω) {a b : ℝ}
    (hab : a < b) : ∃ r ∈ Ioo a b, μ (frontier (Metric.thickening r s)) = 0 := by
  have mbles : ∀ r : ℝ, MeasurableSet (frontier (Metric.thickening r s)) :=
    fun r => isClosed_frontier.measurableSet
  have disjs := Metric.frontier_thickening_disjoint s
  

Proof state:
Ω : Type u_1
inst✝³ : PseudoEMetricSpace Ω
inst✝² : MeasurableSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : SigmaFinite μ
s : Set Ω
a b : ℝ
hab : a < b
mbles : ∀ (r : ℝ), MeasurableSet (frontier (Metric.thickening r s))
disjs : Pairwise (Disjoint on fun r => frontier (Metric.thickening r s))
⊢ ∃ r ∈ Ioo a b, ↑↑μ (frontier (Metric.thickening r s)) = 0

Next tactic:
have key := Measure.countable_meas_pos_of_disjoint_iUnion (μ := μ) mbles disjs
theorem exists_null_frontier_thickening (μ : Measure Ω) [SigmaFinite μ] (s : Set Ω) {a b : ℝ}
    (hab : a < b) : ∃ r ∈ Ioo a b, μ (frontier (Metric.thickening r s)) = 0 := by
  have mbles : ∀ r : ℝ, MeasurableSet (frontier (Metric.thickening r s)) :=
    fun r => isClosed_frontier.measurableSet
  have disjs := Metric.frontier_thickening_disjoint s
  have key := Measure.countable_meas_pos_of_disjoint_iUnion (μ := μ) mbles disjs
  

Proof state:
Ω : Type u_1
inst✝³ : PseudoEMetricSpace Ω
inst✝² : MeasurableSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : SigmaFinite μ
s : Set Ω
a b : ℝ
hab : a < b
mbles : ∀ (r : ℝ), MeasurableSet (frontier (Metric.thickening r s))
disjs : Pairwise (Disjoint on fun r => frontier (Metric.thickening r s))
key : Set.Countable {i | 0 < ↑↑μ (frontier (Metric.thickening i s))}
⊢ ∃ r ∈ Ioo a b, ↑↑μ (frontier (Metric.thickening r s)) = 0

Next tactic:
have aux := measure_diff_null (s₁ := Ioo a b) (Set.Countable.measure_zero key volume)
theorem exists_null_frontier_thickening (μ : Measure Ω) [SigmaFinite μ] (s : Set Ω) {a b : ℝ}
    (hab : a < b) : ∃ r ∈ Ioo a b, μ (frontier (Metric.thickening r s)) = 0 := by
  have mbles : ∀ r : ℝ, MeasurableSet (frontier (Metric.thickening r s)) :=
    fun r => isClosed_frontier.measurableSet
  have disjs := Metric.frontier_thickening_disjoint s
  have key := Measure.countable_meas_pos_of_disjoint_iUnion (μ := μ) mbles disjs
  have aux := measure_diff_null (s₁ := Ioo a b) (Set.Countable.measure_zero key volume)
  

Proof state:
Ω : Type u_1
inst✝³ : PseudoEMetricSpace Ω
inst✝² : MeasurableSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : SigmaFinite μ
s : Set Ω
a b : ℝ
hab : a < b
mbles : ∀ (r : ℝ), MeasurableSet (frontier (Metric.thickening r s))
disjs : Pairwise (Disjoint on fun r => frontier (Metric.thickening r s))
key : Set.Countable {i | 0 < ↑↑μ (frontier (Metric.thickening i s))}
aux : ↑↑volume (Ioo a b \ {i | 0 < ↑↑μ (frontier (Metric.thickening i s))}) = ↑↑volume (Ioo a b)
⊢ ∃ r ∈ Ioo a b, ↑↑μ (frontier (Metric.thickening r s)) = 0

Next tactic:
have len_pos : 0 < ENNReal.ofReal (b - a) := by simp only [hab, ENNReal.ofReal_pos, sub_pos]
theorem exists_null_frontier_thickening (μ : Measure Ω) [SigmaFinite μ] (s : Set Ω) {a b : ℝ}
    (hab : a < b) : ∃ r ∈ Ioo a b, μ (frontier (Metric.thickening r s)) = 0 := by
  have mbles : ∀ r : ℝ, MeasurableSet (frontier (Metric.thickening r s)) :=
    fun r => isClosed_frontier.measurableSet
  have disjs := Metric.frontier_thickening_disjoint s
  have key := Measure.countable_meas_pos_of_disjoint_iUnion (μ := μ) mbles disjs
  have aux := measure_diff_null (s₁ := Ioo a b) (Set.Countable.measure_zero key volume)
  have len_pos : 0 < ENNReal.ofReal (b - a) := by 

Proof state:
Ω : Type u_1
inst✝³ : PseudoEMetricSpace Ω
inst✝² : MeasurableSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : SigmaFinite μ
s : Set Ω
a b : ℝ
hab : a < b
mbles : ∀ (r : ℝ), MeasurableSet (frontier (Metric.thickening r s))
disjs : Pairwise (Disjoint on fun r => frontier (Metric.thickening r s))
key : Set.Countable {i | 0 < ↑↑μ (frontier (Metric.thickening i s))}
aux : ↑↑volume (Ioo a b \ {i | 0 < ↑↑μ (frontier (Metric.thickening i s))}) = ↑↑volume (Ioo a b)
⊢ 0 < ENNReal.ofReal (b - a)

Next tactic:
simp only [hab, ENNReal.ofReal_pos, sub_pos]
theorem exists_null_frontier_thickening (μ : Measure Ω) [SigmaFinite μ] (s : Set Ω) {a b : ℝ}
    (hab : a < b) : ∃ r ∈ Ioo a b, μ (frontier (Metric.thickening r s)) = 0 := by
  have mbles : ∀ r : ℝ, MeasurableSet (frontier (Metric.thickening r s)) :=
    fun r => isClosed_frontier.measurableSet
  have disjs := Metric.frontier_thickening_disjoint s
  have key := Measure.countable_meas_pos_of_disjoint_iUnion (μ := μ) mbles disjs
  have aux := measure_diff_null (s₁ := Ioo a b) (Set.Countable.measure_zero key volume)
  have len_pos : 0 < ENNReal.ofReal (b - a) := by simp only [hab, ENNReal.ofReal_pos, sub_pos]
  

Proof state:
Ω : Type u_1
inst✝³ : PseudoEMetricSpace Ω
inst✝² : MeasurableSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : SigmaFinite μ
s : Set Ω
a b : ℝ
hab : a < b
mbles : ∀ (r : ℝ), MeasurableSet (frontier (Metric.thickening r s))
disjs : Pairwise (Disjoint on fun r => frontier (Metric.thickening r s))
key : Set.Countable {i | 0 < ↑↑μ (frontier (Metric.thickening i s))}
aux : ↑↑volume (Ioo a b \ {i | 0 < ↑↑μ (frontier (Metric.thickening i s))}) = ↑↑volume (Ioo a b)
len_pos : 0 < ENNReal.ofReal (b - a)
⊢ ∃ r ∈ Ioo a b, ↑↑μ (frontier (Metric.thickening r s)) = 0

Next tactic:
rw [← Real.volume_Ioo, ← aux] at len_pos
theorem exists_null_frontier_thickening (μ : Measure Ω) [SigmaFinite μ] (s : Set Ω) {a b : ℝ}
    (hab : a < b) : ∃ r ∈ Ioo a b, μ (frontier (Metric.thickening r s)) = 0 := by
  have mbles : ∀ r : ℝ, MeasurableSet (frontier (Metric.thickening r s)) :=
    fun r => isClosed_frontier.measurableSet
  have disjs := Metric.frontier_thickening_disjoint s
  have key := Measure.countable_meas_pos_of_disjoint_iUnion (μ := μ) mbles disjs
  have aux := measure_diff_null (s₁ := Ioo a b) (Set.Countable.measure_zero key volume)
  have len_pos : 0 < ENNReal.ofReal (b - a) := by simp only [hab, ENNReal.ofReal_pos, sub_pos]
  rw [← Real.volume_Ioo, ← aux] at len_pos
  

Proof state:
Ω : Type u_1
inst✝³ : PseudoEMetricSpace Ω
inst✝² : MeasurableSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : SigmaFinite μ
s : Set Ω
a b : ℝ
hab : a < b
mbles : ∀ (r : ℝ), MeasurableSet (frontier (Metric.thickening r s))
disjs : Pairwise (Disjoint on fun r => frontier (Metric.thickening r s))
key : Set.Countable {i | 0 < ↑↑μ (frontier (Metric.thickening i s))}
aux : ↑↑volume (Ioo a b \ {i | 0 < ↑↑μ (frontier (Metric.thickening i s))}) = ↑↑volume (Ioo a b)
len_pos : 0 < ↑↑volume (Ioo a b \ {i | 0 < ↑↑μ (frontier (Metric.thickening i s))})
⊢ ∃ r ∈ Ioo a b, ↑↑μ (frontier (Metric.thickening r s)) = 0

Next tactic:
rcases nonempty_of_measure_ne_zero len_pos.ne.symm with ⟨r, ⟨r_in_Ioo, hr⟩⟩
theorem exists_null_frontier_thickening (μ : Measure Ω) [SigmaFinite μ] (s : Set Ω) {a b : ℝ}
    (hab : a < b) : ∃ r ∈ Ioo a b, μ (frontier (Metric.thickening r s)) = 0 := by
  have mbles : ∀ r : ℝ, MeasurableSet (frontier (Metric.thickening r s)) :=
    fun r => isClosed_frontier.measurableSet
  have disjs := Metric.frontier_thickening_disjoint s
  have key := Measure.countable_meas_pos_of_disjoint_iUnion (μ := μ) mbles disjs
  have aux := measure_diff_null (s₁ := Ioo a b) (Set.Countable.measure_zero key volume)
  have len_pos : 0 < ENNReal.ofReal (b - a) := by simp only [hab, ENNReal.ofReal_pos, sub_pos]
  rw [← Real.volume_Ioo, ← aux] at len_pos
  rcases nonempty_of_measure_ne_zero len_pos.ne.symm with ⟨r, ⟨r_in_Ioo, hr⟩⟩
  

Proof state:
case intro.intro
Ω : Type u_1
inst✝³ : PseudoEMetricSpace Ω
inst✝² : MeasurableSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : SigmaFinite μ
s : Set Ω
a b : ℝ
hab : a < b
mbles : ∀ (r : ℝ), MeasurableSet (frontier (Metric.thickening r s))
disjs : Pairwise (Disjoint on fun r => frontier (Metric.thickening r s))
key : Set.Countable {i | 0 < ↑↑μ (frontier (Metric.thickening i s))}
aux : ↑↑volume (Ioo a b \ {i | 0 < ↑↑μ (frontier (Metric.thickening i s))}) = ↑↑volume (Ioo a b)
len_pos : 0 < ↑↑volume (Ioo a b \ {i | 0 < ↑↑μ (frontier (Metric.thickening i s))})
r : ℝ
r_in_Ioo : r ∈ Ioo a b
hr : r ∉ {i | 0 < ↑↑μ (frontier (Metric.thickening i s))}
⊢ ∃ r ∈ Ioo a b, ↑↑μ (frontier (Metric.thickening r s)) = 0

Next tactic:
refine' ⟨r, r_in_Ioo, _⟩
theorem exists_null_frontier_thickening (μ : Measure Ω) [SigmaFinite μ] (s : Set Ω) {a b : ℝ}
    (hab : a < b) : ∃ r ∈ Ioo a b, μ (frontier (Metric.thickening r s)) = 0 := by
  have mbles : ∀ r : ℝ, MeasurableSet (frontier (Metric.thickening r s)) :=
    fun r => isClosed_frontier.measurableSet
  have disjs := Metric.frontier_thickening_disjoint s
  have key := Measure.countable_meas_pos_of_disjoint_iUnion (μ := μ) mbles disjs
  have aux := measure_diff_null (s₁ := Ioo a b) (Set.Countable.measure_zero key volume)
  have len_pos : 0 < ENNReal.ofReal (b - a) := by simp only [hab, ENNReal.ofReal_pos, sub_pos]
  rw [← Real.volume_Ioo, ← aux] at len_pos
  rcases nonempty_of_measure_ne_zero len_pos.ne.symm with ⟨r, ⟨r_in_Ioo, hr⟩⟩
  refine' ⟨r, r_in_Ioo, _⟩
  

Proof state:
case intro.intro
Ω : Type u_1
inst✝³ : PseudoEMetricSpace Ω
inst✝² : MeasurableSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : SigmaFinite μ
s : Set Ω
a b : ℝ
hab : a < b
mbles : ∀ (r : ℝ), MeasurableSet (frontier (Metric.thickening r s))
disjs : Pairwise (Disjoint on fun r => frontier (Metric.thickening r s))
key : Set.Countable {i | 0 < ↑↑μ (frontier (Metric.thickening i s))}
aux : ↑↑volume (Ioo a b \ {i | 0 < ↑↑μ (frontier (Metric.thickening i s))}) = ↑↑volume (Ioo a b)
len_pos : 0 < ↑↑volume (Ioo a b \ {i | 0 < ↑↑μ (frontier (Metric.thickening i s))})
r : ℝ
r_in_Ioo : r ∈ Ioo a b
hr : r ∉ {i | 0 < ↑↑μ (frontier (Metric.thickening i s))}
⊢ ↑↑μ (frontier (Metric.thickening r s)) = 0

Next tactic:
simpa only [mem_setOf_eq, not_lt, le_zero_iff] using hr
theorem exists_null_frontiers_thickening (μ : Measure Ω) [SigmaFinite μ] (s : Set Ω) :
    ∃ rs : ℕ → ℝ,
      Tendsto rs atTop (𝓝 0) ∧ ∀ n, 0 < rs n ∧ μ (frontier (Metric.thickening (rs n) s)) = 0 := by
  

Proof state:
Ω : Type u_1
inst✝³ : PseudoEMetricSpace Ω
inst✝² : MeasurableSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : SigmaFinite μ
s : Set Ω
⊢ ∃ rs, Tendsto rs atTop (𝓝 0) ∧ ∀ (n : ℕ), 0 < rs n ∧ ↑↑μ (frontier (Metric.thickening (rs n) s)) = 0

Next tactic:
rcases exists_seq_strictAnti_tendsto (0 : ℝ) with ⟨Rs, ⟨_, ⟨Rs_pos, Rs_lim⟩⟩⟩
theorem exists_null_frontiers_thickening (μ : Measure Ω) [SigmaFinite μ] (s : Set Ω) :
    ∃ rs : ℕ → ℝ,
      Tendsto rs atTop (𝓝 0) ∧ ∀ n, 0 < rs n ∧ μ (frontier (Metric.thickening (rs n) s)) = 0 := by
  rcases exists_seq_strictAnti_tendsto (0 : ℝ) with ⟨Rs, ⟨_, ⟨Rs_pos, Rs_lim⟩⟩⟩
  

Proof state:
case intro.intro.intro
Ω : Type u_1
inst✝³ : PseudoEMetricSpace Ω
inst✝² : MeasurableSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : SigmaFinite μ
s : Set Ω
Rs : ℕ → ℝ
left✝ : StrictAnti Rs
Rs_pos : ∀ (n : ℕ), 0 < Rs n
Rs_lim : Tendsto Rs atTop (𝓝 0)
⊢ ∃ rs, Tendsto rs atTop (𝓝 0) ∧ ∀ (n : ℕ), 0 < rs n ∧ ↑↑μ (frontier (Metric.thickening (rs n) s)) = 0

Next tactic:
have obs := fun n : ℕ => exists_null_frontier_thickening μ s (Rs_pos n)
theorem exists_null_frontiers_thickening (μ : Measure Ω) [SigmaFinite μ] (s : Set Ω) :
    ∃ rs : ℕ → ℝ,
      Tendsto rs atTop (𝓝 0) ∧ ∀ n, 0 < rs n ∧ μ (frontier (Metric.thickening (rs n) s)) = 0 := by
  rcases exists_seq_strictAnti_tendsto (0 : ℝ) with ⟨Rs, ⟨_, ⟨Rs_pos, Rs_lim⟩⟩⟩
  have obs := fun n : ℕ => exists_null_frontier_thickening μ s (Rs_pos n)
  

Proof state:
case intro.intro.intro
Ω : Type u_1
inst✝³ : PseudoEMetricSpace Ω
inst✝² : MeasurableSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : SigmaFinite μ
s : Set Ω
Rs : ℕ → ℝ
left✝ : StrictAnti Rs
Rs_pos : ∀ (n : ℕ), 0 < Rs n
Rs_lim : Tendsto Rs atTop (𝓝 0)
obs : ∀ (n : ℕ), ∃ r ∈ Ioo 0 (Rs n), ↑↑μ (frontier (Metric.thickening r s)) = 0
⊢ ∃ rs, Tendsto rs atTop (𝓝 0) ∧ ∀ (n : ℕ), 0 < rs n ∧ ↑↑μ (frontier (Metric.thickening (rs n) s)) = 0

Next tactic:
refine' ⟨fun n : ℕ => (obs n).choose, ⟨_, _⟩⟩
theorem exists_null_frontiers_thickening (μ : Measure Ω) [SigmaFinite μ] (s : Set Ω) :
    ∃ rs : ℕ → ℝ,
      Tendsto rs atTop (𝓝 0) ∧ ∀ n, 0 < rs n ∧ μ (frontier (Metric.thickening (rs n) s)) = 0 := by
  rcases exists_seq_strictAnti_tendsto (0 : ℝ) with ⟨Rs, ⟨_, ⟨Rs_pos, Rs_lim⟩⟩⟩
  have obs := fun n : ℕ => exists_null_frontier_thickening μ s (Rs_pos n)
  refine' ⟨fun n : ℕ => (obs n).choose, ⟨_, _⟩⟩
  · 

Proof state:
case intro.intro.intro.refine'_1
Ω : Type u_1
inst✝³ : PseudoEMetricSpace Ω
inst✝² : MeasurableSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : SigmaFinite μ
s : Set Ω
Rs : ℕ → ℝ
left✝ : StrictAnti Rs
Rs_pos : ∀ (n : ℕ), 0 < Rs n
Rs_lim : Tendsto Rs atTop (𝓝 0)
obs : ∀ (n : ℕ), ∃ r ∈ Ioo 0 (Rs n), ↑↑μ (frontier (Metric.thickening r s)) = 0
⊢ Tendsto (fun n => Exists.choose (_ : ∃ r ∈ Ioo 0 (Rs n), ↑↑μ (frontier (Metric.thickening r s)) = 0)) atTop (𝓝 0)

Next tactic:
exact tendsto_of_tendsto_of_tendsto_of_le_of_le tendsto_const_nhds Rs_lim
      (fun n => (obs n).choose_spec.1.1.le) fun n => (obs n).choose_spec.1.2.le
theorem exists_null_frontiers_thickening (μ : Measure Ω) [SigmaFinite μ] (s : Set Ω) :
    ∃ rs : ℕ → ℝ,
      Tendsto rs atTop (𝓝 0) ∧ ∀ n, 0 < rs n ∧ μ (frontier (Metric.thickening (rs n) s)) = 0 := by
  rcases exists_seq_strictAnti_tendsto (0 : ℝ) with ⟨Rs, ⟨_, ⟨Rs_pos, Rs_lim⟩⟩⟩
  have obs := fun n : ℕ => exists_null_frontier_thickening μ s (Rs_pos n)
  refine' ⟨fun n : ℕ => (obs n).choose, ⟨_, _⟩⟩
  · exact tendsto_of_tendsto_of_tendsto_of_le_of_le tendsto_const_nhds Rs_lim
      (fun n => (obs n).choose_spec.1.1.le) fun n => (obs n).choose_spec.1.2.le
  · 

Proof state:
case intro.intro.intro.refine'_2
Ω : Type u_1
inst✝³ : PseudoEMetricSpace Ω
inst✝² : MeasurableSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : SigmaFinite μ
s : Set Ω
Rs : ℕ → ℝ
left✝ : StrictAnti Rs
Rs_pos : ∀ (n : ℕ), 0 < Rs n
Rs_lim : Tendsto Rs atTop (𝓝 0)
obs : ∀ (n : ℕ), ∃ r ∈ Ioo 0 (Rs n), ↑↑μ (frontier (Metric.thickening r s)) = 0
⊢ ∀ (n : ℕ),
    0 < (fun n => Exists.choose (_ : ∃ r ∈ Ioo 0 (Rs n), ↑↑μ (frontier (Metric.thickening r s)) = 0)) n ∧
      ↑↑μ
          (frontier
            (Metric.thickening
              ((fun n => Exists.choose (_ : ∃ r ∈ Ioo 0 (Rs n), ↑↑μ (frontier (Metric.thickening r s)) = 0)) n) s)) =
        0

Next tactic:
exact fun n => ⟨(obs n).choose_spec.1.1, (obs n).choose_spec.2⟩
/-- One implication of the portmanteau theorem:
Assuming that for all Borel sets E whose boundary ∂E carries no probability mass under a
candidate limit probability measure μ we have convergence of the measures μsᵢ(E) to μ(E),
then for all closed sets F we have the limsup condition limsup μsᵢ(F) ≤ μ(F). -/
lemma limsup_measure_closed_le_of_forall_tendsto_measure
    {Ω ι : Type*} {L : Filter ι} [NeBot L]
    [MeasurableSpace Ω] [PseudoEMetricSpace Ω] [OpensMeasurableSpace Ω]
    {μ : Measure Ω} [IsFiniteMeasure μ] {μs : ι → Measure Ω}
    (h : ∀ {E : Set Ω}, MeasurableSet E → μ (frontier E) = 0 →
            Tendsto (fun i ↦ μs i E) L (𝓝 (μ E)))
    (F : Set Ω) (F_closed : IsClosed F) :
    L.limsup (fun i ↦ μs i F) ≤ μ F := by
  

Proof state:
Ω✝ : Type u_1
inst✝⁷ : PseudoEMetricSpace Ω✝
inst✝⁶ : MeasurableSpace Ω✝
inst✝⁵ : OpensMeasurableSpace Ω✝
Ω : Type u_2
ι : Type u_3
L : Filter ι
inst✝⁴ : NeBot L
inst✝³ : MeasurableSpace Ω
inst✝² : PseudoEMetricSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : IsFiniteMeasure μ
μs : ι → Measure Ω
h : ∀ {E : Set Ω}, MeasurableSet E → ↑↑μ (frontier E) = 0 → Tendsto (fun i => ↑↑(μs i) E) L (𝓝 (↑↑μ E))
F : Set Ω
F_closed : IsClosed F
⊢ limsup (fun i => ↑↑(μs i) F) L ≤ ↑↑μ F

Next tactic:
have ex := exists_null_frontiers_thickening μ F
/-- One implication of the portmanteau theorem:
Assuming that for all Borel sets E whose boundary ∂E carries no probability mass under a
candidate limit probability measure μ we have convergence of the measures μsᵢ(E) to μ(E),
then for all closed sets F we have the limsup condition limsup μsᵢ(F) ≤ μ(F). -/
lemma limsup_measure_closed_le_of_forall_tendsto_measure
    {Ω ι : Type*} {L : Filter ι} [NeBot L]
    [MeasurableSpace Ω] [PseudoEMetricSpace Ω] [OpensMeasurableSpace Ω]
    {μ : Measure Ω} [IsFiniteMeasure μ] {μs : ι → Measure Ω}
    (h : ∀ {E : Set Ω}, MeasurableSet E → μ (frontier E) = 0 →
            Tendsto (fun i ↦ μs i E) L (𝓝 (μ E)))
    (F : Set Ω) (F_closed : IsClosed F) :
    L.limsup (fun i ↦ μs i F) ≤ μ F := by
  have ex := exists_null_frontiers_thickening μ F
  

Proof state:
Ω✝ : Type u_1
inst✝⁷ : PseudoEMetricSpace Ω✝
inst✝⁶ : MeasurableSpace Ω✝
inst✝⁵ : OpensMeasurableSpace Ω✝
Ω : Type u_2
ι : Type u_3
L : Filter ι
inst✝⁴ : NeBot L
inst✝³ : MeasurableSpace Ω
inst✝² : PseudoEMetricSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : IsFiniteMeasure μ
μs : ι → Measure Ω
h : ∀ {E : Set Ω}, MeasurableSet E → ↑↑μ (frontier E) = 0 → Tendsto (fun i => ↑↑(μs i) E) L (𝓝 (↑↑μ E))
F : Set Ω
F_closed : IsClosed F
ex : ∃ rs, Tendsto rs atTop (𝓝 0) ∧ ∀ (n : ℕ), 0 < rs n ∧ ↑↑μ (frontier (Metric.thickening (rs n) F)) = 0
⊢ limsup (fun i => ↑↑(μs i) F) L ≤ ↑↑μ F

Next tactic:
let rs := Classical.choose ex
/-- One implication of the portmanteau theorem:
Assuming that for all Borel sets E whose boundary ∂E carries no probability mass under a
candidate limit probability measure μ we have convergence of the measures μsᵢ(E) to μ(E),
then for all closed sets F we have the limsup condition limsup μsᵢ(F) ≤ μ(F). -/
lemma limsup_measure_closed_le_of_forall_tendsto_measure
    {Ω ι : Type*} {L : Filter ι} [NeBot L]
    [MeasurableSpace Ω] [PseudoEMetricSpace Ω] [OpensMeasurableSpace Ω]
    {μ : Measure Ω} [IsFiniteMeasure μ] {μs : ι → Measure Ω}
    (h : ∀ {E : Set Ω}, MeasurableSet E → μ (frontier E) = 0 →
            Tendsto (fun i ↦ μs i E) L (𝓝 (μ E)))
    (F : Set Ω) (F_closed : IsClosed F) :
    L.limsup (fun i ↦ μs i F) ≤ μ F := by
  have ex := exists_null_frontiers_thickening μ F
  let rs := Classical.choose ex
  

Proof state:
Ω✝ : Type u_1
inst✝⁷ : PseudoEMetricSpace Ω✝
inst✝⁶ : MeasurableSpace Ω✝
inst✝⁵ : OpensMeasurableSpace Ω✝
Ω : Type u_2
ι : Type u_3
L : Filter ι
inst✝⁴ : NeBot L
inst✝³ : MeasurableSpace Ω
inst✝² : PseudoEMetricSpace Ω
inst✝¹ : OpensMeasurableSpace Ω
μ : Measure Ω
inst✝ : IsFiniteMeasure μ
μs : ι → Measure Ω
h : ∀ {E : Set Ω}, MeasurableSet E → ↑↑μ (frontier E) = 0 → Tendsto (fun i => ↑↑(μs i) E) L (𝓝 (↑↑μ E))
F : Set Ω
F_closed : IsClosed F
ex : ∃ rs, Tendsto rs atTop (𝓝 0) ∧ ∀ (n : ℕ), 0 < rs n ∧ ↑↑μ (frontier (Metric.thickening (rs n) F)) = 0
rs : ℕ → ℝ := Classical.choose ex
⊢ limsup (fun i => ↑↑(μs i) F) L ≤ ↑↑μ F

Next tactic:
have rs_lim : Tendsto rs atTop (𝓝 0) := (Classical.choose_spec ex).1