l3lab/ntp-mathlib huggingface dataset:
/-- The main proof of the lower bound part of the Akra-Bazzi theorem. The factor
`1 + ε n` does not change the asymptotic order, but is needed for the induction step to go
through. -/
lemma smoothingFn_mul_asympBound_isBigO_T :
    (fun (n : ℕ) => (1 + ε n) * asympBound g a b n) =O[atTop] T := by
  let b' := b (min_bi b) / 2
  have hb_pos : 0 < b' := R.bi_min_div_two_pos
  rw [isBigO_atTop_iff_eventually_exists_pos]
  obtain ⟨c₁, hc₁, h_sumTransform_aux⟩ := R.eventually_atTop_sumTransform_le
  

Proof state:
case intro.intro
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
T : ℕ → ℝ
g : ℝ → ℝ
a b : α → ℝ
r : α → ℕ → ℕ
R : AkraBazziRecurrence T g a b r
b' : ℝ := b (min_bi b) / 2
hb_pos : 0 < b'
c₁ : ℝ
hc₁ : c₁ > 0
h_sumTransform_aux : ∀ᶠ (n : ℕ) in atTop, ∀ (i : α), sumTransform (p a b) g (r i n) n ≤ c₁ * g ↑n
⊢ ∀ᶠ (n₀ : ℕ) in atTop, ∃ c > 0, ∀ n ≥ n₀, c * ‖(1 + ε ↑n) * asympBound g a b n‖ ≤ ‖T n‖

Next tactic:
filter_upwards [eventually_ge_atTop R.n₀,                                 -- n₀_ge_Rn₀
      (tendsto_nat_floor_mul_atTop b' hb_pos).eventually_gt_atTop 0,        -- h_b_floor
      eventually_forall_ge_atTop.mpr eventually_one_add_smoothingFn_pos,    -- h_smoothing_pos
      (tendsto_nat_floor_mul_atTop b' hb_pos).eventually_forall_ge_atTop
        eventually_one_add_smoothingFn_pos,                                 -- h_smoothing_pos'
      eventually_forall_ge_atTop.mpr R.eventually_asympBound_pos,            -- h_asympBound_pos
      eventually_forall_ge_atTop.mpr R.eventually_asympBound_r_pos,          -- h_asympBound_r_pos
      (tendsto_nat_floor_mul_atTop b' hb_pos).eventually_forall_ge_atTop
        R.eventually_asympBound_pos,                                         -- h_asympBound_floor
      eventually_gt_atTop 0,                                                -- n₀_pos
      eventually_forall_ge_atTop.mpr R.eventually_one_add_smoothingFn_r_pos,  -- h_smoothing_r_pos
      eventually_forall_ge_atTop.mpr R.rpow_p_mul_one_add_smoothingFn_ge,   -- bound2
      (tendsto_nat_floor_mul_atTop b' hb_pos).eventually_forall_ge_atTop
        eventually_one_add_smoothingFn_pos,                                 -- h_smoothingFn_floor
      eventually_forall_ge_atTop.mpr h_sumTransform_aux,                    -- h_sumTransform
      eventually_forall_ge_atTop.mpr R.eventually_bi_mul_le_r,              -- h_bi_le_r
      eventually_forall_ge_atTop.mpr (eventually_ge_atTop ⌈exp 1⌉₊)]        -- h_exp
    with n₀ n₀_ge_Rn₀ h_b_floor h_smoothing_pos h_smoothing_pos' h_asympBound_pos h_asympBound_r_pos
      h_asympBound_floor n₀_pos h_smoothing_r_pos bound2 h_smoothingFn_floor h_sumTransform
      h_bi_le_r h_exp
/-- The **Akra-Bazzi theorem**: `T ∈ O(n^p (1 + ∑_u^n g(u) / u^{p+1}))` -/
theorem isBigO_asympBound : T =O[atTop] asympBound g a b := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
T : ℕ → ℝ
g : ℝ → ℝ
a b : α → ℝ
r : α → ℕ → ℕ
R : AkraBazziRecurrence T g a b r
⊢ T =O[atTop] asympBound g a b

Next tactic:
calc T =O[atTop] (fun n => (1 - ε n) * asympBound g a b n) := by
              exact R.T_isBigO_smoothingFn_mul_asympBound
         _ =O[atTop] (fun n => 1 * asympBound g a b n) := by
              refine IsBigO.mul (isBigO_const_of_tendsto (y := 1) ?_ one_ne_zero)
                (isBigO_refl _ _)
              show Tendsto ((fun n => 1 - ε n) ∘ (Nat.cast : ℕ → ℝ)) atTop (𝓝 1)
              exact Tendsto.comp isEquivalent_one_sub_smoothingFn_one.tendsto_const
                tendsto_nat_cast_atTop_atTop
         _ = asympBound g a b := by simp
/-- The **Akra-Bazzi theorem**: `T ∈ O(n^p (1 + ∑_u^n g(u) / u^{p+1}))` -/
theorem isBigO_asympBound : T =O[atTop] asympBound g a b := by
  calc T =O[atTop] (fun n => (1 - ε n) * asympBound g a b n) := by
              

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
T : ℕ → ℝ
g : ℝ → ℝ
a b : α → ℝ
r : α → ℕ → ℕ
R : AkraBazziRecurrence T g a b r
⊢ T =O[atTop] fun n => (1 - ε ↑n) * asympBound g a b n

Next tactic:
exact R.T_isBigO_smoothingFn_mul_asympBound
/-- The **Akra-Bazzi theorem**: `T ∈ O(n^p (1 + ∑_u^n g(u) / u^{p+1}))` -/
theorem isBigO_asympBound : T =O[atTop] asympBound g a b := by
  calc T =O[atTop] (fun n => (1 - ε n) * asympBound g a b n) := by
              exact R.T_isBigO_smoothingFn_mul_asympBound
         _ =O[atTop] (fun n => 1 * asympBound g a b n) := by
              

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
T : ℕ → ℝ
g : ℝ → ℝ
a b : α → ℝ
r : α → ℕ → ℕ
R : AkraBazziRecurrence T g a b r
⊢ (fun n => (1 - ε ↑n) * asympBound g a b n) =O[atTop] fun n => 1 * asympBound g a b n

Next tactic:
refine IsBigO.mul (isBigO_const_of_tendsto (y := 1) ?_ one_ne_zero)
                (isBigO_refl _ _)
/-- The **Akra-Bazzi theorem**: `T ∈ O(n^p (1 + ∑_u^n g(u) / u^{p+1}))` -/
theorem isBigO_asympBound : T =O[atTop] asympBound g a b := by
  calc T =O[atTop] (fun n => (1 - ε n) * asympBound g a b n) := by
              exact R.T_isBigO_smoothingFn_mul_asympBound
         _ =O[atTop] (fun n => 1 * asympBound g a b n) := by
              refine IsBigO.mul (isBigO_const_of_tendsto (y := 1) ?_ one_ne_zero)
                (isBigO_refl _ _)
              

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
T : ℕ → ℝ
g : ℝ → ℝ
a b : α → ℝ
r : α → ℕ → ℕ
R : AkraBazziRecurrence T g a b r
⊢ Tendsto (fun n => 1 - ε ↑n) atTop (𝓝 1)

Next tactic:
show Tendsto ((fun n => 1 - ε n) ∘ (Nat.cast : ℕ → ℝ)) atTop (𝓝 1)
/-- The **Akra-Bazzi theorem**: `T ∈ O(n^p (1 + ∑_u^n g(u) / u^{p+1}))` -/
theorem isBigO_asympBound : T =O[atTop] asympBound g a b := by
  calc T =O[atTop] (fun n => (1 - ε n) * asympBound g a b n) := by
              exact R.T_isBigO_smoothingFn_mul_asympBound
         _ =O[atTop] (fun n => 1 * asympBound g a b n) := by
              refine IsBigO.mul (isBigO_const_of_tendsto (y := 1) ?_ one_ne_zero)
                (isBigO_refl _ _)
              show Tendsto ((fun n => 1 - ε n) ∘ (Nat.cast : ℕ → ℝ)) atTop (𝓝 1)
              

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
T : ℕ → ℝ
g : ℝ → ℝ
a b : α → ℝ
r : α → ℕ → ℕ
R : AkraBazziRecurrence T g a b r
⊢ Tendsto ((fun n => 1 - ε n) ∘ Nat.cast) atTop (𝓝 1)

Next tactic:
exact Tendsto.comp isEquivalent_one_sub_smoothingFn_one.tendsto_const
                tendsto_nat_cast_atTop_atTop
/-- The **Akra-Bazzi theorem**: `T ∈ O(n^p (1 + ∑_u^n g(u) / u^{p+1}))` -/
theorem isBigO_asympBound : T =O[atTop] asympBound g a b := by
  calc T =O[atTop] (fun n => (1 - ε n) * asympBound g a b n) := by
              exact R.T_isBigO_smoothingFn_mul_asympBound
         _ =O[atTop] (fun n => 1 * asympBound g a b n) := by
              refine IsBigO.mul (isBigO_const_of_tendsto (y := 1) ?_ one_ne_zero)
                (isBigO_refl _ _)
              show Tendsto ((fun n => 1 - ε n) ∘ (Nat.cast : ℕ → ℝ)) atTop (𝓝 1)
              exact Tendsto.comp isEquivalent_one_sub_smoothingFn_one.tendsto_const
                tendsto_nat_cast_atTop_atTop
         _ = asympBound g a b := by 

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
T : ℕ → ℝ
g : ℝ → ℝ
a b : α → ℝ
r : α → ℕ → ℕ
R : AkraBazziRecurrence T g a b r
⊢ (fun n => 1 * asympBound g a b n) = asympBound g a b

Next tactic:
simp
/-- The **Akra-Bazzi theorem**: `T ∈ Ω(n^p (1 + ∑_u^n g(u) / u^{p+1}))` -/
theorem isBigO_symm_asympBound : asympBound g a b =O[atTop] T := by
  

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
T : ℕ → ℝ
g : ℝ → ℝ
a b : α → ℝ
r : α → ℕ → ℕ
R : AkraBazziRecurrence T g a b r
⊢ asympBound g a b =O[atTop] T

Next tactic:
calc asympBound g a b = (fun n => 1 * asympBound g a b n)  := by simp
                 _ ~[atTop] (fun n => (1 + ε n) * asympBound g a b n) := by
                            refine IsEquivalent.mul (IsEquivalent.symm ?_) IsEquivalent.refl
                            show (fun (n:ℕ) => 1 + ε n) ~[atTop] Function.const ℕ (1:ℝ)
                            rw [isEquivalent_const_iff_tendsto one_ne_zero]
                            show Tendsto ((fun n => 1 + ε n) ∘ (Nat.cast : ℕ → ℝ)) atTop (𝓝 1)
                            exact Tendsto.comp isEquivalent_one_add_smoothingFn_one.tendsto_const
                              tendsto_nat_cast_atTop_atTop
                 _ =O[atTop] T := R.smoothingFn_mul_asympBound_isBigO_T
/-- The **Akra-Bazzi theorem**: `T ∈ Ω(n^p (1 + ∑_u^n g(u) / u^{p+1}))` -/
theorem isBigO_symm_asympBound : asympBound g a b =O[atTop] T := by
  calc asympBound g a b = (fun n => 1 * asympBound g a b n)  := by 

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
T : ℕ → ℝ
g : ℝ → ℝ
a b : α → ℝ
r : α → ℕ → ℕ
R : AkraBazziRecurrence T g a b r
⊢ asympBound g a b = fun n => 1 * asympBound g a b n

Next tactic:
simp
/-- The **Akra-Bazzi theorem**: `T ∈ Ω(n^p (1 + ∑_u^n g(u) / u^{p+1}))` -/
theorem isBigO_symm_asympBound : asympBound g a b =O[atTop] T := by
  calc asympBound g a b = (fun n => 1 * asympBound g a b n)  := by simp
                 _ ~[atTop] (fun n => (1 + ε n) * asympBound g a b n) := by
                            

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
T : ℕ → ℝ
g : ℝ → ℝ
a b : α → ℝ
r : α → ℕ → ℕ
R : AkraBazziRecurrence T g a b r
⊢ (fun n => 1 * asympBound g a b n) ~[atTop] fun n => (1 + ε ↑n) * asympBound g a b n

Next tactic:
refine IsEquivalent.mul (IsEquivalent.symm ?_) IsEquivalent.refl
/-- The **Akra-Bazzi theorem**: `T ∈ Ω(n^p (1 + ∑_u^n g(u) / u^{p+1}))` -/
theorem isBigO_symm_asympBound : asympBound g a b =O[atTop] T := by
  calc asympBound g a b = (fun n => 1 * asympBound g a b n)  := by simp
                 _ ~[atTop] (fun n => (1 + ε n) * asympBound g a b n) := by
                            refine IsEquivalent.mul (IsEquivalent.symm ?_) IsEquivalent.refl
                            

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
T : ℕ → ℝ
g : ℝ → ℝ
a b : α → ℝ
r : α → ℕ → ℕ
R : AkraBazziRecurrence T g a b r
⊢ (fun n => 1 + ε ↑n) ~[atTop] fun n => 1

Next tactic:
show (fun (n:ℕ) => 1 + ε n) ~[atTop] Function.const ℕ (1:ℝ)
/-- The **Akra-Bazzi theorem**: `T ∈ Ω(n^p (1 + ∑_u^n g(u) / u^{p+1}))` -/
theorem isBigO_symm_asympBound : asympBound g a b =O[atTop] T := by
  calc asympBound g a b = (fun n => 1 * asympBound g a b n)  := by simp
                 _ ~[atTop] (fun n => (1 + ε n) * asympBound g a b n) := by
                            refine IsEquivalent.mul (IsEquivalent.symm ?_) IsEquivalent.refl
                            show (fun (n:ℕ) => 1 + ε n) ~[atTop] Function.const ℕ (1:ℝ)
                            

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
T : ℕ → ℝ
g : ℝ → ℝ
a b : α → ℝ
r : α → ℕ → ℕ
R : AkraBazziRecurrence T g a b r
⊢ (fun n => 1 + ε ↑n) ~[atTop] Function.const ℕ 1

Next tactic:
rw [isEquivalent_const_iff_tendsto one_ne_zero]
/-- The **Akra-Bazzi theorem**: `T ∈ Ω(n^p (1 + ∑_u^n g(u) / u^{p+1}))` -/
theorem isBigO_symm_asympBound : asympBound g a b =O[atTop] T := by
  calc asympBound g a b = (fun n => 1 * asympBound g a b n)  := by simp
                 _ ~[atTop] (fun n => (1 + ε n) * asympBound g a b n) := by
                            refine IsEquivalent.mul (IsEquivalent.symm ?_) IsEquivalent.refl
                            show (fun (n:ℕ) => 1 + ε n) ~[atTop] Function.const ℕ (1:ℝ)
                            rw [isEquivalent_const_iff_tendsto one_ne_zero]
                            

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
T : ℕ → ℝ
g : ℝ → ℝ
a b : α → ℝ
r : α → ℕ → ℕ
R : AkraBazziRecurrence T g a b r
⊢ Tendsto (fun n => 1 + ε ↑n) atTop (𝓝 1)

Next tactic:
show Tendsto ((fun n => 1 + ε n) ∘ (Nat.cast : ℕ → ℝ)) atTop (𝓝 1)
/-- The **Akra-Bazzi theorem**: `T ∈ Ω(n^p (1 + ∑_u^n g(u) / u^{p+1}))` -/
theorem isBigO_symm_asympBound : asympBound g a b =O[atTop] T := by
  calc asympBound g a b = (fun n => 1 * asympBound g a b n)  := by simp
                 _ ~[atTop] (fun n => (1 + ε n) * asympBound g a b n) := by
                            refine IsEquivalent.mul (IsEquivalent.symm ?_) IsEquivalent.refl
                            show (fun (n:ℕ) => 1 + ε n) ~[atTop] Function.const ℕ (1:ℝ)
                            rw [isEquivalent_const_iff_tendsto one_ne_zero]
                            show Tendsto ((fun n => 1 + ε n) ∘ (Nat.cast : ℕ → ℝ)) atTop (𝓝 1)
                            

Proof state:
α : Type u_1
inst✝¹ : Fintype α
inst✝ : Nonempty α
T : ℕ → ℝ
g : ℝ → ℝ
a b : α → ℝ
r : α → ℕ → ℕ
R : AkraBazziRecurrence T g a b r
⊢ Tendsto ((fun n => 1 + ε n) ∘ Nat.cast) atTop (𝓝 1)

Next tactic:
exact Tendsto.comp isEquivalent_one_add_smoothingFn_one.tendsto_const
                              tendsto_nat_cast_atTop_atTop
@[simp]
theorem bicategoricalComp_refl {f g h : a ⟶ b} (η : f ⟶ g) (θ : g ⟶ h) : η ⊗≫ θ = η ≫ θ := by
  

Proof state:
B : Type u
inst✝ : Bicategory B
a b c d e : B
f g h : a ⟶ b
η : f ⟶ g
θ : g ⟶ h
⊢ η ⊗≫ θ = η ≫ θ

Next tactic:
dsimp [bicategoricalComp]
@[simp]
theorem bicategoricalComp_refl {f g h : a ⟶ b} (η : f ⟶ g) (θ : g ⟶ h) : η ⊗≫ θ = η ≫ θ := by
  dsimp [bicategoricalComp]; 

Proof state:
B : Type u
inst✝ : Bicategory B
a b c d e : B
f g h : a ⟶ b
η : f ⟶ g
θ : g ⟶ h
⊢ η ≫ 𝟙 g ≫ θ = η ≫ θ

Next tactic:
simp
theorem exists_sum {γ : α ⊕ β → Sort*} (p : (∀ ab, γ ab) → Prop) :
    (∃ fab, p fab) ↔ (∃ fa fb, p (Sum.rec fa fb)) := by
  

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ✝ : Type u_1
δ : Type u_2
γ : α ⊕ β → Sort u_3
p : ((ab : α ⊕ β) → γ ab) → Prop
⊢ (∃ fab, p fab) ↔ ∃ fa fb, p fun t => rec fa fb t

Next tactic:
rw [← not_forall_not, forall_sum]
theorem exists_sum {γ : α ⊕ β → Sort*} (p : (∀ ab, γ ab) → Prop) :
    (∃ fab, p fab) ↔ (∃ fa fb, p (Sum.rec fa fb)) := by
  rw [← not_forall_not, forall_sum]
  

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ✝ : Type u_1
δ : Type u_2
γ : α ⊕ β → Sort u_3
p : ((ab : α ⊕ β) → γ ab) → Prop
⊢ (¬∀ (fa : (val : α) → γ (inl val)) (fb : (val : β) → γ (inr val)), ¬p fun t => rec fa fb t) ↔
    ∃ fa fb, p fun t => rec fa fb t

Next tactic:
simp
theorem sum_rec_congr (P : α ⊕ β → Sort*) (f : ∀ i, P (inl i)) (g : ∀ i, P (inr i))
    {x y : α ⊕ β} (h : x = y) :
    @Sum.rec _ _ _ f g x = cast (congr_arg P h.symm) (@Sum.rec _ _ _ f g y) := by 

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
P : α ⊕ β → Sort u_3
f : (i : α) → P (inl i)
g : (i : β) → P (inr i)
x y : α ⊕ β
h : x = y
⊢ rec f g x = cast (_ : P y = P x) (rec f g y)

Next tactic:
cases h
theorem sum_rec_congr (P : α ⊕ β → Sort*) (f : ∀ i, P (inl i)) (g : ∀ i, P (inr i))
    {x y : α ⊕ β} (h : x = y) :
    @Sum.rec _ _ _ f g x = cast (congr_arg P h.symm) (@Sum.rec _ _ _ f g y) := by cases h; 

Proof state:
case refl
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
P : α ⊕ β → Sort u_3
f : (i : α) → P (inl i)
g : (i : β) → P (inr i)
x : α ⊕ β
⊢ rec f g x = cast (_ : P x = P x) (rec f g x)

Next tactic:
rfl
theorem eq_left_iff_getLeft_eq {a : α} : x = inl a ↔ ∃ h, x.getLeft h = a := by
  

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
x y : α ⊕ β
a : α
⊢ x = inl a ↔ ∃ h, getLeft x h = a

Next tactic:
cases x
theorem eq_left_iff_getLeft_eq {a : α} : x = inl a ↔ ∃ h, x.getLeft h = a := by
  cases x <;> 

Proof state:
case inl
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
y : α ⊕ β
a val✝ : α
⊢ inl val✝ = inl a ↔ ∃ h, getLeft (inl val✝) h = a

Next tactic:
simp
theorem eq_left_iff_getLeft_eq {a : α} : x = inl a ↔ ∃ h, x.getLeft h = a := by
  cases x <;> 

Proof state:
case inr
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
y : α ⊕ β
a : α
val✝ : β
⊢ inr val✝ = inl a ↔ ∃ h, getLeft (inr val✝) h = a

Next tactic:
simp
theorem eq_right_iff_getRight_eq {b : β} : x = inr b ↔ ∃ h, x.getRight h = b := by
  

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
x y : α ⊕ β
b : β
⊢ x = inr b ↔ ∃ h, getRight x h = b

Next tactic:
cases x
theorem eq_right_iff_getRight_eq {b : β} : x = inr b ↔ ∃ h, x.getRight h = b := by
  cases x <;> 

Proof state:
case inl
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
y : α ⊕ β
b : β
val✝ : α
⊢ inl val✝ = inr b ↔ ∃ h, getRight (inl val✝) h = b

Next tactic:
simp
theorem eq_right_iff_getRight_eq {b : β} : x = inr b ↔ ∃ h, x.getRight h = b := by
  cases x <;> 

Proof state:
case inr
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
y : α ⊕ β
b val✝ : β
⊢ inr val✝ = inr b ↔ ∃ h, getRight (inr val✝) h = b

Next tactic:
simp
theorem getLeft_eq_getLeft? (h₁ : x.isLeft) (h₂ : x.getLeft?.isSome) :
    x.getLeft h₁ = x.getLeft?.get h₂ := by 

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
x y : α ⊕ β
h₁ : isLeft x = true
h₂ : Option.isSome (getLeft? x) = true
⊢ getLeft x h₁ = Option.get (getLeft? x) h₂

Next tactic:
simp [← getLeft?_eq_some_iff]
theorem getRight_eq_getRight? (h₁ : x.isRight) (h₂ : x.getRight?.isSome) :
    x.getRight h₁ = x.getRight?.get h₂ := by 

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
x y : α ⊕ β
h₁ : isRight x = true
h₂ : Option.isSome (getRight? x) = true
⊢ getRight x h₁ = Option.get (getRight? x) h₂

Next tactic:
simp [← getRight?_eq_some_iff]
@[simp] theorem isSome_getLeft?_iff_isLeft : x.getLeft?.isSome ↔ x.isLeft := by
  

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
x y : α ⊕ β
⊢ Option.isSome (getLeft? x) = true ↔ isLeft x = true

Next tactic:
rw [isLeft_iff, Option.isSome_iff_exists]
@[simp] theorem isSome_getLeft?_iff_isLeft : x.getLeft?.isSome ↔ x.isLeft := by
  rw [isLeft_iff, Option.isSome_iff_exists]; 

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
x y : α ⊕ β
⊢ (∃ a, getLeft? x = some a) ↔ ∃ y, x = inl y

Next tactic:
simp
@[simp] theorem isSome_getRight?_iff_isRight : x.getRight?.isSome ↔ x.isRight := by
  

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
x y : α ⊕ β
⊢ Option.isSome (getRight? x) = true ↔ isRight x = true

Next tactic:
rw [isRight_iff, Option.isSome_iff_exists]
@[simp] theorem isSome_getRight?_iff_isRight : x.getRight?.isSome ↔ x.isRight := by
  rw [isRight_iff, Option.isSome_iff_exists]; 

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
x y : α ⊕ β
⊢ (∃ a, getRight? x = some a) ↔ ∃ y, x = inr y

Next tactic:
simp
@[simp]
theorem update_elim_inl [DecidableEq α] [DecidableEq (Sum α β)] {f : α → γ} {g : β → γ} {i : α}
    {x : γ} : update (Sum.elim f g) (inl i) x = Sum.elim (update f i x) g :=
  update_eq_iff.2 ⟨by 

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq (α ⊕ β)
f : α → γ
g : β → γ
i : α
x : γ
⊢ x = Sum.elim (update f i x) g (inl i)

Next tactic:
simp
@[simp]
theorem update_elim_inl [DecidableEq α] [DecidableEq (Sum α β)] {f : α → γ} {g : β → γ} {i : α}
    {x : γ} : update (Sum.elim f g) (inl i) x = Sum.elim (update f i x) g :=
  update_eq_iff.2 ⟨by simp, by 

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq (α ⊕ β)
f : α → γ
g : β → γ
i : α
x : γ
⊢ ∀ (x_1 : α ⊕ β), x_1 ≠ inl i → Sum.elim f g x_1 = Sum.elim (update f i x) g x_1

Next tactic:
simp (config := { contextual := true })
@[simp]
theorem update_elim_inr [DecidableEq β] [DecidableEq (Sum α β)] {f : α → γ} {g : β → γ} {i : β}
    {x : γ} : update (Sum.elim f g) (inr i) x = Sum.elim f (update g i x) :=
  update_eq_iff.2 ⟨by 

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
inst✝¹ : DecidableEq β
inst✝ : DecidableEq (α ⊕ β)
f : α → γ
g : β → γ
i : β
x : γ
⊢ x = Sum.elim f (update g i x) (inr i)

Next tactic:
simp
@[simp]
theorem update_elim_inr [DecidableEq β] [DecidableEq (Sum α β)] {f : α → γ} {g : β → γ} {i : β}
    {x : γ} : update (Sum.elim f g) (inr i) x = Sum.elim f (update g i x) :=
  update_eq_iff.2 ⟨by simp, by 

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
inst✝¹ : DecidableEq β
inst✝ : DecidableEq (α ⊕ β)
f : α → γ
g : β → γ
i : β
x : γ
⊢ ∀ (x_1 : α ⊕ β), x_1 ≠ inr i → Sum.elim f g x_1 = Sum.elim f (update g i x) x_1

Next tactic:
simp (config := { contextual := true })
@[simp]
theorem update_inl_apply_inl [DecidableEq α] [DecidableEq (Sum α β)] {f : Sum α β → γ} {i j : α}
    {x : γ} : update f (inl i) x (inl j) = update (f ∘ inl) i x j := by
  

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
inst✝¹ : DecidableEq α
inst✝ : DecidableEq (α ⊕ β)
f : α ⊕ β → γ
i j : α
x : γ
⊢ update f (inl i) x (inl j) = update (f ∘ inl) i x j

Next tactic:
rw [← update_inl_comp_inl, Function.comp_apply]
@[simp]
theorem update_inr_apply_inr [DecidableEq β] [DecidableEq (Sum α β)] {f : Sum α β → γ} {i j : β}
    {x : γ} : update f (inr i) x (inr j) = update (f ∘ inr) i x j := by
  

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
inst✝¹ : DecidableEq β
inst✝ : DecidableEq (α ⊕ β)
f : α ⊕ β → γ
i j : β
x : γ
⊢ update f (inr i) x (inr j) = update (f ∘ inr) i x j

Next tactic:
rw [← update_inr_comp_inr, Function.comp_apply]
theorem isLeft_congr (h : LiftRel r s x y) : x.isLeft ↔ y.isLeft := by 

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
r : α → γ → Prop
s : β → δ → Prop
x : α ⊕ β
y : γ ⊕ δ
a : α
b : β
c : γ
d : δ
h : LiftRel r s x y
⊢ isLeft x = true ↔ isLeft y = true

Next tactic:
cases h
theorem isLeft_congr (h : LiftRel r s x y) : x.isLeft ↔ y.isLeft := by cases h <;> 

Proof state:
case inl
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
r : α → γ → Prop
s : β → δ → Prop
a : α
b : β
c : γ
d : δ
a✝¹ : α
c✝ : γ
a✝ : r a✝¹ c✝
⊢ isLeft (inl a✝¹) = true ↔ isLeft (inl c✝) = true

Next tactic:
rfl
theorem isLeft_congr (h : LiftRel r s x y) : x.isLeft ↔ y.isLeft := by cases h <;> 

Proof state:
case inr
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
r : α → γ → Prop
s : β → δ → Prop
a : α
b : β
c : γ
d : δ
b✝ : β
d✝ : δ
a✝ : s b✝ d✝
⊢ isLeft (inr b✝) = true ↔ isLeft (inr d✝) = true

Next tactic:
rfl
theorem isRight_congr (h : LiftRel r s x y) : x.isRight ↔ y.isRight := by 

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
r : α → γ → Prop
s : β → δ → Prop
x : α ⊕ β
y : γ ⊕ δ
a : α
b : β
c : γ
d : δ
h : LiftRel r s x y
⊢ isRight x = true ↔ isRight y = true

Next tactic:
cases h
theorem isRight_congr (h : LiftRel r s x y) : x.isRight ↔ y.isRight := by cases h <;> 

Proof state:
case inl
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
r : α → γ → Prop
s : β → δ → Prop
a : α
b : β
c : γ
d : δ
a✝¹ : α
c✝ : γ
a✝ : r a✝¹ c✝
⊢ isRight (inl a✝¹) = true ↔ isRight (inl c✝) = true

Next tactic:
rfl
theorem isRight_congr (h : LiftRel r s x y) : x.isRight ↔ y.isRight := by cases h <;> 

Proof state:
case inr
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
r : α → γ → Prop
s : β → δ → Prop
a : α
b : β
c : γ
d : δ
b✝ : β
d✝ : δ
a✝ : s b✝ d✝
⊢ isRight (inr b✝) = true ↔ isRight (inr d✝) = true

Next tactic:
rfl
theorem isLeft_left (h : LiftRel r s x (inl c)) : x.isLeft := by 

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
r : α → γ → Prop
s : β → δ → Prop
x : α ⊕ β
y : γ ⊕ δ
a : α
b : β
c : γ
d : δ
h : LiftRel r s x (inl c)
⊢ isLeft x = true

Next tactic:
cases h
theorem isLeft_left (h : LiftRel r s x (inl c)) : x.isLeft := by cases h; 

Proof state:
case inl
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
r : α → γ → Prop
s : β → δ → Prop
y : γ ⊕ δ
a : α
b : β
c : γ
d : δ
a✝¹ : α
a✝ : r a✝¹ c
⊢ isLeft (inl a✝¹) = true

Next tactic:
rfl
theorem isLeft_right (h : LiftRel r s (inl a) y) : y.isLeft := by 

Proof state:
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
r : α → γ → Prop
s : β → δ → Prop
x : α ⊕ β
y : γ ⊕ δ
a : α
b : β
c : γ
d : δ
h : LiftRel r s (inl a) y
⊢ isLeft y = true

Next tactic:
cases h
theorem isLeft_right (h : LiftRel r s (inl a) y) : y.isLeft := by cases h; 

Proof state:
case inl
α : Type u
α' : Type w
β : Type v
β' : Type x
γ : Type u_1
δ : Type u_2
r : α → γ → Prop
s : β → δ → Prop
x : α ⊕ β
a : α
b : β
c : γ
d : δ
c✝ : γ
a✝ : r a c✝
⊢ isLeft (inl c✝) = true

Next tactic:
rfl