l3lab/ntp-mathlib huggingface dataset:
/-- `MulOpposite` distributes over `TensorProduct`. Note this is an `S`-algebra morphism, where
`A/S/R` is a tower of algebras. -/
def opAlgEquiv : Aᵐᵒᵖ ⊗[R] Bᵐᵒᵖ ≃ₐ[S] (A ⊗[R] B)ᵐᵒᵖ :=
  letI e₁ : Aᵐᵒᵖ ⊗[R] Bᵐᵒᵖ ≃ₗ[S] (A ⊗[R] B)ᵐᵒᵖ :=
    TensorProduct.AlgebraTensorModule.congr
      (opLinearEquiv S).symm (opLinearEquiv R).symm ≪≫ₗ opLinearEquiv S
  letI e₂ : A ⊗[R] B ≃ₗ[S] (Aᵐᵒᵖ ⊗[R] Bᵐᵒᵖ)ᵐᵒᵖ :=
    TensorProduct.AlgebraTensorModule.congr (opLinearEquiv S) (opLinearEquiv R) ≪≫ₗ opLinearEquiv S
  AlgEquiv.ofAlgHom
    (algHomOfLinearMapTensorProduct e₁.toLinearMap
      (fun a₁ a₂ b₁ b₂ => unop_injective rfl) (unop_injective rfl))
    (AlgHom.opComm <| algHomOfLinearMapTensorProduct e₂.toLinearMap
      (fun a₁ a₂ b₁ b₂ => unop_injective rfl) (unop_injective rfl))
    (AlgHom.op.symm.injective <| by ext <;> rfl) (by ext <;> 

Proof state:
case hb.H
R : Type u_1
S : Type u_2
A : Type u_3
B : Type u_4
inst✝⁸ : CommSemiring R
inst✝⁷ : CommSemiring S
inst✝⁶ : Semiring A
inst✝⁵ : Semiring B
inst✝⁴ : Algebra R S
inst✝³ : Algebra R A
inst✝² : Algebra R B
inst✝¹ : Algebra S A
inst✝ : IsScalarTower R S A
e₁ : Aᵐᵒᵖ ⊗[R] Bᵐᵒᵖ ≃ₗ[S] (A ⊗[R] B)ᵐᵒᵖ :=
  TensorProduct.AlgebraTensorModule.congr (LinearEquiv.symm (opLinearEquiv S)) (LinearEquiv.symm (opLinearEquiv R)) ≪≫ₗ
    opLinearEquiv S
e₂ : A ⊗[R] B ≃ₗ[S] (Aᵐᵒᵖ ⊗[R] Bᵐᵒᵖ)ᵐᵒᵖ :=
  TensorProduct.AlgebraTensorModule.congr (opLinearEquiv S) (opLinearEquiv R) ≪≫ₗ opLinearEquiv S
x✝ : Bᵐᵒᵖ
⊢ (AlgHom.comp
        (AlgHom.restrictScalars R
          (AlgHom.comp
            (AlgHom.opComm
              (algHomOfLinearMapTensorProduct ↑e₂
                (_ : ∀ (a₁ a₂ : A) (b₁ b₂ : B), ↑e₂ ((a₁ * a₂) ⊗ₜ[R] (b₁ * b₂)) = ↑e₂ (a₁ ⊗ₜ[R] b₁) * ↑e₂ (a₂ ⊗ₜ[R] b₂))
                (_ : ↑e₂ (1 ⊗ₜ[R] 1) = 1)))
            (algHomOfLinearMapTensorProduct ↑e₁
              (_ :
                ∀ (a₁ a₂ : Aᵐᵒᵖ) (b₁ b₂ : Bᵐᵒᵖ),
                  ↑e₁ ((a₁ * a₂) ⊗ₜ[R] (b₁ * b₂)) = ↑e₁ (a₁ ⊗ₜ[R] b₁) * ↑e₁ (a₂ ⊗ₜ[R] b₂))
              (_ : ↑e₁ (1 ⊗ₜ[R] 1) = 1))))
        includeRight)
      x✝ =
    (AlgHom.comp (AlgHom.restrictScalars R (AlgHom.id S (Aᵐᵒᵖ ⊗[R] Bᵐᵒᵖ))) includeRight) x✝

Next tactic:
rfl
theorem hasFDerivWithinAt_iff_hasGradientWithinAt {frechet : F →L[𝕜] 𝕜} {s : Set F} :
    HasFDerivWithinAt f frechet s x ↔ HasGradientWithinAt f ((toDual 𝕜 F).symm frechet) s x := by
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s✝ : Set F
L : Filter F
frechet : F →L[𝕜] 𝕜
s : Set F
⊢ HasFDerivWithinAt f frechet s x ↔ HasGradientWithinAt f ((LinearIsometryEquiv.symm (toDual 𝕜 F)) frechet) s x

Next tactic:
rw [hasGradientWithinAt_iff_hasFDerivWithinAt, (toDual 𝕜 F).apply_symm_apply frechet]
theorem hasFDerivAt_iff_hasGradientAt {frechet : F →L[𝕜] 𝕜} :
    HasFDerivAt f frechet x ↔ HasGradientAt f ((toDual 𝕜 F).symm frechet) x := by
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
frechet : F →L[𝕜] 𝕜
⊢ HasFDerivAt f frechet x ↔ HasGradientAt f ((LinearIsometryEquiv.symm (toDual 𝕜 F)) frechet) x

Next tactic:
rw [hasGradientAt_iff_hasFDerivAt, (toDual 𝕜 F).apply_symm_apply frechet]
theorem gradient_eq_zero_of_not_differentiableAt (h : ¬DifferentiableAt 𝕜 f x) : ∇ f x = 0 := by
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
h : ¬DifferentiableAt 𝕜 f x
⊢ ∇ f x = 0

Next tactic:
rw [gradient, fderiv_zero_of_not_differentiableAt h, map_zero]
theorem DifferentiableAt.hasGradientAt (h : DifferentiableAt 𝕜 f x) :
    HasGradientAt f (∇ f x) x := by
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
h : DifferentiableAt 𝕜 f x
⊢ HasGradientAt f (∇ f x) x

Next tactic:
rw [hasGradientAt_iff_hasFDerivAt, gradient, (toDual 𝕜 F).apply_symm_apply (fderiv 𝕜 f x)]
theorem DifferentiableAt.hasGradientAt (h : DifferentiableAt 𝕜 f x) :
    HasGradientAt f (∇ f x) x := by
  rw [hasGradientAt_iff_hasFDerivAt, gradient, (toDual 𝕜 F).apply_symm_apply (fderiv 𝕜 f x)]
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
h : DifferentiableAt 𝕜 f x
⊢ HasFDerivAt f (fderiv 𝕜 f x) x

Next tactic:
exact h.hasFDerivAt
theorem DifferentiableWithinAt.hasGradientWithinAt (h : DifferentiableWithinAt 𝕜 f s x) :
    HasGradientWithinAt f (gradientWithin f s x) s x := by
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
h : DifferentiableWithinAt 𝕜 f s x
⊢ HasGradientWithinAt f (gradientWithin f s x) s x

Next tactic:
rw [hasGradientWithinAt_iff_hasFDerivWithinAt, gradientWithin,
    (toDual 𝕜 F).apply_symm_apply (fderivWithin 𝕜 f s x)]
theorem DifferentiableWithinAt.hasGradientWithinAt (h : DifferentiableWithinAt 𝕜 f s x) :
    HasGradientWithinAt f (gradientWithin f s x) s x := by
  rw [hasGradientWithinAt_iff_hasFDerivWithinAt, gradientWithin,
    (toDual 𝕜 F).apply_symm_apply (fderivWithin 𝕜 f s x)]
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
h : DifferentiableWithinAt 𝕜 f s x
⊢ HasFDerivWithinAt f (fderivWithin 𝕜 f s x) s x

Next tactic:
exact h.hasFDerivWithinAt
@[simp]
theorem hasGradientWithinAt_univ : HasGradientWithinAt f f' univ x ↔ HasGradientAt f f' x := by
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
⊢ HasGradientWithinAt f f' univ x ↔ HasGradientAt f f' x

Next tactic:
rw [hasGradientWithinAt_iff_hasFDerivWithinAt, hasGradientAt_iff_hasFDerivAt]
@[simp]
theorem hasGradientWithinAt_univ : HasGradientWithinAt f f' univ x ↔ HasGradientAt f f' x := by
  rw [hasGradientWithinAt_iff_hasFDerivWithinAt, hasGradientAt_iff_hasFDerivAt]
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
⊢ HasFDerivWithinAt f ((toDual 𝕜 F) f') univ x ↔ HasFDerivAt f ((toDual 𝕜 F) f') x

Next tactic:
exact hasFDerivWithinAt_univ
theorem HasGradientAtFilter.hasDerivAtFilter (h : HasGradientAtFilter g g' u L') :
    HasDerivAtFilter g (starRingEnd 𝕜 g') u L' := by
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
g : 𝕜 → 𝕜
g' u : 𝕜
L' : Filter 𝕜
h : HasGradientAtFilter g g' u L'
⊢ HasDerivAtFilter g ((starRingEnd 𝕜) g') u L'

Next tactic:
have : ContinuousLinearMap.smulRight (1 : 𝕜 →L[𝕜] 𝕜) (starRingEnd 𝕜 g') = (toDual 𝕜 𝕜) g'
theorem HasGradientAtFilter.hasDerivAtFilter (h : HasGradientAtFilter g g' u L') :
    HasDerivAtFilter g (starRingEnd 𝕜 g') u L' := by
  have : ContinuousLinearMap.smulRight (1 : 𝕜 →L[𝕜] 𝕜) (starRingEnd 𝕜 g') = (toDual 𝕜 𝕜) g'
  · 

Proof state:
case this
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
g : 𝕜 → 𝕜
g' u : 𝕜
L' : Filter 𝕜
h : HasGradientAtFilter g g' u L'
⊢ ContinuousLinearMap.smulRight 1 ((starRingEnd 𝕜) g') = (toDual 𝕜 𝕜) g'

Next tactic:
ext
theorem HasGradientAtFilter.hasDerivAtFilter (h : HasGradientAtFilter g g' u L') :
    HasDerivAtFilter g (starRingEnd 𝕜 g') u L' := by
  have : ContinuousLinearMap.smulRight (1 : 𝕜 →L[𝕜] 𝕜) (starRingEnd 𝕜 g') = (toDual 𝕜 𝕜) g'
  · ext; 

Proof state:
case this.h
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
g : 𝕜 → 𝕜
g' u : 𝕜
L' : Filter 𝕜
h : HasGradientAtFilter g g' u L'
⊢ (ContinuousLinearMap.smulRight 1 ((starRingEnd 𝕜) g')) 1 = ((toDual 𝕜 𝕜) g') 1

Next tactic:
simp
theorem HasGradientAtFilter.hasDerivAtFilter (h : HasGradientAtFilter g g' u L') :
    HasDerivAtFilter g (starRingEnd 𝕜 g') u L' := by
  have : ContinuousLinearMap.smulRight (1 : 𝕜 →L[𝕜] 𝕜) (starRingEnd 𝕜 g') = (toDual 𝕜 𝕜) g'
  · ext; simp
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
g : 𝕜 → 𝕜
g' u : 𝕜
L' : Filter 𝕜
h : HasGradientAtFilter g g' u L'
this : ContinuousLinearMap.smulRight 1 ((starRingEnd 𝕜) g') = (toDual 𝕜 𝕜) g'
⊢ HasDerivAtFilter g ((starRingEnd 𝕜) g') u L'

Next tactic:
rwa [HasDerivAtFilter, this]
theorem HasDerivAtFilter.hasGradientAtFilter (h : HasDerivAtFilter g g' u L') :
    HasGradientAtFilter g (starRingEnd 𝕜 g') u L' := by
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
g : 𝕜 → 𝕜
g' u : 𝕜
L' : Filter 𝕜
h : HasDerivAtFilter g g' u L'
⊢ HasGradientAtFilter g ((starRingEnd 𝕜) g') u L'

Next tactic:
have : ContinuousLinearMap.smulRight (1 : 𝕜 →L[𝕜] 𝕜) g' = (toDual 𝕜 𝕜) (starRingEnd 𝕜 g')
theorem HasDerivAtFilter.hasGradientAtFilter (h : HasDerivAtFilter g g' u L') :
    HasGradientAtFilter g (starRingEnd 𝕜 g') u L' := by
  have : ContinuousLinearMap.smulRight (1 : 𝕜 →L[𝕜] 𝕜) g' = (toDual 𝕜 𝕜) (starRingEnd 𝕜 g')
  · 

Proof state:
case this
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
g : 𝕜 → 𝕜
g' u : 𝕜
L' : Filter 𝕜
h : HasDerivAtFilter g g' u L'
⊢ ContinuousLinearMap.smulRight 1 g' = (toDual 𝕜 𝕜) ((starRingEnd 𝕜) g')

Next tactic:
ext
theorem HasDerivAtFilter.hasGradientAtFilter (h : HasDerivAtFilter g g' u L') :
    HasGradientAtFilter g (starRingEnd 𝕜 g') u L' := by
  have : ContinuousLinearMap.smulRight (1 : 𝕜 →L[𝕜] 𝕜) g' = (toDual 𝕜 𝕜) (starRingEnd 𝕜 g')
  · ext; 

Proof state:
case this.h
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
g : 𝕜 → 𝕜
g' u : 𝕜
L' : Filter 𝕜
h : HasDerivAtFilter g g' u L'
⊢ (ContinuousLinearMap.smulRight 1 g') 1 = ((toDual 𝕜 𝕜) ((starRingEnd 𝕜) g')) 1

Next tactic:
simp
theorem HasDerivAtFilter.hasGradientAtFilter (h : HasDerivAtFilter g g' u L') :
    HasGradientAtFilter g (starRingEnd 𝕜 g') u L' := by
  have : ContinuousLinearMap.smulRight (1 : 𝕜 →L[𝕜] 𝕜) g' = (toDual 𝕜 𝕜) (starRingEnd 𝕜 g')
  · ext; simp
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
g : 𝕜 → 𝕜
g' u : 𝕜
L' : Filter 𝕜
h : HasDerivAtFilter g g' u L'
this : ContinuousLinearMap.smulRight 1 g' = (toDual 𝕜 𝕜) ((starRingEnd 𝕜) g')
⊢ HasGradientAtFilter g ((starRingEnd 𝕜) g') u L'

Next tactic:
rwa [HasGradientAtFilter, ← this]
theorem HasGradientAt.hasDerivAt (h : HasGradientAt g g' u) :
    HasDerivAt g (starRingEnd 𝕜 g') u := by
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
g : 𝕜 → 𝕜
g' u : 𝕜
L' : Filter 𝕜
h : HasGradientAt g g' u
⊢ HasDerivAt g ((starRingEnd 𝕜) g') u

Next tactic:
rw [hasGradientAt_iff_hasFDerivAt, hasFDerivAt_iff_hasDerivAt] at h
theorem HasGradientAt.hasDerivAt (h : HasGradientAt g g' u) :
    HasDerivAt g (starRingEnd 𝕜 g') u := by
  rw [hasGradientAt_iff_hasFDerivAt, hasFDerivAt_iff_hasDerivAt] at h
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
g : 𝕜 → 𝕜
g' u : 𝕜
L' : Filter 𝕜
h : HasDerivAt g (((toDual 𝕜 𝕜) g') 1) u
⊢ HasDerivAt g ((starRingEnd 𝕜) g') u

Next tactic:
simpa using h
theorem HasDerivAt.hasGradientAt (h : HasDerivAt g g' u) :
    HasGradientAt g (starRingEnd 𝕜 g') u := by
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
g : 𝕜 → 𝕜
g' u : 𝕜
L' : Filter 𝕜
h : HasDerivAt g g' u
⊢ HasGradientAt g ((starRingEnd 𝕜) g') u

Next tactic:
rw [hasGradientAt_iff_hasFDerivAt, hasFDerivAt_iff_hasDerivAt]
theorem HasDerivAt.hasGradientAt (h : HasDerivAt g g' u) :
    HasGradientAt g (starRingEnd 𝕜 g') u := by
  rw [hasGradientAt_iff_hasFDerivAt, hasFDerivAt_iff_hasDerivAt]
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
g : 𝕜 → 𝕜
g' u : 𝕜
L' : Filter 𝕜
h : HasDerivAt g g' u
⊢ HasDerivAt g (((toDual 𝕜 𝕜) ((starRingEnd 𝕜) g')) 1) u

Next tactic:
simpa
theorem gradient_eq_deriv : ∇ g u = starRingEnd 𝕜 (deriv g u) := by
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
g : 𝕜 → 𝕜
g' u : 𝕜
L' : Filter 𝕜
⊢ ∇ g u = (starRingEnd 𝕜) (deriv g u)

Next tactic:
by_cases h : DifferentiableAt 𝕜 g u
theorem gradient_eq_deriv : ∇ g u = starRingEnd 𝕜 (deriv g u) := by
  by_cases h : DifferentiableAt 𝕜 g u
  · 

Proof state:
case pos
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
g : 𝕜 → 𝕜
g' u : 𝕜
L' : Filter 𝕜
h : DifferentiableAt 𝕜 g u
⊢ ∇ g u = (starRingEnd 𝕜) (deriv g u)

Next tactic:
rw [h.hasGradientAt.hasDerivAt.deriv, IsROrC.conj_conj]
theorem gradient_eq_deriv : ∇ g u = starRingEnd 𝕜 (deriv g u) := by
  by_cases h : DifferentiableAt 𝕜 g u
  · rw [h.hasGradientAt.hasDerivAt.deriv, IsROrC.conj_conj]
  · 

Proof state:
case neg
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
g : 𝕜 → 𝕜
g' u : 𝕜
L' : Filter 𝕜
h : ¬DifferentiableAt 𝕜 g u
⊢ ∇ g u = (starRingEnd 𝕜) (deriv g u)

Next tactic:
rw [gradient_eq_zero_of_not_differentiableAt h, deriv_zero_of_not_differentiableAt h, map_zero]
theorem Filter.EventuallyEq.hasGradientAtFilter_iff (h₀ : f₀ =ᶠ[L] f₁) (hx : f₀ x = f₁ x)
    (h₁ : f₀' = f₁') : HasGradientAtFilter f₀ f₀' x L ↔ HasGradientAtFilter f₁ f₁' x L :=
  h₀.hasFDerivAtFilter_iff hx (by 

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
f₀ f₁ : F → 𝕜
f₀' f₁' x₀ x₁ : F
s₀ s₁ t : Set F
L₀ L₁ : Filter F
h₀ : f₀ =ᶠ[L] f₁
hx : f₀ x = f₁ x
h₁ : f₀' = f₁'
⊢ ∀ (x : F), ((toDual 𝕜 F) f₀') x = ((toDual 𝕜 F) f₁') x

Next tactic:
simp [h₁]
theorem HasGradientAtFilter.congr_of_eventuallyEq (h : HasGradientAtFilter f f' x L)
    (hL : f₁ =ᶠ[L] f) (hx : f₁ x = f x) : HasGradientAtFilter f₁ f' x L := by
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
f₀ f₁ : F → 𝕜
f₀' f₁' x₀ x₁ : F
s₀ s₁ t : Set F
L₀ L₁ : Filter F
h : HasGradientAtFilter f f' x L
hL : f₁ =ᶠ[L] f
hx : f₁ x = f x
⊢ HasGradientAtFilter f₁ f' x L

Next tactic:
rwa [hL.hasGradientAtFilter_iff hx rfl]
theorem HasGradientWithinAt.congr (h : HasGradientWithinAt f f' s x) (hs : ∀ x ∈ s, f₁ x = f x)
    (hx : f₁ x = f x) : HasGradientWithinAt f₁ f' s x :=
  h.congr_mono hs hx (by 

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
f₀ f₁ : F → 𝕜
f₀' f₁' x₀ x₁ : F
s₀ s₁ t : Set F
L₀ L₁ : Filter F
h : HasGradientWithinAt f f' s x
hs : ∀ x ∈ s, f₁ x = f x
hx : f₁ x = f x
⊢ s ⊆ s

Next tactic:
tauto
theorem Filter.EventuallyEq.gradient_eq (hL : f₁ =ᶠ[𝓝 x] f) : ∇ f₁ x = ∇ f x := by
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
f₀ f₁ : F → 𝕜
f₀' f₁' x₀ x₁ : F
s₀ s₁ t : Set F
L₀ L₁ : Filter F
hL : f₁ =ᶠ[𝓝 x] f
⊢ ∇ f₁ x = ∇ f x

Next tactic:
unfold gradient
theorem Filter.EventuallyEq.gradient_eq (hL : f₁ =ᶠ[𝓝 x] f) : ∇ f₁ x = ∇ f x := by
  unfold gradient
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
f₀ f₁ : F → 𝕜
f₀' f₁' x₀ x₁ : F
s₀ s₁ t : Set F
L₀ L₁ : Filter F
hL : f₁ =ᶠ[𝓝 x] f
⊢ (LinearIsometryEquiv.symm (toDual 𝕜 F)) (fderiv 𝕜 f₁ x) = (LinearIsometryEquiv.symm (toDual 𝕜 F)) (fderiv 𝕜 f x)

Next tactic:
rwa [Filter.EventuallyEq.fderiv_eq]
theorem hasGradientAtFilter_const : HasGradientAtFilter (fun _ => c) 0 x L := by
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
c : 𝕜
⊢ HasGradientAtFilter (fun x => c) 0 x L

Next tactic:
rw [HasGradientAtFilter, map_zero]
theorem hasGradientAtFilter_const : HasGradientAtFilter (fun _ => c) 0 x L := by
  rw [HasGradientAtFilter, map_zero]; 

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
c : 𝕜
⊢ HasFDerivAtFilter (fun x => c) 0 x L

Next tactic:
apply hasFDerivAtFilter_const c x L
theorem gradient_const : ∇ (fun _ => c) x = 0 := by
  

Proof state:
𝕜 : Type u_1
F : Type u_2
inst✝³ : IsROrC 𝕜
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace 𝕜 F
inst✝ : CompleteSpace F
f : F → 𝕜
f' x : F
s : Set F
L : Filter F
c : 𝕜
⊢ ∇ (fun x => c) x = 0

Next tactic:
rw [gradient, fderiv_const, Pi.zero_apply, map_zero]
/-- Equivalence between `Fin 2` and `Bool`. -/
def finTwoEquiv : Fin 2 ≃ Bool where
  toFun := ![false, true]
  invFun b := b.casesOn 0 1
  left_inv := Fin.forall_fin_two.2 <| by 

Proof state:
m n : ℕ
⊢ (fun b => Bool.casesOn b 0 1) (Matrix.vecCons false ![true] 0) = 0 ∧
    (fun b => Bool.casesOn b 0 1) (Matrix.vecCons false ![true] 1) = 1

Next tactic:
simp
/-- Equivalence between `Fin 2` and `Bool`. -/
def finTwoEquiv : Fin 2 ≃ Bool where
  toFun := ![false, true]
  invFun b := b.casesOn 0 1
  left_inv := Fin.forall_fin_two.2 <| by simp
  right_inv := Bool.forall_bool.2 <| by 

Proof state:
m n : ℕ
⊢ Matrix.vecCons false ![true] ((fun b => Bool.casesOn b 0 1) false) = false ∧
    Matrix.vecCons false ![true] ((fun b => Bool.casesOn b 0 1) true) = true

Next tactic:
simp
theorem Fin.preimage_apply_01_prod {α : Fin 2 → Type u} (s : Set (α 0)) (t : Set (α 1)) :
    (fun f : ∀ i, α i => (f 0, f 1)) ⁻¹' s ×ˢ t =
      Set.pi Set.univ (Fin.cons s <| Fin.cons t finZeroElim) := by
  

Proof state:
m n : ℕ
α : Fin 2 → Type u
s : Set (α 0)
t : Set (α 1)
⊢ (fun f => (f 0, f 1)) ⁻¹' s ×ˢ t = Set.pi Set.univ (cons s (cons t finZeroElim))

Next tactic:
ext f
theorem Fin.preimage_apply_01_prod {α : Fin 2 → Type u} (s : Set (α 0)) (t : Set (α 1)) :
    (fun f : ∀ i, α i => (f 0, f 1)) ⁻¹' s ×ˢ t =
      Set.pi Set.univ (Fin.cons s <| Fin.cons t finZeroElim) := by
  ext f
  

Proof state:
case h
m n : ℕ
α : Fin 2 → Type u
s : Set (α 0)
t : Set (α 1)
f : (i : Fin 2) → α i
⊢ f ∈ (fun f => (f 0, f 1)) ⁻¹' s ×ˢ t ↔ f ∈ Set.pi Set.univ (cons s (cons t finZeroElim))

Next tactic:
simp [Fin.forall_fin_two]
/-- An equivalence that removes `i` and maps it to `none`.
This is a version of `Fin.predAbove` that produces `Option (Fin n)` instead of
mapping both `i.cast_succ` and `i.succ` to `i`. -/
def finSuccEquiv' (i : Fin (n + 1)) : Fin (n + 1) ≃ Option (Fin n)
    where
  toFun := i.insertNth none some
  invFun x := x.casesOn' i (Fin.succAbove i)
  left_inv x := Fin.succAboveCases i (by 

Proof state:
m n : ℕ
i x : Fin (n + 1)
⊢ (fun x => Option.casesOn' x i (Fin.succAbove i)) (Fin.insertNth i none some i) = i

Next tactic:
simp
/-- An equivalence that removes `i` and maps it to `none`.
This is a version of `Fin.predAbove` that produces `Option (Fin n)` instead of
mapping both `i.cast_succ` and `i.succ` to `i`. -/
def finSuccEquiv' (i : Fin (n + 1)) : Fin (n + 1) ≃ Option (Fin n)
    where
  toFun := i.insertNth none some
  invFun x := x.casesOn' i (Fin.succAbove i)
  left_inv x := Fin.succAboveCases i (by simp) (fun j => by 

Proof state:
m n : ℕ
i x : Fin (n + 1)
j : Fin n
⊢ (fun x => Option.casesOn' x i (Fin.succAbove i)) (Fin.insertNth i none some (Fin.succAbove i j)) = Fin.succAbove i j

Next tactic:
simp
/-- An equivalence that removes `i` and maps it to `none`.
This is a version of `Fin.predAbove` that produces `Option (Fin n)` instead of
mapping both `i.cast_succ` and `i.succ` to `i`. -/
def finSuccEquiv' (i : Fin (n + 1)) : Fin (n + 1) ≃ Option (Fin n)
    where
  toFun := i.insertNth none some
  invFun x := x.casesOn' i (Fin.succAbove i)
  left_inv x := Fin.succAboveCases i (by simp) (fun j => by simp) x
  right_inv x := by 

Proof state:
m n : ℕ
i : Fin (n + 1)
x : Option (Fin n)
⊢ Fin.insertNth i none some ((fun x => Option.casesOn' x i (Fin.succAbove i)) x) = x

Next tactic:
cases x
/-- An equivalence that removes `i` and maps it to `none`.
This is a version of `Fin.predAbove` that produces `Option (Fin n)` instead of
mapping both `i.cast_succ` and `i.succ` to `i`. -/
def finSuccEquiv' (i : Fin (n + 1)) : Fin (n + 1) ≃ Option (Fin n)
    where
  toFun := i.insertNth none some
  invFun x := x.casesOn' i (Fin.succAbove i)
  left_inv x := Fin.succAboveCases i (by simp) (fun j => by simp) x
  right_inv x := by cases x <;> 

Proof state:
case none
m n : ℕ
i : Fin (n + 1)
⊢ Fin.insertNth i none some ((fun x => Option.casesOn' x i (Fin.succAbove i)) none) = none

Next tactic:
dsimp
/-- An equivalence that removes `i` and maps it to `none`.
This is a version of `Fin.predAbove` that produces `Option (Fin n)` instead of
mapping both `i.cast_succ` and `i.succ` to `i`. -/
def finSuccEquiv' (i : Fin (n + 1)) : Fin (n + 1) ≃ Option (Fin n)
    where
  toFun := i.insertNth none some
  invFun x := x.casesOn' i (Fin.succAbove i)
  left_inv x := Fin.succAboveCases i (by simp) (fun j => by simp) x
  right_inv x := by cases x <;> 

Proof state:
case some
m n : ℕ
i : Fin (n + 1)
val✝ : Fin n
⊢ Fin.insertNth i none some ((fun x => Option.casesOn' x i (Fin.succAbove i)) (some val✝)) = some val✝

Next tactic:
dsimp
/-- An equivalence that removes `i` and maps it to `none`.
This is a version of `Fin.predAbove` that produces `Option (Fin n)` instead of
mapping both `i.cast_succ` and `i.succ` to `i`. -/
def finSuccEquiv' (i : Fin (n + 1)) : Fin (n + 1) ≃ Option (Fin n)
    where
  toFun := i.insertNth none some
  invFun x := x.casesOn' i (Fin.succAbove i)
  left_inv x := Fin.succAboveCases i (by simp) (fun j => by simp) x
  right_inv x := by cases x <;> dsimp <;> 

Proof state:
case none
m n : ℕ
i : Fin (n + 1)
⊢ Fin.insertNth i none some i = none

Next tactic:
simp
/-- An equivalence that removes `i` and maps it to `none`.
This is a version of `Fin.predAbove` that produces `Option (Fin n)` instead of
mapping both `i.cast_succ` and `i.succ` to `i`. -/
def finSuccEquiv' (i : Fin (n + 1)) : Fin (n + 1) ≃ Option (Fin n)
    where
  toFun := i.insertNth none some
  invFun x := x.casesOn' i (Fin.succAbove i)
  left_inv x := Fin.succAboveCases i (by simp) (fun j => by simp) x
  right_inv x := by cases x <;> dsimp <;> 

Proof state:
case some
m n : ℕ
i : Fin (n + 1)
val✝ : Fin n
⊢ Fin.insertNth i none some (Fin.succAbove i val✝) = some val✝

Next tactic:
simp