analysis.special_functions.gamma.bohr_mollerupMathlib.Analysis.SpecialFunctions.Gamma.BohrMollerup

This file has been ported!

Changes since the initial port

The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.

Changes in mathlib3

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(last sync)

Changes in mathlib3port

mathlib3
mathlib3port
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: David Loeffler
 -/
 import Analysis.SpecialFunctions.Gamma.Basic
-import Analysis.SpecialFunctions.Gaussian
+import Analysis.SpecialFunctions.Gaussian.GaussianIntegral
 
 #align_import analysis.special_functions.gamma.bohr_mollerup from "leanprover-community/mathlib"@"08b63ab58a6ec1157ebeafcbbe6c7a3fb3c9f6d5"
 
Diff
@@ -284,11 +284,11 @@ theorem f_add_nat_ge (hf_conv : ConvexOn ℝ (Ioi 0) f)
   have c :=
     (convex_on_iff_slope_mono_adjacent.mp <| hf_conv).2 npos (by linarith : 0 < (n : ℝ) + x)
       (by linarith : (n : ℝ) - 1 < (n : ℝ)) (by linarith)
-  rw [add_sub_cancel', sub_sub_cancel, div_one] at c
+  rw [add_sub_cancel_left, sub_sub_cancel, div_one] at c
   have : f (↑n - 1) = f n - log (↑n - 1) :=
     by
     nth_rw_rhs 1 [(by ring : (n : ℝ) = ↑n - 1 + 1)]
-    rw [hf_feq npos, add_sub_cancel]
+    rw [hf_feq npos, add_sub_cancel_right]
   rwa [this, le_div_iff hx, sub_sub_cancel, le_sub_iff_add_le, mul_comm _ x, add_comm] at c
 #align real.bohr_mollerup.f_add_nat_ge Real.BohrMollerup.f_add_nat_ge
 -/
@@ -334,7 +334,7 @@ theorem ge_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
   dsimp [log_gamma_seq]
   rw [← add_sub_assoc, sub_le_iff_le_add, ← f_add_nat_eq (@hf_feq) hx, add_comm x _]
   refine' le_trans (le_of_eq _) (f_add_nat_ge hf_conv @hf_feq _ hx)
-  · rw [f_nat_eq @hf_feq, Nat.add_sub_cancel, Nat.cast_add_one, add_sub_cancel]
+  · rw [f_nat_eq @hf_feq, Nat.add_sub_cancel, Nat.cast_add_one, add_sub_cancel_right]
     · ring
     · exact Nat.succ_ne_zero _
   · apply Nat.succ_le_succ
@@ -602,7 +602,7 @@ theorem Gamma_mul_Gamma_add_half_of_pos {s : ℝ} (hs : 0 < s) :
     Gamma s * Gamma (s + 1 / 2) = Gamma (2 * s) * 2 ^ (1 - 2 * s) * sqrt π :=
   by
   rw [← doubling_Gamma_eq_Gamma (mul_pos two_pos hs), doubling_Gamma,
-    mul_div_cancel_left _ (two_ne_zero' ℝ), (by abel : 1 - 2 * s = -(2 * s - 1)),
+    mul_div_cancel_left₀ _ (two_ne_zero' ℝ), (by abel : 1 - 2 * s = -(2 * s - 1)),
     rpow_neg zero_le_two]
   field_simp [(sqrt_pos_of_pos pi_pos).ne', (rpow_pos_of_pos two_pos (2 * s - 1)).ne']
   ring
Diff
@@ -284,12 +284,12 @@ theorem f_add_nat_ge (hf_conv : ConvexOn ℝ (Ioi 0) f)
   have c :=
     (convex_on_iff_slope_mono_adjacent.mp <| hf_conv).2 npos (by linarith : 0 < (n : ℝ) + x)
       (by linarith : (n : ℝ) - 1 < (n : ℝ)) (by linarith)
-  rw [add_sub_cancel', sub_sub_cancel, div_one] at c 
+  rw [add_sub_cancel', sub_sub_cancel, div_one] at c
   have : f (↑n - 1) = f n - log (↑n - 1) :=
     by
     nth_rw_rhs 1 [(by ring : (n : ℝ) = ↑n - 1 + 1)]
     rw [hf_feq npos, add_sub_cancel]
-  rwa [this, le_div_iff hx, sub_sub_cancel, le_sub_iff_add_le, mul_comm _ x, add_comm] at c 
+  rwa [this, le_div_iff hx, sub_sub_cancel, le_sub_iff_add_le, mul_comm _ x, add_comm] at c
 #align real.bohr_mollerup.f_add_nat_ge Real.BohrMollerup.f_add_nat_ge
 -/
 
@@ -380,8 +380,8 @@ theorem tendsto_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
   · rw [Nat.cast_zero, zero_add]
     exact fun _ hx' => tendsto_log_gamma_seq_of_le_one hf_conv (@hf_feq) hx hx'
   · intro hy hy'
-    rw [Nat.cast_succ, ← sub_le_iff_le_add] at hy' 
-    rw [Nat.cast_succ, ← lt_sub_iff_add_lt] at hy 
+    rw [Nat.cast_succ, ← sub_le_iff_le_add] at hy'
+    rw [Nat.cast_succ, ← lt_sub_iff_add_lt] at hy
     specialize hm ((Nat.cast_nonneg _).trans_lt hy) hy hy'
     -- now massage gauss_product n (x - 1) into gauss_product (n - 1) x
     have :
@@ -391,7 +391,7 @@ theorem tendsto_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
       by
       refine' eventually.mp (eventually_ge_at_top 1) (eventually_of_forall fun n hn => _)
       have := log_gamma_seq_add_one (x - 1) (n - 1)
-      rw [sub_add_cancel, Nat.sub_add_cancel hn] at this 
+      rw [sub_add_cancel, Nat.sub_add_cancel hn] at this
       rw [this]
       ring
     replace hm :=
@@ -409,11 +409,11 @@ theorem tendsto_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
       ext1 n
       dsimp only [Function.comp_apply]
       rw [sub_add_cancel, Nat.add_sub_cancel]
-    rw [this] at hm 
+    rw [this] at hm
     convert hm.sub (tendsto_log_nat_add_one_sub_log.const_mul x) using 2
     · ext1 n; ring
     · have := hf_feq ((Nat.cast_nonneg m).trans_lt hy)
-      rw [sub_add_cancel] at this 
+      rw [sub_add_cancel] at this
       rw [this]
       ring
 #align real.bohr_mollerup.tendsto_log_gamma_seq Real.BohrMollerup.tendsto_logGammaSeq
@@ -445,7 +445,7 @@ theorem eq_Gamma_of_log_convex {f : ℝ → ℝ} (hf_conv : ConvexOn ℝ (Ioi 0)
   exact fun x hx => log_inj_on_pos (hf_pos hx) (Gamma_pos_of_pos hx) (this hx)
   intro x hx
   have e1 := bohr_mollerup.tendsto_log_gamma_seq hf_conv _ hx
-  · rw [Function.comp_apply log f 1, hf_one, log_one, sub_zero] at e1 
+  · rw [Function.comp_apply log f 1, hf_one, log_one, sub_zero] at e1
     exact tendsto_nhds_unique e1 (bohr_mollerup.tendsto_log_Gamma hx)
   · intro y hy
     rw [Function.comp_apply, hf_feq hy, log_mul hy.ne' (hf_pos hy).ne']
@@ -480,7 +480,7 @@ theorem Gamma_three_div_two_lt_one : Gamma (3 / 2) < 1 :=
   rw [Function.comp_apply, Function.comp_apply, Nat.cast_two, Gamma_two, log_one, zero_add,
     (by norm_num : (2 : ℝ) + 1 / 2 = 3 / 2 + 1), Gamma_add_one A.ne',
     log_mul A.ne' (Gamma_pos_of_pos A).ne', ← le_sub_iff_add_le',
-    log_le_iff_le_exp (Gamma_pos_of_pos A)] at this 
+    log_le_iff_le_exp (Gamma_pos_of_pos A)] at this
   refine' this.trans_lt (exp_lt_one_iff.mpr _)
   rw [mul_comm, ← mul_div_assoc, div_sub' _ _ (2 : ℝ) two_ne_zero]
   refine' div_neg_of_neg_of_pos _ two_pos
Diff
@@ -130,7 +130,7 @@ theorem Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma {s t a b : ℝ} (hs : 0 <
   -- We will apply Hölder's inequality, for the conjugate exponents `p = 1 / a`
   -- and `q = 1 / b`, to the functions `f a s` and `f b t`, where `f` is as follows:
   let f : ℝ → ℝ → ℝ → ℝ := fun c u x => NormedSpace.exp (-c * x) * x ^ (c * (u - 1))
-  have e : is_conjugate_exponent (1 / a) (1 / b) := Real.isConjugateExponent_one_div ha hb hab
+  have e : is_conjugate_exponent (1 / a) (1 / b) := Real.isConjExponent_one_div ha hb hab
   have hab' : b = 1 - a := by linarith
   have hst : 0 < a * s + b * t := add_pos (mul_pos ha hs) (mul_pos hb ht)
   -- some properties of f:
Diff
@@ -129,7 +129,7 @@ theorem Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma {s t a b : ℝ} (hs : 0 <
   by
   -- We will apply Hölder's inequality, for the conjugate exponents `p = 1 / a`
   -- and `q = 1 / b`, to the functions `f a s` and `f b t`, where `f` is as follows:
-  let f : ℝ → ℝ → ℝ → ℝ := fun c u x => exp (-c * x) * x ^ (c * (u - 1))
+  let f : ℝ → ℝ → ℝ → ℝ := fun c u x => NormedSpace.exp (-c * x) * x ^ (c * (u - 1))
   have e : is_conjugate_exponent (1 / a) (1 / b) := Real.isConjugateExponent_one_div ha hb hab
   have hab' : b = 1 - a := by linarith
   have hst : 0 < a * s + b * t := add_pos (mul_pos ha hs) (mul_pos hb ht)
@@ -139,7 +139,8 @@ theorem Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma {s t a b : ℝ} (hs : 0 <
   have posf' : ∀ c u : ℝ, ∀ᵐ x : ℝ ∂volume.restrict (Ioi 0), 0 ≤ f c u x := fun c u =>
     (ae_restrict_iff' measurableSet_Ioi).mpr (ae_of_all _ (posf c u))
   have fpow :
-    ∀ {c x : ℝ} (hc : 0 < c) (u : ℝ) (hx : 0 < x), exp (-x) * x ^ (u - 1) = f c u x ^ (1 / c) :=
+    ∀ {c x : ℝ} (hc : 0 < c) (u : ℝ) (hx : 0 < x),
+      NormedSpace.exp (-x) * x ^ (u - 1) = f c u x ^ (1 / c) :=
     by
     intro c x hc u hx
     dsimp only [f]
@@ -174,8 +175,8 @@ theorem Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma {s t a b : ℝ} (hs : 0 <
     1
   · refine' set_integral_congr measurableSet_Ioi fun x hx => _
     dsimp only [f]
-    have A : exp (-x) = exp (-a * x) * exp (-b * x) := by
-      rw [← exp_add, ← add_mul, ← neg_add, hab, neg_one_mul]
+    have A : NormedSpace.exp (-x) = NormedSpace.exp (-a * x) * NormedSpace.exp (-b * x) := by
+      rw [← NormedSpace.exp_add, ← add_mul, ← neg_add, hab, neg_one_mul]
     have B : x ^ (a * s + b * t - 1) = x ^ (a * (s - 1)) * x ^ (b * (t - 1)) := by
       rw [← rpow_add hx, hab']; congr 1; ring
     rw [A, B]
@@ -251,7 +252,7 @@ theorem f_add_nat_eq (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = f y + log y)
   by
   induction' n with n hn
   · simp
-  · have : x + n.succ = x + n + 1 := by push_cast ; ring
+  · have : x + n.succ = x + n + 1 := by push_cast; ring
     rw [this, hf_feq, hn]
     rw [Finset.range_succ, Finset.sum_insert Finset.not_mem_range_self]
     abel
Diff
@@ -3,8 +3,8 @@ Copyright (c) 2023 David Loeffler. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: David Loeffler
 -/
-import Mathbin.Analysis.SpecialFunctions.Gamma.Basic
-import Mathbin.Analysis.SpecialFunctions.Gaussian
+import Analysis.SpecialFunctions.Gamma.Basic
+import Analysis.SpecialFunctions.Gaussian
 
 #align_import analysis.special_functions.gamma.bohr_mollerup from "leanprover-community/mathlib"@"08b63ab58a6ec1157ebeafcbbe6c7a3fb3c9f6d5"
 
Diff
@@ -2,15 +2,12 @@
 Copyright (c) 2023 David Loeffler. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: David Loeffler
-
-! This file was ported from Lean 3 source module analysis.special_functions.gamma.bohr_mollerup
-! leanprover-community/mathlib commit 08b63ab58a6ec1157ebeafcbbe6c7a3fb3c9f6d5
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathbin.Analysis.SpecialFunctions.Gamma.Basic
 import Mathbin.Analysis.SpecialFunctions.Gaussian
 
+#align_import analysis.special_functions.gamma.bohr_mollerup from "leanprover-community/mathlib"@"08b63ab58a6ec1157ebeafcbbe6c7a3fb3c9f6d5"
+
 /-! # Convexity properties of the Gamma function
 
 > THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: David Loeffler
 
 ! This file was ported from Lean 3 source module analysis.special_functions.gamma.bohr_mollerup
-! leanprover-community/mathlib commit a3209ddf94136d36e5e5c624b10b2a347cc9d090
+! leanprover-community/mathlib commit 08b63ab58a6ec1157ebeafcbbe6c7a3fb3c9f6d5
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -13,6 +13,9 @@ import Mathbin.Analysis.SpecialFunctions.Gaussian
 
 /-! # Convexity properties of the Gamma function
 
+> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
+> Any changes to this file require a corresponding PR to mathlib4.
+
 In this file, we prove that `Gamma` and `log ∘ Gamma` are convex functions on the positive real
 line. We then prove the Bohr-Mollerup theorem, which characterises `Gamma` as the *unique*
 positive-real-valued, log-convex function on the positive reals satisfying `f (x + 1) = x f x` and
Diff
@@ -54,49 +54,65 @@ section Convexity
 variable {𝕜 E β : Type _} {s : Set E} {f g : E → β} [OrderedSemiring 𝕜] [SMul 𝕜 E] [AddCommMonoid E]
   [OrderedAddCommMonoid β]
 
+#print ConvexOn.congr /-
 theorem ConvexOn.congr [SMul 𝕜 β] (hf : ConvexOn 𝕜 s f) (hfg : EqOn f g s) : ConvexOn 𝕜 s g :=
   ⟨hf.1, fun x hx y hy a b ha hb hab => by
     simpa only [← hfg hx, ← hfg hy, ← hfg (hf.1 hx hy ha hb hab)] using hf.2 hx hy ha hb hab⟩
 #align convex_on.congr ConvexOn.congr
+-/
 
+#print ConcaveOn.congr /-
 theorem ConcaveOn.congr [SMul 𝕜 β] (hf : ConcaveOn 𝕜 s f) (hfg : EqOn f g s) : ConcaveOn 𝕜 s g :=
   ⟨hf.1, fun x hx y hy a b ha hb hab => by
     simpa only [← hfg hx, ← hfg hy, ← hfg (hf.1 hx hy ha hb hab)] using hf.2 hx hy ha hb hab⟩
 #align concave_on.congr ConcaveOn.congr
+-/
 
+#print StrictConvexOn.congr /-
 theorem StrictConvexOn.congr [SMul 𝕜 β] (hf : StrictConvexOn 𝕜 s f) (hfg : EqOn f g s) :
     StrictConvexOn 𝕜 s g :=
   ⟨hf.1, fun x hx y hy hxy a b ha hb hab => by
     simpa only [← hfg hx, ← hfg hy, ← hfg (hf.1 hx hy ha.le hb.le hab)] using
       hf.2 hx hy hxy ha hb hab⟩
 #align strict_convex_on.congr StrictConvexOn.congr
+-/
 
+#print StrictConcaveOn.congr /-
 theorem StrictConcaveOn.congr [SMul 𝕜 β] (hf : StrictConcaveOn 𝕜 s f) (hfg : EqOn f g s) :
     StrictConcaveOn 𝕜 s g :=
   ⟨hf.1, fun x hx y hy hxy a b ha hb hab => by
     simpa only [← hfg hx, ← hfg hy, ← hfg (hf.1 hx hy ha.le hb.le hab)] using
       hf.2 hx hy hxy ha hb hab⟩
 #align strict_concave_on.congr StrictConcaveOn.congr
+-/
 
+#print ConvexOn.add_const /-
 theorem ConvexOn.add_const [Module 𝕜 β] (hf : ConvexOn 𝕜 s f) (b : β) :
     ConvexOn 𝕜 s (f + fun _ => b) :=
   hf.add (convexOn_const _ hf.1)
 #align convex_on.add_const ConvexOn.add_const
+-/
 
+#print ConcaveOn.add_const /-
 theorem ConcaveOn.add_const [Module 𝕜 β] (hf : ConcaveOn 𝕜 s f) (b : β) :
     ConcaveOn 𝕜 s (f + fun _ => b) :=
   hf.add (concaveOn_const _ hf.1)
 #align concave_on.add_const ConcaveOn.add_const
+-/
 
+#print StrictConvexOn.add_const /-
 theorem StrictConvexOn.add_const {γ : Type _} {f : E → γ} [OrderedCancelAddCommMonoid γ]
     [Module 𝕜 γ] (hf : StrictConvexOn 𝕜 s f) (b : γ) : StrictConvexOn 𝕜 s (f + fun _ => b) :=
   hf.add_convexOn (convexOn_const _ hf.1)
 #align strict_convex_on.add_const StrictConvexOn.add_const
+-/
 
+#print StrictConcaveOn.add_const /-
 theorem StrictConcaveOn.add_const {γ : Type _} {f : E → γ} [OrderedCancelAddCommMonoid γ]
     [Module 𝕜 γ] (hf : StrictConcaveOn 𝕜 s f) (b : γ) : StrictConcaveOn 𝕜 s (f + fun _ => b) :=
   hf.add_concaveOn (concaveOn_const _ hf.1)
 #align strict_concave_on.add_const StrictConcaveOn.add_const
+-/
 
 end Convexity
 
@@ -104,9 +120,10 @@ namespace Real
 
 section Convexity
 
+#print Real.Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma /-
 /-- Log-convexity of the Gamma function on the positive reals (stated in multiplicative form),
 proved using the Hölder inequality applied to Euler's integral. -/
-theorem gamma_mul_add_mul_le_rpow_gamma_mul_rpow_gamma {s t a b : ℝ} (hs : 0 < s) (ht : 0 < t)
+theorem Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma {s t a b : ℝ} (hs : 0 < s) (ht : 0 < t)
     (ha : 0 < a) (hb : 0 < b) (hab : a + b = 1) :
     Gamma (a * s + b * t) ≤ Gamma s ^ a * Gamma t ^ b :=
   by
@@ -165,9 +182,11 @@ theorem gamma_mul_add_mul_le_rpow_gamma_mul_rpow_gamma {s t a b : ℝ} (hs : 0 <
     ring
   · rw [one_div_one_div, one_div_one_div]
     congr 2 <;> exact set_integral_congr measurableSet_Ioi fun x hx => fpow (by assumption) _ hx
-#align real.Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma Real.gamma_mul_add_mul_le_rpow_gamma_mul_rpow_gamma
+#align real.Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma Real.Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma
+-/
 
-theorem convexOn_log_gamma : ConvexOn ℝ (Ioi 0) (log ∘ Gamma) :=
+#print Real.convexOn_log_Gamma /-
+theorem convexOn_log_Gamma : ConvexOn ℝ (Ioi 0) (log ∘ Gamma) :=
   by
   refine' convex_on_iff_forall_pos.mpr ⟨convex_Ioi _, fun x hx y hy a b ha hb hab => _⟩
   have : b = 1 - a := by linarith; subst this
@@ -178,9 +197,11 @@ theorem convexOn_log_gamma : ConvexOn ℝ (Ioi 0) (log ∘ Gamma) :=
     log_le_log (Gamma_pos_of_pos (add_pos (mul_pos ha hx) (mul_pos hb hy)))
       (mul_pos (rpow_pos_of_pos (Gamma_pos_of_pos hx) _) (rpow_pos_of_pos (Gamma_pos_of_pos hy) _))]
   exact Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma hx hy ha hb hab
-#align real.convex_on_log_Gamma Real.convexOn_log_gamma
+#align real.convex_on_log_Gamma Real.convexOn_log_Gamma
+-/
 
-theorem convexOn_gamma : ConvexOn ℝ (Ioi 0) Gamma :=
+#print Real.convexOn_Gamma /-
+theorem convexOn_Gamma : ConvexOn ℝ (Ioi 0) Gamma :=
   by
   refine'
     ((convex_on_exp.subset (subset_univ _) _).comp convex_on_log_Gamma
@@ -190,7 +211,8 @@ theorem convexOn_gamma : ConvexOn ℝ (Ioi 0) Gamma :=
   refine' is_preconnected_Ioi.image _ fun x hx => ContinuousAt.continuousWithinAt _
   refine' (differentiable_at_Gamma fun m => _).ContinuousAt.log (Gamma_pos_of_pos hx).ne'
   exact (neg_lt_iff_pos_add.mpr (add_pos_of_pos_of_nonneg hx (Nat.cast_nonneg m))).ne'
-#align real.convex_on_Gamma Real.convexOn_gamma
+#align real.convex_on_Gamma Real.convexOn_Gamma
+-/
 
 end Convexity
 
@@ -198,14 +220,17 @@ section BohrMollerup
 
 namespace BohrMollerup
 
+#print Real.BohrMollerup.logGammaSeq /-
 /-- The function `n ↦ x log n + log n! - (log x + ... + log (x + n))`, which we will show tends to
 `log (Gamma x)` as `n → ∞`. -/
 def logGammaSeq (x : ℝ) (n : ℕ) : ℝ :=
   x * log n + log n ! - ∑ m : ℕ in Finset.range (n + 1), log (x + m)
 #align real.bohr_mollerup.log_gamma_seq Real.BohrMollerup.logGammaSeq
+-/
 
 variable {f : ℝ → ℝ} {x : ℝ} {n : ℕ}
 
+#print Real.BohrMollerup.f_nat_eq /-
 theorem f_nat_eq (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = f y + log y) (hn : n ≠ 0) :
     f n = f 1 + log (n - 1)! :=
   by
@@ -218,7 +243,9 @@ theorem f_nat_eq (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = f y + log y) (hn
   congr
   exact (Nat.succ_pred_eq_of_pos hm).symm
 #align real.bohr_mollerup.f_nat_eq Real.BohrMollerup.f_nat_eq
+-/
 
+#print Real.BohrMollerup.f_add_nat_eq /-
 theorem f_add_nat_eq (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = f y + log y) (hx : 0 < x) (n : ℕ) :
     f (x + n) = f x + ∑ m : ℕ in Finset.range n, log (x + m) :=
   by
@@ -230,7 +257,9 @@ theorem f_add_nat_eq (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = f y + log y)
     abel
     linarith [(Nat.cast_nonneg n : 0 ≤ (n : ℝ))]
 #align real.bohr_mollerup.f_add_nat_eq Real.BohrMollerup.f_add_nat_eq
+-/
 
+#print Real.BohrMollerup.f_add_nat_le /-
 /-- Linear upper bound for `f (x + n)` on unit interval -/
 theorem f_add_nat_le (hf_conv : ConvexOn ℝ (Ioi 0) f)
     (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = f y + log y) (hn : n ≠ 0) (hx : 0 < x) (hx' : x ≤ 1) :
@@ -242,7 +271,9 @@ theorem f_add_nat_le (hf_conv : ConvexOn ℝ (Ioi 0) f)
   simpa only [smul_eq_mul] using
     hf_conv.2 hn' (by linarith : 0 < (n + 1 : ℝ)) (by linarith : 0 ≤ 1 - x) hx.le (by linarith)
 #align real.bohr_mollerup.f_add_nat_le Real.BohrMollerup.f_add_nat_le
+-/
 
+#print Real.BohrMollerup.f_add_nat_ge /-
 /-- Linear lower bound for `f (x + n)` on unit interval -/
 theorem f_add_nat_ge (hf_conv : ConvexOn ℝ (Ioi 0) f)
     (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = f y + log y) (hn : 2 ≤ n) (hx : 0 < x) :
@@ -259,7 +290,9 @@ theorem f_add_nat_ge (hf_conv : ConvexOn ℝ (Ioi 0) f)
     rw [hf_feq npos, add_sub_cancel]
   rwa [this, le_div_iff hx, sub_sub_cancel, le_sub_iff_add_le, mul_comm _ x, add_comm] at c 
 #align real.bohr_mollerup.f_add_nat_ge Real.BohrMollerup.f_add_nat_ge
+-/
 
+#print Real.BohrMollerup.logGammaSeq_add_one /-
 theorem logGammaSeq_add_one (x : ℝ) (n : ℕ) :
     logGammaSeq (x + 1) n = logGammaSeq x (n + 1) + log x - (x + 1) * (log (n + 1) - log n) :=
   by
@@ -279,7 +312,9 @@ theorem logGammaSeq_add_one (x : ℝ) (n : ℕ) :
   rw [← this, Nat.cast_add_one n]
   ring
 #align real.bohr_mollerup.log_gamma_seq_add_one Real.BohrMollerup.logGammaSeq_add_one
+-/
 
+#print Real.BohrMollerup.le_logGammaSeq /-
 theorem le_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
     (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = f y + log y) (hx : 0 < x) (hx' : x ≤ 1) (n : ℕ) :
     f x ≤ f 1 + x * log (n + 1) - x * log n + logGammaSeq x n :=
@@ -289,7 +324,9 @@ theorem le_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
   rw [f_nat_eq @hf_feq (by linarith : n + 1 ≠ 0), Nat.add_sub_cancel, Nat.cast_add_one]
   ring
 #align real.bohr_mollerup.le_log_gamma_seq Real.BohrMollerup.le_logGammaSeq
+-/
 
+#print Real.BohrMollerup.ge_logGammaSeq /-
 theorem ge_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
     (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = f y + log y) (hx : 0 < x) (hn : n ≠ 0) :
     f 1 + logGammaSeq x n ≤ f x := by
@@ -302,7 +339,9 @@ theorem ge_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
   · apply Nat.succ_le_succ
     linarith [Nat.pos_of_ne_zero hn]
 #align real.bohr_mollerup.ge_log_gamma_seq Real.BohrMollerup.ge_logGammaSeq
+-/
 
+#print Real.BohrMollerup.tendsto_logGammaSeq_of_le_one /-
 theorem tendsto_logGammaSeq_of_le_one (hf_conv : ConvexOn ℝ (Ioi 0) f)
     (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = f y + log y) (hx : 0 < x) (hx' : x ≤ 1) :
     Tendsto (logGammaSeq x) atTop (𝓝 <| f x - f 1) :=
@@ -320,7 +359,9 @@ theorem tendsto_logGammaSeq_of_le_one (hf_conv : ConvexOn ℝ (Ioi 0) f)
     nth_rw 1 [this]
     exact tendsto.sub tendsto_const_nhds (tendsto_log_nat_add_one_sub_log.const_mul _)
 #align real.bohr_mollerup.tendsto_log_gamma_seq_of_le_one Real.BohrMollerup.tendsto_logGammaSeq_of_le_one
+-/
 
+#print Real.BohrMollerup.tendsto_logGammaSeq /-
 theorem tendsto_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
     (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = f y + log y) (hx : 0 < x) :
     Tendsto (logGammaSeq x) atTop (𝓝 <| f x - f 1) :=
@@ -375,7 +416,9 @@ theorem tendsto_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
       rw [this]
       ring
 #align real.bohr_mollerup.tendsto_log_gamma_seq Real.BohrMollerup.tendsto_logGammaSeq
+-/
 
+#print Real.BohrMollerup.tendsto_log_gamma /-
 theorem tendsto_log_gamma {x : ℝ} (hx : 0 < x) :
     Tendsto (logGammaSeq x) atTop (𝓝 <| log (Gamma x)) :=
   by
@@ -385,13 +428,15 @@ theorem tendsto_log_gamma {x : ℝ} (hx : 0 < x) :
   refine' bohr_mollerup.tendsto_log_gamma_seq convex_on_log_Gamma (fun y hy => _) hx
   rw [Function.comp_apply, Gamma_add_one hy.ne', log_mul hy.ne' (Gamma_pos_of_pos hy).ne', add_comm]
 #align real.bohr_mollerup.tendsto_log_Gamma Real.BohrMollerup.tendsto_log_gamma
+-/
 
 end BohrMollerup
 
+#print Real.eq_Gamma_of_log_convex /-
 -- (namespace)
 /-- The **Bohr-Mollerup theorem**: the Gamma function is the *unique* log-convex, positive-valued
 function on the positive reals which satisfies `f 1 = 1` and `f (x + 1) = x * f x` for all `x`. -/
-theorem eq_gamma_of_log_convex {f : ℝ → ℝ} (hf_conv : ConvexOn ℝ (Ioi 0) (log ∘ f))
+theorem eq_Gamma_of_log_convex {f : ℝ → ℝ} (hf_conv : ConvexOn ℝ (Ioi 0) (log ∘ f))
     (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = y * f y) (hf_pos : ∀ {y : ℝ}, 0 < y → 0 < f y)
     (hf_one : f 1 = 1) : EqOn f Gamma (Ioi (0 : ℝ)) :=
   by
@@ -404,17 +449,21 @@ theorem eq_gamma_of_log_convex {f : ℝ → ℝ} (hf_conv : ConvexOn ℝ (Ioi 0)
   · intro y hy
     rw [Function.comp_apply, hf_feq hy, log_mul hy.ne' (hf_pos hy).ne']
     ring
-#align real.eq_Gamma_of_log_convex Real.eq_gamma_of_log_convex
+#align real.eq_Gamma_of_log_convex Real.eq_Gamma_of_log_convex
+-/
 
 end BohrMollerup
 
 -- (section)
 section StrictMono
 
-theorem gamma_two : Gamma 2 = 1 := by simpa using Gamma_nat_eq_factorial 1
-#align real.Gamma_two Real.gamma_two
+#print Real.Gamma_two /-
+theorem Gamma_two : Gamma 2 = 1 := by simpa using Gamma_nat_eq_factorial 1
+#align real.Gamma_two Real.Gamma_two
+-/
 
-theorem gamma_three_div_two_lt_one : Gamma (3 / 2) < 1 :=
+#print Real.Gamma_three_div_two_lt_one /-
+theorem Gamma_three_div_two_lt_one : Gamma (3 / 2) < 1 :=
   by
   -- This can also be proved using the closed-form evaluation of `Gamma (1 / 2)` in
   -- `analysis.special_functions.gaussian`, but we give a self-contained proof using log-convexity
@@ -437,9 +486,11 @@ theorem gamma_three_div_two_lt_one : Gamma (3 / 2) < 1 :=
   rw [sub_neg, mul_one, ← Nat.cast_two, ← log_pow, ← exp_lt_exp, Nat.cast_two, exp_log two_pos,
       exp_log] <;>
     norm_num
-#align real.Gamma_three_div_two_lt_one Real.gamma_three_div_two_lt_one
+#align real.Gamma_three_div_two_lt_one Real.Gamma_three_div_two_lt_one
+-/
 
-theorem gamma_strictMonoOn_Ici : StrictMonoOn Gamma (Ici 2) :=
+#print Real.Gamma_strictMonoOn_Ici /-
+theorem Gamma_strictMonoOn_Ici : StrictMonoOn Gamma (Ici 2) :=
   by
   convert
     convex_on_Gamma.strict_mono_of_lt (by norm_num : (0 : ℝ) < 3 / 2)
@@ -447,7 +498,8 @@ theorem gamma_strictMonoOn_Ici : StrictMonoOn Gamma (Ici 2) :=
   symm
   rw [inter_eq_right_iff_subset]
   exact fun x hx => two_pos.trans_le hx
-#align real.Gamma_strict_mono_on_Ici Real.gamma_strictMonoOn_Ici
+#align real.Gamma_strict_mono_on_Ici Real.Gamma_strictMonoOn_Ici
+-/
 
 end StrictMono
 
@@ -462,23 +514,30 @@ log-convex and satisfies the Gamma functional equation, so it must actually be a
 multiple of `Gamma`, and we can compute the constant by specialising at `s = 1`. -/
 
 
+#print Real.doublingGamma /-
 /-- Auxiliary definition for the doubling formula (we'll show this is equal to `Gamma s`) -/
 def doublingGamma (s : ℝ) : ℝ :=
   Gamma (s / 2) * Gamma (s / 2 + 1 / 2) * 2 ^ (s - 1) / sqrt π
 #align real.doubling_Gamma Real.doublingGamma
+-/
 
+#print Real.doublingGamma_add_one /-
 theorem doublingGamma_add_one (s : ℝ) (hs : s ≠ 0) : doublingGamma (s + 1) = s * doublingGamma s :=
   by
   rw [doubling_Gamma, doubling_Gamma, (by abel : s + 1 - 1 = s - 1 + 1), add_div, add_assoc,
     add_halves (1 : ℝ), Gamma_add_one (div_ne_zero hs two_ne_zero), rpow_add two_pos, rpow_one]
   ring
 #align real.doubling_Gamma_add_one Real.doublingGamma_add_one
+-/
 
+#print Real.doublingGamma_one /-
 theorem doublingGamma_one : doublingGamma 1 = 1 := by
   simp_rw [doubling_Gamma, Gamma_one_half_eq, add_halves (1 : ℝ), sub_self, Gamma_one, mul_one,
     rpow_zero, mul_one, div_self (sqrt_ne_zero'.mpr pi_pos)]
 #align real.doubling_Gamma_one Real.doublingGamma_one
+-/
 
+#print Real.log_doublingGamma_eq /-
 theorem log_doublingGamma_eq :
     EqOn (log ∘ doublingGamma)
       (fun s => log (Gamma (s / 2)) + log (Gamma (s / 2 + 1 / 2)) + s * log 2 - log (2 * sqrt π))
@@ -494,7 +553,9 @@ theorem log_doublingGamma_eq :
     log_mul (mul_ne_zero h2 h3) h4, log_mul h2 h3, log_rpow two_pos, log_mul two_ne_zero h1]
   ring_nf
 #align real.log_doubling_Gamma_eq Real.log_doublingGamma_eq
+-/
 
+#print Real.doublingGamma_log_convex_Ioi /-
 theorem doublingGamma_log_convex_Ioi : ConvexOn ℝ (Ioi (0 : ℝ)) (log ∘ doublingGamma) :=
   by
   refine' (((ConvexOn.add _ _).add _).AddConst _).congr log_doubling_Gamma_eq.symm
@@ -519,20 +580,24 @@ theorem doublingGamma_log_convex_Ioi : ConvexOn ℝ (Ioi (0 : ℝ)) (log ∘ dou
     simpa only [mul_comm _ (log _)] using
       (convexOn_id (convex_Ioi (0 : ℝ))).smul (log_pos one_lt_two).le
 #align real.doubling_Gamma_log_convex_Ioi Real.doublingGamma_log_convex_Ioi
+-/
 
-theorem doublingGamma_eq_gamma {s : ℝ} (hs : 0 < s) : doublingGamma s = Gamma s :=
+#print Real.doublingGamma_eq_Gamma /-
+theorem doublingGamma_eq_Gamma {s : ℝ} (hs : 0 < s) : doublingGamma s = Gamma s :=
   by
   refine'
     eq_Gamma_of_log_convex doubling_Gamma_log_convex_Ioi
       (fun y hy => doubling_Gamma_add_one y hy.ne') (fun y hy => _) doubling_Gamma_one hs
   apply_rules [mul_pos, Gamma_pos_of_pos, add_pos, inv_pos_of_pos, rpow_pos_of_pos, two_pos,
     one_pos, sqrt_pos_of_pos pi_pos]
-#align real.doubling_Gamma_eq_Gamma Real.doublingGamma_eq_gamma
+#align real.doubling_Gamma_eq_Gamma Real.doublingGamma_eq_Gamma
+-/
 
+#print Real.Gamma_mul_Gamma_add_half_of_pos /-
 /-- Legendre's doubling formula for the Gamma function, for positive real arguments. Note that
 we shall later prove this for all `s` as `real.Gamma_mul_Gamma_add_half` (superseding this result)
 but this result is needed as an intermediate step. -/
-theorem gamma_mul_gamma_add_half_of_pos {s : ℝ} (hs : 0 < s) :
+theorem Gamma_mul_Gamma_add_half_of_pos {s : ℝ} (hs : 0 < s) :
     Gamma s * Gamma (s + 1 / 2) = Gamma (2 * s) * 2 ^ (1 - 2 * s) * sqrt π :=
   by
   rw [← doubling_Gamma_eq_Gamma (mul_pos two_pos hs), doubling_Gamma,
@@ -540,7 +605,8 @@ theorem gamma_mul_gamma_add_half_of_pos {s : ℝ} (hs : 0 < s) :
     rpow_neg zero_le_two]
   field_simp [(sqrt_pos_of_pos pi_pos).ne', (rpow_pos_of_pos two_pos (2 * s - 1)).ne']
   ring
-#align real.Gamma_mul_Gamma_add_half_of_pos Real.gamma_mul_gamma_add_half_of_pos
+#align real.Gamma_mul_Gamma_add_half_of_pos Real.Gamma_mul_Gamma_add_half_of_pos
+-/
 
 end Doubling
 
Diff
@@ -108,7 +108,7 @@ section Convexity
 proved using the Hölder inequality applied to Euler's integral. -/
 theorem gamma_mul_add_mul_le_rpow_gamma_mul_rpow_gamma {s t a b : ℝ} (hs : 0 < s) (ht : 0 < t)
     (ha : 0 < a) (hb : 0 < b) (hab : a + b = 1) :
-    gamma (a * s + b * t) ≤ gamma s ^ a * gamma t ^ b :=
+    Gamma (a * s + b * t) ≤ Gamma s ^ a * Gamma t ^ b :=
   by
   -- We will apply Hölder's inequality, for the conjugate exponents `p = 1 / a`
   -- and `q = 1 / b`, to the functions `f a s` and `f b t`, where `f` is as follows:
@@ -167,7 +167,7 @@ theorem gamma_mul_add_mul_le_rpow_gamma_mul_rpow_gamma {s t a b : ℝ} (hs : 0 <
     congr 2 <;> exact set_integral_congr measurableSet_Ioi fun x hx => fpow (by assumption) _ hx
 #align real.Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma Real.gamma_mul_add_mul_le_rpow_gamma_mul_rpow_gamma
 
-theorem convexOn_log_gamma : ConvexOn ℝ (Ioi 0) (log ∘ gamma) :=
+theorem convexOn_log_gamma : ConvexOn ℝ (Ioi 0) (log ∘ Gamma) :=
   by
   refine' convex_on_iff_forall_pos.mpr ⟨convex_Ioi _, fun x hx y hy a b ha hb hab => _⟩
   have : b = 1 - a := by linarith; subst this
@@ -180,7 +180,7 @@ theorem convexOn_log_gamma : ConvexOn ℝ (Ioi 0) (log ∘ gamma) :=
   exact Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma hx hy ha hb hab
 #align real.convex_on_log_Gamma Real.convexOn_log_gamma
 
-theorem convexOn_gamma : ConvexOn ℝ (Ioi 0) gamma :=
+theorem convexOn_gamma : ConvexOn ℝ (Ioi 0) Gamma :=
   by
   refine'
     ((convex_on_exp.subset (subset_univ _) _).comp convex_on_log_Gamma
@@ -377,7 +377,7 @@ theorem tendsto_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
 #align real.bohr_mollerup.tendsto_log_gamma_seq Real.BohrMollerup.tendsto_logGammaSeq
 
 theorem tendsto_log_gamma {x : ℝ} (hx : 0 < x) :
-    Tendsto (logGammaSeq x) atTop (𝓝 <| log (gamma x)) :=
+    Tendsto (logGammaSeq x) atTop (𝓝 <| log (Gamma x)) :=
   by
   have : log (Gamma x) = (log ∘ Gamma) x - (log ∘ Gamma) 1 := by
     simp_rw [Function.comp_apply, Gamma_one, log_one, sub_zero]
@@ -393,7 +393,7 @@ end BohrMollerup
 function on the positive reals which satisfies `f 1 = 1` and `f (x + 1) = x * f x` for all `x`. -/
 theorem eq_gamma_of_log_convex {f : ℝ → ℝ} (hf_conv : ConvexOn ℝ (Ioi 0) (log ∘ f))
     (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = y * f y) (hf_pos : ∀ {y : ℝ}, 0 < y → 0 < f y)
-    (hf_one : f 1 = 1) : EqOn f gamma (Ioi (0 : ℝ)) :=
+    (hf_one : f 1 = 1) : EqOn f Gamma (Ioi (0 : ℝ)) :=
   by
   suffices : eq_on (log ∘ f) (log ∘ Gamma) (Ioi (0 : ℝ))
   exact fun x hx => log_inj_on_pos (hf_pos hx) (Gamma_pos_of_pos hx) (this hx)
@@ -411,10 +411,10 @@ end BohrMollerup
 -- (section)
 section StrictMono
 
-theorem gamma_two : gamma 2 = 1 := by simpa using Gamma_nat_eq_factorial 1
+theorem gamma_two : Gamma 2 = 1 := by simpa using Gamma_nat_eq_factorial 1
 #align real.Gamma_two Real.gamma_two
 
-theorem gamma_three_div_two_lt_one : gamma (3 / 2) < 1 :=
+theorem gamma_three_div_two_lt_one : Gamma (3 / 2) < 1 :=
   by
   -- This can also be proved using the closed-form evaluation of `Gamma (1 / 2)` in
   -- `analysis.special_functions.gaussian`, but we give a self-contained proof using log-convexity
@@ -439,7 +439,7 @@ theorem gamma_three_div_two_lt_one : gamma (3 / 2) < 1 :=
     norm_num
 #align real.Gamma_three_div_two_lt_one Real.gamma_three_div_two_lt_one
 
-theorem gamma_strictMonoOn_Ici : StrictMonoOn gamma (Ici 2) :=
+theorem gamma_strictMonoOn_Ici : StrictMonoOn Gamma (Ici 2) :=
   by
   convert
     convex_on_Gamma.strict_mono_of_lt (by norm_num : (0 : ℝ) < 3 / 2)
@@ -464,7 +464,7 @@ multiple of `Gamma`, and we can compute the constant by specialising at `s = 1`.
 
 /-- Auxiliary definition for the doubling formula (we'll show this is equal to `Gamma s`) -/
 def doublingGamma (s : ℝ) : ℝ :=
-  gamma (s / 2) * gamma (s / 2 + 1 / 2) * 2 ^ (s - 1) / sqrt π
+  Gamma (s / 2) * Gamma (s / 2 + 1 / 2) * 2 ^ (s - 1) / sqrt π
 #align real.doubling_Gamma Real.doublingGamma
 
 theorem doublingGamma_add_one (s : ℝ) (hs : s ≠ 0) : doublingGamma (s + 1) = s * doublingGamma s :=
@@ -481,7 +481,7 @@ theorem doublingGamma_one : doublingGamma 1 = 1 := by
 
 theorem log_doublingGamma_eq :
     EqOn (log ∘ doublingGamma)
-      (fun s => log (gamma (s / 2)) + log (gamma (s / 2 + 1 / 2)) + s * log 2 - log (2 * sqrt π))
+      (fun s => log (Gamma (s / 2)) + log (Gamma (s / 2 + 1 / 2)) + s * log 2 - log (2 * sqrt π))
       (Ioi 0) :=
   by
   intro s hs
@@ -520,7 +520,7 @@ theorem doublingGamma_log_convex_Ioi : ConvexOn ℝ (Ioi (0 : ℝ)) (log ∘ dou
       (convexOn_id (convex_Ioi (0 : ℝ))).smul (log_pos one_lt_two).le
 #align real.doubling_Gamma_log_convex_Ioi Real.doublingGamma_log_convex_Ioi
 
-theorem doublingGamma_eq_gamma {s : ℝ} (hs : 0 < s) : doublingGamma s = gamma s :=
+theorem doublingGamma_eq_gamma {s : ℝ} (hs : 0 < s) : doublingGamma s = Gamma s :=
   by
   refine'
     eq_Gamma_of_log_convex doubling_Gamma_log_convex_Ioi
@@ -533,7 +533,7 @@ theorem doublingGamma_eq_gamma {s : ℝ} (hs : 0 < s) : doublingGamma s = gamma
 we shall later prove this for all `s` as `real.Gamma_mul_Gamma_add_half` (superseding this result)
 but this result is needed as an intermediate step. -/
 theorem gamma_mul_gamma_add_half_of_pos {s : ℝ} (hs : 0 < s) :
-    gamma s * gamma (s + 1 / 2) = gamma (2 * s) * 2 ^ (1 - 2 * s) * sqrt π :=
+    Gamma s * Gamma (s + 1 / 2) = Gamma (2 * s) * 2 ^ (1 - 2 * s) * sqrt π :=
   by
   rw [← doubling_Gamma_eq_Gamma (mul_pos two_pos hs), doubling_Gamma,
     mul_div_cancel_left _ (two_ne_zero' ℝ), (by abel : 1 - 2 * s = -(2 * s - 1)),
Diff
@@ -269,7 +269,7 @@ theorem logGammaSeq_add_one (x : ℝ) (n : ℕ) :
   · rw [Nat.cast_ne_zero]; exact Nat.succ_ne_zero n
   · rw [Nat.cast_ne_zero]; exact Nat.factorial_ne_zero n
   have :
-    (∑ m : ℕ in Finset.range (n + 1), log (x + 1 + ↑m)) =
+    ∑ m : ℕ in Finset.range (n + 1), log (x + 1 + ↑m) =
       ∑ k : ℕ in Finset.range (n + 1), log (x + ↑(k + 1)) :=
     by
     refine' Finset.sum_congr (by rfl) fun m hm => _
Diff
@@ -4,11 +4,12 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: David Loeffler
 
 ! This file was ported from Lean 3 source module analysis.special_functions.gamma.bohr_mollerup
-! leanprover-community/mathlib commit 7982767093ae38cba236487f9c9dd9cd99f63c16
+! leanprover-community/mathlib commit a3209ddf94136d36e5e5c624b10b2a347cc9d090
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
 import Mathbin.Analysis.SpecialFunctions.Gamma.Basic
+import Mathbin.Analysis.SpecialFunctions.Gaussian
 
 /-! # Convexity properties of the Gamma function
 
@@ -30,6 +31,14 @@ context of this proof, we place them in a separate namespace `real.bohr_mollerup
 general form of the Euler limit formula valid for any real or complex `x`; see
 `real.Gamma_seq_tendsto_Gamma` and `complex.Gamma_seq_tendsto_Gamma` in the file
 `analysis.special_functions.gamma.beta`.)
+
+As an application of the Bohr-Mollerup theorem we prove the Legendre doubling formula for the
+Gamma function for real positive `s` (which will be upgraded to a proof for all complex `s` in a
+later file).
+
+TODO: This argument can be extended to prove the general `k`-multiplication formula (at least up
+to a constant, and it should be possible to deduce the value of this constant using Stirling's
+formula).
 -/
 
 
@@ -37,7 +46,59 @@ noncomputable section
 
 open Filter Set MeasureTheory
 
-open scoped Nat ENNReal Topology BigOperators
+open scoped Nat ENNReal Topology BigOperators Real
+
+section Convexity
+
+-- Porting note: move the following lemmas to `Analysis.Convex.Function`
+variable {𝕜 E β : Type _} {s : Set E} {f g : E → β} [OrderedSemiring 𝕜] [SMul 𝕜 E] [AddCommMonoid E]
+  [OrderedAddCommMonoid β]
+
+theorem ConvexOn.congr [SMul 𝕜 β] (hf : ConvexOn 𝕜 s f) (hfg : EqOn f g s) : ConvexOn 𝕜 s g :=
+  ⟨hf.1, fun x hx y hy a b ha hb hab => by
+    simpa only [← hfg hx, ← hfg hy, ← hfg (hf.1 hx hy ha hb hab)] using hf.2 hx hy ha hb hab⟩
+#align convex_on.congr ConvexOn.congr
+
+theorem ConcaveOn.congr [SMul 𝕜 β] (hf : ConcaveOn 𝕜 s f) (hfg : EqOn f g s) : ConcaveOn 𝕜 s g :=
+  ⟨hf.1, fun x hx y hy a b ha hb hab => by
+    simpa only [← hfg hx, ← hfg hy, ← hfg (hf.1 hx hy ha hb hab)] using hf.2 hx hy ha hb hab⟩
+#align concave_on.congr ConcaveOn.congr
+
+theorem StrictConvexOn.congr [SMul 𝕜 β] (hf : StrictConvexOn 𝕜 s f) (hfg : EqOn f g s) :
+    StrictConvexOn 𝕜 s g :=
+  ⟨hf.1, fun x hx y hy hxy a b ha hb hab => by
+    simpa only [← hfg hx, ← hfg hy, ← hfg (hf.1 hx hy ha.le hb.le hab)] using
+      hf.2 hx hy hxy ha hb hab⟩
+#align strict_convex_on.congr StrictConvexOn.congr
+
+theorem StrictConcaveOn.congr [SMul 𝕜 β] (hf : StrictConcaveOn 𝕜 s f) (hfg : EqOn f g s) :
+    StrictConcaveOn 𝕜 s g :=
+  ⟨hf.1, fun x hx y hy hxy a b ha hb hab => by
+    simpa only [← hfg hx, ← hfg hy, ← hfg (hf.1 hx hy ha.le hb.le hab)] using
+      hf.2 hx hy hxy ha hb hab⟩
+#align strict_concave_on.congr StrictConcaveOn.congr
+
+theorem ConvexOn.add_const [Module 𝕜 β] (hf : ConvexOn 𝕜 s f) (b : β) :
+    ConvexOn 𝕜 s (f + fun _ => b) :=
+  hf.add (convexOn_const _ hf.1)
+#align convex_on.add_const ConvexOn.add_const
+
+theorem ConcaveOn.add_const [Module 𝕜 β] (hf : ConcaveOn 𝕜 s f) (b : β) :
+    ConcaveOn 𝕜 s (f + fun _ => b) :=
+  hf.add (concaveOn_const _ hf.1)
+#align concave_on.add_const ConcaveOn.add_const
+
+theorem StrictConvexOn.add_const {γ : Type _} {f : E → γ} [OrderedCancelAddCommMonoid γ]
+    [Module 𝕜 γ] (hf : StrictConvexOn 𝕜 s f) (b : γ) : StrictConvexOn 𝕜 s (f + fun _ => b) :=
+  hf.add_convexOn (convexOn_const _ hf.1)
+#align strict_convex_on.add_const StrictConvexOn.add_const
+
+theorem StrictConcaveOn.add_const {γ : Type _} {f : E → γ} [OrderedCancelAddCommMonoid γ]
+    [Module 𝕜 γ] (hf : StrictConcaveOn 𝕜 s f) (b : γ) : StrictConcaveOn 𝕜 s (f + fun _ => b) :=
+  hf.add_concaveOn (concaveOn_const _ hf.1)
+#align strict_concave_on.add_const StrictConcaveOn.add_const
+
+end Convexity
 
 namespace Real
 
@@ -121,18 +182,14 @@ theorem convexOn_log_gamma : ConvexOn ℝ (Ioi 0) (log ∘ gamma) :=
 
 theorem convexOn_gamma : ConvexOn ℝ (Ioi 0) gamma :=
   by
-  refine' ⟨convex_Ioi 0, fun x hx y hy a b ha hb hab => _⟩
-  have :=
-    ConvexOn.comp (convex_on_exp.subset (subset_univ _) _) convex_on_log_Gamma fun u hu v hv huv =>
-      exp_le_exp.mpr huv
-  convert this.2 hx hy ha hb hab
-  · rw [Function.comp_apply, exp_log (Gamma_pos_of_pos <| this.1 hx hy ha hb hab)]
-  · rw [Function.comp_apply, exp_log (Gamma_pos_of_pos hx)]
-  · rw [Function.comp_apply, exp_log (Gamma_pos_of_pos hy)]
-  · rw [convex_iff_is_preconnected]
-    refine' is_preconnected_Ioi.image _ fun x hx => ContinuousAt.continuousWithinAt _
-    refine' (differentiable_at_Gamma fun m => _).ContinuousAt.log (Gamma_pos_of_pos hx).ne'
-    exact (neg_lt_iff_pos_add.mpr (add_pos_of_pos_of_nonneg hx (Nat.cast_nonneg m))).ne'
+  refine'
+    ((convex_on_exp.subset (subset_univ _) _).comp convex_on_log_Gamma
+          (exp_monotone.monotone_on _)).congr
+      fun x hx => exp_log (Gamma_pos_of_pos hx)
+  rw [convex_iff_is_preconnected]
+  refine' is_preconnected_Ioi.image _ fun x hx => ContinuousAt.continuousWithinAt _
+  refine' (differentiable_at_Gamma fun m => _).ContinuousAt.log (Gamma_pos_of_pos hx).ne'
+  exact (neg_lt_iff_pos_add.mpr (add_pos_of_pos_of_nonneg hx (Nat.cast_nonneg m))).ne'
 #align real.convex_on_Gamma Real.convexOn_gamma
 
 end Convexity
@@ -394,5 +451,98 @@ theorem gamma_strictMonoOn_Ici : StrictMonoOn gamma (Ici 2) :=
 
 end StrictMono
 
+section Doubling
+
+/-!
+## The Gamma doubling formula
+
+As a fun application of the Bohr-Mollerup theorem, we prove the Gamma-function doubling formula
+(for positive real `s`). The idea is that `2 ^ s * Gamma (s / 2) * Gamma (s / 2 + 1 / 2)` is
+log-convex and satisfies the Gamma functional equation, so it must actually be a constant
+multiple of `Gamma`, and we can compute the constant by specialising at `s = 1`. -/
+
+
+/-- Auxiliary definition for the doubling formula (we'll show this is equal to `Gamma s`) -/
+def doublingGamma (s : ℝ) : ℝ :=
+  gamma (s / 2) * gamma (s / 2 + 1 / 2) * 2 ^ (s - 1) / sqrt π
+#align real.doubling_Gamma Real.doublingGamma
+
+theorem doublingGamma_add_one (s : ℝ) (hs : s ≠ 0) : doublingGamma (s + 1) = s * doublingGamma s :=
+  by
+  rw [doubling_Gamma, doubling_Gamma, (by abel : s + 1 - 1 = s - 1 + 1), add_div, add_assoc,
+    add_halves (1 : ℝ), Gamma_add_one (div_ne_zero hs two_ne_zero), rpow_add two_pos, rpow_one]
+  ring
+#align real.doubling_Gamma_add_one Real.doublingGamma_add_one
+
+theorem doublingGamma_one : doublingGamma 1 = 1 := by
+  simp_rw [doubling_Gamma, Gamma_one_half_eq, add_halves (1 : ℝ), sub_self, Gamma_one, mul_one,
+    rpow_zero, mul_one, div_self (sqrt_ne_zero'.mpr pi_pos)]
+#align real.doubling_Gamma_one Real.doublingGamma_one
+
+theorem log_doublingGamma_eq :
+    EqOn (log ∘ doublingGamma)
+      (fun s => log (gamma (s / 2)) + log (gamma (s / 2 + 1 / 2)) + s * log 2 - log (2 * sqrt π))
+      (Ioi 0) :=
+  by
+  intro s hs
+  have h1 : sqrt π ≠ 0 := sqrt_ne_zero'.mpr pi_pos
+  have h2 : Gamma (s / 2) ≠ 0 := (Gamma_pos_of_pos <| div_pos hs two_pos).ne'
+  have h3 : Gamma (s / 2 + 1 / 2) ≠ 0 :=
+    (Gamma_pos_of_pos <| add_pos (div_pos hs two_pos) one_half_pos).ne'
+  have h4 : (2 : ℝ) ^ (s - 1) ≠ 0 := (rpow_pos_of_pos two_pos _).ne'
+  rw [Function.comp_apply, doubling_Gamma, log_div (mul_ne_zero (mul_ne_zero h2 h3) h4) h1,
+    log_mul (mul_ne_zero h2 h3) h4, log_mul h2 h3, log_rpow two_pos, log_mul two_ne_zero h1]
+  ring_nf
+#align real.log_doubling_Gamma_eq Real.log_doublingGamma_eq
+
+theorem doublingGamma_log_convex_Ioi : ConvexOn ℝ (Ioi (0 : ℝ)) (log ∘ doublingGamma) :=
+  by
+  refine' (((ConvexOn.add _ _).add _).AddConst _).congr log_doubling_Gamma_eq.symm
+  · convert
+      convex_on_log_Gamma.comp_affine_map (DistribMulAction.toLinearMap ℝ ℝ (1 / 2 : ℝ)).toAffineMap
+    · simpa only [zero_div] using (preimage_const_mul_Ioi (0 : ℝ) one_half_pos).symm
+    · ext1 x
+      change log (Gamma (x / 2)) = log (Gamma ((1 / 2 : ℝ) • x))
+      rw [smul_eq_mul, mul_comm, mul_one_div]
+  · refine' ConvexOn.subset _ (Ioi_subset_Ioi <| neg_one_lt_zero.le) (convex_Ioi _)
+    convert
+      convex_on_log_Gamma.comp_affine_map
+        ((DistribMulAction.toLinearMap ℝ ℝ (1 / 2 : ℝ)).toAffineMap +
+          AffineMap.const _ _ (1 / 2 : ℝ))
+    · change Ioi (-1 : ℝ) = ((fun x : ℝ => x + 1 / 2) ∘ fun x : ℝ => (1 / 2 : ℝ) * x) ⁻¹' Ioi 0
+      rw [preimage_comp, preimage_add_const_Ioi, zero_sub,
+        preimage_const_mul_Ioi (_ : ℝ) one_half_pos, neg_div, div_self (@one_half_pos ℝ _).ne']
+    · ext1 x
+      change log (Gamma (x / 2 + 1 / 2)) = log (Gamma ((1 / 2 : ℝ) • x + 1 / 2))
+      rw [smul_eq_mul, mul_comm, mul_one_div]
+  ·
+    simpa only [mul_comm _ (log _)] using
+      (convexOn_id (convex_Ioi (0 : ℝ))).smul (log_pos one_lt_two).le
+#align real.doubling_Gamma_log_convex_Ioi Real.doublingGamma_log_convex_Ioi
+
+theorem doublingGamma_eq_gamma {s : ℝ} (hs : 0 < s) : doublingGamma s = gamma s :=
+  by
+  refine'
+    eq_Gamma_of_log_convex doubling_Gamma_log_convex_Ioi
+      (fun y hy => doubling_Gamma_add_one y hy.ne') (fun y hy => _) doubling_Gamma_one hs
+  apply_rules [mul_pos, Gamma_pos_of_pos, add_pos, inv_pos_of_pos, rpow_pos_of_pos, two_pos,
+    one_pos, sqrt_pos_of_pos pi_pos]
+#align real.doubling_Gamma_eq_Gamma Real.doublingGamma_eq_gamma
+
+/-- Legendre's doubling formula for the Gamma function, for positive real arguments. Note that
+we shall later prove this for all `s` as `real.Gamma_mul_Gamma_add_half` (superseding this result)
+but this result is needed as an intermediate step. -/
+theorem gamma_mul_gamma_add_half_of_pos {s : ℝ} (hs : 0 < s) :
+    gamma s * gamma (s + 1 / 2) = gamma (2 * s) * 2 ^ (1 - 2 * s) * sqrt π :=
+  by
+  rw [← doubling_Gamma_eq_Gamma (mul_pos two_pos hs), doubling_Gamma,
+    mul_div_cancel_left _ (two_ne_zero' ℝ), (by abel : 1 - 2 * s = -(2 * s - 1)),
+    rpow_neg zero_le_two]
+  field_simp [(sqrt_pos_of_pos pi_pos).ne', (rpow_pos_of_pos two_pos (2 * s - 1)).ne']
+  ring
+#align real.Gamma_mul_Gamma_add_half_of_pos Real.gamma_mul_gamma_add_half_of_pos
+
+end Doubling
+
 end Real
 
Diff
@@ -90,8 +90,9 @@ theorem gamma_mul_add_mul_le_rpow_gamma_mul_rpow_gamma {s t a b : ℝ} (hs : 0 <
       · exact continuous_at_rpow_const _ _ (Or.inl (ne_of_lt hx).symm)
   -- now apply Hölder:
   rw [Gamma_eq_integral hs, Gamma_eq_integral ht, Gamma_eq_integral hst]
-  convert MeasureTheory.integral_mul_le_Lp_mul_Lq_of_nonneg e (posf' a s) (posf' b t)
-      (f_mem_Lp ha hs) (f_mem_Lp hb ht) using
+  convert
+    MeasureTheory.integral_mul_le_Lp_mul_Lq_of_nonneg e (posf' a s) (posf' b t) (f_mem_Lp ha hs)
+      (f_mem_Lp hb ht) using
     1
   · refine' set_integral_congr measurableSet_Ioi fun x hx => _
     dsimp only [f]
@@ -383,7 +384,8 @@ theorem gamma_three_div_two_lt_one : gamma (3 / 2) < 1 :=
 
 theorem gamma_strictMonoOn_Ici : StrictMonoOn gamma (Ici 2) :=
   by
-  convert convex_on_Gamma.strict_mono_of_lt (by norm_num : (0 : ℝ) < 3 / 2)
+  convert
+    convex_on_Gamma.strict_mono_of_lt (by norm_num : (0 : ℝ) < 3 / 2)
       (by norm_num : (3 / 2 : ℝ) < 2) (Gamma_two.symm ▸ Gamma_three_div_two_lt_one)
   symm
   rw [inter_eq_right_iff_subset]
Diff
@@ -66,7 +66,7 @@ theorem gamma_mul_add_mul_le_rpow_gamma_mul_rpow_gamma {s t a b : ℝ} (hs : 0 <
     intro c x hc u hx
     dsimp only [f]
     rw [mul_rpow (exp_pos _).le ((rpow_nonneg_of_nonneg hx.le) _), ← exp_mul, ← rpow_mul hx.le]
-    congr 2 <;> · field_simp [hc.ne'] ; ring
+    congr 2 <;> · field_simp [hc.ne']; ring
   -- show `f c u` is in `ℒp` for `p = 1/c`:
   have f_mem_Lp :
     ∀ {c u : ℝ} (hc : 0 < c) (hu : 0 < u),
@@ -194,12 +194,12 @@ theorem f_add_nat_ge (hf_conv : ConvexOn ℝ (Ioi 0) f)
   have c :=
     (convex_on_iff_slope_mono_adjacent.mp <| hf_conv).2 npos (by linarith : 0 < (n : ℝ) + x)
       (by linarith : (n : ℝ) - 1 < (n : ℝ)) (by linarith)
-  rw [add_sub_cancel', sub_sub_cancel, div_one] at c
+  rw [add_sub_cancel', sub_sub_cancel, div_one] at c 
   have : f (↑n - 1) = f n - log (↑n - 1) :=
     by
     nth_rw_rhs 1 [(by ring : (n : ℝ) = ↑n - 1 + 1)]
     rw [hf_feq npos, add_sub_cancel]
-  rwa [this, le_div_iff hx, sub_sub_cancel, le_sub_iff_add_le, mul_comm _ x, add_comm] at c
+  rwa [this, le_div_iff hx, sub_sub_cancel, le_sub_iff_add_le, mul_comm _ x, add_comm] at c 
 #align real.bohr_mollerup.f_add_nat_ge Real.BohrMollerup.f_add_nat_ge
 
 theorem logGammaSeq_add_one (x : ℝ) (n : ℕ) :
@@ -280,8 +280,8 @@ theorem tendsto_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
   · rw [Nat.cast_zero, zero_add]
     exact fun _ hx' => tendsto_log_gamma_seq_of_le_one hf_conv (@hf_feq) hx hx'
   · intro hy hy'
-    rw [Nat.cast_succ, ← sub_le_iff_le_add] at hy'
-    rw [Nat.cast_succ, ← lt_sub_iff_add_lt] at hy
+    rw [Nat.cast_succ, ← sub_le_iff_le_add] at hy' 
+    rw [Nat.cast_succ, ← lt_sub_iff_add_lt] at hy 
     specialize hm ((Nat.cast_nonneg _).trans_lt hy) hy hy'
     -- now massage gauss_product n (x - 1) into gauss_product (n - 1) x
     have :
@@ -291,7 +291,7 @@ theorem tendsto_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
       by
       refine' eventually.mp (eventually_ge_at_top 1) (eventually_of_forall fun n hn => _)
       have := log_gamma_seq_add_one (x - 1) (n - 1)
-      rw [sub_add_cancel, Nat.sub_add_cancel hn] at this
+      rw [sub_add_cancel, Nat.sub_add_cancel hn] at this 
       rw [this]
       ring
     replace hm :=
@@ -309,11 +309,11 @@ theorem tendsto_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
       ext1 n
       dsimp only [Function.comp_apply]
       rw [sub_add_cancel, Nat.add_sub_cancel]
-    rw [this] at hm
+    rw [this] at hm 
     convert hm.sub (tendsto_log_nat_add_one_sub_log.const_mul x) using 2
     · ext1 n; ring
     · have := hf_feq ((Nat.cast_nonneg m).trans_lt hy)
-      rw [sub_add_cancel] at this
+      rw [sub_add_cancel] at this 
       rw [this]
       ring
 #align real.bohr_mollerup.tendsto_log_gamma_seq Real.BohrMollerup.tendsto_logGammaSeq
@@ -341,7 +341,7 @@ theorem eq_gamma_of_log_convex {f : ℝ → ℝ} (hf_conv : ConvexOn ℝ (Ioi 0)
   exact fun x hx => log_inj_on_pos (hf_pos hx) (Gamma_pos_of_pos hx) (this hx)
   intro x hx
   have e1 := bohr_mollerup.tendsto_log_gamma_seq hf_conv _ hx
-  · rw [Function.comp_apply log f 1, hf_one, log_one, sub_zero] at e1
+  · rw [Function.comp_apply log f 1, hf_one, log_one, sub_zero] at e1 
     exact tendsto_nhds_unique e1 (bohr_mollerup.tendsto_log_Gamma hx)
   · intro y hy
     rw [Function.comp_apply, hf_feq hy, log_mul hy.ne' (hf_pos hy).ne']
@@ -372,7 +372,7 @@ theorem gamma_three_div_two_lt_one : gamma (3 / 2) < 1 :=
   rw [Function.comp_apply, Function.comp_apply, Nat.cast_two, Gamma_two, log_one, zero_add,
     (by norm_num : (2 : ℝ) + 1 / 2 = 3 / 2 + 1), Gamma_add_one A.ne',
     log_mul A.ne' (Gamma_pos_of_pos A).ne', ← le_sub_iff_add_le',
-    log_le_iff_le_exp (Gamma_pos_of_pos A)] at this
+    log_le_iff_le_exp (Gamma_pos_of_pos A)] at this 
   refine' this.trans_lt (exp_lt_one_iff.mpr _)
   rw [mul_comm, ← mul_div_assoc, div_sub' _ _ (2 : ℝ) two_ne_zero]
   refine' div_neg_of_neg_of_pos _ two_pos
Diff
@@ -84,7 +84,7 @@ theorem gamma_mul_add_mul_le_rpow_gamma_mul_rpow_gamma {s t a b : ℝ} (hs : 0 <
       rw [fpow hc u hx]
       congr 1
       exact (norm_of_nonneg (posf _ _ x hx)).symm
-    · refine' ContinuousOn.aEStronglyMeasurable _ measurableSet_Ioi
+    · refine' ContinuousOn.aestronglyMeasurable _ measurableSet_Ioi
       refine' (Continuous.continuousOn _).mul (ContinuousAt.continuousOn fun x hx => _)
       · exact continuous_exp.comp (continuous_const.mul continuous_id')
       · exact continuous_at_rpow_const _ _ (Or.inl (ne_of_lt hx).symm)
Diff
@@ -37,7 +37,7 @@ noncomputable section
 
 open Filter Set MeasureTheory
 
-open Nat ENNReal Topology BigOperators
+open scoped Nat ENNReal Topology BigOperators
 
 namespace Real
 
Diff
@@ -66,9 +66,7 @@ theorem gamma_mul_add_mul_le_rpow_gamma_mul_rpow_gamma {s t a b : ℝ} (hs : 0 <
     intro c x hc u hx
     dsimp only [f]
     rw [mul_rpow (exp_pos _).le ((rpow_nonneg_of_nonneg hx.le) _), ← exp_mul, ← rpow_mul hx.le]
-    congr 2 <;>
-      · field_simp [hc.ne']
-        ring
+    congr 2 <;> · field_simp [hc.ne'] ; ring
   -- show `f c u` is in `ℒp` for `p = 1/c`:
   have f_mem_Lp :
     ∀ {c u : ℝ} (hc : 0 < c) (hu : 0 < u),
@@ -99,11 +97,8 @@ theorem gamma_mul_add_mul_le_rpow_gamma_mul_rpow_gamma {s t a b : ℝ} (hs : 0 <
     dsimp only [f]
     have A : exp (-x) = exp (-a * x) * exp (-b * x) := by
       rw [← exp_add, ← add_mul, ← neg_add, hab, neg_one_mul]
-    have B : x ^ (a * s + b * t - 1) = x ^ (a * (s - 1)) * x ^ (b * (t - 1)) :=
-      by
-      rw [← rpow_add hx, hab']
-      congr 1
-      ring
+    have B : x ^ (a * s + b * t - 1) = x ^ (a * (s - 1)) * x ^ (b * (t - 1)) := by
+      rw [← rpow_add hx, hab']; congr 1; ring
     rw [A, B]
     ring
   · rw [one_div_one_div, one_div_one_div]
@@ -171,9 +166,7 @@ theorem f_add_nat_eq (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = f y + log y)
   by
   induction' n with n hn
   · simp
-  · have : x + n.succ = x + n + 1 := by
-      push_cast
-      ring
+  · have : x + n.succ = x + n + 1 := by push_cast ; ring
     rw [this, hf_feq, hn]
     rw [Finset.range_succ, Finset.sum_insert Finset.not_mem_range_self]
     abel
@@ -186,10 +179,7 @@ theorem f_add_nat_le (hf_conv : ConvexOn ℝ (Ioi 0) f)
     f (n + x) ≤ f n + x * log n :=
   by
   have hn' : 0 < (n : ℝ) := nat.cast_pos.mpr (Nat.pos_of_ne_zero hn)
-  have : f n + x * log n = (1 - x) * f n + x * f (n + 1) :=
-    by
-    rw [hf_feq hn']
-    ring
+  have : f n + x * log n = (1 - x) * f n + x * f (n + 1) := by rw [hf_feq hn']; ring
   rw [this, (by ring : (n : ℝ) + x = (1 - x) * n + x * (n + 1))]
   simpa only [smul_eq_mul] using
     hf_conv.2 hn' (by linarith : 0 < (n + 1 : ℝ)) (by linarith : 0 ≤ 1 - x) hx.le (by linarith)
@@ -200,10 +190,7 @@ theorem f_add_nat_ge (hf_conv : ConvexOn ℝ (Ioi 0) f)
     (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = f y + log y) (hn : 2 ≤ n) (hx : 0 < x) :
     f n + x * log (n - 1) ≤ f (n + x) :=
   by
-  have npos : 0 < (n : ℝ) - 1 :=
-    by
-    rw [← Nat.cast_one, sub_pos, Nat.cast_lt]
-    linarith
+  have npos : 0 < (n : ℝ) - 1 := by rw [← Nat.cast_one, sub_pos, Nat.cast_lt]; linarith
   have c :=
     (convex_on_iff_slope_mono_adjacent.mp <| hf_conv).2 npos (by linarith : 0 < (n : ℝ) + x)
       (by linarith : (n : ℝ) - 1 < (n : ℝ)) (by linarith)
@@ -220,12 +207,9 @@ theorem logGammaSeq_add_one (x : ℝ) (n : ℕ) :
   by
   dsimp only [Nat.factorial_succ, log_gamma_seq]
   conv_rhs => rw [Finset.sum_range_succ', Nat.cast_zero, add_zero]
-  rw [Nat.cast_mul, log_mul]
-  rotate_left
-  · rw [Nat.cast_ne_zero]
-    exact Nat.succ_ne_zero n
-  · rw [Nat.cast_ne_zero]
-    exact Nat.factorial_ne_zero n
+  rw [Nat.cast_mul, log_mul]; rotate_left
+  · rw [Nat.cast_ne_zero]; exact Nat.succ_ne_zero n
+  · rw [Nat.cast_ne_zero]; exact Nat.factorial_ne_zero n
   have :
     (∑ m : ℕ in Finset.range (n + 1), log (x + 1 + ↑m)) =
       ∑ k : ℕ in Finset.range (n + 1), log (x + ↑(k + 1)) :=
@@ -290,8 +274,7 @@ theorem tendsto_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
       · rwa [nat.ceil_eq_zero.mpr (by linarith : x - 1 ≤ 0), Nat.cast_zero]
       · convert Nat.ceil_lt_add_one (by linarith : 0 ≤ x - 1)
         abel
-    · rw [← sub_le_iff_le_add]
-      exact Nat.le_ceil _
+    · rw [← sub_le_iff_le_add]; exact Nat.le_ceil _
   intro m
   induction' m with m hm generalizing x
   · rw [Nat.cast_zero, zero_add]
@@ -328,8 +311,7 @@ theorem tendsto_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
       rw [sub_add_cancel, Nat.add_sub_cancel]
     rw [this] at hm
     convert hm.sub (tendsto_log_nat_add_one_sub_log.const_mul x) using 2
-    · ext1 n
-      ring
+    · ext1 n; ring
     · have := hf_feq ((Nat.cast_nonneg m).trans_lt hy)
       rw [sub_add_cancel] at this
       rw [this]
@@ -383,7 +365,7 @@ theorem gamma_three_div_two_lt_one : gamma (3 / 2) < 1 :=
   have :=
     bohr_mollerup.f_add_nat_le convex_on_log_Gamma (fun y hy => _) two_ne_zero one_half_pos
       (by norm_num : 1 / 2 ≤ (1 : ℝ))
-  swap
+  swap;
   ·
     rw [Function.comp_apply, Gamma_add_one hy.ne', log_mul hy.ne' (Gamma_pos_of_pos hy).ne',
       add_comm]
Diff
@@ -86,7 +86,7 @@ theorem gamma_mul_add_mul_le_rpow_gamma_mul_rpow_gamma {s t a b : ℝ} (hs : 0 <
       rw [fpow hc u hx]
       congr 1
       exact (norm_of_nonneg (posf _ _ x hx)).symm
-    · refine' ContinuousOn.aeStronglyMeasurable _ measurableSet_Ioi
+    · refine' ContinuousOn.aEStronglyMeasurable _ measurableSet_Ioi
       refine' (Continuous.continuousOn _).mul (ContinuousAt.continuousOn fun x hx => _)
       · exact continuous_exp.comp (continuous_const.mul continuous_id')
       · exact continuous_at_rpow_const _ _ (Or.inl (ne_of_lt hx).symm)

Changes in mathlib4

mathlib3
mathlib4
chore: adapt to multiple goal linter 2 (#12361)

A PR analogous to #12338: reformatting proofs following the multiple goals linter of #12339.

Diff
@@ -216,9 +216,9 @@ theorem f_add_nat_eq (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = f y + log y)
   · simp
   · have : x + n.succ = x + n + 1 := by push_cast; ring
     rw [this, hf_feq, hn]
-    rw [Finset.range_succ, Finset.sum_insert Finset.not_mem_range_self]
-    abel
-    linarith [(Nat.cast_nonneg n : 0 ≤ (n : ℝ))]
+    · rw [Finset.range_succ, Finset.sum_insert Finset.not_mem_range_self]
+      abel
+    · linarith [(Nat.cast_nonneg n : 0 ≤ (n : ℝ))]
 #align real.bohr_mollerup.f_add_nat_eq Real.BohrMollerup.f_add_nat_eq
 
 /-- Linear upper bound for `f (x + n)` on unit interval -/
@@ -293,13 +293,13 @@ theorem tendsto_logGammaSeq_of_le_one (hf_conv : ConvexOn ℝ (Ioi 0) f)
   refine' tendsto_of_tendsto_of_tendsto_of_le_of_le' _ tendsto_const_nhds _ _
   -- Porting note: `show` no longer reorders goals
   pick_goal 4
-  show ∀ᶠ n : ℕ in atTop, logGammaSeq x n ≤ f x - f 1
-  · filter_upwards [eventually_ne_atTop 0] with n hn using
+  · show ∀ᶠ n : ℕ in atTop, logGammaSeq x n ≤ f x - f 1
+    filter_upwards [eventually_ne_atTop 0] with n hn using
       le_sub_iff_add_le'.mpr (ge_logGammaSeq hf_conv hf_feq hx hn)
   -- Porting note: `show` no longer reorders goals
   pick_goal 3
-  show ∀ᶠ n : ℕ in atTop, f x - f 1 - x * (log (n + 1) - log n) ≤ logGammaSeq x n
-  · filter_upwards with n
+  · show ∀ᶠ n : ℕ in atTop, f x - f 1 - x * (log (n + 1) - log n) ≤ logGammaSeq x n
+    filter_upwards with n
     rw [sub_le_iff_le_add', sub_le_iff_le_add']
     convert le_logGammaSeq hf_conv (@hf_feq) hx hx' n using 1
     ring
feat: Axiomatise b ≠ 0 → a * b / b = a (#12424)

This lets us unify a few lemmas between GroupWithZero and EuclideanDomain and two lemmas that were previously proved separately for Nat, Int, Polynomial.

Diff
@@ -122,7 +122,7 @@ theorem Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma {s t a b : ℝ} (hs : 0 <
     intro c x hc u hx
     dsimp only [f]
     rw [mul_rpow (exp_pos _).le ((rpow_nonneg hx.le) _), ← exp_mul, ← rpow_mul hx.le]
-    congr 2 <;> · field_simp [hc.ne']; ring
+    congr 2 <;> field_simp [hc.ne']; ring
   -- show `f c u` is in `ℒp` for `p = 1/c`:
   have f_mem_Lp :
     ∀ {c u : ℝ} (hc : 0 < c) (hu : 0 < u),
chore: replace set_integral with setIntegral (#12215)

Done with a global search and replace, and then (to fix the #align lines), replace (#align \S*)setIntegral with $1set_integral.

Diff
@@ -149,7 +149,7 @@ theorem Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma {s t a b : ℝ} (hs : 0 <
     MeasureTheory.integral_mul_le_Lp_mul_Lq_of_nonneg e (posf' a s) (posf' b t) (f_mem_Lp ha hs)
       (f_mem_Lp hb ht) using
     1
-  · refine' set_integral_congr measurableSet_Ioi fun x hx => _
+  · refine' setIntegral_congr measurableSet_Ioi fun x hx => _
     dsimp only
     have A : exp (-x) = exp (-a * x) * exp (-b * x) := by
       rw [← exp_add, ← add_mul, ← neg_add, hab, neg_one_mul]
@@ -158,7 +158,7 @@ theorem Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma {s t a b : ℝ} (hs : 0 <
     rw [A, B]
     ring
   · rw [one_div_one_div, one_div_one_div]
-    congr 2 <;> exact set_integral_congr measurableSet_Ioi fun x hx => fpow (by assumption) _ hx
+    congr 2 <;> exact setIntegral_congr measurableSet_Ioi fun x hx => fpow (by assumption) _ hx
 #align real.Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma Real.Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma
 
 theorem convexOn_log_Gamma : ConvexOn ℝ (Ioi 0) (log ∘ Gamma) := by
refactor(SpecialFunctions/Gaussian): shorten long pole (#12104)

This splits up Analysis/SpecialFunctions/Gaussian.lean into three pieces, with the heaviest imports only needed in the later chunks. As only the first chunk is needed for many applications, including those on the critical path towards NumberTheory/Cyclotomic/PID.lean, this should improve overall build parallelism and shorten mathlib's overall compilation time.

Diff
@@ -3,8 +3,7 @@ Copyright (c) 2023 David Loeffler. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: David Loeffler
 -/
-import Mathlib.Analysis.SpecialFunctions.Gamma.Basic
-import Mathlib.Analysis.SpecialFunctions.Gaussian
+import Mathlib.Analysis.SpecialFunctions.Gaussian.GaussianIntegral
 
 #align_import analysis.special_functions.gamma.bohr_mollerup from "leanprover-community/mathlib"@"a3209ddf94136d36e5e5c624b10b2a347cc9d090"
 
feat: add notation for Real.sqrt (#12056)

This adds the notation √r for Real.sqrt r. The precedence is such that √x⁻¹ is parsed as √(x⁻¹); not because this is particularly desirable, but because it's the default and the choice doesn't really matter.

This is extracted from #7907, which adds a more general nth root typeclass. The idea is to perform all the boring substitutions downstream quickly, so that we can play around with custom elaborators with a much slower rate of code-rot. This PR also won't rot as quickly, as it does not forbid writing x.sqrt as that PR does.

While perhaps claiming for Real.sqrt is greedy; it:

  • Is far more common thatn NNReal.sqrt and Nat.sqrt
  • Is far more interesting to mathlib than sqrt on Float
  • Can be overloaded anyway, so this does not prevent downstream code using the notation on their own types.
  • Will be replaced by a more general typeclass in a future PR.

Zulip

Co-authored-by: Yury G. Kudryashov <urkud@urkud.name>

Diff
@@ -444,7 +444,7 @@ multiple of `Gamma`, and we can compute the constant by specialising at `s = 1`.
 
 /-- Auxiliary definition for the doubling formula (we'll show this is equal to `Gamma s`) -/
 def doublingGamma (s : ℝ) : ℝ :=
-  Gamma (s / 2) * Gamma (s / 2 + 1 / 2) * 2 ^ (s - 1) / sqrt π
+  Gamma (s / 2) * Gamma (s / 2 + 1 / 2) * 2 ^ (s - 1) / √π
 #align real.doubling_Gamma Real.doublingGamma
 
 theorem doublingGamma_add_one (s : ℝ) (hs : s ≠ 0) :
@@ -461,10 +461,10 @@ theorem doublingGamma_one : doublingGamma 1 = 1 := by
 
 theorem log_doublingGamma_eq :
     EqOn (log ∘ doublingGamma)
-      (fun s => log (Gamma (s / 2)) + log (Gamma (s / 2 + 1 / 2)) + s * log 2 - log (2 * sqrt π))
+      (fun s => log (Gamma (s / 2)) + log (Gamma (s / 2 + 1 / 2)) + s * log 2 - log (2 * √π))
       (Ioi 0) := by
   intro s hs
-  have h1 : sqrt π ≠ 0 := sqrt_ne_zero'.mpr pi_pos
+  have h1 : √π ≠ 0 := sqrt_ne_zero'.mpr pi_pos
   have h2 : Gamma (s / 2) ≠ 0 := (Gamma_pos_of_pos <| div_pos hs two_pos).ne'
   have h3 : Gamma (s / 2 + 1 / 2) ≠ 0 :=
     (Gamma_pos_of_pos <| add_pos (div_pos hs two_pos) one_half_pos).ne'
@@ -512,7 +512,7 @@ theorem doublingGamma_eq_Gamma {s : ℝ} (hs : 0 < s) : doublingGamma s = Gamma
 we shall later prove this for all `s` as `Real.Gamma_mul_Gamma_add_half` (superseding this result)
 but this result is needed as an intermediate step. -/
 theorem Gamma_mul_Gamma_add_half_of_pos {s : ℝ} (hs : 0 < s) :
-    Gamma s * Gamma (s + 1 / 2) = Gamma (2 * s) * 2 ^ (1 - 2 * s) * sqrt π := by
+    Gamma s * Gamma (s + 1 / 2) = Gamma (2 * s) * 2 ^ (1 - 2 * s) * √π := by
   rw [← doublingGamma_eq_Gamma (mul_pos two_pos hs), doublingGamma,
     mul_div_cancel_left₀ _ (two_ne_zero' ℝ), (by abel : 1 - 2 * s = -(2 * s - 1)),
     rpow_neg zero_le_two]
chore: avoid Ne.def (adaptation for nightly-2024-03-27) (#11801)
Diff
@@ -130,7 +130,7 @@ theorem Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma {s t a b : ℝ} (hs : 0 <
       Memℒp (f c u) (ENNReal.ofReal (1 / c)) (volume.restrict (Ioi 0)) := by
     intro c u hc hu
     have A : ENNReal.ofReal (1 / c) ≠ 0 := by
-      rwa [Ne.def, ENNReal.ofReal_eq_zero, not_le, one_div_pos]
+      rwa [Ne, ENNReal.ofReal_eq_zero, not_le, one_div_pos]
     have B : ENNReal.ofReal (1 / c) ≠ ∞ := ENNReal.ofReal_ne_top
     rw [← memℒp_norm_rpow_iff _ A B, ENNReal.toReal_ofReal (one_div_nonneg.mpr hc.le),
       ENNReal.div_self A B, memℒp_one_iff_integrable]
chore: Rename mul-div cancellation lemmas (#11530)

Lemma names around cancellation of multiplication and division are a mess.

This PR renames a handful of them according to the following table (each big row contains the multiplicative statement, then the three rows contain the GroupWithZero lemma name, the Group lemma, the AddGroup lemma name).

| Statement | New name | Old name | |

Diff
@@ -241,7 +241,7 @@ theorem f_add_nat_ge (hf_conv : ConvexOn ℝ (Ioi 0) f)
   have c :=
     (convexOn_iff_slope_mono_adjacent.mp <| hf_conv).2 npos (by linarith : 0 < (n : ℝ) + x)
       (by linarith : (n : ℝ) - 1 < (n : ℝ)) (by linarith)
-  rw [add_sub_cancel', sub_sub_cancel, div_one] at c
+  rw [add_sub_cancel_left, sub_sub_cancel, div_one] at c
   have : f (↑n - 1) = f n - log (↑n - 1) := by
     -- Porting note: was
     -- nth_rw_rhs 1 [(by ring : (n : ℝ) = ↑n - 1 + 1)]
@@ -282,7 +282,7 @@ theorem ge_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
   dsimp [logGammaSeq]
   rw [← add_sub_assoc, sub_le_iff_le_add, ← f_add_nat_eq (@hf_feq) hx, add_comm x _]
   refine' le_trans (le_of_eq _) (f_add_nat_ge hf_conv @hf_feq _ hx)
-  · rw [f_nat_eq @hf_feq, Nat.add_sub_cancel, Nat.cast_add_one, add_sub_cancel]
+  · rw [f_nat_eq @hf_feq, Nat.add_sub_cancel, Nat.cast_add_one, add_sub_cancel_right]
     · ring
     · exact Nat.succ_ne_zero _
   · omega
@@ -514,7 +514,7 @@ but this result is needed as an intermediate step. -/
 theorem Gamma_mul_Gamma_add_half_of_pos {s : ℝ} (hs : 0 < s) :
     Gamma s * Gamma (s + 1 / 2) = Gamma (2 * s) * 2 ^ (1 - 2 * s) * sqrt π := by
   rw [← doublingGamma_eq_Gamma (mul_pos two_pos hs), doublingGamma,
-    mul_div_cancel_left _ (two_ne_zero' ℝ), (by abel : 1 - 2 * s = -(2 * s - 1)),
+    mul_div_cancel_left₀ _ (two_ne_zero' ℝ), (by abel : 1 - 2 * s = -(2 * s - 1)),
     rpow_neg zero_le_two]
   field_simp [(sqrt_pos_of_pos pi_pos).ne', (rpow_pos_of_pos two_pos (2 * s - 1)).ne']
   ring
chore: golf using filter_upwards (#11208)

This is presumably not exhaustive, but covers about a hundred instances.

Style opinions (e.g., why a particular change is great/not a good idea) are very welcome; I'm still forming my own.

Diff
@@ -295,12 +295,12 @@ theorem tendsto_logGammaSeq_of_le_one (hf_conv : ConvexOn ℝ (Ioi 0) f)
   -- Porting note: `show` no longer reorders goals
   pick_goal 4
   show ∀ᶠ n : ℕ in atTop, logGammaSeq x n ≤ f x - f 1
-  · refine' Eventually.mp (eventually_ne_atTop 0) (eventually_of_forall fun n hn => _)
-    exact le_sub_iff_add_le'.mpr (ge_logGammaSeq hf_conv (@hf_feq) hx hn)
+  · filter_upwards [eventually_ne_atTop 0] with n hn using
+      le_sub_iff_add_le'.mpr (ge_logGammaSeq hf_conv hf_feq hx hn)
   -- Porting note: `show` no longer reorders goals
   pick_goal 3
   show ∀ᶠ n : ℕ in atTop, f x - f 1 - x * (log (n + 1) - log n) ≤ logGammaSeq x n
-  · refine' eventually_of_forall fun n => _
+  · filter_upwards with n
     rw [sub_le_iff_le_add', sub_le_iff_le_add']
     convert le_logGammaSeq hf_conv (@hf_feq) hx hx' n using 1
     ring
refactor: optimize proofs with omega (#11093)

I ran tryAtEachStep on all files under Mathlib to find all locations where omega succeeds. For each that was a linarith without an only, I tried replacing it with omega, and I verified that elaboration time got smaller. (In almost all cases, there was a noticeable speedup.) I also replaced some slow aesops along the way.

Diff
@@ -285,8 +285,7 @@ theorem ge_logGammaSeq (hf_conv : ConvexOn ℝ (Ioi 0) f)
   · rw [f_nat_eq @hf_feq, Nat.add_sub_cancel, Nat.cast_add_one, add_sub_cancel]
     · ring
     · exact Nat.succ_ne_zero _
-  · apply Nat.succ_le_succ
-    linarith [Nat.pos_of_ne_zero hn]
+  · omega
 #align real.bohr_mollerup.ge_log_gamma_seq Real.BohrMollerup.ge_logGammaSeq
 
 theorem tendsto_logGammaSeq_of_le_one (hf_conv : ConvexOn ℝ (Ioi 0) f)
chore: prepare Lean version bump with explicit simp (#10999)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -121,7 +121,7 @@ theorem Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma {s t a b : ℝ} (hs : 0 <
   have fpow :
     ∀ {c x : ℝ} (_ : 0 < c) (u : ℝ) (_ : 0 < x), exp (-x) * x ^ (u - 1) = f c u x ^ (1 / c) := by
     intro c x hc u hx
-    dsimp only
+    dsimp only [f]
     rw [mul_rpow (exp_pos _).le ((rpow_nonneg hx.le) _), ← exp_mul, ← rpow_mul hx.le]
     congr 2 <;> · field_simp [hc.ne']; ring
   -- show `f c u` is in `ℒp` for `p = 1/c`:
chore: remove stream-of-consciousness uses of have, replace and suffices (#10640)

No changes to tactic file, it's just boring fixes throughout the library.

This follows on from #6964.

Co-authored-by: sgouezel <sebastien.gouezel@univ-rennes1.fr> Co-authored-by: Eric Wieser <wieser.eric@gmail.com>

Diff
@@ -379,8 +379,8 @@ function on the positive reals which satisfies `f 1 = 1` and `f (x + 1) = x * f
 theorem eq_Gamma_of_log_convex {f : ℝ → ℝ} (hf_conv : ConvexOn ℝ (Ioi 0) (log ∘ f))
     (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = y * f y) (hf_pos : ∀ {y : ℝ}, 0 < y → 0 < f y)
     (hf_one : f 1 = 1) : EqOn f Gamma (Ioi (0 : ℝ)) := by
-  suffices : EqOn (log ∘ f) (log ∘ Gamma) (Ioi (0 : ℝ))
-  exact fun x hx => log_injOn_pos (hf_pos hx) (Gamma_pos_of_pos hx) (this hx)
+  suffices EqOn (log ∘ f) (log ∘ Gamma) (Ioi (0 : ℝ)) from
+    fun x hx ↦ log_injOn_pos (hf_pos hx) (Gamma_pos_of_pos hx) (this hx)
   intro x hx
   have e1 := BohrMollerup.tendsto_logGammaSeq hf_conv ?_ hx
   · rw [Function.comp_apply (f := log) (g := f) (x := 1), hf_one, log_one, sub_zero] at e1
feat: Conjugate exponents in ℝ≥0 (#10589)

It happens often that we have p q : ℝ≥0 that are conjugate. So far, we only had a predicate for real numbers to be conjugate, which made dealing with ℝ≥0 conjugates clumsy.

This PR

  • introduces NNReal.IsConjExponent, NNReal.conjExponent
  • renames Real.IsConjugateExponent, Real.conjugateExponent to Real.IsConjExponent, Real.conjExponent
  • renames a few more lemmas to match up the Real and NNReal versions

From LeanAPAP

Diff
@@ -110,7 +110,7 @@ theorem Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma {s t a b : ℝ} (hs : 0 <
   -- We will apply Hölder's inequality, for the conjugate exponents `p = 1 / a`
   -- and `q = 1 / b`, to the functions `f a s` and `f b t`, where `f` is as follows:
   let f : ℝ → ℝ → ℝ → ℝ := fun c u x => exp (-c * x) * x ^ (c * (u - 1))
-  have e : IsConjugateExponent (1 / a) (1 / b) := Real.isConjugateExponent_one_div ha hb hab
+  have e : IsConjExponent (1 / a) (1 / b) := Real.isConjExponent_one_div ha hb hab
   have hab' : b = 1 - a := by linarith
   have hst : 0 < a * s + b * t := add_pos (mul_pos ha hs) (mul_pos hb ht)
   -- some properties of f:
chore: Rename rpow_nonneg_of_nonneg to rpow_nonneg (#9518)

This better matches other lemma names.

From LeanAPAP

Diff
@@ -122,7 +122,7 @@ theorem Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma {s t a b : ℝ} (hs : 0 <
     ∀ {c x : ℝ} (_ : 0 < c) (u : ℝ) (_ : 0 < x), exp (-x) * x ^ (u - 1) = f c u x ^ (1 / c) := by
     intro c x hc u hx
     dsimp only
-    rw [mul_rpow (exp_pos _).le ((rpow_nonneg_of_nonneg hx.le) _), ← exp_mul, ← rpow_mul hx.le]
+    rw [mul_rpow (exp_pos _).le ((rpow_nonneg hx.le) _), ← exp_mul, ← rpow_mul hx.le]
     congr 2 <;> · field_simp [hc.ne']; ring
   -- show `f c u` is in `ℒp` for `p = 1/c`:
   have f_mem_Lp :
feat: golf using gcongr throughout the library (#8752)

Following on from previous gcongr golfing PRs #4702 and #4784.

This is a replacement for #7901: this round of golfs, first introduced there, there exposed some performance issues in gcongr, hopefully fixed by #8731, and I am opening a new PR so that the performance can be checked against current master rather than master at the time of #7901.

Diff
@@ -167,12 +167,11 @@ theorem convexOn_log_Gamma : ConvexOn ℝ (Ioi 0) (log ∘ Gamma) := by
   have : b = 1 - a := by linarith
   subst this
   simp_rw [Function.comp_apply, smul_eq_mul]
-  rw [← log_rpow (Gamma_pos_of_pos hy), ← log_rpow (Gamma_pos_of_pos hx), ←
-    log_mul (rpow_pos_of_pos (Gamma_pos_of_pos hx) _).ne'
-      (rpow_pos_of_pos (Gamma_pos_of_pos hy) _).ne',
-    log_le_log (Gamma_pos_of_pos (add_pos (mul_pos ha hx) (mul_pos hb hy)))
-      (mul_pos (rpow_pos_of_pos (Gamma_pos_of_pos hx) _) (rpow_pos_of_pos (Gamma_pos_of_pos hy) _))]
-  exact Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma hx hy ha hb hab
+  simp only [mem_Ioi] at hx hy
+  rw [← log_rpow, ← log_rpow, ← log_mul]
+  · gcongr
+    exact Gamma_mul_add_mul_le_rpow_Gamma_mul_rpow_Gamma hx hy ha hb hab
+  all_goals positivity
 #align real.convex_on_log_Gamma Real.convexOn_log_Gamma
 
 theorem convexOn_Gamma : ConvexOn ℝ (Ioi 0) Gamma := by
@@ -261,8 +260,7 @@ theorem logGammaSeq_add_one (x : ℝ) (n : ℕ) :
   have :
     ∑ m : ℕ in Finset.range (n + 1), log (x + 1 + ↑m) =
       ∑ k : ℕ in Finset.range (n + 1), log (x + ↑(k + 1)) := by
-    refine' Finset.sum_congr (by rfl) fun m _ => _
-    congr 1
+    congr! 2 with m
     push_cast
     abel
   rw [← this, Nat.cast_add_one n]
chore: add basic @[simp]s for Gamma (#7977)

I don't personally have any need for these. It just seemed like these would make the API more complete.

Diff
@@ -397,8 +397,7 @@ end BohrMollerup
 -- (section)
 section StrictMono
 
-theorem Gamma_two : Gamma 2 = 1 := by
-  simpa [one_add_one_eq_two, Nat.factorial] using Gamma_nat_eq_factorial 1
+theorem Gamma_two : Gamma 2 = 1 := by simp [Nat.factorial_one]
 #align real.Gamma_two Real.Gamma_two
 
 theorem Gamma_three_div_two_lt_one : Gamma (3 / 2) < 1 := by
chore: Make Set/Finset lemmas match lattice lemma names (#7378)

Rename union_eq_left_iff_subset to union_eq_left to match sup_eq_left. Similarly for the right and inter versions.

Diff
@@ -429,7 +429,7 @@ theorem Gamma_strictMonoOn_Ici : StrictMonoOn Gamma (Ici 2) := by
     convexOn_Gamma.strict_mono_of_lt (by norm_num : (0 : ℝ) < 3 / 2)
       (by norm_num : (3 / 2 : ℝ) < 2) (Gamma_two.symm ▸ Gamma_three_div_two_lt_one)
   symm
-  rw [inter_eq_right_iff_subset]
+  rw [inter_eq_right]
   exact fun x hx => two_pos.trans_le <| mem_Ici.mp hx
 #align real.Gamma_strict_mono_on_Ici Real.Gamma_strictMonoOn_Ici
 
chore: rm [@simp](https://github.com/simp) from factorial (#7078)

Co-authored-by: Moritz Firsching <firsching@google.com>

Diff
@@ -397,7 +397,8 @@ end BohrMollerup
 -- (section)
 section StrictMono
 
-theorem Gamma_two : Gamma 2 = 1 := by simpa [one_add_one_eq_two] using Gamma_nat_eq_factorial 1
+theorem Gamma_two : Gamma 2 = 1 := by
+  simpa [one_add_one_eq_two, Nat.factorial] using Gamma_nat_eq_factorial 1
 #align real.Gamma_two Real.Gamma_two
 
 theorem Gamma_three_div_two_lt_one : Gamma (3 / 2) < 1 := by
chore: banish Type _ and Sort _ (#6499)

We remove all possible occurences of Type _ and Sort _ in favor of Type* and Sort*.

This has nice performance benefits.

Diff
@@ -49,7 +49,7 @@ open scoped Nat ENNReal Topology BigOperators Real
 section Convexity
 
 -- Porting note: move the following lemmas to `Analysis.Convex.Function`
-variable {𝕜 E β : Type _} {s : Set E} {f g : E → β} [OrderedSemiring 𝕜] [SMul 𝕜 E] [AddCommMonoid E]
+variable {𝕜 E β : Type*} {s : Set E} {f g : E → β} [OrderedSemiring 𝕜] [SMul 𝕜 E] [AddCommMonoid E]
   [OrderedAddCommMonoid β]
 
 theorem ConvexOn.congr [SMul 𝕜 β] (hf : ConvexOn 𝕜 s f) (hfg : EqOn f g s) : ConvexOn 𝕜 s g :=
@@ -86,12 +86,12 @@ theorem ConcaveOn.add_const [Module 𝕜 β] (hf : ConcaveOn 𝕜 s f) (b : β)
   hf.add (concaveOn_const _ hf.1)
 #align concave_on.add_const ConcaveOn.add_const
 
-theorem StrictConvexOn.add_const {γ : Type _} {f : E → γ} [OrderedCancelAddCommMonoid γ]
+theorem StrictConvexOn.add_const {γ : Type*} {f : E → γ} [OrderedCancelAddCommMonoid γ]
     [Module 𝕜 γ] (hf : StrictConvexOn 𝕜 s f) (b : γ) : StrictConvexOn 𝕜 s (f + fun _ => b) :=
   hf.add_convexOn (convexOn_const _ hf.1)
 #align strict_convex_on.add_const StrictConvexOn.add_const
 
-theorem StrictConcaveOn.add_const {γ : Type _} {f : E → γ} [OrderedCancelAddCommMonoid γ]
+theorem StrictConcaveOn.add_const {γ : Type*} {f : E → γ} [OrderedCancelAddCommMonoid γ]
     [Module 𝕜 γ] (hf : StrictConcaveOn 𝕜 s f) (b : γ) : StrictConcaveOn 𝕜 s (f + fun _ => b) :=
   hf.add_concaveOn (concaveOn_const _ hf.1)
 #align strict_concave_on.add_const StrictConcaveOn.add_const
chore: script to replace headers with #align_import statements (#5979)

Open in Gitpod

Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -2,15 +2,12 @@
 Copyright (c) 2023 David Loeffler. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: David Loeffler
-
-! This file was ported from Lean 3 source module analysis.special_functions.gamma.bohr_mollerup
-! leanprover-community/mathlib commit a3209ddf94136d36e5e5c624b10b2a347cc9d090
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathlib.Analysis.SpecialFunctions.Gamma.Basic
 import Mathlib.Analysis.SpecialFunctions.Gaussian
 
+#align_import analysis.special_functions.gamma.bohr_mollerup from "leanprover-community/mathlib"@"a3209ddf94136d36e5e5c624b10b2a347cc9d090"
+
 /-! # Convexity properties of the Gamma function
 
 In this file, we prove that `Gamma` and `log ∘ Gamma` are convex functions on the positive real
chore: remove occurrences of semicolon after space (#5713)

This is the second half of the changes originally in #5699, removing all occurrences of ; after a space and implementing a linter rule to enforce it.

In most cases this 2-character substring has a space after it, so the following command was run first:

find . -type f -name "*.lean" -exec sed -i -E 's/ ; /; /g' {} \;

The remaining cases were few enough in number that they were done manually.

Diff
@@ -219,7 +219,7 @@ theorem f_add_nat_eq (hf_feq : ∀ {y : ℝ}, 0 < y → f (y + 1) = f y + log y)
     f (x + n) = f x + ∑ m : ℕ in Finset.range n, log (x + m) := by
   induction' n with n hn
   · simp
-  · have : x + n.succ = x + n + 1 := by push_cast ; ring
+  · have : x + n.succ = x + n + 1 := by push_cast; ring
     rw [this, hf_feq, hn]
     rw [Finset.range_succ, Finset.sum_insert Finset.not_mem_range_self]
     abel
feat: port Analysis.SpecialFunctions.Gamma.BohrMollerup (#5486)

Dependencies 12 + 1163

1164 files ported (99.0%)
522063 lines ported (98.9%)
Show graph

The unported dependencies are

The following 1 dependencies have changed in mathlib3 since they were ported, which may complicate porting this file