l3lab/ntp-mathlib huggingface dataset:
theorem upperCrossingTime_succ : upperCrossingTime a b f N (n + 1) ω =
    hitting f (Set.Ici b) (lowerCrossingTimeAux a f (upperCrossingTime a b f N n ω) N ω) N ω := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
inst✝² : Preorder ι
inst✝¹ : OrderBot ι
inst✝ : InfSet ι
a b : ℝ
f : ι → Ω → ℝ
N : ι
n m : ℕ
ω : Ω
⊢ upperCrossingTime a b f N (n + 1) ω =
    hitting f (Set.Ici b) (lowerCrossingTimeAux a f (upperCrossingTime a b f N n ω) N ω) N ω

Next tactic:
rw [upperCrossingTime]
theorem upperCrossingTime_succ_eq (ω : Ω) : upperCrossingTime a b f N (n + 1) ω =
    hitting f (Set.Ici b) (lowerCrossingTime a b f N n ω) N ω := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
inst✝² : Preorder ι
inst✝¹ : OrderBot ι
inst✝ : InfSet ι
a b : ℝ
f : ι → Ω → ℝ
N : ι
n m : ℕ
ω✝ ω : Ω
⊢ upperCrossingTime a b f N (n + 1) ω = hitting f (Set.Ici b) (lowerCrossingTime a b f N n ω) N ω

Next tactic:
simp only [upperCrossingTime_succ]
theorem upperCrossingTime_succ_eq (ω : Ω) : upperCrossingTime a b f N (n + 1) ω =
    hitting f (Set.Ici b) (lowerCrossingTime a b f N n ω) N ω := by
  simp only [upperCrossingTime_succ]
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
inst✝² : Preorder ι
inst✝¹ : OrderBot ι
inst✝ : InfSet ι
a b : ℝ
f : ι → Ω → ℝ
N : ι
n m : ℕ
ω✝ ω : Ω
⊢ hitting f (Set.Ici b) (lowerCrossingTimeAux a f (upperCrossingTime a b f N n ω) N ω) N ω =
    hitting f (Set.Ici b) (lowerCrossingTime a b f N n ω) N ω

Next tactic:
rfl
theorem upperCrossingTime_le : upperCrossingTime a b f N n ω ≤ N := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
inst✝ : ConditionallyCompleteLinearOrderBot ι
a b : ℝ
f : ι → Ω → ℝ
N : ι
n m : ℕ
ω : Ω
⊢ upperCrossingTime a b f N n ω ≤ N

Next tactic:
cases n
theorem upperCrossingTime_le : upperCrossingTime a b f N n ω ≤ N := by
  cases n
  · 

Proof state:
case zero
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
inst✝ : ConditionallyCompleteLinearOrderBot ι
a b : ℝ
f : ι → Ω → ℝ
N : ι
m : ℕ
ω : Ω
⊢ upperCrossingTime a b f N Nat.zero ω ≤ N

Next tactic:
simp only [upperCrossingTime_zero, Pi.bot_apply, bot_le, Nat.zero_eq]
theorem upperCrossingTime_le : upperCrossingTime a b f N n ω ≤ N := by
  cases n
  · simp only [upperCrossingTime_zero, Pi.bot_apply, bot_le, Nat.zero_eq]
  · 

Proof state:
case succ
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
inst✝ : ConditionallyCompleteLinearOrderBot ι
a b : ℝ
f : ι → Ω → ℝ
N : ι
m : ℕ
ω : Ω
n✝ : ℕ
⊢ upperCrossingTime a b f N (Nat.succ n✝) ω ≤ N

Next tactic:
simp only [upperCrossingTime_succ, hitting_le]
theorem lowerCrossingTime_le : lowerCrossingTime a b f N n ω ≤ N := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
inst✝ : ConditionallyCompleteLinearOrderBot ι
a b : ℝ
f : ι → Ω → ℝ
N : ι
n m : ℕ
ω : Ω
⊢ lowerCrossingTime a b f N n ω ≤ N

Next tactic:
simp only [lowerCrossingTime, hitting_le ω]
theorem upperCrossingTime_le_lowerCrossingTime :
    upperCrossingTime a b f N n ω ≤ lowerCrossingTime a b f N n ω := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
inst✝ : ConditionallyCompleteLinearOrderBot ι
a b : ℝ
f : ι → Ω → ℝ
N : ι
n m : ℕ
ω : Ω
⊢ upperCrossingTime a b f N n ω ≤ lowerCrossingTime a b f N n ω

Next tactic:
simp only [lowerCrossingTime, le_hitting upperCrossingTime_le ω]
theorem lowerCrossingTime_le_upperCrossingTime_succ :
    lowerCrossingTime a b f N n ω ≤ upperCrossingTime a b f N (n + 1) ω := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
inst✝ : ConditionallyCompleteLinearOrderBot ι
a b : ℝ
f : ι → Ω → ℝ
N : ι
n m : ℕ
ω : Ω
⊢ lowerCrossingTime a b f N n ω ≤ upperCrossingTime a b f N (n + 1) ω

Next tactic:
rw [upperCrossingTime_succ]
theorem lowerCrossingTime_le_upperCrossingTime_succ :
    lowerCrossingTime a b f N n ω ≤ upperCrossingTime a b f N (n + 1) ω := by
  rw [upperCrossingTime_succ]
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
inst✝ : ConditionallyCompleteLinearOrderBot ι
a b : ℝ
f : ι → Ω → ℝ
N : ι
n m : ℕ
ω : Ω
⊢ lowerCrossingTime a b f N n ω ≤
    hitting f (Set.Ici b) (lowerCrossingTimeAux a f (upperCrossingTime a b f N n ω) N ω) N ω

Next tactic:
exact le_hitting lowerCrossingTime_le ω
theorem lowerCrossingTime_mono (hnm : n ≤ m) :
    lowerCrossingTime a b f N n ω ≤ lowerCrossingTime a b f N m ω := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
inst✝ : ConditionallyCompleteLinearOrderBot ι
a b : ℝ
f : ι → Ω → ℝ
N : ι
n m : ℕ
ω : Ω
hnm : n ≤ m
⊢ lowerCrossingTime a b f N n ω ≤ lowerCrossingTime a b f N m ω

Next tactic:
suffices Monotone fun n => lowerCrossingTime a b f N n ω by exact this hnm
theorem lowerCrossingTime_mono (hnm : n ≤ m) :
    lowerCrossingTime a b f N n ω ≤ lowerCrossingTime a b f N m ω := by
  suffices Monotone fun n => lowerCrossingTime a b f N n ω by 

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
inst✝ : ConditionallyCompleteLinearOrderBot ι
a b : ℝ
f : ι → Ω → ℝ
N : ι
n m : ℕ
ω : Ω
hnm : n ≤ m
this : Monotone fun n => lowerCrossingTime a b f N n ω
⊢ lowerCrossingTime a b f N n ω ≤ lowerCrossingTime a b f N m ω

Next tactic:
exact this hnm
theorem lowerCrossingTime_mono (hnm : n ≤ m) :
    lowerCrossingTime a b f N n ω ≤ lowerCrossingTime a b f N m ω := by
  suffices Monotone fun n => lowerCrossingTime a b f N n ω by exact this hnm
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
inst✝ : ConditionallyCompleteLinearOrderBot ι
a b : ℝ
f : ι → Ω → ℝ
N : ι
n m : ℕ
ω : Ω
hnm : n ≤ m
⊢ Monotone fun n => lowerCrossingTime a b f N n ω

Next tactic:
exact monotone_nat_of_le_succ fun n =>
    le_trans lowerCrossingTime_le_upperCrossingTime_succ upperCrossingTime_le_lowerCrossingTime
theorem upperCrossingTime_mono (hnm : n ≤ m) :
    upperCrossingTime a b f N n ω ≤ upperCrossingTime a b f N m ω := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
inst✝ : ConditionallyCompleteLinearOrderBot ι
a b : ℝ
f : ι → Ω → ℝ
N : ι
n m : ℕ
ω : Ω
hnm : n ≤ m
⊢ upperCrossingTime a b f N n ω ≤ upperCrossingTime a b f N m ω

Next tactic:
suffices Monotone fun n => upperCrossingTime a b f N n ω by exact this hnm
theorem upperCrossingTime_mono (hnm : n ≤ m) :
    upperCrossingTime a b f N n ω ≤ upperCrossingTime a b f N m ω := by
  suffices Monotone fun n => upperCrossingTime a b f N n ω by 

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
inst✝ : ConditionallyCompleteLinearOrderBot ι
a b : ℝ
f : ι → Ω → ℝ
N : ι
n m : ℕ
ω : Ω
hnm : n ≤ m
this : Monotone fun n => upperCrossingTime a b f N n ω
⊢ upperCrossingTime a b f N n ω ≤ upperCrossingTime a b f N m ω

Next tactic:
exact this hnm
theorem upperCrossingTime_mono (hnm : n ≤ m) :
    upperCrossingTime a b f N n ω ≤ upperCrossingTime a b f N m ω := by
  suffices Monotone fun n => upperCrossingTime a b f N n ω by exact this hnm
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
inst✝ : ConditionallyCompleteLinearOrderBot ι
a b : ℝ
f : ι → Ω → ℝ
N : ι
n m : ℕ
ω : Ω
hnm : n ≤ m
⊢ Monotone fun n => upperCrossingTime a b f N n ω

Next tactic:
exact monotone_nat_of_le_succ fun n =>
    le_trans upperCrossingTime_le_lowerCrossingTime lowerCrossingTime_le_upperCrossingTime_succ
theorem stoppedValue_lowerCrossingTime (h : lowerCrossingTime a b f N n ω ≠ N) :
    stoppedValue f (lowerCrossingTime a b f N n) ω ≤ a := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
h : lowerCrossingTime a b f N n ω ≠ N
⊢ stoppedValue f (lowerCrossingTime a b f N n) ω ≤ a

Next tactic:
obtain ⟨j, hj₁, hj₂⟩ := (hitting_le_iff_of_lt _ (lt_of_le_of_ne lowerCrossingTime_le h)).1 le_rfl
theorem stoppedValue_lowerCrossingTime (h : lowerCrossingTime a b f N n ω ≠ N) :
    stoppedValue f (lowerCrossingTime a b f N n) ω ≤ a := by
  obtain ⟨j, hj₁, hj₂⟩ := (hitting_le_iff_of_lt _ (lt_of_le_of_ne lowerCrossingTime_le h)).1 le_rfl
  

Proof state:
case intro.intro
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
h : lowerCrossingTime a b f N n ω ≠ N
j : ℕ
hj₁ : j ∈ Set.Icc (upperCrossingTime a b f N n ω) (lowerCrossingTime a b f N n ω)
hj₂ : f j ω ∈ Set.Iic a
⊢ stoppedValue f (lowerCrossingTime a b f N n) ω ≤ a

Next tactic:
exact stoppedValue_hitting_mem ⟨j, ⟨hj₁.1, le_trans hj₁.2 lowerCrossingTime_le⟩, hj₂⟩
theorem stoppedValue_upperCrossingTime (h : upperCrossingTime a b f N (n + 1) ω ≠ N) :
    b ≤ stoppedValue f (upperCrossingTime a b f N (n + 1)) ω := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
h : upperCrossingTime a b f N (n + 1) ω ≠ N
⊢ b ≤ stoppedValue f (upperCrossingTime a b f N (n + 1)) ω

Next tactic:
obtain ⟨j, hj₁, hj₂⟩ := (hitting_le_iff_of_lt _ (lt_of_le_of_ne upperCrossingTime_le h)).1 le_rfl
theorem stoppedValue_upperCrossingTime (h : upperCrossingTime a b f N (n + 1) ω ≠ N) :
    b ≤ stoppedValue f (upperCrossingTime a b f N (n + 1)) ω := by
  obtain ⟨j, hj₁, hj₂⟩ := (hitting_le_iff_of_lt _ (lt_of_le_of_ne upperCrossingTime_le h)).1 le_rfl
  

Proof state:
case intro.intro
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
h : upperCrossingTime a b f N (n + 1) ω ≠ N
j : ℕ
hj₁ :
  j ∈
    Set.Icc (lowerCrossingTimeAux a f (upperCrossingTime a b f N (Nat.add n 0) ω) N ω)
      (upperCrossingTime a b f N (n + 1) ω)
hj₂ : f j ω ∈ Set.Ici b
⊢ b ≤ stoppedValue f (upperCrossingTime a b f N (n + 1)) ω

Next tactic:
exact stoppedValue_hitting_mem ⟨j, ⟨hj₁.1, le_trans hj₁.2 (hitting_le _)⟩, hj₂⟩
theorem upperCrossingTime_lt_lowerCrossingTime (hab : a < b)
    (hn : lowerCrossingTime a b f N (n + 1) ω ≠ N) :
    upperCrossingTime a b f N (n + 1) ω < lowerCrossingTime a b f N (n + 1) ω := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
hab : a < b
hn : lowerCrossingTime a b f N (n + 1) ω ≠ N
⊢ upperCrossingTime a b f N (n + 1) ω < lowerCrossingTime a b f N (n + 1) ω

Next tactic:
refine' lt_of_le_of_ne upperCrossingTime_le_lowerCrossingTime fun h =>
    not_le.2 hab <| le_trans _ (stoppedValue_lowerCrossingTime hn)
theorem upperCrossingTime_lt_lowerCrossingTime (hab : a < b)
    (hn : lowerCrossingTime a b f N (n + 1) ω ≠ N) :
    upperCrossingTime a b f N (n + 1) ω < lowerCrossingTime a b f N (n + 1) ω := by
  refine' lt_of_le_of_ne upperCrossingTime_le_lowerCrossingTime fun h =>
    not_le.2 hab <| le_trans _ (stoppedValue_lowerCrossingTime hn)
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
hab : a < b
hn : lowerCrossingTime a b f N (n + 1) ω ≠ N
h : upperCrossingTime a b f N (n + 1) ω = lowerCrossingTime a b f N (n + 1) ω
⊢ b ≤ stoppedValue f (lowerCrossingTime a b f N (n + 1)) ω

Next tactic:
simp only [stoppedValue]
theorem upperCrossingTime_lt_lowerCrossingTime (hab : a < b)
    (hn : lowerCrossingTime a b f N (n + 1) ω ≠ N) :
    upperCrossingTime a b f N (n + 1) ω < lowerCrossingTime a b f N (n + 1) ω := by
  refine' lt_of_le_of_ne upperCrossingTime_le_lowerCrossingTime fun h =>
    not_le.2 hab <| le_trans _ (stoppedValue_lowerCrossingTime hn)
  simp only [stoppedValue]
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
hab : a < b
hn : lowerCrossingTime a b f N (n + 1) ω ≠ N
h : upperCrossingTime a b f N (n + 1) ω = lowerCrossingTime a b f N (n + 1) ω
⊢ b ≤ f (lowerCrossingTime a b f N (n + 1) ω) ω

Next tactic:
rw [← h]
theorem upperCrossingTime_lt_lowerCrossingTime (hab : a < b)
    (hn : lowerCrossingTime a b f N (n + 1) ω ≠ N) :
    upperCrossingTime a b f N (n + 1) ω < lowerCrossingTime a b f N (n + 1) ω := by
  refine' lt_of_le_of_ne upperCrossingTime_le_lowerCrossingTime fun h =>
    not_le.2 hab <| le_trans _ (stoppedValue_lowerCrossingTime hn)
  simp only [stoppedValue]
  rw [← h]
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
hab : a < b
hn : lowerCrossingTime a b f N (n + 1) ω ≠ N
h : upperCrossingTime a b f N (n + 1) ω = lowerCrossingTime a b f N (n + 1) ω
⊢ b ≤ f (upperCrossingTime a b f N (n + 1) ω) ω

Next tactic:
exact stoppedValue_upperCrossingTime (h.symm ▸ hn)
theorem lowerCrossingTime_lt_upperCrossingTime (hab : a < b)
    (hn : upperCrossingTime a b f N (n + 1) ω ≠ N) :
    lowerCrossingTime a b f N n ω < upperCrossingTime a b f N (n + 1) ω := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
hab : a < b
hn : upperCrossingTime a b f N (n + 1) ω ≠ N
⊢ lowerCrossingTime a b f N n ω < upperCrossingTime a b f N (n + 1) ω

Next tactic:
refine' lt_of_le_of_ne lowerCrossingTime_le_upperCrossingTime_succ fun h =>
    not_le.2 hab <| le_trans (stoppedValue_upperCrossingTime hn) _
theorem lowerCrossingTime_lt_upperCrossingTime (hab : a < b)
    (hn : upperCrossingTime a b f N (n + 1) ω ≠ N) :
    lowerCrossingTime a b f N n ω < upperCrossingTime a b f N (n + 1) ω := by
  refine' lt_of_le_of_ne lowerCrossingTime_le_upperCrossingTime_succ fun h =>
    not_le.2 hab <| le_trans (stoppedValue_upperCrossingTime hn) _
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
hab : a < b
hn : upperCrossingTime a b f N (n + 1) ω ≠ N
h : lowerCrossingTime a b f N n ω = upperCrossingTime a b f N (n + 1) ω
⊢ stoppedValue f (upperCrossingTime a b f N (n + 1)) ω ≤ a

Next tactic:
simp only [stoppedValue]
theorem lowerCrossingTime_lt_upperCrossingTime (hab : a < b)
    (hn : upperCrossingTime a b f N (n + 1) ω ≠ N) :
    lowerCrossingTime a b f N n ω < upperCrossingTime a b f N (n + 1) ω := by
  refine' lt_of_le_of_ne lowerCrossingTime_le_upperCrossingTime_succ fun h =>
    not_le.2 hab <| le_trans (stoppedValue_upperCrossingTime hn) _
  simp only [stoppedValue]
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
hab : a < b
hn : upperCrossingTime a b f N (n + 1) ω ≠ N
h : lowerCrossingTime a b f N n ω = upperCrossingTime a b f N (n + 1) ω
⊢ f (upperCrossingTime a b f N (n + 1) ω) ω ≤ a

Next tactic:
rw [← h]
theorem lowerCrossingTime_lt_upperCrossingTime (hab : a < b)
    (hn : upperCrossingTime a b f N (n + 1) ω ≠ N) :
    lowerCrossingTime a b f N n ω < upperCrossingTime a b f N (n + 1) ω := by
  refine' lt_of_le_of_ne lowerCrossingTime_le_upperCrossingTime_succ fun h =>
    not_le.2 hab <| le_trans (stoppedValue_upperCrossingTime hn) _
  simp only [stoppedValue]
  rw [← h]
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
hab : a < b
hn : upperCrossingTime a b f N (n + 1) ω ≠ N
h : lowerCrossingTime a b f N n ω = upperCrossingTime a b f N (n + 1) ω
⊢ f (lowerCrossingTime a b f N n ω) ω ≤ a

Next tactic:
exact stoppedValue_lowerCrossingTime (h.symm ▸ hn)
theorem exists_upperCrossingTime_eq (f : ℕ → Ω → ℝ) (N : ℕ) (ω : Ω) (hab : a < b) :
    ∃ n, upperCrossingTime a b f N n ω = N := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f✝ : ℕ → Ω → ℝ
N✝ n m : ℕ
ω✝ : Ω
f : ℕ → Ω → ℝ
N : ℕ
ω : Ω
hab : a < b
⊢ ∃ n, upperCrossingTime a b f N n ω = N

Next tactic:
by_contra h
theorem exists_upperCrossingTime_eq (f : ℕ → Ω → ℝ) (N : ℕ) (ω : Ω) (hab : a < b) :
    ∃ n, upperCrossingTime a b f N n ω = N := by
  by_contra h; 

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f✝ : ℕ → Ω → ℝ
N✝ n m : ℕ
ω✝ : Ω
f : ℕ → Ω → ℝ
N : ℕ
ω : Ω
hab : a < b
h : ¬∃ n, upperCrossingTime a b f N n ω = N
⊢ False

Next tactic:
push_neg at h
theorem exists_upperCrossingTime_eq (f : ℕ → Ω → ℝ) (N : ℕ) (ω : Ω) (hab : a < b) :
    ∃ n, upperCrossingTime a b f N n ω = N := by
  by_contra h; push_neg at h
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f✝ : ℕ → Ω → ℝ
N✝ n m : ℕ
ω✝ : Ω
f : ℕ → Ω → ℝ
N : ℕ
ω : Ω
hab : a < b
h : ∀ (n : ℕ), upperCrossingTime a b f N n ω ≠ N
⊢ False

Next tactic:
have : StrictMono fun n => upperCrossingTime a b f N n ω :=
    strictMono_nat_of_lt_succ fun n => upperCrossingTime_lt_succ hab (h _)
theorem exists_upperCrossingTime_eq (f : ℕ → Ω → ℝ) (N : ℕ) (ω : Ω) (hab : a < b) :
    ∃ n, upperCrossingTime a b f N n ω = N := by
  by_contra h; push_neg at h
  have : StrictMono fun n => upperCrossingTime a b f N n ω :=
    strictMono_nat_of_lt_succ fun n => upperCrossingTime_lt_succ hab (h _)
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f✝ : ℕ → Ω → ℝ
N✝ n m : ℕ
ω✝ : Ω
f : ℕ → Ω → ℝ
N : ℕ
ω : Ω
hab : a < b
h : ∀ (n : ℕ), upperCrossingTime a b f N n ω ≠ N
this : StrictMono fun n => upperCrossingTime a b f N n ω
⊢ False

Next tactic:
obtain ⟨_, ⟨k, rfl⟩, hk⟩ :
      ∃ (m : _) (_ : m ∈ Set.range fun n => upperCrossingTime a b f N n ω), N < m :=
    ⟨upperCrossingTime a b f N (N + 1) ω, ⟨N + 1, rfl⟩,
      lt_of_lt_of_le N.lt_succ_self (StrictMono.id_le this (N + 1))⟩
theorem exists_upperCrossingTime_eq (f : ℕ → Ω → ℝ) (N : ℕ) (ω : Ω) (hab : a < b) :
    ∃ n, upperCrossingTime a b f N n ω = N := by
  by_contra h; push_neg at h
  have : StrictMono fun n => upperCrossingTime a b f N n ω :=
    strictMono_nat_of_lt_succ fun n => upperCrossingTime_lt_succ hab (h _)
  obtain ⟨_, ⟨k, rfl⟩, hk⟩ :
      ∃ (m : _) (_ : m ∈ Set.range fun n => upperCrossingTime a b f N n ω), N < m :=
    ⟨upperCrossingTime a b f N (N + 1) ω, ⟨N + 1, rfl⟩,
      lt_of_lt_of_le N.lt_succ_self (StrictMono.id_le this (N + 1))⟩
  

Proof state:
case intro.intro.intro
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f✝ : ℕ → Ω → ℝ
N✝ n m : ℕ
ω✝ : Ω
f : ℕ → Ω → ℝ
N : ℕ
ω : Ω
hab : a < b
h : ∀ (n : ℕ), upperCrossingTime a b f N n ω ≠ N
this : StrictMono fun n => upperCrossingTime a b f N n ω
k : ℕ
hk : N < (fun n => upperCrossingTime a b f N n ω) k
⊢ False

Next tactic:
exact not_le.2 hk upperCrossingTime_le
theorem upperCrossingTime_lt_bddAbove (hab : a < b) :
    BddAbove {n | upperCrossingTime a b f N n ω < N} := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
hab : a < b
⊢ BddAbove {n | upperCrossingTime a b f N n ω < N}

Next tactic:
obtain ⟨k, hk⟩ := exists_upperCrossingTime_eq f N ω hab
theorem upperCrossingTime_lt_bddAbove (hab : a < b) :
    BddAbove {n | upperCrossingTime a b f N n ω < N} := by
  obtain ⟨k, hk⟩ := exists_upperCrossingTime_eq f N ω hab
  

Proof state:
case intro
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
hab : a < b
k : ℕ
hk : upperCrossingTime a b f N k ω = N
⊢ BddAbove {n | upperCrossingTime a b f N n ω < N}

Next tactic:
refine' ⟨k, fun n (hn : upperCrossingTime a b f N n ω < N) => _⟩
theorem upperCrossingTime_lt_bddAbove (hab : a < b) :
    BddAbove {n | upperCrossingTime a b f N n ω < N} := by
  obtain ⟨k, hk⟩ := exists_upperCrossingTime_eq f N ω hab
  refine' ⟨k, fun n (hn : upperCrossingTime a b f N n ω < N) => _⟩
  

Proof state:
case intro
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n✝ m : ℕ
ω : Ω
hab : a < b
k : ℕ
hk : upperCrossingTime a b f N k ω = N
n : ℕ
hn : upperCrossingTime a b f N n ω < N
⊢ n ≤ k

Next tactic:
by_contra hn'
theorem upperCrossingTime_lt_bddAbove (hab : a < b) :
    BddAbove {n | upperCrossingTime a b f N n ω < N} := by
  obtain ⟨k, hk⟩ := exists_upperCrossingTime_eq f N ω hab
  refine' ⟨k, fun n (hn : upperCrossingTime a b f N n ω < N) => _⟩
  by_contra hn'
  

Proof state:
case intro
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n✝ m : ℕ
ω : Ω
hab : a < b
k : ℕ
hk : upperCrossingTime a b f N k ω = N
n : ℕ
hn : upperCrossingTime a b f N n ω < N
hn' : ¬n ≤ k
⊢ False

Next tactic:
exact hn.ne (upperCrossingTime_stabilize (not_le.1 hn').le hk)
theorem upperCrossingTime_bound_eq (f : ℕ → Ω → ℝ) (N : ℕ) (ω : Ω) (hab : a < b) :
    upperCrossingTime a b f N N ω = N := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f✝ : ℕ → Ω → ℝ
N✝ n m : ℕ
ω✝ : Ω
f : ℕ → Ω → ℝ
N : ℕ
ω : Ω
hab : a < b
⊢ upperCrossingTime a b f N N ω = N

Next tactic:
by_cases hN' : N < Nat.find (exists_upperCrossingTime_eq f N ω hab)
theorem upperCrossingTime_bound_eq (f : ℕ → Ω → ℝ) (N : ℕ) (ω : Ω) (hab : a < b) :
    upperCrossingTime a b f N N ω = N := by
  by_cases hN' : N < Nat.find (exists_upperCrossingTime_eq f N ω hab)
  · 

Proof state:
case pos
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f✝ : ℕ → Ω → ℝ
N✝ n m : ℕ
ω✝ : Ω
f : ℕ → Ω → ℝ
N : ℕ
ω : Ω
hab : a < b
hN' : N < Nat.find (_ : ∃ n, upperCrossingTime a b f N n ω = N)
⊢ upperCrossingTime a b f N N ω = N

Next tactic:
refine' le_antisymm upperCrossingTime_le _
theorem upperCrossingTime_bound_eq (f : ℕ → Ω → ℝ) (N : ℕ) (ω : Ω) (hab : a < b) :
    upperCrossingTime a b f N N ω = N := by
  by_cases hN' : N < Nat.find (exists_upperCrossingTime_eq f N ω hab)
  · refine' le_antisymm upperCrossingTime_le _
    

Proof state:
case pos
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f✝ : ℕ → Ω → ℝ
N✝ n m : ℕ
ω✝ : Ω
f : ℕ → Ω → ℝ
N : ℕ
ω : Ω
hab : a < b
hN' : N < Nat.find (_ : ∃ n, upperCrossingTime a b f N n ω = N)
⊢ N ≤ upperCrossingTime a b f N N ω

Next tactic:
have hmono : StrictMonoOn (fun n => upperCrossingTime a b f N n ω)
        (Set.Iic (Nat.find (exists_upperCrossingTime_eq f N ω hab)).pred) := by
      refine' strictMonoOn_Iic_of_lt_succ fun m hm => upperCrossingTime_lt_succ hab _
      rw [Nat.lt_pred_iff] at hm
      convert Nat.find_min _ hm
theorem upperCrossingTime_bound_eq (f : ℕ → Ω → ℝ) (N : ℕ) (ω : Ω) (hab : a < b) :
    upperCrossingTime a b f N N ω = N := by
  by_cases hN' : N < Nat.find (exists_upperCrossingTime_eq f N ω hab)
  · refine' le_antisymm upperCrossingTime_le _
    have hmono : StrictMonoOn (fun n => upperCrossingTime a b f N n ω)
        (Set.Iic (Nat.find (exists_upperCrossingTime_eq f N ω hab)).pred) := by
      

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f✝ : ℕ → Ω → ℝ
N✝ n m : ℕ
ω✝ : Ω
f : ℕ → Ω → ℝ
N : ℕ
ω : Ω
hab : a < b
hN' : N < Nat.find (_ : ∃ n, upperCrossingTime a b f N n ω = N)
⊢ StrictMonoOn (fun n => upperCrossingTime a b f N n ω)
    (Set.Iic (Nat.pred (Nat.find (_ : ∃ n, upperCrossingTime a b f N n ω = N))))

Next tactic:
refine' strictMonoOn_Iic_of_lt_succ fun m hm => upperCrossingTime_lt_succ hab _
theorem upperCrossingTime_bound_eq (f : ℕ → Ω → ℝ) (N : ℕ) (ω : Ω) (hab : a < b) :
    upperCrossingTime a b f N N ω = N := by
  by_cases hN' : N < Nat.find (exists_upperCrossingTime_eq f N ω hab)
  · refine' le_antisymm upperCrossingTime_le _
    have hmono : StrictMonoOn (fun n => upperCrossingTime a b f N n ω)
        (Set.Iic (Nat.find (exists_upperCrossingTime_eq f N ω hab)).pred) := by
      refine' strictMonoOn_Iic_of_lt_succ fun m hm => upperCrossingTime_lt_succ hab _
      

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f✝ : ℕ → Ω → ℝ
N✝ n m✝ : ℕ
ω✝ : Ω
f : ℕ → Ω → ℝ
N : ℕ
ω : Ω
hab : a < b
hN' : N < Nat.find (_ : ∃ n, upperCrossingTime a b f N n ω = N)
m : ℕ
hm : m < Nat.pred (Nat.find (_ : ∃ n, upperCrossingTime a b f N n ω = N))
⊢ upperCrossingTime a b f N (m + 1) ω ≠ N

Next tactic:
rw [Nat.lt_pred_iff] at hm