l3lab/ntp-mathlib huggingface dataset:
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 _
      rw [Nat.lt_pred_iff] at hm
      

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 : Nat.succ m < Nat.find (_ : ∃ n, upperCrossingTime a b f N n ω = N)
⊢ upperCrossingTime a b f N (m + 1) ω ≠ N

Next tactic:
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
      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
    

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)
hmono :
  StrictMonoOn (fun n => upperCrossingTime a b f N n ω)
    (Set.Iic (Nat.pred (Nat.find (_ : ∃ n, upperCrossingTime a b f N n ω = N))))
⊢ N ≤ upperCrossingTime a b f N N ω

Next tactic:
convert StrictMonoOn.Iic_id_le hmono N (Nat.le_sub_one_of_lt hN')
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 _
      rw [Nat.lt_pred_iff] at hm
      convert Nat.find_min _ hm
    convert StrictMonoOn.Iic_id_le hmono N (Nat.le_sub_one_of_lt hN')
  · 

Proof state:
case neg
Ω : 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:
rw [not_lt] at hN'
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 _
      rw [Nat.lt_pred_iff] at hm
      convert Nat.find_min _ hm
    convert StrictMonoOn.Iic_id_le hmono N (Nat.le_sub_one_of_lt hN')
  · rw [not_lt] at hN'
    

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

Next tactic:
exact upperCrossingTime_stabilize hN' (Nat.find_spec (exists_upperCrossingTime_eq f N ω hab))
theorem Adapted.isStoppingTime_crossing (hf : Adapted ℱ f) :
    IsStoppingTime ℱ (upperCrossingTime a b f N n) ∧
      IsStoppingTime ℱ (lowerCrossingTime a b f N n) := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
hf : Adapted ℱ f
⊢ IsStoppingTime ℱ (upperCrossingTime a b f N n) ∧ IsStoppingTime ℱ (lowerCrossingTime a b f N n)

Next tactic:
induction' n with k ih
theorem Adapted.isStoppingTime_crossing (hf : Adapted ℱ f) :
    IsStoppingTime ℱ (upperCrossingTime a b f N n) ∧
      IsStoppingTime ℱ (lowerCrossingTime a b f N n) := by
  induction' n with k ih
  · 

Proof state:
case zero
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
hf : Adapted ℱ f
⊢ IsStoppingTime ℱ (upperCrossingTime a b f N Nat.zero) ∧ IsStoppingTime ℱ (lowerCrossingTime a b f N Nat.zero)

Next tactic:
refine' ⟨isStoppingTime_const _ 0, _⟩
theorem Adapted.isStoppingTime_crossing (hf : Adapted ℱ f) :
    IsStoppingTime ℱ (upperCrossingTime a b f N n) ∧
      IsStoppingTime ℱ (lowerCrossingTime a b f N n) := by
  induction' n with k ih
  · refine' ⟨isStoppingTime_const _ 0, _⟩
    

Proof state:
case zero
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
hf : Adapted ℱ f
⊢ IsStoppingTime ℱ (lowerCrossingTime a b f N Nat.zero)

Next tactic:
simp [hitting_isStoppingTime hf measurableSet_Iic]
theorem Adapted.isStoppingTime_crossing (hf : Adapted ℱ f) :
    IsStoppingTime ℱ (upperCrossingTime a b f N n) ∧
      IsStoppingTime ℱ (lowerCrossingTime a b f N n) := by
  induction' n with k ih
  · refine' ⟨isStoppingTime_const _ 0, _⟩
    simp [hitting_isStoppingTime hf measurableSet_Iic]
  · 

Proof state:
case succ
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
hf : Adapted ℱ f
k : ℕ
ih : IsStoppingTime ℱ (upperCrossingTime a b f N k) ∧ IsStoppingTime ℱ (lowerCrossingTime a b f N k)
⊢ IsStoppingTime ℱ (upperCrossingTime a b f N (Nat.succ k)) ∧ IsStoppingTime ℱ (lowerCrossingTime a b f N (Nat.succ k))

Next tactic:
obtain ⟨_, ih₂⟩ := ih
theorem Adapted.isStoppingTime_crossing (hf : Adapted ℱ f) :
    IsStoppingTime ℱ (upperCrossingTime a b f N n) ∧
      IsStoppingTime ℱ (lowerCrossingTime a b f N n) := by
  induction' n with k ih
  · refine' ⟨isStoppingTime_const _ 0, _⟩
    simp [hitting_isStoppingTime hf measurableSet_Iic]
  · obtain ⟨_, ih₂⟩ := ih
    

Proof state:
case succ.intro
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
hf : Adapted ℱ f
k : ℕ
left✝ : IsStoppingTime ℱ (upperCrossingTime a b f N k)
ih₂ : IsStoppingTime ℱ (lowerCrossingTime a b f N k)
⊢ IsStoppingTime ℱ (upperCrossingTime a b f N (Nat.succ k)) ∧ IsStoppingTime ℱ (lowerCrossingTime a b f N (Nat.succ k))

Next tactic:
have : IsStoppingTime ℱ (upperCrossingTime a b f N (k + 1)) := by
      intro n
      simp_rw [upperCrossingTime_succ_eq]
      exact isStoppingTime_hitting_isStoppingTime ih₂ (fun _ => lowerCrossingTime_le)
        measurableSet_Ici hf _
theorem Adapted.isStoppingTime_crossing (hf : Adapted ℱ f) :
    IsStoppingTime ℱ (upperCrossingTime a b f N n) ∧
      IsStoppingTime ℱ (lowerCrossingTime a b f N n) := by
  induction' n with k ih
  · refine' ⟨isStoppingTime_const _ 0, _⟩
    simp [hitting_isStoppingTime hf measurableSet_Iic]
  · obtain ⟨_, ih₂⟩ := ih
    have : IsStoppingTime ℱ (upperCrossingTime a b f N (k + 1)) := by
      

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
hf : Adapted ℱ f
k : ℕ
left✝ : IsStoppingTime ℱ (upperCrossingTime a b f N k)
ih₂ : IsStoppingTime ℱ (lowerCrossingTime a b f N k)
⊢ IsStoppingTime ℱ (upperCrossingTime a b f N (k + 1))

Next tactic:
intro n
theorem Adapted.isStoppingTime_crossing (hf : Adapted ℱ f) :
    IsStoppingTime ℱ (upperCrossingTime a b f N n) ∧
      IsStoppingTime ℱ (lowerCrossingTime a b f N n) := by
  induction' n with k ih
  · refine' ⟨isStoppingTime_const _ 0, _⟩
    simp [hitting_isStoppingTime hf measurableSet_Iic]
  · obtain ⟨_, ih₂⟩ := ih
    have : IsStoppingTime ℱ (upperCrossingTime a b f N (k + 1)) := by
      intro n
      

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n✝ m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
hf : Adapted ℱ f
k : ℕ
left✝ : IsStoppingTime ℱ (upperCrossingTime a b f N k)
ih₂ : IsStoppingTime ℱ (lowerCrossingTime a b f N k)
n : ℕ
⊢ MeasurableSet {ω | upperCrossingTime a b f N (k + 1) ω ≤ n}

Next tactic:
simp_rw [upperCrossingTime_succ_eq]
theorem Adapted.isStoppingTime_crossing (hf : Adapted ℱ f) :
    IsStoppingTime ℱ (upperCrossingTime a b f N n) ∧
      IsStoppingTime ℱ (lowerCrossingTime a b f N n) := by
  induction' n with k ih
  · refine' ⟨isStoppingTime_const _ 0, _⟩
    simp [hitting_isStoppingTime hf measurableSet_Iic]
  · obtain ⟨_, ih₂⟩ := ih
    have : IsStoppingTime ℱ (upperCrossingTime a b f N (k + 1)) := by
      intro n
      simp_rw [upperCrossingTime_succ_eq]
      

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n✝ m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
hf : Adapted ℱ f
k : ℕ
left✝ : IsStoppingTime ℱ (upperCrossingTime a b f N k)
ih₂ : IsStoppingTime ℱ (lowerCrossingTime a b f N k)
n : ℕ
⊢ MeasurableSet {ω | hitting f (Set.Ici b) (lowerCrossingTime a b f N k ω) N ω ≤ n}

Next tactic:
exact isStoppingTime_hitting_isStoppingTime ih₂ (fun _ => lowerCrossingTime_le)
        measurableSet_Ici hf _
theorem Adapted.isStoppingTime_crossing (hf : Adapted ℱ f) :
    IsStoppingTime ℱ (upperCrossingTime a b f N n) ∧
      IsStoppingTime ℱ (lowerCrossingTime a b f N n) := by
  induction' n with k ih
  · refine' ⟨isStoppingTime_const _ 0, _⟩
    simp [hitting_isStoppingTime hf measurableSet_Iic]
  · obtain ⟨_, ih₂⟩ := ih
    have : IsStoppingTime ℱ (upperCrossingTime a b f N (k + 1)) := by
      intro n
      simp_rw [upperCrossingTime_succ_eq]
      exact isStoppingTime_hitting_isStoppingTime ih₂ (fun _ => lowerCrossingTime_le)
        measurableSet_Ici hf _
    

Proof state:
case succ.intro
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
hf : Adapted ℱ f
k : ℕ
left✝ : IsStoppingTime ℱ (upperCrossingTime a b f N k)
ih₂ : IsStoppingTime ℱ (lowerCrossingTime a b f N k)
this : IsStoppingTime ℱ (upperCrossingTime a b f N (k + 1))
⊢ IsStoppingTime ℱ (upperCrossingTime a b f N (Nat.succ k)) ∧ IsStoppingTime ℱ (lowerCrossingTime a b f N (Nat.succ k))

Next tactic:
refine' ⟨this, _⟩
theorem Adapted.isStoppingTime_crossing (hf : Adapted ℱ f) :
    IsStoppingTime ℱ (upperCrossingTime a b f N n) ∧
      IsStoppingTime ℱ (lowerCrossingTime a b f N n) := by
  induction' n with k ih
  · refine' ⟨isStoppingTime_const _ 0, _⟩
    simp [hitting_isStoppingTime hf measurableSet_Iic]
  · obtain ⟨_, ih₂⟩ := ih
    have : IsStoppingTime ℱ (upperCrossingTime a b f N (k + 1)) := by
      intro n
      simp_rw [upperCrossingTime_succ_eq]
      exact isStoppingTime_hitting_isStoppingTime ih₂ (fun _ => lowerCrossingTime_le)
        measurableSet_Ici hf _
    refine' ⟨this, _⟩
    · 

Proof state:
case succ.intro
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
hf : Adapted ℱ f
k : ℕ
left✝ : IsStoppingTime ℱ (upperCrossingTime a b f N k)
ih₂ : IsStoppingTime ℱ (lowerCrossingTime a b f N k)
this : IsStoppingTime ℱ (upperCrossingTime a b f N (k + 1))
⊢ IsStoppingTime ℱ (lowerCrossingTime a b f N (Nat.succ k))

Next tactic:
intro n
theorem Adapted.isStoppingTime_crossing (hf : Adapted ℱ f) :
    IsStoppingTime ℱ (upperCrossingTime a b f N n) ∧
      IsStoppingTime ℱ (lowerCrossingTime a b f N n) := by
  induction' n with k ih
  · refine' ⟨isStoppingTime_const _ 0, _⟩
    simp [hitting_isStoppingTime hf measurableSet_Iic]
  · obtain ⟨_, ih₂⟩ := ih
    have : IsStoppingTime ℱ (upperCrossingTime a b f N (k + 1)) := by
      intro n
      simp_rw [upperCrossingTime_succ_eq]
      exact isStoppingTime_hitting_isStoppingTime ih₂ (fun _ => lowerCrossingTime_le)
        measurableSet_Ici hf _
    refine' ⟨this, _⟩
    · intro n
      

Proof state:
case succ.intro
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n✝ m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
hf : Adapted ℱ f
k : ℕ
left✝ : IsStoppingTime ℱ (upperCrossingTime a b f N k)
ih₂ : IsStoppingTime ℱ (lowerCrossingTime a b f N k)
this : IsStoppingTime ℱ (upperCrossingTime a b f N (k + 1))
n : ℕ
⊢ MeasurableSet {ω | lowerCrossingTime a b f N (Nat.succ k) ω ≤ n}

Next tactic:
exact isStoppingTime_hitting_isStoppingTime this (fun _ => upperCrossingTime_le)
        measurableSet_Iic hf _
theorem upcrossingStrat_le_one : upcrossingStrat a b f N n ω ≤ 1 := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
⊢ upcrossingStrat a b f N n ω ≤ 1

Next tactic:
rw [upcrossingStrat, ← Finset.indicator_biUnion_apply]
theorem upcrossingStrat_le_one : upcrossingStrat a b f N n ω ≤ 1 := by
  rw [upcrossingStrat, ← Finset.indicator_biUnion_apply]
  · 

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
⊢ Set.indicator (⋃ i ∈ Finset.range N, Set.Ico (lowerCrossingTime a b f N i ω) (upperCrossingTime a b f N (i + 1) ω)) 1
      n ≤
    1

Next tactic:
exact Set.indicator_le_self' (fun _ _ => zero_le_one) _
theorem upcrossingStrat_le_one : upcrossingStrat a b f N n ω ≤ 1 := by
  rw [upcrossingStrat, ← Finset.indicator_biUnion_apply]
  · exact Set.indicator_le_self' (fun _ _ => zero_le_one) _
  

Proof state:
case h
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
⊢ Set.PairwiseDisjoint ↑(Finset.range N) fun k =>
    Set.Ico (lowerCrossingTime a b f N k ω) (upperCrossingTime a b f N (k + 1) ω)

Next tactic:
intro i _ j _ hij
theorem upcrossingStrat_le_one : upcrossingStrat a b f N n ω ≤ 1 := by
  rw [upcrossingStrat, ← Finset.indicator_biUnion_apply]
  · exact Set.indicator_le_self' (fun _ _ => zero_le_one) _
  intro i _ j _ hij
  

Proof state:
case h
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
i : ℕ
a✝¹ : i ∈ ↑(Finset.range N)
j : ℕ
a✝ : j ∈ ↑(Finset.range N)
hij : i ≠ j
⊢ (Disjoint on fun k => Set.Ico (lowerCrossingTime a b f N k ω) (upperCrossingTime a b f N (k + 1) ω)) i j

Next tactic:
simp only [Set.Ico_disjoint_Ico]
theorem upcrossingStrat_le_one : upcrossingStrat a b f N n ω ≤ 1 := by
  rw [upcrossingStrat, ← Finset.indicator_biUnion_apply]
  · exact Set.indicator_le_self' (fun _ _ => zero_le_one) _
  intro i _ j _ hij
  simp only [Set.Ico_disjoint_Ico]
  

Proof state:
case h
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
i : ℕ
a✝¹ : i ∈ ↑(Finset.range N)
j : ℕ
a✝ : j ∈ ↑(Finset.range N)
hij : i ≠ j
⊢ min (upperCrossingTime a b f N (i + 1) ω) (upperCrossingTime a b f N (j + 1) ω) ≤
    max (lowerCrossingTime a b f N i ω) (lowerCrossingTime a b f N j ω)

Next tactic:
obtain hij' | hij' := lt_or_gt_of_ne hij
theorem upcrossingStrat_le_one : upcrossingStrat a b f N n ω ≤ 1 := by
  rw [upcrossingStrat, ← Finset.indicator_biUnion_apply]
  · exact Set.indicator_le_self' (fun _ _ => zero_le_one) _
  intro i _ j _ hij
  simp only [Set.Ico_disjoint_Ico]
  obtain hij' | hij' := lt_or_gt_of_ne hij
  · 

Proof state:
case h.inl
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
i : ℕ
a✝¹ : i ∈ ↑(Finset.range N)
j : ℕ
a✝ : j ∈ ↑(Finset.range N)
hij : i ≠ j
hij' : i < j
⊢ min (upperCrossingTime a b f N (i + 1) ω) (upperCrossingTime a b f N (j + 1) ω) ≤
    max (lowerCrossingTime a b f N i ω) (lowerCrossingTime a b f N j ω)

Next tactic:
rw [min_eq_left (upperCrossingTime_mono (Nat.succ_le_succ hij'.le) :
      upperCrossingTime a b f N _ ω ≤ upperCrossingTime a b f N _ ω),
      max_eq_right (lowerCrossingTime_mono hij'.le :
        lowerCrossingTime a b f N _ _ ≤ lowerCrossingTime _ _ _ _ _ _)]
theorem upcrossingStrat_le_one : upcrossingStrat a b f N n ω ≤ 1 := by
  rw [upcrossingStrat, ← Finset.indicator_biUnion_apply]
  · exact Set.indicator_le_self' (fun _ _ => zero_le_one) _
  intro i _ j _ hij
  simp only [Set.Ico_disjoint_Ico]
  obtain hij' | hij' := lt_or_gt_of_ne hij
  · rw [min_eq_left (upperCrossingTime_mono (Nat.succ_le_succ hij'.le) :
      upperCrossingTime a b f N _ ω ≤ upperCrossingTime a b f N _ ω),
      max_eq_right (lowerCrossingTime_mono hij'.le :
        lowerCrossingTime a b f N _ _ ≤ lowerCrossingTime _ _ _ _ _ _)]
    

Proof state:
case h.inl
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
i : ℕ
a✝¹ : i ∈ ↑(Finset.range N)
j : ℕ
a✝ : j ∈ ↑(Finset.range N)
hij : i ≠ j
hij' : i < j
⊢ upperCrossingTime a b f N (Nat.succ i) ω ≤ lowerCrossingTime a b f N j ω

Next tactic:
refine' le_trans upperCrossingTime_le_lowerCrossingTime
      (lowerCrossingTime_mono (Nat.succ_le_of_lt hij'))
theorem upcrossingStrat_le_one : upcrossingStrat a b f N n ω ≤ 1 := by
  rw [upcrossingStrat, ← Finset.indicator_biUnion_apply]
  · exact Set.indicator_le_self' (fun _ _ => zero_le_one) _
  intro i _ j _ hij
  simp only [Set.Ico_disjoint_Ico]
  obtain hij' | hij' := lt_or_gt_of_ne hij
  · rw [min_eq_left (upperCrossingTime_mono (Nat.succ_le_succ hij'.le) :
      upperCrossingTime a b f N _ ω ≤ upperCrossingTime a b f N _ ω),
      max_eq_right (lowerCrossingTime_mono hij'.le :
        lowerCrossingTime a b f N _ _ ≤ lowerCrossingTime _ _ _ _ _ _)]
    refine' le_trans upperCrossingTime_le_lowerCrossingTime
      (lowerCrossingTime_mono (Nat.succ_le_of_lt hij'))
  · 

Proof state:
case h.inr
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
i : ℕ
a✝¹ : i ∈ ↑(Finset.range N)
j : ℕ
a✝ : j ∈ ↑(Finset.range N)
hij : i ≠ j
hij' : i > j
⊢ min (upperCrossingTime a b f N (i + 1) ω) (upperCrossingTime a b f N (j + 1) ω) ≤
    max (lowerCrossingTime a b f N i ω) (lowerCrossingTime a b f N j ω)

Next tactic:
rw [gt_iff_lt] at hij'
theorem upcrossingStrat_le_one : upcrossingStrat a b f N n ω ≤ 1 := by
  rw [upcrossingStrat, ← Finset.indicator_biUnion_apply]
  · exact Set.indicator_le_self' (fun _ _ => zero_le_one) _
  intro i _ j _ hij
  simp only [Set.Ico_disjoint_Ico]
  obtain hij' | hij' := lt_or_gt_of_ne hij
  · rw [min_eq_left (upperCrossingTime_mono (Nat.succ_le_succ hij'.le) :
      upperCrossingTime a b f N _ ω ≤ upperCrossingTime a b f N _ ω),
      max_eq_right (lowerCrossingTime_mono hij'.le :
        lowerCrossingTime a b f N _ _ ≤ lowerCrossingTime _ _ _ _ _ _)]
    refine' le_trans upperCrossingTime_le_lowerCrossingTime
      (lowerCrossingTime_mono (Nat.succ_le_of_lt hij'))
  · rw [gt_iff_lt] at hij'
    

Proof state:
case h.inr
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
i : ℕ
a✝¹ : i ∈ ↑(Finset.range N)
j : ℕ
a✝ : j ∈ ↑(Finset.range N)
hij : i ≠ j
hij' : j < i
⊢ min (upperCrossingTime a b f N (i + 1) ω) (upperCrossingTime a b f N (j + 1) ω) ≤
    max (lowerCrossingTime a b f N i ω) (lowerCrossingTime a b f N j ω)

Next tactic:
rw [min_eq_right (upperCrossingTime_mono (Nat.succ_le_succ hij'.le) :
      upperCrossingTime a b f N _ ω ≤ upperCrossingTime a b f N _ ω),
      max_eq_left (lowerCrossingTime_mono hij'.le :
        lowerCrossingTime a b f N _ _ ≤ lowerCrossingTime _ _ _ _ _ _)]
theorem upcrossingStrat_le_one : upcrossingStrat a b f N n ω ≤ 1 := by
  rw [upcrossingStrat, ← Finset.indicator_biUnion_apply]
  · exact Set.indicator_le_self' (fun _ _ => zero_le_one) _
  intro i _ j _ hij
  simp only [Set.Ico_disjoint_Ico]
  obtain hij' | hij' := lt_or_gt_of_ne hij
  · rw [min_eq_left (upperCrossingTime_mono (Nat.succ_le_succ hij'.le) :
      upperCrossingTime a b f N _ ω ≤ upperCrossingTime a b f N _ ω),
      max_eq_right (lowerCrossingTime_mono hij'.le :
        lowerCrossingTime a b f N _ _ ≤ lowerCrossingTime _ _ _ _ _ _)]
    refine' le_trans upperCrossingTime_le_lowerCrossingTime
      (lowerCrossingTime_mono (Nat.succ_le_of_lt hij'))
  · rw [gt_iff_lt] at hij'
    rw [min_eq_right (upperCrossingTime_mono (Nat.succ_le_succ hij'.le) :
      upperCrossingTime a b f N _ ω ≤ upperCrossingTime a b f N _ ω),
      max_eq_left (lowerCrossingTime_mono hij'.le :
        lowerCrossingTime a b f N _ _ ≤ lowerCrossingTime _ _ _ _ _ _)]
    

Proof state:
case h.inr
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
i : ℕ
a✝¹ : i ∈ ↑(Finset.range N)
j : ℕ
a✝ : j ∈ ↑(Finset.range N)
hij : i ≠ j
hij' : j < i
⊢ upperCrossingTime a b f N (Nat.succ j) ω ≤ lowerCrossingTime a b f N i ω

Next tactic:
refine' le_trans upperCrossingTime_le_lowerCrossingTime
      (lowerCrossingTime_mono (Nat.succ_le_of_lt hij'))
theorem Adapted.upcrossingStrat_adapted (hf : Adapted ℱ f) :
    Adapted ℱ (upcrossingStrat a b f N) := by
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
hf : Adapted ℱ f
⊢ Adapted ℱ (upcrossingStrat a b f N)

Next tactic:
intro n
theorem Adapted.upcrossingStrat_adapted (hf : Adapted ℱ f) :
    Adapted ℱ (upcrossingStrat a b f N) := by
  intro n
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n✝ m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
hf : Adapted ℱ f
n : ℕ
⊢ StronglyMeasurable (upcrossingStrat a b f N n)

Next tactic:
change StronglyMeasurable[ℱ n] fun ω =>
    ∑ k in Finset.range N, ({n | lowerCrossingTime a b f N k ω ≤ n} ∩
      {n | n < upperCrossingTime a b f N (k + 1) ω}).indicator 1 n
theorem Adapted.upcrossingStrat_adapted (hf : Adapted ℱ f) :
    Adapted ℱ (upcrossingStrat a b f N) := by
  intro n
  change StronglyMeasurable[ℱ n] fun ω =>
    ∑ k in Finset.range N, ({n | lowerCrossingTime a b f N k ω ≤ n} ∩
      {n | n < upperCrossingTime a b f N (k + 1) ω}).indicator 1 n
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n✝ m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
hf : Adapted ℱ f
n : ℕ
⊢ StronglyMeasurable fun ω =>
    ∑ k in Finset.range N,
      Set.indicator ({n | lowerCrossingTime a b f N k ω ≤ n} ∩ {n | n < upperCrossingTime a b f N (k + 1) ω}) 1 n

Next tactic:
refine' Finset.stronglyMeasurable_sum _ fun i _ =>
    stronglyMeasurable_const.indicator ((hf.isStoppingTime_lowerCrossingTime n).inter _)
theorem Adapted.upcrossingStrat_adapted (hf : Adapted ℱ f) :
    Adapted ℱ (upcrossingStrat a b f N) := by
  intro n
  change StronglyMeasurable[ℱ n] fun ω =>
    ∑ k in Finset.range N, ({n | lowerCrossingTime a b f N k ω ≤ n} ∩
      {n | n < upperCrossingTime a b f N (k + 1) ω}).indicator 1 n
  refine' Finset.stronglyMeasurable_sum _ fun i _ =>
    stronglyMeasurable_const.indicator ((hf.isStoppingTime_lowerCrossingTime n).inter _)
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n✝ m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
hf : Adapted ℱ f
n i : ℕ
x✝ : i ∈ Finset.range N
⊢ MeasurableSet fun ω => setOf (fun n => n < upperCrossingTime a b f N (i + 1) ω) n

Next tactic:
simp_rw [← not_le]
theorem Adapted.upcrossingStrat_adapted (hf : Adapted ℱ f) :
    Adapted ℱ (upcrossingStrat a b f N) := by
  intro n
  change StronglyMeasurable[ℱ n] fun ω =>
    ∑ k in Finset.range N, ({n | lowerCrossingTime a b f N k ω ≤ n} ∩
      {n | n < upperCrossingTime a b f N (k + 1) ω}).indicator 1 n
  refine' Finset.stronglyMeasurable_sum _ fun i _ =>
    stronglyMeasurable_const.indicator ((hf.isStoppingTime_lowerCrossingTime n).inter _)
  simp_rw [← not_le]
  

Proof state:
Ω : Type u_1
ι : Type u_2
m0 : MeasurableSpace Ω
μ : Measure Ω
a b : ℝ
f : ℕ → Ω → ℝ
N n✝ m : ℕ
ω : Ω
ℱ : Filtration ℕ m0
hf : Adapted ℱ f
n i : ℕ
x✝ : i ∈ Finset.range N
⊢ MeasurableSet fun ω => setOf (fun n => ¬upperCrossingTime a b f N (i + 1) ω ≤ n) n

Next tactic:
exact (hf.isStoppingTime_upperCrossingTime n).compl