Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,22 @@ public lemma convexOn_ringInverse :
by_cases ha' : a = 0
· have hb' : b = 1 := by grind
simp only [ha', hb', one_mul, zero_add, gt_iff_lt]
grind
#adaptation_note /-- Before nightly-2026-06-04, this was just `grind.
`spectrum_pos` is not activating in `grind` despite the
```
grind_pattern IsStrictlyPositive.spectrum_pos => x ∈ spectrum 𝕜 a, IsStrictlyPositive a
```
rule, because `grind` will not fill in the `𝕜 := ℝ`. -/
exact zpos.spectrum_pos hr
· grind [add_pos_of_pos_of_nonneg, mul_nonneg]
have h₂ : (a • 1 + b • z ^ (-1 : ℝ)) = cfc (fun r => (a + b * r ^ (-1 : ℝ))) z := by
rw [CFC.rpow_eq_cfc_real zpos.nonneg]
have hcont : ContinuousOn (fun r : ℝ => (r ^ (-1 : ℝ))) (spectrum ℝ z) :=
ContinuousOn.rpow_const (f := id) (by fun_prop) (by grind)
ContinuousOn.rpow_const (f := id) (by fun_prop) (by
#adaptation_note /-- Before nightly-2026-06-04, this was just `grind. -/
intro x h
have := IsStrictlyPositive.spectrum_pos (𝕜 := ℝ) zpos h
grind)
rw [← cfc_smul b _ z hcont, ← Algebra.algebraMap_eq_smul_one, ← cfc_const_add a _ z]
refine cfc_congr fun r hr => ?_
simp
Expand All @@ -72,7 +82,11 @@ public lemma convexOn_ringInverse :
have : 0 ≤ b * r := by positivity
cases lt_or_eq_of_le ha <;> grind
· refine ContinuousOn.const_add (ContinuousOn.const_mul ?_ _) _
exact ContinuousOn.rpow_const (by fun_prop) (by grind)
exact ContinuousOn.rpow_const (by fun_prop) (by
#adaptation_note /-- Before nightly-2026-06-04, this was just `grind. -/
intro x h
have := IsStrictlyPositive.spectrum_pos (𝕜 := ℝ) zpos h
grind)
· intro r hr
suffices (a • 1 + b • r) ^ (-1 : ℤ) ≤ a • 1 ^ (-1 : ℤ) + b • r ^ (-1 : ℤ) by
simp_rw [← Real.rpow_intCast] at this
Expand Down
11 changes: 11 additions & 0 deletions Mathlib/Analysis/SpecialFunctions/Pow/NthRootLemmas.lean
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,20 @@ private theorem nthRoot.lt_pow_go_succ_aux0 (hb : b ≠ 0) :
rw [Nat.le_div_iff_mul_le (by positivity), Nat.mul_comm,
← Nat.add_mul_div_right _ _ (by positivity),
Nat.le_div_iff_mul_le (by positivity)]
#adaptation_note /-- Prior to nightly-2026-04-06, this was
```
have := (Commute.all (b : ℤ) (a - b)).pow_add_mul_le_add_pow_of_sq_nonneg
(by positivity) (sq_nonneg _) (sq_nonneg _) (by grind) (n + 1)
grind
```
-/
zify
have h := pow_add_mul_le_add_pow_of_sq_nonneg (a := (b : ℤ)) (b := (a : ℤ) - b)
(ha := by positivity) (Hsq := by positivity) (Hsq' := by positivity) (H := by omega)
(n := n + 1)
rw [← sub_nonneg] at h ⊢
convert h using 1
rw [pow_succ]; push_cast; ring1

private theorem nthRoot.always_exists (n a : ℕ) :
∃ c, c ^ (n + 1) ≤ a ∧ a < (c + 1) ^ (n + 1) := by
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,15 @@ theorem eval_T_real_mem_Icc (n : ℤ) {x : ℝ} (hx : x ∈ Set.Icc (-1) 1) :
grind [T_real_cos, cos_mem_Icc]

theorem abs_eval_T_real_le_one (n : ℤ) {x : ℝ} (hx : |x| ≤ 1) :
|(T ℝ n).eval x| ≤ 1 := by grind [eval_T_real_mem_Icc]
|(T ℝ n).eval x| ≤ 1 := by
#adaptation_note /-- Before nightly-2026-04-07, this was just
`grind [eval_T_real_mem_Icc]`. `grind`'s e-matching now keeps the
`Polynomial.eval` produced by the lemma (which uses `instCommSemiring.toSemiring`)
and the `Polynomial.eval` propagated by abs unfolding (which uses `Real.semiring`)
as distinct atoms, even though they are `rfl`-equal, so the contradiction is
never found. -/
have h := eval_T_real_mem_Icc n (Set.mem_Icc.mpr (abs_le.mp hx))
exact abs_le.mpr (Set.mem_Icc.mp h)

theorem one_le_eval_T_real (n : ℤ) {x : ℝ} (hx : 1 ≤ x) : 1 ≤ (T ℝ n).eval x := by
rw [← cosh_arcosh hx]
Expand Down
9 changes: 3 additions & 6 deletions Mathlib/Computability/Partrec.lean
Original file line number Diff line number Diff line change
Expand Up @@ -718,9 +718,6 @@ theorem fix_aux {α σ} (f : α →. σ ⊕ α) (a : α) (b : σ) :
b ∈ PFun.fix f a := by
intro F; refine ⟨fun h => ?_, fun h => ?_⟩
· rcases h with ⟨n, ⟨_x, h₁⟩, h₂⟩
#adaptation_note /-- Before leanprover/lean4#13166, the proof from here to the end of the
first branch was:
```
have : ∀ m a', Sum.inr a' ∈ F a m → b ∈ PFun.fix f a' → b ∈ PFun.fix f a := by
intro m a' am ba
induction m generalizing a' with simp [F] at am
Expand Down Expand Up @@ -754,9 +751,9 @@ theorem fix_aux {α σ} (f : α →. σ ⊕ α) (a : α) (b : σ) :
· simpa [F] using Or.inr ⟨_, hk, h₂⟩
· rwa [le_antisymm (Nat.le_of_lt_succ mk) km]
· rcases IH _ am₃ k.succ (by simpa [F] using ⟨_, hk, am₃⟩) with ⟨n, hn₁, hn₂⟩
#adaptation_note /-- After leanprover/lean4#13166 which arrived in nightly-2026-03-28:
This `clear_value` used to not be necessary.
-/
#adaptation_note /-- Before https://github.com/leanprover/lean4/pull/13166
(replacing grind's canonicalizer with a type-directed normalizer),
the `clear_value F` was not required here. -/
clear_value F
grind

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ lemma G2_eq_tsum_G2Term (z : ℍ) : G2 z = ∑' m, ∑' n, G2Term z ![m, n] := b
exact tsum_congr (fun b ↦ by simp [eisSummand, G2Term, aux_identity z a b, zpow_ofNat])
· simpa only [tsum_symmetricIco_linear_sub_linear_add_one_eq_zero z, add_zero]
using (G2Term_prod_summable z).prod
· grind [(G2Term_prod_summable z).prod.congr]
· exact (G2Term_prod_summable z).prod
· exact summable_zero.congr
fun b ↦ by simp [← tsum_symmetricIco_linear_sub_linear_add_one_eq_zero z b]

Expand Down
4 changes: 2 additions & 2 deletions Mathlib/NumberTheory/Padics/MahlerBasis.lean
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,12 @@ private lemma bojanic_mahler_step2 {f : C(ℤ_[p], E)} {s t : ℕ}
refine (nnnorm_smul_le _ _).trans <| mul_le_mul_of_nonneg_right ?_ (by simp only [zero_le])
-- remains to show norm of binomial coeff is `≤ p⁻¹`
rw [mem_range] at hi
have : 0 < (p ^ t).choose (i + 1) := Nat.choose_pos (by lia)
have : 0 < (p ^ t).choose (i + 1) := Nat.choose_pos (by omega)
rw [← zpow_neg_one, ← coe_le_coe, coe_nnnorm, PadicInt.norm_eq_zpow_neg_valuation
(mod_cast this.ne'), coe_zpow, NNReal.coe_natCast,
zpow_le_zpow_iff_right₀ (mod_cast hp.out.one_lt), neg_le_neg_iff,
← PadicInt.valuation_coe, PadicInt.coe_natCast, Padic.valuation_natCast, Nat.one_le_cast]
exact one_le_padicValNat_of_dvd this.ne' <| hp.out.dvd_choose_pow (by lia) (by lia)
exact one_le_padicValNat_of_dvd this.ne' <| hp.out.dvd_choose_pow (by lia) (by omega)
· -- Bounding the sum over `range (n + 1)`: every term is small by the choice of `t`
refine norm_sum_le_of_forall_le_of_nonempty nonempty_range_add_one (fun i _ ↦ ?_)
calc ‖((-1 : ℤ) ^ (n - i) * n.choose i) • (f (i + ↑(p ^ t)) - f i)‖
Expand Down
4 changes: 3 additions & 1 deletion Mathlib/RingTheory/LocalRing/ResidueField/Polynomial.lean
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ def residueFieldMapCAlgEquiv [J.LiesOver I] (hJ : J = I.map C) :
apply_fun aeval (algebraMap R[X] J.ResidueField X) at hr
simpa [hx, aeval_map_algebraMap, aeval_algebraMap_apply, Algebra.smul_def] using hr
refine ((IsUnit.mk0 (algebraMap R I.ResidueField s) (by simpa)).map C).mul_right_injective ?_
simp only [← algebraMap_eq, ← Algebra.smul_def, algebraMap_smul, ← hr]
simp only [← algebraMap_eq, ← Algebra.smul_def]
erw [algebraMap_smul]
simp only [← hr]
simpa [Polynomial.ext_iff, Ideal.mem_map_C_iff] using hJ.le hx
· apply AlgHom.coe_ringHom_injective
apply IsFractionRing.injective_comp_algebraMap (A := I.ResidueField[X])
Expand Down
9 changes: 8 additions & 1 deletion Mathlib/RingTheory/Smooth/Local.lean
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,14 @@ theorem FormallySmooth.iff_injective_cotangentComplexBaseChange
(cotangentComplexBaseChange R S P (ResidueField S)).baseChange K ∘ₗ
(AlgebraTensorModule.cancelBaseChange _ _ _ _ _).symm.toLinearMap =
(cotangentComplexBaseChange R S P K) := by
ext; simp [cotangentComplexBaseChange_tmul]
ext
#adaptation_note /-- Prior to nightly-2026-04-06, this was just `simp`. -/
simp_rw [AlgebraTensorModule.curry_apply, LinearMap.restrictScalars_comp, curry_apply,
LinearMap.coe_comp, LinearMap.coe_restrictScalars, LinearEquiv.coe_coe, Function.comp_apply,
AlgebraTensorModule.cancelBaseChange_symm_tmul, LinearMap.baseChange_tmul,
cotangentComplexBaseChange_tmul, kerToTensor_apply, one_smul]
erw [AlgebraTensorModule.cancelBaseChange_tmul]
simp
rw [← this]
refine .trans ?_ ((AlgebraTensorModule.cancelBaseChange _ _ _ _ _).comp_injective _).symm
exact ((AlgebraTensorModule.cancelBaseChange _ _ _ _ _).symm.injective_comp _).symm
Expand Down
4 changes: 3 additions & 1 deletion Mathlib/RingTheory/Spectrum/Prime/FreeLocus.lean
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,8 @@ lemma rankAtStalk_eq (p : PrimeSpectrum R) :
let e : k ⊗[Localization.AtPrime p.asIdeal] (Localization.AtPrime p.asIdeal ⊗[R] M) ≃ₗ[k]
k ⊗[R] M :=
AlgebraTensorModule.cancelBaseChange _ _ _ _ _
rw [← e.finrank_eq, finrank_baseChange, rankAtStalk_eq_finrank_tensorProduct]
rw [← e.finrank_eq]
erw [finrank_baseChange]
rw [rankAtStalk_eq_finrank_tensorProduct]

end Module
8 changes: 6 additions & 2 deletions Mathlib/RingTheory/Spectrum/Prime/Polynomial.lean
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,16 @@ lemma isNilpotent_tensor_residueField_iff
· have := (algebraMap R (A ⊗[R] I.ResidueField)).codomain_trivial
simp [Subsingleton.elim I ⊤, Subsingleton.elim (f ⊗ₜ[R] (1 : I.ResidueField)) 0]
have : Module.finrank I.ResidueField (I.ResidueField ⊗[R] A) = Module.finrank R A := by
rw [Module.finrank_tensorProduct, Module.finrank_self, one_mul]
rw [Module.finrank_tensorProduct]
erw [Module.finrank_self]
rw [one_mul]
rw [← IsNilpotent.map_iff (Algebra.TensorProduct.comm R A I.ResidueField).injective]
simp only [Algebra.TensorProduct.algebraMap_apply, Algebra.algebraMap_self, RingHom.id_apply,
Algebra.coe_lmul_eq_mul, Algebra.TensorProduct.comm_tmul]
rw [← IsNilpotent.map_iff (Algebra.lmul_injective (R := I.ResidueField)),
LinearMap.isNilpotent_iff_charpoly, ← Algebra.baseChange_lmul, LinearMap.charpoly_baseChange]
simp_rw [this, ← ((LinearMap.mul R A) f).charpoly_natDegree]
erw [this]
simp_rw [← ((LinearMap.mul R A) f).charpoly_natDegree]
constructor
· intro e i hi
replace e := congr(($e).coeff i)
Expand Down Expand Up @@ -137,6 +140,7 @@ end PrimeSpectrum

namespace Polynomial

set_option backward.isDefEq.respectTransparency false in
lemma mem_image_comap_C_basicOpen (f : R[X]) (x : PrimeSpectrum R) :
x ∈ comap C '' basicOpen f ↔ ∃ i, f.coeff i ∉ x.asIdeal := by
trans f.map (algebraMap R x.asIdeal.ResidueField) ≠ 0
Expand Down
5 changes: 5 additions & 0 deletions Mathlib/RingTheory/Unramified/LocalStructure.lean
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,11 @@ lemma exists_notMem_forall_ne_mem_and_adjoin_eq_top
#adaptation_note /-- Needed after nightly-2023-02-23 -/
have : p.IsPrime := Ideal.IsPrime.under R Q
classical
#adaptation_note /-- After nightly-2026-04-06, typeclass synthesis fails to find these
instances; provide them explicitly. -/
letI : Module p.ResidueField (p.Fiber S) := TensorProduct.leftModule
letI : IsScalarTower p.ResidueField (p.Fiber S) (p.Fiber S) := IsScalarTower.right
letI : Module.Finite p.ResidueField (p.Fiber S) := Module.Finite.base_change R p.ResidueField S
have : IsArtinianRing (p.Fiber S) := .of_finite p.ResidueField _
let α := PrimeSpectrum.primesOverOrderIsoFiber R S p
obtain ⟨x, hx0, hx⟩ : ∃ x : Q.ResidueField, x ≠ 0 ∧ p.ResidueField[x] = ⊤ := by
Expand Down
2 changes: 1 addition & 1 deletion Mathlib/Tactic/Linter/HashCommandLinter.lean
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Intended to be used in the `hashCommand` linter, where we want to enter `set_opt
private partial def withSetOptionIn' (cmd : CommandElab) : CommandElab := fun stx => do
if stx.getKind == ``Lean.Parser.Command.in then
if stx[0].getKind == ``Lean.Parser.Command.set_option then
let opts ← Elab.elabSetOption stx[0][1] stx[0][3]
let (opts, _) ← Elab.elabSetOption stx[0][1] stx[0][3]
withScope (fun scope => { scope with opts }) do
withSetOptionIn' cmd stx[2]
else
Expand Down
8 changes: 4 additions & 4 deletions lake-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,20 @@
"type": "git",
"subDir": null,
"scope": "leanprover-community",
"rev": "f74c7555aaa94eadd7b7bff9170f7983f92aac21",
"rev": "ad416ddf6cc9d5b1c00eaf04a48e703538132760",
"name": "aesop",
"manifestFile": "lake-manifest.json",
"inputRev": "v4.30.0-rc1",
"inputRev": "nightly-testing",
"inherited": false,
"configFile": "lakefile.toml"},
{"url": "https://github.com/leanprover-community/quote4",
"type": "git",
"subDir": null,
"scope": "leanprover-community",
"rev": "7aa86cb20b8458748dc24d55dab2d7ea01161057",
"rev": "bee778191c7fbea31864ecfe1809b8837626aba0",
"name": "Qq",
"manifestFile": "lake-manifest.json",
"inputRev": "v4.30.0-rc1",
"inputRev": "nightly-testing",
"inherited": false,
"configFile": "lakefile.toml"},
{"url": "https://github.com/leanprover-community/batteries",
Expand Down
4 changes: 2 additions & 2 deletions lakefile.lean
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ open Lake DSL
-/

require "leanprover-community" / "batteries" @ git "v4.30.0-rc1"
require "leanprover-community" / "Qq" @ git "v4.30.0-rc1"
require "leanprover-community" / "aesop" @ git "v4.30.0-rc1"
require "leanprover-community" / "Qq" @ git "nightly-testing"
require "leanprover-community" / "aesop" @ git "nightly-testing"
require "leanprover-community" / "proofwidgets" @ git "v0.0.97"
with NameMap.empty.insert `errorOnBuild
"ProofWidgets failed to reuse pre-built JS code. \
Expand Down
2 changes: 1 addition & 1 deletion lean-toolchain
Original file line number Diff line number Diff line change
@@ -1 +1 @@
leanprover/lean4:nightly-2026-04-06
leanprover/lean4:nightly-2026-04-07
Loading