l3lab/ntp-mathlib huggingface dataset:
lemma eq_zero_of_toRatCircle_apply_self
    (h : toRatCircle ⟨a, Submodule.mem_span_singleton_self a⟩ = 0) : a = 0 := by
  -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
  erw [toRatCircle, LinearMap.comp_apply, LinearEquiv.coe_toLinearMap,
    equivZModSpanAddOrderOf_apply_self, Submodule.liftQSpanSingleton_apply,
    LinearMap.toSpanSingleton_one, AddCircle.coe_eq_zero_iff] at h
  obtain ⟨n, hn⟩ := h
  apply_fun Rat.den at hn
  rw [zsmul_one, Rat.coe_int_den, Rat.inv_coe_nat_den_of_pos] at hn
  · split_ifs at hn
    · cases hn
    · 

Proof state:
case neg
A : Type u
inst✝ : AddCommGroup A
A_ : AddCommGroupCat
a : ↑A_
n : ℤ
h✝ : ¬addOrderOf a = 0
hn : 1 = addOrderOf a
⊢ a = 0

Next tactic:
rwa [eq_comm, AddMonoid.addOrderOf_eq_one_iff] at hn
lemma eq_zero_of_toRatCircle_apply_self
    (h : toRatCircle ⟨a, Submodule.mem_span_singleton_self a⟩ = 0) : a = 0 := by
  -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
  erw [toRatCircle, LinearMap.comp_apply, LinearEquiv.coe_toLinearMap,
    equivZModSpanAddOrderOf_apply_self, Submodule.liftQSpanSingleton_apply,
    LinearMap.toSpanSingleton_one, AddCircle.coe_eq_zero_iff] at h
  obtain ⟨n, hn⟩ := h
  apply_fun Rat.den at hn
  rw [zsmul_one, Rat.coe_int_den, Rat.inv_coe_nat_den_of_pos] at hn
  · split_ifs at hn
    · cases hn
    · rwa [eq_comm, AddMonoid.addOrderOf_eq_one_iff] at hn
  · 

Proof state:
case intro
A : Type u
inst✝ : AddCommGroup A
A_ : AddCommGroupCat
a : ↑A_
n : ℤ
hn : 1 = (↑(if addOrderOf a = 0 then 2 else addOrderOf a))⁻¹.den
⊢ 0 < if addOrderOf a = 0 then 2 else addOrderOf a

Next tactic:
split_ifs with h
lemma eq_zero_of_toRatCircle_apply_self
    (h : toRatCircle ⟨a, Submodule.mem_span_singleton_self a⟩ = 0) : a = 0 := by
  -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
  erw [toRatCircle, LinearMap.comp_apply, LinearEquiv.coe_toLinearMap,
    equivZModSpanAddOrderOf_apply_self, Submodule.liftQSpanSingleton_apply,
    LinearMap.toSpanSingleton_one, AddCircle.coe_eq_zero_iff] at h
  obtain ⟨n, hn⟩ := h
  apply_fun Rat.den at hn
  rw [zsmul_one, Rat.coe_int_den, Rat.inv_coe_nat_den_of_pos] at hn
  · split_ifs at hn
    · cases hn
    · rwa [eq_comm, AddMonoid.addOrderOf_eq_one_iff] at hn
  · split_ifs with h
    · 

Proof state:
case pos
A : Type u
inst✝ : AddCommGroup A
A_ : AddCommGroupCat
a : ↑A_
n : ℤ
hn : 1 = (↑(if addOrderOf a = 0 then 2 else addOrderOf a))⁻¹.den
h : addOrderOf a = 0
⊢ 0 < 2

Next tactic:
norm_num
lemma eq_zero_of_toRatCircle_apply_self
    (h : toRatCircle ⟨a, Submodule.mem_span_singleton_self a⟩ = 0) : a = 0 := by
  -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
  erw [toRatCircle, LinearMap.comp_apply, LinearEquiv.coe_toLinearMap,
    equivZModSpanAddOrderOf_apply_self, Submodule.liftQSpanSingleton_apply,
    LinearMap.toSpanSingleton_one, AddCircle.coe_eq_zero_iff] at h
  obtain ⟨n, hn⟩ := h
  apply_fun Rat.den at hn
  rw [zsmul_one, Rat.coe_int_den, Rat.inv_coe_nat_den_of_pos] at hn
  · split_ifs at hn
    · cases hn
    · rwa [eq_comm, AddMonoid.addOrderOf_eq_one_iff] at hn
  · split_ifs with h
    · norm_num
    · 

Proof state:
case neg
A : Type u
inst✝ : AddCommGroup A
A_ : AddCommGroupCat
a : ↑A_
n : ℤ
hn : 1 = (↑(if addOrderOf a = 0 then 2 else addOrderOf a))⁻¹.den
h : ¬addOrderOf a = 0
⊢ 0 < addOrderOf a

Next tactic:
exact Nat.pos_of_ne_zero h
theorem HasFDerivAtFilter.comp {g : F → G} {g' : F →L[𝕜] G} {L' : Filter F}
    (hg : HasFDerivAtFilter g g' (f x) L') (hf : HasFDerivAtFilter f f' x L) (hL : Tendsto f L L') :
    HasFDerivAtFilter (g ∘ f) (g'.comp f') x L := by
  

Proof state:
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f f₀ f₁ g✝ : E → F
f' f₀' f₁' g'✝ e : E →L[𝕜] F
x : E
s t : Set E
L L₁ L₂ : Filter E
g : F → G
g' : F →L[𝕜] G
L' : Filter F
hg : HasFDerivAtFilter g g' (f x) L'
hf : HasFDerivAtFilter f f' x L
hL : Tendsto f L L'
⊢ HasFDerivAtFilter (g ∘ f) (ContinuousLinearMap.comp g' f') x L

Next tactic:
let eq₁ := (g'.isBigO_comp _ _).trans_isLittleO hf.isLittleO
theorem HasFDerivAtFilter.comp {g : F → G} {g' : F →L[𝕜] G} {L' : Filter F}
    (hg : HasFDerivAtFilter g g' (f x) L') (hf : HasFDerivAtFilter f f' x L) (hL : Tendsto f L L') :
    HasFDerivAtFilter (g ∘ f) (g'.comp f') x L := by
  let eq₁ := (g'.isBigO_comp _ _).trans_isLittleO hf.isLittleO
  

Proof state:
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f f₀ f₁ g✝ : E → F
f' f₀' f₁' g'✝ e : E →L[𝕜] F
x : E
s t : Set E
L L₁ L₂ : Filter E
g : F → G
g' : F →L[𝕜] G
L' : Filter F
hg : HasFDerivAtFilter g g' (f x) L'
hf : HasFDerivAtFilter f f' x L
hL : Tendsto f L L'
eq₁ : (fun x' => g' (f x' - f x - f' (x' - x))) =o[L] fun x' => x' - x :=
  IsBigO.trans_isLittleO (isBigO_comp g' (fun x' => f x' - f x - f' (x' - x)) L) hf.isLittleO
⊢ HasFDerivAtFilter (g ∘ f) (ContinuousLinearMap.comp g' f') x L

Next tactic:
let eq₂ := (hg.isLittleO.comp_tendsto hL).trans_isBigO hf.isBigO_sub
theorem HasFDerivAtFilter.comp {g : F → G} {g' : F →L[𝕜] G} {L' : Filter F}
    (hg : HasFDerivAtFilter g g' (f x) L') (hf : HasFDerivAtFilter f f' x L) (hL : Tendsto f L L') :
    HasFDerivAtFilter (g ∘ f) (g'.comp f') x L := by
  let eq₁ := (g'.isBigO_comp _ _).trans_isLittleO hf.isLittleO
  let eq₂ := (hg.isLittleO.comp_tendsto hL).trans_isBigO hf.isBigO_sub
  

Proof state:
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f f₀ f₁ g✝ : E → F
f' f₀' f₁' g'✝ e : E →L[𝕜] F
x : E
s t : Set E
L L₁ L₂ : Filter E
g : F → G
g' : F →L[𝕜] G
L' : Filter F
hg : HasFDerivAtFilter g g' (f x) L'
hf : HasFDerivAtFilter f f' x L
hL : Tendsto f L L'
eq₁ : (fun x' => g' (f x' - f x - f' (x' - x))) =o[L] fun x' => x' - x :=
  IsBigO.trans_isLittleO (isBigO_comp g' (fun x' => f x' - f x - f' (x' - x)) L) hf.isLittleO
eq₂ : ((fun x' => g x' - g (f x) - g' (x' - f x)) ∘ f) =o[L] fun x' => x' - x :=
  IsLittleO.trans_isBigO (IsLittleO.comp_tendsto hg.isLittleO hL) (isBigO_sub hf)
⊢ HasFDerivAtFilter (g ∘ f) (ContinuousLinearMap.comp g' f') x L

Next tactic:
refine .of_isLittleO <| eq₂.triangle <| eq₁.congr_left fun x' => ?_
theorem HasFDerivAtFilter.comp {g : F → G} {g' : F →L[𝕜] G} {L' : Filter F}
    (hg : HasFDerivAtFilter g g' (f x) L') (hf : HasFDerivAtFilter f f' x L) (hL : Tendsto f L L') :
    HasFDerivAtFilter (g ∘ f) (g'.comp f') x L := by
  let eq₁ := (g'.isBigO_comp _ _).trans_isLittleO hf.isLittleO
  let eq₂ := (hg.isLittleO.comp_tendsto hL).trans_isBigO hf.isBigO_sub
  refine .of_isLittleO <| eq₂.triangle <| eq₁.congr_left fun x' => ?_
  

Proof state:
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f f₀ f₁ g✝ : E → F
f' f₀' f₁' g'✝ e : E →L[𝕜] F
x : E
s t : Set E
L L₁ L₂ : Filter E
g : F → G
g' : F →L[𝕜] G
L' : Filter F
hg : HasFDerivAtFilter g g' (f x) L'
hf : HasFDerivAtFilter f f' x L
hL : Tendsto f L L'
eq₁ : (fun x' => g' (f x' - f x - f' (x' - x))) =o[L] fun x' => x' - x :=
  IsBigO.trans_isLittleO (isBigO_comp g' (fun x' => f x' - f x - f' (x' - x)) L) hf.isLittleO
eq₂ : ((fun x' => g x' - g (f x) - g' (x' - f x)) ∘ f) =o[L] fun x' => x' - x :=
  IsLittleO.trans_isBigO (IsLittleO.comp_tendsto hg.isLittleO hL) (isBigO_sub hf)
x' : E
⊢ g' (f x' - f x - f' (x' - x)) = g' (f x' - f x) - (ContinuousLinearMap.comp g' f') (x' - x)

Next tactic:
simp
example {g : F → G} {g' : F →L[𝕜] G} (hg : HasFDerivAtFilter g g' (f x) (L.map f))
    (hf : HasFDerivAtFilter f f' x L) : HasFDerivAtFilter (g ∘ f) (g'.comp f') x L := by
  

Proof state:
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f f₀ f₁ g✝ : E → F
f' f₀' f₁' g'✝ e : E →L[𝕜] F
x : E
s t : Set E
L L₁ L₂ : Filter E
g : F → G
g' : F →L[𝕜] G
hg : HasFDerivAtFilter g g' (f x) (map f L)
hf : HasFDerivAtFilter f f' x L
⊢ HasFDerivAtFilter (g ∘ f) (comp g' f') x L

Next tactic:
have :=
    calc
      (fun x' => g (f x') - g (f x) - g' (f x' - f x)) =o[L] fun x' => f x' - f x :=
        hg.isLittleO.comp_tendsto le_rfl
      _ =O[L] fun x' => x' - x := hf.isBigO_sub
example {g : F → G} {g' : F →L[𝕜] G} (hg : HasFDerivAtFilter g g' (f x) (L.map f))
    (hf : HasFDerivAtFilter f f' x L) : HasFDerivAtFilter (g ∘ f) (g'.comp f') x L := by
  have :=
    calc
      (fun x' => g (f x') - g (f x) - g' (f x' - f x)) =o[L] fun x' => f x' - f x :=
        hg.isLittleO.comp_tendsto le_rfl
      _ =O[L] fun x' => x' - x := hf.isBigO_sub
  

Proof state:
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f f₀ f₁ g✝ : E → F
f' f₀' f₁' g'✝ e : E →L[𝕜] F
x : E
s t : Set E
L L₁ L₂ : Filter E
g : F → G
g' : F →L[𝕜] G
hg : HasFDerivAtFilter g g' (f x) (map f L)
hf : HasFDerivAtFilter f f' x L
this : (fun x' => g (f x') - g (f x) - g' (f x' - f x)) =o[L] fun x' => x' - x
⊢ HasFDerivAtFilter (g ∘ f) (comp g' f') x L

Next tactic:
refine' .of_isLittleO <| this.triangle _
example {g : F → G} {g' : F →L[𝕜] G} (hg : HasFDerivAtFilter g g' (f x) (L.map f))
    (hf : HasFDerivAtFilter f f' x L) : HasFDerivAtFilter (g ∘ f) (g'.comp f') x L := by
  have :=
    calc
      (fun x' => g (f x') - g (f x) - g' (f x' - f x)) =o[L] fun x' => f x' - f x :=
        hg.isLittleO.comp_tendsto le_rfl
      _ =O[L] fun x' => x' - x := hf.isBigO_sub
  refine' .of_isLittleO <| this.triangle _
  

Proof state:
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f f₀ f₁ g✝ : E → F
f' f₀' f₁' g'✝ e : E →L[𝕜] F
x : E
s t : Set E
L L₁ L₂ : Filter E
g : F → G
g' : F →L[𝕜] G
hg : HasFDerivAtFilter g g' (f x) (map f L)
hf : HasFDerivAtFilter f f' x L
this : (fun x' => g (f x') - g (f x) - g' (f x' - f x)) =o[L] fun x' => x' - x
⊢ (fun x_1 => g' (f x_1 - f x) - (comp g' f') (x_1 - x)) =o[L] fun x' => x' - x

Next tactic:
calc
    (fun x' : E => g' (f x' - f x) - g'.comp f' (x' - x))
    _ =ᶠ[L] fun x' => g' (f x' - f x - f' (x' - x)) := eventually_of_forall fun x' => by simp
    _ =O[L] fun x' => f x' - f x - f' (x' - x) := (g'.isBigO_comp _ _)
    _ =o[L] fun x' => x' - x := hf.isLittleO
example {g : F → G} {g' : F →L[𝕜] G} (hg : HasFDerivAtFilter g g' (f x) (L.map f))
    (hf : HasFDerivAtFilter f f' x L) : HasFDerivAtFilter (g ∘ f) (g'.comp f') x L := by
  have :=
    calc
      (fun x' => g (f x') - g (f x) - g' (f x' - f x)) =o[L] fun x' => f x' - f x :=
        hg.isLittleO.comp_tendsto le_rfl
      _ =O[L] fun x' => x' - x := hf.isBigO_sub
  refine' .of_isLittleO <| this.triangle _
  calc
    (fun x' : E => g' (f x' - f x) - g'.comp f' (x' - x))
    _ =ᶠ[L] fun x' => g' (f x' - f x - f' (x' - x)) := eventually_of_forall fun x' => by 

Proof state:
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f f₀ f₁ g✝ : E → F
f' f₀' f₁' g'✝ e : E →L[𝕜] F
x : E
s t : Set E
L L₁ L₂ : Filter E
g : F → G
g' : F →L[𝕜] G
hg : HasFDerivAtFilter g g' (f x) (map f L)
hf : HasFDerivAtFilter f f' x L
this : (fun x' => g (f x') - g (f x) - g' (f x' - f x)) =o[L] fun x' => x' - x
x' : E
⊢ (fun x' => g' (f x' - f x) - (comp g' f') (x' - x)) x' = (fun x' => g' (f x' - f x - f' (x' - x))) x'

Next tactic:
simp
/-- A version of `fderivWithin.comp` that is useful to rewrite the composition of two derivatives
  into a single derivative. This version always applies, but creates a new side-goal `f x = y`. -/
theorem fderivWithin_fderivWithin {g : F → G} {f : E → F} {x : E} {y : F} {s : Set E} {t : Set F}
    (hg : DifferentiableWithinAt 𝕜 g t y) (hf : DifferentiableWithinAt 𝕜 f s x) (h : MapsTo f s t)
    (hxs : UniqueDiffWithinAt 𝕜 s x) (hy : f x = y) (v : E) :
    fderivWithin 𝕜 g t y (fderivWithin 𝕜 f s x v) = fderivWithin 𝕜 (g ∘ f) s x v := by
  

Proof state:
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f✝ f₀ f₁ g✝ : E → F
f' f₀' f₁' g' e : E →L[𝕜] F
x✝ : E
s✝ t✝ : Set E
L L₁ L₂ : Filter E
g : F → G
f : E → F
x : E
y : F
s : Set E
t : Set F
hg : DifferentiableWithinAt 𝕜 g t y
hf : DifferentiableWithinAt 𝕜 f s x
h : MapsTo f s t
hxs : UniqueDiffWithinAt 𝕜 s x
hy : f x = y
v : E
⊢ (fderivWithin 𝕜 g t y) ((fderivWithin 𝕜 f s x) v) = (fderivWithin 𝕜 (g ∘ f) s x) v

Next tactic:
subst y
/-- A version of `fderivWithin.comp` that is useful to rewrite the composition of two derivatives
  into a single derivative. This version always applies, but creates a new side-goal `f x = y`. -/
theorem fderivWithin_fderivWithin {g : F → G} {f : E → F} {x : E} {y : F} {s : Set E} {t : Set F}
    (hg : DifferentiableWithinAt 𝕜 g t y) (hf : DifferentiableWithinAt 𝕜 f s x) (h : MapsTo f s t)
    (hxs : UniqueDiffWithinAt 𝕜 s x) (hy : f x = y) (v : E) :
    fderivWithin 𝕜 g t y (fderivWithin 𝕜 f s x v) = fderivWithin 𝕜 (g ∘ f) s x v := by
  subst y
  

Proof state:
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f✝ f₀ f₁ g✝ : E → F
f' f₀' f₁' g' e : E →L[𝕜] F
x✝ : E
s✝ t✝ : Set E
L L₁ L₂ : Filter E
g : F → G
f : E → F
x : E
s : Set E
t : Set F
hf : DifferentiableWithinAt 𝕜 f s x
h : MapsTo f s t
hxs : UniqueDiffWithinAt 𝕜 s x
v : E
hg : DifferentiableWithinAt 𝕜 g t (f x)
⊢ (fderivWithin 𝕜 g t (f x)) ((fderivWithin 𝕜 f s x) v) = (fderivWithin 𝕜 (g ∘ f) s x) v

Next tactic:
rw [fderivWithin.comp x hg hf h hxs, coe_comp', Function.comp_apply]
/-- Ternary version of `fderivWithin.comp`, with equality assumptions of basepoints added, in
  order to apply more easily as a rewrite from right-to-left. -/
theorem fderivWithin.comp₃ {g' : G → G'} {g : F → G} {t : Set F} {u : Set G} {y : F} {y' : G}
    (hg' : DifferentiableWithinAt 𝕜 g' u y') (hg : DifferentiableWithinAt 𝕜 g t y)
    (hf : DifferentiableWithinAt 𝕜 f s x) (h2g : MapsTo g t u) (h2f : MapsTo f s t) (h3g : g y = y')
    (h3f : f x = y) (hxs : UniqueDiffWithinAt 𝕜 s x) :
    fderivWithin 𝕜 (g' ∘ g ∘ f) s x =
      (fderivWithin 𝕜 g' u y').comp ((fderivWithin 𝕜 g t y).comp (fderivWithin 𝕜 f s x)) := by
  

Proof state:
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f f₀ f₁ g✝ : E → F
f' f₀' f₁' g'✝ e : E →L[𝕜] F
x : E
s t✝ : Set E
L L₁ L₂ : Filter E
g' : G → G'
g : F → G
t : Set F
u : Set G
y : F
y' : G
hg' : DifferentiableWithinAt 𝕜 g' u y'
hg : DifferentiableWithinAt 𝕜 g t y
hf : DifferentiableWithinAt 𝕜 f s x
h2g : MapsTo g t u
h2f : MapsTo f s t
h3g : g y = y'
h3f : f x = y
hxs : UniqueDiffWithinAt 𝕜 s x
⊢ fderivWithin 𝕜 (g' ∘ g ∘ f) s x =
    ContinuousLinearMap.comp (fderivWithin 𝕜 g' u y')
      (ContinuousLinearMap.comp (fderivWithin 𝕜 g t y) (fderivWithin 𝕜 f s x))

Next tactic:
substs h3g h3f
/-- Ternary version of `fderivWithin.comp`, with equality assumptions of basepoints added, in
  order to apply more easily as a rewrite from right-to-left. -/
theorem fderivWithin.comp₃ {g' : G → G'} {g : F → G} {t : Set F} {u : Set G} {y : F} {y' : G}
    (hg' : DifferentiableWithinAt 𝕜 g' u y') (hg : DifferentiableWithinAt 𝕜 g t y)
    (hf : DifferentiableWithinAt 𝕜 f s x) (h2g : MapsTo g t u) (h2f : MapsTo f s t) (h3g : g y = y')
    (h3f : f x = y) (hxs : UniqueDiffWithinAt 𝕜 s x) :
    fderivWithin 𝕜 (g' ∘ g ∘ f) s x =
      (fderivWithin 𝕜 g' u y').comp ((fderivWithin 𝕜 g t y).comp (fderivWithin 𝕜 f s x)) := by
  substs h3g h3f
  

Proof state:
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f f₀ f₁ g✝ : E → F
f' f₀' f₁' g'✝ e : E →L[𝕜] F
x : E
s t✝ : Set E
L L₁ L₂ : Filter E
g' : G → G'
g : F → G
t : Set F
u : Set G
hf : DifferentiableWithinAt 𝕜 f s x
h2g : MapsTo g t u
h2f : MapsTo f s t
hxs : UniqueDiffWithinAt 𝕜 s x
hg : DifferentiableWithinAt 𝕜 g t (f x)
hg' : DifferentiableWithinAt 𝕜 g' u (g (f x))
⊢ fderivWithin 𝕜 (g' ∘ g ∘ f) s x =
    ContinuousLinearMap.comp (fderivWithin 𝕜 g' u (g (f x)))
      (ContinuousLinearMap.comp (fderivWithin 𝕜 g t (f x)) (fderivWithin 𝕜 f s x))

Next tactic:
exact (hg'.hasFDerivWithinAt.comp x (hg.hasFDerivWithinAt.comp x hf.hasFDerivWithinAt h2f) <|
    h2g.comp h2f).fderivWithin hxs
/-- The chain rule for derivatives in the sense of strict differentiability. -/
protected theorem HasStrictFDerivAt.comp {g : F → G} {g' : F →L[𝕜] G}
    (hg : HasStrictFDerivAt g g' (f x)) (hf : HasStrictFDerivAt f f' x) :
    HasStrictFDerivAt (fun x => g (f x)) (g'.comp f') x :=
  ((hg.comp_tendsto (hf.continuousAt.prod_map' hf.continuousAt)).trans_isBigO
      hf.isBigO_sub).triangle <| by
    

Proof state:
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f f₀ f₁ g✝ : E → F
f' f₀' f₁' g'✝ e : E →L[𝕜] F
x : E
s t : Set E
L L₁ L₂ : Filter E
g : F → G
g' : F →L[𝕜] G
hg : HasStrictFDerivAt g g' (f x)
hf : HasStrictFDerivAt f f' x
⊢ (fun x =>
      g' (((fun p => (f p.1, f p.2)) x).1 - ((fun p => (f p.1, f p.2)) x).2) - (comp g' f') (x.1 - x.2)) =o[𝓝 (x, x)]
    fun p => p.1 - p.2

Next tactic:
simpa only [g'.map_sub, f'.coe_comp'] using (g'.isBigO_comp _ _).trans_isLittleO hf
protected theorem HasFDerivAtFilter.iterate {f : E → E} {f' : E →L[𝕜] E}
    (hf : HasFDerivAtFilter f f' x L) (hL : Tendsto f L L) (hx : f x = x) (n : ℕ) :
    HasFDerivAtFilter f^[n] (f' ^ n) x L := by
  

Proof state:
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f✝ f₀ f₁ g : E → F
f'✝ f₀' f₁' g' e : E →L[𝕜] F
x : E
s t : Set E
L L₁ L₂ : Filter E
f : E → E
f' : E →L[𝕜] E
hf : HasFDerivAtFilter f f' x L
hL : Tendsto f L L
hx : f x = x
n : ℕ
⊢ HasFDerivAtFilter f^[n] (f' ^ n) x L

Next tactic:
induction' n with n ihn
protected theorem HasFDerivAtFilter.iterate {f : E → E} {f' : E →L[𝕜] E}
    (hf : HasFDerivAtFilter f f' x L) (hL : Tendsto f L L) (hx : f x = x) (n : ℕ) :
    HasFDerivAtFilter f^[n] (f' ^ n) x L := by
  induction' n with n ihn
  · 

Proof state:
case zero
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f✝ f₀ f₁ g : E → F
f'✝ f₀' f₁' g' e : E →L[𝕜] F
x : E
s t : Set E
L L₁ L₂ : Filter E
f : E → E
f' : E →L[𝕜] E
hf : HasFDerivAtFilter f f' x L
hL : Tendsto f L L
hx : f x = x
⊢ HasFDerivAtFilter f^[Nat.zero] (f' ^ Nat.zero) x L

Next tactic:
exact hasFDerivAtFilter_id x L
protected theorem HasFDerivAtFilter.iterate {f : E → E} {f' : E →L[𝕜] E}
    (hf : HasFDerivAtFilter f f' x L) (hL : Tendsto f L L) (hx : f x = x) (n : ℕ) :
    HasFDerivAtFilter f^[n] (f' ^ n) x L := by
  induction' n with n ihn
  · exact hasFDerivAtFilter_id x L
  · 

Proof state:
case succ
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f✝ f₀ f₁ g : E → F
f'✝ f₀' f₁' g' e : E →L[𝕜] F
x : E
s t : Set E
L L₁ L₂ : Filter E
f : E → E
f' : E →L[𝕜] E
hf : HasFDerivAtFilter f f' x L
hL : Tendsto f L L
hx : f x = x
n : ℕ
ihn : HasFDerivAtFilter f^[n] (f' ^ n) x L
⊢ HasFDerivAtFilter f^[Nat.succ n] (f' ^ Nat.succ n) x L

Next tactic:
rw [Function.iterate_succ, pow_succ']
protected theorem HasFDerivAtFilter.iterate {f : E → E} {f' : E →L[𝕜] E}
    (hf : HasFDerivAtFilter f f' x L) (hL : Tendsto f L L) (hx : f x = x) (n : ℕ) :
    HasFDerivAtFilter f^[n] (f' ^ n) x L := by
  induction' n with n ihn
  · exact hasFDerivAtFilter_id x L
  · rw [Function.iterate_succ, pow_succ']
    

Proof state:
case succ
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f✝ f₀ f₁ g : E → F
f'✝ f₀' f₁' g' e : E →L[𝕜] F
x : E
s t : Set E
L L₁ L₂ : Filter E
f : E → E
f' : E →L[𝕜] E
hf : HasFDerivAtFilter f f' x L
hL : Tendsto f L L
hx : f x = x
n : ℕ
ihn : HasFDerivAtFilter f^[n] (f' ^ n) x L
⊢ HasFDerivAtFilter (f^[n] ∘ f) (f' ^ n * f') x L

Next tactic:
rw [← hx] at ihn
protected theorem HasFDerivAtFilter.iterate {f : E → E} {f' : E →L[𝕜] E}
    (hf : HasFDerivAtFilter f f' x L) (hL : Tendsto f L L) (hx : f x = x) (n : ℕ) :
    HasFDerivAtFilter f^[n] (f' ^ n) x L := by
  induction' n with n ihn
  · exact hasFDerivAtFilter_id x L
  · rw [Function.iterate_succ, pow_succ']
    rw [← hx] at ihn
    

Proof state:
case succ
𝕜 : Type u_1
inst✝⁸ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝⁷ : NormedAddCommGroup E
inst✝⁶ : NormedSpace 𝕜 E
F : Type u_3
inst✝⁵ : NormedAddCommGroup F
inst✝⁴ : NormedSpace 𝕜 F
G : Type u_4
inst✝³ : NormedAddCommGroup G
inst✝² : NormedSpace 𝕜 G
G' : Type u_5
inst✝¹ : NormedAddCommGroup G'
inst✝ : NormedSpace 𝕜 G'
f✝ f₀ f₁ g : E → F
f'✝ f₀' f₁' g' e : E →L[𝕜] F
x : E
s t : Set E
L L₁ L₂ : Filter E
f : E → E
f' : E →L[𝕜] E
hf : HasFDerivAtFilter f f' x L
hL : Tendsto f L L
hx : f x = x
n : ℕ
ihn : HasFDerivAtFilter f^[n] (f' ^ n) (f x) L
⊢ HasFDerivAtFilter (f^[n] ∘ f) (f' ^ n * f') x L

Next tactic:
exact ihn.comp x hf hL