Skip to content

Commit

Permalink
feat: golf using gcongr throughout the library (#4784)
Browse files Browse the repository at this point in the history
Following on from #4702, another hundred sample uses of the `gcongr` tactic.
  • Loading branch information
hrmacbeth committed Jun 8, 2023
1 parent 2bb9fc3 commit 1507c18
Show file tree
Hide file tree
Showing 26 changed files with 220 additions and 255 deletions.
5 changes: 3 additions & 2 deletions Mathlib/Algebra/Order/SMul.lean
Expand Up @@ -13,6 +13,7 @@ import Mathlib.Algebra.Module.Prod
import Mathlib.Algebra.Order.Monoid.Prod
import Mathlib.Algebra.Order.Pi
import Mathlib.Data.Set.Pointwise.SMul
import Mathlib.Tactic.GCongr.Core
import Mathlib.Tactic.Positivity

/-!
Expand Down Expand Up @@ -88,11 +89,11 @@ section OrderedSMul
variable [OrderedSemiring R] [OrderedAddCommMonoid M] [SMulWithZero R M] [OrderedSMul R M]
{s : Set M} {a b : M} {c : R}

theorem smul_lt_smul_of_pos : a < b → 0 < c → c • a < c • b :=
@[gcongr] theorem smul_lt_smul_of_pos : a < b → 0 < c → c • a < c • b :=
OrderedSMul.smul_lt_smul_of_pos
#align smul_lt_smul_of_pos smul_lt_smul_of_pos

theorem smul_le_smul_of_nonneg (h₁ : a ≤ b) (h₂ : 0 ≤ c) : c • a ≤ c • b := by
@[gcongr] theorem smul_le_smul_of_nonneg (h₁ : a ≤ b) (h₂ : 0 ≤ c) : c • a ≤ c • b := by
rcases h₁.eq_or_lt with (rfl | hab)
· rfl
· rcases h₂.eq_or_lt with (rfl | hc)
Expand Down
25 changes: 13 additions & 12 deletions Mathlib/Analysis/Analytic/Basic.lean
Expand Up @@ -206,7 +206,7 @@ theorem isLittleO_of_lt_radius (h : ↑r < p.radius) :
calc
|‖p n‖ * (r : ℝ) ^ n| = ‖p n‖ * (t : ℝ) ^ n * (r / t : ℝ) ^ n := by
field_simp [mul_right_comm, abs_mul, this.ne']
_ ≤ C * (r / t : ℝ) ^ n := mul_le_mul_of_nonneg_right (hC n) (pow_nonneg (div_nonneg r.2 t.2) _)
_ ≤ C * (r / t : ℝ) ^ n := by gcongr; apply hC
#align formal_multilinear_series.is_o_of_lt_radius FormalMultilinearSeries.isLittleO_of_lt_radius

/-- For `r` strictly smaller than the radius of `p`, then `‖pₙ‖ rⁿ = o(1)`. -/
Expand Down Expand Up @@ -665,16 +665,16 @@ theorem HasFPowerSeriesOnBall.uniform_geometric_approx' {r' : ℝ≥0}
mul_le_of_le_one_right ha.1.le (div_le_one_of_le yr'.le r'.coe_nonneg)
suffices ‖p.partialSum n y - f (x + y)‖ ≤ C * (a * (‖y‖ / r')) ^ n / (1 - a * (‖y‖ / r')) by
refine' this.trans _
apply_rules [div_le_div_of_le_left, sub_pos.2, div_nonneg, mul_nonneg, pow_nonneg, hC.lt.le,
ha.1.le, norm_nonneg, NNReal.coe_nonneg, ha.2, (sub_le_sub_iff_left _).2]
have : 0 < a := ha.1
gcongr
apply_rules [sub_pos.2, ha.2]
apply norm_sub_le_of_geometric_bound_of_hasSum (ya.trans_lt ha.2) _ (hf.hasSum this)
intro n
calc
‖(p n) fun _ : Fin n => y‖
_ ≤ ‖p n‖ * ∏ _i : Fin n, ‖y‖ := ContinuousMultilinearMap.le_op_norm _ _
_ = ‖p n‖ * (r' : ℝ) ^ n * (‖y‖ / r') ^ n := by field_simp [hr'0.ne', mul_right_comm]
_ ≤ C * a ^ n * (‖y‖ / r') ^ n :=
(mul_le_mul_of_nonneg_right (hp n) (pow_nonneg (div_nonneg (norm_nonneg _) r'.coe_nonneg) _))
_ ≤ C * a ^ n * (‖y‖ / r') ^ n := by gcongr ?_ * _; apply hp
_ ≤ C * (a * (‖y‖ / r')) ^ n := by rw [mul_pow, mul_assoc]
#align has_fpower_series_on_ball.uniform_geometric_approx' HasFPowerSeriesOnBall.uniform_geometric_approx'

Expand All @@ -689,7 +689,7 @@ theorem HasFPowerSeriesOnBall.uniform_geometric_approx {r' : ℝ≥0}
hf.uniform_geometric_approx' h
refine' ⟨a, ha, C, hC, fun y hy n => (hp y hy n).trans _⟩
have yr' : ‖y‖ < r' := by rwa [ball_zero_eq] at hy
refine' mul_le_mul_of_nonneg_left (pow_le_pow_of_le_left _ _ _) hC.lt.le
gcongr
exacts [mul_nonneg ha.1.le (div_nonneg (norm_nonneg y) r'.coe_nonneg),
mul_le_of_le_one_right ha.1.le (div_le_one_of_le yr'.le r'.coe_nonneg)]
#align has_fpower_series_on_ball.uniform_geometric_approx HasFPowerSeriesOnBall.uniform_geometric_approx
Expand Down Expand Up @@ -752,10 +752,12 @@ theorem HasFPowerSeriesOnBall.isBigO_image_sub_image_sub_deriv_principal
ring
-- porting note: the two `↑` in `↑r'` are new, without them, Lean fails to synthesize
-- instances `HDiv ℝ ℝ≥0 ?m` or `HMul ℝ ℝ≥0 ?m`
_ ≤ C * a ^ (n + 2) / ↑r' ^ (n + 2) * ↑r' ^ n * (↑(n + 2) * ‖y - (x, x)‖ * ‖y.1 - y.2‖) :=
by apply_rules [mul_le_mul_of_nonneg_right, mul_le_mul, hp, pow_le_pow_of_le_left, hy'.le,
norm_nonneg, pow_nonneg, div_nonneg, mul_nonneg, Nat.cast_nonneg, hC.le, r'.coe_nonneg,
ha.1.le]
_ ≤ C * a ^ (n + 2) / ↑r' ^ (n + 2)
* ↑r' ^ n * (↑(n + 2) * ‖y - (x, x)‖ * ‖y.1 - y.2‖) := by
have : 0 < a := ha.1
gcongr
· apply hp
· apply hy'.le
_ = B n := by
-- porting note: in the original, `B` was in the `field_simp`, but now Lean does not
-- accept it. The current proof works in Lean 4, but does not in Lean 3.
Expand Down Expand Up @@ -971,8 +973,7 @@ theorem Asymptotics.IsBigO.continuousMultilinearMap_apply_eq_zero {n : ℕ} {p :
simpa only [inv_smul_smul₀ (norm_pos_iff.mp k_pos), norm_smul, Finset.prod_const,
Finset.card_fin] using
congr_arg norm (p.map_smul_univ (fun _ : Fin n.succ => k⁻¹) fun _ : Fin n.succ => k • y)
_ ≤ ‖k⁻¹ ^ n.succ‖ * (‖k‖ ^ n.succ * (‖k‖ * (c * ‖y‖ ^ (n.succ + 1)))) :=
(mul_le_mul_of_nonneg_left h₂ (norm_nonneg _))
_ ≤ ‖k⁻¹ ^ n.succ‖ * (‖k‖ ^ n.succ * (‖k‖ * (c * ‖y‖ ^ (n.succ + 1)))) := by gcongr
_ = ‖(k⁻¹ * k) ^ n.succ‖ * (‖k‖ * (c * ‖y‖ ^ (n.succ + 1))) := by
rw [← mul_assoc]
simp [norm_mul, mul_pow]
Expand Down
26 changes: 8 additions & 18 deletions Mathlib/Analysis/Calculus/FDerivMeasurable.lean
Expand Up @@ -179,10 +179,7 @@ theorem mem_a_of_differentiable {ε : ℝ} (hε : 0 < ε) {x : E} (hx : Differen
(norm_sub_le _ _)
_ ≤ ε / 2 * ‖z - x‖ + ε / 2 * ‖y - x‖ :=
(add_le_add (hR _ (lt_trans (mem_ball.1 hz) hr.2)) (hR _ (lt_trans (mem_ball.1 hy) hr.2)))
_ ≤ ε / 2 * r + ε / 2 * r :=
(add_le_add
(mul_le_mul_of_nonneg_left (le_of_lt (mem_ball_iff_norm.1 hz)) (le_of_lt (half_pos hε)))
(mul_le_mul_of_nonneg_left (le_of_lt (mem_ball_iff_norm.1 hy)) (le_of_lt (half_pos hε))))
_ ≤ ε / 2 * r + ε / 2 * r := by rw [mem_ball_iff_norm] at hz hy; gcongr
_ = ε * r := by ring
#align fderiv_measurable_aux.mem_A_of_differentiable FDerivMeasurableAux.mem_a_of_differentiable

Expand Down Expand Up @@ -297,8 +294,7 @@ theorem d_subset_differentiable_set {K : Set (E →L[𝕜] F)} (hK : IsComplete
rw [dist_comm, dist_eq_norm]
calc
‖L0 e - L0 e'‖ ≤ 12 * ‖c‖ * (1 / 2) ^ e := M _ _ _ _ _ _ le_rfl le_rfl le_rfl le_rfl he'
_ < 12 * ‖c‖ * (ε / (12 * ‖c‖)) :=
(mul_lt_mul' le_rfl he (le_of_lt P) (mul_pos (by norm_num) cpos))
_ < 12 * ‖c‖ * (ε / (12 * ‖c‖)) := by gcongr
_ = ε := by field_simp [(by norm_num : (12 : ℝ) ≠ 0), ne_of_gt cpos] ; ring
-- As it is Cauchy, the sequence `L0` converges, to a limit `f'` in `K`.
obtain ⟨f', f'K, hf'⟩ : ∃ f' ∈ K, Tendsto L0 atTop (𝓝 f') :=
Expand All @@ -316,8 +312,7 @@ theorem d_subset_differentiable_set {K : Set (E →L[𝕜] F)} (hK : IsComplete
this makes it possible to cover all scales, and thus to obtain a good linear approximation in
the whole ball of radius `(1/2)^(n e)`. -/
intro ε εpos
have pos : 0 < 4 + 12 * ‖c‖ :=
add_pos_of_pos_of_nonneg (by norm_num) (mul_nonneg (by norm_num) (norm_nonneg _))
have pos : 0 < 4 + 12 * ‖c‖ := by positivity
obtain ⟨e, he⟩ : ∃ e : ℕ, (1 / 2) ^ e < ε / (4 + 12 * ‖c‖) :=
exists_pow_lt_of_lt_one (div_pos εpos pos) (by norm_num)
rw [eventually_nhds_iff_ball]
Expand Down Expand Up @@ -365,10 +360,7 @@ theorem d_subset_differentiable_set {K : Set (E →L[𝕜] F)} (hK : IsComplete
(norm_add_le_of_le J2
((le_op_norm _ _).trans (mul_le_mul_of_nonneg_right (Lf' _ _ m_ge) (norm_nonneg _))))
_ = (4 + 12 * ‖c‖) * ‖y‖ * (1 / 2) ^ e := by ring
_ ≤ (4 + 12 * ‖c‖) * ‖y‖ * (ε / (4 + 12 * ‖c‖)) :=
(mul_le_mul_of_nonneg_left he.le
(mul_nonneg (add_nonneg (by norm_num) (mul_nonneg (by norm_num) (norm_nonneg _)))
(norm_nonneg _)))
_ ≤ (4 + 12 * ‖c‖) * ‖y‖ * (ε / (4 + 12 * ‖c‖)) := by gcongr
_ = ε * ‖y‖ := by field_simp [ne_of_gt pos]; ring
rw [← this.fderiv] at f'K
exact ⟨this.differentiableAt, f'K⟩
Expand Down Expand Up @@ -554,11 +546,9 @@ theorem mem_a_of_differentiable {ε : ℝ} (hε : 0 < ε) {x : ℝ}
(add_le_add (hm ⟨hz.1, hz.2.trans_lt (by linarith [hr.2])⟩)
(hm ⟨hy.1, hy.2.trans_lt (by linarith [hr.2])⟩))
_ ≤ ε / 2 * r + ε / 2 * r := by
apply add_le_add
· apply mul_le_mul_of_nonneg_left _ (le_of_lt (half_pos hε))
rw [Real.norm_of_nonneg] <;> linarith [hz.1, hz.2]
· apply mul_le_mul_of_nonneg_left _ (le_of_lt (half_pos hε))
rw [Real.norm_of_nonneg] <;> linarith [hy.1, hy.2]
gcongr
· rw [Real.norm_of_nonneg] <;> linarith [hz.1, hz.2]
· rw [Real.norm_of_nonneg] <;> linarith [hy.1, hy.2]
_ = ε * r := by ring
#align right_deriv_measurable_aux.mem_A_of_differentiable RightDerivMeasurableAux.mem_a_of_differentiable

Expand Down Expand Up @@ -650,7 +640,7 @@ theorem d_subset_differentiable_set {K : Set F} (hK : IsComplete K) :
by congr 1; abel
_ ≤ ‖L e p q - L e p r‖ + ‖L e p r - L e' p' r‖ + ‖L e' p' r - L e' p' q'‖ :=
(le_trans (norm_add_le _ _) (add_le_add_right (norm_add_le _ _) _))
_ ≤ 4 * (1 / 2) ^ e + 4 * (1 / 2) ^ e + 4 * (1 / 2) ^ e := add_le_add (add_le_add J1 J2) J3
_ ≤ 4 * (1 / 2) ^ e + 4 * (1 / 2) ^ e + 4 * (1 / 2) ^ e := by gcongr
-- Porting note: proof was `by apply_rules [add_le_add]`
_ = 12 * (1 / 2) ^ e := by ring

Expand Down
9 changes: 3 additions & 6 deletions Mathlib/Analysis/Calculus/FDerivSymmetric.lean
Expand Up @@ -136,9 +136,7 @@ theorem Convex.taylor_approx_two_segment {v w : E} (hv : x + v ∈ interior s)
_ = h * ‖v‖ + t * (h * ‖w‖) := by
simp only [norm_smul, Real.norm_eq_abs, hpos.le, abs_of_nonneg, abs_mul, ht.left,
mul_assoc]
_ ≤ h * ‖v‖ + 1 * (h * ‖w‖) :=
(add_le_add le_rfl
(mul_le_mul_of_nonneg_right ht.2.le (mul_nonneg hpos.le (norm_nonneg _))))
_ ≤ h * ‖v‖ + 1 * (h * ‖w‖) := by gcongr; exact ht.2.le
_ = h * (‖v‖ + ‖w‖) := by ring
calc
‖g' t‖ = ‖(f' (x + h • v + (t * h) • w) - f' x - f'' (h • v + (t * h) • w)) (h • w)‖ := by
Expand All @@ -157,10 +155,9 @@ theorem Convex.taylor_approx_two_segment {v w : E} (hv : x + v ∈ interior s)
exact I.trans_lt hδ
simpa only [mem_setOf_eq, add_assoc x, add_sub_cancel'] using sδ H
_ ≤ ε * (‖h • v‖ + ‖h • w‖) * ‖h • w‖ := by
apply mul_le_mul_of_nonneg_right _ (norm_nonneg _)
apply mul_le_mul_of_nonneg_left _ εpos.le
gcongr
apply (norm_add_le _ _).trans
refine' add_le_add le_rfl _
gcongr
simp only [norm_smul, Real.norm_eq_abs, abs_mul, abs_of_nonneg, ht.1, hpos.le, mul_assoc]
exact mul_le_of_le_one_left (mul_nonneg hpos.le (norm_nonneg _)) ht.2.le
_ = ε * ((‖v‖ + ‖w‖) * ‖w‖) * h ^ 2 := by
Expand Down
35 changes: 18 additions & 17 deletions Mathlib/Analysis/Calculus/Inverse.lean
Expand Up @@ -201,10 +201,10 @@ theorem surjOn_closedBall_of_nonlinearRightInverse (hf : ApproximatesLinearOn f
· refine' ⟨b, by simp [ε0], _⟩
have : dist y (f b) ≤ 0 :=
(mem_closedBall.1 hy).trans (mul_nonpos_of_nonpos_of_nonneg (by linarith) ε0)
simp only [dist_le_zero] at this
simp only [dist_le_zero] at this
rw [this]
have If' : (0 : ℝ) < f'symm.nnnorm := by rw [← inv_pos]; exact (NNReal.coe_nonneg _).trans_lt hc
have Icf' : (c : ℝ) * f'symm.nnnorm < 1 := by rwa [inv_eq_one_div, lt_div_iff If'] at hc
have Icf' : (c : ℝ) * f'symm.nnnorm < 1 := by rwa [inv_eq_one_div, lt_div_iff If'] at hc
have Jf' : (f'symm.nnnorm : ℝ) ≠ 0 := ne_of_gt If'
have Jcf' : (1 : ℝ) - c * f'symm.nnnorm ≠ 0 := by apply ne_of_gt; linarith
/- We have to show that `y` can be written as `f x` for some `x ∈ closed_ball b ε`.
Expand All @@ -214,7 +214,7 @@ theorem surjOn_closedBall_of_nonlinearRightInverse (hf : ApproximatesLinearOn f
is nonlinear, this map is not contracting (it is not even continuous), but still the proof of
the contraction theorem holds: `uₙ = gⁿ b` is a Cauchy sequence, converging exponentially fast
to the desired point `x`. Instead of appealing to general results, we check this by hand.
The main point is that `f (u n)` becomes exponentially close to `y`, and therefore
`dist (u (n+1)) (u n)` becomes exponentally small, making it possible to get an inductive
bound on `dist (u n) b`, from which one checks that `u n` stays in the ball on which one has a
Expand Down Expand Up @@ -244,7 +244,7 @@ theorem surjOn_closedBall_of_nonlinearRightInverse (hf : ApproximatesLinearOn f
sub_add_cancel]
_ ≤ c * ‖z + v - z‖ := (hf _ (hε hgz) _ (hε hz))
_ ≤ c * (f'symm.nnnorm * dist (f z) y) := by
apply mul_le_mul_of_nonneg_left _ (NNReal.coe_nonneg c)
gcongr
simpa [dist_eq_norm'] using f'symm.bound (y - f z)
_ = c * f'symm.nnnorm * dist (f z) y := by ring
-- Third bound: a complicated bound on `dist w b` (that will show up in the induction) is enough
Expand All @@ -259,14 +259,15 @@ theorem surjOn_closedBall_of_nonlinearRightInverse (hf : ApproximatesLinearOn f
f'symm.nnnorm * dist (f b) y * (1 - ((c : ℝ) * f'symm.nnnorm) ^ n) :=
by ring
_ ≤ f'symm.nnnorm * dist (f b) y * 1 := by
apply mul_le_mul_of_nonneg_left _ (mul_nonneg (NNReal.coe_nonneg _) dist_nonneg)
gcongr
rw [sub_le_self_iff]
exact pow_nonneg (mul_nonneg (NNReal.coe_nonneg _) (NNReal.coe_nonneg _)) _
positivity
_ ≤ f'symm.nnnorm * (((f'symm.nnnorm : ℝ)⁻¹ - c) * ε) := by
rw [mul_one]
exact mul_le_mul_of_nonneg_left (mem_closedBall'.1 hy) (NNReal.coe_nonneg _)
gcongr
exact mem_closedBall'.1 hy
_ = ε * (1 - c * f'symm.nnnorm) := by field_simp; ring

/- Main inductive control: `f (u n)` becomes exponentially close to `y`, and therefore
`dist (u (n+1)) (u n)` becomes exponentally small, making it possible to get an inductive
bound on `dist (u n) b`, from which one checks that `u n` remains in the ball on which we
Expand All @@ -283,26 +284,27 @@ theorem surjOn_closedBall_of_nonlinearRightInverse (hf : ApproximatesLinearOn f
_ ≤ f'symm.nnnorm * dist (f (u n)) y + dist (u n) b := (add_le_add (A _) le_rfl)
_ ≤ f'symm.nnnorm * (((c : ℝ) * f'symm.nnnorm) ^ n * dist (f b) y) +
f'symm.nnnorm * (1 - ((c : ℝ) * f'symm.nnnorm) ^ n) / (1 - c * f'symm.nnnorm) *
dist (f b) y :=
(add_le_add (mul_le_mul_of_nonneg_left IH.1 (NNReal.coe_nonneg _)) IH.2)
dist (f b) y := by gcongr; exact IH.1; exact IH.2
_ = f'symm.nnnorm * (1 - ((c : ℝ) * f'symm.nnnorm) ^ n.succ) /
(1 - (c : ℝ) * f'symm.nnnorm) * dist (f b) y := by
field_simp [Jcf', pow_succ]; ring
refine' ⟨_, Ign⟩
calc
dist (f (g (u n))) y ≤ c * f'symm.nnnorm * dist (f (u n)) y :=
B _ (C n _ IH.2) (C n.succ _ Ign)
_ ≤ (c : ℝ) * f'symm.nnnorm * (((c : ℝ) * f'symm.nnnorm) ^ n * dist (f b) y) :=
(mul_le_mul_of_nonneg_left IH.1 (mul_nonneg (NNReal.coe_nonneg _) (NNReal.coe_nonneg _)))
_ ≤ (c : ℝ) * f'symm.nnnorm * (((c : ℝ) * f'symm.nnnorm) ^ n * dist (f b) y) := by
gcongr
apply IH.1
_ = ((c : ℝ) * f'symm.nnnorm) ^ n.succ * dist (f b) y := by simp only [pow_succ']; ring
-- Deduce from the inductive bound that `uₙ` is a Cauchy sequence, therefore converging.
have : CauchySeq u
· refine cauchySeq_of_le_geometric _ (↑f'symm.nnnorm * dist (f b) y) Icf' fun n ↦ ?_
calc
dist (u n) (u (n + 1)) = dist (g (u n)) (u n) := by rw [usucc, dist_comm]
_ ≤ f'symm.nnnorm * dist (f (u n)) y := (A _)
_ ≤ f'symm.nnnorm * (((c : ℝ) * f'symm.nnnorm) ^ n * dist (f b) y) :=
(mul_le_mul_of_nonneg_left (D n).1 (NNReal.coe_nonneg _))
_ ≤ f'symm.nnnorm * (((c : ℝ) * f'symm.nnnorm) ^ n * dist (f b) y) := by
gcongr
exact (D n).1
_ = f'symm.nnnorm * dist (f b) y * ((c : ℝ) * f'symm.nnnorm) ^ n := by ring
obtain ⟨x, hx⟩ : ∃ x, Tendsto u atTop (𝓝 x) := cauchySeq_tendsto_of_complete this
-- As all the `uₙ` belong to the ball `closed_ball b ε`, so does their limit `x`.
Expand Down Expand Up @@ -434,7 +436,7 @@ theorem to_inv (hf : ApproximatesLinearOn f (f' : E →L[𝕜] F) s c) (hc : Sub
abel
_ ≤ N * (c * ‖y' - x'‖) := (mul_le_mul_of_nonneg_left (hf _ y's _ x's) (NNReal.coe_nonneg _))
_ ≤ N * (c * (((N⁻¹ - c)⁻¹ : ℝ≥0) * ‖A y' - A x'‖)) := by
apply_rules [mul_le_mul_of_nonneg_left, NNReal.coe_nonneg]
gcongr
rw [← dist_eq_norm, ← dist_eq_norm]
exact (hf.antilipschitz hc).le_mul_dist ⟨y', y's⟩ ⟨x', x's⟩
_ = (N * (N⁻¹ - c)⁻¹ * c : ℝ≥0) * ‖A x' - A y'‖ := by
Expand Down Expand Up @@ -542,7 +544,7 @@ theorem approximates_deriv_on_nhds {f : E → F} {f' : E →L[𝕜] F} {a : E}
· refine' ⟨univ, IsOpen.mem_nhds isOpen_univ trivial, fun x _ y _ => _⟩
simp [@Subsingleton.elim E hE x y]
have := hf.def hc
rw [nhds_prod_eq, Filter.Eventually, mem_prod_same_iff] at this
rw [nhds_prod_eq, Filter.Eventually, mem_prod_same_iff] at this
rcases this with ⟨s, has, hs⟩
exact ⟨s, has, fun x hx y hy => hs (mk_mem_prod hx hy)⟩
#align has_strict_fderiv_at.approximates_deriv_on_nhds HasStrictFDerivAt.approximates_deriv_on_nhds
Expand Down Expand Up @@ -797,4 +799,3 @@ theorem to_localInverse {n : ℕ∞} (hf : ContDiffAt 𝕂 n f a)
#align cont_diff_at.to_local_inverse ContDiffAt.to_localInverse

end ContDiffAt

6 changes: 2 additions & 4 deletions Mathlib/Analysis/Calculus/Taylor.lean
Expand Up @@ -353,10 +353,8 @@ theorem taylor_mean_remainder_bound {f : ℝ → E} {a b C x : ℝ} {n : ℕ} (h
-- The rest is a trivial calculation
rw [abs_mul, abs_pow, abs_inv, Nat.abs_cast]
-- Porting note: was `mono* with 0 ≤ (n ! : ℝ)⁻¹; any_goals positivity; linarith [hx.1, hyx]`
have : 0 ≤ (n ! : ℝ)⁻¹ := by simp only [inv_nonneg, Nat.cast_nonneg]
refine' mul_le_mul_of_nonneg_left (pow_le_pow_of_le_left _ _ n) this
· simp only [abs_nonneg]
· rw [abs_of_nonneg, abs_of_nonneg] <;> linarith
gcongr
rw [abs_of_nonneg, abs_of_nonneg] <;> linarith
-- Apply the mean value theorem for vector valued functions:
have A : ∀ t ∈ Icc a x, HasDerivWithinAt (fun y => taylorWithinEval f n (Icc a b) y x)
(((↑n !)⁻¹ * (x - t) ^ n) • iteratedDerivWithin (n + 1) f (Icc a b) t) (Icc a x) t := by
Expand Down
4 changes: 2 additions & 2 deletions Mathlib/Analysis/Calculus/UniformLimitsDeriv.lean
Expand Up @@ -478,7 +478,7 @@ theorem UniformCauchySeqOnFilter.one_smulRight {l' : Filter 𝕜}
simp only [ContinuousLinearMap.coe_sub', Pi.sub_apply, ContinuousLinearMap.smulRight_apply,
ContinuousLinearMap.one_apply]
rw [← smul_sub, norm_smul, mul_comm]
exact mul_le_mul hn.le rfl.le (norm_nonneg _) hq.le
gcongr
#align uniform_cauchy_seq_on_filter.one_smul_right UniformCauchySeqOnFilter.one_smulRight

theorem uniformCauchySeqOnFilter_of_deriv (hf' : UniformCauchySeqOnFilter f' l (𝓝 x))
Expand Down Expand Up @@ -526,7 +526,7 @@ theorem hasDerivAt_of_tendstoUniformlyOnFilter [NeBot l]
simp only [ContinuousLinearMap.coe_sub', Pi.sub_apply, ContinuousLinearMap.smulRight_apply,
ContinuousLinearMap.one_apply]
rw [← smul_sub, norm_smul, mul_comm]
exact mul_le_mul hn.le rfl.le (norm_nonneg _) hq.le
gcongr
exact hasFDerivAt_of_tendstoUniformlyOnFilter hf' hf hfg
#align has_deriv_at_of_tendsto_uniformly_on_filter hasDerivAt_of_tendstoUniformlyOnFilter

Expand Down

0 comments on commit 1507c18

Please sign in to comment.